diff --git a/.dockerignore b/.dockerignore index afe81bb0f..1a47908ab 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,6 @@ node_modules print/node_modules -front/node_modules -services \ No newline at end of file +front +db +e2e +storage diff --git a/Jenkinsfile b/Jenkinsfile index a0442422c..4bacaa6d2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -20,15 +20,16 @@ node { RUN_BUILD = PROTECTED_BRANCH && FROM_GIT // https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables - echo "Node: ${env.NODE_NAME}" - echo "Workspace: ${env.WORKSPACE}" + echo "NODE_NAME: ${env.NODE_NAME}" + echo "WORKSPACE: ${env.WORKSPACE}" configFileProvider([ configFile(fileId: 'salix.properties', variable: 'PROPS_FILE') ]) { def props = readProperties file: PROPS_FILE - props.each { key, value -> env[key] = value } + props.each {key, value -> env."${key}" = value } + props.each {key, value -> echo "${key}: ${value}" } } if (PROTECTED_BRANCH) { @@ -37,7 +38,8 @@ node { variable: 'BRANCH_PROPS_FILE') ]) { def props = readProperties file: BRANCH_PROPS_FILE - props.each { key, value -> env[key] = value } + props.each {key, value -> env."${key}" = value } + props.each {key, value -> echo "${key}: ${value}" } } } } @@ -84,9 +86,6 @@ pipeline { } } stage('Stack') { - environment { - TZ = 'Europe/Madrid' - } parallel { stage('Back') { stages { @@ -102,14 +101,10 @@ pipeline { } post { always { - script { - try { - junit 'junitresults.xml' - junit 'junit.xml' - } catch (e) { - echo e.toString() - } - } + junit( + testResults: 'junitresults.xml', + allowEmptyResults: true + ) } } } @@ -142,6 +137,14 @@ pipeline { steps { sh 'jest --ci --reporters=default --reporters=jest-junit --maxWorkers=10' } + post { + always { + junit( + testResults: 'junit.xml', + allowEmptyResults: true + ) + } + } } stage('Build') { when { diff --git a/back/models/bank-entity.js b/back/models/bank-entity.js index c89e0b364..ac352f93c 100644 --- a/back/models/bank-entity.js +++ b/back/models/bank-entity.js @@ -8,6 +8,26 @@ module.exports = Self => { }); Self.validatesUniquenessOf('bic', { - message: 'This BIC already exist.' + message: 'This BIC already exist' }); + + Self.validatesPresenceOf('countryFk', { + message: 'CountryFK cannot be empty' + }); + + Self.validateAsync('bic', checkBic, { + message: 'Bank entity id must be specified' + }); + async function checkBic(err, done) { + const filter = { + fields: ['code'], + where: {id: this.countryFk} + }; + const country = await Self.app.models.Country.findOne(filter); + const code = country ? country.code.toLowerCase() : null; + + if (code == 'es' && !this.id) + err(); + done(); + } }; diff --git a/back/tests.js b/back/tests.js index c48c64b77..6c1b366e2 100644 --- a/back/tests.js +++ b/back/tests.js @@ -1,19 +1,36 @@ /* eslint-disable no-console */ const path = require('path'); +const getopts = require('getopts'); const Myt = require('@verdnatura/myt/myt'); const Run = require('@verdnatura/myt/myt-run'); const helper = require('./tests-helper'); +const opts = getopts(process.argv.slice(2), { + string: [ + 'network' + ], + boolean: [ + 'ci', + 'junit' + ] +}); + let server; -const isCI = process.argv[2] === 'ci'; const PARALLEL = false; const TIMEOUT = 900000; -process.on('SIGINT', teardown); process.on('exit', teardown); process.on('uncaughtException', onError); process.on('unhandledRejection', onError); +const exitSignals = [ + 'SIGINT', + 'SIGUSR1', + 'SIGUSR2' +]; +for (const signal of exitSignals) + process.on(signal, () => process.exit()); + async function setup() { console.log('Building and running DB container.'); @@ -21,9 +38,9 @@ async function setup() { await myt.init({ workspace: path.join(__dirname, '..'), random: true, - ci: isCI, + ci: opts.ci, tmpfs: process.platform == 'linux', - network: isCI ? 'jenkins' : null + network: opts.network || null }); server = await myt.run(Run); await myt.deinit(); @@ -38,18 +55,19 @@ async function setup() { async function teardown() { if (!server) return; + const oldServer = server; + server = null; if (!PARALLEL) await helper.deinit(); console.log('Stopping and removing DB container.'); - await server.rm(); - server = null; + await oldServer.rm(); } async function onError(err) { - await teardown(); console.error(err); + process.exit(1); } async function test() { @@ -79,8 +97,8 @@ async function test() { const SpecReporter = require('jasmine-spec-reporter').SpecReporter; runner.addReporter(new SpecReporter({ spec: { - displaySuccessful: isCI, - displayPending: isCI + displaySuccessful: opts.ci, + displayPending: opts.ci }, summary: { displayPending: false, @@ -88,11 +106,12 @@ async function test() { })); } - if (isCI) { + if (opts.junit) { const JunitReporter = require('jasmine-reporters'); runner.addReporter(new JunitReporter.JUnitXmlReporter()); - runner.jasmine.DEFAULT_TIMEOUT_INTERVAL = TIMEOUT; } + if (opts.ci) + runner.jasmine.DEFAULT_TIMEOUT_INTERVAL = TIMEOUT; // runner.loadConfigFile('back/jasmine.json'); runner.loadConfig(config); diff --git a/db/routines/vn/functions/intrastat_estimateNet.sql b/db/routines/vn/functions/intrastat_estimateNet.sql new file mode 100644 index 000000000..350cb788a --- /dev/null +++ b/db/routines/vn/functions/intrastat_estimateNet.sql @@ -0,0 +1,32 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`intrastat_estimateNet`( + vSelf INT, + vStems INT +) + RETURNS double + DETERMINISTIC +BEGIN +/** +* Calcula un valor neto estimado en función de +* datos históricos de facturas intrastat. +* +* @param vSelf Id de intrastat +* @param vStems Número de unidades +* @return vNet +*/ + DECLARE vNet DOUBLE; + + SELECT ROUND(vStems / (SUM(average) / COUNT(average)), 2) INTO vNet + FROM ( + SELECT *, stems / net average + FROM invoiceInIntrastat + WHERE intrastatFk = vSelf + AND net + AND stems > 0 + ORDER BY dated DESC + LIMIT 20 + ) sub; + + RETURN vNet/2; +END$$ +DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn2008/functions/intrastat_neto.sql b/db/routines/vn2008/functions/intrastat_neto.sql deleted file mode 100644 index 34e01de8c..000000000 --- a/db/routines/vn2008/functions/intrastat_neto.sql +++ /dev/null @@ -1,20 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn2008`.`intrastat_neto`(intINSTRASTAT INTEGER,intUNIDADES INTEGER) - RETURNS double - DETERMINISTIC -BEGIN - - DECLARE n DOUBLE; - - SELECT ROUND(intUNIDADES / (SUM(MEDIA) / COUNT(media)), 2) INTO n FROM - (SELECT *, unidades / neto MEDIA - FROM intrastat_data - WHERE intrastat_id = intINSTRASTAT AND neto - AND unidades > 0 - ORDER BY odbc_date DESC - LIMIT 20) t; - -- JGF 01/06 per a evitar Kg en negatiu - RETURN n/2; - -END$$ -DELIMITER ; diff --git a/docker-compose.yml b/docker-compose.yml index dda4187f2..8391a5e23 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,8 +3,9 @@ services: front: image: registry.verdnatura.es/salix-front:${VERSION:?} build: - context: . - dockerfile: front/Dockerfile + context: front + environment: + - TZ ports: - 80 deploy: @@ -18,11 +19,12 @@ services: back: image: registry.verdnatura.es/salix-back:${VERSION:?} build: . - ports: - - 3000 environment: - NODE_ENV - DEBUG + - TZ + ports: + - 3000 configs: - source: datasources target: /etc/salix/datasources.json diff --git a/front/Dockerfile b/front/Dockerfile index d0ee26904..c507d863c 100644 --- a/front/Dockerfile +++ b/front/Dockerfile @@ -10,7 +10,7 @@ RUN apt-get update \ && ln -sf /dev/stderr /var/log/nginx/error.log WORKDIR /etc/nginx -COPY front/nginx.conf sites-available/salix +COPY nginx.conf sites-available/salix RUN rm sites-enabled/default && ln -s ../sites-available/salix sites-enabled/salix COPY dist /salix/dist diff --git a/gulpfile.js b/gulpfile.js index a4caa6196..1c6fe2a2d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -17,7 +17,7 @@ if (argv.NODE_ENV) let langs = ['es', 'en']; let srcDir = './front'; let modulesDir = './modules'; -let buildDir = 'dist'; +let buildDir = 'front/dist'; let backSources = [ '!node_modules', diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 10ab08d57..7e010e1b5 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -198,6 +198,7 @@ "Booking completed": "Booking complete", "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation", "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets", + "Bank entity must be specified": "Bank entity must be specified", "Try again": "Try again", "keepPrice": "keepPrice", "Cannot past travels with entries": "Cannot past travels with entries", diff --git a/loopback/locale/es.json b/loopback/locale/es.json index eff73cc3a..0c17e2c8e 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -339,5 +339,6 @@ "No tickets to invoice": "No hay tickets para facturar", "This ticket already has a cmr saved": "Este ticket ya tiene un cmr guardado", "Name should be uppercase": "El nombre debe ir en mayúscula", + "Bank entity must be specified": "La entidad bancaria es obligatoria", "An email is necessary": "Es necesario un email" } \ No newline at end of file diff --git a/package.json b/package.json index 04c0e6d04..73fa5fc7a 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@babel/plugin-syntax-dynamic-import": "^7.7.4", "@babel/preset-env": "^7.11.0", "@babel/register": "^7.7.7", - "@verdnatura/myt": "^1.6.3", + "@verdnatura/myt": "^1.6.5", "angular-mocks": "^1.7.9", "babel-jest": "^26.0.1", "babel-loader": "^8.2.4", @@ -67,6 +67,7 @@ "eslint-plugin-jasmine": "^2.10.1", "fancy-log": "^1.3.2", "file-loader": "^6.2.0", + "getopts": "^2.3.0", "gulp": "^4.0.2", "gulp-concat": "^2.6.1", "gulp-env": "^0.4.0", @@ -107,7 +108,7 @@ "scripts": { "dbtest": "nodemon -q db/tests.js -w db/tests", "test:back": "nodemon -q back/tests.js --config back/nodemonConfig.json", - "test:back:ci": "node back/tests.js ci", + "test:back:ci": "node back/tests.js --ci --junit --network jenkins", "test:e2e": "node e2e/helpers/tests.js", "test:front": "jest --watch", "back": "nodemon --inspect -w modules ./node_modules/gulp/bin/gulp.js back", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2df0ae49c..83904cf41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -128,8 +128,8 @@ devDependencies: specifier: ^7.7.7 version: 7.23.7(@babel/core@7.23.9) '@verdnatura/myt': - specifier: ^1.6.3 - version: 1.6.3 + specifier: ^1.6.5 + version: 1.6.5 angular-mocks: specifier: ^1.7.9 version: 1.8.3 @@ -163,6 +163,9 @@ devDependencies: file-loader: specifier: ^6.2.0 version: 6.2.0(webpack@5.90.1) + getopts: + specifier: ^2.3.0 + version: 2.3.0 gulp: specifier: ^4.0.2 version: 4.0.2 @@ -2630,8 +2633,8 @@ packages: dev: false optional: true - /@verdnatura/myt@1.6.3: - resolution: {integrity: sha512-VRoTB5sEPL8a7VaX9l2afpaPNT6pBa+If1tP9tpaJ4enFQbNITlApcC0GK6XYmWMkJQjl2lgdN4/u0UCiNb2MQ==} + /@verdnatura/myt@1.6.5: + resolution: {integrity: sha512-0h7FvhSewd2W9EOymc59YymZJOBfCXmY5CWNFhol1yBfWSOOF9JAEE9DKRMbKaMqd/5Dy9LriS5PYOfeqm3HjA==} hasBin: true dependencies: '@sqltools/formatter': 1.2.5 diff --git a/webpack.config.js b/webpack.config.js index a102b838e..7296a62d1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -11,7 +11,7 @@ let baseConfig = { entry: {salix: 'salix'}, mode, output: { - path: path.join(__dirname, 'dist'), + path: path.join(__dirname, 'front/dist'), publicPath: '/' }, module: { @@ -139,7 +139,7 @@ let devConfig = { host: '0.0.0.0', port: 5000, publicPath: '/', - contentBase: 'dist', + contentBase: 'front/dist', quiet: false, noInfo: false, hot: true,