@gameroom/cli
Version:
A command line tool for Gameroom
93 lines (88 loc) • 5.23 kB
JavaScript
const cosmetic = require('cosmetic'),
{ calculateGamePrices, difference, dollarString, grGreen, timeout, tryRepeatedly, writeCSVFile } = require('../../helpers'),
{ Price_Charting } = require('../../models'),
{ spinner } = require('../../refs'),
{ models: { Line, Price, Product, Unit } } = require('@gameroom/kit'),
PRICE_CHARTING = cosmetic.cyan('price charting'),
TRUE = 'true',
FALSE = 'false'
module.exports = async ({ path, products }) => {
if (!process.env.PRICE_CHARTING_TOKEN) throw new Error('missing price charting env keys')
spinner.info(`generating ${PRICE_CHARTING} ratio csv @ ${new Date().toLocaleString()}`)
const data = {}
for (const [i, product] of products.entries()) {
spinner.text = `checking ${grGreen('product')} ${i}/${products.length}`
// only products matched with pcid
const { pcid, price_baseline, price_game_plus_ratio } = product.properties
if (!pcid) continue
// get prices
const pricePlusGroup = ['PS5', 'Xbox Series X', 'PS4', 'Xbox One', 'PS3', 'Xbox 360', 'PS2', 'Xbox', 'PS1', 'Dreamcast', 'Wii U', 'Wii', 'Gamecube', 'Sega CD', 'Saturn', 'Switch', 'DS', '3DS', 'PSP', 'Vita', 'CD-i', '3DO']
const priceOnlyGroup = ['NES', 'SNES', 'N64', 'Genesis', 'Master System', 'Gameboy', 'Gameboy Advance', 'Gameboy Color', 'Game Gear', 'Atari', 'Intellivision', 'Colecovision']
const prices = await tryRepeatedly(() => Price.get({ filter: { key: 'product_id', value: product.id } }), (err) => spinner.warn(`err getting ${grGreen('product')} ${product.id} ${grGreen('prices')} ${err}`))
//get sell price
let salePrice = null
if (pricePlusGroup.some(i => product.tags.includes(i))) {
salePrice = prices.find(p => (p.name === 'Disc Plus') || (p.name === 'Cartridge Plus'))
} else if (priceOnlyGroup.some(i => product.tags.includes(i))) {
salePrice = prices.find(p => (p.name === 'Cartridge Only'))
} else if (product.tags.includes("32X")) {
salePrice = prices.find(p => (p.name === 'Disc Plus') || (p.name === 'Cartridge Only'))
}
if (!salePrice || salePrice == null) spinner.warn(`${grGreen('product')} ${product.id} missing game_plus price`)
//get buy price
let buyPrice = null
if (pricePlusGroup.some(i => product.tags.includes(i))) {
buyPrice = prices.find(p => (p.name === 'Buy In Disc Plus') || (p.name === 'Buy In Cartridge Plus'))
} else if (priceOnlyGroup.some(i => product.tags.includes(i))) {
buyPrice = prices.find(p => (p.name === 'Buy In Cartridge Only'))
} else if (product.tags.includes("32X")) {
buyPrice = prices.find(p => (p.name === 'Buy In Disc Plus') || (p.name === 'Buy In Cartridge Only'))
}
if (!buyPrice || buyPrice == null) spinner.warn(`${grGreen('product')} ${product.id} missing game_plus price`)
// instantiate csv data
if (!data[pcid]) data[pcid] = {
pcid,
product_count: 0,
product_ids: null,
name: product.name,
subname: product.subname,
tags: null,
auto_price: product.properties.auto_price || 'false',
bought: 0,
in_stock: 0,
out_of_stock: 0,
current_price: salePrice ? salePrice.amount : 0,
current_ratio: price_game_plus_ratio || 0,
baseline: price_baseline || 0,
target_price: 0,
ratio: 0
}
product.tags.map(t => !data[pcid].tags ? data[pcid].tags = t : !data[pcid].tags.includes(t) ? data[pcid].tags += `, ${t}` : null)
if (!data[pcid].auto_price.includes(product.properties.auto_price)) data[pcid].auto_price += product.properties.auto_price
// get units counts
const units = await tryRepeatedly(() => Unit.get({ filter: { key: 'product_id', value: product.id } }), (err) => spinner.warn(`err getting ${grGreen('product')} ${product.id} ${grGreen('units')} ${err}`))
data[pcid].in_stock += units.filter(u => u.quantity > 0).length
data[pcid].out_of_stock += units.filter(u => u.quantity <= 0).length
// products count
data[pcid].product_count++
data[pcid].product_ids = data[pcid].product_ids ? `${data[pcid].product_ids}, ${product.id}` : product.id
// get lines for bought
if (!buyPrice) continue
const lines = await tryRepeatedly(() => Line.get({ filter: { key: 'saleable_id', value: buyPrice.id } }))
lines.map((l) => data[pcid].bought += l.quantity)
// if (units.length > 0) {
// const or = []
// units.map(u => or.push({ key: 'saleable_id', value: u.id }))
// const lines = await tryRepeatedly(() => Line.get({ filter: { or } }), (err) => spinner.warn(`err getting ${grGreen('product')} ${product.id} ${grGreen('lines')} ${err}`))
// data.bought = lines.filter(l => l.amount < 0).length
// data.sold = lines.filter(l => l.amount > 0).length
// }
}
const csv_data = []
Object.keys(data).map(k => csv_data.push(data[k]))
path = await writeCSVFile(path, csv_data)
// const path = await writeCSVFile(join(resolve(dir === true ? '.' : write), 'gameroom_auto_pricer.csv'), csv_data)
spinner.succeed(`wrote data to ${path}`)
spinner.info(`total ${grGreen('products')}: ${products.length}`)
spinner.succeed(`completed ${PRICE_CHARTING} ratio export @ ${new Date().toLocaleString()}`).stop()
}