refs #4823 Code refactor

This commit is contained in:
Guillermo Bonet 2023-04-04 20:14:20 +02:00
parent cdd2fa269f
commit ecf9ceb44b
4 changed files with 179 additions and 137 deletions

View File

@ -1,7 +1,5 @@
# Floriday # Floriday
Requires [Node.js](https://nodejs.org/en/) v15.14.0 or higher.
The Floriday service project should perform the following tasks: The Floriday service project should perform the following tasks:
1. Create / mantain the table structure to allow the storage of the data provided by the Floriday API. 1. Create / mantain the table structure to allow the storage of the data provided by the Floriday API.
@ -12,13 +10,51 @@ The Floriday service project should perform the following tasks:
This is done using the [Sequelize](https://sequelize.org/) ORM and storing the data as it is received from the API, This is done using the [Sequelize](https://sequelize.org/) ORM and storing the data as it is received from the API,
so it can be compared with the previous data. so it can be compared with the previous data.
## Requeriments
* Git
* Nodejs (v15.14.0 or higher)
## Installation
Pull from repository.
Run this commands on project root directory to install Node dependencies.
```bash
npm i
```
### .env file template
```bash
#FLORIDAY DATA
CLIENT_ID = xxxxxxxxxx
CLIENT_SECRET = xxxxxxxxxx
API_KEY = xxxxxxxxxx
#SEQUELIZE CONFIG
DB_SCHEMA = schema
DB_USER = root
DB_PWD = root
DB_HOST = localhost
DB_DIALECT = mariadb
#GENERAL CONFIG
IS_PRODUCTION = false
SECRETS = true
FORCE_SYNC = true
SYNC_SEQUENCE = true
SYNC_SUPPLIER = true
SYNC_TRADEITEM = true
```
## Guidelines ## Guidelines
- In case a new model is created, it should follow the following structure: - In case a new model is created, it should follow the following structure:
- /models - /models
- index.js - main.js
- foo.js - foo.js
### Foo.js ### Foo.js
@ -51,7 +87,7 @@ export default (sequelize) => {
}; };
``` ```
### Index.js ### main.js
```javascript ```javascript
import foo from "./foo"; import foo from "./foo";
@ -62,32 +98,7 @@ let models = {
``` ```
To install dependencies: ## Built With
```bash * [nodejs](https://nodejs.org/)
npm install * [sequalize](https://sequelize.org/)
```
To run:
```bash
npm start # run the service
npm dev-sync # run and create the db structure
```
### .env file
```bash
# FLORIDAY SERVICE CONFIG
CLIENT_ID = floriday-client_id
CLIENT_SECRET = floriday-client_secret
STATUS = production_or_development
# SEQUELIZE CONFIG
DB_SCHEMA = edi
DB_USER = root
DB_PWD = root
DB_HOST = localhost
DB_DIALECT = mariadb
FORCE_SYNC = false
```

47
main.js
View File

@ -2,22 +2,26 @@ import * as vnUtils from './utils.js';
import { models } from './models/index.js'; import { models } from './models/index.js';
import moment from 'moment'; import moment from 'moment';
console.log = (...args) => console.info(`${new moment().format('HH:mm:ss')} -`, ...args); // Añade la hora a todos los console.log
// console.log = (...args) => console.info(`${new moment().format('HH:mm:ss')} -`, ...args);
async function main() { async function main() {
let tokenExpirationDate = await vnUtils.getClientToken(models); try {
const env = process.env; const env = process.env;
env.SYNC_SEQUENCE ? await vnUtils.syncSequence() : null; let tokenExpirationDate = await vnUtils.getClientToken(models);
env.SYNC_SUPPLIER ? await vnUtils.syncSuppliers() : null;
await vnUtils.syncConnections();
env.SYNC_TRADEITEM ? await vnUtils.syncTradeItems() : null;
console.log('Synced trade items');
if (JSON.parse(env.SYNC_SEQUENCE)) await vnUtils.syncSequence()
if (JSON.parse(env.SYNC_SUPPLIER)) await vnUtils.syncSuppliers();
await vnUtils.syncConnections();
if (JSON.parse(env.SYNC_TRADEITEM)) await vnUtils.syncTradeItems();
console.log('Synced trade items');
try { try {
while (true) { while (true) {
try{ try{
console.log('Querying the API to check for new data...'); console.log('Querying the API to check for new data...');
console.log('Current token expiration date: ', tokenExpirationDate);
if (moment().isAfter(tokenExpirationDate)) { if (moment().isAfter(tokenExpirationDate)) {
console.log('Token expired, getting a new one...'); console.log('Token expired, getting a new one...');
@ -25,19 +29,32 @@ async function main() {
} }
await vnUtils.syncSupplyLines(); await vnUtils.syncSupplyLines();
} catch (error) { } catch (err) {
console.error(error); console.error(err);
} }
if (env.STATUS == 'development') { if (JSON.parse(env.IS_PRODUCTION))
await vnUtils.sleep(120000);
} else {
await vnUtils.sleep(300000); await vnUtils.sleep(300000);
else
await vnUtils.sleep(120000);
} }
} catch (err) {
myErr(err);
} }
} catch (error) { } catch (err) {
console.error('Unable to connect to the database:', error); myErr(err);
} }
} }
/**
* Creates the connection to the database.
*
* @param {err}
**/
function myErr(err) {
console.log(`[ERROR]`.red.bold, `${err.name}: ${err.message}`.red);
process.exit();
}
main() main()

View File

@ -16,7 +16,7 @@ console.log(
) )
let sequelize = createConnection(); let sequelize = createConnection();
const conSpinner = ora('Creating the connection...').start(); const conSpinner = ora('Creating connection...').start();
try { try {
await sequelize.authenticate(); await sequelize.authenticate();
conSpinner.succeed(); conSpinner.succeed();
@ -161,18 +161,18 @@ models.tradeItem.belongsTo(models.supplier, {
}); });
let action, force; let action, isForce;
if (process.env.FORCE_SYNC === 'true') { if (JSON.parse(process.env.FORCE_SYNC)) {
action = 'Forcing' action = 'Forcing'
force = true isForce = true
} else { } else {
action = 'Altering' action = 'Altering'
force = false isForce = false
} }
const modSpinner = ora(`${action} the models...`).start(); const modSpinner = ora(`${action} models...`).start();
try { try {
await sequelize.sync({ force: force }); await sequelize.sync({ force: isForce });
if (process.env.SECRETS) { if (process.env.SECRETS) {
await models.clientConfig.findOrCreate({ await models.clientConfig.findOrCreate({
where: { where: {

View File

@ -24,6 +24,7 @@ async function getClientToken() {
throw colors.red.bold('No data found in the configuration table, ', throw colors.red.bold('No data found in the configuration table, ',
'if you have configured the .env file, declare the variable SECRET as true') 'if you have configured the .env file, declare the variable SECRET as true')
const spinner = ora(`Requesting token...`).start();
const now = moment().format('YYYY-MM-DD HH:mm:ss'); const now = moment().format('YYYY-MM-DD HH:mm:ss');
const tokenExpirationDate = clientConfigData[0].tokenExpiration; const tokenExpirationDate = clientConfigData[0].tokenExpiration;
@ -42,11 +43,11 @@ async function getClientToken() {
const tokenResponse = await tokenRequest.json(); const tokenResponse = await tokenRequest.json();
if (tokenRequest.status === 200) { if (tokenRequest.status === 200) {
console.log('Token request successful'); spinner.succeed();
} else { } else {
throw new Error( spinner.fail();
`Token request failed with status ${tokenRequest.status}` throw new Error(`Token request failed with status: ${tokenRequest.status} - ${tokenRequest.statusText}`);
);
} }
const accessToken = tokenResponse.access_token; const accessToken = tokenResponse.access_token;
@ -65,7 +66,8 @@ async function getClientToken() {
return tokenExpirationDate; return tokenExpirationDate;
} else { } else {
console.log('Using the current token...'); spinner.text = 'Using stored token...'
spinner.succeed();
return tokenExpirationDate; return tokenExpirationDate;
} }
} }
@ -81,7 +83,7 @@ async function getClientToken() {
*/ */
async function updateClientConfig(clientId, clientSecret, accessToken, tokenExpirationDate) { async function updateClientConfig(clientId, clientSecret, accessToken, tokenExpirationDate) {
try { try {
console.log('Updating the client config with the new token...'); const spinner = ora(`Updating config...`).start();
await models.clientConfig.upsert({ await models.clientConfig.upsert({
id: 1, id: 1,
clientId: clientId, clientId: clientId,
@ -90,9 +92,9 @@ async function updateClientConfig(clientId, clientSecret, accessToken, tokenExpi
tokenExpiration: tokenExpirationDate, tokenExpiration: tokenExpirationDate,
requestLimit: 500, requestLimit: 500,
}); });
console.log('Client config updated, new Token set'); spinner.succeed();
console.log('New token expiration date: ', tokenExpirationDate);
} catch (error) { } catch (error) {
spinner.fail();
console.log('There was a error while updating the client config'); console.log('There was a error while updating the client config');
console.log(error); console.log(error);
} }
@ -168,19 +170,23 @@ async function asyncQueue(fnArray, concurrency = 1) {
*/ */
async function syncSequence(current = 0, model = null , maximumSequenceNumber = 0){ async function syncSequence(current = 0, model = null , maximumSequenceNumber = 0){
if (model == null && current == 0){ if (model == null && current == 0){
try {
let mockModels = [ let mockModels = [
'suppliers'.green, 'suppliers',
'tradeItems'.blue, 'tradeItems',
'supplyLines'.yellow]; 'supplyLines',
];
const spinner = ora(`Syncing sequence...`).start();
for (let mockModel in mockModels) { for (let mockModel in mockModels) {
const element = mockModels[mockModel]; const element = mockModels[mockModel];
console.log('Syncing sequence for:', element);
await syncSequence(0, element); await syncSequence(0, element);
} }
spinner.succeed();
} else { } catch (err) {
spinner.fail();
throw(err);
}
} else if (current) {
let tx = await models.sequelize.transaction(); let tx = await models.sequelize.transaction();
@ -219,6 +225,8 @@ async function syncSequence(current = 0, model = null , maximumSequenceNumber =
} }
async function syncSuppliers(){ async function syncSuppliers(){
try {
const spinner = ora('Preparing to load suppliers...').start();
let headers = { let headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': `Bearer ${await getJWT()}`, 'Authorization': `Bearer ${await getJWT()}`,
@ -230,25 +238,23 @@ async function syncSuppliers(){
headers: headers headers: headers
}); });
const maxSequenceNumber = await response.json(); const maxSequenceNumber = await response.json();
let timeFinish, timeToGoSec, timeToGoMin, timeLeft;
let spinner;
for (let curSequenceNumber = 0; curSequenceNumber <= maxSequenceNumber; curSequenceNumber++) { for (let curSequenceNumber = 0; curSequenceNumber <= maxSequenceNumber; curSequenceNumber++) {
let timeStart = new moment();
let query = `${url}/organizations/sync/${curSequenceNumber}?organizationType=SUPPLIER`; let query = `${url}/organizations/sync/${curSequenceNumber}?organizationType=SUPPLIER`;
let response = await fetch(query, { let response = await fetch(query, {
method: 'GET', method: 'GET',
headers: headers headers: headers
}); });
let data = await response.json(); let data = await response.json();
let suppliers = data.results; let suppliers = data.results;
for (let supplier of suppliers) { for (let supplier of suppliers) {
curSequenceNumber = supplier.sequenceNumber; curSequenceNumber = supplier.sequenceNumber;
if (!spinner) { spinner.text = `Loading suppliers, ${maxSequenceNumber - curSequenceNumber} are missing`
spinner = ora('').start(); if (timeFinish)
spinner.color = 'green'; spinner.text = spinner.text + ` (${timeLeft})`
}
spinner.text = `Loading suppliers ${curSequenceNumber} of ${maxSequenceNumber}`.green
await models.supplier.upsert({ await models.supplier.upsert({
sequenceNumber: supplier.sequenceNumber, sequenceNumber: supplier.sequenceNumber,
companyGln: supplier.companyGln, companyGln: supplier.companyGln,
@ -268,9 +274,20 @@ async function syncSuppliers(){
}); });
} }
await syncSequence(curSequenceNumber, 'suppliers', maxSequenceNumber); await syncSequence(curSequenceNumber, 'suppliers', maxSequenceNumber);
timeFinish = new moment();
timeToGoSec = (timeFinish.diff(timeStart, 'seconds') * (maxSequenceNumber - curSequenceNumber) / 1000)
timeToGoMin = Math.trunc(timeToGoSec / 60)
if (!timeToGoMin)
timeLeft = `${Math.trunc(timeToGoSec)} sec`
else
timeLeft = `${timeToGoMin} min`
} }
if (spinner)
spinner.succeed() spinner.succeed()
}
catch (err) {
spinner.fail();
throw(err);
}
} }
async function syncConnections(){ async function syncConnections(){
@ -331,11 +348,8 @@ async function syncConnections(){
} }
async function syncTradeItems(){ async function syncTradeItems(){
const suppliers = await models.supplier.findAll(); const suppliers = await models.supplier.findAll();
let i = 0; let i = 0;
console.log('Syncing trade items'); console.log('Syncing trade items');
for (let supplier of suppliers) { for (let supplier of suppliers) {
i++; i++;