From 759a140e6141778c37184946909b2f37dd661122 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 17 Jan 2023 11:45:50 +0100 Subject: [PATCH 001/170] feat(print): create entry-update-comission template refs #4586 --- .../assets/css/import.js | 13 +++++ .../assets/css/style.css | 5 ++ .../entry-update-comission.html | 48 +++++++++++++++++++ .../entry-update-comission.js | 21 ++++++++ .../entry-update-comission/locale/es.yml | 4 ++ 5 files changed, 91 insertions(+) create mode 100644 print/templates/email/entry-update-comission/assets/css/import.js create mode 100644 print/templates/email/entry-update-comission/assets/css/style.css create mode 100644 print/templates/email/entry-update-comission/entry-update-comission.html create mode 100755 print/templates/email/entry-update-comission/entry-update-comission.js create mode 100644 print/templates/email/entry-update-comission/locale/es.yml diff --git a/print/templates/email/entry-update-comission/assets/css/import.js b/print/templates/email/entry-update-comission/assets/css/import.js new file mode 100644 index 000000000..7360587f7 --- /dev/null +++ b/print/templates/email/entry-update-comission/assets/css/import.js @@ -0,0 +1,13 @@ +const Stylesheet = require(`vn-print/core/stylesheet`); + +const path = require('path'); +const vnPrintPath = path.resolve('print'); + +module.exports = new Stylesheet([ + `${vnPrintPath}/common/css/spacing.css`, + `${vnPrintPath}/common/css/misc.css`, + `${vnPrintPath}/common/css/layout.css`, + `${vnPrintPath}/common/css/email.css`, + `${__dirname}/style.css`]) + .mergeStyles(); + diff --git a/print/templates/email/entry-update-comission/assets/css/style.css b/print/templates/email/entry-update-comission/assets/css/style.css new file mode 100644 index 000000000..5db85befa --- /dev/null +++ b/print/templates/email/entry-update-comission/assets/css/style.css @@ -0,0 +1,5 @@ +.external-link { + border: 2px dashed #8dba25; + border-radius: 3px; + text-align: center +} \ No newline at end of file diff --git a/print/templates/email/entry-update-comission/entry-update-comission.html b/print/templates/email/entry-update-comission/entry-update-comission.html new file mode 100644 index 000000000..003a1f09a --- /dev/null +++ b/print/templates/email/entry-update-comission/entry-update-comission.html @@ -0,0 +1,48 @@ + + + + + + {{ $t('subject') }} + + + + + + + + +
+ +
+
+
+ +
+
+ +
+
+ +
+
+

+ {{$t('dear')}} +

+

+
+
+ + +
+
+ +
+
+ +
+
+
+
+ + diff --git a/print/templates/email/entry-update-comission/entry-update-comission.js b/print/templates/email/entry-update-comission/entry-update-comission.js new file mode 100755 index 000000000..7e23c2b7c --- /dev/null +++ b/print/templates/email/entry-update-comission/entry-update-comission.js @@ -0,0 +1,21 @@ +const Component = require(`vn-print/core/component`); +const emailHeader = new Component('email-header'); +const emailFooter = new Component('email-footer'); + +module.exports = { + name: 'entry-update-comission', + components: { + 'email-header': emailHeader.build(), + 'email-footer': emailFooter.build() + }, + props: { + currencyName: { + type: [String], + required: true + }, + referenceCurrent: { + type: [String], + required: true + } + } +}; diff --git a/print/templates/email/entry-update-comission/locale/es.yml b/print/templates/email/entry-update-comission/locale/es.yml new file mode 100644 index 000000000..de58be3e7 --- /dev/null +++ b/print/templates/email/entry-update-comission/locale/es.yml @@ -0,0 +1,4 @@ +subject: Actualización tipo de cambio en entradas +title: Actualización tipo de cambio en entradas +dear: Hola, +body: 'El tipo de cambio para las ENTRADAS/COMPRAS en {0} se ha actualizado a partir de hoy en: {1}' \ No newline at end of file From 31d23f7dd1ee92f2fe1106d32794eaaf49ba5037 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 17 Jan 2023 11:50:27 +0100 Subject: [PATCH 002/170] feat(print): create entry-update-comission template refs #5112 --- .../email/entry-update-comission/entry-update-comission.html | 1 - 1 file changed, 1 deletion(-) diff --git a/print/templates/email/entry-update-comission/entry-update-comission.html b/print/templates/email/entry-update-comission/entry-update-comission.html index 003a1f09a..4c29d5b4b 100644 --- a/print/templates/email/entry-update-comission/entry-update-comission.html +++ b/print/templates/email/entry-update-comission/entry-update-comission.html @@ -29,7 +29,6 @@

-
From d5daa172d548ac834b5d0aaa5c1ca566120e6e8b Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 17 Jan 2023 11:53:29 +0100 Subject: [PATCH 003/170] refs #5112 feat(print): create entry-update-comission template --- .../email/entry-update-comission/entry-update-comission.html | 1 + 1 file changed, 1 insertion(+) diff --git a/print/templates/email/entry-update-comission/entry-update-comission.html b/print/templates/email/entry-update-comission/entry-update-comission.html index 4c29d5b4b..85439475b 100644 --- a/print/templates/email/entry-update-comission/entry-update-comission.html +++ b/print/templates/email/entry-update-comission/entry-update-comission.html @@ -29,6 +29,7 @@

+
From af0523a15537947f46c2a8018baa03a1fab0ffbf Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 25 Apr 2023 15:17:45 +0200 Subject: [PATCH 004/170] refs #5468 descriptor account solo lo puede ejecutar sysadmin y mail-forwarding solo el mismo o un superior --- db/changes/231601/00-aclAccount.sql | 6 +++ modules/account/front/aliases/index.html | 6 ++- modules/account/front/aliases/index.js | 7 +++ modules/account/front/descriptor/index.html | 16 +++---- .../account/front/mail-forwarding/index.html | 6 +-- .../account/front/mail-forwarding/index.js | 17 ++++++- .../methods/worker/authorizeSelfOrSuperior.js | 44 +++++++++++++++++++ modules/worker/back/models/worker.js | 1 + 8 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 db/changes/231601/00-aclAccount.sql create mode 100644 modules/worker/back/methods/worker/authorizeSelfOrSuperior.js diff --git a/db/changes/231601/00-aclAccount.sql b/db/changes/231601/00-aclAccount.sql new file mode 100644 index 000000000..42579a65b --- /dev/null +++ b/db/changes/231601/00-aclAccount.sql @@ -0,0 +1,6 @@ +DELETE + FROM `salix`.`ACL` + WHERE model='Account' AND property='*' AND accessType='*'; + +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES('Account', '*', 'WRITE', 'ALLOW', 'ROLE', 'sysadmin'); diff --git a/modules/account/front/aliases/index.html b/modules/account/front/aliases/index.html index 9f4ba857f..87f3c92de 100644 --- a/modules/account/front/aliases/index.html +++ b/modules/account/front/aliases/index.html @@ -15,7 +15,9 @@ @@ -32,7 +34,7 @@ ng-click="$ctrl.onAddClick()" fixed-bottom-right> - @@ -49,7 +51,7 @@ - this.isSubordinate = res.data); } refresh() { diff --git a/modules/account/front/descriptor/index.html b/modules/account/front/descriptor/index.html index 7a7ba43f3..625c50ba2 100644 --- a/modules/account/front/descriptor/index.html +++ b/modules/account/front/descriptor/index.html @@ -6,7 +6,7 @@ Delete @@ -15,7 +15,7 @@ ng-if="::$root.user.id == $ctrl.id" ng-click="$ctrl.onChangePassClick(true)" name="changePassword" - vn-acl="hr" + vn-acl="sysadmin" vn-acl-action="remove" translate> Change password @@ -23,7 +23,7 @@ Set password @@ -32,7 +32,7 @@ ng-if="!$ctrl.hasAccount" ng-click="enableAccount.show()" name="enableAccount" - vn-acl="it" + vn-acl="sysadmin" vn-acl-action="remove" translate> Enable account @@ -41,7 +41,7 @@ ng-if="$ctrl.hasAccount" ng-click="disableAccount.show()" name="disableAccount" - vn-acl="it" + vn-acl="sysadmin" vn-acl-action="remove" translate> Disable account @@ -50,8 +50,7 @@ ng-if="!$ctrl.user.active" ng-click="activateUser.show()" name="activateUser" - vn-acl="hr" - vn-acl-action="remove" + vn-acl="sysadmin" translate> Activate user @@ -59,8 +58,7 @@ ng-if="$ctrl.user.active" ng-click="deactivateUser.show()" name="deactivateUser" - vn-acl="hr" - vn-acl-action="remove" + vn-acl="sysadmin" translate> Deactivate user diff --git a/modules/account/front/mail-forwarding/index.html b/modules/account/front/mail-forwarding/index.html index 6c688f504..1e0504c23 100644 --- a/modules/account/front/mail-forwarding/index.html +++ b/modules/account/front/mail-forwarding/index.html @@ -9,17 +9,17 @@
{ + this.isAuthorized = res.data; + + if (!this.isAuthorized) throw new UserError(`You don't have enough privileges`); + this.$.watcher.submit(); + }); + } +} ngModule.component('vnUserMailForwarding', { template: require('./index.html'), diff --git a/modules/worker/back/methods/worker/authorizeSelfOrSuperior.js b/modules/worker/back/methods/worker/authorizeSelfOrSuperior.js new file mode 100644 index 000000000..30dfd17c1 --- /dev/null +++ b/modules/worker/back/methods/worker/authorizeSelfOrSuperior.js @@ -0,0 +1,44 @@ +module.exports = Self => { + Self.remoteMethod('authorizeSelfOrSuperior', { + description: 'Return true if is himself or a superior', + accessType: 'READ', + accepts: [{ + arg: 'ctx', + type: 'Object', + http: {source: 'context'} + }, { + arg: 'id', + type: 'number', + required: true, + description: 'The worker id', + http: {source: 'path'} + }], + returns: { + type: 'boolean', + root: true + }, + http: { + path: `/:id/authorizeSelfOrSuperior`, + verb: 'GET' + } + }); + + Self.authorizeSelfOrSuperior = async(ctx, id, options) => { + const models = Self.app.models; + const currentUserId = ctx.req.accessToken.userId; + const isHimself = currentUserId == id; + + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const isSubordinate = await models.Worker.isSubordinate(ctx, id, myOptions); + const isTeamBoss = await models.VnUser.hasRole(currentUserId, 'teamBoss', myOptions); + + if (!isSubordinate || (isSubordinate && !isHimself && !isTeamBoss)) + return false; + + return true; + }; +}; diff --git a/modules/worker/back/models/worker.js b/modules/worker/back/models/worker.js index fa17640a8..ffcb688ee 100644 --- a/modules/worker/back/models/worker.js +++ b/modules/worker/back/models/worker.js @@ -16,6 +16,7 @@ module.exports = Self => { require('../methods/worker/new')(Self); require('../methods/worker/deallocatePDA')(Self); require('../methods/worker/allocatePDA')(Self); + require('../methods/worker/authorizeSelfOrSuperior')(Self); Self.validatesUniquenessOf('locker', { message: 'This locker has already been assigned' From d6ff61b76861a93a616186e91cf62a55c7add360 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 26 Apr 2023 09:48:02 +0200 Subject: [PATCH 005/170] =?UTF-8?q?refs=20#5468=20corregidas=20condiciones?= =?UTF-8?q?=20de=20autorizaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/account/front/aliases/index.html | 4 ++-- modules/account/front/aliases/index.js | 7 ++++--- modules/account/front/mail-forwarding/index.js | 7 +++---- modules/account/front/mail-forwarding/locale/es.yml | 1 + .../{authorizeSelfOrSuperior.js => isAuthorized.js} | 10 +++++----- modules/worker/back/models/worker.js | 2 +- 6 files changed, 16 insertions(+), 15 deletions(-) rename modules/worker/back/methods/worker/{authorizeSelfOrSuperior.js => isAuthorized.js} (75%) diff --git a/modules/account/front/aliases/index.html b/modules/account/front/aliases/index.html index 87f3c92de..57f7ae968 100644 --- a/modules/account/front/aliases/index.html +++ b/modules/account/front/aliases/index.html @@ -15,9 +15,8 @@ @@ -28,6 +27,7 @@ this.isSubordinate = res.data); + this.$http.get(`Workers/${this.$params.id}/isAuthorized`) + .then(res => { + this.isAuthorized = res.data; + }); } refresh() { diff --git a/modules/account/front/mail-forwarding/index.js b/modules/account/front/mail-forwarding/index.js index 2047cdaa8..b48fd2258 100644 --- a/modules/account/front/mail-forwarding/index.js +++ b/modules/account/front/mail-forwarding/index.js @@ -8,11 +8,10 @@ export default class Controller extends Section { } getIsAuthorized() { - this.$http.get(`Workers/${this.$params.id}/authorizeSelfOrSuperior`) + this.$http.get(`Workers/${this.$params.id}/isSubordinate`) .then(res => { - this.isAuthorized = res.data; - - if (!this.isAuthorized) throw new UserError(`You don't have enough privileges`); + this.isSubordinate = res.data; + if (!this.isSubordinate) throw new UserError(`You don't have enough privileges`); this.$.watcher.submit(); }); } diff --git a/modules/account/front/mail-forwarding/locale/es.yml b/modules/account/front/mail-forwarding/locale/es.yml index 0322e3e42..688ace6b5 100644 --- a/modules/account/front/mail-forwarding/locale/es.yml +++ b/modules/account/front/mail-forwarding/locale/es.yml @@ -4,3 +4,4 @@ Enable mail forwarding: Habilitar redirección de correo All emails will be forwarded to the specified address.: > Todos los correos serán reenviados a la dirección especificada, no se mantendrá copia de los mismos en el buzón del usuario. +You don't have enough privileges: No tienes suficientes permisos diff --git a/modules/worker/back/methods/worker/authorizeSelfOrSuperior.js b/modules/worker/back/methods/worker/isAuthorized.js similarity index 75% rename from modules/worker/back/methods/worker/authorizeSelfOrSuperior.js rename to modules/worker/back/methods/worker/isAuthorized.js index 30dfd17c1..519aab94f 100644 --- a/modules/worker/back/methods/worker/authorizeSelfOrSuperior.js +++ b/modules/worker/back/methods/worker/isAuthorized.js @@ -1,6 +1,6 @@ module.exports = Self => { - Self.remoteMethod('authorizeSelfOrSuperior', { - description: 'Return true if is himself or a superior', + Self.remoteMethod('isAuthorized', { + description: 'Return true if the current user is a superior of the worker that is passed by parameter', accessType: 'READ', accepts: [{ arg: 'ctx', @@ -18,12 +18,12 @@ module.exports = Self => { root: true }, http: { - path: `/:id/authorizeSelfOrSuperior`, + path: `/:id/isAuthorized`, verb: 'GET' } }); - Self.authorizeSelfOrSuperior = async(ctx, id, options) => { + Self.isAuthorized = async(ctx, id, options) => { const models = Self.app.models; const currentUserId = ctx.req.accessToken.userId; const isHimself = currentUserId == id; @@ -36,7 +36,7 @@ module.exports = Self => { const isSubordinate = await models.Worker.isSubordinate(ctx, id, myOptions); const isTeamBoss = await models.VnUser.hasRole(currentUserId, 'teamBoss', myOptions); - if (!isSubordinate || (isSubordinate && !isHimself && !isTeamBoss)) + if (!isSubordinate || (isSubordinate && isHimself && !isTeamBoss)) return false; return true; diff --git a/modules/worker/back/models/worker.js b/modules/worker/back/models/worker.js index ffcb688ee..b44703a88 100644 --- a/modules/worker/back/models/worker.js +++ b/modules/worker/back/models/worker.js @@ -16,7 +16,7 @@ module.exports = Self => { require('../methods/worker/new')(Self); require('../methods/worker/deallocatePDA')(Self); require('../methods/worker/allocatePDA')(Self); - require('../methods/worker/authorizeSelfOrSuperior')(Self); + require('../methods/worker/isAuthorized')(Self); Self.validatesUniquenessOf('locker', { message: 'This locker has already been assigned' From 2e5a43af681294dcea50df303773138458f521d2 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 26 Apr 2023 11:40:21 +0200 Subject: [PATCH 006/170] refs #5468 restringido permisos 'WRITE' para sysadmin en VnUser --- db/changes/231601/00-aclAccount.sql | 3 +++ db/changes/231601/00-userAcl.sql | 3 ++- modules/account/front/descriptor/index.html | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/db/changes/231601/00-aclAccount.sql b/db/changes/231601/00-aclAccount.sql index 42579a65b..875c4aa8a 100644 --- a/db/changes/231601/00-aclAccount.sql +++ b/db/changes/231601/00-aclAccount.sql @@ -4,3 +4,6 @@ DELETE INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) VALUES('Account', '*', 'WRITE', 'ALLOW', 'ROLE', 'sysadmin'); + +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES('Account', '*', 'READ', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/231601/00-userAcl.sql b/db/changes/231601/00-userAcl.sql index 64803bf18..b880496d7 100644 --- a/db/changes/231601/00-userAcl.sql +++ b/db/changes/231601/00-userAcl.sql @@ -1,6 +1,7 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) VALUES - ('VnUser', '*', '*', 'ALLOW', 'ROLE', 'employee'), + ('VnUser', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('VnUser', '*', 'WRITE', 'ALLOW', 'ROLE', 'sysadmin'), ('VnUser','acl','READ','ALLOW','ROLE','account'), ('VnUser','getCurrentUserData','READ','ALLOW','ROLE','account'), ('VnUser','changePassword', 'WRITE', 'ALLOW', 'ROLE', 'account'), diff --git a/modules/account/front/descriptor/index.html b/modules/account/front/descriptor/index.html index 625c50ba2..61c7c5ee1 100644 --- a/modules/account/front/descriptor/index.html +++ b/modules/account/front/descriptor/index.html @@ -51,6 +51,7 @@ ng-click="activateUser.show()" name="activateUser" vn-acl="sysadmin" + vn-acl-action="remove" translate> Activate user @@ -59,6 +60,7 @@ ng-click="deactivateUser.show()" name="deactivateUser" vn-acl="sysadmin" + vn-acl-action="remove" translate> Deactivate user From 74d543884e442b958b40c092cf472ebc749b49d1 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 26 Apr 2023 11:55:01 +0200 Subject: [PATCH 007/170] =?UTF-8?q?refs=20#5468=20a=C3=B1adido=20scope=20a?= =?UTF-8?q?l=20modelo=20VnUser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/models/vn-user.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 17efc8ce6..162130f35 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -121,5 +121,8 @@ "principalId": "$authenticated", "permission": "ALLOW" } - ] + ], + "scope": { + "fields": ["id", "name", "username", "roleFk", "nickname", "lang", "active", "email", "created", "updated", "image", "hasGrant", "realm", "emailVerified"] + } } From 37a7d02006dfe401724cbe3b6258ade5def7e617 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 26 Apr 2023 12:18:32 +0200 Subject: [PATCH 008/170] quitado scope --- back/models/vn-user.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 162130f35..17efc8ce6 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -121,8 +121,5 @@ "principalId": "$authenticated", "permission": "ALLOW" } - ], - "scope": { - "fields": ["id", "name", "username", "roleFk", "nickname", "lang", "active", "email", "created", "updated", "image", "hasGrant", "realm", "emailVerified"] - } + ] } From 8a9e4ccefba0891a64e49a1d3b9ffe7594493814 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 26 Apr 2023 12:35:00 +0200 Subject: [PATCH 009/170] refs #5468 fix e2e --- e2e/paths/14-account/01_create_and_basic_data.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/paths/14-account/01_create_and_basic_data.spec.js b/e2e/paths/14-account/01_create_and_basic_data.spec.js index 54e4d1f12..6f4987419 100644 --- a/e2e/paths/14-account/01_create_and_basic_data.spec.js +++ b/e2e/paths/14-account/01_create_and_basic_data.spec.js @@ -8,7 +8,7 @@ describe('Account create and basic data path', () => { beforeAll(async() => { browser = await getBrowser(); page = browser.page; - await page.loginAndModule('developer', 'account'); + await page.loginAndModule('sysadmin', 'account'); }); afterAll(async() => { From 1597f7ab694ecfe70a79570a969862006d2c5ee3 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 27 Apr 2023 15:05:41 +0200 Subject: [PATCH 010/170] =?UTF-8?q?refs=20#5468=20permitir=20acceso=20al?= =?UTF-8?q?=20m=C3=B3dulo=20'Usuarios'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/account/front/routes.json | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/modules/account/front/routes.json b/modules/account/front/routes.json index cc66df103..f843e71a4 100644 --- a/modules/account/front/routes.json +++ b/modules/account/front/routes.json @@ -49,8 +49,7 @@ "url": "/index?q", "state": "account.index", "component": "vn-user-index", - "description": "Users", - "acl": ["marketing", "hr"] + "description": "Users" }, { "url": "/create", @@ -98,8 +97,7 @@ "url": "/roles", "state": "account.card.roles", "component": "vn-user-roles", - "description": "Inherited roles", - "acl": ["it"] + "description": "Inherited roles" }, { "url": "/mail-forwarding", @@ -111,15 +109,13 @@ "url": "/aliases", "state": "account.card.aliases", "component": "vn-user-aliases", - "description": "Mail aliases", - "acl": ["marketing", "hr"] + "description": "Mail aliases" }, { "url": "/privileges", "state": "account.card.privileges", "component": "vn-user-privileges", - "description": "Privileges", - "acl": ["hr"] + "description": "Privileges" }, { "url": "/role?q", @@ -180,8 +176,7 @@ "url": "/alias?q", "state": "account.alias", "component": "vn-alias", - "description": "Mail aliases", - "acl": ["marketing"] + "description": "Mail aliases" }, { "url": "/create", From 87ffd2668ed2f4a030b1d5c6e2e2222be82b265f Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 27 Apr 2023 15:06:05 +0200 Subject: [PATCH 011/170] refs #5468 scope para VnUser --- back/models/vn-user.json | 7 ++++++- modules/account/front/card/index.js | 8 ++++++-- modules/account/front/summary/index.js | 8 ++++++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 17efc8ce6..c0df160cd 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -121,5 +121,10 @@ "principalId": "$authenticated", "permission": "ALLOW" } - ] + ], + "scopes": { + "preview": { + "fields": ["id", "name", "username", "roleFk", "nickname", "lang", "active", "created", "updated", "image", "hasGrant", "realm"] + } + } } diff --git a/modules/account/front/card/index.js b/modules/account/front/card/index.js index e06f991bb..2c8cc7637 100644 --- a/modules/account/front/card/index.js +++ b/modules/account/front/card/index.js @@ -5,6 +5,7 @@ import './style.scss'; class Controller extends ModuleCard { reload() { const filter = { + where: {id: this.$params.id}, include: { relation: 'role', scope: { @@ -14,8 +15,11 @@ class Controller extends ModuleCard { }; return Promise.all([ - this.$http.get(`VnUsers/${this.$params.id}`, {filter}) - .then(res => this.user = res.data), + this.$http.get(`VnUsers/preview`, {filter}) + .then(res => { + const [user] = res.data; + this.user = user; + }), this.$http.get(`Accounts/${this.$params.id}/exists`) .then(res => this.hasAccount = res.data.exists) ]); diff --git a/modules/account/front/summary/index.js b/modules/account/front/summary/index.js index 8d30070e9..53b66dbe2 100644 --- a/modules/account/front/summary/index.js +++ b/modules/account/front/summary/index.js @@ -8,6 +8,7 @@ class Controller extends Summary { if (!value) return; const filter = { + where: {id: value.id}, include: { relation: 'role', scope: { @@ -15,8 +16,11 @@ class Controller extends Summary { } } }; - this.$http.get(`VnUsers/${value.id}`, {filter}) - .then(res => this.$.summary = res.data); + this.$http.get(`VnUsers/preview`, {filter}) + .then(res => { + const [summary] = res.data; + this.$.summary = summary; + }); } get isHr() { return this.aclService.hasAny(['hr']); From 42fc0b62d83f49bb6e2569a32a140d650a79409f Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 27 Apr 2023 15:18:27 +0200 Subject: [PATCH 012/170] refs #5472 feat(user): add passExpired --- back/methods/vn-user/signIn.js | 21 +++++++++----- back/models/vn-user.js | 29 +++++++++++++++++++ back/models/vn-user.json | 5 +++- db/changes/231601/00-userPassExpired.sql | 1 + .../salix/components/reset-password/index.js | 2 +- loopback/locale/en.json | 5 ++-- loopback/locale/es.json | 23 ++++++++------- 7 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 db/changes/231601/00-userPassExpired.sql diff --git a/back/methods/vn-user/signIn.js b/back/methods/vn-user/signIn.js index da3172ae4..5750beaef 100644 --- a/back/methods/vn-user/signIn.js +++ b/back/methods/vn-user/signIn.js @@ -27,33 +27,38 @@ module.exports = Self => { }); Self.signIn = async function(user, password) { - let models = Self.app.models; + const models = Self.app.models; + const usesEmail = user.indexOf('@') !== -1; let token; - let usesEmail = user.indexOf('@') !== -1; - let userInfo = usesEmail + const userInfo = usesEmail ? {email: user} : {username: user}; - let instance = await Self.findOne({ + const instance = await Self.findOne({ fields: ['username', 'password'], where: userInfo }); - let where = usesEmail + const where = usesEmail ? {email: user} : {name: user}; - let vnUser = await Self.findOne({ - fields: ['active'], + const vnUser = await Self.findOne({ + fields: ['active', 'passExpired'], where }); - let validCredentials = instance + const validCredentials = instance && await instance.hasPassword(password); + const today = Date.vnNew(); + today.setHours(0, 0, 0, 0); if (validCredentials) { if (!vnUser.active) throw new UserError('User disabled'); + if (vnUser.passExpired && vnUser.passExpired.getTime() <= today.getTime()) + throw new UserError('Pass expired'); + try { await models.Account.sync(instance.username, password); } catch (err) { diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 84ba11794..de3b0e0ba 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -107,4 +107,33 @@ module.exports = function(Self) { return email.send(); }); + + Self.remoteMethod('setPassword', { + description: 'Reset user\'s password via a password-reset token.', + accepts: [ + {arg: 'id', type: 'any', http: getUserIdFromRequestContext}, + {arg: 'newPassword', type: 'string', required: true, http: {source: 'form'}}, + {arg: 'options', type: 'object', http: 'optionsFromRequest'}, + ], + accessScopes: setPasswordScopes, + http: {verb: 'POST', path: '/reset-password'}, + }, + ); + + function getUserIdFromRequestContext(ctx) { + const token = ctx.req.accessToken; + if (!token) return; + + const hasPrincipalType = 'principalType' in token; + if (hasPrincipalType && token.principalType !== UserModel.modelName) { + // We have multiple user models related to the same access token model + // and the token used to authorize reset-password request was created + // for a different user model. + const err = new Error(g.f('Access Denied')); + err.statusCode = 403; + throw err; + } + + return token.userId; + } }; diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 17efc8ce6..ce78b09a8 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -62,7 +62,10 @@ }, "hasGrant": { "type": "boolean" - } + }, + "passExpired": { + "type": "date" + } }, "relations": { "role": { diff --git a/db/changes/231601/00-userPassExpired.sql b/db/changes/231601/00-userPassExpired.sql new file mode 100644 index 000000000..3cf9c4b6f --- /dev/null +++ b/db/changes/231601/00-userPassExpired.sql @@ -0,0 +1 @@ +ALTER TABLE `account`.`user` ADD passExpired DATE DEFAULT NULL; diff --git a/front/salix/components/reset-password/index.js b/front/salix/components/reset-password/index.js index 20c6c34fe..a3ca03237 100644 --- a/front/salix/components/reset-password/index.js +++ b/front/salix/components/reset-password/index.js @@ -33,7 +33,7 @@ export default class Controller { const newPassword = this.newPassword; - this.$http.post('users/reset-password', {newPassword}, {headers}) + this.$http.post('VnUsers/reset-password', {newPassword}, {headers}) .then(() => { this.vnApp.showSuccess(this.$translate.instant('Password changed!')); this.$state.go('login'); diff --git a/loopback/locale/en.json b/loopback/locale/en.json index ae0da8170..a9ac8aeaa 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -170,5 +170,6 @@ "comercialName": "Comercial", "Added observation": "Added observation", "Comment added to client": "Comment added to client", - "This ticket is already a refund": "This ticket is already a refund" -} \ No newline at end of file + "This ticket is already a refund": "This ticket is already a refund", + "Pass expired": "The password has expired, change it from Salix" +} diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 3ef3c4a22..6c5d90399 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -279,15 +279,16 @@ "Comment added to client": "Observación añadida al cliente {{clientFk}}", "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" + "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" } From 79e7e7c604944b8ab6ed1ba7b2e4e7ead5337114 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 2 May 2023 15:16:13 +0200 Subject: [PATCH 013/170] refs #5472 feat: add change-password section --- back/methods/vn-user/signIn.js | 10 +-- back/models/vn-user.js | 65 ++++++++++++------- .../components/change-password/index.html | 33 ++++++++++ .../salix/components/change-password/index.js | 49 ++++++++++++++ .../components/change-password/locale/en.yml | 4 ++ .../components/change-password/locale/es.yml | 8 +++ .../components/change-password/style.scss | 24 +++++++ front/salix/components/index.js | 1 + front/salix/components/login/index.js | 3 + .../salix/components/reset-password/index.js | 1 + loopback/locale/es.json | 1 - loopback/server/boot/set-password.js | 7 ++ 12 files changed, 176 insertions(+), 30 deletions(-) create mode 100644 front/salix/components/change-password/index.html create mode 100644 front/salix/components/change-password/index.js create mode 100644 front/salix/components/change-password/locale/en.yml create mode 100644 front/salix/components/change-password/locale/es.yml create mode 100644 front/salix/components/change-password/style.scss create mode 100644 loopback/server/boot/set-password.js diff --git a/back/methods/vn-user/signIn.js b/back/methods/vn-user/signIn.js index 5750beaef..36a2fb870 100644 --- a/back/methods/vn-user/signIn.js +++ b/back/methods/vn-user/signIn.js @@ -47,18 +47,18 @@ module.exports = Self => { where }); - const validCredentials = instance - && await instance.hasPassword(password); const today = Date.vnNew(); today.setHours(0, 0, 0, 0); + if (vnUser.passExpired && vnUser.passExpired.getTime() <= today.getTime()) + throw new UserError('Pass expired'); + + const validCredentials = instance + && await instance.hasPassword(password); if (validCredentials) { if (!vnUser.active) throw new UserError('User disabled'); - if (vnUser.passExpired && vnUser.passExpired.getTime() <= today.getTime()) - throw new UserError('Pass expired'); - try { await models.Account.sync(instance.username, password); } catch (err) { diff --git a/back/models/vn-user.js b/back/models/vn-user.js index de3b0e0ba..05102478c 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -108,32 +108,49 @@ module.exports = function(Self) { return email.send(); }); - Self.remoteMethod('setPassword', { - description: 'Reset user\'s password via a password-reset token.', - accepts: [ - {arg: 'id', type: 'any', http: getUserIdFromRequestContext}, - {arg: 'newPassword', type: 'string', required: true, http: {source: 'form'}}, - {arg: 'options', type: 'object', http: 'optionsFromRequest'}, - ], - accessScopes: setPasswordScopes, - http: {verb: 'POST', path: '/reset-password'}, - }, - ); + // FIX THIS + Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => { + if (!ctx.args || !ctx.args.data.email) return; + const models = Self.app.models; - function getUserIdFromRequestContext(ctx) { - const token = ctx.req.accessToken; - if (!token) return; + const loopBackContext = LoopBackContext.getCurrentContext(); + const httpCtx = {req: loopBackContext.active}; + const httpRequest = httpCtx.req.http.req; + const headers = httpRequest.headers; + const origin = headers.origin; + const url = origin.split(':'); - const hasPrincipalType = 'principalType' in token; - if (hasPrincipalType && token.principalType !== UserModel.modelName) { - // We have multiple user models related to the same access token model - // and the token used to authorize reset-password request was created - // for a different user model. - const err = new Error(g.f('Access Denied')); - err.statusCode = 403; - throw err; + const userId = ctx.instance.id; + const user = await models.VnUser.findById(userId); + + class Mailer { + async send(verifyOptions, cb) { + const params = { + url: verifyOptions.verifyHref, + recipient: verifyOptions.to, + lang: ctx.req.getLocale() + }; + + const email = new Email('email-verify', params); + email.send(); + + cb(null, verifyOptions.to); + } } - return token.userId; - } + const options = { + type: 'email', + to: instance.email, + from: {}, + redirect: `${origin}/#!/account/${instance.id}/basic-data?emailConfirmed`, + template: false, + mailer: new Mailer, + host: url[1].split('/')[2], + port: url[2], + protocol: url[0], + user: Self + }; + + await user.verify(options); + }); }; diff --git a/front/salix/components/change-password/index.html b/front/salix/components/change-password/index.html new file mode 100644 index 000000000..8d2726d3d --- /dev/null +++ b/front/salix/components/change-password/index.html @@ -0,0 +1,33 @@ +
Change password
+ + + + + + + + + diff --git a/front/salix/components/change-password/index.js b/front/salix/components/change-password/index.js new file mode 100644 index 000000000..4462b9221 --- /dev/null +++ b/front/salix/components/change-password/index.js @@ -0,0 +1,49 @@ +import ngModule from '../../module'; +import './style.scss'; +const UserError = require('vn-loopback/util/user-error'); + +export default class Controller { + constructor($scope, $element, $http, vnApp, $translate, $state, $location) { + Object.assign(this, { + $scope, + $element, + $http, + vnApp, + $translate, + $state, + $location + }); + } + + $onInit() { + this.$http.get('UserPasswords/findOne') + .then(res => { + this.passRequirements = res.data; + }); + } + + submit() { + if (!this.newPassword) + throw new UserError(`You must enter a new password`); + if (this.newPassword != this.repeatPassword) + throw new UserError(`Passwords don't match`); + + const headers = { + Authorization: this.$location.$$search.access_token + }; + + const newPassword = this.newPassword; + + this.$http.post('VnUsers/reset-password', {newPassword}, {headers}) + .then(() => { + this.vnApp.showSuccess(this.$translate.instant('Password changed!')); + this.$state.go('login'); + }); + } +} +Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state', '$location']; + +ngModule.vnComponent('vnResetPassword', { + template: require('./index.html'), + controller: Controller +}); diff --git a/front/salix/components/change-password/locale/en.yml b/front/salix/components/change-password/locale/en.yml new file mode 100644 index 000000000..e5419e1c8 --- /dev/null +++ b/front/salix/components/change-password/locale/en.yml @@ -0,0 +1,4 @@ +Password requirements: > + The password must have at least {{ length }} length characters, + {{nAlpha}} alphabetic characters, {{nUpper}} capital letters, {{nDigits}} + digits and {{nPunct}} symbols (Ex: $%&.) diff --git a/front/salix/components/change-password/locale/es.yml b/front/salix/components/change-password/locale/es.yml new file mode 100644 index 000000000..30893a152 --- /dev/null +++ b/front/salix/components/change-password/locale/es.yml @@ -0,0 +1,8 @@ +Reset password: Restrablecer contraseña +New password: Nueva contraseña +Repeat password: Repetir contraseña +Password changed!: ¡Contraseña cambiada! +Password requirements: > + La contraseña debe tener al menos {{ length }} caracteres de longitud, + {{nAlpha}} caracteres alfabéticos, {{nUpper}} letras mayúsculas, {{nDigits}} + dígitos y {{nPunct}} símbolos (Ej: $%&.) diff --git a/front/salix/components/change-password/style.scss b/front/salix/components/change-password/style.scss new file mode 100644 index 000000000..87e4adc8c --- /dev/null +++ b/front/salix/components/change-password/style.scss @@ -0,0 +1,24 @@ +@import "variables"; + +vn-reset-password{ + .footer { + margin-top: 32px; + text-align: center; + position: relative; + & > .vn-submit { + display: block; + + & > input { + display: block; + width: 100%; + } + } + & > .spinner-wrapper { + position: absolute; + width: 0; + top: 3px; + right: -8px; + overflow: visible; + } + } +} diff --git a/front/salix/components/index.js b/front/salix/components/index.js index 8f5724862..0999d9aca 100644 --- a/front/salix/components/index.js +++ b/front/salix/components/index.js @@ -9,6 +9,7 @@ import './login'; import './outLayout'; import './recover-password'; import './reset-password'; +import './change-password'; import './module-card'; import './module-main'; import './side-menu/side-menu'; diff --git a/front/salix/components/login/index.js b/front/salix/components/login/index.js index 150e896a1..d248f56a3 100644 --- a/front/salix/components/login/index.js +++ b/front/salix/components/login/index.js @@ -26,6 +26,9 @@ export default class Controller { this.loading = false; this.password = ''; this.focusUser(); + console.log('hola'); + console.log(err); + console.log(err.error); throw err; }); } diff --git a/front/salix/components/reset-password/index.js b/front/salix/components/reset-password/index.js index a3ca03237..4462b9221 100644 --- a/front/salix/components/reset-password/index.js +++ b/front/salix/components/reset-password/index.js @@ -1,5 +1,6 @@ import ngModule from '../../module'; import './style.scss'; +const UserError = require('vn-loopback/util/user-error'); export default class Controller { constructor($scope, $element, $http, vnApp, $translate, $state, $location) { diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 6c5d90399..f38678811 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -77,7 +77,6 @@ "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 current ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", "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", diff --git a/loopback/server/boot/set-password.js b/loopback/server/boot/set-password.js new file mode 100644 index 000000000..ae4dc30ea --- /dev/null +++ b/loopback/server/boot/set-password.js @@ -0,0 +1,7 @@ +// SET IN VN_USER +module.exports = async function(app) { + const _setPassword = app.models.VnUser.setPassword; + app.models.VnUser.setPassword = function(newPassword, options, cb) { + return _setPassword.call(this, newPassword, options, cb); + }; +}; From ad3c6dcee2b2066dacabf0b7bbfd92f69dae98f9 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 3 May 2023 14:34:36 +0200 Subject: [PATCH 014/170] wip #5595 --- loopback/common/models/vn-model.js | 12 ++++++++++++ modules/ticket/back/methods/ticket/makeInvoice.js | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/loopback/common/models/vn-model.js b/loopback/common/models/vn-model.js index f469e893a..992598fb5 100644 --- a/loopback/common/models/vn-model.js +++ b/loopback/common/models/vn-model.js @@ -197,6 +197,18 @@ module.exports = function(Self) { * Shortcut to VnMySQL.executeP() */ rawSql(query, params, options, cb) { + const userId = options.userId; + if (userId) { + params.unshift(userId); + return this.dataSource.connector.executeP( + `CALL account.myUser_loginWithName((SELECT name FROM account.user WHERE id = ?)); + ${query}; + CALL account.myUser_logout();`, + params, + options, + cb + ); + } return this.dataSource.connector.executeP(query, params, options, cb); }, diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js index 9739f5985..c2de55c96 100644 --- a/modules/ticket/back/methods/ticket/makeInvoice.js +++ b/modules/ticket/back/methods/ticket/makeInvoice.js @@ -29,7 +29,7 @@ module.exports = function(Self) { const date = Date.vnNew(); date.setHours(0, 0, 0, 0); - const myOptions = {}; + const myOptions = {userId}; let tx; if (typeof options == 'object') From 5eca583c626c3ea92248882b209dd2e3e8ca8057 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 3 May 2023 15:19:19 +0200 Subject: [PATCH 015/170] refs #5472 feat(vnUser): override setPassword --- back/models/vn-user.js | 9 +++++++++ front/core/services/auth.js | 6 +++--- front/salix/components/change-password/index.js | 2 +- front/salix/components/login/index.js | 3 ++- front/salix/routes.js | 6 ++++++ loopback/server/boot/set-password.js | 7 ------- 6 files changed, 21 insertions(+), 12 deletions(-) delete mode 100644 loopback/server/boot/set-password.js diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 05102478c..710710e4e 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -108,6 +108,15 @@ module.exports = function(Self) { return email.send(); }); + const _setPassword = Self.setPassword; + Self.setPassword = async function(id, newPassword, options, cb) { + // await Self.rawSql(`CALL account.user_checkPassword(?)`, [newPassword]); + await _setPassword.call(this, id, newPassword, options, cb); + const user = await Self.findById(id); + await user.updateAttribute('passExpired', null); + return; + }; + // FIX THIS Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => { if (!ctx.args || !ctx.args.data.email) return; diff --git a/front/core/services/auth.js b/front/core/services/auth.js index 0b89a8e88..41cd27f03 100644 --- a/front/core/services/auth.js +++ b/front/core/services/auth.js @@ -24,7 +24,7 @@ export default class Auth { initialize() { let criteria = { to: state => { - const outLayout = ['login', 'recover-password', 'reset-password']; + const outLayout = ['login', 'recover-password', 'reset-password', 'change-password']; return !outLayout.some(ol => ol == state.name); } }; @@ -59,8 +59,8 @@ export default class Auth { password: password || undefined }; - return this.$http.post('VnUsers/signIn', params).then( - json => this.onLoginOk(json, remember)); + return this.$http.post('VnUsers/signIn', params) + .then(json => this.onLoginOk(json, remember)); } onLoginOk(json, remember) { diff --git a/front/salix/components/change-password/index.js b/front/salix/components/change-password/index.js index 4462b9221..9b1f748b7 100644 --- a/front/salix/components/change-password/index.js +++ b/front/salix/components/change-password/index.js @@ -43,7 +43,7 @@ export default class Controller { } Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state', '$location']; -ngModule.vnComponent('vnResetPassword', { +ngModule.vnComponent('vnChangePassword', { template: require('./index.html'), controller: Controller }); diff --git a/front/salix/components/login/index.js b/front/salix/components/login/index.js index d248f56a3..74828dd9b 100644 --- a/front/salix/components/login/index.js +++ b/front/salix/components/login/index.js @@ -28,7 +28,8 @@ export default class Controller { this.focusUser(); console.log('hola'); console.log(err); - console.log(err.error); + console.log(err.message); + console.log(err.stack); throw err; }); } diff --git a/front/salix/routes.js b/front/salix/routes.js index f32c143ef..c649236a3 100644 --- a/front/salix/routes.js +++ b/front/salix/routes.js @@ -33,6 +33,12 @@ function config($stateProvider, $urlRouterProvider) { description: 'Reset password', template: '' }) + .state('change-password', { + parent: 'outLayout', + url: '/change-password', + description: 'Change password', + template: '' + }) .state('home', { parent: 'layout', url: '/', diff --git a/loopback/server/boot/set-password.js b/loopback/server/boot/set-password.js deleted file mode 100644 index ae4dc30ea..000000000 --- a/loopback/server/boot/set-password.js +++ /dev/null @@ -1,7 +0,0 @@ -// SET IN VN_USER -module.exports = async function(app) { - const _setPassword = app.models.VnUser.setPassword; - app.models.VnUser.setPassword = function(newPassword, options, cb) { - return _setPassword.call(this, newPassword, options, cb); - }; -}; From b3100d2653e3c0b2d9ebec5768390676f666dedb Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 4 May 2023 09:55:36 +0200 Subject: [PATCH 016/170] refs #5595 remove OkPackets from logIn and logOut --- loopback/common/models/vn-model.js | 2 +- loopback/server/connectors/vn-mysql.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/loopback/common/models/vn-model.js b/loopback/common/models/vn-model.js index 992598fb5..1cb389099 100644 --- a/loopback/common/models/vn-model.js +++ b/loopback/common/models/vn-model.js @@ -197,7 +197,7 @@ module.exports = function(Self) { * Shortcut to VnMySQL.executeP() */ rawSql(query, params, options, cb) { - const userId = options.userId; + const userId = options?.userId; if (userId) { params.unshift(userId); return this.dataSource.connector.executeP( diff --git a/loopback/server/connectors/vn-mysql.js b/loopback/server/connectors/vn-mysql.js index 40ad78bde..9ba65d517 100644 --- a/loopback/server/connectors/vn-mysql.js +++ b/loopback/server/connectors/vn-mysql.js @@ -17,6 +17,12 @@ class VnMySQL extends MySQL { executeP(query, params, options = {}, cb) { return new Promise((resolve, reject) => { this.execute(query, params, options, (error, response) => { + if(options?.userId) + { + response.shift(); // Remove OkPacket from logIn + response.pop(); // Remove OkPacket from logOut + response = response[response.length - 1] // Keep only query response + } if (cb) cb(error, response); if (error) From 2da42896954da4aa35432ae7d4bcabffa40d2a46 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 4 May 2023 15:01:29 +0200 Subject: [PATCH 017/170] refs #5472 feat(vn-user): override change-password & set-password --- back/methods/vn-user/signIn.js | 4 ++-- back/models/vn-user.js | 14 ++++++++++- .../components/change-password/index.html | 15 ++++-------- .../salix/components/change-password/index.js | 11 ++++----- .../components/change-password/locale/es.yml | 5 ++-- .../components/change-password/style.scss | 24 ------------------- front/salix/components/login/index.js | 17 ++++++------- front/salix/components/outLayout/style.scss | 21 ++++++++++++++++ .../components/recover-password/index.js | 1 - .../components/recover-password/style.scss | 24 ------------------- .../salix/components/reset-password/index.js | 1 - .../components/reset-password/style.scss | 24 ------------------- .../back/methods/account/change-password.js | 4 +--- .../back/methods/account/set-password.js | 4 +--- modules/account/back/methods/account/sync.js | 2 +- 15 files changed, 60 insertions(+), 111 deletions(-) delete mode 100644 front/salix/components/change-password/style.scss delete mode 100644 front/salix/components/recover-password/style.scss delete mode 100644 front/salix/components/reset-password/style.scss diff --git a/back/methods/vn-user/signIn.js b/back/methods/vn-user/signIn.js index 36a2fb870..8b14bd12d 100644 --- a/back/methods/vn-user/signIn.js +++ b/back/methods/vn-user/signIn.js @@ -43,14 +43,14 @@ module.exports = Self => { ? {email: user} : {name: user}; const vnUser = await Self.findOne({ - fields: ['active', 'passExpired'], + fields: ['id', 'active', 'passExpired'], where }); const today = Date.vnNew(); today.setHours(0, 0, 0, 0); if (vnUser.passExpired && vnUser.passExpired.getTime() <= today.getTime()) - throw new UserError('Pass expired'); + throw new UserError('Pass expired', 'passExpired', {'id': vnUser.id}); const validCredentials = instance && await instance.hasPassword(password); diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 710710e4e..47c7fd82d 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -110,13 +110,25 @@ module.exports = function(Self) { const _setPassword = Self.setPassword; Self.setPassword = async function(id, newPassword, options, cb) { - // await Self.rawSql(`CALL account.user_checkPassword(?)`, [newPassword]); + // await Self.rawSql(`CALL account.user_setPassword(?, ?)`, + // [id, newPassword]); + await Self.app.models.Account.syncById(id, newPassword); await _setPassword.call(this, id, newPassword, options, cb); + const user = await Self.findById(id); await user.updateAttribute('passExpired', null); return; }; + const _changePassword = Self.changePassword; + Self.changePassword = async function(id, oldPassword, newPassword, options, cb) { + // await Self.rawSql(`CALL account.user_changePassword(?, ?, ?)`, + // [id, oldPassword, newPassword]); + await Self.app.models.Account.syncById(id, newPassword); + await _changePassword.call(this, id, oldPassword, newPassword, options, cb); + return; + }; + // FIX THIS Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => { if (!ctx.args || !ctx.args.data.email) return; diff --git a/front/salix/components/change-password/index.html b/front/salix/components/change-password/index.html index 8d2726d3d..5ea5ced97 100644 --- a/front/salix/components/change-password/index.html +++ b/front/salix/components/change-password/index.html @@ -3,7 +3,6 @@ label="Old password" ng-model="$ctrl.oldPassword" type="password" - info="{{'Password requirements' | translate:$ctrl.passRequirements}}" vn-focus> - - + autocomplete="false"> + type="password" + autocomplete="false"> - \ No newline at end of file + From 60024f845497ac90a5ef5a439da1d4e7350340ee Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 7 Jun 2023 13:44:52 +0200 Subject: [PATCH 073/170] typo --- e2e/paths/06-claim/05_summary.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/paths/06-claim/05_summary.spec.js b/e2e/paths/06-claim/05_summary.spec.js index 46c208723..b67c665ae 100644 --- a/e2e/paths/06-claim/05_summary.spec.js +++ b/e2e/paths/06-claim/05_summary.spec.js @@ -53,7 +53,7 @@ describe('Claim summary path', () => { await page.evaluate(selectors => { document.querySelector(selectors).scrollIntoView(); }, firstItem); - await page.waitToClick(firstItem, true); + await page.waitToClick(firstItem); await page.waitImgLoad(selectors.claimSummary.firstSaleDescriptorImage); const visible = await page.isVisible(selectors.claimSummary.itemDescriptorPopover); From 0afc26e20c1a65c53aca7d495ac5148673483246 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 8 Jun 2023 10:30:03 +0200 Subject: [PATCH 074/170] refs #5728 remove add, quit e2e --- e2e/paths/12-entry/07_buys.spec.js | 19 -- modules/entry/back/methods/entry/addBuy.js | 165 ------------------ .../back/methods/entry/specs/addBuy.spec.js | 42 ----- modules/entry/back/models/entry.js | 1 - modules/entry/front/buy/index/index.html | 7 - modules/entry/front/buy/index/index.js | 5 - modules/entry/front/buy/index/index.spec.js | 11 -- 7 files changed, 250 deletions(-) delete mode 100644 modules/entry/back/methods/entry/addBuy.js delete mode 100644 modules/entry/back/methods/entry/specs/addBuy.spec.js diff --git a/e2e/paths/12-entry/07_buys.spec.js b/e2e/paths/12-entry/07_buys.spec.js index e501452bc..260d1be57 100644 --- a/e2e/paths/12-entry/07_buys.spec.js +++ b/e2e/paths/12-entry/07_buys.spec.js @@ -67,25 +67,6 @@ describe('Entry import, create and edit buys path', () => { await page.waitForNumberOfElements(selectors.entryBuys.anyBuyLine, 1); }); - it('should add a new buy', async() => { - await page.waitToClick(selectors.entryBuys.addBuyButton); - await page.write(selectors.entryBuys.secondBuyPackingPrice, '999'); - await page.write(selectors.entryBuys.secondBuyGroupingPrice, '999'); - await page.write(selectors.entryBuys.secondBuyPrice, '999'); - await page.write(selectors.entryBuys.secondBuyGrouping, '999'); - await page.write(selectors.entryBuys.secondBuyPacking, '999'); - await page.write(selectors.entryBuys.secondBuyWeight, '999'); - await page.write(selectors.entryBuys.secondBuyStickers, '999'); - await page.autocompleteSearch(selectors.entryBuys.secondBuyPackage, '1'); - await page.write(selectors.entryBuys.secondBuyQuantity, '999'); - await page.autocompleteSearch(selectors.entryBuys.secondBuyItem, '1'); - const message = await page.waitForSnackbar(); - - expect(message.text).toContain('Data saved!'); - - await page.waitForNumberOfElements(selectors.entryBuys.anyBuyLine, 2); - }); - it('should edit the newest buy and check data', async() => { await page.clearInput(selectors.entryBuys.secondBuyPackingPrice); await page.waitForTimeout(250); diff --git a/modules/entry/back/methods/entry/addBuy.js b/modules/entry/back/methods/entry/addBuy.js deleted file mode 100644 index f612c1651..000000000 --- a/modules/entry/back/methods/entry/addBuy.js +++ /dev/null @@ -1,165 +0,0 @@ - -const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; - -module.exports = Self => { - Self.remoteMethodCtx('addBuy', { - description: 'Inserts a new buy for the current entry', - accessType: 'WRITE', - accepts: [{ - arg: 'id', - type: 'number', - required: true, - description: 'The entry id', - http: {source: 'path'} - }, - { - arg: 'itemFk', - type: 'number', - required: true - }, - { - arg: 'quantity', - type: 'number', - required: true - }, - { - arg: 'packageFk', - type: 'string', - required: true - }, - { - arg: 'packing', - type: 'number', - }, - { - arg: 'grouping', - type: 'number' - }, - { - arg: 'weight', - type: 'number', - }, - { - arg: 'stickers', - type: 'number', - }, - { - arg: 'price2', - type: 'number', - }, - { - arg: 'price3', - type: 'number', - }, - { - arg: 'buyingValue', - type: 'number' - }], - returns: { - type: 'object', - root: true - }, - http: { - path: `/:id/addBuy`, - verb: 'POST' - } - }); - - Self.addBuy = async(ctx, options) => { - const conn = Self.dataSource.connector; - let tx; - const myOptions = {}; - - if (typeof options == 'object') - Object.assign(myOptions, options); - - if (!myOptions.transaction) { - tx = await Self.beginTransaction({}); - myOptions.transaction = tx; - } - - try { - const models = Self.app.models; - - ctx.args.entryFk = ctx.args.id; - - // remove unwanted properties - delete ctx.args.id; - delete ctx.args.ctx; - - const newBuy = await models.Buy.create(ctx.args, myOptions); - - const filter = { - fields: [ - 'id', - 'itemFk', - 'stickers', - 'packing', - 'grouping', - 'quantity', - 'packageFk', - 'weight', - 'buyingValue', - 'price2', - 'price3' - ], - include: { - relation: 'item', - scope: { - fields: [ - 'id', - 'typeFk', - 'name', - 'size', - 'minPrice', - 'tag5', - 'value5', - 'tag6', - 'value6', - 'tag7', - 'value7', - 'tag8', - 'value8', - 'tag9', - 'value9', - 'tag10', - 'value10', - 'groupingMode' - ], - include: { - relation: 'itemType', - scope: { - fields: ['code', 'description'] - } - } - } - } - }; - - const stmts = []; - let stmt; - - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.buyRecalc'); - stmt = new ParameterizedSQL( - `CREATE TEMPORARY TABLE tmp.buyRecalc - (INDEX (id)) - ENGINE = MEMORY - SELECT ? AS id`, [newBuy.id]); - - stmts.push(stmt); - stmts.push('CALL buy_recalcPrices()'); - - const sql = ParameterizedSQL.join(stmts, ';'); - await conn.executeStmt(sql, myOptions); - - const buy = await models.Buy.findById(newBuy.id, filter, myOptions); - - if (tx) await tx.commit(); - - return buy; - } catch (e) { - if (tx) await tx.rollback(); - throw e; - } - }; -}; diff --git a/modules/entry/back/methods/entry/specs/addBuy.spec.js b/modules/entry/back/methods/entry/specs/addBuy.spec.js deleted file mode 100644 index ead75f2d2..000000000 --- a/modules/entry/back/methods/entry/specs/addBuy.spec.js +++ /dev/null @@ -1,42 +0,0 @@ -const models = require('vn-loopback/server/server').models; -const LoopBackContext = require('loopback-context'); - -describe('entry addBuy()', () => { - const activeCtx = { - accessToken: {userId: 18}, - }; - - const ctx = { - req: activeCtx - }; - - const entryId = 2; - it('should create a new buy for the given entry', async() => { - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ - active: activeCtx - }); - const itemId = 4; - const quantity = 10; - - ctx.args = { - id: entryId, - itemFk: itemId, - quantity: quantity, - packageFk: 3 - }; - - const tx = await models.Entry.beginTransaction({}); - const options = {transaction: tx}; - - try { - const newBuy = await models.Entry.addBuy(ctx, options); - - expect(newBuy.itemFk).toEqual(itemId); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); -}); diff --git a/modules/entry/back/models/entry.js b/modules/entry/back/models/entry.js index 0eabd70ee..6148ae559 100644 --- a/modules/entry/back/models/entry.js +++ b/modules/entry/back/models/entry.js @@ -3,7 +3,6 @@ module.exports = Self => { require('../methods/entry/filter')(Self); require('../methods/entry/getEntry')(Self); require('../methods/entry/getBuys')(Self); - require('../methods/entry/addBuy')(Self); require('../methods/entry/importBuys')(Self); require('../methods/entry/importBuysPreview')(Self); require('../methods/entry/lastItemBuys')(Self); diff --git a/modules/entry/front/buy/index/index.html b/modules/entry/front/buy/index/index.html index e6d1a0b76..28fdabdb4 100644 --- a/modules/entry/front/buy/index/index.html +++ b/modules/entry/front/buy/index/index.html @@ -222,13 +222,6 @@
- - { if (!res.data) return; diff --git a/modules/entry/front/buy/index/index.spec.js b/modules/entry/front/buy/index/index.spec.js index aff52bc80..0e221302c 100644 --- a/modules/entry/front/buy/index/index.spec.js +++ b/modules/entry/front/buy/index/index.spec.js @@ -25,17 +25,6 @@ describe('Entry buy', () => { controller.saveBuy(buy); $httpBackend.flush(); }); - - it(`should call the entry addBuy post route if the received buy has no ID`, () => { - controller.entry = {id: 1}; - const buy = {itemFk: 1, quantity: 1, packageFk: 1}; - - const query = `Entries/${controller.entry.id}/addBuy`; - - $httpBackend.expectPOST(query).respond(200); - controller.saveBuy(buy); - $httpBackend.flush(); - }); }); describe('deleteBuys()', () => { From 9cdaf2e51916f481cc9327f7cb5b9e39a3c812a6 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 8 Jun 2023 10:45:27 +0200 Subject: [PATCH 075/170] refs #5728 fix e2e buy --- e2e/helpers/selectors.js | 2 - e2e/paths/12-entry/07_buys.spec.js | 74 ------------------------------ 2 files changed, 76 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index fff0a2f15..ed9c9daba 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -1179,8 +1179,6 @@ export default { allBuyCheckbox: 'vn-entry-buy-index thead vn-check', firstBuyCheckbox: 'vn-entry-buy-index tbody:nth-child(2) vn-check', deleteBuysButton: 'vn-entry-buy-index vn-button[icon="delete"]', - addBuyButton: 'vn-entry-buy-index vn-icon[icon="add"]', - secondBuyPackingPrice: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.price3"]', secondBuyGroupingPrice: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.price2"]', secondBuyPrice: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.buyingValue"]', secondBuyGrouping: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.grouping"]', diff --git a/e2e/paths/12-entry/07_buys.spec.js b/e2e/paths/12-entry/07_buys.spec.js index 260d1be57..28d39fb1d 100644 --- a/e2e/paths/12-entry/07_buys.spec.js +++ b/e2e/paths/12-entry/07_buys.spec.js @@ -66,78 +66,4 @@ describe('Entry import, create and edit buys path', () => { await page.waitToClick(selectors.globalItems.acceptButton); await page.waitForNumberOfElements(selectors.entryBuys.anyBuyLine, 1); }); - - it('should edit the newest buy and check data', async() => { - await page.clearInput(selectors.entryBuys.secondBuyPackingPrice); - await page.waitForTimeout(250); - await page.write(selectors.entryBuys.secondBuyPackingPrice, '100'); - await page.keyboard.press('Enter'); - await page.waitForSnackbar(); - - await page.clearInput(selectors.entryBuys.secondBuyGroupingPrice); - await page.waitForTimeout(250); - await page.write(selectors.entryBuys.secondBuyGroupingPrice, '200'); - await page.keyboard.press('Enter'); - await page.waitForSnackbar(); - - await page.clearInput(selectors.entryBuys.secondBuyPrice); - await page.waitForTimeout(250); - await page.write(selectors.entryBuys.secondBuyPrice, '300'); - await page.keyboard.press('Enter'); - await page.waitForSnackbar(); - - await page.clearInput(selectors.entryBuys.secondBuyGrouping); - await page.waitForTimeout(250); - await page.write(selectors.entryBuys.secondBuyGrouping, '400'); - await page.keyboard.press('Enter'); - await page.waitForSnackbar(); - - await page.clearInput(selectors.entryBuys.secondBuyPacking); - await page.waitForTimeout(250); - await page.write(selectors.entryBuys.secondBuyPacking, '500'); - await page.keyboard.press('Enter'); - await page.waitForSnackbar(); - - await page.clearInput(selectors.entryBuys.secondBuyWeight); - await page.waitForTimeout(250); - await page.write(selectors.entryBuys.secondBuyWeight, '600'); - await page.keyboard.press('Enter'); - await page.waitForSnackbar(); - - await page.clearInput(selectors.entryBuys.secondBuyStickers); - await page.waitForTimeout(250); - await page.write(selectors.entryBuys.secondBuyStickers, '700'); - await page.keyboard.press('Enter'); - await page.waitForSnackbar(); - - await page.autocompleteSearch(selectors.entryBuys.secondBuyPackage, '94'); - await page.waitForSnackbar(); - - await page.clearInput(selectors.entryBuys.secondBuyQuantity); - await page.waitForTimeout(250); - await page.write(selectors.entryBuys.secondBuyQuantity, '800'); - await page.keyboard.press('Enter'); - - await page.reloadSection('entry.card.buy.index'); - - const secondBuyPackingPrice = await page.getValue(selectors.entryBuys.secondBuyPackingPrice); - const secondBuyGroupingPrice = await page.getValue(selectors.entryBuys.secondBuyGroupingPrice); - const secondBuyPrice = await page.getValue(selectors.entryBuys.secondBuyPrice); - const secondBuyGrouping = await page.getValue(selectors.entryBuys.secondBuyGrouping); - const secondBuyPacking = await page.getValue(selectors.entryBuys.secondBuyPacking); - const secondBuyWeight = await page.getValue(selectors.entryBuys.secondBuyWeight); - const secondBuyStickers = await page.getValue(selectors.entryBuys.secondBuyStickers); - const secondBuyPackage = await page.getValue(selectors.entryBuys.secondBuyPackage); - const secondBuyQuantity = await page.getValue(selectors.entryBuys.secondBuyQuantity); - - expect(secondBuyPackingPrice).toEqual('100'); - expect(secondBuyGroupingPrice).toEqual('200'); - expect(secondBuyPrice).toEqual('300'); - expect(secondBuyGrouping).toEqual('400'); - expect(secondBuyPacking).toEqual('500'); - expect(secondBuyWeight).toEqual('600'); - expect(secondBuyStickers).toEqual('700'); - expect(secondBuyPackage).toEqual('94'); - expect(secondBuyQuantity).toEqual('800'); - }); }); From 32a0955c1d5e210176868d1f39539f555fdb6970 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Thu, 8 Jun 2023 12:48:14 +0200 Subject: [PATCH 076/170] refs #5667 Zone translations fixed --- modules/zone/back/locale/zone-event/en.yml | 8 ++++---- modules/zone/back/locale/zone-event/es.yml | 6 +++--- modules/zone/back/locale/zone-exclusion/en.yml | 4 ++-- modules/zone/back/locale/zone-exclusion/es.yml | 2 +- modules/zone/back/locale/zone-included/en.yml | 4 +++- modules/zone/back/locale/zone-included/es.yml | 4 +++- modules/zone/back/locale/zone-warehouse/en.yml | 2 +- modules/zone/back/locale/zone-warehouse/es.yml | 2 +- 8 files changed, 18 insertions(+), 14 deletions(-) diff --git a/modules/zone/back/locale/zone-event/en.yml b/modules/zone/back/locale/zone-event/en.yml index 2d6ef39ab..1988c1239 100644 --- a/modules/zone/back/locale/zone-event/en.yml +++ b/modules/zone/back/locale/zone-event/en.yml @@ -1,14 +1,14 @@ -name: zone event +name: event columns: id: id zoneFk: zone type: type dated: dated - started: started - ended: ended + started: starts + ended: ends weekDays: week days hour: hour travelingDays: traveling days price: price bonus: bonus - m3Max: max m3 + m3Max: max. m3 diff --git a/modules/zone/back/locale/zone-event/es.yml b/modules/zone/back/locale/zone-event/es.yml index 9bc8db9fe..5092cc933 100644 --- a/modules/zone/back/locale/zone-event/es.yml +++ b/modules/zone/back/locale/zone-event/es.yml @@ -1,11 +1,11 @@ -name: evento zona +name: evento columns: id: id zoneFk: zona type: tipo dated: fecha - started: comenzado - ended: terminado + started: empieza + ended: termina weekDays: días semana hour: hora travelingDays: días de viaje diff --git a/modules/zone/back/locale/zone-exclusion/en.yml b/modules/zone/back/locale/zone-exclusion/en.yml index 4389d8b93..6a2383b87 100644 --- a/modules/zone/back/locale/zone-exclusion/en.yml +++ b/modules/zone/back/locale/zone-exclusion/en.yml @@ -1,5 +1,5 @@ -name: zone exclusion +name: exclusion columns: id: id - dated: dated + dated: date zoneFk: zone diff --git a/modules/zone/back/locale/zone-exclusion/es.yml b/modules/zone/back/locale/zone-exclusion/es.yml index 4e59cba46..35102a670 100644 --- a/modules/zone/back/locale/zone-exclusion/es.yml +++ b/modules/zone/back/locale/zone-exclusion/es.yml @@ -1,4 +1,4 @@ -name: zone exclusion +name: exclusión columns: id: id dated: fecha diff --git a/modules/zone/back/locale/zone-included/en.yml b/modules/zone/back/locale/zone-included/en.yml index 0e44989e9..65e4faac6 100644 --- a/modules/zone/back/locale/zone-included/en.yml +++ b/modules/zone/back/locale/zone-included/en.yml @@ -1,5 +1,7 @@ -name: zone included +name: inclusion columns: id: id dated: dated zoneFk: zone + isIncluded: incluida + geoFk: localización diff --git a/modules/zone/back/locale/zone-included/es.yml b/modules/zone/back/locale/zone-included/es.yml index 30a89373a..bd48cdbe5 100644 --- a/modules/zone/back/locale/zone-included/es.yml +++ b/modules/zone/back/locale/zone-included/es.yml @@ -1,5 +1,7 @@ -name: zona incluida +name: inclusión columns: id: id dated: fecha zoneFk: zona + isIncluded: incluida + geoFk: localización diff --git a/modules/zone/back/locale/zone-warehouse/en.yml b/modules/zone/back/locale/zone-warehouse/en.yml index b9c4f7609..6caa3de1b 100644 --- a/modules/zone/back/locale/zone-warehouse/en.yml +++ b/modules/zone/back/locale/zone-warehouse/en.yml @@ -1,4 +1,4 @@ -name: zone warehouse +name: warehouse columns: id: id warehouseFk: warehouse diff --git a/modules/zone/back/locale/zone-warehouse/es.yml b/modules/zone/back/locale/zone-warehouse/es.yml index ec8dec2dd..caf0d8f1a 100644 --- a/modules/zone/back/locale/zone-warehouse/es.yml +++ b/modules/zone/back/locale/zone-warehouse/es.yml @@ -1,4 +1,4 @@ -name: almacén zona +name: almacén columns: id: id warehouseFk: almacén From 0ab23477d1cbafe2f5c01c87ebb532a0e9c87fe7 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 8 Jun 2023 13:13:55 +0200 Subject: [PATCH 077/170] refs #5468 move sql changes --- db/changes/{232201 => 232601}/00-aclAccount.sql | 0 db/changes/{232201 => 232601}/00-aclMailAliasAccount.sql | 0 db/changes/{232201 => 232601}/00-aclMailForward.sql | 0 db/changes/{232201 => 232601}/00-aclRole.sql | 0 db/changes/{232201 => 232601}/00-aclVnUser.sql | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename db/changes/{232201 => 232601}/00-aclAccount.sql (100%) rename db/changes/{232201 => 232601}/00-aclMailAliasAccount.sql (100%) rename db/changes/{232201 => 232601}/00-aclMailForward.sql (100%) rename db/changes/{232201 => 232601}/00-aclRole.sql (100%) rename db/changes/{232201 => 232601}/00-aclVnUser.sql (100%) diff --git a/db/changes/232201/00-aclAccount.sql b/db/changes/232601/00-aclAccount.sql similarity index 100% rename from db/changes/232201/00-aclAccount.sql rename to db/changes/232601/00-aclAccount.sql diff --git a/db/changes/232201/00-aclMailAliasAccount.sql b/db/changes/232601/00-aclMailAliasAccount.sql similarity index 100% rename from db/changes/232201/00-aclMailAliasAccount.sql rename to db/changes/232601/00-aclMailAliasAccount.sql diff --git a/db/changes/232201/00-aclMailForward.sql b/db/changes/232601/00-aclMailForward.sql similarity index 100% rename from db/changes/232201/00-aclMailForward.sql rename to db/changes/232601/00-aclMailForward.sql diff --git a/db/changes/232201/00-aclRole.sql b/db/changes/232601/00-aclRole.sql similarity index 100% rename from db/changes/232201/00-aclRole.sql rename to db/changes/232601/00-aclRole.sql diff --git a/db/changes/232201/00-aclVnUser.sql b/db/changes/232601/00-aclVnUser.sql similarity index 100% rename from db/changes/232201/00-aclVnUser.sql rename to db/changes/232601/00-aclVnUser.sql From dfdf948c42240d0950da1fa6fc93c9b0c2aba31c Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 8 Jun 2023 13:15:00 +0200 Subject: [PATCH 078/170] move sql changes --- db/changes/{232201 => 232601}/00-salix.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{232201 => 232601}/00-salix.sql (100%) diff --git a/db/changes/232201/00-salix.sql b/db/changes/232601/00-salix.sql similarity index 100% rename from db/changes/232201/00-salix.sql rename to db/changes/232601/00-salix.sql From 96d88cdf4bdc4571130732c5c1b766424675fe50 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 8 Jun 2023 14:42:07 +0200 Subject: [PATCH 079/170] refs #5366 refactor(invoiceIn_toBook): use invoiceIn_booking --- db/dump/dumpedFixtures.sql | 32 ++ db/dump/fixtures.sql | 7 + db/dump/structure.sql | 326 ++++++++++-------- db/export-data.sh | 1 + .../back/methods/invoice-in/toBook.js | 2 +- 5 files changed, 232 insertions(+), 136 deletions(-) diff --git a/db/dump/dumpedFixtures.sql b/db/dump/dumpedFixtures.sql index abb5516f7..2513972db 100644 --- a/db/dump/dumpedFixtures.sql +++ b/db/dump/dumpedFixtures.sql @@ -782,6 +782,38 @@ USE `sage`; -- Dumping data for table `TiposIva` -- +LOCK TABLES `taxType` WRITE; +/*!40000 ALTER TABLE `taxType` DISABLE KEYS */; +INSERT INTO `sage`.`taxType` (id, code, isIntracommunity) VALUES + (2, NULL, 0), + (4, 'national4', 0), + (5, NULL, 0), + (6, NULL, 1), + (7, NULL, 1), + (8, NULL, 1), + (10, 'national10', 0), + (11, NULL, 0), + (16, 'CEEServices21', 1), + (18, NULL, 0), + (20, 'national0', 0), + (21, 'national21', 0), + (22, 'import10', 0), + (26, NULL, 0), + (90, 'import21', 0), + (91, NULL, 0), + (92, NULL, 0), + (93, NULL, 0), + (94, NULL, 0), + (100, NULL, 0), + (108, NULL, 0), + (109, NULL, 0), + (110, NULL, 1), + (111, NULL, 0), + (112, NULL, 0), + (113, 'ISP21', 0), + (114, NULL, 0), + (115, 'import4', 0); + LOCK TABLES `TiposIva` WRITE; /*!40000 ALTER TABLE `TiposIva` DISABLE KEYS */; INSERT INTO `TiposIva` VALUES (2,0,'Operaciones no sujetas',0.0000000000,0.0000000000,0.0000000000,'','4770000020','','','','','','','95B21A93-5910-489D-83BB-C32788C9B19D','','','','','','','','','',0,0),(4,0,'I.V.A. 4%',0.0000000000,4.0000000000,0.0000000000,'4720000004','4770000004','','6310000000','','','','','9E6160D5-984E-4643-ACBC-1EBC3BF73360','','','','','','','','','',0,0),(5,0,'I.V.A. 4% y R.E. 0.5%',0.0000000000,4.0000000000,0.5000000000,'','4770000504','4770000405','','','','','','DBEFA562-63FB-4FFC-8171-64F0C6F065FF','','','','','','','','','',0,0),(6,0,'H.P. IVA 4% CEE',0.0000000000,4.0000000000,0.0000000000,'4721000004','4771000004','','','','','','','DD0ECBA8-2EF5-425E-911B-623580BADA77','','','','','','','','','',0,1),(7,0,'H.P. IVA 10% CEE',0.0000000000,10.0000000000,0.0000000000,'4721000011','4771000010','','','','','','','593208CD-6F28-4489-B6EC-907AD689EAC9','','','','','','','','','',0,1),(8,0,'H.P. IVA 21% CEE',0.0000000000,21.0000000000,0.0000000000,'4721000021','4771000021','','','','','','','27061852-9BC1-4C4F-9B6E-69970E208F23','','','','','','','','','',0,1),(10,0,'I.V.A. 10% Nacional',0.0000000000,10.0000000000,0.0000000000,'4720000011','4770000010','','6290000553','','','','','828A9D6F-5C01-4C3A-918A-B2E4482830D3','','','','','','','','','',0,0),(11,0,'I.V.A. 10% y R.E. 1,4%',0.0000000000,10.0000000000,1.4000000000,'','4770000101','4770000110','','','','','','C1F2D910-83A1-4191-A76C-8B3D7AB98348','','','','','','','','','',0,0),(16,0,'I.V.A. Adqui. servicios CEE',0.0000000000,21.0000000000,0.0000000000,'4721000015','4771000016','','','','','','','E3EDE961-CE8F-41D4-9E6C-D8BCD32275A1','','','','','','','','','',0,1),(18,0,'H.P. Iva Importación 0% ISP',0.0000000000,0.0000000000,0.0000000000,'4720000005','4770000005','','','','','','','27AD4158-2349-49C2-B53A-A4E0EFAC5D09','','','','','','','','','',0,0),(20,0,'I.V.A 0% Nacional',0.0000000000,0.0000000000,0.0000000000,'4720000000','','','','','','','','B90B0FBD-E513-4F04-9721-C873504E08DF','','','','','','','','','',0,0),(21,0,'I.V.A. 21%',0.0000000000,21.0000000000,0.0000000000,'4720000021','4770000021','4770000000','','','','','','BA8C4E28-DCFA-4F7B-AE4F-CA044626B55E','','','','','','','','','',0,0),(22,0,'IVA 10% importaciones',0.0000000000,10.0000000000,0.0000000000,'4722000010','','','','','','','','540450A8-4B41-4607-96D1-E7F296FB6933','','','','','','','','','',0,0),(26,0,'I.V.A. 21% y R.E. 5,2%',0.0000000000,21.0000000000,5.2000000000,'4720000021','4770000215','4770000521','631000000','','','','','2BC0765F-7739-49AE-A5F0-28B648B81677','','','','','','','','','',0,0),(90,0,'IVA 21% importaciones',0.0000000000,21.0000000000,0.0000000000,'4722000021','','','','','','','','EB675F91-5FF2-4E26-A31E-EEB674125945','','','','','','','','','',0,0),(91,0,'IVA 0% importaciones',0.0000000000,0.0000000000,0.0000000000,'4723000000','','','','','','','','5E5EFA56-2A99-4D54-A16B-5D818274CA18','','','','','','','','','',0,0),(92,0,'8.5% comp. ganadera o pesquera',0.0000000000,8.5000000000,0.0000000000,'4720000000','4770000000','477000000','631000000','','','','','','','','','','','','','','',0,0),(93,0,'12% com. agrícola o forestal',0.0000000000,12.0000000000,0.0000000000,'4720000012','','','','','','','','267B1DDB-247F-4A71-AB95-3349FEFC5F92','','','','','','','','','',0,0),(94,0,'10,5% com. ganadera o pesquera',0.0000000000,10.5000000000,0.0000000000,'4770000000','4720000000','631000000','477000000','','','','','','','','','','','','','','',0,0),(100,0,'HP IVA SOPORTADO 5%',0.0000000000,5.0000000000,0.0000000000,'4720000055','','','','','','','','3AD36CB2-4172-4CC9-9F87-2BF2B56AAC80','','','','','','','','','',0,0),(108,0,'I.V.A. 8%',0.0000000000,8.0000000000,0.0000000000,'4720000000','4770000000','477000000','631000000','','','','','','','','','','','','','','',0,0),(109,0,'I.V.A. 8% y R.E. 1%',0.0000000000,8.0000000000,1.0000000000,'4720000000','4770000000','477000000','631000000','','','','','','','','','','','','','','',0,0),(110,0,'HP IVA Devengado Exento CEE',0.0000000000,0.0000000000,0.0000000000,'','4771000000','','','','','','','C605BC32-E161-42FD-83F3-3A66B1FBE399','','','','','','','','','',0,1),(111,0,'H.P. Iva Devengado Exento Ser',0.0000000000,0.0000000000,0.0000000000,'','4771000001','','','','','','','F1AEC4DC-AFE5-498E-A713-2648FFB6DA32','','','','','','','','','',0,0),(112,0,'H.P. IVA Devengado en exportac',0.0000000000,0.0000000000,0.0000000000,'','4770000002','','','','','','','F980AE74-BF75-4F4C-927F-0CCCE0DB8D15','','','','','','','','','',0,0),(113,0,'HP DEVENGADO 21 ISP ',0.0000000000,21.0000000000,0.0000000000,'4720000006','4770000006','','','','','','','728D7A76-E936-438C-AF05-3CA38FE16EA5','','','','','','','','','',0,0),(114,0,'HP.IVA NO DEDUCIBLE 10%',0.0000000000,0.0000000000,0.0000000000,'4720000026','','','','','','','','','','','','','','','','','',0,0),(115,0,'H.P. IVA Soportado Impor 4% ',0.0000000000,4.0000000000,0.0000000000,'4722000004','','','','','','','','','','','','','','','','','',0,0); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 3476bfe48..50aea9aeb 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2896,3 +2896,10 @@ INSERT INTO `vn`.`travelConfig` (`id`, `warehouseInFk`, `warehouseOutFk`, `agenc INSERT INTO `vn`.`buyConfig` (`id`, `monthsAgo`) VALUES (1, 6); + +INSERT INTO `vn`.`invoiceInSerial` (`code`, `description`, `cplusTerIdNifFk`, `taxAreaFk`) + VALUES + ('C', 'Asgard', 1, 'WORLD'), + ('E', 'Midgard', 1, 'CEE'), + ('R', 'Jotunheim', 1, 'NATIONAL'), + ('W', 'Vanaheim', 1, 'WORLD'); diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 3ce7f7bb5..b07e88fde 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -15620,6 +15620,18 @@ CREATE TABLE `ClavesOperacion` ( -- -- Table structure for table `Municipios` -- +DROP TABLE IF EXISTS `taxType`; + +CREATE TABLE `taxType` ( + id INT(11) NOT NULL, + code VARCHAR(25) DEFAULT NULL NULL, + isIntracommunity TINYINT(1) DEFAULT FALSE NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `taxType_UN` (`code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci COMMENT='Coincidencia del id con Sage.TiposIVA.CodigoIva(propia de Sage), en ningún caso vincular mediate FK'; + +ALTER TABLE `sage`.`taxType` ADD CONSTRAINT taxType_PK PRIMARY KEY IF NOT EXISTS (id); +ALTER TABLE `sage`.`taxType` ADD CONSTRAINT taxType_UN UNIQUE KEY IF NOT EXISTS (code); DROP TABLE IF EXISTS `Municipios`; /*!40101 SET @saved_cs_client = @@character_set_client */; @@ -22074,12 +22086,14 @@ CREATE TABLE `autonomy` ( `name` varchar(100) NOT NULL, `countryFk` mediumint(8) unsigned NOT NULL, `geoFk` int(11) DEFAULT NULL, + `isUeeMember` tinyint(1) DEFAULT NULL, + `hasDailyInvoice` tinyint(4) DEFAULT NULL, PRIMARY KEY (`id`), KEY `autonomy_FK` (`countryFk`), KEY `autonomy_FK_1` (`geoFk`), CONSTRAINT `autonomy_FK` FOREIGN KEY (`countryFk`) REFERENCES `country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `autonomy_FK_1` FOREIGN KEY (`geoFk`) REFERENCES `zoneGeo` (`id`) ON UPDATE CASCADE -) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Comunidades autónomas o su equivalente en otros paises. Agrupación de provincias, en una categoria inferior a country.'; +) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Comunidades autónomas o su equivalente en otros paises. Agrupación de provincias, en una categoria inferior a country.'; /*!40101 SET character_set_client = @saved_cs_client */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -28805,7 +28819,10 @@ CREATE TABLE `expence` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; - +ALTER TABLE `vn`.`expence` + ADD code VARCHAR(25) DEFAULT NULL NULL; +ALTER TABLE `vn`.`expence` + ADD CONSTRAINT expence_UN UNIQUE KEY IF NOT EXISTS (code); -- -- Table structure for table `farming` -- @@ -57317,7 +57334,7 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `invoiceInBookingMain` */; +/*!50003 DROP PROCEDURE IF EXISTS `invoiceIn_booking` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -57326,28 +57343,71 @@ DELIMITER ; /*!50003 SET collation_connection = utf8mb4_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; + + + DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceInBookingMain`(vInvoiceInId INT) +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceIn_booking`(vSelf INT) BEGIN - DECLARE vTotalAmount,vTotalAmountDivisa DECIMAL(10,2); - DECLARE vBookNumber,vSerialNumber INT; - DECLARE vRate DECIMAL(10,4); + DECLARE vBookNumber INT; - CALL invoiceInBookingCommon(vInvoiceInId,vSerialNumber); - - SELECT SUM(iit.taxableBase * IF( i.serial= 'R' AND ti.Iva <> 'HP DEVENGADO 21 ISP', 1 +(ti.PorcentajeIva/100),1)), - SUM(iit.foreignValue * IF( i.serial= 'R', 1 + (ti.PorcentajeIva/100),1)), - iit.taxableBase/iit.foreignValue - INTO vTotalAmount, vTotalAmountDivisa, vRate - FROM newInvoiceIn i - JOIN invoiceInTax iit ON iit.invoiceInFk = i.id - LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk; + DROP TEMPORARY TABLE IF EXISTS tInvoiceIn; + CREATE TEMPORARY TABLE tInvoiceIn + ENGINE = MEMORY + SELECT ii.bookEntried, + iit.foreignValue, + ii.companyFk, + ii.expenceFkDeductible, + iit.taxableBase, + ii.serial, + ii.issued, + ii.operated, + ii.supplierRef, + ii.cplusTrascendency472Fk, + ii.cplusTaxBreakFk, + ii.cplusSubjectOpFk, + ii.cplusInvoiceType472Fk, + ii.cplusRectificationTypeFk, + ii.booked, + IFNULL(a.isUeeMember, c.isUeeMember) isUeeMember, + (c.id = cc.id) isSameCountry, + s.account supplierAccount, + s.name supplierName, + s.nif, + iit.taxTypeSageFk, + tt.code taxCode, + ti.Iva, + ti.CuentaIvaSoportado, + ti.PorcentajeIva, + ti.CuentaIvaRepercutido, + ttr.ClaveOperacionDefecto, + iis.cplusTerIdNifFk, + cit.id invoicesCount, + e.code, + e.isWithheld, + e.id expenceFk, + e.name expenceName + FROM invoiceIn ii + JOIN supplier s ON s.id = ii.supplierFk + LEFT JOIN province p ON p.id = s.provinceFk + LEFT JOIN autonomy a ON a.id = p.autonomyFk + JOIN country c ON c.id = s.countryFk + JOIN supplier sc ON sc.id = ii.companyFk + JOIN country cc ON cc.id = sc.countryFk + JOIN invoiceInSerial iis ON iis.code = ii.serial + JOIN cplusInvoiceType472 cit ON cit.id = ii.cplusInvoiceType472Fk + LEFT JOIN invoiceInTax iit ON iit.invoiceInFk = ii.id + LEFT JOIN sage.TiposTransacciones ttr ON ttr.CodigoTransaccion = iit.transactionTypeSageFk + LEFT JOIN expence e ON e.id = iit.expenceFk + LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk + LEFT JOIN sage.taxType tt ON tt.id = ti.CodigoIva + WHERE ii.id = vSelf; CALL vn.ledger_next(vBookNumber); -- Apunte del proveedor - - INSERT INTO XDiario(ASIEN, + INSERT INTO XDiario( + ASIEN, FECHA, SUBCTA, EUROHABER, @@ -57356,24 +57416,30 @@ BEGIN HABERME, NFACTICK, CLAVE, - empresa_id - ) + empresa_id) SELECT - vBookNumber, - n.bookEntried, - s.supplierAccount, - vTotalAmount EUROHABER, - n.conceptWithSupplier, - vRate, - vTotalAmountDivisa, - n.invoicesCount, - vInvoiceInId, - n.companyFk - FROM newInvoiceIn n - JOIN newSupplier s; + vBookNumber ASIEN, + tii.bookEntried FECHA, + tii.supplierAccount SUBCTA, + SUM(tii.taxableBase * + IF(tii.serial= 'R' AND ((tii.taxCode IS NULL OR tii.taxCode <> 'ISP21') + AND tii.taxTypeSageFk IS NOT NULL), + 1 + (tii.PorcentajeIva / 100), + 1)) EUROHABER, + CONCAT('s/fra', + RIGHT(tii.supplierRef, 8), + ':', + LEFT(tii.supplierName, 10)) CONCEPTO, + CAST(tii.taxableBase / tii.foreignValue AS DECIMAL (10,4)) CAMBIO, + SUM(tii.foreignValue * IF(tii.serial = 'R', 1 + (tii.PorcentajeIva / 100), 1)) HABERME, + tii.invoicesCount NFACTICK, + vSelf CLAVE, + tii.companyFk empresa_id + FROM tInvoiceIn tii; -- Línea de Gastos - INSERT INTO XDiario ( ASIEN, + INSERT INTO XDiario( + ASIEN, FECHA, SUBCTA, CONTRA, @@ -57384,30 +57450,29 @@ BEGIN DEBEME, HABERME, NFACTICK, - empresa_id - ) + empresa_id) SELECT vBookNumber ASIEN, - n.bookEntried FECHA, - IF(e.isWithheld , LPAD(RIGHT(s.supplierAccount,5),10,iit.expenceFk),iit.expenceFk) SUBCTA, - s.supplierAccount CONTRA, - IF(e.isWithheld AND iit.taxableBase < 0, NULL, ROUND(SUM(iit.taxableBase),2)) EURODEBE, - IF(e.isWithheld AND iit.taxableBase < 0,ROUND(SUM(-iit.taxableBase),2),NULL) EUROHABER, - n.conceptWithSupplier CONCEPTO, - vRate, - IF(e.isWithheld,NULL,ABS(ROUND(SUM(iit.foreignValue),2))) DEBEME, - IF(e.isWithheld,ABS(ROUND(SUM(iit.foreignValue),2)),NULL) HABERME, - n.invoicesCount NFACTICK, - n.companyFk empresa_id - FROM newInvoiceIn n - JOIN newSupplier s - JOIN invoiceInTax iit ON iit.invoiceInFk = n.id - JOIN (SELECT * FROM expence e GROUP BY e.id)e ON e.id = iit.expenceFk - WHERE e.name != 'Suplidos Transitarios nacionales' - GROUP BY iit.expenceFk; + tii.bookEntried FECHA, + IF(tii.isWithheld, LPAD(RIGHT(tii.supplierAccount, 5), 10, tii.expenceFk),tii.expenceFk) SUBCTA, + tii.supplierAccount CONTRA, + IF(tii.isWithheld AND tii.taxableBase < 0, NULL, ROUND(SUM(tii.taxableBase),2)) EURODEBE, + IF(tii.isWithheld AND tii.taxableBase < 0, ROUND(SUM(-tii.taxableBase), 2), NULL) EUROHABER, + CONCAT('s/fra', + RIGHT(tii.supplierRef, 8), + ':', + LEFT(tii.supplierName, 10)) CONCEPTO, + CAST(tii.taxableBase / tii.foreignValue AS DECIMAL (10, 4)) CAMBIO, + IF(tii.isWithheld, NULL,ABS(ROUND(SUM(tii.foreignValue), 2))) DEBEME, + IF(tii.isWithheld, ABS(ROUND(SUM(tii.foreignValue), 2)) ,NULL) HABERME, + tii.invoicesCount NFACTICK, + tii.companyFk empresa_id + FROM tInvoiceIn tii + WHERE tii.code IS NULL OR tii.code <> 'suplido' + GROUP BY tii.expenceFk; -- Líneas de IVA - - INSERT INTO XDiario( ASIEN, + INSERT INTO XDiario( + ASIEN, FECHA, SUBCTA, CONTRA, @@ -57434,56 +57499,50 @@ BEGIN TERNIF, TERNOM, FECREGCON, - empresa_id - ) + empresa_id) SELECT vBookNumber ASIEN, - n.bookEntried FECHA, - IF(n.expenceFkDeductible>0, n.expenceFkDeductible, ti.CuentaIvaSoportado) SUBCTA, - s.supplierAccount CONTRA, - SUM(ROUND(ti.PorcentajeIva * it.taxableBase / 100 /* + 0.0001*/ , 2)) EURODEBE, - SUM(it.taxableBase) BASEEURO, - GROUP_CONCAT(DISTINCT e.`name` SEPARATOR ', ') CONCEPTO, - vSerialNumber FACTURA, - ti.PorcentajeIva IVA, - IF(isUeeMember AND eWithheld.id IS NULL,'','*') AUXILIAR, - n.serial SERIE, - ttr.ClaveOperacionDefecto, - n.issued FECHA_EX, - n.operated FECHA_OP, - n.invoicesCount NFACTICK, - n.supplierRef FACTURAEX, + tii.bookEntried FECHA, + IF(tii.expenceFkDeductible>0, tii.expenceFkDeductible, tii.CuentaIvaSoportado) SUBCTA, + tii.supplierAccount CONTRA, + SUM(ROUND(tii.PorcentajeIva * tii.taxableBase / 100, 2)) EURODEBE, + SUM(tii.taxableBase) BASEEURO, + GROUP_CONCAT(DISTINCT tii.expenceName SEPARATOR ', ') CONCEPTO, + vSelf FACTURA, + tii.PorcentajeIva IVA, + IF(tii.isUeeMember AND eWithheld.id IS NULL, '', '*') AUXILIAR, + tii.serial SERIE, + tii.ClaveOperacionDefecto, + tii.issued FECHA_EX, + tii.operated FECHA_OP, + tii.invoicesCount NFACTICK, + tii.supplierRef FACTURAEX, TRUE L340, - (isSameCountry OR NOT isUeeMember) LRECT349, - n.cplusTrascendency472Fk TIPOCLAVE, - n.cplusTaxBreakFk TIPOEXENCI, - n.cplusSubjectOpFk TIPONOSUJE, - n.cplusInvoiceType472Fk TIPOFACT, - n.cplusRectificationTypeFk TIPORECTIF, - iis.cplusTerIdNifFk TERIDNIF, - s.nif AS TERNIF, - s.name AS TERNOM, - n.booked FECREGCON, - n.companyFk - FROM newInvoiceIn n - JOIN newSupplier s - JOIN invoiceInTax it ON n.id = it.invoiceInFk - JOIN sage.TiposIva ti ON ti.CodigoIva = it.taxTypeSageFk - JOIN sage.TiposTransacciones ttr ON ttr.CodigoTransaccion = it.transactionTypeSageFk - JOIN invoiceInSerial iis ON iis.code = n.serial - JOIN (SELECT * FROM expence e GROUP BY e.id)e ON e.id = it.expenceFk + (tii.isSameCountry OR NOT tii.isUeeMember) LRECT349, + tii.cplusTrascendency472Fk TIPOCLAVE, + tii.cplusTaxBreakFk TIPOEXENCI, + tii.cplusSubjectOpFk TIPONOSUJE, + tii.cplusInvoiceType472Fk TIPOFACT, + tii.cplusRectificationTypeFk TIPORECTIF, + tii.cplusTerIdNifFk TERIDNIF, + tii.nif TERNIF, + tii.supplierName TERNOM, + tii.booked FECREGCON, + tii.companyFk + FROM tInvoiceIn tii LEFT JOIN ( - SELECT eWithheld.id - FROM invoiceInTax hold - JOIN expence eWithheld ON eWithheld.id = hold.expenceFk AND eWithheld.isWithheld - WHERE hold.invoiceInFk = vInvoiceInId LIMIT 1 + SELECT e.id + FROM tInvoiceIn tii + JOIN expence e ON e.id = tii.expenceFk + WHERE e.isWithheld + LIMIT 1 ) eWithheld ON TRUE - WHERE it.taxTypeSageFk IS NOT NULL - AND it.taxTypeSageFk NOT IN (22, 90) - GROUP BY ti.PorcentajeIva, e.id; + WHERE tii.taxTypeSageFk IS NOT NULL + AND (tii.taxCode IS NULL OR tii.taxCode NOT IN ('import10', 'import21')) + GROUP BY tii.PorcentajeIva, tii.expenceFk; -- Línea iva inversor sujeto pasivo - - INSERT INTO XDiario( ASIEN, + INSERT INTO XDiario( + ASIEN, FECHA, SUBCTA, CONTRA, @@ -57509,50 +57568,43 @@ BEGIN TERIDNIF, TERNIF, TERNOM, - empresa_id - ) + empresa_id) SELECT vBookNumber ASIEN, - n.bookEntried FECHA, - ti.CuentaIvaRepercutido SUBCTA, - s.supplierAccount CONTRA, - SUM(ROUND(ti.PorcentajeIva * it.taxableBase / 100,2)) EUROHABER, - ROUND(SUM(it.taxableBase),2) BASEEURO, - GROUP_CONCAT(DISTINCT e.`name` SEPARATOR ', ') CONCEPTO, - vSerialNumber FACTURA, - ti.PorcentajeIva IVA, + tii.bookEntried FECHA, + tii.CuentaIvaRepercutido SUBCTA, + tii.supplierAccount CONTRA, + SUM(ROUND(tii.PorcentajeIva * tii.taxableBase / 100,2)) EUROHABER, + ROUND(SUM(tii.taxableBase),2) BASEEURO, + GROUP_CONCAT(DISTINCT tii.expenceName SEPARATOR ', ') CONCEPTO, + vSelf FACTURA, + tii.PorcentajeIva IVA, '*' AUXILIAR, - n.serial SERIE, - ttr.ClaveOperacionDefecto, - n.issued FECHA_EX, - n.operated FECHA_OP, - n.invoicesCount NFACTICK, - n.supplierRef FACTURAEX, + tii.serial SERIE, + tii.ClaveOperacionDefecto, + tii.issued FECHA_EX, + tii.operated FECHA_OP, + tii.invoicesCount NFACTICK, + tii.supplierRef FACTURAEX, FALSE L340, - (isSameCountry OR NOT isUeeMember) LRECT349, + (tii.isSameCountry OR NOT tii.isUeeMember) LRECT349, 1 TIPOCLAVE, - n.cplusTaxBreakFk TIPOEXENCI, - n.cplusSubjectOpFk TIPONOSUJE, - n.cplusInvoiceType472Fk TIPOFACT, - n.cplusRectificationTypeFk TIPORECTIF, - iis.cplusTerIdNifFk TERIDNIF, - s.nif AS TERNIF, - s.name AS TERNOM, - n.companyFk - FROM newInvoiceIn n - JOIN newSupplier s - JOIN invoiceInTax it ON n.id = it.invoiceInFk - JOIN sage.TiposIva ti ON ti.CodigoIva = it.taxTypeSageFk - JOIN sage.TiposTransacciones ttr ON ttr.CodigoTransaccion = it.transactionTypeSageFk - JOIN invoiceInSerial iis ON iis.code = n.serial - JOIN (SELECT * FROM expence e GROUP BY e.id)e ON e.id = it.expenceFk - WHERE ti.Iva = 'HP DEVENGADO 21 ISP' OR MID(s.account, 4, 1) = '1' - GROUP BY ti.PorcentajeIva, e.id; + tii.cplusTaxBreakFk TIPOEXENCI, + tii.cplusSubjectOpFk TIPONOSUJE, + tii.cplusInvoiceType472Fk TIPOFACT, + tii.cplusRectificationTypeFk TIPORECTIF, + tii.cplusTerIdNifFk TERIDNIF, + tii.nif TERNIF, + tii.supplierName TERNOM, + tii.companyFk + FROM tInvoiceIn tii + WHERE tii.taxCode = 'ISP21' OR MID(tii.supplierAccount, 4, 1) = '1' + AND tii.taxTypeSageFk IS NOT NULL + GROUP BY tii.PorcentajeIva, tii.expenceFk; -- Actualización del registro original UPDATE invoiceIn ii - JOIN newInvoiceIn ni ON ii.id = ni.id - SET ii.serialNumber = vSerialNumber, - ii.isBooked = TRUE; + SET ii.isBooked = TRUE + WHERE ii.id = vSelf; -- Problemas derivados de la precisión en los decimales al calcular los impuestos UPDATE XDiario @@ -57569,8 +57621,12 @@ BEGIN ORDER BY id DESC LIMIT 1; + DROP TEMPORARY TABLE tInvoiceIn; END ;; DELIMITER ; + + + /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; diff --git a/db/export-data.sh b/db/export-data.sh index 2288c1c62..1df4db030 100755 --- a/db/export-data.sh +++ b/db/export-data.sh @@ -110,5 +110,6 @@ TABLES=( TiposIva TiposTransacciones TiposRetencion + taxType ) dump_tables ${TABLES[@]} diff --git a/modules/invoiceIn/back/methods/invoice-in/toBook.js b/modules/invoiceIn/back/methods/invoice-in/toBook.js index 588d53f1f..6fb1c9fea 100644 --- a/modules/invoiceIn/back/methods/invoice-in/toBook.js +++ b/modules/invoiceIn/back/methods/invoice-in/toBook.js @@ -32,7 +32,7 @@ module.exports = Self => { } try { - await Self.rawSql(`CALL vn.invoiceInBookingMain(?)`, [id], myOptions); + await Self.rawSql(`CALL vn.invoiceIn_booking(?)`, [id], myOptions); if (tx) await tx.commit(); } catch (e) { if (tx) await tx.rollback(); From bdffc0401fd98a4ff2b410f97c0509269a557151 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 8 Jun 2023 15:29:03 +0200 Subject: [PATCH 080/170] refs #5760 update getChanges, traduccion --- .eslintrc.yml | 4 ++-- .../ticket/back/methods/ticket-log/getChanges.js | 16 ++++++++-------- modules/ticket/front/descriptor/locale/es.yml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 13fc2b140..ee20324ff 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,6 +1,6 @@ extends: [eslint:recommended, google, plugin:jasmine/recommended] parserOptions: - ecmaVersion: 2018 + ecmaVersion: 2020 sourceType: "module" plugins: - jasmine @@ -35,4 +35,4 @@ rules: space-in-parens: ["error", "never"] jasmine/no-focused-tests: 0 jasmine/prefer-toHaveBeenCalledWith: 0 - arrow-spacing: ["error", { "before": true, "after": true }] \ No newline at end of file + arrow-spacing: ["error", { "before": true, "after": true }] diff --git a/modules/ticket/back/methods/ticket-log/getChanges.js b/modules/ticket/back/methods/ticket-log/getChanges.js index 7a6de49e8..1b74ec1d7 100644 --- a/modules/ticket/back/methods/ticket-log/getChanges.js +++ b/modules/ticket/back/methods/ticket-log/getChanges.js @@ -61,15 +61,15 @@ module.exports = Self => { const oldQuantity = log.oldInstance.quantity; const newQuantity = log.newInstance?.quantity || 0; - if (oldQuantity || newQuantity) { - const changeMessage = $t('Change quantity', { - concept: log.changedModelValue, - oldQuantity: oldQuantity || 0, - newQuantity: newQuantity || 0, - }); - changes.push(changeMessage); + if (oldQuantity > newQuantity) { + const changeMessage = $t('Change quantity', { + concept: log.changedModelValue, + oldQuantity: oldQuantity || 0, + newQuantity: newQuantity || 0, + }); + changes.push(changeMessage); } - } + } return changes.join('\n'); }; diff --git a/modules/ticket/front/descriptor/locale/es.yml b/modules/ticket/front/descriptor/locale/es.yml index d921b5dc2..3da013467 100644 --- a/modules/ticket/front/descriptor/locale/es.yml +++ b/modules/ticket/front/descriptor/locale/es.yml @@ -23,4 +23,4 @@ Restore ticket: Restaurar ticket You are going to restore this ticket: Vas a restaurar este ticket Are you sure you want to restore this ticket?: ¿Seguro que quieres restaurar el ticket? Are you sure you want to refund all?: ¿Seguro que quieres abonar todo? -Send changes: "Verdnatura le recuerda:\rPedido {{ticketId}} día {{created | date: 'dd/MM/yyyy'}}\r{{changes}}" +Send changes: "Verdnatura:\rPedido {{ticketId}}\r{{changes}}" From ec9dfa90fd0b8061f6812ff4b4f87fde7f7f7510 Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 9 Jun 2023 08:06:45 +0200 Subject: [PATCH 081/170] refs #5760 fixtures --- db/dump/fixtures.sql | 7 ++++--- .../back/methods/ticket-log/specs/getChanges.spec.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 3476bfe48..88b837247 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2781,12 +2781,14 @@ UPDATE `account`.`user` SET `hasGrant` = 1 WHERE `id` = 66; -INSERT INTO `vn`.`ticketLog` (`originFk`, userFk, `action`, changedModel, oldInstance, newInstance, changedModelId, `description`) +INSERT INTO `vn`.`ticketLog` (originFk, userFk, `action`, `changedModel`, `oldInstance`, `newInstance`, changedModelId, `description`) VALUES (7, 18, 'update', 'Sale', '{"quantity":1}', '{"quantity":10}', 1, NULL), (7, 18, 'update', 'Ticket', '{"quantity":1,"concept":"Chest ammo box"}', '{"quantity":10,"concept":"Chest ammo box"}', 1, NULL), (7, 18, 'update', 'Sale', '{"price":3}', '{"price":5}', 1, NULL), - (7, 18, 'update', NULL, NULL, NULL, NULL, "Cambio cantidad Melee weapon heavy shield 1x0.5m de '5' a '10'"); + (7, 18, 'update', NULL, NULL, NULL, NULL, "Cambio cantidad Melee weapon heavy shield 1x0.5m de '5' a '10'"), + (16, 9, 'update', 'Sale', '{"quantity":10,"concept":"Shield", "price": 10.5, "itemFk": 1}', '{"quantity":8,"concept":"Shield", "price": 10.5, "itemFk": 1}' , 5689, 'Shield'); + INSERT INTO `vn`.`ticketLog` (originFk, userFk, `action`, creationDate, changedModel, changedModelId, changedModelValue, oldInstance, newInstance, description) VALUES @@ -2800,7 +2802,6 @@ INSERT INTO `vn`.`ticketLog` (originFk, userFk, `action`, creationDate, changedM (1, 18, 'select', '2000-12-27 03:40:30', 'Ticket', 45, NULL , NULL, NULL, NULL), (1, 18, 'insert', '2000-04-10 09:40:15', 'Sale', 5689, 'Shield' , NULL, '{"quantity":10,"concept":"Shield", "price": 10.5, "itemFk": 1}', NULL), (1, 18, 'insert', '1999-05-09 10:00:00', 'Ticket', 45, 'Super Man' , NULL, '{"id":45,"clientFk":8608,"warehouseFk":60,"shipped":"2023-05-16T22:00:00.000Z","nickname":"Super Man","addressFk":48637,"isSigned":true,"isLabeled":true,"isPrinted":true,"packages":0,"hour":0,"created":"2023-05-16T11:42:56.000Z","isBlocked":false,"hasPriority":false,"companyFk":442,"agencyModeFk":639,"landed":"2023-05-17T22:00:00.000Z","isBoxed":true,"isDeleted":true,"zoneFk":713,"zonePrice":13,"zoneBonus":0}', NULL); - INSERT INTO `vn`.`osTicketConfig` (`id`, `host`, `user`, `password`, `oldStatus`, `newStatusId`, `day`, `comment`, `hostDb`, `userDb`, `passwordDb`, `portDb`, `responseType`, `fromEmailId`, `replyTo`) VALUES (0, 'http://localhost:56596/scp', 'ostadmin', 'Admin1', '1,6', 3, 60, 'Este CAU se ha cerrado automáticamente. Si el problema persiste responda a este mensaje.', 'localhost', 'osticket', 'osticket', 40003, 'reply', 1, 'all'); 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 c0f7dde0e..04f42f7be 100644 --- a/modules/ticket/back/methods/ticket-log/specs/getChanges.spec.js +++ b/modules/ticket/back/methods/ticket-log/specs/getChanges.spec.js @@ -7,7 +7,7 @@ describe('ticketLog getChanges()', () => { return value; }; it('should return the changes in the sales of a ticket', async() => { - const ticketId = 7; + const ticketId = 16; const changues = await models.TicketLog.getChanges(ctx, ticketId); From c66feb53f0aab7dcaf95fab743b39b8a31b74ae2 Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 9 Jun 2023 08:29:18 +0200 Subject: [PATCH 082/170] refs #5760 fix fixtures --- db/dump/fixtures.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 88b837247..4441ec19c 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2781,7 +2781,7 @@ UPDATE `account`.`user` SET `hasGrant` = 1 WHERE `id` = 66; -INSERT INTO `vn`.`ticketLog` (originFk, userFk, `action`, `changedModel`, `oldInstance`, `newInstance`, changedModelId, `description`) +INSERT INTO `vn`.`ticketLog` (`originFk`, userFk, `action`, changedModel, oldInstance, newInstance, changedModelId, `description`) VALUES (7, 18, 'update', 'Sale', '{"quantity":1}', '{"quantity":10}', 1, NULL), (7, 18, 'update', 'Ticket', '{"quantity":1,"concept":"Chest ammo box"}', '{"quantity":10,"concept":"Chest ammo box"}', 1, NULL), From f797cc17615faa129e1780f658144bcf594d6ebb Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 9 Jun 2023 08:31:05 +0200 Subject: [PATCH 083/170] refs #5489 refactor e2e --- e2e/paths/01-salix/05_changePassword.spec.js | 54 +++++++++----------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/e2e/paths/01-salix/05_changePassword.spec.js b/e2e/paths/01-salix/05_changePassword.spec.js index 318e26799..6e4cfb7f3 100644 --- a/e2e/paths/01-salix/05_changePassword.spec.js +++ b/e2e/paths/01-salix/05_changePassword.spec.js @@ -16,60 +16,56 @@ describe('ChangePassword path', async() => { await browser.close(); }); - const toExpects = []; - async function saveExpets(message, expectMessage, expectState) { - if (!message && expectMessage) message = await page.waitForSnackbar(); - if (expectState) - toExpects.push({value: await page.getState(), expected: expectState}); - if (expectMessage) - toExpects.push({value: message.text, expected: expectMessage}); - } - const oldPassword = 'nightmare'; const newPassword = 'newPass.1234'; describe('Bad login', async() => { it('should receive an error when the password is expired', async() => { // Expired login - await saveExpets(await page.doLogin( - 'Maintenance', - oldPassword - ), 'The password has expired, change it from Salix', 'change-password'); + await page.doLogin('Maintenance', oldPassword); + let message = await page.waitForSnackbar(); + + expect(message.text).toContain('The password has expired, change it from Salix'); + expect(await page.getState()).toContain('change-password'); // Bad attempt: incorrect current password - await saveExpets(await page.sendForm($.form, { + message = await page.sendForm($.form, { oldPassword: newPassword, newPassword: oldPassword, repeatPassword: oldPassword - }), 'Invalid current password'); + }); + + expect(message.text).toContain('Invalid current password'); // Bad attempt: password not meet requirements - await saveExpets(await page.sendForm($.form, { + message = await page.sendForm($.form, { oldPassword: oldPassword, newPassword: oldPassword, repeatPassword: oldPassword - }), 'Password does not meet requirements'); + }); + + expect(message.text).toContain('Password does not meet requirements'); // Correct attempt: change password - await saveExpets(await page.sendForm($.form, { + message = await page.sendForm($.form, { oldPassword: oldPassword, newPassword: newPassword, repeatPassword: newPassword - }), 'Password updated!', 'login'); + }); + + expect(message.text).toContain('Password updated!'); + expect(await page.getState()).toContain('login'); // Bad login, old password - await saveExpets(await page.doLogin( - 'Maintenance', - oldPassword - ), 'Invalid login'); + await page.doLogin('Maintenance', oldPassword); + message = await page.waitForSnackbar(); + + expect(message.text).toContain('Invalid login'); // Correct login, new password - await saveExpets(await page.doLogin( - 'Maintenance', - newPassword - ), null, 'login'); + await page.doLogin('Maintenance', newPassword); + await page.waitForSelector('vn-home'); - for (let toExpect of toExpects) - expect(toExpect.value).toContain(toExpect.expected); // eslint-disable-line + expect(await page.getState()).toBe('home'); }); }); }); From fdb9d2ed7f6e9dc01aa58d8c5a5af5817bbecf7a Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 9 Jun 2023 14:38:44 +0200 Subject: [PATCH 084/170] refs #5701 fix dockerFile and sh's --- db/Dockerfile | 20 +++++-------------- ...ocker-temp-start.sh => docker-fixtures.sh} | 3 +++ db/docker/docker-init.sh | 2 ++ db/docker/docker-structure.sh | 18 +++++++++++++++++ db/docker/docker-temp-stop.sh | 6 ------ 5 files changed, 28 insertions(+), 21 deletions(-) rename db/docker/{docker-temp-start.sh => docker-fixtures.sh} (62%) create mode 100755 db/docker/docker-structure.sh delete mode 100755 db/docker/docker-temp-stop.sh diff --git a/db/Dockerfile b/db/Dockerfile index 719b85393..15f947e08 100644 --- a/db/Dockerfile +++ b/db/Dockerfile @@ -7,11 +7,9 @@ ARG DEBIAN_FRONTEND=noninteractive COPY docker/docker.cnf /etc/mysql/conf.d/ COPY \ - docker/docker-init.sh \ - docker/docker-temp-start.sh \ - docker/docker-temp-stop.sh \ docker/docker-dump.sh \ - docker/docker-start.sh \ + docker/docker-structure.sh \ + docker/docker-fixtures.sh \ /usr/local/bin/ RUN mkdir /mysql-data \ @@ -26,20 +24,12 @@ COPY \ dump/mockDate.sql \ dump/dumpedFixtures.sql \ ./ -RUN gosu mysql docker-init.sh \ - && docker-dump.sh structure \ - && sed -i -e 's/@mockDate/'"$MOCKDATE"'/g' mockDate.sql \ - && docker-dump.sh mockDate \ - && docker-dump.sh dumpedFixtures \ - && gosu mysql docker-temp-stop.sh - +RUN sed -i -e 's/@mockDate/'"$MOCKDATE"'/g' mockDate.sql \ + && gosu mysql docker-structure.sh COPY changes ./changes COPY dump/fixtures.sql ./ ARG STAMP=unknown -RUN gosu mysql docker-temp-start.sh \ - && ./import-changes.sh \ - && docker-dump.sh fixtures \ - && gosu mysql docker-temp-stop.sh +RUN gosu mysql docker-fixtures.sh RUN echo "[INFO] -> Import finished" \ && rm -rf /docker-boot diff --git a/db/docker/docker-temp-start.sh b/db/docker/docker-fixtures.sh similarity index 62% rename from db/docker/docker-temp-start.sh rename to db/docker/docker-fixtures.sh index fc067102f..0de6114d9 100755 --- a/db/docker/docker-temp-start.sh +++ b/db/docker/docker-fixtures.sh @@ -5,3 +5,6 @@ CMD=mysqld docker_setup_env "$CMD" docker_temp_server_start "$CMD" +bash import-changes.sh +docker-dump.sh fixtures +docker_temp_server_stop diff --git a/db/docker/docker-init.sh b/db/docker/docker-init.sh index ccd14283e..b58510436 100755 --- a/db/docker/docker-init.sh +++ b/db/docker/docker-init.sh @@ -12,3 +12,5 @@ docker_init_database_dir "$CMD" docker_temp_server_start "$CMD" docker_setup_db docker_process_init_files /docker-entrypoint-initdb.d/* +echo $MARIADB_PID +export MARIADB_PID diff --git a/db/docker/docker-structure.sh b/db/docker/docker-structure.sh new file mode 100755 index 000000000..b119e38fd --- /dev/null +++ b/db/docker/docker-structure.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +. /usr/local/bin/docker-entrypoint.sh +CMD=mysqld + +mysql_check_config "$CMD" +docker_setup_env "$CMD" +docker_create_db_directories + +docker_verify_minimum_env +docker_init_database_dir "$CMD" +docker_temp_server_start "$CMD" +docker_setup_db +docker_process_init_files /docker-entrypoint-initdb.d/* +docker-dump.sh structure +docker-dump.sh mockDate +docker-dump.sh dumpedFixtures +docker_temp_server_stop diff --git a/db/docker/docker-temp-stop.sh b/db/docker/docker-temp-stop.sh deleted file mode 100755 index 418331f75..000000000 --- a/db/docker/docker-temp-stop.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -. /usr/local/bin/docker-entrypoint.sh -CMD=mysqld - -docker_setup_env "$CMD" From 0fb114b06dcf5a10486990d51de6a128d2f32f40 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 9 Jun 2023 21:45:36 +0200 Subject: [PATCH 085/170] refs #5667 Search & entity filters moved to top --- front/salix/components/log/index.html | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index f68919f00..8b33c811b 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -110,6 +110,25 @@ + + + + + + + + - - - - - - - - From decc5e471f00c584cfbcf86adf92b376dcc8b572 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 9 Jun 2023 21:57:47 +0200 Subject: [PATCH 086/170] refs #5667 Changes added to changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f2c0e6e5..d4717b711 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - (Tickets -> Abono) Al abonar permite crear el ticket abono con almacén o sin almmacén - (General -> Desplegables) Mejorada eficiencia de carga de datos +- (General -> Históricos) Ahora, ademas de los ids, se muestra la descripión de los atributos +- (General -> Históricos) Botón para hacer más ágil mostrar sólo los cambios en un registro +- (General -> Históricos) Filtro por cambios ### Changed - (General -> Permisos) Mejorada seguridad +- (General -> Históricos) Elementos de la interfaz reorganizados para hacerla más ágil e intuitiva ### Fixed - From 33f2d556fd92606eb9c105c9448c5d2ae125e1b0 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 12 Jun 2023 07:33:45 +0200 Subject: [PATCH 087/170] refs #5701 fix(db/dockerFile): fix docker-temp-stop --- db/Dockerfile | 3 +++ db/docker/docker-init.sh | 2 -- db/docker/docker-structure.sh | 15 ++------------- db/docker/docker-temp-stop.sh | 7 +++++++ 4 files changed, 12 insertions(+), 15 deletions(-) create mode 100644 db/docker/docker-temp-stop.sh diff --git a/db/Dockerfile b/db/Dockerfile index 15f947e08..448b8b03a 100644 --- a/db/Dockerfile +++ b/db/Dockerfile @@ -7,6 +7,9 @@ ARG DEBIAN_FRONTEND=noninteractive COPY docker/docker.cnf /etc/mysql/conf.d/ COPY \ + docker/docker-start.sh \ + docker/docker-init.sh \ + docker/docker-temp-stop.sh \ docker/docker-dump.sh \ docker/docker-structure.sh \ docker/docker-fixtures.sh \ diff --git a/db/docker/docker-init.sh b/db/docker/docker-init.sh index b58510436..ccd14283e 100755 --- a/db/docker/docker-init.sh +++ b/db/docker/docker-init.sh @@ -12,5 +12,3 @@ docker_init_database_dir "$CMD" docker_temp_server_start "$CMD" docker_setup_db docker_process_init_files /docker-entrypoint-initdb.d/* -echo $MARIADB_PID -export MARIADB_PID diff --git a/db/docker/docker-structure.sh b/db/docker/docker-structure.sh index b119e38fd..75a1c24f3 100755 --- a/db/docker/docker-structure.sh +++ b/db/docker/docker-structure.sh @@ -1,18 +1,7 @@ #!/bin/bash -. /usr/local/bin/docker-entrypoint.sh -CMD=mysqld - -mysql_check_config "$CMD" -docker_setup_env "$CMD" -docker_create_db_directories - -docker_verify_minimum_env -docker_init_database_dir "$CMD" -docker_temp_server_start "$CMD" -docker_setup_db -docker_process_init_files /docker-entrypoint-initdb.d/* +. docker-init.sh docker-dump.sh structure docker-dump.sh mockDate docker-dump.sh dumpedFixtures -docker_temp_server_stop +. docker-temp-stop.sh diff --git a/db/docker/docker-temp-stop.sh b/db/docker/docker-temp-stop.sh new file mode 100644 index 000000000..df66959df --- /dev/null +++ b/db/docker/docker-temp-stop.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +. /usr/local/bin/docker-entrypoint.sh +CMD=mysqld + +docker_setup_env "$CMD" +docker_temp_server_stop From 1a58424531e919e291f15d6296807205ac2c2c45 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 12 Jun 2023 08:33:31 +0200 Subject: [PATCH 088/170] refs #5327 warnFix(ticket_sale): fix orderBy amount itemPackingType --- modules/ticket/front/sale/index.html | 4 ++-- modules/ticket/front/sale/index.js | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index f50ef10a5..e0f4e4ed5 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -69,7 +69,7 @@ Price Disc Amount - Packaging + Packaging @@ -202,7 +202,7 @@ - {{$ctrl.getSaleTotal(sale) | currency: 'EUR':2}} + {{::sale.amount | currency: 'EUR':2}} {{::sale.item.itemPackingTypeFk | dashIfEmpty}} diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index 88a59e605..b68db6dc0 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -34,6 +34,11 @@ class Controller extends Section { } get sales() { + if (this._sales) { + for (let sale of this._sales) + sale.amount = this.getSaleTotal(sale); + } + return this._sales; } @@ -49,6 +54,7 @@ class Controller extends Section { return ticketState && ticketState.state.code; } + getConfig() { let filter = { fields: ['daysForWarningClaim'], From 2c0c0f24b0083f9c898680da9843ab4b9be690d7 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 12 Jun 2023 08:36:19 +0200 Subject: [PATCH 089/170] reactive --- modules/ticket/front/sale/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index e0f4e4ed5..be9e81964 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -202,7 +202,7 @@ - {{::sale.amount | currency: 'EUR':2}} + {{sale.amount | currency: 'EUR':2}} {{::sale.item.itemPackingTypeFk | dashIfEmpty}} From 703c224e91e2e5d0ab668fc68224be3363723f6a Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 12 Jun 2023 10:26:50 +0200 Subject: [PATCH 090/170] refs #5513 modified-entry email --- db/dump/fixtures.sql | 3 ++- modules/entry/back/methods/entry/addFromBuy.js | 2 +- .../back/methods/supplier/getItemsPackaging.js | 4 ++-- .../email/modified-entry/assets/css/import.js | 11 +++++++++++ .../templates/email/modified-entry/locale/en.yml | 3 +++ .../templates/email/modified-entry/locale/es.yml | 3 +++ .../email/modified-entry/modified-entry.html | 11 +++++++++++ .../email/modified-entry/modified-entry.js | 16 ++++++++++++++++ 8 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 print/templates/email/modified-entry/assets/css/import.js create mode 100644 print/templates/email/modified-entry/locale/en.yml create mode 100644 print/templates/email/modified-entry/locale/es.yml create mode 100644 print/templates/email/modified-entry/modified-entry.html create mode 100755 print/templates/email/modified-entry/modified-entry.js diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 4441ec19c..5e3efd1de 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2732,7 +2732,8 @@ INSERT INTO `util`.`notification` (`id`, `name`, `description`) (1, 'print-email', 'notification fixture one'), (2, 'invoice-electronic', 'A electronic invoice has been generated'), (3, 'not-main-printer-configured', 'A printer distinct than main has been configured'), - (4, 'supplier-pay-method-update', 'A supplier pay method has been updated'); + (4, 'supplier-pay-method-update', 'A supplier pay method has been updated'), + (5, 'modified-entry', 'An entry has been modified'); INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`) VALUES diff --git a/modules/entry/back/methods/entry/addFromBuy.js b/modules/entry/back/methods/entry/addFromBuy.js index f7e1b637e..bfbd1b416 100644 --- a/modules/entry/back/methods/entry/addFromBuy.js +++ b/modules/entry/back/methods/entry/addFromBuy.js @@ -46,7 +46,7 @@ module.exports = Self => { } try { - let buy = await models.Buy.findOne({where: {entryFk: args.id}}, myOptions); + let buy = await models.Buy.findOne({where: {entryFk: args.id, itemFk: args.item}}, myOptions); if (buy) await buy.updateAttribute('printedStickers', args.printedStickers, myOptions); else { diff --git a/modules/supplier/back/methods/supplier/getItemsPackaging.js b/modules/supplier/back/methods/supplier/getItemsPackaging.js index 8ef80529b..c06195a55 100644 --- a/modules/supplier/back/methods/supplier/getItemsPackaging.js +++ b/modules/supplier/back/methods/supplier/getItemsPackaging.js @@ -26,14 +26,14 @@ module.exports = Self => { Self.getItemsPackaging = async(id, entry) => { return Self.rawSql(` WITH entryTmp AS ( - SELECT i.id, SUM(b.quantity) quantity + SELECT i.id, SUM(b.quantity) quantity, SUM(b.printedStickers) printedStickers FROM vn.entry e JOIN vn.buy b ON b.entryFk = e.id JOIN vn.supplier s ON s.id = e.supplierFk JOIN vn.item i ON i.id = b.itemFk WHERE e.id = ? AND e.supplierFk = ? GROUP BY i.id - ) SELECT i.id, i.name, et.quantity, SUM(b.quantity) quantityTotal + ) SELECT i.id, i.name, et.quantity, SUM(b.quantity) quantityTotal, et.printedStickers FROM vn.buy b JOIN vn.item i ON i.id = b.itemFk JOIN vn.entry e ON e.id = b.entryFk diff --git a/print/templates/email/modified-entry/assets/css/import.js b/print/templates/email/modified-entry/assets/css/import.js new file mode 100644 index 000000000..4b4bb7086 --- /dev/null +++ b/print/templates/email/modified-entry/assets/css/import.js @@ -0,0 +1,11 @@ +const Stylesheet = require(`vn-print/core/stylesheet`); + +const path = require('path'); +const vnPrintPath = path.resolve('print'); + +module.exports = new Stylesheet([ + `${vnPrintPath}/common/css/spacing.css`, + `${vnPrintPath}/common/css/misc.css`, + `${vnPrintPath}/common/css/layout.css`, + `${vnPrintPath}/common/css/email.css`]) + .mergeStyles(); diff --git a/print/templates/email/modified-entry/locale/en.yml b/print/templates/email/modified-entry/locale/en.yml new file mode 100644 index 000000000..c70cfe5cc --- /dev/null +++ b/print/templates/email/modified-entry/locale/en.yml @@ -0,0 +1,3 @@ +subject: Modified entry +title: Modified entry +description: 'From Warehouse the following packaging entry has been created/modified: ' diff --git a/print/templates/email/modified-entry/locale/es.yml b/print/templates/email/modified-entry/locale/es.yml new file mode 100644 index 000000000..72ddb5ca5 --- /dev/null +++ b/print/templates/email/modified-entry/locale/es.yml @@ -0,0 +1,3 @@ +subject: Entrada modificada +title: Entrada modificada +description: 'Desde Almacén se ha creado/modificado la siguiente entrada de embalajes: ' diff --git a/print/templates/email/modified-entry/modified-entry.html b/print/templates/email/modified-entry/modified-entry.html new file mode 100644 index 000000000..a0f297354 --- /dev/null +++ b/print/templates/email/modified-entry/modified-entry.html @@ -0,0 +1,11 @@ + + + diff --git a/print/templates/email/modified-entry/modified-entry.js b/print/templates/email/modified-entry/modified-entry.js new file mode 100755 index 000000000..35474a12f --- /dev/null +++ b/print/templates/email/modified-entry/modified-entry.js @@ -0,0 +1,16 @@ +const Component = require(`vn-print/core/component`); +const emailBody = new Component('email-body'); + +module.exports = { + name: 'modified-entry', + components: { + 'email-body': emailBody.build(), + }, + props: { + url: { + type: String, + required: true + } + } +}; + From 5c1b867d0537b521125fcf3823a6e9f4b543e27d Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 12 Jun 2023 10:46:21 +0200 Subject: [PATCH 091/170] WIP: d735f142a Merge branch 'dev' into 5472-user_passExpired --- back/methods/collection/newCollection.js | 12 +- back/methods/edi/updateData.js | 350 +++++++++--------- back/models/vn-user.js | 1 + loopback/common/models/vn-model.js | 44 ++- .../back/methods/account/change-password.js | 2 +- .../importToNewRefundTicket.js | 2 +- .../back/methods/client/confirmTransaction.js | 2 +- .../methods/client/consumptionSendQueued.js | 6 +- .../back/methods/client/createReceipt.js | 2 +- modules/client/back/methods/client/filter.js | 4 +- modules/client/back/methods/client/getCard.js | 6 +- modules/client/back/methods/client/getDebt.js | 6 +- .../back/methods/client/specs/getCard.spec.js | 3 +- .../back/methods/client/specs/getDebt.spec.js | 3 +- .../back/methods/client/specs/summary.spec.js | 15 +- modules/client/back/methods/client/summary.js | 6 +- .../back/methods/tpv-transaction/confirm.js | 6 +- .../back/methods/tpv-transaction/end.js | 2 +- .../back/methods/tpv-transaction/start.js | 2 +- .../entry/back/methods/entry/importBuys.js | 4 +- .../back/methods/invoice-in/toBook.js | 2 +- .../back/methods/invoiceOut/book.js | 6 +- .../methods/invoiceOut/clientsToInvoice.js | 2 +- .../methods/invoiceOut/createManualInvoice.js | 2 +- .../back/methods/invoiceOut/invoiceClient.js | 2 +- .../back/methods/invoiceOut/refund.js | 6 +- .../methods/invoiceOut/specs/book.spec.js | 3 +- .../methods/invoiceOut/specs/refund.spec.js | 3 +- modules/item/back/methods/item/getBalance.js | 6 +- modules/item/back/methods/item/new.js | 6 +- .../methods/item/specs/getBalance.spec.js | 7 +- .../item/back/methods/item/specs/new.spec.js | 3 +- .../back/methods/order-row/addToOrder.js | 6 +- .../order-row/specs/addToOrder.spec.js | 3 +- modules/order/back/methods/order/confirm.js | 2 +- modules/order/back/methods/order/new.js | 6 +- .../order/back/methods/order/newFromTicket.js | 6 +- .../back/methods/order/specs/new.spec.js | 5 +- .../methods/order/specs/newFromTicket.spec.js | 3 +- .../methods/agency-term/createInvoiceIn.js | 6 +- .../agency-term/specs/createInvoiceIn.spec.js | 3 +- .../route/back/methods/route/guessPriority.js | 2 +- .../route/back/methods/route/updateVolume.js | 2 +- .../back/methods/sale/recalculatePrice.js | 2 +- modules/ticket/back/methods/sale/refund.js | 6 +- .../back/methods/sale/specs/refund.spec.js | 7 +- .../back/methods/sale/specs/reserve.spec.js | 4 +- .../ticket/back/methods/sale/updatePrice.js | 2 +- modules/ticket/back/methods/sale/usesMana.js | 2 +- .../back/methods/ticket-request/confirm.js | 2 +- modules/ticket/back/methods/ticket/addSale.js | 2 +- .../ticket/back/methods/ticket/closeAll.js | 8 +- modules/ticket/back/methods/ticket/closure.js | 29 +- .../back/methods/ticket/componentUpdate.js | 2 +- .../ticket/back/methods/ticket/getSales.js | 6 +- .../ticket/back/methods/ticket/makeInvoice.js | 2 +- modules/ticket/back/methods/ticket/new.js | 6 +- .../back/methods/ticket/priceDifference.js | 2 +- .../methods/ticket/recalculateComponents.js | 2 +- modules/ticket/back/methods/ticket/refund.js | 6 +- .../ticket/back/methods/ticket/saveSign.js | 2 +- .../ticket/back/methods/ticket/setDeleted.js | 2 +- .../methods/ticket/specs/getSales.spec.js | 3 +- .../back/methods/ticket/specs/summary.spec.js | 9 +- .../ticket/specs/transferSales.spec.js | 16 +- modules/ticket/back/methods/ticket/summary.js | 6 +- .../back/methods/ticket/transferSales.js | 2 +- .../back/methods/ticket/updateDiscount.js | 2 +- .../methods/thermograph/createThermograph.js | 6 +- .../specs/createThermograph.spec.js | 7 +- .../back/methods/travel/deleteThermograph.js | 6 +- .../back/methods/department/getLeaves.js | 7 +- .../worker-time-control/addTimeEntry.js | 6 +- .../worker-time-control/deleteTimeEntry.js | 6 +- .../methods/worker-time-control/sendMail.js | 2 +- modules/worker/back/methods/worker/new.js | 2 +- .../back/methods/worker/specs/new.spec.js | 18 +- .../agency/getAgenciesWithWarehouse.js | 6 +- .../zone/back/methods/agency/landsThatDay.js | 6 +- .../specs/getAgenciesWithWarehouse.spec.js | 5 +- .../methods/agency/specs/landsThatDay.spec.js | 3 +- modules/zone/back/methods/zone/deleteZone.js | 2 +- modules/zone/back/methods/zone/getEvents.js | 6 +- modules/zone/back/methods/zone/getLeaves.js | 6 +- .../methods/zone/getUpcomingDeliveries.js | 6 +- .../back/methods/zone/specs/getEvents.spec.js | 3 +- .../back/methods/zone/specs/getLeaves.spec.js | 3 +- .../zone/specs/getUpcomingDeliveries.spec.js | 3 +- 88 files changed, 440 insertions(+), 371 deletions(-) diff --git a/back/methods/collection/newCollection.js b/back/methods/collection/newCollection.js index 31e419b67..2be9f8b0e 100644 --- a/back/methods/collection/newCollection.js +++ b/back/methods/collection/newCollection.js @@ -30,11 +30,11 @@ module.exports = Self => { Self.newCollection = async(ctx, collectionFk, sectorFk, vWagons) => { let query = ''; + const userId = ctx.req.accessToken.userId; if (!collectionFk) { - const userId = ctx.req.accessToken.userId; query = `CALL vn.collectionTrain_newBeta(?,?,?)`; - const [result] = await Self.rawSql(query, [sectorFk, vWagons, userId]); + const [result] = await Self.rawSql(query, [sectorFk, vWagons, userId], {userId}); if (result.length == 0) throw new Error(`No collections for today`); @@ -42,16 +42,16 @@ module.exports = Self => { } query = `CALL vn.collectionTicket_get(?)`; - const [tickets] = await Self.rawSql(query, [collectionFk]); + const [tickets] = await Self.rawSql(query, [collectionFk], {userId}); query = `CALL vn.collectionSale_get(?)`; - const [sales] = await Self.rawSql(query, [collectionFk]); + const [sales] = await Self.rawSql(query, [collectionFk], {userId}); query = `CALL vn.collectionPlacement_get(?)`; - const [placements] = await Self.rawSql(query, [collectionFk]); + const [placements] = await Self.rawSql(query, [collectionFk], {userId}); query = `CALL vn.collectionSticker_print(?,?)`; - await Self.rawSql(query, [collectionFk, sectorFk]); + await Self.rawSql(query, [collectionFk, sectorFk], {userId}); return makeCollection(tickets, sales, placements, collectionFk); }; diff --git a/back/methods/edi/updateData.js b/back/methods/edi/updateData.js index 1057be39b..10c81a795 100644 --- a/back/methods/edi/updateData.js +++ b/back/methods/edi/updateData.js @@ -3,237 +3,237 @@ const path = require('path'); const fs = require('fs-extra'); module.exports = Self => { - Self.remoteMethodCtx('updateData', { - description: 'Updates schema data from external provider', - accessType: 'WRITE', - returns: { - type: 'object', - root: true - }, - http: { - path: `/updateData`, - verb: 'POST' - } - }); + Self.remoteMethodCtx('updateData', { + description: 'Updates schema data from external provider', + accessType: 'WRITE', + returns: { + type: 'object', + root: true + }, + http: { + path: `/updateData`, + verb: 'POST' + } + }); - Self.updateData = async() => { - const models = Self.app.models; + Self.updateData = async ctx => { + const models = Self.app.models; - // Get files checksum - const tx = await Self.beginTransaction({}); + // Get files checksum + const tx = await Self.beginTransaction({}); - try { - const options = {transaction: tx}; - const files = await Self.rawSql('SELECT name, checksum, keyValue FROM edi.fileConfig', null, options); + try { + const options = {transaction: tx, userId: ctx.req.accessToken.userId}; + const files = await Self.rawSql('SELECT name, checksum, keyValue FROM edi.fileConfig', null, options); - const updatableFiles = []; - for (const file of files) { - const fileChecksum = await getChecksum(file); + const updatableFiles = []; + for (const file of files) { + const fileChecksum = await getChecksum(file); - if (file.checksum != fileChecksum) { - updatableFiles.push({ - name: file.name, - checksum: fileChecksum - }); - } else - console.debug(`File already updated, skipping...`); - } + if (file.checksum != fileChecksum) { + updatableFiles.push({ + name: file.name, + checksum: fileChecksum + }); + } else + console.debug(`File already updated, skipping...`); + } - if (updatableFiles.length === 0) - return false; + if (updatableFiles.length === 0) + return false; - // Download files - const container = await models.TempContainer.container('edi'); - const tempPath = path.join(container.client.root, container.name); + // Download files + const container = await models.TempContainer.container('edi'); + const tempPath = path.join(container.client.root, container.name); - let remoteFile; - let tempDir; - let tempFile; + let remoteFile; + let tempDir; + let tempFile; - const fileNames = updatableFiles.map(file => file.name); + const fileNames = updatableFiles.map(file => file.name); - const tables = await Self.rawSql(` + const tables = await Self.rawSql(` SELECT fileName, toTable, file FROM edi.tableConfig WHERE file IN (?)`, [fileNames], options); - for (const table of tables) { - const fileName = table.file; + for (const table of tables) { + const fileName = table.file; - remoteFile = `codes/${fileName}.ZIP`; - tempDir = `${tempPath}/${fileName}`; - tempFile = `${tempPath}/${fileName}.zip`; + remoteFile = `codes/${fileName}.ZIP`; + tempDir = `${tempPath}/${fileName}`; + tempFile = `${tempPath}/${fileName}.zip`; - try { - await fs.readFile(tempFile); - } catch (error) { - if (error.code === 'ENOENT') { - console.debug(`Downloading file ${fileName}...`); - const downloadOutput = await downloadFile(remoteFile, tempFile); - if (downloadOutput.error) - continue; - } - } + try { + await fs.readFile(tempFile); + } catch (error) { + if (error.code === 'ENOENT') { + console.debug(`Downloading file ${fileName}...`); + const downloadOutput = await downloadFile(remoteFile, tempFile); + if (downloadOutput.error) + continue; + } + } - await extractFile(fileName, tempFile, tempDir); + await extractFile(fileName, tempFile, tempDir); - console.debug(`Updating table ${table.toTable}...`); - await dumpData(tempDir, table, options); - } + console.debug(`Updating table ${table.toTable}...`); + await dumpData(tempDir, table, options); + } - // Update files checksum - for (const file of updatableFiles) { - console.log(`Updating file ${file.name} checksum...`); - await Self.rawSql(` + // Update files checksum + for (const file of updatableFiles) { + console.log(`Updating file ${file.name} checksum...`); + await Self.rawSql(` UPDATE edi.fileConfig SET checksum = ? WHERE name = ?`, - [file.checksum, file.name], options); - } + [file.checksum, file.name], options); + } - await tx.commit(); + await tx.commit(); - // Clean files - try { - console.debug(`Cleaning files...`); - await fs.remove(tempPath); - } catch (error) { - if (error.code !== 'ENOENT') - throw e; - } + // Clean files + try { + console.debug(`Cleaning files...`); + await fs.remove(tempPath); + } catch (error) { + if (error.code !== 'ENOENT') + throw e; + } - return true; - } catch (error) { - await tx.rollback(); - throw error; - } - }; + return true; + } catch (error) { + await tx.rollback(); + throw error; + } + }; - let ftpClient; - async function getFtpClient() { - if (!ftpClient) { - const [ftpConfig] = await Self.rawSql('SELECT host, user, password FROM edi.ftpConfig'); - console.debug(`Openning FTP connection to ${ftpConfig.host}...\n`); + let ftpClient; + async function getFtpClient() { + if (!ftpClient) { + const [ftpConfig] = await Self.rawSql('SELECT host, user, password FROM edi.ftpConfig'); + console.debug(`Openning FTP connection to ${ftpConfig.host}...\n`); - const FtpClient = require('ftps'); + const FtpClient = require('ftps'); - ftpClient = new FtpClient({ - host: ftpConfig.host, - username: ftpConfig.user, - password: ftpConfig.password, - procotol: 'ftp', - additionalLftpCommands: 'set ssl:verify-certificate no' - }); - } + ftpClient = new FtpClient({ + host: ftpConfig.host, + username: ftpConfig.user, + password: ftpConfig.password, + procotol: 'ftp', + additionalLftpCommands: 'set ssl:verify-certificate no' + }); + } - return ftpClient; - } + return ftpClient; + } - async function getChecksum(file) { - const ftpClient = await getFtpClient(); - console.debug(`Checking checksum for file ${file.name}...`); + async function getChecksum(file) { + const ftpClient = await getFtpClient(); + console.debug(`Checking checksum for file ${file.name}...`); - ftpClient.cat(`codes/${file.name}.TXT`); + ftpClient.cat(`codes/${file.name}.TXT`); - const response = await new Promise((resolve, reject) => { - ftpClient.exec((err, response) => { - if (err || response.error) { - console.debug(`Error downloading checksum file... ${response.error}`); - return reject(err); - } + const response = await new Promise((resolve, reject) => { + ftpClient.exec((err, response) => { + if (err || response.error) { + console.debug(`Error downloading checksum file... ${response.error}`); + return reject(err); + } - resolve(response); - }); - }); + resolve(response); + }); + }); - if (response && response.data) { - const fileContents = response.data; - const rows = fileContents.split('\n'); - const row = rows[4]; - const columns = row.split(/\s+/); + if (response && response.data) { + const fileContents = response.data; + const rows = fileContents.split('\n'); + const row = rows[4]; + const columns = row.split(/\s+/); - let fileChecksum; - if (file.keyValue) - fileChecksum = columns[1]; + let fileChecksum; + if (file.keyValue) + fileChecksum = columns[1]; - if (!file.keyValue) - fileChecksum = columns[0]; + if (!file.keyValue) + fileChecksum = columns[0]; - return fileChecksum; - } - } + return fileChecksum; + } + } - async function downloadFile(remoteFile, tempFile) { - const ftpClient = await getFtpClient(); + async function downloadFile(remoteFile, tempFile) { + const ftpClient = await getFtpClient(); - ftpClient.get(remoteFile, tempFile); + ftpClient.get(remoteFile, tempFile); - return new Promise((resolve, reject) => { - ftpClient.exec((err, response) => { - if (err || response.error) { - console.debug(`Error downloading file... ${response.error}`); - return reject(err); - } + return new Promise((resolve, reject) => { + ftpClient.exec((err, response) => { + if (err || response.error) { + console.debug(`Error downloading file... ${response.error}`); + return reject(err); + } - resolve(response); - }); - }); - } + resolve(response); + }); + }); + } - async function extractFile(fileName, tempFile, tempDir) { - const JSZip = require('jszip'); + async function extractFile(fileName, tempFile, tempDir) { + const JSZip = require('jszip'); - try { - await fs.mkdir(tempDir); - console.debug(`Extracting file ${fileName}...`); - } catch (error) { - if (error.code !== 'EEXIST') - throw e; - } + try { + await fs.mkdir(tempDir); + console.debug(`Extracting file ${fileName}...`); + } catch (error) { + if (error.code !== 'EEXIST') + throw e; + } - const fileStream = await fs.readFile(tempFile); - if (fileStream) { - const zip = new JSZip(); - const zipContents = await zip.loadAsync(fileStream); + const fileStream = await fs.readFile(tempFile); + if (fileStream) { + const zip = new JSZip(); + const zipContents = await zip.loadAsync(fileStream); - if (!zipContents) return; + if (!zipContents) return; - const fileNames = Object.keys(zipContents.files); + const fileNames = Object.keys(zipContents.files); - for (const fileName of fileNames) { - const fileContent = await zip.file(fileName).async('nodebuffer'); - const dest = path.join(tempDir, fileName); - await fs.writeFile(dest, fileContent); - } - } - } + for (const fileName of fileNames) { + const fileContent = await zip.file(fileName).async('nodebuffer'); + const dest = path.join(tempDir, fileName); + await fs.writeFile(dest, fileContent); + } + } + } - async function dumpData(tempDir, table, options) { - const toTable = table.toTable; - const baseName = table.fileName; + async function dumpData(tempDir, table, options) { + const toTable = table.toTable; + const baseName = table.fileName; - console.log(`Emptying table ${toTable}...`); - const tableName = `edi.${toTable}`; - await Self.rawSql(`DELETE FROM ??`, [tableName]); + console.log(`Emptying table ${toTable}...`); + const tableName = `edi.${toTable}`; + await Self.rawSql(`DELETE FROM ??`, [tableName]); - const dirFiles = await fs.readdir(tempDir); - const files = dirFiles.filter(file => file.startsWith(baseName)); + const dirFiles = await fs.readdir(tempDir); + const files = dirFiles.filter(file => file.startsWith(baseName)); - for (const file of files) { - console.log(`Dumping data from file ${file}...`); + for (const file of files) { + console.log(`Dumping data from file ${file}...`); - const templatePath = path.join(__dirname, `./sql/${toTable}.sql`); - const sqlTemplate = await fs.readFile(templatePath, 'utf8'); - const filePath = path.join(tempDir, file); + const templatePath = path.join(__dirname, `./sql/${toTable}.sql`); + const sqlTemplate = await fs.readFile(templatePath, 'utf8'); + const filePath = path.join(tempDir, file); - await Self.rawSql(sqlTemplate, [filePath], options); - await Self.rawSql(` + await Self.rawSql(sqlTemplate, [filePath], options); + await Self.rawSql(` UPDATE edi.tableConfig SET updated = ? WHERE fileName = ? `, [Date.vnNew(), baseName], options); - } + } - console.log(`Updated table ${toTable}\n`); - } + console.log(`Updated table ${toTable}\n`); + } }; diff --git a/back/models/vn-user.js b/back/models/vn-user.js index fb3279353..bf568e85c 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -110,6 +110,7 @@ module.exports = function(Self) { const _setPassword = Self.prototype.setPassword; Self.prototype.setPassword = async function(newPassword, options, cb) { + console.log('ENTRY'); if (cb === undefined && typeof options === 'function') { cb = options; options = undefined; diff --git a/loopback/common/models/vn-model.js b/loopback/common/models/vn-model.js index d63d1be38..f92e1ea09 100644 --- a/loopback/common/models/vn-model.js +++ b/loopback/common/models/vn-model.js @@ -195,8 +195,48 @@ module.exports = function(Self) { /* * Shortcut to VnMySQL.executeP() */ - rawSql(query, params, options, cb) { - return this.dataSource.connector.executeP(query, params, options, cb); + async rawSql(query, params, options) { + const userId = options?.userId; + const connector = this.dataSource.connector; + let conn; + let res; + const opts = Object.assign({}, options); + + try { + if (userId) { + conn = await new Promise((resolve, reject) => { + connector.client.getConnection(function(err, conn) { + if (err) + reject(err); + else + resolve(conn); + }); + }); + + const opts = Object.assign({}, options); + if (!opts.transaction) { + opts.transaction = { + connection: conn, + connector + }; + } + + await connector.executeP( + 'CALL account.myUser_loginWithName((SELECT name FROM account.user WHERE id = ?))', + [userId], opts + ); + } + + res = await connector.executeP(query, params, opts); + + if (userId) { + await connector.executeP('CALL account.myUser_logout()', null, opts); + } + } finally { + if (conn) conn.release(); + } + + return res; }, /* diff --git a/modules/account/back/methods/account/change-password.js b/modules/account/back/methods/account/change-password.js index c6f08a232..c5372d977 100644 --- a/modules/account/back/methods/account/change-password.js +++ b/modules/account/back/methods/account/change-password.js @@ -1,6 +1,6 @@ module.exports = Self => { - Self.remoteMethod('changePassword', { + Self.remoteMethodCtx('changePassword', { description: 'Changes the user password', accessType: 'WRITE', accepts: [ diff --git a/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js b/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js index 83043f012..cdf3fc2c3 100644 --- a/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js +++ b/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js @@ -63,7 +63,7 @@ module.exports = Self => { }; let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/client/back/methods/client/confirmTransaction.js b/modules/client/back/methods/client/confirmTransaction.js index a1969d6fd..fcb33c4ca 100644 --- a/modules/client/back/methods/client/confirmTransaction.js +++ b/modules/client/back/methods/client/confirmTransaction.js @@ -23,7 +23,7 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/client/back/methods/client/consumptionSendQueued.js b/modules/client/back/methods/client/consumptionSendQueued.js index 07b5fb57b..a7081c550 100644 --- a/modules/client/back/methods/client/consumptionSendQueued.js +++ b/modules/client/back/methods/client/consumptionSendQueued.js @@ -1,7 +1,7 @@ const {Email} = require('vn-print'); module.exports = Self => { - Self.remoteMethod('consumptionSendQueued', { + Self.remoteMethodCtx('consumptionSendQueued', { description: 'Send all queued invoices', accessType: 'WRITE', accepts: [], @@ -15,7 +15,7 @@ module.exports = Self => { } }); - Self.consumptionSendQueued = async() => { + Self.consumptionSendQueued = async ctx => { const queues = await Self.rawSql(` SELECT id, @@ -68,7 +68,7 @@ module.exports = Self => { SET status = 'printed', printed = ? WHERE id = ?`, - [Date.vnNew(), queue.id]); + [Date.vnNew(), queue.id], {userId: ctx.req.accessToken.userId}); } catch (error) { await Self.rawSql(` UPDATE clientConsumptionQueue diff --git a/modules/client/back/methods/client/createReceipt.js b/modules/client/back/methods/client/createReceipt.js index cb032270a..b70b9bbe0 100644 --- a/modules/client/back/methods/client/createReceipt.js +++ b/modules/client/back/methods/client/createReceipt.js @@ -55,7 +55,7 @@ module.exports = function(Self) { date.setHours(0, 0, 0, 0); let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/client/back/methods/client/filter.js b/modules/client/back/methods/client/filter.js index 1ae569fd3..3bf29501b 100644 --- a/modules/client/back/methods/client/filter.js +++ b/modules/client/back/methods/client/filter.js @@ -72,7 +72,7 @@ module.exports = Self => { Self.filter = async(ctx, filter, options) => { const conn = Self.dataSource.connector; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; const postalCode = []; const args = ctx.args; @@ -120,7 +120,7 @@ module.exports = Self => { const stmts = []; const stmt = new ParameterizedSQL( - `SELECT + `SELECT DISTINCT c.id, c.name, c.fi, diff --git a/modules/client/back/methods/client/getCard.js b/modules/client/back/methods/client/getCard.js index 48840b036..10e6f7adf 100644 --- a/modules/client/back/methods/client/getCard.js +++ b/modules/client/back/methods/client/getCard.js @@ -1,5 +1,5 @@ module.exports = function(Self) { - Self.remoteMethod('getCard', { + Self.remoteMethodCtx('getCard', { description: 'Get client basic data and debt', accepts: { arg: 'id', @@ -18,8 +18,8 @@ module.exports = function(Self) { } }); - Self.getCard = async(id, options) => { - const myOptions = {}; + Self.getCard = async(ctx, id, options) => { + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/client/back/methods/client/getDebt.js b/modules/client/back/methods/client/getDebt.js index 859746083..6ed59684b 100644 --- a/modules/client/back/methods/client/getDebt.js +++ b/modules/client/back/methods/client/getDebt.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('getDebt', { + Self.remoteMethodCtx('getDebt', { description: 'Returns the boolean debt of a client', accessType: 'READ', accepts: [{ @@ -19,8 +19,8 @@ module.exports = Self => { } }); - Self.getDebt = async(clientFk, options) => { - const myOptions = {}; + Self.getDebt = async(ctx, clientFk, options) => { + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/client/back/methods/client/specs/getCard.spec.js b/modules/client/back/methods/client/specs/getCard.spec.js index e713c9883..962e0a2d4 100644 --- a/modules/client/back/methods/client/specs/getCard.spec.js +++ b/modules/client/back/methods/client/specs/getCard.spec.js @@ -5,10 +5,11 @@ describe('Client getCard()', () => { const tx = await models.Client.beginTransaction({}); try { + const ctx = {req: {accessToken: {userId: 9}}}; const options = {transaction: tx}; const id = 1101; - const result = await models.Client.getCard(id, options); + const result = await models.Client.getCard(ctx, id, options); expect(result.id).toEqual(id); expect(result.name).toEqual('Bruce Wayne'); diff --git a/modules/client/back/methods/client/specs/getDebt.spec.js b/modules/client/back/methods/client/specs/getDebt.spec.js index 471d45a6d..b3b5286c0 100644 --- a/modules/client/back/methods/client/specs/getDebt.spec.js +++ b/modules/client/back/methods/client/specs/getDebt.spec.js @@ -3,11 +3,12 @@ const models = require('vn-loopback/server/server').models; describe('client getDebt()', () => { it('should return the client debt', async() => { const tx = await models.Client.beginTransaction({}); + const ctx = {req: {accessToken: {userId: 9}}}; try { const options = {transaction: tx}; - const result = await models.Client.getDebt(1101, options); + const result = await models.Client.getDebt(ctx, 1101, options); expect(result.debt).toEqual(jasmine.any(Number)); diff --git a/modules/client/back/methods/client/specs/summary.spec.js b/modules/client/back/methods/client/specs/summary.spec.js index f2d576e39..227f4c398 100644 --- a/modules/client/back/methods/client/specs/summary.spec.js +++ b/modules/client/back/methods/client/specs/summary.spec.js @@ -1,6 +1,7 @@ const models = require('vn-loopback/server/server').models; describe('client summary()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; it('should return a summary object containing data', async() => { const clientId = 1101; const tx = await models.Client.beginTransaction({}); @@ -8,7 +9,7 @@ describe('client summary()', () => { try { const options = {transaction: tx}; - const result = await models.Client.summary(clientId, options); + const result = await models.Client.summary(ctx, clientId, options); expect(result.id).toEqual(clientId); expect(result.name).toEqual('Bruce Wayne'); @@ -27,7 +28,7 @@ describe('client summary()', () => { try { const options = {transaction: tx}; - const result = await models.Client.summary(clientId, options); + const result = await models.Client.summary(ctx, clientId, options); expect(result.mana.mana).toEqual(0.34); @@ -45,7 +46,7 @@ describe('client summary()', () => { try { const options = {transaction: tx}; - const result = await models.Client.summary(clientId, options); + const result = await models.Client.summary(ctx, clientId, options); expect(result.debt.debt).toEqual(jasmine.any(Number)); @@ -63,7 +64,7 @@ describe('client summary()', () => { try { const options = {transaction: tx}; - const result = await models.Client.summary(clientId, options); + const result = await models.Client.summary(ctx, clientId, options); expect(result.averageInvoiced.invoiced).toEqual(1500); @@ -81,7 +82,7 @@ describe('client summary()', () => { try { const options = {transaction: tx}; - const result = await models.Client.summary(clientId, options); + const result = await models.Client.summary(ctx, clientId, options); expect(result.totalGreuge).toEqual(203.71); @@ -99,7 +100,7 @@ describe('client summary()', () => { try { const options = {transaction: tx}; - const result = await models.Client.summary(clientId, options); + const result = await models.Client.summary(ctx, clientId, options); expect(result.recovery).toEqual(null); @@ -117,7 +118,7 @@ describe('client summary()', () => { try { const options = {transaction: tx}; - const result = await models.Client.summary(clientId, options); + const result = await models.Client.summary(ctx, clientId, options); expect(result.recovery.id).toEqual(3); await tx.rollback(); diff --git a/modules/client/back/methods/client/summary.js b/modules/client/back/methods/client/summary.js index 7dab1f68b..8de887b47 100644 --- a/modules/client/back/methods/client/summary.js +++ b/modules/client/back/methods/client/summary.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('summary', { + Self.remoteMethodCtx('summary', { description: 'Returns a client summary', accessType: 'READ', accepts: [{ @@ -19,7 +19,7 @@ module.exports = Self => { } }); - Self.summary = async(clientFk, options) => { + Self.summary = async(ctx, clientFk, options) => { const models = Self.app.models; const myOptions = {}; @@ -28,7 +28,7 @@ module.exports = Self => { const summaryObj = await getSummary(models.Client, clientFk, myOptions); summaryObj.mana = await models.Client.getMana(clientFk, myOptions); - summaryObj.debt = await models.Client.getDebt(clientFk, myOptions); + summaryObj.debt = await models.Client.getDebt(ctx, clientFk, myOptions); summaryObj.averageInvoiced = await models.Client.getAverageInvoiced(clientFk, myOptions); summaryObj.totalGreuge = await models.Greuge.sumAmount(clientFk, myOptions); summaryObj.recovery = await getRecoveries(models.Recovery, clientFk, myOptions); diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 41229a1fd..4faa21bb5 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -2,7 +2,7 @@ const UserError = require('vn-loopback/util/user-error'); const base64url = require('base64url'); module.exports = Self => { - Self.remoteMethod('confirm', { + Self.remoteMethodCtx('confirm', { description: 'Confirms electronic payment transaction', accessType: 'WRITE', accepts: [ @@ -30,7 +30,7 @@ module.exports = Self => { } }); - Self.confirm = async(signatureVersion, merchantParameters, signature) => { + Self.confirm = async(ctx, signatureVersion, merchantParameters, signature) => { const $ = Self.app.models; let transaction; @@ -83,7 +83,7 @@ module.exports = Self => { params['Ds_Currency'], params['Ds_Response'], params['Ds_ErrorCode'] - ]); + ], {userId: ctx.req.accessToken.userId}); return true; } catch (err) { diff --git a/modules/client/back/methods/tpv-transaction/end.js b/modules/client/back/methods/tpv-transaction/end.js index 5a757aa48..3233f482f 100644 --- a/modules/client/back/methods/tpv-transaction/end.js +++ b/modules/client/back/methods/tpv-transaction/end.js @@ -34,6 +34,6 @@ module.exports = Self => { 'CALL hedera.tpvTransaction_end(?, ?)', [ orderId, status - ]); + ], {userId}); }; }; diff --git a/modules/client/back/methods/tpv-transaction/start.js b/modules/client/back/methods/tpv-transaction/start.js index ea6ed05eb..178c56d76 100644 --- a/modules/client/back/methods/tpv-transaction/start.js +++ b/modules/client/back/methods/tpv-transaction/start.js @@ -40,7 +40,7 @@ module.exports = Self => { amount, companyId, userId - ]); + ], {userId}); if (!row) throw new UserError('Transaction error'); diff --git a/modules/entry/back/methods/entry/importBuys.js b/modules/entry/back/methods/entry/importBuys.js index fdc6b058e..1e6f01a5e 100644 --- a/modules/entry/back/methods/entry/importBuys.js +++ b/modules/entry/back/methods/entry/importBuys.js @@ -46,7 +46,7 @@ module.exports = Self => { const args = ctx.args; const models = Self.app.models; let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); @@ -79,7 +79,7 @@ module.exports = Self => { ], myOptions); const buyUltimate = await Self.rawSql(` - SELECT * + SELECT * FROM tmp.buyUltimate WHERE warehouseFk = ? `, [travel.warehouseInFk], myOptions); diff --git a/modules/invoiceIn/back/methods/invoice-in/toBook.js b/modules/invoiceIn/back/methods/invoice-in/toBook.js index 588d53f1f..877552f41 100644 --- a/modules/invoiceIn/back/methods/invoice-in/toBook.js +++ b/modules/invoiceIn/back/methods/invoice-in/toBook.js @@ -21,7 +21,7 @@ module.exports = Self => { Self.toBook = async(ctx, id, options) => { let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/book.js b/modules/invoiceOut/back/methods/invoiceOut/book.js index 7aa0eac1f..af5633ff2 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/book.js +++ b/modules/invoiceOut/back/methods/invoiceOut/book.js @@ -1,6 +1,6 @@ module.exports = Self => { - Self.remoteMethod('book', { + Self.remoteMethodCtx('book', { description: 'Book an invoiceOut', accessType: 'WRITE', accepts: { @@ -20,10 +20,10 @@ module.exports = Self => { } }); - Self.book = async(ref, options) => { + Self.book = async(ctx, ref, options) => { const models = Self.app.models; let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/clientsToInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/clientsToInvoice.js index f18b0c682..63b00fe38 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/clientsToInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/clientsToInvoice.js @@ -36,7 +36,7 @@ module.exports = Self => { Self.clientsToInvoice = async(ctx, clientId, invoiceDate, maxShipped, companyFk, options) => { let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js index a458aa18e..18e6903d6 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js @@ -51,7 +51,7 @@ module.exports = Self => { const args = ctx.args; let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js index c8f8a6778..421cbaea1 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js +++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js @@ -50,7 +50,7 @@ module.exports = Self => { Self.invoiceClient = async(ctx, options) => { const args = ctx.args; const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/invoiceOut/back/methods/invoiceOut/refund.js b/modules/invoiceOut/back/methods/invoiceOut/refund.js index c722d9806..1b7ccc1e4 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/refund.js +++ b/modules/invoiceOut/back/methods/invoiceOut/refund.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('refund', { + Self.remoteMethodCtx('refund', { description: 'Create refund tickets with sales and services if provided', accessType: 'WRITE', accepts: [ @@ -25,7 +25,7 @@ module.exports = Self => { } }); - Self.refund = async(ref, withWarehouse, options) => { + Self.refund = async(ctx, ref, withWarehouse, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -43,7 +43,7 @@ module.exports = Self => { const tickets = await models.Ticket.find(filter, myOptions); const ticketsIds = tickets.map(ticket => ticket.id); - const refundedTickets = await models.Ticket.refund(ticketsIds, withWarehouse, myOptions); + const refundedTickets = await models.Ticket.refund(ctx, ticketsIds, withWarehouse, myOptions); if (tx) await tx.commit(); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/book.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/book.spec.js index ee72f2218..3af7542ca 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/book.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/book.spec.js @@ -1,6 +1,7 @@ const models = require('vn-loopback/server/server').models; describe('invoiceOut book()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; const invoiceOutId = 5; it('should update the booked property', async() => { @@ -12,7 +13,7 @@ describe('invoiceOut book()', () => { const bookedDate = originalInvoiceOut.booked; const invoiceOutRef = originalInvoiceOut.ref; - await models.InvoiceOut.book(invoiceOutRef, options); + await models.InvoiceOut.book(ctx, invoiceOutRef, options); const updatedInvoiceOut = await models.InvoiceOut.findById(invoiceOutId, {}, options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js index 3d0ea6809..072fcc12c 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js @@ -3,6 +3,7 @@ const LoopBackContext = require('loopback-context'); describe('InvoiceOut refund()', () => { const userId = 5; + const ctx = {req: {accessToken: userId}}; const withWarehouse = true; const activeCtx = { accessToken: {userId: userId}, @@ -16,7 +17,7 @@ describe('InvoiceOut refund()', () => { const options = {transaction: tx}; try { - const result = await models.InvoiceOut.refund('T1111111', withWarehouse, options); + const result = await models.InvoiceOut.refund(ctx, 'T1111111', withWarehouse, options); expect(result).toBeDefined(); diff --git a/modules/item/back/methods/item/getBalance.js b/modules/item/back/methods/item/getBalance.js index 5751b0a04..d4e2d0f74 100644 --- a/modules/item/back/methods/item/getBalance.js +++ b/modules/item/back/methods/item/getBalance.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('getBalance', { + Self.remoteMethodCtx('getBalance', { description: 'Returns the ', accessType: 'READ', accepts: [{ @@ -19,8 +19,8 @@ module.exports = Self => { } }); - Self.getBalance = async(filter, options) => { - const myOptions = {}; + Self.getBalance = async(ctx, filter, options) => { + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/item/back/methods/item/new.js b/modules/item/back/methods/item/new.js index d066f2c9f..c82e2a6b1 100644 --- a/modules/item/back/methods/item/new.js +++ b/modules/item/back/methods/item/new.js @@ -1,7 +1,7 @@ let UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethod('new', { + Self.remoteMethodCtx('new', { description: 'returns the created item', accessType: 'WRITE', accepts: [{ @@ -19,9 +19,9 @@ module.exports = Self => { } }); - Self.new = async(params, options) => { + Self.new = async(ctx, params, options) => { const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/item/back/methods/item/specs/getBalance.spec.js b/modules/item/back/methods/item/specs/getBalance.spec.js index 1ffd3c302..e013d8956 100644 --- a/modules/item/back/methods/item/specs/getBalance.spec.js +++ b/modules/item/back/methods/item/specs/getBalance.spec.js @@ -2,6 +2,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('item getBalance()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; it('should return the balance lines of a client type loses in which one has highlighted true', async() => { const tx = await models.Item.beginTransaction({}); const options = {transaction: tx}; @@ -25,7 +26,7 @@ describe('item getBalance()', () => { date: null } }; - const results = await models.Item.getBalance(filter, options); + const results = await models.Item.getBalance(ctx, filter, options); const result = results.find(element => element.clientType == 'loses'); @@ -59,8 +60,8 @@ describe('item getBalance()', () => { } }; - const firstItemBalance = await models.Item.getBalance(firstFilter, options); - const secondItemBalance = await models.Item.getBalance(secondFilter, options); + const firstItemBalance = await models.Item.getBalance(ctx, firstFilter, options); + const secondItemBalance = await models.Item.getBalance(ctx, secondFilter, options); expect(firstItemBalance[9].claimFk).toEqual(null); expect(secondItemBalance[5].claimFk).toEqual(2); diff --git a/modules/item/back/methods/item/specs/new.spec.js b/modules/item/back/methods/item/specs/new.spec.js index a1c741649..2ffaf87a5 100644 --- a/modules/item/back/methods/item/specs/new.spec.js +++ b/modules/item/back/methods/item/specs/new.spec.js @@ -2,6 +2,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('item new()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; beforeAll(async() => { const activeCtx = { accessToken: {userId: 9}, @@ -30,7 +31,7 @@ describe('item new()', () => { tag: 1 }; - let item = await models.Item.new(itemParams, options); + let item = await models.Item.new(ctx, itemParams, options); let itemType = await models.ItemType.findById(item.typeFk, options); diff --git a/modules/order/back/methods/order-row/addToOrder.js b/modules/order/back/methods/order-row/addToOrder.js index 639fa8be7..0bf65ef1f 100644 --- a/modules/order/back/methods/order-row/addToOrder.js +++ b/modules/order/back/methods/order-row/addToOrder.js @@ -1,7 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethod('addToOrder', { + Self.remoteMethodCtx('addToOrder', { description: 'Creates rows (lines) for a order', accessType: 'WRITE', accepts: [{ @@ -21,8 +21,8 @@ module.exports = Self => { } }); - Self.addToOrder = async(params, options) => { - const myOptions = {}; + Self.addToOrder = async(ctx, params, options) => { + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/order/back/methods/order-row/specs/addToOrder.spec.js b/modules/order/back/methods/order-row/specs/addToOrder.spec.js index d902a1062..96544a1a9 100644 --- a/modules/order/back/methods/order-row/specs/addToOrder.spec.js +++ b/modules/order/back/methods/order-row/specs/addToOrder.spec.js @@ -1,6 +1,7 @@ const models = require('vn-loopback/server/server').models; describe('order addToOrder()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; const orderId = 8; it('should add a row to a given order', async() => { const tx = await models.Order.beginTransaction({}); @@ -21,7 +22,7 @@ describe('order addToOrder()', () => { }] }; - await models.OrderRow.addToOrder(params, options); + await models.OrderRow.addToOrder(ctx, params, options); const modifiedRows = await models.OrderRow.find({where: {orderFk: orderId}}, options); diff --git a/modules/order/back/methods/order/confirm.js b/modules/order/back/methods/order/confirm.js index 52acc8648..5fdab29b3 100644 --- a/modules/order/back/methods/order/confirm.js +++ b/modules/order/back/methods/order/confirm.js @@ -23,7 +23,7 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; const query = `CALL hedera.order_confirmWithUser(?, ?)`; - const response = await Self.rawSql(query, [orderFk, userId]); + const response = await Self.rawSql(query, [orderFk, userId], {userId}); return response; }; diff --git a/modules/order/back/methods/order/new.js b/modules/order/back/methods/order/new.js index 147859dcc..d65b18e12 100644 --- a/modules/order/back/methods/order/new.js +++ b/modules/order/back/methods/order/new.js @@ -1,7 +1,7 @@ let UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethod('new', { + Self.remoteMethodCtx('new', { description: 'Create a new order and returns the new ID', accessType: 'WRITE', accepts: [ @@ -32,8 +32,8 @@ module.exports = Self => { } }); - Self.new = async(landed, addressId, agencyModeId, options) => { - const myOptions = {}; + Self.new = async(ctx, landed, addressId, agencyModeId, options) => { + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/order/back/methods/order/newFromTicket.js b/modules/order/back/methods/order/newFromTicket.js index e0578ff9a..3614d8e32 100644 --- a/modules/order/back/methods/order/newFromTicket.js +++ b/modules/order/back/methods/order/newFromTicket.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('newFromTicket', { + Self.remoteMethodCtx('newFromTicket', { description: 'Create a new order and returns the new ID', accessType: 'WRITE', accepts: [{ @@ -18,7 +18,7 @@ module.exports = Self => { } }); - Self.newFromTicket = async(ticketFk, options) => { + Self.newFromTicket = async(ctx, ticketFk, options) => { const myOptions = {}; let tx; @@ -39,7 +39,7 @@ module.exports = Self => { const addressFk = ticket.addressFk; const agencyModeFk = ticket.agencyModeFk; - const orderID = await Self.app.models.Order.new(landed, addressFk, agencyModeFk, myOptions); + const orderID = await Self.app.models.Order.new(ctx, landed, addressFk, agencyModeFk, myOptions); if (tx) await tx.commit(); diff --git a/modules/order/back/methods/order/specs/new.spec.js b/modules/order/back/methods/order/specs/new.spec.js index f11367579..c43527f66 100644 --- a/modules/order/back/methods/order/specs/new.spec.js +++ b/modules/order/back/methods/order/specs/new.spec.js @@ -2,6 +2,7 @@ const models = require('vn-loopback/server/server').models; const UserError = require('vn-loopback/util/user-error'); describe('order new()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; it('should throw an error if the client isnt active', async() => { const tx = await models.Order.beginTransaction({}); @@ -13,7 +14,7 @@ describe('order new()', () => { const addressFk = 6; const agencyModeFk = 1; - await models.Order.new(landed, addressFk, agencyModeFk, options); + await models.Order.new(ctx, landed, addressFk, agencyModeFk, options); await tx.rollback(); } catch (e) { @@ -34,7 +35,7 @@ describe('order new()', () => { const addressFk = 121; const agencyModeFk = 1; - orderId = await models.Order.new(landed, addressFk, agencyModeFk, options); + orderId = await models.Order.new(ctx, landed, addressFk, agencyModeFk, options); const highestOrderIdInFixtures = 3; diff --git a/modules/order/back/methods/order/specs/newFromTicket.spec.js b/modules/order/back/methods/order/specs/newFromTicket.spec.js index 6f18d1751..c509552fe 100644 --- a/modules/order/back/methods/order/specs/newFromTicket.spec.js +++ b/modules/order/back/methods/order/specs/newFromTicket.spec.js @@ -1,6 +1,7 @@ const models = require('vn-loopback/server/server').models; describe('order newFromTicket()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; it('should create a new order from an existing ticket', async() => { const tx = await models.Order.beginTransaction({}); @@ -9,7 +10,7 @@ describe('order newFromTicket()', () => { const ticketId = 11; - const orderId = await models.Order.newFromTicket(ticketId, options); + const orderId = await models.Order.newFromTicket(ctx, ticketId, options); const highestOrderIdInFixtures = 3; diff --git a/modules/route/back/methods/agency-term/createInvoiceIn.js b/modules/route/back/methods/agency-term/createInvoiceIn.js index 836655bd3..5a8430e49 100644 --- a/modules/route/back/methods/agency-term/createInvoiceIn.js +++ b/modules/route/back/methods/agency-term/createInvoiceIn.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('createInvoiceIn', { + Self.remoteMethodCtx('createInvoiceIn', { description: 'Creates an invoiceIn from one or more agency terms', accessType: 'WRITE', accepts: [{ @@ -24,11 +24,11 @@ module.exports = Self => { } }); - Self.createInvoiceIn = async(rows, dms, options) => { + Self.createInvoiceIn = async(ctx, rows, dms, options) => { const models = Self.app.models; let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js b/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js index 628c5fb9a..d3a0755ef 100644 --- a/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js +++ b/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js @@ -2,6 +2,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('AgencyTerm createInvoiceIn()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; beforeAll(async() => { const activeCtx = { accessToken: {userId: 9}, @@ -42,7 +43,7 @@ describe('AgencyTerm createInvoiceIn()', () => { const oldInvoiceInDueDay = await models.InvoiceInDueDay.findById(invoiceInDueDayId, null, options); const oldInvoiceInTax = await models.InvoiceInTax.findById(invoiceInTaxId, null, options); - await models.AgencyTerm.createInvoiceIn(rows, dms, options); + await models.AgencyTerm.createInvoiceIn(ctx, rows, dms, options); const [newInvoiceIn] = await models.InvoiceIn.rawSql('SELECT MAX(id) id FROM invoiceIn', null, options); diff --git a/modules/route/back/methods/route/guessPriority.js b/modules/route/back/methods/route/guessPriority.js index eab9f3473..67b68aa89 100644 --- a/modules/route/back/methods/route/guessPriority.js +++ b/modules/route/back/methods/route/guessPriority.js @@ -26,7 +26,7 @@ module.exports = Self => { const tx = await Self.beginTransaction({}); try { - let options = {transaction: tx}; + let options = {transaction: tx, userId}; const priority = await Self.rawSql(query, [id], options); diff --git a/modules/route/back/methods/route/updateVolume.js b/modules/route/back/methods/route/updateVolume.js index f3b8da130..cdced3882 100644 --- a/modules/route/back/methods/route/updateVolume.js +++ b/modules/route/back/methods/route/updateVolume.js @@ -24,7 +24,7 @@ module.exports = Self => { const models = Self.app.models; let tx; - const myOptions = {}; + const myOptions = {userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/ticket/back/methods/sale/recalculatePrice.js b/modules/ticket/back/methods/sale/recalculatePrice.js index 2c8e6768b..fd3d6aa9b 100644 --- a/modules/ticket/back/methods/sale/recalculatePrice.js +++ b/modules/ticket/back/methods/sale/recalculatePrice.js @@ -23,7 +23,7 @@ module.exports = Self => { Self.recalculatePrice = async(ctx, sales, options) => { const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index e84232752..7abcedd90 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('refund', { + Self.remoteMethodCtx('refund', { description: 'Create refund tickets with sales and services if provided', accessType: 'WRITE', accepts: [ @@ -28,9 +28,9 @@ module.exports = Self => { } }); - Self.refund = async(salesIds, servicesIds, withWarehouse, options) => { + Self.refund = async(ctx, salesIds, servicesIds, withWarehouse, options) => { const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/sale/specs/refund.spec.js b/modules/ticket/back/methods/sale/specs/refund.spec.js index b870a36f7..b81f7f84d 100644 --- a/modules/ticket/back/methods/sale/specs/refund.spec.js +++ b/modules/ticket/back/methods/sale/specs/refund.spec.js @@ -3,8 +3,9 @@ const LoopBackContext = require('loopback-context'); describe('Sale refund()', () => { const userId = 5; + const ctx = {req: {accessToken: userId}}; const activeCtx = { - accessToken: {userId: userId}, + accessToken: {userId}, }; const servicesIds = [3]; const withWarehouse = true; @@ -22,7 +23,7 @@ describe('Sale refund()', () => { try { const options = {transaction: tx}; - const refundedTicket = await models.Sale.refund(salesIds, servicesIds, withWarehouse, options); + const refundedTicket = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options); expect(refundedTicket).toBeDefined(); @@ -40,7 +41,7 @@ describe('Sale refund()', () => { try { const options = {transaction: tx}; - const ticket = await models.Sale.refund(salesIds, servicesIds, withWarehouse, options); + const ticket = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options); const refundedTicket = await models.Ticket.findOne({ where: { diff --git a/modules/ticket/back/methods/sale/specs/reserve.spec.js b/modules/ticket/back/methods/sale/specs/reserve.spec.js index 259cb8cd5..7ba5999b3 100644 --- a/modules/ticket/back/methods/sale/specs/reserve.spec.js +++ b/modules/ticket/back/methods/sale/specs/reserve.spec.js @@ -52,7 +52,7 @@ describe('sale reserve()', () => { try { const options = {transaction: tx}; - originalTicketSales = await models.Ticket.getSales(11, options); + originalTicketSales = await models.Ticket.getSales(ctx, 11, options); expect(originalTicketSales[0].reserved).toEqual(false); expect(originalTicketSales[1].reserved).toEqual(false); @@ -63,7 +63,7 @@ describe('sale reserve()', () => { await models.Sale.reserve(ctx, ticketId, sales, reserved, options); - const reservedTicketSales = await models.Ticket.getSales(ticketId, options); + const reservedTicketSales = await models.Ticket.getSales(ctx, ticketId, options); expect(reservedTicketSales[0].reserved).toEqual(true); expect(reservedTicketSales[1].reserved).toEqual(true); diff --git a/modules/ticket/back/methods/sale/updatePrice.js b/modules/ticket/back/methods/sale/updatePrice.js index 505de5180..649395da6 100644 --- a/modules/ticket/back/methods/sale/updatePrice.js +++ b/modules/ticket/back/methods/sale/updatePrice.js @@ -31,7 +31,7 @@ module.exports = Self => { Self.updatePrice = async(ctx, id, newPrice, options) => { const $t = ctx.req.__; // $translate const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/sale/usesMana.js b/modules/ticket/back/methods/sale/usesMana.js index 3f55293bf..75d8cdda7 100644 --- a/modules/ticket/back/methods/sale/usesMana.js +++ b/modules/ticket/back/methods/sale/usesMana.js @@ -22,7 +22,7 @@ module.exports = Self => { Object.assign(myOptions, options); const salesDepartment = await models.Department.findOne({where: {code: 'VT'}, fields: 'id'}, myOptions); - const departments = await models.Department.getLeaves(salesDepartment.id, null, myOptions); + const departments = await models.Department.getLeaves(ctx, salesDepartment.id, null, myOptions); const workerDepartment = await models.WorkerDepartment.findById(userId, null, myOptions); if (!workerDepartment) return false; diff --git a/modules/ticket/back/methods/ticket-request/confirm.js b/modules/ticket/back/methods/ticket-request/confirm.js index f7f7fbc2a..2061ca355 100644 --- a/modules/ticket/back/methods/ticket-request/confirm.js +++ b/modules/ticket/back/methods/ticket-request/confirm.js @@ -34,7 +34,7 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; const models = Self.app.models; const $t = ctx.req.__; // $translate - const myOptions = {}; + const myOptions = {userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/ticket/addSale.js b/modules/ticket/back/methods/ticket/addSale.js index 37d97b2c7..85b0510ae 100644 --- a/modules/ticket/back/methods/ticket/addSale.js +++ b/modules/ticket/back/methods/ticket/addSale.js @@ -35,7 +35,7 @@ module.exports = Self => { Self.addSale = async(ctx, id, itemId, quantity, options) => { const $t = ctx.req.__; // $translate const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/ticket/closeAll.js b/modules/ticket/back/methods/ticket/closeAll.js index 6690126b9..660c16893 100644 --- a/modules/ticket/back/methods/ticket/closeAll.js +++ b/modules/ticket/back/methods/ticket/closeAll.js @@ -2,7 +2,7 @@ const UserError = require('vn-loopback/util/user-error'); const closure = require('./closure'); module.exports = Self => { - Self.remoteMethod('closeAll', { + Self.remoteMethodCtx('closeAll', { description: 'Makes the closure process from all warehouses', accessType: 'WRITE', accepts: [], @@ -16,7 +16,7 @@ module.exports = Self => { } }); - Self.closeAll = async() => { + Self.closeAll = async ctx => { const toDate = Date.vnNew(); toDate.setHours(0, 0, 0, 0); toDate.setDate(toDate.getDate() - 1); @@ -59,7 +59,7 @@ module.exports = Self => { GROUP BY t.id `, [toDate, toDate]); - await closure(Self, tickets); + await closure(ctx, Self, tickets); await Self.rawSql(` UPDATE ticket t @@ -73,7 +73,7 @@ module.exports = Self => { AND util.dayEnd(?) AND al.code NOT IN('DELIVERED','PACKED') AND t.routeFk - AND z.name LIKE '%MADRID%'`, [toDate, toDate]); + AND z.name LIKE '%MADRID%'`, [toDate, toDate], {userId: ctx.req.accessToken.userId}); return { message: 'Success' diff --git a/modules/ticket/back/methods/ticket/closure.js b/modules/ticket/back/methods/ticket/closure.js index 9b3355d6c..eee5e28e2 100644 --- a/modules/ticket/back/methods/ticket/closure.js +++ b/modules/ticket/back/methods/ticket/closure.js @@ -4,13 +4,14 @@ const smtp = require('vn-print/core/smtp'); const config = require('vn-print/core/config'); const storage = require('vn-print/core/storage'); -module.exports = async function(Self, tickets, reqArgs = {}) { +module.exports = async function(ctx, Self, tickets, reqArgs = {}) { + const userId = ctx.req.accessToken.userId; if (tickets.length == 0) return; const failedtickets = []; for (const ticket of tickets) { try { - await Self.rawSql(`CALL vn.ticket_closeByTicket(?)`, [ticket.id]); + await Self.rawSql(`CALL vn.ticket_closeByTicket(?)`, [ticket.id], {userId}); const [invoiceOut] = await Self.rawSql(` SELECT io.id, io.ref, io.serial, cny.code companyCode, io.issued @@ -52,7 +53,7 @@ module.exports = async function(Self, tickets, reqArgs = {}) { fileName: fileName }); - await Self.rawSql('UPDATE invoiceOut SET hasPdf = true WHERE id = ?', [invoiceOut.id]); + await Self.rawSql('UPDATE invoiceOut SET hasPdf = true WHERE id = ?', [invoiceOut.id], {userId}); if (isToBeMailed) { const invoiceAttachment = { @@ -91,7 +92,7 @@ module.exports = async function(Self, tickets, reqArgs = {}) { // Incoterms authorization const [{firstOrder}] = await Self.rawSql(` SELECT COUNT(*) as firstOrder - FROM ticket t + FROM ticket t JOIN client c ON c.id = t.clientFk WHERE t.clientFk = ? AND NOT t.isDeleted @@ -111,14 +112,14 @@ module.exports = async function(Self, tickets, reqArgs = {}) { await email.send(); const [sample] = await Self.rawSql( - `SELECT id - FROM sample + `SELECT id + FROM sample WHERE code = 'incoterms-authorization' `); await Self.rawSql(` INSERT INTO clientSample (clientFk, typeFk, companyFk) VALUES(?, ?, ?) - `, [ticket.clientFk, sample.id, ticket.companyFk]); + `, [ticket.clientFk, sample.id, ticket.companyFk], {userId}); } } catch (error) { // Domain not found @@ -152,23 +153,23 @@ module.exports = async function(Self, tickets, reqArgs = {}) { async function invalidEmail(ticket) { await Self.rawSql(`UPDATE client SET email = NULL WHERE id = ?`, [ ticket.clientFk - ]); + ], {userId}); const oldInstance = `{"email": "${ticket.recipient}"}`; const newInstance = `{"email": ""}`; await Self.rawSql(` - INSERT INTO clientLog (originFk, userFk, action, changedModel, oldInstance, newInstance) + INSERT INTO clientLog (originFk, userFk, action, changedModel, oldInstance, newInstance) 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} - porque la dirección de email "${ticket.recipient}" no es correcta + const body = `No se ha podido enviar el albarán ${ticket.id} + al cliente ${ticket.clientFk} - ${ticket.clientName} + porque la dirección de email "${ticket.recipient}" no es correcta o no está disponible.

- Para evitar que se repita este error, se ha eliminado la dirección de email de la ficha del cliente. + Para evitar que se repita este error, se ha eliminado la dirección de email de la ficha del cliente. Actualiza la dirección de email con una correcta.`; smtp.send({ diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index dac8e4f52..a8b631d7c 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -101,7 +101,7 @@ module.exports = Self => { Self.componentUpdate = async(ctx, options) => { const args = ctx.args; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/ticket/getSales.js b/modules/ticket/back/methods/ticket/getSales.js index 321e8e24e..e721d90ae 100644 --- a/modules/ticket/back/methods/ticket/getSales.js +++ b/modules/ticket/back/methods/ticket/getSales.js @@ -1,6 +1,6 @@ module.exports = Self => { - Self.remoteMethod('getSales', { + Self.remoteMethodCtx('getSales', { description: 'New filter', accessType: 'READ', accepts: [{ @@ -20,10 +20,10 @@ module.exports = Self => { } }); - Self.getSales = async(id, options) => { + Self.getSales = async(ctx, id, options) => { const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js index d8ec5eb9a..ee82b874f 100644 --- a/modules/ticket/back/methods/ticket/makeInvoice.js +++ b/modules/ticket/back/methods/ticket/makeInvoice.js @@ -28,7 +28,7 @@ module.exports = function(Self) { const date = Date.vnNew(); date.setHours(0, 0, 0, 0); - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/ticket/new.js b/modules/ticket/back/methods/ticket/new.js index 5f7cf3cb6..b461fb26d 100644 --- a/modules/ticket/back/methods/ticket/new.js +++ b/modules/ticket/back/methods/ticket/new.js @@ -59,9 +59,9 @@ module.exports = Self => { Self.new = async(ctx, options) => { const args = ctx.args; - const myUserId = ctx.req.accessToken.userId; + const userId = ctx.req.accessToken.userId; const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId}; let tx; if (typeof options == 'object') @@ -123,7 +123,7 @@ module.exports = Self => { args.routeId || null, args.landed, true, - myUserId + userId ], myOptions); const ticket = await models.Ticket.findById(result[1][0].newTicketId, null, myOptions); diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 27fdb9160..42a71f1c8 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -60,7 +60,7 @@ module.exports = Self => { Self.priceDifference = async(ctx, options) => { const args = ctx.args; const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/ticket/recalculateComponents.js b/modules/ticket/back/methods/ticket/recalculateComponents.js index 5b9e8e5dc..eb9c8a72e 100644 --- a/modules/ticket/back/methods/ticket/recalculateComponents.js +++ b/modules/ticket/back/methods/ticket/recalculateComponents.js @@ -21,7 +21,7 @@ module.exports = Self => { }); Self.recalculateComponents = async(ctx, id, options) => { - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/ticket/refund.js b/modules/ticket/back/methods/ticket/refund.js index fe17b7101..c99b6aa83 100644 --- a/modules/ticket/back/methods/ticket/refund.js +++ b/modules/ticket/back/methods/ticket/refund.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('refund', { + Self.remoteMethodCtx('refund', { description: 'Create refund tickets with all their sales and services', accessType: 'WRITE', accepts: [ @@ -24,7 +24,7 @@ module.exports = Self => { } }); - Self.refund = async(ticketsIds, withWarehouse, options) => { + Self.refund = async(ctx, ticketsIds, withWarehouse, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -46,7 +46,7 @@ module.exports = Self => { const services = await models.TicketService.find(filter, myOptions); const servicesIds = services.map(service => service.id); - const refundedTickets = await models.Sale.refund(salesIds, servicesIds, withWarehouse, myOptions); + const refundedTickets = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, myOptions); if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/saveSign.js b/modules/ticket/back/methods/ticket/saveSign.js index b8f9d5ced..55d2e3281 100644 --- a/modules/ticket/back/methods/ticket/saveSign.js +++ b/modules/ticket/back/methods/ticket/saveSign.js @@ -31,7 +31,7 @@ module.exports = Self => { Self.saveSign = async(ctx, tickets, location, signedTime, options) => { const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; let dms; let gestDocCreated = false; diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js index 228e2e765..7cc300547 100644 --- a/modules/ticket/back/methods/ticket/setDeleted.js +++ b/modules/ticket/back/methods/ticket/setDeleted.js @@ -24,7 +24,7 @@ module.exports = Self => { Self.setDeleted = async(ctx, id, options) => { const models = Self.app.models; const $t = ctx.req.__; // $translate - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/ticket/specs/getSales.spec.js b/modules/ticket/back/methods/ticket/specs/getSales.spec.js index b9f78e40b..7c0a67d45 100644 --- a/modules/ticket/back/methods/ticket/specs/getSales.spec.js +++ b/modules/ticket/back/methods/ticket/specs/getSales.spec.js @@ -1,13 +1,14 @@ const models = require('vn-loopback/server/server').models; describe('ticket getSales()', () => { + const ctx = {req: {accessToken: 9}}; it('should return the sales of a ticket', async() => { const tx = await models.Ticket.beginTransaction({}); try { const options = {transaction: tx}; - const sales = await models.Ticket.getSales(16, options); + const sales = await models.Ticket.getSales(ctx, 16, options); expect(sales.length).toEqual(4); expect(sales[0].item).toBeDefined(); diff --git a/modules/ticket/back/methods/ticket/specs/summary.spec.js b/modules/ticket/back/methods/ticket/specs/summary.spec.js index 5d2991b0a..2c4aedf1e 100644 --- a/modules/ticket/back/methods/ticket/specs/summary.spec.js +++ b/modules/ticket/back/methods/ticket/specs/summary.spec.js @@ -1,13 +1,14 @@ const models = require('vn-loopback/server/server').models; describe('ticket summary()', () => { + const ctx = {req: {accessToken: 9}}; it('should return a summary object containing data from 1 ticket', async() => { const tx = await models.Ticket.beginTransaction({}); try { const options = {transaction: tx}; - const result = await models.Ticket.summary(1, options); + const result = await models.Ticket.summary(ctx, 1, options); expect(result.id).toEqual(1); expect(result.nickname).toEqual('Bat cave'); @@ -25,7 +26,7 @@ describe('ticket summary()', () => { try { const options = {transaction: tx}; - const result = await models.Ticket.summary(1, options); + const result = await models.Ticket.summary(ctx, 1, options); expect(result.sales.length).toEqual(4); @@ -42,7 +43,7 @@ describe('ticket summary()', () => { try { const options = {transaction: tx}; - const result = await models.Ticket.summary(1, options); + const result = await models.Ticket.summary(ctx, 1, options); expect(result.totalWithoutVat).toEqual(jasmine.any(Number)); @@ -59,7 +60,7 @@ describe('ticket summary()', () => { try { const options = {transaction: tx}; - const result = await models.Ticket.summary(1, options); + const result = await models.Ticket.summary(ctx, 1, options); expect(result.totalWithVat).toEqual(jasmine.any(Number)); diff --git a/modules/ticket/back/methods/ticket/specs/transferSales.spec.js b/modules/ticket/back/methods/ticket/specs/transferSales.spec.js index 270aae2f8..562688917 100644 --- a/modules/ticket/back/methods/ticket/specs/transferSales.spec.js +++ b/modules/ticket/back/methods/ticket/specs/transferSales.spec.js @@ -67,7 +67,7 @@ describe('sale transferSales()', () => { const ticketId = 11; const receiverTicketId = null; - const sales = await models.Ticket.getSales(ticketId, options); + const sales = await models.Ticket.getSales(ctx, ticketId, options); await models.Ticket.transferSales(ctx, ticketId, receiverTicketId, sales, options); @@ -89,7 +89,7 @@ describe('sale transferSales()', () => { const formerTicketId = 22; let createdTicketId = undefined; - let formerTicketSales = await models.Ticket.getSales(formerTicketId, options); + let formerTicketSales = await models.Ticket.getSales(ctx, formerTicketId, options); expect(formerTicketSales.length).toEqual(2); @@ -98,8 +98,8 @@ describe('sale transferSales()', () => { createdTicketId = createdTicket.id; - formerTicketSales = await models.Ticket.getSales(formerTicketId, options); - let createdTicketSales = await models.Ticket.getSales(createdTicketId, options); + formerTicketSales = await models.Ticket.getSales(ctx, formerTicketId, options); + let createdTicketSales = await models.Ticket.getSales(ctx, createdTicketId, options); expect(formerTicketSales.length).toEqual(0); expect(createdTicketSales.length).toEqual(2); @@ -120,7 +120,7 @@ describe('sale transferSales()', () => { const options = {transaction: tx}; const currentTicketId = 22; - const currentTicketSales = await models.Ticket.getSales(currentTicketId, options); + const currentTicketSales = await models.Ticket.getSales(ctx, currentTicketId, options); const receiverTicketId = undefined; @@ -147,7 +147,7 @@ describe('sale transferSales()', () => { const formerTicketId = 22; let createdTicketId = undefined; - let formerTicketSales = await models.Ticket.getSales(formerTicketId, options); + let formerTicketSales = await models.Ticket.getSales(ctx, formerTicketId, options); const completeSaleId = formerTicketSales[1].id; let partialSaleTotalQuantity = formerTicketSales[0].quantity; @@ -161,8 +161,8 @@ describe('sale transferSales()', () => { createdTicketId = createdTicket.id; - formerTicketSales = await models.Ticket.getSales(formerTicketId, options); - createdTicketSales = await models.Ticket.getSales(createdTicketId, options); + formerTicketSales = await models.Ticket.getSales(ctx, formerTicketId, options); + createdTicketSales = await models.Ticket.getSales(ctx, createdTicketId, options); const [createdPartialSale] = createdTicketSales.filter(sale => { return sale.id != completeSaleId; diff --git a/modules/ticket/back/methods/ticket/summary.js b/modules/ticket/back/methods/ticket/summary.js index a57968fc1..1ce91e1b2 100644 --- a/modules/ticket/back/methods/ticket/summary.js +++ b/modules/ticket/back/methods/ticket/summary.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('summary', { + Self.remoteMethodCtx('summary', { description: 'Returns a ticket summary', accessType: 'READ', accepts: [{ @@ -19,7 +19,7 @@ module.exports = Self => { } }); - Self.summary = async(ticketFk, options) => { + Self.summary = async(ctx, ticketFk, options) => { const models = Self.app.models; const myOptions = {}; @@ -28,7 +28,7 @@ module.exports = Self => { const summaryObj = await getTicketData(Self, ticketFk, myOptions); - summaryObj.sales = await models.Ticket.getSales(ticketFk, myOptions); + summaryObj.sales = await models.Ticket.getSales(ctx, ticketFk, myOptions); summaryObj.packagings = await models.TicketPackaging.find({ where: {ticketFk: ticketFk}, diff --git a/modules/ticket/back/methods/ticket/transferSales.js b/modules/ticket/back/methods/ticket/transferSales.js index 5737e628f..01ada49d0 100644 --- a/modules/ticket/back/methods/ticket/transferSales.js +++ b/modules/ticket/back/methods/ticket/transferSales.js @@ -36,7 +36,7 @@ module.exports = Self => { Self.transferSales = async(ctx, id, ticketId, sales, options) => { const userId = ctx.req.accessToken.userId; const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId}; let tx; if (typeof options == 'object') diff --git a/modules/ticket/back/methods/ticket/updateDiscount.js b/modules/ticket/back/methods/ticket/updateDiscount.js index 4b31c0ce4..6feeafa1a 100644 --- a/modules/ticket/back/methods/ticket/updateDiscount.js +++ b/modules/ticket/back/methods/ticket/updateDiscount.js @@ -44,7 +44,7 @@ module.exports = Self => { Self.updateDiscount = async(ctx, id, salesIds, newDiscount, manaCode, options) => { const $t = ctx.req.__; // $translate const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') diff --git a/modules/travel/back/methods/thermograph/createThermograph.js b/modules/travel/back/methods/thermograph/createThermograph.js index 75d967628..243e2129f 100644 --- a/modules/travel/back/methods/thermograph/createThermograph.js +++ b/modules/travel/back/methods/thermograph/createThermograph.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('createThermograph', { + Self.remoteMethodCtx('createThermograph', { description: 'Creates a new thermograph', accessType: 'WRITE', accepts: [{ @@ -36,10 +36,10 @@ module.exports = Self => { } }); - Self.createThermograph = async(thermographId, model, temperatureFk, warehouseId, options) => { + Self.createThermograph = async(ctx, thermographId, model, temperatureFk, warehouseId, options) => { const models = Self.app.models; let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; const date = Date.vnNew(); if (typeof options == 'object') diff --git a/modules/travel/back/methods/thermograph/specs/createThermograph.spec.js b/modules/travel/back/methods/thermograph/specs/createThermograph.spec.js index 32014e303..90855bf81 100644 --- a/modules/travel/back/methods/thermograph/specs/createThermograph.spec.js +++ b/modules/travel/back/methods/thermograph/specs/createThermograph.spec.js @@ -5,6 +5,7 @@ describe('Termograph createThermograph()', () => { const model = 'DISPOSABLE'; const temperatureFk = 'COOL'; const warehouseId = 1; + const ctx = {req: {accessToken: {userId: 9}}}; it(`should create a thermograph which is saved in both thermograph and travelThermograph`, async() => { const tx = await models.Thermograph.beginTransaction({}); @@ -12,7 +13,7 @@ describe('Termograph createThermograph()', () => { try { const options = {transaction: tx}; - const createdThermograph = await models.Thermograph.createThermograph(thermographId, model, temperatureFk, warehouseId, options); + const createdThermograph = await models.Thermograph.createThermograph(ctx, thermographId, model, temperatureFk, warehouseId, options); expect(createdThermograph.id).toEqual(thermographId); expect(createdThermograph.model).toEqual(model); @@ -37,8 +38,8 @@ describe('Termograph createThermograph()', () => { try { const options = {transaction: tx}; - await models.Thermograph.createThermograph(thermographId, model, temperatureFk, warehouseId, options); - await models.Thermograph.createThermograph(thermographId, model, temperatureFk, warehouseId, options); + await models.Thermograph.createThermograph(ctx, thermographId, model, temperatureFk, warehouseId, options); + await models.Thermograph.createThermograph(ctx, thermographId, model, temperatureFk, warehouseId, options); await tx.rollback(); } catch (e) { diff --git a/modules/travel/back/methods/travel/deleteThermograph.js b/modules/travel/back/methods/travel/deleteThermograph.js index ba541c560..d22fc8b29 100644 --- a/modules/travel/back/methods/travel/deleteThermograph.js +++ b/modules/travel/back/methods/travel/deleteThermograph.js @@ -26,9 +26,9 @@ module.exports = Self => { await models.Dms.removeFile(ctx, travelThermograph.dmsFk); await Self.rawSql(` - UPDATE travelThermograph - SET travelFk = NULL, dmsFk = NULL - WHERE id = ?`, [id]); + UPDATE travelThermograph + SET travelFk = NULL, dmsFk = NULL + WHERE id = ?`, [id], {userId}); const oldInstance = { travelFk: travelThermograph.travelFk, diff --git a/modules/worker/back/methods/department/getLeaves.js b/modules/worker/back/methods/department/getLeaves.js index 614f3388e..48fe78e08 100644 --- a/modules/worker/back/methods/department/getLeaves.js +++ b/modules/worker/back/methods/department/getLeaves.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('getLeaves', { + Self.remoteMethodCtx, ('getLeaves', { description: 'Returns the nodes for a department', accepts: [{ arg: 'parentId', @@ -20,10 +20,11 @@ module.exports = Self => { } }); - Self.getLeaves = async(parentId = null, search) => { + Self.getLeaves = async(ctx, parentId = null, search) => { let [res] = await Self.rawSql( `CALL department_getLeaves(?, ?)`, - [parentId, search] + [parentId, search], + {userId: ctx.req.accessToken.userId} ); let map = new Map(); diff --git a/modules/worker/back/methods/worker-time-control/addTimeEntry.js b/modules/worker/back/methods/worker-time-control/addTimeEntry.js index bcc96985f..cc652fb90 100644 --- a/modules/worker/back/methods/worker-time-control/addTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/addTimeEntry.js @@ -33,15 +33,15 @@ module.exports = Self => { Self.addTimeEntry = async(ctx, workerId, options) => { const models = Self.app.models; const args = ctx.args; - const currentUserId = ctx.req.accessToken.userId; - const myOptions = {}; + const userId = ctx.req.accessToken.userId; + const myOptions = {userId}; if (typeof options == 'object') Object.assign(myOptions, options); const isSubordinate = await models.Worker.isSubordinate(ctx, workerId, myOptions); const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); - const isHimself = currentUserId == workerId; + const isHimself = userId == workerId; if (!isSubordinate || (isSubordinate && isHimself && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); diff --git a/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js b/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js index 80482901f..8f9541596 100644 --- a/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js @@ -22,10 +22,10 @@ module.exports = Self => { }); Self.deleteTimeEntry = async(ctx, id, options) => { - const currentUserId = ctx.req.accessToken.userId; + const userId = ctx.req.accessToken.userId; const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId}; if (typeof options == 'object') Object.assign(myOptions, options); @@ -33,7 +33,7 @@ module.exports = Self => { const targetTimeEntry = await Self.findById(id, null, myOptions); const isSubordinate = await models.Worker.isSubordinate(ctx, targetTimeEntry.userFk, myOptions); const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); - const isHimself = currentUserId == targetTimeEntry.userFk; + const isHimself = userId == targetTimeEntry.userFk; if (isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); diff --git a/modules/worker/back/methods/worker-time-control/sendMail.js b/modules/worker/back/methods/worker-time-control/sendMail.js index 3d57ebbbd..ab5e56a77 100644 --- a/modules/worker/back/methods/worker-time-control/sendMail.js +++ b/modules/worker/back/methods/worker-time-control/sendMail.js @@ -33,7 +33,7 @@ module.exports = Self => { const conn = Self.dataSource.connector; const args = ctx.args; let tx; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 398411118..27acc98ab 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -119,7 +119,7 @@ module.exports = Self => { Self.new = async(ctx, options) => { const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; const args = ctx.args; let tx; diff --git a/modules/worker/back/methods/worker/specs/new.spec.js b/modules/worker/back/methods/worker/specs/new.spec.js index 44f6e9b09..b2804c203 100644 --- a/modules/worker/back/methods/worker/specs/new.spec.js +++ b/modules/worker/back/methods/worker/specs/new.spec.js @@ -36,6 +36,7 @@ describe('Worker new', () => { payMethodFk: 1, roleFk: 1 }; + const req = {accessToken: {userId: 9}}; it('should return error if personal mail already exists', async() => { const user = await models.VnUser.findById(employeeId, {fields: ['email']}); @@ -46,7 +47,8 @@ describe('Worker new', () => { try { const options = {transaction: tx}; const ctx = { - args: Object.assign({}, defaultWorker, {email: user.email}) + args: Object.assign({}, defaultWorker, {email: user.email}), + req }; await models.Worker.new(ctx, options); @@ -69,7 +71,8 @@ describe('Worker new', () => { try { const options = {transaction: tx}; const ctx = { - args: Object.assign({}, defaultWorker, {code: worker.code}) + args: Object.assign({}, defaultWorker, {code: worker.code}), + req }; await models.Worker.new(ctx, options); @@ -92,7 +95,8 @@ describe('Worker new', () => { try { const options = {transaction: tx}; const ctx = { - args: Object.assign({}, defaultWorker, {fi: worker.fi}) + args: Object.assign({}, defaultWorker, {fi: worker.fi}), + req }; await models.Worker.new(ctx, options); @@ -119,7 +123,8 @@ describe('Worker new', () => { try { const options = {transaction: tx}; const ctx = { - args: Object.assign({}, defaultWorker, {payMethodFk: payMethodIbanRequired.id}) + args: Object.assign({}, defaultWorker, {payMethodFk: payMethodIbanRequired.id}), + req }; await models.Worker.new(ctx, options); @@ -133,7 +138,7 @@ describe('Worker new', () => { }); it('should create a new worker', async() => { - const newWorker = await models.Worker.new({args: defaultWorker}); + const newWorker = await models.Worker.new({args: defaultWorker, req}); await models.Worker.destroyById(newWorker.id); await models.Address.destroyAll({clientFk: newWorker.id}); @@ -155,7 +160,8 @@ describe('Worker new', () => { { fi: client.fi, email: client.email - }) + }), + req }; const newWorker = await models.Worker.new(newWorkerData); diff --git a/modules/zone/back/methods/agency/getAgenciesWithWarehouse.js b/modules/zone/back/methods/agency/getAgenciesWithWarehouse.js index 846ad6a3d..c8ab4f67c 100644 --- a/modules/zone/back/methods/agency/getAgenciesWithWarehouse.js +++ b/modules/zone/back/methods/agency/getAgenciesWithWarehouse.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('getAgenciesWithWarehouse', { + Self.remoteMethodCtx('getAgenciesWithWarehouse', { description: 'Returns a list of agencies that can land a shipment on a day for an address and a warehouse', accepts: [ { @@ -28,8 +28,8 @@ module.exports = Self => { } }); - Self.getAgenciesWithWarehouse = async(addressFk, landed, warehouseFk, options) => { - const myOptions = {}; + Self.getAgenciesWithWarehouse = async(ctx, addressFk, landed, warehouseFk, options) => { + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/agency/landsThatDay.js b/modules/zone/back/methods/agency/landsThatDay.js index b7f13ddda..4d73e4d08 100644 --- a/modules/zone/back/methods/agency/landsThatDay.js +++ b/modules/zone/back/methods/agency/landsThatDay.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('landsThatDay', { + Self.remoteMethodCtx('landsThatDay', { description: 'Returns a list of agencies that can land a shipment on a day for an address', accepts: [ { @@ -22,8 +22,8 @@ module.exports = Self => { } }); - Self.landsThatDay = async(addressFk, landed, options) => { - const myOptions = {}; + Self.landsThatDay = async(ctx, addressFk, landed, options) => { + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/agency/specs/getAgenciesWithWarehouse.spec.js b/modules/zone/back/methods/agency/specs/getAgenciesWithWarehouse.spec.js index 4f79b2315..f760559cb 100644 --- a/modules/zone/back/methods/agency/specs/getAgenciesWithWarehouse.spec.js +++ b/modules/zone/back/methods/agency/specs/getAgenciesWithWarehouse.spec.js @@ -2,6 +2,7 @@ const app = require('vn-loopback/server/server'); describe('Agency getAgenciesWithWarehouse()', () => { const today = Date.vnNew(); + const ctx = {req: {accessToken: {userId: 9}}}; it('should return the agencies that can handle the given delivery request', async() => { const tx = await app.models.Zone.beginTransaction({}); @@ -9,7 +10,7 @@ describe('Agency getAgenciesWithWarehouse()', () => { const options = {transaction: tx}; const addressId = 101; - const agencies = await app.models.Agency.getAgenciesWithWarehouse(addressId, today, 1, options); + const agencies = await app.models.Agency.getAgenciesWithWarehouse(ctx, addressId, today, 1, options); expect(agencies.length).toEqual(3); expect(agencies[0].agencyMode).toEqual('inhouse pickup'); @@ -30,7 +31,7 @@ describe('Agency getAgenciesWithWarehouse()', () => { const options = {transaction: tx}; const addressId = 101; - const agencies = await app.models.Agency.getAgenciesWithWarehouse(addressId, null, 1, options); + const agencies = await app.models.Agency.getAgenciesWithWarehouse(ctx, addressId, null, 1, options); expect(agencies.length).toEqual(0); diff --git a/modules/zone/back/methods/agency/specs/landsThatDay.spec.js b/modules/zone/back/methods/agency/specs/landsThatDay.spec.js index 4bde37984..1ec675071 100644 --- a/modules/zone/back/methods/agency/specs/landsThatDay.spec.js +++ b/modules/zone/back/methods/agency/specs/landsThatDay.spec.js @@ -1,6 +1,7 @@ const {models} = require('vn-loopback/server/server'); describe('Agency landsThatDay()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; const today = Date.vnNew(); it('should return a list of agencies that can land a shipment on a day for an address', async() => { const tx = await models.Agency.beginTransaction({}); @@ -8,7 +9,7 @@ describe('Agency landsThatDay()', () => { try { const options = {transaction: tx}; - const agencies = await models.Agency.landsThatDay(101, today, options); + const agencies = await models.Agency.landsThatDay(ctx, 101, today, options); expect(agencies.length).toBeGreaterThanOrEqual(3); diff --git a/modules/zone/back/methods/zone/deleteZone.js b/modules/zone/back/methods/zone/deleteZone.js index e3846132b..bcfb91e3d 100644 --- a/modules/zone/back/methods/zone/deleteZone.js +++ b/modules/zone/back/methods/zone/deleteZone.js @@ -26,7 +26,7 @@ module.exports = Self => { today.setHours(0, 0, 0, 0); let tx; - const myOptions = {}; + const myOptions = {userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/zone/getEvents.js b/modules/zone/back/methods/zone/getEvents.js index a8ee8bb7b..03fb31438 100644 --- a/modules/zone/back/methods/zone/getEvents.js +++ b/modules/zone/back/methods/zone/getEvents.js @@ -1,6 +1,6 @@ module.exports = Self => { - Self.remoteMethod('getEvents', { + Self.remoteMethodCtx('getEvents', { description: 'Returns delivery days for a postcode', accepts: [ { @@ -25,8 +25,8 @@ module.exports = Self => { } }); - Self.getEvents = async(geoFk, agencyModeFk, options) => { - const myOptions = {}; + Self.getEvents = async(ctx, geoFk, agencyModeFk, options) => { + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/zone/getLeaves.js b/modules/zone/back/methods/zone/getLeaves.js index ed421e339..a6db3b711 100644 --- a/modules/zone/back/methods/zone/getLeaves.js +++ b/modules/zone/back/methods/zone/getLeaves.js @@ -1,6 +1,6 @@ module.exports = Self => { - Self.remoteMethod('getLeaves', { + Self.remoteMethodCtx('getLeaves', { description: 'Returns the nodes for a zone', accepts: [ { @@ -31,8 +31,8 @@ module.exports = Self => { } }); - Self.getLeaves = async(id, parentId = null, search, options) => { - const myOptions = {}; + Self.getLeaves = async(ctx, id, parentId = null, search, options) => { + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/zone/getUpcomingDeliveries.js b/modules/zone/back/methods/zone/getUpcomingDeliveries.js index 2a1c39ed6..e8b7e7636 100644 --- a/modules/zone/back/methods/zone/getUpcomingDeliveries.js +++ b/modules/zone/back/methods/zone/getUpcomingDeliveries.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('getUpcomingDeliveries', { + Self.remoteMethodCtx('getUpcomingDeliveries', { description: 'Returns the upcomings deliveries', accessType: 'READ', accepts: [], @@ -13,8 +13,8 @@ module.exports = Self => { } }); - Self.getUpcomingDeliveries = async options => { - const myOptions = {}; + Self.getUpcomingDeliveries = async(ctx, options) => { + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/zone/specs/getEvents.spec.js b/modules/zone/back/methods/zone/specs/getEvents.spec.js index d1c51baff..c1dee3e0f 100644 --- a/modules/zone/back/methods/zone/specs/getEvents.spec.js +++ b/modules/zone/back/methods/zone/specs/getEvents.spec.js @@ -1,13 +1,14 @@ const models = require('vn-loopback/server/server').models; describe('zone getEvents()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; it('should return all events for the specified geo and agency mode', async() => { const tx = await models.Zone.beginTransaction({}); try { const options = {transaction: tx}; - let result = await models.Zone.getEvents(20, 1, options); + let result = await models.Zone.getEvents(ctx, 20, 1, options); expect(result.events.length).toEqual(10); diff --git a/modules/zone/back/methods/zone/specs/getLeaves.spec.js b/modules/zone/back/methods/zone/specs/getLeaves.spec.js index db7359671..9342a0b50 100644 --- a/modules/zone/back/methods/zone/specs/getLeaves.spec.js +++ b/modules/zone/back/methods/zone/specs/getLeaves.spec.js @@ -1,13 +1,14 @@ const models = require('vn-loopback/server/server').models; describe('zone getLeaves()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; it('should return the country and the childs containing the search value', async() => { const tx = await models.Zone.beginTransaction({}); try { const options = {transaction: tx}; - let result = await models.Zone.getLeaves(1, null, '46000', options); + let result = await models.Zone.getLeaves(ctx, 1, null, '46000', options); expect(result.length).toEqual(1); diff --git a/modules/zone/back/methods/zone/specs/getUpcomingDeliveries.spec.js b/modules/zone/back/methods/zone/specs/getUpcomingDeliveries.spec.js index acef079f6..fe542fbf3 100644 --- a/modules/zone/back/methods/zone/specs/getUpcomingDeliveries.spec.js +++ b/modules/zone/back/methods/zone/specs/getUpcomingDeliveries.spec.js @@ -1,12 +1,13 @@ const models = require('vn-loopback/server/server').models; describe('zone getUpcomingDeliveries()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; it('should check returns data', async() => { const tx = await models.Zone.beginTransaction({}); try { const options = {transaction: tx}; - let result = await models.Zone.getUpcomingDeliveries(options); + let result = await models.Zone.getUpcomingDeliveries(ctx, options); const firstResultLines = result[0].lines; const secondResultLines = result[1].lines; From 1c39ad873c276e992881e800ca81ef011eecd4eb Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 12 Jun 2023 11:06:45 +0200 Subject: [PATCH 092/170] resolve dev conflicts --- back/models/vn-user.js | 1 - .../account/back/methods/account/specs/set-password.spec.js | 5 ++--- modules/client/back/methods/client/specs/setPassword.spec.js | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index bf568e85c..fb3279353 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -110,7 +110,6 @@ module.exports = function(Self) { const _setPassword = Self.prototype.setPassword; Self.prototype.setPassword = async function(newPassword, options, cb) { - console.log('ENTRY'); if (cb === undefined && typeof options === 'function') { cb = options; options = undefined; diff --git a/modules/account/back/methods/account/specs/set-password.spec.js b/modules/account/back/methods/account/specs/set-password.spec.js index f54fba36f..5de2a7bad 100644 --- a/modules/account/back/methods/account/specs/set-password.spec.js +++ b/modules/account/back/methods/account/specs/set-password.spec.js @@ -1,15 +1,14 @@ const {models} = require('vn-loopback/server/server'); describe('Account setPassword()', () => { - const ctx = {req: {accessToken: {userId: 9}}}; it('should throw an error when password does not meet requirements', async() => { - let req = models.Account.setPassword(ctx, 1, 'insecurePass'); + let req = models.Account.setPassword(1, 'insecurePass'); await expectAsync(req).toBeRejected(); }); it('should update password when it passes requirements', async() => { - let req = models.Account.setPassword(ctx, 1, 'Very$ecurePa22.'); + let req = models.Account.setPassword(1, 'Very$ecurePa22.'); await expectAsync(req).toBeResolved(); }); diff --git a/modules/client/back/methods/client/specs/setPassword.spec.js b/modules/client/back/methods/client/specs/setPassword.spec.js index c004b0372..590172a02 100644 --- a/modules/client/back/methods/client/specs/setPassword.spec.js +++ b/modules/client/back/methods/client/specs/setPassword.spec.js @@ -1,12 +1,11 @@ const models = require('vn-loopback/server/server').models; describe('Client setPassword', () => { - const ctx = {req: {accessToken: {userId: 9}}}; it('should throw an error the setPassword target is not just a client but a worker', async() => { let error; try { - await models.Client.setPassword(ctx, 1, 't0pl3v3l.p455w0rd!'); + await models.Client.setPassword(1, 't0pl3v3l.p455w0rd!'); } catch (e) { error = e; } @@ -18,7 +17,7 @@ describe('Client setPassword', () => { let error; try { - await models.Client.setPassword(ctx, 1101, 't0pl3v3l.p455w0rd!'); + await models.Client.setPassword(1101, 't0pl3v3l.p455w0rd!'); } catch (e) { error = e; } From d3c4a6ba5c68a0458cefa0c4c0867b3ab9530f41 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 12 Jun 2023 15:20:46 +0200 Subject: [PATCH 093/170] refs #5094 feat(ticket_index): docuware multiple deliveryNote --- back/methods/docuware/core.js | 8 +- back/methods/docuware/upload.js | 227 +++++++++--------- loopback/locale/en.json | 3 +- loopback/locale/es.json | 2 +- modules/ticket/front/descriptor-menu/index.js | 8 +- .../front/descriptor-menu/index.spec.js | 4 +- modules/ticket/front/index/index.html | 42 ++-- modules/ticket/front/index/index.js | 31 +-- 8 files changed, 161 insertions(+), 164 deletions(-) diff --git a/back/methods/docuware/core.js b/back/methods/docuware/core.js index 2053ddf85..be310e82b 100644 --- a/back/methods/docuware/core.js +++ b/back/methods/docuware/core.js @@ -20,8 +20,8 @@ module.exports = Self => { const options = await Self.getOptions(); - if (!process.env.NODE_ENV) - return Math.round(); + // if (!process.env.NODE_ENV) + // return Math.round(); const response = await axios.get(`${options.url}/FileCabinets/${fileCabinetId}/dialogs`, options.headers); const dialogs = response.data.Dialog; @@ -44,8 +44,8 @@ module.exports = Self => { } }); - if (!process.env.NODE_ENV) - return Math.round(); + // if (!process.env.NODE_ENV) + // return Math.round(); const fileCabinetResponse = await axios.get(`${options.url}/FileCabinets`, options.headers); const fileCabinets = fileCabinetResponse.data.FileCabinet; diff --git a/back/methods/docuware/upload.js b/back/methods/docuware/upload.js index ea9ee3622..d14e8a668 100644 --- a/back/methods/docuware/upload.js +++ b/back/methods/docuware/upload.js @@ -7,30 +7,27 @@ module.exports = Self => { accessType: 'WRITE', accepts: [ { - arg: 'id', - type: 'number', - description: 'The ticket id', - http: {source: 'path'} + arg: 'ticketIds', + type: ['number'], + description: 'The ticket ids', + required: true }, { arg: 'fileCabinet', type: 'string', - description: 'The file cabinet' - }, - { - arg: 'dialog', - type: 'string', - description: 'The dialog' + description: 'The file cabinet', + required: true } ], returns: [], http: { - path: `/:id/upload`, + path: `/upload`, verb: 'POST' } }); - Self.upload = async function(ctx, id, fileCabinet) { + Self.upload = async function(ctx, ticketIds, fileCabinet) { + delete ctx.args.ticketIds; const models = Self.app.models; const action = 'store'; @@ -38,104 +35,116 @@ module.exports = Self => { const fileCabinetId = await Self.getFileCabinet(fileCabinet); const dialogId = await Self.getDialog(fileCabinet, action, fileCabinetId); + const uploaded = []; + // get delivery note - const deliveryNote = await models.Ticket.deliveryNotePdf(ctx, { - id, - type: 'deliveryNote' - }); - - // get ticket data - const ticket = await models.Ticket.findById(id, { - include: [{ - relation: 'client', - scope: { - fields: ['id', 'socialName', 'fi'] - } - }] - }); - - // upload file - const templateJson = { - 'Fields': [ - { - 'FieldName': 'N__ALBAR_N', - 'ItemElementName': 'string', - 'Item': id, - }, - { - 'FieldName': 'CIF_PROVEEDOR', - 'ItemElementName': 'string', - 'Item': ticket.client().fi, - }, - { - 'FieldName': 'CODIGO_PROVEEDOR', - 'ItemElementName': 'string', - 'Item': ticket.client().id, - }, - { - 'FieldName': 'NOMBRE_PROVEEDOR', - 'ItemElementName': 'string', - 'Item': ticket.client().socialName, - }, - { - 'FieldName': 'FECHA_FACTURA', - 'ItemElementName': 'date', - 'Item': ticket.shipped, - }, - { - 'FieldName': 'TOTAL_FACTURA', - 'ItemElementName': 'Decimal', - 'Item': ticket.totalWithVat, - }, - { - 'FieldName': 'ESTADO', - 'ItemElementName': 'string', - 'Item': 'Pendiente procesar', - }, - { - 'FieldName': 'FIRMA_', - 'ItemElementName': 'string', - 'Item': 'Si', - }, - { - 'FieldName': 'FILTRO_TABLET', - 'ItemElementName': 'string', - 'Item': 'Tablet1', - } - ] - }; - - if (process.env.NODE_ENV != 'production') - throw new UserError('Action not allowed on the test environment'); - - // delete old - const docuwareFile = await models.Docuware.checkFile(ctx, id, fileCabinet, false); - if (docuwareFile) { - const deleteJson = { - 'Field': [{'FieldName': 'ESTADO', 'Item': 'Pendiente eliminar', 'ItemElementName': 'String'}] - }; - const deleteUri = `${options.url}/FileCabinets/${fileCabinetId}/Documents/${docuwareFile.id}/Fields`; - await axios.put(deleteUri, deleteJson, options.headers); - } - - const uploadUri = `${options.url}/FileCabinets/${fileCabinetId}/Documents?StoreDialogId=${dialogId}`; - const FormData = require('form-data'); - const data = new FormData(); - - data.append('document', JSON.stringify(templateJson), 'schema.json'); - data.append('file[]', deliveryNote[0], 'file.pdf'); - const uploadOptions = { - headers: { - 'Content-Type': 'multipart/form-data', - 'X-File-ModifiedDate': Date.vnNew(), - 'Cookie': options.headers.headers.Cookie, - ...data.getHeaders() - }, - }; - - return await axios.post(uploadUri, data, uploadOptions) - .catch(() => { - throw new UserError('Failed to upload file'); + for (id of ticketIds) { + // get delivery note + ctx.args.id = id; + const deliveryNote = await models.Ticket.deliveryNotePdf(ctx, { + id, + type: 'deliveryNote' }); + // get ticket data + const ticket = await models.Ticket.findById(id, { + include: [{ + relation: 'client', + scope: { + fields: ['id', 'name', 'fi'] + } + }] + }); + + // upload file + const templateJson = { + 'Fields': [ + { + 'FieldName': 'N__ALBAR_N', + 'ItemElementName': 'string', + 'Item': id, + }, + { + 'FieldName': 'CIF_PROVEEDOR', + 'ItemElementName': 'string', + 'Item': ticket.client().fi, + }, + { + 'FieldName': 'CODIGO_PROVEEDOR', + 'ItemElementName': 'string', + 'Item': ticket.client().id, + }, + { + 'FieldName': 'NOMBRE_PROVEEDOR', + 'ItemElementName': 'string', + 'Item': ticket.client().name + ' - ' + id, + }, + { + 'FieldName': 'FECHA_FACTURA', + 'ItemElementName': 'date', + 'Item': ticket.shipped, + }, + { + 'FieldName': 'TOTAL_FACTURA', + 'ItemElementName': 'Decimal', + 'Item': ticket.totalWithVat, + }, + { + 'FieldName': 'ESTADO', + 'ItemElementName': 'string', + 'Item': 'Pendiente procesar', + }, + { + 'FieldName': 'FIRMA_', + 'ItemElementName': 'string', + 'Item': 'Si', + }, + { + 'FieldName': 'FILTRO_TABLET', + 'ItemElementName': 'string', + 'Item': 'Tablet1', + } + ] + }; + + // if (process.env.NODE_ENV != 'production') + // throw new UserError('Action not allowed on the test environment'); + + // delete old + const docuwareFile = await models.Docuware.checkFile(ctx, id, fileCabinet, false); + if (docuwareFile) { + const deleteJson = { + 'Field': [{'FieldName': 'ESTADO', 'Item': 'Pendiente eliminar', 'ItemElementName': 'String'}] + }; + const deleteUri = `${options.url}/FileCabinets/${fileCabinetId}/Documents/${docuwareFile.id}/Fields`; + await axios.put(deleteUri, deleteJson, options.headers); + } + + const uploadUri = `${options.url}/FileCabinets/${fileCabinetId}/Documents?StoreDialogId=${dialogId}`; + const FormData = require('form-data'); + const data = new FormData(); + + data.append('document', JSON.stringify(templateJson), 'schema.json'); + data.append('file[]', deliveryNote[0], 'file.pdf'); + const uploadOptions = { + headers: { + 'Content-Type': 'multipart/form-data', + 'X-File-ModifiedDate': Date.vnNew(), + 'Cookie': options.headers.headers.Cookie, + ...data.getHeaders() + }, + }; + + try { + await axios.post(uploadUri, data, uploadOptions); + } catch (err) { + const $t = ctx.req.__; + const message = $t('Failed to upload ticket', {id}); + if (uploaded.length) + await models.TicketTracking.setDelivered(ctx, uploaded); + throw new UserError(message); + } + uploaded.push(id); + } + return models.TicketTracking.setDelivered(ctx, ticketIds); }; }; diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 14ffffeb5..b334b8676 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -173,5 +173,6 @@ "This ticket is already a refund": "This ticket is already a refund", "A claim with that sale already exists": "A claim with that sale already exists", "Can't transfer claimed sales": "Can't transfer claimed sales", - "Invalid quantity": "Invalid quantity" + "Invalid quantity": "Invalid quantity", + "Failed to upload delivery note": "Error to upload delivery note {{id}}" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index d88a4ebc9..bd49db9b3 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -259,7 +259,7 @@ "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 file": "Error al subir archivo", + "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", diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index 835f395a8..17a34ad59 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -326,14 +326,8 @@ class Controller extends Section { if (!force) return this.$.pdfToTablet.show(); - return this.$http.post(`Docuwares/${this.id}/upload`, {fileCabinet: 'deliveryNote'}) + return this.$http.post(`Docuwares/upload`, {fileCabinet: 'deliveryNote', ticketIds: [this.id]}) .then(() => { - this.$.balanceCreate.amountPaid = this.ticket.totalWithVat; - this.$.balanceCreate.clientFk = this.ticket.clientFk; - this.$.balanceCreate.description = 'Albaran: '; - this.$.balanceCreate.description += this.ticket.id; - - this.$.balanceCreate.show(); this.vnApp.showSuccess(this.$t('PDF sent!')); }); } diff --git a/modules/ticket/front/descriptor-menu/index.spec.js b/modules/ticket/front/descriptor-menu/index.spec.js index 5d27acff1..95a580fe5 100644 --- a/modules/ticket/front/descriptor-menu/index.spec.js +++ b/modules/ticket/front/descriptor-menu/index.spec.js @@ -304,9 +304,8 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { expect(controller.$.pdfToTablet.show).toHaveBeenCalled(); }); - it('should make a query and show balance create', () => { + it('should make a query', () => { controller.$.balanceCreate = {show: () => {}}; - jest.spyOn(controller.$.balanceCreate, 'show'); jest.spyOn(controller.vnApp, 'showSuccess'); $httpBackend.whenPOST(`Docuwares/${ticket.id}/upload`).respond(true); @@ -314,7 +313,6 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { $httpBackend.flush(); expect(controller.vnApp.showSuccess).toHaveBeenCalled(); - expect(controller.$.balanceCreate.show).toHaveBeenCalled(); }); }); diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index 1e18ce284..d6e230ebe 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -9,7 +9,7 @@ - @@ -33,7 +33,7 @@ class="clickable vn-tr search-result" ui-sref="ticket.card.summary({id: {{::ticket.id}}})"> - @@ -109,7 +109,7 @@ class="link"> {{::ticket.refFk}} - {{ticket.state}} @@ -132,8 +132,8 @@
- - - - - - Filter by selection - Exclude selection - Remove filter - Remove all filters - Copy value @@ -241,4 +241,4 @@ on-accept="$ctrl.makeInvoice()" question="{{$ctrl.confirmationMessage}}" message="Invoice selected tickets"> - \ No newline at end of file + diff --git a/modules/ticket/front/index/index.js b/modules/ticket/front/index/index.js index 42332ccc8..55229eabb 100644 --- a/modules/ticket/front/index/index.js +++ b/modules/ticket/front/index/index.js @@ -9,28 +9,23 @@ export default class Controller extends Section { this.vnReport = vnReport; } - setDelivered() { + sendDocuware() { const checkedTickets = this.checked; - let ids = []; + let ticketIds = []; for (let ticket of checkedTickets) - ids.push(ticket.id); + ticketIds.push(ticket.id); - this.$http.post('TicketTrackings/setDelivered', ids).then(res => { - let state = res.data; - for (let ticket of checkedTickets) { - ticket.stateFk = state.id; - ticket.state = state.name; - ticket.alertLevel = state.alertLevel; - ticket.alertLevelCode = state.code; - } - this.openDeliveryNotes(ids); - }); - } - - openDeliveryNotes(ids) { - for (let id of ids) - this.vnReport.show(`Tickets/${id}/delivery-note-pdf`); + return this.$http.post(`Docuwares/upload`, {fileCabinet: 'deliveryNote', ticketIds}) + .then(res => { + let state = res.data; + for (let ticket of checkedTickets) { + ticket.stateFk = state.id; + ticket.state = state.name; + ticket.alertLevel = state.alertLevel; + ticket.alertLevelCode = state.code; + } + }); } openBalanceDialog() { From 59642ab3ca579cc7bb90ea349ebe6cce1dce5a2a Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 12 Jun 2023 15:44:22 +0200 Subject: [PATCH 094/170] refs #5325 defaultSearch --- modules/claim/front/action/index.js | 1 + modules/claim/front/index/index.js | 1 + modules/client/front/defaulter/index.js | 1 + modules/client/front/extended-list/index.js | 1 + modules/client/front/notification/index.js | 1 + modules/entry/front/latest-buys/index.js | 1 + modules/invoiceOut/front/negative-bases/index.js | 4 +++- modules/item/front/index/index.js | 1 + modules/item/front/item-shelving/index.js | 1 + modules/monitor/front/index/clients/index.js | 1 + modules/monitor/front/index/tickets/index.js | 1 + modules/route/front/agency-term/index/index.js | 1 + modules/ticket/front/advance/index.js | 1 + modules/ticket/front/expedition/index.js | 1 + modules/ticket/front/future/index.js | 1 + modules/ticket/front/weekly/index.js | 1 + 16 files changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/claim/front/action/index.js b/modules/claim/front/action/index.js index 10b629f27..6b4879a85 100644 --- a/modules/claim/front/action/index.js +++ b/modules/claim/front/action/index.js @@ -26,6 +26,7 @@ export default class Controller extends Section { activeButtons: { search: true }, + defaultSearch: true, columns: [ { field: 'claimDestinationFk', diff --git a/modules/claim/front/index/index.js b/modules/claim/front/index/index.js index e3fdabf79..8e948f426 100644 --- a/modules/claim/front/index/index.js +++ b/modules/claim/front/index/index.js @@ -9,6 +9,7 @@ class Controller extends Section { activeButtons: { search: true }, + defaultSearch: true, columns: [ { field: 'clientName', diff --git a/modules/client/front/defaulter/index.js b/modules/client/front/defaulter/index.js index 95c7622f9..1244191f1 100644 --- a/modules/client/front/defaulter/index.js +++ b/modules/client/front/defaulter/index.js @@ -12,6 +12,7 @@ export default class Controller extends Section { activeButtons: { search: true }, + defaultSearch: true, columns: [ { field: 'clientFk', diff --git a/modules/client/front/extended-list/index.js b/modules/client/front/extended-list/index.js index 8eed48d01..2cb7a6d58 100644 --- a/modules/client/front/extended-list/index.js +++ b/modules/client/front/extended-list/index.js @@ -11,6 +11,7 @@ class Controller extends Section { search: true, shownColumns: true, }, + defaultSearch: true, columns: [ { field: 'socialName', diff --git a/modules/client/front/notification/index.js b/modules/client/front/notification/index.js index faa062b25..ada543715 100644 --- a/modules/client/front/notification/index.js +++ b/modules/client/front/notification/index.js @@ -9,6 +9,7 @@ export default class Controller extends Section { activeButtons: { search: true }, + defaultSearch: true, columns: [ { field: 'socialName', diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js index d9065193e..1a9b3627b 100644 --- a/modules/entry/front/latest-buys/index.js +++ b/modules/entry/front/latest-buys/index.js @@ -14,6 +14,7 @@ export default class Controller extends Section { search: true, shownColumns: true, }, + defaultSearch: true, columns: [ { field: 'code', diff --git a/modules/invoiceOut/front/negative-bases/index.js b/modules/invoiceOut/front/negative-bases/index.js index 1a838507c..b70a2f7be 100644 --- a/modules/invoiceOut/front/negative-bases/index.js +++ b/modules/invoiceOut/front/negative-bases/index.js @@ -19,7 +19,9 @@ export default class Controller extends Section { this.smartTableOptions = { activeButtons: { search: true, - }, columns: [ + }, + defaultSearch: true, + columns: [ { field: 'isActive', searchable: false diff --git a/modules/item/front/index/index.js b/modules/item/front/index/index.js index 10bd4bbb7..f341f6454 100644 --- a/modules/item/front/index/index.js +++ b/modules/item/front/index/index.js @@ -11,6 +11,7 @@ class Controller extends Section { search: true, shownColumns: true, }, + defaultSearch: true, columns: [ { field: 'category', diff --git a/modules/item/front/item-shelving/index.js b/modules/item/front/item-shelving/index.js index b8584039b..8e5df459d 100644 --- a/modules/item/front/item-shelving/index.js +++ b/modules/item/front/item-shelving/index.js @@ -9,6 +9,7 @@ export default class Controller extends Section { activeButtons: { search: true }, + defaultSearch: true, columns: [ { field: 'parking', diff --git a/modules/monitor/front/index/clients/index.js b/modules/monitor/front/index/clients/index.js index ac3ce9140..9faf2ed53 100644 --- a/modules/monitor/front/index/clients/index.js +++ b/modules/monitor/front/index/clients/index.js @@ -20,6 +20,7 @@ export default class Controller extends Section { activeButtons: { search: true }, + defaultSearch: true, columns: [ { field: 'clientFk', diff --git a/modules/monitor/front/index/tickets/index.js b/modules/monitor/front/index/tickets/index.js index 2f2dead05..92097833b 100644 --- a/modules/monitor/front/index/tickets/index.js +++ b/modules/monitor/front/index/tickets/index.js @@ -12,6 +12,7 @@ export default class Controller extends Section { search: true, shownColumns: true, }, + defaultSearch: true, columns: [ { field: 'totalProblems', diff --git a/modules/route/front/agency-term/index/index.js b/modules/route/front/agency-term/index/index.js index 6c3bafc9a..6277fb9a1 100644 --- a/modules/route/front/agency-term/index/index.js +++ b/modules/route/front/agency-term/index/index.js @@ -9,6 +9,7 @@ class Controller extends Section { activeButtons: { search: true }, + defaultSearch: true, columns: [ { field: 'agencyModeFk', diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index 0cec41227..0cd1b0981 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -11,6 +11,7 @@ export default class Controller extends Section { activeButtons: { search: true, }, + defaultSearch: true, columns: [ { field: 'state', diff --git a/modules/ticket/front/expedition/index.js b/modules/ticket/front/expedition/index.js index b8046be52..1e30ce447 100644 --- a/modules/ticket/front/expedition/index.js +++ b/modules/ticket/front/expedition/index.js @@ -11,6 +11,7 @@ class Controller extends Section { search: true, shownColumns: true, }, + defaultSearch: true, columns: [ { field: 'packageItemName', diff --git a/modules/ticket/front/future/index.js b/modules/ticket/front/future/index.js index 66d626993..846c3883f 100644 --- a/modules/ticket/front/future/index.js +++ b/modules/ticket/front/future/index.js @@ -10,6 +10,7 @@ export default class Controller extends Section { activeButtons: { search: true, }, + defaultSearch: true, columns: [{ field: 'totalProblems', searchable: false, diff --git a/modules/ticket/front/weekly/index.js b/modules/ticket/front/weekly/index.js index a10ff7184..d0a333158 100644 --- a/modules/ticket/front/weekly/index.js +++ b/modules/ticket/front/weekly/index.js @@ -22,6 +22,7 @@ export default class Controller extends Section { search: true, shownColumns: true, }, + defaultSearch: true, columns: [ { field: 'ticketFk', From 3386af9b17bb5c1b27ff3c5012b34c0700e380a3 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 12 Jun 2023 16:27:02 +0200 Subject: [PATCH 095/170] refs #5667 MailAliasAccount translations added --- modules/account/back/locale/mail-alias-account/en.yml | 5 +++++ modules/account/back/locale/mail-alias-account/es.yml | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 modules/account/back/locale/mail-alias-account/en.yml create mode 100644 modules/account/back/locale/mail-alias-account/es.yml diff --git a/modules/account/back/locale/mail-alias-account/en.yml b/modules/account/back/locale/mail-alias-account/en.yml new file mode 100644 index 000000000..2449ab252 --- /dev/null +++ b/modules/account/back/locale/mail-alias-account/en.yml @@ -0,0 +1,5 @@ +name: Mail alias +columns: + id: id + mailAlias: alias + account: account diff --git a/modules/account/back/locale/mail-alias-account/es.yml b/modules/account/back/locale/mail-alias-account/es.yml new file mode 100644 index 000000000..0565b7a77 --- /dev/null +++ b/modules/account/back/locale/mail-alias-account/es.yml @@ -0,0 +1,5 @@ +name: Alias de correo +columns: + id: id + mailAlias: alias + account: cuenta From cc788d7e0606412b4b149864bdac45b59aecd801 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 12 Jun 2023 16:28:47 +0200 Subject: [PATCH 096/170] refs #5667 Account translations added --- modules/account/back/locale/account/en.yml | 3 +++ modules/account/back/locale/account/es.yml | 3 +++ modules/account/back/locale/mail-alias-account/en.yml | 2 +- modules/account/back/locale/mail-alias-account/es.yml | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 modules/account/back/locale/account/en.yml create mode 100644 modules/account/back/locale/account/es.yml diff --git a/modules/account/back/locale/account/en.yml b/modules/account/back/locale/account/en.yml new file mode 100644 index 000000000..221afef5f --- /dev/null +++ b/modules/account/back/locale/account/en.yml @@ -0,0 +1,3 @@ +name: account +columns: + id: id diff --git a/modules/account/back/locale/account/es.yml b/modules/account/back/locale/account/es.yml new file mode 100644 index 000000000..a79b1f40c --- /dev/null +++ b/modules/account/back/locale/account/es.yml @@ -0,0 +1,3 @@ +name: cuenta +columns: + id: id diff --git a/modules/account/back/locale/mail-alias-account/en.yml b/modules/account/back/locale/mail-alias-account/en.yml index 2449ab252..bf805d66f 100644 --- a/modules/account/back/locale/mail-alias-account/en.yml +++ b/modules/account/back/locale/mail-alias-account/en.yml @@ -1,4 +1,4 @@ -name: Mail alias +name: mail alias columns: id: id mailAlias: alias diff --git a/modules/account/back/locale/mail-alias-account/es.yml b/modules/account/back/locale/mail-alias-account/es.yml index 0565b7a77..b53ade996 100644 --- a/modules/account/back/locale/mail-alias-account/es.yml +++ b/modules/account/back/locale/mail-alias-account/es.yml @@ -1,4 +1,4 @@ -name: Alias de correo +name: alias de correo columns: id: id mailAlias: alias From 7127c5a3a820add9c2168975ae1c82aa615cc0ce Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 12 Jun 2023 17:37:25 +0200 Subject: [PATCH 097/170] refs #5325 e2e 1 smart Table --- e2e/helpers/selectors.js | 8 ++++---- e2e/paths/02-client/21_defaulter.spec.js | 2 +- e2e/paths/04-item/01_summary.spec.js | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 039f6ee8f..19ea23d73 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -311,9 +311,9 @@ export default { }, clientDefaulter: { anyClient: 'vn-client-defaulter tbody > tr', - firstClientName: 'vn-client-defaulter tbody > tr:nth-child(1) > td:nth-child(2) > span', - firstSalesPersonName: 'vn-client-defaulter tbody > tr:nth-child(1) > td:nth-child(3) > span', - firstObservation: 'vn-client-defaulter tbody > tr:nth-child(1) > td:nth-child(8) > vn-textarea[ng-model="defaulter.observation"]', + firstClientName: 'vn-client-defaulter tbody > tr:nth-child(2) > td:nth-child(2) > span', + firstSalesPersonName: 'vn-client-defaulter tbody > tr:nth-child(2) > td:nth-child(3) > span', + firstObservation: 'vn-client-defaulter tbody > tr:nth-child(2) > td:nth-child(8) > vn-textarea[ng-model="defaulter.observation"]', allDefaulterCheckbox: 'vn-client-defaulter thead vn-multi-check', addObservationButton: 'vn-client-defaulter vn-button[icon="icon-notes"]', observation: '.vn-dialog.shown vn-textarea[ng-model="$ctrl.defaulter.observation"]', @@ -336,7 +336,7 @@ export default { createItemButton: `vn-float-button`, firstSearchResult: 'vn-item-index tbody tr:nth-child(1)', searchResult: 'vn-item-index tbody tr:not(.empty-rows)', - firstResultPreviewButton: 'vn-item-index tbody > :nth-child(1) .buttons > [icon="preview"]', + firstResultPreviewButton: 'vn-item-index tbody > :nth-child(2) .buttons > [icon="preview"]', searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]', acceptClonationAlertButton: '.vn-confirm.shown [response="accept"]', closeItemSummaryPreview: '.vn-popup.shown', diff --git a/e2e/paths/02-client/21_defaulter.spec.js b/e2e/paths/02-client/21_defaulter.spec.js index 97e62abef..2bb3d6254 100644 --- a/e2e/paths/02-client/21_defaulter.spec.js +++ b/e2e/paths/02-client/21_defaulter.spec.js @@ -19,7 +19,7 @@ describe('Client defaulter path', () => { it('should count the amount of clients in the turns section', async() => { const result = await page.countElement(selectors.clientDefaulter.anyClient); - expect(result).toEqual(5); + expect(result).toEqual(6); }); it('should check contain expected client', async() => { diff --git a/e2e/paths/04-item/01_summary.spec.js b/e2e/paths/04-item/01_summary.spec.js index e24fa6a9f..621dd9cd8 100644 --- a/e2e/paths/04-item/01_summary.spec.js +++ b/e2e/paths/04-item/01_summary.spec.js @@ -1,7 +1,7 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; -describe('Item summary path', () => { +fdescribe('Item summary path', () => { let browser; let page; beforeAll(async() => { @@ -22,7 +22,7 @@ describe('Item summary path', () => { await page.waitToClick(selectors.itemsIndex.firstResultPreviewButton); const isVisible = await page.isVisible(selectors.itemSummary.basicData); - expect(resultsCount).toBe(3); + expect(resultsCount).toBe(4); expect(isVisible).toBeTruthy(); }); From b7c8b03a650e3d6dca07e1ec27e924be58cd08dc Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 12 Jun 2023 19:51:16 +0200 Subject: [PATCH 098/170] refs #5325 e2e 2 --- e2e/helpers/selectors.js | 32 +++++++++---------- e2e/paths/04-item/01_summary.spec.js | 6 ++-- e2e/paths/04-item/10_item_log.spec.js | 2 +- .../05-ticket/01-sale/02_edit_sale.spec.js | 4 +-- .../05-ticket/02_expeditions_and_log.spec.js | 2 +- e2e/paths/05-ticket/09_weekly.spec.js | 6 ++-- e2e/paths/05-ticket/20_moveExpedition.spec.js | 4 +-- e2e/paths/05-ticket/21_future.spec.js | 2 +- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 19ea23d73..3d5bcddb5 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -334,7 +334,7 @@ export default { }, itemsIndex: { createItemButton: `vn-float-button`, - firstSearchResult: 'vn-item-index tbody tr:nth-child(1)', + firstSearchResult: 'vn-item-index tbody tr:nth-child(2)', searchResult: 'vn-item-index tbody tr:not(.empty-rows)', firstResultPreviewButton: 'vn-item-index tbody > :nth-child(2) .buttons > [icon="preview"]', searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]', @@ -342,7 +342,7 @@ export default { closeItemSummaryPreview: '.vn-popup.shown', shownColumns: 'vn-item-index vn-button[id="shownColumns"]', shownColumnsList: '.vn-popover.shown .content', - firstItemImage: 'vn-item-index tbody > tr:nth-child(1) > td:nth-child(1) > img', + firstItemImage: 'vn-item-index tbody > tr:nth-child(2) > td:nth-child(1) > img', firstItemImageTd: 'vn-item-index smart-table tr:nth-child(1) td:nth-child(1)', firstItemId: 'vn-item-index tbody > tr:nth-child(1) > td:nth-child(2)', idCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check[label="Identifier"]', @@ -526,8 +526,8 @@ export default { fourthWeeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(4)', fiveWeeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(5)', weeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table table tbody tr', - firstWeeklyTicketDeleteIcon: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(1) vn-icon-button[icon="delete"]', - firstWeeklyTicketAgency: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(1) [ng-model="weekly.agencyModeFk"]', + firstWeeklyTicketDeleteIcon: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(2) vn-icon-button[icon="delete"]', + firstWeeklyTicketAgency: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(2) [ng-model="weekly.agencyModeFk"]', acceptDeleteTurn: '.vn-confirm.shown button[response="accept"]' }, createTicketView: { @@ -572,8 +572,8 @@ export default { submitNotesButton: 'button[type=submit]' }, ticketExpedition: { - firstSaleCheckbox: 'vn-ticket-expedition tr:nth-child(1) vn-check[ng-model="expedition.checked"]', - thirdSaleCheckbox: 'vn-ticket-expedition tr:nth-child(3) vn-check[ng-model="expedition.checked"]', + firstSaleCheckbox: 'vn-ticket-expedition tr:nth-child(2) vn-check[ng-model="expedition.checked"]', + thirdSaleCheckbox: 'vn-ticket-expedition tr:nth-child(4) vn-check[ng-model="expedition.checked"]', deleteExpeditionButton: 'vn-ticket-expedition slot-actions > vn-button[icon="delete"]', moveExpeditionButton: 'vn-ticket-expedition slot-actions > vn-button[icon="keyboard_arrow_down"]', moreMenuWithoutRoute: 'vn-item[name="withoutRoute"]', @@ -606,16 +606,16 @@ export default { firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img', firstSaleZoomedImage: 'body > div > div > img', firstSaleQuantity: 'vn-ticket-sale [ng-model="sale.quantity"]', - firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(7)', + firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(2) > vn-td-editable:nth-child(7)', firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(9) > span', firstSalePriceInput: '.vn-popover.shown input[ng-model="$ctrl.field"]', firstSaleDiscount: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(10) > span', firstSaleDiscountInput: '.vn-popover.shown [ng-model="$ctrl.field"]', saveSaleDiscountButton: '.vn-popover.shown vn-button[label="Save"]', - firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(11)', - firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(3)', + firstSaleImport: 'vn-ticket-sale:nth-child(3) vn-td:nth-child(11)', + firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(2) > vn-td:nth-child(2) > vn-icon:nth-child(3)', firstSaleColour: 'vn-ticket-sale vn-tr:nth-child(1) vn-fetched-tags section', - firstSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(1) vn-check[ng-model="sale.checked"]', + firstSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(2) vn-check[ng-model="sale.checked"]', secondSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(2)', secondSaleId: 'vn-ticket-sale:nth-child(2) vn-td-editable:nth-child(4) text > span', secondSaleIdAutocomplete: 'vn-ticket-sale vn-tr:nth-child(2) vn-autocomplete[ng-model="sale.itemFk"]', @@ -625,9 +625,9 @@ export default { secondSaleConceptInput: 'vn-ticket-sale vn-tbody > :nth-child(2) > vn-td-editable.ng-isolate-scope.selected vn-textfield', totalImport: 'vn-ticket-sale vn-one.taxes > p:nth-child(3) > strong', selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check', - secondSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(2) vn-check[ng-model="sale.checked"]', - thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[ng-model="sale.checked"]', - fourthSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(4) vn-check[ng-model="sale.checked"]', + secondSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[ng-model="sale.checked"]', + thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(4) vn-check[ng-model="sale.checked"]', + fourthSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(5) vn-check[ng-model="sale.checked"]', deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]', transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]', moveToTicketInput: 'form vn-input-number[ng-model="$ctrl.transfer.ticketId"] input', @@ -712,7 +712,7 @@ export default { problems: 'vn-check[label="With problems"]', tableButtonSearch: 'vn-button[vn-tooltip="Search"]', moveButton: 'vn-button[vn-tooltip="Future tickets"]', - firstCheck: 'tbody > tr:nth-child(1) > td > vn-check', + firstCheck: 'tbody > tr:nth-child(2) > td > vn-check', multiCheck: 'vn-multi-check', tableId: 'vn-textfield[name="id"]', tableFutureId: 'vn-textfield[name="futureId"]', @@ -736,7 +736,7 @@ export default { tableButtonSearch: 'vn-button[vn-tooltip="Search"]', moveButton: 'vn-button[vn-tooltip="Advance tickets"]', acceptButton: '.vn-confirm.shown button[response="accept"]', - firstCheck: 'tbody > tr:nth-child(1) > td > vn-check', + firstCheck: 'tbody > tr:nth-child(2) > td > vn-check', tableId: 'vn-textfield[name="id"]', tableFutureId: 'vn-textfield[name="futureId"]', tableLiters: 'vn-textfield[name="liters"]', @@ -810,7 +810,7 @@ export default { claimAction: { importClaimButton: 'vn-claim-action vn-button[label="Import claim"]', anyLine: 'vn-claim-action vn-tbody > vn-tr', - firstDeleteLine: 'vn-claim-action tr:nth-child(1) vn-icon-button[icon="delete"]', + firstDeleteLine: 'vn-claim-action tr:nth-child(2) vn-icon-button[icon="delete"]', isPaidWithManaCheckbox: 'vn-claim-action vn-check[ng-model="$ctrl.claim.isChargedToMana"]' }, ordersIndex: { diff --git a/e2e/paths/04-item/01_summary.spec.js b/e2e/paths/04-item/01_summary.spec.js index 621dd9cd8..e09ecb778 100644 --- a/e2e/paths/04-item/01_summary.spec.js +++ b/e2e/paths/04-item/01_summary.spec.js @@ -1,7 +1,7 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; -fdescribe('Item summary path', () => { +describe('Item summary path', () => { let browser; let page; beforeAll(async() => { @@ -18,7 +18,7 @@ fdescribe('Item summary path', () => { await page.doSearch('Ranged weapon'); const resultsCount = await page.countElement(selectors.itemsIndex.searchResult); - await page.waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon'); + await page.waitForTextInElement(selectors.itemsIndex.firstSearchResult, 'Ranged weapon'); await page.waitToClick(selectors.itemsIndex.firstResultPreviewButton); const isVisible = await page.isVisible(selectors.itemSummary.basicData); @@ -66,7 +66,7 @@ fdescribe('Item summary path', () => { await page.waitToClick(selectors.itemsIndex.firstResultPreviewButton); await page.waitForSelector(selectors.itemSummary.basicData, {visible: true}); - expect(resultsCount).toBe(2); + expect(resultsCount).toBe(3); }); it(`should now check the item summary preview shows fields from basic data`, async() => { diff --git a/e2e/paths/04-item/10_item_log.spec.js b/e2e/paths/04-item/10_item_log.spec.js index dc467044d..c88fbd337 100644 --- a/e2e/paths/04-item/10_item_log.spec.js +++ b/e2e/paths/04-item/10_item_log.spec.js @@ -18,7 +18,7 @@ describe('Item log path', () => { await page.doSearch('Knowledge artifact'); const nResults = await page.countElement(selectors.itemsIndex.searchResult); - expect(nResults).toEqual(0); + expect(nResults).toEqual(1); }); it('should access to the create item view by clicking the create floating button', async() => { diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index 6264073f6..a494a8848 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -365,7 +365,7 @@ describe('Ticket Edit sale path', () => { }); it('should confirm the original ticket received the line', async() => { - const expectedLines = 4; + const expectedLines = 3; await page.waitForNumberOfElements(selectors.ticketSales.saleLine, expectedLines); const result = await page.countElement(selectors.ticketSales.saleLine); @@ -402,7 +402,7 @@ describe('Ticket Edit sale path', () => { }); it('should confirm the new ticket received the line', async() => { - const expectedLines = 1; + const expectedLines = 3; const result = await page.countElement(selectors.ticketSales.saleLine); expect(result).toEqual(expectedLines); diff --git a/e2e/paths/05-ticket/02_expeditions_and_log.spec.js b/e2e/paths/05-ticket/02_expeditions_and_log.spec.js index edccd5561..b97576940 100644 --- a/e2e/paths/05-ticket/02_expeditions_and_log.spec.js +++ b/e2e/paths/05-ticket/02_expeditions_and_log.spec.js @@ -27,6 +27,6 @@ describe('Ticket expeditions and log path', () => { const result = await page .countElement(selectors.ticketExpedition.expeditionRow); - expect(result).toEqual(3); + expect(result).toEqual(4); }); }); diff --git a/e2e/paths/05-ticket/09_weekly.spec.js b/e2e/paths/05-ticket/09_weekly.spec.js index 0ba57aa9d..a9cce2ead 100644 --- a/e2e/paths/05-ticket/09_weekly.spec.js +++ b/e2e/paths/05-ticket/09_weekly.spec.js @@ -19,7 +19,7 @@ describe('Ticket descriptor path', () => { it('should count the amount of tickets in the turns section', async() => { const result = await page.countElement(selectors.ticketsIndex.weeklyTicket); - expect(result).toEqual(6); + expect(result).toEqual(7); }); it('should go back to the ticket index then search and access a ticket summary', async() => { @@ -89,7 +89,7 @@ describe('Ticket descriptor path', () => { await page.doSearch('11'); const nResults = await page.countElement(selectors.ticketsIndex.searchWeeklyResult); - expect(nResults).toEqual(1); + expect(nResults).toEqual(2); }); it('should delete the weekly ticket 11', async() => { @@ -104,7 +104,7 @@ describe('Ticket descriptor path', () => { await page.doSearch(); const nResults = await page.countElement(selectors.ticketsIndex.searchWeeklyResult); - expect(nResults).toEqual(6); + expect(nResults).toEqual(7); }); it('should update the agency then remove it afterwards', async() => { diff --git a/e2e/paths/05-ticket/20_moveExpedition.spec.js b/e2e/paths/05-ticket/20_moveExpedition.spec.js index cf1c5ded3..ae23c9c99 100644 --- a/e2e/paths/05-ticket/20_moveExpedition.spec.js +++ b/e2e/paths/05-ticket/20_moveExpedition.spec.js @@ -29,7 +29,7 @@ describe('Ticket expeditions', () => { const result = await page .countElement(selectors.ticketExpedition.expeditionRow); - expect(result).toEqual(1); + expect(result).toEqual(2); }); it(`should move one expedition to new ticket with route`, async() => { @@ -45,6 +45,6 @@ describe('Ticket expeditions', () => { const result = await page .countElement(selectors.ticketExpedition.expeditionRow); - expect(result).toEqual(1); + expect(result).toEqual(2); }); }); diff --git a/e2e/paths/05-ticket/21_future.spec.js b/e2e/paths/05-ticket/21_future.spec.js index c854dcbaf..7b7d478f7 100644 --- a/e2e/paths/05-ticket/21_future.spec.js +++ b/e2e/paths/05-ticket/21_future.spec.js @@ -87,7 +87,7 @@ describe('Ticket Future path', () => { await page.clearInput(selectors.ticketFuture.futureState); await page.waitToClick(selectors.ticketFuture.submit); - await page.waitForNumberOfElements(selectors.ticketFuture.searchResult, 4); + await page.waitForNumberOfElements(selectors.ticketFuture.searchResult, 5); await page.waitToClick(selectors.ticketFuture.multiCheck); await page.waitToClick(selectors.ticketFuture.firstCheck); await page.waitToClick(selectors.ticketFuture.moveButton); From d8b041c734a9a013a400c3257f2c5746f23cf500 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 12 Jun 2023 22:04:02 +0200 Subject: [PATCH 099/170] refs #5472 correcto version folder --- db/changes/{232401 => 232601}/00-userPassExpired.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{232401 => 232601}/00-userPassExpired.sql (100%) diff --git a/db/changes/232401/00-userPassExpired.sql b/db/changes/232601/00-userPassExpired.sql similarity index 100% rename from db/changes/232401/00-userPassExpired.sql rename to db/changes/232601/00-userPassExpired.sql From 6f3c28c4a4d0922bf426455622bf8aec8c3527c4 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 13 Jun 2023 07:34:41 +0200 Subject: [PATCH 100/170] =?UTF-8?q?refs=20#5468=20refactor:=20eliminado=20?= =?UTF-8?q?c=C3=B3digo=20obsoleto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/account/front/privileges/index.js | 4 ---- modules/worker/front/calendar/index.js | 10 ++++------ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/modules/account/front/privileges/index.js b/modules/account/front/privileges/index.js index 017d878de..f69428666 100644 --- a/modules/account/front/privileges/index.js +++ b/modules/account/front/privileges/index.js @@ -10,10 +10,6 @@ export default class Controller extends Section { this._user = value; if (!value) return; } - - get isHr() { - return this.aclService.hasAny(['hr']); - } } ngModule.component('vnUserPrivileges', { diff --git a/modules/worker/front/calendar/index.js b/modules/worker/front/calendar/index.js index a492e8306..a52ecd7da 100644 --- a/modules/worker/front/calendar/index.js +++ b/modules/worker/front/calendar/index.js @@ -91,12 +91,10 @@ class Controller extends Section { } getActiveContract() { - this.$http.get(`Workers/${this.worker.id}/activeContract`).then(res => { - if (res.data) { - this.businessId = res.data.businessFk; - console.log(this.businessId); - } - }); + this.$http.get(`Workers/${this.worker.id}/activeContract`) + .then(res => { + if (res.data) this.businessId = res.data.businessFk; + }); } getContractHolidays() { From fa9719de78b3211f5f9855f19936347ff46f5354 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 13 Jun 2023 08:16:37 +0200 Subject: [PATCH 101/170] refs #5691 feat: cambiado url por data en los crudModel --- modules/route/front/index/index.html | 55 ++++++++++++++++++---------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/modules/route/front/index/index.html b/modules/route/front/index/index.html index 7a64a9aff..9384af6be 100644 --- a/modules/route/front/index/index.html +++ b/modules/route/front/index/index.html @@ -1,11 +1,26 @@ + + + + + +
-
@@ -35,7 +50,7 @@ - @@ -52,19 +67,19 @@ Vehicle - Date + Date - + - Description + Description - Hour started + Hour started - Hour finished + Hour finished @@ -74,7 +89,7 @@ class="clickable vn-tr search-result" ng-attr-id="{{::route.id}}" vn-droppable="$ctrl.onDrop($event)"> - @@ -83,7 +98,7 @@ - + - - - + @@ -156,7 +171,7 @@ - +
@@ -171,7 +186,7 @@ route="$ctrl.routeSelected"> - - @@ -210,4 +225,4 @@ - \ No newline at end of file + From 72b779f5c0409781b95f2722c59952e48648dd79 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 13 Jun 2023 10:26:12 +0200 Subject: [PATCH 102/170] refs #5528 fix: editar compras (seleccionar todas), cuando aplicas un filtro --- modules/entry/back/methods/entry/editLatestBuys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/entry/back/methods/entry/editLatestBuys.js b/modules/entry/back/methods/entry/editLatestBuys.js index 2642d4f4d..0da2b1625 100644 --- a/modules/entry/back/methods/entry/editLatestBuys.js +++ b/modules/entry/back/methods/entry/editLatestBuys.js @@ -75,7 +75,7 @@ module.exports = Self => { value[field] = newValue; if (filter) { - ctx.args.filter = {where: filter, limit: null}; + ctx.args = {where: filter, limit: null}; lines = await models.Buy.latestBuysFilter(ctx, null, myOptions); } From ddd23a98420bd89211246d395a66c7c61801d9e2 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 13 Jun 2023 10:40:26 +0200 Subject: [PATCH 103/170] refs #5554 refactor: sustiuido window.localStorage por this --- front/salix/components/layout/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/front/salix/components/layout/index.js b/front/salix/components/layout/index.js index 032a68037..dc2313f4f 100644 --- a/front/salix/components/layout/index.js +++ b/front/salix/components/layout/index.js @@ -36,8 +36,8 @@ export class Layout extends Component { this.$http.get('AccessTokenConfigs').then(json => { const firtsResult = json.data[0]; if (!firtsResult) return; - window.localStorage.renewPeriod = firtsResult.renewPeriod; - window.localStorage.renewInterval = firtsResult.renewInterval; + this.renewPeriod = firtsResult.renewPeriod; + this.renewInterval = firtsResult.renewInterval; const intervalMilliseconds = firtsResult.renewInterval * 1000; this.inservalId = setInterval(this.checkTokenValidity.bind(this), intervalMilliseconds); @@ -49,7 +49,7 @@ export class Layout extends Component { const differenceMilliseconds = now - new Date(this.vnToken.created); const differenceSeconds = Math.floor(differenceMilliseconds / 1000); - if (differenceSeconds > window.localStorage.renewPeriod) { + if (differenceSeconds > this.renewPeriod) { this.$http.post('VnUsers/renewToken') .then(json => { if (json.data.token) { From 5d3ecfa00e525e1d751fec662c6a85a89b20ed2a Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 13 Jun 2023 10:44:29 +0200 Subject: [PATCH 104/170] refs #5554 fix: test front --- front/salix/components/layout/index.spec.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/front/salix/components/layout/index.spec.js b/front/salix/components/layout/index.spec.js index e94ded787..8f65f32ce 100644 --- a/front/salix/components/layout/index.spec.js +++ b/front/salix/components/layout/index.spec.js @@ -49,18 +49,15 @@ describe('Component vnLayout', () => { controller.getAccessTokenConfig(); $httpBackend.flush(); - const renewPeriod = localStorage.getItem('renewPeriod'); - const renewInterval = localStorage.getItem('renewInterval'); - - expect(renewPeriod).toBe('100'); - expect(renewInterval).toBe('5'); + expect(controller.renewPeriod).toBe(100); + expect(controller.renewInterval).toBe(5); expect(controller.inservalId).toBeDefined(); }); }); describe('checkTokenValidity()', () => { it(`should not call renewToken and not set vnToken in the controller`, () => { - localStorage.setItem('renewPeriod', 100); + controller.renewPeriod = 100; controller.vnToken.created = new Date(); controller.checkTokenValidity(); @@ -73,7 +70,7 @@ describe('Component vnLayout', () => { token: 999, created: new Date() }; - localStorage.setItem('renewPeriod', 100); + controller.renewPeriod = 100; const oneHourBefore = new Date(Date.now() - (60 * 60 * 1000)); controller.vnToken.created = oneHourBefore; From 92953b9aa821e392a7c8d9969e101d40c99dd1d1 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 13 Jun 2023 11:37:35 +0200 Subject: [PATCH 105/170] refs #5094 test(docuware): adapt tests --- back/methods/docuware/core.js | 8 ++++---- back/methods/docuware/specs/upload.spec.js | 5 +++-- back/methods/docuware/upload.js | 9 ++++++--- .../front/descriptor-menu/index.spec.js | 2 +- modules/ticket/front/index/index.spec.js | 20 +++++++++---------- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/back/methods/docuware/core.js b/back/methods/docuware/core.js index be310e82b..2053ddf85 100644 --- a/back/methods/docuware/core.js +++ b/back/methods/docuware/core.js @@ -20,8 +20,8 @@ module.exports = Self => { const options = await Self.getOptions(); - // if (!process.env.NODE_ENV) - // return Math.round(); + if (!process.env.NODE_ENV) + return Math.round(); const response = await axios.get(`${options.url}/FileCabinets/${fileCabinetId}/dialogs`, options.headers); const dialogs = response.data.Dialog; @@ -44,8 +44,8 @@ module.exports = Self => { } }); - // if (!process.env.NODE_ENV) - // return Math.round(); + if (!process.env.NODE_ENV) + return Math.round(); const fileCabinetResponse = await axios.get(`${options.url}/FileCabinets`, options.headers); const fileCabinets = fileCabinetResponse.data.FileCabinet; diff --git a/back/methods/docuware/specs/upload.spec.js b/back/methods/docuware/specs/upload.spec.js index 7ac873e95..3b8c55a50 100644 --- a/back/methods/docuware/specs/upload.spec.js +++ b/back/methods/docuware/specs/upload.spec.js @@ -2,8 +2,9 @@ const models = require('vn-loopback/server/server').models; describe('docuware upload()', () => { const userId = 9; - const ticketId = 10; + const ticketIds = [10]; const ctx = { + args: {ticketIds}, req: { getLocale: () => { return 'en'; @@ -27,7 +28,7 @@ describe('docuware upload()', () => { let error; try { - await models.Docuware.upload(ctx, ticketId, fileCabinetName); + await models.Docuware.upload(ctx, ticketIds, fileCabinetName); } catch (e) { error = e.message; } diff --git a/back/methods/docuware/upload.js b/back/methods/docuware/upload.js index d14e8a668..57e96170f 100644 --- a/back/methods/docuware/upload.js +++ b/back/methods/docuware/upload.js @@ -19,7 +19,10 @@ module.exports = Self => { required: true } ], - returns: [], + returns: { + type: 'object', + root: true + }, http: { path: `/upload`, verb: 'POST' @@ -106,8 +109,8 @@ module.exports = Self => { ] }; - // if (process.env.NODE_ENV != 'production') - // throw new UserError('Action not allowed on the test environment'); + if (process.env.NODE_ENV != 'production') + throw new UserError('Action not allowed on the test environment'); // delete old const docuwareFile = await models.Docuware.checkFile(ctx, id, fileCabinet, false); diff --git a/modules/ticket/front/descriptor-menu/index.spec.js b/modules/ticket/front/descriptor-menu/index.spec.js index 95a580fe5..0aef956db 100644 --- a/modules/ticket/front/descriptor-menu/index.spec.js +++ b/modules/ticket/front/descriptor-menu/index.spec.js @@ -308,7 +308,7 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { controller.$.balanceCreate = {show: () => {}}; jest.spyOn(controller.vnApp, 'showSuccess'); - $httpBackend.whenPOST(`Docuwares/${ticket.id}/upload`).respond(true); + $httpBackend.whenPOST(`Docuwares/upload`).respond(true); controller.uploadDocuware(true); $httpBackend.flush(); diff --git a/modules/ticket/front/index/index.spec.js b/modules/ticket/front/index/index.spec.js index 5046387b0..951c6aa09 100644 --- a/modules/ticket/front/index/index.spec.js +++ b/modules/ticket/front/index/index.spec.js @@ -12,12 +12,14 @@ describe('Component vnTicketIndex', () => { id: 2, clientFk: 1, checked: true, - totalWithVat: 20.5 + totalWithVat: 20.5, + stateFk: 1 }, { id: 3, clientFk: 1, checked: true, - totalWithVat: 30 + totalWithVat: 30, + stateFk: 1 }]; beforeEach(ngModule('ticket')); @@ -86,18 +88,16 @@ describe('Component vnTicketIndex', () => { }); }); - describe('setDelivered()/openDeliveryNotes()', () => { - it('should perform a post to setDelivered and open tabs with the delivery notes', () => { + describe('sendDocuware()', () => { + it('should perform a post to sendDocuware and change tickets state', () => { controller.$.model = {data: tickets, refresh: () => {}}; + const newState = {id: 2}; - $window.open = jest.fn(); - - $httpBackend.expect('POST', 'TicketTrackings/setDelivered').respond('ok'); - controller.setDelivered(); + $httpBackend.expect('POST', 'Docuwares/upload').respond({id: newState.id}); + controller.sendDocuware(); $httpBackend.flush(); - expect($window.open).toHaveBeenCalledWith(`api/Tickets/${tickets[1].id}/delivery-note-pdf`); - expect($window.open).toHaveBeenCalledWith(`api/Tickets/${tickets[2].id}/delivery-note-pdf`); + expect(controller.$.model.data[1].stateFk).toEqual(newState.id); }); }); From dd4b62d0a53ac810f2dd8ef7442e6683988e69e0 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 13 Jun 2023 12:42:12 +0200 Subject: [PATCH 106/170] description --- back/methods/docuware/upload.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/back/methods/docuware/upload.js b/back/methods/docuware/upload.js index 57e96170f..421c1c4d8 100644 --- a/back/methods/docuware/upload.js +++ b/back/methods/docuware/upload.js @@ -3,7 +3,7 @@ const axios = require('axios'); module.exports = Self => { Self.remoteMethodCtx('upload', { - description: 'Upload an docuware PDF', + description: 'Upload docuware PDFs', accessType: 'WRITE', accepts: [ { @@ -39,8 +39,6 @@ module.exports = Self => { const dialogId = await Self.getDialog(fileCabinet, action, fileCabinetId); const uploaded = []; - - // get delivery note for (id of ticketIds) { // get delivery note ctx.args.id = id; From 61ce25c1e1e22563d7853b1f14b1c072e33e8f18 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 13 Jun 2023 13:32:04 +0200 Subject: [PATCH 107/170] refs #5325 all e2e fix smartTable --- e2e/helpers/selectors.js | 20 +++++++++---------- ..._smartTable_searchBar_integrations.spec.js | 6 +++--- .../05-ticket/01-sale/02_edit_sale.spec.js | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 3d5bcddb5..b8eaa99a1 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -523,8 +523,8 @@ export default { searchResultDate: 'vn-ticket-summary [label=Landed] span', topbarSearch: 'vn-searchbar', moreMenu: 'vn-ticket-index vn-icon-button[icon=more_vert]', - fourthWeeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(4)', - fiveWeeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(5)', + fourthWeeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(5)', + fiveWeeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(6)', weeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table table tbody tr', firstWeeklyTicketDeleteIcon: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(2) vn-icon-button[icon="delete"]', firstWeeklyTicketAgency: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(2) [ng-model="weekly.agencyModeFk"]', @@ -606,16 +606,16 @@ export default { firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img', firstSaleZoomedImage: 'body > div > div > img', firstSaleQuantity: 'vn-ticket-sale [ng-model="sale.quantity"]', - firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(2) > vn-td-editable:nth-child(7)', + firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(7)', firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(9) > span', firstSalePriceInput: '.vn-popover.shown input[ng-model="$ctrl.field"]', firstSaleDiscount: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(10) > span', firstSaleDiscountInput: '.vn-popover.shown [ng-model="$ctrl.field"]', saveSaleDiscountButton: '.vn-popover.shown vn-button[label="Save"]', - firstSaleImport: 'vn-ticket-sale:nth-child(3) vn-td:nth-child(11)', - firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(2) > vn-td:nth-child(2) > vn-icon:nth-child(3)', + firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(11)', + firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(3)', firstSaleColour: 'vn-ticket-sale vn-tr:nth-child(1) vn-fetched-tags section', - firstSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(2) vn-check[ng-model="sale.checked"]', + firstSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(1) vn-check[ng-model="sale.checked"]', secondSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(2)', secondSaleId: 'vn-ticket-sale:nth-child(2) vn-td-editable:nth-child(4) text > span', secondSaleIdAutocomplete: 'vn-ticket-sale vn-tr:nth-child(2) vn-autocomplete[ng-model="sale.itemFk"]', @@ -625,9 +625,9 @@ export default { secondSaleConceptInput: 'vn-ticket-sale vn-tbody > :nth-child(2) > vn-td-editable.ng-isolate-scope.selected vn-textfield', totalImport: 'vn-ticket-sale vn-one.taxes > p:nth-child(3) > strong', selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check', - secondSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[ng-model="sale.checked"]', - thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(4) vn-check[ng-model="sale.checked"]', - fourthSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(5) vn-check[ng-model="sale.checked"]', + secondSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(2) vn-check[ng-model="sale.checked"]', + thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[ng-model="sale.checked"]', + fourthSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(4) vn-check[ng-model="sale.checked"]', deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]', transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]', moveToTicketInput: 'form vn-input-number[ng-model="$ctrl.transfer.ticketId"] input', @@ -1216,7 +1216,7 @@ export default { addTagButton: 'vn-icon-button[vn-tooltip="Add tag"]', itemTagInput: 'vn-autocomplete[ng-model="itemTag.tagFk"]', itemTagValueInput: 'vn-autocomplete[ng-model="itemTag.value"]', - firstBuy: 'vn-entry-latest-buys tbody > tr:nth-child(1)', + firstBuy: 'vn-entry-latest-buys tbody > tr:nth-child(2)', allBuysCheckBox: 'vn-entry-latest-buys thead vn-check', secondBuyCheckBox: 'vn-entry-latest-buys tbody tr:nth-child(2) vn-check[ng-model="buy.checked"]', editBuysButton: 'vn-entry-latest-buys vn-button[icon="edit"]', diff --git a/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js b/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js index 526afa140..a56f54185 100644 --- a/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js +++ b/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js @@ -19,16 +19,16 @@ describe('SmartTable SearchBar integration', () => { await page.waitToClick(selectors.itemsIndex.openAdvancedSearchButton); await page.autocompleteSearch(selectors.itemsIndex.advancedSearchItemType, 'Anthurium'); await page.waitToClick(selectors.itemsIndex.advancedSearchButton); - await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 3); + await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 4); await page.reload({ waitUntil: 'networkidle2' }); - await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 3); + await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 4); await page.waitToClick(selectors.itemsIndex.advancedSmartTableButton); - await page.write(selectors.itemsIndex.advancedSmartTableGrouping, '1'); + await page.write(selectors.itemsIndex.advancedSmartTableGrouping, 3); await page.keyboard.press('Enter'); await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 2); diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index a494a8848..6264073f6 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -365,7 +365,7 @@ describe('Ticket Edit sale path', () => { }); it('should confirm the original ticket received the line', async() => { - const expectedLines = 3; + const expectedLines = 4; await page.waitForNumberOfElements(selectors.ticketSales.saleLine, expectedLines); const result = await page.countElement(selectors.ticketSales.saleLine); @@ -402,7 +402,7 @@ describe('Ticket Edit sale path', () => { }); it('should confirm the new ticket received the line', async() => { - const expectedLines = 3; + const expectedLines = 1; const result = await page.countElement(selectors.ticketSales.saleLine); expect(result).toEqual(expectedLines); From 3cef6d642d4d8129cf38dfa8a67edc2a79a0a76f Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 13 Jun 2023 14:15:31 +0200 Subject: [PATCH 108/170] refs #5325 smartTable e2e fix --- .../01-salix/03_smartTable_searchBar_integrations.spec.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js b/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js index a56f54185..9c37ce9ba 100644 --- a/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js +++ b/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js @@ -27,8 +27,7 @@ describe('SmartTable SearchBar integration', () => { await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 4); - await page.waitToClick(selectors.itemsIndex.advancedSmartTableButton); - await page.write(selectors.itemsIndex.advancedSmartTableGrouping, 3); + await page.write(selectors.itemsIndex.advancedSmartTableGrouping, '1'); await page.keyboard.press('Enter'); await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 2); @@ -36,7 +35,7 @@ describe('SmartTable SearchBar integration', () => { waitUntil: 'networkidle2' }); - await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 2); + await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1); }); it('should filter in section without smart-table and search in searchBar go to zone section', async() => { From 66c5eda6f2989c017c2a5d5813c1db03d9039058 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 13 Jun 2023 16:08:11 +0200 Subject: [PATCH 109/170] refs #5325 remove defaultSearch --- front/core/components/smart-table/index.js | 2 ++ modules/claim/front/action/index.js | 1 - modules/claim/front/index/index.js | 1 - modules/client/front/defaulter/index.js | 1 - modules/client/front/extended-list/index.js | 1 - modules/client/front/notification/index.js | 1 - modules/entry/front/latest-buys/index.js | 1 - modules/invoiceOut/front/negative-bases/index.js | 1 - modules/item/front/fixed-price/index.js | 1 - modules/item/front/index/index.js | 1 - modules/item/front/item-shelving/index.js | 1 - modules/monitor/front/index/clients/index.js | 1 - modules/monitor/front/index/tickets/index.js | 1 - modules/route/front/agency-term/index/index.js | 1 - modules/ticket/front/advance/index.js | 1 - modules/ticket/front/expedition/index.js | 1 - modules/ticket/front/future/index.js | 1 - modules/ticket/front/weekly/index.js | 1 - 18 files changed, 2 insertions(+), 17 deletions(-) diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index b2380a62f..c3b927c62 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -40,6 +40,8 @@ export default class SmartTable extends Component { this._options = options; if (!options) return; + options.defaultSearch = true; + if (options.defaultSearch) this.displaySearch(); diff --git a/modules/claim/front/action/index.js b/modules/claim/front/action/index.js index 6b4879a85..10b629f27 100644 --- a/modules/claim/front/action/index.js +++ b/modules/claim/front/action/index.js @@ -26,7 +26,6 @@ export default class Controller extends Section { activeButtons: { search: true }, - defaultSearch: true, columns: [ { field: 'claimDestinationFk', diff --git a/modules/claim/front/index/index.js b/modules/claim/front/index/index.js index 8e948f426..e3fdabf79 100644 --- a/modules/claim/front/index/index.js +++ b/modules/claim/front/index/index.js @@ -9,7 +9,6 @@ class Controller extends Section { activeButtons: { search: true }, - defaultSearch: true, columns: [ { field: 'clientName', diff --git a/modules/client/front/defaulter/index.js b/modules/client/front/defaulter/index.js index 1244191f1..95c7622f9 100644 --- a/modules/client/front/defaulter/index.js +++ b/modules/client/front/defaulter/index.js @@ -12,7 +12,6 @@ export default class Controller extends Section { activeButtons: { search: true }, - defaultSearch: true, columns: [ { field: 'clientFk', diff --git a/modules/client/front/extended-list/index.js b/modules/client/front/extended-list/index.js index 2cb7a6d58..8eed48d01 100644 --- a/modules/client/front/extended-list/index.js +++ b/modules/client/front/extended-list/index.js @@ -11,7 +11,6 @@ class Controller extends Section { search: true, shownColumns: true, }, - defaultSearch: true, columns: [ { field: 'socialName', diff --git a/modules/client/front/notification/index.js b/modules/client/front/notification/index.js index ada543715..faa062b25 100644 --- a/modules/client/front/notification/index.js +++ b/modules/client/front/notification/index.js @@ -9,7 +9,6 @@ export default class Controller extends Section { activeButtons: { search: true }, - defaultSearch: true, columns: [ { field: 'socialName', diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js index 1a9b3627b..d9065193e 100644 --- a/modules/entry/front/latest-buys/index.js +++ b/modules/entry/front/latest-buys/index.js @@ -14,7 +14,6 @@ export default class Controller extends Section { search: true, shownColumns: true, }, - defaultSearch: true, columns: [ { field: 'code', diff --git a/modules/invoiceOut/front/negative-bases/index.js b/modules/invoiceOut/front/negative-bases/index.js index b70a2f7be..f60668b20 100644 --- a/modules/invoiceOut/front/negative-bases/index.js +++ b/modules/invoiceOut/front/negative-bases/index.js @@ -20,7 +20,6 @@ export default class Controller extends Section { activeButtons: { search: true, }, - defaultSearch: true, columns: [ { field: 'isActive', diff --git a/modules/item/front/fixed-price/index.js b/modules/item/front/fixed-price/index.js index a39cd6602..fe6788e9c 100644 --- a/modules/item/front/fixed-price/index.js +++ b/modules/item/front/fixed-price/index.js @@ -13,7 +13,6 @@ export default class Controller extends Section { activeButtons: { search: true }, - defaultSearch: true, columns: [ { field: 'warehouseFk', diff --git a/modules/item/front/index/index.js b/modules/item/front/index/index.js index f341f6454..10bd4bbb7 100644 --- a/modules/item/front/index/index.js +++ b/modules/item/front/index/index.js @@ -11,7 +11,6 @@ class Controller extends Section { search: true, shownColumns: true, }, - defaultSearch: true, columns: [ { field: 'category', diff --git a/modules/item/front/item-shelving/index.js b/modules/item/front/item-shelving/index.js index 8e5df459d..b8584039b 100644 --- a/modules/item/front/item-shelving/index.js +++ b/modules/item/front/item-shelving/index.js @@ -9,7 +9,6 @@ export default class Controller extends Section { activeButtons: { search: true }, - defaultSearch: true, columns: [ { field: 'parking', diff --git a/modules/monitor/front/index/clients/index.js b/modules/monitor/front/index/clients/index.js index 9faf2ed53..ac3ce9140 100644 --- a/modules/monitor/front/index/clients/index.js +++ b/modules/monitor/front/index/clients/index.js @@ -20,7 +20,6 @@ export default class Controller extends Section { activeButtons: { search: true }, - defaultSearch: true, columns: [ { field: 'clientFk', diff --git a/modules/monitor/front/index/tickets/index.js b/modules/monitor/front/index/tickets/index.js index 92097833b..2f2dead05 100644 --- a/modules/monitor/front/index/tickets/index.js +++ b/modules/monitor/front/index/tickets/index.js @@ -12,7 +12,6 @@ export default class Controller extends Section { search: true, shownColumns: true, }, - defaultSearch: true, columns: [ { field: 'totalProblems', diff --git a/modules/route/front/agency-term/index/index.js b/modules/route/front/agency-term/index/index.js index 6277fb9a1..6c3bafc9a 100644 --- a/modules/route/front/agency-term/index/index.js +++ b/modules/route/front/agency-term/index/index.js @@ -9,7 +9,6 @@ class Controller extends Section { activeButtons: { search: true }, - defaultSearch: true, columns: [ { field: 'agencyModeFk', diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index 0cd1b0981..0cec41227 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -11,7 +11,6 @@ export default class Controller extends Section { activeButtons: { search: true, }, - defaultSearch: true, columns: [ { field: 'state', diff --git a/modules/ticket/front/expedition/index.js b/modules/ticket/front/expedition/index.js index 1e30ce447..b8046be52 100644 --- a/modules/ticket/front/expedition/index.js +++ b/modules/ticket/front/expedition/index.js @@ -11,7 +11,6 @@ class Controller extends Section { search: true, shownColumns: true, }, - defaultSearch: true, columns: [ { field: 'packageItemName', diff --git a/modules/ticket/front/future/index.js b/modules/ticket/front/future/index.js index 846c3883f..66d626993 100644 --- a/modules/ticket/front/future/index.js +++ b/modules/ticket/front/future/index.js @@ -10,7 +10,6 @@ export default class Controller extends Section { activeButtons: { search: true, }, - defaultSearch: true, columns: [{ field: 'totalProblems', searchable: false, diff --git a/modules/ticket/front/weekly/index.js b/modules/ticket/front/weekly/index.js index d0a333158..a10ff7184 100644 --- a/modules/ticket/front/weekly/index.js +++ b/modules/ticket/front/weekly/index.js @@ -22,7 +22,6 @@ export default class Controller extends Section { search: true, shownColumns: true, }, - defaultSearch: true, columns: [ { field: 'ticketFk', From 961941ecb3095b7857da9bb9481d8b6290bd9a14 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Tue, 13 Jun 2023 20:52:26 +0200 Subject: [PATCH 110/170] refs #5667 TicketRequest translations added/fixed --- .../ticket/back/locale/ticket-request/en.yml | 19 ++++++++++------- .../ticket/back/locale/ticket-request/es.yml | 21 +++++++++++-------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/modules/ticket/back/locale/ticket-request/en.yml b/modules/ticket/back/locale/ticket-request/en.yml index f381e0c9d..fc9210501 100644 --- a/modules/ticket/back/locale/ticket-request/en.yml +++ b/modules/ticket/back/locale/ticket-request/en.yml @@ -2,14 +2,17 @@ name: request columns: id: id description: description - created: created + buyerCode: buyer quantity: quantity price: price - isOk: ok - response: response - saleFk: sale - ticketFk: ticket - attenderFk: attender - requesterFk: requester itemFk: item - + clientFk: client + response: response + total: total + buyed: buyed + saleFk: sale + created: created + isOk: ok + requesterFk: requester + attenderFk: attender + ticketFk: ticket diff --git a/modules/ticket/back/locale/ticket-request/es.yml b/modules/ticket/back/locale/ticket-request/es.yml index 5504448bf..fd89ddf60 100644 --- a/modules/ticket/back/locale/ticket-request/es.yml +++ b/modules/ticket/back/locale/ticket-request/es.yml @@ -1,15 +1,18 @@ -name: peticion +name: petición columns: id: id description: descripción - created: creado + buyerCode: comprador quantity: cantidad price: precio - isOk: ok - response: respuesta - saleFk: línea - ticketFk: ticket - attenderFk: asistente - requesterFk: solicitante itemFk: artículo - + clientFk: cliente + response: respuesta + total: total + buyed: comprado + saleFk: línea + created: creado + isOk: ok + requesterFk: solicitante + attenderFk: asistente + ticketFk: ticket From aa2d3be4516b750bacf1cf80eb062577032cdf04 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 14 Jun 2023 07:30:50 +0200 Subject: [PATCH 111/170] typo --- back/methods/docuware/upload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/methods/docuware/upload.js b/back/methods/docuware/upload.js index 421c1c4d8..096301e56 100644 --- a/back/methods/docuware/upload.js +++ b/back/methods/docuware/upload.js @@ -139,7 +139,7 @@ module.exports = Self => { await axios.post(uploadUri, data, uploadOptions); } catch (err) { const $t = ctx.req.__; - const message = $t('Failed to upload ticket', {id}); + const message = $t('Failed to upload delivery note', {id}); if (uploaded.length) await models.TicketTracking.setDelivered(ctx, uploaded); throw new UserError(message); From c62e6fa0eb19b7805107086587ac554fd20673f3 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Wed, 14 Jun 2023 10:51:22 +0200 Subject: [PATCH 112/170] refs #5651 packingSiteAdvanced --- db/changes/232601/00-packingSiteAdvanced.sql | 63 +++++++++++++++++++ modules/ticket/back/model-config.json | 3 + .../back/models/packing-site-advanced.json | 18 ++++++ 3 files changed, 84 insertions(+) create mode 100644 db/changes/232601/00-packingSiteAdvanced.sql create mode 100644 modules/ticket/back/models/packing-site-advanced.json diff --git a/db/changes/232601/00-packingSiteAdvanced.sql b/db/changes/232601/00-packingSiteAdvanced.sql new file mode 100644 index 000000000..63c348fcc --- /dev/null +++ b/db/changes/232601/00-packingSiteAdvanced.sql @@ -0,0 +1,63 @@ +CREATE TABLE `vn`.`packingSiteAdvanced` ( + `ticketFk` int(11), + `workerFk` int(10) unsigned, + PRIMARY KEY (`ticketFk`), + KEY `packingSiteAdvanced_FK_1` (`workerFk`), + CONSTRAINT `packingSiteAdvanced_FK` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `packingSiteAdvanced_FK_1` FOREIGN KEY (`workerFk`) REFERENCES `worker` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('PackingSiteAdvanced', '*', '*', 'ALLOW', 'ROLE', 'production'); + +DROP PROCEDURE IF EXISTS `vn`.`packingSite_startCollection`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`packingSite_startCollection`(vSelf INT, vTicketFk INT) +proc: BEGIN +/** + * @param vSelf packingSite id + * @param vTicketFk A ticket id from the collection to start + */ + DECLARE vNewCollectionFk INT; + DECLARE vIsAdvanced BOOL; + DECLARE vOldCollectionFk INT; + DECLARE vIsPackingByOther BOOL; + + SELECT COUNT(*) > 0 + INTO vIsAdvanced + FROM packingSiteAdvanced + WHERE ticketFk = vTicketFk; + + IF vIsAdvanced THEN + LEAVE proc; + END IF; + + SELECT collectionFk INTO vNewCollectionFk + FROM ticketCollection WHERE ticketFk = vTicketFk; + + SELECT collectionFk INTO vOldCollectionFk + FROM packingSite WHERE id = vSelf; + + IF NOT (vOldCollectionFk <=> vNewCollectionFk) THEN + SELECT COUNT(*) > 0 + INTO vIsPackingByOther + FROM packingSite + WHERE id <> vSelf + AND collectionFk = vOldCollectionFk; + + IF NOT vIsPackingByOther AND NOT collection_isPacked(vOldCollectionFk) AND vSelf IS NOT NULL THEN + CALL util.throw('cannotChangeCollection'); + END IF; + END IF; + + UPDATE packingSite SET collectionFk = vNewCollectionFk + WHERE id = vSelf; +END$$ +DELIMITER ; + + + diff --git a/modules/ticket/back/model-config.json b/modules/ticket/back/model-config.json index bee01a875..3c7e12eea 100644 --- a/modules/ticket/back/model-config.json +++ b/modules/ticket/back/model-config.json @@ -100,5 +100,8 @@ }, "TicketConfig": { "dataSource": "vn" + }, + "PackingSiteAdvanced": { + "dataSource": "vn" } } diff --git a/modules/ticket/back/models/packing-site-advanced.json b/modules/ticket/back/models/packing-site-advanced.json new file mode 100644 index 000000000..f48cbf412 --- /dev/null +++ b/modules/ticket/back/models/packing-site-advanced.json @@ -0,0 +1,18 @@ +{ + "name": "PackingSiteAdvanced", + "base": "VnModel", + "options": { + "mysql": { + "table": "packingSiteAdvanced" + } + }, + "properties": { + "ticketFk": { + "id": true, + "type": "number" + }, + "workerFk": { + "type": "number" + } + } +} From 65108943abeae3fcb9a67d0573708f43fa1e1f70 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 14 Jun 2023 12:48:14 +0200 Subject: [PATCH 113/170] refs #5528 feat: back test --- modules/entry/back/methods/entry/specs/editLatestBuys.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js b/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js index 99d2df67b..1ffe27918 100644 --- a/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js +++ b/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js @@ -53,7 +53,7 @@ describe('Buy editLatestsBuys()', () => { const options = {transaction: tx}; try { - const filter = {'i.typeFk': 1}; + const filter = {'categoryFk': 1}; const ctx = { args: { filter: filter From 98b270b885a061dff168408e561db8156bbc419e Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 14 Jun 2023 13:05:46 +0200 Subject: [PATCH 114/170] refs #5528 feat: add back test --- .../entry/specs/editLatestBuys.spec.js | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js b/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js index 1ffe27918..a4dd185fd 100644 --- a/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js +++ b/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js @@ -53,7 +53,36 @@ describe('Buy editLatestsBuys()', () => { const options = {transaction: tx}; try { - const filter = {'categoryFk': 1}; + const filter = {'categoryFk': 1, 'tags': []}; + const ctx = { + args: { + filter: filter + }, + req: {accessToken: {userId: 1}} + }; + + const field = 'size'; + const newValue = 88; + + await models.Buy.editLatestBuys(ctx, field, newValue, null, filter, options); + + const [result] = await models.Buy.latestBuysFilter(ctx, null, options); + + expect(result[field]).toEqual(newValue); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should change the value of a given column for filter tags', async() => { + const tx = await models.Buy.beginTransaction({}); + const options = {transaction: tx}; + + try { + const filter = {'tags': [{tagFk: 1, value: 'Brown'}]}; const ctx = { args: { filter: filter From 927c0fddc6231075f15209b83291726ee6468b6d Mon Sep 17 00:00:00 2001 From: sergiodt Date: Wed, 14 Jun 2023 13:15:37 +0200 Subject: [PATCH 115/170] refs #5651 --- db/changes/232601/00-packingSiteAdvanced.sql | 64 +++++++++++--------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/db/changes/232601/00-packingSiteAdvanced.sql b/db/changes/232601/00-packingSiteAdvanced.sql index 63c348fcc..0e33744cd 100644 --- a/db/changes/232601/00-packingSiteAdvanced.sql +++ b/db/changes/232601/00-packingSiteAdvanced.sql @@ -12,7 +12,7 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri VALUES ('PackingSiteAdvanced', '*', '*', 'ALLOW', 'ROLE', 'production'); -DROP PROCEDURE IF EXISTS `vn`.`packingSite_startCollection`; + DROP PROCEDURE IF EXISTS `vn`.`packingSite_startCollection`; DELIMITER $$ $$ @@ -22,40 +22,48 @@ proc: BEGIN * @param vSelf packingSite id * @param vTicketFk A ticket id from the collection to start */ - DECLARE vNewCollectionFk INT; - DECLARE vIsAdvanced BOOL; - DECLARE vOldCollectionFk INT; - DECLARE vIsPackingByOther BOOL; + DECLARE vExists BOOL; + DECLARE vIsAdvanced BOOL; + DECLARE vNewCollectionFk INT; + DECLARE vOldCollectionFk INT; + DECLARE vIsPackingByOther BOOL; - SELECT COUNT(*) > 0 - INTO vIsAdvanced - FROM packingSiteAdvanced - WHERE ticketFk = vTicketFk; + SELECT id, collectionFk + INTO vExists, vOldCollectionFk + FROM packingSite + WHERE id = vSelf; - IF vIsAdvanced THEN - LEAVE proc; - END IF; + IF NOT vExists THEN + CALL util.throw('packingSiteNotExists'); + END IF; - SELECT collectionFk INTO vNewCollectionFk - FROM ticketCollection WHERE ticketFk = vTicketFk; + SELECT COUNT(*) > 0 + INTO vIsAdvanced + FROM packingSiteAdvanced + WHERE ticketFk = vTicketFk; - SELECT collectionFk INTO vOldCollectionFk - FROM packingSite WHERE id = vSelf; + IF vIsAdvanced THEN + LEAVE proc; + END IF; - IF NOT (vOldCollectionFk <=> vNewCollectionFk) THEN - SELECT COUNT(*) > 0 - INTO vIsPackingByOther - FROM packingSite - WHERE id <> vSelf - AND collectionFk = vOldCollectionFk; + SELECT collectionFk INTO vNewCollectionFk + FROM ticketCollection WHERE ticketFk = vTicketFk; - IF NOT vIsPackingByOther AND NOT collection_isPacked(vOldCollectionFk) AND vSelf IS NOT NULL THEN - CALL util.throw('cannotChangeCollection'); - END IF; - END IF; + IF vOldCollectionFk IS NOT NULL + AND vOldCollectionFk <> vNewCollectionFk THEN + SELECT COUNT(*) > 0 + INTO vIsPackingByOther + FROM packingSite + WHERE id <> vSelf + AND collectionFk = vOldCollectionFk; - UPDATE packingSite SET collectionFk = vNewCollectionFk - WHERE id = vSelf; + IF NOT vIsPackingByOther AND NOT collection_isPacked(vOldCollectionFk) THEN + CALL util.throw('cannotChangeCollection'); + END IF; + END IF; + + UPDATE packingSite SET collectionFk = vNewCollectionFk + WHERE id = vSelf; END$$ DELIMITER ; From 7fa4eabf86df48b01a25ee1981e7f0475d3a12c4 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 14 Jun 2023 14:59:18 +0200 Subject: [PATCH 116/170] refs #5842 fix: recalcula invoiceDate cuando se cambia la company --- .../front/global-invoicing/index.html | 3 +- .../front/global-invoicing/index.js | 34 +++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/modules/invoiceOut/front/global-invoicing/index.html b/modules/invoiceOut/front/global-invoicing/index.html index 6d5b16329..1df01c7f0 100644 --- a/modules/invoiceOut/front/global-invoicing/index.html +++ b/modules/invoiceOut/front/global-invoicing/index.html @@ -118,7 +118,8 @@ label="Company" show-field="code" value-field="id" - ng-model="$ctrl.companyFk"> + ng-model="$ctrl.companyFk" + on-change="$ctrl.recalcInvoiceDate($ctrl.companyFk)"> { - this.companyFk = res.data.companyFk; - const params = { - companyFk: this.companyFk - }; - return this.$http.get('InvoiceOuts/getInvoiceDate', {params}); - }) - .then(res => { - this.minInvoicingDate = res.data.issued ? new Date(res.data.issued) : null; - this.invoiceDate = this.minInvoicingDate; - }); - } + .then(res => { + this.companyFk = res.data.companyFk; + this.recalcInvoiceDate(this.companyFk); + }); + } + + recalcInvoiceDate(companyFk) { + const params = { companyFk: companyFk }; + this.fetchInvoiceDate(params); + } + + fetchInvoiceDate(params) { + this.$http.get('InvoiceOuts/getInvoiceDate', { params }) + .then(res => { + this.minInvoicingDate = res.data.issued ? new Date(res.data.issued) : null; + this.invoiceDate = this.minInvoicingDate; + }); + } stopInvoicing() { this.status = 'stopping'; From 14ebcf96c05931c6318d7dbcbab2f3ded84cfee7 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 15 Jun 2023 07:24:17 +0200 Subject: [PATCH 117/170] refs #5842 refactor: change names --- modules/invoiceOut/front/global-invoicing/index.html | 2 +- modules/invoiceOut/front/global-invoicing/index.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/invoiceOut/front/global-invoicing/index.html b/modules/invoiceOut/front/global-invoicing/index.html index 1df01c7f0..3f0a10650 100644 --- a/modules/invoiceOut/front/global-invoicing/index.html +++ b/modules/invoiceOut/front/global-invoicing/index.html @@ -119,7 +119,7 @@ show-field="code" value-field="id" ng-model="$ctrl.companyFk" - on-change="$ctrl.recalcInvoiceDate($ctrl.companyFk)"> + on-change="$ctrl.getInvoiceDate(value)"> { this.companyFk = res.data.companyFk; - this.recalcInvoiceDate(this.companyFk); + this.getInvoiceDate(this.companyFk); }); } - recalcInvoiceDate(companyFk) { + getInvoiceDate(companyFk) { const params = { companyFk: companyFk }; this.fetchInvoiceDate(params); } From a50de4e509d11fae67b6d069bd9f7183330be973 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 15 Jun 2023 09:50:46 +0200 Subject: [PATCH 118/170] refs #5842 feat: comprueba que invoiceDate no sea null --- modules/invoiceOut/front/global-invoicing/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/invoiceOut/front/global-invoicing/index.js b/modules/invoiceOut/front/global-invoicing/index.js index f300d4496..965782e5b 100644 --- a/modules/invoiceOut/front/global-invoicing/index.js +++ b/modules/invoiceOut/front/global-invoicing/index.js @@ -42,13 +42,14 @@ class Controller extends Section { this.addresses = null; try { + console.log(this.invoiceDate, this.minInvoicingDate); if (this.clientsToInvoice == 'one' && !this.clientId) throw new UserError('Choose a valid client'); if (!this.invoiceDate || !this.maxShipped) throw new UserError('Invoice date and the max date should be filled'); if (this.invoiceDate < this.maxShipped) throw new UserError('Invoice date can\'t be less than max date'); - if (this.invoiceDate.getTime() < this.minInvoicingDate.getTime()) + if (this.minInvoicingDate && this.invoiceDate.getTime() < this.minInvoicingDate.getTime()) throw new UserError('Exists an invoice with a previous date'); if (!this.companyFk) throw new UserError('Choose a valid company'); From 5f2c5c5f9d93ee7416f84309c095e45535433cd8 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 15 Jun 2023 09:55:32 +0200 Subject: [PATCH 119/170] refs #5842 delete console.log --- modules/invoiceOut/front/global-invoicing/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/invoiceOut/front/global-invoicing/index.js b/modules/invoiceOut/front/global-invoicing/index.js index 965782e5b..5a078dfbb 100644 --- a/modules/invoiceOut/front/global-invoicing/index.js +++ b/modules/invoiceOut/front/global-invoicing/index.js @@ -42,7 +42,6 @@ class Controller extends Section { this.addresses = null; try { - console.log(this.invoiceDate, this.minInvoicingDate); if (this.clientsToInvoice == 'one' && !this.clientId) throw new UserError('Choose a valid client'); if (!this.invoiceDate || !this.maxShipped) From 99ad9d3afa56d8d38a1dc112e11fc39c69571a19 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 15 Jun 2023 11:49:39 +0200 Subject: [PATCH 120/170] refs #5753 fix(change-password) --- CHANGELOG.md | 2 +- README.md | 4 ++-- back/methods/vn-user/signIn.js | 7 +++---- db/changes/{232601 => 232401}/00-userPassExpired.sql | 0 db/changes/232601/.gitkeep | 0 front/salix/components/change-password/index.js | 8 ++++---- front/salix/components/login/index.js | 7 +++---- front/salix/routes.js | 2 +- modules/account/front/accounts/index.js | 3 +-- package.json | 2 +- 10 files changed, 16 insertions(+), 19 deletions(-) rename db/changes/{232601 => 232401}/00-userPassExpired.sql (100%) delete mode 100644 db/changes/232601/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index 708ebbc4b..8967a1633 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - -## [2324.01] - 2023-06-08 +## [2324.01] - 2023-06-15 ### Added - (Tickets -> Abono) Al abonar permite crear el ticket abono con almacén o sin almmacén diff --git a/README.md b/README.md index f73a8551b..59f5dbcf7 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Salix is also the scientific name of a beautifull tree! :) Required applications. -* Node.js = 14.x LTS +* Node.js >= 16.x LTS * Docker * Git @@ -71,7 +71,7 @@ $ npm run test:e2e Open Visual Studio Code, press Ctrl+P and paste the following commands. -In Visual Studio Code we use the ESLint extension. +In Visual Studio Code we use the ESLint extension. ``` ext install dbaeumer.vscode-eslint ``` diff --git a/back/methods/vn-user/signIn.js b/back/methods/vn-user/signIn.js index d7db90a21..6615cb5f1 100644 --- a/back/methods/vn-user/signIn.js +++ b/back/methods/vn-user/signIn.js @@ -62,10 +62,9 @@ module.exports = Self => { scopes: ['change-password'], userId: vnUser.id }); - throw new UserError('Pass expired', 'passExpired', { - id: vnUser.id, - token: changePasswordToken.id - }); + const err = new UserError('Pass expired', 'passExpired'); + err.details = {token: changePasswordToken}; + throw err; } try { diff --git a/db/changes/232601/00-userPassExpired.sql b/db/changes/232401/00-userPassExpired.sql similarity index 100% rename from db/changes/232601/00-userPassExpired.sql rename to db/changes/232401/00-userPassExpired.sql diff --git a/db/changes/232601/.gitkeep b/db/changes/232601/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/front/salix/components/change-password/index.js b/front/salix/components/change-password/index.js index 3d660e894..baa9d96e5 100644 --- a/front/salix/components/change-password/index.js +++ b/front/salix/components/change-password/index.js @@ -15,7 +15,7 @@ export default class Controller { } $onInit() { - if (!this.$state.params || !this.$state.params.id || !this.$state.params.token) + if (!this.$state.params.id) this.$state.go('login'); this.$http.get('UserPasswords/findOne') @@ -25,7 +25,7 @@ export default class Controller { } submit() { - const id = this.$state.params.id; + const userId = this.$state.params.userId; const newPassword = this.newPassword; const oldPassword = this.oldPassword; @@ -35,12 +35,12 @@ export default class Controller { throw new UserError(`Passwords don't match`); const headers = { - Authorization: this.$state.params.token + Authorization: this.$state.params.id }; this.$http.post('VnUsers/change-password', { - id, + id: userId, oldPassword, newPassword }, diff --git a/front/salix/components/login/index.js b/front/salix/components/login/index.js index 0412f3b74..8e8f08244 100644 --- a/front/salix/components/login/index.js +++ b/front/salix/components/login/index.js @@ -27,10 +27,9 @@ export default class Controller { this.loading = false; this.password = ''; this.focusUser(); - if (req?.data?.error?.code == 'passExpired') { - const [args] = req.data.error.translateArgs; - this.$state.go('change-password', args); - } + const err = req.data?.error; + if (err?.code == 'passExpired') + this.$state.go('change-password', err.details.token); throw req; }); diff --git a/front/salix/routes.js b/front/salix/routes.js index d6dea244a..675da719a 100644 --- a/front/salix/routes.js +++ b/front/salix/routes.js @@ -38,7 +38,7 @@ function config($stateProvider, $urlRouterProvider) { }) .state('change-password', { parent: 'outLayout', - url: '/change-password?id&token', + url: '/change-password?id&userId', description: 'Change password', template: '' }) diff --git a/modules/account/front/accounts/index.js b/modules/account/front/accounts/index.js index 7a341b0b0..0e78ab8d6 100644 --- a/modules/account/front/accounts/index.js +++ b/modules/account/front/accounts/index.js @@ -5,8 +5,7 @@ import UserError from 'core/lib/user-error'; export default class Controller extends Section { onSynchronizeAll() { this.vnApp.showSuccess(this.$t('Synchronizing in the background')); - this.$http.patch(`Accounts/syncAll`) - .then(() => this.vnApp.showSuccess(this.$t('Users synchronized!'))); + this.$http.patch(`Accounts/syncAll`); } onUserSync() { diff --git a/package.json b/package.json index 4358c86a7..f1b3daca3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.26.01", + "version": "23.24.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From 2a34abac611ba522648bba05a85890b21d714384 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 15 Jun 2023 12:06:42 +0200 Subject: [PATCH 121/170] refs #5513 minor fixes --- print/templates/email/modified-entry/locale/en.yml | 2 +- print/templates/email/modified-entry/locale/es.yml | 2 +- print/templates/email/modified-entry/modified-entry.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/print/templates/email/modified-entry/locale/en.yml b/print/templates/email/modified-entry/locale/en.yml index c70cfe5cc..7bdfa15ff 100644 --- a/print/templates/email/modified-entry/locale/en.yml +++ b/print/templates/email/modified-entry/locale/en.yml @@ -1,3 +1,3 @@ subject: Modified entry title: Modified entry -description: 'From Warehouse the following packaging entry has been created/modified: ' +description: From Warehouse the following packaging entry has been created/modified diff --git a/print/templates/email/modified-entry/locale/es.yml b/print/templates/email/modified-entry/locale/es.yml index 72ddb5ca5..5a00307f9 100644 --- a/print/templates/email/modified-entry/locale/es.yml +++ b/print/templates/email/modified-entry/locale/es.yml @@ -1,3 +1,3 @@ subject: Entrada modificada title: Entrada modificada -description: 'Desde Almacén se ha creado/modificado la siguiente entrada de embalajes: ' +description: Desde Almacén se ha creado/modificado la siguiente entrada de embalajes diff --git a/print/templates/email/modified-entry/modified-entry.html b/print/templates/email/modified-entry/modified-entry.html index a0f297354..869d019a4 100644 --- a/print/templates/email/modified-entry/modified-entry.html +++ b/print/templates/email/modified-entry/modified-entry.html @@ -3,7 +3,7 @@

{{ $t('title') }}

- {{ $t('description') }} + {{ $t('description') }}: {{ url }}

From 8b832c68b3c1289a5457e3827c791e9a7221797a Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 15 Jun 2023 12:49:53 +0200 Subject: [PATCH 122/170] refs #5325 fix back --- modules/ticket/back/methods/ticket-request/specs/filter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket-request/specs/filter.spec.js b/modules/ticket/back/methods/ticket-request/specs/filter.spec.js index ae004a024..565e006fb 100644 --- a/modules/ticket/back/methods/ticket-request/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/filter.spec.js @@ -173,7 +173,7 @@ describe('ticket-request filter()', () => { const result = await models.TicketRequest.filter(ctx, options); const requestId = result[0].id; - expect(requestId).toEqual(3); + expect(requestId).toEqual(4); await tx.rollback(); } catch (e) { From 1c666cd48e04ce883e128d2b9a42b2bd1109f501 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Thu, 15 Jun 2023 13:10:44 +0200 Subject: [PATCH 123/170] refs #5595 Fix: ctx & userId removed from TpvTransaction/confirm --- modules/client/back/methods/tpv-transaction/confirm.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 4faa21bb5..41229a1fd 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -2,7 +2,7 @@ const UserError = require('vn-loopback/util/user-error'); const base64url = require('base64url'); module.exports = Self => { - Self.remoteMethodCtx('confirm', { + Self.remoteMethod('confirm', { description: 'Confirms electronic payment transaction', accessType: 'WRITE', accepts: [ @@ -30,7 +30,7 @@ module.exports = Self => { } }); - Self.confirm = async(ctx, signatureVersion, merchantParameters, signature) => { + Self.confirm = async(signatureVersion, merchantParameters, signature) => { const $ = Self.app.models; let transaction; @@ -83,7 +83,7 @@ module.exports = Self => { params['Ds_Currency'], params['Ds_Response'], params['Ds_ErrorCode'] - ], {userId: ctx.req.accessToken.userId}); + ]); return true; } catch (err) { From e8d28ddb025a2191bb92c106c8334015f168519a Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 15 Jun 2023 15:15:41 +0200 Subject: [PATCH 124/170] v232601 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4ed50e256..c190065b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.24.01", + "version": "23.26.01", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/package.json b/package.json index f1b3daca3..4358c86a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.24.01", + "version": "23.26.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From 7bff915a7f3cb62dba4224e5c6e4ca1731afc0d5 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 15 Jun 2023 17:14:34 +0200 Subject: [PATCH 125/170] refs #5325 back fix correct --- modules/ticket/back/methods/ticket-request/specs/filter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket-request/specs/filter.spec.js b/modules/ticket/back/methods/ticket-request/specs/filter.spec.js index 565e006fb..ae004a024 100644 --- a/modules/ticket/back/methods/ticket-request/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/filter.spec.js @@ -173,7 +173,7 @@ describe('ticket-request filter()', () => { const result = await models.TicketRequest.filter(ctx, options); const requestId = result[0].id; - expect(requestId).toEqual(4); + expect(requestId).toEqual(3); await tx.rollback(); } catch (e) { From ef0ae335e81e2bb86da4323165efd7c029167321 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 16 Jun 2023 11:56:36 +0200 Subject: [PATCH 126/170] fix: muestra las observaciones de los tickets --- print/templates/reports/invoice/invoice.html | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/print/templates/reports/invoice/invoice.html b/print/templates/reports/invoice/invoice.html index 727621b2c..d74325dfd 100644 --- a/print/templates/reports/invoice/invoice.html +++ b/print/templates/reports/invoice/invoice.html @@ -242,7 +242,7 @@
-
+
{{$t('observations')}}
@@ -267,9 +267,7 @@ v-bind:left-text="$t('invoiceRef', [invoice.ref])" v-bind:center-text="client.socialName" v-bind:recipient-id="client.id" - v-bind="$props" - - > + v-bind="$props"> From 75bb0f8160d7464dde79ce47e487d0f355f5b069 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 16 Jun 2023 12:19:59 +0200 Subject: [PATCH 127/170] refs #5860 fix hash smbhash --- back/process.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/process.yml b/back/process.yml index 38d2b9eaf..a29323240 100644 --- a/back/process.yml +++ b/back/process.yml @@ -4,4 +4,4 @@ apps: instances: 1 max_restarts: 3 restart_delay: 15000 - node_args: --tls-min-v1.0 + node_args: --tls-min-v1.0 --openssl-legacy-provider From 081cf43eceaeb775d3118b8f169a41049dde7278 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 16 Jun 2023 13:39:24 +0200 Subject: [PATCH 128/170] refs #5667 SupplierAccount translation added --- modules/supplier/back/locale/supplier-account/en.yml | 1 + modules/supplier/back/locale/supplier-account/es.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/supplier/back/locale/supplier-account/en.yml b/modules/supplier/back/locale/supplier-account/en.yml index 2bce50cfa..43c4ba40d 100644 --- a/modules/supplier/back/locale/supplier-account/en.yml +++ b/modules/supplier/back/locale/supplier-account/en.yml @@ -5,3 +5,4 @@ columns: beneficiary: beneficiary supplierFk: supplier bankEntityFk: bank entity + accountingFk: ledger account diff --git a/modules/supplier/back/locale/supplier-account/es.yml b/modules/supplier/back/locale/supplier-account/es.yml index 120293c8a..9db5708a3 100644 --- a/modules/supplier/back/locale/supplier-account/es.yml +++ b/modules/supplier/back/locale/supplier-account/es.yml @@ -5,3 +5,4 @@ columns: beneficiary: beneficiario supplierFk: proveedor bankEntityFk: entidad bancaria + accountingFk: cuenta contable From b6c8ca20ee9e2eb7b932499300522913f0338175 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Mon, 19 Jun 2023 08:58:20 +0200 Subject: [PATCH 129/170] refs #5339 data --- modules/worker/back/models/operator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/models/operator.js b/modules/worker/back/models/operator.js index e9b590fa6..63b5154ed 100644 --- a/modules/worker/back/models/operator.js +++ b/modules/worker/back/models/operator.js @@ -1,6 +1,6 @@ module.exports = function(Self) { Self.observe('after save', async function(ctx) { - const instance = ctx.instance; + const instance = ctx.data; const models = Self.app.models; const options = ctx.options; From 63888e2d6441b277250c1ea7873d3a9b13a81933 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 19 Jun 2023 13:52:25 +0200 Subject: [PATCH 130/170] refs #5595 console.log(orderFk, userId) for rawSQL logs --- modules/order/back/methods/order/confirm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/order/back/methods/order/confirm.js b/modules/order/back/methods/order/confirm.js index 5fdab29b3..5a31e7149 100644 --- a/modules/order/back/methods/order/confirm.js +++ b/modules/order/back/methods/order/confirm.js @@ -21,7 +21,7 @@ module.exports = Self => { Self.confirm = async(ctx, orderFk) => { const userId = ctx.req.accessToken.userId; - + console.log(orderFk, userId); const query = `CALL hedera.order_confirmWithUser(?, ?)`; const response = await Self.rawSql(query, [orderFk, userId], {userId}); From 9fa6e2df71ed50fad312acdcdff4cd3f5cd08834 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 19 Jun 2023 14:54:32 +0200 Subject: [PATCH 131/170] refs #5595 VnModel.rawSql() bugfix --- loopback/common/models/vn-model.js | 31 ++++++++++----------- modules/order/back/methods/order/confirm.js | 1 - 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/loopback/common/models/vn-model.js b/loopback/common/models/vn-model.js index f92e1ea09..22b535f62 100644 --- a/loopback/common/models/vn-model.js +++ b/loopback/common/models/vn-model.js @@ -200,22 +200,20 @@ module.exports = function(Self) { const connector = this.dataSource.connector; let conn; let res; - const opts = Object.assign({}, options); try { if (userId) { - conn = await new Promise((resolve, reject) => { - connector.client.getConnection(function(err, conn) { - if (err) - reject(err); - else - resolve(conn); + if (!options.transaction) { + options = Object.assign({}, options); + conn = await new Promise((resolve, reject) => { + connector.client.getConnection(function(err, conn) { + if (err) + reject(err); + else + resolve(conn); + }); }); - }); - - const opts = Object.assign({}, options); - if (!opts.transaction) { - opts.transaction = { + options.transaction = { connection: conn, connector }; @@ -223,15 +221,14 @@ module.exports = function(Self) { await connector.executeP( 'CALL account.myUser_loginWithName((SELECT name FROM account.user WHERE id = ?))', - [userId], opts + [userId], options ); } - res = await connector.executeP(query, params, opts); + res = await connector.executeP(query, params, options); - if (userId) { - await connector.executeP('CALL account.myUser_logout()', null, opts); - } + if (userId) + await connector.executeP('CALL account.myUser_logout()', null, options); } finally { if (conn) conn.release(); } diff --git a/modules/order/back/methods/order/confirm.js b/modules/order/back/methods/order/confirm.js index 5a31e7149..1fcb3a760 100644 --- a/modules/order/back/methods/order/confirm.js +++ b/modules/order/back/methods/order/confirm.js @@ -21,7 +21,6 @@ module.exports = Self => { Self.confirm = async(ctx, orderFk) => { const userId = ctx.req.accessToken.userId; - console.log(orderFk, userId); const query = `CALL hedera.order_confirmWithUser(?, ?)`; const response = await Self.rawSql(query, [orderFk, userId], {userId}); From 503054fe05d4d04acfc43d952ba0c258cf1f7798 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 20 Jun 2023 08:58:22 +0200 Subject: [PATCH 132/170] refs #5112 modificaciones entry_updateComission --- .../232601/00-entry_updateComission.sql | 40 +++++++++++++ .../entry-update-comission.html | 58 ++++--------------- .../entry-update-comission.js | 10 ++-- 3 files changed, 54 insertions(+), 54 deletions(-) create mode 100644 db/changes/232601/00-entry_updateComission.sql diff --git a/db/changes/232601/00-entry_updateComission.sql b/db/changes/232601/00-entry_updateComission.sql new file mode 100644 index 000000000..5a25d72e8 --- /dev/null +++ b/db/changes/232601/00-entry_updateComission.sql @@ -0,0 +1,40 @@ +DELIMITER $$ +$$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`entry_updateComission`(vCurrency INT) +BEGIN +/** + * Actualiza la comision de las entradas de hoy a futuro y las recalcula + * + * @param vCurrency id del tipo de moneda(SAR,EUR,USD,GBP,JPY) + */ + DECLARE vCurrencyName VARCHAR(25); + DECLARE vComission INT; + + CREATE OR REPLACE TEMPORARY TABLE tmp.recalcEntryCommision + SELECT e.id + FROM vn.entry e + JOIN vn.travel t ON t.id = e.travelFk + JOIN vn.warehouse w ON w.id = t.warehouseInFk + WHERE t.shipped >= util.VN_CURDATE() + AND e.currencyFk = vCurrency; + + SET vComission = currency_getCommission(vCurrency); + + UPDATE vn.entry e + JOIN tmp.recalcEntryCommision tmp ON tmp.id = e.id + SET e.commission = vComission; + + SELECT `name` INTO vCurrencyName + FROM currency + WHERE id = vCurrency; + + CALL entry_recalc(); + SELECT util.notification_send( + 'entry-update-comission', + JSON_OBJECT('currencyName', vCurrencyName, 'referenceCurrent', vComission), + account.myUser_getId() + ); + + DROP TEMPORARY TABLE tmp.recalcEntryCommision; +END$$ +DELIMITER ; \ No newline at end of file diff --git a/print/templates/email/entry-update-comission/entry-update-comission.html b/print/templates/email/entry-update-comission/entry-update-comission.html index 85439475b..d3ca1202a 100644 --- a/print/templates/email/entry-update-comission/entry-update-comission.html +++ b/print/templates/email/entry-update-comission/entry-update-comission.html @@ -1,48 +1,10 @@ - - - - - - {{ $t('subject') }} - - - - - - - - -
- -
-
-
- -
-
- -
-
- -
-
-

- {{$t('dear')}} -

-

-
-
- - -
-
- -
-
- -
-
-
-
- - + +
+
+

+ {{$t('dear')}} +

+

+
+
+
diff --git a/print/templates/email/entry-update-comission/entry-update-comission.js b/print/templates/email/entry-update-comission/entry-update-comission.js index 7e23c2b7c..8afe10ea0 100755 --- a/print/templates/email/entry-update-comission/entry-update-comission.js +++ b/print/templates/email/entry-update-comission/entry-update-comission.js @@ -1,20 +1,18 @@ const Component = require(`vn-print/core/component`); -const emailHeader = new Component('email-header'); -const emailFooter = new Component('email-footer'); +const emailBody = new Component('email-body'); module.exports = { name: 'entry-update-comission', components: { - 'email-header': emailHeader.build(), - 'email-footer': emailFooter.build() + 'email-body': emailBody.build(), }, props: { currencyName: { - type: [String], + type: String, required: true }, referenceCurrent: { - type: [String], + type: Number, required: true } } From ffbaa4532006e7b448cd0cefe8d3be24b7903331 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 20 Jun 2023 09:05:39 +0200 Subject: [PATCH 133/170] refs #5112 changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8967a1633..fa2ebcd62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [2326.01] - 2023-06-29 ### Added +- (Entradas -> Correo) Al cambiar el tipo de cambio enviará un correo a las personas designadas ### Changed From dcfb991f94a0e74fcc629d12af877389073d90f1 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 20 Jun 2023 09:20:06 +0200 Subject: [PATCH 134/170] hotFix(getLeaves): remoteMethodCtx correct defined --- modules/worker/back/methods/department/getLeaves.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/methods/department/getLeaves.js b/modules/worker/back/methods/department/getLeaves.js index 48fe78e08..b1ce2fbe8 100644 --- a/modules/worker/back/methods/department/getLeaves.js +++ b/modules/worker/back/methods/department/getLeaves.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethodCtx, ('getLeaves', { + Self.remoteMethodCtx('getLeaves', { description: 'Returns the nodes for a department', accepts: [{ arg: 'parentId', From 6c00e704cc95f7c5750ca6d9b544cdb2502a76b6 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 20 Jun 2023 09:42:08 +0200 Subject: [PATCH 135/170] refs #5697 fix: eliminado por la columna fecha, que no se formatea correctamente --- modules/monitor/front/index/tickets/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html index bdd4e76ff..94a950baf 100644 --- a/modules/monitor/front/index/tickets/index.html +++ b/modules/monitor/front/index/tickets/index.html @@ -50,13 +50,13 @@ Salesperson - + Date - + Theoretical - + Practical From a7d9bbc582abf96611fecfb3ac31aa7fdaf4b506 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 20 Jun 2023 10:22:30 +0200 Subject: [PATCH 136/170] refs #5537 change cl c --- print/core/components/report-footer/report-footer.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/print/core/components/report-footer/report-footer.js b/print/core/components/report-footer/report-footer.js index 077ef0bde..ed718b8dc 100755 --- a/print/core/components/report-footer/report-footer.js +++ b/print/core/components/report-footer/report-footer.js @@ -5,10 +5,9 @@ module.exports = { name: 'report-footer', async serverPrefetch() { this.company = await db.findOne(` - SELECT IFNULL(ci.footnotes, cl.footnotes) as footnotes + SELECT IFNULL(ci.footnotes, c.footnotes) footnotes FROM company c - LEFT JOIN companyL10n cl ON c.id = cl.id - LEFT JOIN companyI18n ci ON ci.companyFk = cl.id + LEFT JOIN companyI18n ci ON ci.companyFk = c.id AND ci.lang = (SELECT lang FROM account.user where id = ?) WHERE c.code = ?`, [this.recipientId, this.companyCode]); From cea6fae64949f828aaf202e06ee82963e357cc07 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 20 Jun 2023 10:40:57 +0200 Subject: [PATCH 137/170] fix: eliminada variable que no estaba definida --- modules/ticket/back/methods/ticket/setDeleted.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js index 7cc300547..40f3db8c5 100644 --- a/modules/ticket/back/methods/ticket/setDeleted.js +++ b/modules/ticket/back/methods/ticket/setDeleted.js @@ -81,7 +81,7 @@ module.exports = Self => { throw new UserError('You must delete all the buy requests first'); // removes item shelvings - if (hasItemShelvingSales && isSalesAssistant) { + if (hasItemShelvingSales && canDeleteTicketWithPartPrepared) { const promises = []; for (let sale of sales) { if (sale.itemShelvingSale()) { From e99627c0b238c4019fdd894ee154d38616f839dc Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 20 Jun 2023 11:28:25 +0200 Subject: [PATCH 138/170] codigo innecesario --- modules/ticket/back/methods/ticket/setDeleted.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js index 40f3db8c5..4d7fe73d4 100644 --- a/modules/ticket/back/methods/ticket/setDeleted.js +++ b/modules/ticket/back/methods/ticket/setDeleted.js @@ -81,17 +81,15 @@ module.exports = Self => { throw new UserError('You must delete all the buy requests first'); // removes item shelvings - if (hasItemShelvingSales && canDeleteTicketWithPartPrepared) { - const promises = []; - for (let sale of sales) { - if (sale.itemShelvingSale()) { - const itemShelvingSale = sale.itemShelvingSale(); - const destroyedShelving = models.ItemShelvingSale.destroyById(itemShelvingSale.id, myOptions); - promises.push(destroyedShelving); - } + const promises = []; + for (let sale of sales) { + if (sale.itemShelvingSale()) { + const itemShelvingSale = sale.itemShelvingSale(); + const destroyedShelving = models.ItemShelvingSale.destroyById(itemShelvingSale.id, myOptions); + promises.push(destroyedShelving); } - await Promise.all(promises); } + await Promise.all(promises); // Remove ticket greuges const ticketGreuges = await models.Greuge.find({where: {ticketFk: id}}, myOptions); From 2649db852f215a477ac0804068887c853336dfc8 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Tue, 20 Jun 2023 11:50:36 +0200 Subject: [PATCH 139/170] refs #5772 Invoice PDF size reduced --- print/templates/reports/invoice/assets/css/style.css | 6 +++++- print/templates/reports/invoice/invoice.html | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/print/templates/reports/invoice/assets/css/style.css b/print/templates/reports/invoice/assets/css/style.css index 9fda2a613..d4526ce56 100644 --- a/print/templates/reports/invoice/assets/css/style.css +++ b/print/templates/reports/invoice/assets/css/style.css @@ -16,6 +16,10 @@ h2 { font-size: 22px } +.column-oriented td, +.column-oriented th { + padding: 6px +} #nickname h2 { max-width: 400px; @@ -39,4 +43,4 @@ h2 { .phytosanitary-info { margin-top: 10px -} \ No newline at end of file +} diff --git a/print/templates/reports/invoice/invoice.html b/print/templates/reports/invoice/invoice.html index d74325dfd..32138befc 100644 --- a/print/templates/reports/invoice/invoice.html +++ b/print/templates/reports/invoice/invoice.html @@ -62,7 +62,7 @@
-
+

{{$t('deliveryNote')}}

@@ -106,6 +106,7 @@ {{sale.vatType}} {{saleImport(sale) | currency('EUR', $i18n.locale)}} + From 6f9fd9bb72109aed288fe46671ca40aa5c417c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Wed, 21 Jun 2023 09:40:14 +0200 Subject: [PATCH 140/170] refs #5772 mensajes de error --- loopback/locale/es.json | 2 +- modules/invoiceOut/front/global-invoicing/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 7e2701f95..b66a13569 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -265,7 +265,7 @@ "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 previous date": "Existe una factura con fecha anterior", + "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", diff --git a/modules/invoiceOut/front/global-invoicing/index.js b/modules/invoiceOut/front/global-invoicing/index.js index 5a078dfbb..70838a5a2 100644 --- a/modules/invoiceOut/front/global-invoicing/index.js +++ b/modules/invoiceOut/front/global-invoicing/index.js @@ -49,7 +49,7 @@ class Controller extends Section { if (this.invoiceDate < this.maxShipped) throw new UserError('Invoice date can\'t be less than max date'); if (this.minInvoicingDate && this.invoiceDate.getTime() < this.minInvoicingDate.getTime()) - throw new UserError('Exists an invoice with a previous date'); + throw new UserError('Exists an invoice with a future date'); if (!this.companyFk) throw new UserError('Choose a valid company'); if (!this.printerFk) From 44192c0606ba7611946f21bf1189d2fa8a3e9df3 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Wed, 21 Jun 2023 11:08:28 +0200 Subject: [PATCH 141/170] refs #5667 Client translations added --- modules/client/back/locale/client/en.yml | 3 ++- modules/client/back/locale/client/es.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/client/back/locale/client/en.yml b/modules/client/back/locale/client/en.yml index 74384461c..ad21a6ce6 100644 --- a/modules/client/back/locale/client/en.yml +++ b/modules/client/back/locale/client/en.yml @@ -52,4 +52,5 @@ columns: hasInvoiceSimplified: simplified invoice typeFk: type lastSalesPersonFk: last salesperson - + rating: rating + recommendedCredit: recommended credit diff --git a/modules/client/back/locale/client/es.yml b/modules/client/back/locale/client/es.yml index 47bf896d9..b17f53b1c 100644 --- a/modules/client/back/locale/client/es.yml +++ b/modules/client/back/locale/client/es.yml @@ -52,4 +52,5 @@ columns: hasInvoiceSimplified: factura simple typeFk: tipo lastSalesPersonFk: último comercial - + rating: clasificación + recommendedCredit: crédito recomendado From d9afdccd9cd48f28ac38421967a5f5a0c2db69fc Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 21 Jun 2023 14:12:42 +0200 Subject: [PATCH 142/170] fix: acl renewToken --- back/methods/vn-user/renew-token.js | 1 + db/changes/232601/00-aclVnUser_renewToken.sql | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 db/changes/232601/00-aclVnUser_renewToken.sql diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index 1f3532bd6..41470dfea 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -3,6 +3,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('renewToken', { description: 'Checks if the token has more than renewPeriod seconds to live and if so, renews it', + accessType: 'WRITE', accepts: [], returns: { type: 'Object', diff --git a/db/changes/232601/00-aclVnUser_renewToken.sql b/db/changes/232601/00-aclVnUser_renewToken.sql new file mode 100644 index 000000000..aa20f7a82 --- /dev/null +++ b/db/changes/232601/00-aclVnUser_renewToken.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('VnUser', 'renewToken', 'WRITE', 'ALLOW', 'ROLE', 'employee') From 10a25ff59058ff198880d4e66434783196ccfe2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 22 Jun 2023 07:49:35 +0200 Subject: [PATCH 143/170] refs #5772 --- loopback/locale/en.json | 2 +- loopback/locale/es.json | 8 ++- .../back/methods/invoiceOut/createPdf.js | 42 +++--------- .../back/methods/invoiceOut/download.js | 6 +- .../back/methods/invoiceOut/invoiceClient.js | 65 +++++++++++-------- .../back/methods/invoiceOut/invoiceEmail.js | 7 +- modules/invoiceOut/back/models/invoice-out.js | 33 ++++++++++ .../front/global-invoicing/index.html | 6 +- .../front/global-invoicing/index.js | 13 +++- print/core/smtp.js | 13 +++- 10 files changed, 122 insertions(+), 73 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 43ff4b86a..7a973460d 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -115,7 +115,7 @@ "This client is not invoiceable": "This client is not invoiceable", "INACTIVE_PROVIDER": "Inactive provider", "reference duplicated": "reference duplicated", - "The PDF document does not exists": "The PDF document does not exists. Try regenerating it from 'Regenerate invoice PDF' option", + "The PDF document does not exist": "The PDF document does not exists. Try regenerating it from 'Regenerate invoice PDF' option", "This item is not available": "This item is not available", "Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}", "The type of business must be filled in basic data": "The type of business must be filled in basic data", diff --git a/loopback/locale/es.json b/loopback/locale/es.json index b66a13569..2afe5bab5 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -211,7 +211,7 @@ "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 exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'", + "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", @@ -293,5 +293,7 @@ "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" -} + "Ticket is already signed": "Este ticket ya ha sido firmado", + "Fecha fuera de rango": "Fecha fuera de rango", + "Error while generating PDF": "Error while generating PDF" +} \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index dfdb3c1a7..8cc584c94 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -1,5 +1,4 @@ const UserError = require('vn-loopback/util/user-error'); -const print = require('vn-print'); module.exports = Self => { Self.remoteMethodCtx('createPdf', { @@ -26,9 +25,6 @@ module.exports = Self => { Self.createPdf = async function(ctx, id, options) { const models = Self.app.models; - if (process.env.NODE_ENV == 'test') - throw new UserError(`Action not allowed on the test environment`); - let tx; const myOptions = {}; @@ -41,40 +37,20 @@ module.exports = Self => { } try { - const invoiceOut = await Self.findById(id, null, myOptions); - const canCreatePdf = await models.ACL.checkAccessAcl(ctx, 'InvoiceOut', 'canCreatePdf', 'WRITE'); + const invoiceOut = await Self.findById(id, {fields: ['hasPdf']}, myOptions); - if (invoiceOut.hasPdf && !canCreatePdf) - throw new UserError(`You don't have enough privileges`); + if (invoiceOut.hasPdf) { + const canCreatePdf = await models.ACL.checkAccessAcl(ctx, 'InvoiceOut', 'canCreatePdf', 'WRITE'); + if (!canCreatePdf) + throw new UserError(`You don't have enough privileges`); + } - await invoiceOut.updateAttributes({ - hasPdf: true - }, myOptions); - - const invoiceReport = new print.Report('invoice', { - reference: invoiceOut.ref, - recipientId: invoiceOut.clientFk - }); - const buffer = await invoiceReport.toPdfStream(); - - const issued = invoiceOut.issued; - const year = issued.getFullYear().toString(); - const month = (issued.getMonth() + 1).toString(); - const day = issued.getDate().toString(); - - const fileName = `${year}${invoiceOut.ref}.pdf`; - - // Store invoice - await print.storage.write(buffer, { - type: 'invoice', - path: `${year}/${month}/${day}`, - fileName: fileName - }); + await Self.makePdf(id, myOptions); if (tx) await tx.commit(); - } catch (e) { + } catch (err) { if (tx) await tx.rollback(); - throw e; + throw err; } }; }; diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index 5c787428b..49bba046b 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -43,7 +43,9 @@ module.exports = Self => { Object.assign(myOptions, options); try { - const invoiceOut = await models.InvoiceOut.findById(id, null, myOptions); + const invoiceOut = await models.InvoiceOut.findById(id, { + fields: ['ref', 'issued'] + }, myOptions); const issued = invoiceOut.issued; const year = issued.getFullYear().toString(); @@ -73,7 +75,7 @@ module.exports = Self => { return [stream, file.contentType, `filename="${file.name}"`]; } catch (error) { if (error.code === 'ENOENT') - throw new UserError('The PDF document does not exists'); + throw new UserError('The PDF document does not exist'); throw error; } diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js index 421cbaea1..ff814fea9 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js +++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js @@ -109,17 +109,22 @@ module.exports = Self => { ], myOptions); const [newInvoice] = await Self.rawSql(`SELECT @invoiceId id`, null, myOptions); - if (newInvoice.id) { - await Self.rawSql('CALL invoiceOutBooking(?)', [newInvoice.id], myOptions); + if (!newInvoice) + throw new UserError('No tickets to invoice', 'notInvoiced'); - invoiceOut = await models.InvoiceOut.findById(newInvoice.id, { - include: { - relation: 'client' + await Self.rawSql('CALL invoiceOutBooking(?)', [newInvoice.id], myOptions); + + invoiceOut = await models.InvoiceOut.findById(newInvoice.id, { + fields: ['id', 'ref', 'clientFk'], + include: { + relation: 'client', + scope: { + fields: ['email', 'isToBeMailed'] } - }, myOptions); + } + }, myOptions); - invoiceId = newInvoice.id; - } + invoiceId = newInvoice.id; if (tx) await tx.commit(); } catch (e) { @@ -127,26 +132,32 @@ module.exports = Self => { throw e; } - if (invoiceId) { - if (!invoiceOut.client().isToBeMailed) { - const query = ` - CALL vn.report_print( - 'invoice', - ?, - account.myUser_getId(), - JSON_OBJECT('refFk', ?), - 'normal' - );`; - await models.InvoiceOut.rawSql(query, [args.printerFk, invoiceOut.ref]); - } else { - ctx.args = { - reference: invoiceOut.ref, - recipientId: invoiceOut.clientFk, - recipient: invoiceOut.client().email - }; - await models.InvoiceOut.invoiceEmail(ctx, invoiceOut.ref); - } + try { + await Self.makePdf(invoiceId); + } catch (err) { + console.error(err); + throw new UserError('Error while generating PDF', 'pdfError'); } + + if (invoiceOut.client().isToBeMailed) { + ctx.args = { + reference: invoiceOut.ref, + recipientId: args.clientId, + recipient: invoiceOut.client().email + }; + await models.InvoiceOut.invoiceEmail(ctx, invoiceOut.ref); + } else { + const query = ` + CALL vn.report_print( + 'invoice', + ?, + account.myUser_getId(), + JSON_OBJECT('refFk', ?), + 'normal' + );`; + await models.InvoiceOut.rawSql(query, [args.printerFk, invoiceOut.ref]); + } + return invoiceId; }; diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js index 83cb84881..45894e9c5 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js +++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js @@ -1,3 +1,4 @@ +const UserError = require('vn-loopback/util/user-error'); const {Email} = require('vn-print'); module.exports = Self => { @@ -74,6 +75,10 @@ module.exports = Self => { ] }; - return email.send(mailOptions); + try { + return email.send(mailOptions); + } catch(err) { + throw new UserError('Error when sending mail to client', 'mailNotSent'); + } }; }; diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js index 5fcef7744..bfef57f58 100644 --- a/modules/invoiceOut/back/models/invoice-out.js +++ b/modules/invoiceOut/back/models/invoice-out.js @@ -1,3 +1,5 @@ +const print = require('vn-print'); + module.exports = Self => { require('../methods/invoiceOut/filter')(Self); require('../methods/invoiceOut/summary')(Self); @@ -19,4 +21,35 @@ module.exports = Self => { require('../methods/invoiceOut/getInvoiceDate')(Self); require('../methods/invoiceOut/negativeBases')(Self); require('../methods/invoiceOut/negativeBasesCsv')(Self); + + Self.makePdf = async function(id, options) { + const fields = ['id', 'hasPdf', 'ref', 'issued']; + const invoiceOut = await Self.findById(id, {fields}, options); + + const invoiceReport = new print.Report('invoice', { + reference: invoiceOut.ref + }); + const buffer = await invoiceReport.toPdfStream(); + + const issued = invoiceOut.issued; + const year = issued.getFullYear().toString(); + const month = (issued.getMonth() + 1).toString(); + const day = issued.getDate().toString(); + + const fileName = `${year}${invoiceOut.ref}.pdf`; + + // Store invoice + + await invoiceOut.updateAttributes({ + hasPdf: true + }, options); + + if (process.env.NODE_ENV !== 'test') { + await print.storage.write(buffer, { + type: 'invoice', + path: `${year}/${month}/${day}`, + fileName: fileName + }); + } + } }; diff --git a/modules/invoiceOut/front/global-invoicing/index.html b/modules/invoiceOut/front/global-invoicing/index.html index 3f0a10650..52bf8b619 100644 --- a/modules/invoiceOut/front/global-invoicing/index.html +++ b/modules/invoiceOut/front/global-invoicing/index.html @@ -55,7 +55,11 @@ {{::error.address.nickname}} - {{::error.message}} + + {{::error.message}} + diff --git a/modules/invoiceOut/front/global-invoicing/index.js b/modules/invoiceOut/front/global-invoicing/index.js index 70838a5a2..2e4ac1888 100644 --- a/modules/invoiceOut/front/global-invoicing/index.js +++ b/modules/invoiceOut/front/global-invoicing/index.js @@ -108,9 +108,18 @@ class Controller extends Section { this.$http.post(`InvoiceOuts/invoiceClient`, params) .then(() => this.invoiceNext()) .catch(res => { - const message = res.data?.error?.message || res.message; if (res.status >= 400 && res.status < 500) { - this.errors.unshift({address, message}); + const error = res.data?.error; + let isWarning; + switch(error?.code) { + case 'pdfError': + case 'mailNotSent': + isWarning = true; + break; + } + + const message = error?.message || res.message; + this.errors.unshift({address, message, isWarning}); this.invoiceNext(); } else { this.invoicing = false; diff --git a/print/core/smtp.js b/print/core/smtp.js index 61b115b5a..04bede5b5 100644 --- a/print/core/smtp.js +++ b/print/core/smtp.js @@ -46,14 +46,21 @@ module.exports = { const fileNames = attachments.join(',\n'); await db.rawSql(` - INSERT INTO vn.mail (receiver, replyTo, sent, subject, body, attachment, status) - VALUES (?, ?, 1, ?, ?, ?, ?)`, [ + INSERT INTO vn.mail + SET receiver = ?, + replyTo = ?, + sent = ?, + subject = ?, + body = ?, + attachment = ?, + status = ?`, [ options.to, options.replyTo, + error ? 2 : 1, options.subject, options.text || options.html, fileNames, - error && error.message || 'Sent' + error && error.message || 'OK' ]); } From 807596f735d9684419e9757a020a0a43fad680dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 22 Jun 2023 08:50:18 +0200 Subject: [PATCH 144/170] refs #5772 --- loopback/locale/es.json | 3 ++- .../back/methods/invoiceOut/invoiceClient.js | 4 ++-- .../invoiceOut/specs/invoiceClient.spec.js | 2 +- modules/invoiceOut/back/models/invoice-out.js | 16 +++++++++++++--- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 2afe5bab5..5870dcb4f 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -295,5 +295,6 @@ "Ticket does not exist": "Este ticket no existe", "Ticket is already signed": "Este ticket ya ha sido firmado", "Fecha fuera de rango": "Fecha fuera de rango", - "Error while generating PDF": "Error while generating PDF" + "Error while generating PDF": "Error al generar PDF", + "Error when sending mail to client": "Error al enviar el correo al cliente" } \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js index ff814fea9..5d61bfcd0 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js +++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js @@ -131,9 +131,9 @@ module.exports = Self => { if (tx) await tx.rollback(); throw e; } - + try { - await Self.makePdf(invoiceId); + await Self.makePdf(invoiceId, myOptions); } catch (err) { console.error(err); throw new UserError('Error while generating PDF', 'pdfError'); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/invoiceClient.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/invoiceClient.spec.js index 9a0574dba..e26a0b3f1 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/invoiceClient.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/invoiceClient.spec.js @@ -23,7 +23,7 @@ describe('InvoiceOut invoiceClient()', () => { const ctx = {req: activeCtx}; it('should make a global invoicing', async() => { - spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true))); + spyOn(models.InvoiceOut, 'makePdf').and.returnValue(new Promise(resolve => resolve(true))); spyOn(models.InvoiceOut, 'invoiceEmail'); const tx = await models.InvoiceOut.beginTransaction({}); diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js index bfef57f58..027ec2fb2 100644 --- a/modules/invoiceOut/back/models/invoice-out.js +++ b/modules/invoiceOut/back/models/invoice-out.js @@ -23,9 +23,19 @@ module.exports = Self => { require('../methods/invoiceOut/negativeBasesCsv')(Self); Self.makePdf = async function(id, options) { - const fields = ['id', 'hasPdf', 'ref', 'issued']; - const invoiceOut = await Self.findById(id, {fields}, options); + let tx; + const myOptions = {}; + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + const fields = ['id', 'hasPdf', 'ref', 'issued']; + const invoiceOut = await Self.findById(id, {fields}, myOptions); const invoiceReport = new print.Report('invoice', { reference: invoiceOut.ref }); @@ -42,7 +52,7 @@ module.exports = Self => { await invoiceOut.updateAttributes({ hasPdf: true - }, options); + }, myOptions); if (process.env.NODE_ENV !== 'test') { await print.storage.write(buffer, { From 18a810646136d890f9a38035d20c12720e84f079 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 22 Jun 2023 08:56:27 +0200 Subject: [PATCH 145/170] refs #5339 fix after save --- modules/worker/back/models/operator.js | 4 ++-- modules/worker/back/models/operator.json | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/modules/worker/back/models/operator.js b/modules/worker/back/models/operator.js index 63b5154ed..db1ac7e49 100644 --- a/modules/worker/back/models/operator.js +++ b/modules/worker/back/models/operator.js @@ -1,10 +1,10 @@ module.exports = function(Self) { Self.observe('after save', async function(ctx) { - const instance = ctx.data; + const instance = ctx.data || ctx.instance; const models = Self.app.models; const options = ctx.options; - if (!instance.sectorFk || !instance.labelerFk) return; + if (!instance?.sectorFk || !instance?.labelerFk) return; const sector = await models.Sector.findById(instance.sectorFk, { fields: ['mainPrinterFk'] diff --git a/modules/worker/back/models/operator.json b/modules/worker/back/models/operator.json index 9433a0fd5..2417078e1 100644 --- a/modules/worker/back/models/operator.json +++ b/modules/worker/back/models/operator.json @@ -16,18 +16,12 @@ "type": "number" }, "trainFk": { - "type": "number", - "required": true + "type": "number" }, "itemPackingTypeFk": { - "type": "string", - "required": true + "type": "string" }, "warehouseFk": { - "type": "number", - "required": true - }, - "sectorFk": { "type": "number" }, "labelerFk": { From 9d1a181b73e7738dde3fa5cde757416e3cfd1e76 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 22 Jun 2023 11:10:56 +0200 Subject: [PATCH 146/170] refs #5772 feat: si falla al enviar el pdf, envia un rocket al comercial --- .../front/global-invoicing/index.js | 69 ++++++++++++------- .../front/global-invoicing/locale/en.yml | 1 + .../front/global-invoicing/locale/es.yml | 3 +- 3 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 modules/invoiceOut/front/global-invoicing/locale/en.yml diff --git a/modules/invoiceOut/front/global-invoicing/index.js b/modules/invoiceOut/front/global-invoicing/index.js index 2e4ac1888..36552d25b 100644 --- a/modules/invoiceOut/front/global-invoicing/index.js +++ b/modules/invoiceOut/front/global-invoicing/index.js @@ -7,29 +7,29 @@ class Controller extends Section { $onInit() { const date = Date.vnNew(); Object.assign(this, { - maxShipped: new Date(date.getFullYear(), date.getMonth(), 0), - clientsToInvoice: 'all', + maxShipped: new Date(date.getFullYear(), date.getMonth(), 0), + clientsToInvoice: 'all', }); this.$http.get('UserConfigs/getUserConfig') - .then(res => { - this.companyFk = res.data.companyFk; - this.getInvoiceDate(this.companyFk); - }); - } + .then(res => { + this.companyFk = res.data.companyFk; + this.getInvoiceDate(this.companyFk); + }); + } - getInvoiceDate(companyFk) { - const params = { companyFk: companyFk }; + getInvoiceDate(companyFk) { + const params = {companyFk: companyFk}; this.fetchInvoiceDate(params); - } + } - fetchInvoiceDate(params) { - this.$http.get('InvoiceOuts/getInvoiceDate', { params }) - .then(res => { - this.minInvoicingDate = res.data.issued ? new Date(res.data.issued) : null; - this.invoiceDate = this.minInvoicingDate; - }); - } + fetchInvoiceDate(params) { + this.$http.get('InvoiceOuts/getInvoiceDate', {params}) + .then(res => { + this.minInvoicingDate = res.data.issued ? new Date(res.data.issued) : null; + this.invoiceDate = this.minInvoicingDate; + }); + } stopInvoicing() { this.status = 'stopping'; @@ -111,11 +111,34 @@ class Controller extends Section { if (res.status >= 400 && res.status < 500) { const error = res.data?.error; let isWarning; - switch(error?.code) { - case 'pdfError': - case 'mailNotSent': - isWarning = true; - break; + const filter = { + where: { + id: address.clientId + } + }; + switch (error?.code) { + case 'pdfError': + isWarning = true; + break; + case 'mailNotSent': + this.$http.get(`Clients/findOne`, {filter}) + .then(res => { + const salesPersonFk = res.data.salesPersonFk; + if (!salesPersonFk) return; + + const message = this.$t('Mail not sent', { + clientId: address.clientId, + clientUrl: `${window.location.origin}/#!/client/${this.clientId}/summary` + }); + + const params = { + workerId: salesPersonFk, + message: message, + }; + this.$http.post('Chats/sendCheckingPresence', params); + }); + isWarning = true; + break; } const message = error?.message || res.message; @@ -126,7 +149,7 @@ class Controller extends Section { this.status = 'done'; throw new UserError(`Critical invoicing error, proccess stopped`); } - }) + }); } invoiceNext() { diff --git a/modules/invoiceOut/front/global-invoicing/locale/en.yml b/modules/invoiceOut/front/global-invoicing/locale/en.yml new file mode 100644 index 000000000..171822ef7 --- /dev/null +++ b/modules/invoiceOut/front/global-invoicing/locale/en.yml @@ -0,0 +1 @@ +Mail not sent: There has been an error sending the invoice to the client {{clientId}} {{clientUrl}}, please check the email address diff --git a/modules/invoiceOut/front/global-invoicing/locale/es.yml b/modules/invoiceOut/front/global-invoicing/locale/es.yml index 5b1f7e883..4c31df729 100644 --- a/modules/invoiceOut/front/global-invoicing/locale/es.yml +++ b/modules/invoiceOut/front/global-invoicing/locale/es.yml @@ -18,4 +18,5 @@ Invoice out: Facturar One client: Un solo cliente Choose a valid client: Selecciona un cliente válido Stop: Parar -Critical invoicing error, proccess stopped: Error crítico al facturar, proceso detenido \ No newline at end of file +Critical invoicing error, proccess stopped: Error crítico al facturar, proceso detenido +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 From 591fc14ffaf192fea7683b63beccc64994513391 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 22 Jun 2023 12:48:50 +0200 Subject: [PATCH 147/170] refs #5772 refactor: movido codigo para enviar rocket al back --- loopback/locale/en.json | 3 +- loopback/locale/es.json | 6 ++-- .../back/methods/invoiceOut/invoiceClient.js | 34 ++++++++++++++----- .../back/methods/invoiceOut/invoiceEmail.js | 2 +- modules/invoiceOut/back/models/invoice-out.js | 17 ++-------- .../front/global-invoicing/index.js | 18 ---------- .../front/global-invoicing/locale/en.yml | 1 - .../front/global-invoicing/locale/es.yml | 1 - 8 files changed, 35 insertions(+), 47 deletions(-) delete mode 100644 modules/invoiceOut/front/global-invoicing/locale/en.yml diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 7a973460d..40df9a712 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -175,5 +175,6 @@ "Pass expired": "The password has expired, change it from Salix", "Can't transfer claimed sales": "Can't transfer claimed sales", "Invalid quantity": "Invalid quantity", - "Failed to upload delivery note": "Error to upload delivery note {{id}}" + "Failed to upload delivery note": "Error to upload delivery note {{id}}", + "Mail not sent": "There has been an error sending the invoice to the client [{{clientId}}]({{{clientUrl}}}), please check the email address" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 5870dcb4f..ce93b27ce 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -296,5 +296,7 @@ "Ticket is already signed": "Este ticket ya ha sido firmado", "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" -} \ No newline at end of file + "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" + +} diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js index 5d61bfcd0..d010ef631 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js +++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js @@ -51,6 +51,9 @@ module.exports = Self => { const args = ctx.args; const models = Self.app.models; const myOptions = {userId: ctx.req.accessToken.userId}; + const $t = ctx.req.__; // $translate + const origin = ctx.req.headers.origin; + let tx; if (typeof options == 'object') @@ -119,7 +122,7 @@ module.exports = Self => { include: { relation: 'client', scope: { - fields: ['email', 'isToBeMailed'] + fields: ['email', 'isToBeMailed', 'salesPersonFk'] } } }, myOptions); @@ -131,21 +134,34 @@ module.exports = Self => { if (tx) await tx.rollback(); throw e; } - + try { - await Self.makePdf(invoiceId, myOptions); + await Self.makePdf(invoiceId); } catch (err) { console.error(err); throw new UserError('Error while generating PDF', 'pdfError'); } if (invoiceOut.client().isToBeMailed) { - ctx.args = { - reference: invoiceOut.ref, - recipientId: args.clientId, - recipient: invoiceOut.client().email - }; - await models.InvoiceOut.invoiceEmail(ctx, invoiceOut.ref); + try { + ctx.args = { + reference: invoiceOut.ref, + recipientId: args.clientId, + recipient: invoiceOut.client().email + }; + await models.InvoiceOut.invoiceEmail(ctx, invoiceOut.ref); + } catch (err) { + const message = $t('Mail not sent', { + clientId: args.clientId, + clientUrl: `${origin}/#!/claim/${args.id}/summary` + }); + const salesPersonId = invoiceOut.client().salesPersonFk; + + if (salesPersonId) + await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); + + throw new UserError('Error when sending mail to client', 'mailNotSent'); + } } else { const query = ` CALL vn.report_print( diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js index 45894e9c5..113526484 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js +++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js @@ -77,7 +77,7 @@ module.exports = Self => { try { return email.send(mailOptions); - } catch(err) { + } catch (err) { throw new UserError('Error when sending mail to client', 'mailNotSent'); } }; diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js index 027ec2fb2..0d5ed021c 100644 --- a/modules/invoiceOut/back/models/invoice-out.js +++ b/modules/invoiceOut/back/models/invoice-out.js @@ -23,19 +23,8 @@ module.exports = Self => { require('../methods/invoiceOut/negativeBasesCsv')(Self); Self.makePdf = async function(id, options) { - let tx; - const myOptions = {}; - - if (typeof options == 'object') - Object.assign(myOptions, options); - - if (!myOptions.transaction) { - tx = await Self.beginTransaction({}); - myOptions.transaction = tx; - } - const fields = ['id', 'hasPdf', 'ref', 'issued']; - const invoiceOut = await Self.findById(id, {fields}, myOptions); + const invoiceOut = await Self.findById(id, {fields}, options); const invoiceReport = new print.Report('invoice', { reference: invoiceOut.ref }); @@ -52,7 +41,7 @@ module.exports = Self => { await invoiceOut.updateAttributes({ hasPdf: true - }, myOptions); + }, options); if (process.env.NODE_ENV !== 'test') { await print.storage.write(buffer, { @@ -61,5 +50,5 @@ module.exports = Self => { fileName: fileName }); } - } + }; }; diff --git a/modules/invoiceOut/front/global-invoicing/index.js b/modules/invoiceOut/front/global-invoicing/index.js index 36552d25b..930dfd459 100644 --- a/modules/invoiceOut/front/global-invoicing/index.js +++ b/modules/invoiceOut/front/global-invoicing/index.js @@ -118,25 +118,7 @@ class Controller extends Section { }; switch (error?.code) { case 'pdfError': - isWarning = true; - break; case 'mailNotSent': - this.$http.get(`Clients/findOne`, {filter}) - .then(res => { - const salesPersonFk = res.data.salesPersonFk; - if (!salesPersonFk) return; - - const message = this.$t('Mail not sent', { - clientId: address.clientId, - clientUrl: `${window.location.origin}/#!/client/${this.clientId}/summary` - }); - - const params = { - workerId: salesPersonFk, - message: message, - }; - this.$http.post('Chats/sendCheckingPresence', params); - }); isWarning = true; break; } diff --git a/modules/invoiceOut/front/global-invoicing/locale/en.yml b/modules/invoiceOut/front/global-invoicing/locale/en.yml deleted file mode 100644 index 171822ef7..000000000 --- a/modules/invoiceOut/front/global-invoicing/locale/en.yml +++ /dev/null @@ -1 +0,0 @@ -Mail not sent: There has been an error sending the invoice to the client {{clientId}} {{clientUrl}}, please check the email address diff --git a/modules/invoiceOut/front/global-invoicing/locale/es.yml b/modules/invoiceOut/front/global-invoicing/locale/es.yml index 4c31df729..ed61e832a 100644 --- a/modules/invoiceOut/front/global-invoicing/locale/es.yml +++ b/modules/invoiceOut/front/global-invoicing/locale/es.yml @@ -19,4 +19,3 @@ One client: Un solo cliente Choose a valid client: Selecciona un cliente válido Stop: Parar Critical invoicing error, proccess stopped: Error crítico al facturar, proceso detenido -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 From b7cd32f4ce2bb0a558e4ca17e887f4400f2f2b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 22 Jun 2023 13:18:16 +0200 Subject: [PATCH 148/170] refs #5772 eliminar tags en report invoice --- print/templates/reports/invoice/invoice.html | 9 --------- 1 file changed, 9 deletions(-) diff --git a/print/templates/reports/invoice/invoice.html b/print/templates/reports/invoice/invoice.html index 32138befc..45b6c3934 100644 --- a/print/templates/reports/invoice/invoice.html +++ b/print/templates/reports/invoice/invoice.html @@ -106,15 +106,6 @@ {{sale.vatType}} {{saleImport(sale) | currency('EUR', $i18n.locale)}} - From 389b53ceff499dc3d186df5886b9495b5e893356 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 22 Jun 2023 13:37:43 +0200 Subject: [PATCH 149/170] refs #5772 fix: back test --- .../back/methods/invoiceOut/specs/invoiceClient.spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/invoiceClient.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/invoiceClient.spec.js index e26a0b3f1..0faa8fe1a 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/invoiceClient.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/invoiceClient.spec.js @@ -18,7 +18,9 @@ describe('InvoiceOut invoiceClient()', () => { accessToken: {userId: userId}, __: value => { return value; - } + }, + headers: {origin: 'http://localhost'} + }; const ctx = {req: activeCtx}; From 344ba298f8390ebd7369dc62c989481572ff1063 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 22 Jun 2023 14:27:33 +0200 Subject: [PATCH 150/170] refs #5832 232801 init --- CHANGELOG.md | 9 +++++++++ db/changes/232801/.gitkeep | 0 package.json | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 db/changes/232801/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index fa2ebcd62..cbfc6e9e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ 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). +## [2328.01] - 2023-07-13 + +### Added + +### Changed + +### Fixed + + ## [2326.01] - 2023-06-29 ### Added diff --git a/db/changes/232801/.gitkeep b/db/changes/232801/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/package.json b/package.json index 4358c86a7..64c374841 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.26.01", + "version": "23.28.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From 47a4a9950f30fd3c87cdff002ac12a85f5695c48 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 23 Jun 2023 11:42:30 +0200 Subject: [PATCH 151/170] refs #5772 Parallelism added to PDF generation --- .eslintrc.yml | 2 +- db/changes/232601/01-invoiceOutPdf.sql | 13 ++ db/dump/fixtures.sql | 3 + .../back/methods/invoiceOut/invoiceClient.js | 133 +++++------------- .../methods/invoiceOut/makePdfAndNotify.js | 87 ++++++++++++ modules/invoiceOut/back/model-config.json | 3 + .../back/models/invoice-out config.json | 22 +++ modules/invoiceOut/back/models/invoice-out.js | 1 + .../front/global-invoicing/index.html | 16 ++- .../front/global-invoicing/index.js | 86 ++++++----- .../front/global-invoicing/locale/es.yml | 1 + .../front/global-invoicing/style.scss | 14 +- 12 files changed, 231 insertions(+), 150 deletions(-) create mode 100644 db/changes/232601/01-invoiceOutPdf.sql create mode 100644 modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js create mode 100644 modules/invoiceOut/back/models/invoice-out config.json diff --git a/.eslintrc.yml b/.eslintrc.yml index ee20324ff..edbc47195 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -17,7 +17,7 @@ rules: camelcase: 0 default-case: 0 no-eq-null: 0 - no-console: ["error"] + no-console: ["warn"] no-warning-comments: 0 no-empty: [error, allowEmptyCatch: true] complexity: 0 diff --git a/db/changes/232601/01-invoiceOutPdf.sql b/db/changes/232601/01-invoiceOutPdf.sql new file mode 100644 index 000000000..38e0b8bbb --- /dev/null +++ b/db/changes/232601/01-invoiceOutPdf.sql @@ -0,0 +1,13 @@ +INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId) + VALUES + ('InvoiceOut','makePdfAndNotify','WRITE','ALLOW','ROLE','invoicing'), + ('InvoiceOutConfig','*','READ','ALLOW','ROLE','invoicing'); + +CREATE OR REPLACE TABLE vn.invoiceOutConfig ( + id INT UNSIGNED auto_increment NOT NULL, + parallelism int UNSIGNED DEFAULT 1 NOT NULL, + PRIMARY KEY (id) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8mb3 +COLLATE=utf8mb3_unicode_ci; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 9c930222f..c4338a555 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -603,6 +603,9 @@ UPDATE `vn`.`invoiceOut` SET ref = 'T3333333' WHERE id = 3; UPDATE `vn`.`invoiceOut` SET ref = 'T4444444' WHERE id = 4; UPDATE `vn`.`invoiceOut` SET ref = 'A1111111' WHERE id = 5; +INSERT INTO vn.invoiceOutConfig + SET parallelism = 8; + INSERT INTO `vn`.`invoiceOutTax` (`invoiceOutFk`, `taxableBase`, `vat`, `pgcFk`) VALUES (1, 895.76, 89.58, 4722000010), diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js index d010ef631..ab076b46f 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js +++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js @@ -30,15 +30,10 @@ module.exports = Self => { type: 'number', description: 'The company id to invoice', required: true - }, { - arg: 'printerFk', - type: 'number', - description: 'The printer to print', - required: true } ], returns: { - type: 'object', + type: 'number', root: true }, http: { @@ -50,29 +45,23 @@ module.exports = Self => { Self.invoiceClient = async(ctx, options) => { const args = ctx.args; const models = Self.app.models; - const myOptions = {userId: ctx.req.accessToken.userId}; - const $t = ctx.req.__; // $translate - const origin = ctx.req.headers.origin; + + options = typeof options == 'object' + ? Object.assign({}, options) : {}; + options.userId = ctx.req.accessToken.userId; let tx; - - if (typeof options == 'object') - Object.assign(myOptions, options); - - if (!myOptions.transaction) { - tx = await Self.beginTransaction({}); - myOptions.transaction = tx; - } + if (!options.transaction) + tx = options.transaction = await Self.beginTransaction({}); const minShipped = Date.vnNew(); minShipped.setFullYear(args.maxShipped.getFullYear() - 1); let invoiceId; - let invoiceOut; try { const client = await models.Client.findById(args.clientId, { fields: ['id', 'hasToInvoiceByAddress'] - }, myOptions); + }, options); if (client.hasToInvoiceByAddress) { await Self.rawSql('CALL ticketToInvoiceByAddress(?, ?, ?, ?)', [ @@ -80,53 +69,57 @@ module.exports = Self => { args.maxShipped, args.addressId, args.companyFk - ], myOptions); + ], options); } else { await Self.rawSql('CALL invoiceFromClient(?, ?, ?)', [ args.maxShipped, client.id, args.companyFk - ], myOptions); + ], options); } - // Make invoice - const isSpanishCompany = await getIsSpanishCompany(args.companyFk, myOptions); + // Check negative bases - // Validates ticket nagative base - const hasAnyNegativeBase = await getNegativeBase(myOptions); + let query = + `SELECT COUNT(*) isSpanishCompany + FROM supplier s + JOIN country c ON c.id = s.countryFk + AND c.code = 'ES' + WHERE s.id = ?`; + const [supplierCompany] = await Self.rawSql(query, [ + args.companyFk + ], options); + + const isSpanishCompany = supplierCompany?.isSpanishCompany; + + query = 'SELECT hasAnyNegativeBase() AS base'; + const [result] = await Self.rawSql(query, null, options); + + const hasAnyNegativeBase = result?.base; if (hasAnyNegativeBase && isSpanishCompany) throw new UserError('Negative basis'); + // Invoicing + query = `SELECT invoiceSerial(?, ?, ?) AS serial`; const [invoiceSerial] = await Self.rawSql(query, [ client.id, args.companyFk, 'G' - ], myOptions); + ], options); const serialLetter = invoiceSerial.serial; query = `CALL invoiceOut_new(?, ?, NULL, @invoiceId)`; await Self.rawSql(query, [ serialLetter, args.invoiceDate - ], myOptions); + ], options); - const [newInvoice] = await Self.rawSql(`SELECT @invoiceId id`, null, myOptions); + const [newInvoice] = await Self.rawSql(`SELECT @invoiceId id`, null, options); if (!newInvoice) throw new UserError('No tickets to invoice', 'notInvoiced'); - await Self.rawSql('CALL invoiceOutBooking(?)', [newInvoice.id], myOptions); - - invoiceOut = await models.InvoiceOut.findById(newInvoice.id, { - fields: ['id', 'ref', 'clientFk'], - include: { - relation: 'client', - scope: { - fields: ['email', 'isToBeMailed', 'salesPersonFk'] - } - } - }, myOptions); - + await Self.rawSql('CALL invoiceOutBooking(?)', [newInvoice.id], options); invoiceId = newInvoice.id; if (tx) await tx.commit(); @@ -135,66 +128,6 @@ module.exports = Self => { throw e; } - try { - await Self.makePdf(invoiceId); - } catch (err) { - console.error(err); - throw new UserError('Error while generating PDF', 'pdfError'); - } - - if (invoiceOut.client().isToBeMailed) { - try { - ctx.args = { - reference: invoiceOut.ref, - recipientId: args.clientId, - recipient: invoiceOut.client().email - }; - await models.InvoiceOut.invoiceEmail(ctx, invoiceOut.ref); - } catch (err) { - const message = $t('Mail not sent', { - clientId: args.clientId, - clientUrl: `${origin}/#!/claim/${args.id}/summary` - }); - const salesPersonId = invoiceOut.client().salesPersonFk; - - if (salesPersonId) - await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); - - throw new UserError('Error when sending mail to client', 'mailNotSent'); - } - } else { - const query = ` - CALL vn.report_print( - 'invoice', - ?, - account.myUser_getId(), - JSON_OBJECT('refFk', ?), - 'normal' - );`; - await models.InvoiceOut.rawSql(query, [args.printerFk, invoiceOut.ref]); - } - return invoiceId; }; - - async function getNegativeBase(options) { - const models = Self.app.models; - const query = 'SELECT hasAnyNegativeBase() AS base'; - const [result] = await models.InvoiceOut.rawSql(query, null, options); - return result && result.base; - } - - async function getIsSpanishCompany(companyId, options) { - const models = Self.app.models; - const query = `SELECT COUNT(*) isSpanishCompany - FROM supplier s - JOIN country c ON c.id = s.countryFk - AND c.code = 'ES' - WHERE s.id = ?`; - const [supplierCompany] = await models.InvoiceOut.rawSql(query, [ - companyId - ], options); - - return supplierCompany && supplierCompany.isSpanishCompany; - } }; diff --git a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js new file mode 100644 index 000000000..a999437c0 --- /dev/null +++ b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js @@ -0,0 +1,87 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('makePdfAndNotify', { + description: 'Create invoice PDF and send it to client', + accessType: 'WRITE', + accepts: [ + { + arg: 'id', + type: 'number', + description: 'The invoice id', + required: true, + http: {source: 'path'} + }, { + arg: 'printerFk', + type: 'number', + description: 'The printer to print', + required: true + } + ], + http: { + path: '/:id/makePdfAndNotify', + verb: 'POST' + } + }); + + Self.makePdfAndNotify = async function(ctx, id, printerFk) { + const models = Self.app.models; + + options = typeof options == 'object' + ? Object.assign({}, options) : {}; + options.userId = ctx.req.accessToken.userId; + + try { + await Self.makePdf(id, options); + } catch (err) { + console.error(err); + throw new UserError('Error while generating PDF', 'pdfError'); + } + + const invoiceOut = await Self.findById(id, { + fields: ['ref', 'clientFk'], + include: { + relation: 'client', + scope: { + fields: ['id', 'email', 'isToBeMailed', 'salesPersonFk'] + } + } + }, options); + + const ref = invoiceOut.ref; + const client = invoiceOut.client(); + + if (client.isToBeMailed) { + try { + ctx.args = { + reference: ref, + recipientId: client.id, + recipient: client.email + }; + await Self.invoiceEmail(ctx, ref); + } catch (err) { + const origin = ctx.req.headers.origin; + const message = ctx.req.__('Mail not sent', { + clientId: client.id, + clientUrl: `${origin}/#!/claim/${id}/summary` + }); + const salesPersonId = client.salesPersonFk; + + if (salesPersonId) + await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); + + throw new UserError('Error when sending mail to client', 'mailNotSent'); + } + } else { + const query = ` + CALL vn.report_print( + 'invoice', + ?, + account.myUser_getId(), + JSON_OBJECT('refFk', ?), + 'normal' + );`; + await Self.rawSql(query, [printerFk, ref], options); + } + }; +}; diff --git a/modules/invoiceOut/back/model-config.json b/modules/invoiceOut/back/model-config.json index b190126ea..9e8b119ab 100644 --- a/modules/invoiceOut/back/model-config.json +++ b/modules/invoiceOut/back/model-config.json @@ -2,6 +2,9 @@ "InvoiceOut": { "dataSource": "vn" }, + "InvoiceOutConfig": { + "dataSource": "vn" + }, "InvoiceOutSerial": { "dataSource": "vn" }, diff --git a/modules/invoiceOut/back/models/invoice-out config.json b/modules/invoiceOut/back/models/invoice-out config.json new file mode 100644 index 000000000..d5595f687 --- /dev/null +++ b/modules/invoiceOut/back/models/invoice-out config.json @@ -0,0 +1,22 @@ +{ + "name": "InvoiceOutConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "invoiceOutConfig" + } + }, + "properties": { + "id": { + "id": true, + "type": "number", + "description": "Identifier" + }, + "parallelism": { + "type": "number", + "required": true + } + } +} + + diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js index 0d5ed021c..9baa1e7e6 100644 --- a/modules/invoiceOut/back/models/invoice-out.js +++ b/modules/invoiceOut/back/models/invoice-out.js @@ -12,6 +12,7 @@ module.exports = Self => { require('../methods/invoiceOut/createManualInvoice')(Self); require('../methods/invoiceOut/clientsToInvoice')(Self); require('../methods/invoiceOut/invoiceClient')(Self); + require('../methods/invoiceOut/makePdfAndNotify')(Self); require('../methods/invoiceOut/refund')(Self); require('../methods/invoiceOut/invoiceEmail')(Self); require('../methods/invoiceOut/exportationPdf')(Self); diff --git a/modules/invoiceOut/front/global-invoicing/index.html b/modules/invoiceOut/front/global-invoicing/index.html index 52bf8b619..3ece30862 100644 --- a/modules/invoiceOut/front/global-invoicing/index.html +++ b/modules/invoiceOut/front/global-invoicing/index.html @@ -1,7 +1,6 @@ + class="status vn-w-lg vn-pa-md"> @@ -20,8 +19,15 @@ Ended process
-
- {{$ctrl.percentage | percentage: 0}} ({{$ctrl.addressNumber}} {{'of' | translate}} {{$ctrl.nAddresses}}) +
+
+ {{$ctrl.percentage | percentage: 0}} + ({{$ctrl.addressNumber}} of {{$ctrl.nAddresses}}) +
+
+ {{$ctrl.nPdfs}} of {{$ctrl.totalPdfs}} + PDFs +
@@ -141,7 +147,7 @@ + ng-click="$ctrl.status = 'stopping'"> diff --git a/modules/invoiceOut/front/global-invoicing/index.js b/modules/invoiceOut/front/global-invoicing/index.js index 930dfd459..283e84a6c 100644 --- a/modules/invoiceOut/front/global-invoicing/index.js +++ b/modules/invoiceOut/front/global-invoicing/index.js @@ -9,30 +9,21 @@ class Controller extends Section { Object.assign(this, { maxShipped: new Date(date.getFullYear(), date.getMonth(), 0), clientsToInvoice: 'all', + companyFk: this.vnConfig.companyFk }); - this.$http.get('UserConfigs/getUserConfig') - .then(res => { - this.companyFk = res.data.companyFk; - this.getInvoiceDate(this.companyFk); - }); - } - - getInvoiceDate(companyFk) { - const params = {companyFk: companyFk}; - this.fetchInvoiceDate(params); - } - - fetchInvoiceDate(params) { + const params = {companyFk: this.companyFk}; this.$http.get('InvoiceOuts/getInvoiceDate', {params}) .then(res => { this.minInvoicingDate = res.data.issued ? new Date(res.data.issued) : null; this.invoiceDate = this.minInvoicingDate; }); - } - stopInvoicing() { - this.status = 'stopping'; + const filter = {fields: ['parallelism']}; + this.$http.get('InvoiceOutConfigs/findOne', {filter}) + .then(res => { + this.parallelism = res.data.parallelism || 1; + }); } makeInvoice() { @@ -70,8 +61,11 @@ class Controller extends Section { if (!this.addresses.length) throw new UserError(`There aren't tickets to invoice`); + this.nRequests = 0; + this.nPdfs = 0; + this.totalPdfs = 0; this.addressIndex = 0; - return this.invoiceOut(); + this.invoiceClient(); }) .catch(err => this.handleError(err)); } catch (err) { @@ -85,8 +79,11 @@ class Controller extends Section { throw err; } - invoiceOut() { - if (this.addressIndex == this.addresses.length || this.status == 'stopping') { + invoiceClient() { + if (this.nRequests == this.parallelism || this.isInvoicing) return; + + if (this.addressIndex >= this.addresses.length || this.status == 'stopping') { + if (this.nRequests) return; this.invoicing = false; this.status = 'done'; return; @@ -95,36 +92,27 @@ class Controller extends Section { this.status = 'invoicing'; const address = this.addresses[this.addressIndex]; this.currentAddress = address; + this.isInvoicing = true; const params = { clientId: address.clientId, addressId: address.id, invoiceDate: this.invoiceDate, maxShipped: this.maxShipped, - companyFk: this.companyFk, - printerFk: this.printerFk, + companyFk: this.companyFk }; this.$http.post(`InvoiceOuts/invoiceClient`, params) - .then(() => this.invoiceNext()) + .then(res => { + this.isInvoicing = false; + if (res.data) + this.makePdfAndNotify(res.data, address); + this.invoiceNext(); + }) .catch(res => { + this.isInvoicing = false; if (res.status >= 400 && res.status < 500) { - const error = res.data?.error; - let isWarning; - const filter = { - where: { - id: address.clientId - } - }; - switch (error?.code) { - case 'pdfError': - case 'mailNotSent': - isWarning = true; - break; - } - - const message = error?.message || res.message; - this.errors.unshift({address, message, isWarning}); + this.invoiceError(address, res); this.invoiceNext(); } else { this.invoicing = false; @@ -136,7 +124,27 @@ class Controller extends Section { invoiceNext() { this.addressIndex++; - this.invoiceOut(); + this.invoiceClient(); + } + + makePdfAndNotify(invoiceId, address) { + this.nRequests++; + this.totalPdfs++; + const params = {printerFk: this.printerFk}; + this.$http.post(`InvoiceOuts/${invoiceId}/makePdfAndNotify`, params) + .catch(res => { + this.invoiceError(address, res, true); + }) + .finally(() => { + this.nPdfs++; + this.nRequests--; + this.invoiceClient(); + }); + } + + invoiceError(address, res, isWarning) { + const message = res.data?.error?.message || res.message; + this.errors.unshift({address, message, isWarning}); } get nAddresses() { diff --git a/modules/invoiceOut/front/global-invoicing/locale/es.yml b/modules/invoiceOut/front/global-invoicing/locale/es.yml index ed61e832a..f1a411ba1 100644 --- a/modules/invoiceOut/front/global-invoicing/locale/es.yml +++ b/modules/invoiceOut/front/global-invoicing/locale/es.yml @@ -10,6 +10,7 @@ Build packaging tickets: Generando tickets de embalajes Address id: Id dirección Printer: Impresora of: de +PDFs: PDFs Client: Cliente Current client id: Id cliente actual Invoicing client: Facturando cliente diff --git a/modules/invoiceOut/front/global-invoicing/style.scss b/modules/invoiceOut/front/global-invoicing/style.scss index 6fdfac0ba..3ad767aba 100644 --- a/modules/invoiceOut/front/global-invoicing/style.scss +++ b/modules/invoiceOut/front/global-invoicing/style.scss @@ -1,17 +1,21 @@ @import "variables"; -vn-invoice-out-global-invoicing{ - - h5{ +vn-invoice-out-global-invoicing { + h5 { color: $color-primary; } - + .status { + height: 80px; + display: flex; + align-items: center; + justify-content: center; + gap: 20px; + } #error { line-break: normal; overflow-wrap: break-word; white-space: normal; } - } From 8c0e8e9e1223acc2ee55401fb2b986b4e07bbfe4 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 23 Jun 2023 11:50:40 +0200 Subject: [PATCH 152/170] refs #5772 Fixes fetching parallelism from front --- modules/invoiceOut/front/global-invoicing/index.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/invoiceOut/front/global-invoicing/index.js b/modules/invoiceOut/front/global-invoicing/index.js index 283e84a6c..9a936611a 100644 --- a/modules/invoiceOut/front/global-invoicing/index.js +++ b/modules/invoiceOut/front/global-invoicing/index.js @@ -9,7 +9,8 @@ class Controller extends Section { Object.assign(this, { maxShipped: new Date(date.getFullYear(), date.getMonth(), 0), clientsToInvoice: 'all', - companyFk: this.vnConfig.companyFk + companyFk: this.vnConfig.companyFk, + parallelism: 1 }); const params = {companyFk: this.companyFk}; @@ -22,7 +23,12 @@ class Controller extends Section { const filter = {fields: ['parallelism']}; this.$http.get('InvoiceOutConfigs/findOne', {filter}) .then(res => { - this.parallelism = res.data.parallelism || 1; + if (res.data.parallelism) + this.parallelism = res.data.parallelism; + }) + .catch(res => { + if (res.status == 404) return; + throw res; }); } From c9f11830a202dc5d15423fa43cd79dc3bad971a1 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 23 Jun 2023 20:03:56 +0200 Subject: [PATCH 153/170] refs #5772 smtp.send() error throw flow fix --- print/core/smtp.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/print/core/smtp.js b/print/core/smtp.js index 04bede5b5..7ff9ca41d 100644 --- a/print/core/smtp.js +++ b/print/core/smtp.js @@ -20,14 +20,18 @@ module.exports = { options.to = config.app.senderEmail; } + let res; let error; - return this.transporter.sendMail(options).catch(err => { + try { + res = await this.transporter.sendMail(options); + } catch (err) { error = err; - throw err; - }).finally(async() => { + } finally { await this.mailLog(options, error); - }); + } + + return res; }, async mailLog(options, error) { From 665339c8d25252c9fc0eced9b0fd8dea1e8de239 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 23 Jun 2023 22:02:33 +0200 Subject: [PATCH 154/170] refs #5772 Fix for unhandled ENOENT error --- .../back/methods/invoiceOut/download.js | 68 +++++++++---------- print/core/email.js | 4 +- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index 49bba046b..ce80ecffd 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -42,42 +42,42 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); + const invoiceOut = await models.InvoiceOut.findById(id, { + fields: ['ref', 'issued'] + }, myOptions); + + const issued = invoiceOut.issued; + const year = issued.getFullYear().toString(); + const month = (issued.getMonth() + 1).toString(); + const day = issued.getDate().toString(); + + const container = await models.InvoiceContainer.container(year); + const rootPath = container.client.root; + const src = path.join(rootPath, year, month, day); + const fileName = `${year}${invoiceOut.ref}.pdf`; + const fileSrc = path.join(src, fileName); + + const file = { + path: fileSrc, + contentType: 'application/pdf', + name: fileName + }; + try { - const invoiceOut = await models.InvoiceOut.findById(id, { - fields: ['ref', 'issued'] - }, myOptions); - - const issued = invoiceOut.issued; - const year = issued.getFullYear().toString(); - const month = (issued.getMonth() + 1).toString(); - const day = issued.getDate().toString(); - - const container = await models.InvoiceContainer.container(year); - const rootPath = container.client.root; - const src = path.join(rootPath, year, month, day); - const fileName = `${year}${invoiceOut.ref}.pdf`; - const fileSrc = path.join(src, fileName); - - const file = { - path: fileSrc, - contentType: 'application/pdf', - name: fileName - }; - - try { - await fs.access(file.path); - } catch (error) { - await Self.createPdf(ctx, id, myOptions); - } - - const stream = fs.createReadStream(file.path); - - return [stream, file.contentType, `filename="${file.name}"`]; + await fs.access(file.path); } catch (error) { - if (error.code === 'ENOENT') - throw new UserError('The PDF document does not exist'); - - throw error; + await Self.createPdf(ctx, id, myOptions); } + + const stream = await fs.createReadStream(file.path); + // XXX: To prevent unhandled ENOENT error + // https://stackoverflow.com/questions/17136536/is-enoent-from-fs-createreadstream-uncatchable + stream.on('error', err => { + const e = new Error(err.message); + err.stack = e.stack; + console.error(err); + }); + + return [stream, file.contentType, `filename="${file.name}"`]; }; }; diff --git a/print/core/email.js b/print/core/email.js index 6e96f5c2e..43e92e619 100644 --- a/print/core/email.js +++ b/print/core/email.js @@ -63,12 +63,12 @@ class Email extends Component { await getAttachments(componentPath, component.attachments); if (component.components) - await getSubcomponentAttachments(component) + await getSubcomponentAttachments(component); } } } - await getSubcomponentAttachments(instance) + await getSubcomponentAttachments(instance); if (this.attachments) await getAttachments(this.path, this.attachments); From 7660d7685061241206e6c5324113fdbdc29b1959 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 23 Jun 2023 22:52:03 +0200 Subject: [PATCH 155/170] refs #5772 Test environment fix --- .../back/methods/invoiceOut/createPdf.js | 17 +++----- .../back/methods/invoiceOut/download.js | 39 ++++++++----------- .../back/methods/invoiceOut/invoiceClient.js | 1 - .../back/methods/invoiceOut/invoiceEmail.js | 16 +++----- modules/invoiceOut/back/models/invoice-out.js | 30 +++++++++----- 5 files changed, 49 insertions(+), 54 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index 8cc584c94..c4d50a4ee 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -24,20 +24,15 @@ module.exports = Self => { Self.createPdf = async function(ctx, id, options) { const models = Self.app.models; + options = typeof options == 'object' + ? Object.assign({}, options) : {}; let tx; - const myOptions = {}; - - if (typeof options == 'object') - Object.assign(myOptions, options); - - if (!myOptions.transaction) { - tx = await Self.beginTransaction({}); - myOptions.transaction = tx; - } + if (!options.transaction) + tx = options.transaction = await Self.beginTransaction({}); try { - const invoiceOut = await Self.findById(id, {fields: ['hasPdf']}, myOptions); + const invoiceOut = await Self.findById(id, {fields: ['hasPdf']}, options); if (invoiceOut.hasPdf) { const canCreatePdf = await models.ACL.checkAccessAcl(ctx, 'InvoiceOut', 'canCreatePdf', 'WRITE'); @@ -45,7 +40,7 @@ module.exports = Self => { throw new UserError(`You don't have enough privileges`); } - await Self.makePdf(id, myOptions); + await Self.makePdf(id, options); if (tx) await tx.commit(); } catch (err) { diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index ce80ecffd..4c76f7c07 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -1,6 +1,5 @@ const fs = require('fs-extra'); const path = require('path'); -const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('download', { @@ -37,39 +36,27 @@ module.exports = Self => { Self.download = async function(ctx, id, options) { const models = Self.app.models; - const myOptions = {}; + options = typeof options == 'object' + ? Object.assign({}, options) : {}; - if (typeof options == 'object') - Object.assign(myOptions, options); + const pdfFile = await Self.filePath(id, options); - const invoiceOut = await models.InvoiceOut.findById(id, { - fields: ['ref', 'issued'] - }, myOptions); - - const issued = invoiceOut.issued; - const year = issued.getFullYear().toString(); - const month = (issued.getMonth() + 1).toString(); - const day = issued.getDate().toString(); - - const container = await models.InvoiceContainer.container(year); + const container = await models.InvoiceContainer.container(pdfFile.year); const rootPath = container.client.root; - const src = path.join(rootPath, year, month, day); - const fileName = `${year}${invoiceOut.ref}.pdf`; - const fileSrc = path.join(src, fileName); const file = { - path: fileSrc, + path: path.join(rootPath, pdfFile.path, pdfFile.name), contentType: 'application/pdf', - name: fileName + name: pdfFile.name }; try { await fs.access(file.path); } catch (error) { - await Self.createPdf(ctx, id, myOptions); + await Self.createPdf(ctx, id, options); } - const stream = await fs.createReadStream(file.path); + let stream = await fs.createReadStream(file.path); // XXX: To prevent unhandled ENOENT error // https://stackoverflow.com/questions/17136536/is-enoent-from-fs-createreadstream-uncatchable stream.on('error', err => { @@ -78,6 +65,14 @@ module.exports = Self => { console.error(err); }); - return [stream, file.contentType, `filename="${file.name}"`]; + if (process.env.NODE_ENV == 'test') { + try { + await fs.access(file.path); + } catch (error) { + stream = null; + } + } + + return [stream, file.contentType, `filename="${pdfFile.name}"`]; }; }; diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js index ab076b46f..ddd008942 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js +++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js @@ -45,7 +45,6 @@ module.exports = Self => { Self.invoiceClient = async(ctx, options) => { const args = ctx.args; const models = Self.app.models; - options = typeof options == 'object' ? Object.assign({}, options) : {}; options.userId = ctx.req.accessToken.userId; diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js index 113526484..400328fef 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js +++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceEmail.js @@ -11,20 +11,17 @@ module.exports = Self => { type: 'string', required: true, http: {source: 'path'} - }, - { + }, { arg: 'recipient', type: 'string', description: 'The recipient email', required: true, - }, - { + }, { arg: 'replyTo', type: 'string', description: 'The sender email to reply to', required: false - }, - { + }, { arg: 'recipientId', type: 'number', description: 'The recipient id to send to the recipient preferred language', @@ -43,16 +40,13 @@ module.exports = Self => { Self.invoiceEmail = async(ctx, reference) => { const args = Object.assign({}, ctx.args); - const {InvoiceOut} = Self.app.models; const params = { recipient: args.recipient, lang: ctx.req.getLocale() }; - const invoiceOut = await InvoiceOut.findOne({ - where: { - ref: reference - } + const invoiceOut = await Self.findOne({ + where: {ref: reference} }); delete args.ctx; diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js index 9baa1e7e6..d3aaf3b3d 100644 --- a/modules/invoiceOut/back/models/invoice-out.js +++ b/modules/invoiceOut/back/models/invoice-out.js @@ -1,4 +1,5 @@ const print = require('vn-print'); +const path = require('path'); module.exports = Self => { require('../methods/invoiceOut/filter')(Self); @@ -23,20 +24,31 @@ module.exports = Self => { require('../methods/invoiceOut/negativeBases')(Self); require('../methods/invoiceOut/negativeBasesCsv')(Self); - Self.makePdf = async function(id, options) { - const fields = ['id', 'hasPdf', 'ref', 'issued']; + Self.filePath = async function(id, options) { + const fields = ['ref', 'issued']; const invoiceOut = await Self.findById(id, {fields}, options); - const invoiceReport = new print.Report('invoice', { - reference: invoiceOut.ref - }); - const buffer = await invoiceReport.toPdfStream(); const issued = invoiceOut.issued; const year = issued.getFullYear().toString(); const month = (issued.getMonth() + 1).toString(); const day = issued.getDate().toString(); - const fileName = `${year}${invoiceOut.ref}.pdf`; + return { + path: path.join(year, month, day), + name: `${year}${invoiceOut.ref}.pdf`, + year + }; + }; + + Self.makePdf = async function(id, options) { + const fields = ['id', 'hasPdf', 'ref']; + const invoiceOut = await Self.findById(id, {fields}, options); + const invoiceReport = new print.Report('invoice', { + reference: invoiceOut.ref + }); + const buffer = await invoiceReport.toPdfStream(); + + const pdfFile = await Self.filePath(id, options); // Store invoice @@ -47,8 +59,8 @@ module.exports = Self => { if (process.env.NODE_ENV !== 'test') { await print.storage.write(buffer, { type: 'invoice', - path: `${year}/${month}/${day}`, - fileName: fileName + path: pdfFile.path, + fileName: pdfFile.name }); } }; From f70df714df81b75d675f37a4751c5670b101114e Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 25 Jun 2023 16:31:24 +0200 Subject: [PATCH 156/170] refs #5772, #5900 InvoiceOut back test removed, logs improved --- e2e/helpers/selectors.js | 12 - front/salix/components/log/index.html | 199 +++++++----- front/salix/components/log/index.js | 242 ++++++++++---- front/salix/components/log/locale/es.yml | 1 + front/salix/components/log/style.scss | 296 +++++++++++------- loopback/common/methods/log/pitInstance.js | 56 ++++ loopback/common/models/log.js | 1 + .../methods/invoiceOut/specs/download.spec.js | 28 -- 8 files changed, 545 insertions(+), 290 deletions(-) create mode 100644 loopback/common/methods/log/pitInstance.js delete mode 100644 modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index b8eaa99a1..d92cb129b 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -479,9 +479,6 @@ export default { fourthBalance: 'vn-item-diary vn-tbody > vn-tr:nth-child(4) > vn-td.balance > span', firstBalance: 'vn-item-diary vn-tbody > vn-tr:nth-child(1) > vn-td.balance' }, - itemLog: { - anyLineCreated: 'vn-item-log > vn-log vn-tbody > vn-tr', - }, ticketSummary: { header: 'vn-ticket-summary > vn-card > h5', state: 'vn-ticket-summary vn-label-value[label="State"] > section > span', @@ -667,15 +664,6 @@ export default { thirdRemoveRequestButton: 'vn-ticket-request-index vn-tr:nth-child(3) vn-icon[icon="delete"]', thirdRequestQuantity: 'vn-ticket-request-index vn-table vn-tr:nth-child(3) > vn-td:nth-child(6) vn-input-number', saveButton: 'vn-ticket-request-create button[type=submit]', - - }, - ticketLog: { - firstTD: 'vn-ticket-log vn-table vn-td:nth-child(1)', - logButton: 'vn-left-menu a[ui-sref="ticket.card.log"]', - user: 'vn-ticket-log vn-tbody vn-tr vn-td:nth-child(2)', - action: 'vn-ticket-log vn-tbody vn-tr vn-td:nth-child(4)', - changes: 'vn-ticket-log vn-data-viewer vn-tbody vn-tr table tr:nth-child(2) td.after', - id: 'vn-ticket-log vn-tr:nth-child(1) table tr:nth-child(1) td.before' }, ticketService: { addServiceButton: 'vn-ticket-service vn-icon-button[vn-tooltip="Add service"] > button', diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index 8b33c811b..ac4e5cb6e 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -2,8 +2,6 @@ vn-id="model" url="{{$ctrl.url}}" filter="$ctrl.filter" - link="{originFk: $ctrl.originId}" - where="{changedModel: $ctrl.changedModel, changedModelId: $ctrl.changedModelId}" data="$ctrl.logs" order="creationDate DESC, id DESC" limit="20"> @@ -17,90 +15,107 @@ -
-
- - - - -
+
+
+
+ {{$ctrl.modelI18n}} #{{::originLog.originFk}} +
- -
-
- - {{::log.changedModelI18n}} - -
-
- {{::$ctrl.relativeDate(log.creationDate)}} - - -
+
+
+ + + + +
+
-
- #{{::log.changedModelId}} - - - {{::log.changedModelValue}} -
-
- - - - - - {{::prop.nameI18n}}: +
+
+
+ + + + {{::modelLog.modelI18n}} - , - -
-
- - {{::prop.nameI18n}}: - - - - ← - -
+ #{{::modelLog.id}} + {{::modelLog.showValue}}
- - - {{::log.description}} - - + +
+
+ {{::$ctrl.relativeDate(log.creationDate)}} +
+
+ + + + +
+
+
+ + + + + + {{::prop.nameI18n}}: + + , + +
+
+ + {{::prop.nameI18n}}: + + + + ← + +
+
+
+ + {{::log.description}} + + +
+
+
- + + + + + +
+
+ {{$ctrl.instance.modelLog.modelI18n}} #{{$ctrl.instance.modelLog.id}} +
+
+
+ + {{::prop.nameI18n}}: + + +
+
+ No data +
+
+
+
+
diff --git a/front/salix/components/log/index.js b/front/salix/components/log/index.js index 8aea255a2..ecbeaefe7 100644 --- a/front/salix/components/log/index.js +++ b/front/salix/components/log/index.js @@ -3,7 +3,10 @@ import Section from '../section'; import {hashToColor} from 'core/lib/string'; import './style.scss'; -const validDate = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/; +const validDate = new RegExp( + /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])/.source + + /T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/.source +); export default class Controller extends Section { constructor($element, $) { @@ -28,6 +31,20 @@ export default class Controller extends Section { select: 'visibility' }; this.filter = { + fields: [ + 'id', + 'originFk', + 'userFk', + 'action', + 'changedModel', + 'oldInstance', + 'newInstance', + 'creationDate', + 'changedModel', + 'changedModelId', + 'changedModelValue', + 'description' + ], include: [{ relation: 'user', scope: { @@ -48,6 +65,12 @@ export default class Controller extends Section { this.today.setHours(0, 0, 0, 0); } + $onInit() { + const match = this.url?.match(/(.*)Logs$/); + this.model = match && match[1]; + this.modelI18n = this.translateModel(this.model); + } + $postLink() { this.resetFilter(); this.$.$watch( @@ -63,47 +86,80 @@ export default class Controller extends Section { set logs(value) { this._logs = value; + this.logTree = []; if (!value) return; const empty = {}; const validations = window.validations; - const castJsonValue = this.castJsonValue; - for (const log of value) { + let originLog; + let userLog; + let modelLog; + let nLogs; + + for (let i = 0; i < value.length; i++) { + const log = value[i]; + const prevLog = i > 0 ? value[i - 1] : null; + const locale = validations[log.changedModel]?.locale || empty; + + // Origin + + const originChanged = !prevLog + || log.originFk != prevLog.originFk; + if (originChanged) { + this.logTree.push(originLog = { + originFk: log.originFk, + logs: [] + }); + } + + // User + + const day = 86400 * 1000; + const time = new Date(log.creationDate).getTime(); + const prevTime = prevLog && new Date(prevLog.creationDate).getTime(); + const userChanged = !prevLog + || log.userFk != prevLog.userFk + || time < prevTime - day * 2 + || nLogs >= 10; + + if (userChanged) { + originLog.logs.push(userLog = { + user: log.user, + userFk: log.userFk, + logs: [] + }); + nLogs = 0; + } + nLogs++; + + // Model + + const modelChanged = userChanged + || log.changedModel != prevLog.changedModel + || log.changedModelId != prevLog.changedModelId; + if (modelChanged) { + userLog.logs.push(modelLog = { + model: log.changedModel, + modelI18n: firstUpper(locale.name) || log.changedModel, + id: log.changedModelId, + showValue: log.changedModelValue, + logs: [] + }); + } + + modelLog.logs.push(log); + + // Changes + const notDelete = log.action != 'delete'; const olds = (notDelete ? log.oldInstance : null) || empty; const vals = (notDelete ? log.newInstance : log.oldInstance) || empty; - const locale = validations[log.changedModel]?.locale || empty; - log.changedModelI18n = firstUpper(locale.name) || log.changedModel; - let props = Object.keys(olds).concat(Object.keys(vals)); - props = [...new Set(props)]; + let propNames = Object.keys(olds).concat(Object.keys(vals)); + propNames = [...new Set(propNames)]; - log.props = []; - for (const prop of props) { - if (prop.endsWith('$')) continue; - log.props.push({ - name: prop, - nameI18n: firstUpper(locale.columns?.[prop]) || prop, - old: getVal(olds, prop), - val: getVal(vals, prop) - }); - } - log.props.sort( - (a, b) => a.nameI18n.localeCompare(b.nameI18n)); - } - - function getVal(vals, prop) { - let val, id; - const showProp = `${prop}$`; - - if (vals[showProp] != null) { - val = vals[showProp]; - id = vals[prop]; - } else - val = vals[prop]; - - return {val: castJsonValue(val), id}; + log.props = this.parseProps(propNames, locale, vals, olds); } } @@ -114,17 +170,76 @@ export default class Controller extends Section { set models(value) { this._models = value; if (!value) return; - for (const model of value) { - const name = model.changedModel; - model.changedModelI18n = - firstUpper(window.validations[name]?.locale?.name) || name; - } + for (const model of value) + model.changedModelI18n = this.translateModel(model.changedModel); } get showModelName() { return !(this.changedModel && this.changedModelId); } + parseProps(propNames, locale, vals, olds) { + const castJsonValue = this.castJsonValue; + const props = []; + + for (const prop of propNames) { + if (prop.endsWith('$')) continue; + props.push({ + name: prop, + nameI18n: firstUpper(locale.columns?.[prop]) || prop, + old: getVal(olds, prop), + val: getVal(vals, prop) + }); + } + props.sort( + (a, b) => a.nameI18n.localeCompare(b.nameI18n)); + + function getVal(vals, prop) { + let val; let id; + const showProp = `${prop}$`; + + if (vals[showProp] != null) { + val = vals[showProp]; + id = vals[prop]; + } else + val = vals[prop]; + + return {val: castJsonValue(val), id}; + } + + return props; + } + + viewPitInstance(event, id, modelLog) { + if (this.instance?.canceler) + this.instance.canceler.resolve(); + + const canceler = this.$q.defer(); + this.instance = { + modelLog, + canceler + }; + const options = {timeout: canceler.promise}; + + this.$http.get(`${this.url}/${id}/pitInstance`, options) + .then(res => { + const instance = res.data; + const propNames = Object.keys(instance); + const locale = window.validations[modelLog.model]?.locale || {}; + this.instance.props = this.parseProps(propNames, locale, instance, {}); + }) + .finally(() => { + this.instance.canceler = null; + this.$.$applyAsync(() => this.$.instancePopover.relocate()); + }); + + this.$.instancePopover.show(event); + } + + translateModel(name) { + return firstUpper(window.validations[name]?.locale?.name) || name; + } + castJsonValue(value) { return typeof value === 'string' && validDate.test(value) ? new Date(value) @@ -160,12 +275,11 @@ export default class Controller extends Section { applyFilter() { const filter = this.$.filter; - function getParam(prop, value) { + const getParam = (prop, value) => { if (value == null || value == '') return null; switch (prop) { case 'search': - const or = []; - if (/^\s*[0-9]+\s*$/.test(value)) + if (/^\s*[0-9]+\s*$/.test(value) || this.byEntity) return {changedModelId: value.trim()}; else return {changedModelValue: {like: `%${value}%`}}; @@ -177,72 +291,86 @@ export default class Controller extends Section { ]}; case 'who': switch (value) { - case 'all': - return null; case 'user': return {userFk: {neq: null}}; case 'system': return {userFk: null}; + case 'all': + default: + return null; } - case 'actions': + case 'actions': { const inq = []; for (const action in value) { if (value[action]) inq.push(action); } return inq.length ? {action: {inq}} : null; + } case 'from': - if (filter.to) { + if (filter.to) return {creationDate: {gte: value}}; - } else { + else { const to = new Date(value); to.setHours(23, 59, 59, 999); return {creationDate: {between: [value, to]}}; } - case 'to': + case 'to': { const to = new Date(value); to.setHours(23, 59, 59, 999); return {creationDate: {lte: to}}; + } case 'userFk': return filter.who != 'system' ? {[prop]: value} : null; default: return {[prop]: value}; } - } + }; + this.hasFilter = false; const and = []; + + if (!filter.search || !filter.changedModel) + this.byEntity = false; + if (!this.byEntity) + and.push({originFk: this.originId}); + for (const prop in filter) { const param = getParam(prop, filter[prop]); - if (param) and.push(param); + if (param) { + and.push(param); + this.hasFilter = true; + } } const lbFilter = and.length ? {where: {and}} : null; return this.$.model.applyFilter(lbFilter); } - filterByEntity(log) { + filterByEntity(modelLog) { + this.byEntity = true; this.$.filter = { who: 'all', - search: log.changedModelId, - changedModel: log.changedModel + search: modelLog.id, + changedModel: modelLog.model }; } searchUser(search) { - if (/^[0-9]+$/.test(search)) { + if (/^[0-9]+$/.test(search)) return {id: search}; - } else { + else { return {or: [ {name: search}, {nickname: {like: `%${search}%`}} - ]} + ]}; } } - showWorkerDescriptor(event, log) { - if (log.user?.worker) - this.$.workerDescriptor.show(event.target, log.userFk); + showWorkerDescriptor(event, userLog) { + if (userLog.user?.worker) + this.$.workerDescriptor.show(event.target, userLog.userFk); } } diff --git a/front/salix/components/log/locale/es.yml b/front/salix/components/log/locale/es.yml index 90a42911b..09154f04e 100644 --- a/front/salix/components/log/locale/es.yml +++ b/front/salix/components/log/locale/es.yml @@ -24,4 +24,5 @@ Changes: Cambios today: hoy yesterday: ayer Show all record changes: Mostrar todos los cambios realizados en el registro +View record at this point in time: Ver el registro en este punto Quit filter: Quitar filtro diff --git a/front/salix/components/log/style.scss b/front/salix/components/log/style.scss index de294972d..8c39559fc 100644 --- a/front/salix/components/log/style.scss +++ b/front/salix/components/log/style.scss @@ -1,13 +1,49 @@ @import "util"; vn-log { - .change { + .origin-log { + & > .origin-info { + display: flex; + text-align: right; + justify-content: space-between; + align-items: center; + column-gap: 4px; + padding-left: 48px; + margin-bottom: 10px; + + & > .line { + flex-grow: 1; + background-color: $color-font-secondary; + height: 2px; + } + & > .origin-id { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + font-size: 1.1rem; + color: $color-font-secondary; + } + } + } + .user-log { display: flex; - & > .left { + & > .timeline { position: relative; padding-right: 10px; + width: 38px; + min-width: 38px; + flex-grow: auto; + & > .arrow { + height: 8px; + width: 8px; + position: absolute; + transform: rotateY(0deg) rotate(45deg); + top: 14px; + right: -4px; + z-index: 1; + } & > vn-avatar { cursor: pointer; @@ -15,15 +51,6 @@ vn-log { background-color: $color-main !important; } } - & > .arrow { - height: 8px; - width: 8px; - position: absolute; - transform: rotateY(0deg) rotate(45deg); - top: 18px; - right: -4px; - z-index: 1; - } & > .line { position: absolute; background-color: $color-main; @@ -34,134 +61,173 @@ vn-log { bottom: -8px; } } - &:last-child > .left > .line { + &:last-child > .timeline > .line { display: none; } - .detail { - position: relative; + & > .user-changes { flex-grow: 1; - width: 100%; - border-radius: 2px; overflow: hidden; + } + } + .model-log { + & > .model-info { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + margin-top: 6px; - & > .header { - display: flex; - justify-content: space-between; - align-items: center; - overflow: hidden; + & > .model-name { + display: inline-block; + padding: 2px 5px; + color: $color-font-dark; + border-radius: 8px; + vertical-align: middle; + } + & > .model-value { + font-style: italic; + } + & > .model-id { + color: $color-font-secondary; + font-size: .9rem; + } + & > vn-icon[icon="filter_alt"] { + @extend %clickable-light; + vertical-align: middle; + font-size: 18px; + color: $color-font-secondary; + float: right; + display: none; - & > .action-model { - display: inline-flex; - overflow: hidden; - - & > .model-name { - display: inline-block; - padding: 2px 5px; - color: $color-font-dark; - border-radius: 8px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - } - & > .action-date { - white-space: nowrap; - - & > .action { - display: inline-flex; - align-items: center; - justify-content: center; - color: $color-font-bg; - vertical-align: middle; - border-radius: 50%; - width: 24px; - height: 24px; - font-size: 18px; - - &.notice { - background-color: $color-notice-medium - } - &.success { - background-color: $color-success-medium; - } - &.warning { - background-color: $color-main-medium; - } - &.alert { - background-color: lighten($color-alert, 5%); - } - } + @include mobile { + display: initial; } } - & > .model { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-height: 18px; + } + &:hover > .model-info > vn-icon[icon="filter_alt"] { + display: initial; + } + } + .changes-log { + position: relative; + max-width: 100%; + width: 100%; + border-radius: 2px; + overflow: hidden; - & > vn-icon { + & > .change-info { + display: flex; + justify-content: space-between; + align-items: center; + overflow: hidden; + + & > .date { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + & > div { + white-space: nowrap; + + & > vn-icon.pit { @extend %clickable-light; vertical-align: middle; - padding: 2px; - margin: -2px; font-size: 18px; color: $color-font-secondary; - float: right; display: none; @include mobile { - display: initial; + display: inline-block; } } - & > .model-value { - font-style: italic; - } - & > .model-id { - color: $color-font-secondary; - font-size: .9rem; - } - } - &:hover > .model > vn-icon { - display: initial; - } - } - } - .changes { - overflow: hidden; - background-color: rgba(255, 255, 255, .05); - color: $color-font-light; - position: relative; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - min-height: 34px; - box-sizing: border-box; + & > .action { + display: inline-flex; + align-items: center; + justify-content: center; + color: $color-font-bg; + vertical-align: middle; + border-radius: 50%; + width: 24px; + height: 24px; + font-size: 18px; - & > vn-icon { - @extend %clickable; - float: right; - position: relative; - transition-property: transform, background-color; - transition-duration: 150ms; - margin: -5px; - margin-left: 4px; - padding: 1px; - border-radius: 50%; + &.notice { + background-color: $color-notice-medium + } + &.success { + background-color: $color-success-medium; + } + &.warning { + background-color: $color-main-medium; + } + &.alert { + background-color: lighten($color-alert, 5%); + } + } + } + &:hover vn-icon.pit { + display: inline-block; + } } - &.expanded { - text-overflow: initial; - white-space: initial; + & > .change-detail { + overflow: hidden; + background-color: rgba(255, 255, 255, .05); + color: $color-font-light; + position: relative; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + min-height: 34px; + box-sizing: border-box; & > vn-icon { - transform: rotate(180deg); + @extend %clickable; + float: right; + position: relative; + transition-property: transform, background-color; + transition-duration: 150ms; + margin: -5px; + margin-left: 4px; + padding: 1px; + border-radius: 50%; + } + &.expanded { + text-overflow: initial; + white-space: initial; + + & > vn-icon { + transform: rotate(180deg); + } + } + & > .no-changes { + font-style: italic; } } - & > .no-changes { - font-style: italic; + } + .id-value { + font-size: .9rem; + color: $color-font-secondary; + } +} +.vn-log-instance { + display: block; + + & > .loading { + display: flex; + justify-content: center; + } + & > .instance { + min-width: 180px; + max-width: 400px; + + & > .header { + background-color: $color-main; + color: $color-font-dark; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + & > .change-detail { + color: $color-font-light; } } } -vn-log-value > .id-value { - font-size: .9rem; - color: $color-font-secondary; -} diff --git a/loopback/common/methods/log/pitInstance.js b/loopback/common/methods/log/pitInstance.js new file mode 100644 index 000000000..3cbe013b3 --- /dev/null +++ b/loopback/common/methods/log/pitInstance.js @@ -0,0 +1,56 @@ +module.exports = Self => { + Self.remoteMethod('pitInstance', { + description: 'Gets the status of instance at specific point in time', + accepts: [ + { + arg: 'id', + type: 'integer', + description: 'The log id', + required: true + } + ], + returns: { + type: [Self], + root: true + }, + http: { + path: `/:id/pitInstance`, + verb: 'GET' + } + }); + + Self.pitInstance = async function(id) { + const log = await Self.findById(id, { + fields: ['changedModel', 'changedModelId'] + }); + + const where = { + changedModel: log.changedModel, + changedModelId: log.changedModelId + }; + + const createdWhere = {action: 'insert'}; + const createdLog = await Self.findOne({ + fields: ['id'], + where: Object.assign(createdWhere, where) + }); + + const logsWhere = { + id: {between: [ + Math.min(id, createdLog.id), + Math.max(id, createdLog.id) + ]} + }; + const logs = await Self.find({ + fields: ['newInstance'], + where: Object.assign(logsWhere, where), + order: 'creationDate' + }); + + const instance = {}; + for (const log of logs) + Object.assign(instance, log.newInstance); + + return instance; + }; +}; diff --git a/loopback/common/models/log.js b/loopback/common/models/log.js index 0622431a6..b0d3cfc00 100644 --- a/loopback/common/models/log.js +++ b/loopback/common/models/log.js @@ -5,6 +5,7 @@ module.exports = function(Self) { Self.super_.setup.call(this); require('../methods/log/editors')(this); require('../methods/log/models')(this); + require('../methods/log/pitInstance')(this); } }); }; diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js deleted file mode 100644 index 4029bfbcf..000000000 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js +++ /dev/null @@ -1,28 +0,0 @@ -const models = require('vn-loopback/server/server').models; -const fs = require('fs-extra'); - -describe('InvoiceOut download()', () => { - const userId = 9; - const invoiceId = 1; - const ctx = { - req: { - - accessToken: {userId: userId}, - headers: {origin: 'http://localhost:5000'}, - } - }; - - it('should return the downloaded file name', async() => { - spyOn(models.InvoiceContainer, 'container').and.returnValue({ - client: {root: '/path'} - }); - spyOn(fs, 'createReadStream').and.returnValue(new Promise(resolve => resolve('streamObject'))); - spyOn(fs, 'access').and.returnValue(true); - spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true))); - - const result = await models.InvoiceOut.download(ctx, invoiceId); - - expect(result[1]).toEqual('application/pdf'); - expect(result[2]).toMatch(/filename="\d{4}T1111111.pdf"/); - }); -}); From 98301f8e709158e8431d93e583b7bcb41ee6d641 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 25 Jun 2023 17:06:38 +0200 Subject: [PATCH 157/170] refs #5900 Small fixes & code clean --- .../02-client/07_edit_web_access.spec.js | 4 +-- front/salix/components/log/index.html | 8 +++--- front/salix/components/log/index.js | 13 ++++----- front/salix/components/log/style.scss | 5 ++-- loopback/common/methods/log/pitInstance.js | 28 ++++++++++++++++--- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/e2e/paths/02-client/07_edit_web_access.spec.js b/e2e/paths/02-client/07_edit_web_access.spec.js index 5386d12bd..3847ec7cd 100644 --- a/e2e/paths/02-client/07_edit_web_access.spec.js +++ b/e2e/paths/02-client/07_edit_web_access.spec.js @@ -5,8 +5,8 @@ const $ = { userName: 'vn-client-web-access vn-textfield[ng-model="$ctrl.account.name"]', email: 'vn-client-web-access vn-textfield[ng-model="$ctrl.account.email"]', saveButton: 'vn-client-web-access button[type=submit]', - nameValue: 'vn-client-log .change:nth-child(1) .basic-json:nth-child(2) vn-json-value', - activeValue: 'vn-client-log .change:nth-child(2) .basic-json:nth-child(1) vn-json-value' + nameValue: 'vn-client-log .changes-log:nth-child(2) .basic-json:nth-child(2) vn-json-value', + activeValue: 'vn-client-log .changes-log:nth-child(3) .basic-json:nth-child(1) vn-json-value' }; describe('Client web access path', () => { diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index ac4e5cb6e..e0465b840 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -33,16 +33,16 @@ ng-src="/api/Images/user/160x160/{{::userLog.userFk}}/download?access_token={{::$ctrl.vnToken.token}}"> -
+
-
+
+ ng-click="$ctrl.filterByRecord(modelLog)"> diff --git a/front/salix/components/log/index.js b/front/salix/components/log/index.js index ecbeaefe7..822a31801 100644 --- a/front/salix/components/log/index.js +++ b/front/salix/components/log/index.js @@ -67,8 +67,7 @@ export default class Controller extends Section { $onInit() { const match = this.url?.match(/(.*)Logs$/); - this.model = match && match[1]; - this.modelI18n = this.translateModel(this.model); + this.modelI18n = this.translateModel(match && match[1]); } $postLink() { @@ -279,7 +278,7 @@ export default class Controller extends Section { if (value == null || value == '') return null; switch (prop) { case 'search': - if (/^\s*[0-9]+\s*$/.test(value) || this.byEntity) + if (/^\s*[0-9]+\s*$/.test(value) || this.byRecord) return {changedModelId: value.trim()}; else return {changedModelValue: {like: `%${value}%`}}; @@ -332,8 +331,8 @@ export default class Controller extends Section { const and = []; if (!filter.search || !filter.changedModel) - this.byEntity = false; - if (!this.byEntity) + this.byRecord = false; + if (!this.byRecord) and.push({originFk: this.originId}); for (const prop in filter) { @@ -348,8 +347,8 @@ export default class Controller extends Section { return this.$.model.applyFilter(lbFilter); } - filterByEntity(modelLog) { - this.byEntity = true; + filterByRecord(modelLog) { + this.byRecord = true; this.$.filter = { who: 'all', search: modelLog.id, diff --git a/front/salix/components/log/style.scss b/front/salix/components/log/style.scss index 8c39559fc..f11fc2f25 100644 --- a/front/salix/components/log/style.scss +++ b/front/salix/components/log/style.scss @@ -74,7 +74,8 @@ vn-log { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; - margin-top: 6px; + margin-top: 5px; + min-height: 22px; & > .model-name { display: inline-block; @@ -131,7 +132,7 @@ vn-log { & > vn-icon.pit { @extend %clickable-light; vertical-align: middle; - font-size: 18px; + font-size: 20px; color: $color-font-secondary; display: none; diff --git a/loopback/common/methods/log/pitInstance.js b/loopback/common/methods/log/pitInstance.js index 3cbe013b3..1c054c53e 100644 --- a/loopback/common/methods/log/pitInstance.js +++ b/loopback/common/methods/log/pitInstance.js @@ -1,3 +1,5 @@ +const NotFoundError = require('vn-loopback/util/not-found-error'); + module.exports = Self => { Self.remoteMethod('pitInstance', { description: 'Gets the status of instance at specific point in time', @@ -21,24 +23,40 @@ module.exports = Self => { Self.pitInstance = async function(id) { const log = await Self.findById(id, { - fields: ['changedModel', 'changedModelId'] + fields: [ + 'changedModel', + 'changedModelId', + 'creationDate' + ] }); + if (!log) + throw new NotFoundError(); const where = { changedModel: log.changedModel, changedModelId: log.changedModelId }; - const createdWhere = {action: 'insert'}; + const createdWhere = { + action: 'insert', + creationDate: {lte: log.creationDate} + }; const createdLog = await Self.findOne({ - fields: ['id'], - where: Object.assign(createdWhere, where) + fields: ['id', 'creationDate'], + where: Object.assign(createdWhere, where), + order: 'creationDate DESC' }); + if (!createdLog) + throw new NotFoundError('Cannot find creation log'); const logsWhere = { id: {between: [ Math.min(id, createdLog.id), Math.max(id, createdLog.id) + ]}, + creationDate: {between: [ + createdLog.creationDate, + log.creationDate ]} }; const logs = await Self.find({ @@ -46,6 +64,8 @@ module.exports = Self => { where: Object.assign(logsWhere, where), order: 'creationDate' }); + if (!logs.length) + throw new NotFoundError('No logs found for record'); const instance = {}; for (const log of logs) From 21988fba8c2939da1e0e2eb0d3e6497931654c59 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 25 Jun 2023 17:11:01 +0200 Subject: [PATCH 158/170] refs #5900 Hide PIT button on insert actions --- front/salix/components/log/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index e0465b840..2a6bd9abe 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -65,6 +65,7 @@ class="pit vn-ml-xs" icon="preview" translate-attr="::{title: 'View record at this point in time'}" + ng-show="::log.action != 'insert'" ng-click="$ctrl.viewPitInstance($event, log.id, modelLog)"> Date: Sun, 25 Jun 2023 17:14:41 +0200 Subject: [PATCH 159/170] refs #5900 Optimization: remove unnecessary watcher --- front/salix/components/log/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index 2a6bd9abe..892268a64 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -19,7 +19,7 @@
- {{$ctrl.modelI18n}} #{{::originLog.originFk}} + {{::$ctrl.modelI18n}} #{{::originLog.originFk}}
From 57277ceb2e2b406a8d4b0ec212c11b6dba886a42 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 25 Jun 2023 17:17:04 +0200 Subject: [PATCH 160/170] refs #5900 Show user every 6 changes, model info margin fix --- front/salix/components/log/index.html | 2 +- front/salix/components/log/index.js | 2 +- front/salix/components/log/style.scss | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index 892268a64..7c7c5b068 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -38,7 +38,7 @@
-
+
= 10; + || nLogs >= 6; if (userChanged) { originLog.logs.push(userLog = { diff --git a/front/salix/components/log/style.scss b/front/salix/components/log/style.scss index f11fc2f25..481a7fbb3 100644 --- a/front/salix/components/log/style.scss +++ b/front/salix/components/log/style.scss @@ -74,7 +74,6 @@ vn-log { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; - margin-top: 5px; min-height: 22px; & > .model-name { From d31d1e5a133f5a978253692d1da651ebe70f6170 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 25 Jun 2023 17:25:11 +0200 Subject: [PATCH 161/170] refs #5900 User avatar margin fix --- front/salix/components/log/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/front/salix/components/log/style.scss b/front/salix/components/log/style.scss index 481a7fbb3..53d13b7f9 100644 --- a/front/salix/components/log/style.scss +++ b/front/salix/components/log/style.scss @@ -46,6 +46,7 @@ vn-log { } & > vn-avatar { cursor: pointer; + margin-top: 4px; &.system { background-color: $color-main !important; From fd69d69ff0bb2a76cc0f02c9511916223305e57f Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 25 Jun 2023 17:40:09 +0200 Subject: [PATCH 162/170] refs #5900 Style: margin adjustments --- front/core/components/avatar/style.scss | 4 ++-- front/salix/components/log/style.scss | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/front/core/components/avatar/style.scss b/front/core/components/avatar/style.scss index 272930821..b3a80db55 100644 --- a/front/core/components/avatar/style.scss +++ b/front/core/components/avatar/style.scss @@ -4,8 +4,8 @@ vn-avatar { display: block; border-radius: 50%; overflow: hidden; - height: 36px; - width: 36px; + height: 38px; + width: 38px; font-size: 22px; background-color: $color-main; position: relative; diff --git a/front/salix/components/log/style.scss b/front/salix/components/log/style.scss index 53d13b7f9..050e3f9d9 100644 --- a/front/salix/components/log/style.scss +++ b/front/salix/components/log/style.scss @@ -40,13 +40,12 @@ vn-log { width: 8px; position: absolute; transform: rotateY(0deg) rotate(45deg); - top: 14px; + top: 15px; right: -4px; z-index: 1; } & > vn-avatar { cursor: pointer; - margin-top: 4px; &.system { background-color: $color-main !important; @@ -56,10 +55,10 @@ vn-log { position: absolute; background-color: $color-main; width: 2px; - left: 17px; + left: 18px; z-index: -1; top: 44px; - bottom: -8px; + bottom: -2px; } } &:last-child > .timeline > .line { @@ -115,6 +114,9 @@ vn-log { border-radius: 2px; overflow: hidden; + &:last-child { + margin-bottom: 0; + } & > .change-info { display: flex; justify-content: space-between; From 631c0e312139bdecf1ca44ba21e0ada85f0cb808 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 25 Jun 2023 18:09:28 +0200 Subject: [PATCH 163/170] refs #5900 Log grouping fix --- front/salix/components/log/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/salix/components/log/index.js b/front/salix/components/log/index.js index b144b6446..ad5a3b355 100644 --- a/front/salix/components/log/index.js +++ b/front/salix/components/log/index.js @@ -117,7 +117,7 @@ export default class Controller extends Section { const day = 86400 * 1000; const time = new Date(log.creationDate).getTime(); const prevTime = prevLog && new Date(prevLog.creationDate).getTime(); - const userChanged = !prevLog + const userChanged = originChanged || log.userFk != prevLog.userFk || time < prevTime - day * 2 || nLogs >= 6; From c15d9a4753e271fe54b528e4b470425464e99b0d Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 25 Jun 2023 18:49:38 +0200 Subject: [PATCH 164/170] refs #5900 Log order fix --- front/salix/components/log/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index 7c7c5b068..5c10aa205 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -3,7 +3,7 @@ url="{{$ctrl.url}}" filter="$ctrl.filter" data="$ctrl.logs" - order="creationDate DESC, id DESC" + order="creationDate DESC, originFk DESC, id DESC" limit="20"> Date: Sun, 25 Jun 2023 19:01:46 +0200 Subject: [PATCH 165/170] refs #5900 Removed code to split user changes based on date --- front/salix/components/log/index.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/front/salix/components/log/index.js b/front/salix/components/log/index.js index ad5a3b355..b5dac196e 100644 --- a/front/salix/components/log/index.js +++ b/front/salix/components/log/index.js @@ -114,14 +114,9 @@ export default class Controller extends Section { // User - const day = 86400 * 1000; - const time = new Date(log.creationDate).getTime(); - const prevTime = prevLog && new Date(prevLog.creationDate).getTime(); const userChanged = originChanged || log.userFk != prevLog.userFk - || time < prevTime - day * 2 || nLogs >= 6; - if (userChanged) { originLog.logs.push(userLog = { user: log.user, From d69cbe0ad4c3dd5451c7fafb9fc82722ed1e054d Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 25 Jun 2023 19:39:27 +0200 Subject: [PATCH 166/170] refs #5900 Origin separator style fix --- front/salix/components/log/index.html | 9 +++------ front/salix/components/log/style.scss | 27 +++++++-------------------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index 5c10aa205..68c828772 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -16,12 +16,9 @@ model="model" class="vn-w-sm vn-px-sm vn-pb-xl">
-
-
-
- {{::$ctrl.modelI18n}} #{{::originLog.originFk}} -
-
+
+ {{::$ctrl.modelI18n}} #{{::originLog.originFk}} +
.origin-info { + margin-top: 0; + } & > .origin-info { - display: flex; - text-align: right; - justify-content: space-between; - align-items: center; - column-gap: 4px; - padding-left: 48px; - margin-bottom: 10px; - - & > .line { - flex-grow: 1; - background-color: $color-font-secondary; - height: 2px; - } - & > .origin-id { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - font-size: 1.1rem; - color: $color-font-secondary; - } + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + color: $color-font-secondary; } } .user-log { From 544445c4ae6f6c976db61e09702d6f0c75440d23 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 25 Jun 2023 19:52:14 +0200 Subject: [PATCH 167/170] refs #5800 Origin separator style more clear --- front/salix/components/log/index.html | 9 ++++++--- front/salix/components/log/style.scss | 21 +++++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index 68c828772..084bf9834 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -16,9 +16,12 @@ model="model" class="vn-w-sm vn-px-sm vn-pb-xl">
-
- {{::$ctrl.modelI18n}} #{{::originLog.originFk}} -
+
+
+ {{::$ctrl.modelI18n}} #{{::originLog.originFk}} +
+
+
.origin-info { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - color: $color-font-secondary; + display: flex; + align-items: center; + margin-top: 28px; + gap: 6px; + + & > .origin-id { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + color: $color-font-secondary; + margin: 0; + } + & > .line { + flex-grow: 1; + background-color: $color-font-secondary; + height: 2px; + } } } .user-log { From c42b38c5ccdd296e8130db159d849891afdb05a1 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 26 Jun 2023 10:23:34 +0200 Subject: [PATCH 168/170] refs #5900 Code clean, refactor & accurated --- front/salix/components/log/index.html | 12 +++--- front/salix/components/log/index.js | 10 ++--- front/salix/components/log/style.scss | 1 + loopback/common/methods/log/pitInstance.js | 47 ++++++++++++++-------- 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index 084bf9834..16342783d 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -3,7 +3,7 @@ url="{{$ctrl.url}}" filter="$ctrl.filter" data="$ctrl.logs" - order="creationDate DESC, originFk DESC, id DESC" + order="creationDate DESC, id DESC" limit="20"> - -
-
+
{{$ctrl.instance.modelLog.modelI18n}} #{{$ctrl.instance.modelLog.id}} -
+
@@ -258,3 +255,6 @@
+ + diff --git a/front/salix/components/log/index.js b/front/salix/components/log/index.js index b5dac196e..3df367cae 100644 --- a/front/salix/components/log/index.js +++ b/front/salix/components/log/index.js @@ -67,7 +67,7 @@ export default class Controller extends Section { $onInit() { const match = this.url?.match(/(.*)Logs$/); - this.modelI18n = this.translateModel(match && match[1]); + this.modelI18n = match && this.translateModel(match[1]); } $postLink() { @@ -116,7 +116,7 @@ export default class Controller extends Section { const userChanged = originChanged || log.userFk != prevLog.userFk - || nLogs >= 6; + || nLogs >= 5; if (userChanged) { originLog.logs.push(userLog = { user: log.user, @@ -181,8 +181,8 @@ export default class Controller extends Section { props.push({ name: prop, nameI18n: firstUpper(locale.columns?.[prop]) || prop, - old: getVal(olds, prop), - val: getVal(vals, prop) + val: getVal(vals, prop), + old: olds && getVal(olds, prop) }); } props.sort( @@ -220,7 +220,7 @@ export default class Controller extends Section { const instance = res.data; const propNames = Object.keys(instance); const locale = window.validations[modelLog.model]?.locale || {}; - this.instance.props = this.parseProps(propNames, locale, instance, {}); + this.instance.props = this.parseProps(propNames, locale, instance); }) .finally(() => { this.instance.canceler = null; diff --git a/front/salix/components/log/style.scss b/front/salix/components/log/style.scss index 3ecbbb609..d729d09a3 100644 --- a/front/salix/components/log/style.scss +++ b/front/salix/components/log/style.scss @@ -228,6 +228,7 @@ vn-log { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; + margin: 0; } & > .change-detail { color: $color-font-light; diff --git a/loopback/common/methods/log/pitInstance.js b/loopback/common/methods/log/pitInstance.js index 1c054c53e..cb671cb7e 100644 --- a/loopback/common/methods/log/pitInstance.js +++ b/loopback/common/methods/log/pitInstance.js @@ -37,37 +37,52 @@ module.exports = Self => { changedModelId: log.changedModelId }; + // Fetch creation and all update logs for record up to requested log + const createdWhere = { action: 'insert', creationDate: {lte: log.creationDate} }; const createdLog = await Self.findOne({ - fields: ['id', 'creationDate'], + fields: ['id', 'creationDate', 'newInstance'], where: Object.assign(createdWhere, where), - order: 'creationDate DESC' + order: 'creationDate DESC, id DESC' }); - if (!createdLog) - throw new NotFoundError('Cannot find creation log'); - const logsWhere = { - id: {between: [ - Math.min(id, createdLog.id), - Math.max(id, createdLog.id) - ]}, - creationDate: {between: [ - createdLog.creationDate, - log.creationDate - ]} + const instance = {}; + + let logsWhere = { + action: 'update' }; + if (createdLog) { + Object.assign(instance, createdLog.newInstance); + Object.assign(logsWhere, { + creationDate: {between: [ + createdLog.creationDate, + log.creationDate + ]}, + id: {between: [ + Math.min(id, createdLog.id), + Math.max(id, createdLog.id) + ]} + }); + } else { + Object.assign(logsWhere, { + creationDate: {lte: log.creationDate}, + id: {lte: id} + }); + } + const logs = await Self.find({ fields: ['newInstance'], where: Object.assign(logsWhere, where), - order: 'creationDate' + order: 'creationDate, id' }); - if (!logs.length) + if (!logs.length && !createdLog) throw new NotFoundError('No logs found for record'); - const instance = {}; + // Merge all logs in order into one instance + for (const log of logs) Object.assign(instance, log.newInstance); From e980717d149466c5b2c87a7ff4b25f331e02e19a Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 26 Jun 2023 10:56:53 +0200 Subject: [PATCH 169/170] refs #5900, #5772 Changelog updated --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa2ebcd62..47eeb47a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - (Entradas -> Correo) Al cambiar el tipo de cambio enviará un correo a las personas designadas +- (General -> Históricos) Botón para ver el estado del registro en cada punto +- (General -> Históricos) Al filtar por registro se muestra todo el histórial desde que fue creado ### Changed +- (General -> Históricos) Los registros se muestran agrupados por usuario y entidad +- (Facturas -> Facturación global) Optimizada, generación de PDFs y notificaciones en paralelo ### Fixed -- +- (General -> Históricos) Duplicidades eliminadas +- (Facturas -> Facturación global) Solucionados fallos que paran el proceso ## [2324.01] - 2023-06-15 From ef8e1c4169b1008098615c34ba2429623a0b8b0a Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 26 Jun 2023 10:57:12 +0200 Subject: [PATCH 170/170] refs #5531 refs #5753 fix travelConfig sql --- db/changes/232402/00-hotFix_travelConfig.sql | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 db/changes/232402/00-hotFix_travelConfig.sql diff --git a/db/changes/232402/00-hotFix_travelConfig.sql b/db/changes/232402/00-hotFix_travelConfig.sql new file mode 100644 index 000000000..65450a74d --- /dev/null +++ b/db/changes/232402/00-hotFix_travelConfig.sql @@ -0,0 +1,22 @@ +CREATE TABLE `vn`.`travelConfig` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `warehouseInFk` smallint(6) unsigned NOT NULL DEFAULT 8 COMMENT 'Warehouse de origen', + `warehouseOutFk` smallint(6) unsigned NOT NULL DEFAULT 60 COMMENT 'Warehouse destino', + `agencyFk` int(11) NOT NULL DEFAULT 1378 COMMENT 'Agencia por defecto', + `companyFk` int(10) unsigned NOT NULL DEFAULT 442 COMMENT 'Compañía por defecto', + PRIMARY KEY (`id`), + KEY `travelConfig_FK` (`warehouseInFk`), + KEY `travelConfig_FK_1` (`warehouseOutFk`), + KEY `travelConfig_FK_2` (`agencyFk`), + KEY `travelConfig_FK_3` (`companyFk`), + CONSTRAINT `travelConfig_FK` FOREIGN KEY (`warehouseInFk`) REFERENCES `warehouse` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `travelConfig_FK_1` FOREIGN KEY (`warehouseOutFk`) REFERENCES `warehouse` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `travelConfig_FK_2` FOREIGN KEY (`agencyFk`) REFERENCES `agencyMode` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `travelConfig_FK_3` FOREIGN KEY (`companyFk`) REFERENCES `company` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Entry', 'addFromPackaging', 'WRITE', 'ALLOW', 'ROLE', 'production'), + ('Entry', 'addFromBuy', 'WRITE', 'ALLOW', 'ROLE', 'production'), + ('Supplier', 'getItemsPackaging', 'READ', 'ALLOW', 'ROLE', 'production');