UNPKG

@gameroom/cli

Version:

A command line tool for Gameroom

122 lines (120 loc) 5.69 kB
const cosmetic = require('cosmetic'), { models: { Price, Product } } = require('@gameroom/kit'), { grGreen } = require('../../../helpers'), { ShopifyV2 } = require('../../../models'), { config, spinner } = require('../../../refs'), LIMIT = 500 module.exports = async ({ verbose }) => { // Gameroom prices >> Shopify variants // date filter let filter if (config.shopify_price_sync) { const date = new Date(config.shopify_price_sync) spinner.info(`last price sync ${date.toLocaleString()}`) // just in case... // date.setTime(date.getTime() - 1) filter = { key: 'updated_at', comparison: '>', value: date } } else { spinner.info(`first price sync`) } // Get updated prices and add or update or remove them on shopify let offset = 0, done = false, processed = {}, products = {} // 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 prices const prices = await Price.get({ filter, limit: LIMIT, offset, sort: [{ updated_at: 1 }] }) done = prices.length === 0 offset += prices.length total += prices.length if (verbose) spinner.info(`got ${prices.length} ${grGreen('prices')}`) // iterate through batch for (let [i, price] of prices.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('price')} ${price.id}`) // snapshot price properties const { properties: { shopify_id, shopify_inventory_id }, updated_at } = price // check updated_at if (updated_at.equals(processed[price.id])) { delete processed[price.id] config.shopify_price_sync = new Date(updated_at * 1000) if (verbose) spinner.succeed(`already processed ${grGreen('price')}`) skipped++ continue } // get shopify variant let shopify_variant = shopify_id ? await ShopifyV2.Variant.getWithId(shopify_id) : null // conditions const shopifyable = price.amount > 0 const add = !shopify_variant && shopifyable const remove = shopify_variant && !shopifyable const update = shopify_variant && shopifyable if (add) { // get gameroom product // create inventory levels too on add const product = products[price.product_id] || await Product.find(price.product_id) products[product.id] = product if (!product) throw new Error('product not found') if (!product.offered) { // will be removed at the product level config.shopify_price_sync = new Date(updated_at * 1000) if (verbose) spinner.warn(`skipping ${grGreen('price')}`) skipped++ continue } // create shopify product shopify_variant = await ShopifyV2.Variant.fromProductAndPrice(product, price) shopify_variant = await shopify_variant.save() if (verbose) spinner.info(`created shopify ${cosmetic.green('variant')}`) added++ } else if (remove) { // delete shopify product await ShopifyV2.Variant.delete(shopify_id) shopify_variant = null if (verbose) spinner.info(`removed shopify ${cosmetic.green('variant')}`) removed++ } else if (update) { // update shopify variant shopify_variant = await shopify_variant.updateFromPrice(price) if (verbose) spinner.info(`updated shopify ${cosmetic.green('variant')}`) updated++ } else { // not offered and not shopified, no action necessary config.shopify_price_sync = new Date(updated_at * 1000) if (verbose) spinner.warn(`skipping ${grGreen('price')}`) skipped++ continue } // update shopify id if (shopify_variant) { price.properties.shopify_id = shopify_variant.id price.properties.shopify_inventory_id = shopify_variant.inventory_item_id } else { delete price.properties.shopify_id delete price.properties.shopify_inventory_id } if (price.properties.shopify_id != shopify_id || price.properties.shopify_inventory_id != shopify_inventory_id) { // update price if need be price = await Price.update({ id: price.id, properties: price.properties }) if (verbose) spinner.info(`updated gameroom ${grGreen('price')}`) // updated prices go to the end of the pagination line and mess up the offset... processed[price.id] = price.updated_at offset-- } config.shopify_price_sync = new Date(updated_at * 1000) if (verbose) spinner.succeed(`synced ${grGreen('price')}`) } catch (err) { // if verbose, the id has already been printed spinner.fail(`failed ${grGreen('price')}${verbose ? '' : ` ${price.id}`} ${err}`) skipped++ } } } spinner.succeed(`${total} processed, ${added} ${cosmetic.green('added')}, ${removed} ${cosmetic.red('removed')}, ${updated} ${cosmetic.yellow('updated')}, ${skipped} skipped`) spinner.succeed(`completed price sync to ${cosmetic.green('shopify')} @ ${new Date().toLocaleString()}`) }