@gameroom/cli
Version:
A command line tool for Gameroom
111 lines (109 loc) • 5.07 kB
JavaScript
const cosmetic = require('cosmetic'),
{ models: { Product } } = require('@gameroom/kit'),
{ grGreen } = require('../../../helpers'),
{ ShopifyV2 } = require('../../../models'),
{ config, spinner } = require('../../../refs'),
LIMIT = 500
module.exports = async (options) => {
// setup options
const { verbose } = options
// Gameroom products >> Shopify products
// date filter
let filter
if (config.shopify_product_sync) {
const date = new Date(config.shopify_product_sync)
spinner.info(`last product sync ${date.toLocaleString()}`)
// just in case...
// date.setTime(date.getTime() - 1)
filter = { key: 'updated_at', comparison: '>', value: date }
} else {
spinner.info(`first product sync`)
}
// Get updated products and add or update or remove them on shopify
let offset = 0, done = false, processed = {}
// update shopify
let added = 0, removed = 0, skipped = 0, updated = 0, current = 0, total = 0
spinner.text = `0 / 0 processed, 0 ${cosmetic.green('added')}, 0 ${cosmetic.red('removed')}, 0 ${cosmetic.yellow('updated')}, 0 skipped, 0 not offered`
while (!done) {
if (config.should_exit) break
// get batch of products
const products = await Product.get({ filter, limit: LIMIT, offset, sort: [{ updated_at: 1 }] })
done = products.length === 0
offset += products.length
total += products.length
if (verbose) spinner.info(`got ${products.length} ${grGreen('products')}`)
// iterate through batch
for (let [i, product] of products.entries()) {
try {
spinner.text = `${current} / ${total} processed, ${added} ${cosmetic.green('added')}, ${removed} ${cosmetic.red('removed')}, ${updated} ${cosmetic.yellow('updated')}, ${skipped} skipped`
current++
if (config.should_exit) break
if (verbose) spinner.info(`syncing gameroom ${grGreen('product')} ${product.id}`)
// snapshot product properties
const { properties: { shopify_id }, updated_at } = product
// check updated_at
if (updated_at.equals(processed[product.id])) {
delete processed[product.id]
config.shopify_product_sync = new Date(updated_at * 1000)
if (verbose) spinner.succeed(`already processed ${grGreen('product')}`)
skipped++
continue
}
// get shopify product
let shopify_product = shopify_id ? await ShopifyV2.Product.getWithId(shopify_id) : null
// conditions
const shopifyable = product.offered
const add = !shopify_product && shopifyable
const remove = shopify_product && !shopifyable
const update = shopify_product && shopifyable
if (add) {
// create shopify product
// create variants and inventory levels too on add
shopify_product = await ShopifyV2.Product.fromProduct(product)
shopify_product = await shopify_product.save()
if (verbose) spinner.info(`created shopify ${cosmetic.green('product')}`)
added++
} else if (remove) {
// delete shopify product
await ShopifyV2.Product.delete(shopify_id)
shopify_product = null
if (verbose) spinner.info(`removed shopify ${cosmetic.green('product')}`)
removed++
} else if (update) {
// update shopify product
// shopify_product = await shopify_product.updateFromProduct(product)
if (verbose) spinner.info(`updated shopify ${cosmetic.green('product')}`)
updated++
} else {
// not offered and not shopified, no action necessary
config.shopify_product_sync = new Date(updated_at * 1000)
if (verbose) spinner.succeed(`skipping ${grGreen('product')}`)
skipped++
continue
}
// update shopify id
if (shopify_product) {
product.properties.shopify_id = shopify_product.id
} else {
delete product.properties.shopify_id
}
// update product if need be
if (product.properties.shopify_id != shopify_id) {
product = await Product.update({ id: product.id, properties: product.properties })
if (verbose) spinner.info(`updated gameroom ${grGreen('product')}`)
// updated products go to the end of the pagination line and mess up the offset...
offset--
}
config.shopify_product_sync = new Date(updated_at * 1000)
processed[product.id] = product.updated_at
if (verbose) spinner.succeed(`synced ${grGreen('product')}`)
} catch (err) {
// if verbose, the id has already been printed
spinner.fail(`failed ${grGreen('product')}${verbose ? '' : ` ${product.id}`} ${err}`)
skipped++
}
}
}
spinner.succeed(`${total} processed, ${added} ${cosmetic.green('added')}, ${removed} ${cosmetic.red('removed')}, ${updated} ${cosmetic.yellow('updated')}, ${skipped} skipped`)
spinner.succeed(`completed product sync to ${cosmetic.green('shopify')} @ ${new Date().toLocaleString()}`)
}