This commit is contained in:
Pau 2023-02-03 13:56:34 +01:00
parent 53b11dfca0
commit e10ee70d4a
9 changed files with 393 additions and 4918 deletions

View File

@ -1,14 +1,12 @@
import moment from 'moment';
import * as vnUtils from './utils.js';
import cliProgress from 'cli-progress';
//import cliProgress from 'cli-progress';
import dotenv from 'dotenv';
dotenv.config();
import { models } from './models/index.js';
import suppliers from './suppliersGln.js';
console.log = function () {
let args = Array.prototype.slice.call(arguments);
args.unshift(new moment().format('HH:mm:ss') + ' -');
@ -17,48 +15,22 @@ console.log = function () {
let tokenExpirationDate = await vnUtils.getClientToken(models);
process.env.SYNC_SEQUENCE ? await vnUtils.syncSequence() : null;
process.env.SYNC_SUPPLIER ? await vnUtils.syncSuppliers() : null;
process.env.SYNC_TRADEITEM ? await vnUtils.syncTradeItems() : null;
try {
if (process.env.QUERYSUPPLIERS) {
process.env.HowManySuppliers ??= suppliers.suppliers.length;
console.log('Querying suppliers...');
console.log(process.env.HowManySuppliers + ' suppliers will be queried.');
const bar1 = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);
bar1.start(process.env.HowManySuppliers, 0);
let functionQueue = [];
// vnUtils.getTradeitems(suppliers.suppliers[i].SupplierGLN)
for (let i = 0; i < process.env.HowManySuppliers; i++) {
functionQueue.push(async () => {
await vnUtils.getTradeitems(suppliers.suppliers[i].SupplierGLN);
bar1.increment();
});
}
await vnUtils.asyncQueue(functionQueue, 10);
bar1.stop();
console.log('Done querying trade items.');
}
// eslint-disable-next-line no-constant-condition
while (true) {
try{
console.log('Querying the API to check for new data...');
console.log('Current token expiration date: ', tokenExpirationDate);
await vnUtils.getStock();
if (moment().isAfter(tokenExpirationDate)) {
console.log('Token expired, getting a new one...');
tokenExpirationDate = await vnUtils.getClientToken(models);
}
} catch (error) {
console.error(error);
}

View File

@ -0,0 +1,34 @@
import { Sequelize } from 'sequelize';
const sequenceNumber = {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
sequenceNumber: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
},
maximumSequenceNumber: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
},
model: {
type: Sequelize.STRING,
},
};
export default (sequelize) => {
const sequenceNumbers = sequelize.define(
'FDsequenceNumber',
sequenceNumber,
{
timestamps: false,
freezeTableName: true,
}
);
return sequenceNumbers;
};

View File

@ -4,24 +4,36 @@ dotenv.config();
let sequelize = createConnection();
// Supply Line Models
import supplyLine from './supplyLine/supplyLine.js';
import volumePrices from './supplyLine/volumePrices.js';
// Conf Models
import clientConfig from './conf/clientConfig.js';
import sequenceNumber from './conf/sequenceNumber.js';
// Supplier Models
import suppliers from './supplier/suppliers.js';
import connections from './supplier/connections.js';
// TradeItem Models
import tradeItem from './tradeItem/tradeItem.js';
import botanicalNames from './tradeItem/botanicalNames.js';
import countryOfOriginIsoCodes from './tradeItem/countryOfOriginIsoCodes.js';
import packageModel from './tradeItem/package.js';
import packingConfigurations from './tradeItem/packingConfigurations.js';
import photos from './tradeItem/photos.js';
import seasonalPeriod from './tradeItem/seasonalPeriod.js';
import tradeItem from './tradeItem/tradeItem.js';
import clientConfig from './conf/clientConfig.js';
import characteristics from './tradeItem/characteristics.js';
import supplyLine from './supplyLine/supplyLine.js';
import volumePrices from './supplyLine/volumePrices.js';
import suppliers from './supplier/suppliers.js';
/**
* Contains all the models that are related to the application.
*
* @example
* models.tradeItem.findAll();
* models.@modelName@.findAll();
*
* @example
* models.tradeItem.findAll().then((data) => {
@ -38,6 +50,7 @@ import suppliers from './supplier/suppliers.js';
* @type {Object.<string, Sequelize.Model>}
*/
let models = {
sequelize: sequelize,
tradeItem: tradeItem(sequelize),
packingConfigurations: packingConfigurations(sequelize),
photos: photos(sequelize),
@ -50,6 +63,8 @@ let models = {
supplyLines: supplyLine(sequelize),
volumePrices: volumePrices(sequelize),
suppliers: suppliers(sequelize),
sequenceNumber: sequenceNumber(sequelize),
connections: connections(sequelize),
};
models.characteristics.belongsTo(models.tradeItem, {
@ -125,9 +140,12 @@ models.supplyLines.belongsTo(models.tradeItem, {
targetKey: 'tradeItemId',
});
if (process.env.FORCE_SYNC) {
console.log('Syncing the models...');
if (process.env.FORCE_SYNC == true) {
console.log('Forcing the models...');
await sequelize.sync({ force: true });
} else {
console.log('Altering the models...');
await sequelize.sync({ alter: true });
}
if (process.env.SECRETS) {

View File

@ -0,0 +1,25 @@
import { Sequelize } from 'sequelize';
const connections = {
organizationId: {
type: Sequelize.STRING,
primaryKey: true,
allowNull: false,
},
connect: {
type: Sequelize.BOOLEAN,
defaultValue: false,
},
};
export default (sequelize) => {
const connection = sequelize.define(
'FDconnections',
connections,
{
timestamps: false,
freezeTableName: true,
}
);
return connection;
};

View File

@ -1,16 +1,56 @@
import { Sequelize } from 'sequelize';
const suppliers = {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
isConnected: {
type: Sequelize.BOOLEAN,
defaultValue: false,
},
supplierId: {
commercialName: {
type: Sequelize.STRING,
unique: true,
allowNull: false,
},
supplierGln: {
email: {
type: Sequelize.STRING,
},
phone: {
type: Sequelize.STRING,
},
website: {
type: Sequelize.STRING,
},
mailingAddress: {
type: Sequelize.JSON,
},
physicalAddress: {
type: Sequelize.JSON,
},
pythosanitaryNumber: {
type: Sequelize.STRING,
},
sequenceNumber: {
type: Sequelize.INTEGER,
allowNull: false,
},
organizationId: {
type: Sequelize.STRING,
primaryKey: true,
},
companyGln: {
type: Sequelize.STRING,
},
name: {
type: Sequelize.STRING,
},
endDate: {
type: Sequelize.DATE,
},
rfhRelationId: {
type: Sequelize.INTEGER,
},
organizationType: {
type: Sequelize.STRING,
},
paymentProviders: {
type: Sequelize.STRING,
},
};

View File

@ -7,7 +7,7 @@
"dev-sync": "FORCE_SYNC=true node --max-old-space-size=4096 index.js",
"dev-secrets": "SECRETS=true node --max-old-space-size=4096 index.js",
"dev-both": "FORCE_SYNC=true SECRETS=true node --max-old-space-size=4096 index.js",
"dev-query": "QUERYSUPPLIERS=true FORCE_SYNC=true SECRETS=true node --max-old-space-size=4096 index.js"
"dev-query": "QUERYSUPPLIERS=true SECRETS=true node --max-old-space-size=4096 index.js"
},
"dependencies": {
"cli-progress": "^3.11.2",

File diff suppressed because it is too large Load Diff

29
test.json Normal file
View File

@ -0,0 +1,29 @@
{
"commercialName": "Viveros Las Cunas",
"email": null,
"phone": null,
"website": null,
"mailingAddress": {
"addressLine": "Carretera 0A-352",
"city": "Vera - Almeria",
"countryCode": "ES",
"postalCode": "04620",
"stateOrProvince": null
},
"physicalAddress": {
"addressLine": "Carretera 0A-352",
"city": "Vera - Almeria",
"countryCode": "ES",
"postalCode": "04620",
"stateOrProvince": null
},
"phytosanitaryNumber": null,
"sequenceNumber": 195803,
"organizationId": "ebc1894a-c3be-3a19-9de2-40b2e691cc9f",
"companyGln": "8718288089847",
"name": "Viveros Las Cunas",
"endDate": null,
"rfhRelationId": 0,
"organizationType": "SUPPLIER",
"paymentProviders": []
}

626
utils.js
View File

@ -2,8 +2,9 @@ import moment from 'moment';
import fetch from 'node-fetch';
import dotenv from 'dotenv';
import { models } from './models/index.js';
import { v4 as uuidv4 } from 'uuid';
import cliProgress from 'cli-progress';
//import { v4 as uuidv4 } from 'uuid';
//import cliProgress from 'cli-progress';
import suppliersGln from './suppliersGln.js';
dotenv.config();
/**
@ -86,6 +87,7 @@ async function updateClientConfig(clientId, clientSecret, accessToken, tokenExpi
clientSecret: clientSecret,
currentToken: accessToken,
tokenExpiration: tokenExpirationDate,
requestLimit : 500
},
{
where: {
@ -123,25 +125,6 @@ async function sleep(ms) {
});
}
/**
* Returns the uuidv4 string with the prefix 'Vn-'
*
* @param {string} uuidv4 - uuidv4 string
* @returns
*/
async function vnUuid(uuidv4) {
return 'Vn-' + uuidv4;
}
/**
* Returns the uuidv4 string without the prefix 'Vn-'
*
* @param {string} uuidv4 - uuidv4 string with prefix 'Vn-'
* @returns
*/
async function removeVnPrefix(uuidv4) {
return uuidv4.replace('Vn-', '');
}
/**
* Recieves an array of functions and executes them in a queue with the given concurrency
*
@ -179,425 +162,252 @@ async function asyncQueue(fnArray, concurrency = 1) {
// 4. Execute the run function while the concurrency is greater than 0
// 5. Return the results
/**
* Syncs the sequence number for the given model
* if no params are given it will reset all the sequence number to 0
*
* Inserts every tradeitem from the organization into the DB
*
* @param {*} organizationGln
* @param {Number} current - current sequence number
* @param {String} model - model name
* @param {Number} maximumSequenceNumber - maximum sequence number
* @returns
*/
async function getTradeitems(organizationGln) {
async function syncSequence(current = 0, model = null ,maximumSequenceNumber = 0){
if (model == null && current == 0){
let mockModels = ['suppliers','tradeItems','supplyLines',];
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + await getJWT(),
'X-Api-Key': process.env.API_KEY,
};
// Get the organization id from the organizationGln
const organizationsUrl = `${BASE_CUSTOMER_URL}organizations/gln/${organizationGln}`;
const organizationsRequest = await fetch(organizationsUrl, {
method: 'GET',
headers: headers,
});
const organizationsResponse = await organizationsRequest.json();
const organizationId = organizationsResponse.organizationId;
console.log('Organization ID: ', organizationId);
// Get the tradeitems from the organization
const tradeitemsUrl = `${BASE_CUSTOMER_URL}trade-items?supplierOrganizationId=${organizationId}`;
const tradeitemsRequest = await fetch(tradeitemsUrl, {
method: 'GET',
headers: headers,
});
const tradeitemsResponse = await tradeitemsRequest.json();
// If there is no tradeitems
if (tradeitemsResponse.length == 0) {
return;
}
// if there is at least one tradeitem, save it in the database
//console.log(tradeitemsResponse[0]);
try {
if (tradeitemsResponse.length > 0 && tradeitemsResponse != null) {
let bar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_grey);
bar.start(tradeitemsResponse.length, 0);
await tradeitemsResponse.forEach(async item => {
bar.increment();
try {
item.tradeItemId = await vnUuid(item.tradeItemId);
await models.suppliers.upsert({
supplierId: await vnUuid(organizationId),
supplierGln: organizationGln,
});
await models.tradeItem.upsert({
tradeItemId: item.tradeItemId,
supplierOrganizationId: organizationGln,
supplierOrganizationUuid: await vnUuid(organizationId),
code: item.code,
gtin: item.gtin,
vbnProductCode: item.vbnProductCode,
name: item.name,
isDeleted: item.isDeleted,
sequenceNumber: item.sequenceNumber,
tradeItemVersion: item.tradeItemVersion,
isCustomerSpecific: item.isCustomerSpecific,
isHiddenInCatalog: item.isHiddenInCatalog,
});
await item.characteristics.forEach((characteristic) => {
models.characteristics.upsert({
tradeItemFk: item.tradeItemId,
vbnCode: characteristic.vbnCode,
vbnValueCode: characteristic.vbnValueCode,
});
});
await item.seasonalPeriods.forEach((seasonalPeriod) => {
models.seasonalPeriod.upsert({
tradeItemFk: item.tradeItemId,
startWeek: seasonalPeriod.startWeek,
endWeek: seasonalPeriod.endWeek,
});
});
await item.photos.forEach(async (photo) => {
photo.id = await vnUuid(photo.id);
models.photos.upsert({
tradeItemFk: item.tradeItemId,
photoId: photo.id,
url: photo.url,
seasonalPeriodFk: JSON.stringify(photo.seasonalPeriod),
type: photo.type,
primary: photo.primary,
});
});
await item.packingConfigurations.forEach(async (packagingConfiguration) => {
let uuid = uuidv4();
uuid = await vnUuid(uuid);
await models.packingConfigurations.upsert({
tradeItemFk: item.tradeItemId,
packingConfigurationId: uuid,
piecesPerPackage: packagingConfiguration.piecesPerPackage,
bunchesPerPackage: packagingConfiguration.bunchesPerPackage,
photoUrl: packagingConfiguration.photoUrl,
packagesPerLayer: packagingConfiguration.packagesPerLayer,
layersPerLoadCarrier: packagingConfiguration.layersPerLoadCarrier,
transportHeightInCm: packagingConfiguration.transportHeightInCm,
loadCarrierType: packagingConfiguration.loadCarrierType,
isPrimary: packagingConfiguration.isPrimary,
additionalPricePerPiece: JSON.stringify(packagingConfiguration.additionalPricePerPiece),
});
await models.package.upsert({
packingConfigurationsId: uuid,
vbnPackageCode: packagingConfiguration.package.vbnPackageCode,
vbnPackageValueCode: packagingConfiguration.package.vbnPackageValueCode,
});
});
await item.botanicalNames.forEach((botanicalName) => {
models.botanicalNames.upsert({
tradeItemFk: item.tradeItemId,
name: botanicalName,
});
});
await item.countryOfOriginIsoCodes.forEach((countryOfOriginIsoCode) => {
models.countryOfOriginIsoCodes.upsert({
tradeItemFk: item.tradeItemId,
isoCode: countryOfOriginIsoCode,
});
});
} catch (error) {
console.log('Missing data for the tradeitem: ' + item.tradeItemId);
bar.stop();
return;
}
});
bar.stop();
for (let i = 0; i < mockModels.length; i++) {
const element = mockModels[i];
console.log('Syncing sequence for: ', element);
await syncSequence(0, element);
}
} catch (error) {
console.log('There was an error while saving the data to the database, trying again in 5 seconds...');
await sleep(5000);
await getTradeitems(organizationGln);
} else {
let tx = await models.sequelize.transaction();
try {
await models.sequenceNumber.upsert({
model: model,
sequenceNumber: current,
maximumSequenceNumber: maximumSequenceNumber
},{ transaction: tx });
await tx.commit();
} catch (error) {
await tx.rollback();
console.log('Error while syncing sequence number for: ', model);
}
}
}
/**
* Gets a single tradeitem from the API and inserts it into the database
*
* @param {*} tradeItemId
*/
async function getTradeItem(tradeItemId) {
async function syncSuppliers(){
try {
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${await getJWT()}`,
'X-Api-Key': process.env.API_KEY,
};
const tradeitemUrl = `${BASE_CUSTOMER_URL}trade-items/${tradeItemId}`;
const tradeitemRequest = await fetch(tradeitemUrl, {
method: 'GET',
headers: headers,
});
const tradeitemResponse = await tradeitemRequest.json();
tradeitemResponse.tradeItemId = await vnUuid(tradeitemResponse.tradeItemId);
await models.tradeItem.upsert({
tradeItemId: tradeitemResponse.tradeItemId,
supplierOrganizationId: tradeitemResponse.supplierOrganizationGln,
supplierOrganizationUuid: await vnUuid(tradeitemResponse.supplierOrganizationId),
code: tradeitemResponse.code,
gtin: tradeitemResponse.gtin,
vbnProductCode: tradeitemResponse.vbnProductCode,
name: tradeitemResponse.name,
isDeleted: tradeitemResponse.isDeleted,
sequenceNumber: tradeitemResponse.sequenceNumber,
tradeItemVersion: tradeitemResponse.tradeItemVersion,
isCustomerSpecific: tradeitemResponse.isCustomerSpecific,
isHiddenInCatalog: tradeitemResponse.isHiddenInCatalog,
});
await tradeitemResponse.characteristics.forEach((characteristic) => {
models.characteristics.upsert({
tradeItemFk: tradeitemResponse.tradeItemId,
vbnCode: characteristic.vbnCode,
vbnValueCode: characteristic.vbnValueCode,
});
});
await tradeitemResponse.seasonalPeriods.forEach((seasonalPeriod) => {
models.seasonalPeriod.upsert({
tradeItemFk: tradeitemResponse.tradeItemId,
startWeek: seasonalPeriod.startWeek,
endWeek: seasonalPeriod.endWeek,
});
});
await tradeitemResponse.photos.forEach(async (photo) => {
photo.id = await vnUuid(photo.id);
models.photos.upsert({
tradeItemFk: tradeitemResponse.tradeItemId,
photoId: photo.id,
url: photo.url,
seasonalPeriodFk: JSON.stringify(photo.seasonalPeriod),
type: photo.type,
primary: photo.primary,
});
});
await tradeitemResponse.packingConfigurations.forEach(async (packagingConfiguration) => {
let uuid = uuidv4();
uuid = await vnUuid(uuid);
await models.packingConfigurations.upsert({
tradeItemFk: tradeitemResponse.tradeItemId,
packingConfigurationId: uuid,
piecesPerPackage: packagingConfiguration.piecesPerPackage,
bunchesPerPackage: packagingConfiguration.bunchesPerPackage,
photoUrl: packagingConfiguration.photoUrl,
packagesPerLayer: packagingConfiguration.packagesPerLayer,
layersPerLoadCarrier: packagingConfiguration.layersPerLoadCarrier,
transportHeightInCm: packagingConfiguration.transportHeightInCm,
loadCarrierType: packagingConfiguration.loadCarrierType,
isPrimary: packagingConfiguration.isPrimary,
additionalPricePerPiece: JSON.stringify(packagingConfiguration.additionalPricePerPiece),
});
await models.package.upsert({
packingConfigurationsId: uuid,
vbnPackageCode: packagingConfiguration.package.vbnPackageCode,
vbnPackageValueCode: packagingConfiguration.package.vbnPackageValueCode,
});
});
await tradeitemResponse.botanicalNames.forEach((botanicalName) => {
models.botanicalNames.upsert({
tradeItemFk: tradeitemResponse.tradeItemId,
name: botanicalName,
});
});
await tradeitemResponse.countryOfOriginIsoCodes.forEach((countryOfOriginIsoCode) => {
models.countryOfOriginIsoCodes.upsert({
tradeItemFk: tradeitemResponse.tradeItemId,
isoCode: countryOfOriginIsoCode,
});
});
return true;
} catch (error) {
console.log('There was an error while saving the data to the database, trying again in 5 seconds...');
console.log(error.message);
await sleep(5000);
await getTradeItem(tradeItemId);
}
}
/**
* Gets the stock for all suppliers
*
* Does this by getting all suppliers and then calling the getStockBySupplier function for each supplier
*/
async function getStock() {
const suppliers = await models.suppliers.findAll();
const supplierQueue = [];
suppliers.forEach(async (supplier) => {
supplierQueue.push(await getStockBySupplier(supplier.supplierId));
});
await asyncQueue(supplierQueue);
}
/**
* Returns the stock for a given supplier
*
* @param {*} supplierId
* @returns void - inserts the stock into the database
*/
async function getStockBySupplier(supplierId) {
supplierId = await removeVnPrefix(supplierId);
const headers = {
let headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${await getJWT()}`,
'X-Api-Key': process.env.API_KEY,
'X-Api-Key': process.env.API_KEY
};
let rFloraHolland = suppliersGln.floraholland;
const stockUrl = `${BASE_CUSTOMER_URL}supply-lines?supplierOrganizationId=${supplierId}`;
let queryConnections = `${BASE_CUSTOMER_URL}connections`;
let stockRequest;
let responseConnections = await fetch(queryConnections, {
method: 'GET',
headers: headers
});
try {
stockRequest = await fetch(stockUrl, {
method: 'GET',
headers: headers,
let dataConnections = await responseConnections.json();
for(let connection of dataConnections){
await models.connections.findOrCreate({
where: {
organizationId: connection
},
defaults: {
organizationId: connection,
connect : true
}
});
} catch (error) {
console.log(error.message);
return;
}
const stockResponse = await stockRequest.json();
for(let producer of rFloraHolland){
if (stockResponse.length == 0) {
return;
}
let query = `${BASE_CUSTOMER_URL}organizations/gln/${producer}`;
try {
let response = await fetch(query, {
method: 'GET',
headers: headers
});
if (stockResponse.length > 0 && stockResponse != null) {
let data = await response.json();
let bar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_grey);
bar.start(stockResponse.length, 0);
if (response.status === 200) {
console.log('Supplier request successful');
await stockResponse.forEach(async supplyLine => {
let connection = await models.connections.findOne({
where: {
organizationId: data.organizationId,
connect: true
}
});
bar.increment();
let isConnected = false;
let alreadyExists = await models.supplyLines.findOne({
if (connection != null) {
isConnected = true;
let where = {
companyGln: producer,
isConnected: isConnected
};
let defaults = {
isConnected: isConnected,
commercialName: data.commercialName,
email: data.email,
phone: data.phone,
website: data.website,
mailingAddress: data.mailingAddress,
physicalAddress: data.physicalAddress,
pythosanitaryNumber: data.phytosanitaryNumber,
sequenceNumber: data.sequenceNumber,
organizationId: data.organizationId,
companyGln: producer,
name: data.name,
endDate: data.endDate,
rfhRelationId: data.rfhRelationId,
organizationType: data.organizationType,
paymentProviders: JSON.stringify(data.paymentProviders),
};
await models.suppliers.destroy({
where: {
supplyLineId: supplyLine.supplyLineId,
companyGln: producer,
isConnected: false
}
});
if (alreadyExists) {
return;
}
try {
await models.supplyLines.upsert({
supplyLineId: supplyLine.supplyLineId,
status: supplyLine.status,
supplierOrganizationId: await vnUuid(supplyLine.supplierOrganizationId),
pricePerPiece: supplyLine.pricePerPiece,
numberOfPieces: supplyLine.numberOfPieces,
deliveryPeriod: supplyLine.deliveryPeriod,
orderPeriod: supplyLine.orderPeriod,
warehouseId: await vnUuid(supplyLine.warehouseId),
sequenceNumber: supplyLine.sequenceNumber,
type: supplyLine.type,
isDeleted: supplyLine.isDeleted,
salesUnit: supplyLine.salesUnit,
agreementReferenceCode: supplyLine.agreementReference.code,
agreementReferenceDescription: supplyLine.agreementReference.description,
isLimited: supplyLine.isLimited,
isCustomerSpecific: supplyLine.isCustomerSpecific,
tradeItemFk: await vnUuid(supplyLine.tradeItemId),
});
supplyLine.volumePrices.forEach(async (volumePrice) => {
await models.volumePrices.upsert({
supplyLineFk: supplyLine.supplyLineId,
unit: volumePrice.unit,
pricePerPiece: volumePrice.pricePerPiece,
});
});
} catch (error) {
if (error.name == 'SequelizeForeignKeyConstraintError') {
bar.stop();
console.log('Missing data for the tradeitem: ' + supplyLine.tradeItemId);
console.log('Trying to get the tradeitem data...');
await getTradeItem(supplyLine.tradeItemId);
return;
await models.suppliers.findOrCreate({
where : where,
defaults: defaults
});
} else {
let where = {
companyGln: producer,
isConnected: isConnected
};
let defaults = {
isConnected: isConnected,
commercialName: data.commercialName,
email: data.email,
phone: data.phone,
website: data.website,
mailingAddress: data.mailingAddress,
physicalAddress: data.physicalAddress,
pythosanitaryNumber: data.phytosanitaryNumber,
sequenceNumber: data.sequenceNumber,
organizationId: data.organizationId,
companyGln: producer,
name: data.name,
endDate: data.endDate,
rfhRelationId: data.rfhRelationId,
organizationType: data.organizationType,
paymentProviders: JSON.stringify(data.paymentProviders),
};
await models.suppliers.destroy({
where: {
companyGln: producer,
isConnected: true
}
}
});
await models.suppliers.findOrCreate({
where: where,
defaults: defaults
});
}
});
bar.stop();
console.log(`DATA FOR SUPPLIER: ${data.name} OK`);
} else {
console.log('Supplier request failed with status ', response.status);
console.log('Supplier: ', data);
console.log('response: ', response);
console.log('query: ', query);
}
} catch (error) {
console.log('There was an error while saving the data to the database, trying again in 5 seconds...');
await sleep(5000);
await getStockBySupplier(supplierId);
}
}
export { getClientToken, updateClientConfig, getJWT, getTradeitems, sleep, asyncQueue, getStock };
async function syncTradeItems(){
let suppliers = await models.suppliers.findAll({
where: {
isConnected: true
}
});
let headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${await getJWT()}`,
'X-Api-Key': process.env.API_KEY
};
for (let i = 0; i < suppliers.length; i++) {
let queryMaxSequence = `${BASE_CUSTOMER_URL}trade-items/current-max-sequence`;
let responseMaxSequence = await fetch(queryMaxSequence, {
method: 'GET',
headers: headers
});
let maximumSequenceNumber = await responseMaxSequence.json();
await syncSequence(0, 'tradeItems', maximumSequenceNumber);
let currentSequence = await models.sequenceNumber.findOne({
where: {
model: 'tradeItems'
}
});
currentSequence = currentSequence.sequenceNumber;
let estimatedIterations = Math.ceil(maximumSequenceNumber / 1000);
let supplier = suppliers[i];
console.log('Syncing trade items for: ', supplier.name);
console.log('Supplier Id: ', supplier.organizationId);
console.log('Current sequence number: ', currentSequence);
console.log('Maximum sequence number: ', maximumSequenceNumber);
console.log('Estimated iterations: ', estimatedIterations);
for (let j = 0; j < estimatedIterations; j++) {
let query = `${BASE_CUSTOMER_URL}trade-items/sync/${currentSequence}?supplierOrganizationId=${supplier.organizationId}&limit=1000`;
let request = await fetch(query, {
method: 'GET',
headers: headers
});
let data = await request.json();
let results = data.results;
if (results.length == 0) {
console.log('No more trade items to sync');
break;
}
}
}
}
export { getClientToken, updateClientConfig, getJWT, sleep, asyncQueue, syncSequence, syncSuppliers, syncTradeItems };