diff --git a/.env_template b/.env_template index 5fd5191..00bb43b 100644 --- a/.env_template +++ b/.env_template @@ -21,10 +21,6 @@ MS_PRODUCTION_SCHEDULE = 300000 MS_TEST_SCHEDULE = 100000 SECRETS = true FORCE_SYNC = true -SYNC_ORGANIZATION = true -SYNC_WAREHOUSE = true -SYNC_CON = true -SYNC_TRADEITEM = true #REQUEST CONFIG MS_RETRY_UNHANDLED_ERROR = 900000 diff --git a/floriday.js b/floriday.js index ec2446e..ceaf17c 100644 --- a/floriday.js +++ b/floriday.js @@ -11,10 +11,6 @@ class Floriday { try { await utils.checkConfig(); await utils.requestToken(); - if (JSON.parse(env.SYNC_ORGANIZATION)) await utils.syncOrganizations(); - if (JSON.parse(env.SYNC_CON)) await utils.syncConnections(); - if (JSON.parse(env.SYNC_WAREHOUSE)) await utils.syncWarehouses(); - if (JSON.parse(env.SYNC_TRADEITEM)) await utils.syncTradeItems(); } catch (err) { utils.criticalError(err); } @@ -52,14 +48,17 @@ class Floriday { async trunk() { try{ - // ------------------------ + const models = [ + 'organization', + 'warehouse', + 'tradeItem', + 'supplyLine', + 'clockPresaleSupply', + ]; + for (let model of models) + await utils.syncModel(model); - await utils.syncOrganizations(); await utils.syncConnections(); - await utils.syncSupplyLines(); - - // Deshabilitado porque no hay de momento - // await utils.syncClockPresaleSupply(); } catch (err) { if (err.name === 'SequelizeConnectionRefusedError') throw err; diff --git a/models/sequelize.js b/models/sequelize.js index b228536..476b282 100644 --- a/models/sequelize.js +++ b/models/sequelize.js @@ -144,6 +144,7 @@ try { foreignKey: 'supplyLineId', targetKey: 'supplyLineId', }); + /* models.warehouse.belongsTo(models.organization, { foreignKey: 'organizationId', targetKey: 'organizationId', @@ -159,7 +160,7 @@ try { models.clockPresaleSupply.belongsTo(models.organization, { foreignKey: 'organizationId', targetKey: 'organizationId', - }); + });*/ } catch (err) { criticalError(err); } diff --git a/utils.js b/utils.js index 1511438..29ee10f 100644 --- a/utils.js +++ b/utils.js @@ -104,11 +104,12 @@ export async function getCurrentTokenExpiration() { */ export async function updateClientConfig(clientConfig) { try { - if (!JSON.parse(process.env.USE_SECRETS_DB)) clientId = clientSecret = null - await models.config.upsert({ - id: 1, - ...clientConfig, - }); + if (!JSON.parse(process.env.USE_SECRETS_DB)) + clientId = clientSecret = null + await models.config.upsert({ + id: 1, + ...clientConfig, + }); } catch (err) { throw(err); } @@ -124,43 +125,95 @@ export async function sleep(ms) { } /** - * Sync the organizations. + * Sync a model. + * + * @param {String} model (organization | tradeItem | supplyLine | clockPresaleSupply) */ -export async function syncOrganizations(){ - let spinner = ora('Syncing organizations...').start(); - let i = 0; +export async function syncModel(model) { + let spinner = ora(`Syncing ${model}...`).start(); + let i = 1; try { - const sequenceNumberDb = await models.sequenceNumber.findOne({ - where: { model: 'organization' } - }); - const maxSequenceNumber = (await vnRequest('GET', `${env.API_URL}/organizations/current-max-sequence`, null, null, spinner)).data; - let curSequenceNumber = (sequenceNumberDb?.maxSequenceNumber) - ? sequenceNumberDb.maxSequenceNumber - : 0 - for (curSequenceNumber; curSequenceNumber <= maxSequenceNumber; curSequenceNumber++) { - const params = new URLSearchParams({ - organizationType: 'SUPPLIER' - }).toString(); - let response = (await vnRequest('GET', `${env.API_URL}/organizations/sync/${curSequenceNumber}?${params}`, null, null, spinner)).data; - curSequenceNumber = response.maximumSequenceNumber; - const orgs = response.results; - for (let org of orgs) { - await insertOrganization(org); - spinner.text = `Syncing ${i++} organizations, ${maxSequenceNumber - curSequenceNumber} missing...` - }; - await insertSequenceNumber('organization', curSequenceNumber) - } - await insertSequenceNumber('organization', maxSequenceNumber) - spinner.text = (i) ? `Syncing ${i} organizations...` - : `Syncing organizations... (Not found)` - spinner.succeed(); - } - catch (err) { + const dbSeqNum = await models.sequenceNumber.findOne({ where: { model } }) + let curSeqNum = dbSeqNum?.maxSequenceNumber ?? 0; + + let maxSeqUrl, syncUrl; + switch (model) { + case 'organization': + maxSeqUrl = `${env.API_URL}/organizations/current-max-sequence`; + syncUrl = `${env.API_URL}/organizations/sync/`; + break; + case 'warehouse': + maxSeqUrl = `${env.API_URL}/warehouses/current-max-sequence`; + syncUrl = `${env.API_URL}/warehouses/sync/`; + break; + case 'tradeItem': + maxSeqUrl = `${env.API_URL}/trade-items/current-max-sequence`; + syncUrl = `${env.API_URL}/trade-items/sync/`; + break; + case 'supplyLine': + maxSeqUrl = `${env.API_URL}/supply-lines/current-max-sequence`; + syncUrl = `${env.API_URL}/supply-lines/sync/`; + break; + case 'clockPresaleSupply': + maxSeqUrl = `${env.API_URL}/auction/clock-presales-supply/max-sequence-number`; + syncUrl = `${env.API_URL}/auction/clock-presales-supply/sync/`; + break; + default: + throw new Error('Unsupported model'); + } + + const maxSeqNum = (await vnRequest('GET', maxSeqUrl, null, null, spinner)).data; + for (curSeqNum; curSeqNum < maxSeqNum; curSeqNum++) { + let params, misSeqNum; + if (model === 'organization') + params = new URLSearchParams({organizationType: 'SUPPLIER'}).toString(); + else if (model === 'supplyLine') + params = new URLSearchParams({postFilterSelectedTradeItems: false}).toString(); + + const res = (await vnRequest('GET', `${syncUrl}${curSeqNum}${params ? `?${params}` : ''}`, null, null, spinner)).data; + curSeqNum = res.maximumSequenceNumber; + const objects = res.results; + misSeqNum = maxSeqNum - curSeqNum; + spinner.text = `Syncing ${i - 1} ${model}, ${misSeqNum} missing...`; + for (let object of objects) { + switch (model) { + case 'organization': + await insertOrganization(object); + break; + case 'warehouse': + await insertWarehouse(object); + break; + case 'tradeItem': + await insertTradeItem(object); + break; + case 'supplyLine': + await insertSupplyLine(object); + break; + case 'clockPresaleSupply': + await insertClockPresalesSupply(object); + break; + default: + throw new Error('Unsupported model'); + } + + spinner.text = `Syncing ${i++} ${model}, ${misSeqNum} missing...` + }; + + await insertSequenceNumber(model, curSeqNum); + } + if (curSeqNum < maxSeqNum) + await insertSequenceNumber(model, maxSeqNum); + spinner.text = (i != 1) + ? `Syncing ${i} ${model}...` + : `Syncing ${model}... ${chalk.gray('(Not found)')}`; + spinner.succeed(); + } catch (err) { spinner.fail(); - throw new Error(err); + throw err; } } + /** * Create the connections in Floriday. */ @@ -169,15 +222,16 @@ export async function syncConnections(){ let spinner; try { - let connectionsInDb = await models.supplyLine.findAll({ - include : { - model: models.organization, - where: { - isConnected: true, - } - }, - attributes: ['organizationId'], - group: ['organizationId'], + let connectionsInDb = await models.organization.findAll({ + where: { + isConnected: true, + companyGln: { + [Op.ne]: null + }, + rfhRelationId: { + [Op.ne]: null + }, + } }); const connectionsInFloriday = (await vnRequest('GET', `${env.API_URL}/connections`, null, null, spinner)).data; @@ -207,159 +261,6 @@ export async function syncConnections(){ } } -/** - * Sync the trade items for organizations that are connected. - */ -export async function syncTradeItems(){ - const spinner = ora(`Syncing trade items...`).start(); - const orgs = await models.organization.findAll({ - attributes: ['organizationId'], - where: { isConnected: true } - }); - let i = 0, x = 0; - for (let org of orgs) { - try { - const params = new URLSearchParams({ - supplierOrganizationId: org.organizationId, - }).toString(); - let tradeItems = (await vnRequest('GET', `${env.API_URL}/trade-items?${params}`, null, null, spinner)).data - - spinner.text = `Syncing ${i} trade items of [${x++}|${orgs.length}] organizations...` - if (!tradeItems.length) continue; - - for (let tradeItem of tradeItems) { - await insertTradeItem(tradeItem); - spinner.text = `Syncing ${i++} trade items of [${x}|${orgs.length}] organizations...` - }; - } catch (err) { - spinner.fail(); - throw err; - } - } - spinner.succeed() -} - -/** - * Sync the supply lines for organizations that are connected. - * - * If necessary, create the dependences. - */ -export async function syncSupplyLines() { - const spinner = ora(`Syncing supply lines...`).start(); - try { - let conOrgs = await models.organization.findAll({ - attributes: ['organizationId'], - where: { isConnected: true } - }); - - let i = 0, x = 1; - for (let org of conOrgs) { - spinner.text = `Syncing ${i} supply lines of [${x++}|${conOrgs.length}] organizations...` - const params = new URLSearchParams({ - supplierOrganizationId: org.organizationId, - }).toString(); - let supplyLines = (await vnRequest('GET',`${env.API_URL}/supply-lines?${params}`, null, null, spinner)).data; - if (!supplyLines.length) continue - - for (let supplyLine of supplyLines) { - // Check if the warehouse exists, and if it doesn't, create it - let warehouse = await models.warehouse.findOne({ - where: { warehouseId: supplyLine.warehouseId } - }); - if (!warehouse) { - let warehouse = (await vnRequest('GET', `${env.API_URL}/warehouses/${supplyLine.warehouseId}`, null, null, spinner)).data; - - // Check if the organization exists, and if it doesn't, create it - let organization = await models.organization.findOne({ - where: { organizationId: warehouse.organizationId } - }); - if (!organization) { - let organization = (await vnRequest('GET', `${env.API_URL}/organizations/${warehouse.organizationId}`, null, null, spinner)).data; - await insertOrganization(organization); - } - - await insertWarehouse(warehouse); - } - - // Check if the trade item exists, and if it doesn't, create it - let tradeItem = await models.tradeItem.findOne({ - where: { tradeItemId: supplyLine.tradeItemId } - }); - if (!tradeItem) { - let tradeItem = (await vnRequest('GET', `${env.API_URL}/trade-items/${supplyLine.tradeItemId}`, null, null, spinner)).data; - await insertTradeItem(tradeItem); - } - - spinner.text = `Syncing ${i++} supply lines of [${x}|${conOrgs.length}] organizations...` - await insertSupplyLine(supplyLine); - - for (let volumePrice of supplyLine.volumePrices) - await models.volumePrice.upsert({ - supplyLineId: supplyLine.supplyLineId, - ...volumePrice, - }); - } - } - spinner.succeed(); - } - catch (err) { - spinner.fail(); - throw err; - } -} - -/** - * Sync the lock presales supply for supply lines of today. - */ -export async function syncClockPresaleSupply() { - const spinner = ora(`Syncing clock presales supply...`).start(); - const supplyLines = await models.supplyLine.findAll({ - attributes: ['supplyLineId'], - where: { - lastSync: { - [Op.between]: [moment().startOf('day').toDate(), moment().endOf('day').toDate()] - } - } - }); - let i = 0, x = 1; - for (let supplyLine of supplyLines) { - spinner.text = `Syncing ${i} clock presales supplies of [${x++}|${supplyLines.length}] supply lines...` - try { - let response = await vnRequest('GET', `${env.API_URL}/auction/clock-presales-supply/${supplyLine.supplyLineId}`, null, null, spinner) - - if (response.response.status == 404) continue; // Not Found - const clockPresalesSupplies = response.data; - - for (let clockPresalesSupply of clockPresalesSupplies) { - // Check if the organization exists, and if it doesn't, create it - let organization = await models.organization.findOne({ - where: { organizationId: clockPresalesSupply.supplierOrganizationId } - }); - if (!organization) { - let organization = (await vnRequest('GET', `${env.API_URL}/organizations/${clockPresalesSupply.supplierOrganizationId}`, null, null, spinner)).data; - await insertOrganization(organization); - } - - // Check if the trade item exists, and if it doesn't, create it - let tradeItem = await models.tradeItem.findOne({ - where: { tradeItemId: clockPresalesSupply.tradeItemId } - }); - if (!tradeItem) { - let tradeItem = (await vnRequest('GET', `${env.API_URL}/trade-items/${clockPresalesSupply.tradeItemId}`, null, null, spinner)).data; - await insertTradeItem(tradeItem); - } - - await insertClockPresalesSupply(clockPresalesSupply); - spinner.text = `Syncing ${i++} clock presales supplies of [${x}|${supplyLines.length}] supply lines...` - }; - } catch (err) { - spinner.fail(); - throw err; - } - } - spinner.succeed() -} - /** * Insert sequence number in the database. * @@ -546,6 +447,34 @@ export async function insertOrganization(organization) { export async function insertSupplyLine(supplyLine) { const tx = await models.sequelize.transaction(); try { + // Check if the warehouse exists, and if it doesn't, create it + let warehouse = await models.warehouse.findOne({ + where: { warehouseId: object.warehouseId } + }); + if (!warehouse) { + let warehouse = (await vnRequest('GET', `${env.API_URL}/warehouses/${supplyLine.warehouseId}`, null, null, spinner)).data; + + // Check if the organization exists, and if it doesn't, create it + let organization = await models.organization.findOne({ + where: { organizationId: warehouse.organizationId } + }, { transaction: tx }); + if (!organization) { + let organization = (await vnRequest('GET', `${env.API_URL}/organizations/${warehouse.organizationId}`, null, null, spinner)).data; + await insertOrganization(organization); + } + + await insertWarehouse(warehouse); + } + + // Check if the trade item exists, and if it doesn't, create it + let tradeItem = await models.tradeItem.findOne({ + where: { tradeItemId: supplyLine.tradeItemId } + }, { transaction: tx }); + if (!tradeItem) { + let tradeItem = (await vnRequest('GET', `${env.API_URL}/trade-items/${supplyLine.tradeItemId}`, null, null, spinner)).data; + await insertTradeItem(tradeItem); + } + await models.supplyLine.upsert({ ...supplyLine, organizationId: supplyLine.supplierOrganizationId, @@ -560,7 +489,7 @@ export async function insertSupplyLine(supplyLine) { // Upsert packing configurations if (supplyLine.packingConfigurations.length) - for (const packingConfiguration of supplyLine.packingConfigurations) { + for (const packingConfiguration of supplyLine.packingConfigurations) await models.supplyLinePackingConfiguration.upsert({ packingConfigurationId: uuidv4(), ...packingConfiguration, @@ -570,7 +499,13 @@ export async function insertSupplyLine(supplyLine) { additionalPricePerPieceValue: packingConfiguration.additionalPricePerPiece.value, supplyLineId: supplyLine.supplyLineId, }, { transaction: tx }); - } + + // Upsert volume price + for (let volumePrice of supplyLine.volumePrices) + await models.volumePrice.upsert({ + supplyLineId: supplyLine.supplyLineId, + ...volumePrice, + }, { transaction: tx }); await tx.commit(); } catch (err) { @@ -579,33 +514,6 @@ export async function insertSupplyLine(supplyLine) { } } -/** - * Sync the warehouses for organizations that are connected. - **/ -export async function syncWarehouses(){ - let spinner = ora('Syncing warehouses...').start(); - try { - const orgs = await models.organization.findAll({ - where: { isConnected: true } - }); - - let x = 0, i = 0; - for (let org of orgs) { - spinner.text = `Syncing ${i} warehouses of [${x++}|${orgs.length}] organizations...` - const warehouses = (await vnRequest('GET', `${env.API_URL}/organizations/supplier/${org.organizationId}/warehouses`, null, null, spinner)).data; - for (let warehouse of warehouses) { - spinner.text = `Syncing ${i++} warehouses of [${x}|${orgs.length}] organizations...` - await insertWarehouse(warehouse); - } - } - spinner.succeed(); - } - catch (err) { - spinner.fail(); - throw new Error(err); - } -} - /** * Removes Floriday connections that we don't have in the database. **/ @@ -634,7 +542,7 @@ export async function deleteConnections() { for (let connection of ghostConnections) { await vnRequest('DELETE', `${env.API_URL}/connections/${connection}`, null, null, spinner); - spinner.text = `Deleting ${i++} of ${ghostConnections.length} that aren't in the db...` + spinner.text = `Deleting ${i++} of ${ghostConnections.length} connections that aren't in the db...` } if (spinner) spinner.succeed(); } catch (err) {