From 7b862c5c30c659addf7b7136db49ddcf97ab60ba Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 12 Feb 2024 16:10:58 +0100 Subject: [PATCH 01/62] fix: refs #6744 fix setPassword --- .../worker/back/methods/worker/setPassword.js | 47 +++++++++++-------- modules/worker/front/descriptor/index.html | 4 +- modules/worker/front/descriptor/index.js | 5 +- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/modules/worker/back/methods/worker/setPassword.js b/modules/worker/back/methods/worker/setPassword.js index 43d3d946f..0f6905e80 100644 --- a/modules/worker/back/methods/worker/setPassword.js +++ b/modules/worker/back/methods/worker/setPassword.js @@ -2,42 +2,49 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('setPassword', { description: 'Set a new password', - accepts: [ - { - arg: 'workerFk', - type: 'number', - required: true, - description: 'The worker id', - }, - { - arg: 'newPass', - type: 'String', - required: true, - description: 'The new worker password' - } + accepts: [{ + arg: 'workerFk', + type: 'number', + required: true, + description: 'The worker id', + }, { + arg: 'newPass', + type: 'String', + required: true, + description: 'The new worker password' + }, { + arg: 'emailVerified', + type: 'Boolean', + required: true, + }, ], http: { path: `/:id/setPassword`, verb: 'PATCH' } }); - Self.setPassword = async(ctx, options) => { + Self.setPassword = async(ctx, workerFk, newPass, emailVerified, options) => { + const userId = ctx.req.accessToken.userId; const models = Self.app.models; const myOptions = {}; - const {args} = ctx; let tx; + if (typeof options == 'object') Object.assign(myOptions, options); if (!myOptions.transaction) { tx = await Self.beginTransaction({}); myOptions.transaction = tx; } - try { - const isSubordinate = await models.Worker.isSubordinate(ctx, args.workerFk, myOptions); - if (!isSubordinate) throw new UserError('You don\'t have enough privileges.'); - await models.VnUser.setPassword(args.workerFk, args.newPass, myOptions); - await models.VnUser.updateAll({id: args.workerFk}, {emailVerified: true}, myOptions); + try { + const ishimself = userId === workerFk; + const isSubordinate = await models.Worker.isSubordinate(ctx, workerFk, myOptions); + + if (ishimself || (isSubordinate && !emailVerified)) { + await models.VnUser.setPassword(workerFk, newPass, myOptions); + await models.VnUser.updateAll({id: workerFk}, {emailVerified: true}, myOptions); + } else + throw new UserError('You don\'t have enough privileges.'); if (tx) await tx.commit(); } catch (e) { diff --git a/modules/worker/front/descriptor/index.html b/modules/worker/front/descriptor/index.html index 8290e2a15..67776ce47 100644 --- a/modules/worker/front/descriptor/index.html +++ b/modules/worker/front/descriptor/index.html @@ -11,8 +11,8 @@ ? 'Click to allow the user to be disabled' : 'Click to exclude the user from getting disabled'}} - - Change password + + Change password diff --git a/modules/worker/front/descriptor/index.js b/modules/worker/front/descriptor/index.js index 13ffa6f2f..4ef98fe3b 100644 --- a/modules/worker/front/descriptor/index.js +++ b/modules/worker/front/descriptor/index.js @@ -15,6 +15,8 @@ class Controller extends Descriptor { this.entity = value; if (value) this.getIsExcluded(); + this.$http.get(`UserConfigs/getUserConfig`) + .then(res => this.userFk = res.data.userFk); if (this.entity && !this.entity.user.emailVerified) this.getPassRequirements(); @@ -69,6 +71,7 @@ class Controller extends Descriptor { } ] }; + return this.getData(`Workers/${this.id}`, {filter}) .then(res => this.entity = res.data); } @@ -87,7 +90,7 @@ class Controller extends Descriptor { throw new UserError(`Passwords don't match`); this.$http.patch( `Workers/${this.entity.id}/setPassword`, - {workerFk: this.entity.id, newPass: this.newPassword} + {workerFk: this.entity.id, newPass: this.newPassword, emailVerified: !!this.entity.user.emailVerified} ) .then(() => { this.vnApp.showSuccess(this.$translate.instant('Password changed!')); }); From 47bfb34507df24839642afa49694f699036a3f71 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 13 Feb 2024 10:10:48 +0100 Subject: [PATCH 02/62] fix: refs #6744 remove params --- .../worker/back/methods/worker/setPassword.js | 21 ++++++++----------- modules/worker/front/descriptor/index.js | 8 +++---- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/modules/worker/back/methods/worker/setPassword.js b/modules/worker/back/methods/worker/setPassword.js index 0f6905e80..cf9cd4cf2 100644 --- a/modules/worker/back/methods/worker/setPassword.js +++ b/modules/worker/back/methods/worker/setPassword.js @@ -3,27 +3,23 @@ module.exports = Self => { Self.remoteMethodCtx('setPassword', { description: 'Set a new password', accepts: [{ - arg: 'workerFk', + arg: 'id', type: 'number', required: true, description: 'The worker id', + http: {source: 'path'} }, { arg: 'newPass', type: 'String', required: true, description: 'The new worker password' - }, { - arg: 'emailVerified', - type: 'Boolean', - required: true, - }, - ], + }], http: { path: `/:id/setPassword`, verb: 'PATCH' } }); - Self.setPassword = async(ctx, workerFk, newPass, emailVerified, options) => { + Self.setPassword = async(ctx, workerId, newPass, options) => { const userId = ctx.req.accessToken.userId; const models = Self.app.models; const myOptions = {}; @@ -37,12 +33,13 @@ module.exports = Self => { } try { - const ishimself = userId === workerFk; - const isSubordinate = await models.Worker.isSubordinate(ctx, workerFk, myOptions); + const ishimself = userId === workerId; + const isSubordinate = await Self.isSubordinate(ctx, workerId, myOptions); + const {emailVerified} = await models.VnUser.findById(workerId, {fields: ['emailVerified']}, myOptions); if (ishimself || (isSubordinate && !emailVerified)) { - await models.VnUser.setPassword(workerFk, newPass, myOptions); - await models.VnUser.updateAll({id: workerFk}, {emailVerified: true}, myOptions); + await models.VnUser.setPassword(workerId, newPass, myOptions); + await models.VnUser.updateAll({id: workerId}, {emailVerified: true}, myOptions); } else throw new UserError('You don\'t have enough privileges.'); diff --git a/modules/worker/front/descriptor/index.js b/modules/worker/front/descriptor/index.js index 4ef98fe3b..3cbeb2c55 100644 --- a/modules/worker/front/descriptor/index.js +++ b/modules/worker/front/descriptor/index.js @@ -5,6 +5,9 @@ class Controller extends Descriptor { constructor($element, $, $rootScope) { super($element, $); this.$rootScope = $rootScope; + + this.$http.get(`UserConfigs/getUserConfig`) + .then(res => this.userFk = res.data.userFk); } get worker() { @@ -15,8 +18,6 @@ class Controller extends Descriptor { this.entity = value; if (value) this.getIsExcluded(); - this.$http.get(`UserConfigs/getUserConfig`) - .then(res => this.userFk = res.data.userFk); if (this.entity && !this.entity.user.emailVerified) this.getPassRequirements(); @@ -89,8 +90,7 @@ class Controller extends Descriptor { if (this.newPassword != this.repeatPassword) throw new UserError(`Passwords don't match`); this.$http.patch( - `Workers/${this.entity.id}/setPassword`, - {workerFk: this.entity.id, newPass: this.newPassword, emailVerified: !!this.entity.user.emailVerified} + `Workers/${this.entity.id}/setPassword`, {newPass: this.newPassword} ) .then(() => { this.vnApp.showSuccess(this.$translate.instant('Password changed!')); }); From 9f2768c131b6cb04d8fea1ce4fc3d4376c20a6c7 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 16 Feb 2024 15:51:54 +0100 Subject: [PATCH 03/62] fix: refs #6776 tests --- .../worker/back/methods/worker/setPassword.js | 4 +- .../methods/worker/specs/setPassword.spec.js | 92 +++++++++++++------ modules/worker/front/descriptor/index.spec.js | 1 + 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/modules/worker/back/methods/worker/setPassword.js b/modules/worker/back/methods/worker/setPassword.js index cf9cd4cf2..5571ea1d2 100644 --- a/modules/worker/back/methods/worker/setPassword.js +++ b/modules/worker/back/methods/worker/setPassword.js @@ -33,11 +33,11 @@ module.exports = Self => { } try { - const ishimself = userId === workerId; + const isHimself = userId === workerId; const isSubordinate = await Self.isSubordinate(ctx, workerId, myOptions); const {emailVerified} = await models.VnUser.findById(workerId, {fields: ['emailVerified']}, myOptions); - if (ishimself || (isSubordinate && !emailVerified)) { + if (isHimself || (isSubordinate && !emailVerified)) { await models.VnUser.setPassword(workerId, newPass, myOptions); await models.VnUser.updateAll({id: workerId}, {emailVerified: true}, myOptions); } else diff --git a/modules/worker/back/methods/worker/specs/setPassword.spec.js b/modules/worker/back/methods/worker/specs/setPassword.spec.js index fbb403b24..0f0700561 100644 --- a/modules/worker/back/methods/worker/specs/setPassword.spec.js +++ b/modules/worker/back/methods/worker/specs/setPassword.spec.js @@ -1,31 +1,30 @@ -const UserError = require('vn-loopback/util/user-error'); - -const models = require('vn-loopback/server/server').models; +const {models} = require('vn-loopback/server/server'); describe('worker setPassword()', () => { let ctx; + const newPass = 'H3rn4d3z#'; + const employeeId = 1; + const managerId = 20; + const administrativeId = 5; + beforeAll(() => { ctx = { req: { - accessToken: {}, + accessToken: {userId: managerId}, headers: {origin: 'http://localhost'} }, - args: {workerFk: 9} }; }); - beforeEach(() => { - ctx.req.accessToken.userId = 20; - ctx.args.newPass = 'H3rn4d3z#'; - }); - - it('should change the password', async() => { + it('should change the password if it is a subordinate and the email is not verified', async() => { const tx = await models.Worker.beginTransaction({}); try { const options = {transaction: tx}; - await models.Worker.setPassword(ctx, options); + await models.Worker.setPassword(ctx, employeeId, newPass, options); + const isNewPass = await passHasBeenChanged(employeeId, newPass, options); + expect(isNewPass).toBeTrue(); await tx.rollback(); } catch (e) { await tx.rollback(); @@ -33,29 +32,64 @@ describe('worker setPassword()', () => { } }); - it('should throw an error: Password does not meet requirements', async() => { - const tx = await models.Collection.beginTransaction({}); - ctx.args.newPass = 'Hi'; + it('should not change the password if it is a subordinate and the email is verified', async() => { + const tx = await models.Worker.beginTransaction({}); + try { const options = {transaction: tx}; - await models.Worker.setPassword(ctx, options); + await models.VnUser.updateAll({id: employeeId}, {emailVerified: true}, options); + await models.Worker.setPassword(ctx, employeeId, newPass, options); + + await tx.rollback(); + } catch (e) { + expect(e.message).toEqual(`You don't have enough privileges.`); + await tx.rollback(); + } + }); + + it('should change the password if it is himself', async() => { + const tx = await models.Worker.beginTransaction({}); + + try { + const options = {transaction: tx}; + await models.VnUser.updateAll({id: managerId}, {emailVerified: true}, options); + await models.Worker.setPassword(ctx, managerId, newPass, options); + const isNewPass = await passHasBeenChanged(managerId, newPass, options); + + expect(isNewPass).toBeTrue(); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + } + }); + + it('should not change the password if it is not a subordinate', async() => { + const tx = await models.Worker.beginTransaction({}); + try { + const options = {transaction: tx}; + await models.Worker.setPassword(ctx, administrativeId, newPass, options); + await tx.rollback(); + } catch (e) { + expect(e.message).toEqual(`You don't have enough privileges.`); + await tx.rollback(); + } + }); + + it('should throw an error: Password does not meet requirements', async() => { + const tx = await models.Worker.beginTransaction({}); + const newPass = 'Hi'; + try { + const options = {transaction: tx}; + await models.Worker.setPassword(ctx, employeeId, newPass, options); await tx.rollback(); } catch (e) { expect(e.sqlMessage).toEqual('Password does not meet requirements'); await tx.rollback(); } }); - - it('should throw an error: You don\'t have enough privileges.', async() => { - ctx.req.accessToken.userId = 5; - const tx = await models.Collection.beginTransaction({}); - try { - const options = {transaction: tx}; - await models.Worker.setPassword(ctx, options); - await tx.rollback(); - } catch (e) { - expect(e).toEqual(new UserError(`You don't have enough privileges.`)); - await tx.rollback(); - } - }); }); + +const passHasBeenChanged = async(userId, pass, options) => { + const user = await models.VnUser.findById(userId, null, options); + return user.hasPassword(pass); +}; diff --git a/modules/worker/front/descriptor/index.spec.js b/modules/worker/front/descriptor/index.spec.js index d158a9e8e..4f7fa6a05 100644 --- a/modules/worker/front/descriptor/index.spec.js +++ b/modules/worker/front/descriptor/index.spec.js @@ -16,6 +16,7 @@ describe('vnWorkerDescriptor', () => { const id = 1; const response = 'foo'; + $httpBackend.whenGET('UserConfigs/getUserConfig').respond({}); $httpBackend.expectRoute('GET', `Workers/${id}`).respond(response); controller.id = id; $httpBackend.flush(); From 2e01b6ee0a9ef4a3d187e7589e02a1d6d4a109c2 Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 19 Feb 2024 09:55:54 +0100 Subject: [PATCH 04/62] refactor(packing): refs #6875 add restriction on vn.buy.packing field not null and > 0 --- db/routines/vn/procedures/inventoryMake.sql | 2 +- db/versions/10892-yellowGerbera/00-firstScript.sql | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 db/versions/10892-yellowGerbera/00-firstScript.sql diff --git a/db/routines/vn/procedures/inventoryMake.sql b/db/routines/vn/procedures/inventoryMake.sql index 0def763dc..abf185c9f 100644 --- a/db/routines/vn/procedures/inventoryMake.sql +++ b/db/routines/vn/procedures/inventoryMake.sql @@ -182,7 +182,7 @@ proc: BEGIN LEFT JOIN producer p ON p.id = i.producerFk SET inv.buyingValue = b.buyingValue, inv.freightValue = b.freightValue, - inv.packing = b.packing, + inv.packing = IFNULL(GREATEST(b.packing, 1), 1), inv.`grouping`= b.`grouping`, inv.groupingMode = b.groupingMode, inv.comissionValue = b.comissionValue, diff --git a/db/versions/10892-yellowGerbera/00-firstScript.sql b/db/versions/10892-yellowGerbera/00-firstScript.sql new file mode 100644 index 000000000..4df616f3a --- /dev/null +++ b/db/versions/10892-yellowGerbera/00-firstScript.sql @@ -0,0 +1,12 @@ +-- Place your SQL code here + +UPDATE vn.buy + SET packing = 1 + WHERE packing IS NULL + OR NOT packing + +ALTER TABLE vn.buy MODIFY COLUMN packing int(11) NOT NULL CHECK(packing > 0); + +-- antes tenia '0=sin obligar 1=groping 2=packing' +ALTER TABLE vn.buy MODIFY COLUMN groupingMode tinyint(4) DEFAULT 0 NOT NULL COMMENT '0=sin obligar 1=grouping 2=packing'; + From 9e3b4e84515e832a454b161f7a12f8e63138012c Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 19 Feb 2024 13:30:03 +0100 Subject: [PATCH 05/62] refs #6842 sql mod sage --- .../vn/triggers/invoiceOut_beforeInsert.sql | 12 +++---- db/versions/10893-limeFern/00-sage.sql | 35 +++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 db/versions/10893-limeFern/00-sage.sql diff --git a/db/routines/vn/triggers/invoiceOut_beforeInsert.sql b/db/routines/vn/triggers/invoiceOut_beforeInsert.sql index 0081c8803..f3a292edd 100644 --- a/db/routines/vn/triggers/invoiceOut_beforeInsert.sql +++ b/db/routines/vn/triggers/invoiceOut_beforeInsert.sql @@ -17,16 +17,16 @@ BEGIN DECLARE vRefLen INT; DECLARE vRefPrefix VARCHAR(255); DECLARE vLastRef VARCHAR(255); - DECLARE vCompanyCode INT; + DECLARE vSage200Company INT; DECLARE vYearLen INT DEFAULT 2; DECLARE vPrefixLen INT; - SELECT companyCode INTO vCompanyCode + SELECT sage200Company INTO vSage200Company FROM company WHERE id = NEW.companyFk; - IF vCompanyCode IS NULL THEN - CALL util.throw('companyCodeNotDefined'); + IF vSage200Company IS NULL THEN + CALL util.throw('vSage200CompanyNotDefined'); END IF; SELECT MAX(i.ref) INTO vLastRef @@ -36,7 +36,7 @@ BEGIN AND i.companyFk = NEW.companyFk; IF vLastRef IS NOT NULL THEN - SET vPrefixLen = LENGTH(NEW.serial) + LENGTH(vCompanyCode) + vYearLen; + SET vPrefixLen = LENGTH(NEW.serial) + LENGTH(vSage200Company) + vYearLen; SET vRefLen = LENGTH(vLastRef) - vPrefixLen; SET vRefPrefix = LEFT(vLastRef, vPrefixLen); SET vRef = RIGHT(vLastRef, vRefLen); @@ -44,7 +44,7 @@ BEGIN SELECT refLen INTO vRefLen FROM invoiceOutConfig; SET vRefPrefix = CONCAT( NEW.serial, - vCompanyCode, + vSage200Company, RIGHT(YEAR(NEW.issued), vYearLen) ); END IF; diff --git a/db/versions/10893-limeFern/00-sage.sql b/db/versions/10893-limeFern/00-sage.sql new file mode 100644 index 000000000..049bb2993 --- /dev/null +++ b/db/versions/10893-limeFern/00-sage.sql @@ -0,0 +1,35 @@ +-- Auto-generated SQL script #202402151810 +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=69; +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=567; +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=791; +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=792; +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=965; +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=1381; +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=1463; +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=2142; +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=2292; +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=2393; +UPDATE vn.company + SET companyGroupFk=NULL + WHERE id=3869; +ALTER TABLE vn.company MODIFY COLUMN sage200Company int(2) DEFAULT NULL NULL COMMENT 'Campo para la serie InvoiceOut'; From 744dd61561af56ad76771a59612ee8ba86bc6bbc Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 22 Feb 2024 15:42:54 +0100 Subject: [PATCH 06/62] fix: refs #6744 create setUnverifiedPassword --- loopback/locale/en.json | 3 ++- loopback/locale/es.json | 3 ++- modules/account/back/models/account.js | 11 +++++++++++ .../worker/back/methods/worker/setPassword.js | 15 ++++----------- .../methods/worker/specs/setPassword.spec.js | 18 +----------------- modules/worker/front/descriptor/index.html | 2 +- modules/worker/front/descriptor/index.js | 7 ++----- 7 files changed, 23 insertions(+), 36 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 2187371cd..39596467c 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -209,5 +209,6 @@ "You cannot update these fields": "You cannot update these fields", "CountryFK cannot be empty": "Country cannot be empty", "You are not allowed to modify the alias": "You are not allowed to modify the alias", - "You already have the mailAlias": "You already have the mailAlias" + "You already have the mailAlias": "You already have the mailAlias", + "The email has been already verified": "The email has been already verified" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index aea0c311c..d36348472 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -344,5 +344,6 @@ "CountryFK cannot be empty": "El país no puede estar vacío", "Cmr file does not exist": "El archivo del cmr no existe", "You are not allowed to modify the alias": "No estás autorizado a modificar el alias", - "No tickets to invoice": "No hay tickets para facturar" + "No tickets to invoice": "No hay tickets para facturar", + "The email has been already verified": "El correo ya ha sido verificado" } diff --git a/modules/account/back/models/account.js b/modules/account/back/models/account.js index 5021a5d94..7c97711d0 100644 --- a/modules/account/back/models/account.js +++ b/modules/account/back/models/account.js @@ -1,4 +1,7 @@ +const ForbiddenError = require('vn-loopback/util/forbiddenError'); +const {models} = require('vn-loopback/server/server'); + module.exports = Self => { require('../methods/account/sync')(Self); require('../methods/account/sync-by-id')(Self); @@ -7,4 +10,12 @@ module.exports = Self => { require('../methods/account/logout')(Self); require('../methods/account/change-password')(Self); require('../methods/account/set-password')(Self); + + Self.setUnverifiedPassword = async(id, pass, options) => { + const user = await models.VnUser.findById(id, null, options); + if (user.emailVerified) throw new ForbiddenError('The email has been already verified'); + + await models.VnUser.setPassword(id, pass, options); + await user.updateAttribute('emailVerified', true, options); + }; }; diff --git a/modules/worker/back/methods/worker/setPassword.js b/modules/worker/back/methods/worker/setPassword.js index 5571ea1d2..e6bdfb364 100644 --- a/modules/worker/back/methods/worker/setPassword.js +++ b/modules/worker/back/methods/worker/setPassword.js @@ -19,8 +19,7 @@ module.exports = Self => { verb: 'PATCH' } }); - Self.setPassword = async(ctx, workerId, newPass, options) => { - const userId = ctx.req.accessToken.userId; + Self.setPassword = async(ctx, id, newPass, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -31,17 +30,11 @@ module.exports = Self => { tx = await Self.beginTransaction({}); myOptions.transaction = tx; } - try { - const isHimself = userId === workerId; - const isSubordinate = await Self.isSubordinate(ctx, workerId, myOptions); - const {emailVerified} = await models.VnUser.findById(workerId, {fields: ['emailVerified']}, myOptions); + const isSubordinate = await Self.isSubordinate(ctx, id, myOptions); + if (!isSubordinate) throw new UserError('You don\'t have enough privileges.'); - if (isHimself || (isSubordinate && !emailVerified)) { - await models.VnUser.setPassword(workerId, newPass, myOptions); - await models.VnUser.updateAll({id: workerId}, {emailVerified: true}, myOptions); - } else - throw new UserError('You don\'t have enough privileges.'); + await models.Account.setUnverifiedPassword(id, newPass, myOptions); if (tx) await tx.commit(); } catch (e) { diff --git a/modules/worker/back/methods/worker/specs/setPassword.spec.js b/modules/worker/back/methods/worker/specs/setPassword.spec.js index 0f0700561..d2daec103 100644 --- a/modules/worker/back/methods/worker/specs/setPassword.spec.js +++ b/modules/worker/back/methods/worker/specs/setPassword.spec.js @@ -42,23 +42,7 @@ describe('worker setPassword()', () => { await tx.rollback(); } catch (e) { - expect(e.message).toEqual(`You don't have enough privileges.`); - await tx.rollback(); - } - }); - - it('should change the password if it is himself', async() => { - const tx = await models.Worker.beginTransaction({}); - - try { - const options = {transaction: tx}; - await models.VnUser.updateAll({id: managerId}, {emailVerified: true}, options); - await models.Worker.setPassword(ctx, managerId, newPass, options); - const isNewPass = await passHasBeenChanged(managerId, newPass, options); - - expect(isNewPass).toBeTrue(); - await tx.rollback(); - } catch (e) { + expect(e.message).toEqual(`The email has been already verified`); await tx.rollback(); } }); diff --git a/modules/worker/front/descriptor/index.html b/modules/worker/front/descriptor/index.html index 67776ce47..73332efac 100644 --- a/modules/worker/front/descriptor/index.html +++ b/modules/worker/front/descriptor/index.html @@ -11,7 +11,7 @@ ? 'Click to allow the user to be disabled' : 'Click to exclude the user from getting disabled'}} - + Change password diff --git a/modules/worker/front/descriptor/index.js b/modules/worker/front/descriptor/index.js index 3cbeb2c55..d7962369c 100644 --- a/modules/worker/front/descriptor/index.js +++ b/modules/worker/front/descriptor/index.js @@ -5,9 +5,6 @@ class Controller extends Descriptor { constructor($element, $, $rootScope) { super($element, $); this.$rootScope = $rootScope; - - this.$http.get(`UserConfigs/getUserConfig`) - .then(res => this.userFk = res.data.userFk); } get worker() { @@ -93,11 +90,11 @@ class Controller extends Descriptor { `Workers/${this.entity.id}/setPassword`, {newPass: this.newPassword} ) .then(() => { this.vnApp.showSuccess(this.$translate.instant('Password changed!')); - }); + }).then(() => this.loadData()); } } -Controller.$inject = ['$element', '$scope', '$rootScope']; +Controller.$inject = ['$element', '$scope', '$rootScope', 'vnConfig']; ngModule.vnComponent('vnWorkerDescriptor', { template: require('./index.html'), From 3bf25e5759ce1169c83d03a1c9c46c71aebcdd38 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 23 Feb 2024 09:31:01 +0100 Subject: [PATCH 07/62] fix: refs #6744 locale --- loopback/locale/en.json | 2 +- loopback/locale/es.json | 2 +- modules/account/back/models/account.js | 2 +- modules/worker/back/methods/worker/specs/setPassword.spec.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 39596467c..efcf0ef31 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -210,5 +210,5 @@ "CountryFK cannot be empty": "Country cannot be empty", "You are not allowed to modify the alias": "You are not allowed to modify the alias", "You already have the mailAlias": "You already have the mailAlias", - "The email has been already verified": "The email has been already verified" + "This password can only be changed by the user themselves": "This password can only be changed by the user themselves" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index d36348472..64832553b 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -345,5 +345,5 @@ "Cmr file does not exist": "El archivo del cmr no existe", "You are not allowed to modify the alias": "No estás autorizado a modificar el alias", "No tickets to invoice": "No hay tickets para facturar", - "The email has been already verified": "El correo ya ha sido verificado" + "This password can only be changed by the user themselves": "Esta contraseña solo puede ser modificada por el propio usuario" } diff --git a/modules/account/back/models/account.js b/modules/account/back/models/account.js index 7c97711d0..dd04182f6 100644 --- a/modules/account/back/models/account.js +++ b/modules/account/back/models/account.js @@ -13,7 +13,7 @@ module.exports = Self => { Self.setUnverifiedPassword = async(id, pass, options) => { const user = await models.VnUser.findById(id, null, options); - if (user.emailVerified) throw new ForbiddenError('The email has been already verified'); + if (user.emailVerified) throw new ForbiddenError('This password can only be changed by the user themselves'); await models.VnUser.setPassword(id, pass, options); await user.updateAttribute('emailVerified', true, options); diff --git a/modules/worker/back/methods/worker/specs/setPassword.spec.js b/modules/worker/back/methods/worker/specs/setPassword.spec.js index d2daec103..03cbee03b 100644 --- a/modules/worker/back/methods/worker/specs/setPassword.spec.js +++ b/modules/worker/back/methods/worker/specs/setPassword.spec.js @@ -42,7 +42,7 @@ describe('worker setPassword()', () => { await tx.rollback(); } catch (e) { - expect(e.message).toEqual(`The email has been already verified`); + expect(e.message).toEqual(`This password can only be changed by the user themselves`); await tx.rollback(); } }); From a078de95210a4e99aba1cffea2050761312d0445 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 26 Feb 2024 06:51:19 +0100 Subject: [PATCH 08/62] refs #6930 feat: return multimediaToken when login --- back/models/vn-user.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 3a416d7e3..e1bce7c06 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -167,7 +167,11 @@ module.exports = function(Self) { console.warn(err); } - return {token: token.id, ttl: token.ttl}; + const multimediaToken = await token.user().accessTokens.create({ + scopes: ['read:multimedia'] + }); + + return {token: token.id, ttl: token.ttl, multimediaToken}; }; Self.userUses = function(user) { From ae0ce8e49a7dec0e6cc7cdef044852f107a5fd3b Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 26 Feb 2024 06:53:30 +0100 Subject: [PATCH 09/62] refs #6930 feat: use tokenMultimedia intead tokenUser --- front/core/services/auth.js | 2 +- front/core/services/token.js | 15 ++++++++++----- front/salix/components/layout/index.js | 3 +-- front/salix/components/log/index.html | 4 ++-- front/salix/module.js | 2 +- modules/client/front/balance/index/index.html | 2 +- .../invoiceOut/front/descriptor-menu/index.html | 2 +- modules/invoiceOut/front/index/index.js | 2 +- modules/route/front/index/index.js | 2 +- 9 files changed, 19 insertions(+), 15 deletions(-) diff --git a/front/core/services/auth.js b/front/core/services/auth.js index 844a5145d..0253eb3c3 100644 --- a/front/core/services/auth.js +++ b/front/core/services/auth.js @@ -83,7 +83,7 @@ export default class Auth { } onLoginOk(json, now, remember) { - this.vnToken.set(json.data.token, now, json.data.ttl, remember); + this.vnToken.set(json.data.token, json.data.multimediaToken.id, now, json.data.ttl, remember); return this.loadAcls().then(() => { let continueHash = this.$state.params.continue; diff --git a/front/core/services/token.js b/front/core/services/token.js index c8cb4f6bb..125de6b9a 100644 --- a/front/core/services/token.js +++ b/front/core/services/token.js @@ -24,21 +24,22 @@ export default class Token { } catch (e) {} } - set(token, created, ttl, remember) { + set(token, tokenMultimedia, created, ttl, remember) { this.unset(); Object.assign(this, { token, + tokenMultimedia, created, ttl, remember }); - this.vnInterceptor.setToken(token); + this.vnInterceptor.setToken(token, tokenMultimedia); try { if (remember) - this.setStorage(localStorage, token, created, ttl); + this.setStorage(localStorage, token, tokenMultimedia, created, ttl); else - this.setStorage(sessionStorage, token, created, ttl); + this.setStorage(sessionStorage, token, tokenMultimedia, created, ttl); } catch (err) { console.error(err); } @@ -46,6 +47,7 @@ export default class Token { unset() { this.token = null; + this.tokenMultimedia = null; this.created = null; this.ttl = null; this.remember = null; @@ -57,13 +59,15 @@ export default class Token { getStorage(storage) { this.token = storage.getItem('vnToken'); + this.tokenMultimedia = storage.getItem('vnTokenMultimedia'); if (!this.token) return; const created = storage.getItem('vnTokenCreated'); this.created = created && new Date(created); this.ttl = storage.getItem('vnTokenTtl'); } - setStorage(storage, token, created, ttl) { + setStorage(storage, token, tokenMultimedia, created, ttl) { + storage.setItem('vnTokenMultimedia', tokenMultimedia); storage.setItem('vnToken', token); storage.setItem('vnTokenCreated', created.toJSON()); storage.setItem('vnTokenTtl', ttl); @@ -71,6 +75,7 @@ export default class Token { removeStorage(storage) { storage.removeItem('vnToken'); + storage.removeItem('vnTokenMultimedia'); storage.removeItem('vnTokenCreated'); storage.removeItem('vnTokenTtl'); } diff --git a/front/salix/components/layout/index.js b/front/salix/components/layout/index.js index 89912d4e3..e935c6d99 100644 --- a/front/salix/components/layout/index.js +++ b/front/salix/components/layout/index.js @@ -23,8 +23,7 @@ export class Layout extends Component { if (!this.$.$root.user) return; const userId = this.$.$root.user.id; - const token = this.vnToken.token; - return `/api/Images/user/160x160/${userId}/download?access_token=${token}`; + return `/api/Images/user/160x160/${userId}/download?access_token=${this.vnToken.tokenMultimedia}`; } refresh() { diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index c75030100..a3aaf0011 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -31,7 +31,7 @@ ng-click="$ctrl.showDescriptor($event, userLog)"> + ng-src="/api/Images/user/160x160/{{::userLog.userFk}}/download?access_token={{::$ctrl.vnToken.tokenMultimedia}}"> @@ -181,7 +181,7 @@ val="{{::nickname}}"> + ng-src="/api/Images/user/160x160/{{::id}}/download?access_token={{::$ctrl.vnToken.tokenMultimedia}}">
diff --git a/front/salix/module.js b/front/salix/module.js index 0ce855308..53b718427 100644 --- a/front/salix/module.js +++ b/front/salix/module.js @@ -13,7 +13,7 @@ export function run($window, $rootScope, vnAuth, vnApp, vnToken, $state) { if (!collection || !size || !id) return; const basePath = `/api/Images/${collection}/${size}/${id}`; - return `${basePath}/download?access_token=${vnToken.token}`; + return `${basePath}/download?access_token=${vnToken.tokenMultimedia}`; }; $window.validations = {}; diff --git a/modules/client/front/balance/index/index.html b/modules/client/front/balance/index/index.html index faf772c2d..34524d2f3 100644 --- a/modules/client/front/balance/index/index.html +++ b/modules/client/front/balance/index/index.html @@ -114,7 +114,7 @@ + href="api/InvoiceOuts/{{::balance.id}}/download?access_token={{::$ctrl.vnToken.tokenMultimedia}}"> diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index 435db3612..e26650e10 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -37,7 +37,7 @@ diff --git a/modules/invoiceOut/front/index/index.js b/modules/invoiceOut/front/index/index.js index 2cde3c940..403c51d58 100644 --- a/modules/invoiceOut/front/index/index.js +++ b/modules/invoiceOut/front/index/index.js @@ -25,7 +25,7 @@ export default class Controller extends Section { openPdf() { if (this.checked.length <= 1) { const [invoiceOutId] = this.checked; - const url = `api/InvoiceOuts/${invoiceOutId}/download?access_token=${this.vnToken.token}`; + const url = `api/InvoiceOuts/${invoiceOutId}/download?access_token=${this.vnToken.tokenMultimedia}`; window.open(url, '_blank'); } else { const invoiceOutIds = this.checked; diff --git a/modules/route/front/index/index.js b/modules/route/front/index/index.js index 7c19a26cd..0c5dfe7f3 100644 --- a/modules/route/front/index/index.js +++ b/modules/route/front/index/index.js @@ -40,7 +40,7 @@ export default class Controller extends Section { const stringRoutesIds = routesIds.join(','); if (this.checked.length <= 1) { - const url = `api/Routes/${stringRoutesIds}/driver-route-pdf?access_token=${this.vnToken.token}`; + const url = `api/Routes/${stringRoutesIds}/driver-route-pdf?access_token=${this.vnToken.tokenMultimedia}`; window.open(url, '_blank'); } else { const serializedParams = this.$httpParamSerializer({ From 04086e37eeffe433d0ed26a85d7c78ab8eb80330 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 26 Feb 2024 06:57:17 +0100 Subject: [PATCH 10/62] refs #6930 feat: add accessScopes: ['read:multimedia'] forEarch method --- back/methods/dms/downloadFile.js | 3 ++- back/methods/docuware/download.js | 3 ++- back/methods/image/download.js | 3 ++- modules/claim/back/methods/claim/downloadFile.js | 3 ++- modules/invoiceOut/back/methods/invoiceOut/download.js | 3 ++- modules/invoiceOut/back/methods/invoiceOut/downloadZip.js | 3 ++- modules/item/back/methods/item-image-queue/download.js | 1 + modules/route/back/methods/route/downloadCmrsZip.js | 3 ++- modules/route/back/methods/route/downloadZip.js | 3 ++- modules/route/back/methods/route/driverRoutePdf.js | 4 +++- modules/worker/back/methods/worker-dms/downloadFile.js | 3 ++- 11 files changed, 22 insertions(+), 10 deletions(-) diff --git a/back/methods/dms/downloadFile.js b/back/methods/dms/downloadFile.js index 1b9150053..d64b15b70 100644 --- a/back/methods/dms/downloadFile.js +++ b/back/methods/dms/downloadFile.js @@ -29,7 +29,8 @@ module.exports = Self => { http: { path: `/:id/downloadFile`, verb: 'GET' - } + }, + accessScopes: ['read:multimedia'] }); Self.downloadFile = async function(ctx, id) { diff --git a/back/methods/docuware/download.js b/back/methods/docuware/download.js index a0d72ce01..a1776cde5 100644 --- a/back/methods/docuware/download.js +++ b/back/methods/docuware/download.js @@ -42,7 +42,8 @@ module.exports = Self => { http: { path: `/:id/download`, verb: 'GET' - } + }, + accessScopes: ['read:multimedia'] }); Self.download = async function(id, fileCabinet, filter) { diff --git a/back/methods/image/download.js b/back/methods/image/download.js index 2b1a4b546..201e16164 100644 --- a/back/methods/image/download.js +++ b/back/methods/image/download.js @@ -47,7 +47,8 @@ module.exports = Self => { http: { path: `/:collection/:size/:id/download`, verb: 'GET' - } + }, + accessScopes: ['read:multimedia'] }); Self.download = async function(ctx, collection, size, id) { diff --git a/modules/claim/back/methods/claim/downloadFile.js b/modules/claim/back/methods/claim/downloadFile.js index 750356b0b..61784f39e 100644 --- a/modules/claim/back/methods/claim/downloadFile.js +++ b/modules/claim/back/methods/claim/downloadFile.js @@ -32,7 +32,8 @@ module.exports = Self => { http: { path: `/:id/downloadFile`, verb: 'GET' - } + }, + accessScopes: ['read:multimedia'] }); Self.downloadFile = async function(ctx, id) { diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index 4c76f7c07..cb71121d5 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -31,7 +31,8 @@ module.exports = Self => { http: { path: '/:id/download', verb: 'GET' - } + }, + accessScopes: ['read:multimedia'] }); Self.download = async function(ctx, id, options) { diff --git a/modules/invoiceOut/back/methods/invoiceOut/downloadZip.js b/modules/invoiceOut/back/methods/invoiceOut/downloadZip.js index fe005f1ab..4f2a8aab3 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/downloadZip.js +++ b/modules/invoiceOut/back/methods/invoiceOut/downloadZip.js @@ -31,7 +31,8 @@ module.exports = Self => { http: { path: '/downloadZip', verb: 'GET' - } + }, + accessScopes: ['read:multimedia'] }); Self.downloadZip = async function(ctx, ids, options) { diff --git a/modules/item/back/methods/item-image-queue/download.js b/modules/item/back/methods/item-image-queue/download.js index eb952daa4..e1bc248ae 100644 --- a/modules/item/back/methods/item-image-queue/download.js +++ b/modules/item/back/methods/item-image-queue/download.js @@ -11,6 +11,7 @@ module.exports = Self => { path: `/download`, verb: 'POST', }, + accessScopes: ['read:multimedia'] }); Self.download = async() => { diff --git a/modules/route/back/methods/route/downloadCmrsZip.js b/modules/route/back/methods/route/downloadCmrsZip.js index 58445f6f1..43f6e9648 100644 --- a/modules/route/back/methods/route/downloadCmrsZip.js +++ b/modules/route/back/methods/route/downloadCmrsZip.js @@ -29,7 +29,8 @@ module.exports = Self => { http: { path: '/downloadCmrsZip', verb: 'GET' - } + }, + accessScopes: ['read:multimedia'] }); Self.downloadCmrsZip = async function(ctx, ids, options) { diff --git a/modules/route/back/methods/route/downloadZip.js b/modules/route/back/methods/route/downloadZip.js index 597f1d1f6..d7fc30aa3 100644 --- a/modules/route/back/methods/route/downloadZip.js +++ b/modules/route/back/methods/route/downloadZip.js @@ -29,7 +29,8 @@ module.exports = Self => { http: { path: '/downloadZip', verb: 'GET' - } + }, + accessScopes: ['read:multimedia'] }); Self.downloadZip = async function(ctx, id, options) { diff --git a/modules/route/back/methods/route/driverRoutePdf.js b/modules/route/back/methods/route/driverRoutePdf.js index f0cd75f0e..e7b4dee17 100644 --- a/modules/route/back/methods/route/driverRoutePdf.js +++ b/modules/route/back/methods/route/driverRoutePdf.js @@ -34,7 +34,9 @@ module.exports = Self => { http: { path: '/:id/driver-route-pdf', verb: 'GET' - } + }, + accessScopes: ['read:multimedia'] + }); Self.driverRoutePdf = (ctx, id) => Self.printReport(ctx, id, 'driver-route'); diff --git a/modules/worker/back/methods/worker-dms/downloadFile.js b/modules/worker/back/methods/worker-dms/downloadFile.js index cc8653e0e..08fbcf924 100644 --- a/modules/worker/back/methods/worker-dms/downloadFile.js +++ b/modules/worker/back/methods/worker-dms/downloadFile.js @@ -29,7 +29,8 @@ module.exports = Self => { http: { path: `/:id/downloadFile`, verb: 'GET' - } + }, + accessScopes: ['read:multimedia'] }); Self.downloadFile = async function(ctx, id) { From 96abdd46306fff648a4515e852616b6b7f6a96de Mon Sep 17 00:00:00 2001 From: sergiodt Date: Mon, 26 Feb 2024 12:52:34 +0100 Subject: [PATCH 11/62] refs #6078 feat:add workeractivity --- back/model-config.json | 13 +- back/models/workerActivity.json | 33 + back/models/workerActivityType.json | 19 + db/versions/10905-grayIvy/00-firstScript.sql | 41 ++ loopback/locale/es.json | 695 ++++++++++--------- modules/worker/back/models/department.json | 7 +- 6 files changed, 455 insertions(+), 353 deletions(-) create mode 100644 back/models/workerActivity.json create mode 100644 back/models/workerActivityType.json create mode 100644 db/versions/10905-grayIvy/00-firstScript.sql diff --git a/back/model-config.json b/back/model-config.json index 27a94498c..02c1c8c7f 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -16,7 +16,7 @@ "Bank": { "dataSource": "vn" }, - "Buyer": { + "Buyer": { "dataSource": "vn" }, "Campaign": { @@ -159,8 +159,11 @@ }, "VnRole": { "dataSource": "vn" + }, + "WorkerActivity": { + "dataSource": "vn" + }, + "WorkerActivityType": { + "dataSource": "vn" } -} - - - +} \ No newline at end of file diff --git a/back/models/workerActivity.json b/back/models/workerActivity.json new file mode 100644 index 000000000..34f375586 --- /dev/null +++ b/back/models/workerActivity.json @@ -0,0 +1,33 @@ +{ + "name": "WorkerActivity", + "base": "VnModel", + "options": { + "mysql": { + "table": "workerActivity" + } + }, + "properties": { + "id": { + "id": true, + "type": "number" + }, + "workerActivityTypeFk": { + "type": "string" + }, + "created": { + "type": "date" + }, + "relations": { + "workerFk": { + "type": "belongsTo", + "model": "Worker", + "foreignKey": "workerFk" + }, + "workerActivityTypeFk": { + "type": "belongsTo", + "model": "WorkerActivityType", + "foreignKey": "workerActivityTypeFk" + } + } + } +} \ No newline at end of file diff --git a/back/models/workerActivityType.json b/back/models/workerActivityType.json new file mode 100644 index 000000000..f010363a7 --- /dev/null +++ b/back/models/workerActivityType.json @@ -0,0 +1,19 @@ +{ + "name": "WorkerActivityType", + "base": "VnModel", + "options": { + "mysql": { + "table": "workerActivityType" + } + }, + "properties": { + "code": { + "id": true, + "type": "string" + }, + "description": { + "type": "string", + "required": false + } + } +} \ No newline at end of file diff --git a/db/versions/10905-grayIvy/00-firstScript.sql b/db/versions/10905-grayIvy/00-firstScript.sql new file mode 100644 index 000000000..a85efd836 --- /dev/null +++ b/db/versions/10905-grayIvy/00-firstScript.sql @@ -0,0 +1,41 @@ +CREATE OR REPLACE TABLE `workerActivityType` ( + `code` varchar(20) NOT NULL, + `description` varchar(45) NOT NULL, + PRIMARY KEY (`code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + + +CREATE OR REPLACE TABLE `workerActivity` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `workerFk` int(10) unsigned NOT NULL, + `workerActivityTypeFk` varchar(20) NOT NULL, + `created` datetime NOT NULL DEFAULT current_timestamp(), + PRIMARY KEY (`id`), + KEY `workerActivity_worker_FK` (`workerFk`), + KEY `workerActivity_workerActivityType_FK` (`workerActivityTypeFk`), + CONSTRAINT `workerActivity_workerActivityType_FK` FOREIGN KEY (`workerActivityTypeFk`) REFERENCES `workerActivityType` (`code`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `workerActivity_worker_FK` FOREIGN KEY (`workerFk`) REFERENCES `worker` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Registros actividades por los trabajadores'; + +-- vn.workerMistakeType definition + + +ALTER TABLE vn.department ADD workerActivityTypeFk varchar(20) NULL COMMENT 'Indica la actitividad que desempeña por defecto ese departamento'; +ALTER TABLE vn.department ADD CONSTRAINT department_workerActivityType_FK FOREIGN KEY (workerActivityTypeFk) REFERENCES vn.workerActivityType(code) ON DELETE CASCADE ON UPDATE CASCADE; + + + +INSERT INTO vn.workerActivityType (code, description) VALUES('ON_CHECKING', 'REVISION'); +INSERT INTO vn.workerActivityType (code, description) VALUES('PREVIOUS_CAM', 'CAMARA'); +INSERT INTO vn.workerActivityType (code, description) VALUES('PREVIOUS_ART', 'ARTIFICIAL'); +INSERT INTO vn.workerActivityType (code, description) VALUES('ON_PREPARATION', 'SACADO'); +INSERT INTO vn.workerActivityType (code, description) VALUES('PACKING', 'ENCAJADO'); +INSERT INTO vn.workerActivityType (code, description) VALUES('FIELD', 'CAMPOS'); +INSERT INTO vn.workerActivityType (code, description) VALUES('DELIVERY', 'REPARTO'); +INSERT INTO vn.workerActivityType (code, description) VALUES('STORAGE', 'ALMACENAJE'); +INSERT INTO vn.workerActivityType (code, description) VALUES('PALLETIZING', 'PALETIZADO'); +INSERT INTO vn.workerActivityType (code, description) VALUES('STOP', 'PARADA'); + + +INSERT INTO salix.ACL ( model, property, accessType, permission, principalType, principalId) VALUES('WorkerActivityType', '*', 'READ', 'ALLOW', 'ROLE', 'production'); +INSERT INTO salix.ACL ( model, property, accessType, permission, principalType, principalId) VALUES('WorkerActivity', '*', '*', 'ALLOW', 'ROLE', 'production'); \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index aea0c311c..d2663df13 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -1,348 +1,349 @@ { - "Phone format is invalid": "El formato del teléfono no es correcto", - "You are not allowed to change the credit": "No tienes privilegios para modificar el crédito", - "Unable to mark the equivalence surcharge": "No se puede marcar el recargo de equivalencia", - "The default consignee can not be unchecked": "No se puede desmarcar el consignatario predeterminado", - "Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado", - "Can't be blank": "No puede estar en blanco", - "Invalid TIN": "NIF/CIF inválido", - "TIN must be unique": "El NIF/CIF debe ser único", - "A client with that Web User name already exists": "Ya existe un cliente con ese Usuario Web", - "Is invalid": "Es inválido", - "Quantity cannot be zero": "La cantidad no puede ser cero", - "Enter an integer different to zero": "Introduce un entero distinto de cero", - "Package cannot be blank": "El embalaje no puede estar en blanco", - "The company name must be unique": "La razón social debe ser única", - "Invalid email": "Correo electrónico inválido", - "The IBAN does not have the correct format": "El IBAN no tiene el formato correcto", - "That payment method requires an IBAN": "El método de pago seleccionado requiere un IBAN", - "That payment method requires a BIC": "El método de pago seleccionado requiere un BIC", - "State cannot be blank": "El estado no puede estar en blanco", - "Worker cannot be blank": "El trabajador no puede estar en blanco", - "Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado", - "can't be blank": "El campo no puede estar vacío", - "Observation type must be unique": "El tipo de observación no puede repetirse", - "The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero", - "The grade must be similar to the last one": "El grade debe ser similar al último", - "Only manager can change the credit": "Solo el gerente puede cambiar el credito de este cliente", - "Name cannot be blank": "El nombre no puede estar en blanco", - "Phone cannot be blank": "El teléfono no puede estar en blanco", - "Period cannot be blank": "El periodo no puede estar en blanco", - "Choose a company": "Selecciona una empresa", - "Se debe rellenar el campo de texto": "Se debe rellenar el campo de texto", - "Description should have maximum of 45 characters": "La descripción debe tener maximo 45 caracteres", - "Cannot be blank": "El campo no puede estar en blanco", - "The grade must be an integer greater than or equal to zero": "El grade debe ser un entero mayor o igual a cero", - "Sample type cannot be blank": "El tipo de plantilla no puede quedar en blanco", - "Description cannot be blank": "Se debe rellenar el campo de texto", - "The price of the item changed": "El precio del artículo cambió", - "The value should not be greater than 100%": "El valor no debe de ser mayor de 100%", - "The value should be a number": "El valor debe ser un numero", - "This order is not editable": "Esta orden no se puede modificar", - "You can't create an order for a frozen client": "No puedes crear una orden para un cliente congelado", - "You can't create an order for a client that has a debt": "No puedes crear una orden para un cliente con deuda", - "is not a valid date": "No es una fecha valida", - "Barcode must be unique": "El código de barras debe ser único", - "The warehouse can't be repeated": "El almacén no puede repetirse", - "The tag or priority can't be repeated for an item": "El tag o prioridad no puede repetirse para un item", - "The observation type can't be repeated": "El tipo de observación no puede repetirse", - "A claim with that sale already exists": "Ya existe una reclamación para esta línea", - "You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo", - "Warehouse cannot be blank": "El almacén no puede quedar en blanco", - "Agency cannot be blank": "La agencia no puede quedar en blanco", - "Not enough privileges to edit a client with verified data": "No tienes permisos para hacer cambios en un cliente con datos comprobados", - "This address doesn't exist": "Este consignatario no existe", - "You must delete the claim id %d first": "Antes debes borrar la reclamación %d", - "You don't have enough privileges": "No tienes suficientes permisos", - "Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF", - "You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos básicos de una orden con artículos", - "INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no está permitido el uso de la letra ñ", - "You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado", - "You can't create a ticket for an inactive client": "No puedes crear un ticket para un cliente inactivo", - "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", - "ORDER_EMPTY": "Cesta vacía", - "You don't have enough privileges to do that": "No tienes permisos para cambiar esto", - "NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT", - "Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido", - "Street cannot be empty": "Dirección no puede estar en blanco", - "City cannot be empty": "Ciudad no puede estar en blanco", - "Code cannot be blank": "Código no puede estar en blanco", - "You cannot remove this department": "No puedes eliminar este departamento", - "The extension must be unique": "La extensión debe ser unica", - "The secret can't be blank": "La contraseña no puede estar en blanco", - "We weren't able to send this SMS": "No hemos podido enviar el SMS", - "This client can't be invoiced": "Este cliente no puede ser facturado", - "You must provide the correction information to generate a corrective invoice": "Debes informar la información de corrección para generar una factura rectificativa", - "This ticket can't be invoiced": "Este ticket no puede ser facturado", - "You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado", - "This ticket can not be modified": "Este ticket no puede ser modificado", - "The introduced hour already exists": "Esta hora ya ha sido introducida", - "INFINITE_LOOP": "Existe una dependencia entre dos Jefes", - "The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas", - "NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros", - "ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado", - "The current ticket can't be modified": "El ticket actual no puede ser modificado", - "The current claim can't be modified": "La reclamación actual no puede ser modificada", - "The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", - "The sales do not exists": "La(s) línea(s) seleccionada(s) no existe(n)", - "Please select at least one sale": "Por favor selecciona al menos una linea", - "All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket", - "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", - "This item doesn't exists": "El artículo no existe", - "NOT_ZONE_WITH_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", - "Extension format is invalid": "El formato de la extensión es inválido", - "Invalid parameters to create a new ticket": "Parámetros inválidos para crear un nuevo ticket", - "This item is not available": "Este artículo no está disponible", - "This postcode already exists": "Este código postal ya existe", - "Concept cannot be blank": "El concepto no puede quedar en blanco", - "File doesn't exists": "El archivo no existe", - "You don't have privileges to change the zone": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias", - "This ticket is already on weekly tickets": "Este ticket ya está en tickets programados", - "Ticket id cannot be blank": "El id de ticket no puede quedar en blanco", - "Weekday cannot be blank": "El día de la semana no puede quedar en blanco", - "You can't delete a confirmed order": "No puedes borrar un pedido confirmado", - "The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto", - "Invalid quantity": "Cantidad invalida", - "This postal code is not valid": "Este código postal no es válido", - "is invalid": "es inválido", - "The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto", - "The department name can't be repeated": "El nombre del departamento no puede repetirse", - "This phone already exists": "Este teléfono ya existe", - "You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos", - "You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado", - "You cannot delete a ticket that part of it is being prepared": "No puedes eliminar un ticket en el que una parte que está siendo preparada", - "You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero", - "You should specify a date": "Debes especificar una fecha", - "You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fin", - "Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fin", - "You should mark at least one week day": "Debes marcar al menos un día de la semana", - "Swift / BIC can't be empty": "Swift / BIC no puede estar vacío", - "Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios", - "Incoterms is required for a non UEE member": "El incoterms es requerido para los clientes extracomunitarios", - "Deleted sales from ticket": "He eliminado las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{deletions}}}", - "Added sale to ticket": "He añadido la siguiente linea al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}", - "Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})", - "Changed sale quantity": "He cambiado la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* del ticket [{{ticketId}}]({{{ticketUrl}}})", - "State": "Estado", - "regular": "normal", - "reserved": "reservado", - "Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})", - "Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}", - "MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*", - "Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})", - "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})", - "Change quantity": "{{concept}} cambia de {{oldQuantity}} a {{newQuantity}}", - "Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*", - "Claim state has changed to": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *{{newState}}*", - "Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}", - "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", - "Distance must be lesser than 4000": "La distancia debe ser inferior a 4000", - "This ticket is deleted": "Este ticket está eliminado", - "Unable to clone this travel": "No ha sido posible clonar este travel", - "This thermograph id already exists": "La id del termógrafo ya existe", - "Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante", - "ORDER_ALREADY_CONFIRMED": "ORDEN YA CONFIRMADA", - "Invalid password": "Invalid password", - "Password does not meet requirements": "La contraseña no cumple los requisitos", - "Role already assigned": "Rol ya asignado", - "Invalid role name": "Nombre de rol no válido", - "Role name must be written in camelCase": "El nombre del rol debe escribirse en camelCase", - "Email already exists": "El correo ya existe", - "User already exists": "El/La usuario/a ya existe", - "Absence change notification on the labour calendar": "Notificación de cambio de ausencia en el calendario laboral", - "Record of hours week": "Registro de horas semana {{week}} año {{year}} ", - "Created absence": "El empleado {{author}} ha añadido una ausencia de tipo '{{absenceType}}' a {{employee}} para el día {{dated}}.", - "Deleted absence": "El empleado {{author}} ha eliminado una ausencia de tipo '{{absenceType}}' a {{employee}} del día {{dated}}.", - "I have deleted the ticket id": "He eliminado el ticket id [{{id}}]({{{url}}})", - "I have restored the ticket id": "He restaurado el ticket id [{{id}}]({{{url}}})", - "You can only restore a ticket within the first hour after deletion": "Únicamente puedes restaurar el ticket dentro de la primera hora después de su eliminación", - "Changed this data from the ticket": "He cambiado estos datos del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "agencyModeFk": "Agencia", - "clientFk": "Cliente", - "zoneFk": "Zona", - "warehouseFk": "Almacén", - "shipped": "F. envío", - "landed": "F. entrega", - "addressFk": "Consignatario", - "companyFk": "Empresa", - "The social name cannot be empty": "La razón social no puede quedar en blanco", - "The nif cannot be empty": "El NIF no puede quedar en blanco", - "You need to fill sage information before you check verified data": "Debes rellenar la información de sage antes de marcar datos comprobados", - "ASSIGN_ZONE_FIRST": "Asigna una zona primero", - "Amount cannot be zero": "El importe no puede ser cero", - "Company has to be official": "Empresa inválida", - "You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria", - "Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas", - "The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta", - "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*", - "New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*", - "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", - "This BIC already exist.": "Este BIC ya existe.", - "That item doesn't exists": "Ese artículo no existe", - "There's a new urgent ticket:": "Hay un nuevo ticket urgente:", - "Invalid account": "Cuenta inválida", - "Compensation account is empty": "La cuenta para compensar está vacia", - "This genus already exist": "Este genus ya existe", - "This specie already exist": "Esta especie ya existe", - "Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})", - "None": "Ninguno", - "The contract was not active during the selected date": "El contrato no estaba activo durante la fecha seleccionada", - "Cannot add more than one '1/2 day vacation'": "No puedes añadir más de un 'Vacaciones 1/2 dia'", - "This document already exists on this ticket": "Este documento ya existe en el ticket", - "Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables", - "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", - "nickname": "nickname", - "INACTIVE_PROVIDER": "Proveedor inactivo", - "This client is not invoiceable": "Este cliente no es facturable", - "serial non editable": "Esta serie no permite asignar la referencia", - "Max shipped required": "La fecha límite es requerida", - "Can't invoice to future": "No se puede facturar a futuro", - "Can't invoice to past": "No se puede facturar a pasado", - "This ticket is already invoiced": "Este ticket ya está facturado", - "A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero", - "A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa", - "Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes", - "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes", - "Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio", - "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito", - "You can't change the credit set to zero from a financialBoss": "No puedes cambiar el cŕedito establecido a cero por un jefe de finanzas", - "Amounts do not match": "Las cantidades no coinciden", - "The PDF document does not exist": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'", - "The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos", - "You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días", - "The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día", - "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", - "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", - "The account size must be exactly 10 characters": "El tamaño de la cuenta debe ser exactamente de 10 caracteres", - "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", - "You don't have privileges to create refund": "No tienes permisos para crear un abono", - "The item is required": "El artículo es requerido", - "The agency is already assigned to another autonomous": "La agencia ya está asignada a otro autónomo", - "date in the future": "Fecha en el futuro", - "reference duplicated": "Referencia duplicada", - "This ticket is already a refund": "Este ticket ya es un abono", - "isWithoutNegatives": "Sin negativos", - "routeFk": "routeFk", - "Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador", - "No hay un contrato en vigor": "No hay un contrato en vigor", - "No se permite fichar a futuro": "No se permite fichar a futuro", - "No está permitido trabajar": "No está permitido trabajar", - "Fichadas impares": "Fichadas impares", - "Descanso diario 12h.": "Descanso diario 12h.", - "Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.", - "Dirección incorrecta": "Dirección incorrecta", - "Modifiable user details only by an administrator": "Detalles de usuario modificables solo por un administrador", - "Modifiable password only via recovery or by an administrator": "Contraseña modificable solo a través de la recuperación o por un administrador", - "Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente", - "This route does not exists": "Esta ruta no existe", - "Claim pickup order sent": "Reclamación Orden de recogida enviada [{{claimId}}]({{{claimUrl}}}) al cliente *{{clientName}}*", - "You don't have grant privilege": "No tienes privilegios para dar privilegios", - "You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario", - "Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) fusionado con [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})", - "Already has this status": "Ya tiene este estado", - "There aren't records for this week": "No existen registros para esta semana", - "Empty data source": "Origen de datos vacio", - "App locked": "Aplicación bloqueada por el usuario {{userId}}", - "Email verify": "Correo de verificación", - "Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment", - "Receipt's bank was not found": "No se encontró el banco del recibo", - "This receipt was not compensated": "Este recibo no ha sido compensado", - "Client's email was not found": "No se encontró el email del cliente", - "Negative basis": "Base negativa", - "This worker code already exists": "Este codigo de trabajador ya existe", - "This personal mail already exists": "Este correo personal ya existe", - "This worker already exists": "Este trabajador ya existe", - "App name does not exist": "El nombre de aplicación no es válido", - "Try again": "Vuelve a intentarlo", - "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9", - "Failed to upload delivery note": "Error al subir albarán {{id}}", - "The DOCUWARE PDF document does not exists": "El documento PDF Docuware no existe", - "It is not possible to modify tracked sales": "No es posible modificar líneas de pedido que se hayan empezado a preparar", - "It is not possible to modify sales that their articles are from Floramondo": "No es posible modificar líneas de pedido cuyos artículos sean de Floramondo", - "It is not possible to modify cloned sales": "No es posible modificar líneas de pedido clonadas", - "A supplier with the same name already exists. Change the country.": "Un proveedor con el mismo nombre ya existe. Cambie el país.", - "There is no assigned email for this client": "No hay correo asignado para este cliente", - "Exists an invoice with a future date": "Existe una factura con fecha posterior", - "Invoice date can't be less than max date": "La fecha de factura no puede ser inferior a la fecha límite", - "Warehouse inventory not set": "El almacén inventario no está establecido", - "This locker has already been assigned": "Esta taquilla ya ha sido asignada", - "Tickets with associated refunds": "No se pueden borrar tickets con abonos asociados. Este ticket está asociado al abono Nº %d", - "Not exist this branch": "La rama no existe", - "This ticket cannot be signed because it has not been boxed": "Este ticket no puede firmarse porque no ha sido encajado", - "Collection does not exist": "La colección no existe", - "Cannot obtain exclusive lock": "No se puede obtener un bloqueo exclusivo", - "Insert a date range": "Inserte un rango de fechas", - "Added observation": "{{user}} añadió esta observacion: {{text}}", - "Comment added to client": "Observación añadida al cliente {{clientFk}}", - "Invalid auth code": "Código de verificación incorrecto", - "Invalid or expired verification code": "Código de verificación incorrecto o expirado", - "Cannot create a new claimBeginning from a different ticket": "No se puede crear una línea de reclamación de un ticket diferente al origen", - "company": "Compañía", - "country": "País", - "clientId": "Id cliente", - "clientSocialName": "Cliente", - "amount": "Importe", - "taxableBase": "Base", - "ticketFk": "Id ticket", - "isActive": "Activo", - "hasToInvoice": "Facturar", - "isTaxDataChecked": "Datos comprobados", - "comercialId": "Id comercial", - "comercialName": "Comercial", - "Pass expired": "La contraseña ha caducado, cambiela desde Salix", - "Invalid NIF for VIES": "Invalid NIF for VIES", - "Ticket does not exist": "Este ticket no existe", - "Ticket is already signed": "Este ticket ya ha sido firmado", - "Authentication failed": "Autenticación fallida", - "You can't use the same password": "No puedes usar la misma contraseña", - "You can only add negative amounts in refund tickets": "Solo se puede añadir cantidades negativas en tickets abono", - "Fecha fuera de rango": "Fecha fuera de rango", - "Error while generating PDF": "Error al generar PDF", - "Error when sending mail to client": "Error al enviar el correo al cliente", - "Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico", - "The renew period has not been exceeded": "El periodo de renovación no ha sido superado", - "Valid priorities": "Prioridades válidas: %d", - "hasAnyNegativeBase": "Base negativa para los tickets: {{ticketsIds}}", - "hasAnyPositiveBase": "Base positivas para los tickets: {{ticketsIds}}", - "You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado", - "This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s", - "The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias", - "You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado", - "This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado", - "You don't have enough privileges.": "No tienes suficientes permisos.", - "This ticket is locked": "Este ticket está bloqueado.", - "This ticket is not editable.": "Este ticket no es editable.", - "The ticket doesn't exist.": "No existe el ticket.", - "Social name should be uppercase": "La razón social debe ir en mayúscula", - "Street should be uppercase": "La dirección fiscal debe ir en mayúscula", - "Ticket without Route": "Ticket sin ruta", - "Select a different client": "Seleccione un cliente distinto", - "Fill all the fields": "Rellene todos los campos", - "The response is not a PDF": "La respuesta no es un PDF", - "Booking completed": "Reserva completada", - "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", - "Incoterms data for consignee is missing": "Faltan los datos de los Incoterms para el consignatario", - "The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada", - "User disabled": "Usuario desactivado", - "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", - "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", - "Cannot past travels with entries": "No se pueden pasar envíos con entradas", - "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", - "This claim has been updated": "La reclamación con Id: {{claimId}}, ha sido actualizada", - "This user does not have an assigned tablet": "Este usuario no tiene tablet asignada", - "Incorrect pin": "Pin incorrecto", - "You already have the mailAlias": "Ya tienes este alias de correo", - "The alias cant be modified": "Este alias de correo no puede ser modificado", - "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", - "You cannot update these fields": "No puedes actualizar estos campos", - "CountryFK cannot be empty": "El país no puede estar vacío", - "Cmr file does not exist": "El archivo del cmr no existe", - "You are not allowed to modify the alias": "No estás autorizado a modificar el alias", - "No tickets to invoice": "No hay tickets para facturar" -} + "Phone format is invalid": "El formato del teléfono no es correcto", + "You are not allowed to change the credit": "No tienes privilegios para modificar el crédito", + "Unable to mark the equivalence surcharge": "No se puede marcar el recargo de equivalencia", + "The default consignee can not be unchecked": "No se puede desmarcar el consignatario predeterminado", + "Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado", + "Can't be blank": "No puede estar en blanco", + "Invalid TIN": "NIF/CIF inválido", + "TIN must be unique": "El NIF/CIF debe ser único", + "A client with that Web User name already exists": "Ya existe un cliente con ese Usuario Web", + "Is invalid": "Es inválido", + "Quantity cannot be zero": "La cantidad no puede ser cero", + "Enter an integer different to zero": "Introduce un entero distinto de cero", + "Package cannot be blank": "El embalaje no puede estar en blanco", + "The company name must be unique": "La razón social debe ser única", + "Invalid email": "Correo electrónico inválido", + "The IBAN does not have the correct format": "El IBAN no tiene el formato correcto", + "That payment method requires an IBAN": "El método de pago seleccionado requiere un IBAN", + "That payment method requires a BIC": "El método de pago seleccionado requiere un BIC", + "State cannot be blank": "El estado no puede estar en blanco", + "Worker cannot be blank": "El trabajador no puede estar en blanco", + "Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado", + "can't be blank": "El campo no puede estar vacío", + "Observation type must be unique": "El tipo de observación no puede repetirse", + "The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero", + "The grade must be similar to the last one": "El grade debe ser similar al último", + "Only manager can change the credit": "Solo el gerente puede cambiar el credito de este cliente", + "Name cannot be blank": "El nombre no puede estar en blanco", + "Phone cannot be blank": "El teléfono no puede estar en blanco", + "Period cannot be blank": "El periodo no puede estar en blanco", + "Choose a company": "Selecciona una empresa", + "Se debe rellenar el campo de texto": "Se debe rellenar el campo de texto", + "Description should have maximum of 45 characters": "La descripción debe tener maximo 45 caracteres", + "Cannot be blank": "El campo no puede estar en blanco", + "The grade must be an integer greater than or equal to zero": "El grade debe ser un entero mayor o igual a cero", + "Sample type cannot be blank": "El tipo de plantilla no puede quedar en blanco", + "Description cannot be blank": "Se debe rellenar el campo de texto", + "The price of the item changed": "El precio del artículo cambió", + "The value should not be greater than 100%": "El valor no debe de ser mayor de 100%", + "The value should be a number": "El valor debe ser un numero", + "This order is not editable": "Esta orden no se puede modificar", + "You can't create an order for a frozen client": "No puedes crear una orden para un cliente congelado", + "You can't create an order for a client that has a debt": "No puedes crear una orden para un cliente con deuda", + "is not a valid date": "No es una fecha valida", + "Barcode must be unique": "El código de barras debe ser único", + "The warehouse can't be repeated": "El almacén no puede repetirse", + "The tag or priority can't be repeated for an item": "El tag o prioridad no puede repetirse para un item", + "The observation type can't be repeated": "El tipo de observación no puede repetirse", + "A claim with that sale already exists": "Ya existe una reclamación para esta línea", + "You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo", + "Warehouse cannot be blank": "El almacén no puede quedar en blanco", + "Agency cannot be blank": "La agencia no puede quedar en blanco", + "Not enough privileges to edit a client with verified data": "No tienes permisos para hacer cambios en un cliente con datos comprobados", + "This address doesn't exist": "Este consignatario no existe", + "You must delete the claim id %d first": "Antes debes borrar la reclamación %d", + "You don't have enough privileges": "No tienes suficientes permisos", + "Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF", + "You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos básicos de una orden con artículos", + "INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no está permitido el uso de la letra ñ", + "You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado", + "You can't create a ticket for an inactive client": "No puedes crear un ticket para un cliente inactivo", + "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", + "ORDER_EMPTY": "Cesta vacía", + "You don't have enough privileges to do that": "No tienes permisos para cambiar esto", + "NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT", + "Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido", + "Street cannot be empty": "Dirección no puede estar en blanco", + "City cannot be empty": "Ciudad no puede estar en blanco", + "Code cannot be blank": "Código no puede estar en blanco", + "You cannot remove this department": "No puedes eliminar este departamento", + "The extension must be unique": "La extensión debe ser unica", + "The secret can't be blank": "La contraseña no puede estar en blanco", + "We weren't able to send this SMS": "No hemos podido enviar el SMS", + "This client can't be invoiced": "Este cliente no puede ser facturado", + "You must provide the correction information to generate a corrective invoice": "Debes informar la información de corrección para generar una factura rectificativa", + "This ticket can't be invoiced": "Este ticket no puede ser facturado", + "You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado", + "This ticket can not be modified": "Este ticket no puede ser modificado", + "The introduced hour already exists": "Esta hora ya ha sido introducida", + "INFINITE_LOOP": "Existe una dependencia entre dos Jefes", + "The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas", + "NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros", + "ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado", + "The current ticket can't be modified": "El ticket actual no puede ser modificado", + "The current claim can't be modified": "La reclamación actual no puede ser modificada", + "The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", + "The sales do not exists": "La(s) línea(s) seleccionada(s) no existe(n)", + "Please select at least one sale": "Por favor selecciona al menos una linea", + "All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket", + "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", + "This item doesn't exists": "El artículo no existe", + "NOT_ZONE_WITH_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", + "Extension format is invalid": "El formato de la extensión es inválido", + "Invalid parameters to create a new ticket": "Parámetros inválidos para crear un nuevo ticket", + "This item is not available": "Este artículo no está disponible", + "This postcode already exists": "Este código postal ya existe", + "Concept cannot be blank": "El concepto no puede quedar en blanco", + "File doesn't exists": "El archivo no existe", + "You don't have privileges to change the zone": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias", + "This ticket is already on weekly tickets": "Este ticket ya está en tickets programados", + "Ticket id cannot be blank": "El id de ticket no puede quedar en blanco", + "Weekday cannot be blank": "El día de la semana no puede quedar en blanco", + "You can't delete a confirmed order": "No puedes borrar un pedido confirmado", + "The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto", + "Invalid quantity": "Cantidad invalida", + "This postal code is not valid": "Este código postal no es válido", + "is invalid": "es inválido", + "The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto", + "The department name can't be repeated": "El nombre del departamento no puede repetirse", + "This phone already exists": "Este teléfono ya existe", + "You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos", + "You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado", + "You cannot delete a ticket that part of it is being prepared": "No puedes eliminar un ticket en el que una parte que está siendo preparada", + "You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero", + "You should specify a date": "Debes especificar una fecha", + "You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fin", + "Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fin", + "You should mark at least one week day": "Debes marcar al menos un día de la semana", + "Swift / BIC can't be empty": "Swift / BIC no puede estar vacío", + "Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios", + "Incoterms is required for a non UEE member": "El incoterms es requerido para los clientes extracomunitarios", + "Deleted sales from ticket": "He eliminado las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{deletions}}}", + "Added sale to ticket": "He añadido la siguiente linea al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}", + "Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})", + "Changed sale quantity": "He cambiado la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* del ticket [{{ticketId}}]({{{ticketUrl}}})", + "State": "Estado", + "regular": "normal", + "reserved": "reservado", + "Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})", + "Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}", + "MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*", + "Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})", + "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})", + "Change quantity": "{{concept}} cambia de {{oldQuantity}} a {{newQuantity}}", + "Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*", + "Claim state has changed to": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *{{newState}}*", + "Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}", + "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", + "Distance must be lesser than 4000": "La distancia debe ser inferior a 4000", + "This ticket is deleted": "Este ticket está eliminado", + "Unable to clone this travel": "No ha sido posible clonar este travel", + "This thermograph id already exists": "La id del termógrafo ya existe", + "Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante", + "ORDER_ALREADY_CONFIRMED": "ORDEN YA CONFIRMADA", + "Invalid password": "Invalid password", + "Password does not meet requirements": "La contraseña no cumple los requisitos", + "Role already assigned": "Rol ya asignado", + "Invalid role name": "Nombre de rol no válido", + "Role name must be written in camelCase": "El nombre del rol debe escribirse en camelCase", + "Email already exists": "El correo ya existe", + "User already exists": "El/La usuario/a ya existe", + "Absence change notification on the labour calendar": "Notificación de cambio de ausencia en el calendario laboral", + "Record of hours week": "Registro de horas semana {{week}} año {{year}} ", + "Created absence": "El empleado {{author}} ha añadido una ausencia de tipo '{{absenceType}}' a {{employee}} para el día {{dated}}.", + "Deleted absence": "El empleado {{author}} ha eliminado una ausencia de tipo '{{absenceType}}' a {{employee}} del día {{dated}}.", + "I have deleted the ticket id": "He eliminado el ticket id [{{id}}]({{{url}}})", + "I have restored the ticket id": "He restaurado el ticket id [{{id}}]({{{url}}})", + "You can only restore a ticket within the first hour after deletion": "Únicamente puedes restaurar el ticket dentro de la primera hora después de su eliminación", + "Changed this data from the ticket": "He cambiado estos datos del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "agencyModeFk": "Agencia", + "clientFk": "Cliente", + "zoneFk": "Zona", + "warehouseFk": "Almacén", + "shipped": "F. envío", + "landed": "F. entrega", + "addressFk": "Consignatario", + "companyFk": "Empresa", + "The social name cannot be empty": "La razón social no puede quedar en blanco", + "The nif cannot be empty": "El NIF no puede quedar en blanco", + "You need to fill sage information before you check verified data": "Debes rellenar la información de sage antes de marcar datos comprobados", + "ASSIGN_ZONE_FIRST": "Asigna una zona primero", + "Amount cannot be zero": "El importe no puede ser cero", + "Company has to be official": "Empresa inválida", + "You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria", + "Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas", + "The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta", + "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*", + "New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*", + "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", + "This BIC already exist.": "Este BIC ya existe.", + "That item doesn't exists": "Ese artículo no existe", + "There's a new urgent ticket:": "Hay un nuevo ticket urgente:", + "Invalid account": "Cuenta inválida", + "Compensation account is empty": "La cuenta para compensar está vacia", + "This genus already exist": "Este genus ya existe", + "This specie already exist": "Esta especie ya existe", + "Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})", + "None": "Ninguno", + "The contract was not active during the selected date": "El contrato no estaba activo durante la fecha seleccionada", + "Cannot add more than one '1/2 day vacation'": "No puedes añadir más de un 'Vacaciones 1/2 dia'", + "This document already exists on this ticket": "Este documento ya existe en el ticket", + "Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables", + "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", + "nickname": "nickname", + "INACTIVE_PROVIDER": "Proveedor inactivo", + "This client is not invoiceable": "Este cliente no es facturable", + "serial non editable": "Esta serie no permite asignar la referencia", + "Max shipped required": "La fecha límite es requerida", + "Can't invoice to future": "No se puede facturar a futuro", + "Can't invoice to past": "No se puede facturar a pasado", + "This ticket is already invoiced": "Este ticket ya está facturado", + "A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero", + "A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa", + "Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes", + "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes", + "Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio", + "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito", + "You can't change the credit set to zero from a financialBoss": "No puedes cambiar el cŕedito establecido a cero por un jefe de finanzas", + "Amounts do not match": "Las cantidades no coinciden", + "The PDF document does not exist": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'", + "The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos", + "You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días", + "The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día", + "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", + "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", + "The account size must be exactly 10 characters": "El tamaño de la cuenta debe ser exactamente de 10 caracteres", + "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", + "You don't have privileges to create refund": "No tienes permisos para crear un abono", + "The item is required": "El artículo es requerido", + "The agency is already assigned to another autonomous": "La agencia ya está asignada a otro autónomo", + "date in the future": "Fecha en el futuro", + "reference duplicated": "Referencia duplicada", + "This ticket is already a refund": "Este ticket ya es un abono", + "isWithoutNegatives": "Sin negativos", + "routeFk": "routeFk", + "Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador", + "No hay un contrato en vigor": "No hay un contrato en vigor", + "No se permite fichar a futuro": "No se permite fichar a futuro", + "No está permitido trabajar": "No está permitido trabajar", + "Fichadas impares": "Fichadas impares", + "Descanso diario 12h.": "Descanso diario 12h.", + "Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.", + "Dirección incorrecta": "Dirección incorrecta", + "Modifiable user details only by an administrator": "Detalles de usuario modificables solo por un administrador", + "Modifiable password only via recovery or by an administrator": "Contraseña modificable solo a través de la recuperación o por un administrador", + "Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente", + "This route does not exists": "Esta ruta no existe", + "Claim pickup order sent": "Reclamación Orden de recogida enviada [{{claimId}}]({{{claimUrl}}}) al cliente *{{clientName}}*", + "You don't have grant privilege": "No tienes privilegios para dar privilegios", + "You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario", + "Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) fusionado con [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})", + "Already has this status": "Ya tiene este estado", + "There aren't records for this week": "No existen registros para esta semana", + "Empty data source": "Origen de datos vacio", + "App locked": "Aplicación bloqueada por el usuario {{userId}}", + "Email verify": "Correo de verificación", + "Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment", + "Receipt's bank was not found": "No se encontró el banco del recibo", + "This receipt was not compensated": "Este recibo no ha sido compensado", + "Client's email was not found": "No se encontró el email del cliente", + "Negative basis": "Base negativa", + "This worker code already exists": "Este codigo de trabajador ya existe", + "This personal mail already exists": "Este correo personal ya existe", + "This worker already exists": "Este trabajador ya existe", + "App name does not exist": "El nombre de aplicación no es válido", + "Try again": "Vuelve a intentarlo", + "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9", + "Failed to upload delivery note": "Error al subir albarán {{id}}", + "The DOCUWARE PDF document does not exists": "El documento PDF Docuware no existe", + "It is not possible to modify tracked sales": "No es posible modificar líneas de pedido que se hayan empezado a preparar", + "It is not possible to modify sales that their articles are from Floramondo": "No es posible modificar líneas de pedido cuyos artículos sean de Floramondo", + "It is not possible to modify cloned sales": "No es posible modificar líneas de pedido clonadas", + "A supplier with the same name already exists. Change the country.": "Un proveedor con el mismo nombre ya existe. Cambie el país.", + "There is no assigned email for this client": "No hay correo asignado para este cliente", + "Exists an invoice with a future date": "Existe una factura con fecha posterior", + "Invoice date can't be less than max date": "La fecha de factura no puede ser inferior a la fecha límite", + "Warehouse inventory not set": "El almacén inventario no está establecido", + "This locker has already been assigned": "Esta taquilla ya ha sido asignada", + "Tickets with associated refunds": "No se pueden borrar tickets con abonos asociados. Este ticket está asociado al abono Nº %d", + "Not exist this branch": "La rama no existe", + "This ticket cannot be signed because it has not been boxed": "Este ticket no puede firmarse porque no ha sido encajado", + "Collection does not exist": "La colección no existe", + "Cannot obtain exclusive lock": "No se puede obtener un bloqueo exclusivo", + "Insert a date range": "Inserte un rango de fechas", + "Added observation": "{{user}} añadió esta observacion: {{text}}", + "Comment added to client": "Observación añadida al cliente {{clientFk}}", + "Invalid auth code": "Código de verificación incorrecto", + "Invalid or expired verification code": "Código de verificación incorrecto o expirado", + "Cannot create a new claimBeginning from a different ticket": "No se puede crear una línea de reclamación de un ticket diferente al origen", + "company": "Compañía", + "country": "País", + "clientId": "Id cliente", + "clientSocialName": "Cliente", + "amount": "Importe", + "taxableBase": "Base", + "ticketFk": "Id ticket", + "isActive": "Activo", + "hasToInvoice": "Facturar", + "isTaxDataChecked": "Datos comprobados", + "comercialId": "Id comercial", + "comercialName": "Comercial", + "Pass expired": "La contraseña ha caducado, cambiela desde Salix", + "Invalid NIF for VIES": "Invalid NIF for VIES", + "Ticket does not exist": "Este ticket no existe", + "Ticket is already signed": "Este ticket ya ha sido firmado", + "Authentication failed": "Autenticación fallida", + "You can't use the same password": "No puedes usar la misma contraseña", + "You can only add negative amounts in refund tickets": "Solo se puede añadir cantidades negativas en tickets abono", + "Fecha fuera de rango": "Fecha fuera de rango", + "Error while generating PDF": "Error al generar PDF", + "Error when sending mail to client": "Error al enviar el correo al cliente", + "Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico", + "The renew period has not been exceeded": "El periodo de renovación no ha sido superado", + "Valid priorities": "Prioridades válidas: %d", + "hasAnyNegativeBase": "Base negativa para los tickets: {{ticketsIds}}", + "hasAnyPositiveBase": "Base positivas para los tickets: {{ticketsIds}}", + "You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado", + "This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s", + "The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias", + "You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado", + "This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado", + "You don't have enough privileges.": "No tienes suficientes permisos.", + "This ticket is locked": "Este ticket está bloqueado.", + "This ticket is not editable.": "Este ticket no es editable.", + "The ticket doesn't exist.": "No existe el ticket.", + "Social name should be uppercase": "La razón social debe ir en mayúscula", + "Street should be uppercase": "La dirección fiscal debe ir en mayúscula", + "Ticket without Route": "Ticket sin ruta", + "Select a different client": "Seleccione un cliente distinto", + "Fill all the fields": "Rellene todos los campos", + "The response is not a PDF": "La respuesta no es un PDF", + "Booking completed": "Reserva completada", + "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", + "Incoterms data for consignee is missing": "Faltan los datos de los Incoterms para el consignatario", + "The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada", + "User disabled": "Usuario desactivado", + "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", + "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", + "Cannot past travels with entries": "No se pueden pasar envíos con entradas", + "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", + "This claim has been updated": "La reclamación con Id: {{claimId}}, ha sido actualizada", + "This user does not have an assigned tablet": "Este usuario no tiene tablet asignada", + "Incorrect pin": "Pin incorrecto", + "You already have the mailAlias": "Ya tienes este alias de correo", + "The alias cant be modified": "Este alias de correo no puede ser modificado", + "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", + "You cannot update these fields": "No puedes actualizar estos campos", + "CountryFK cannot be empty": "El país no puede estar vacío", + "Cmr file does not exist": "El archivo del cmr no existe", + "You are not allowed to modify the alias": "No estás autorizado a modificar el alias", + "No tickets to invoice": "No hay tickets para facturar", + "parkingNotExist": "parkingNotExist" +} \ No newline at end of file diff --git a/modules/worker/back/models/department.json b/modules/worker/back/models/department.json index edeba74f7..0245a7486 100644 --- a/modules/worker/back/models/department.json +++ b/modules/worker/back/models/department.json @@ -62,6 +62,11 @@ "type": "belongsTo", "model": "Worker", "foreignKey": "workerFk" + }, + "workerActivity": { + "type": "belongsTo", + "model": "Worker", + "foreignKey": "workerActivityTypeFk" } } -} +} \ No newline at end of file From f2ad06918692e3a1474f10660d8ea31e720d224d Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 27 Feb 2024 14:26:54 +0100 Subject: [PATCH 12/62] refs 6930 feat: get multimediaToken from new method --- back/methods/vn-user/share-token.js | 27 ++ .../methods/vn-user/specs/share-token.spec.js | 27 ++ back/models/vn-user.js | 7 +- back/models/vn-user.json | 247 +++++++++--------- front/core/services/auth.js | 21 +- 5 files changed, 197 insertions(+), 132 deletions(-) create mode 100644 back/methods/vn-user/share-token.js create mode 100644 back/methods/vn-user/specs/share-token.spec.js diff --git a/back/methods/vn-user/share-token.js b/back/methods/vn-user/share-token.js new file mode 100644 index 000000000..8efa22db4 --- /dev/null +++ b/back/methods/vn-user/share-token.js @@ -0,0 +1,27 @@ + +module.exports = Self => { + Self.remoteMethodCtx('shareToken', { + description: 'Returns token to view files or images and share it', + accessType: 'WRITE', + accepts: [], + returns: { + type: 'Object', + root: true + }, + http: { + path: `/shareToken`, + verb: 'GET' + } + }); + + Self.shareToken = async function(ctx) { + const {accessToken: token} = ctx.req; + + const user = await Self.findById(token.userId); + const multimediaToken = await user.accessTokens.create({ + scopes: ['read:multimedia'] + }); + + return {multimediaToken}; + }; +}; diff --git a/back/methods/vn-user/specs/share-token.spec.js b/back/methods/vn-user/specs/share-token.spec.js new file mode 100644 index 000000000..4d113f10a --- /dev/null +++ b/back/methods/vn-user/specs/share-token.spec.js @@ -0,0 +1,27 @@ +const {models} = require('vn-loopback/server/server'); +fdescribe('Share Token', () => { + let ctx = null; + beforeAll(async() => { + const unAuthCtx = { + req: { + headers: {}, + connection: { + remoteAddress: '127.0.0.1' + }, + getLocale: () => 'en' + }, + args: {} + }; + let login = await models.VnUser.signIn(unAuthCtx, 'salesAssistant', 'nightmare'); + let accessToken = await models.AccessToken.findById(login.token); + ctx = {req: {accessToken: accessToken}}; + }); + + it('should renew token', async() => { + const multimediaToken = await models.VnUser.shareToken(ctx); + + expect(Object.keys(multimediaToken).length).toEqual(1); + expect(multimediaToken.multimediaToken.userId).toEqual(ctx.req.accessToken.userId); + expect(multimediaToken.multimediaToken.scopes[0]).toEqual('read:multimedia'); + }); +}); diff --git a/back/models/vn-user.js b/back/models/vn-user.js index e1bce7c06..b59f13ffa 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -13,6 +13,7 @@ module.exports = function(Self) { require('../methods/vn-user/privileges')(Self); require('../methods/vn-user/validate-auth')(Self); require('../methods/vn-user/renew-token')(Self); + require('../methods/vn-user/share-token')(Self); require('../methods/vn-user/update-user')(Self); Self.definition.settings.acls = Self.definition.settings.acls.filter(acl => acl.property !== 'create'); @@ -167,11 +168,7 @@ module.exports = function(Self) { console.warn(err); } - const multimediaToken = await token.user().accessTokens.create({ - scopes: ['read:multimedia'] - }); - - return {token: token.id, ttl: token.ttl, multimediaToken}; + return {token: token.id, ttl: token.ttl}; }; Self.userUses = function(user) { diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 639603643..5f6ac3f47 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -1,129 +1,140 @@ { - "name": "VnUser", - "base": "User", - "validateUpsert": true, - "options": { - "mysql": { - "table": "account.user" - } - }, + "name": "VnUser", + "base": "User", + "validateUpsert": true, + "options": { + "mysql": { + "table": "account.user" + } + }, "mixins": { "Loggable": true }, "resetPasswordTokenTTL": "604800", - "properties": { - "id": { - "type": "number", - "id": true - }, + "properties": { + "id": { + "type": "number", + "id": true + }, "name": { - "type": "string", - "required": true - }, - "username": { - "type": "string" - }, - "roleFk": { - "type": "number", - "mysql": { - "columnName": "role" - } - }, - "nickname": { - "type": "string" - }, - "lang": { - "type": "string" - }, - "active": { - "type": "boolean" - }, - "email": { - "type": "string" - }, - "emailVerified": { - "type": "boolean" - }, - "created": { - "type": "date" - }, - "updated": { - "type": "date" - }, - "image": { - "type": "string" - }, - "hasGrant": { - "type": "boolean" - }, + "type": "string", + "required": true + }, + "username": { + "type": "string" + }, + "roleFk": { + "type": "number", + "mysql": { + "columnName": "role" + } + }, + "nickname": { + "type": "string" + }, + "lang": { + "type": "string" + }, + "active": { + "type": "boolean" + }, + "email": { + "type": "string" + }, + "emailVerified": { + "type": "boolean" + }, + "created": { + "type": "date" + }, + "updated": { + "type": "date" + }, + "image": { + "type": "string" + }, + "hasGrant": { + "type": "boolean" + }, "passExpired": { "type": "date" }, - "twoFactor": { - "type": "string" - } - }, - "relations": { - "role": { - "type": "belongsTo", - "model": "VnRole", - "foreignKey": "roleFk" - }, - "roles": { - "type": "hasMany", - "model": "RoleRole", - "foreignKey": "role", - "primaryKey": "roleFk" - }, - "emailUser": { - "type": "hasOne", - "model": "EmailUser", - "foreignKey": "userFk" - }, - "worker": { - "type": "hasOne", - "model": "Worker", - "foreignKey": "id" - }, - "userConfig": { - "type": "hasOne", - "model": "UserConfig", - "foreignKey": "userFk" - } - }, - "acls": [ - { - "property": "signIn", - "accessType": "EXECUTE", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - }, { - "property": "recoverPassword", - "accessType": "EXECUTE", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - }, { - "property": "validateAuth", - "accessType": "EXECUTE", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - }, { - "property": "privileges", - "accessType": "*", - "principalType": "ROLE", - "principalId": "$authenticated", - "permission": "ALLOW" - }, { - "property": "renewToken", - "accessType": "WRITE", - "principalType": "ROLE", - "principalId": "$authenticated", - "permission": "ALLOW" - } - ], + "twoFactor": { + "type": "string" + } + }, + "relations": { + "role": { + "type": "belongsTo", + "model": "VnRole", + "foreignKey": "roleFk" + }, + "roles": { + "type": "hasMany", + "model": "RoleRole", + "foreignKey": "role", + "primaryKey": "roleFk" + }, + "emailUser": { + "type": "hasOne", + "model": "EmailUser", + "foreignKey": "userFk" + }, + "worker": { + "type": "hasOne", + "model": "Worker", + "foreignKey": "id" + }, + "userConfig": { + "type": "hasOne", + "model": "UserConfig", + "foreignKey": "userFk" + } + }, + "acls": [ + { + "property": "signIn", + "accessType": "EXECUTE", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }, + { + "property": "recoverPassword", + "accessType": "EXECUTE", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }, + { + "property": "validateAuth", + "accessType": "EXECUTE", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }, + { + "property": "privileges", + "accessType": "*", + "principalType": "ROLE", + "principalId": "$authenticated", + "permission": "ALLOW" + }, + { + "property": "renewToken", + "accessType": "WRITE", + "principalType": "ROLE", + "principalId": "$authenticated", + "permission": "ALLOW" + }, + { + "property": "shareToken", + "accessType": "WRITE", + "principalType": "ROLE", + "principalId": "$authenticated", + "permission": "ALLOW" + } + ], "scopes": { "preview": { "fields": [ @@ -140,7 +151,7 @@ "hasGrant", "realm", "email", - "emailVerified" + "emailVerified" ] } } diff --git a/front/core/services/auth.js b/front/core/services/auth.js index 0253eb3c3..a734e076e 100644 --- a/front/core/services/auth.js +++ b/front/core/services/auth.js @@ -83,15 +83,18 @@ export default class Auth { } onLoginOk(json, now, remember) { - this.vnToken.set(json.data.token, json.data.multimediaToken.id, now, json.data.ttl, remember); - - return this.loadAcls().then(() => { - let continueHash = this.$state.params.continue; - if (continueHash) - this.$window.location = continueHash; - else - this.$state.go('home'); - }); + return this.$http.get('VnUsers/ShareToken', { + headers: {Authorization: json.data.token} + }).then(({data}) => { + this.vnToken.set(json.data.token, data.multimediaToken.id, now, json.data.ttl, remember); + this.loadAcls().then(() => { + let continueHash = this.$state.params.continue; + if (continueHash) + this.$window.location = continueHash; + else + this.$state.go('home'); + }); + }).catch(() => {}); } logout() { From fdc5ea244f93b9cfb62d98b964fc45e33d11ef04 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 28 Feb 2024 10:43:07 +0100 Subject: [PATCH 13/62] refs 6930 feat: implements logout in front side --- front/core/services/auth.js | 23 +++++++++++++---------- front/core/services/interceptor.js | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/front/core/services/auth.js b/front/core/services/auth.js index a734e076e..e51a2ff12 100644 --- a/front/core/services/auth.js +++ b/front/core/services/auth.js @@ -98,17 +98,20 @@ export default class Auth { } logout() { - let promise = this.$http.post('VnUsers/logout', null, { - headers: {Authorization: this.vnToken.token} - }).catch(() => {}); + this.$http.post('VnUsers/logoutMultimedia', null, {headers: {'Authorization': this.vnToken.tokenMultimedia}, + }).then(({data}) => { + if (data) { + this.$http.post('VnUsers/logout', null, { + headers: {Authorization: this.vnToken.token} + }).catch(() => {}); - this.vnToken.unset(); - this.loggedIn = false; - this.vnModules.reset(); - this.aclService.reset(); - this.$state.go('login'); - - return promise; + this.vnToken.unset(); + this.loggedIn = false; + this.vnModules.reset(); + this.aclService.reset(); + this.$state.go('login'); + } + }); } loadAcls() { diff --git a/front/core/services/interceptor.js b/front/core/services/interceptor.js index 0c3253c69..90d813ed4 100644 --- a/front/core/services/interceptor.js +++ b/front/core/services/interceptor.js @@ -19,7 +19,7 @@ function interceptor($q, vnApp, $translate) { if (config.url.charAt(0) !== '/' && apiPath) config.url = `${apiPath}${config.url}`; - if (token) + if (token && !config.headers.Authorization) config.headers.Authorization = token; if ($translate.use()) config.headers['Accept-Language'] = $translate.use(); From 23b3fb81f9989480f9146fe8b937726950db3697 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 28 Feb 2024 10:43:19 +0100 Subject: [PATCH 14/62] refs 6930 feat: implements logout remoteMethod --- back/models/vn-user.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index b59f13ffa..473e619db 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -31,6 +31,32 @@ module.exports = function(Self) { message: `A client with that Web User name already exists` }); + Self.remoteMethod('logoutMultimedia', { + description: 'Logout current MultimediaToken', + accepts: [{ + arg: 'ctx', + type: 'Object', + http: {source: 'context'} + }], + returns: { + type: 'Boolean', + root: true + }, + http: { + verb: 'POST', + path: '/logoutMultimedia' + }, + accessScopes: ['read:multimedia'] + }); + Self.logoutMultimedia = async function(ctx) { + let {accessToken} = ctx.req; + try { + Self.logout(accessToken.id); + return true; + } catch (error) { + return error; + } + }; Self.remoteMethod('getCurrentUserData', { description: 'Gets the current user data', accepts: [ From a06a59341250eb18ce7aae81ee1459e10cab8998 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 28 Feb 2024 10:55:36 +0100 Subject: [PATCH 15/62] refs 6930 feat: ACL --- db/versions/10919-brownMoss/00-firstScript.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 db/versions/10919-brownMoss/00-firstScript.sql diff --git a/db/versions/10919-brownMoss/00-firstScript.sql b/db/versions/10919-brownMoss/00-firstScript.sql new file mode 100644 index 000000000..da10027e0 --- /dev/null +++ b/db/versions/10919-brownMoss/00-firstScript.sql @@ -0,0 +1,4 @@ +-- Place your SQL code here + +INSERT IGNORE INTO `salix`.`ACL`(`model`,`property`,`accessType`,`permission`, `principalType`, `principalId`) +VALUES(VnUser,logoutMultimedia,*,ALLOW,ROLE,employee) From 1d1d950e4b543d02604bca6db5afbaeb2cce0f34 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 28 Feb 2024 11:57:00 +0100 Subject: [PATCH 16/62] refs 6930 feat: ACL --- db/versions/10919-brownMoss/00-firstScript.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/versions/10919-brownMoss/00-firstScript.sql b/db/versions/10919-brownMoss/00-firstScript.sql index da10027e0..a6abdbe79 100644 --- a/db/versions/10919-brownMoss/00-firstScript.sql +++ b/db/versions/10919-brownMoss/00-firstScript.sql @@ -1,4 +1,5 @@ -- Place your SQL code here INSERT IGNORE INTO `salix`.`ACL`(`model`,`property`,`accessType`,`permission`, `principalType`, `principalId`) -VALUES(VnUser,logoutMultimedia,*,ALLOW,ROLE,employee) +VALUES +('VnUser','logoutMultimedia','*','ALLOW','ROLE','employee') From 5ee9c2b01ef4d5f2d2b43ae23b7bd66524dbe286 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 29 Feb 2024 07:40:20 +0100 Subject: [PATCH 17/62] refs #6930 fix: revert fdescribe --- back/methods/vn-user/specs/share-token.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/methods/vn-user/specs/share-token.spec.js b/back/methods/vn-user/specs/share-token.spec.js index 4d113f10a..aaa83817c 100644 --- a/back/methods/vn-user/specs/share-token.spec.js +++ b/back/methods/vn-user/specs/share-token.spec.js @@ -1,5 +1,5 @@ const {models} = require('vn-loopback/server/server'); -fdescribe('Share Token', () => { +describe('Share Token', () => { let ctx = null; beforeAll(async() => { const unAuthCtx = { From c79bdeb3f4bfc3379222552c605b7d2f5ccdc302 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 29 Feb 2024 13:41:27 +0100 Subject: [PATCH 18/62] fix: refs #6744 drop to set emailVerified --- modules/account/back/models/account.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/account/back/models/account.js b/modules/account/back/models/account.js index dd04182f6..ceb26053c 100644 --- a/modules/account/back/models/account.js +++ b/modules/account/back/models/account.js @@ -12,10 +12,9 @@ module.exports = Self => { require('../methods/account/set-password')(Self); Self.setUnverifiedPassword = async(id, pass, options) => { - const user = await models.VnUser.findById(id, null, options); - if (user.emailVerified) throw new ForbiddenError('This password can only be changed by the user themselves'); + const {emailVerified} = await models.VnUser.findById(id, {fields: ['emailVerified']}, options); + if (emailVerified) throw new ForbiddenError('This password can only be changed by the user themselves'); await models.VnUser.setPassword(id, pass, options); - await user.updateAttribute('emailVerified', true, options); }; }; From 893320b1149fb33d73355b2895167b17cde5203c Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 4 Mar 2024 15:00:43 +0100 Subject: [PATCH 19/62] refs #6755 model ticketlog, restore --- modules/ticket/back/methods/ticket/restore.js | 5 +++ modules/ticket/back/models/ticket-log.json | 37 ++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index e268c3891..49e6c4389 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -37,6 +37,11 @@ module.exports = Self => { } }] }, myOptions); + const lastUpdatedTicket = await models.ticketLog.findById(id, { + include: [{ + + }] + }); const now = Date.vnNew(); const maxDate = new Date(ticket.updated); diff --git a/modules/ticket/back/models/ticket-log.json b/modules/ticket/back/models/ticket-log.json index d5d1e5520..ac912856b 100644 --- a/modules/ticket/back/models/ticket-log.json +++ b/modules/ticket/back/models/ticket-log.json @@ -5,5 +5,40 @@ "mysql": { "table": "ticketLog" } - } + }, + "properties": { + "id": { + "type": "string" + }, + "originFk": { + "type": "number" + }, + "userFk": { + "type":"number" + }, + "action": { + "type": "string" + }, + "creationDate": { + "type": "date" + }, + "description": { + "type": "string" + }, + "changeModel": { + "type": "string" + }, + "oldInstance": { + "type": "string" + }, + "newInstance": { + "type": "string" + }, + "changedModelId": { + "type": "number" + }, + "changedModelValue": { + "type": "string" + } + } } From cac388f986d28fd737c854bccc7a7eff4c5d86d9 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 5 Mar 2024 09:43:07 +0100 Subject: [PATCH 20/62] refs #6755 fix ticket --- modules/ticket/back/methods/ticket/restore.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 49e6c4389..8ba005b93 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -30,18 +30,8 @@ module.exports = Self => { Object.assign(myOptions, options); const ticket = await models.Ticket.findById(id, { - include: [{ - relation: 'client', - scope: { - fields: ['id', 'salesPersonFk'] - } - }] + fields: ['originFk', 'creationDate', 'newInstance'] }, myOptions); - const lastUpdatedTicket = await models.ticketLog.findById(id, { - include: [{ - - }] - }); const now = Date.vnNew(); const maxDate = new Date(ticket.updated); From 16fc446b852fb8b3903a28e25f3098f4679d4b2f Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 5 Mar 2024 10:46:15 +0100 Subject: [PATCH 21/62] refs #6755 fix method --- modules/ticket/back/methods/ticket/restore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 8ba005b93..c92f8767e 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -29,7 +29,7 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - const ticket = await models.Ticket.findById(id, { + const ticket = await models.TicketLog.findById(id, { fields: ['originFk', 'creationDate', 'newInstance'] }, myOptions); From cf181521d66f82c6a9e62e8be439ec4aaecb922c Mon Sep 17 00:00:00 2001 From: sergiodt Date: Tue, 5 Mar 2024 11:53:57 +0100 Subject: [PATCH 22/62] refs #6078 feat:add workeractivity --- back/models/workerActivity.json | 12 ++++++--- db/versions/10905-grayIvy/00-firstScript.sql | 27 ++++++++------------ 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/back/models/workerActivity.json b/back/models/workerActivity.json index 34f375586..e3b994f77 100644 --- a/back/models/workerActivity.json +++ b/back/models/workerActivity.json @@ -11,12 +11,18 @@ "id": true, "type": "number" }, - "workerActivityTypeFk": { - "type": "string" - }, "created": { "type": "date" }, + "model": { + "type": "string" + }, + "event": { + "type": "string" + }, + "description": { + "type": "string" + }, "relations": { "workerFk": { "type": "belongsTo", diff --git a/db/versions/10905-grayIvy/00-firstScript.sql b/db/versions/10905-grayIvy/00-firstScript.sql index a85efd836..a7c3c4c17 100644 --- a/db/versions/10905-grayIvy/00-firstScript.sql +++ b/db/versions/10905-grayIvy/00-firstScript.sql @@ -4,22 +4,6 @@ CREATE OR REPLACE TABLE `workerActivityType` ( PRIMARY KEY (`code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; - -CREATE OR REPLACE TABLE `workerActivity` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `workerFk` int(10) unsigned NOT NULL, - `workerActivityTypeFk` varchar(20) NOT NULL, - `created` datetime NOT NULL DEFAULT current_timestamp(), - PRIMARY KEY (`id`), - KEY `workerActivity_worker_FK` (`workerFk`), - KEY `workerActivity_workerActivityType_FK` (`workerActivityTypeFk`), - CONSTRAINT `workerActivity_workerActivityType_FK` FOREIGN KEY (`workerActivityTypeFk`) REFERENCES `workerActivityType` (`code`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `workerActivity_worker_FK` FOREIGN KEY (`workerFk`) REFERENCES `worker` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Registros actividades por los trabajadores'; - --- vn.workerMistakeType definition - - ALTER TABLE vn.department ADD workerActivityTypeFk varchar(20) NULL COMMENT 'Indica la actitividad que desempeña por defecto ese departamento'; ALTER TABLE vn.department ADD CONSTRAINT department_workerActivityType_FK FOREIGN KEY (workerActivityTypeFk) REFERENCES vn.workerActivityType(code) ON DELETE CASCADE ON UPDATE CASCADE; @@ -38,4 +22,13 @@ INSERT INTO vn.workerActivityType (code, description) VALUES('STOP', 'PARADA'); INSERT INTO salix.ACL ( model, property, accessType, permission, principalType, principalId) VALUES('WorkerActivityType', '*', 'READ', 'ALLOW', 'ROLE', 'production'); -INSERT INTO salix.ACL ( model, property, accessType, permission, principalType, principalId) VALUES('WorkerActivity', '*', '*', 'ALLOW', 'ROLE', 'production'); \ No newline at end of file +INSERT INTO salix.ACL ( model, property, accessType, permission, principalType, principalId) VALUES('WorkerActivity', '*', '*', 'ALLOW', 'ROLE', 'production'); + + +ALTER TABLE vn.workerActivity MODIFY COLUMN event enum('open','close','insert','delete','update','refresh') CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL; +ALTER TABLE vn.workerActivity MODIFY COLUMN model enum('COM','ENT','TPV','ENC','LAB','ETI','APP') CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL; + + +ALTER TABLE vn.workerActivity ADD workerActivityTypeFk varchar(20) NULL; +ALTER TABLE vn.workerActivity ADD CONSTRAINT workerActivity_workerActivityType_FK FOREIGN KEY (workerActivityTypeFk) REFERENCES vn.workerActivityType(code) ON DELETE CASCADE ON UPDATE CASCADE; + From 70096e7a762c6c928654ba98626a728e5dfe0b63 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 5 Mar 2024 14:24:32 +0100 Subject: [PATCH 23/62] refs #6755 fix restore --- modules/ticket/back/methods/ticket/restore.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index c92f8767e..c85efb1c8 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -33,12 +33,15 @@ module.exports = Self => { fields: ['originFk', 'creationDate', 'newInstance'] }, myOptions); + console.log('ticket', ticket); const now = Date.vnNew(); - const maxDate = new Date(ticket.updated); + const maxDate = new Date(ticket.creationDate); maxDate.setHours(maxDate.getHours() + 1); - if (now > maxDate) - throw new UserError(`You can only restore a ticket within the first hour after deletion`); + if (ticket.newInstance.includes('isDeleted: true')) { + if (now > maxDate) + throw new UserError(`You can only restore a ticket within the first hour after deletion`); + } // Send notification to salesPerson const salesPersonId = ticket.client().salesPersonFk; From 1b3a8ddbdde53982a4231820ff3017d397d03a37 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 6 Mar 2024 12:03:35 +0100 Subject: [PATCH 24/62] refs #6755 fix restore --- modules/ticket/back/methods/ticket/restore.js | 16 ++++++++++------ modules/ticket/back/models/ticket-log.json | 2 +- modules/ticket/front/descriptor-menu/index.js | 15 ++++++++++----- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index c85efb1c8..754c2e562 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -29,19 +29,23 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - const ticket = await models.TicketLog.findById(id, { - fields: ['originFk', 'creationDate', 'newInstance'] + const ticket = await models.TicketLog.findOne({ + fields: ['originFk', 'creationDate', 'newInstance'], + where: { + originFk: id, + newInstance: {like: '%"isDeleted":true%'} + }, + order: 'creationDate DESC' }, myOptions); + console.log('id', id); console.log('ticket', ticket); const now = Date.vnNew(); const maxDate = new Date(ticket.creationDate); maxDate.setHours(maxDate.getHours() + 1); - if (ticket.newInstance.includes('isDeleted: true')) { - if (now > maxDate) - throw new UserError(`You can only restore a ticket within the first hour after deletion`); - } + if (now > maxDate) + throw new UserError(`You can only restore a ticket within the first hour after deletion`); // Send notification to salesPerson const salesPersonId = ticket.client().salesPersonFk; diff --git a/modules/ticket/back/models/ticket-log.json b/modules/ticket/back/models/ticket-log.json index ac912856b..e46995a91 100644 --- a/modules/ticket/back/models/ticket-log.json +++ b/modules/ticket/back/models/ticket-log.json @@ -25,7 +25,7 @@ "description": { "type": "string" }, - "changeModel": { + "changedModel": { "type": "string" }, "oldInstance": { diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index e71913267..a73fed500 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -172,12 +172,17 @@ class Controller extends Section { } get canRestoreTicket() { - const isDeleted = this.ticket.isDeleted; - const now = Date.vnNew(); - const maxDate = new Date(this.ticket.updated); - maxDate.setHours(maxDate.getHours() + 1); + // const isDeleted = this.ticket.isDeleted; + // const now = Date.vnNew(); + // const maxDate = new Date(this.ticket.updated); + // maxDate.setHours(maxDate.getHours() + 1); - return isDeleted && (now <= maxDate); + // return isDeleted && (now <= maxDate); + return this.$http.get(`TicketLogs`).then(res => { + if (res && res.data.length) + console.log(res.data); + return true; + }); } restoreTicket() { From 59a0cb3f4aa9e461f7143e7d8666afa22cd11161 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 6 Mar 2024 13:08:20 +0100 Subject: [PATCH 25/62] refs #6842 deprecated and move --- .../vn/triggers/invoiceOut_beforeInsert.sql | 12 ++-- db/versions/10893-limeFern/00-sage.sql | 57 ++++++++++++------- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/db/routines/vn/triggers/invoiceOut_beforeInsert.sql b/db/routines/vn/triggers/invoiceOut_beforeInsert.sql index f3a292edd..eb5c1150f 100644 --- a/db/routines/vn/triggers/invoiceOut_beforeInsert.sql +++ b/db/routines/vn/triggers/invoiceOut_beforeInsert.sql @@ -17,16 +17,16 @@ BEGIN DECLARE vRefLen INT; DECLARE vRefPrefix VARCHAR(255); DECLARE vLastRef VARCHAR(255); - DECLARE vSage200Company INT; + DECLARE vCompanyCode INT; DECLARE vYearLen INT DEFAULT 2; DECLARE vPrefixLen INT; - SELECT sage200Company INTO vSage200Company + SELECT companyCode INTO vCompanyCode FROM company WHERE id = NEW.companyFk; - IF vSage200Company IS NULL THEN - CALL util.throw('vSage200CompanyNotDefined'); + IF vCompanyCode IS NULL THEN + CALL util.throw('vCompanyCodeNotDefined'); END IF; SELECT MAX(i.ref) INTO vLastRef @@ -36,7 +36,7 @@ BEGIN AND i.companyFk = NEW.companyFk; IF vLastRef IS NOT NULL THEN - SET vPrefixLen = LENGTH(NEW.serial) + LENGTH(vSage200Company) + vYearLen; + SET vPrefixLen = LENGTH(NEW.serial) + LENGTH(vCompanyCode) + vYearLen; SET vRefLen = LENGTH(vLastRef) - vPrefixLen; SET vRefPrefix = LEFT(vLastRef, vPrefixLen); SET vRef = RIGHT(vLastRef, vRefLen); @@ -44,7 +44,7 @@ BEGIN SELECT refLen INTO vRefLen FROM invoiceOutConfig; SET vRefPrefix = CONCAT( NEW.serial, - vSage200Company, + vCompanyCode, RIGHT(YEAR(NEW.issued), vYearLen) ); END IF; diff --git a/db/versions/10893-limeFern/00-sage.sql b/db/versions/10893-limeFern/00-sage.sql index 049bb2993..9d076050e 100644 --- a/db/versions/10893-limeFern/00-sage.sql +++ b/db/versions/10893-limeFern/00-sage.sql @@ -1,35 +1,54 @@ --- Auto-generated SQL script #202402151810 +-- Auto-generated SQL script #202403061303 UPDATE vn.company - SET companyGroupFk=NULL + SET companyCode=0 WHERE id=69; UPDATE vn.company - SET companyGroupFk=NULL - WHERE id=567; -UPDATE vn.company - SET companyGroupFk=NULL + SET companyCode=0 WHERE id=791; UPDATE vn.company - SET companyGroupFk=NULL + SET companyCode=3 WHERE id=792; UPDATE vn.company - SET companyGroupFk=NULL + SET companyCode=5 WHERE id=965; UPDATE vn.company - SET companyGroupFk=NULL + SET companyCode=7 WHERE id=1381; UPDATE vn.company - SET companyGroupFk=NULL + SET companyCode=3 WHERE id=1463; UPDATE vn.company - SET companyGroupFk=NULL - WHERE id=2142; -UPDATE vn.company - SET companyGroupFk=NULL - WHERE id=2292; -UPDATE vn.company - SET companyGroupFk=NULL + SET companyCode=6 WHERE id=2393; UPDATE vn.company - SET companyGroupFk=NULL + SET companyCode=9 WHERE id=3869; -ALTER TABLE vn.company MODIFY COLUMN sage200Company int(2) DEFAULT NULL NULL COMMENT 'Campo para la serie InvoiceOut'; + +-- Auto-generated SQL script #202403061303 +UPDATE vn.company + SET companyCode=0 + WHERE id=69; +UPDATE vn.company + SET companyCode=0 + WHERE id=791; +UPDATE vn.company + SET companyCode=3 + WHERE id=792; +UPDATE vn.company + SET companyCode=5 + WHERE id=965; +UPDATE vn.company + SET companyCode=7 + WHERE id=1381; +UPDATE vn.company + SET companyCode=3 + WHERE id=1463; +UPDATE vn.company + SET companyCode=6 + WHERE id=2393; +UPDATE vn.company + SET companyCode=9 + WHERE id=3869; + +ALTER TABLE vn.company CHANGE sage200Company sage200Company__ int(2) DEFAULT NULL NULL COMMENT '@deprecated 06/03/2024'; +ALTER TABLE vn.company MODIFY COLUMN sage200Company__ int(2) DEFAULT NULL NULL COMMENT '@deprecated 06/03/2024'; From a24445439ab389ebf8054f766d81bbd1e2b1c3af Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 6 Mar 2024 13:09:03 +0100 Subject: [PATCH 26/62] remove v --- db/routines/vn/triggers/invoiceOut_beforeInsert.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/routines/vn/triggers/invoiceOut_beforeInsert.sql b/db/routines/vn/triggers/invoiceOut_beforeInsert.sql index eb5c1150f..8eb25e710 100644 --- a/db/routines/vn/triggers/invoiceOut_beforeInsert.sql +++ b/db/routines/vn/triggers/invoiceOut_beforeInsert.sql @@ -26,7 +26,7 @@ BEGIN WHERE id = NEW.companyFk; IF vCompanyCode IS NULL THEN - CALL util.throw('vCompanyCodeNotDefined'); + CALL util.throw('CompanyCodeNotDefined'); END IF; SELECT MAX(i.ref) INTO vLastRef From 6a13a33f840b550c72b6dfd34fe4f6bd9ec12d0a Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 6 Mar 2024 13:09:41 +0100 Subject: [PATCH 27/62] min c --- db/routines/vn/triggers/invoiceOut_beforeInsert.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/routines/vn/triggers/invoiceOut_beforeInsert.sql b/db/routines/vn/triggers/invoiceOut_beforeInsert.sql index 8eb25e710..0081c8803 100644 --- a/db/routines/vn/triggers/invoiceOut_beforeInsert.sql +++ b/db/routines/vn/triggers/invoiceOut_beforeInsert.sql @@ -26,7 +26,7 @@ BEGIN WHERE id = NEW.companyFk; IF vCompanyCode IS NULL THEN - CALL util.throw('CompanyCodeNotDefined'); + CALL util.throw('companyCodeNotDefined'); END IF; SELECT MAX(i.ref) INTO vLastRef From 58a239708d1dca4dbd23af0f260ad03e801d8790 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 6 Mar 2024 13:11:41 +0100 Subject: [PATCH 28/62] refs #6842 remove sage --- db/versions/10893-limeFern/00-sage.sql | 28 +++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/db/versions/10893-limeFern/00-sage.sql b/db/versions/10893-limeFern/00-sage.sql index 9d076050e..01508b932 100644 --- a/db/versions/10893-limeFern/00-sage.sql +++ b/db/versions/10893-limeFern/00-sage.sql @@ -24,31 +24,41 @@ UPDATE vn.company SET companyCode=9 WHERE id=3869; --- Auto-generated SQL script #202403061303 +-- Auto-generated SQL script #202403061311 UPDATE vn.company - SET companyCode=0 + SET sage200Company=NULL WHERE id=69; UPDATE vn.company - SET companyCode=0 + SET sage200Company=NULL + WHERE id=442; +UPDATE vn.company + SET sage200Company=NULL + WHERE id=567; +UPDATE vn.company + SET sage200Company=NULL WHERE id=791; UPDATE vn.company - SET companyCode=3 + SET sage200Company=NULL WHERE id=792; UPDATE vn.company - SET companyCode=5 + SET sage200Company=NULL WHERE id=965; UPDATE vn.company - SET companyCode=7 + SET sage200Company=NULL WHERE id=1381; UPDATE vn.company - SET companyCode=3 + SET sage200Company=NULL WHERE id=1463; UPDATE vn.company - SET companyCode=6 + SET sage200Company=NULL + WHERE id=2142; +UPDATE vn.company + SET sage200Company=NULL WHERE id=2393; UPDATE vn.company - SET companyCode=9 + SET sage200Company=NULL WHERE id=3869; + ALTER TABLE vn.company CHANGE sage200Company sage200Company__ int(2) DEFAULT NULL NULL COMMENT '@deprecated 06/03/2024'; ALTER TABLE vn.company MODIFY COLUMN sage200Company__ int(2) DEFAULT NULL NULL COMMENT '@deprecated 06/03/2024'; From a14ab90d5a8ef1cb513c867ac50109c491fb68fb Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 6 Mar 2024 14:41:58 +0100 Subject: [PATCH 29/62] refs #6755 fix restore add fixtures --- db/dump/fixtures.before.sql | 7 +++++++ modules/ticket/front/descriptor-menu/index.js | 1 + 2 files changed, 8 insertions(+) diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index aef0f13e3..b8f31ac3a 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -3069,3 +3069,10 @@ INSERT INTO `vn`.`cmr` (id,truckPlate,observations,senderInstruccions,paymentIns UPDATE vn.department SET workerFk = null; + +INSERT INTO vn.ticketLog (originFk,userFk,`action`,creationDate,changedModel,newInstance,changedModelId,changedModelValue) + VALUES (9,9,'insert','2000-01-01 11:01:00.000','Ticket','{"isDeleted":true}',45,'Super Man'); + +UPDATE vn.ticket + SET isDeleted=1 + WHERE id=9; diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index a73fed500..245142a60 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -181,6 +181,7 @@ class Controller extends Section { return this.$http.get(`TicketLogs`).then(res => { if (res && res.data.length) console.log(res.data); + console.log(res); return true; }); } From 2e4a5029b8304f8a452b0033331c4313e7bc21c1 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 6 Mar 2024 14:52:49 +0100 Subject: [PATCH 30/62] refs #6755 fix restore --- modules/ticket/back/methods/ticket/restore.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 754c2e562..0d2452df9 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -38,6 +38,15 @@ module.exports = Self => { order: 'creationDate DESC' }, myOptions); + const ticketOG = await models.Ticket.findById(id, { + include: [{ + relation: 'client', + scope: { + fields: ['id', 'salesPersonFk'] + } + }] + }, myOptions); + console.log('id', id); console.log('ticket', ticket); const now = Date.vnNew(); @@ -48,7 +57,7 @@ module.exports = Self => { throw new UserError(`You can only restore a ticket within the first hour after deletion`); // Send notification to salesPerson - const salesPersonId = ticket.client().salesPersonFk; + const salesPersonId = ticketOG.client().salesPersonFk; if (salesPersonId) { const url = await Self.app.models.Url.getUrl(); const message = $t(`I have restored the ticket id`, { @@ -59,12 +68,12 @@ module.exports = Self => { } const fullYear = Date.vnNew().getFullYear(); - const newShipped = ticket.shipped; - const newLanded = ticket.landed; + const newShipped = ticketOG.shipped; + const newLanded = ticketOG.landed; newShipped.setFullYear(fullYear); newLanded.setFullYear(fullYear); - return ticket.updateAttributes({ + return ticketOG.updateAttributes({ shipped: newShipped, landed: newLanded, isDeleted: false From dd732297c4e671a6f5b3d54c097a4cdd3e87ebf7 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Thu, 7 Mar 2024 07:31:04 +0100 Subject: [PATCH 31/62] Merge branch 'dev' into 6078_workerActivty --- back/model-config.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/back/model-config.json b/back/model-config.json index 6a85fac71..8e4ef901d 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -94,6 +94,9 @@ "Module": { "dataSource": "vn" }, + "MrwConfig": { + "dataSource": "vn" + }, "Notification": { "dataSource": "vn" }, From a94fd1a61cdbacbd604b89a1a2712d4cdcae546b Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 7 Mar 2024 09:29:51 +0100 Subject: [PATCH 32/62] fix: refs #6744 change error kind --- loopback/locale/en.json | 3 ++- loopback/locale/es.json | 3 ++- modules/worker/back/methods/worker/setPassword.js | 4 ++-- modules/worker/back/methods/worker/specs/setPassword.spec.js | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 62c0afcf8..31b954a32 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -221,5 +221,6 @@ "printerNotExists": "The printer does not exist", "There are not picking tickets": "There are not picking tickets", "ticketCommercial": "The ticket {{ ticket }} for the salesperson {{ salesMan }} is in preparation. (automatically generated message)", - "This password can only be changed by the user themselves": "This password can only be changed by the user themselves" + "This password can only be changed by the user themselves": "This password can only be changed by the user themselves", + "They're not your subordinate": "They're not your subordinate" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index bf4717c97..945474726 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -348,5 +348,6 @@ "Cmr file does not exist": "El archivo del cmr no existe", "You are not allowed to modify the alias": "No estás autorizado a modificar el alias", "The address of the customer must have information about Incoterms and Customs Agent": "El consignatario del cliente debe tener informado Incoterms y Agente de aduanas", - "This password can only be changed by the user themselves": "Esta contraseña solo puede ser modificada por el propio usuario" + "This password can only be changed by the user themselves": "Esta contraseña solo puede ser modificada por el propio usuario", + "They're not your subordinate": "No es tu subordinado/a." } diff --git a/modules/worker/back/methods/worker/setPassword.js b/modules/worker/back/methods/worker/setPassword.js index e6bdfb364..9969530a4 100644 --- a/modules/worker/back/methods/worker/setPassword.js +++ b/modules/worker/back/methods/worker/setPassword.js @@ -1,4 +1,4 @@ -const UserError = require('vn-loopback/util/user-error'); +const ForbiddenError = require('vn-loopback/util/forbiddenError'); module.exports = Self => { Self.remoteMethodCtx('setPassword', { description: 'Set a new password', @@ -32,7 +32,7 @@ module.exports = Self => { } try { const isSubordinate = await Self.isSubordinate(ctx, id, myOptions); - if (!isSubordinate) throw new UserError('You don\'t have enough privileges.'); + if (!isSubordinate) throw new ForbiddenError('They\'re not your subordinate'); await models.Account.setUnverifiedPassword(id, newPass, myOptions); diff --git a/modules/worker/back/methods/worker/specs/setPassword.spec.js b/modules/worker/back/methods/worker/specs/setPassword.spec.js index 03cbee03b..8d152bdd1 100644 --- a/modules/worker/back/methods/worker/specs/setPassword.spec.js +++ b/modules/worker/back/methods/worker/specs/setPassword.spec.js @@ -54,7 +54,7 @@ describe('worker setPassword()', () => { await models.Worker.setPassword(ctx, administrativeId, newPass, options); await tx.rollback(); } catch (e) { - expect(e.message).toEqual(`You don't have enough privileges.`); + expect(e.message).toEqual(`They're not your subordinate`); await tx.rollback(); } }); From d4d3fdceb5075874f19d4a163d0bc54326c6e130 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 7 Mar 2024 11:36:30 +0100 Subject: [PATCH 33/62] refs #6755 fix canRestoreTicket --- modules/ticket/back/methods/ticket/restore.js | 2 -- .../back/methods/ticket/specs/filter.spec.js | 2 +- .../back/methods/ticket/specs/restore.spec.js | 18 ++++++++++++------ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 0d2452df9..9dde43ff9 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -47,8 +47,6 @@ module.exports = Self => { }] }, myOptions); - console.log('id', id); - console.log('ticket', ticket); const now = Date.vnNew(); const maxDate = new Date(ticket.creationDate); maxDate.setHours(maxDate.getHours() + 1); diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js index c1d3f1a9c..09c4ebbb7 100644 --- a/modules/ticket/back/methods/ticket/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js @@ -68,7 +68,7 @@ describe('ticket filter()', () => { const filter = {}; const result = await models.Ticket.filter(ctx, filter, options); - expect(result.length).toEqual(6); + expect(result.length).toEqual(5); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket/specs/restore.spec.js b/modules/ticket/back/methods/ticket/specs/restore.spec.js index 3b35ae2b4..736e68628 100644 --- a/modules/ticket/back/methods/ticket/specs/restore.spec.js +++ b/modules/ticket/back/methods/ticket/specs/restore.spec.js @@ -2,9 +2,9 @@ const app = require('vn-loopback/server/server'); const LoopBackContext = require('loopback-context'); const models = app.models; -describe('ticket restore()', () => { +fdescribe('ticket restore()', () => { const employeeUser = 1110; - const ticketId = 18; + const ticketId = 9; const activeCtx = { accessToken: {userId: employeeUser}, headers: { @@ -48,25 +48,31 @@ describe('ticket restore()', () => { const tx = await app.models.Ticket.beginTransaction({}); const now = Date.vnNew(); + console.log('now', now); try { const options = {transaction: tx}; - const ticketBeforeUpdate = await models.Ticket.findById(ticketId, null, options); + const ticketBeforeUpdate = await models.TicketLog.findById(ticketId, null, options); await ticketBeforeUpdate.updateAttributes({ - isDeleted: true, - updated: now + creationDate: '2001-01-01T11:00:00.000Z', }, options); - const ticketAfterUpdate = await models.Ticket.findById(ticketId, null, options); + console.log('ticketBeforeUpdate', ticketBeforeUpdate); + const ticketAfterUpdate = await models.TicketLog.findById(ticketId, null, options); + console.log('ticketAfterUpdate: ', ticketAfterUpdate); expect(ticketAfterUpdate.isDeleted).toBeTruthy(); await models.Ticket.restore(ctx, ticketId, options); const ticketAfterRestore = await models.Ticket.findById(ticketId, null, options); + console.log('ticketAfterRestore: ', ticketAfterRestore); const fullYear = now.getFullYear(); + console.log('fullYear: ', fullYear); const shippedFullYear = ticketAfterRestore.shipped.getFullYear(); + console.log('shippedFullYear: ', shippedFullYear); const landedFullYear = ticketAfterRestore.landed.getFullYear(); + console.log('landedFullYear: ', landedFullYear); expect(ticketAfterRestore.isDeleted).toBeFalsy(); expect(shippedFullYear).toEqual(fullYear); From 8a16c24245afac127bbf785ff9923ed8f6ebaf88 Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 8 Mar 2024 12:27:47 +0100 Subject: [PATCH 34/62] refs #6755 fix ticket --- modules/ticket/front/descriptor-menu/index.js | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index 245142a60..f60e0012c 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -8,6 +8,7 @@ class Controller extends Section { this.vnReport = vnReport; this.vnEmail = vnEmail; this.vnFile = vnFile; + this.restoreTicket = vnRestoreTicket; } get ticketId() { @@ -172,18 +173,18 @@ class Controller extends Section { } get canRestoreTicket() { - // const isDeleted = this.ticket.isDeleted; - // const now = Date.vnNew(); - // const maxDate = new Date(this.ticket.updated); - // maxDate.setHours(maxDate.getHours() + 1); + const isDeleted = this.ticket.isDeleted; + const now = Date.vnNew(); + const maxDate = new Date(this.ticket.updated); + maxDate.setHours(maxDate.getHours() + 1); - // return isDeleted && (now <= maxDate); - return this.$http.get(`TicketLogs`).then(res => { - if (res && res.data.length) - console.log(res.data); - console.log(res); - return true; - }); + return isDeleted && (now <= maxDate); + // return this.$http.get(`TicketLogs`).then(res => { + // if (res && res.data.length) + // console.log(res.data); + // console.log(res); + // return true; + // }); } restoreTicket() { From 879adfaac8db6a72e92bf607004e5f0c207d081e Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 8 Mar 2024 14:59:33 +0100 Subject: [PATCH 35/62] refs #6755 restore fix --- .../ticket/front/descriptor-menu/index.html | 1 + modules/ticket/front/descriptor-menu/index.js | 45 ++++++++++++------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/modules/ticket/front/descriptor-menu/index.html b/modules/ticket/front/descriptor-menu/index.html index cb7eeb8ee..0b9b1b2a1 100644 --- a/modules/ticket/front/descriptor-menu/index.html +++ b/modules/ticket/front/descriptor-menu/index.html @@ -86,6 +86,7 @@ translate> Delete ticket + {{$ctrl.canRestoreTicket}} { + console.log(res); + console.log(res.data.creationDate); + if (res && res.data) { + console.log(res.data); + const now = Date.vnNew(); + const maxDate = new Date(res.data.creationDate); + maxDate.setHours(maxDate.getHours() + 1); + console.log(now, maxDatenow); + console.log(now.getTime(), maxDate.getTime()); + if (now <= maxDate) + return this.canRestoreTicket = true; + } + this.canRestoreTicket = false; + }) + .catch(() => { + console.log('ENTRY'); + this.canRestoreTicket = false; + }); } get isInvoiced() { @@ -172,21 +200,6 @@ class Controller extends Section { }); } - get canRestoreTicket() { - const isDeleted = this.ticket.isDeleted; - const now = Date.vnNew(); - const maxDate = new Date(this.ticket.updated); - maxDate.setHours(maxDate.getHours() + 1); - - return isDeleted && (now <= maxDate); - // return this.$http.get(`TicketLogs`).then(res => { - // if (res && res.data.length) - // console.log(res.data); - // console.log(res); - // return true; - // }); - } - restoreTicket() { return this.$http.post(`Tickets/${this.id}/restore`) .then(() => this.reload()) From 51fa0e1a757531ddb516cf26fa33c895857a7b7a Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 11 Mar 2024 08:12:29 +0100 Subject: [PATCH 36/62] fix: refs #6925 refund invoice transaltions --- modules/invoiceOut/front/descriptor-menu/index.html | 2 +- modules/invoiceOut/front/descriptor-menu/index.js | 11 +++++++---- .../invoiceOut/front/descriptor-menu/locale/es.yml | 2 +- modules/ticket/front/descriptor-menu/locale/es.yml | 1 + 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index 435db3612..face46293 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -102,7 +102,7 @@ diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index 2c28599e7..5184c137e 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -118,11 +118,14 @@ class Controller extends Section { const query = 'InvoiceOuts/refund'; const params = {ref: this.invoiceOut.ref, withWarehouse: withWarehouse}; this.$http.post(query, params).then(res => { - const refundTicket = res.data; - this.vnApp.showSuccess(this.$t('The following refund ticket have been created', { - ticketId: refundTicket.id + const tickets = res.data; + const refundTickets = tickets.map(ticket => ticket.id); + + this.vnApp.showSuccess(this.$t('The following refund tickets have been created', { + ticketId: refundTickets.join(',') })); - this.$state.go('ticket.card.sale', {id: refundTicket.id}); + if (refundTickets.length == 1) + this.$state.go('ticket.card.sale', {id: refundTickets[0]}); }); } diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml index aaeefd9cc..9285fafa7 100644 --- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml +++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml @@ -15,7 +15,7 @@ Are you sure you want to clone this invoice?: Estas seguro de clonar esta factur InvoiceOut booked: Factura asentada Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? Are you sure you want to refund this invoice?: Estas seguro de querer abonar esta factura? -Create a single ticket with all the content of the current invoice: Crear un ticket unico con todo el contenido de la factura actual +Create a refund ticket for each ticket on the current invoice: Crear un ticket abono por cada ticket de la factura actual Regenerate PDF invoice: Regenerar PDF factura The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado The email can't be empty: El correo no puede estar vacío diff --git a/modules/ticket/front/descriptor-menu/locale/es.yml b/modules/ticket/front/descriptor-menu/locale/es.yml index 3181a753c..d0802fc4d 100644 --- a/modules/ticket/front/descriptor-menu/locale/es.yml +++ b/modules/ticket/front/descriptor-menu/locale/es.yml @@ -15,6 +15,7 @@ with warehouse: con almacén without warehouse: sin almacén Invoice sent: Factura enviada The following refund ticket have been created: "Se ha creado siguiente ticket de abono: {{ticketId}}" +The following refund tickets have been created: "Se ha creado los siguientes tickets de abono: {{ticketId}}" Transfer client: Transferir cliente Send SMS...: Enviar SMS... Notify changes: Notificar cambios From b051b0512fcb8abf63c2207cee732d641ce746c7 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 11 Mar 2024 09:48:29 +0100 Subject: [PATCH 37/62] refs #6842 fix fixtures --- db/dump/fixtures.before.sql | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 094b956af..05e183bfd 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -592,13 +592,13 @@ INSERT INTO `vn`.`supplierAccount`(`id`, `supplierFk`, `iban`, `bankEntityFk`) VALUES (241, 442, 'ES111122333344111122221111', 128); -INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`, `companyCode`, `sage200Company`, `expired`, `companyGroupFk`, `phytosanitary` , `clientFk`) +INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`, `companyCode`, `expired`, `companyGroupFk`, `phytosanitary` , `clientFk`) VALUES - (69 , 'CCs', NULL, 30, NULL, 0, NULL, 1, NULL , NULL), - (442 , 'VNL', 241, 30, 2 , 1, NULL, 2, 'VNL Company - Plant passport' , 1101), - (567 , 'VNH', NULL, 30, NULL, 4, NULL, 1, 'VNH Company - Plant passport' , NULL), - (791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', 1, NULL , NULL), - (1381, 'ORN', NULL, 30, NULL, 7, NULL, 1, 'ORN Company - Plant passport' , NULL); + (69 , 'CCs', NULL, 30, 0, NULL, 1, NULL , NULL), + (442 , 'VNL', 241, 30, 1, NULL, 2, 'VNL Company - Plant passport' , 1101), + (567 , 'VNH', NULL, 30, 4, NULL, 1, 'VNH Company - Plant passport' , NULL), + (791 , 'FTH', NULL, 30, 3, '2015-11-30', 1, NULL , NULL), + (1381, 'ORN', NULL, 30, 7, NULL, 1, 'ORN Company - Plant passport' , NULL); INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`) VALUES @@ -728,7 +728,7 @@ INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agen INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `zonePrice`, `zoneBonus`, `created`, `weight`, `cmrFk`) VALUES (1 , 3, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 121, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 1), - (2 , 1, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 1, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 2), + (2 , 1, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 1, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 2), (3 , 1, 7, 1, 6, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 3, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), NULL, 3), (4 , 3, 2, 1, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 9, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), NULL, NULL), (5 , 3, 3, 3, 3, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 10, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), NULL, NULL), From 552a1a33c27d59e91e48026e1f834fda4df35187 Mon Sep 17 00:00:00 2001 From: guillermo Date: Mon, 11 Mar 2024 12:38:52 +0100 Subject: [PATCH 38/62] hotfix: itemProposal --- db/routines/vn/procedures/itemProposal.sql | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/db/routines/vn/procedures/itemProposal.sql b/db/routines/vn/procedures/itemProposal.sql index 47a4e9779..d0d98fed7 100644 --- a/db/routines/vn/procedures/itemProposal.sql +++ b/db/routines/vn/procedures/itemProposal.sql @@ -19,17 +19,17 @@ BEGIN DECLARE vTypeFk INT; DECLARE vPriority INT DEFAULT 1; - DECLARE vTag1 VARCHAR(25) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vTag5 VARCHAR(25) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vTag6 VARCHAR(25) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vTag7 VARCHAR(25) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vTag8 VARCHAR(25) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - - DECLARE vValue1 VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vValue5 VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vValue6 VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vValue7 VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vValue8 VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; + DECLARE vTag1 VARCHAR(20) COLLATE 'utf8_unicode_ci'; + DECLARE vTag5 VARCHAR(20) COLLATE 'utf8_unicode_ci'; + DECLARE vTag6 VARCHAR(20) COLLATE 'utf8_unicode_ci'; + DECLARE vTag7 VARCHAR(20) COLLATE 'utf8_unicode_ci'; + DECLARE vTag8 VARCHAR(20) COLLATE 'utf8_unicode_ci'; + + DECLARE vValue1 VARCHAR(50) COLLATE 'utf8_unicode_ci'; + DECLARE vValue5 VARCHAR(50) COLLATE 'utf8_unicode_ci'; + DECLARE vValue6 VARCHAR(50) COLLATE 'utf8_unicode_ci'; + DECLARE vValue7 VARCHAR(50) COLLATE 'utf8_unicode_ci'; + DECLARE vValue8 VARCHAR(50) COLLATE 'utf8_unicode_ci'; SELECT warehouseFk, shipped INTO vWarehouseFk, vShipped @@ -86,7 +86,8 @@ BEGIN IF(b.groupingMode = 1, b.grouping, b.packing) minQuantity, iss.visible located FROM item i - JOIN cache.available a ON a.item_id = i.id + STRAIGHT_JOIN cache.available a ON a.item_id = i.id + AND a.calc_id = vCalcFk LEFT JOIN itemProposal ip ON ip.mateFk = i.id AND ip.itemFk = vSelf LEFT JOIN itemTag it ON it.itemFk = i.id @@ -97,8 +98,7 @@ BEGIN LEFT JOIN buy b ON b.id = lb.buy_id LEFT JOIN itemShelvingStock iss ON iss.itemFk = i.id AND iss.warehouseFk = vWarehouseFk - WHERE a.calc_id = vCalcFk - AND a.available > 0 + WHERE a.available > 0 AND IF(vShowType, i.typeFk = vTypeFk, TRUE) AND i.id <> vSelf ORDER BY `counter` DESC, From 6627c7a16a8f30b8c0219eea0ad86dc9fbaeb263 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 12 Mar 2024 08:25:01 +0100 Subject: [PATCH 39/62] refs #6913 routeKm --- modules/route/back/models/route.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/route/back/models/route.js b/modules/route/back/models/route.js index 3505609d1..bf1f26e74 100644 --- a/modules/route/back/models/route.js +++ b/modules/route/back/models/route.js @@ -30,9 +30,11 @@ module.exports = Self => { }); function validateDistance(err) { - const routeTotalKm = this.kmEnd - this.kmStart; - const routeMaxKm = 4000; - if (routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd) - err(); + if (this.kmEnd) { + const routeTotalKm = this.kmEnd - this.kmStart; + const routeMaxKm = 4000; + if (routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd) + err(); + } } }; From 1bcb61a22458e684fa8dd97de6b8de8e37f4b070 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 12 Mar 2024 08:25:58 +0100 Subject: [PATCH 40/62] refactor: refs #7018 Mirated procs to vn --- .../vn/procedures/invoiceInTaxMakeByDua.sql | 9 ++- .../vn/procedures/invoiceInTax_insert.sql | 56 +++++++++++++++++++ .../procedures/ListaTicketsEncajados.sql | 25 --------- .../procedures/customerDebtEvolution.sql | 49 ---------------- .../vn2008/procedures/preOrdenarRuta.sql | 22 -------- .../vn2008/procedures/prepare_ticket_list.sql | 22 -------- .../vn2008/procedures/recibidaIvaInsert.sql | 39 ------------- 7 files changed, 62 insertions(+), 160 deletions(-) create mode 100644 db/routines/vn/procedures/invoiceInTax_insert.sql delete mode 100644 db/routines/vn2008/procedures/ListaTicketsEncajados.sql delete mode 100644 db/routines/vn2008/procedures/customerDebtEvolution.sql delete mode 100644 db/routines/vn2008/procedures/preOrdenarRuta.sql delete mode 100644 db/routines/vn2008/procedures/prepare_ticket_list.sql delete mode 100644 db/routines/vn2008/procedures/recibidaIvaInsert.sql diff --git a/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql b/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql index 2ff478d6b..6707486d0 100644 --- a/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql +++ b/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql @@ -1,8 +1,11 @@ DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceInTaxMakeByDua`(vDuaFk INT) +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceInTaxMakeByDua`( + vDuaFk INT +) BEGIN /** - * Borra los valores de duaTax y sus vctos. y los vuelve a crear en base a la tabla duaEntry + * Borra los valores de duaTax y sus vctos. y los vuelve a + * crear en base a la tabla duaEntry. * * @param vDuaFk Id del dua a recalcular */ @@ -26,7 +29,7 @@ BEGIN LEAVE l; END IF; - CALL vn2008.recibidaIvaInsert(vInvoiceInFk); + CALL invoiceInTax_insert(vInvoiceInFk); CALL invoiceInDueDay_recalc(vInvoiceInFk); END LOOP; diff --git a/db/routines/vn/procedures/invoiceInTax_insert.sql b/db/routines/vn/procedures/invoiceInTax_insert.sql new file mode 100644 index 000000000..e43a7763d --- /dev/null +++ b/db/routines/vn/procedures/invoiceInTax_insert.sql @@ -0,0 +1,56 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceInTax_insert`( + IN vSelf INT +) +BEGIN + DECLARE vRate DOUBLE DEFAULT 1; + DECLARE vDated DATE; + DECLARE vExpenseFk INT; + + SELECT MAX(rr.dated) INTO vDated + FROM referenceRate rr + JOIN invoiceIn ii ON ii.id = vSelf + WHERE rr.dated <= ii.issued + AND rr.currencyFk = ii.currencyFk; + + IF vDated THEN + SELECT `value` INTO vRate + FROM referenceRate + WHERE dated = vDated; + END IF; + + DELETE FROM invoiceInTax WHERE invoiceInFk = vSelf; + + SELECT id INTO vExpenseFk + FROM expense + WHERE code = 'extraCommGoodsAcquisition'; + + IF vExpenseFk IS NULL THEN + CALL util.throw('Expense extraCommGoodsAcquisition not exists'); + END IF; + + INSERT INTO invoiceInTax( + invoiceInFk, + taxableBase, + expenseFk, + foreignValue, + taxTypeSageFk, + transactionTypeSageFk + ) + SELECT ii.id, + SUM(b.buyingValue * b.quantity) / vRate bi, + vExpenseFk, + IF(c.code = 'EUR', NULL, SUM(b.buyingValue * b.quantity)), + s.taxTypeSageFk, + s.transactionTypeSageFk + FROM invoiceIn ii + JOIN currency c ON c.id = ii.currencyFk + JOIN `entry` e ON e.invoiceInFk = ii.id + JOIN supplier s ON s.id = e.supplierFk + JOIN buy b ON b.entryFk = e.id + LEFT JOIN referenceRate rr ON rr.currencyFk = ii.currencyFk + AND rr.dated = ii.issued + WHERE ii.id = vSelf + HAVING bi IS NOT NULL; +END$$ +DELIMITER ; diff --git a/db/routines/vn2008/procedures/ListaTicketsEncajados.sql b/db/routines/vn2008/procedures/ListaTicketsEncajados.sql deleted file mode 100644 index ce99916ee..000000000 --- a/db/routines/vn2008/procedures/ListaTicketsEncajados.sql +++ /dev/null @@ -1,25 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`ListaTicketsEncajados`(IN intId_Trabajador int) -BEGIN - -SELECT Agencia, - Consignatario, - ti.Id_Ticket, - ts.userFk Id_Trabajador, - IFNULL(ncajas,0) AS ncajas, - IFNULL(nbultos,0) AS nbultos, - IFNULL(notros,0) AS notros, - ts.code AS Estado - FROM Tickets ti - INNER JOIN Consignatarios ON ti.Id_Consigna = Consignatarios.Id_consigna - INNER JOIN Agencias ON ti.Id_Agencia = Agencias.Id_Agencia - LEFT JOIN (SELECT ticketFk,count(*) AS ncajas FROM vn.expedition WHERE packagingFk=94 GROUP BY ticketFk) sub1 ON ti.Id_Ticket=sub1.ticketFk - LEFT JOIN (SELECT ticketFk,count(*) AS nbultos FROM vn.expedition WHERE packagingFk IS NULL GROUP BY ticketFk) sub2 ON ti.Id_Ticket=sub2.ticketFk - LEFT JOIN (SELECT ticketFk,count(*) AS notros FROM vn.expedition WHERE packagingFk >0 GROUP BY ticketFk) sub3 ON ti.Id_Ticket=sub3.ticketFk - INNER JOIN vn.ticketState ts ON ti.Id_ticket = ts.ticketFk - WHERE ti.Fecha=util.VN_CURDATE() AND - ts.userFk=intId_Trabajador - GROUP BY ti.Id_Ticket; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/customerDebtEvolution.sql b/db/routines/vn2008/procedures/customerDebtEvolution.sql deleted file mode 100644 index b9763b985..000000000 --- a/db/routines/vn2008/procedures/customerDebtEvolution.sql +++ /dev/null @@ -1,49 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`customerDebtEvolution`(IN vCustomer INT) -BEGIN - -SELECT * FROM -( - SELECT day, date, @s:= round(IFNULL(Euros,0) + @s,2) as Saldo, Euros, Credito, 0 as Cero - FROM - ( - SELECT day, date, IFNULL(Euros,0) as Euros, Credito - FROM time - JOIN (SELECT @s:= 0, - Credito as Credito FROM Clientes WHERE Id_Cliente = vCustomer) c - LEFT JOIN - (SELECT Euros, date(Fecha) as Fecha FROM - ( - SELECT Fechacobro as Fecha, Entregado as Euros - FROM Recibos - WHERE Id_Cliente = vCustomer - AND Fechacobro >= '2017-01-01' - UNION ALL - SELECT vn.getDueDate(io.issued,c.Vencimiento), - io.amount - FROM vn.invoiceOut io - JOIN Clientes c ON io.clientFk = c.Id_Cliente - WHERE io.clientFk = vCustomer - AND io.issued >= '2017-01-01' - UNION ALL - SELECT '2016-12-31', Debt - FROM bi.customerDebtInventory - WHERE Id_Cliente = vCustomer - UNION ALL - SELECT Fecha, - SUM(Cantidad * Preu * (100 - Descuento ) * 1.10 / 100) - FROM Tickets t - JOIN Movimientos m on m.Id_Ticket = t.Id_Ticket - WHERE Id_Cliente = vCustomer - AND Factura IS NULL - AND Fecha >= '2017-01-01' - GROUP BY Fecha - ) sub2 - ORDER BY Fecha - )sub ON time.date = sub.Fecha - WHERE time.date BETWEEN '2016-12-31' AND util.VN_CURDATE() - ORDER BY date - ) sub3 -)sub4 -; - - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/preOrdenarRuta.sql b/db/routines/vn2008/procedures/preOrdenarRuta.sql deleted file mode 100644 index b5fd2b24b..000000000 --- a/db/routines/vn2008/procedures/preOrdenarRuta.sql +++ /dev/null @@ -1,22 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`preOrdenarRuta`(IN vRutaId INT) -BEGIN -/* Usa los valores del ultimo año para adivinar el orden de los tickets en la ruta - * vRutaId id ruta - * DEPRECATED use vn.routeGressPriority -*/ - -UPDATE Tickets mt -JOIN ( - SELECT tt.Id_Consigna, round(ifnull(avg(t.Prioridad),0),0) as Prioridad - from Tickets t - JOIN Tickets tt on tt.Id_Consigna = t.Id_Consigna - where t.Fecha > TIMESTAMPADD(YEAR,-1,util.VN_CURDATE()) - AND tt.Id_Ruta = vRutaId - GROUP BY Id_Consigna - ) sub ON sub.Id_Consigna = mt.Id_Consigna - SET mt.Prioridad = sub.Prioridad - WHERE mt.Id_Ruta = vRutaId; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/prepare_ticket_list.sql b/db/routines/vn2008/procedures/prepare_ticket_list.sql deleted file mode 100644 index e407a91b7..000000000 --- a/db/routines/vn2008/procedures/prepare_ticket_list.sql +++ /dev/null @@ -1,22 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`prepare_ticket_list`(vStartingDate DATETIME, vEndingDate DATETIME) -BEGIN - DROP TEMPORARY TABLE IF EXISTS tmp.ticket_list; - CREATE TEMPORARY TABLE tmp.ticket_list - (PRIMARY KEY (Id_Ticket)) - ENGINE = MEMORY - SELECT t.Id_Ticket, c.Id_Cliente - FROM Tickets t - LEFT JOIN vn.ticketState ts ON ts.ticketFk = t.Id_Ticket - JOIN Clientes c ON c.Id_Cliente = t.Id_Cliente - WHERE c.typeFk IN ('normal','handMaking','internalUse') - AND ( - Fecha BETWEEN util.today() AND vEndingDate - OR ( - ts.alertLevel < 3 - AND t.Fecha >= vStartingDate - AND t.Fecha < util.today() - ) - ); -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/recibidaIvaInsert.sql b/db/routines/vn2008/procedures/recibidaIvaInsert.sql deleted file mode 100644 index e2aba0a35..000000000 --- a/db/routines/vn2008/procedures/recibidaIvaInsert.sql +++ /dev/null @@ -1,39 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`recibidaIvaInsert`(IN vId INT) -BEGIN - - DECLARE vRate DOUBLE DEFAULT 1; - DECLARE vDated DATE; - - SELECT MAX(rr.date) INTO vDated - FROM reference_rate rr - JOIN recibida r ON r.id = vId - WHERE rr.date <= r.fecha - AND rr.moneda_id = r.moneda_id ; - - IF vDated THEN - - SELECT rate INTO vRate - FROM reference_rate - WHERE `date` = vDated; - END IF; - - DELETE FROM recibida_iva WHERE recibida_id = vId; - - INSERT INTO recibida_iva(recibida_id, bi, gastos_id, divisa, taxTypeSageFk, transactionTypeSageFk) - SELECT r.id, - SUM(Costefijo * Cantidad) / IFNULL(vRate,1) bi, - 6003000000, - IF(r.moneda_id = 1,NULL,SUM(Costefijo * Cantidad )) divisa, - taxTypeSageFk, - transactionTypeSageFk - FROM recibida r - JOIN Entradas e ON e.recibida_id = r.id - JOIN Proveedores p ON p.Id_Proveedor = e.Id_Proveedor - JOIN Compres c ON c.Id_Entrada = e.Id_Entrada - LEFT JOIN reference_rate rr ON rr.moneda_id = r.moneda_id AND rr.date = r.fecha - WHERE r.id = vId - HAVING bi IS NOT NULL; - -END$$ -DELIMITER ; From e2eddbaef7d7ca8ccd297ac4265aef3290899507 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 12 Mar 2024 08:35:13 +0100 Subject: [PATCH 41/62] refactor: refs #7018 Added comment --- db/routines/vn/procedures/invoiceInTax_insert.sql | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/db/routines/vn/procedures/invoiceInTax_insert.sql b/db/routines/vn/procedures/invoiceInTax_insert.sql index e43a7763d..761d8b0c5 100644 --- a/db/routines/vn/procedures/invoiceInTax_insert.sql +++ b/db/routines/vn/procedures/invoiceInTax_insert.sql @@ -1,8 +1,14 @@ DELIMITER $$ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceInTax_insert`( - IN vSelf INT + vSelf INT ) BEGIN +/** + * Inserta los impuestos de una factura, ajustando por + * tasa de cambio y detalles de compra. + * + * @param vSelf Id de invoiceInTax + */ DECLARE vRate DOUBLE DEFAULT 1; DECLARE vDated DATE; DECLARE vExpenseFk INT; From 1d398a0acf6b71ccf35b97a8f34bb5b8559d8f31 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 12 Mar 2024 08:40:11 +0100 Subject: [PATCH 42/62] refactor: refs #7018 Added comment and minor changes --- .../vn/procedures/invoiceInTaxMakeByDua.sql | 2 +- ...eInTax_insert.sql => invoiceInTax_recalc.sql} | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) rename db/routines/vn/procedures/{invoiceInTax_insert.sql => invoiceInTax_recalc.sql} (79%) diff --git a/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql b/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql index 6707486d0..3453516cc 100644 --- a/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql +++ b/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql @@ -29,7 +29,7 @@ BEGIN LEAVE l; END IF; - CALL invoiceInTax_insert(vInvoiceInFk); + CALL invoiceInTax_recalc(vInvoiceInFk); CALL invoiceInDueDay_recalc(vInvoiceInFk); END LOOP; diff --git a/db/routines/vn/procedures/invoiceInTax_insert.sql b/db/routines/vn/procedures/invoiceInTax_recalc.sql similarity index 79% rename from db/routines/vn/procedures/invoiceInTax_insert.sql rename to db/routines/vn/procedures/invoiceInTax_recalc.sql index 761d8b0c5..3b5ce5247 100644 --- a/db/routines/vn/procedures/invoiceInTax_insert.sql +++ b/db/routines/vn/procedures/invoiceInTax_recalc.sql @@ -1,13 +1,13 @@ DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceInTax_insert`( - vSelf INT +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceInTax_recalc`( + vInvoiceInFk INT ) BEGIN /** - * Inserta los impuestos de una factura, ajustando por - * tasa de cambio y detalles de compra. + * Recalcula y actualiza los impuestos de la factura + * usando la última tasa de cambio y detalles de compra. * - * @param vSelf Id de invoiceInTax + * @param vInvoiceInFk Id de factura recibida */ DECLARE vRate DOUBLE DEFAULT 1; DECLARE vDated DATE; @@ -15,7 +15,7 @@ BEGIN SELECT MAX(rr.dated) INTO vDated FROM referenceRate rr - JOIN invoiceIn ii ON ii.id = vSelf + JOIN invoiceIn ii ON ii.id = vInvoiceInFk WHERE rr.dated <= ii.issued AND rr.currencyFk = ii.currencyFk; @@ -25,7 +25,7 @@ BEGIN WHERE dated = vDated; END IF; - DELETE FROM invoiceInTax WHERE invoiceInFk = vSelf; + DELETE FROM invoiceInTax WHERE invoiceInFk = vInvoiceInFk; SELECT id INTO vExpenseFk FROM expense @@ -56,7 +56,7 @@ BEGIN JOIN buy b ON b.entryFk = e.id LEFT JOIN referenceRate rr ON rr.currencyFk = ii.currencyFk AND rr.dated = ii.issued - WHERE ii.id = vSelf + WHERE ii.id = vInvoiceInFk HAVING bi IS NOT NULL; END$$ DELIMITER ; From 9d94259d67700c0df52ca33d6f36d227ef67f7c4 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Tue, 12 Mar 2024 12:21:46 +0100 Subject: [PATCH 43/62] refs #6078 feat: workerActivity --- db/versions/10905-grayIvy/00-firstScript.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db/versions/10905-grayIvy/00-firstScript.sql b/db/versions/10905-grayIvy/00-firstScript.sql index a7c3c4c17..cca41cd48 100644 --- a/db/versions/10905-grayIvy/00-firstScript.sql +++ b/db/versions/10905-grayIvy/00-firstScript.sql @@ -1,4 +1,6 @@ -CREATE OR REPLACE TABLE `workerActivityType` ( +USE vn; + +CREATE OR REPLACE TABLE vn.workerActivityType ( `code` varchar(20) NOT NULL, `description` varchar(45) NOT NULL, PRIMARY KEY (`code`) From ed572126181361995176c6d148096a9d595d2eae Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 12 Mar 2024 12:55:14 +0100 Subject: [PATCH 44/62] refs #6755 fix restore --- modules/ticket/back/methods/ticket/restore.js | 16 +++++------ .../back/methods/ticket/specs/restore.spec.js | 27 +++++++++++-------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 9dde43ff9..555982f8d 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -29,7 +29,7 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - const ticket = await models.TicketLog.findOne({ + const ticketLog = await models.TicketLog.findOne({ fields: ['originFk', 'creationDate', 'newInstance'], where: { originFk: id, @@ -38,7 +38,7 @@ module.exports = Self => { order: 'creationDate DESC' }, myOptions); - const ticketOG = await models.Ticket.findById(id, { + const ticket = await models.Ticket.findById(id, { include: [{ relation: 'client', scope: { @@ -48,14 +48,14 @@ module.exports = Self => { }, myOptions); const now = Date.vnNew(); - const maxDate = new Date(ticket.creationDate); + const maxDate = new Date(ticketLog.creationDate); maxDate.setHours(maxDate.getHours() + 1); - if (now > maxDate) + throw new UserError(`You can only restore a ticket within the first hour after deletion`); // Send notification to salesPerson - const salesPersonId = ticketOG.client().salesPersonFk; + const salesPersonId = ticket.client().salesPersonFk; if (salesPersonId) { const url = await Self.app.models.Url.getUrl(); const message = $t(`I have restored the ticket id`, { @@ -66,12 +66,12 @@ module.exports = Self => { } const fullYear = Date.vnNew().getFullYear(); - const newShipped = ticketOG.shipped; - const newLanded = ticketOG.landed; + const newShipped = ticket.shipped; + const newLanded = ticket.landed; newShipped.setFullYear(fullYear); newLanded.setFullYear(fullYear); - return ticketOG.updateAttributes({ + return ticket.updateAttributes({ shipped: newShipped, landed: newLanded, isDeleted: false diff --git a/modules/ticket/back/methods/ticket/specs/restore.spec.js b/modules/ticket/back/methods/ticket/specs/restore.spec.js index 736e68628..a44d39a7b 100644 --- a/modules/ticket/back/methods/ticket/specs/restore.spec.js +++ b/modules/ticket/back/methods/ticket/specs/restore.spec.js @@ -2,7 +2,7 @@ const app = require('vn-loopback/server/server'); const LoopBackContext = require('loopback-context'); const models = app.models; -fdescribe('ticket restore()', () => { +describe('ticket restore()', () => { const employeeUser = 1110; const ticketId = 9; const activeCtx = { @@ -48,31 +48,36 @@ fdescribe('ticket restore()', () => { const tx = await app.models.Ticket.beginTransaction({}); const now = Date.vnNew(); - console.log('now', now); try { const options = {transaction: tx}; - const ticketBeforeUpdate = await models.TicketLog.findById(ticketId, null, options); + const ticketBeforeUpdate = await models.Ticket.findById(ticketId, null, options); await ticketBeforeUpdate.updateAttributes({ - creationDate: '2001-01-01T11:00:00.000Z', + isDeleted: true, + updated: now }, options); - console.log('ticketBeforeUpdate', ticketBeforeUpdate); - const ticketAfterUpdate = await models.TicketLog.findById(ticketId, null, options); - console.log('ticketAfterUpdate: ', ticketAfterUpdate); + await models.TicketLog.create({ + originFk: ticketId, + userFk: employeeUser, + action: 'update', + changedModel: 'Ticket', + creationDate: new Date('2001-01-01 11:01:00'), + newInstance: '{"isDeleted":true}' + }, options); + + const ticketAfterUpdate = await models.Ticket.findById(ticketId, null, options); expect(ticketAfterUpdate.isDeleted).toBeTruthy(); await models.Ticket.restore(ctx, ticketId, options); const ticketAfterRestore = await models.Ticket.findById(ticketId, null, options); - console.log('ticketAfterRestore: ', ticketAfterRestore); const fullYear = now.getFullYear(); - console.log('fullYear: ', fullYear); + const shippedFullYear = ticketAfterRestore.shipped.getFullYear(); - console.log('shippedFullYear: ', shippedFullYear); + const landedFullYear = ticketAfterRestore.landed.getFullYear(); - console.log('landedFullYear: ', landedFullYear); expect(ticketAfterRestore.isDeleted).toBeFalsy(); expect(shippedFullYear).toEqual(fullYear); From f2f6e7be0b5354d041fe3c746fcf572ea06c7c3e Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 12 Mar 2024 13:29:53 +0100 Subject: [PATCH 45/62] refs #6930 perf: parallel calls --- front/core/services/auth.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/front/core/services/auth.js b/front/core/services/auth.js index e51a2ff12..8727f92bc 100644 --- a/front/core/services/auth.js +++ b/front/core/services/auth.js @@ -98,20 +98,19 @@ export default class Auth { } logout() { - this.$http.post('VnUsers/logoutMultimedia', null, {headers: {'Authorization': this.vnToken.tokenMultimedia}, - }).then(({data}) => { - if (data) { - this.$http.post('VnUsers/logout', null, { - headers: {Authorization: this.vnToken.token} - }).catch(() => {}); - - this.vnToken.unset(); - this.loggedIn = false; - this.vnModules.reset(); - this.aclService.reset(); - this.$state.go('login'); - } + this.$http.post('Accounts/logout', null, {headers: {'Authorization': this.vnToken.tokenMultimedia}, }); + + let promise = this.$http.post('VnUsers/logout', null, { + headers: {Authorization: this.vnToken.token} + }).catch(() => {}); + this.vnToken.unset(); + this.loggedIn = false; + this.vnModules.reset(); + this.aclService.reset(); + this.$state.go('login'); + + return promise; } loadAcls() { From c84e86270c8c910903f26f2311883b9771d38a19 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 12 Mar 2024 13:30:32 +0100 Subject: [PATCH 46/62] refs #6930 perf: remove logoutMultimedia method --- back/models/vn-user.js | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 473e619db..b59f13ffa 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -31,32 +31,6 @@ module.exports = function(Self) { message: `A client with that Web User name already exists` }); - Self.remoteMethod('logoutMultimedia', { - description: 'Logout current MultimediaToken', - accepts: [{ - arg: 'ctx', - type: 'Object', - http: {source: 'context'} - }], - returns: { - type: 'Boolean', - root: true - }, - http: { - verb: 'POST', - path: '/logoutMultimedia' - }, - accessScopes: ['read:multimedia'] - }); - Self.logoutMultimedia = async function(ctx) { - let {accessToken} = ctx.req; - try { - Self.logout(accessToken.id); - return true; - } catch (error) { - return error; - } - }; Self.remoteMethod('getCurrentUserData', { description: 'Gets the current user data', accepts: [ From a6d1c5b6db243a1c032f693da5e9180fefe44bbd Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 12 Mar 2024 13:33:14 +0100 Subject: [PATCH 47/62] refs #6755 remove --- modules/ticket/front/descriptor-menu/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/ticket/front/descriptor-menu/index.html b/modules/ticket/front/descriptor-menu/index.html index 0b9b1b2a1..cb7eeb8ee 100644 --- a/modules/ticket/front/descriptor-menu/index.html +++ b/modules/ticket/front/descriptor-menu/index.html @@ -86,7 +86,6 @@ translate> Delete ticket - {{$ctrl.canRestoreTicket}} Date: Tue, 12 Mar 2024 13:39:01 +0100 Subject: [PATCH 48/62] refs #6930 perf: remove logoutMultimedia acl --- db/versions/10919-brownMoss/00-firstScript.sql | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/db/versions/10919-brownMoss/00-firstScript.sql b/db/versions/10919-brownMoss/00-firstScript.sql index a6abdbe79..640d2180a 100644 --- a/db/versions/10919-brownMoss/00-firstScript.sql +++ b/db/versions/10919-brownMoss/00-firstScript.sql @@ -1,5 +1,3 @@ -- Place your SQL code here -INSERT IGNORE INTO `salix`.`ACL`(`model`,`property`,`accessType`,`permission`, `principalType`, `principalId`) -VALUES -('VnUser','logoutMultimedia','*','ALLOW','ROLE','employee') + From 99f01a1dbd165bc89eee52dc2bbd66a0dde54de3 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 12 Mar 2024 13:39:21 +0100 Subject: [PATCH 49/62] refs #6930 perf: add accessScopes to account.logout --- modules/account/back/methods/account/logout.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/account/back/methods/account/logout.js b/modules/account/back/methods/account/logout.js index 5db3efa33..7d2e8153e 100644 --- a/modules/account/back/methods/account/logout.js +++ b/modules/account/back/methods/account/logout.js @@ -15,7 +15,8 @@ module.exports = Self => { http: { path: `/logout`, verb: 'POST' - } + }, + accessScopes: ['DEFAULT', 'read:multimedia'] }); Self.logout = async ctx => Self.app.models.VnUser.logout(ctx.req.accessToken.id); From 319bf314b3ba848299de4c71e4f927a7dccabbb0 Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 13 Mar 2024 07:38:14 +0100 Subject: [PATCH 50/62] hotfix: itemProposal --- db/routines/vn/procedures/itemProposal.sql | 96 +++++++++------------- 1 file changed, 38 insertions(+), 58 deletions(-) diff --git a/db/routines/vn/procedures/itemProposal.sql b/db/routines/vn/procedures/itemProposal.sql index d0d98fed7..eb8a7ab33 100644 --- a/db/routines/vn/procedures/itemProposal.sql +++ b/db/routines/vn/procedures/itemProposal.sql @@ -19,98 +19,78 @@ BEGIN DECLARE vTypeFk INT; DECLARE vPriority INT DEFAULT 1; - DECLARE vTag1 VARCHAR(20) COLLATE 'utf8_unicode_ci'; - DECLARE vTag5 VARCHAR(20) COLLATE 'utf8_unicode_ci'; - DECLARE vTag6 VARCHAR(20) COLLATE 'utf8_unicode_ci'; - DECLARE vTag7 VARCHAR(20) COLLATE 'utf8_unicode_ci'; - DECLARE vTag8 VARCHAR(20) COLLATE 'utf8_unicode_ci'; - - DECLARE vValue1 VARCHAR(50) COLLATE 'utf8_unicode_ci'; - DECLARE vValue5 VARCHAR(50) COLLATE 'utf8_unicode_ci'; - DECLARE vValue6 VARCHAR(50) COLLATE 'utf8_unicode_ci'; - DECLARE vValue7 VARCHAR(50) COLLATE 'utf8_unicode_ci'; - DECLARE vValue8 VARCHAR(50) COLLATE 'utf8_unicode_ci'; - SELECT warehouseFk, shipped INTO vWarehouseFk, vShipped FROM ticket WHERE id = vTicketFk; - SELECT typeFk, - tag5, - value5, - tag6, - value6, - tag7, - value7, - tag8, - value8, - t.name, - it.value - INTO vTypeFk, - vTag5, - vValue5, - vTag6, - vValue6, - vTag7, - vValue7, - vTag8, - vValue8, - vTag1, - vValue1 - FROM item i - LEFT JOIN itemTag it ON it.itemFk = i.id - AND it.priority = vPriority - LEFT JOIN tag t ON t.id = it.tagFk - WHERE i.id = vSelf; - CALL cache.available_refresh(vCalcFk, FALSE, vWarehouseFk, vShipped); + WITH itemTags AS ( + SELECT i.id, + typeFk, + tag5, + value5, + tag6, + value6, + tag7, + value7, + tag8, + value8, + t.name, + it.value + FROM vn.item i + LEFT JOIN vn.itemTag it ON it.itemFk = i.id + AND it.priority = vPriority + LEFT JOIN vn.tag t ON t.id = it.tagFk + WHERE i.id = vSelf + ) SELECT i.id itemFk, i.longName, i.subName, i.tag5, i.value5, - (i.value5 <=> vValue5) match5, + (i.value5 <=> its.value5) match5, i.tag6, i.value6, - (i.value6 <=> vValue6) match6, + (i.value6 <=> its.value6) match6, i.tag7, i.value7, - (i.value7 <=> vValue7) match7, + (i.value7 <=> its.value7) match7, i.tag8, i.value8, - (i.value8 <=> vValue8) match8, + (i.value8 <=> its.value8) match8, a.available, IFNULL(ip.counter, 0) `counter`, IF(b.groupingMode = 1, b.grouping, b.packing) minQuantity, iss.visible located - FROM item i - STRAIGHT_JOIN cache.available a ON a.item_id = i.id + FROM vn.item i + JOIN cache.available a ON a.item_id = i.id AND a.calc_id = vCalcFk - LEFT JOIN itemProposal ip ON ip.mateFk = i.id + LEFT JOIN vn.itemProposal ip ON ip.mateFk = i.id AND ip.itemFk = vSelf - LEFT JOIN itemTag it ON it.itemFk = i.id + LEFT JOIN vn.itemTag it ON it.itemFk = i.id AND it.priority = vPriority - LEFT JOIN tag t ON t.id = it.tagFk + LEFT JOIN vn.tag t ON t.id = it.tagFk LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = vWarehouseFk - LEFT JOIN buy b ON b.id = lb.buy_id - LEFT JOIN itemShelvingStock iss ON iss.itemFk = i.id + LEFT JOIN vn.buy b ON b.id = lb.buy_id + LEFT JOIN vn.itemShelvingStock iss ON iss.itemFk = i.id AND iss.warehouseFk = vWarehouseFk + JOIN itemTags its WHERE a.available > 0 - AND IF(vShowType, i.typeFk = vTypeFk, TRUE) + AND IF(vShowType, i.typeFk = its.typeFk, TRUE) AND i.id <> vSelf ORDER BY `counter` DESC, - (t.name = vTag1) DESC, - (it.value = vValue1) DESC, - (i.tag5 = vTag5) DESC, + (t.name = its.name) DESC, + (it.value = its.value) DESC, + (i.tag5 = its.tag5) DESC, match5 DESC, - (i.tag6 = vTag6) DESC, + (i.tag6 = its.tag6) DESC, match6 DESC, - (i.tag7 = vTag7) DESC, + (i.tag7 = its.tag7) DESC, match7 DESC, - (i.tag8 = vTag8) DESC, + (i.tag8 = its.tag8) DESC, match8 DESC; END$$ DELIMITER ; From 92cf8fc5e1bde70adabcfe74d4a70245994beb69 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 13 Mar 2024 11:46:43 +0100 Subject: [PATCH 51/62] refs #6755 remove console --- modules/ticket/front/descriptor-menu/index.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index 9c7a58719..d2dd13f73 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -46,22 +46,16 @@ class Controller extends Section { }; this.$http.get(`TicketLogs/findOne`, {filter}) .then(res => { - console.log(res); - console.log(res.data.creationDate); if (res && res.data) { - console.log(res.data); const now = Date.vnNew(); const maxDate = new Date(res.data.creationDate); maxDate.setHours(maxDate.getHours() + 1); - console.log(now, maxDatenow); - console.log(now.getTime(), maxDate.getTime()); if (now <= maxDate) return this.canRestoreTicket = true; } this.canRestoreTicket = false; }) .catch(() => { - console.log('ENTRY'); this.canRestoreTicket = false; }); } From 11dcb6e79f22b187e5259216a0d2e1b46f85bb77 Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 13 Mar 2024 13:45:57 +0100 Subject: [PATCH 52/62] refactor: refs #6875 packing not null, negative or zero --- db/routines/vn/procedures/inventoryMake.sql | 2 +- db/routines/vn/procedures/inventory_repair.sql | 7 +------ .../10892-yellowGerbera/00-firstScript.sql | 17 ++++++++++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/db/routines/vn/procedures/inventoryMake.sql b/db/routines/vn/procedures/inventoryMake.sql index 8788336ae..ed6a7fa43 100644 --- a/db/routines/vn/procedures/inventoryMake.sql +++ b/db/routines/vn/procedures/inventoryMake.sql @@ -175,7 +175,7 @@ BEGIN LEFT JOIN producer p ON p.id = i.producerFk SET inv.buyingValue = b.buyingValue, inv.freightValue = b.freightValue, - inv.packing = IFNULL(GREATEST(b.packing, 1), 1), + inv.packing = b.packing, inv.`grouping`= b.`grouping`, inv.groupingMode = b.groupingMode, inv.comissionValue = b.comissionValue, diff --git a/db/routines/vn/procedures/inventory_repair.sql b/db/routines/vn/procedures/inventory_repair.sql index ea65ac37d..93527d84b 100644 --- a/db/routines/vn/procedures/inventory_repair.sql +++ b/db/routines/vn/procedures/inventory_repair.sql @@ -37,7 +37,7 @@ BEGIN LEFT JOIN origin o ON o.id = i.originFk ) ON it.id = i.typeFk LEFT JOIN edi.ekt ek ON b.ektFk = ek.id - WHERE (b.packagingFk = "--" OR b.price2 = 0 OR b.packing = 0 OR b.buyingValue = 0) AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-1,util.VN_CURDATE())) AND s.name = 'INVENTARIO'; + WHERE (b.packagingFk = "--" OR b.price2 = 0 OR b.buyingValue = 0) AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-1,util.VN_CURDATE())) AND s.name = 'INVENTARIO'; DROP TEMPORARY TABLE IF EXISTS tmp.lastEntryOk; CREATE TEMPORARY TABLE tmp.lastEntryOk @@ -94,11 +94,6 @@ BEGIN JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk SET b.price2 = eo.price2 WHERE b.price2 = 0 ; - UPDATE buy b - JOIN tmp.lastEntry lt ON lt.buyFk = b.id - JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk - SET b.packing = eo.packing WHERE b.packing = 0; - UPDATE buy b JOIN tmp.lastEntry lt ON lt.buyFk = b.id JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk diff --git a/db/versions/10892-yellowGerbera/00-firstScript.sql b/db/versions/10892-yellowGerbera/00-firstScript.sql index 4df616f3a..76c0cb46d 100644 --- a/db/versions/10892-yellowGerbera/00-firstScript.sql +++ b/db/versions/10892-yellowGerbera/00-firstScript.sql @@ -1,12 +1,15 @@ --- Place your SQL code here - UPDATE vn.buy - SET packing = 1 - WHERE packing IS NULL - OR NOT packing + SET packing = 1 + WHERE packing IS NULL + OR packing <= 0; + +UPDATE vn.itemShelving + SET packing = 1 + WHERE packing IS NULL + OR NOT packing; ALTER TABLE vn.buy MODIFY COLUMN packing int(11) NOT NULL CHECK(packing > 0); +ALTER TABLE vn.itemShelving MODIFY COLUMN packing int(11) NOT NULL CHECK(packing > 0); --- antes tenia '0=sin obligar 1=groping 2=packing' +-- Antes tenia '0=sin obligar 1=groping 2=packing' (groping → grouping) ALTER TABLE vn.buy MODIFY COLUMN groupingMode tinyint(4) DEFAULT 0 NOT NULL COMMENT '0=sin obligar 1=grouping 2=packing'; - From 1315bfda8839d89c68ebafc117341d5499d576f0 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 13 Mar 2024 14:18:53 +0100 Subject: [PATCH 53/62] refs #6755 fix test --- db/dump/fixtures.before.sql | 8 -------- .../back/methods/ticket-log/specs/getChanges.spec.js | 4 ++-- modules/ticket/back/methods/ticket/restore.js | 5 ++--- .../ticket/back/methods/ticket/specs/filter.spec.js | 2 +- .../ticket/back/methods/ticket/specs/restore.spec.js | 12 ++++++++++++ 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 1f6c44d2e..35de9dd47 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -3068,14 +3068,6 @@ INSERT INTO `vn`.`cmr` (id,truckPlate,observations,senderInstruccions,paymentIns UPDATE vn.department SET workerFk = null; -INSERT INTO vn.ticketLog (originFk,userFk,`action`,creationDate,changedModel,newInstance,changedModelId,changedModelValue) - VALUES (9,9,'insert','2000-01-01 11:01:00.000','Ticket','{"isDeleted":true}',45,'Super Man'); - -UPDATE vn.ticket - SET isDeleted=1 - WHERE id=9; --- NEW WAREHOUSE - INSERT INTO vn.packaging VALUES('--', 2745600.00, 100.00, 120.00, 220.00, 0.00, 1, '2001-01-01 00:00:00.000', NULL, NULL, NULL, 0.00, 16, 0.00, 0, NULL, 0.00, NULL, NULL, 0, NULL, 0, 0); diff --git a/modules/ticket/back/methods/ticket-log/specs/getChanges.spec.js b/modules/ticket/back/methods/ticket-log/specs/getChanges.spec.js index 04f42f7be..cccaa182f 100644 --- a/modules/ticket/back/methods/ticket-log/specs/getChanges.spec.js +++ b/modules/ticket/back/methods/ticket-log/specs/getChanges.spec.js @@ -9,8 +9,8 @@ describe('ticketLog getChanges()', () => { it('should return the changes in the sales of a ticket', async() => { const ticketId = 16; - const changues = await models.TicketLog.getChanges(ctx, ticketId); + const changes = await models.TicketLog.getChanges(ctx, ticketId); - expect(changues).toContain(`Change quantity`); + expect(changes).toContain(`Change quantity`); }); }); diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 555982f8d..01b5d1652 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -48,10 +48,9 @@ module.exports = Self => { }, myOptions); const now = Date.vnNew(); - const maxDate = new Date(ticketLog.creationDate); + const maxDate = new Date(ticketLog?.creationDate); maxDate.setHours(maxDate.getHours() + 1); - if (now > maxDate) - + if (!ticketLog || now > maxDate) throw new UserError(`You can only restore a ticket within the first hour after deletion`); // Send notification to salesPerson diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js index 09c4ebbb7..c1d3f1a9c 100644 --- a/modules/ticket/back/methods/ticket/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js @@ -68,7 +68,7 @@ describe('ticket filter()', () => { const filter = {}; const result = await models.Ticket.filter(ctx, filter, options); - expect(result.length).toEqual(5); + expect(result.length).toEqual(6); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket/specs/restore.spec.js b/modules/ticket/back/methods/ticket/specs/restore.spec.js index a44d39a7b..121a6ba96 100644 --- a/modules/ticket/back/methods/ticket/specs/restore.spec.js +++ b/modules/ticket/back/methods/ticket/specs/restore.spec.js @@ -30,10 +30,21 @@ describe('ticket restore()', () => { try { const options = {transaction: tx}; const ticket = await models.Ticket.findById(ticketId, null, options); + await ticket.updateAttributes({ isDeleted: true, updated: now }, options); + + await models.TicketLog.create({ + originFk: ticketId, + userFk: employeeUser, + action: 'update', + changedModel: 'Ticket', + creationDate: new Date('2001-01-01 10:59:00'), + newInstance: '{"isDeleted":true}' + }, options); + await app.models.Ticket.restore(ctx, ticketId, options); await tx.rollback(); } catch (e) { @@ -52,6 +63,7 @@ describe('ticket restore()', () => { const options = {transaction: tx}; const ticketBeforeUpdate = await models.Ticket.findById(ticketId, null, options); + await ticketBeforeUpdate.updateAttributes({ isDeleted: true, updated: now From 33bd21d40b00f7658d7c266ffc555b599e1bfab0 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 13 Mar 2024 16:29:05 +0100 Subject: [PATCH 54/62] refs #6755 fix model --- modules/ticket/back/models/ticket-log.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ticket/back/models/ticket-log.json b/modules/ticket/back/models/ticket-log.json index e46995a91..32b4afd13 100644 --- a/modules/ticket/back/models/ticket-log.json +++ b/modules/ticket/back/models/ticket-log.json @@ -29,13 +29,13 @@ "type": "string" }, "oldInstance": { - "type": "string" + "type": "any" }, "newInstance": { - "type": "string" + "type": "any" }, "changedModelId": { - "type": "number" + "type": "string" }, "changedModelValue": { "type": "string" From b4b6b47a9caf3e89e7abbedfa4b18f162c10d04a Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 14 Mar 2024 07:53:24 +0100 Subject: [PATCH 55/62] hotfix: itemProposal added transaction --- db/routines/vn/procedures/itemProposal.sql | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/db/routines/vn/procedures/itemProposal.sql b/db/routines/vn/procedures/itemProposal.sql index eb8a7ab33..0dc04124d 100644 --- a/db/routines/vn/procedures/itemProposal.sql +++ b/db/routines/vn/procedures/itemProposal.sql @@ -18,12 +18,19 @@ BEGIN DECLARE vCalcFk INT; DECLARE vTypeFk INT; DECLARE vPriority INT DEFAULT 1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + ROLLBACK; + RESIGNAL; + END; SELECT warehouseFk, shipped INTO vWarehouseFk, vShipped FROM ticket WHERE id = vTicketFk; + START TRANSACTION; + CALL cache.available_refresh(vCalcFk, FALSE, vWarehouseFk, vShipped); WITH itemTags AS ( @@ -92,5 +99,6 @@ BEGIN match7 DESC, (i.tag8 = its.tag8) DESC, match8 DESC; + COMMIT; END$$ DELIMITER ; From e24eed16c1b3240cd1bbb80010c7cbb08af0768f Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 14 Mar 2024 08:26:50 +0100 Subject: [PATCH 56/62] refs #6842 fix companyCode --- db/versions/10893-limeFern/00-sage.sql | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/db/versions/10893-limeFern/00-sage.sql b/db/versions/10893-limeFern/00-sage.sql index 01508b932..d4c7e6221 100644 --- a/db/versions/10893-limeFern/00-sage.sql +++ b/db/versions/10893-limeFern/00-sage.sql @@ -3,7 +3,13 @@ UPDATE vn.company SET companyCode=0 WHERE id=69; UPDATE vn.company - SET companyCode=0 + SET companyCode=1 + WHERE id=442; +UPDATE vn.company + SET companyCode=4 + WHERE id=567; +UPDATE vn.company + SET companyCode=2 WHERE id=791; UPDATE vn.company SET companyCode=3 @@ -17,6 +23,9 @@ UPDATE vn.company UPDATE vn.company SET companyCode=3 WHERE id=1463; +UPDATE vn.company + SET companyCode=8 + WHERE id=2142; UPDATE vn.company SET companyCode=6 WHERE id=2393; From 0ad052c34a4be6a5fc21a994375c86480dd59329 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 14 Mar 2024 08:36:19 +0100 Subject: [PATCH 57/62] refs #7033 deploy(2412): dev to test --- back/methods/collection/assign.js | 31 + back/methods/collection/getSales.js | 157 ++++ back/methods/collection/spec/assign.spec.js | 38 + back/methods/collection/spec/getSales.spec.js | 62 ++ .../machine-worker/specs/updateInTime.spec.js | 132 ++++ back/methods/machine-worker/updateInTime.js | 77 ++ .../mobile-app-version-control/getVersion.js | 45 ++ .../specs/getVersion.spec.js | 29 + back/model-config.json | 23 +- back/models/{bank.json => accounting.json} | 9 +- back/models/collection.js | 2 + back/models/machine-worker-config.json | 18 + back/models/machine-worker.js | 3 + back/models/machine.json | 18 + back/models/mobile-app-version-control.js | 3 + back/models/mobile-app-version-control.json | 39 + back/models/payment.json | 2 +- back/models/workerActivity.json | 39 + back/models/workerActivityType.json | 19 + db/dump/.dump/data.sql | 2 - db/dump/fixtures.before.sql | 696 +++++++++++++++++- .../bs/procedures/manaCustomerUpdate.sql | 2 +- db/routines/cache/procedures/clean.sql | 6 +- .../hedera/procedures/tpvTransaction_undo.sql | 2 +- .../procedures/accountingMovements_add.sql | 6 +- db/routines/sage/procedures/pgc_add.sql | 12 +- .../vn/events/sale_checkWithoutComponents.sql | 8 - db/routines/vn/functions/till_new.sql | 2 +- .../procedures/balanceNestTree_addChild.sql | 52 ++ .../vn/procedures/balanceNestTree_delete.sql | 53 ++ .../vn/procedures/balanceNestTree_move.sql | 117 +++ .../procedures/bankPolicy_notifyExpired.sql | 12 +- db/routines/vn/procedures/clean.sql | 263 +++---- db/routines/vn/procedures/client_getMana.sql | 3 +- .../procedures/confection_controlSource.sql | 103 +++ .../vn/procedures/invoiceInTaxMakeByDua.sql | 9 +- .../vn/procedures/invoiceInTax_recalc.sql | 62 ++ db/routines/vn/procedures/itemProposal.sql | 104 --- .../vn/procedures/itemProposal_beta.sql | 76 -- .../vn/procedures/itemShelving_inventory.sql | 7 +- db/routines/vn/procedures/item_getSimilar.sql | 160 ++-- db/routines/vn/procedures/payment_add.sql | 84 +++ db/routines/vn/procedures/remittance_calc.sql | 70 ++ .../vn/procedures/sale_checkNoComponents.sql | 70 -- .../vn/procedures/sale_getBoxPickingList.sql | 4 +- .../sale_getFromTicketOrCollection.sql | 5 +- .../vn/procedures/supplier_statement.sql | 2 +- .../vn/procedures/ticket_closeByTicket.sql | 3 +- .../vn/triggers/parking_afterDelete.sql | 12 + .../vn/triggers/parking_beforeInsert.sql | 2 +- .../vn/triggers/parking_beforeUpdate.sql | 2 +- .../vn/triggers/payment_beforeInsert.sql | 10 +- db/routines/vn/views/bank.sql | 12 - db/routines/vn/views/exchangeInsuranceOut.sql | 4 +- .../vn2008/procedures/CalculoRemesas.sql | 66 -- .../procedures/ListaTicketsEncajados.sql | 25 - db/routines/vn2008/procedures/cacheReset.sql | 11 - db/routines/vn2008/procedures/camiones.sql | 23 - db/routines/vn2008/procedures/clean.sql | 74 -- .../vn2008/procedures/clean_launcher.sql | 6 - db/routines/vn2008/procedures/cobro.sql | 79 -- .../procedures/confection_control_source.sql | 105 --- .../procedures/customerDebtEvolution.sql | 49 -- .../emailYesterdayPurchasesByConsigna.sql | 100 --- .../emailYesterdayPurchasesLauncher.sql | 27 - .../vn2008/procedures/embalajes_stocks.sql | 51 -- .../procedures/embalajes_stocks_detalle.sql | 78 -- .../vn2008/procedures/nest_child_add.sql | 48 -- db/routines/vn2008/procedures/nest_delete.sql | 51 -- db/routines/vn2008/procedures/nest_move.sql | 108 --- db/routines/vn2008/procedures/pay.sql | 67 -- .../vn2008/procedures/preOrdenarRuta.sql | 22 - .../vn2008/procedures/prepare_ticket_list.sql | 22 - .../vn2008/procedures/recibidaIvaInsert.sql | 39 - db/routines/vn2008/views/Bancos.sql | 16 +- .../10832-purpleAralia/00-newWareHouse.sql | 12 + db/versions/10905-grayIvy/00-firstScript.sql | 36 + .../10913-bronzeGalax/00-firstScript.sql | 4 + .../10915-limeMastic/00-firstScript.sql | 2 + .../10918-wheatRose/00-firstScript.sql | 2 + .../10923-pinkOak/00-createParkingLog.sql | 60 ++ .../10923-pinkOak/01-aclParkingLog.sql | 2 + .../10924-pinkCordyline/00-firstScript.sql | 31 + .../10925-orangeLaurel/00-firstScript.sql | 15 + .../10926-limeFern/00-refactorClaimState.sql | 8 + .../10928-orangeEucalyptus/00-firstScript.sql | 5 + .../10929-orangeAnthurium/00-firstScript.sql | 2 + e2e/paths/06-claim/01_basic_data.spec.js | 4 +- .../salix/components/user-popover/index.html | 2 +- jest.front.config.js | 3 + loopback/common/mixins/loggable.js | 3 +- loopback/locale/en.json | 13 +- loopback/locale/es.json | 3 +- loopback/server/connectors/vn-mysql.js | 6 +- loopback/util/validateIban.js | 1 - .../claim-state/specs/isEditable.spec.js | 2 +- .../methods/claim/specs/updateClaim.spec.js | 126 +--- .../claim/specs/updateClaimAction.spec.js | 2 +- modules/claim/back/model-config.json | 5 +- modules/claim/back/models/claim-rma.js | 9 - modules/claim/back/models/claim.json | 9 - .../back/methods/client/createReceipt.js | 2 +- .../receipt/balanceCompensationEmail.js | 2 +- modules/client/back/models/receipt.json | 2 +- modules/client/back/models/till.json | 2 +- .../client/front/balance/create/index.html | 2 +- modules/client/front/billing-data/index.html | 1 + .../back/methods/entry/specs/filter.spec.js | 4 +- .../back/models/invoice-in-due-day.json | 2 +- modules/invoiceIn/front/dueDay/index.html | 2 +- modules/invoiceOut/back/models/invoice-out.js | 21 + .../item/back/methods/item-barcode/delete.js | 34 + .../methods/item-barcode/specs/delete.spec.js | 22 + .../methods/item-shelving/getAlternative.js | 64 ++ .../specs/getAlternative.spec.js | 25 + .../specs/updateFromSale.spec.js | 22 + .../methods/item-shelving/updateFromSale.js | 48 ++ modules/item/back/methods/item/get.js | 48 ++ .../item/back/methods/item/specs/get.spec.js | 12 + modules/item/back/models/item-barcode.js | 1 + modules/item/back/models/item-shelving.js | 2 + modules/item/back/models/item-shelving.json | 5 +- modules/item/back/models/item.js | 1 + modules/parking/back/model-config.json | 5 + modules/parking/back/models/parking-log.json | 9 + modules/shelving/back/locale/parking/en.yml | 9 + modules/shelving/back/locale/parking/es.yml | 10 + .../shelving/back/methods/shelving/addLog.js | 56 ++ .../methods/shelving/specs/addLog.spec.js | 46 ++ modules/shelving/back/models/parking.json | 8 +- modules/shelving/back/models/shelving.js | 1 + .../back/methods/sale-tracking/delete.js | 36 +- .../back/methods/sale-tracking/setPicked.js | 106 +++ .../sale-tracking/specs/delete.spec.js | 5 +- .../sale-tracking/specs/setPicked.spec.js | 114 +++ .../specs/updateTracking.spec.js | 104 +++ .../methods/sale-tracking/updateTracking.js | 110 +++ .../methods/sale/getFromSectorCollection.js | 61 ++ .../specs/getFromSectorCollection.spec.js | 23 + .../back/methods/ticket/addSaleByCode.js | 56 ++ .../ticket/back/methods/ticket/closeAll.js | 1 + modules/ticket/back/methods/ticket/closure.js | 83 ++- .../ticket/back/methods/ticket/makeInvoice.js | 18 +- .../ticket/specs/addSaleByCode.spec.js | 39 + .../methods/ticket/specs/makeInvoice.spec.js | 2 +- .../methods/ticket/specs/setDeleted.spec.js | 13 +- modules/ticket/back/model-config.json | 3 + .../ticket/back/models/expeditionPallet.json | 26 +- .../back/models/sale-buy.json} | 20 +- modules/ticket/back/models/sale-tracking.js | 2 + modules/ticket/back/models/sale-tracking.json | 3 + modules/ticket/back/models/sale.js | 1 + modules/ticket/back/models/ticket.js | 1 + modules/ticket/front/sale-tracking/index.js | 2 +- modules/worker/back/model-config.json | 3 + modules/worker/back/models/department.json | 7 +- modules/worker/back/models/operator.js | 2 +- modules/worker/back/models/operator.json | 6 + .../worker/back/models/worker-app-tester.json | 22 + myt.config.yml | 1 - package.json | 2 +- .../reports/cmr/assets/css/style.css | 17 +- print/templates/reports/cmr/cmr.html | 22 +- print/templates/reports/cmr/cmr.js | 75 +- print/templates/reports/cmr/sql/data.sql | 1 + 165 files changed, 3756 insertions(+), 1916 deletions(-) create mode 100644 back/methods/collection/assign.js create mode 100644 back/methods/collection/getSales.js create mode 100644 back/methods/collection/spec/assign.spec.js create mode 100644 back/methods/collection/spec/getSales.spec.js create mode 100644 back/methods/machine-worker/specs/updateInTime.spec.js create mode 100644 back/methods/machine-worker/updateInTime.js create mode 100644 back/methods/mobile-app-version-control/getVersion.js create mode 100644 back/methods/mobile-app-version-control/specs/getVersion.spec.js rename back/models/{bank.json => accounting.json} (85%) create mode 100644 back/models/machine-worker-config.json create mode 100644 back/models/machine-worker.js create mode 100644 back/models/machine.json create mode 100644 back/models/mobile-app-version-control.js create mode 100644 back/models/mobile-app-version-control.json create mode 100644 back/models/workerActivity.json create mode 100644 back/models/workerActivityType.json delete mode 100644 db/routines/vn/events/sale_checkWithoutComponents.sql create mode 100644 db/routines/vn/procedures/balanceNestTree_addChild.sql create mode 100644 db/routines/vn/procedures/balanceNestTree_delete.sql create mode 100644 db/routines/vn/procedures/balanceNestTree_move.sql create mode 100644 db/routines/vn/procedures/confection_controlSource.sql create mode 100644 db/routines/vn/procedures/invoiceInTax_recalc.sql delete mode 100644 db/routines/vn/procedures/itemProposal.sql delete mode 100644 db/routines/vn/procedures/itemProposal_beta.sql create mode 100644 db/routines/vn/procedures/payment_add.sql create mode 100644 db/routines/vn/procedures/remittance_calc.sql delete mode 100644 db/routines/vn/procedures/sale_checkNoComponents.sql create mode 100644 db/routines/vn/triggers/parking_afterDelete.sql delete mode 100644 db/routines/vn/views/bank.sql delete mode 100644 db/routines/vn2008/procedures/CalculoRemesas.sql delete mode 100644 db/routines/vn2008/procedures/ListaTicketsEncajados.sql delete mode 100644 db/routines/vn2008/procedures/cacheReset.sql delete mode 100644 db/routines/vn2008/procedures/camiones.sql delete mode 100644 db/routines/vn2008/procedures/clean.sql delete mode 100644 db/routines/vn2008/procedures/clean_launcher.sql delete mode 100644 db/routines/vn2008/procedures/cobro.sql delete mode 100644 db/routines/vn2008/procedures/confection_control_source.sql delete mode 100644 db/routines/vn2008/procedures/customerDebtEvolution.sql delete mode 100644 db/routines/vn2008/procedures/emailYesterdayPurchasesByConsigna.sql delete mode 100644 db/routines/vn2008/procedures/emailYesterdayPurchasesLauncher.sql delete mode 100644 db/routines/vn2008/procedures/embalajes_stocks.sql delete mode 100644 db/routines/vn2008/procedures/embalajes_stocks_detalle.sql delete mode 100644 db/routines/vn2008/procedures/nest_child_add.sql delete mode 100644 db/routines/vn2008/procedures/nest_delete.sql delete mode 100644 db/routines/vn2008/procedures/nest_move.sql delete mode 100644 db/routines/vn2008/procedures/pay.sql delete mode 100644 db/routines/vn2008/procedures/preOrdenarRuta.sql delete mode 100644 db/routines/vn2008/procedures/prepare_ticket_list.sql delete mode 100644 db/routines/vn2008/procedures/recibidaIvaInsert.sql create mode 100644 db/versions/10832-purpleAralia/00-newWareHouse.sql create mode 100644 db/versions/10905-grayIvy/00-firstScript.sql create mode 100644 db/versions/10913-bronzeGalax/00-firstScript.sql create mode 100644 db/versions/10915-limeMastic/00-firstScript.sql create mode 100644 db/versions/10918-wheatRose/00-firstScript.sql create mode 100644 db/versions/10923-pinkOak/00-createParkingLog.sql create mode 100644 db/versions/10923-pinkOak/01-aclParkingLog.sql create mode 100644 db/versions/10924-pinkCordyline/00-firstScript.sql create mode 100644 db/versions/10925-orangeLaurel/00-firstScript.sql create mode 100644 db/versions/10926-limeFern/00-refactorClaimState.sql create mode 100644 db/versions/10928-orangeEucalyptus/00-firstScript.sql create mode 100644 db/versions/10929-orangeAnthurium/00-firstScript.sql delete mode 100644 modules/claim/back/models/claim-rma.js create mode 100644 modules/item/back/methods/item-barcode/delete.js create mode 100644 modules/item/back/methods/item-barcode/specs/delete.spec.js create mode 100644 modules/item/back/methods/item-shelving/getAlternative.js create mode 100644 modules/item/back/methods/item-shelving/specs/getAlternative.spec.js create mode 100644 modules/item/back/methods/item-shelving/specs/updateFromSale.spec.js create mode 100644 modules/item/back/methods/item-shelving/updateFromSale.js create mode 100644 modules/item/back/methods/item/get.js create mode 100644 modules/item/back/methods/item/specs/get.spec.js create mode 100644 modules/parking/back/model-config.json create mode 100644 modules/parking/back/models/parking-log.json create mode 100644 modules/shelving/back/locale/parking/en.yml create mode 100644 modules/shelving/back/locale/parking/es.yml create mode 100644 modules/shelving/back/methods/shelving/addLog.js create mode 100644 modules/shelving/back/methods/shelving/specs/addLog.spec.js create mode 100644 modules/ticket/back/methods/sale-tracking/setPicked.js create mode 100644 modules/ticket/back/methods/sale-tracking/specs/setPicked.spec.js create mode 100644 modules/ticket/back/methods/sale-tracking/specs/updateTracking.spec.js create mode 100644 modules/ticket/back/methods/sale-tracking/updateTracking.js create mode 100644 modules/ticket/back/methods/sale/getFromSectorCollection.js create mode 100644 modules/ticket/back/methods/sale/specs/getFromSectorCollection.spec.js create mode 100644 modules/ticket/back/methods/ticket/addSaleByCode.js create mode 100644 modules/ticket/back/methods/ticket/specs/addSaleByCode.spec.js rename modules/{claim/back/models/claim-rma.json => ticket/back/models/sale-buy.json} (56%) create mode 100644 modules/worker/back/models/worker-app-tester.json diff --git a/back/methods/collection/assign.js b/back/methods/collection/assign.js new file mode 100644 index 000000000..b0c1d9995 --- /dev/null +++ b/back/methods/collection/assign.js @@ -0,0 +1,31 @@ +const UserError = require('vn-loopback/util/user-error'); +module.exports = Self => { + Self.remoteMethodCtx('assign', { + description: 'Assign a collection', + accessType: 'WRITE', + http: { + path: `/assign`, + verb: 'POST' + }, + returns: { + type: ['object'], + root: true + }, + }); + + Self.assign = async(ctx, options) => { + const userId = ctx.req.accessToken.userId; + const myOptions = {userId}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const [,, {collectionFk}] = await Self.rawSql('CALL vn.collection_assign(?, @vCollectionFk); SELECT @vCollectionFk collectionFk', + [userId], myOptions); + + if (!collectionFk) throw new UserError('There are not picking tickets'); + await Self.rawSql('CALL vn.collection_printSticker(?, NULL)', [collectionFk], myOptions); + + return collectionFk; + }; +}; diff --git a/back/methods/collection/getSales.js b/back/methods/collection/getSales.js new file mode 100644 index 000000000..78945dc80 --- /dev/null +++ b/back/methods/collection/getSales.js @@ -0,0 +1,157 @@ +module.exports = Self => { + Self.remoteMethodCtx('getSales', { + description: 'Get sales from ticket or collection', + accessType: 'READ', + accepts: [ + { + arg: 'collectionOrTicketFk', + type: 'number', + required: true + }, { + arg: 'print', + type: 'boolean', + required: true + }, { + arg: 'source', + type: 'string', + required: true + }, + + ], + returns: { + type: 'Object', + root: true + }, + http: { + path: `/getSales`, + verb: 'GET' + }, + }); + + Self.getSales = async(ctx, collectionOrTicketFk, print, source, options) => { + const userId = ctx.req.accessToken.userId; + const myOptions = {userId}; + const $t = ctx.req.__; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const [{id}] = await Self.rawSql('SELECT vn.ticket_get(?) as id', + [collectionOrTicketFk], + myOptions); + + const [tickets] = await Self.rawSql('CALL vn.collection_getTickets(?)', [id], myOptions); + + if (source) { + await Self.rawSql( + 'CALL vn.ticketStateToday_setState(?,?)', [id, source], myOptions + ); + } + + const [sales] = await Self.rawSql('CALL vn.sale_getFromTicketOrCollection(?)', + [id], myOptions); + + const isPicker = source != 'CHECKER'; + const [placements] = await Self.rawSql('CALL vn.collectionPlacement_get(?, ?)', + [id, isPicker], myOptions + ); + + if (print) await Self.rawSql('CALL vn.collection_printSticker(?,NULL)', [id], myOptions); + + for (let ticket of tickets) { + let observations = ticket.observaciones.split(' '); + + for (let observation of observations) { + const salesPerson = ticket.salesPersonFk; + if (observation.startsWith('#') || observation.startsWith('@')) { + await models.Chat.send(ctx, + observation, + $t('ticketCommercial', {ticket: ticket.ticketFk, salesPerson}) + ); + } + } + } + + return getCollection(id, tickets, sales, placements, myOptions); + }; + + async function getCollection(id, tickets, sales, placements, options) { + const collection = { + collectionFk: id, + tickets: [], + }; + for (let ticket of tickets) { + const {ticketFk} = ticket; + ticket.sales = []; + + const barcodes = await getBarcodes(ticketFk, options); + await Self.rawSql( + 'CALL util.log_add(?, ?, ?, ?, ?, ?, ?, ?)', + ['vn', 'ticket', 'Ticket', ticketFk, ticketFk, 'select', null, null], + options + ); + + for (let sale of sales) { + if (sale.ticketFk == ticketFk) { + sale.placements = []; + for (const salePlacement of placements) { + if (salePlacement.saleFk == sale.saleFk && salePlacement.order) { + const placement = { + saleFk: salePlacement.saleFk, + itemFk: salePlacement.itemFk, + placement: salePlacement.placement, + shelving: salePlacement.shelving, + created: salePlacement.created, + visible: salePlacement.visible, + order: salePlacement.order, + grouping: salePlacement.grouping, + priority: salePlacement.priority, + saleOrder: salePlacement.saleOrder, + isPreviousPrepared: salePlacement.isPreviousPrepared, + itemShelvingSaleFk: salePlacement.itemShelvingSaleFk, + ticketFk: salePlacement.ticketFk, + id: salePlacement.id + }; + sale.placements.push(placement); + } + } + + sale.barcodes = []; + for (const barcode of barcodes) { + if (barcode.movementId == sale.saleFk) { + if (barcode.code) { + sale.barcodes.push(barcode.code); + sale.barcodes.push(`0 ${barcode.code}`); + } + + if (barcode.id) { + sale.barcodes.push(barcode.id); + sale.barcodes.push(`0 ${barcode.id}`); + } + } + } + + ticket.sales.push(sale); + } + } + collection.tickets.push(ticket); + } + + return collection; + } + + async function getBarcodes(ticketId, options) { + const query = + `SELECT s.id movementId, + b.code, + c.id + FROM vn.sale s + LEFT JOIN vn.itemBarcode b ON b.itemFk = s.itemFk + LEFT JOIN vn.buy c ON c.itemFk = s.itemFk + LEFT JOIN vn.entry e ON e.id = c.entryFk + LEFT JOIN vn.travel tr ON tr.id = e.travelFk + WHERE s.ticketFk = ? + AND tr.landed >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)`; + return Self.rawSql(query, [ticketId], options); + } +}; diff --git a/back/methods/collection/spec/assign.spec.js b/back/methods/collection/spec/assign.spec.js new file mode 100644 index 000000000..745343819 --- /dev/null +++ b/back/methods/collection/spec/assign.spec.js @@ -0,0 +1,38 @@ +const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); + +describe('ticket assign()', () => { + let ctx; + let options; + let tx; + beforeEach(async() => { + ctx = { + req: { + accessToken: {userId: 1106}, + headers: {origin: 'http://localhost'}, + __: value => value + }, + args: {} + }; + + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: ctx.req + }); + + options = {transaction: tx}; + tx = await models.Sale.beginTransaction({}); + options.transaction = tx; + }); + + afterEach(async() => { + await tx.rollback(); + }); + + it('should throw an error when there is not picking tickets', async() => { + try { + await models.Collection.assign(ctx, options); + } catch (e) { + expect(e.message).toEqual('There are not picking tickets'); + } + }); +}); diff --git a/back/methods/collection/spec/getSales.spec.js b/back/methods/collection/spec/getSales.spec.js new file mode 100644 index 000000000..e6205cc79 --- /dev/null +++ b/back/methods/collection/spec/getSales.spec.js @@ -0,0 +1,62 @@ +const {models} = require('vn-loopback/server/server'); + +describe('collection getSales()', () => { + const collectionOrTicketFk = 999999; + const print = true; + const source = 'CHECKER'; + + beforeAll(() => { + ctx = { + req: { + accessToken: {userId: 9}, + headers: {origin: 'http://localhost'}, + } + }; + }); + + it('should return a collection with tickets, placements and barcodes settled correctly', async() => { + const tx = await models.Collection.beginTransaction({}); + const options = {transaction: tx}; + try { + const collection = await models.Collection.getSales(ctx, + collectionOrTicketFk, print, source, options); + + const [firstTicket] = collection.tickets; + const [firstSale] = firstTicket.sales; + const [firstPlacement] = firstSale.placements; + + expect(collection.tickets.length).toBeTruthy(); + expect(collection.collectionFk).toEqual(firstTicket.ticketFk); + + expect(firstSale.ticketFk).toEqual(firstTicket.ticketFk); + expect(firstSale.placements.length).toBeTruthy(); + expect(firstSale.barcodes.length).toBeTruthy(); + + expect(firstSale.saleFk).toEqual(firstPlacement.saleFk); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should print a sticker', async() => { + const tx = await models.Collection.beginTransaction({}); + const options = {transaction: tx}; + const query = 'SELECT * FROM printQueue pq JOIN printQueueArgs pqa ON pqa.printQueueFk = pq.id'; + try { + const printQueueBefore = await models.Collection.rawSql( + query, [], options); + await models.Collection.getSales(ctx, + collectionOrTicketFk, true, source, options); + const printQueueAfter = await models.Collection.rawSql( + query, [], options); + + expect(printQueueAfter.length).toEqual(printQueueBefore.length + 1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/back/methods/machine-worker/specs/updateInTime.spec.js b/back/methods/machine-worker/specs/updateInTime.spec.js new file mode 100644 index 000000000..f166214b0 --- /dev/null +++ b/back/methods/machine-worker/specs/updateInTime.spec.js @@ -0,0 +1,132 @@ +const {models} = require('vn-loopback/server/server'); + +describe('machineWorker updateInTime()', () => { + const itBoss = 104; + const davidCharles = 1106; + + beforeAll(async() => { + ctx = { + req: { + accessToken: {}, + headers: {origin: 'http://localhost'}, + __: value => value + } + }; + }); + + it('should throw an error if the plate does not exist', async() => { + const tx = await models.MachineWorker.beginTransaction({}); + const options = {transaction: tx}; + const plate = 'RE-123'; + ctx.req.accessToken.userId = 1106; + try { + await models.MachineWorker.updateInTime(ctx, plate, options); + await tx.rollback(); + } catch (e) { + const error = e; + + expect(error.message).toContain('the plate does not exist'); + await tx.rollback(); + } + }); + + it('should grab a machine where is not in use', async() => { + const tx = await models.MachineWorker.beginTransaction({}); + const options = {transaction: tx}; + const plate = 'RE-003'; + ctx.req.accessToken.userId = 1107; + try { + const totalBefore = await models.MachineWorker.find(null, options); + await models.MachineWorker.updateInTime(ctx, plate, options); + const totalAfter = await models.MachineWorker.find(null, options); + + expect(totalAfter.length).toEqual(totalBefore.length + 1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + } + }); + + describe('less than 12h', () => { + const plate = 'RE-001'; + it('should trow an error if it is not himself', async() => { + const tx = await models.MachineWorker.beginTransaction({}); + const options = {transaction: tx}; + ctx.req.accessToken.userId = davidCharles; + + try { + await models.MachineWorker.updateInTime(ctx, plate, options); + await tx.rollback(); + } catch (e) { + const error = e; + + expect(error.message).toContain('This machine is already in use'); + await tx.rollback(); + } + }); + + it('should throw an error if it is himself with a different machine', async() => { + const tx = await models.MachineWorker.beginTransaction({}); + const options = {transaction: tx}; + ctx.req.accessToken.userId = itBoss; + const plate = 'RE-003'; + try { + await models.MachineWorker.updateInTime(ctx, plate, options); + await tx.rollback(); + } catch (e) { + const error = e; + + expect(error.message).toEqual('You are already using a machine'); + await tx.rollback(); + } + }); + + it('should set the out time if it is himself', async() => { + const tx = await models.MachineWorker.beginTransaction({}); + const options = {transaction: tx}; + ctx.req.accessToken.userId = itBoss; + + try { + const isNotParked = await models.MachineWorker.findOne({ + where: {workerFk: itBoss} + }, options); + await models.MachineWorker.updateInTime(ctx, plate, options); + const isParked = await models.MachineWorker.findOne({ + where: {workerFk: itBoss} + }, options); + + expect(isNotParked.outTime).toBeNull(); + expect(isParked.outTime).toBeDefined(); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + } + }); + }); + + describe('equal or more than 12h', () => { + const plate = 'RE-002'; + it('should set the out time and grab the machine', async() => { + const tx = await models.MachineWorker.beginTransaction({}); + const options = {transaction: tx}; + ctx.req.accessToken.userId = davidCharles; + const filter = { + where: {workerFk: davidCharles, machineFk: 2} + }; + try { + const isNotParked = await models.MachineWorker.findOne(filter, options); + const totalBefore = await models.MachineWorker.find(null, options); + await models.MachineWorker.updateInTime(ctx, plate, options); + const isParked = await models.MachineWorker.findOne(filter, options); + const totalAfter = await models.MachineWorker.find(null, options); + + expect(isNotParked.outTime).toBeNull(); + expect(isParked.outTime).toBeDefined(); + expect(totalAfter.length).toEqual(totalBefore.length + 1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + } + }); + }); +}); diff --git a/back/methods/machine-worker/updateInTime.js b/back/methods/machine-worker/updateInTime.js new file mode 100644 index 000000000..8f663302d --- /dev/null +++ b/back/methods/machine-worker/updateInTime.js @@ -0,0 +1,77 @@ +const UserError = require('vn-loopback/util/user-error'); +module.exports = Self => { + Self.remoteMethodCtx('updateInTime', { + description: 'Updates the corresponding registry if the worker has been registered in the last few hours', + accessType: 'WRITE', + accepts: [ + { + arg: 'plate', + type: 'string', + } + ], + http: { + path: `/updateInTime`, + verb: 'POST' + } + }); + + Self.updateInTime = async(ctx, plate, options) => { + const models = Self.app.models; + const userId = ctx.req.accessToken.userId; + const $t = ctx.req.__; + + let tx; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const machine = await models.Machine.findOne({ + fields: ['id', 'plate'], + where: {plate} + }, myOptions); + + if (!machine) + throw new Error($t('the plate does not exist', {plate})); + + const machineWorker = await Self.findOne({ + where: { + or: [{machineFk: machine.id}, {workerFk: userId}], + outTime: null, + } + }, myOptions); + + const {maxHours} = await models.MachineWorkerConfig.findOne({fields: ['maxHours']}, myOptions); + const hoursDifference = (Date.vnNow() - machineWorker.inTime.getTime()) / (60 * 60 * 1000); + + if (machineWorker) { + const isHimself = userId == machineWorker.workerFk; + const isSameMachine = machine.id == machineWorker.machineFk; + + if (hoursDifference < maxHours && !isHimself) + throw new UserError($t('This machine is already in use.')); + + if (hoursDifference < maxHours && isHimself && !isSameMachine) + throw new UserError($t('You are already using a machine')); + + await machineWorker.updateAttributes({ + outTime: Date.vnNew() + }, myOptions); + } + + if (!machineWorker || hoursDifference >= maxHours) + await models.MachineWorker.create({machineFk: machine.id, workerFk: userId}, myOptions); + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/back/methods/mobile-app-version-control/getVersion.js b/back/methods/mobile-app-version-control/getVersion.js new file mode 100644 index 000000000..38f4acc54 --- /dev/null +++ b/back/methods/mobile-app-version-control/getVersion.js @@ -0,0 +1,45 @@ +module.exports = Self => { + Self.remoteMethodCtx('getVersion', { + description: 'gets app version data', + accessType: 'READ', + accepts: [{ + arg: 'app', + type: 'string', + required: true + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/getVersion`, + verb: 'GET' + } + }); + + Self.getVersion = async(ctx, app) => { + const {models} = Self.app; + const userId = ctx.req.accessToken.userId; + + const workerFk = await models.WorkerAppTester.findOne({ + where: { + workerFk: userId + } + }); + let fields = ['id', 'appName']; + + if (workerFk) + fields = fields.concat(['isVersionBetaCritical', 'versionBeta', 'urlBeta']); + else + fields = fields.concat(['isVersionCritical', 'version', 'urlProduction']); + + const filter = { + where: { + appName: app + }, + fields, + }; + + return Self.findOne(filter); + }; +}; diff --git a/back/methods/mobile-app-version-control/specs/getVersion.spec.js b/back/methods/mobile-app-version-control/specs/getVersion.spec.js new file mode 100644 index 000000000..59d794ccf --- /dev/null +++ b/back/methods/mobile-app-version-control/specs/getVersion.spec.js @@ -0,0 +1,29 @@ +const {models} = require('vn-loopback/server/server'); + +describe('mobileAppVersionControl getVersion()', () => { + const appName = 'delivery'; + beforeAll(async() => { + ctx = { + req: { + accessToken: {}, + headers: {origin: 'http://localhost'}, + } + }; + }); + + it('should get the version app', async() => { + ctx.req.accessToken.userId = 9; + const {version, versionBeta} = await models.MobileAppVersionControl.getVersion(ctx, appName); + + expect(version).toEqual('9.2'); + expect(versionBeta).toBeUndefined(); + }); + + it('should get the beta version app', async() => { + ctx.req.accessToken.userId = 66; + const {version, versionBeta} = await models.MobileAppVersionControl.getVersion(ctx, appName); + + expect(versionBeta).toBeDefined(); + expect(version).toBeUndefined(); + }); +}); diff --git a/back/model-config.json b/back/model-config.json index c4eefd932..f48ec11e6 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -13,10 +13,10 @@ "AuthCode": { "dataSource": "vn" }, - "Bank": { + "Accounting": { "dataSource": "vn" }, - "Buyer": { + "Buyer": { "dataSource": "vn" }, "Campaign": { @@ -79,15 +79,24 @@ "Language": { "dataSource": "vn" }, + "Machine": { + "dataSource": "vn" + }, "MachineWorker": { "dataSource": "vn" }, + "MachineWorkerConfig": { + "dataSource": "vn" + }, "MobileAppVersionControl": { "dataSource": "vn" }, "Module": { "dataSource": "vn" }, + "MrwConfig": { + "dataSource": "vn" + }, "Notification": { "dataSource": "vn" }, @@ -160,10 +169,10 @@ "VnRole": { "dataSource": "vn" }, - "MrwConfig": { + "WorkerActivity": { + "dataSource": "vn" + }, + "WorkerActivityType": { "dataSource": "vn" } -} - - - +} \ No newline at end of file diff --git a/back/models/bank.json b/back/models/accounting.json similarity index 85% rename from back/models/bank.json rename to back/models/accounting.json index da73b1141..979947471 100644 --- a/back/models/bank.json +++ b/back/models/accounting.json @@ -1,9 +1,9 @@ { - "name": "Bank", + "name": "Accounting", "base": "VnModel", "options": { "mysql": { - "table": "bank" + "table": "accounting" } }, "properties": { @@ -22,10 +22,7 @@ }, "accountingTypeFk": { "type": "number", - "required": true, - "mysql": { - "columnName": "cash" - } + "required": true }, "entityFk": { "type": "number", diff --git a/back/models/collection.js b/back/models/collection.js index 52ef26e88..f2c2f1566 100644 --- a/back/models/collection.js +++ b/back/models/collection.js @@ -3,4 +3,6 @@ module.exports = Self => { require('../methods/collection/setSaleQuantity')(Self); require('../methods/collection/previousLabel')(Self); require('../methods/collection/getTickets')(Self); + require('../methods/collection/assign')(Self); + require('../methods/collection/getSales')(Self); }; diff --git a/back/models/machine-worker-config.json b/back/models/machine-worker-config.json new file mode 100644 index 000000000..dfb77124e --- /dev/null +++ b/back/models/machine-worker-config.json @@ -0,0 +1,18 @@ +{ + "name": "MachineWorkerConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "vn.machineWorkerConfig" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "maxHours": { + "type": "number" + } + } +} diff --git a/back/models/machine-worker.js b/back/models/machine-worker.js new file mode 100644 index 000000000..cbc5fd53e --- /dev/null +++ b/back/models/machine-worker.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/machine-worker/updateInTime')(Self); +}; diff --git a/back/models/machine.json b/back/models/machine.json new file mode 100644 index 000000000..7029091a2 --- /dev/null +++ b/back/models/machine.json @@ -0,0 +1,18 @@ +{ + "name": "Machine", + "base": "VnModel", + "options": { + "mysql": { + "table": "vn.machine" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "plate": { + "type": "string" + } + } +} diff --git a/back/models/mobile-app-version-control.js b/back/models/mobile-app-version-control.js new file mode 100644 index 000000000..ee8fa2ab6 --- /dev/null +++ b/back/models/mobile-app-version-control.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/mobile-app-version-control/getVersion')(Self); +}; diff --git a/back/models/mobile-app-version-control.json b/back/models/mobile-app-version-control.json new file mode 100644 index 000000000..819ad33f5 --- /dev/null +++ b/back/models/mobile-app-version-control.json @@ -0,0 +1,39 @@ +{ + "name": "MobileAppVersionControl", + "base": "VnModel", + "options": { + "mysql": { + "table": "vn.mobileAppVersionControl" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "appName": { + "type": "string" + }, + + "version": { + "type": "string" + }, + + "isVersionCritical": { + "type": "boolean" + }, + + "urlProduction": { + "type": "string" + }, + "urlBeta": { + "type": "string" + }, + "versionBeta": { + "type": "string" + }, + "isVersionBetaCritical": { + "type": "boolean" + } + } +} diff --git a/back/models/payment.json b/back/models/payment.json index 7eca36e4d..ed354969e 100644 --- a/back/models/payment.json +++ b/back/models/payment.json @@ -47,7 +47,7 @@ }, "bank": { "type": "belongsTo", - "model": "Bank", + "model": "Accounting", "foreignKey": "bankFk" }, "payMethod": { diff --git a/back/models/workerActivity.json b/back/models/workerActivity.json new file mode 100644 index 000000000..e3b994f77 --- /dev/null +++ b/back/models/workerActivity.json @@ -0,0 +1,39 @@ +{ + "name": "WorkerActivity", + "base": "VnModel", + "options": { + "mysql": { + "table": "workerActivity" + } + }, + "properties": { + "id": { + "id": true, + "type": "number" + }, + "created": { + "type": "date" + }, + "model": { + "type": "string" + }, + "event": { + "type": "string" + }, + "description": { + "type": "string" + }, + "relations": { + "workerFk": { + "type": "belongsTo", + "model": "Worker", + "foreignKey": "workerFk" + }, + "workerActivityTypeFk": { + "type": "belongsTo", + "model": "WorkerActivityType", + "foreignKey": "workerActivityTypeFk" + } + } + } +} \ No newline at end of file diff --git a/back/models/workerActivityType.json b/back/models/workerActivityType.json new file mode 100644 index 000000000..f010363a7 --- /dev/null +++ b/back/models/workerActivityType.json @@ -0,0 +1,19 @@ +{ + "name": "WorkerActivityType", + "base": "VnModel", + "options": { + "mysql": { + "table": "workerActivityType" + } + }, + "properties": { + "code": { + "id": true, + "type": "string" + }, + "description": { + "type": "string", + "required": false + } + } +} \ No newline at end of file diff --git a/db/dump/.dump/data.sql b/db/dump/.dump/data.sql index e9801647e..905847119 100644 --- a/db/dump/.dump/data.sql +++ b/db/dump/.dump/data.sql @@ -1393,8 +1393,6 @@ INSERT INTO `ACL` VALUES (385,'Route','driverRoutePdf','READ','ALLOW','ROLE','em INSERT INTO `ACL` VALUES (386,'Route','driverRouteEmail','WRITE','ALLOW','ROLE','employee'); INSERT INTO `ACL` VALUES (387,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','customer'); INSERT INTO `ACL` VALUES (388,'Supplier','newSupplier','WRITE','ALLOW','ROLE','administrative'); -INSERT INTO `ACL` VALUES (389,'ClaimRma','*','READ','ALLOW','ROLE','claimManager'); -INSERT INTO `ACL` VALUES (390,'ClaimRma','*','WRITE','ALLOW','ROLE','claimManager'); INSERT INTO `ACL` VALUES (391,'Notification','*','WRITE','ALLOW','ROLE','system'); INSERT INTO `ACL` VALUES (392,'Boxing','*','*','ALLOW','ROLE','employee'); INSERT INTO `ACL` VALUES (393,'Url','*','READ','ALLOW','ROLE','employee'); diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index cb9ee0fe6..4ad007f5c 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -1239,6 +1239,7 @@ INSERT INTO `vn`.`train`(`id`, `name`) INSERT INTO `vn`.`operator` (`workerFk`, `numberOfWagons`, `trainFk`, `itemPackingTypeFk`, `warehouseFk`, `sectorFk`, `labelerFk`) VALUES ('1106', '1', '1', 'H', '1', '1', '1'), + ('9', '2', '1', 'H', '1', '1', '1'), ('1107', '1', '1', 'V', '1', '1', '1'); INSERT INTO `vn`.`collection`(`id`, `workerFk`, `stateFk`, `created`, `trainFk`) @@ -1819,19 +1820,16 @@ INSERT INTO `vn`.`clientSample`(`id`, `clientFk`, `typeFk`, `created`, `workerFk INSERT INTO `vn`.`claimState`(`id`, `code`, `description`, `roleFk`, `priority`, `hasToNotify`) VALUES ( 1, 'pending', 'Pendiente', 1, 1, 0), - ( 2, 'managed', 'Gestionado', 72, 5, 0), ( 3, 'resolved', 'Resuelto', 72, 7, 0), ( 4, 'canceled', 'Anulado', 72, 6, 1), - ( 5, 'incomplete', 'Incompleta', 1, 3, 1), - ( 6, 'mana', 'Mana', 72, 4, 0), - ( 7, 'lack', 'Faltas', 72, 2, 0); + ( 5, 'incomplete', 'Incompleta', 1, 3, 1); -INSERT INTO `vn`.`claim`(`id`, `ticketCreated`, `claimStateFk`, `clientFk`, `workerFk`, `responsibility`, `isChargedToMana`, `created`, `packages`, `rma`, `ticketFk`) +INSERT INTO `vn`.`claim`(`id`, `ticketCreated`, `claimStateFk`, `clientFk`, `workerFk`, `responsibility`, `isChargedToMana`, `created`, `packages`, `ticketFk`) VALUES - (1, util.VN_CURDATE(), 1, 1101, 18, 3, 0, util.VN_CURDATE(), 0, '02676A049183', 11), - (2, util.VN_CURDATE(), 2, 1101, 18, 3, 0, util.VN_CURDATE(), 1, NULL, 16), - (3, util.VN_CURDATE(), 3, 1101, 18, 1, 1, util.VN_CURDATE(), 5, NULL, 7), - (4, util.VN_CURDATE(), 3, 1104, 18, 5, 0, util.VN_CURDATE(), 10, NULL, 8); + (1, util.VN_CURDATE(), 1, 1101, 18, 3, 0, util.VN_CURDATE(), 0, 11), + (2, util.VN_CURDATE(), 4, 1101, 18, 3, 0, util.VN_CURDATE(), 1, 16), + (3, util.VN_CURDATE(), 3, 1101, 18, 1, 1, util.VN_CURDATE(), 5, 7), + (4, util.VN_CURDATE(), 3, 1104, 18, 5, 0, util.VN_CURDATE(), 10, 8); INSERT INTO `vn`.`claimObservation` (`claimFk`, `workerFk`, `text`, `created`) VALUES @@ -1880,14 +1878,6 @@ INSERT INTO `vn`.`claimRatio`(`clientFk`, `yearSale`, `claimAmount`, `claimingRa (1103, 2000, 0.00, 0.00, 0.02, 1.00), (1104, 2500, 150.00, 0.02, 0.10, 1.00); -INSERT INTO vn.claimRma (`id`, `code`, `created`, `workerFk`) - VALUES - (1, '02676A049183', DEFAULT, 1106), - (2, '02676A049183', DEFAULT, 1106), - (3, '02676A049183', DEFAULT, 1107), - (4, '02676A049183', DEFAULT, 1107), - (5, '01837B023653', DEFAULT, 1106); - INSERT INTO `vn`.`claimLog` (`originFk`, userFk, `action`, changedModel, oldInstance, newInstance, changedModelId, `description`) VALUES (1, 18, 'update', 'Claim', '{"hasToPickUp":false}', '{"hasToPickUp":true}', 1, NULL), @@ -2737,10 +2727,10 @@ INSERT INTO `vn`.`chat` (`senderFk`, `recipient`, `dated`, `checkUserStatus`, `m (1101, '@PetterParker', util.VN_CURDATE(), 0, 'Second test message', 0, 'pending'); -INSERT INTO `vn`.`mobileAppVersionControl` (`appName`, `version`, `isVersionCritical`) +INSERT INTO `vn`.`mobileAppVersionControl` (`appName`, `version`, `isVersionCritical`,`versionBeta`) VALUES - ('delivery', '9.2', 0), - ('warehouse', '8.1', 0); + ('delivery', '9.2', 0,'9.7'), + ('warehouse', '8.1', 0,'8.3'); INSERT INTO `vn`.`machine` (`plate`, `maker`, `model`, `warehouseFk`, `departmentFk`, `type`, `use`, `productionYear`, `workerFk`, `companyFk`) VALUES @@ -3077,3 +3067,669 @@ INSERT INTO `vn`.`cmr` (id,truckPlate,observations,senderInstruccions,paymentIns UPDATE vn.department SET workerFk = null; + +-- NEW WAREHOUSE + +INSERT INTO vn.packaging + VALUES('--', 2745600.00, 100.00, 120.00, 220.00, 0.00, 1, '2001-01-01 00:00:00.000', NULL, NULL, NULL, 0.00, 16, 0.00, 0, NULL, 0.00, NULL, NULL, 0, NULL, 0, 0); + + +INSERT IGNORE INTO vn.intrastat + SET id = 44219999, + description = 'Manufacturas de madera', + taxClassFk = 1, + taxCodeFk = 1; + +INSERT IGNORE INTO vn.warehouse + SET id = 999, + name = 'TestingWarehouse', + hasAvailable = TRUE, + isForTicket = TRUE, + isInventory = TRUE, + hasUbications = TRUE, + hasProduction = TRUE; + +INSERT IGNORE INTO vn.sector + SET id = 9991, + description = 'NormalSector', + warehouseFk = 999, + code = 'NS', + isPackagingArea = FALSE, + sonFk = NULL, + isMain = TRUE, + itemPackingTypeFk = NULL; + +INSERT IGNORE INTO vn.sector + SET id = 9992, + description = 'PreviousSector', + warehouseFk = 999, + code = 'PS', + isPackagingArea = FALSE, + sonFk = NULL, + isMain = TRUE, + itemPackingTypeFk = NULL; + +INSERT IGNORE INTO vn.sector + SET id = 9993, + description = 'MezaninneSector', + warehouseFk = 999, + code = 'MS', + isPackagingArea = FALSE, + sonFk = 9991, + isMain = TRUE, + itemPackingTypeFk = NULL; + + +INSERT INTO vn.parking (id,sectorFk, code, pickingOrder) + VALUES (4,9991, 'A-01-1', 1), + (5,9991, 'A-02-2', 2), + (6,9991, 'A-03-3', 3), + (7,9991, 'A-04-4', 4), + (8,9991, 'A-05-5', 5), + (9,9992, 'P-01-1', 6), + (10,9992, 'P-02-2', 7), + (11,9992, 'P-03-3', 8), + (12,9993, 'M-01-1', 9), + (13,9993, 'M-02-2', 10), + (14,9993, 'M-03-3', 11); + +INSERT INTO vn.shelving (code, parkingFk, priority) + VALUES ('NAA', 4, 1), + ('NBB', 5, 1), + ('NCC', 6, 1), + ('NDD', 7, 1), + ('NEE', 8, 1), + ('PAA', 9, 1), + ('PBB', 10, 1), + ('PCC', 11, 1), + ('MAA', 12, 1), + ('MBB', 13, 1), + ('MCC', 14, 1); + +INSERT IGNORE INTO vn.itemType + SET id = 999, + code = 'WOO', + name = 'Wood Objects', + categoryFk = 3, + workerFk = 103, + isInventory = TRUE, + life = 10, + density = 250, + itemPackingTypeFk = NULL, + temperatureFk = 'warm'; + +INSERT IGNORE INTO vn.travel + SET id = 99, + shipped = CURDATE(), + landed = CURDATE(), + warehouseInFk = 999, + warehouseOutFk = 1, + isReceived = TRUE; + +INSERT INTO vn.entry + SET id = 999, + supplierFk = 791, + isConfirmed = TRUE, + dated = CURDATE(), + travelFk = 99, + companyFk = 442; + +INSERT INTO vn.ticket + SET id = 999999, + clientFk = 2, + warehouseFk = 999, + shipped = CURDATE(), + nickname = 'Cliente', + addressFk = 1, + companyFk = 442, + agencyModeFk = 10, + landed = CURDATE(); + +INSERT INTO vn.collection + SET id = 10101010, + workerFk = 9; + +INSERT IGNORE INTO vn.ticketCollection + SET id = 10101010, + ticketFk = 999999, + collectionFk = 10101010; + +INSERT INTO vn.item + SET id = 999991, + name = 'Palito para pinchos', + `size` = 25, + stems = NULL, + category = 'EXT', + typeFk = 999, + longName = 'Palito para pinchos', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 6, + intrastatFk = 44219999; + +INSERT INTO vn.buy + SET id = 9999991, + entryFk = 999, + itemFk = 999991, + quantity = 8, + buyingValue = 0.61, + stickers = 1, + packing = 20, + `grouping` = 1, + groupingMode = 1, + packageFk = 94, + price1 = 1, + price2 = 1, + price3 = 1, + minPrice = 1, + weight = 50; + +INSERT INTO vn.sale + SET id = 99991, + itemFk = 999991, + ticketFk = 999999, + concept = 'Palito para pinchos', + quantity = 3, + price = 1, + discount = 0; + +INSERT INTO vn.item + SET id = 999992, + name = 'Madera verde', + `size` = 10, + stems = NULL, + category = 'EXT', + typeFk = 999, + longName = 'Madera verde', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 50, + intrastatFk = 44219999; + +INSERT INTO vn.buy + SET id = 9999992, + entryFk = 999, + itemFk = 999992, + quantity = 40, + buyingValue = 0.62, + stickers = 1, + packing = 40, + `grouping` = 5, + groupingMode = 1, + packageFk = 94, + price1 = 1, + price2 = 1, + price3 = 1, + minPrice = 1, + weight = 25; + +INSERT INTO vn.sale + SET id = 99992, + itemFk = 999992, + ticketFk = 999999, + concept = 'Madera Verde', + quantity = 10, + price = 1, + discount = 0; + +INSERT INTO vn.item + SET id = 999993, + name = 'Madera Roja/Morada', + `size` = 12, + stems = 2, + category = 'EXT', + typeFk = 999, + longName = 'Madera Roja/Morada', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 35, + intrastatFk = 44219999; + +INSERT INTO vn.buy + SET id = 9999993, + entryFk = 999, + itemFk = 999993, + quantity = 20, + buyingValue = 0.63, + stickers = 2, + packing = 10, + `grouping` = 5, + groupingMode = 1, + packageFk = 94, + price1 = 1, + price2 = 1, + price3 = 1, + minPrice = 1, + weight = 25; + +INSERT INTO vn.itemShelving + SET id = 9931, + itemFk = 999993, + shelvingFk = 'NCC', + visible = 10, + `grouping` = 5, + packing = 10; + +INSERT INTO vn.sale + SET id = 99993, + itemFk = 999993, + ticketFk = 999999, + concept = 'Madera Roja/Morada', + quantity = 15, + price = 1, + discount = 0; + +INSERT INTO vn.item + SET id = 999994, + name = 'Madera Naranja', + `size` = 18, + stems = 1, + category = 'EXT', + typeFk = 999, + longName = 'Madera Naranja', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 160, + intrastatFk = 44219999; + +INSERT INTO vn.buy + SET id = 9999994, + entryFk = 999, + itemFk = 999994, + quantity = 20, + buyingValue = 0.64, + stickers = 1, + packing = 20, + `grouping` = 4, + groupingMode = 1, + packageFk = 94, + price1 = 1, + price2 = 1, + price3 = 1, + minPrice = 1, + weight = 25; + +INSERT INTO vn.sale + SET id = 99994, + itemFk = 999994, + ticketFk = 999999, + concept = 'Madera Naranja', + quantity = 4, + price = 1, + discount = 0; + +INSERT INTO vn.item + SET id = 999995, + name = 'Madera Amarilla', + `size` = 11, + stems = 5, + category = 'EXT', + typeFk = 999, + longName = 'Madera Amarilla', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 78, + intrastatFk = 44219999; + +INSERT INTO vn.buy + SET id = 9999995, + entryFk = 999, + itemFk = 999995, + quantity = 4, + buyingValue = 0.65, + stickers = 1, + packing = 20, + `grouping` = 1, + groupingMode = 1, + packageFk = 94, + price1 = 1, + price2 = 1, + price3 = 1, + minPrice = 1, + weight = 35; + +INSERT INTO vn.sale + SET id = 99995, + itemFk = 999995, + ticketFk = 999999, + concept = 'Madera Amarilla', + quantity = 5, + price = 1, + discount = 0; + +-- Palito naranja +INSERT INTO vn.item + SET id = 999998, + name = 'Palito naranja', + `size` = 11, + stems = 1, + category = 'EXT', + typeFk = 999, + longName = 'Palito naranja', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 78, + intrastatFk = 44219999; + +INSERT INTO vn.buy + SET id = 9999998, + entryFk = 999, + itemFk = 999998, + quantity = 80, + buyingValue = 0.65, + stickers = 1, + packing = 200, + `grouping` = 30, + groupingMode = 1, + packageFk = 94, + price1 = 1, + price2 = 1, + price3 = 1, + minPrice = 1, + weight = 35; + +INSERT INTO vn.sale + SET id = 99998, + itemFk = 999998, + ticketFk = 999999, + concept = 'Palito naranja', + quantity = 60, + price = 1, + discount = 0; + +-- Palito amarillo +INSERT INTO vn.item + SET id = 999999, + name = 'Palito amarillo', + `size` = 11, + stems = 1, + category = 'EXT', + typeFk = 999, + longName = 'Palito amarillo', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 78, + intrastatFk = 44219999; + +INSERT INTO vn.buy + SET id = 9999999, + entryFk = 999, + itemFk = 999999, + quantity = 70, + buyingValue = 0.65, + stickers = 1, + packing = 500, + `grouping` = 10, + groupingMode = 1, + packageFk = 94, + price1 = 1, + price2 = 1, + price3 = 1, + minPrice = 1, + weight = 35; + +INSERT INTO vn.sale + SET id = 99999, + itemFk = 999999, + ticketFk = 999999, + concept = 'Palito amarillo', + quantity = 50, + price = 1, + discount = 0; + +-- Palito azul +INSERT INTO vn.item + SET id = 1000000, + name = 'Palito azul', + `size` = 10, + stems = 1, + category = 'EXT', + typeFk = 999, + longName = 'Palito azul', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 78, + intrastatFk = 44219999; + +INSERT INTO vn.buy + SET id = 10000000, + entryFk = 999, + itemFk = 1000000, + quantity = 75, + buyingValue = 0.65, + stickers = 2, + packing = 300, + `grouping` = 50, + groupingMode = 1, + packageFk = 94, + price1 = 1, + price2 = 1, + price3 = 1, + minPrice = 1, + weight = 35; + +INSERT INTO vn.sale + SET id = 100000, + itemFk = 1000000, + ticketFk = 999999, + concept = 'Palito azul', + quantity = 50, + price = 1, + discount = 0; + +-- Palito rojo +INSERT INTO vn.item + SET id = 1000001, + name = 'Palito rojo', + `size` = 10, + stems = NULL, + category = 'EXT', + typeFk = 999, + longName = 'Palito rojo', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 78, + intrastatFk = 44219999; + +INSERT INTO vn.buy + SET id = 10000001, + entryFk = 999, + itemFk = 1000001, + quantity = 12, + buyingValue = 0.65, + stickers = 2, + packing = 50, + `grouping` = 5, + groupingMode = 1, + packageFk = 94, + price1 = 1, + price2 = 1, + price3 = 1, + minPrice = 1, + weight = 35; + + +INSERT INTO vn.sale + SET id = 100001, + itemFk = 1000001, + ticketFk = 999999, + concept = 'Palito rojo', + quantity = 10, + price = 1, + discount = 0; + +-- Previa +INSERT IGNORE INTO vn.item + SET id = 999996, + name = 'Bolas de madera', + `size` = 2, + stems = 4, + category = 'EXT', + typeFk = 999, + longName = 'Bolas de madera', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 20, + intrastatFk = 44219999; + +INSERT vn.buy + SET id = 9999996, + entryFk = 999, + itemFk = 999996, + quantity = 5, + buyingValue = 3, + stickers = 1, + packing = 5, + `grouping` = 2, + groupingMode = 1, + packageFk = 94, + price1 = 7, + price2 = 7, + price3 = 7, + minPrice = 7, + weight = 80; + +INSERT vn.sale + SET id = 99996, + itemFk = 999996, + ticketFk = 999999, + concept = 'Bolas de madera', + quantity = 4, + price = 7, + discount = 0, + isPicked = TRUE; + +INSERT IGNORE INTO vn.item + SET id = 999997, + name = 'Palitos de polo MIX', + `size` = 14, + stems = NULL, + category = 'EXT', + typeFk = 999, + longName = 'Palitos de polo MIX', + itemPackingTypeFk = NULL, + originFk = 1, + weightByPiece = 20, + intrastatFk = 44219999; + +INSERT vn.buy + SET id = 9999997, + entryFk = 999, + itemFk = 999997, + quantity = 100, + buyingValue = 3.2, + stickers = 1, + packing = 100, + `grouping` = 5, + groupingMode = 1, + packageFk = 94, + price1 = 7, + price2 = 7, + price3 = 7, + minPrice = 7, + weight = 80; + +INSERT vn.sale + SET id = 99997, + itemFk = 999997, + ticketFk = 999999, + concept = 'Palitos de polo MIX', + quantity = 5, + price = 7, + discount = 0; + +USE vn; +DELETE ish.* FROM vn.itemShelving ish + JOIN vn.shelving sh ON sh.code = ish.shelvingFk + JOIN vn.parking p ON p.id = sh.parkingFk + JOIN vn.sector s ON s.id = p.sectorFk + JOIN vn.warehouse w ON w.id = s.warehouseFk + WHERE w.name = 'TestingWarehouse'; + +INSERT INTO vn.itemShelving +(itemFk, shelvingFk, visible, created, `grouping`, packing, packagingFk, userFk, isChecked) +VALUES + (999991, 'NAA', 8, '2023-09-20', 1, 20, NULL, 103, NULL), + (999998, 'NAA', 80, '2023-09-20', 10, 30, NULL, 103, NULL), + (1000001, 'NAA', 6, '2023-09-20', 3, 50, NULL, 103, NULL), + (1000000, 'NBB', 50, '2023-09-18', 25, 500, NULL, 103, NULL), + (999993, 'NBB', 25, '2023-09-18', NULL, 10, NULL, 103, NULL), + (999999, 'NBB', 30, '2023-09-18', 10, 500, NULL, 103, NULL), + (999993, 'NCC', 25, '2023-09-20', 5, 10, NULL, 103, NULL), + (999997, 'NCC', 10, '2023-09-20', NULL, 100, NULL, 103, NULL), + (999999, 'NCC', 40, '2023-09-20', 10, 500, NULL, 103, NULL), + (999995, 'NDD', 10, '2023-09-19', NULL, 20, NULL, 103, NULL), + (999994, 'NDD', 48, '2023-09-19', 4, 20, NULL, 103, NULL), + (1000001, 'NEE', 6, '2023-09-21', 3, 50, NULL, 103, NULL), + (999992, 'NEE', 50, '2023-09-21', NULL, 1, NULL, 103, NULL), + (1000000, 'NEE', 25, '2023-09-21', 25, 500, NULL, 103, NULL), + (999996, 'PAA', 5, '2023-09-27', 1, 5, NULL, 103, NULL), + (999997, 'PCC', 10, '2023-09-27', 5, 100, NULL, 103, NULL); + +-- Previous for Bolas de madera +INSERT IGNORE INTO vn.sectorCollection + SET id = 99, + userFk = 1, + sectorFk = 9992; + +INSERT IGNORE INTO vn.saleGroup + SET id = 4, + userFk = 1, + parkingFk = 9, + sectorFk = 9992; + +INSERT IGNORE INTO vn.sectorCollectionSaleGroup + SET id = 9999, + sectorCollectionFk = 99, + saleGroupFk = 999; + +INSERT vn.saleGroupDetail + SET id = 99991, + saleFk = 99996, + saleGroupFk = 999; + +INSERT INTO vn.saleTracking + SET id = 7, + saleFk = 99996, + isChecked = TRUE, + workerFk = 103, + stateFk = 28; + +INSERT IGNORE INTO vn.itemShelvingSale + SET id = 991, + itemShelvingFk = 9962, + saleFk = 99996, + quantity = 5, + userFk = 1; + +UPDATE vn.ticket + SET zoneFk=1 + WHERE id=999999; + +UPDATE vn.collection + SET workerFk=9 + WHERE id=10101010; + +UPDATE vn.sale + SET isPicked =FALSE; + +INSERT INTO vn.machineWorkerConfig(maxHours) + VALUES(12); + +INSERT INTO vn.workerAppTester(workerFk) VALUES(66); + +INSERT INTO `vn`.`machine` (`plate`, `maker`, `model`, `warehouseFk`, `departmentFk`, `type`, `use`, `productionYear`, `workerFk`, `companyFk`) + VALUES + ('RE-003', 'IRON', 'JPH-24', 60, 23, 'ELECTRIC TOW', 'Drag cars', 2020, 103, 442); + + +INSERT INTO vn.machineWorker(workerFk,machineFk,inTimed) VALUES (104,1,'2001-01-01 10:00:00.00.000'); + +UPDATE vn.buy SET itemOriginalFk = 1 WHERE id = 1; + +UPDATE vn.saleTracking SET stateFk = 26 WHERE id = 5; + +INSERT INTO vn.report (name) VALUES ('LabelCollection'); + +INSERT INTO vn.parkingLog(originFk, userFk, `action`, creationDate, description, changedModel,oldInstance, newInstance, changedModelId, changedModelValue) + VALUES(1, 18, 'update', util.VN_CURDATE(), NULL, 'SaleGroup', '{"parkingFk":null}', '{"parkingFk":1}', 1, NULL); \ No newline at end of file diff --git a/db/routines/bs/procedures/manaCustomerUpdate.sql b/db/routines/bs/procedures/manaCustomerUpdate.sql index 2cb25d135..2038f976a 100644 --- a/db/routines/bs/procedures/manaCustomerUpdate.sql +++ b/db/routines/bs/procedures/manaCustomerUpdate.sql @@ -22,7 +22,7 @@ BEGIN FROM vn.component WHERE code = 'manaClaim'; SELECT id INTO vManaBankId - FROM vn.bank WHERE code = 'mana'; + FROM vn.accounting WHERE code = 'mana'; SELECT id INTO vManaGreugeTypeId FROM vn.greugeType WHERE code = 'mana'; diff --git a/db/routines/cache/procedures/clean.sql b/db/routines/cache/procedures/clean.sql index 95841a713..5e6628689 100644 --- a/db/routines/cache/procedures/clean.sql +++ b/db/routines/cache/procedures/clean.sql @@ -1,10 +1,6 @@ DELIMITER $$ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `cache`.`clean`() BEGIN - DECLARE vDateShort DATETIME; - - SET vDateShort = TIMESTAMPADD(MONTH, -1, util.VN_CURDATE()); - - DELETE FROM cache.departure_limit WHERE Fecha < vDateShort; + DELETE FROM cache.departure_limit WHERE Fecha < util.VN_CURDATE() - INTERVAL 1 MONTH; END$$ DELIMITER ; diff --git a/db/routines/hedera/procedures/tpvTransaction_undo.sql b/db/routines/hedera/procedures/tpvTransaction_undo.sql index ed72dd76d..f31ba6a80 100644 --- a/db/routines/hedera/procedures/tpvTransaction_undo.sql +++ b/db/routines/hedera/procedures/tpvTransaction_undo.sql @@ -54,7 +54,7 @@ p: BEGIN FROM vn.`client` WHERE id = vCustomer; SELECT account INTO vAccount - FROM vn.bank WHERE id = vBank; + FROM vn.accounting WHERE id = vBank; DELETE FROM vn.XDiario WHERE SUBCTA = vSubaccount diff --git a/db/routines/sage/procedures/accountingMovements_add.sql b/db/routines/sage/procedures/accountingMovements_add.sql index bd86e132d..575c63f6c 100644 --- a/db/routines/sage/procedures/accountingMovements_add.sql +++ b/db/routines/sage/procedures/accountingMovements_add.sql @@ -253,9 +253,9 @@ BEGIN LIMIT 10000000000000000000 ) sub GROUP BY ASIEN )sub2 ON sub2.ASIEN = x.ASIEN - LEFT JOIN ( SELECT DISTINCT(account),cu.code - FROM vn.bank b - JOIN vn.currency cu ON cu.id = b.currencyFk + LEFT JOIN ( SELECT DISTINCT(a.account),cu.code + FROM vn.accounting a + JOIN vn.currency cu ON cu.id = a.currencyFk WHERE cu.code <> 'EUR' -- no se informa cuando la divisa en EUR )sub3 ON sub3.account = x.SUBCTA WHERE x.enlazadoSage = FALSE diff --git a/db/routines/sage/procedures/pgc_add.sql b/db/routines/sage/procedures/pgc_add.sql index 6dd5bc72d..ebcb2d043 100644 --- a/db/routines/sage/procedures/pgc_add.sql +++ b/db/routines/sage/procedures/pgc_add.sql @@ -17,15 +17,15 @@ BEGIN e.id accountFk, UCASE(e.name), '' - FROM vn.expense e + FROM expense e UNION SELECT company_getCode(vCompanyFk), - b.account, - UCASE(b.bank), + a.account, + UCASE(a.bank), '' - FROM vn.bank b - WHERE b.isActive - AND b.`account` + FROM accounting a + WHERE a.isActive + AND a.`account` UNION SELECT CodigoEmpresa, CodigoCuenta, diff --git a/db/routines/vn/events/sale_checkWithoutComponents.sql b/db/routines/vn/events/sale_checkWithoutComponents.sql deleted file mode 100644 index 2a1ced6ca..000000000 --- a/db/routines/vn/events/sale_checkWithoutComponents.sql +++ /dev/null @@ -1,8 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` EVENT `vn`.`sale_checkWithoutComponents` - ON SCHEDULE EVERY 10 MINUTE - STARTS '2020-05-04 11:56:23.000' - ON COMPLETION PRESERVE - ENABLE -DO call sale_checkNoComponents(DATE_ADD(util.VN_NOW(), INTERVAL -10 MINUTE),DATE_ADD(util.VN_NOW(), INTERVAL -1 MINUTE))$$ -DELIMITER ; diff --git a/db/routines/vn/functions/till_new.sql b/db/routines/vn/functions/till_new.sql index cfca5945d..24f4f2b79 100644 --- a/db/routines/vn/functions/till_new.sql +++ b/db/routines/vn/functions/till_new.sql @@ -34,7 +34,7 @@ BEGIN -- Inserta los asientos contables SELECT account INTO vAccount - FROM bank WHERE id = vBank; + FROM accounting WHERE id = vBank; SELECT accountingAccount INTO vSubaccount FROM `client` WHERE id = vClient; diff --git a/db/routines/vn/procedures/balanceNestTree_addChild.sql b/db/routines/vn/procedures/balanceNestTree_addChild.sql new file mode 100644 index 000000000..5cd1ab470 --- /dev/null +++ b/db/routines/vn/procedures/balanceNestTree_addChild.sql @@ -0,0 +1,52 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`balanceNestTree_addChild`( + vSelf INT, + vName VARCHAR(45) +) +BEGIN +/** + * Agrega un nuevo nodo hijo a un nodo existente dentro de la estructura + * de árbol de vn.balanceNestTree. + * + * @param vSelf Identificador del nodo + * @param vName Nombre del nuevo nodo hijo + */ + DECLARE vTable VARCHAR(45) DEFAULT util.quoteIdentifier('balanceNestTree'); + DECLARE vLeft INT; + + CREATE OR REPLACE TEMPORARY TABLE tAux + SELECT 0 lft; + + EXECUTE IMMEDIATE CONCAT( + 'UPDATE tAux + SET lft = (SELECT lft + FROM ', vTable, + ' WHERE id = ?)') + USING vSelf; + + SELECT lft INTO vLeft FROM tAux; + + EXECUTE IMMEDIATE CONCAT( + 'UPDATE ', vTable, ' + SET rgt = rgt + 2 + WHERE rgt > ? + ORDER BY rgt DESC') + USING vLeft; + + EXECUTE IMMEDIATE CONCAT( + 'UPDATE ', vTable, ' + SET lft = lft + 2 + WHERE lft > ? + ORDER BY lft DESC') + USING vLeft; + + EXECUTE IMMEDIATE CONCAT( + 'INSERT INTO ', vTable, ' (name, lft, rgt) + VALUES(?, ? + 1, ? + 2)') + USING vName, + vLeft, + vLeft; + + DROP TEMPORARY TABLE tAux; +END$$ +DELIMITER ; diff --git a/db/routines/vn/procedures/balanceNestTree_delete.sql b/db/routines/vn/procedures/balanceNestTree_delete.sql new file mode 100644 index 000000000..1d6a9efff --- /dev/null +++ b/db/routines/vn/procedures/balanceNestTree_delete.sql @@ -0,0 +1,53 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`balanceNestTree_delete`( + vSelf INT +) +BEGIN +/** + * Elimina un nodo dentro de la estructura de árbol de vn.balanceNestTree. + * + * @param vSelf Identificador del nodo + */ + DECLARE vTable VARCHAR(45) DEFAULT util.quoteIdentifier('balanceNestTree'); + DECLARE vRight INT; + DECLARE vLeft INT; + DECLARE vWidth INT; + + CREATE OR REPLACE TEMPORARY TABLE tAux + SELECT 0 rgt, 0 lft, 0 wdt; + + EXECUTE IMMEDIATE CONCAT( + 'UPDATE tAux a + JOIN ', vTable, ' t + SET a.rgt = t.rgt, + a.lft = t.lft, + a.wdt = t.rgt - t.lft + 1 + WHERE t.id = ?') + USING vSelf; + + SELECT rgt, lft, wdt + INTO vRight, vLeft, vWidth + FROM tAux; + + EXECUTE IMMEDIATE CONCAT( + 'DELETE FROM ', vTable, + ' WHERE lft BETWEEN ? AND ?') + USING vLeft, vRight; + + EXECUTE IMMEDIATE CONCAT( + 'UPDATE ', vTable, + ' SET rgt = rgt - ? + WHERE rgt > ? + ORDER BY rgt') + USING vWidth,vRight; + + EXECUTE IMMEDIATE CONCAT( + 'UPDATE ', vTable, + ' SET lft = lft - ? + WHERE lft > ? + ORDER BY lft') + USING vWidth, vRight; + + DROP TEMPORARY TABLE tAux; +END$$ +DELIMITER ; diff --git a/db/routines/vn/procedures/balanceNestTree_move.sql b/db/routines/vn/procedures/balanceNestTree_move.sql new file mode 100644 index 000000000..ce29de1d9 --- /dev/null +++ b/db/routines/vn/procedures/balanceNestTree_move.sql @@ -0,0 +1,117 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`balanceNestTree_move`( + vSelf INT, + vFather INT +) +BEGIN +/** + * Mueve un nodo dentro de la estructura de árbol de vn.balanceNestTree. + * + * @param vSelf Identificador del nodo + * @param vFather Identificador del nuevo padre del nodo + */ + DECLARE vTable VARCHAR(45) DEFAULT util.quoteIdentifier('balanceNestTree'); + DECLARE vRight INT; + DECLARE vLeft INT; + DECLARE vWidth INT; + DECLARE vFatherRight INT; + DECLARE vFatherLeft INT; + DECLARE vGap INT; + + CREATE OR REPLACE TEMPORARY TABLE tAux + SELECT 0 rgt, 0 lft, 0 wdt, 0 frg, 0 flf; + + -- Averiguamos el ancho de la rama + EXECUTE IMMEDIATE CONCAT( + 'UPDATE tAux a + JOIN ', vTable, ' t + SET a.wdt = t.rgt - t.lft + 1 + WHERE t.id = ?') + USING vSelf; + + -- Averiguamos la posicion del nuevo padre + EXECUTE IMMEDIATE CONCAT( + 'UPDATE tAux a + JOIN ', vTable, ' t + SET a.frg = t.rgt, + a.flf = t.lft + WHERE t.id = ?') + USING vFather; + + SELECT wdt, frg, flf + INTO vWidth, vFatherRight, vFatherLeft + FROM tAux; + + -- 1º Incrementamos los valores de todos los nodos a la derecha + -- del punto de inserción (vFatherRight) , para hacer sitio + EXECUTE IMMEDIATE CONCAT( + 'UPDATE ', vTable, + 'SET rgt = rgt + ? + WHERE rgt >= ? + ORDER BY rgt DESC') + USING vWidth, + vFatherRight; + + EXECUTE IMMEDIATE CONCAT( + 'UPDATE ', vTable, + 'SET lft = lft + ? + WHERE lft >= ? + ORDER BY lft DESC') + USING vWidth, + vFatherRight; + + -- Es preciso recalcular los valores del nodo en el + -- caso de que estuviera a la derecha del nuevo padre + EXECUTE IMMEDIATE CONCAT( + 'UPDATE tAux a + JOIN ', vTable, ' t + SET a.rgt = t.rgt, + a.lft = t.lft + WHERE t.id = ?') + USING vSelf; + + SELECT lft, rgt, frg - lft + INTO vLeft, vRight, vGap + FROM tAux; + + -- 2º Incrementamos el valor de todos los nodos a + -- trasladar hasta alcanzar su nueva posicion + EXECUTE IMMEDIATE CONCAT( + 'UPDATE ', vTable, + 'SET lft = lft + ? + WHERE lft BETWEEN ? AND ? + ORDER BY lft DESC') + USING vGap, + vLeft, + vRight; + + EXECUTE IMMEDIATE CONCAT( + 'UPDATE ', vTable, + 'SET rgt = rgt + ? + WHERE rgt BETWEEN ? AND ? + ORDER BY rgt DESC') + USING vGap, + vLeft, + vRight; + + -- 3º Restaremos a todos los nodos resultantes, a la derecha + -- de la posicion arrancada el ancho de la rama escindida + EXECUTE IMMEDIATE CONCAT( + 'UPDATE ', vTable, + 'SET lft = lft - ? + WHERE lft > ? + ORDER BY lft') + USING vWidth, + vLeft; + + EXECUTE IMMEDIATE CONCAT( + 'UPDATE ', vTable, + 'SET rgt = rgt - ? + WHERE rgt > ? + ORDER BY rgt') + USING vWidth, + vRight; + + DROP TEMPORARY TABLE tAux; +END$$ +DELIMITER ; diff --git a/db/routines/vn/procedures/bankPolicy_notifyExpired.sql b/db/routines/vn/procedures/bankPolicy_notifyExpired.sql index 52b747659..61216938d 100644 --- a/db/routines/vn/procedures/bankPolicy_notifyExpired.sql +++ b/db/routines/vn/procedures/bankPolicy_notifyExpired.sql @@ -10,13 +10,11 @@ BEGIN INSERT INTO mail (receiver,replyTo,subject,body) SELECT 'administracion@verdnatura.es' receiver, 'noreply@verdnatura.es' replyTo, - CONCAT('El seguro de la poliza ',b.id,' ',b.bank,' ha finalizado.') subject, - CONCAT('El seguro de la poliza ',b.id,' ',b.bank,' ha finalizado.') body - FROM vn.bankPolicy bp - LEFT JOIN vn.supplier s - ON s.id = bp.supplierFk - LEFT JOIN vn.bank b - ON b.id = bp.accountingFk + CONCAT('El seguro de la poliza ',a.id,' ',a.bank,' ha finalizado.') subject, + CONCAT('El seguro de la poliza ',a.id,' ',a.bank,' ha finalizado.') body + FROM bankPolicy bp + LEFT JOIN supplier s ON s.id = bp.supplierFk + LEFT JOIN accounting a ON a.id = bp.accountingFk WHERE bp.insuranceExpired = util.VN_CURDATE(); END$$ DELIMITER ; diff --git a/db/routines/vn/procedures/clean.sql b/db/routines/vn/procedures/clean.sql index cee64d772..5ffb03f6d 100644 --- a/db/routines/vn/procedures/clean.sql +++ b/db/routines/vn/procedures/clean.sql @@ -1,48 +1,42 @@ DELIMITER $$ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`clean`() BEGIN - DECLARE vDateShort DATETIME; - DECLARE vOneYearAgo DATE; - DECLARE vFourYearsAgo DATE; - DECLARE vFiveYearsAgo DATE; - DECLARE v18Month DATE; - DECLARE v26Month DATE; - DECLARE v3Month DATE; +/** + * Purges outdated data to optimize performance. + * Exercise caution when executing. + */ + DECLARE v2Months DATE DEFAULT util.VN_CURDATE() - INTERVAL 2 MONTH; + DECLARE v3Months DATE DEFAULT util.VN_CURDATE() - INTERVAL 3 MONTH; + DECLARE v18Months DATE DEFAULT util.VN_CURDATE() - INTERVAL 18 MONTH; + DECLARE v26Months DATE DEFAULT util.VN_CURDATE() - INTERVAL 26 MONTH; + DECLARE v1Years DATE DEFAULT util.VN_CURDATE() - INTERVAL 1 YEAR; + DECLARE v2Years DATE DEFAULT util.VN_CURDATE() - INTERVAL 2 YEAR; + DECLARE v4Years DATE DEFAULT util.VN_CURDATE() - INTERVAL 4 YEAR; + DECLARE v5Years DATE DEFAULT util.VN_CURDATE() - INTERVAL 5 YEAR; DECLARE vTrashId VARCHAR(15); - DECLARE v2Years DATE; - DECLARE v5Years DATE; - - SET vDateShort = util.VN_CURDATE() - INTERVAL 2 MONTH; - SET vOneYearAgo = util.VN_CURDATE() - INTERVAL 1 YEAR; - SET vFourYearsAgo = util.VN_CURDATE() - INTERVAL 4 YEAR; - SET vFiveYearsAgo = util.VN_CURDATE() - INTERVAL 5 YEAR; - SET v18Month = util.VN_CURDATE() - INTERVAL 18 MONTH; - SET v26Month = util.VN_CURDATE() - INTERVAL 26 MONTH; - SET v3Month = util.VN_CURDATE() - INTERVAL 3 MONTH; - SET v2Years = util.VN_CURDATE() - INTERVAL 2 YEAR; - SET v5Years = util.VN_CURDATE() - INTERVAL 5 YEAR; + DECLARE vCompanyBlk INT; DELETE FROM workerActivity WHERE created < v2Years; - DELETE FROM ticketParking WHERE created < vDateShort; - DELETE FROM routesMonitor WHERE dated < vDateShort; - DELETE FROM workerTimeControlLog WHERE created < vDateShort; - DELETE FROM `message` WHERE sendDate < vDateShort; - DELETE FROM messageInbox WHERE sendDate < vDateShort; - DELETE FROM messageInbox WHERE sendDate < vDateShort; - DELETE FROM workerTimeControl WHERE timed < vFourYearsAgo; + DELETE FROM ticketParking WHERE created < v2Months; + DELETE FROM routesMonitor WHERE dated < v2Months; + DELETE FROM workerTimeControlLog WHERE created < v2Months; + DELETE FROM `message` WHERE sendDate < v2Months; + DELETE FROM messageInbox WHERE sendDate < v2Months; + DELETE FROM messageInbox WHERE sendDate < v2Months; + DELETE FROM workerTimeControl WHERE timed < v4Years; DELETE FROM itemShelving WHERE created < util.VN_CURDATE() AND visible = 0; - DELETE FROM ticketDown WHERE created < TIMESTAMPADD(DAY,-1,util.VN_CURDATE()); - DELETE FROM entryLog WHERE creationDate < vDateShort; - DELETE IGNORE FROM expedition WHERE created < v26Month; - DELETE FROM sms WHERE created < v18Month; - DELETE FROM saleTracking WHERE created < vOneYearAgo; - DELETE FROM ticketTracking WHERE created < v18Month; + DELETE FROM ticketDown WHERE created < util.yesterday(); + DELETE FROM entryLog WHERE creationDate < v2Months; + DELETE IGNORE FROM expedition WHERE created < v26Months; + DELETE FROM sms WHERE created < v18Months; + DELETE FROM saleTracking WHERE created < v1Years; + DELETE FROM ticketTracking WHERE created < v18Months; DELETE tobs FROM ticketObservation tobs JOIN ticket t ON tobs.ticketFk = t.id WHERE t.shipped < v5Years; - DELETE sc.* FROM saleCloned sc JOIN sale s ON s.id = sc.saleClonedFk JOIN ticket t ON t.id = s.ticketFk WHERE t.shipped < vOneYearAgo; - DELETE FROM sharingCart where ended < vDateShort; - DELETE FROM sharingClient where ended < vDateShort; + DELETE sc.* FROM saleCloned sc JOIN sale s ON s.id = sc.saleClonedFk JOIN ticket t ON t.id = s.ticketFk WHERE t.shipped < v1Years; + DELETE FROM sharingCart where ended < v2Months; + DELETE FROM sharingClient where ended < v2Months; DELETE tw.* FROM ticketWeekly tw LEFT JOIN sale s ON s.ticketFk = tw.ticketFk LEFT JOIN ticketRequest tr ON tr.ticketFk = tw.ticketFk @@ -50,165 +44,182 @@ BEGIN WHERE s.id IS NULL AND tr.id IS NULL AND ts.id IS NULL; - DELETE FROM claim WHERE ticketCreated < vFourYearsAgo; - DELETE FROM message WHERE sendDate < vDateShort; - -- Robert ubicacion anterior de trevelLog comentario para debug - DELETE FROM zoneEvent WHERE `type` = 'day' AND dated < v3Month; + DELETE FROM claim WHERE ticketCreated < v4Years; + -- Robert ubicacion anterior de travelLog comentario para debug + DELETE FROM zoneEvent WHERE `type` = 'day' AND dated < v3Months; DELETE bm FROM buyMark bm JOIN buy b ON b.id = bm.id JOIN entry e ON e.id = b.entryFk JOIN travel t ON t.id = e.travelFk - WHERE t.landed <= vDateShort; - DELETE b FROM vn.buy b - JOIN vn.entryConfig e ON e.defaultEntry = b.entryFk - WHERE b.created < vDateShort; - DELETE FROM vn.itemShelvingLog WHERE created < vDateShort; - DELETE FROM vn.stockBuyed WHERE creationDate < vDateShort; - DELETE FROM vn.itemCleanLog WHERE created < util.VN_NOW() - INTERVAL 1 YEAR; - DELETE FROM printQueue WHERE statusCode = 'printed' AND created < vDateShort; - DELETE FROM ticketLog WHERE creationDate <= vFiveYearsAgo; + WHERE t.landed <= v2Months; + DELETE b FROM buy b + JOIN entryConfig e ON e.defaultEntry = b.entryFk + WHERE b.created < v2Months; + DELETE FROM itemShelvingLog WHERE created < v2Months; + DELETE FROM stockBuyed WHERE creationDate < v2Months; + DELETE FROM itemCleanLog WHERE created < util.VN_NOW() - INTERVAL 1 YEAR; + DELETE FROM printQueue WHERE statusCode = 'printed' AND created < v2Months; + DELETE FROM ticketLog WHERE creationDate <= v5Years; -- Equipos duplicados DELETE w.* FROM workerTeam w - JOIN (SELECT id, team, workerFk, COUNT(*) - 1 as duplicated + JOIN ( + SELECT id, team, workerFk, COUNT(*) - 1 duplicated FROM workerTeam GROUP BY team,workerFk HAVING duplicated - ) d ON d.team = w.team AND d.workerFk = w.workerFk AND d.id != w.id; + ) d ON d.team = w.team + AND d.workerFk = w.workerFk + AND d.id <> w.id; DELETE sc FROM saleComponent sc JOIN sale s ON s.id= sc.saleFk JOIN ticket t ON t.id= s.ticketFk - WHERE t.shipped < v18Month; + WHERE t.shipped < v18Months; DELETE c - FROM vn.claim c - JOIN vn.claimState cs ON cs.id = c.claimStateFk - WHERE cs.description = "Anulado" AND - c.created < vDateShort; - DELETE - FROM vn.expeditionTruck - WHERE eta < v3Month; + FROM claim c + JOIN claimState cs ON cs.id = c.claimStateFk + WHERE cs.description = 'Anulado' + AND c.created < v2Months; - DELETE FROM XDiario WHERE FECHA < v3Month OR FECHA IS NULL; - -- borrar travels sin entradas - DROP TEMPORARY TABLE IF EXISTS tmp.thermographToDelete; - CREATE TEMPORARY TABLE tmp.thermographToDelete + DELETE FROM expeditionTruck WHERE eta < v3Months; + DELETE FROM XDiario WHERE FECHA < v3Months OR FECHA IS NULL; + + -- Borrar travels sin entradas + CREATE OR REPLACE TEMPORARY TABLE tThermographToDelete SELECT th.id,th.dmsFk - FROM vn.travel t - LEFT JOIN vn.entry e ON e.travelFk = t.id - JOIN vn.travelThermograph th ON th.travelFk = t.id - WHERE t.shipped < TIMESTAMPADD(MONTH, -3, util.VN_CURDATE()) AND e.travelFk IS NULL; + FROM travel t + LEFT JOIN entry e ON e.travelFk = t.id + JOIN travelThermograph th ON th.travelFk = t.id + WHERE t.shipped < v3Months + AND e.travelFk IS NULL; SELECT dt.id INTO vTrashId - FROM vn.dmsType dt + FROM dmsType dt WHERE dt.code = 'trash'; - UPDATE tmp.thermographToDelete th - JOIN vn.dms d ON d.id = th.dmsFk + UPDATE tThermographToDelete th + JOIN dms d ON d.id = th.dmsFk SET d.dmsTypeFk = vTrashId; DELETE th - FROM tmp.thermographToDelete tmp - JOIN vn.travelThermograph th ON th.id = tmp.id; + FROM tThermographToDelete tmp + JOIN travelThermograph th ON th.id = tmp.id; DELETE t - FROM vn.travel t - LEFT JOIN vn.entry e ON e.travelFk = t.id - WHERE t.shipped < TIMESTAMPADD(MONTH, -3, util.VN_CURDATE()) AND e.travelFk IS NULL; + FROM travel t + LEFT JOIN entry e ON e.travelFk = t.id + WHERE t.shipped < v3Months AND e.travelFk IS NULL; UPDATE dms d JOIN dmsType dt ON dt.id = d.dmsTypeFk SET d.dmsTypeFk = vTrashId - WHERE created < TIMESTAMPADD(MONTH, -dt.monthToDelete, util.VN_CURDATE()); + WHERE created < util.VN_CURDATE() - INTERVAL dt.monthToDelete MONTH; -- borrar entradas sin compras - DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete; - CREATE TEMPORARY TABLE tmp.entryToDelete + CREATE OR REPLACE TEMPORARY TABLE tEntryToDelete SELECT e.* - FROM vn.entry e - LEFT JOIN vn.buy b ON b.entryFk = e.id - JOIN vn.entryConfig ec ON e.id != ec.defaultEntry - WHERE e.dated < TIMESTAMPADD(MONTH, -3, util.VN_CURDATE()) AND b.entryFK IS NULL; + FROM entry e + LEFT JOIN buy b ON b.entryFk = e.id + JOIN entryConfig ec ON e.id <> ec.defaultEntry + WHERE e.dated < v3Months + AND b.entryFK IS NULL; DELETE e - FROM vn.entry e - JOIN tmp.entryToDelete tmp ON tmp.id = e.id; + FROM entry e + JOIN tEntryToDelete tmp ON tmp.id = e.id; -- borrar de route registros menores a 4 años - DROP TEMPORARY TABLE IF EXISTS tmp.routeToDelete; - CREATE TEMPORARY TABLE tmp.routeToDelete + CREATE OR REPLACE TEMPORARY TABLE tRouteToDelete SELECT * - FROM vn.route r - WHERE created < TIMESTAMPADD(YEAR,-4,util.VN_CURDATE()); + FROM route r + WHERE created < v4Years; - UPDATE tmp.routeToDelete tmp - JOIN vn.dms d ON d.id = tmp.gestdocFk + UPDATE tRouteToDelete tmp + JOIN dms d ON d.id = tmp.gestdocFk SET d.dmsTypeFk = vTrashId; DELETE r - FROM tmp.routeToDelete tmp - JOIN vn.route r ON r.id = tmp.id; + FROM tRouteToDelete tmp + JOIN route r ON r.id = tmp.id; -- borrar registros de dua y awb menores a 2 años - DROP TEMPORARY TABLE IF EXISTS tmp.duaToDelete; - CREATE TEMPORARY TABLE tmp.duaToDelete + CREATE OR REPLACE TEMPORARY TABLE tDuaToDelete SELECT * - FROM vn.dua - WHERE operated < TIMESTAMPADD(YEAR,-2,CURDATE()); + FROM dua + WHERE operated < v2Years; - UPDATE tmp.duaToDelete tm - JOIN vn.dms d ON d.id = tm.gestdocFk + UPDATE tDuaToDelete tm + JOIN dms d ON d.id = tm.gestdocFk SET d.dmsTypeFk = vTrashId; DELETE d - FROM tmp.duaToDelete tmp - JOIN vn.dua d ON d.id = tmp.id; + FROM tDuaToDelete tmp + JOIN dua d ON d.id = tmp.id; DELETE a - FROM vn.awb a - LEFT JOIN vn.travel t ON t.awbFk = a.id + FROM awb a + LEFT JOIN travel t ON t.awbFk = a.id WHERE a.created < v2Years AND t.id IS NULL; -- Borra los registros de collection y ticketcollection - DELETE FROM vn.collection WHERE created < vDateShort; + DELETE FROM collection WHERE created < v2Months; + DELETE FROM travelLog WHERE creationDate < v3Months; - DROP TEMPORARY TABLE IF EXISTS tmp.thermographToDelete; - DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete; - DROP TEMPORARY TABLE IF EXISTS tmp.duaToDelete; + CALL shelving_clean(); - DELETE FROM travelLog WHERE creationDate < v3Month; + DELETE FROM chat WHERE dated < v5Years; + DELETE tt FROM ticketTracking tt + JOIN ticket t ON tt.ticketFk = t.id + WHERE t.shipped <= v2Months; + DELETE FROM mail WHERE creationDate < v2Months; + DELETE FROM split WHERE dated < v18Months; + DELETE FROM remittance WHERE dated < v18Months; + CREATE OR REPLACE TEMPORARY TABLE tTicketDelete - SELECT DISTINCT tl.originFk ticketFk - FROM ticketLog tl - JOIN ( - SELECT MAX(tl.id)ids - FROM ticket t - JOIN ticketLog tl ON tl.originFk = t.id - LEFT JOIN ticketWeekly tw ON tw.ticketFk =t.id - WHERE t.shipped BETWEEN '2000-01-01' AND '2000-12-31' - AND t.isDeleted - AND tw.ticketFk IS NULL - GROUP BY t.id - ) sub ON sub.ids = tl.id - WHERE tl.creationDate <= vDateShort; - + SELECT DISTINCT tl.originFk ticketFk + FROM ticketLog tl + JOIN ( + SELECT MAX(tl.id)ids + FROM ticket t + JOIN ticketLog tl ON tl.originFk = t.id + LEFT JOIN ticketWeekly tw ON tw.ticketFk = t.id + WHERE t.shipped BETWEEN '2000-01-01' AND '2000-12-31' + AND t.isDeleted + AND tw.ticketFk IS NULL + GROUP BY t.id + ) sub ON sub.ids = tl.id + WHERE tl.creationDate <= v2Months; DELETE t FROM ticket t JOIN tTicketDelete tmp ON tmp.ticketFk = t.id; - DROP TEMPORARY TABLE tTicketDelete; + DELETE sl + FROM saleLabel sl + JOIN sale s ON s.id = sl.saleFk + JOIN ticket t ON t.id = s.ticketFk + WHERE t.shipped < v2Months; - CALL shelving_clean; + -- Tickets Nulos PAK 11/10/2016 + SELECT id INTO vCompanyBlk FROM company WHERE code = 'BLK'; + UPDATE ticket + SET companyFk = vCompanyBlk + WHERE clientFk = (SELECT id FROM client WHERE name = 'AUTOCONSUMO') + AND companyFk <> vCompanyBlk; - DELETE FROM chat WHERE dated < v5Years; - - DELETE tt FROM ticketTracking tt JOIN vn.ticket t ON tt.ticketFk = t.id - WHERE t.shipped <= vDateShort; + DROP TEMPORARY TABLE tTicketDelete, + tThermographToDelete, + tEntryToDelete, + tDuaToDelete, + tRouteToDelete; + -- Other schemas + DELETE FROM hedera.`order` WHERE date_send < v18Months; + DELETE FROM pbx.cdr WHERE call_date < v18Months; END$$ DELIMITER ; diff --git a/db/routines/vn/procedures/client_getMana.sql b/db/routines/vn/procedures/client_getMana.sql index 99b00c6df..f5bb5747d 100644 --- a/db/routines/vn/procedures/client_getMana.sql +++ b/db/routines/vn/procedures/client_getMana.sql @@ -39,7 +39,8 @@ BEGIN FROM receipt r JOIN `client` c ON c.id = r.clientFk JOIN tmp.client tc ON tc.id = c.id - JOIN bank b ON r.bankFk = b.id AND b.code = 'mana' + JOIN accounting a ON r.bankFk = a.id + AND a.code = 'mana' WHERE r.payed > vFromDated AND r.payed <= util.VN_CURDATE() UNION ALL diff --git a/db/routines/vn/procedures/confection_controlSource.sql b/db/routines/vn/procedures/confection_controlSource.sql new file mode 100644 index 000000000..f011a52e9 --- /dev/null +++ b/db/routines/vn/procedures/confection_controlSource.sql @@ -0,0 +1,103 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`confection_controlSource`( + vDated DATE, + vScopeDays INT, + vMaxAlertLevel INT, + vWarehouseFk INT +) +BEGIN +/** + * Obtiene la información para el control de confección, + * ya sean tickets y/o entradas. + * + * @param vDated Fecha a calcular + * @param vScopeDays Número de días desde hoy en adelante que entran en el cálculo. + * @param vMaxAlertLevel Id nivel de alerta + * @param vWarehouseFk Id de almacén + */ + DECLARE vEndingDate DATETIME DEFAULT util.dayEnd(vDated) + INTERVAL vScopeDays DAY; + + SELECT t.shipped, + t.id ticketFk, + s.id saleFk, + s.quantity, + s.concept, + ABS(s.reserved) isReserved, + i.category, + it.name itemType, + t.nickname, + wh.name warehouse, + t.warehouseFk warehouseFk, + a.provinceFk, + am.agencyFk, + ct.description, + stock.visible, + stock.available + FROM ticket t + JOIN agencyMode am ON am.id = t.agencyModeFk + JOIN warehouse wh ON wh.id = t.warehouseFk + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it ON it.id = i.typeFk + JOIN confectionType ct ON ct.id = it.making + JOIN `address` a on a.id = t.addressFk + LEFT JOIN ticketState tls on tls.ticketFk = t.id + LEFT JOIN + ( + SELECT item_id, + SUM(visible) visible, + SUM(available) available + FROM ( + SELECT a.item_id, + 0 visible, + a.available + FROM cache.cache_calc cc + LEFT JOIN cache.available a ON a.calc_id = cc.id + WHERE cc.cache_id IN ('visible', 'available') + AND cc.params = CONCAT(vWarehouseFk, "/", util.VN_CURDATE()) + UNION ALL + SELECT v.item_id, + v.visible, + 0 + FROM cache.cache_calc cc + LEFT JOIN cache.visible v ON v.calc_id = cc.id + WHERE cc.cacheName IN ('visible', 'available') + AND cc.params = vWarehouseFk + ) sub + GROUP BY item_id + ) stock ON stock.item_id = s.itemFk + WHERE it.making + AND tls.alertLevel < vMaxAlertLevel + AND wh.hasConfectionTeam + AND t.shipped BETWEEN vDated AND vEndingDate + AND s.quantity > 0 + UNION ALL + SELECT tr.shipped, + e.id, + NULL, + b.quantity, + i.name, + NULL, + i.category, + NULL, + whi.name, + who.name, + NULL, + NULL, + NULL, + ct.description, + NULL, + NULL + FROM buy b + JOIN `entry` e ON e.id = b.entryFk + JOIN travel tr ON tr.id = e.travelFk + JOIN warehouse whi ON whi.id = tr.warehouseInFk + JOIN warehouse who ON who.id = tr.warehouseOutFk + JOIN item i ON i.id = b.itemFk + JOIN itemType it ON it.id = i.typeFk + JOIN confectionType ct ON ct.id = it.making + WHERE who.hasConfectionTeam + AND it.making + AND tr.shipped BETWEEN vDated AND vEndingDate; +END$$ +DELIMITER ; diff --git a/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql b/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql index 2ff478d6b..3453516cc 100644 --- a/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql +++ b/db/routines/vn/procedures/invoiceInTaxMakeByDua.sql @@ -1,8 +1,11 @@ DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceInTaxMakeByDua`(vDuaFk INT) +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceInTaxMakeByDua`( + vDuaFk INT +) BEGIN /** - * Borra los valores de duaTax y sus vctos. y los vuelve a crear en base a la tabla duaEntry + * Borra los valores de duaTax y sus vctos. y los vuelve a + * crear en base a la tabla duaEntry. * * @param vDuaFk Id del dua a recalcular */ @@ -26,7 +29,7 @@ BEGIN LEAVE l; END IF; - CALL vn2008.recibidaIvaInsert(vInvoiceInFk); + CALL invoiceInTax_recalc(vInvoiceInFk); CALL invoiceInDueDay_recalc(vInvoiceInFk); END LOOP; diff --git a/db/routines/vn/procedures/invoiceInTax_recalc.sql b/db/routines/vn/procedures/invoiceInTax_recalc.sql new file mode 100644 index 000000000..3b5ce5247 --- /dev/null +++ b/db/routines/vn/procedures/invoiceInTax_recalc.sql @@ -0,0 +1,62 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceInTax_recalc`( + vInvoiceInFk INT +) +BEGIN +/** + * Recalcula y actualiza los impuestos de la factura + * usando la última tasa de cambio y detalles de compra. + * + * @param vInvoiceInFk Id de factura recibida + */ + DECLARE vRate DOUBLE DEFAULT 1; + DECLARE vDated DATE; + DECLARE vExpenseFk INT; + + SELECT MAX(rr.dated) INTO vDated + FROM referenceRate rr + JOIN invoiceIn ii ON ii.id = vInvoiceInFk + WHERE rr.dated <= ii.issued + AND rr.currencyFk = ii.currencyFk; + + IF vDated THEN + SELECT `value` INTO vRate + FROM referenceRate + WHERE dated = vDated; + END IF; + + DELETE FROM invoiceInTax WHERE invoiceInFk = vInvoiceInFk; + + SELECT id INTO vExpenseFk + FROM expense + WHERE code = 'extraCommGoodsAcquisition'; + + IF vExpenseFk IS NULL THEN + CALL util.throw('Expense extraCommGoodsAcquisition not exists'); + END IF; + + INSERT INTO invoiceInTax( + invoiceInFk, + taxableBase, + expenseFk, + foreignValue, + taxTypeSageFk, + transactionTypeSageFk + ) + SELECT ii.id, + SUM(b.buyingValue * b.quantity) / vRate bi, + vExpenseFk, + IF(c.code = 'EUR', NULL, SUM(b.buyingValue * b.quantity)), + s.taxTypeSageFk, + s.transactionTypeSageFk + FROM invoiceIn ii + JOIN currency c ON c.id = ii.currencyFk + JOIN `entry` e ON e.invoiceInFk = ii.id + JOIN supplier s ON s.id = e.supplierFk + JOIN buy b ON b.entryFk = e.id + LEFT JOIN referenceRate rr ON rr.currencyFk = ii.currencyFk + AND rr.dated = ii.issued + WHERE ii.id = vInvoiceInFk + HAVING bi IS NOT NULL; +END$$ +DELIMITER ; diff --git a/db/routines/vn/procedures/itemProposal.sql b/db/routines/vn/procedures/itemProposal.sql deleted file mode 100644 index 0dc04124d..000000000 --- a/db/routines/vn/procedures/itemProposal.sql +++ /dev/null @@ -1,104 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemProposal`( - vSelf INT, - vTicketFk INT, - vShowType BOOL -) -BEGIN -/** -* Propone articulos disponibles ordenados, con la cantidad -* de veces usado y segun sus caracteristicas. -* -* @param vSelf Id de artículo -* @param vTicketFk Id de ticket -* @param vShowType Mostrar tipos -*/ - DECLARE vWarehouseFk INT; - DECLARE vShipped DATE; - DECLARE vCalcFk INT; - DECLARE vTypeFk INT; - DECLARE vPriority INT DEFAULT 1; - DECLARE EXIT HANDLER FOR SQLEXCEPTION - BEGIN - ROLLBACK; - RESIGNAL; - END; - - SELECT warehouseFk, shipped - INTO vWarehouseFk, vShipped - FROM ticket - WHERE id = vTicketFk; - - START TRANSACTION; - - CALL cache.available_refresh(vCalcFk, FALSE, vWarehouseFk, vShipped); - - WITH itemTags AS ( - SELECT i.id, - typeFk, - tag5, - value5, - tag6, - value6, - tag7, - value7, - tag8, - value8, - t.name, - it.value - FROM vn.item i - LEFT JOIN vn.itemTag it ON it.itemFk = i.id - AND it.priority = vPriority - LEFT JOIN vn.tag t ON t.id = it.tagFk - WHERE i.id = vSelf - ) - SELECT i.id itemFk, - i.longName, - i.subName, - i.tag5, - i.value5, - (i.value5 <=> its.value5) match5, - i.tag6, - i.value6, - (i.value6 <=> its.value6) match6, - i.tag7, - i.value7, - (i.value7 <=> its.value7) match7, - i.tag8, - i.value8, - (i.value8 <=> its.value8) match8, - a.available, - IFNULL(ip.counter, 0) `counter`, - IF(b.groupingMode = 1, b.grouping, b.packing) minQuantity, - iss.visible located - FROM vn.item i - JOIN cache.available a ON a.item_id = i.id - AND a.calc_id = vCalcFk - LEFT JOIN vn.itemProposal ip ON ip.mateFk = i.id - AND ip.itemFk = vSelf - LEFT JOIN vn.itemTag it ON it.itemFk = i.id - AND it.priority = vPriority - LEFT JOIN vn.tag t ON t.id = it.tagFk - LEFT JOIN cache.last_buy lb ON lb.item_id = i.id - AND lb.warehouse_id = vWarehouseFk - LEFT JOIN vn.buy b ON b.id = lb.buy_id - LEFT JOIN vn.itemShelvingStock iss ON iss.itemFk = i.id - AND iss.warehouseFk = vWarehouseFk - JOIN itemTags its - WHERE a.available > 0 - AND IF(vShowType, i.typeFk = its.typeFk, TRUE) - AND i.id <> vSelf - ORDER BY `counter` DESC, - (t.name = its.name) DESC, - (it.value = its.value) DESC, - (i.tag5 = its.tag5) DESC, - match5 DESC, - (i.tag6 = its.tag6) DESC, - match6 DESC, - (i.tag7 = its.tag7) DESC, - match7 DESC, - (i.tag8 = its.tag8) DESC, - match8 DESC; - COMMIT; -END$$ -DELIMITER ; diff --git a/db/routines/vn/procedures/itemProposal_beta.sql b/db/routines/vn/procedures/itemProposal_beta.sql deleted file mode 100644 index 4a6f761a9..000000000 --- a/db/routines/vn/procedures/itemProposal_beta.sql +++ /dev/null @@ -1,76 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemProposal_beta`(vItemFk INT, vTicketFk INT) -BEGIN - - DECLARE vWarehouseFk INT; - DECLARE vShipped DATE; - DECLARE vCalcFk INT; - DECLARE vTypeFk INT; - DECLARE vResultsMax INT DEFAULT 10; - - DECLARE vTag1 VARCHAR(25); - DECLARE vTag5 VARCHAR(25); - DECLARE vTag6 VARCHAR(25); - DECLARE vTag7 VARCHAR(25); - DECLARE vTag8 VARCHAR(25); - - DECLARE vValue1 VARCHAR(50); - DECLARE vValue5 VARCHAR(50); - DECLARE vValue6 VARCHAR(50); - DECLARE vValue7 VARCHAR(50); - DECLARE vValue8 VARCHAR(50); - - SELECT warehouseFk, shipped INTO vWarehouseFk, vShipped - FROM vn.ticket - WHERE id = vTicketFk; - - SELECT typeFk, tag5, value5, tag6, value6, tag7, value7, tag8, value8, t1.name, it1.value - INTO vTypeFk, vTag5, vValue5, vTag6, vValue6, vTag7, vValue7, vTag8, vValue8, vTag1, vValue1 - FROM vn.item i - LEFT JOIN vn.itemTag it1 ON it1.itemFk = i.id AND it1.priority = 1 - LEFT JOIN vn.tag t1 ON t1.id = it1.tagFk - WHERE i.id = vItemFk; - - CALL cache.available_refresh(vCalcFk, FALSE, vWarehouseFk, vShipped); - - SELECT i.id itemFk, - i.longName, - i.subName, - i.tag5, - i.value5, - (i.value5 <=> vValue5 COLLATE utf8_general_ci) match5, - i.tag6, - i.value6, - (i.value6 <=> vValue6 COLLATE utf8_general_ci) match6, - i.tag7, - i.value7, - (i.value7 <=> vValue7 COLLATE utf8_general_ci) match7, - i.tag8, - i.value8, - (i.value8 <=> vValue8 COLLATE utf8_general_ci) match8, - a.available, - IFNULL(ip.counter,0) counter - FROM vn.item i - JOIN cache.available a ON a.item_id = i.id - LEFT JOIN vn.itemProposal ip ON ip.mateFk = i.id AND ip.itemFk = vItemFk - LEFT JOIN vn.itemTag it1 ON it1.itemFk = i.id AND it1.priority = 1 - LEFT JOIN vn.tag t1 ON t1.id = it1.tagFk - WHERE a.calc_id = vCalcFk - AND available > 0 - AND i.typeFk = vTypeFk - AND i.id != vItemFk - ORDER BY counter DESC, - (t1.name = vTag1 COLLATE utf8_general_ci) DESC, - (it1.value = vValue1 COLLATE utf8_general_ci) DESC, - (i.tag5 = vTag5 COLLATE utf8_general_ci) DESC, - (i.value5 = vValue5 COLLATE utf8_general_ci) DESC, - (i.tag6 = vTag6 COLLATE utf8_general_ci) DESC, - (i.value6 = vValue6 COLLATE utf8_general_ci) DESC, - (i.tag7 = vTag7 COLLATE utf8_general_ci) DESC, - (i.value7 = vValue7 COLLATE utf8_general_ci) DESC, - (i.tag8 = vTag8 COLLATE utf8_general_ci) DESC, - (i.value8 = vValue8 COLLATE utf8_general_ci) DESC - LIMIT vResultsMax; - -END$$ -DELIMITER ; diff --git a/db/routines/vn/procedures/itemShelving_inventory.sql b/db/routines/vn/procedures/itemShelving_inventory.sql index ce2934426..73e438fbb 100644 --- a/db/routines/vn/procedures/itemShelving_inventory.sql +++ b/db/routines/vn/procedures/itemShelving_inventory.sql @@ -30,10 +30,11 @@ BEGIN ish.visible, p.sectorFk, it.workerFk buyer, - CONCAT('http:',ic.url, '/catalog/1600x900/',i.image) urlImage, + ic.url, + i.image, ish.isChecked, CASE - WHEN s.notPrepared > sm.parked THEN 0 + WHEN IFNULL (s.notPrepared, 0) > sm.parked THEN 0 WHEN sm.visible > sm.parked THEN 1 ELSE 2 END priority @@ -43,7 +44,7 @@ BEGIN JOIN tmp.stockMisfit sm ON sm.itemFk = ish.itemFk JOIN shelving sh ON sh.code = ish.shelvingFk JOIN parking p ON p.id = sh.parkingFk - JOIN ( + LEFT JOIN ( SELECT s.itemFk, sum(s.quantity) notPrepared FROM sale s JOIN ticket t ON t.id = s.ticketFk diff --git a/db/routines/vn/procedures/item_getSimilar.sql b/db/routines/vn/procedures/item_getSimilar.sql index 7cc9ad63e..0ddfe21b5 100644 --- a/db/routines/vn/procedures/item_getSimilar.sql +++ b/db/routines/vn/procedures/item_getSimilar.sql @@ -1,84 +1,92 @@ DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_getSimilar`(vItemFk INT, vWarehouseFk INT, vDate DATE, vIsShowedByType BOOL) +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_getSimilar`( + vSelf INT, + vWarehouseFk INT, + vDated DATE, + vShowType BOOL +) BEGIN - /** - * Propone articulos similares para posible cambio, - * ordenado con la cantidad de veces usado y segun sus caracteristicas - * - * @param vItemFk item id - * @param vWarehouseFk warehouse id - * @param vDate fecha para revisar disponible - * @param vIsShowedByType para mostrar solo artículos de ese tipo - */ +* Propone articulos disponibles ordenados, con la cantidad +* de veces usado y segun sus caracteristicas. +* +* @param vSelf Id de artículo +* @param vWarehouseFk Id de almacen +* @param vDated Fecha +* @param vShowType Mostrar tipos +*/ + DECLARE vCalcFk INT; + DECLARE vTypeFk INT; + DECLARE vPriority INT DEFAULT 1; - DECLARE vCalcFk INT; - DECLARE vTypeFk INT; - - DECLARE vTag1 VARCHAR(25) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vTag5 VARCHAR(25) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vTag6 VARCHAR(25) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vTag7 VARCHAR(25) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vTag8 VARCHAR(25) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - - DECLARE vValue1 VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vValue5 VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vValue6 VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vValue7 VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; - DECLARE vValue8 VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'; + CALL cache.available_refresh(vCalcFk, FALSE, vWarehouseFk, vDated); - - SELECT typeFk, tag5, value5, tag6, value6, tag7, value7, tag8, value8, t1.name, it1.value - INTO vTypeFk, vTag5, vValue5, vTag6, vValue6, vTag7, vValue7, vTag8, vValue8, vTag1, vValue1 - FROM vn.item i - LEFT JOIN vn.itemTag it1 ON it1.itemFk = i.id AND it1.priority = 1 - LEFT JOIN vn.tag t1 ON t1.id = it1.tagFk - WHERE i.id = vItemFk; - - CALL cache.available_refresh(vCalcFk, FALSE, vWarehouseFk, vDate); - - SELECT i.id itemFk, - i.longName, - i.subName, - i.tag5, - i.value5, - (i.value5 <=> vValue5) match5, - i.tag6, - i.value6, - (i.value6 <=> vValue6) match6, - i.tag7, - i.value7, - (i.value7 <=> vValue7) match7, - i.tag8, - i.value8, - (i.value8 <=> vValue8) match8, - a.available, - IFNULL(ip.counter,0) counter, - IF(b.groupingMode = 1, b.grouping, b.packing) as minQuantity - FROM vn.item i - JOIN cache.available a ON a.item_id = i.id - LEFT JOIN vn.itemProposal ip ON ip.mateFk = i.id AND ip.itemFk = vItemFk - LEFT JOIN vn.itemTag it1 ON it1.itemFk = i.id AND it1.priority = 1 - LEFT JOIN vn.tag t1 ON t1.id = it1.tagFk - LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = vWarehouseFk + + WITH itemTags AS ( + SELECT i.id, + typeFk, + tag5, + value5, + tag6, + value6, + tag7, + value7, + tag8, + value8, + t.name, + it.value + FROM vn.item i + LEFT JOIN vn.itemTag it ON it.itemFk = i.id + AND it.priority = vPriority + LEFT JOIN vn.tag t ON t.id = it.tagFk + WHERE i.id = vSelf + ) + SELECT i.id itemFk, + i.longName, + i.subName, + i.tag5, + i.value5, + (i.value5 <=> its.value5) match5, + i.tag6, + i.value6, + (i.value6 <=> its.value6) match6, + i.tag7, + i.value7, + (i.value7 <=> its.value7) match7, + i.tag8, + i.value8, + (i.value8 <=> its.value8) match8, + a.available, + IFNULL(ip.counter, 0) `counter`, + IF(b.groupingMode = 1, b.grouping, b.packing) minQuantity, + iss.visible located + FROM vn.item i + JOIN cache.available a ON a.item_id = i.id + AND a.calc_id = vCalcFk + LEFT JOIN vn.itemProposal ip ON ip.mateFk = i.id + AND ip.itemFk = vSelf + LEFT JOIN vn.itemTag it ON it.itemFk = i.id + AND it.priority = vPriority + LEFT JOIN vn.tag t ON t.id = it.tagFk + LEFT JOIN cache.last_buy lb ON lb.item_id = i.id + AND lb.warehouse_id = vWarehouseFk LEFT JOIN vn.buy b ON b.id = lb.buy_id - WHERE a.calc_id = vCalcFk - AND available > 0 - AND IF(vIsShowedByType, i.typeFk = vTypeFk, TRUE) - AND i.id != vItemFk - ORDER BY counter DESC, - (t1.name = vTag1) DESC, - (it1.value = vValue1) DESC, - (i.tag6 = vTag6) DESC, - (i.value6 = vValue6) DESC, - (i.tag5 = vTag5) DESC, - (i.value5 = vValue5) DESC, - (i.tag7 = vTag7) DESC, - (i.value7 = vValue7) DESC, - (i.tag8 = vTag8) DESC, - (i.value8 = vValue8) DESC - LIMIT 30; - - + LEFT JOIN vn.itemShelvingStock iss ON iss.itemFk = i.id + AND iss.warehouseFk = vWarehouseFk + JOIN itemTags its + WHERE a.available > 0 + AND IF(vShowType, i.typeFk = its.typeFk, TRUE) + AND i.id <> vSelf + ORDER BY `counter` DESC, + (t.name = its.name) DESC, + (it.value = its.value) DESC, + (i.tag5 = its.tag5) DESC, + match5 DESC, + (i.tag6 = its.tag6) DESC, + match6 DESC, + (i.tag7 = its.tag7) DESC, + match7 DESC, + (i.tag8 = its.tag8) DESC, + match8 DESC; END$$ DELIMITER ; diff --git a/db/routines/vn/procedures/payment_add.sql b/db/routines/vn/procedures/payment_add.sql new file mode 100644 index 000000000..061a75848 --- /dev/null +++ b/db/routines/vn/procedures/payment_add.sql @@ -0,0 +1,84 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`payment_add`( + vDated DATE, + vSupplierFk INT, + vAmount DOUBLE, + vCurrencyFk INT, + vForeignValue DOUBLE, + vBankFk INT, + vPayMethodFk INT, + vExpenseFk DOUBLE, + vConcept VARCHAR(40), + vCompanyFk INT) +BEGIN +/** + * Registra un pago realizado a un proveedor y + * su correspondiente registro en caja. + * + * @param vDated Fecha del pago + * @param vSupplierFk Id del proveedor + * @param vAmount Cantidad a pagar + * @param vCurrencyFk Id de la moneda + * @param vForeignValue Tipo de cambio utilizado + * @param vBankFk Id del banco + * @param vPayMethodFk Id del método de pago + * @param vExpenseFk Id de gasto + * @param vConcept Concepto del pago + * @param vCompanyFk Id de la empresa + * @return paymentFk Id de pago insertado + */ + INSERT INTO till( + concept, + serie, + `number`, + `out`, + dated, + isAccountable, + bankFk, + workerFk, + companyFk, + isConciliate + ) + SELECT CONCAT('n/pago a ', `name`), + 'R', + vSupplierFk, + vAmount, + vDated, + 1, + vBankFk, + account.myUser_getId(), + vCompanyFk, + 1 + FROM supplier + WHERE id = vSupplierFk; + + INSERT INTO payment( + received, + dueDated, + supplierFk, + amount, + currencyFk, + divisa, + bankFk, + payMethodFk, + bankingFees, + concept, + companyFk + ) + VALUES( + vDated, + vDated, + vSupplierFk, + vAmount, + vCurrencyFk, + IF(NOT vForeignValue, NULL, vForeignValue), + vBankFk, + vPayMethodFk, + vExpenseFk, + vConcept, + vCompanyFk + ); + + SELECT LAST_INSERT_ID() paymentFk; +END$$ +DELIMITER ; diff --git a/db/routines/vn/procedures/remittance_calc.sql b/db/routines/vn/procedures/remittance_calc.sql new file mode 100644 index 000000000..ed0a18662 --- /dev/null +++ b/db/routines/vn/procedures/remittance_calc.sql @@ -0,0 +1,70 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`remittance_calc`( + vDated DATE +) +BEGIN +/** +* Calcula los datos de remesa, incluyendo el importe, +* el vencimiento, y otros datos relevantes. +* +* @param vDated Fecha a calcular +* @return tmp.remittance +*/ + CREATE OR REPLACE TEMPORARY TABLE tmp.remittance + SELECT CONCAT(s.nif, REPEAT('0', 12 - LENGTH(s.nif))) cif, + c.id clientFk, + c.name client, + c.fi, + sub.paymentDate, + 0 invoiceAmount, + CAST(sub.receipt AS DECIMAL(10,2)) receiptAmount, + 0 currentAmount, + sub.companyFk, + c.socialName, + CAST(sub.receipt AS DECIMAL(10,2)) totalAmount, + CAST(sub.receipt AS DECIMAL(10,2)) balance, + s.name company, + co.code companyCode, + c.accountingAccount, + c.iban, + c.hasSepaVnl, + c.hasCoreVnl, + c.hasLcr, + be.bic, + be.`name` entityName + FROM client c + JOIN ( + SELECT risk.companyFk, + c.id, + SUM(risk.amount) receipt, + IF((c.dueDay + graceDays) MOD 30.001 <= DAY(vDated), + LAST_DAY(vDated - INTERVAL 1 MONTH) + INTERVAL (c.dueDay + graceDays) MOD 30.001 DAY, + LAST_DAY(vDated - INTERVAL 2 MONTH) + INTERVAL (c.dueDay + graceDays) MOD 30.001 DAY + ) paymentDate + FROM client c + JOIN payMethod pm ON pm.id = c.payMethodFk + JOIN ( + SELECT cr.companyFk, cr.clientFk, cr.amount + FROM client c + JOIN clientRisk cr ON cr.clientFk = c.id + JOIN payMethod pm ON pm.id = c.payMethodFk + WHERE pm.code = 'bankDraft' + UNION ALL + SELECT io.companyFk, io.clientFk, - io.amount + FROM invoiceOut io + JOIN client c ON c.id = io.clientFk + JOIN payMethod pm ON pm.id = c.payMethodFk + WHERE io.dued > vDated + AND pm.code = 'bankDraft' + AND pm.outstandingDebt + AND io.amount > 0 + + ) risk ON risk.clientFk = c.id + GROUP BY risk.companyFk, c.id + HAVING receipt > 10 + ) sub ON sub.id = c.id + JOIN supplier s ON s.id = sub.companyFk + JOIN company co ON co.id = sub.companyFk + LEFT JOIN bankEntity be ON be.id = c.bankEntityFk; +END$$ +DELIMITER ; diff --git a/db/routines/vn/procedures/sale_checkNoComponents.sql b/db/routines/vn/procedures/sale_checkNoComponents.sql deleted file mode 100644 index 79abbbf92..000000000 --- a/db/routines/vn/procedures/sale_checkNoComponents.sql +++ /dev/null @@ -1,70 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`sale_checkNoComponents`(vCreatedFrom DATETIME, vCreatedTo DATETIME) -BEGIN -/** - * Comprueba que las ventas creadas entre un rango de fechas tienen componentes - * - * @param vCreatedFrom inicio del rango - * @param vCreatedTo fin del rango - */ - DECLARE v_done BOOL DEFAULT FALSE; - DECLARE vSaleFk INTEGER; - DECLARE vTicketFk INTEGER; - DECLARE vConcept VARCHAR(50); - DECLARE vCur CURSOR FOR - SELECT s.id - FROM sale s - JOIN ticket t ON t.id = s.ticketFk - JOIN item i ON i.id = s.itemFk - JOIN itemType tp ON tp.id = i.typeFk - JOIN itemCategory ic ON ic.id = tp.categoryFk - LEFT JOIN tmp.coste c ON c.id = s.id - WHERE s.created >= vCreatedFrom AND s.created <= vCreatedTo - AND c.id IS NULL - AND t.agencyModeFk IS NOT NULL - AND t.isDeleted IS FALSE - AND t.warehouseFk = 60 - AND ic.merchandise != FALSE - GROUP BY s.id; - - DECLARE CONTINUE HANDLER FOR NOT FOUND - SET v_done = TRUE; - - DROP TEMPORARY TABLE IF EXISTS tmp.coste; - - DROP TEMPORARY TABLE IF EXISTS tmp.coste; - CREATE TEMPORARY TABLE tmp.coste - (PRIMARY KEY (id)) ENGINE = MEMORY - SELECT s.id - FROM sale s - JOIN item i ON i.id = s.itemFk - JOIN itemType tp ON tp.id = i.typeFk - JOIN itemCategory ic ON ic.id = tp.categoryFk - JOIN saleComponent sc ON sc.saleFk = s.id - JOIN component c ON c.id = sc.componentFk - JOIN componentType ct ON ct.id = c.typeFk AND ct.id = 6 - WHERE s.created >= vCreatedFrom - AND ic.merchandise != FALSE; - - OPEN vCur; - - l: LOOP - SET v_done = FALSE; - FETCH vCur INTO vSaleFk; - - IF v_done THEN - LEAVE l; - END IF; - - SELECT ticketFk, concept - INTO vTicketFk, vConcept - FROM sale - WHERE id = vSaleFk; - - CALL sale_calculateComponent(vSaleFk, 'renewPrices'); - END LOOP; - - CLOSE vCur; - DROP TEMPORARY TABLE tmp.coste; -END$$ -DELIMITER ; diff --git a/db/routines/vn/procedures/sale_getBoxPickingList.sql b/db/routines/vn/procedures/sale_getBoxPickingList.sql index 0af23e945..ff0e85259 100644 --- a/db/routines/vn/procedures/sale_getBoxPickingList.sql +++ b/db/routines/vn/procedures/sale_getBoxPickingList.sql @@ -27,7 +27,7 @@ BEGIN s.quantity, MAKETIME(pb.HH,pb.mm,0) etd, pb.routeFk, - FLOOR(s.quantity / ish.packing) stickers, + FLOOR(s.quantity / IF(i.isBoxPickingMode, ish.packing, i.packingOut)) stickers, IF(i.isBoxPickingMode, ish.packing, i.packingOut) packing, b.packagingFk FROM sale s @@ -71,5 +71,3 @@ BEGIN DROP TEMPORARY TABLE tmp.sale; END$$ DELIMITER ; - -CALL `vn`.`sale_getBoxPickingList`(1, curdate()); \ No newline at end of file diff --git a/db/routines/vn/procedures/sale_getFromTicketOrCollection.sql b/db/routines/vn/procedures/sale_getFromTicketOrCollection.sql index e0cff202f..5308bdd28 100644 --- a/db/routines/vn/procedures/sale_getFromTicketOrCollection.sql +++ b/db/routines/vn/procedures/sale_getFromTicketOrCollection.sql @@ -79,7 +79,10 @@ DECLARE vIsCollection BOOL; IF(SUM(iss.quantity) IS NULL, 0, SUM(iss.quantity)) pickedQuantity, MIN(iss.created) picked, IF(sm.id, TRUE, FALSE) hasMistake, - sg.sectorFk + sg.sectorFk, + b.packing, + b.grouping, + o.code FROM tmp.ticket t JOIN sale s ON s.ticketFk = t.id JOIN ticket tt ON tt.id = t.id diff --git a/db/routines/vn/procedures/supplier_statement.sql b/db/routines/vn/procedures/supplier_statement.sql index 406286e9d..a03a7770c 100644 --- a/db/routines/vn/procedures/supplier_statement.sql +++ b/db/routines/vn/procedures/supplier_statement.sql @@ -94,7 +94,7 @@ BEGIN 'payment' FROM payment p LEFT JOIN currency c ON c.id = p.currencyFk - LEFT JOIN bank b ON b.id = p.bankFk + LEFT JOIN accounting a ON a.id = p.bankFk LEFT JOIN payMethod pm ON pm.id = p.payMethodFk LEFT JOIN promissoryNote pn ON pn.paymentFk = p.id WHERE p.received > '2014-12-31' diff --git a/db/routines/vn/procedures/ticket_closeByTicket.sql b/db/routines/vn/procedures/ticket_closeByTicket.sql index 6e32a3e76..837b809a2 100644 --- a/db/routines/vn/procedures/ticket_closeByTicket.sql +++ b/db/routines/vn/procedures/ticket_closeByTicket.sql @@ -18,7 +18,8 @@ BEGIN WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code != 'delivered')) AND t.id = vTicketFk AND t.refFk IS NULL - GROUP BY t.id); + GROUP BY t.id + ); CALL ticket_close(); diff --git a/db/routines/vn/triggers/parking_afterDelete.sql b/db/routines/vn/triggers/parking_afterDelete.sql new file mode 100644 index 000000000..1ec96c24d --- /dev/null +++ b/db/routines/vn/triggers/parking_afterDelete.sql @@ -0,0 +1,12 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`parking_afterDelete` + AFTER DELETE ON `parking` + FOR EACH ROW +BEGIN + INSERT INTO parkingLog + SET `action` = 'delete', + `changedModel` = 'Parking', + `changedModelId` = OLD.id, + `userFk` = account.myUser_getId(); +END$$ +DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/triggers/parking_beforeInsert.sql b/db/routines/vn/triggers/parking_beforeInsert.sql index 9cf0bd42a..cdec4c759 100644 --- a/db/routines/vn/triggers/parking_beforeInsert.sql +++ b/db/routines/vn/triggers/parking_beforeInsert.sql @@ -3,7 +3,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`parking_beforeInsert` BEFORE INSERT ON `parking` FOR EACH ROW BEGIN - + SET NEW.editorFk = account.myUser_getId(); -- SET new.`code` = CONCAT(new.`column`,' - ',new.`row`) ; END$$ diff --git a/db/routines/vn/triggers/parking_beforeUpdate.sql b/db/routines/vn/triggers/parking_beforeUpdate.sql index 38238daa1..3e808f505 100644 --- a/db/routines/vn/triggers/parking_beforeUpdate.sql +++ b/db/routines/vn/triggers/parking_beforeUpdate.sql @@ -3,7 +3,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`parking_beforeUpdate` BEFORE UPDATE ON `parking` FOR EACH ROW BEGIN - + SET NEW.editorFk = account.myUser_getId(); -- SET new.`code` = CONCAT(new.`column`,' - ',new.`row`) ; END$$ diff --git a/db/routines/vn/triggers/payment_beforeInsert.sql b/db/routines/vn/triggers/payment_beforeInsert.sql index 6a28a1382..1b343712f 100644 --- a/db/routines/vn/triggers/payment_beforeInsert.sql +++ b/db/routines/vn/triggers/payment_beforeInsert.sql @@ -10,21 +10,21 @@ BEGIN -- PAK 10/02/15 No se asientan los pagos directamente, salvo en el caso de las cajas de CASH SELECT (at2.code = 'cash') INTO bolCASH - FROM vn.bank b - JOIN vn.accountingType at2 ON at2.id = b.cash - WHERE b.id = NEW.bankFk; + FROM accounting a + JOIN accountingType at2 ON at2.id = a.accountingTypeFk + WHERE a.id = NEW.bankFk; IF bolCASH THEN SELECT account INTO cuenta_banco - FROM bank + FROM accounting WHERE id = NEW.bankFk; SELECT account INTO cuenta_proveedor FROM supplier WHERE id = NEW.supplierFk; - CALL vn.ledger_next(vNewBookEntry); + CALL ledger_next(vNewBookEntry); INSERT INTO XDiario ( ASIEN, FECHA, diff --git a/db/routines/vn/views/bank.sql b/db/routines/vn/views/bank.sql deleted file mode 100644 index fa0d9a4f0..000000000 --- a/db/routines/vn/views/bank.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE OR REPLACE DEFINER=`root`@`localhost` - SQL SECURITY DEFINER - VIEW `vn`.`bank` -AS SELECT `a`.`id` AS `id`, - `a`.`bank` AS `bank`, - `a`.`account` AS `account`, - `a`.`accountingTypeFk` AS `cash`, - `a`.`entityFk` AS `entityFk`, - `a`.`isActive` AS `isActive`, - `a`.`currencyFk` AS `currencyFk`, - `a`.`code` AS `code` -FROM `vn`.`accounting` `a` diff --git a/db/routines/vn/views/exchangeInsuranceOut.sql b/db/routines/vn/views/exchangeInsuranceOut.sql index f93b65331..5c41dbb24 100644 --- a/db/routines/vn/views/exchangeInsuranceOut.sql +++ b/db/routines/vn/views/exchangeInsuranceOut.sql @@ -7,9 +7,9 @@ AS SELECT `p`.`received` AS `received`, FROM ( ( `vn`.`payment` `p` - JOIN `vn`.`bank` `b` ON(`b`.`id` = `p`.`bankFk`) + JOIN `vn`.`accounting` `a` ON(`a`.`id` = `p`.`bankFk`) ) - JOIN `vn`.`accountingType` `at2` ON(`at2`.`id` = `b`.`cash`) + JOIN `vn`.`accountingType` `at2` ON(`at2`.`id` = `a`.`accountingTypeFk`) ) WHERE `p`.`currencyFk` = 2 AND `at2`.`code` = 'wireTransfer' diff --git a/db/routines/vn2008/procedures/CalculoRemesas.sql b/db/routines/vn2008/procedures/CalculoRemesas.sql deleted file mode 100644 index a4c191a80..000000000 --- a/db/routines/vn2008/procedures/CalculoRemesas.sql +++ /dev/null @@ -1,66 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`CalculoRemesas`(IN vFechaRemesa DATE) -BEGIN - - DROP TEMPORARY TABLE IF EXISTS TMP_REMESAS; - CREATE TEMPORARY TABLE TMP_REMESAS - SELECT - CONCAT(p.NIF,REPEAT('0', 12-LENGTH(p.NIF))) as CIF1, - cli.Id_Cliente, - cli.Cliente, - cli.`IF` as NIF, - c.PaymentDate as Vencimiento, - 0 ImporteFac, - cast(c.Recibo as decimal(10,2)) as ImporteRec, - 0 as ImporteActual, - c.companyFk empresa_id, - cli.RazonSocial, - cast(c.Recibo as decimal(10,2)) as ImporteTotal, - cast(c.Recibo as decimal(10,2)) as Saldo, - p.Proveedor as Empresa, - e.abbreviation as EMP, - cli.cuenta, - iban AS Iban, - CONVERT(SUBSTRING(iban,5,4),UNSIGNED INT) AS nrbe, - sepavnl as SEPA, - corevnl as RecibidoCORE, - hasLcr, - be.bic, - be.`name` entityName - FROM Clientes cli - JOIN - (SELECT risk.companyFk, - c.Id_Cliente, - sum(risk.amount) as Recibo, - IF((c.Vencimiento + graceDays) mod 30.001 <= day(vFechaRemesa) - ,TIMESTAMPADD(DAY, (c.Vencimiento + graceDays) MOD 30.001, LAST_DAY(TIMESTAMPADD(MONTH,-1,vFechaRemesa))) - ,TIMESTAMPADD(DAY, (c.Vencimiento + graceDays) MOD 30.001, LAST_DAY(TIMESTAMPADD(MONTH,-2,vFechaRemesa))) - ) as PaymentDate - FROM Clientes c - JOIN pay_met pm on pm.id = pay_met_id - JOIN - ( - SELECT companyFk, clientFk, amount - FROM Clientes c - JOIN vn.clientRisk cr ON cr.clientFk = c.Id_Cliente - WHERE pay_met_id = 4 - - UNION ALL - - SELECT io.companyFk, io.clientFk Id_Cliente, - io.amount - FROM vn.invoiceOut io - JOIN Clientes c ON c.Id_Cliente = io.clientFk - JOIN pay_met pm on pm.id = pay_met_id - WHERE io.dued > vFechaRemesa - AND pay_met_id = 4 AND pm.deudaviva - AND io.amount > 0 - - ) risk ON c.Id_Cliente = risk.clientFk - GROUP BY risk.companyFk, Id_Cliente - HAVING Recibo > 10 - ) c on c.Id_Cliente = cli.Id_Cliente - JOIN Proveedores p on p.Id_Proveedor = c.companyFk - JOIN empresa e on e.id = c.companyFk - LEFT JOIN vn.bankEntity be ON be.id = cli.bankEntityFk; -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/ListaTicketsEncajados.sql b/db/routines/vn2008/procedures/ListaTicketsEncajados.sql deleted file mode 100644 index ce99916ee..000000000 --- a/db/routines/vn2008/procedures/ListaTicketsEncajados.sql +++ /dev/null @@ -1,25 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`ListaTicketsEncajados`(IN intId_Trabajador int) -BEGIN - -SELECT Agencia, - Consignatario, - ti.Id_Ticket, - ts.userFk Id_Trabajador, - IFNULL(ncajas,0) AS ncajas, - IFNULL(nbultos,0) AS nbultos, - IFNULL(notros,0) AS notros, - ts.code AS Estado - FROM Tickets ti - INNER JOIN Consignatarios ON ti.Id_Consigna = Consignatarios.Id_consigna - INNER JOIN Agencias ON ti.Id_Agencia = Agencias.Id_Agencia - LEFT JOIN (SELECT ticketFk,count(*) AS ncajas FROM vn.expedition WHERE packagingFk=94 GROUP BY ticketFk) sub1 ON ti.Id_Ticket=sub1.ticketFk - LEFT JOIN (SELECT ticketFk,count(*) AS nbultos FROM vn.expedition WHERE packagingFk IS NULL GROUP BY ticketFk) sub2 ON ti.Id_Ticket=sub2.ticketFk - LEFT JOIN (SELECT ticketFk,count(*) AS notros FROM vn.expedition WHERE packagingFk >0 GROUP BY ticketFk) sub3 ON ti.Id_Ticket=sub3.ticketFk - INNER JOIN vn.ticketState ts ON ti.Id_ticket = ts.ticketFk - WHERE ti.Fecha=util.VN_CURDATE() AND - ts.userFk=intId_Trabajador - GROUP BY ti.Id_Ticket; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/cacheReset.sql b/db/routines/vn2008/procedures/cacheReset.sql deleted file mode 100644 index f36169fda..000000000 --- a/db/routines/vn2008/procedures/cacheReset.sql +++ /dev/null @@ -1,11 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`cacheReset`(vCacheName VARCHAR(10), vParams VARCHAR(15)) -BEGIN - - UPDATE cache.cache_calc - SET expires = util.VN_NOW() - WHERE cacheName = vCacheName collate utf8_unicode_ci - AND params = vParams collate utf8_unicode_ci; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/camiones.sql b/db/routines/vn2008/procedures/camiones.sql deleted file mode 100644 index 4c37cf9da..000000000 --- a/db/routines/vn2008/procedures/camiones.sql +++ /dev/null @@ -1,23 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`camiones`(vWarehouse INT, vDate DATE) -BEGIN - SELECT Temperatura - ,ROUND(SUM(Etiquetas * volume)) AS cm3 - ,ROUND(SUM(IF(scanned, Etiquetas, 0) * volume)) AS cm3s - ,ROUND(SUM(Vida * volume)) AS cm3e - FROM ( - SELECT t.Temperatura, c.Etiquetas, b.scanned, c.Vida, - IF(cu.Volumen > 0, cu.Volumen, cu.x * cu.y * IF(cu.z > 0, cu.z, a.Medida + 10)) volume - FROM Compres c - LEFT JOIN buy_edi b ON b.id = c.buy_edi_id - JOIN Articles a ON a.Id_Article = c.Id_Article - JOIN Tipos t ON t.tipo_id = a.tipo_id - JOIN Entradas e ON e.Id_Entrada = c.Id_Entrada - JOIN travel tr ON tr.id = e.travel_id - JOIN Cubos cu ON cu.Id_Cubo = c.Id_Cubo - WHERE tr.warehouse_id = vWarehouse - AND tr.landing = vDate - ) sub - GROUP BY Temperatura; -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/clean.sql b/db/routines/vn2008/procedures/clean.sql deleted file mode 100644 index 5a62b133e..000000000 --- a/db/routines/vn2008/procedures/clean.sql +++ /dev/null @@ -1,74 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`clean`(IN `v_full` TINYINT(1)) -proc: BEGIN - DECLARE vDate DATETIME; - DECLARE vDate18 DATETIME; - DECLARE vDate26 DATETIME; - DECLARE vDate8 DATE; - DECLARE vDate6 DATE; - DECLARE vDate3 DATE; - DECLARE vDate2000 DATE; - DECLARE vRangeDeleteTicket INT; - DECLARE vStrtable VARCHAR(15) DEFAULT NULL; - - SET vDate = util.VN_CURDATE() - INTERVAL 2 MONTH; - SET vDate18 = util.VN_CURDATE() - INTERVAL 18 MONTH; - SET vDate26 = util.VN_CURDATE() - INTERVAL 26 MONTH; - SET vDate3 = util.VN_CURDATE() - INTERVAL 3 MONTH; - SET vDate8 = util.VN_CURDATE() - INTERVAL 8 DAY; - SET vDate6 = util.VN_CURDATE() - INTERVAL 6 DAY; - SET vDate2000 = util.VN_CURDATE() + INTERVAL (2000 - YEAR(util.VN_CURDATE())) YEAR; - SET vRangeDeleteTicket = 60; - - DELETE FROM cdr WHERE calldate < vDate18; - DELETE FROM mail WHERE DATE_ODBC < vDate; - DELETE FROM Movimientos_mark WHERE odbc_date < vDate; - DELETE FROM Splits WHERE Fecha < vDate18; - - DELETE FROM Remesas WHERE `Fecha Remesa` < vDate18; - - DELETE tt.* - FROM Tickets_turno tt - LEFT JOIN Movimientos m USING(Id_Ticket) - WHERE m.Id_Article IS NULL; - - DELETE FROM cl_main WHERE Fecha < vDate18; - DELETE FROM hedera.`order` WHERE date_send < vDate18; - DELETE FROM vn.message WHERE sendDate < vDate; - - DELETE FROM cache.departure_limit WHERE Fecha < util.VN_CURDATE() - INTERVAL 1 MONTH; - - DELETE cm - FROM Compres_mark cm - JOIN Compres c ON c.Id_Compra = cm.Id_Compra - JOIN Entradas e ON e.Id_Entrada = c.Id_Entrada - JOIN travel t ON t.id = e.travel_id - WHERE t.landing <= vDate; - - IF v_full THEN - CREATE OR REPLACE TEMPORARY TABLE tTicketDelete - SELECT DISTINCT tl.originFk ticketFk - FROM vn.ticketLog tl - JOIN (SELECT MAX(tl.id)ids - FROM vn.ticket t - JOIN vn.ticketLog tl ON tl.originFk = t.id - WHERE t.shipped BETWEEN '2000-01-01' AND '2000-12-31' - AND t.isDeleted - GROUP BY t.id - )sub ON sub.ids = tl.id - WHERE tl.creationDate <= util.VN_CURDATE() - INTERVAL 60 DAY; - - DELETE t - FROM vn.ticket t - JOIN tTicketDelete tmp ON tmp.ticketFk = t.id; - - DROP TEMPORARY TABLE tTicketDelete; - END IF; - - -- Tickets Nulos PAK 11/10/2016 - UPDATE Tickets - SET empresa_id = 965 - WHERE Id_Cliente = 31 - AND empresa_id != 965; -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/clean_launcher.sql b/db/routines/vn2008/procedures/clean_launcher.sql deleted file mode 100644 index 63c23e8cf..000000000 --- a/db/routines/vn2008/procedures/clean_launcher.sql +++ /dev/null @@ -1,6 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`clean_launcher`() -BEGIN - CALL clean(TRUE); -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/cobro.sql b/db/routines/vn2008/procedures/cobro.sql deleted file mode 100644 index 26d906813..000000000 --- a/db/routines/vn2008/procedures/cobro.sql +++ /dev/null @@ -1,79 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`cobro`(IN datFEC DATE - , IN idCLI INT - , IN dblIMPORTE DOUBLE - , IN idCAJA INT - , IN idPAYMET INT - , IN strCONCEPTO VARCHAR(40) - , IN idEMP INT - , IN idWH INT - , IN idTRABAJADOR INT) -BEGIN - - DECLARE bolCASH BOOLEAN; - DECLARE cuenta_banco BIGINT; - DECLARE cuenta_cliente BIGINT; - DECLARE max_asien INT; - -- XDIARIO - -- No se asientan los cobros directamente, salvo en el caso de las cajas de CASH - SELECT (at2.code = 'cash') INTO bolCASH FROM Bancos b JOIN vn.accountingType at2 ON at2.id = b.cash WHERE b.Id_Banco = idCAJA; - IF bolCASH THEN - SELECT Cuenta INTO cuenta_banco - FROM Bancos - WHERE Id_Banco = idCAJA; - SELECT Cuenta INTO cuenta_cliente - FROM Clientes - WHERE Id_Cliente = idCLI; - CALL vn.ledger_next(max_asien); - INSERT INTO vn.XDiario (ASIEN,FECHA,SUBCTA,CONTRA,CONCEPTO,EURODEBE,EUROHABER,empresa_id) - SELECT max_asien,datFEC,SUBCTA,CONTRA,strCONCEPTO,EURODEBE,EUROHABER,idEMP - FROM(SELECT cuenta_banco SUBCTA, cuenta_cliente CONTRA, 0 EURODEBE, dblIMPORTE EUROHABER - UNION ALL - SELECT cuenta_cliente SUBCTA, cuenta_banco CONTRA, dblIMPORTE EURODEBE, 0 EUROHABER - ) gf; - END IF; - - -- CAJERA - INSERT INTO Cajas(Id_Trabajador, - Id_Banco, - Entrada, - Concepto, - Cajafecha, - Serie, - Partida, - Numero, - empresa_id, - warehouse_id - ) - VALUES (idTRABAJADOR, - idCAJA, - dblIMPORTE, - strCONCEPTO, - datFEC, - 'A', - TRUE, - idCLI, - idEMP, - idWH - ); - - -- RECIBO - INSERT INTO Recibos(Entregado, - Fechacobro, - Id_Trabajador, - Id_Banco, - Id_Cliente, - Id_Factura, - empresa_id - ) - VALUES ( dblIMPORTE, - datFEC, - idTRABAJADOR, - idCAJA, - idCLI, - strCONCEPTO, - idEMP - ); - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/confection_control_source.sql b/db/routines/vn2008/procedures/confection_control_source.sql deleted file mode 100644 index 77b4df5f3..000000000 --- a/db/routines/vn2008/procedures/confection_control_source.sql +++ /dev/null @@ -1,105 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`confection_control_source`(vDated DATE, vScopeDays TINYINT) -BEGIN - - DECLARE vMidnight DATETIME DEFAULT TIMESTAMP(vDated,'23:59:59'); - DECLARE vEndingDate DATETIME DEFAULT TIMESTAMPADD(DAY,vScopeDays,vMidnight); - DECLARE maxAlertLevel INT DEFAULT 2; - - DROP TEMPORARY TABLE IF EXISTS tmp.production_buffer; - - CREATE TEMPORARY TABLE tmp.production_buffer - ENGINE = MEMORY - SELECT - date(t.Fecha) as Fecha, - hour(t.Fecha) as Hora, - hour(t.Fecha) as Departure, - t.Id_Ticket, - m.Id_Movimiento, - m.Cantidad, - m.Concepte, - ABS(m.Reservado) Reservado, - i.Categoria, - tp.Tipo, - t.Alias as Cliente, - wh.name as Almacen, - t.warehouse_id, - cs.province_id, - a.agency_id, - ct.description as Taller, - stock.visible, - stock.available - FROM vn2008.Tickets t - JOIN vn2008.Agencias a ON a.Id_Agencia = t.Id_Agencia - JOIN vn.warehouse wh ON wh.id = t.warehouse_id - JOIN vn2008.Movimientos m ON m.Id_Ticket = t.Id_Ticket - JOIN vn2008.Articles i ON i.Id_Article = m.Id_Article - JOIN vn2008.Tipos tp ON tp.tipo_id = i.tipo_id - JOIN vn.confectionType ct ON ct.id = tp.confeccion - JOIN vn2008.Consignatarios cs on cs.Id_Consigna = t.Id_Consigna - LEFT JOIN vn.ticketState tls on tls.ticketFk = t.Id_Ticket - LEFT JOIN - ( - SELECT item_id, sum(visible) visible, sum(available) available - FROM - ( - SELECT a.item_id, 0 as visible, a.available - FROM cache.cache_calc cc - LEFT JOIN cache.available a ON a.calc_id = cc.id - WHERE cc.cache_id IN (2,8) - AND cc.params IN (concat("1/", util.VN_CURDATE()),concat("44/", util.VN_CURDATE())) - - UNION ALL - - SELECT v.item_id, v.visible, 0 as available - FROM cache.cache_calc cc - LEFT JOIN cache.visible v ON v.calc_id = cc.id - where cc.cache_id IN (2,8) and cc.params IN ("1","44") - ) sub - GROUP BY item_id - ) stock ON stock.item_id = m.Id_Article - WHERE tp.confeccion - AND tls.alertLevel < maxAlertLevel - AND wh.hasConfectionTeam - AND t.Fecha BETWEEN vDated AND vEndingDate - AND m.Cantidad > 0; - - -- Entradas - - INSERT INTO tmp.production_buffer( - Fecha, - Id_Ticket, - Cantidad, - Concepte, - Categoria, - Cliente, - Almacen, - Taller - ) - SELECT - tr.shipment AS Fecha, - e.Id_Entrada AS Id_Ticket, - c.Cantidad, - a.Article, - a.Categoria, - whi.name as Cliente, - who.name as Almacen, - ct.description as Taller - FROM vn2008.Compres c - JOIN vn2008.Entradas e ON e.Id_Entrada = c.Id_Entrada - JOIN vn2008.travel tr ON tr.id = e.travel_id - JOIN vn.warehouse whi ON whi.id = tr.warehouse_id - JOIN vn.warehouse who ON who.id = tr.warehouse_id_out - JOIN vn2008.Articles a ON a.Id_Article = c.Id_Article - JOIN vn2008.Tipos tp ON tp.tipo_id = a.tipo_id - JOIN vn.confectionType ct ON ct.id = tp.confeccion - WHERE who.hasConfectionTeam - AND tp.confeccion - AND tr.shipment BETWEEN vDated AND vEndingDate; - - - SELECT * FROM tmp.production_buffer; - - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/customerDebtEvolution.sql b/db/routines/vn2008/procedures/customerDebtEvolution.sql deleted file mode 100644 index b9763b985..000000000 --- a/db/routines/vn2008/procedures/customerDebtEvolution.sql +++ /dev/null @@ -1,49 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`customerDebtEvolution`(IN vCustomer INT) -BEGIN - -SELECT * FROM -( - SELECT day, date, @s:= round(IFNULL(Euros,0) + @s,2) as Saldo, Euros, Credito, 0 as Cero - FROM - ( - SELECT day, date, IFNULL(Euros,0) as Euros, Credito - FROM time - JOIN (SELECT @s:= 0, - Credito as Credito FROM Clientes WHERE Id_Cliente = vCustomer) c - LEFT JOIN - (SELECT Euros, date(Fecha) as Fecha FROM - ( - SELECT Fechacobro as Fecha, Entregado as Euros - FROM Recibos - WHERE Id_Cliente = vCustomer - AND Fechacobro >= '2017-01-01' - UNION ALL - SELECT vn.getDueDate(io.issued,c.Vencimiento), - io.amount - FROM vn.invoiceOut io - JOIN Clientes c ON io.clientFk = c.Id_Cliente - WHERE io.clientFk = vCustomer - AND io.issued >= '2017-01-01' - UNION ALL - SELECT '2016-12-31', Debt - FROM bi.customerDebtInventory - WHERE Id_Cliente = vCustomer - UNION ALL - SELECT Fecha, - SUM(Cantidad * Preu * (100 - Descuento ) * 1.10 / 100) - FROM Tickets t - JOIN Movimientos m on m.Id_Ticket = t.Id_Ticket - WHERE Id_Cliente = vCustomer - AND Factura IS NULL - AND Fecha >= '2017-01-01' - GROUP BY Fecha - ) sub2 - ORDER BY Fecha - )sub ON time.date = sub.Fecha - WHERE time.date BETWEEN '2016-12-31' AND util.VN_CURDATE() - ORDER BY date - ) sub3 -)sub4 -; - - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/emailYesterdayPurchasesByConsigna.sql b/db/routines/vn2008/procedures/emailYesterdayPurchasesByConsigna.sql deleted file mode 100644 index 439eba5ad..000000000 --- a/db/routines/vn2008/procedures/emailYesterdayPurchasesByConsigna.sql +++ /dev/null @@ -1,100 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`emailYesterdayPurchasesByConsigna`(IN v_Date DATE, IN v_Client_Id INT) -BEGIN - - DECLARE MyIdTicket BIGINT; - DECLARE MyAlias VARCHAR(50); - DECLARE MyDomicilio VARCHAR(255); - DECLARE MyPoblacion VARCHAR(25); - DECLARE MyImporte DOUBLE; - DECLARE MyMailTo VARCHAR(250); - DECLARE MyMailReplyTo VARCHAR(250); - DECLARE done INT DEFAULT FALSE; - DECLARE emptyList INT DEFAULT 0; - DECLARE txt TEXT; - - DECLARE rs CURSOR FOR - SELECT t.Id_Ticket, Alias, cast(amount as decimal(10,2)) Importe, Domicilio, POBLACION - FROM Tickets t - JOIN Consignatarios cs ON t.Id_Consigna = cs.Id_Consigna - JOIN ( - SELECT `Movimientos`.`Id_Ticket` AS `Id_Ticket`, - sum( - `Movimientos`.`Cantidad` * `Movimientos`.`Preu` * (100 - `Movimientos`.`Descuento`) / 100 - ) AS `amount` - FROM ( - `vn2008`.`Movimientos` - JOIN `vn2008`.`Tickets` ON( - `Movimientos`.`Id_Ticket` = `Tickets`.`Id_Ticket` - ) - ) - WHERE `Tickets`.`Fecha` >= `util`.`VN_CURDATE`() + INTERVAL -6 MONTH - GROUP BY `Movimientos`.`Id_Ticket` - ) v ON v.Id_Ticket = t.Id_Ticket - WHERE t.Fecha BETWEEN v_Date AND util.dayEnd(v_Date) - AND t.Id_Cliente = v_Client_Id; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; - - SET v_Date = IFNULL(v_Date, util.yesterday()); - - OPEN rs; - - FETCH rs INTO MyIdTicket, MyAlias, MyImporte, MyDomicilio, MyPoblacion; - - SET emptyList = done; - - SET txt = CONCAT('

', - '

Relación de envíos.

', - '

Dia: ', v_Date, '

'); - - WHILE NOT done DO - - SET txt = CONCAT(txt, '

', - ' - - - - - - -
- Ticket ', MyIdTicket,' ', MyImporte, ' €
' - , ' ', MyAlias, '
' - , ' ', MyDomicilio, '(', MyPoblacion, ')'); - - FETCH rs INTO MyIdTicket, MyAlias, MyImporte, MyDomicilio, MyPoblacion; - - END WHILE; - - SET txt = CONCAT( - txt, - '', - '', - '
', - '

Puede acceder al detalle de los albaranes haciendo click sobre el número de Ticket', - '

Muchas gracias por su confianza

', - '

'); - - -- Envío del email - IF emptyList = 0 THEN - - SELECT CONCAT(`e-mail`,',pako@verdnatura.es') INTO MyMailTo - FROM Clientes - WHERE Id_Cliente = v_Client_Id AND `e-mail`>''; - - IF v_Client_Id = 7818 THEN -- LOEWE - SET MyMailTo = 'isabel@elisabethblumen.com,emunozca@loewe.es,pako@verdnatura.es'; - END IF; - - CALL vn.mail_insert( - IFNULL(MyMailTo,'pako.natek@gmail.com'), - 'pako@verdnatura.es', - 'Resumen de pedidos preparados', - txt - ); - - END IF; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/emailYesterdayPurchasesLauncher.sql b/db/routines/vn2008/procedures/emailYesterdayPurchasesLauncher.sql deleted file mode 100644 index c414cf1c4..000000000 --- a/db/routines/vn2008/procedures/emailYesterdayPurchasesLauncher.sql +++ /dev/null @@ -1,27 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`emailYesterdayPurchasesLauncher`() -BEGIN - -DECLARE done INT DEFAULT 0; -DECLARE vMyClientId INT; - -DECLARE rs CURSOR FOR -SELECT Id_Cliente -FROM Clientes -WHERE EYPBC != 0; - -DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; - -OPEN rs; - -FETCH rs INTO vMyClientId; - -WHILE NOT done DO - - CALL emailYesterdayPurchasesByConsigna(util.yesterday(), vMyClientId); - - FETCH rs INTO vMyClientId; - -END WHILE; -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/embalajes_stocks.sql b/db/routines/vn2008/procedures/embalajes_stocks.sql deleted file mode 100644 index b20e44c79..000000000 --- a/db/routines/vn2008/procedures/embalajes_stocks.sql +++ /dev/null @@ -1,51 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`embalajes_stocks`(IN idPEOPLE INT, IN bolCLIENT BOOLEAN) -BEGIN - -if bolCLIENT then - - select m.Id_Article, Article, - cast(sum(m.Cantidad) as decimal) as Saldo - from Movimientos m - join Articles a on m.Id_Article = a.Id_Article - join Tipos tp on tp.tipo_id = a.tipo_id - join Tickets t using(Id_Ticket) - join Consignatarios cs using(Id_Consigna) - where cs.Id_Cliente = idPEOPLE - and Tipo = 'Contenedores' - and t.Fecha > '2010-01-01' - group by m.Id_Article; - -else - -select Id_Article, Article, sum(Cantidad) as Saldo -from -(select Id_Article, Cantidad -from Compres c -join Articles a using(Id_Article) -join Tipos tp using(tipo_id) -join Entradas e using(Id_Entrada) -join travel tr on tr.id = travel_id -where Id_Proveedor = idPEOPLE -and landing >= '2010-01-01' -and reino_id = 6 - -union all - -select Id_Article, - Cantidad -from Movimientos m -join Articles a using(Id_Article) -join Tipos tp using(tipo_id) -join Tickets t using(Id_Ticket) -join Consignatarios cs using(Id_Consigna) -join proveedores_clientes pc on pc.Id_Cliente = cs.Id_Cliente -where Id_Proveedor = idPEOPLE -and reino_id = 6 -and t.Fecha > '2010-01-01') mov - -join Articles a using(Id_Article) -group by Id_Article; - -end if; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/embalajes_stocks_detalle.sql b/db/routines/vn2008/procedures/embalajes_stocks_detalle.sql deleted file mode 100644 index c49d1b88a..000000000 --- a/db/routines/vn2008/procedures/embalajes_stocks_detalle.sql +++ /dev/null @@ -1,78 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`embalajes_stocks_detalle`(IN idPEOPLE INT, IN idARTICLE INT, IN bolCLIENT BOOLEAN) -BEGIN - - -if bolCLIENT then - - select m.Id_Article - , Article - , IF(Cantidad < 0, - Cantidad, NULL) as Entrada - , IF(Cantidad < 0, NULL, Cantidad) as Salida - , 'T' as Tabla - , t.Id_Ticket as Registro - , t.Fecha - , w.name as Almacen - , cast(Preu as Decimal(5,2)) Precio - , c.Cliente as Proveedor - , abbreviation as Empresa - from Movimientos m - join Articles a using(Id_Article) - join Tickets t using(Id_Ticket) - join empresa e on e.id = t.empresa_id - join warehouse w on w.id = t.warehouse_id - join Consignatarios cs using(Id_Consigna) - join Clientes c on c.Id_Cliente = cs.Id_Cliente - where cs.Id_Cliente = idPEOPLE - and m.Id_Article = idARTICLE - and t.Fecha > '2010-01-01'; - -else - -select Id_Article, Tabla, Registro, Fecha, Article -, w.name as Almacen, Entrada, Salida, Proveedor, cast(Precio as Decimal(5,2)) Precio - -from - -(select Id_Article - , IF(Cantidad > 0, Cantidad, NULL) as Entrada - , IF(Cantidad > 0, NULL,- Cantidad) as Salida - , 'E' as Tabla - , Id_Entrada as Registro - , landing as Fecha - , tr.warehouse_id - , Costefijo as Precio -from Compres c -join Entradas e using(Id_Entrada) -join travel tr on tr.id = travel_id -where Id_Proveedor = idPEOPLE -and Id_Article = idARTICLE -and landing >= '2010-01-01' - -union all - -select Id_Article - , IF(Cantidad < 0, - Cantidad, NULL) as Entrada - , IF(Cantidad < 0, NULL, Cantidad) as Salida - , 'T' - , Id_Ticket - , Fecha - , t.warehouse_id - , Preu -from Movimientos m -join Tickets t using(Id_Ticket) -join Consignatarios cs using(Id_Consigna) -join proveedores_clientes pc on pc.Id_Cliente = cs.Id_Cliente -where Id_Proveedor = idPEOPLE -and Id_Article = idARTICLE -and t.Fecha > '2010-01-01') mov - -join Articles a using(Id_Article) -join Proveedores p on Id_Proveedor = idPEOPLE -join warehouse w on w.id = mov.warehouse_id -; - -end if; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/nest_child_add.sql b/db/routines/vn2008/procedures/nest_child_add.sql deleted file mode 100644 index 5b45a9d07..000000000 --- a/db/routines/vn2008/procedures/nest_child_add.sql +++ /dev/null @@ -1,48 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`nest_child_add`( - vTable VARCHAR(45) - ,vChild VARCHAR(45) - ,vFatherId INT -) -BEGIN - DECLARE vMyLeft INT; - - SET vTable = util.quoteIdentifier(vTable); - - DROP TEMPORARY TABLE IF EXISTS aux; - CREATE TEMPORARY TABLE aux - SELECT 0 as lft; - - EXECUTE IMMEDIATE CONCAT( - 'UPDATE aux - SET lft = (SELECT lft - FROM ', vTable, - ' WHERE id = ?)') - USING vFatherId; - - SELECT lft INTO vMyLeft FROM aux; - DROP TEMPORARY TABLE aux; - - EXECUTE IMMEDIATE CONCAT( - 'UPDATE ', vTable, ' - SET rgt = rgt + 2 - WHERE rgt > ? - ORDER BY rgt DESC') - USING vMyLeft; - - EXECUTE IMMEDIATE CONCAT( - 'UPDATE ', vTable, ' - SET lft = lft + 2 - WHERE lft > ? - ORDER BY lft DESC') - USING vMyLeft; - - EXECUTE IMMEDIATE CONCAT( - 'INSERT INTO ', vTable, ' (name, lft, rgt) - VALUES(?, ? + 1, ? + 2)') - USING vChild, - vMyLeft, - vMyLeft; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/nest_delete.sql b/db/routines/vn2008/procedures/nest_delete.sql deleted file mode 100644 index 84f75294b..000000000 --- a/db/routines/vn2008/procedures/nest_delete.sql +++ /dev/null @@ -1,51 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`nest_delete`( - vTable VARCHAR(45) - ,vNodeId INT -) -BEGIN - DECLARE vMyRight INT; - DECLARE vMyLeft INT; - DECLARE vMyWidth INT; - - DROP TEMPORARY TABLE IF EXISTS aux; - CREATE TEMPORARY TABLE aux - SELECT 0 rgt, 0 lft, 0 wdt; - - SET vTable = util.quoteIdentifier(vTable); - - EXECUTE IMMEDIATE CONCAT( - 'UPDATE aux a - JOIN ', vTable, ' t - SET a.rgt = t.rgt, - a.lft = t.lft, - a.wdt = t.rgt - t.lft + 1 - WHERE t.id = ?') - USING vNodeId; - - SELECT rgt, lft, wdt - INTO vMyRight, vMyLeft, vMyWidth - FROM aux; - - DROP TEMPORARY TABLE aux; - - EXECUTE IMMEDIATE CONCAT( - 'DELETE FROM ', vTable, - ' WHERE lft BETWEEN ? AND ?') - USING vMyLeft, vMyRight; - - EXECUTE IMMEDIATE CONCAT( - 'UPDATE ', vTable, - ' SET rgt = rgt - ? - WHERE rgt > ? - ORDER BY rgt') - USING vMyWidth,vMyRight; - - EXECUTE IMMEDIATE CONCAT( - 'UPDATE ', vTable, - ' SET lft = lft - ? - WHERE lft > ? - ORDER BY lft') - USING vMyWidth, vMyRight; -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/nest_move.sql b/db/routines/vn2008/procedures/nest_move.sql deleted file mode 100644 index 950d46e68..000000000 --- a/db/routines/vn2008/procedures/nest_move.sql +++ /dev/null @@ -1,108 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`nest_move`( - vTable VARCHAR(45) - ,idNODE INT - ,idFATHER INT -) -BEGIN - DECLARE myRight INT; - DECLARE myLeft INT; - DECLARE myWidth INT; - DECLARE fatherRight INT; - DECLARE fatherLeft INT; - DECLARE gap INT; - - SET vTable = util.quoteIdentifier(vTable); - - DROP TEMPORARY TABLE IF EXISTS aux; - CREATE TEMPORARY TABLE aux - SELECT 0 as rgt, 0 as lft, 0 as wdt, 0 as frg, 0 as flf; - - -- Averiguamos el ancho de la rama - EXECUTE IMMEDIATE CONCAT( - 'UPDATE aux a - JOIN ', vTable, ' t - SET a.wdt = t.rgt - t.lft + 1 - WHERE t.id = ?') - USING idNODE; - - -- Averiguamos la posicion del nuevo padre - EXECUTE IMMEDIATE CONCAT( - 'UPDATE aux a - JOIN ', vTable, ' t - SET a.frg = t.rgt, - a.flf = t.lft - WHERE t.id = ?') - USING idFATHER; - - SELECT wdt, frg, flf INTO myWidth, fatherRight, fatherLeft - FROM aux; - - -- 1º Incrementamos los valores de todos los nodos a la derecha del punto de inserción (fatherRight) , para hacer sitio - EXECUTE IMMEDIATE CONCAT( - 'UPDATE ', vTable, - 'SET rgt = rgt + ? - WHERE rgt >= ? - ORDER BY rgt DESC') - USING myWidth, - fatherRight; - - EXECUTE IMMEDIATE CONCAT( - 'UPDATE ', vTable, - 'SET lft = lft + ? - WHERE lft >= ? - ORDER BY lft DESC') - USING myWidth, - fatherRight; - - -- Es preciso recalcular los valores del nodo en el caso de que estuviera a la derecha del nuevo padre - EXECUTE IMMEDIATE CONCAT( - 'UPDATE aux a - JOIN ', vTable, ' t - SET a.rgt = t.rgt, - a.lft = t.lft - WHERE t.id = ?') - USING idNODE; - - SELECT lft, rgt, frg - lft INTO myLeft, myRight, gap - FROM aux; - - -- 2º Incrementamos el valor de todos los nodos a trasladar hasta alcanzar su nueva posicion - EXECUTE IMMEDIATE CONCAT( - 'UPDATE ', vTable, - 'SET lft = lft + ? - WHERE lft BETWEEN ? AND ? - ORDER BY lft DESC') - USING gap, - myLeft, - myRight; - - EXECUTE IMMEDIATE CONCAT( - 'UPDATE ', vTable, - 'SET rgt = rgt + ? - WHERE rgt BETWEEN ? AND ? - ORDER BY rgt DESC') - USING gap, - myLeft, - myRight; - - -- 3º Restaremos a todos los nodos resultantes, a la derecha de la posicion arrancada el ancho de la rama escindida - EXECUTE IMMEDIATE CONCAT( - 'UPDATE ', vTable, - 'SET lft = lft - ? - WHERE lft > ? - ORDER BY lft') - USING myWidth, - myLeft; - - EXECUTE IMMEDIATE CONCAT( - 'UPDATE ', vTable, - 'SET rgt = rgt - ? - WHERE rgt > ? - ORDER BY rgt') - USING myWidth, - myRight; - - DROP TEMPORARY TABLE aux; -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/pay.sql b/db/routines/vn2008/procedures/pay.sql deleted file mode 100644 index ec73ee696..000000000 --- a/db/routines/vn2008/procedures/pay.sql +++ /dev/null @@ -1,67 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`pay`(IN datFEC DATE - , IN idPROV INT - , IN dblIMPORTE DOUBLE - , IN idMONEDA INT - , IN dblDIVISA DOUBLE - , IN idCAJA INT - , IN idPAYMET INT - , IN dblGASTOS DOUBLE - , IN strCONCEPTO VARCHAR(40) - , IN idEMP INT) -BEGIN - - -- Registro en la tabla Cajas - INSERT INTO Cajas ( Concepto - , Serie - , Numero - , Salida - , Cajafecha - , Partida - , Id_Banco - , Id_Trabajador - ,empresa_id - ,conciliado) - - SELECT CONCAT('n/pago a ', Proveedor) - , 'R' - , idPROV - , dblIMPORTE - , datFEC - , 1 - , idCAJA - , account.myUser_getId() - , idEMP - , 1 - FROM Proveedores - WHERE Id_Proveedor = idPROV; - - -- Registro en la tabla pago - INSERT INTO pago(fecha - , dueDated - , id_proveedor - , importe - , id_moneda - , divisa - , id_banco - , pay_met_id - , g_bancarios - , concepte - , empresa_id) - - VALUES(datFEC - , datFEC - , idPROV - , dblIMPORTE - , idMONEDA - , IF(dblDIVISA = 0, NULL, dblDIVISA) - , idCAJA - , idPAYMET - , dblGASTOS - , strCONCEPTO - , idEMP); - - SELECT LAST_INSERT_ID() as pago_id; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/preOrdenarRuta.sql b/db/routines/vn2008/procedures/preOrdenarRuta.sql deleted file mode 100644 index b5fd2b24b..000000000 --- a/db/routines/vn2008/procedures/preOrdenarRuta.sql +++ /dev/null @@ -1,22 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`preOrdenarRuta`(IN vRutaId INT) -BEGIN -/* Usa los valores del ultimo año para adivinar el orden de los tickets en la ruta - * vRutaId id ruta - * DEPRECATED use vn.routeGressPriority -*/ - -UPDATE Tickets mt -JOIN ( - SELECT tt.Id_Consigna, round(ifnull(avg(t.Prioridad),0),0) as Prioridad - from Tickets t - JOIN Tickets tt on tt.Id_Consigna = t.Id_Consigna - where t.Fecha > TIMESTAMPADD(YEAR,-1,util.VN_CURDATE()) - AND tt.Id_Ruta = vRutaId - GROUP BY Id_Consigna - ) sub ON sub.Id_Consigna = mt.Id_Consigna - SET mt.Prioridad = sub.Prioridad - WHERE mt.Id_Ruta = vRutaId; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/prepare_ticket_list.sql b/db/routines/vn2008/procedures/prepare_ticket_list.sql deleted file mode 100644 index e407a91b7..000000000 --- a/db/routines/vn2008/procedures/prepare_ticket_list.sql +++ /dev/null @@ -1,22 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`prepare_ticket_list`(vStartingDate DATETIME, vEndingDate DATETIME) -BEGIN - DROP TEMPORARY TABLE IF EXISTS tmp.ticket_list; - CREATE TEMPORARY TABLE tmp.ticket_list - (PRIMARY KEY (Id_Ticket)) - ENGINE = MEMORY - SELECT t.Id_Ticket, c.Id_Cliente - FROM Tickets t - LEFT JOIN vn.ticketState ts ON ts.ticketFk = t.Id_Ticket - JOIN Clientes c ON c.Id_Cliente = t.Id_Cliente - WHERE c.typeFk IN ('normal','handMaking','internalUse') - AND ( - Fecha BETWEEN util.today() AND vEndingDate - OR ( - ts.alertLevel < 3 - AND t.Fecha >= vStartingDate - AND t.Fecha < util.today() - ) - ); -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/procedures/recibidaIvaInsert.sql b/db/routines/vn2008/procedures/recibidaIvaInsert.sql deleted file mode 100644 index e2aba0a35..000000000 --- a/db/routines/vn2008/procedures/recibidaIvaInsert.sql +++ /dev/null @@ -1,39 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`recibidaIvaInsert`(IN vId INT) -BEGIN - - DECLARE vRate DOUBLE DEFAULT 1; - DECLARE vDated DATE; - - SELECT MAX(rr.date) INTO vDated - FROM reference_rate rr - JOIN recibida r ON r.id = vId - WHERE rr.date <= r.fecha - AND rr.moneda_id = r.moneda_id ; - - IF vDated THEN - - SELECT rate INTO vRate - FROM reference_rate - WHERE `date` = vDated; - END IF; - - DELETE FROM recibida_iva WHERE recibida_id = vId; - - INSERT INTO recibida_iva(recibida_id, bi, gastos_id, divisa, taxTypeSageFk, transactionTypeSageFk) - SELECT r.id, - SUM(Costefijo * Cantidad) / IFNULL(vRate,1) bi, - 6003000000, - IF(r.moneda_id = 1,NULL,SUM(Costefijo * Cantidad )) divisa, - taxTypeSageFk, - transactionTypeSageFk - FROM recibida r - JOIN Entradas e ON e.recibida_id = r.id - JOIN Proveedores p ON p.Id_Proveedor = e.Id_Proveedor - JOIN Compres c ON c.Id_Entrada = e.Id_Entrada - LEFT JOIN reference_rate rr ON rr.moneda_id = r.moneda_id AND rr.date = r.fecha - WHERE r.id = vId - HAVING bi IS NOT NULL; - -END$$ -DELIMITER ; diff --git a/db/routines/vn2008/views/Bancos.sql b/db/routines/vn2008/views/Bancos.sql index 0c6f8d1bd..6e850f365 100644 --- a/db/routines/vn2008/views/Bancos.sql +++ b/db/routines/vn2008/views/Bancos.sql @@ -1,11 +1,11 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vn2008`.`Bancos` -AS SELECT `b`.`id` AS `Id_Banco`, - `b`.`bank` AS `Banco`, - `b`.`account` AS `Cuenta`, - `b`.`cash` AS `cash`, - `b`.`entityFk` AS `entity_id`, - `b`.`isActive` AS `activo`, - `b`.`currencyFk` AS `currencyFk` -FROM `vn`.`bank` `b` +AS SELECT `a`.`id` AS `Id_Banco`, + `a`.`bank` AS `Banco`, + `a`.`account` AS `Cuenta`, + `a`.`accountingTypeFk` AS `cash`, + `a`.`entityFk` AS `entity_id`, + `a`.`isActive` AS `activo`, + `a`.`currencyFk` AS `currencyFk` +FROM `vn`.`accounting` `a` diff --git a/db/versions/10832-purpleAralia/00-newWareHouse.sql b/db/versions/10832-purpleAralia/00-newWareHouse.sql new file mode 100644 index 000000000..dd2c16bdb --- /dev/null +++ b/db/versions/10832-purpleAralia/00-newWareHouse.sql @@ -0,0 +1,12 @@ +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('Collection', 'assign', 'WRITE', 'ALLOW', 'ROLE', 'production'), + ('ExpeditionPallet', 'getPallet', 'READ', 'ALLOW', 'ROLE', 'production'), + ('MachineWorker','updateInTime','WRITE','ALLOW','ROLE','production'), + ('MobileAppVersionControl','getVersion','READ','ALLOW','ROLE','production'), + ('SaleTracking','delete','WRITE','ALLOW','ROLE','production'), + ('SaleTracking','updateTracking','WRITE','ALLOW','ROLE','production'), + ('SaleTracking','setPicked','WRITE','ALLOW','ROLE','production'), + ('ExpeditionPallet', '*', 'READ', 'ALLOW', 'ROLE', 'production'), + ('Sale', 'getFromSectorCollection', 'READ', 'ALLOW', 'ROLE', 'production'), + ('ItemBarcode', 'delete', 'WRITE', 'ALLOW', 'ROLE', 'production'); \ No newline at end of file diff --git a/db/versions/10905-grayIvy/00-firstScript.sql b/db/versions/10905-grayIvy/00-firstScript.sql new file mode 100644 index 000000000..cca41cd48 --- /dev/null +++ b/db/versions/10905-grayIvy/00-firstScript.sql @@ -0,0 +1,36 @@ +USE vn; + +CREATE OR REPLACE TABLE vn.workerActivityType ( + `code` varchar(20) NOT NULL, + `description` varchar(45) NOT NULL, + PRIMARY KEY (`code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +ALTER TABLE vn.department ADD workerActivityTypeFk varchar(20) NULL COMMENT 'Indica la actitividad que desempeña por defecto ese departamento'; +ALTER TABLE vn.department ADD CONSTRAINT department_workerActivityType_FK FOREIGN KEY (workerActivityTypeFk) REFERENCES vn.workerActivityType(code) ON DELETE CASCADE ON UPDATE CASCADE; + + + +INSERT INTO vn.workerActivityType (code, description) VALUES('ON_CHECKING', 'REVISION'); +INSERT INTO vn.workerActivityType (code, description) VALUES('PREVIOUS_CAM', 'CAMARA'); +INSERT INTO vn.workerActivityType (code, description) VALUES('PREVIOUS_ART', 'ARTIFICIAL'); +INSERT INTO vn.workerActivityType (code, description) VALUES('ON_PREPARATION', 'SACADO'); +INSERT INTO vn.workerActivityType (code, description) VALUES('PACKING', 'ENCAJADO'); +INSERT INTO vn.workerActivityType (code, description) VALUES('FIELD', 'CAMPOS'); +INSERT INTO vn.workerActivityType (code, description) VALUES('DELIVERY', 'REPARTO'); +INSERT INTO vn.workerActivityType (code, description) VALUES('STORAGE', 'ALMACENAJE'); +INSERT INTO vn.workerActivityType (code, description) VALUES('PALLETIZING', 'PALETIZADO'); +INSERT INTO vn.workerActivityType (code, description) VALUES('STOP', 'PARADA'); + + +INSERT INTO salix.ACL ( model, property, accessType, permission, principalType, principalId) VALUES('WorkerActivityType', '*', 'READ', 'ALLOW', 'ROLE', 'production'); +INSERT INTO salix.ACL ( model, property, accessType, permission, principalType, principalId) VALUES('WorkerActivity', '*', '*', 'ALLOW', 'ROLE', 'production'); + + +ALTER TABLE vn.workerActivity MODIFY COLUMN event enum('open','close','insert','delete','update','refresh') CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL; +ALTER TABLE vn.workerActivity MODIFY COLUMN model enum('COM','ENT','TPV','ENC','LAB','ETI','APP') CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL; + + +ALTER TABLE vn.workerActivity ADD workerActivityTypeFk varchar(20) NULL; +ALTER TABLE vn.workerActivity ADD CONSTRAINT workerActivity_workerActivityType_FK FOREIGN KEY (workerActivityTypeFk) REFERENCES vn.workerActivityType(code) ON DELETE CASCADE ON UPDATE CASCADE; + diff --git a/db/versions/10913-bronzeGalax/00-firstScript.sql b/db/versions/10913-bronzeGalax/00-firstScript.sql new file mode 100644 index 000000000..aef0c8738 --- /dev/null +++ b/db/versions/10913-bronzeGalax/00-firstScript.sql @@ -0,0 +1,4 @@ +-- Place your SQL code here +RENAME TABLE IF EXISTS vn.claimRma TO vn.claimRma__; +ALTER TABLE IF EXISTS vn.claimRma__ COMMENT='kkeada el 2024-02-26 por Pablo'; +ALTER TABLE vn.claim CHANGE IF EXISTS rma rma__ varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL NULL; diff --git a/db/versions/10915-limeMastic/00-firstScript.sql b/db/versions/10915-limeMastic/00-firstScript.sql new file mode 100644 index 000000000..be83a4984 --- /dev/null +++ b/db/versions/10915-limeMastic/00-firstScript.sql @@ -0,0 +1,2 @@ +DELETE IGNORE FROM bs.nightTask + WHERE `procedure` = 'clean_launcher'; diff --git a/db/versions/10918-wheatRose/00-firstScript.sql b/db/versions/10918-wheatRose/00-firstScript.sql new file mode 100644 index 000000000..5d0fb1c32 --- /dev/null +++ b/db/versions/10918-wheatRose/00-firstScript.sql @@ -0,0 +1,2 @@ +DELETE FROM bs.nightTask + WHERE `procedure` = 'emailYesterdayPurchasesLauncher'; diff --git a/db/versions/10923-pinkOak/00-createParkingLog.sql b/db/versions/10923-pinkOak/00-createParkingLog.sql new file mode 100644 index 000000000..f31f58196 --- /dev/null +++ b/db/versions/10923-pinkOak/00-createParkingLog.sql @@ -0,0 +1,60 @@ +CREATE OR REPLACE TABLE vn.parkingLog ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + + `originFk` int(11) DEFAULT NULL, + + `userFk` int(10) unsigned DEFAULT NULL, + + `action` set('insert','update','delete','select') NOT NULL, + + `creationDate` timestamp NULL DEFAULT current_timestamp(), + + `description` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + + `changedModel` enum('Parking','SaleGroup','SaleGroupDetail') NOT NULL DEFAULT 'Parking', + + `oldInstance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`oldInstance`)), + + `newInstance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`newInstance`)), + + `changedModelId` int(11) NOT NULL, + + `changedModelValue` varchar(45) DEFAULT NULL, + + PRIMARY KEY (`id`), + + KEY `logParkinguserFk` (`userFk`), + + KEY `parkingLog_changedModel` (`changedModel`,`changedModelId`,`creationDate`), + + KEY `parkingLog_originFk` (`originFk`,`creationDate`), + + CONSTRAINT `parkingOriginFk` FOREIGN KEY (`originFk`) REFERENCES `parking` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + + CONSTRAINT `parkingUserFk` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE + +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +ALTER TABLE vn.parking DROP COLUMN IF EXISTS editorFk; +ALTER TABLE IF EXISTS vn.parking ADD COLUMN editorFk INT; + +ALTER TABLE vn.saleGroupDetail DROP COLUMN IF EXISTS editorFk; +ALTER TABLE IF EXISTS vn.saleGroupDetail ADD COLUMN editorFk INT; + + +ALTER TABLE vn.ticketLog + MODIFY COLUMN changedModel ENUM( + 'Ticket', + 'Sale', + 'TicketWeekly', + 'TicketTracking', + 'TicketService', + 'TicketRequest', + 'TicketRefund', + 'TicketPackaging', + 'TicketObservation', + 'TicketDms', + 'Expedition', + 'Sms' + ) NOT NULL DEFAULT 'Ticket'; diff --git a/db/versions/10923-pinkOak/01-aclParkingLog.sql b/db/versions/10923-pinkOak/01-aclParkingLog.sql new file mode 100644 index 000000000..8f7e55d63 --- /dev/null +++ b/db/versions/10923-pinkOak/01-aclParkingLog.sql @@ -0,0 +1,2 @@ +INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) + VALUES ('ParkingLog', '*', 'READ', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/db/versions/10924-pinkCordyline/00-firstScript.sql b/db/versions/10924-pinkCordyline/00-firstScript.sql new file mode 100644 index 000000000..1c6c1c0f8 --- /dev/null +++ b/db/versions/10924-pinkCordyline/00-firstScript.sql @@ -0,0 +1,31 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`balanceNestTree_addChild`() +BEGIN + SELECT 1; +END$$ +DELIMITER ; +GRANT EXECUTE ON PROCEDURE vn.balanceNestTree_addChild TO adminBoss; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`balanceNestTree_delete`() +BEGIN + SELECT 1; +END$$ +DELIMITER ; +GRANT EXECUTE ON PROCEDURE vn.balanceNestTree_delete TO adminBoss; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`balanceNestTree_move`() +BEGIN + SELECT 1; +END$$ +DELIMITER ; +GRANT EXECUTE ON PROCEDURE vn.balanceNestTree_move TO adminBoss; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`payment_add`() +BEGIN + SELECT 1; +END$$ +DELIMITER ; +GRANT EXECUTE ON PROCEDURE vn.payment_add TO financial; diff --git a/db/versions/10925-orangeLaurel/00-firstScript.sql b/db/versions/10925-orangeLaurel/00-firstScript.sql new file mode 100644 index 000000000..049627082 --- /dev/null +++ b/db/versions/10925-orangeLaurel/00-firstScript.sql @@ -0,0 +1,15 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`confection_controlSource`() +BEGIN + SELECT 1; +END$$ +DELIMITER ; +GRANT EXECUTE ON PROCEDURE vn.confection_controlSource TO handmadeBoss, productionAssi, artificialBoss; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`remittance_calc`() +BEGIN + SELECT 1; +END$$ +DELIMITER ; +GRANT EXECUTE ON PROCEDURE vn.remittance_calc TO financial; \ No newline at end of file diff --git a/db/versions/10926-limeFern/00-refactorClaimState.sql b/db/versions/10926-limeFern/00-refactorClaimState.sql new file mode 100644 index 000000000..bb2dc349a --- /dev/null +++ b/db/versions/10926-limeFern/00-refactorClaimState.sql @@ -0,0 +1,8 @@ +UPDATE vn.claim c + JOIN vn.claimState cs ON cs.id = c.claimStateFk + JOIN vn.claimState ns ON ns.code = 'resolved' + SET c.claimStateFk = ns.id + WHERE cs.code IN ('managed', 'mana', 'lack', 'relocation'); + +DELETE FROM vn.claimState + WHERE code IN ('managed', 'mana', 'lack', 'relocation'); diff --git a/db/versions/10928-orangeEucalyptus/00-firstScript.sql b/db/versions/10928-orangeEucalyptus/00-firstScript.sql new file mode 100644 index 000000000..58d3605de --- /dev/null +++ b/db/versions/10928-orangeEucalyptus/00-firstScript.sql @@ -0,0 +1,5 @@ +REVOKE SELECT ON TABLE vn.bank FROM administrative, hr; +GRANT SELECT ON TABLE vn.accounting TO administrative, hr; +UPDATE salix.ACL + SET model = 'Accounting' + WHERE model = 'Bank'; diff --git a/db/versions/10929-orangeAnthurium/00-firstScript.sql b/db/versions/10929-orangeAnthurium/00-firstScript.sql new file mode 100644 index 000000000..299ac63c7 --- /dev/null +++ b/db/versions/10929-orangeAnthurium/00-firstScript.sql @@ -0,0 +1,2 @@ +-- Place your SQL code here +ALTER TABLE dipole.expedition_PrintOut MODIFY COLUMN street varchar(42) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT ' ' NOT NULL; \ No newline at end of file diff --git a/e2e/paths/06-claim/01_basic_data.spec.js b/e2e/paths/06-claim/01_basic_data.spec.js index 0a08cad9f..2df95bd4a 100644 --- a/e2e/paths/06-claim/01_basic_data.spec.js +++ b/e2e/paths/06-claim/01_basic_data.spec.js @@ -21,7 +21,7 @@ describe('Claim edit basic data path', () => { }); it(`should edit claim state and observation fields`, async() => { - await page.autocompleteSearch(selectors.claimBasicData.claimState, 'Gestionado'); + await page.autocompleteSearch(selectors.claimBasicData.claimState, 'Resuelto'); await page.clearInput(selectors.claimBasicData.packages); await page.write(selectors.claimBasicData.packages, '2'); await page.waitToClick(selectors.claimBasicData.saveButton); @@ -48,7 +48,7 @@ describe('Claim edit basic data path', () => { await page.waitForSelector(selectors.claimBasicData.claimState); const result = await page.waitToGetProperty(selectors.claimBasicData.claimState, 'value'); - expect(result).toEqual('Gestionado'); + expect(result).toEqual('Resuelto'); }); it('should confirm the "is paid with mana" and "Pick up" checkbox are checked', async() => { diff --git a/front/salix/components/user-popover/index.html b/front/salix/components/user-popover/index.html index 0fa6800c5..06a4af1e0 100644 --- a/front/salix/components/user-popover/index.html +++ b/front/salix/components/user-popover/index.html @@ -58,7 +58,7 @@ label="Local bank" id="localBank" ng-model="$ctrl.localBankFk" - url="Banks" + url="Accountings" select-fields="['id','bank']" show-field="bank" order="id" diff --git a/jest.front.config.js b/jest.front.config.js index a843832ea..4b292801e 100644 --- a/jest.front.config.js +++ b/jest.front.config.js @@ -1,6 +1,8 @@ // For a detailed explanation regarding each configuration property, visit: // https://jestjs.io/docs/en/configuration.html /* eslint max-len: ["error", { "code": 150 }]*/ +const cpus = require('os').cpus().length; +const maxCpus = Math.floor(cpus * 0.45); module.exports = { name: 'front end', @@ -12,6 +14,7 @@ module.exports = { setupFilesAfterEnv: [ './front/jest-setup.js' ], + maxWorkers: maxCpus, testMatch: [ '**/front/**/*.spec.js', '**/print/**/*.spec.js', diff --git a/loopback/common/mixins/loggable.js b/loopback/common/mixins/loggable.js index 760fdf60a..24243ba68 100644 --- a/loopback/common/mixins/loggable.js +++ b/loopback/common/mixins/loggable.js @@ -1,6 +1,7 @@ const LoopBackContext = require('loopback-context'); async function handleObserve(ctx) { - ctx.options.httpCtx = LoopBackContext.getCurrentContext(); + const httpCtx = LoopBackContext.getCurrentContext(); + ctx.options.userId = httpCtx?.active?.accessToken?.userId; } module.exports = function(Self) { let Mixin = { diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 2187371cd..53b1a8bb5 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -209,5 +209,16 @@ "You cannot update these fields": "You cannot update these fields", "CountryFK cannot be empty": "Country cannot be empty", "You are not allowed to modify the alias": "You are not allowed to modify the alias", - "You already have the mailAlias": "You already have the mailAlias" + "You already have the mailAlias": "You already have the mailAlias", + "This machine is already in use.": "This machine is already in use.", + "the plate does not exist": "The plate {{plate}} does not exist", + "We do not have availability for the selected item": "We do not have availability for the selected item", + "You are already using a machine": "You are already using a machine", + "this state does not exist": "This state does not exist", + "The line could not be marked": "The line could not be marked", + "The sale cannot be tracked": "The sale cannot be tracked", + "Shelving not valid": "Shelving not valid", + "printerNotExists": "The printer does not exist", + "There are not picking tickets": "There are not picking tickets", + "ticketCommercial": "The ticket {{ ticket }} for the salesperson {{ salesMan }} is in preparation. (automatically generated message)" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 4079fa1ca..3748b6eaf 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -324,7 +324,6 @@ "The response is not a PDF": "La respuesta no es un PDF", "Booking completed": "Reserva completada", "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", - "Incoterms data for consignee is missing": "Faltan los datos de los Incoterms para el consignatario", "The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada", "User disabled": "Usuario desactivado", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", @@ -348,4 +347,4 @@ "Cmr file does not exist": "El archivo del cmr no existe", "You are not allowed to modify the alias": "No estás autorizado a modificar el alias", "The address of the customer must have information about Incoterms and Customs Agent": "El consignatario del cliente debe tener informado Incoterms y Agente de aduanas" -} +} \ No newline at end of file diff --git a/loopback/server/connectors/vn-mysql.js b/loopback/server/connectors/vn-mysql.js index 737fd94d5..5edef4395 100644 --- a/loopback/server/connectors/vn-mysql.js +++ b/loopback/server/connectors/vn-mysql.js @@ -275,7 +275,7 @@ class VnMySQL extends MySQL { } invokeMethod(method, args, model, ctx, opts, cb) { - if (!this.isLoggable(model)) + if (!this.isLoggable(model) && !opts?.userId) return super[method].apply(this, args); this.invokeMethodP(method, [...args], model, ctx, opts) @@ -287,11 +287,11 @@ class VnMySQL extends MySQL { let tx; if (!opts.transaction) { tx = await Transaction.begin(this, {}); - opts = Object.assign({transaction: tx, httpCtx: opts.httpCtx}, opts); + opts = Object.assign({transaction: tx}, opts); } try { - const userId = opts.httpCtx && opts.httpCtx.active?.accessToken?.userId; + const {userId} = opts; if (userId) { const user = await Model.app.models.VnUser.findById(userId, {fields: ['name']}, opts); await this.executeP(`CALL account.myUser_loginWithName(?)`, [user.name], opts); diff --git a/loopback/util/validateIban.js b/loopback/util/validateIban.js index ed3e00426..2386538b5 100644 --- a/loopback/util/validateIban.js +++ b/loopback/util/validateIban.js @@ -3,7 +3,6 @@ module.exports = function(iban, countryCode) { if (typeof iban != 'string') return false; if (countryCode?.toLowerCase() != 'es') return true; - iban = iban.toUpperCase(); iban = trim(iban); iban = iban.replace(/\s/g, ''); diff --git a/modules/claim/back/methods/claim-state/specs/isEditable.spec.js b/modules/claim/back/methods/claim-state/specs/isEditable.spec.js index 1fb8e1536..6d97eed06 100644 --- a/modules/claim/back/methods/claim-state/specs/isEditable.spec.js +++ b/modules/claim/back/methods/claim-state/specs/isEditable.spec.js @@ -64,7 +64,7 @@ describe('claimstate isEditable()', () => { const options = {transaction: tx}; const ctx = {req: {accessToken: {userId: claimManagerId}}}; - const result = await app.models.ClaimState.isEditable(ctx, 7, options); + const result = await app.models.ClaimState.isEditable(ctx, 5, options); expect(result).toEqual(true); diff --git a/modules/claim/back/methods/claim/specs/updateClaim.spec.js b/modules/claim/back/methods/claim/specs/updateClaim.spec.js index e2d5fcfeb..bd77ae406 100644 --- a/modules/claim/back/methods/claim/specs/updateClaim.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaim.spec.js @@ -21,12 +21,13 @@ describe('Update Claim', () => { claimStatesMap = claimStates.reduce((acc, state) => ({...acc, [state.code]: state.id}), {}); }); const newDate = Date.vnNew(); + const claimManagerId = 72; const originalData = { ticketFk: 3, clientFk: 1101, ticketCreated: newDate, workerFk: 18, - claimStateFk: 2, + claimStateFk: 5, isChargedToMana: true, responsibility: 4, observation: 'observation' @@ -77,7 +78,6 @@ describe('Update Claim', () => { spyOn(chatModel, 'sendCheckingPresence').and.callThrough(); const pendingState = claimStatesMap.pending; - const claimManagerId = 72; const ctx = { req: { accessToken: {userId: claimManagerId}, @@ -104,85 +104,7 @@ describe('Update Claim', () => { } }); - it(`should success to update the claimState to 'managed' and send a rocket message`, async() => { - const tx = await app.models.Claim.beginTransaction({}); - - try { - const options = {transaction: tx}; - - const newClaim = await app.models.Claim.create(originalData, options); - - const chatModel = app.models.Chat; - spyOn(chatModel, 'sendCheckingPresence').and.callThrough(); - - const managedState = claimStatesMap.managed; - const claimManagerId = 72; - const ctx = { - req: { - accessToken: {userId: claimManagerId}, - headers: {origin: url} - }, - args: { - observation: 'valid observation', - claimStateFk: managedState, - hasToPickUp: false - } - }; - ctx.req.__ = i18n.__; - await app.models.Claim.updateClaim(ctx, newClaim.id, options); - - let updatedClaim = await app.models.Claim.findById(newClaim.id, null, options); - - expect(updatedClaim.observation).toEqual(ctx.args.observation); - expect(chatModel.sendCheckingPresence).toHaveBeenCalled(); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it(`should success to update the claimState to 'resolved' and send a rocket message`, async() => { - const tx = await app.models.Claim.beginTransaction({}); - - try { - const options = {transaction: tx}; - - const newClaim = await app.models.Claim.create(originalData, options); - - const chatModel = app.models.Chat; - spyOn(chatModel, 'sendCheckingPresence').and.callThrough(); - - const resolvedState = claimStatesMap.resolved; - const claimManagerId = 72; - const ctx = { - req: { - accessToken: {userId: claimManagerId}, - headers: {origin: url} - }, - args: { - observation: 'valid observation', - claimStateFk: resolvedState, - hasToPickUp: false - } - }; - ctx.req.__ = i18n.__; - await app.models.Claim.updateClaim(ctx, newClaim.id, options); - - let updatedClaim = await app.models.Claim.findById(newClaim.id, null, options); - - expect(updatedClaim.observation).toEqual(ctx.args.observation); - expect(chatModel.sendCheckingPresence).toHaveBeenCalled(); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it(`should success to update the claimState to 'canceled' and send a rocket message`, async() => { + it(`should success to update the claimState to 'canceled' and send two rocket message`, async() => { const tx = await app.models.Claim.beginTransaction({}); try { @@ -194,7 +116,6 @@ describe('Update Claim', () => { spyOn(chatModel, 'sendCheckingPresence').and.callThrough(); const canceledState = claimStatesMap.canceled; - const claimManagerId = 72; const ctx = { req: { accessToken: {userId: claimManagerId}, @@ -212,46 +133,7 @@ describe('Update Claim', () => { let updatedClaim = await app.models.Claim.findById(newClaim.id, null, options); expect(updatedClaim.observation).toEqual(ctx.args.observation); - expect(chatModel.sendCheckingPresence).toHaveBeenCalled(); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it(`should success to update the claimState to 'incomplete' and send a rocket message`, async() => { - const tx = await app.models.Claim.beginTransaction({}); - - try { - const options = {transaction: tx}; - - const newClaim = await app.models.Claim.create(originalData, options); - - const chatModel = app.models.Chat; - spyOn(chatModel, 'sendCheckingPresence').and.callThrough(); - - const incompleteState = 5; - const claimManagerId = 72; - const ctx = { - req: { - accessToken: {userId: claimManagerId}, - headers: {origin: url} - }, - args: { - observation: 'valid observation', - claimStateFk: incompleteState, - hasToPickUp: false - } - }; - ctx.req.__ = i18n.__; - await app.models.Claim.updateClaim(ctx, newClaim.id, options); - - let updatedClaim = await app.models.Claim.findById(newClaim.id, null, options); - - expect(updatedClaim.observation).toEqual(ctx.args.observation); - expect(chatModel.sendCheckingPresence).toHaveBeenCalled(); + expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(2); await tx.rollback(); } catch (e) { diff --git a/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js b/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js index 2f16d002c..99436fed6 100644 --- a/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js @@ -21,7 +21,7 @@ describe('Update Claim', () => { clientFk: 1101, ticketCreated: newDate, workerFk: 18, - claimStateFk: 2, + claimStateFk: 1, isChargedToMana: true, responsibility: 4, observation: 'observation' diff --git a/modules/claim/back/model-config.json b/modules/claim/back/model-config.json index 83d88039c..d90ed4c1e 100644 --- a/modules/claim/back/model-config.json +++ b/modules/claim/back/model-config.json @@ -43,8 +43,5 @@ }, "ClaimObservation": { "dataSource": "vn" - }, - "ClaimRma": { - "dataSource": "vn" - } + } } diff --git a/modules/claim/back/models/claim-rma.js b/modules/claim/back/models/claim-rma.js deleted file mode 100644 index 6a93613bd..000000000 --- a/modules/claim/back/models/claim-rma.js +++ /dev/null @@ -1,9 +0,0 @@ -const LoopBackContext = require('loopback-context'); - -module.exports = Self => { - Self.observe('before save', async function(ctx) { - const changes = ctx.data || ctx.instance; - const loopBackContext = LoopBackContext.getCurrentContext(); - changes.workerFk = loopBackContext.active.accessToken.userId; - }); -}; diff --git a/modules/claim/back/models/claim.json b/modules/claim/back/models/claim.json index b85b9e073..1fbbb00b1 100644 --- a/modules/claim/back/models/claim.json +++ b/modules/claim/back/models/claim.json @@ -45,9 +45,6 @@ }, "packages": { "type": "number" - }, - "rma": { - "type": "string" } }, "relations": { @@ -56,12 +53,6 @@ "model": "ClaimState", "foreignKey": "claimStateFk" }, - "rmas": { - "type": "hasMany", - "model": "ClaimRma", - "foreignKey": "code", - "primaryKey": "rma" - }, "client": { "type": "belongsTo", "model": "Client", diff --git a/modules/client/back/methods/client/createReceipt.js b/modules/client/back/methods/client/createReceipt.js index b70b9bbe0..debdaf066 100644 --- a/modules/client/back/methods/client/createReceipt.js +++ b/modules/client/back/methods/client/createReceipt.js @@ -69,7 +69,7 @@ module.exports = function(Self) { delete args.ctx; // Remove unwanted properties const originalClient = await models.Client.findById(args.clientFk, null, myOptions); - const bank = await models.Bank.findById(args.bankFk, null, myOptions); + const bank = await models.Accounting.findById(args.bankFk, null, myOptions); const accountingType = await models.AccountingType.findById(bank.accountingTypeFk, null, myOptions); if (accountingType.code == 'compensation') { diff --git a/modules/client/back/methods/receipt/balanceCompensationEmail.js b/modules/client/back/methods/receipt/balanceCompensationEmail.js index afae5dabc..994d5124a 100644 --- a/modules/client/back/methods/receipt/balanceCompensationEmail.js +++ b/modules/client/back/methods/receipt/balanceCompensationEmail.js @@ -28,7 +28,7 @@ module.exports = Self => { const models = Self.app.models; const receipt = await models.Receipt.findById(id, {fields: ['clientFk', 'bankFk']}); - const bank = await models.Bank.findById(receipt.bankFk); + const bank = await models.Accounting.findById(receipt.bankFk); if (!bank) throw new UserError(`Receipt's bank was not found`); diff --git a/modules/client/back/models/receipt.json b/modules/client/back/models/receipt.json index da7879df9..6ade21ac5 100644 --- a/modules/client/back/models/receipt.json +++ b/modules/client/back/models/receipt.json @@ -60,7 +60,7 @@ }, "bank": { "type": "belongsTo", - "model": "Bank", + "model": "Accounting", "foreignKey": "bankFk" }, "supplier": { diff --git a/modules/client/back/models/till.json b/modules/client/back/models/till.json index 4b86e50e2..6677b27d4 100644 --- a/modules/client/back/models/till.json +++ b/modules/client/back/models/till.json @@ -46,7 +46,7 @@ "relations": { "bank": { "type": "belongsTo", - "model": "Bank", + "model": "Accounting", "foreignKey": "bankFk" }, "worker": { diff --git a/modules/client/front/balance/create/index.html b/modules/client/front/balance/create/index.html index 27b182c9a..25789b01a 100644 --- a/modules/client/front/balance/create/index.html +++ b/modules/client/front/balance/create/index.html @@ -29,7 +29,7 @@ { const result = await models.Entry.filter(ctx, options); - expect(result.length).toEqual(8); + expect(result.length).toEqual(9); await tx.rollback(); } catch (e) { @@ -81,7 +81,7 @@ describe('Entry filter()', () => { const result = await models.Entry.filter(ctx, options); - expect(result.length).toEqual(7); + expect(result.length).toEqual(8); await tx.rollback(); } catch (e) { diff --git a/modules/invoiceIn/back/models/invoice-in-due-day.json b/modules/invoiceIn/back/models/invoice-in-due-day.json index d2cffc81b..ca3616ef8 100644 --- a/modules/invoiceIn/back/models/invoice-in-due-day.json +++ b/modules/invoiceIn/back/models/invoice-in-due-day.json @@ -34,7 +34,7 @@ "relations": { "bank": { "type": "belongsTo", - "model": "Bank", + "model": "Accounting", "foreignKey": "bankFk" } } diff --git a/modules/invoiceIn/front/dueDay/index.html b/modules/invoiceIn/front/dueDay/index.html index 1a1935e72..abc91312d 100644 --- a/modules/invoiceIn/front/dueDay/index.html +++ b/modules/invoiceIn/front/dueDay/index.html @@ -23,7 +23,7 @@ { require('../methods/invoiceOut/filter')(Self); @@ -66,4 +67,24 @@ module.exports = Self => { }); } }; + + Self.getSerial = async function(clientId, companyId, addressId, type, myOptions) { + const [{serial}] = await Self.rawSql( + `SELECT vn.invoiceSerial(?, ?, ?) AS serial`, + [ + clientId, + companyId, + type + ], + myOptions); + + const invoiceOutSerial = await Self.app.models.InvoiceOutSerial.findById(serial); + if (invoiceOutSerial?.taxAreaFk == 'WORLD') { + const address = await Self.app.models.Address.findById(addressId); + if (!address || !address.customsAgentFk || !address.incotermsFk) + throw new UserError('The address of the customer must have information about Incoterms and Customs Agent'); + } + + return serial; + }; }; diff --git a/modules/item/back/methods/item-barcode/delete.js b/modules/item/back/methods/item-barcode/delete.js new file mode 100644 index 000000000..0eea651d3 --- /dev/null +++ b/modules/item/back/methods/item-barcode/delete.js @@ -0,0 +1,34 @@ +module.exports = Self => { + Self.remoteMethod('delete', { + description: 'Delete an ItemBarcode by itemFk and code', + accessType: 'WRITE', + accepts: [ + { + arg: 'barcode', + type: 'string', + required: true, + }, + { + arg: 'itemFk', + type: 'number', + required: true, + } + ], + http: { + path: `/delete`, + verb: 'DELETE' + } + }); + + Self.delete = async(barcode, itemFk, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + await Self.destroyAll({ + code: barcode, + itemFk + }, myOptions); + }; +}; diff --git a/modules/item/back/methods/item-barcode/specs/delete.spec.js b/modules/item/back/methods/item-barcode/specs/delete.spec.js new file mode 100644 index 000000000..094a351a3 --- /dev/null +++ b/modules/item/back/methods/item-barcode/specs/delete.spec.js @@ -0,0 +1,22 @@ +const {models} = require('vn-loopback/server/server'); + +describe('itemBarcode delete()', () => { + it('should delete a record by itemFk and code', async() => { + const tx = await models.ItemBarcode.beginTransaction({}); + const options = {transaction: tx}; + const itemFk = 1; + const code = 1111111111; + + try { + const itemsBarcodeBefore = await models.ItemBarcode.find({}, options); + await models.ItemBarcode.delete(code, itemFk, options); + const itemsBarcodeAfter = await models.ItemBarcode.find({}, options); + + expect(itemsBarcodeBefore.length).toBeGreaterThan(itemsBarcodeAfter.length); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/item/back/methods/item-shelving/getAlternative.js b/modules/item/back/methods/item-shelving/getAlternative.js new file mode 100644 index 000000000..8108bfa6e --- /dev/null +++ b/modules/item/back/methods/item-shelving/getAlternative.js @@ -0,0 +1,64 @@ +module.exports = Self => { + Self.remoteMethod('getAlternative', { + description: 'Returns a list of items and possible alternative locations', + accessType: 'READ', + accepts: [{ + arg: 'shelvingFk', + type: 'string', + required: true, + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/getAlternative`, + verb: 'GET' + } + }); + + Self.getAlternative = async(shelvingFk, options) => { + const models = Self.app.models; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const filterItemShelvings = { + fields: ['id', 'visible', 'itemFk', 'shelvingFk'], + where: {shelvingFk}, + include: [ + { + relation: 'item', + scope: { + fields: ['longName', 'name', 'size'] + } + }, + + ] + }; + + let itemShelvings = await models.ItemShelving.find(filterItemShelvings, myOptions); + + if (itemShelvings) { + const [alternatives] = await models.ItemShelving.rawSql('CALL vn.itemShelving_getAlternatives(?)', + [shelvingFk], myOptions + ); + return itemShelvings.map(itemShelving => { + const item = itemShelving.item(); + + const shelvings = alternatives.filter(alternative => alternative.itemFk == itemShelving.itemFk); + + return { + id: itemShelving.id, + itemFk: itemShelving.itemFk, + name: item.name, + size: item.size, + longName: item.longName, + quantity: itemShelving.visible, + shelvings + }; + }); + } + }; +}; diff --git a/modules/item/back/methods/item-shelving/specs/getAlternative.spec.js b/modules/item/back/methods/item-shelving/specs/getAlternative.spec.js new file mode 100644 index 000000000..3f4917477 --- /dev/null +++ b/modules/item/back/methods/item-shelving/specs/getAlternative.spec.js @@ -0,0 +1,25 @@ +const {models} = require('vn-loopback/server/server'); + +describe('itemShelving getAlternative()', () => { + beforeAll(async() => { + ctx = { + req: { + headers: {origin: 'http://localhost'}, + } + }; + }); + + it('should return a list of items without alternatives', async() => { + const shelvingFk = 'HEJ'; + const itemShelvings = await models.ItemShelving.getAlternative(shelvingFk); + + expect(itemShelvings[0].shelvings.length).toEqual(0); + }); + + it('should return an empty list', async() => { + const shelvingFk = 'ZZP'; + const itemShelvings = await models.ItemShelving.getAlternative(shelvingFk); + + expect(itemShelvings.length).toEqual(0); + }); +}); diff --git a/modules/item/back/methods/item-shelving/specs/updateFromSale.spec.js b/modules/item/back/methods/item-shelving/specs/updateFromSale.spec.js new file mode 100644 index 000000000..dfa294000 --- /dev/null +++ b/modules/item/back/methods/item-shelving/specs/updateFromSale.spec.js @@ -0,0 +1,22 @@ +const {models} = require('vn-loopback/server/server'); + +describe('itemShelving updateFromSale()', () => { + it('should update the quantity', async() => { + const tx = await models.ItemBarcode.beginTransaction({}); + const options = {transaction: tx}; + const saleFk = 2; + const filter = {where: {itemFk: 4, shelvingFk: 'HEJ'} + }; + try { + const {visible: visibleBefore} = await models.ItemShelving.findOne(filter, options); + await models.ItemShelving.updateFromSale(saleFk, options); + const {visible: visibleAfter} = await models.ItemShelving.findOne(filter, options); + + expect(visibleAfter).toEqual(visibleBefore + 5); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/item/back/methods/item-shelving/updateFromSale.js b/modules/item/back/methods/item-shelving/updateFromSale.js new file mode 100644 index 000000000..2b9f49cae --- /dev/null +++ b/modules/item/back/methods/item-shelving/updateFromSale.js @@ -0,0 +1,48 @@ +module.exports = Self => { + Self.remoteMethod('updateFromSale', { + description: 'Update the visible items', + accessType: 'WRITE', + accepts: [{ + arg: 'saleFk', + type: 'number', + required: true, + }], + http: { + path: `/updateFromSale`, + verb: 'POST' + } + }); + + Self.updateFromSale = async(saleFk, options) => { + const models = Self.app.models; + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const itemShelvingSale = await models.ItemShelvingSale.findOne({ + where: {saleFk}, + include: {relation: 'itemShelving'} + }, myOptions); + + const itemShelving = itemShelvingSale.itemShelving(); + const quantity = itemShelving.visible + itemShelvingSale.quantity; + + await itemShelving.updateAttributes( + {visible: quantity}, + myOptions + ); + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/item/back/methods/item/get.js b/modules/item/back/methods/item/get.js new file mode 100644 index 000000000..38b37a90c --- /dev/null +++ b/modules/item/back/methods/item/get.js @@ -0,0 +1,48 @@ +module.exports = Self => { + Self.remoteMethod('get', { + description: 'Get the data from an item', + accessType: 'READ', + http: { + path: `/get`, + verb: 'GET' + }, + accepts: [ + { + arg: 'barcode', + type: 'number', + required: true, + }, + { + arg: 'warehouseFk', + type: 'number', + required: true, + } + ], + returns: { + type: ['object'], + root: true + }, + }); + + Self.get = async(barcode, warehouseFk, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const models = Self.app.models; + + const [[itemInfo]] = await Self.rawSql('CALL vn.item_getInfo(?, ?)', [barcode, warehouseFk], myOptions); + + if (itemInfo) { + itemInfo.barcodes = await models.ItemBarcode.find({ + fields: ['code'], + where: { + itemFk: itemInfo.id + } + }); + } + + return itemInfo; + }; +}; diff --git a/modules/item/back/methods/item/specs/get.spec.js b/modules/item/back/methods/item/specs/get.spec.js new file mode 100644 index 000000000..55262004a --- /dev/null +++ b/modules/item/back/methods/item/specs/get.spec.js @@ -0,0 +1,12 @@ +const {models} = require('vn-loopback/server/server'); + +describe('item get()', () => { + const barcode = 1; + const warehouseFk = 1; + it('should get an item with several barcodes', async() => { + const card = await models.Item.get(barcode, warehouseFk); + + expect(card).toBeDefined(); + expect(card.barcodes.length).toBeTruthy(); + }); +}); diff --git a/modules/item/back/models/item-barcode.js b/modules/item/back/models/item-barcode.js index b608a7fe9..616d973e1 100644 --- a/modules/item/back/models/item-barcode.js +++ b/modules/item/back/models/item-barcode.js @@ -1,5 +1,6 @@ module.exports = Self => { require('../methods/item-barcode/toItem')(Self); + require('../methods/item-barcode/delete')(Self); Self.validatesUniquenessOf('code', { message: `Barcode must be unique` diff --git a/modules/item/back/models/item-shelving.js b/modules/item/back/models/item-shelving.js index c031d8271..53e57dcee 100644 --- a/modules/item/back/models/item-shelving.js +++ b/modules/item/back/models/item-shelving.js @@ -2,4 +2,6 @@ module.exports = Self => { require('../methods/item-shelving/deleteItemShelvings')(Self); require('../methods/item-shelving/upsertItem')(Self); require('../methods/item-shelving/getInventory')(Self); + require('../methods/item-shelving/getAlternative')(Self); + require('../methods/item-shelving/updateFromSale')(Self); }; diff --git a/modules/item/back/models/item-shelving.json b/modules/item/back/models/item-shelving.json index f3be98fc4..893a1f81d 100644 --- a/modules/item/back/models/item-shelving.json +++ b/modules/item/back/models/item-shelving.json @@ -54,7 +54,8 @@ "shelving": { "type": "belongsTo", "model": "Shelving", - "foreignKey": "shelvingFk" - } + "foreignKey": "shelvingFk", + "primaryKey": "code" + } } } diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js index eac1ecb7d..e715ab431 100644 --- a/modules/item/back/models/item.js +++ b/modules/item/back/models/item.js @@ -17,6 +17,7 @@ module.exports = Self => { require('../methods/item/buyerWasteEmail')(Self); require('../methods/item/labelPdf')(Self); require('../methods/item/setVisibleDiscard')(Self); + require('../methods/item/get')(Self); Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'}); diff --git a/modules/parking/back/model-config.json b/modules/parking/back/model-config.json new file mode 100644 index 000000000..5c0d3d916 --- /dev/null +++ b/modules/parking/back/model-config.json @@ -0,0 +1,5 @@ +{ + "ParkingLog": { + "dataSource": "vn" + } +} diff --git a/modules/parking/back/models/parking-log.json b/modules/parking/back/models/parking-log.json new file mode 100644 index 000000000..1bbb031d8 --- /dev/null +++ b/modules/parking/back/models/parking-log.json @@ -0,0 +1,9 @@ +{ + "name": "ParkingLog", + "base": "Log", + "options": { + "mysql": { + "table": "parkingLog" + } + } +} diff --git a/modules/shelving/back/locale/parking/en.yml b/modules/shelving/back/locale/parking/en.yml new file mode 100644 index 000000000..5ef6add52 --- /dev/null +++ b/modules/shelving/back/locale/parking/en.yml @@ -0,0 +1,9 @@ +name: parking +columns: + id: id + column: column + row: row + sectorFk: sector + code: code + pickingOrder: picking order + editorFk: editor \ No newline at end of file diff --git a/modules/shelving/back/locale/parking/es.yml b/modules/shelving/back/locale/parking/es.yml new file mode 100644 index 000000000..d4dd7bb2c --- /dev/null +++ b/modules/shelving/back/locale/parking/es.yml @@ -0,0 +1,10 @@ +name: parking +columns: + id: id + column: columna + row: fila + sectorFk: sector + code: código + pickingOrder: orden de recogida + editorFk: editor + \ No newline at end of file diff --git a/modules/shelving/back/methods/shelving/addLog.js b/modules/shelving/back/methods/shelving/addLog.js new file mode 100644 index 000000000..fe6d8b8da --- /dev/null +++ b/modules/shelving/back/methods/shelving/addLog.js @@ -0,0 +1,56 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('addLog', { + description: 'Add a new log', + accessType: 'WRITE', + accepts: { + arg: 'code', + type: 'string', + required: true, + }, + http: { + path: '/addLog', + verb: 'POST' + } + }); + Self.addLog = async(ctx, code, options) => { + const userId = ctx.req.accessToken.userId; + const $t = ctx.req.__; + const models = Self.app.models; + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const shelving = await Self.findOne({ + where: { + code + } + }, myOptions); + + if (!shelving) throw new UserError($t('Shelving not valid')); + + await models.ShelvingLog.create({ + changedModel: 'Shelving', + originFk: shelving.id, + changedModelId: shelving.id, + action: 'select', + userFk: userId + + }, myOptions); + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/shelving/back/methods/shelving/specs/addLog.spec.js b/modules/shelving/back/methods/shelving/specs/addLog.spec.js new file mode 100644 index 000000000..d538c24ec --- /dev/null +++ b/modules/shelving/back/methods/shelving/specs/addLog.spec.js @@ -0,0 +1,46 @@ +const {models} = require('vn-loopback/server/server'); + +describe('shelving addLog()', () => { + beforeAll(async() => { + ctx = { + req: { + headers: {origin: 'http://localhost'}, + accessToken: {userId: 66}, + __: value => value + } + }; + }); + + it('should add a log', async() => { + const tx = await models.SaleTracking.beginTransaction({}); + const options = {transaction: tx}; + const code = 'AA6'; + + try { + const shelvingLogsBefore = await models.ShelvingLog.find(null, options); + await models.Shelving.addLog(ctx, code, options); + const shelvingLogsAfter = await models.ShelvingLog.find(null, options); + + expect(shelvingLogsAfter.length).toEqual(shelvingLogsBefore.length + 1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw an error when the code does not exist', async() => { + const tx = await models.SaleTracking.beginTransaction({}); + const options = {transaction: tx}; + const code = 'DXI345'; + + try { + await models.Shelving.addLog(ctx, code, options); + + await tx.rollback(); + } catch (e) { + expect(e.message).toEqual('Shelving not valid'); + await tx.rollback(); + } + }); +}); diff --git a/modules/shelving/back/models/parking.json b/modules/shelving/back/models/parking.json index 53fec6e69..47a3305ae 100644 --- a/modules/shelving/back/models/parking.json +++ b/modules/shelving/back/models/parking.json @@ -20,9 +20,6 @@ "type": "string", "required": true }, - "sectorFk": { - "type": "number" - }, "code": { "type": "string" }, @@ -35,6 +32,11 @@ "type": "hasMany", "model": "saleGroup", "foreignKey": "parkingFk" + }, + "sector": { + "type": "belongsTo", + "model": "Sector", + "foreignKey": "sectorFk" } } } diff --git a/modules/shelving/back/models/shelving.js b/modules/shelving/back/models/shelving.js index 3e27f5863..bf611d2ba 100644 --- a/modules/shelving/back/models/shelving.js +++ b/modules/shelving/back/models/shelving.js @@ -1,3 +1,4 @@ module.exports = Self => { require('../methods/shelving/getSummary')(Self); + require('../methods/shelving/addLog')(Self); }; diff --git a/modules/ticket/back/methods/sale-tracking/delete.js b/modules/ticket/back/methods/sale-tracking/delete.js index 0b977e5d4..fda21a014 100644 --- a/modules/ticket/back/methods/sale-tracking/delete.js +++ b/modules/ticket/back/methods/sale-tracking/delete.js @@ -2,7 +2,7 @@ module.exports = Self => { Self.remoteMethod('delete', { description: 'Delete sale trackings and item shelving sales', - accessType: 'READ', + accessType: 'WRITE', accepts: [ { arg: 'saleFk', @@ -10,21 +10,17 @@ module.exports = Self => { description: 'The sale id' }, { - arg: 'stateCode', - type: 'string' - } + arg: 'stateCodes', + type: ['string'] + }, ], - returns: { - type: ['object'], - root: true - }, http: { path: `/delete`, verb: 'POST' } }); - Self.delete = async(saleFk, stateCode, options) => { + Self.delete = async(saleFk, stateCodes, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -38,20 +34,24 @@ module.exports = Self => { } try { - if (stateCode === 'PREPARED') { - const itemShelvingSales = await models.ItemShelvingSale.find({where: {saleFk: saleFk}}, myOptions); - for (let itemShelvingSale of itemShelvingSales) - await itemShelvingSale.destroy(myOptions); - } + const itemShelvingSales = await models.ItemShelvingSale.find({where: {saleFk: saleFk}}, myOptions); - const state = await models.State.findOne({ - where: {code: stateCode} + for (let itemShelvingSale of itemShelvingSales) + await itemShelvingSale.destroy(myOptions); + + const states = await models.State.find({ + fields: ['id'], + where: { + code: {inq: stateCodes} + } }, myOptions); + const stateIds = states.map(state => state.id); + const filter = { where: { saleFk: saleFk, - stateFk: state.id + stateFk: {inq: stateIds} } }; const saleTrackings = await models.SaleTracking.find(filter, myOptions); @@ -59,8 +59,6 @@ module.exports = Self => { await saleTracking.destroy(myOptions); if (tx) await tx.commit(); - - return true; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/ticket/back/methods/sale-tracking/setPicked.js b/modules/ticket/back/methods/sale-tracking/setPicked.js new file mode 100644 index 000000000..828f6eb7e --- /dev/null +++ b/modules/ticket/back/methods/sale-tracking/setPicked.js @@ -0,0 +1,106 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('setPicked', { + description: 'Add the sales line of the item and set the tracking.', + accessType: 'WRITE', + accepts: [ + { + arg: 'saleFk', + type: 'number', + required: true + }, + { + arg: 'originalQuantity', + type: 'number', + required: true + }, + { + arg: 'code', + type: 'string', + required: true + }, + { + arg: 'isChecked', + type: 'boolean', + required: true + }, + { + arg: 'buyFk', + type: 'number', + required: true + }, + { + arg: 'isScanned', + type: 'boolean', + }, + { + arg: 'quantity', + type: 'number', + required: true + }, + { + arg: 'itemShelvingFk', + type: 'number', + required: true + } + ], + http: { + path: `/setPicked`, + verb: 'POST' + } + }); + + Self.setPicked = async(ctx, saleFk, originalQuantity, code, isChecked, buyFk, isScanned, quantity, itemShelvingFk, options) => { + const userId = ctx.req.accessToken.userId; + const models = Self.app.models; + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + await models.ItemShelvingSale.create({ + itemShelvingFk, + saleFk, + quantity, + userFk: userId + }, myOptions); + + const itemShelving = await models.ItemShelving.findById(itemShelvingFk, null, myOptions); + + await itemShelving.updateAttributes({visible: itemShelving.visible - quantity}, myOptions); + + await Self.updateAll( + {saleFk}, + {isChecked: true}, + myOptions + ); + + await Self.updateTracking(ctx, saleFk, originalQuantity, code, isChecked, null, isScanned, myOptions); + + try { + const {itemOriginalFk} = await models.Buy.findById(buyFk, {fields: ['itemOriginalFk']}, myOptions); + if (itemOriginalFk) await models.SaleBuy.create({saleFk, buyFk}, myOptions); + } catch (e) { + throw new UserError('The sale cannot be tracked'); + } + + if (tx) await tx.commit(); + } catch (e) { + if (e.message == 'The sale cannot be tracked') { + if (tx) tx.commit(); + throw e; + } + + if (tx) await tx.rollback(); + throw new UserError('The line could not be marked'); + } + }; +}; diff --git a/modules/ticket/back/methods/sale-tracking/specs/delete.spec.js b/modules/ticket/back/methods/sale-tracking/specs/delete.spec.js index a8bcf5692..bb66db4f3 100644 --- a/modules/ticket/back/methods/sale-tracking/specs/delete.spec.js +++ b/modules/ticket/back/methods/sale-tracking/specs/delete.spec.js @@ -11,13 +11,12 @@ describe('sale-tracking delete()', () => { const saleTrackingsBefore = await models.SaleTracking.find(null, options); const saleFk = 1; - const stateCode = 'PREPARED'; - const result = await models.SaleTracking.delete(saleFk, stateCode, options); + const stateCode = ['PREPARED']; + await models.SaleTracking.delete(saleFk, stateCode, options); const itemShelvingsAfter = await models.ItemShelvingSale.find(null, options); const saleTrackingsAfter = await models.SaleTracking.find(null, options); - expect(result).toEqual(true); expect(saleTrackingsAfter.length).toBeLessThan(saleTrackingsBefore.length); expect(itemShelvingsAfter.length).toBeLessThan(itemShelvingsBefore.length); diff --git a/modules/ticket/back/methods/sale-tracking/specs/setPicked.spec.js b/modules/ticket/back/methods/sale-tracking/specs/setPicked.spec.js new file mode 100644 index 000000000..0cf2ccbeb --- /dev/null +++ b/modules/ticket/back/methods/sale-tracking/specs/setPicked.spec.js @@ -0,0 +1,114 @@ +const {models} = require('vn-loopback/server/server'); +describe('saleTracking setPicked()', () => { + const saleFk = 1; + const originalQuantity = 10; + const code = 'PREPARED'; + const isChecked = true; + const buyFk = 1; + const isScanned = false; + const quantity = 1; + const itemShelvingFk = 1; + + beforeAll(async() => { + ctx = { + req: { + accessToken: {userId: 104}, + headers: {origin: 'http://localhost'}, + __: value => value + } + }; + }); + + it('should throw an error if the line was not able to be marked', async() => { + const tx = await models.SaleTracking.beginTransaction({}); + const options = {transaction: tx}; + const code = 'FAKESTATE'; + try { + await models.SaleTracking.setPicked( + ctx, + saleFk, + originalQuantity, + code, + isChecked, + buyFk, + isScanned, + quantity, + itemShelvingFk, + options + ); + + await tx.rollback(); + } catch (e) { + const error = e; + + expect(error.message).toEqual('The line could not be marked'); + await tx.rollback(); + } + }); + + it('should throw an error if there are duplicate salebuys', async() => { + const tx = await models.SaleTracking.beginTransaction({}); + const options = {transaction: tx}; + try { + await models.SaleTracking.setPicked( + ctx, + saleFk, + originalQuantity, + code, + isChecked, + buyFk, + isScanned, + quantity, + itemShelvingFk, + options + ); + + await models.SaleTracking.setPicked( + ctx, + saleFk, + originalQuantity, + code, + isChecked, + buyFk, + isScanned, + quantity, + itemShelvingFk, + options + ); + await tx.rollback(); + } catch (e) { + const error = e; + + expect(error.message).toEqual('The sale cannot be tracked'); + await tx.rollback(); + } + }); + + it('should add an itemShelvingSale and Modify a saleTracking', async() => { + const tx = await models.SaleTracking.beginTransaction({}); + const options = {transaction: tx}; + try { + const itemShelvingSaleBefore = await models.ItemShelvingSale.find({}, options); + await models.SaleTracking.setPicked( + ctx, + saleFk, + originalQuantity, + code, + isChecked, + buyFk, + isScanned, + quantity, + itemShelvingFk, + options + ); + const itemShelvingSaleAfter = await models.ItemShelvingSale.find({}, options); + const saleTracking = await models.SaleTracking.findOne({where: {saleFk, isChecked: false}}, options); + + expect(itemShelvingSaleAfter.length).toEqual(itemShelvingSaleBefore.length + 1); + expect(saleTracking.isChecked).toBeFalse(); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + } + }); +}); diff --git a/modules/ticket/back/methods/sale-tracking/specs/updateTracking.spec.js b/modules/ticket/back/methods/sale-tracking/specs/updateTracking.spec.js new file mode 100644 index 000000000..44bd1a60a --- /dev/null +++ b/modules/ticket/back/methods/sale-tracking/specs/updateTracking.spec.js @@ -0,0 +1,104 @@ +const {models} = require('vn-loopback/server/server'); + +describe('saleTracking updateTracking()', () => { + const saleFk = 1; + const originalQuantity = 10; + const code = 'PREPARED'; + const isChecked = true; + const buyFk = 1; + const isScanned = false; + + beforeAll(async() => { + ctx = { + req: { + accessToken: {userId: 104}, + headers: {origin: 'http://localhost'}, + __: value => value + } + }; + }); + + it('should throw an error if the state does not exist', async() => { + const tx = await models.SaleTracking.beginTransaction({}); + const options = {transaction: tx}; + const code = 'FAKESTATE'; + try { + await models.SaleTracking.updateTracking( + ctx, + saleFk, + originalQuantity, + code, + isChecked, + buyFk, + isScanned, + options + ); + + await tx.rollback(); + } catch (e) { + const error = e; + + expect(error.message).toEqual('this state does not exist'); + await tx.rollback(); + } + }); + + it('should add a new saleTracking and saleBuy', async() => { + const tx = await models.SaleTracking.beginTransaction({}); + const options = {transaction: tx}; + + try { + const saleTrackingBefore = await models.SaleTracking.find(null, options); + const saleBuyBefore = await models.SaleBuy.find(null, options); + await models.SaleTracking.updateTracking( + ctx, + saleFk, + originalQuantity, + code, + isChecked, + buyFk, + isScanned, + options + ); + + const saleTrackingAfter = await models.SaleTracking.find(null, options); + const saleBuyAfter = await models.SaleBuy.find(null, options); + + expect(saleTrackingAfter.length).toEqual(saleTrackingBefore.length + 1); + expect(saleBuyAfter.length).toEqual(saleBuyBefore.length + 1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should only update a saleTracking', async() => { + const tx = await models.SaleTracking.beginTransaction({}); + const options = {transaction: tx}; + const saleFk = 2; + + try { + const saleTrackingBefore = await models.SaleTracking.find(null, options); + await models.SaleTracking.updateTracking( + ctx, + saleFk, + originalQuantity, + code, + isChecked, + buyFk, + isScanned, + options + ); + const saleTrackingAfter = await models.SaleTracking.find(null, options); + + expect(saleTrackingAfter.length).toEqual(saleTrackingBefore.length + 1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/ticket/back/methods/sale-tracking/updateTracking.js b/modules/ticket/back/methods/sale-tracking/updateTracking.js new file mode 100644 index 000000000..f58429790 --- /dev/null +++ b/modules/ticket/back/methods/sale-tracking/updateTracking.js @@ -0,0 +1,110 @@ +const UserError = require('vn-loopback/util/user-error'); +module.exports = Self => { + Self.remoteMethodCtx('updateTracking', { + description: 'Modify a saleTracking record and, if applicable, add a corresponding record in saleBuy.', + accessType: 'WRITE', + accepts: [ + { + arg: 'saleFk', + type: 'number', + required: true + }, + { + arg: 'originalQuantity', + type: 'number', + required: true + }, + { + arg: 'code', + type: 'string', + required: true + }, + { + arg: 'isChecked', + type: 'boolean', + required: true + }, + { + arg: 'buyFk', + type: 'number', + required: true + }, + { + arg: 'isScanned', + type: 'boolean', + }, + ], + http: { + path: `/updateTracking`, + verb: 'POST' + } + }); + + Self.updateTracking = async(ctx, saleFk, originalQuantity, code, isChecked, buyFk, isScanned = null, options) => { + const userId = ctx.req.accessToken.userId; + const models = Self.app.models; + const myOptions = {userId}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const state = await models.State.findOne({ + where: {code}, + }, myOptions); + + if (!state) throw new UserError('this state does not exist'); + const uniqueAttributes = { + saleFk, + workerFk: userId, + stateFk: state?.id, + }; + const attributes = { + isChecked, + originalQuantity, + isScanned + }; + + const saleTracking = await models.SaleTracking.findOne({ + where: uniqueAttributes, + }, myOptions); + + if (!saleTracking) { + await models.SaleTracking.create({ + ...uniqueAttributes, + ...attributes + }, myOptions); + } else { + await saleTracking.updateAttributes({ + ...attributes + }, myOptions); + } + + let isBuy; + if (buyFk) { + isBuy = await models.Buy.findOne({ + where: { + id: buyFk, + itemOriginalFk: { + neq: null + } + } + }, myOptions); + } + + if (isBuy) + await models.SaleBuy.create({saleFk, buyFk}, myOptions); + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/ticket/back/methods/sale/getFromSectorCollection.js b/modules/ticket/back/methods/sale/getFromSectorCollection.js new file mode 100644 index 000000000..c8925c3a9 --- /dev/null +++ b/modules/ticket/back/methods/sale/getFromSectorCollection.js @@ -0,0 +1,61 @@ +module.exports = Self => { + Self.remoteMethodCtx('getFromSectorCollection', { + description: 'Get sales from sector collection', + accessType: 'READ', + accepts: [ + { + arg: 'sectorCollectionFk', + type: 'number', + required: true, + }, + { + arg: 'sectorFk', + type: 'number', + required: true + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/getFromSectorCollection`, + verb: 'GET' + }, + }); + + Self.getFromSectorCollection = async(ctx, sectorCollectionFk, sectorFk, options) => { + const userId = ctx.req.accessToken.userId; + const myOptions = {userId}; + + if (typeof options == 'object') Object.assign(myOptions, options); + + const [sales] = await Self.rawSql('CALL sectorCollection_getSale(?)', [sectorCollectionFk], myOptions); + + const itemShelvings = []; + for (let sale of sales) { + const [carros] = await Self.rawSql( + 'CALL vn.itemPlacementSupplyStockGetTargetList(?, ?)', + [sale.itemFk, sectorFk], + myOptions + ); + + itemShelvings.push({ + id: sale.ticketFk, + itemFk: sale.itemFk, + longName: sale.longName, + packingType: sale.itemPackingTypeFk, + subName: sale.subName, + quantity: sale.quantity, + saldo: sale.quantity, + trabajador: sale.workerCode, + idMovimiento: sale.saleFk, + salesPersonFk: sale.salesPersonFk, + picked: sale.pickedQuantity, + carros + }); + } + + return itemShelvings; + }; +}; diff --git a/modules/ticket/back/methods/sale/specs/getFromSectorCollection.spec.js b/modules/ticket/back/methods/sale/specs/getFromSectorCollection.spec.js new file mode 100644 index 000000000..1501426e4 --- /dev/null +++ b/modules/ticket/back/methods/sale/specs/getFromSectorCollection.spec.js @@ -0,0 +1,23 @@ +const {models} = require('vn-loopback/server/server'); + +describe('sale getFromSectorCollection()', () => { + const sectorCollectionFk = 1; + const sectorFk = 1; + + beforeAll(async() => { + ctx = { + req: { + headers: {origin: 'http://localhost'}, + accessToken: {userId: 40} + } + }; + }); + + it('should find an item and a shelving', async() => { + const options = {}; + const itemShelvings = await models.Sale.getFromSectorCollection(ctx, sectorCollectionFk, sectorFk, options); + + expect(itemShelvings.length).toEqual(1); + expect(itemShelvings[0].carros.length).toEqual(1); + }); +}); diff --git a/modules/ticket/back/methods/ticket/addSaleByCode.js b/modules/ticket/back/methods/ticket/addSaleByCode.js new file mode 100644 index 000000000..a73628c86 --- /dev/null +++ b/modules/ticket/back/methods/ticket/addSaleByCode.js @@ -0,0 +1,56 @@ +const UserError = require('vn-loopback/util/user-error'); +module.exports = Self => { + Self.remoteMethodCtx('addSaleByCode', { + description: 'Add a collection', + accessType: 'WRITE', + accepts: [ + { + arg: 'barcode', + type: 'string', + required: true + }, { + arg: 'quantity', + type: 'number', + required: true + }, { + arg: 'ticketFk', + type: 'number', + required: true + }, { + arg: 'warehouseFk', + type: 'number', + required: true + }, + + ], + http: { + path: `/addSaleByCode`, + verb: 'POST' + }, + }); + + Self.addSaleByCode = async(ctx, barcode, quantity, ticketFk, warehouseFk, options) => { + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const [[item]] = await Self.rawSql('CALL vn.item_getInfo(?,?)', [barcode, warehouseFk], myOptions); + if (!item?.available) throw new UserError('We do not have availability for the selected item'); + + await Self.rawSql('CALL vn.collection_addItem(?, ?, ?)', [item.id, quantity, ticketFk], myOptions); + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/ticket/back/methods/ticket/closeAll.js b/modules/ticket/back/methods/ticket/closeAll.js index 46c45aa92..06e9e0ed1 100644 --- a/modules/ticket/back/methods/ticket/closeAll.js +++ b/modules/ticket/back/methods/ticket/closeAll.js @@ -35,6 +35,7 @@ module.exports = Self => { SELECT t.id, t.clientFk, t.companyFk, + c.id clientFk, c.name clientName, c.email recipient, c.salesPersonFk, diff --git a/modules/ticket/back/methods/ticket/closure.js b/modules/ticket/back/methods/ticket/closure.js index 1d04679d3..90fe2d794 100644 --- a/modules/ticket/back/methods/ticket/closure.js +++ b/modules/ticket/back/methods/ticket/closure.js @@ -1,3 +1,5 @@ +/* eslint max-len: ["error", { "code": 150 }]*/ + const Report = require('vn-print/core/report'); const Email = require('vn-print/core/email'); const smtp = require('vn-print/core/smtp'); @@ -11,19 +13,27 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) { const failedtickets = []; for (const ticket of tickets) { try { - await Self.rawSql(`CALL vn.ticket_closeByTicket(?)`, [ticket.id], {userId}); + await Self.app.models.InvoiceOut.getSerial(ticket.clientFk, ticket.companyFk, ticket.addressFk, 'M'); + await Self.rawSql( + `CALL vn.ticket_closeByTicket(?)`, + [ticket.id], + {userId} + ); - const [invoiceOut] = await Self.rawSql(` + const [invoiceOut] = await Self.rawSql( + ` SELECT io.id, io.ref, io.serial, cny.code companyCode, io.issued FROM ticket t JOIN invoiceOut io ON io.ref = t.refFk JOIN company cny ON cny.id = io.companyFk WHERE t.id = ? - `, [ticket.id]); + `, + [ticket.id], + ); const mailOptions = { overrideAttachments: true, - attachments: [] + attachments: [], }; const isToBeMailed = ticket.recipient && ticket.salesPersonFk && ticket.isToBeMailed; @@ -33,7 +43,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) { reference: invoiceOut.ref, recipientId: ticket.clientFk, recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail + replyTo: ticket.salesPersonEmail, }; const invoiceReport = new Report('invoice', args); @@ -50,15 +60,19 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) { await storage.write(stream, { type: 'invoice', path: `${year}/${month}/${day}`, - fileName: fileName + fileName: fileName, }); - await Self.rawSql('UPDATE invoiceOut SET hasPdf = true WHERE id = ?', [invoiceOut.id], {userId}); + await Self.rawSql( + 'UPDATE invoiceOut SET hasPdf = true WHERE id = ?', + [invoiceOut.id], + {userId}, + ); if (isToBeMailed) { const invoiceAttachment = { filename: fileName, - content: stream + content: stream, }; if (invoiceOut.serial == 'E' && invoiceOut.companyCode == 'VNL') { @@ -68,7 +82,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) { mailOptions.attachments.push({ filename: fileName, - content: stream + content: stream, }); } @@ -82,7 +96,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) { id: ticket.id, recipientId: ticket.clientFk, recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail + replyTo: ticket.salesPersonEmail, }; const email = new Email('delivery-note-link', args); @@ -90,14 +104,17 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) { } // Incoterms authorization - const [{firstOrder}] = await Self.rawSql(` + const [{firstOrder}] = await Self.rawSql( + ` SELECT COUNT(*) as firstOrder FROM ticket t JOIN client c ON c.id = t.clientFk WHERE t.clientFk = ? AND NOT t.isDeleted AND c.isVies - `, [ticket.clientFk]); + `, + [ticket.clientFk], + ); if (firstOrder == 1) { const args = { @@ -106,7 +123,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) { recipientId: ticket.clientFk, recipient: ticket.recipient, replyTo: ticket.salesPersonEmail, - addressId: ticket.addressFk + addressId: ticket.addressFk, }; const email = new Email('incoterms-authorization', args); @@ -116,21 +133,25 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) { `SELECT id FROM sample WHERE code = 'incoterms-authorization' - `); + `, + ); - await Self.rawSql(` + await Self.rawSql( + ` INSERT INTO clientSample (clientFk, typeFk, companyFk) VALUES(?, ?, ?) - `, [ticket.clientFk, sample.id, ticket.companyFk], {userId}); + `, + [ticket.clientFk, sample.id, ticket.companyFk], + {userId}, + ); } } catch (error) { // Domain not found - if (error.responseCode == 450) - return invalidEmail(ticket); + if (error.responseCode == 450) return invalidEmail(ticket); // Save tickets on a list of failed ids failedtickets.push({ id: ticket.id, - stacktrace: error + stacktrace: error, }); } } @@ -147,24 +168,26 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) { smtp.send({ to: config.app.reportEmail, subject: '[API] Nightly ticket closure report', - html: body + html: body, }); } async function invalidEmail(ticket) { - await Self.rawSql(`UPDATE client SET email = NULL WHERE id = ?`, [ - ticket.clientFk - ], {userId}); + await Self.rawSql( + `UPDATE client SET email = NULL WHERE id = ?`, + [ticket.clientFk], + {userId}, + ); const oldInstance = `{"email": "${ticket.recipient}"}`; const newInstance = `{"email": ""}`; - await Self.rawSql(` + await Self.rawSql( + ` INSERT INTO clientLog (originFk, userFk, action, changedModel, oldInstance, newInstance) - VALUES (?, NULL, 'UPDATE', 'Client', ?, ?)`, [ - ticket.clientFk, - oldInstance, - newInstance - ], {userId}); + VALUES (?, NULL, 'UPDATE', 'Client', ?, ?)`, + [ticket.clientFk, oldInstance, newInstance], + {userId}, + ); const body = `No se ha podido enviar el albarán ${ticket.id} al cliente ${ticket.clientFk} - ${ticket.clientName} @@ -176,7 +199,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) { smtp.send({ to: ticket.salesPersonEmail, subject: 'No se ha podido enviar el albarán', - html: body + html: body, }); } }; diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js index 706da6f39..aedb960c3 100644 --- a/modules/ticket/back/methods/ticket/makeInvoice.js +++ b/modules/ticket/back/methods/ticket/makeInvoice.js @@ -77,22 +77,10 @@ module.exports = function(Self) { if (!clientCanBeInvoiced) throw new UserError(`This client can't be invoiced`); - const [{serial}] = invoiceCorrection ? [{serial: 'R'}] : await Self.rawSql( - `SELECT vn.invoiceSerial(?, ?, ?) AS serial`, - [ - clientId, - companyFk, - invoiceType - ], - myOptions); + const serial = !invoiceCorrection + ? await models.InvoiceOut.getSerial(clientId, companyFk, firstTicket.addressFk, invoiceType, myOptions) + : 'R'; - const invoiceOutSerial = await models.InvoiceOutSerial.findById(serial); - if (invoiceOutSerial?.taxAreaFk == 'WORLD') { - const address = await models.Address.findById(firstTicket.addressFk); - - if (!address || !address.customsAgentFk || !address.incotermsFk) - throw new UserError('Incoterms data for consignee is missing'); - } await Self.rawSql('CALL invoiceOut_new(?, ?, null, @invoiceId)', [serial, invoiceDate], myOptions); const [resultInvoice] = await Self.rawSql('SELECT @invoiceId id', [], myOptions); diff --git a/modules/ticket/back/methods/ticket/specs/addSaleByCode.spec.js b/modules/ticket/back/methods/ticket/specs/addSaleByCode.spec.js new file mode 100644 index 000000000..b97139178 --- /dev/null +++ b/modules/ticket/back/methods/ticket/specs/addSaleByCode.spec.js @@ -0,0 +1,39 @@ +const {models} = require('vn-loopback/server/server'); +const LoopBackContext = require('loopback-context'); + +describe('Ticket addSaleByCode()', () => { + const quantity = 3; + const ticketFk = 13; + const warehouseFk = 1; + beforeAll(async() => { + activeCtx = { + req: { + accessToken: {userId: 9}, + headers: {origin: 'http://localhost'}, + __: value => value + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + + it('should add a new sale', async() => { + const tx = await models.Ticket.beginTransaction({}); + + try { + const options = {transaction: tx}; + const code = '1111111111'; + + const salesBefore = await models.Sale.find(null, options); + await models.Ticket.addSaleByCode(activeCtx, code, quantity, ticketFk, warehouseFk, options); + const salesAfter = await models.Sale.find(null, options); + + expect(salesAfter.length).toEqual(salesBefore.length + 1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js index 456303602..fea8b2096 100644 --- a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js +++ b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js @@ -77,6 +77,6 @@ describe('ticket makeInvoice()', () => { await tx.rollback(); } - expect(error.message).toEqual(`Incoterms data for consignee is missing`); + expect(error.message).toEqual(`The address of the customer must have information about Incoterms and Customs Agent`); }); }); diff --git a/modules/ticket/back/methods/ticket/specs/setDeleted.spec.js b/modules/ticket/back/methods/ticket/specs/setDeleted.spec.js index 7931935b7..520a9e403 100644 --- a/modules/ticket/back/methods/ticket/specs/setDeleted.spec.js +++ b/modules/ticket/back/methods/ticket/specs/setDeleted.spec.js @@ -50,14 +50,17 @@ describe('ticket setDeleted()', () => { return value; }; const ticketId = 23; - - await models.Ticket.setDeleted(ctx, ticketId, options); - - const [sectorCollection] = await models.Ticket.rawSql( + const [sectorCollectionBefore] = await models.Ticket.rawSql( `SELECT COUNT(*) numberRows FROM vn.sectorCollection`, [], options); - expect(sectorCollection.numberRows).toEqual(0); + await models.Ticket.setDeleted(ctx, ticketId, options); + + const [sectorCollectionAfter] = await models.Ticket.rawSql( + `SELECT COUNT(*) numberRows + FROM vn.sectorCollection`, [], options); + + expect(sectorCollectionAfter.numberRows).toEqual(sectorCollectionBefore.numberRows - 1); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/model-config.json b/modules/ticket/back/model-config.json index 76a289cc3..db90b55e1 100644 --- a/modules/ticket/back/model-config.json +++ b/modules/ticket/back/model-config.json @@ -65,6 +65,9 @@ "SaleTracking": { "dataSource": "vn" }, + "SaleBuy": { + "dataSource": "vn" + }, "State": { "dataSource": "vn" }, diff --git a/modules/ticket/back/models/expeditionPallet.json b/modules/ticket/back/models/expeditionPallet.json index c5a38df75..cab3af6ec 100644 --- a/modules/ticket/back/models/expeditionPallet.json +++ b/modules/ticket/back/models/expeditionPallet.json @@ -1,5 +1,6 @@ { "name": "ExpeditionPallet", + "base": "VnModel", "options": { "mysql": { "table": "expeditionPallet" @@ -10,13 +11,24 @@ "type": "number", "id": true, "description": "Identifier" - } + }, + "built": { + "type": "date" + }, + "position": { + "type": "number" + }, + "isPrint": { + "type": "number" + } }, - "acls": [{ - "accessType": "WRITE", - "principalType": "ROLE", - "principalId": "production", - "permission": "ALLOW" - }] + "relations": { + "expeditionTruck": { + "type": "belongsTo", + "model": "ExpeditionTruck", + "foreignKey": "truckFk" + } + } + } diff --git a/modules/claim/back/models/claim-rma.json b/modules/ticket/back/models/sale-buy.json similarity index 56% rename from modules/claim/back/models/claim-rma.json rename to modules/ticket/back/models/sale-buy.json index 27c3c9729..a431f1224 100644 --- a/modules/claim/back/models/claim-rma.json +++ b/modules/ticket/back/models/sale-buy.json @@ -1,26 +1,29 @@ { - "name": "ClaimRma", + "name": "SaleBuy", "base": "VnModel", "options": { "mysql": { - "table": "claimRma" + "table": "saleBuy" } }, "properties": { - "id": { + "saleFk": { "id": true, - "type": "number", - "description": "Identifier" + "type": "number" }, - "code": { - "type": "string", - "required": true + "buyFk": { + "type": "number" }, "created": { "type": "date" } }, "relations": { + "sale": { + "type": "belongsTo", + "model": "Sale", + "foreignKey": "saleFk" + }, "worker": { "type": "belongsTo", "model": "Worker", @@ -28,3 +31,4 @@ } } } + \ No newline at end of file diff --git a/modules/ticket/back/models/sale-tracking.js b/modules/ticket/back/models/sale-tracking.js index 54a2b5a1a..b5f8aeed5 100644 --- a/modules/ticket/back/models/sale-tracking.js +++ b/modules/ticket/back/models/sale-tracking.js @@ -3,4 +3,6 @@ module.exports = Self => { require('../methods/sale-tracking/listSaleTracking')(Self); require('../methods/sale-tracking/new')(Self); require('../methods/sale-tracking/delete')(Self); + require('../methods/sale-tracking/updateTracking')(Self); + require('../methods/sale-tracking/setPicked')(Self); }; diff --git a/modules/ticket/back/models/sale-tracking.json b/modules/ticket/back/models/sale-tracking.json index 4a103ea15..5e512f844 100644 --- a/modules/ticket/back/models/sale-tracking.json +++ b/modules/ticket/back/models/sale-tracking.json @@ -26,6 +26,9 @@ }, "originalQuantity": { "type": "number" + }, + "isScanned": { + "type": "number" } }, "relations": { diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 22ad40184..1b4d8e31c 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -12,6 +12,7 @@ module.exports = Self => { require('../methods/sale/canEdit')(Self); require('../methods/sale/usesMana')(Self); require('../methods/sale/clone')(Self); + require('../methods/sale/getFromSectorCollection')(Self); Self.validatesPresenceOf('concept', { message: `Concept cannot be blank` diff --git a/modules/ticket/back/models/ticket.js b/modules/ticket/back/models/ticket.js index 1930765fb..51a8372e3 100644 --- a/modules/ticket/back/models/ticket.js +++ b/modules/ticket/back/models/ticket.js @@ -1,4 +1,5 @@ module.exports = Self => { require('./ticket-methods')(Self); require('../methods/ticket/state')(Self); + require('../methods/ticket/addSaleByCode')(Self); }; diff --git a/modules/ticket/front/sale-tracking/index.js b/modules/ticket/front/sale-tracking/index.js index 6c0e7232e..095d581a1 100644 --- a/modules/ticket/front/sale-tracking/index.js +++ b/modules/ticket/front/sale-tracking/index.js @@ -100,7 +100,7 @@ class Controller extends Section { saleTrackingDel(sale, stateCode) { const params = { saleFk: sale.saleFk, - stateCode: stateCode + stateCodes: [stateCode] }; this.$http.post(`SaleTrackings/delete`, params).then(() => { this.vnApp.showSuccess(this.$t('Data saved!')); diff --git a/modules/worker/back/model-config.json b/modules/worker/back/model-config.json index e12ceada5..e1a47b7e9 100644 --- a/modules/worker/back/model-config.json +++ b/modules/worker/back/model-config.json @@ -53,6 +53,9 @@ "Time": { "dataSource": "vn" }, + "WorkerAppTester": { + "dataSource": "vn" + }, "WorkCenter": { "dataSource": "vn" }, diff --git a/modules/worker/back/models/department.json b/modules/worker/back/models/department.json index edeba74f7..0245a7486 100644 --- a/modules/worker/back/models/department.json +++ b/modules/worker/back/models/department.json @@ -62,6 +62,11 @@ "type": "belongsTo", "model": "Worker", "foreignKey": "workerFk" + }, + "workerActivity": { + "type": "belongsTo", + "model": "Worker", + "foreignKey": "workerActivityTypeFk" } } -} +} \ No newline at end of file diff --git a/modules/worker/back/models/operator.js b/modules/worker/back/models/operator.js index db1ac7e49..cf6c198b6 100644 --- a/modules/worker/back/models/operator.js +++ b/modules/worker/back/models/operator.js @@ -1,4 +1,4 @@ -module.exports = function(Self) { +module.exports = Self => { Self.observe('after save', async function(ctx) { const instance = ctx.data || ctx.instance; const models = Self.app.models; diff --git a/modules/worker/back/models/operator.json b/modules/worker/back/models/operator.json index 6da3945fc..a2f3ee01c 100644 --- a/modules/worker/back/models/operator.json +++ b/modules/worker/back/models/operator.json @@ -43,6 +43,12 @@ "type": "belongsTo", "model": "Printer", "foreignKey": "labelerFk" + }, + "itemPackingType": { + "type": "belongsTo", + "model": "ItemPackingType", + "foreignKey": "itemPackingTypeFk", + "primaryKey": "code" } } } diff --git a/modules/worker/back/models/worker-app-tester.json b/modules/worker/back/models/worker-app-tester.json new file mode 100644 index 000000000..7e9706dcb --- /dev/null +++ b/modules/worker/back/models/worker-app-tester.json @@ -0,0 +1,22 @@ +{ + "name": "WorkerAppTester", + "base": "VnModel", + "options": { + "mysql": { + "table": "vn.workerAppTester" + } + }, + "properties": { + "workerFk": { + "id": true, + "type": "number" + } + }, + "relations": { + "worker": { + "type": "belongsTo", + "model": "Worker", + "foreignKey": "workerFk" + } + } +} \ No newline at end of file diff --git a/myt.config.yml b/myt.config.yml index 0b1d62d25..d7d1ad181 100755 --- a/myt.config.yml +++ b/myt.config.yml @@ -179,7 +179,6 @@ localFixtures: - claimLog - claimObservation - claimRatio - - claimRma - claimState - client - clientConfig diff --git a/package.json b/package.json index 6956cabeb..9e897823d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "24.10.0", + "version": "24.12.0", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", diff --git a/print/templates/reports/cmr/assets/css/style.css b/print/templates/reports/cmr/assets/css/style.css index 201afc3b6..8b007b3b0 100644 --- a/print/templates/reports/cmr/assets/css/style.css +++ b/print/templates/reports/cmr/assets/css/style.css @@ -3,7 +3,7 @@ html { margin: 10px; font-size: 22px; } -.mainTable, .specialTable, .categoryTable { +.mainTable, .specialTable, .categoryTable, .observationTable { width: 100%; border-collapse: collapse; font-size: inherit; @@ -98,4 +98,19 @@ img { #merchandiseLabels td { padding-bottom: 11px; max-width: 300px; +} + +.observationTable tr td { + border: none; + padding: 5px; +} + +#qrSection { + text-align: center; + width: 30%; +} + +#truckPlateQr { + width: 125px; + margin-bottom: 10px; } \ No newline at end of file diff --git a/print/templates/reports/cmr/cmr.html b/print/templates/reports/cmr/cmr.html index c6a9e79d6..a8f302086 100644 --- a/print/templates/reports/cmr/cmr.html +++ b/print/templates/reports/cmr/cmr.html @@ -30,8 +30,11 @@ 16. Transportista / Transporteur / Carrier
{{data.carrierName}}
- {{data.carrierStreet}}
- {{data.carrierPostalCode}} {{data.carrierCity}} {{(data.carrierCountry) ? `(${data.carrierCountry})` : null}} + {{data.carrierStreet}} {{data.carrierPostalCode}} + {{data.carrierCity}} {{(data.carrierCountry) + ? `(${data.carrierCountry})` + : null}}
+ CIF: {{data.carrierCif}} @@ -71,8 +74,19 @@ Carrier's reservations and observations
- {{data.truckPlate}}
- {{data.observations}} + + + + + +
+ {{data.observations}} + + +
+ {{data.truckPlate}} +
+ diff --git a/print/templates/reports/cmr/cmr.js b/print/templates/reports/cmr/cmr.js index c939e5152..ef99a08a0 100644 --- a/print/templates/reports/cmr/cmr.js +++ b/print/templates/reports/cmr/cmr.js @@ -2,44 +2,51 @@ const config = require(`vn-print/core/config`); const vnReport = require('../../../core/mixins/vn-report.js'); const md5 = require('md5'); const fs = require('fs-extra'); +const qrcode = require('qrcode'); const prefixBase64 = 'data:image/png;base64,'; module.exports = { - name: 'cmr', - mixins: [vnReport], - async serverPrefetch() { - this.data = await this.findOneFromDef('data', [this.id]); - if (this.data.ticketFk) { - this.merchandises = await this.rawSqlFromDef('merchandise', [this.data.ticketFk]); - this.signature = await this.findOneFromDef('signature', [this.data.ticketFk]); - } else - this.merchandises = null; + name: 'cmr', + mixins: [vnReport], + async serverPrefetch() { + this.data = await this.findOneFromDef('data', [this.id]); + if (this.data.ticketFk) { + this.merchandises = await this.rawSqlFromDef('merchandise', [this.data.ticketFk]); + this.signature = await this.findOneFromDef('signature', [this.data.ticketFk]); + } else + this.merchandises = null; - this.senderStamp = (this.data.senderStamp) - ? `${prefixBase64} ${this.data.senderStamp.toString('base64')}` - : null; - this.deliveryStamp = (this.data.deliveryStamp) - ? `${prefixBase64} ${this.data.deliveryStamp.toString('base64')}` - : null; - }, - props: { - id: { - type: Number, - required: true, - description: 'The cmr id' - }, - }, - computed: { - signPath() { - if (!this.signature) return; + this.senderStamp = (this.data.senderStamp) + ? `${prefixBase64} ${this.data.senderStamp.toString('base64')}` + : null; + this.deliveryStamp = (this.data.deliveryStamp) + ? `${prefixBase64} ${this.data.deliveryStamp.toString('base64')}` + : null; + this.truckPlateQr = await this.getQR(this.data.truckPlate); + }, + props: { + id: { + type: Number, + required: true, + description: 'The cmr id' + }, + }, + computed: { + signPath() { + if (!this.signature) return; - const signatureName = this.signature.signature - const hash = md5(signatureName.toString()).substring(0, 3); - const file = `${config.storage.root}/${hash}/${signatureName}.png`; - if (!fs.existsSync(file)) return null; + const signatureName = this.signature.signature; + const hash = md5(signatureName.toString()).substring(0, 3); + const file = `${config.storage.root}/${hash}/${signatureName}.png`; + if (!fs.existsSync(file)) return null; - return `${prefixBase64} ${Buffer.from(fs.readFileSync(file), 'utf8').toString('base64')}`; - }, - } -}; \ No newline at end of file + return `${prefixBase64} ${Buffer.from(fs.readFileSync(file), 'utf8').toString('base64')}`; + }, + }, + methods: { + getQR(id) { + return qrcode.toDataURL(String(id), {margin: 0}); + }, + } +}; diff --git a/print/templates/reports/cmr/sql/data.sql b/print/templates/reports/cmr/sql/data.sql index 9708c4483..e9500cc4b 100644 --- a/print/templates/reports/cmr/sql/data.sql +++ b/print/templates/reports/cmr/sql/data.sql @@ -10,6 +10,7 @@ SELECT c.id cmrFk, c.merchandiseDetail, c.ead, s.name carrierName, + s.nif carrierCif, s.street carrierStreet, s.postCode carrierPostCode, s.city carrierCity, From a00e363fd59d7e0929237c6ee06d45a2b39f4faa Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 14 Mar 2024 08:40:25 +0100 Subject: [PATCH 58/62] refs #7033 deploy: init version 2414 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f48811338..4eed71921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2414.01] - 2024-04-04 + +### Added + +### Changed + +### Fixed + ## [2408.01] - 2024-02-22 ### Added diff --git a/package.json b/package.json index 9e897823d..6aecaccdc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "24.12.0", + "version": "24.14.0", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From 4ad562a4daa5268408d374d6cb601463e635ca82 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 14 Mar 2024 09:12:19 +0100 Subject: [PATCH 59/62] fix: refs #6925 transalation --- modules/ticket/front/descriptor-menu/locale/es.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ticket/front/descriptor-menu/locale/es.yml b/modules/ticket/front/descriptor-menu/locale/es.yml index d0802fc4d..111fc2702 100644 --- a/modules/ticket/front/descriptor-menu/locale/es.yml +++ b/modules/ticket/front/descriptor-menu/locale/es.yml @@ -14,8 +14,8 @@ Refund all...: Abonar todo... with warehouse: con almacén without warehouse: sin almacén Invoice sent: Factura enviada -The following refund ticket have been created: "Se ha creado siguiente ticket de abono: {{ticketId}}" -The following refund tickets have been created: "Se ha creado los siguientes tickets de abono: {{ticketId}}" +The following refund ticket have been created: "Se ha creado el siguiente ticket de abono: {{ticketId}}" +The following refund tickets have been created: "Se han creado los siguientes tickets de abono: {{ticketId}}" Transfer client: Transferir cliente Send SMS...: Enviar SMS... Notify changes: Notificar cambios From ad7b7be661df76210ca4e063847efad39295edd8 Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 14 Mar 2024 09:15:19 +0100 Subject: [PATCH 60/62] refs #6875 Fix version --- db/versions/10892-yellowGerbera/00-firstScript.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/db/versions/10892-yellowGerbera/00-firstScript.sql b/db/versions/10892-yellowGerbera/00-firstScript.sql index 76c0cb46d..1795300f2 100644 --- a/db/versions/10892-yellowGerbera/00-firstScript.sql +++ b/db/versions/10892-yellowGerbera/00-firstScript.sql @@ -1,3 +1,5 @@ +SET @isTriggerDisabled := TRUE; + UPDATE vn.buy SET packing = 1 WHERE packing IS NULL @@ -8,6 +10,8 @@ UPDATE vn.itemShelving WHERE packing IS NULL OR NOT packing; +SET @isTriggerDisabled := FALSE; + ALTER TABLE vn.buy MODIFY COLUMN packing int(11) NOT NULL CHECK(packing > 0); ALTER TABLE vn.itemShelving MODIFY COLUMN packing int(11) NOT NULL CHECK(packing > 0); From dd7c70013055f9bb199a867a9c629920ff9000de Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 14 Mar 2024 09:53:50 +0100 Subject: [PATCH 61/62] refs #6755 fix test --- db/dump/fixtures.before.sql | 3 ++ .../front/descriptor-menu/index.spec.js | 37 ------------------- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 35de9dd47..8ea0baff2 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -3731,3 +3731,6 @@ INSERT INTO vn.report (name) VALUES ('LabelCollection'); INSERT INTO vn.parkingLog(originFk, userFk, `action`, creationDate, description, changedModel,oldInstance, newInstance, changedModelId, changedModelValue) VALUES(1, 18, 'update', util.VN_CURDATE(), NULL, 'SaleGroup', '{"parkingFk":null}', '{"parkingFk":1}', 1, NULL); + +INSERT INTO vn.ticketLog (originFk,userFk,`action`,creationDate,changedModel,newInstance,changedModelId,changedModelValue) + VALUES (18,9,'insert','2001-01-01 11:01:00.000','Ticket','{"isDeleted":true}',45,'Super Man'); diff --git a/modules/ticket/front/descriptor-menu/index.spec.js b/modules/ticket/front/descriptor-menu/index.spec.js index 6d74881b8..80ad9a33a 100644 --- a/modules/ticket/front/descriptor-menu/index.spec.js +++ b/modules/ticket/front/descriptor-menu/index.spec.js @@ -40,29 +40,6 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { controller.ticket = ticket; })); - describe('canRestoreTicket() getter', () => { - it('should return true for a ticket deleted within the last hour', () => { - controller.ticket.isDeleted = true; - controller.ticket.updated = Date.vnNew(); - - const result = controller.canRestoreTicket; - - expect(result).toBeTruthy(); - }); - - it('should return false for a ticket deleted more than one hour ago', () => { - const pastHour = Date.vnNew(); - pastHour.setHours(pastHour.getHours() - 2); - - controller.ticket.isDeleted = true; - controller.ticket.updated = pastHour; - - const result = controller.canRestoreTicket; - - expect(result).toBeFalsy(); - }); - }); - describe('addTurn()', () => { it('should make a query and call $.addTurn.hide() and vnApp.showSuccess()', () => { controller.$.addTurn = {hide: () => {}}; @@ -105,20 +82,6 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { }); }); - describe('restoreTicket()', () => { - it('should make a query to restore the ticket and call vnApp.showSuccess()', () => { - jest.spyOn(controller, 'reload').mockReturnThis(); - jest.spyOn(controller.vnApp, 'showSuccess'); - - $httpBackend.expectPOST(`Tickets/${ticket.id}/restore`).respond(); - controller.restoreTicket(); - $httpBackend.flush(); - - expect(controller.reload).toHaveBeenCalled(); - expect(controller.vnApp.showSuccess).toHaveBeenCalled(); - }); - }); - describe('showPdfDeliveryNote()', () => { it('should open a new window showing a delivery note PDF document', () => { jest.spyOn(window, 'open').mockReturnThis(); From a7faf4e325544ad8f8605156dc92555038c925d4 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 14 Mar 2024 13:05:39 +0000 Subject: [PATCH 62/62] refs #6930 perf: logout update --- front/core/services/auth.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/core/services/auth.js b/front/core/services/auth.js index 8727f92bc..753bc3fba 100644 --- a/front/core/services/auth.js +++ b/front/core/services/auth.js @@ -99,7 +99,7 @@ export default class Auth { logout() { this.$http.post('Accounts/logout', null, {headers: {'Authorization': this.vnToken.tokenMultimedia}, - }); + }).catch(() => {}); let promise = this.$http.post('VnUsers/logout', null, { headers: {Authorization: this.vnToken.token}