From c2de5c5ff4fa4c07f9c6721b540832d566778b52 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 2 May 2023 07:28:59 +0200 Subject: [PATCH 001/449] refs #4797 added redirection section --- db/dump/fixtures.sql | 7 +++++- loopback/locale/es.json | 23 ++++++++++--------- modules/client/back/models/client.json | 2 +- modules/worker/front/index.js | 1 + modules/worker/front/notifications/index.html | 2 ++ modules/worker/front/notifications/index.js | 21 +++++++++++++++++ modules/worker/front/routes.json | 9 ++++++++ 7 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 modules/worker/front/notifications/index.html create mode 100644 modules/worker/front/notifications/index.js diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 15ccece355..6554adc33c 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2723,7 +2723,10 @@ INSERT INTO `util`.`notification` (`id`, `name`, `description`) INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`) VALUES - (1, 9); + (1, 9), + (1, 1), + (2, 1), + (4, 1); INSERT INTO `util`.`notificationQueue` (`id`, `notificationFk`, `params`, `authorFk`, `status`, `created`) VALUES @@ -2735,6 +2738,8 @@ INSERT INTO `util`.`notificationSubscription` (`notificationFk`, `userFk`) VALUES (1, 1109), (1, 1110), + (2, 1110), + (4, 1110), (2, 1109), (1,9), (1,3); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 3ef3c4a227..628f7ace68 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", + "You dont have permission to modify this user": "No tienes permiso para modificar este usuario" } diff --git a/modules/client/back/models/client.json b/modules/client/back/models/client.json index 5f56a1ed2e..73b6cccb45 100644 --- a/modules/client/back/models/client.json +++ b/modules/client/back/models/client.json @@ -158,7 +158,7 @@ }, "user": { "type": "belongsTo", - "model": "Account", + "model": "VnUser", "foreignKey": "id" }, "payMethod": { diff --git a/modules/worker/front/index.js b/modules/worker/front/index.js index 8fad2c0df7..5c03dc8de7 100644 --- a/modules/worker/front/index.js +++ b/modules/worker/front/index.js @@ -20,4 +20,5 @@ import './dms/create'; import './dms/edit'; import './note/index'; import './note/create'; +import './notifications'; diff --git a/modules/worker/front/notifications/index.html b/modules/worker/front/notifications/index.html new file mode 100644 index 0000000000..7fb3b870e0 --- /dev/null +++ b/modules/worker/front/notifications/index.html @@ -0,0 +1,2 @@ + + diff --git a/modules/worker/front/notifications/index.js b/modules/worker/front/notifications/index.js new file mode 100644 index 0000000000..622892979a --- /dev/null +++ b/modules/worker/front/notifications/index.js @@ -0,0 +1,21 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +class Controller extends Section { + constructor($element, $) { + super($element, $); + } + + async $onInit() { + const url = await this.vnApp.getUrl(`worker/${this.$params.id}/notifications`); + window.open(url).focus(); + } +} + +ngModule.vnComponent('vnWorkerNotifications', { + template: require('./index.html'), + controller: Controller, + bindings: { + ticket: '<' + } +}); diff --git a/modules/worker/front/routes.json b/modules/worker/front/routes.json index 25a0ffbcf2..bce0172a20 100644 --- a/modules/worker/front/routes.json +++ b/modules/worker/front/routes.json @@ -15,6 +15,7 @@ {"state": "worker.card.timeControl", "icon": "access_time"}, {"state": "worker.card.calendar", "icon": "icon-calendar"}, {"state": "worker.card.pda", "icon": "phone_android"}, + {"state": "worker.card.notifications", "icon": "notifications"}, {"state": "worker.card.pbx", "icon": "icon-pbx"}, {"state": "worker.card.dms.index", "icon": "cloud_upload"}, { @@ -109,6 +110,14 @@ "params": { "worker": "$ctrl.worker" } + }, { + "url": "/notifications", + "state": "worker.card.notifications", + "component": "vn-worker-notifications", + "description": "Notifications", + "params": { + "worker": "$ctrl.worker" + } }, { "url": "/time-control?timestamp", "state": "worker.card.timeControl", From 70c46efe275e0e518c884d8e76eedf4174f02ec9 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 2 May 2023 09:51:04 +0200 Subject: [PATCH 002/449] refs #4797 fix back test --- .../specs/notificationSubscription.spec.js | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/back/models/specs/notificationSubscription.spec.js b/back/models/specs/notificationSubscription.spec.js index c7f37abedd..c5ef698fd9 100644 --- a/back/models/specs/notificationSubscription.spec.js +++ b/back/models/specs/notificationSubscription.spec.js @@ -1,8 +1,9 @@ const models = require('vn-loopback/server/server').models; describe('loopback model NotificationSubscription', () => { - it('Should fail to delete a notification if the user is not editing itself or a subordinate', async() => { + it('should fail to delete a notification if the user is not editing itself or a subordinate', async() => { const tx = await models.NotificationSubscription.beginTransaction({}); + let error; try { const options = {transaction: tx}; @@ -11,29 +12,23 @@ describe('loopback model NotificationSubscription', () => { const ctx = {req: {accessToken: {userId: user}}}; const notification = await models.NotificationSubscription.findById(notificationSubscriptionId); - let error; - - try { - await models.NotificationSubscription.deleteNotification(ctx, notification.id, options); - } catch (e) { - error = e; - } + await models.NotificationSubscription.deleteNotification(ctx, notification.id, options); expect(error.message).toContain('You dont have permission to modify this user'); await tx.rollback(); } catch (e) { + error = e; await tx.rollback(); - throw e; } }); - it('Should delete a notification if the user is editing itself', async() => { + it('should delete a notification if the user is editing itself', async() => { const tx = await models.NotificationSubscription.beginTransaction({}); try { const options = {transaction: tx}; const user = 9; - const notificationSubscriptionId = 4; + const notificationSubscriptionId = 6; const ctx = {req: {accessToken: {userId: user}}}; const notification = await models.NotificationSubscription.findById(notificationSubscriptionId); @@ -49,13 +44,13 @@ describe('loopback model NotificationSubscription', () => { } }); - it('Should delete a notification if the user is editing a subordinate', async() => { + it('should delete a notification if the user is editing a subordinate', async() => { const tx = await models.NotificationSubscription.beginTransaction({}); try { const options = {transaction: tx}; - const user = 9; - const notificationSubscriptionId = 5; + const user = 19; + const notificationSubscriptionId = 4; const ctx = {req: {accessToken: {userId: user}}}; const notification = await models.NotificationSubscription.findById(notificationSubscriptionId); From 4c0ec6faf53a4118a46e97ddc1b59d7d71651341 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 2 May 2023 14:26:47 +0200 Subject: [PATCH 003/449] changedModel sms --- e2e/paths/13-supplier/03_fiscal_data.spec.js | 2 +- modules/client/back/methods/client/sendSms.js | 2 +- modules/ticket/back/methods/ticket/sendSms.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/paths/13-supplier/03_fiscal_data.spec.js b/e2e/paths/13-supplier/03_fiscal_data.spec.js index 31b3fafd2f..170a8d05ac 100644 --- a/e2e/paths/13-supplier/03_fiscal_data.spec.js +++ b/e2e/paths/13-supplier/03_fiscal_data.spec.js @@ -15,7 +15,7 @@ const $inputs = { sageTaxType: 'vn-supplier-fiscal-data [ng-model="$ctrl.supplier.sageTaxTypeFk"]' }; -fdescribe('Supplier fiscal data path', () => { +describe('Supplier fiscal data path', () => { let browser; let page; diff --git a/modules/client/back/methods/client/sendSms.js b/modules/client/back/methods/client/sendSms.js index 9d6a12416e..456d1d6217 100644 --- a/modules/client/back/methods/client/sendSms.js +++ b/modules/client/back/methods/client/sendSms.js @@ -44,7 +44,7 @@ module.exports = Self => { originFk: id, userFk: userId, action: 'insert', - changedModel: 'sms', + changedModel: 'Sms', newInstance: { destinationFk: id, destination: destination, diff --git a/modules/ticket/back/methods/ticket/sendSms.js b/modules/ticket/back/methods/ticket/sendSms.js index 2336ae8595..3c361b7833 100644 --- a/modules/ticket/back/methods/ticket/sendSms.js +++ b/modules/ticket/back/methods/ticket/sendSms.js @@ -58,7 +58,7 @@ module.exports = Self => { originFk: id, userFk: userId, action: 'insert', - changedModel: 'sms', + changedModel: 'Sms', newInstance: { destinationFk: id, destination: destination, From e7d16dc8baf1e26c8a02cd7f80082b49967a1f9d Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 9 May 2023 11:34:32 +0200 Subject: [PATCH 004/449] refs #4797 fix test, add getList --- back/methods/notification/getList.js | 80 ++++++++++++ .../notification/specs/getList.spec.js | 38 ++++++ back/models/notificationSubscription.js | 76 ++++------- .../specs/notificationSubscription.spec.js | 123 +++++++++++++----- .../232001/00-notificationSubscription.sql | 3 + loopback/locale/es.json | 3 +- 6 files changed, 240 insertions(+), 83 deletions(-) create mode 100644 back/methods/notification/getList.js create mode 100644 back/methods/notification/specs/getList.spec.js create mode 100644 db/changes/232001/00-notificationSubscription.sql diff --git a/back/methods/notification/getList.js b/back/methods/notification/getList.js new file mode 100644 index 0000000000..9f33671843 --- /dev/null +++ b/back/methods/notification/getList.js @@ -0,0 +1,80 @@ +module.exports = Self => { + Self.remoteMethod('getList', { + description: 'Get list of the available and active notification subscriptions', + accessType: 'READ', + accepts: [ + { + arg: 'id', + type: 'number', + description: 'User to modify', + http: {source: 'path'} + } + ], + returns: { + type: 'object', + root: true + }, + http: { + path: `/:id/getList`, + verb: 'GET' + } + }); + + Self.getList = async(id, options) => { + const notifications = []; + const models = Self.app.models; + + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const activeNotifications = await models.NotificationSubscription.find({ + include: {relation: 'notification'}, + where: {userFk: id} + }, myOptions); + + const roles = await models.RoleMapping.find({ + fields: ['roleId'], + where: {principalId: id} + }, myOptions); + + const availableNotifications = await models.NotificationAcl.find({ + include: {relation: 'notification'}, + where: { + roleFk: { + inq: roles.map(role => { + return role.roleId; + }), + }, + } + }, myOptions); + + activeNotifications.forEach(subscription => { + notifications.push({ + id: subscription.id, + notificationFk: subscription.notificationFk, + name: subscription.notification().name, + description: subscription.notification().description, + active: true + }); + }); + + availableNotifications.forEach(acl => { + const activeNotif = notifications.find( + notif => notif.notificationFk === acl.notificationFk + ); + if (!activeNotif) { + notifications.push({ + id: null, + notificationFk: acl.notificationFk, + name: acl.notification().name, + description: acl.notification().description, + active: false, + }); + } + }); + + return notifications; + }; +}; diff --git a/back/methods/notification/specs/getList.spec.js b/back/methods/notification/specs/getList.spec.js new file mode 100644 index 0000000000..b220f2215a --- /dev/null +++ b/back/methods/notification/specs/getList.spec.js @@ -0,0 +1,38 @@ +const models = require('vn-loopback/server/server').models; + +describe('NotificationSubscription getList()', () => { + it('should return a list of available and active notifications of a user', async() => { + const userId = 1109; + const activeNotifications = await models.NotificationSubscription.find({ + where: {userFk: userId} + }); + const roles = await models.RoleMapping.find({ + fields: ['roleId'], + where: {principalId: userId} + }); + const availableNotifications = await models.NotificationAcl.find({ + where: { + roleFk: { + inq: roles.map(role => { + return role.roleId; + }), + }, + } + }); + + const result = await models.NotificationSubscription.getList(userId); + + expect(result.filter(notification => notification.active == true).length) + .toEqual(activeNotifications.length); + + expect(result.filter(notification => notification.active == false).length) + .toEqual(availableNotifications.length - activeNotifications.length); + }); + + it('should return empty from a non existent user', async() => { + const userId = 123456789; + const result = await models.NotificationSubscription.getList(userId); + + expect(result.length).toEqual(0); + }); +}); diff --git a/back/models/notificationSubscription.js b/back/models/notificationSubscription.js index f1b2811fa7..a4d4a8bacd 100644 --- a/back/models/notificationSubscription.js +++ b/back/models/notificationSubscription.js @@ -1,62 +1,40 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { + require('../methods/notification/getList')(Self); + Self.observe('before save', async function(ctx) { + await checkModifyPermission(ctx); + }); + + Self.observe('before delete', async function(ctx) { + await checkModifyPermission(ctx); + }); + + async function checkModifyPermission(ctx) { const models = Self.app.models; + const instance = ctx.instance; const userId = ctx.options.accessToken.userId; - const user = await ctx.instance.userFk; - const modifiedUser = await getUserToModify(null, user, models); - if (userId != modifiedUser.id && userId != modifiedUser.bossFk) - throw new UserError('You dont have permission to modify this user'); - }); + let notificationFk; + let workerId; - Self.remoteMethod('deleteNotification', { - description: 'Deletes a notification subscription', - accepts: [ - { - arg: 'ctx', - type: 'object', - http: {source: 'context'} - }, - { - arg: 'notificationId', - type: 'number', - required: true - }, - ], - returns: { - type: 'object', - root: true - }, - http: { - verb: 'POST', - path: '/deleteNotification' + if (instance) { + notificationFk = instance.notificationFk; + workerId = instance.userFk; + } else { + const notificationSubscription = await models.NotificationSubscription.findById(ctx.where.id); + notificationFk = notificationSubscription.notificationFk; + workerId = notificationSubscription.userFk; } - }); - Self.deleteNotification = async function(ctx, notificationId) { - const models = Self.app.models; - const user = ctx.req.accessToken.userId; - const modifiedUser = await getUserToModify(notificationId, null, models); - - if (user != modifiedUser.id && user != modifiedUser.bossFk) - throw new UserError('You dont have permission to modify this user'); - - await models.NotificationSubscription.destroyById(notificationId); - }; - - async function getUserToModify(notificationId, userFk, models) { - let userToModify = userFk; - if (notificationId) { - const subscription = await models.NotificationSubscription.findById(notificationId); - userToModify = subscription.userFk; - } - return await models.Worker.findOne({ - fields: ['id', 'bossFk'], - where: { - id: userToModify - } + const worker = await models.Worker.findById(workerId, {fields: ['id', 'bossFk']}); + const notificationsAvailables = await models.NotificationSubscription.getList(workerId); + const hasAcl = notificationsAvailables.some(function(available) { + return available.notificationFk === notificationFk; }); + + if (!hasAcl || (userId != worker.id && userId != worker.bossFk)) + throw new UserError('The notification subscription of this worker cant be modified'); } }; diff --git a/back/models/specs/notificationSubscription.spec.js b/back/models/specs/notificationSubscription.spec.js index c5ef698fd9..c2adcbc59d 100644 --- a/back/models/specs/notificationSubscription.spec.js +++ b/back/models/specs/notificationSubscription.spec.js @@ -1,69 +1,126 @@ const models = require('vn-loopback/server/server').models; describe('loopback model NotificationSubscription', () => { - it('should fail to delete a notification if the user is not editing itself or a subordinate', async() => { + it('should fail to add a notification subscription if the worker doesnt have ACLs', async() => { const tx = await models.NotificationSubscription.beginTransaction({}); let error; try { - const options = {transaction: tx}; - const user = 9; - const notificationSubscriptionId = 2; - const ctx = {req: {accessToken: {userId: user}}}; - const notification = await models.NotificationSubscription.findById(notificationSubscriptionId); + const options = {transaction: tx, accessToken: {userId: 9}}; + await models.NotificationSubscription.create({notificationFk: 1, userFk: 62}, options); - await models.NotificationSubscription.deleteNotification(ctx, notification.id, options); - - expect(error.message).toContain('You dont have permission to modify this user'); await tx.rollback(); } catch (e) { + await tx.rollback(); error = e; - await tx.rollback(); } + + expect(error.message).toEqual('The notification subscription of this worker cant be modified'); }); - it('should delete a notification if the user is editing itself', async() => { + it('should fail to add a notification subscription if the user isnt editing itself or subordinate', async() => { const tx = await models.NotificationSubscription.beginTransaction({}); + let error; try { - const options = {transaction: tx}; - const user = 9; + const options = {transaction: tx, accessToken: {userId: 1}}; + await models.NotificationSubscription.create({notificationFk: 1, userFk: 9}, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toEqual('The notification subscription of this worker cant be modified'); + }); + + it('should fail to delete a notification subscription if the user isnt editing itself or subordinate', async() => { + const tx = await models.NotificationSubscription.beginTransaction({}); + let error; + + try { + const options = {transaction: tx, accessToken: {userId: 9}}; + const notificationSubscriptionId = 2; + await models.NotificationSubscription.destroyAll({id: notificationSubscriptionId}, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toEqual('The notification subscription of this worker cant be modified'); + }); + + it('should add a notification subscription if the user is editing itself', async() => { + const tx = await models.NotificationSubscription.beginTransaction({}); + let error; + + try { + const options = {transaction: tx, accessToken: {userId: 9}}; + await models.NotificationSubscription.create({notificationFk: 2, userFk: 9}, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toBeUndefined(); + }); + + it('should delete a notification subscription if the user is editing itself', async() => { + const tx = await models.NotificationSubscription.beginTransaction({}); + let error; + + try { + const options = {transaction: tx, accessToken: {userId: 9}}; const notificationSubscriptionId = 6; - const ctx = {req: {accessToken: {userId: user}}}; - const notification = await models.NotificationSubscription.findById(notificationSubscriptionId); + await models.NotificationSubscription.destroyAll({id: notificationSubscriptionId}, options); - await models.NotificationSubscription.deleteNotification(ctx, notification.id, options); - - const deletedNotification = await models.NotificationSubscription.findById(notificationSubscriptionId); - - expect(deletedNotification).toBeNull(); await tx.rollback(); } catch (e) { await tx.rollback(); - throw e; + error = e; } + + expect(error).toBeUndefined(); }); - it('should delete a notification if the user is editing a subordinate', async() => { + it('should add a notification subscription if the user is editing a subordinate', async() => { const tx = await models.NotificationSubscription.beginTransaction({}); + let error; try { - const options = {transaction: tx}; - const user = 19; - const notificationSubscriptionId = 4; - const ctx = {req: {accessToken: {userId: user}}}; - const notification = await models.NotificationSubscription.findById(notificationSubscriptionId); + const options = {transaction: tx, accessToken: {userId: 9}}; + await models.NotificationSubscription.create({notificationFk: 1, userFk: 5}, options); - await models.NotificationSubscription.deleteNotification(ctx, notification.id, options); - - const deletedNotification = await models.NotificationSubscription.findById(notificationSubscriptionId); - - expect(deletedNotification).toBeNull(); await tx.rollback(); } catch (e) { await tx.rollback(); - throw e; + error = e; } + + expect(error).toBeUndefined(); + }); + + it('should delete a notification subscription if the user is editing a subordinate', async() => { + const tx = await models.NotificationSubscription.beginTransaction({}); + let error; + + try { + const options = {transaction: tx, accessToken: {userId: 19}}; + const notificationSubscriptionId = 4; + await models.NotificationSubscription.destroyAll({id: notificationSubscriptionId}, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toBeUndefined(); }); }); diff --git a/db/changes/232001/00-notificationSubscription.sql b/db/changes/232001/00-notificationSubscription.sql new file mode 100644 index 0000000000..ef081437dd --- /dev/null +++ b/db/changes/232001/00-notificationSubscription.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('NotificationSubscription', 'getList', 'READ', 'ALLOW', 'ROLE', 'employee'); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 527fa1108a..a9659329f5 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -290,5 +290,6 @@ "isTaxDataChecked": "Datos comprobados", "comercialId": "Id comercial", "comercialName": "Comercial", - "Invalid NIF for VIES": "Invalid NIF for VIES" + "Invalid NIF for VIES": "Invalid NIF for VIES", + "The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada" } From 5171e63188bbd3dbc5f1b3ab1bf5fa354d9572cd Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 9 May 2023 14:20:20 +0200 Subject: [PATCH 005/449] refs #4797 minor fixes --- back/methods/notification/getList.js | 8 ++++---- back/methods/notification/specs/getList.spec.js | 7 ------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/back/methods/notification/getList.js b/back/methods/notification/getList.js index 9f33671843..f8a1631268 100644 --- a/back/methods/notification/getList.js +++ b/back/methods/notification/getList.js @@ -50,7 +50,7 @@ module.exports = Self => { } }, myOptions); - activeNotifications.forEach(subscription => { + for (subscription of activeNotifications) { notifications.push({ id: subscription.id, notificationFk: subscription.notificationFk, @@ -58,9 +58,9 @@ module.exports = Self => { description: subscription.notification().description, active: true }); - }); + } - availableNotifications.forEach(acl => { + for (acl of availableNotifications) { const activeNotif = notifications.find( notif => notif.notificationFk === acl.notificationFk ); @@ -73,7 +73,7 @@ module.exports = Self => { active: false, }); } - }); + } return notifications; }; diff --git a/back/methods/notification/specs/getList.spec.js b/back/methods/notification/specs/getList.spec.js index b220f2215a..7c986eba2d 100644 --- a/back/methods/notification/specs/getList.spec.js +++ b/back/methods/notification/specs/getList.spec.js @@ -28,11 +28,4 @@ describe('NotificationSubscription getList()', () => { expect(result.filter(notification => notification.active == false).length) .toEqual(availableNotifications.length - activeNotifications.length); }); - - it('should return empty from a non existent user', async() => { - const userId = 123456789; - const result = await models.NotificationSubscription.getList(userId); - - expect(result.length).toEqual(0); - }); }); From f9e7963e74c1c2701e89c8ba9e47663f97381b64 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 10 May 2023 14:10:00 +0200 Subject: [PATCH 006/449] refs #4797 minor fixes --- back/methods/notification/getList.js | 48 +++++++++---------------- back/models/notificationSubscription.js | 4 +-- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/back/methods/notification/getList.js b/back/methods/notification/getList.js index f8a1631268..cb0f1a4f97 100644 --- a/back/methods/notification/getList.js +++ b/back/methods/notification/getList.js @@ -21,7 +21,7 @@ module.exports = Self => { }); Self.getList = async(id, options) => { - const notifications = []; + const notifications = new Map(); const models = Self.app.models; const myOptions = {}; @@ -29,11 +29,6 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - const activeNotifications = await models.NotificationSubscription.find({ - include: {relation: 'notification'}, - where: {userFk: id} - }, myOptions); - const roles = await models.RoleMapping.find({ fields: ['roleId'], where: {principalId: id} @@ -43,38 +38,29 @@ module.exports = Self => { include: {relation: 'notification'}, where: { roleFk: { - inq: roles.map(role => { - return role.roleId; - }), + inq: roles.map(role => role.roleId), }, } }, myOptions); - for (subscription of activeNotifications) { - notifications.push({ - id: subscription.id, - notificationFk: subscription.notificationFk, - name: subscription.notification().name, - description: subscription.notification().description, - active: true + for (acl of availableNotifications) { + notifications.set(acl.notificationFk, { + id: null, + notificationFk: acl.notificationFk, + name: acl.notification().name, + description: acl.notification().description, + active: false, }); } - for (acl of availableNotifications) { - const activeNotif = notifications.find( - notif => notif.notificationFk === acl.notificationFk - ); - if (!activeNotif) { - notifications.push({ - id: null, - notificationFk: acl.notificationFk, - name: acl.notification().name, - description: acl.notification().description, - active: false, - }); - } - } + const activeNotifications = await models.NotificationSubscription.find({ + include: {relation: 'notification'}, + where: {userFk: id} + }, myOptions); - return notifications; + for (subscription of activeNotifications) + notifications.get(subscription.notificationFk).active = true; + + return [...notifications.values()]; }; }; diff --git a/back/models/notificationSubscription.js b/back/models/notificationSubscription.js index a4d4a8bacd..f750a0528a 100644 --- a/back/models/notificationSubscription.js +++ b/back/models/notificationSubscription.js @@ -30,9 +30,7 @@ module.exports = Self => { const worker = await models.Worker.findById(workerId, {fields: ['id', 'bossFk']}); const notificationsAvailables = await models.NotificationSubscription.getList(workerId); - const hasAcl = notificationsAvailables.some(function(available) { - return available.notificationFk === notificationFk; - }); + const hasAcl = notificationsAvailables.some(available => available.notificationFk === notificationFk); if (!hasAcl || (userId != worker.id && userId != worker.bossFk)) throw new UserError('The notification subscription of this worker cant be modified'); From 9cb756544e69ec3561d153604145067d5e01d752 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 10 May 2023 14:13:38 +0200 Subject: [PATCH 007/449] refs #4797 added id to notification in activeNotifications --- back/methods/notification/getList.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/back/methods/notification/getList.js b/back/methods/notification/getList.js index cb0f1a4f97..fe5aa23a50 100644 --- a/back/methods/notification/getList.js +++ b/back/methods/notification/getList.js @@ -58,8 +58,13 @@ module.exports = Self => { where: {userFk: id} }, myOptions); - for (subscription of activeNotifications) - notifications.get(subscription.notificationFk).active = true; + for (subscription of activeNotifications) { + const notification = notifications.get(subscription.notificationFk); + if (notification) { + notification.active = true; + notification.id = subscription.id; + } + } return [...notifications.values()]; }; From 33ef9bdf61ea9f42a3ef5053ab81a5fe5a95be61 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 11 May 2023 07:18:58 +0200 Subject: [PATCH 008/449] refs #4797 refactor --- back/methods/notification/getList.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/back/methods/notification/getList.js b/back/methods/notification/getList.js index fe5aa23a50..35a0498c00 100644 --- a/back/methods/notification/getList.js +++ b/back/methods/notification/getList.js @@ -43,6 +43,11 @@ module.exports = Self => { } }, myOptions); + const activeNotifications = await models.NotificationSubscription.find({ + include: {relation: 'notification'}, + where: {userFk: id} + }, myOptions); + for (acl of availableNotifications) { notifications.set(acl.notificationFk, { id: null, @@ -53,17 +58,14 @@ module.exports = Self => { }); } - const activeNotifications = await models.NotificationSubscription.find({ - include: {relation: 'notification'}, - where: {userFk: id} - }, myOptions); - for (subscription of activeNotifications) { - const notification = notifications.get(subscription.notificationFk); - if (notification) { - notification.active = true; - notification.id = subscription.id; - } + notifications.set(subscription.notificationFk, { + id: subscription.id, + notificationFk: subscription.notificationFk, + name: subscription.notification().name, + description: subscription.notification().description, + active: true, + }); } return [...notifications.values()]; From 2c254cbc089ab55d2d0c2f3a91edc5704dd7487b Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 15 May 2023 14:34:32 +0200 Subject: [PATCH 009/449] refs #4797 added fields --- back/methods/notification/getList.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/back/methods/notification/getList.js b/back/methods/notification/getList.js index 35a0498c00..780b8eb746 100644 --- a/back/methods/notification/getList.js +++ b/back/methods/notification/getList.js @@ -35,6 +35,7 @@ module.exports = Self => { }, myOptions); const availableNotifications = await models.NotificationAcl.find({ + fields: ['notificationFk', 'roleFk'], include: {relation: 'notification'}, where: { roleFk: { @@ -44,6 +45,7 @@ module.exports = Self => { }, myOptions); const activeNotifications = await models.NotificationSubscription.find({ + fields: ['id', 'notificationFk'], include: {relation: 'notification'}, where: {userFk: id} }, myOptions); From 8db7a5b16a812c4b74adfb77782bcbb8e42b5c7d Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 18 May 2023 14:53:09 +0200 Subject: [PATCH 010/449] refs #4797 moved sql --- db/changes/232201/.gitkeep | 0 db/changes/{232001 => 232201}/00-notificationSubscription.sql | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 db/changes/232201/.gitkeep rename db/changes/{232001 => 232201}/00-notificationSubscription.sql (100%) diff --git a/db/changes/232201/.gitkeep b/db/changes/232201/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/db/changes/232001/00-notificationSubscription.sql b/db/changes/232201/00-notificationSubscription.sql similarity index 100% rename from db/changes/232001/00-notificationSubscription.sql rename to db/changes/232201/00-notificationSubscription.sql From 6e4d7e8b01682e3327c82213d4b44a0cb12b30ec Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 6 Jun 2023 10:31:08 +0200 Subject: [PATCH 011/449] refs #5749 added id --- db/changes/232401/00-zoneIncluded.sql | 27 +++++++++++++++++++ .../back/methods/zone/toggleIsIncluded.js | 15 +++++++---- modules/zone/back/models/zone-included.json | 4 +-- 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 db/changes/232401/00-zoneIncluded.sql diff --git a/db/changes/232401/00-zoneIncluded.sql b/db/changes/232401/00-zoneIncluded.sql new file mode 100644 index 0000000000..592350629c --- /dev/null +++ b/db/changes/232401/00-zoneIncluded.sql @@ -0,0 +1,27 @@ +ALTER TABLE `vn`.`zoneIncluded` + ADD COLUMN `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT FIRST, + DROP PRIMARY KEY, + DROP FOREIGN KEY `zoneFk2`, + DROP FOREIGN KEY `zoneGeoFk2`, + DROP KEY `geoFk_idx`, + ADD PRIMARY KEY (`id`), + ADD CONSTRAINT `zoneIncluded_FK_1` FOREIGN KEY (zoneFk) REFERENCES `vn`.`zone`(id) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `zoneIncluded_FK_2` FOREIGN KEY (geoFk) REFERENCES `vn`.`zoneGeo`(id) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `unique_zone_geo` UNIQUE (`zoneFk`, `geoFk`); + +DROP TRIGGER IF EXISTS `vn`.`zoneIncluded_afterDelete`; +USE `vn`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` TRIGGER `vn`.`zoneIncluded_afterDelete` + AFTER DELETE ON `zoneIncluded` + FOR EACH ROW +BEGIN + INSERT INTO zoneLog + SET `action` = 'delete', + `changedModel` = 'ZoneIncluded', + `changedModelId` = OLD.id, + `userFk` = account.myUser_getId(); +END$$ +DELIMITER ; diff --git a/modules/zone/back/methods/zone/toggleIsIncluded.js b/modules/zone/back/methods/zone/toggleIsIncluded.js index bf8c86f464..06532e5c05 100644 --- a/modules/zone/back/methods/zone/toggleIsIncluded.js +++ b/modules/zone/back/methods/zone/toggleIsIncluded.js @@ -37,11 +37,16 @@ module.exports = Self => { if (isIncluded === undefined) return models.ZoneIncluded.destroyAll({zoneFk: id, geoFk: geoId}, myOptions); else { - return models.ZoneIncluded.upsert({ - zoneFk: id, - geoFk: geoId, - isIncluded: isIncluded - }, myOptions); + const zoneIncluded = await models.ZoneIncluded.findOne({where: {zoneFk: id, geoFk: geoId}}, myOptions); + if (zoneIncluded) + return zoneIncluded.updateAttribute('isIncluded', isIncluded, myOptions); + else { + return models.ZoneIncluded.create({ + zoneFk: id, + geoFk: geoId, + isIncluded: isIncluded + }, myOptions); + } } }; }; diff --git a/modules/zone/back/models/zone-included.json b/modules/zone/back/models/zone-included.json index 61633a3c71..deba73f34e 100644 --- a/modules/zone/back/models/zone-included.json +++ b/modules/zone/back/models/zone-included.json @@ -7,8 +7,8 @@ } }, "properties": { - "zoneFk": { - "id": true, + "id": { + "id": true, "type": "number" }, "isIncluded": { From 639d5963a3517463d0364ec73276583b42cb00b5 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Mon, 17 Jul 2023 13:50:07 +0200 Subject: [PATCH 012/449] refs #6028 get_routes --- db/changes/233001/00-getRoutesByWorker.sql | 24 ++++++++++ db/export-data.sh | 1 + .../client/specs/getRoutesByWorker.spec.js | 19 ++++++++ .../back/methods/route/getDeliveryPoint.js | 2 +- .../back/methods/route/getRoutesByWorker.js | 48 +++++++++++++++++++ .../route/back/methods/route/guessPriority.js | 4 +- .../route/back/methods/route/insertTicket.js | 2 +- modules/route/back/models/route.js | 1 + modules/route/front/tickets/index.js | 2 +- 9 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 db/changes/233001/00-getRoutesByWorker.sql create mode 100644 modules/client/back/methods/client/specs/getRoutesByWorker.spec.js create mode 100644 modules/route/back/methods/route/getRoutesByWorker.js diff --git a/db/changes/233001/00-getRoutesByWorker.sql b/db/changes/233001/00-getRoutesByWorker.sql new file mode 100644 index 0000000000..aa612d48e0 --- /dev/null +++ b/db/changes/233001/00-getRoutesByWorker.sql @@ -0,0 +1,24 @@ +DELETE FROM `salix`.`ACL` + WHERE + model = 'Route' + AND property = '*' + AND accessType = 'READ'; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Route', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'getRoutesByWorker', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'canViewAllRoute', 'READ', 'ALLOW', 'ROLE', 'deliveryBoss'), + ('Route', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'getSuggestedTickets', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'getTickets', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'guessPriority', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'insertTicket', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'getDeliveryPoint', 'READ', 'ALLOW', 'ROLE', 'deliveryBoss'), + ('Route', 'summary', 'READ', 'ALLOW', 'ROLE', 'employee'); + + +INSERT INTO salix.AccessToken (id, ttl, scopes, created, userId, outdated) VALUES('1z0GILWTs8huKrJGp7Fj0PvHaGA8Gg9DTNhm6nn6AfhkNJygeVUHMZKOGfMPp0xO', 1209600, NULL, '2023-07-17 13:34:10', 56, '2023-07-31 13:34:10'); +INSERT INTO salix.AccessToken (id, ttl, scopes, created, userId, outdated) VALUES('1z0GILWTs8huKrJGp7Fj0PvHaGA8Gg9DTNhm6nn6AfhkNJygeVUHMZKOGfMPp0xP', 1209600, NULL, '2023-07-17 13:34:10', 57, '2023-07-31 13:34:10'); diff --git a/db/export-data.sh b/db/export-data.sh index 1df4db0307..914564093c 100755 --- a/db/export-data.sh +++ b/db/export-data.sh @@ -69,6 +69,7 @@ TABLES=( volumeConfig workCenter companyI18n + silexACL ) dump_tables ${TABLES[@]} diff --git a/modules/client/back/methods/client/specs/getRoutesByWorker.spec.js b/modules/client/back/methods/client/specs/getRoutesByWorker.spec.js new file mode 100644 index 0000000000..b43fe49d2b --- /dev/null +++ b/modules/client/back/methods/client/specs/getRoutesByWorker.spec.js @@ -0,0 +1,19 @@ +const {models} = require('vn-loopback/server/server'); + +describe('getRoutesByWorker', () => { + fit('should return the routes of the worker can view all routes', async() => { + const deliveryBossId = 57; + const ctx = {req: {accessToken: {userId: deliveryBossId}}}; + const result = await models.Route.getRoutesByWorker(ctx); + + expect(result.length).toEqual(7); + }); + + fit('should return the routes of the worker can not view all routes', async() => { + const deliveryId = 56; + const ctx = {req: {accessToken: {userId: deliveryId}}}; + const result = await models.Route.getRoutesByWorker(ctx); + + expect(result.length).toEqual(5); + }); +}); diff --git a/modules/route/back/methods/route/getDeliveryPoint.js b/modules/route/back/methods/route/getDeliveryPoint.js index e5a50805ad..3359f666eb 100644 --- a/modules/route/back/methods/route/getDeliveryPoint.js +++ b/modules/route/back/methods/route/getDeliveryPoint.js @@ -1,7 +1,7 @@ module.exports = Self => { Self.remoteMethod('getDeliveryPoint', { description: 'get the deliveryPoint address', - accessType: 'WRITE', + accessType: 'READ', accepts: { arg: 'vehicleId', type: 'number', diff --git a/modules/route/back/methods/route/getRoutesByWorker.js b/modules/route/back/methods/route/getRoutesByWorker.js new file mode 100644 index 0000000000..0a6f598166 --- /dev/null +++ b/modules/route/back/methods/route/getRoutesByWorker.js @@ -0,0 +1,48 @@ +module.exports = Self => { + Self.remoteMethodCtx('getRoutesByWorker', { + description: 'Return the routes by worker', + accessType: 'READ', + returns: { + type: 'object', + root: true + }, + http: { + path: `/get-routes-by-worker`, + verb: 'GET' + } + }); + + Self.getRoutesByWorker = async(ctx, options) => { + const userId = ctx.req.accessToken.userId; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const canViewAll = await Self.app.models.ACL.checkAccessAcl(ctx, 'Route', 'canViewAllRoute', 'READ'); + const condition = canViewAll ? `ay.warehouseFK = uc.warehouseFk` : `r.workerFk = ${userId}`; + + return Self.rawSql(` + SELECT concat(w.firstName , ' ', w.lastName) driver, + r.id, + Date_format(r.time, '%H:%i') hour, + r.created, + r.m3, + v.numberPlate, + a.name, + r.kmStart, + r.kmEnd, + r.started, + r.finished + FROM vn.route r + JOIN vn.vehicle v ON r.vehicleFk = v.id + JOIN vn.agencyMode a ON r.agencyModeFk = a.id + JOIN vn.agency ay ON a.agencyFk = ay.id + JOIN vn.worker w ON r.workerFk = w.id + LEFT JOIN vn.userConfig uc ON uc.userFk = ? + WHERE (r.created = util.VN_CURDATE() OR r.created = TIMESTAMPADD(day, 1, util.VN_CURDATE())) + AND ${condition} + ORDER BY r.created ASC, r.time ASC, a.name ASC + `, [userId], myOptions); + }; +}; diff --git a/modules/route/back/methods/route/guessPriority.js b/modules/route/back/methods/route/guessPriority.js index c6b2a9b744..749075388d 100644 --- a/modules/route/back/methods/route/guessPriority.js +++ b/modules/route/back/methods/route/guessPriority.js @@ -1,7 +1,7 @@ module.exports = Self => { Self.remoteMethodCtx('guessPriority', { description: 'Changes automatically the priority of the tickets in a route', - accessType: 'READ', + accessType: 'WRITE', accepts: [{ arg: 'id', type: 'number', @@ -15,7 +15,7 @@ module.exports = Self => { }, http: { path: `/:id/guessPriority`, - verb: 'GET' + verb: 'PATCH' } }); diff --git a/modules/route/back/methods/route/insertTicket.js b/modules/route/back/methods/route/insertTicket.js index f78e1cb831..4ac8bad1a3 100644 --- a/modules/route/back/methods/route/insertTicket.js +++ b/modules/route/back/methods/route/insertTicket.js @@ -3,7 +3,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethod('insertTicket', { description: 'Check if the ticket can be insert into the route and insert it', - accessType: 'READ', + accessType: 'WRITE', accepts: [{ arg: 'routeId', type: 'number', diff --git a/modules/route/back/models/route.js b/modules/route/back/models/route.js index 883f4597e4..fe88f2e08e 100644 --- a/modules/route/back/models/route.js +++ b/modules/route/back/models/route.js @@ -14,6 +14,7 @@ module.exports = Self => { require('../methods/route/driverRouteEmail')(Self); require('../methods/route/sendSms')(Self); require('../methods/route/downloadZip')(Self); + require('../methods/route/getRoutesByWorker')(Self); Self.validate('kmStart', validateDistance, { message: 'Distance must be lesser than 1000' diff --git a/modules/route/front/tickets/index.js b/modules/route/front/tickets/index.js index 8789708ac2..a1b97005ee 100644 --- a/modules/route/front/tickets/index.js +++ b/modules/route/front/tickets/index.js @@ -120,7 +120,7 @@ class Controller extends Section { guessPriority() { let query = `Routes/${this.$params.id}/guessPriority/`; - this.$http.get(query).then(() => { + this.$http.patch(query).then(() => { this.vnApp.showSuccess(this.$t('Order changed')); this.$.model.refresh(); }); From 8267daef3a80304060afe759f91276ac05c20ae3 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 21 Jul 2023 12:58:44 +0200 Subject: [PATCH 013/449] refs #5918 fix: permite reenviar el correo si ha dado fallo --- modules/worker/front/time-control/index.html | 2 ++ modules/worker/front/time-control/index.js | 31 ++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/modules/worker/front/time-control/index.html b/modules/worker/front/time-control/index.html index 760b0dafcb..b6161db2d2 100644 --- a/modules/worker/front/time-control/index.html +++ b/modules/worker/front/time-control/index.html @@ -97,6 +97,8 @@ ng-if="$ctrl.reason && ($ctrl.isHimSelf || $ctrl.isHr)" ng-click="reason.show()"> + + { + if (!res.data.length) { + this.canResend = false; + return; + } + + const filter = { + where: { + workerFk: this.$params.id + }, + include: { + relation: 'department' + } + }; + this.$http.get('WorkerDepartments', {filter}) + .then(res => { + const department = res.data[0].department; + if (department.isTeleworking) this.canResend = true; + }); + }); + } + /** * Worker hours data */ From 50155cea8d5e3669b5293764f7666f0223a35c9c Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 28 Jul 2023 15:21:43 +0200 Subject: [PATCH 014/449] refs #5914 WIP transfer invoiceOut --- .../233201/00-transferInvoiceOutACL.sql | 6 + db/dump/fixtures.sql | 13 ++ loopback/locale/es.json | 3 +- .../methods/invoiceOut/transferInvoiceOut.js | 81 +++++++++++ modules/invoiceOut/back/model-config.json | 12 ++ .../back/models/cplus-correcting-type.json | 19 +++ .../back/models/cplus-rectification-type.json | 19 +++ .../back/models/invoice-correction-type.json | 19 +++ modules/invoiceOut/back/models/invoice-out.js | 1 + .../back/models/invoiceCorrection.json | 28 ++++ .../front/descriptor-menu/index.html | 89 ++++++++++++ .../invoiceOut/front/descriptor-menu/index.js | 13 ++ .../front/descriptor-menu/locale/en.yml | 2 + .../front/descriptor-menu/locale/es.yml | 2 + modules/ticket/back/methods/sale/clone.js | 76 ++++++++++ .../back/methods/sale/createTicketRefund.js | 25 ++++ modules/ticket/back/methods/sale/refund.js | 137 +++++++++++++++++- 17 files changed, 543 insertions(+), 2 deletions(-) create mode 100644 db/changes/233201/00-transferInvoiceOutACL.sql create mode 100644 modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js create mode 100644 modules/invoiceOut/back/models/cplus-correcting-type.json create mode 100644 modules/invoiceOut/back/models/cplus-rectification-type.json create mode 100644 modules/invoiceOut/back/models/invoice-correction-type.json create mode 100644 modules/invoiceOut/back/models/invoiceCorrection.json create mode 100644 modules/ticket/back/methods/sale/clone.js create mode 100644 modules/ticket/back/methods/sale/createTicketRefund.js diff --git a/db/changes/233201/00-transferInvoiceOutACL.sql b/db/changes/233201/00-transferInvoiceOutACL.sql new file mode 100644 index 0000000000..b549e52a84 --- /dev/null +++ b/db/changes/233201/00-transferInvoiceOutACL.sql @@ -0,0 +1,6 @@ +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('CplusRectificationType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('CplusCorrectingType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('InvoiceCorrectionType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('InvoiceOut', 'transferInvoiceOut', 'WRITE', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index eaa00a3de0..0a17e2e420 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2958,3 +2958,16 @@ INSERT INTO `vn`.`invoiceInSerial` (`code`, `description`, `cplusTerIdNifFk`, `t INSERT INTO `hedera`.`imageConfig` (`id`, `maxSize`, `useXsendfile`, `url`) VALUES (1, 0, 0, 'marvel.com'); + +INSERT INTO `vn`.`cplusCorrectingType` (`description`) + VALUES + ('Embalajes'), + ('Anulación'), + ('Impagado'), + ('Moroso'); + +INSERT INTO `vn`.`invoiceCorrectionType` (`description`) + VALUES + ('Error en el cálculo del IVA'), + ('Error en el detalle de las ventas'), + ('Error en los datos del cliente'); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index ac62d62e13..3439adcde0 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -311,5 +311,6 @@ "You don't have enough privileges.": "No tienes suficientes permisos.", "This ticket is locked.": "Este ticket está bloqueado.", "This ticket is not editable.": "Este ticket no es editable.", - "The ticket doesn't exist.": "No existe el ticket." + "The ticket doesn't exist.": "No existe el ticket.", + "There are missing fields.": "There are missing fields." } \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js new file mode 100644 index 0000000000..b50e4b1a79 --- /dev/null +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js @@ -0,0 +1,81 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('transferInvoiceOut', { + description: 'Transfer an invoice out to another client', + accessType: 'WRITE', + accepts: [ + { + arg: 'data', + type: 'Object', + required: true + } + ], + returns: { + type: 'boolean', + root: true + }, + http: { + path: '/transferInvoice', + verb: 'post' + } + }); + + Self.transferInvoiceOut = async(ctx, params, options) => { + const models = Self.app.models; + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + try { + const {ref, newClientFk, cplusRectificationId, cplusCorrectingTypeId, invoiceCorrectionTypeId} = params; + if (!ref || !newClientFk || !cplusRectificationId || !cplusCorrectingTypeId || !invoiceCorrectionTypeId) + throw new UserError(`There are missing fields.`); + + const filter = {where: {refFk: ref}}; + const tickets = await models.Ticket.find(filter, myOptions); + const ticketsIds = tickets.map(ticket => ticket.id); + const refundTicket = await models.Ticket.refund(ctx, ticketsIds, null, myOptions); + // Clonar tickets + const refundAgencyMode = await models.AgencyMode.findOne({ + include: { + relation: 'zones', + scope: { + limit: 1, + field: ['id', 'name'] + } + }, + where: {code: 'refund'} + }, myOptions); + const refoundZoneId = refundAgencyMode.zones()[0].id; + const services = await models.TicketService.find(filter, myOptions); + const servicesIds = services.map(service => service.id); + const salesFilter = { + where: {id: {inq: salesIds}}, + include: { + relation: 'components', + scope: { + fields: ['saleFk', 'componentFk', 'value'] + } + } + }; + const sales = await models.Sale.find(salesFilter, myOptions); + // Actualizar cliente + + // Invoice Ticket - Factura rápida ?? + + // Insert InvoiceCorrection + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + return true; + }; +}; diff --git a/modules/invoiceOut/back/model-config.json b/modules/invoiceOut/back/model-config.json index 9e8b119ab3..995ea976ba 100644 --- a/modules/invoiceOut/back/model-config.json +++ b/modules/invoiceOut/back/model-config.json @@ -31,5 +31,17 @@ }, "ZipConfig": { "dataSource": "vn" + }, + "CplusRectificationType": { + "dataSource": "vn" + }, + "CplusCorrectingType": { + "dataSource": "vn" + }, + "InvoiceCorrectionType": { + "dataSource": "vn" + }, + "InvoiceCorrection": { + "dataSource": "vn" } } diff --git a/modules/invoiceOut/back/models/cplus-correcting-type.json b/modules/invoiceOut/back/models/cplus-correcting-type.json new file mode 100644 index 0000000000..660f600082 --- /dev/null +++ b/modules/invoiceOut/back/models/cplus-correcting-type.json @@ -0,0 +1,19 @@ +{ + "name": "CplusCorrectingType", + "base": "VnModel", + "options": { + "mysql": { + "table": "cplusCorrectingType" + } + }, + "properties": { + "id": { + "id": true, + "type": "number", + "description": "Identifier" + }, + "description": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/modules/invoiceOut/back/models/cplus-rectification-type.json b/modules/invoiceOut/back/models/cplus-rectification-type.json new file mode 100644 index 0000000000..e7bfb957f7 --- /dev/null +++ b/modules/invoiceOut/back/models/cplus-rectification-type.json @@ -0,0 +1,19 @@ +{ + "name": "CplusRectificationType", + "base": "VnModel", + "options": { + "mysql": { + "table": "cplusRectificationType" + } + }, + "properties": { + "id": { + "id": true, + "type": "number", + "description": "Identifier" + }, + "description": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/modules/invoiceOut/back/models/invoice-correction-type.json b/modules/invoiceOut/back/models/invoice-correction-type.json new file mode 100644 index 0000000000..ad3f034eaa --- /dev/null +++ b/modules/invoiceOut/back/models/invoice-correction-type.json @@ -0,0 +1,19 @@ +{ + "name": "InvoiceCorrectionType", + "base": "VnModel", + "options": { + "mysql": { + "table": "invoiceCorrectionType" + } + }, + "properties": { + "id": { + "id": true, + "type": "number", + "description": "Identifier" + }, + "description": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js index d3aaf3b3dd..0bb31ce12b 100644 --- a/modules/invoiceOut/back/models/invoice-out.js +++ b/modules/invoiceOut/back/models/invoice-out.js @@ -23,6 +23,7 @@ module.exports = Self => { require('../methods/invoiceOut/getInvoiceDate')(Self); require('../methods/invoiceOut/negativeBases')(Self); require('../methods/invoiceOut/negativeBasesCsv')(Self); + require('../methods/invoiceOut/transferInvoiceOut')(Self); Self.filePath = async function(id, options) { const fields = ['ref', 'issued']; diff --git a/modules/invoiceOut/back/models/invoiceCorrection.json b/modules/invoiceOut/back/models/invoiceCorrection.json new file mode 100644 index 0000000000..48bd172a6d --- /dev/null +++ b/modules/invoiceOut/back/models/invoiceCorrection.json @@ -0,0 +1,28 @@ +{ + "name": "InvoiceCorrection", + "base": "VnModel", + "options": { + "mysql": { + "table": "invoiceCorrection" + } + }, + "properties": { + "correctingFk": { + "id": true, + "type": "number", + "description": "Identifier" + }, + "correctedFk": { + "type": "number" + }, + "cplusRectificationTypeFk": { + "type": "number" + }, + "cplusInvoiceType477Fk": { + "type": "number" + }, + "invoiceCorrectionTypeFk": { + "type": "number" + } + } +} \ No newline at end of file diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index 106f8e3cc1..d6eaa1cc76 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -1,3 +1,19 @@ + + + + + + + + Transfer invoice to... + Confirm + + + + + + + #{{id}} - {{::name}} + + + + + {{::description}} + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index 38c3c94348..0b43b73a74 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -125,6 +125,19 @@ class Controller extends Section { this.$state.go('ticket.card.sale', {id: refundTicket.id}); }); } + + transferInvoice() { + const params = { + data: { + ref: this.invoiceOut.ref, + newClientFk: this.invoiceOut.client.id, + cplusRectificationId: this.cplusRectificationType, + cplusCorrectingTypeId: this.cplusCorrectingType, + invoiceCorrectionTypeId: this.invoiceCorrectionType + } + }; + this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => console.log(res.data)); + } } Controller.$inject = ['$element', '$scope', 'vnReport', 'vnEmail']; diff --git a/modules/invoiceOut/front/descriptor-menu/locale/en.yml b/modules/invoiceOut/front/descriptor-menu/locale/en.yml index d299155d79..8fad5f25e7 100644 --- a/modules/invoiceOut/front/descriptor-menu/locale/en.yml +++ b/modules/invoiceOut/front/descriptor-menu/locale/en.yml @@ -1 +1,3 @@ The following refund tickets have been created: "The following refund tickets have been created: {{ticketIds}}" +Transfer invoice to...: Transfer invoice to... +Cplus Type: Cplus Type \ No newline at end of file diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml index 393efd58c2..0f74b5fece 100644 --- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml +++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml @@ -21,3 +21,5 @@ The invoice PDF document has been regenerated: El documento PDF de la factura ha The email can't be empty: El correo no puede estar vacío The following refund tickets have been created: "Se han creado los siguientes tickets de abono: {{ticketIds}}" Refund...: Abono... +Transfer invoice to...: Transferir factura a... +Cplus Type: Cplus Tipo diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js new file mode 100644 index 0000000000..1d69ca1586 --- /dev/null +++ b/modules/ticket/back/methods/sale/clone.js @@ -0,0 +1,76 @@ +module.exports = async function clone(ctx, Self, sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, group, isRefund, myOptions) { + const models = Self.app.models; + const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; + const [firstTicketId] = ticketsIds; + + const now = Date.vnNew(); + let refundTickets = []; + let refundTicket; + + if (!group) { + for (const ticketId of ticketsIds) { + refundTicket = await createTicketRefund( + ticketId, + now, + refundAgencyMode, + refoundZoneId, + null, + myOptions + ); + refundTickets.push(refundTicket); + } + } else { + refundTicket = await createTicketRefund( + firstTicketId, + now, + refundAgencyMode, + refoundZoneId, + withWarehouse, + myOptions + ); + } + + for (const sale of sales) { + const createdSale = await models.Sale.create({ + ticketFk: (group) ? refundTicket.id : sale.ticketFk, + itemFk: sale.itemFk, + quantity: (isRefund) ? - sale.quantity : sale.quantity, + concept: sale.concept, + price: sale.price, + discount: sale.discount, + }, myOptions); + + const components = sale.components(); + for (const component of components) + component.saleFk = createdSale.id; + + await models.SaleComponent.create(components, myOptions); + } + + if (servicesIds && servicesIds.length > 0) { + const servicesFilter = { + where: {id: {inq: servicesIds}} + }; + const services = await models.TicketService.find(servicesFilter, myOptions); + for (const service of services) { + await models.TicketService.create({ + description: service.description, + quantity: (isRefund) ? - service.quantity : service.quantity, + price: service.price, + taxClassFk: service.taxClassFk, + ticketFk: (group) ? refundTicket.id : service.ticketFk, + ticketServiceTypeFk: service.ticketServiceTypeFk, + }, myOptions); + } + } + + const query = `CALL vn.ticket_recalc(?, NULL)`; + if (refundTickets.length > 0) { + for (const refundTicket of refundTickets) + await Self.rawSql(query, [refundTicket.id], myOptions); + return refundTickets.map(refundTicket => refundTicket.id); + } else { + await Self.rawSql(query, [refundTicket.id], myOptions); + return refundTicket; + } +}; diff --git a/modules/ticket/back/methods/sale/createTicketRefund.js b/modules/ticket/back/methods/sale/createTicketRefund.js new file mode 100644 index 0000000000..0ecc62e0c6 --- /dev/null +++ b/modules/ticket/back/methods/sale/createTicketRefund.js @@ -0,0 +1,25 @@ +module.exports = async function createTicketRefund(models, ticketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions) { + // const models = Self.app.models; + + const filter = {include: {relation: 'address'}}; + const ticket = await models.Ticket.findById(ticketId, filter, myOptions); + + const refundTicket = await models.Ticket.create({ + clientFk: ticket.clientFk, + shipped: now, + addressFk: ticket.address().id, + agencyModeFk: refundAgencyMode.id, + nickname: ticket.address().nickname, + warehouseFk: withWarehouse ? ticket.warehouseFk : null, + companyFk: ticket.companyFk, + landed: now, + zoneFk: refoundZoneId + }, myOptions); + + await models.TicketRefund.create({ + refundTicketFk: refundTicket.id, + originalTicketFk: ticket.id, + }, myOptions); + + return refundTicket; +}; diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index a8191610ac..fc6d8bbc2b 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -28,7 +28,7 @@ module.exports = Self => { } }); - Self.refund = async(ctx, salesIds, servicesIds, withWarehouse, options) => { + /* Self.refund = async(ctx, salesIds, servicesIds, withWarehouse, options) => { const models = Self.app.models; const myOptions = {userId: ctx.req.accessToken.userId}; let tx; @@ -111,6 +111,64 @@ module.exports = Self => { if (tx) await tx.commit(); + return refundTicket; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; */ + + Self.refund = async(ctx, salesIds, servicesIds, withWarehouse, options) => { + const models = Self.app.models; + const myOptions = {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; + } + + try { + const refundAgencyMode = await models.AgencyMode.findOne({ + include: { + relation: 'zones', + scope: { + limit: 1, + field: ['id', 'name'] + } + }, + where: {code: 'refund'} + }, myOptions); + + const refoundZoneId = refundAgencyMode.zones()[0].id; + + const salesFilter = { + where: {id: {inq: salesIds}}, + include: { + relation: 'components', + scope: { + fields: ['saleFk', 'componentFk', 'value'] + } + } + }; + const sales = await models.Sale.find(salesFilter, myOptions); + const group = true; + const isRefund = true; + + const refundTicket = await clone( + sales, + refundAgencyMode, + refoundZoneId, servicesIds, + withWarehouse, + group, + isRefund, + myOptions + ); + if (tx) await tx.commit(); + return refundTicket; } catch (e) { if (tx) await tx.rollback(); @@ -118,6 +176,83 @@ module.exports = Self => { } }; + async function clone(sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, group, isRefund, myOptions) { + const models = Self.app.models; + const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; + const [firstTicketId] = ticketsIds; + + const now = Date.vnNew(); + let refundTickets = []; + let refundTicket; + + if (!group) { + for (const ticketId of ticketsIds) { + refundTicket = await createTicketRefund( + ticketId, + now, + refundAgencyMode, + refoundZoneId, + null, + myOptions + ); + refundTickets.push(refundTicket); + } + } else { + refundTicket = await createTicketRefund( + firstTicketId, + now, + refundAgencyMode, + refoundZoneId, + withWarehouse, + myOptions + ); + } + + for (const sale of sales) { + const createdSale = await models.Sale.create({ + ticketFk: (group) ? refundTicket.id : sale.ticketFk, + itemFk: sale.itemFk, + quantity: (isRefund) ? - sale.quantity : sale.quantity, + concept: sale.concept, + price: sale.price, + discount: sale.discount, + }, myOptions); + + const components = sale.components(); + for (const component of components) + component.saleFk = createdSale.id; + + await models.SaleComponent.create(components, myOptions); + } + + if (servicesIds && servicesIds.length > 0) { + const servicesFilter = { + where: {id: {inq: servicesIds}} + }; + const services = await models.TicketService.find(servicesFilter, myOptions); + for (const service of services) { + await models.TicketService.create({ + description: service.description, + quantity: (isRefund) ? - service.quantity : service.quantity, + price: service.price, + taxClassFk: service.taxClassFk, + ticketFk: (group) ? refundTicket.id : service.ticketFk, + ticketServiceTypeFk: service.ticketServiceTypeFk, + }, myOptions); + } + } + + const query = `CALL vn.ticket_recalc(?, NULL)`; + if (refundTickets.length > 0) { + for (const refundTicket of refundTickets) + await Self.rawSql(query, [refundTicket.id], myOptions); + return refundTickets.map(refundTicket => refundTicket.id); + } else { + await Self.rawSql(query, [refundTicket.id], myOptions); + return refundTicket; + } + } + async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions) { const models = Self.app.models; From 22f76ec6a943282c8e870e54f17b2cebe79f1d5a Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 31 Jul 2023 10:33:51 +0200 Subject: [PATCH 015/449] refs #5914 WIP clone method created --- .../233201/00-transferInvoiceOutACL.sql | 2 +- .../methods/invoiceOut/transferInvoiceOut.js | 31 ++++- modules/invoiceOut/back/model-config.json | 6 +- ...-type.json => cplus-invoice-type-477.json} | 4 +- .../front/descriptor-menu/index.html | 10 +- .../invoiceOut/front/descriptor-menu/index.js | 3 +- modules/ticket/back/methods/sale/clone.js | 127 ++++++++---------- .../back/methods/sale/createTicketRefund.js | 25 ---- modules/ticket/back/methods/sale/refund.js | 71 +++++----- modules/ticket/back/models/sale.js | 1 + 10 files changed, 129 insertions(+), 151 deletions(-) rename modules/invoiceOut/back/models/{cplus-correcting-type.json => cplus-invoice-type-477.json} (78%) delete mode 100644 modules/ticket/back/methods/sale/createTicketRefund.js diff --git a/db/changes/233201/00-transferInvoiceOutACL.sql b/db/changes/233201/00-transferInvoiceOutACL.sql index b549e52a84..6e8d88c5d9 100644 --- a/db/changes/233201/00-transferInvoiceOutACL.sql +++ b/db/changes/233201/00-transferInvoiceOutACL.sql @@ -1,6 +1,6 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) VALUES ('CplusRectificationType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('CplusCorrectingType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('CplusInvoiceType477', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), ('InvoiceCorrectionType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), ('InvoiceOut', 'transferInvoiceOut', 'WRITE', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js index b50e4b1a79..d53581ac62 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js @@ -34,15 +34,17 @@ module.exports = Self => { myOptions.transaction = tx; } try { - const {ref, newClientFk, cplusRectificationId, cplusCorrectingTypeId, invoiceCorrectionTypeId} = params; - if (!ref || !newClientFk || !cplusRectificationId || !cplusCorrectingTypeId || !invoiceCorrectionTypeId) + const {id, ref, newClientFk, cplusRectificationId, cplusInvoiceType477FkId, invoiceCorrectionTypeId} = params; + if (!id || !ref || !newClientFk || !cplusRectificationId || !cplusInvoiceType477FkId || !invoiceCorrectionTypeId) throw new UserError(`There are missing fields.`); + // Refund tickets and group const filter = {where: {refFk: ref}}; const tickets = await models.Ticket.find(filter, myOptions); const ticketsIds = tickets.map(ticket => ticket.id); - const refundTicket = await models.Ticket.refund(ctx, ticketsIds, null, myOptions); - // Clonar tickets + await models.Ticket.refund(ctx, ticketsIds, null, myOptions); + + // Clone tickets const refundAgencyMode = await models.AgencyMode.findOne({ include: { relation: 'zones', @@ -66,11 +68,28 @@ module.exports = Self => { } }; const sales = await models.Sale.find(salesFilter, myOptions); - // Actualizar cliente + const isRefund = false; + const clonedTicketIds = await models.Sale.clone(sales, refundAgencyMode, refoundZoneId, servicesIds, null, isRefund, myOptions); - // Invoice Ticket - Factura rápida ?? + // Update client + for (const clonedTicketId of clonedTicketIds) { + const ticket = await models.Ticket.findById(clonedTicketId, myOptions); + await ticket.updateAttributes({clientFk: newClientFk}); + } + // Quick invoice + const invoiceIds = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); // Insert InvoiceCorrection + for (const invoiceId of invoiceIds) { + await models.invoiceCorrection.create({ + correctingFk: invoiceId, + correctedFk: id, + cplusRectificationTypeFk: cplusRectificationId, + cplusInvoiceType477Fk: cplusInvoiceType477FkId, + invoiceCorrectionType: invoiceCorrectionTypeId + }); + } + if (tx) await tx.commit(); } catch (e) { if (tx) await tx.rollback(); diff --git a/modules/invoiceOut/back/model-config.json b/modules/invoiceOut/back/model-config.json index 995ea976ba..23246893b4 100644 --- a/modules/invoiceOut/back/model-config.json +++ b/modules/invoiceOut/back/model-config.json @@ -35,13 +35,13 @@ "CplusRectificationType": { "dataSource": "vn" }, - "CplusCorrectingType": { - "dataSource": "vn" - }, "InvoiceCorrectionType": { "dataSource": "vn" }, "InvoiceCorrection": { "dataSource": "vn" + }, + "CplusInvoiceType477": { + "dataSource": "vn" } } diff --git a/modules/invoiceOut/back/models/cplus-correcting-type.json b/modules/invoiceOut/back/models/cplus-invoice-type-477.json similarity index 78% rename from modules/invoiceOut/back/models/cplus-correcting-type.json rename to modules/invoiceOut/back/models/cplus-invoice-type-477.json index 660f600082..840a9a7e4e 100644 --- a/modules/invoiceOut/back/models/cplus-correcting-type.json +++ b/modules/invoiceOut/back/models/cplus-invoice-type-477.json @@ -1,9 +1,9 @@ { - "name": "CplusCorrectingType", + "name": "CplusInvoiceType477", "base": "VnModel", "options": { "mysql": { - "table": "cplusCorrectingType" + "table": "cplusInvoiceType477" } }, "properties": { diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index d6eaa1cc76..1655290f44 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -6,8 +6,8 @@ + url="CplusInvoiceType477s" + data="cplusInvoiceType477"> sale.ticketFk))]; - const [firstTicketId] = ticketsIds; +module.exports = Self => { + Self.clone = async(sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, isRefund, myOptions) => { + const models = Self.app.models; + const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; - const now = Date.vnNew(); - let refundTickets = []; - let refundTicket; + const now = Date.vnNew(); + let updatedTickets = []; - if (!group) { for (const ticketId of ticketsIds) { - refundTicket = await createTicketRefund( - ticketId, - now, - refundAgencyMode, - refoundZoneId, - null, - myOptions - ); - refundTickets.push(refundTicket); - } - } else { - refundTicket = await createTicketRefund( - firstTicketId, - now, - refundAgencyMode, - refoundZoneId, - withWarehouse, - myOptions - ); - } + const filter = {include: {relation: 'address'}}; + const ticket = await models.Ticket.findById(ticketId, filter, myOptions); - for (const sale of sales) { - const createdSale = await models.Sale.create({ - ticketFk: (group) ? refundTicket.id : sale.ticketFk, - itemFk: sale.itemFk, - quantity: (isRefund) ? - sale.quantity : sale.quantity, - concept: sale.concept, - price: sale.price, - discount: sale.discount, - }, myOptions); - - const components = sale.components(); - for (const component of components) - component.saleFk = createdSale.id; - - await models.SaleComponent.create(components, myOptions); - } - - if (servicesIds && servicesIds.length > 0) { - const servicesFilter = { - where: {id: {inq: servicesIds}} - }; - const services = await models.TicketService.find(servicesFilter, myOptions); - for (const service of services) { - await models.TicketService.create({ - description: service.description, - quantity: (isRefund) ? - service.quantity : service.quantity, - price: service.price, - taxClassFk: service.taxClassFk, - ticketFk: (group) ? refundTicket.id : service.ticketFk, - ticketServiceTypeFk: service.ticketServiceTypeFk, + const ticketUpdated = await models.Ticket.create({ + clientFk: ticket.clientFk, + shipped: now, + addressFk: ticket.address().id, + agencyModeFk: refundAgencyMode.id, + nickname: ticket.address().nickname, + warehouseFk: withWarehouse ? ticket.warehouseFk : null, + companyFk: ticket.companyFk, + landed: now, + zoneFk: refoundZoneId }, myOptions); + updatedTickets.push(ticketUpdated); } - } - const query = `CALL vn.ticket_recalc(?, NULL)`; - if (refundTickets.length > 0) { - for (const refundTicket of refundTickets) - await Self.rawSql(query, [refundTicket.id], myOptions); - return refundTickets.map(refundTicket => refundTicket.id); - } else { - await Self.rawSql(query, [refundTicket.id], myOptions); - return refundTicket; - } + for (const sale of sales) { + const createdSale = await models.Sale.create({ + ticketFk: sale.ticketFk, + itemFk: sale.itemFk, + quantity: (isRefund) ? - sale.quantity : sale.quantity, + concept: sale.concept, + price: sale.price, + discount: sale.discount, + }, myOptions); + + const components = sale.components(); + for (const component of components) + component.saleFk = createdSale.id; + + await models.SaleComponent.create(components, myOptions); + } + + if (servicesIds && servicesIds.length > 0) { + const servicesFilter = { + where: {id: {inq: servicesIds}} + }; + const services = await models.TicketService.find(servicesFilter, myOptions); + for (const service of services) { + await models.TicketService.create({ + description: service.description, + quantity: (isRefund) ? - service.quantity : service.quantity, + price: service.price, + taxClassFk: service.taxClassFk, + ticketFk: service.ticketFk, + ticketServiceTypeFk: service.ticketServiceTypeFk, + }, myOptions); + } + } + + const query = `CALL vn.ticket_recalc(?, NULL)`; + + for (const updatedTicket of updatedTickets) + await Self.rawSql(query, [updatedTicket.id], myOptions); + return updatedTickets.map(updatedTicket => updatedTicket.id); + }; }; diff --git a/modules/ticket/back/methods/sale/createTicketRefund.js b/modules/ticket/back/methods/sale/createTicketRefund.js deleted file mode 100644 index 0ecc62e0c6..0000000000 --- a/modules/ticket/back/methods/sale/createTicketRefund.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = async function createTicketRefund(models, ticketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions) { - // const models = Self.app.models; - - const filter = {include: {relation: 'address'}}; - const ticket = await models.Ticket.findById(ticketId, filter, myOptions); - - const refundTicket = await models.Ticket.create({ - clientFk: ticket.clientFk, - shipped: now, - addressFk: ticket.address().id, - agencyModeFk: refundAgencyMode.id, - nickname: ticket.address().nickname, - warehouseFk: withWarehouse ? ticket.warehouseFk : null, - companyFk: ticket.companyFk, - landed: now, - zoneFk: refoundZoneId - }, myOptions); - - await models.TicketRefund.create({ - refundTicketFk: refundTicket.id, - originalTicketFk: ticket.id, - }, myOptions); - - return refundTicket; -}; diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index fc6d8bbc2b..6bb131e4d3 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -158,10 +158,11 @@ module.exports = Self => { const group = true; const isRefund = true; - const refundTicket = await clone( + const refundTicket = await cloneAndGroup( sales, refundAgencyMode, - refoundZoneId, servicesIds, + refoundZoneId, + servicesIds, withWarehouse, group, isRefund, @@ -176,41 +177,37 @@ module.exports = Self => { } }; - async function clone(sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, group, isRefund, myOptions) { - const models = Self.app.models; + async function cloneAndGroup(sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, group, isRefund, myOptions) { + if (!group) { + const tickets = await models.Sale.clone(sales, + refundAgencyMode, + refoundZoneId, servicesIds, + withWarehouse, + isRefund, + myOptions); + return tickets; + } + const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; const [firstTicketId] = ticketsIds; + const filter = {include: {relation: 'address'}}; + const ticket = await models.Ticket.findById(firstTicketId, filter, myOptions); - const now = Date.vnNew(); - let refundTickets = []; - let refundTicket; - - if (!group) { - for (const ticketId of ticketsIds) { - refundTicket = await createTicketRefund( - ticketId, - now, - refundAgencyMode, - refoundZoneId, - null, - myOptions - ); - refundTickets.push(refundTicket); - } - } else { - refundTicket = await createTicketRefund( - firstTicketId, - now, - refundAgencyMode, - refoundZoneId, - withWarehouse, - myOptions - ); - } + const ticketUpdated = await models.Ticket.create({ + clientFk: ticket.clientFk, + shipped: now, + addressFk: ticket.address().id, + agencyModeFk: refundAgencyMode.id, + nickname: ticket.address().nickname, + warehouseFk: withWarehouse ? ticket.warehouseFk : null, + companyFk: ticket.companyFk, + landed: now, + zoneFk: refoundZoneId + }, myOptions); for (const sale of sales) { const createdSale = await models.Sale.create({ - ticketFk: (group) ? refundTicket.id : sale.ticketFk, + ticketFk: ticketUpdated.id, itemFk: sale.itemFk, quantity: (isRefund) ? - sale.quantity : sale.quantity, concept: sale.concept, @@ -236,21 +233,15 @@ module.exports = Self => { quantity: (isRefund) ? - service.quantity : service.quantity, price: service.price, taxClassFk: service.taxClassFk, - ticketFk: (group) ? refundTicket.id : service.ticketFk, + ticketFk: ticketUpdated.id, ticketServiceTypeFk: service.ticketServiceTypeFk, }, myOptions); } } const query = `CALL vn.ticket_recalc(?, NULL)`; - if (refundTickets.length > 0) { - for (const refundTicket of refundTickets) - await Self.rawSql(query, [refundTicket.id], myOptions); - return refundTickets.map(refundTicket => refundTicket.id); - } else { - await Self.rawSql(query, [refundTicket.id], myOptions); - return refundTicket; - } + await Self.rawSql(query, [refundTicket.id], myOptions); + return ticketUpdated; } async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions) { diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index bab201fddb..e65c98feae 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -10,6 +10,7 @@ module.exports = Self => { require('../methods/sale/refund')(Self); require('../methods/sale/canEdit')(Self); require('../methods/sale/usesMana')(Self); + require('../methods/sale/clone')(Self); Self.validatesPresenceOf('concept', { message: `Concept cannot be blank` From 3ef74cab5c00ee70ebc8ad78e15a5b0f40145f59 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 1 Aug 2023 12:45:57 +0200 Subject: [PATCH 016/449] refs #5914 WIP created transferInvoiceOut --- .../methods/invoiceOut/transferInvoiceOut.js | 66 +++++--- .../front/descriptor-menu/index.html | 3 +- .../invoiceOut/front/descriptor-menu/index.js | 14 +- modules/ticket/back/methods/sale/clone.js | 151 +++++++++++------- modules/ticket/back/methods/sale/refund.js | 87 ++-------- .../back/methods/sale/specs/refund.spec.js | 2 +- modules/ticket/back/methods/ticket/refund.js | 1 - modules/ticket/back/models/ticket.json | 5 + 8 files changed, 161 insertions(+), 168 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js index d53581ac62..86de59e9db 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js @@ -6,10 +6,35 @@ module.exports = Self => { accessType: 'WRITE', accepts: [ { - arg: 'data', - type: 'Object', + arg: 'id', + type: 'number', required: true - } + }, + { + arg: 'ref', + type: 'string', + required: true + }, + { + arg: 'newClientFk', + type: 'number', + required: true + }, + { + arg: 'cplusRectificationId', + type: 'number', + required: true + }, + { + arg: 'cplusInvoiceType477Id', + type: 'number', + required: true + }, + { + arg: 'invoiceCorrectionTypeId', + type: 'number', + required: true + }, ], returns: { type: 'boolean', @@ -21,7 +46,7 @@ module.exports = Self => { } }); - Self.transferInvoiceOut = async(ctx, params, options) => { + Self.transferInvoiceOut = async(ctx, id, ref, newClientFk, cplusRectificationId, cplusInvoiceType477Id, invoiceCorrectionTypeId, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -34,16 +59,12 @@ module.exports = Self => { myOptions.transaction = tx; } try { - const {id, ref, newClientFk, cplusRectificationId, cplusInvoiceType477FkId, invoiceCorrectionTypeId} = params; - if (!id || !ref || !newClientFk || !cplusRectificationId || !cplusInvoiceType477FkId || !invoiceCorrectionTypeId) - throw new UserError(`There are missing fields.`); - // Refund tickets and group const filter = {where: {refFk: ref}}; const tickets = await models.Ticket.find(filter, myOptions); const ticketsIds = tickets.map(ticket => ticket.id); await models.Ticket.refund(ctx, ticketsIds, null, myOptions); - + console.log('Ticket refunded'); // Clone tickets const refundAgencyMode = await models.AgencyMode.findOne({ include: { @@ -58,25 +79,20 @@ module.exports = Self => { const refoundZoneId = refundAgencyMode.zones()[0].id; const services = await models.TicketService.find(filter, myOptions); const servicesIds = services.map(service => service.id); - const salesFilter = { - where: {id: {inq: salesIds}}, - include: { - relation: 'components', - scope: { - fields: ['saleFk', 'componentFk', 'value'] - } - } - }; + const salesFilter = {where: {ticketFk: {inq: ticketsIds}}}; const sales = await models.Sale.find(salesFilter, myOptions); - const isRefund = false; - const clonedTicketIds = await models.Sale.clone(sales, refundAgencyMode, refoundZoneId, servicesIds, null, isRefund, myOptions); - + const clonedTickets = await models.Sale.clone(sales, refundAgencyMode, refoundZoneId, servicesIds, null, false, false, myOptions); + console.log('cloned tickets'); // Update client - for (const clonedTicketId of clonedTicketIds) { - const ticket = await models.Ticket.findById(clonedTicketId, myOptions); - await ticket.updateAttributes({clientFk: newClientFk}); + for (const clonedTicket of clonedTickets) { + // const ticket = await models.Ticket.findById(clonedTicketId, myOptions); + console.log(clonedTicket); + await clonedTicket.updateAttributes({clientFk: newClientFk}, myOptions); + console.log(clonedTicket); } // Quick invoice + const clonedTicketIds = clonedTickets.map(clonedTicket => clonedTicket.id); + console.log(clonedTicketIds); const invoiceIds = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); // Insert InvoiceCorrection @@ -85,7 +101,7 @@ module.exports = Self => { correctingFk: invoiceId, correctedFk: id, cplusRectificationTypeFk: cplusRectificationId, - cplusInvoiceType477Fk: cplusInvoiceType477FkId, + cplusInvoiceType477Fk: cplusInvoiceType477Id, invoiceCorrectionType: invoiceCorrectionTypeId }); } diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index 1655290f44..dc5c2a8e92 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -222,12 +222,13 @@ console.log(res.data)); } diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index 96e66de2c4..e1793d0882 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -1,67 +1,104 @@ module.exports = Self => { - Self.clone = async(sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, isRefund, myOptions) => { + Self.clone = async(sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, group, negative, myOptions) => { const models = Self.app.models; - const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; + let tx; + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; + const [firstTicketId] = ticketsIds; const now = Date.vnNew(); let updatedTickets = []; + let newTicket; + const filter = { + include: [ + {relation: 'address'}, + { + relation: 'sale', + inq: sales, + }, + ] + }; + try { + for (const [index, ticketId] of ticketsIds.entries()) { + const ticket = await models.Ticket.findById(ticketId, filter, myOptions); + if (!group || !index) { + newTicket = await models.Ticket.create({ + clientFk: ticket.clientFk, + shipped: now, + addressFk: ticket.address().id, + agencyModeFk: refundAgencyMode.id, + nickname: ticket.address().nickname, + warehouseFk: withWarehouse ? ticket.warehouseFk : null, + companyFk: ticket.companyFk, + landed: now, + zoneFk: refoundZoneId + }, myOptions); + updatedTickets.push(newTicket); + } + const sales = ticket.sale(); + const saleIds = sales.map(sale => sale.id); + const saleComponentsFilter = { + where: {saleFk: {inq: saleIds}}, + scope: { + fields: ['saleFk', 'componentFk', 'value'] + } + }; + for (const sale of sales) { + const createdSale = await models.Sale.create({ + ticketFk: newTicket.id, + itemFk: sale.itemFk, + quantity: (negative) ? - sale.quantity : sale.quantity, + concept: sale.concept, + price: sale.price, + discount: sale.discount, + }, myOptions); + const components = await models.SaleComponent.find(saleComponentsFilter, myOptions); + // const components = sale.components(); + for (const component of components) + component.saleFk = createdSale.id; - for (const ticketId of ticketsIds) { - const filter = {include: {relation: 'address'}}; - const ticket = await models.Ticket.findById(ticketId, filter, myOptions); - - const ticketUpdated = await models.Ticket.create({ - clientFk: ticket.clientFk, - shipped: now, - addressFk: ticket.address().id, - agencyModeFk: refundAgencyMode.id, - nickname: ticket.address().nickname, - warehouseFk: withWarehouse ? ticket.warehouseFk : null, - companyFk: ticket.companyFk, - landed: now, - zoneFk: refoundZoneId - }, myOptions); - updatedTickets.push(ticketUpdated); - } - - for (const sale of sales) { - const createdSale = await models.Sale.create({ - ticketFk: sale.ticketFk, - itemFk: sale.itemFk, - quantity: (isRefund) ? - sale.quantity : sale.quantity, - concept: sale.concept, - price: sale.price, - discount: sale.discount, - }, myOptions); - - const components = sale.components(); - for (const component of components) - component.saleFk = createdSale.id; - - await models.SaleComponent.create(components, myOptions); - } - - if (servicesIds && servicesIds.length > 0) { - const servicesFilter = { - where: {id: {inq: servicesIds}} - }; - const services = await models.TicketService.find(servicesFilter, myOptions); - for (const service of services) { - await models.TicketService.create({ - description: service.description, - quantity: (isRefund) ? - service.quantity : service.quantity, - price: service.price, - taxClassFk: service.taxClassFk, - ticketFk: service.ticketFk, - ticketServiceTypeFk: service.ticketServiceTypeFk, - }, myOptions); + await models.SaleComponent.create(components, myOptions); + } } + if (servicesIds && servicesIds.length > 0) { + const servicesFilter = { + where: {id: {inq: servicesIds}} + }; + const services = await models.TicketService.find(servicesFilter, myOptions); + for (const service of services) { + await models.TicketService.create({ + description: service.description, + quantity: (negative) ? - service.quantity : service.quantity, + price: service.price, + taxClassFk: service.taxClassFk, + ticketFk: service.ticketFk, + ticketServiceTypeFk: service.ticketServiceTypeFk, + }, myOptions); + } + } + + const query = `CALL vn.ticket_recalc(?, NULL)`; + + if (group) { + await Self.rawSql(query, [newTicket.id], myOptions); + if (tx) await tx.commit(); + return { + refundTicket: newTicket, + originalTicketFk: firstTicketId + }; + } else { + for (const updatedTicket of updatedTickets) + await Self.rawSql(query, [updatedTicket.id], myOptions); + if (tx) await tx.commit(); + return updatedTickets/* updatedTickets.map(updatedTicket => updatedTicket.id) */; + } + } catch (e) { + if (tx) await tx.rollback(); + throw e; } - - const query = `CALL vn.ticket_recalc(?, NULL)`; - - for (const updatedTicket of updatedTickets) - await Self.rawSql(query, [updatedTicket.id], myOptions); - return updatedTickets.map(updatedTicket => updatedTicket.id); }; }; diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 6bb131e4d3..c85bcd834f 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -155,19 +155,23 @@ module.exports = Self => { } }; const sales = await models.Sale.find(salesFilter, myOptions); - const group = true; - const isRefund = true; - - const refundTicket = await cloneAndGroup( + const clonedTicket = await models.Sale.clone( sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, - group, - isRefund, + true, + true, myOptions ); + + const refundTicket = clonedTicket.refundTicket; + + await models.TicketRefund.create({ + refundTicketFk: refundTicket.id, + originalTicketFk: clonedTicket.originalTicketFk, + }, myOptions); if (tx) await tx.commit(); return refundTicket; @@ -177,74 +181,7 @@ module.exports = Self => { } }; - async function cloneAndGroup(sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, group, isRefund, myOptions) { - if (!group) { - const tickets = await models.Sale.clone(sales, - refundAgencyMode, - refoundZoneId, servicesIds, - withWarehouse, - isRefund, - myOptions); - return tickets; - } - - const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; - const [firstTicketId] = ticketsIds; - const filter = {include: {relation: 'address'}}; - const ticket = await models.Ticket.findById(firstTicketId, filter, myOptions); - - const ticketUpdated = await models.Ticket.create({ - clientFk: ticket.clientFk, - shipped: now, - addressFk: ticket.address().id, - agencyModeFk: refundAgencyMode.id, - nickname: ticket.address().nickname, - warehouseFk: withWarehouse ? ticket.warehouseFk : null, - companyFk: ticket.companyFk, - landed: now, - zoneFk: refoundZoneId - }, myOptions); - - for (const sale of sales) { - const createdSale = await models.Sale.create({ - ticketFk: ticketUpdated.id, - itemFk: sale.itemFk, - quantity: (isRefund) ? - sale.quantity : sale.quantity, - concept: sale.concept, - price: sale.price, - discount: sale.discount, - }, myOptions); - - const components = sale.components(); - for (const component of components) - component.saleFk = createdSale.id; - - await models.SaleComponent.create(components, myOptions); - } - - if (servicesIds && servicesIds.length > 0) { - const servicesFilter = { - where: {id: {inq: servicesIds}} - }; - const services = await models.TicketService.find(servicesFilter, myOptions); - for (const service of services) { - await models.TicketService.create({ - description: service.description, - quantity: (isRefund) ? - service.quantity : service.quantity, - price: service.price, - taxClassFk: service.taxClassFk, - ticketFk: ticketUpdated.id, - ticketServiceTypeFk: service.ticketServiceTypeFk, - }, myOptions); - } - } - - const query = `CALL vn.ticket_recalc(?, NULL)`; - await Self.rawSql(query, [refundTicket.id], myOptions); - return ticketUpdated; - } - - async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions) { + /* async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions) { const models = Self.app.models; const filter = {include: {relation: 'address'}}; @@ -268,5 +205,5 @@ module.exports = Self => { }, myOptions); return refundTicket; - } + } */ }; diff --git a/modules/ticket/back/methods/sale/specs/refund.spec.js b/modules/ticket/back/methods/sale/specs/refund.spec.js index b81f7f84d8..727ce2face 100644 --- a/modules/ticket/back/methods/sale/specs/refund.spec.js +++ b/modules/ticket/back/methods/sale/specs/refund.spec.js @@ -1,7 +1,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); -describe('Sale refund()', () => { +fdescribe('Sale refund()', () => { const userId = 5; const ctx = {req: {accessToken: userId}}; const activeCtx = { diff --git a/modules/ticket/back/methods/ticket/refund.js b/modules/ticket/back/methods/ticket/refund.js index c99b6aa835..758384ae2b 100644 --- a/modules/ticket/back/methods/ticket/refund.js +++ b/modules/ticket/back/methods/ticket/refund.js @@ -39,7 +39,6 @@ module.exports = Self => { try { const filter = {where: {ticketFk: {inq: ticketsIds}}}; - const sales = await models.Sale.find(filter, myOptions); const salesIds = sales.map(sale => sale.id); diff --git a/modules/ticket/back/models/ticket.json b/modules/ticket/back/models/ticket.json index ec4193bed7..1c5610a2a1 100644 --- a/modules/ticket/back/models/ticket.json +++ b/modules/ticket/back/models/ticket.json @@ -136,6 +136,11 @@ "type": "belongsTo", "model": "Zone", "foreignKey": "zoneFk" + }, + "sale": { + "type": "hasMany", + "model": "Sale", + "foreignKey": "ticketFk" } } } From bd122e6327024b2ad885cfcd340d9bcb2f5e42e5 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 1 Aug 2023 16:13:24 +0200 Subject: [PATCH 017/449] refs #5014 WIP trasactions added --- .../methods/invoiceOut/transferInvoiceOut.js | 17 +++++------------ ...orrection.json => invoice-correction.json} | 0 modules/ticket/back/methods/sale/clone.js | 19 ++++++++++--------- modules/ticket/back/methods/sale/refund.js | 14 ++++++++------ 4 files changed, 23 insertions(+), 27 deletions(-) rename modules/invoiceOut/back/models/{invoiceCorrection.json => invoice-correction.json} (100%) diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js index 86de59e9db..e059aa4310 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js @@ -48,7 +48,7 @@ module.exports = Self => { Self.transferInvoiceOut = async(ctx, id, ref, newClientFk, cplusRectificationId, cplusInvoiceType477Id, invoiceCorrectionTypeId, options) => { const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; let tx; if (typeof options == 'object') @@ -64,7 +64,6 @@ module.exports = Self => { const tickets = await models.Ticket.find(filter, myOptions); const ticketsIds = tickets.map(ticket => ticket.id); await models.Ticket.refund(ctx, ticketsIds, null, myOptions); - console.log('Ticket refunded'); // Clone tickets const refundAgencyMode = await models.AgencyMode.findOne({ include: { @@ -82,22 +81,17 @@ module.exports = Self => { const salesFilter = {where: {ticketFk: {inq: ticketsIds}}}; const sales = await models.Sale.find(salesFilter, myOptions); const clonedTickets = await models.Sale.clone(sales, refundAgencyMode, refoundZoneId, servicesIds, null, false, false, myOptions); - console.log('cloned tickets'); // Update client - for (const clonedTicket of clonedTickets) { - // const ticket = await models.Ticket.findById(clonedTicketId, myOptions); - console.log(clonedTicket); + for (const clonedTicket of clonedTickets) await clonedTicket.updateAttributes({clientFk: newClientFk}, myOptions); - console.log(clonedTicket); - } + // Quick invoice const clonedTicketIds = clonedTickets.map(clonedTicket => clonedTicket.id); - console.log(clonedTicketIds); const invoiceIds = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); // Insert InvoiceCorrection for (const invoiceId of invoiceIds) { - await models.invoiceCorrection.create({ + await models.InvoiceCorrection.create({ correctingFk: invoiceId, correctedFk: id, cplusRectificationTypeFk: cplusRectificationId, @@ -105,12 +99,11 @@ module.exports = Self => { invoiceCorrectionType: invoiceCorrectionTypeId }); } - if (tx) await tx.commit(); + return true; } catch (e) { if (tx) await tx.rollback(); throw e; } - return true; }; }; diff --git a/modules/invoiceOut/back/models/invoiceCorrection.json b/modules/invoiceOut/back/models/invoice-correction.json similarity index 100% rename from modules/invoiceOut/back/models/invoiceCorrection.json rename to modules/invoiceOut/back/models/invoice-correction.json diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index e1793d0882..dae15d7df6 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -1,8 +1,12 @@ module.exports = Self => { - Self.clone = async(sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, group, negative, myOptions) => { + Self.clone = async(sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, group, negative, options) => { const models = Self.app.models; + const myOptions = {}; let tx; + if (typeof options == 'object') + Object.assign(myOptions, options); + if (!myOptions.transaction) { tx = await Self.beginTransaction({}); myOptions.transaction = tx; @@ -39,15 +43,15 @@ module.exports = Self => { }, myOptions); updatedTickets.push(newTicket); } - const sales = ticket.sale(); - const saleIds = sales.map(sale => sale.id); + const salesByTicket = ticket.sale(); + const saleIds = salesByTicket.map(sale => sale.id); const saleComponentsFilter = { where: {saleFk: {inq: saleIds}}, scope: { fields: ['saleFk', 'componentFk', 'value'] } }; - for (const sale of sales) { + for (const sale of salesByTicket) { const createdSale = await models.Sale.create({ ticketFk: newTicket.id, itemFk: sale.itemFk, @@ -56,7 +60,7 @@ module.exports = Self => { price: sale.price, discount: sale.discount, }, myOptions); - const components = await models.SaleComponent.find(saleComponentsFilter, myOptions); + const components = await models.SaleComponent.find(saleComponentsFilter, myOptions); // Revisar con Alex // const components = sale.components(); for (const component of components) component.saleFk = createdSale.id; @@ -86,10 +90,7 @@ module.exports = Self => { if (group) { await Self.rawSql(query, [newTicket.id], myOptions); if (tx) await tx.commit(); - return { - refundTicket: newTicket, - originalTicketFk: firstTicketId - }; + return newTicket; } else { for (const updatedTicket of updatedTickets) await Self.rawSql(query, [updatedTicket.id], myOptions); diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index c85bcd834f..a69c05f36d 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -155,7 +155,7 @@ module.exports = Self => { } }; const sales = await models.Sale.find(salesFilter, myOptions); - const clonedTicket = await models.Sale.clone( + const refundTicket = await models.Sale.clone( sales, refundAgencyMode, refoundZoneId, @@ -166,12 +166,14 @@ module.exports = Self => { myOptions ); - const refundTicket = clonedTicket.refundTicket; + const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; + for (const ticketId of ticketsIds) { + await models.TicketRefund.create({ + refundTicketFk: refundTicket.id, + originalTicketFk: ticketId, + }, myOptions); + } - await models.TicketRefund.create({ - refundTicketFk: refundTicket.id, - originalTicketFk: clonedTicket.originalTicketFk, - }, myOptions); if (tx) await tx.commit(); return refundTicket; From 725fe674c0babb414a7ea7f7b99763c8f066bcce Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 3 Aug 2023 14:01:50 +0200 Subject: [PATCH 018/449] refs #5914 WIP fixing transacticions --- .../methods/invoiceOut/transferInvoiceOut.js | 47 ++++------ .../invoiceOut/front/descriptor-menu/index.js | 6 +- modules/ticket/back/methods/sale/clone.js | 9 +- modules/ticket/back/methods/sale/refund.js | 90 ------------------- 4 files changed, 27 insertions(+), 125 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js index e059aa4310..fbb40061da 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js @@ -1,5 +1,3 @@ -const UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethodCtx('transferInvoiceOut', { description: 'Transfer an invoice out to another client', @@ -48,7 +46,7 @@ module.exports = Self => { Self.transferInvoiceOut = async(ctx, id, ref, newClientFk, cplusRectificationId, cplusInvoiceType477Id, invoiceCorrectionTypeId, options) => { const models = Self.app.models; - const myOptions = {userId: ctx.req.accessToken.userId}; + const myOptions = {}; let tx; if (typeof options == 'object') @@ -65,42 +63,35 @@ module.exports = Self => { const ticketsIds = tickets.map(ticket => ticket.id); await models.Ticket.refund(ctx, ticketsIds, null, myOptions); // Clone tickets - const refundAgencyMode = await models.AgencyMode.findOne({ - include: { - relation: 'zones', - scope: { - limit: 1, - field: ['id', 'name'] - } - }, - where: {code: 'refund'} - }, myOptions); - const refoundZoneId = refundAgencyMode.zones()[0].id; const services = await models.TicketService.find(filter, myOptions); const servicesIds = services.map(service => service.id); const salesFilter = {where: {ticketFk: {inq: ticketsIds}}}; const sales = await models.Sale.find(salesFilter, myOptions); - const clonedTickets = await models.Sale.clone(sales, refundAgencyMode, refoundZoneId, servicesIds, null, false, false, myOptions); + const clonedTickets = await models.Sale.clone(sales, servicesIds, null, false, false, myOptions); + console.log('cloned tickets', clonedTickets); // Update client - for (const clonedTicket of clonedTickets) - await clonedTicket.updateAttributes({clientFk: newClientFk}, myOptions); + for (const clonedTicket of clonedTickets) { + const ticket = await models.Ticket.findById(clonedTicket); + console.log(ticket); + await ticket.updateAttributes({clientFk: newClientFk}, myOptions); + // await clonedTicket.updateAttributes({clientFk: newClientFk}, myOptions); + } // Quick invoice const clonedTicketIds = clonedTickets.map(clonedTicket => clonedTicket.id); - const invoiceIds = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); + const invoiceId = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); // Insert InvoiceCorrection - for (const invoiceId of invoiceIds) { - await models.InvoiceCorrection.create({ - correctingFk: invoiceId, - correctedFk: id, - cplusRectificationTypeFk: cplusRectificationId, - cplusInvoiceType477Fk: cplusInvoiceType477Id, - invoiceCorrectionType: invoiceCorrectionTypeId - }); - } + await models.InvoiceCorrection.create({ + correctingFk: invoiceId, + correctedFk: id, + cplusRectificationTypeFk: cplusRectificationId, + cplusInvoiceType477Fk: cplusInvoiceType477Id, + invoiceCorrectionType: invoiceCorrectionTypeId + }); + if (tx) await tx.commit(); - return true; + return invoiceId; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index 8ec5de3e60..ef69098c49 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -135,7 +135,11 @@ class Controller extends Section { cplusInvoiceType477Id: this.cplusInvoiceType477, invoiceCorrectionTypeId: this.invoiceCorrectionType }; - this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => console.log(res.data)); + this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => { + newInvoice = res.data;// id de la nueva factura + this.vnApp.showSucces(this.$t('Invoice trasfered!')); + this.$state.go('invoiceOut.index', {id: newInvoice}); + }); } } diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index dae15d7df6..c168f4b3c4 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.clone = async(sales, refundAgencyMode, refoundZoneId, servicesIds, withWarehouse, group, negative, options) => { + Self.clone = async(sales, servicesIds, withWarehouse, group, negative, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -13,7 +13,6 @@ module.exports = Self => { } const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; - const [firstTicketId] = ticketsIds; const now = Date.vnNew(); let updatedTickets = []; let newTicket; @@ -22,7 +21,7 @@ module.exports = Self => { {relation: 'address'}, { relation: 'sale', - inq: sales, + where: {saleFk: {inq: sales}}, }, ] }; @@ -34,12 +33,10 @@ module.exports = Self => { clientFk: ticket.clientFk, shipped: now, addressFk: ticket.address().id, - agencyModeFk: refundAgencyMode.id, nickname: ticket.address().nickname, warehouseFk: withWarehouse ? ticket.warehouseFk : null, companyFk: ticket.companyFk, landed: now, - zoneFk: refoundZoneId }, myOptions); updatedTickets.push(newTicket); } @@ -95,7 +92,7 @@ module.exports = Self => { for (const updatedTicket of updatedTickets) await Self.rawSql(query, [updatedTicket.id], myOptions); if (tx) await tx.commit(); - return updatedTickets/* updatedTickets.map(updatedTicket => updatedTicket.id) */; + return /* updatedTickets */updatedTickets.map(updatedTicket => updatedTicket.id); } } catch (e) { if (tx) await tx.rollback(); diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index a69c05f36d..dabafb4694 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -28,96 +28,6 @@ module.exports = Self => { } }); - /* Self.refund = async(ctx, salesIds, servicesIds, withWarehouse, options) => { - const models = Self.app.models; - const myOptions = {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; - } - - try { - const refundAgencyMode = await models.AgencyMode.findOne({ - include: { - relation: 'zones', - scope: { - limit: 1, - field: ['id', 'name'] - } - }, - where: {code: 'refund'} - }, myOptions); - - const refoundZoneId = refundAgencyMode.zones()[0].id; - - const salesFilter = { - where: {id: {inq: salesIds}}, - include: { - relation: 'components', - scope: { - fields: ['saleFk', 'componentFk', 'value'] - } - } - }; - const sales = await models.Sale.find(salesFilter, myOptions); - const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; - - const now = Date.vnNew(); - const [firstTicketId] = ticketsIds; - - const refundTicket = await createTicketRefund(firstTicketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions); - - for (const sale of sales) { - const createdSale = await models.Sale.create({ - ticketFk: refundTicket.id, - itemFk: sale.itemFk, - quantity: - sale.quantity, - concept: sale.concept, - price: sale.price, - discount: sale.discount, - }, myOptions); - - const components = sale.components(); - for (const component of components) - component.saleFk = createdSale.id; - - await models.SaleComponent.create(components, myOptions); - } - - if (servicesIds && servicesIds.length > 0) { - const servicesFilter = { - where: {id: {inq: servicesIds}} - }; - const services = await models.TicketService.find(servicesFilter, myOptions); - for (const service of services) { - await models.TicketService.create({ - description: service.description, - quantity: - service.quantity, - price: service.price, - taxClassFk: service.taxClassFk, - ticketFk: refundTicket.id, - ticketServiceTypeFk: service.ticketServiceTypeFk, - }, myOptions); - } - } - - const query = `CALL vn.ticket_recalc(?, NULL)`; - await Self.rawSql(query, [refundTicket.id], myOptions); - - if (tx) await tx.commit(); - - return refundTicket; - } catch (e) { - if (tx) await tx.rollback(); - throw e; - } - }; */ - Self.refund = async(ctx, salesIds, servicesIds, withWarehouse, options) => { const models = Self.app.models; const myOptions = {userId: ctx.req.accessToken.userId}; From 700ba4a7b1fce37f7575b3308ead22163687a14b Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 4 Aug 2023 08:22:43 +0200 Subject: [PATCH 019/449] refs #5914 feat(transferInvoiceOut): optimization --- .../methods/invoiceOut/transferInvoiceOut.js | 18 ++++++++---------- modules/ticket/back/methods/sale/clone.js | 2 +- .../back/methods/ticket/invoiceTickets.js | 7 +++++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js index fbb40061da..440ebe4d3f 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js @@ -46,7 +46,8 @@ module.exports = Self => { Self.transferInvoiceOut = async(ctx, id, ref, newClientFk, cplusRectificationId, cplusInvoiceType477Id, invoiceCorrectionTypeId, options) => { const models = Self.app.models; - const myOptions = {}; + const myOptions = {userId: ctx.req.accessToken.userId}; + let tx; if (typeof options == 'object') @@ -65,20 +66,17 @@ module.exports = Self => { // Clone tickets const services = await models.TicketService.find(filter, myOptions); const servicesIds = services.map(service => service.id); - const salesFilter = {where: {ticketFk: {inq: ticketsIds}}}; - const sales = await models.Sale.find(salesFilter, myOptions); + const sales = await models.Sale.find({where: {ticketFk: {inq: ticketsIds}}}, myOptions); const clonedTickets = await models.Sale.clone(sales, servicesIds, null, false, false, myOptions); - console.log('cloned tickets', clonedTickets); + const clonedTicketIds = []; + // Update client for (const clonedTicket of clonedTickets) { - const ticket = await models.Ticket.findById(clonedTicket); - console.log(ticket); - await ticket.updateAttributes({clientFk: newClientFk}, myOptions); - // await clonedTicket.updateAttributes({clientFk: newClientFk}, myOptions); + await clonedTicket.updateAttribute('clientFk', newClientFk, myOptions); + clonedTicketIds.push(clonedTicket.id); } // Quick invoice - const clonedTicketIds = clonedTickets.map(clonedTicket => clonedTicket.id); const invoiceId = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); // Insert InvoiceCorrection @@ -88,7 +86,7 @@ module.exports = Self => { cplusRectificationTypeFk: cplusRectificationId, cplusInvoiceType477Fk: cplusInvoiceType477Id, invoiceCorrectionType: invoiceCorrectionTypeId - }); + }, myOptions); if (tx) await tx.commit(); return invoiceId; diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index c168f4b3c4..7d52fd0e65 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -92,7 +92,7 @@ module.exports = Self => { for (const updatedTicket of updatedTickets) await Self.rawSql(query, [updatedTicket.id], myOptions); if (tx) await tx.commit(); - return /* updatedTickets */updatedTickets.map(updatedTicket => updatedTicket.id); + return /* updatedTickets */updatedTickets; } } catch (e) { if (tx) await tx.rollback(); diff --git a/modules/ticket/back/methods/ticket/invoiceTickets.js b/modules/ticket/back/methods/ticket/invoiceTickets.js index ca1bf15fb6..7baee133de 100644 --- a/modules/ticket/back/methods/ticket/invoiceTickets.js +++ b/modules/ticket/back/methods/ticket/invoiceTickets.js @@ -77,9 +77,11 @@ module.exports = function(Self) { if (tx) await tx.rollback(); throw e; } - - for (const invoiceId of invoicesIds) + console.log(invoicesIds, 'invoicesIds'); + for (const invoiceId of invoicesIds) { + console.log(await models.InvoiceOut.find()); await models.InvoiceOut.makePdfAndNotify(ctx, invoiceId, null); + } return invoicesIds; }; @@ -98,6 +100,7 @@ module.exports = function(Self) { `, [ticketsIds], myOptions); const invoiceId = await models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), myOptions); + console.log(await models.InvoiceOut.find(null, myOptions)); invoicesIds.push(invoiceId); } }; From 1f63648697d585ef03cc18ba77108c14f744ba57 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 24 Aug 2023 09:10:04 +0200 Subject: [PATCH 020/449] =?UTF-8?q?refs=20#5918=20fix:=20muestra=20los=20b?= =?UTF-8?q?otones=20en=20una=20l=C3=ADnea=20y=20no=20carga=20todos=20los?= =?UTF-8?q?=20datos=20de=20workerTimeControlMail=20de=20la=20semana?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/changes/233601/00-ACL_workerDepartment.sql | 3 +++ modules/worker/front/time-control/index.html | 12 +++++------- modules/worker/front/time-control/index.js | 3 ++- 3 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 db/changes/233601/00-ACL_workerDepartment.sql diff --git a/db/changes/233601/00-ACL_workerDepartment.sql b/db/changes/233601/00-ACL_workerDepartment.sql new file mode 100644 index 0000000000..ceb8d5d753 --- /dev/null +++ b/db/changes/233601/00-ACL_workerDepartment.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('WorkerDepartment', '*', '*', 'ALLOW', 'ROLE', 'employee'); diff --git a/modules/worker/front/time-control/index.html b/modules/worker/front/time-control/index.html index 307d9a50ff..847eb95056 100644 --- a/modules/worker/front/time-control/index.html +++ b/modules/worker/front/time-control/index.html @@ -79,32 +79,30 @@ - + - - + ng-show="$ctrl.isHr && $ctrl.canResend"> diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index f63a766e84..91f095334b 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -117,7 +117,8 @@ class Controller extends Section { where: { year: this._date.getFullYear(), week: this.getWeekNumber(this._date) - } + }, + limit: 1 }; this.$http.get('WorkerTimeControlMails', {filter}) .then(res => { From 3d4a99b07e0024d4161bbc91d65e5cd97c560973 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 24 Aug 2023 10:51:34 +0200 Subject: [PATCH 021/449] refs 5914 transferInvoice created --- loopback/locale/es.json | 346 ++---------------- .../methods/invoiceOut/makePdfAndNotify.js | 2 +- ...ansferInvoiceOut.js => transferInvoice.js} | 28 +- .../front/descriptor-menu/index.html | 3 +- .../invoiceOut/front/descriptor-menu/index.js | 6 +- .../front/descriptor-menu/style.scss | 8 +- modules/ticket/back/methods/sale/clone.js | 171 ++++++--- modules/ticket/back/methods/sale/refund.js | 18 +- .../back/methods/ticket/invoiceTickets.js | 8 +- .../methods/ticket/invoiceTicketsWithPdf.js | 0 print/templates/reports/invoice/invoice.js | 3 + 11 files changed, 178 insertions(+), 415 deletions(-) rename modules/invoiceOut/back/methods/invoiceOut/{transferInvoiceOut.js => transferInvoice.js} (76%) create mode 100644 modules/ticket/back/methods/ticket/invoiceTicketsWithPdf.js diff --git a/loopback/locale/es.json b/loopback/locale/es.json index d196f99fac..627ab9a469 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -1,324 +1,26 @@ { - "Phone format is invalid": "El formato del teléfono no es correcto", - "You are not allowed to change the credit": "No tienes privilegios para modificar el crédito", - "Unable to mark the equivalence surcharge": "No se puede marcar el recargo de equivalencia", - "The default consignee can not be unchecked": "No se puede desmarcar el consignatario predeterminado", - "Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado", - "Can't be blank": "No puede estar en blanco", - "Invalid TIN": "NIF/CIF invalido", - "TIN must be unique": "El NIF/CIF debe ser único", - "A client with that Web User name already exists": "Ya existe un cliente con ese Usuario Web", - "Is invalid": "Is invalid", - "Quantity cannot be zero": "La cantidad no puede ser cero", - "Enter an integer different to zero": "Introduce un entero distinto de cero", - "Package cannot be blank": "El embalaje no puede estar en blanco", - "The company name must be unique": "La razón social debe ser única", - "Invalid email": "Correo electrónico inválido", - "The IBAN does not have the correct format": "El IBAN no tiene el formato correcto", - "That payment method requires an IBAN": "El método de pago seleccionado requiere un IBAN", - "That payment method requires a BIC": "El método de pago seleccionado requiere un BIC", - "State cannot be blank": "El estado no puede estar en blanco", - "Worker cannot be blank": "El trabajador no puede estar en blanco", - "Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado", - "can't be blank": "El campo no puede estar vacío", - "Observation type must be unique": "El tipo de observación no puede repetirse", + "Name cannot be blank": "Name cannot be blank", + "Swift / BIC cannot be empty": "Swift / BIC cannot be empty", + "Social name should be uppercase": "Social name should be uppercase", + "Street cannot be empty": "Street cannot be empty", + "Street should be uppercase": "Street should be uppercase", + "City cannot be empty": "City cannot be empty", + "Invalid email": "Invalid email", + "Phone cannot be blank": "Phone cannot be blank", "The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero", - "The grade must be similar to the last one": "El grade debe ser similar al último", - "Only manager can change the credit": "Solo el gerente puede cambiar el credito de este cliente", - "Name cannot be blank": "El nombre no puede estar en blanco", - "Phone cannot be blank": "El teléfono no puede estar en blanco", - "Period cannot be blank": "El periodo no puede estar en blanco", - "Choose a company": "Selecciona una empresa", - "Se debe rellenar el campo de texto": "Se debe rellenar el campo de texto", - "Description should have maximum of 45 characters": "La descripción debe tener maximo 45 caracteres", - "Cannot be blank": "El campo no puede estar en blanco", - "The grade must be an integer greater than or equal to zero": "El grade debe ser un entero mayor o igual a cero", - "Sample type cannot be blank": "El tipo de plantilla no puede quedar en blanco", - "Description cannot be blank": "Se debe rellenar el campo de texto", - "The new quantity should be smaller than the old one": "La nueva cantidad debe de ser menor que la anterior", - "The value should not be greater than 100%": "El valor no debe de ser mayor de 100%", - "The value should be a number": "El valor debe ser un numero", - "This order is not editable": "Esta orden no se puede modificar", - "You can't create an order for a frozen client": "No puedes crear una orden para un cliente congelado", - "You can't create an order for a client that has a debt": "No puedes crear una orden para un cliente con deuda", - "is not a valid date": "No es una fecha valida", - "Barcode must be unique": "El código de barras debe ser único", - "The warehouse can't be repeated": "El almacén no puede repetirse", - "The tag or priority can't be repeated for an item": "El tag o prioridad no puede repetirse para un item", - "The observation type can't be repeated": "El tipo de observación no puede repetirse", - "A claim with that sale already exists": "Ya existe una reclamación para esta línea", - "You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo", - "Warehouse cannot be blank": "El almacén no puede quedar en blanco", - "Agency cannot be blank": "La agencia no puede quedar en blanco", - "Not enough privileges to edit a client with verified data": "No tienes permisos para hacer cambios en un cliente con datos comprobados", - "This address doesn't exist": "Este consignatario no existe", - "You must delete the claim id %d first": "Antes debes borrar la reclamación %d", - "You don't have enough privileges": "No tienes suficientes permisos", - "Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF", - "You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos basicos de una orden con artículos", - "INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no esta permitido el uso de la letra ñ", - "You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado", - "You can't create a ticket for a inactive client": "No puedes crear un ticket para un cliente inactivo", - "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", - "ORDER_EMPTY": "Cesta vacía", - "You don't have enough privileges to do that": "No tienes permisos para cambiar esto", - "NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT", - "Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido", - "Street cannot be empty": "Dirección no puede estar en blanco", - "City cannot be empty": "Cuidad no puede estar en blanco", - "Code cannot be blank": "Código no puede estar en blanco", - "You cannot remove this department": "No puedes eliminar este departamento", - "The extension must be unique": "La extensión debe ser unica", - "The secret can't be blank": "La contraseña no puede estar en blanco", - "We weren't able to send this SMS": "No hemos podido enviar el SMS", - "This client can't be invoiced": "Este cliente no puede ser facturado", - "This ticket can't be invoiced": "Este ticket no puede ser facturado", - "You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado", - "This ticket can not be modified": "Este ticket no puede ser modificado", - "The introduced hour already exists": "Esta hora ya ha sido introducida", - "INFINITE_LOOP": "Existe una dependencia entre dos Jefes", - "The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas", - "NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros", - "ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado", - "The current ticket can't be modified": "El ticket actual no puede ser modificado", - "The current claim can't be modified": "La reclamación actual no puede ser modificada", - "The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", - "The sales do not exists": "La(s) línea(s) seleccionada(s) no existe(n)", - "Please select at least one sale": "Por favor selecciona al menos una linea", - "All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket", - "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", - "This item doesn't exists": "El artículo no existe", - "NOT_ZONE_WITH_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", - "Extension format is invalid": "El formato de la extensión es inválido", - "Invalid parameters to create a new ticket": "Parámetros inválidos para crear un nuevo ticket", - "This item is not available": "Este artículo no está disponible", - "This postcode already exists": "Este código postal ya existe", - "Concept cannot be blank": "El concepto no puede quedar en blanco", - "File doesn't exists": "El archivo no existe", - "You don't have privileges to change the zone": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias", - "This ticket is already on weekly tickets": "Este ticket ya está en tickets programados", - "Ticket id cannot be blank": "El id de ticket no puede quedar en blanco", - "Weekday cannot be blank": "El día de la semana no puede quedar en blanco", - "You can't delete a confirmed order": "No puedes borrar un pedido confirmado", - "The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto", - "Invalid quantity": "Cantidad invalida", - "This postal code is not valid": "This postal code is not valid", - "is invalid": "is invalid", - "The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto", - "The department name can't be repeated": "El nombre del departamento no puede repetirse", - "This phone already exists": "Este teléfono ya existe", - "You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos", - "You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado", - "You cannot delete a ticket that part of it is being prepared": "No puedes eliminar un ticket en el que una parte que está siendo preparada", - "You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero", - "You should specify a date": "Debes especificar una fecha", - "You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín", - "Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín", - "You should mark at least one week day": "Debes marcar al menos un día de la semana", - "Swift / BIC can't be empty": "Swift / BIC no puede estar vacío", - "Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios", - "Incoterms is required for a non UEE member": "El incoterms es requerido para los clientes extracomunitarios", - "Deleted sales from ticket": "He eliminado las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{deletions}}}", - "Added sale to ticket": "He añadido la siguiente linea al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}", - "Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})", - "Changed sale quantity": "He cambiado la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* del ticket [{{ticketId}}]({{{ticketUrl}}})", - "State": "Estado", - "regular": "normal", - "reserved": "reservado", - "Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})", - "Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}", - "MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*", - "Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})", - "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})", - "Change quantity": "{{concept}} cambia de {{oldQuantity}} a {{newQuantity}}", - "Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*", - "Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*", - "Claim state has changed to canceled": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *anulado*", - "Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}", - "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", - "Distance must be lesser than 1000": "La distancia debe ser inferior a 1000", - "This ticket is deleted": "Este ticket está eliminado", - "Unable to clone this travel": "No ha sido posible clonar este travel", - "This thermograph id already exists": "La id del termógrafo ya existe", - "Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante", - "ORDER_ALREADY_CONFIRMED": "ORDER_ALREADY_CONFIRMED", - "Invalid password": "Invalid password", - "Password does not meet requirements": "La contraseña no cumple los requisitos", - "Role already assigned": "Role already assigned", - "Invalid role name": "Invalid role name", - "Role name must be written in camelCase": "Role name must be written in camelCase", - "Email already exists": "Email already exists", - "User already exists": "User already exists", - "Absence change notification on the labour calendar": "Notificacion de cambio de ausencia en el calendario laboral", - "Record of hours week": "Registro de horas semana {{week}} año {{year}} ", - "Created absence": "El empleado {{author}} ha añadido una ausencia de tipo '{{absenceType}}' a {{employee}} para el día {{dated}}.", - "Deleted absence": "El empleado {{author}} ha eliminado una ausencia de tipo '{{absenceType}}' a {{employee}} del día {{dated}}.", - "I have deleted the ticket id": "He eliminado el ticket id [{{id}}]({{{url}}})", - "I have restored the ticket id": "He restaurado el ticket id [{{id}}]({{{url}}})", - "You can only restore a ticket within the first hour after deletion": "Únicamente puedes restaurar el ticket dentro de la primera hora después de su eliminación", - "Changed this data from the ticket": "He cambiado estos datos del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "agencyModeFk": "Agencia", - "clientFk": "Cliente", - "zoneFk": "Zona", - "warehouseFk": "Almacén", - "shipped": "F. envío", - "landed": "F. entrega", - "addressFk": "Consignatario", - "companyFk": "Empresa", - "The social name cannot be empty": "La razón social no puede quedar en blanco", - "The nif cannot be empty": "El NIF no puede quedar en blanco", - "You need to fill sage information before you check verified data": "Debes rellenar la información de sage antes de marcar datos comprobados", - "ASSIGN_ZONE_FIRST": "Asigna una zona primero", - "Amount cannot be zero": "El importe no puede ser cero", - "Company has to be official": "Empresa inválida", - "You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria", - "Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas", - "The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta", - "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*", - "New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*", - "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", - "This BIC already exist.": "Este BIC ya existe.", - "That item doesn't exists": "Ese artículo no existe", - "There's a new urgent ticket:": "Hay un nuevo ticket urgente:", - "Invalid account": "Cuenta inválida", - "Compensation account is empty": "La cuenta para compensar está vacia", - "This genus already exist": "Este genus ya existe", - "This specie already exist": "Esta especie ya existe", - "Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})", - "None": "Ninguno", - "The contract was not active during the selected date": "El contrato no estaba activo durante la fecha seleccionada", - "Cannot add more than one '1/2 day vacation'": "No puedes añadir más de un 'Vacaciones 1/2 dia'", - "This document already exists on this ticket": "Este documento ya existe en el ticket", - "Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables", - "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", - "nickname": "nickname", - "INACTIVE_PROVIDER": "Proveedor inactivo", - "This client is not invoiceable": "Este cliente no es facturable", - "serial non editable": "Esta serie no permite asignar la referencia", - "Max shipped required": "La fecha límite es requerida", - "Can't invoice to future": "No se puede facturar a futuro", - "Can't invoice to past": "No se puede facturar a pasado", - "This ticket is already invoiced": "Este ticket ya está facturado", - "A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero", - "A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa", - "Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes", - "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes", - "Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio", - "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito", - "You can't change the credit set to zero from a financialBoss": "No puedes cambiar el cŕedito establecido a cero por un jefe de finanzas", - "Amounts do not match": "Las cantidades no coinciden", - "The PDF document does not exist": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'", - "The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos", - "You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días", - "The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día", - "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", - "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", - "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", - "You don't have privileges to create refund": "No tienes permisos para crear un abono", - "The item is required": "El artículo es requerido", - "The agency is already assigned to another autonomous": "La agencia ya está asignada a otro autónomo", - "date in the future": "Fecha en el futuro", - "reference duplicated": "Referencia duplicada", - "This ticket is already a refund": "Este ticket ya es un abono", - "isWithoutNegatives": "isWithoutNegatives", - "routeFk": "routeFk", - "Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador", - "No hay un contrato en vigor": "No hay un contrato en vigor", - "No se permite fichar a futuro": "No se permite fichar a futuro", - "No está permitido trabajar": "No está permitido trabajar", - "Fichadas impares": "Fichadas impares", - "Descanso diario 12h.": "Descanso diario 12h.", - "Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.", - "Dirección incorrecta": "Dirección incorrecta", - "Modifiable user details only by an administrator": "Detalles de usuario modificables solo por un administrador", - "Modifiable password only via recovery or by an administrator": "Contraseña modificable solo a través de la recuperación o por un administrador", - "Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente", - "This route does not exists": "Esta ruta no existe", - "Claim pickup order sent": "Reclamación Orden de recogida enviada [{{claimId}}]({{{claimUrl}}}) al cliente *{{clientName}}*", - "You don't have grant privilege": "No tienes privilegios para dar privilegios", - "You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario", - "Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) fusionado con [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})", - "Already has this status": "Ya tiene este estado", - "There aren't records for this week": "No existen registros para esta semana", - "Empty data source": "Origen de datos vacio", - "App locked": "Aplicación bloqueada por el usuario {{userId}}", - "Email verify": "Correo de verificación", - "Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment", - "Receipt's bank was not found": "No se encontró el banco del recibo", - "This receipt was not compensated": "Este recibo no ha sido compensado", - "Client's email was not found": "No se encontró el email del cliente", - "Negative basis": "Base negativa", - "This worker code already exists": "Este codigo de trabajador ya existe", - "This personal mail already exists": "Este correo personal ya existe", - "This worker already exists": "Este trabajador ya existe", - "App name does not exist": "El nombre de aplicación no es válido", - "Try again": "Vuelve a intentarlo", - "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9", - "Failed to upload delivery note": "Error al subir albarán {{id}}", - "The DOCUWARE PDF document does not exists": "El documento PDF Docuware no existe", - "It is not possible to modify tracked sales": "No es posible modificar líneas de pedido que se hayan empezado a preparar", - "It is not possible to modify sales that their articles are from Floramondo": "No es posible modificar líneas de pedido cuyos artículos sean de Floramondo", - "It is not possible to modify cloned sales": "No es posible modificar líneas de pedido clonadas", - "A supplier with the same name already exists. Change the country.": "Un proveedor con el mismo nombre ya existe. Cambie el país.", - "There is no assigned email for this client": "No hay correo asignado para este cliente", - "Exists an invoice with a future date": "Existe una factura con fecha posterior", - "Invoice date can't be less than max date": "La fecha de factura no puede ser inferior a la fecha límite", - "Warehouse inventory not set": "El almacén inventario no está establecido", - "This locker has already been assigned": "Esta taquilla ya ha sido asignada", - "Tickets with associated refunds": "No se pueden borrar tickets con abonos asociados. Este ticket está asociado al abono Nº %d", - "Not exist this branch": "La rama no existe", - "This ticket cannot be signed because it has not been boxed": "Este ticket no puede firmarse porque no ha sido encajado", - "Collection does not exist": "La colección no existe", - "Cannot obtain exclusive lock": "No se puede obtener un bloqueo exclusivo", - "Insert a date range": "Inserte un rango de fechas", - "Added observation": "{{user}} añadió esta observacion: {{text}}", - "Comment added to client": "Observación añadida al cliente {{clientFk}}", - "Invalid auth code": "Código de verificación incorrecto", - "Invalid or expired verification code": "Código de verificación incorrecto o expirado", - "Cannot create a new claimBeginning from a different ticket": "No se puede crear una línea de reclamación de un ticket diferente al origen", - "company": "Compañía", - "country": "País", - "clientId": "Id cliente", - "clientSocialName": "Cliente", - "amount": "Importe", - "taxableBase": "Base", - "ticketFk": "Id ticket", - "isActive": "Activo", - "hasToInvoice": "Facturar", - "isTaxDataChecked": "Datos comprobados", - "comercialId": "Id comercial", - "comercialName": "Comercial", - "Pass expired": "La contraseña ha caducado, cambiela desde Salix", - "Invalid NIF for VIES": "Invalid NIF for VIES", - "Ticket does not exist": "Este ticket no existe", - "Ticket is already signed": "Este ticket ya ha sido firmado", - "Authentication failed": "Autenticación fallida", - "You can't use the same password": "No puedes usar la misma contraseña", - "You can only add negative amounts in refund tickets": "Solo se puede añadir cantidades negativas en tickets abono", - "Fecha fuera de rango": "Fecha fuera de rango", - "Error while generating PDF": "Error al generar PDF", - "Error when sending mail to client": "Error al enviar el correo al cliente", - "Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico", - "The renew period has not been exceeded": "El periodo de renovación no ha sido superado", - "Valid priorities": "Prioridades válidas: %d", - "Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}", - "You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado", - "This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s", - "The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias", - "You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado", - "This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado", - "You don't have enough privileges.": "No tienes suficientes permisos.", - "This ticket is locked.": "Este ticket está bloqueado.", - "This ticket is not editable.": "Este ticket no es editable.", - "The ticket doesn't exist.": "No existe el ticket.", -<<<<<<< HEAD - "There are missing fields.": "There are missing fields." -} -======= - "Social name should be uppercase": "La razón social debe ir en mayúscula", - "Street should be uppercase": "La dirección fiscal debe ir en mayúscula" -} ->>>>>>> ce78fc8e5dd383b3c6457fe5f78a45b21b246858 + "The grade must be an integer greater than or equal to zero": "The grade must be an integer greater than or equal to zero", + "Description should have maximum of 45 characters": "Description should have maximum of 45 characters", + "Amount cannot be zero": "Amount cannot be zero", + "Period cannot be blank": "Period cannot be blank", + "Sample type cannot be blank": "Sample type cannot be blank", + "Cannot be blank": "Cannot be blank", + "The social name cannot be empty": "The social name cannot be empty", + "Concept cannot be blank": "Concept cannot be blank", + "Enter an integer different to zero": "Enter an integer different to zero", + "Package cannot be blank": "Package cannot be blank", + "State cannot be blank": "State cannot be blank", + "Worker cannot be blank": "Worker cannot be blank", + "Description cannot be blank": "Description cannot be blank", + "Agency cannot be blank": "Agency cannot be blank", + "The renew period has not been exceeded": "The renew period has not been exceeded" +} \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js index a48664b302..e13ec0255a 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js +++ b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js @@ -23,7 +23,7 @@ module.exports = Self => { } }); - Self.makePdfAndNotify = async function(ctx, id, printerFk) { + Self.makePdfAndNotify = async function(ctx, id, printerFk, options) { const models = Self.app.models; options = typeof options == 'object' diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js similarity index 76% rename from modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js rename to modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js index 440ebe4d3f..c590ff9eab 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoiceOut.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js @@ -1,6 +1,6 @@ module.exports = Self => { - Self.remoteMethodCtx('transferInvoiceOut', { - description: 'Transfer an invoice out to another client', + Self.remoteMethodCtx('transferInvoice', { + description: 'Transfer an issued invoice to another client', accessType: 'WRITE', accepts: [ { @@ -49,7 +49,6 @@ module.exports = Self => { const myOptions = {userId: ctx.req.accessToken.userId}; let tx; - if (typeof options == 'object') Object.assign(myOptions, options); @@ -59,15 +58,21 @@ module.exports = Self => { } try { // Refund tickets and group - const filter = {where: {refFk: ref}}; - const tickets = await models.Ticket.find(filter, myOptions); + const filterRef = {where: {refFk: ref}}; + const tickets = await models.Ticket.find(filterRef, myOptions); const ticketsIds = tickets.map(ticket => ticket.id); await models.Ticket.refund(ctx, ticketsIds, null, myOptions); + // Clone tickets - const services = await models.TicketService.find(filter, myOptions); + const filterTicket = {where: {ticketFk: {inq: ticketsIds}}}; + + const services = await models.TicketService.find(filterTicket, myOptions); const servicesIds = services.map(service => service.id); - const sales = await models.Sale.find({where: {ticketFk: {inq: ticketsIds}}}, myOptions); - const clonedTickets = await models.Sale.clone(sales, servicesIds, null, false, false, myOptions); + + const sales = await models.Sale.find(filterTicket, myOptions); + const salesIds = sales.map(sale => sale.id); + + const clonedTickets = await models.Sale.clone(salesIds, servicesIds, null, false, false, myOptions); const clonedTicketIds = []; // Update client @@ -77,7 +82,8 @@ module.exports = Self => { } // Quick invoice - const invoiceId = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); + const invoiceIds = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); + const [invoiceId] = invoiceIds; // Insert InvoiceCorrection await models.InvoiceCorrection.create({ @@ -89,6 +95,10 @@ module.exports = Self => { }, myOptions); if (tx) await tx.commit(); + + // Crear PDF + await models.InvoiceOut.makePdfAndNotify(ctx, invoiceId, null); + return invoiceId; } catch (e) { if (tx) await tx.rollback(); diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index dc5c2a8e92..7d465f4ea5 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -184,9 +184,9 @@ +
+
diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index ef69098c49..7d2644158e 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -136,9 +136,9 @@ class Controller extends Section { invoiceCorrectionTypeId: this.invoiceCorrectionType }; this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => { - newInvoice = res.data;// id de la nueva factura - this.vnApp.showSucces(this.$t('Invoice trasfered!')); - this.$state.go('invoiceOut.index', {id: newInvoice}); + const invoiceId = res.data; + this.vnApp.showSuccess(this.$t('Invoice trasfered!')); + this.$state.go('invoiceOut.card.summary', {id: invoiceId}); }); } } diff --git a/modules/invoiceOut/front/descriptor-menu/style.scss b/modules/invoiceOut/front/descriptor-menu/style.scss index b683019613..25c02c80c1 100644 --- a/modules/invoiceOut/front/descriptor-menu/style.scss +++ b/modules/invoiceOut/front/descriptor-menu/style.scss @@ -21,4 +21,10 @@ vn-invoice-out-descriptor-menu { font-size: 1.75rem; } } -} \ No newline at end of file + +} +@media screen and (min-width: 1000px) { + .transferInvoice { + min-width: 900px; + } +} diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index 7d52fd0e65..9a3b5fedc9 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.clone = async(sales, servicesIds, withWarehouse, group, negative, options) => { + Self.clone = async(salesIds, servicesIds, withWarehouse, group, negative, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -12,91 +12,142 @@ module.exports = Self => { myOptions.transaction = tx; } - const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; - const now = Date.vnNew(); - let updatedTickets = []; - let newTicket; - const filter = { - include: [ - {relation: 'address'}, - { - relation: 'sale', - where: {saleFk: {inq: sales}}, - }, - ] - }; try { - for (const [index, ticketId] of ticketsIds.entries()) { - const ticket = await models.Ticket.findById(ticketId, filter, myOptions); - if (!group || !index) { - newTicket = await models.Ticket.create({ - clientFk: ticket.clientFk, - shipped: now, - addressFk: ticket.address().id, - nickname: ticket.address().nickname, - warehouseFk: withWarehouse ? ticket.warehouseFk : null, - companyFk: ticket.companyFk, - landed: now, - }, myOptions); - updatedTickets.push(newTicket); - } - const salesByTicket = ticket.sale(); - const saleIds = salesByTicket.map(sale => sale.id); - const saleComponentsFilter = { - where: {saleFk: {inq: saleIds}}, + const salesFilter = { + where: {id: {inq: salesIds}}, + include: { + relation: 'components', scope: { fields: ['saleFk', 'componentFk', 'value'] } - }; - for (const sale of salesByTicket) { - const createdSale = await models.Sale.create({ - ticketFk: newTicket.id, - itemFk: sale.itemFk, - quantity: (negative) ? - sale.quantity : sale.quantity, - concept: sale.concept, - price: sale.price, - discount: sale.discount, - }, myOptions); - const components = await models.SaleComponent.find(saleComponentsFilter, myOptions); // Revisar con Alex - // const components = sale.components(); - for (const component of components) - component.saleFk = createdSale.id; + } + }; + const sales = await models.Sale.find(salesFilter, myOptions); + const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; - await models.SaleComponent.create(components, myOptions); + const refundTickets = []; + const mappedTickets = new Map(); + const now = Date.vnNew(); + + const [firstTicketId] = ticketsIds; + if (group) { + await createTicketRefund( + firstTicketId, + withWarehouse, + refundTickets, + mappedTickets, + now, + myOptions + ); + } else { + for (let ticketId of ticketsIds) { + await createTicketRefund( + ticketId, + withWarehouse, + refundTickets, + mappedTickets, + now, + myOptions + ); } } + + for (const sale of sales) { + const refundTicketId = await getTicketRefundId(group, sale.ticketFk, refundTickets, mappedTickets); + + const createdSale = await models.Sale.create({ + ticketFk: refundTicketId, + itemFk: sale.itemFk, + quantity: negative ? - sale.quantity : sale.quantity, + concept: sale.concept, + price: sale.price, + discount: sale.discount, + }, myOptions); + + const components = sale.components(); + for (const component of components) + component.saleFk = createdSale.id; + + await models.SaleComponent.create(components, myOptions); + } + if (servicesIds && servicesIds.length > 0) { const servicesFilter = { where: {id: {inq: servicesIds}} }; const services = await models.TicketService.find(servicesFilter, myOptions); + for (const service of services) { + const refundTicketId = await getTicketRefundId(group, service.ticketFk, refundTickets, mappedTickets); + await models.TicketService.create({ description: service.description, - quantity: (negative) ? - service.quantity : service.quantity, + quantity: negative ? - service.quantity : service.quantity, price: service.price, taxClassFk: service.taxClassFk, - ticketFk: service.ticketFk, + ticketFk: refundTicketId, ticketServiceTypeFk: service.ticketServiceTypeFk, }, myOptions); } } - const query = `CALL vn.ticket_recalc(?, NULL)`; + if (tx) await tx.commit(); - if (group) { - await Self.rawSql(query, [newTicket.id], myOptions); - if (tx) await tx.commit(); - return newTicket; - } else { - for (const updatedTicket of updatedTickets) - await Self.rawSql(query, [updatedTicket.id], myOptions); - if (tx) await tx.commit(); - return /* updatedTickets */updatedTickets; - } + return refundTickets; } catch (e) { if (tx) await tx.rollback(); throw e; } }; + + async function createTicketRefund( + ticketId, + withWarehouse, + refundTickets, + mappedTickets, + now, + myOptions + ) { + const models = Self.app.models; + + const filter = { + include: [ + { + relation: 'address' + }, + { + relation: 'agencyMode' + }, + { + relation: 'zone' + } + ] + }; + const ticket = await models.Ticket.findById(ticketId, filter, myOptions); + const refundTicket = await models.Ticket.create({ + clientFk: ticket.clientFk, + shipped: now, + addressFk: ticket.address().id, + agencyModeFk: ticket.agencyMode().id, + nickname: ticket.address().nickname, + warehouseFk: withWarehouse ? ticket.warehouseFk : null, + companyFk: ticket.companyFk, + zonePrice: ticket.zonePrice, + zoneBonus: ticket.zoneBonus, + weight: ticket.weight, + landed: now, + zoneFk: ticket.zone().id, + }, myOptions); + + refundTickets.push(refundTicket); + + mappedTickets.set(ticketId, refundTicket.id); + } + + async function getTicketRefundId(group, ticketId, refundTickets, mappedTickets) { + if (group) { + const [firstRefundTicket] = refundTickets; + return firstRefundTicket.id; + } else return mappedTickets.get(ticketId); + } }; diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index dabafb4694..3f7e1cd217 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -64,27 +64,19 @@ module.exports = Self => { } } }; - const sales = await models.Sale.find(salesFilter, myOptions); + // const sales = await models.Sale.find(salesFilter, myOptions); const refundTicket = await models.Sale.clone( - sales, - refundAgencyMode, - refoundZoneId, + salesIds, servicesIds, withWarehouse, + // refundAgencyMode, + // refoundZoneId, true, true, myOptions ); - const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; - for (const ticketId of ticketsIds) { - await models.TicketRefund.create({ - refundTicketFk: refundTicket.id, - originalTicketFk: ticketId, - }, myOptions); - } - - if (tx) await tx.commit(); + if (tx && !options) await tx.commit(); return refundTicket; } catch (e) { diff --git a/modules/ticket/back/methods/ticket/invoiceTickets.js b/modules/ticket/back/methods/ticket/invoiceTickets.js index 7baee133de..e65c14e9a3 100644 --- a/modules/ticket/back/methods/ticket/invoiceTickets.js +++ b/modules/ticket/back/methods/ticket/invoiceTickets.js @@ -77,10 +77,9 @@ module.exports = function(Self) { if (tx) await tx.rollback(); throw e; } - console.log(invoicesIds, 'invoicesIds'); - for (const invoiceId of invoicesIds) { - console.log(await models.InvoiceOut.find()); - await models.InvoiceOut.makePdfAndNotify(ctx, invoiceId, null); + if (tx) { + for (const invoiceId of invoicesIds) + await models.InvoiceOut.makePdfAndNotify(ctx, invoiceId, null, myOptions); } return invoicesIds; @@ -100,7 +99,6 @@ module.exports = function(Self) { `, [ticketsIds], myOptions); const invoiceId = await models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), myOptions); - console.log(await models.InvoiceOut.find(null, myOptions)); invoicesIds.push(invoiceId); } }; diff --git a/modules/ticket/back/methods/ticket/invoiceTicketsWithPdf.js b/modules/ticket/back/methods/ticket/invoiceTicketsWithPdf.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/print/templates/reports/invoice/invoice.js b/print/templates/reports/invoice/invoice.js index 1c9965d3b3..4424c8ea35 100755 --- a/print/templates/reports/invoice/invoice.js +++ b/print/templates/reports/invoice/invoice.js @@ -6,7 +6,10 @@ module.exports = { name: 'invoice', mixins: [vnReport], async serverPrefetch() { + console.log(this.reference); this.invoice = await this.findOneFromDef('invoice', [this.reference]); + console.log(this.invoice); + this.checkMainEntity(this.invoice); this.client = await this.findOneFromDef('client', [this.reference]); this.taxes = await this.rawSqlFromDef(`taxes`, [this.reference]); From f3e43686a3db0f7a1e43434fd8e3396f5436b657 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 24 Aug 2023 14:59:28 +0200 Subject: [PATCH 022/449] refs #5811 feat: al borrar expedicion borrar tmb de viaexpress --- .../viaexpress-config/deleteShipment.ejs | 11 +++++ .../viaexpress-config/deleteShipment.js | 45 +++++++++++++++++++ .../deleteShipmentRenderer.js | 44 ++++++++++++++++++ modules/ticket/back/models/expedition.json | 3 ++ 4 files changed, 103 insertions(+) create mode 100644 back/methods/viaexpress-config/deleteShipment.ejs create mode 100644 back/methods/viaexpress-config/deleteShipment.js create mode 100644 back/methods/viaexpress-config/deleteShipmentRenderer.js diff --git a/back/methods/viaexpress-config/deleteShipment.ejs b/back/methods/viaexpress-config/deleteShipment.ejs new file mode 100644 index 0000000000..3be459a8d2 --- /dev/null +++ b/back/methods/viaexpress-config/deleteShipment.ejs @@ -0,0 +1,11 @@ + + + + + <%= viaexpressConfig.client %> + <%= viaexpressConfig.user %> + <%= viaexpressConfig.password %> + <%= externalId %> + + + diff --git a/back/methods/viaexpress-config/deleteShipment.js b/back/methods/viaexpress-config/deleteShipment.js new file mode 100644 index 0000000000..40509899bc --- /dev/null +++ b/back/methods/viaexpress-config/deleteShipment.js @@ -0,0 +1,45 @@ +const axios = require('axios'); +const {DOMParser} = require('xmldom'); + +module.exports = Self => { + Self.remoteMethod('deleteShipment', { + description: 'Create an expedition and return a label', + accessType: 'WRITE', + accepts: [{ + arg: 'expeditionFk', + type: 'number', + required: true + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/deleteShipment`, + verb: 'POST' + } + }); + + Self.deleteShipment = async expeditionFk => { + const models = Self.app.models; + + const viaexpressConfig = await models.ViaexpressConfig.findOne({ + fields: ['url'] + }); + + const renderedXml = await models.ViaexpressConfig.deleteShipmentRenderer(expeditionFk); + const response = await axios.post(`${viaexpressConfig.url}ServicioVxClientes.asmx`, renderedXml, { + headers: { + 'Content-Type': 'application/soap+xml; charset=utf-8' + } + }); + + const xmlString = response.data; + const parser = new DOMParser(); + const xmlDoc = parser.parseFromString(xmlString, 'text/xml'); + const resultElement = xmlDoc.getElementsByTagName('DeleteEnvioResult')[0]; + const result = resultElement.textContent; + + return result; + }; +}; diff --git a/back/methods/viaexpress-config/deleteShipmentRenderer.js b/back/methods/viaexpress-config/deleteShipmentRenderer.js new file mode 100644 index 0000000000..d9106a9ec8 --- /dev/null +++ b/back/methods/viaexpress-config/deleteShipmentRenderer.js @@ -0,0 +1,44 @@ +const fs = require('fs'); +const ejs = require('ejs'); + +module.exports = Self => { + Self.remoteMethod('deleteShipmentRenderer', { + description: 'Renders the data from an XML', + accessType: 'READ', + accepts: [{ + arg: 'expeditionFk', + type: 'number', + required: true + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/deleteShipmentRenderer`, + verb: 'GET' + } + }); + + Self.deleteShipmentRenderer = async expeditionFk => { + const models = Self.app.models; + + const viaexpressConfig = await models.ViaexpressConfig.findOne({ + fields: ['client', 'user', 'password'] + }); + + const expedition = await models.Expedition.findOne({ + fields: ['id', 'externalId'], + where: {id: expeditionFk} + }); + + const data = { + viaexpressConfig, + externalId: expedition.externalId + }; + + const template = fs.readFileSync(__dirname + '/deleteShipment.ejs', 'utf-8'); + const renderedXml = ejs.render(template, data); + return renderedXml; + }; +}; diff --git a/modules/ticket/back/models/expedition.json b/modules/ticket/back/models/expedition.json index e32a3b23d1..1ad083ce38 100644 --- a/modules/ticket/back/models/expedition.json +++ b/modules/ticket/back/models/expedition.json @@ -20,6 +20,9 @@ }, "counter": { "type": "number" + }, + "externalId": { + "type": "string" } }, "relations": { From 9da5c4c1db4d9bff39b578d943406333d33a7625 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 25 Aug 2023 10:04:27 +0200 Subject: [PATCH 023/449] refs #5918 refacotr: cambiado nombre variable --- modules/worker/front/time-control/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index 91f095334b..88bd2e92a0 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -113,21 +113,21 @@ class Controller extends Section { } isMailSended() { - const filter = { + const filterTimeControl = { where: { year: this._date.getFullYear(), week: this.getWeekNumber(this._date) }, limit: 1 }; - this.$http.get('WorkerTimeControlMails', {filter}) + this.$http.get('WorkerTimeControlMails', {filterTimeControl}) .then(res => { if (!res.data.length) { this.canResend = false; return; } - const filter = { + const filterDepartment = { where: { workerFk: this.$params.id }, @@ -135,7 +135,7 @@ class Controller extends Section { relation: 'department' } }; - this.$http.get('WorkerDepartments', {filter}) + this.$http.get('WorkerDepartments', {filterDepartment}) .then(res => { const department = res.data[0].department; if (department.isTeleworking) this.canResend = true; From d1df8009a620138e1a53de2c19ab952d725590d8 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 29 Aug 2023 10:52:05 +0200 Subject: [PATCH 024/449] refs #6023 Fix change rol bug --- back/methods/vn-user/privileges.js | 66 ++++++++++++-------- modules/account/back/methods/account/sync.js | 5 ++ 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/back/methods/vn-user/privileges.js b/back/methods/vn-user/privileges.js index 08cfaaae88..05ad4481c7 100644 --- a/back/methods/vn-user/privileges.js +++ b/back/methods/vn-user/privileges.js @@ -40,44 +40,56 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; const myOptions = {}; + let tx; if (typeof options == 'object') Object.assign(myOptions, options); - const user = await Self.findById(userId, {fields: ['hasGrant']}, myOptions); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + }; - const userToUpdate = await Self.findById(id, { - fields: ['id', 'name', 'hasGrant', 'roleFk', 'password', 'email'], - include: { - relation: 'role', - scope: { - fields: ['name'] + try { + const user = await Self.findById(userId, {fields: ['hasGrant']}, myOptions); + + const userToUpdate = await Self.findById(id, { + fields: ['id', 'name', 'hasGrant', 'roleFk', 'password', 'email'], + include: { + relation: 'role', + scope: { + fields: ['name'] + } } - } - }, myOptions); + }, myOptions); - if (!user.hasGrant) - throw new UserError(`You don't have grant privilege`); + if (!user.hasGrant) + throw new UserError(`You don't have grant privilege`); - const hasRoleFromUser = await Self.hasRole(userId, userToUpdate.role().name, myOptions); + const hasRoleFromUser = await Self.hasRole(userId, userToUpdate.role().name, myOptions); - if (!hasRoleFromUser) - throw new UserError(`You don't own the role and you can't assign it to another user`); - - if (hasGrant != null) - userToUpdate.hasGrant = hasGrant; - - if (roleFk) { - const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions); - const hasRole = await Self.hasRole(userId, role.name, myOptions); - - if (!hasRole) + if (!hasRoleFromUser) throw new UserError(`You don't own the role and you can't assign it to another user`); - userToUpdate.roleFk = roleFk; - } + if (hasGrant != null) + userToUpdate.hasGrant = hasGrant; - await userToUpdate.save(userToUpdate); - await models.Account.sync(userToUpdate.name); + if (roleFk) { + const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions); + const hasRole = await Self.hasRole(userId, role.name, myOptions); + + if (!hasRole) + throw new UserError(`You don't own the role and you can't assign it to another user`); + + userToUpdate.roleFk = roleFk; + } + + await userToUpdate.save(myOptions); + await models.Account.sync(userToUpdate.name, null, null, myOptions); + await tx.commit(); + } catch (err) { + await tx.rollback(); + throw err; + }; }; }; diff --git a/modules/account/back/methods/account/sync.js b/modules/account/back/methods/account/sync.js index a5befc22c5..3ab19eed53 100644 --- a/modules/account/back/methods/account/sync.js +++ b/modules/account/back/methods/account/sync.js @@ -30,6 +30,11 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + }; + const models = Self.app.models; const user = await models.VnUser.findOne({ fields: ['id'], From 9f6d034f9cf044f9ab688bb860bf4277d1df7bec Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 29 Aug 2023 13:45:20 +0200 Subject: [PATCH 025/449] refs #6023 Minor changes --- back/methods/vn-user/privileges.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/back/methods/vn-user/privileges.js b/back/methods/vn-user/privileges.js index 05ad4481c7..0520fd5c2c 100644 --- a/back/methods/vn-user/privileges.js +++ b/back/methods/vn-user/privileges.js @@ -86,9 +86,9 @@ module.exports = Self => { await userToUpdate.save(myOptions); await models.Account.sync(userToUpdate.name, null, null, myOptions); - await tx.commit(); + if (tx) await tx.commit(); } catch (err) { - await tx.rollback(); + if (tx) await tx.rollback(); throw err; }; }; From 0dbb77fc646f625df5432ba655c7a9da0357034e Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 31 Aug 2023 09:20:33 +0200 Subject: [PATCH 026/449] refs #6023 Transactioned sync --- modules/account/back/methods/account/sync.js | 31 +++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/modules/account/back/methods/account/sync.js b/modules/account/back/methods/account/sync.js index 3ab19eed53..c4f9cb181b 100644 --- a/modules/account/back/methods/account/sync.js +++ b/modules/account/back/methods/account/sync.js @@ -25,8 +25,10 @@ module.exports = Self => { }); Self.sync = async function(userName, password, force, options) { + const models = Self.app.models; const myOptions = {}; - + let tx; + if (typeof options == 'object') Object.assign(myOptions, options); @@ -35,16 +37,23 @@ module.exports = Self => { myOptions.transaction = tx; }; - const models = Self.app.models; - const user = await models.VnUser.findOne({ - fields: ['id'], - where: {name: userName} - }, myOptions); - const isSync = !await models.UserSync.exists(userName, myOptions); + try { + const user = await models.VnUser.findOne({ + fields: ['id'], + where: {name: userName} + }, myOptions); + const isSync = !await models.UserSync.exists(userName, myOptions); - if (!force && isSync && user) return; - await models.AccountConfig.syncUser(userName, password); - await models.UserSync.destroyById(userName, myOptions); + if (!force && isSync && user) { + if (tx) await tx.rollback(); + return; + } + await models.AccountConfig.syncUser(userName, password); + await models.UserSync.destroyById(userName, myOptions); + if (tx) await tx.commit(); + } catch (err) { + if (tx) await tx.rollback(); + throw err; + } }; }; - From 04008110f155653bf7ba1e04d31b7fbd9178d5ca Mon Sep 17 00:00:00 2001 From: guillermo Date: Mon, 4 Sep 2023 08:32:02 +0200 Subject: [PATCH 027/449] refs #6172 Change --- front/salix/module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/salix/module.js b/front/salix/module.js index f8fa0faf0b..5025eec22e 100644 --- a/front/salix/module.js +++ b/front/salix/module.js @@ -120,7 +120,7 @@ function $exceptionHandler(vnApp, $window, $state, $injector) { messageT = 'Invalid login'; break; case 403: - messageT = 'Access denied'; + messageT = (exception.data.error.message) ? exception.data.error.message : 'Access denied'; break; case 502: messageT = 'It seems that the server has fall down'; From 66e851b5ea631c021d7461d1a35ec286130ead42 Mon Sep 17 00:00:00 2001 From: pablone Date: Wed, 13 Sep 2023 19:48:58 +0200 Subject: [PATCH 028/449] refs #4131 changeStateRefactor --- .../233801/00-ACLticketTrackingState.sql | 3 + .../233801/00-ticketSetStateRefactor.sql | 69 +++++++++++++++++++ db/dump/dumpedFixtures.sql | 2 +- front/core/directives/anchor.js | 4 +- modules/claim/front/summary/index.html | 2 +- modules/claim/front/summary/index.js | 2 +- modules/claim/front/summary/index.spec.js | 4 +- .../methods/ticket-tracking/setDelivered.js | 2 +- .../ticket-tracking/specs/changeState.spec.js | 10 +-- .../{changeState.js => state.js} | 6 +- modules/ticket/back/models/ticket-tracking.js | 2 +- modules/ticket/front/sale/index.html | 4 +- modules/ticket/front/sale/index.js | 4 +- modules/ticket/front/sale/index.spec.js | 6 +- modules/ticket/front/summary/index.html | 2 +- modules/ticket/front/summary/index.js | 4 +- modules/ticket/front/summary/index.spec.js | 6 +- modules/ticket/front/tracking/edit/index.html | 2 +- modules/ticket/front/tracking/edit/index.js | 2 +- .../ticket/front/tracking/edit/index.spec.js | 2 +- modules/worker/front/time-control/index.js | 2 +- 21 files changed, 106 insertions(+), 34 deletions(-) create mode 100644 db/changes/233801/00-ACLticketTrackingState.sql create mode 100644 db/changes/233801/00-ticketSetStateRefactor.sql rename modules/ticket/back/methods/ticket-tracking/{changeState.js => state.js} (94%) diff --git a/db/changes/233801/00-ACLticketTrackingState.sql b/db/changes/233801/00-ACLticketTrackingState.sql new file mode 100644 index 0000000000..a0e3824db3 --- /dev/null +++ b/db/changes/233801/00-ACLticketTrackingState.sql @@ -0,0 +1,3 @@ +UPDATE `salix`.`ACL` + SET property = 'state' + WHERE property = 'changeState'; \ No newline at end of file diff --git a/db/changes/233801/00-ticketSetStateRefactor.sql b/db/changes/233801/00-ticketSetStateRefactor.sql new file mode 100644 index 0000000000..1ad4532994 --- /dev/null +++ b/db/changes/233801/00-ticketSetStateRefactor.sql @@ -0,0 +1,69 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setState`( + vSelf INT, + vStateCode VARCHAR(255) COLLATE utf8_general_ci +) +BEGIN +/** + * Modifica el estado de un ticket si se cumplen las condiciones necesarias. + * + * @param vSelf el id del ticket + * @param vStateCode estado a modificar del ticket + */ + DECLARE vticketAlertLevel INT; + DECLARE vTicketStateCode VARCHAR(255); + DECLARE vCanChangeState BOOL; + DECLARE vPackedAlertLevel INT; + DECLARE vOnPreparationAlertLevel INT; + DECLARE vNextAlertLevel INT; + DECLARE vZoneFk INT; + + SELECT s.alertLevel, s.`code`, s2.alertLevel, t.zoneFk + INTO vticketAlertLevel, vTicketStateCode, vNextAlertLevel , vZoneFk + FROM state s + JOIN ticketTracking tt ON tt.stateFk = s.id + JOIN state s2 ON s2.code = vStateCode + JOIN ticket t ON t.id = tt.ticketFk + WHERE tt.ticketFk = vSelf + ORDER BY tt.created DESC + LIMIT 1; + + SELECT id INTO vPackedAlertLevel FROM alertLevel WHERE code = 'PACKED'; + SELECT id INTO vOnPreparationAlertLevel + FROM alertLevel + WHERE code = 'ON_PREPARATION'; + + IF vStateCode = 'OK' AND vZoneFk IS NULL THEN + CALL util.throw('ASSIGN_ZONE_FIRST'); + END IF; + + IF vNextAlertLevel > vticketAlertLevel && + vticketAlertLevel < vOnPreparationAlertLevel + THEN + UPDATE sale + SET originalQuantity = quantity + WHERE ticketFk = vSelf; + END IF; + + SET vCanChangeState = ( + vStateCode <> 'ON_CHECKING' OR + vticketAlertLevel < vPackedAlertLevel + )AND NOT ( + vTicketStateCode IN ('CHECKED', 'CHECKING') + AND vStateCode IN ('PREPARED', 'ON_PREPARATION') + ); + + IF vCanChangeState THEN + INSERT INTO ticketTracking (stateFk, ticketFk, workerFk) + SELECT id, vSelf, account.myUser_getId() + FROM state + WHERE `code` = vStateCode COLLATE utf8_unicode_ci; + + IF vStateCode = 'PACKED' THEN + CALL ticket_doCmr(vSelf); + END IF; + ELSE + CALL util.throw('INCORRECT_TICKET_STATE'); + END IF; +END$$ +DELIMITER ; diff --git a/db/dump/dumpedFixtures.sql b/db/dump/dumpedFixtures.sql index 2e1511b590..5ff2e03efb 100644 --- a/db/dump/dumpedFixtures.sql +++ b/db/dump/dumpedFixtures.sql @@ -164,7 +164,7 @@ USE `salix`; LOCK TABLES `ACL` WRITE; /*!40000 ALTER TABLE `ACL` DISABLE KEYS */; -INSERT INTO `ACL` VALUES (3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','trainee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','trainee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','trainee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','trainee'),(30,'GreugeType','*','READ','ALLOW','ROLE','trainee'),(31,'Mandate','*','READ','ALLOW','ROLE','trainee'),(32,'MandateType','*','READ','ALLOW','ROLE','trainee'),(33,'Company','*','READ','ALLOW','ROLE','trainee'),(34,'Greuge','*','READ','ALLOW','ROLE','trainee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer'),(55,'Recovery','*','READ','ALLOW','ROLE','trainee'),(56,'Recovery','*','WRITE','ALLOW','ROLE','administrative'),(58,'CreditClassification','*','*','ALLOW','ROLE','insurance'),(60,'CreditInsurance','*','*','ALLOW','ROLE','insurance'),(61,'InvoiceOut','*','READ','ALLOW','ROLE','employee'),(63,'TicketObservation','*','*','ALLOW','ROLE','employee'),(64,'Route','*','READ','ALLOW','ROLE','employee'),(65,'Sale','*','READ','ALLOW','ROLE','employee'),(66,'TicketTracking','*','READ','ALLOW','ROLE','employee'),(68,'TicketPackaging','*','*','ALLOW','ROLE','employee'),(69,'Packaging','*','READ','ALLOW','ROLE','employee'),(70,'Packaging','*','WRITE','ALLOW','ROLE','logistic'),(72,'SaleComponent','*','READ','ALLOW','ROLE','employee'),(73,'Expedition','*','READ','ALLOW','ROLE','employee'),(74,'Expedition','*','WRITE','ALLOW','ROLE','deliveryBoss'),(75,'Expedition','*','WRITE','ALLOW','ROLE','production'),(76,'AnnualAverageInvoiced','*','READ','ALLOW','ROLE','employee'),(77,'WorkerMana','*','READ','ALLOW','ROLE','employee'),(78,'TicketTracking','*','WRITE','ALLOW','ROLE','production'),(79,'TicketTracking','changeState','*','ALLOW','ROLE','employee'),(80,'Sale','deleteSales','*','ALLOW','ROLE','employee'),(81,'Sale','moveToTicket','*','ALLOW','ROLE','employee'),(82,'Sale','updateQuantity','*','ALLOW','ROLE','employee'),(83,'Sale','updatePrice','*','ALLOW','ROLE','employee'),(84,'Sale','updateDiscount','*','ALLOW','ROLE','employee'),(85,'SaleTracking','*','READ','ALLOW','ROLE','employee'),(86,'Order','*','*','ALLOW','ROLE','employee'),(87,'OrderRow','*','*','ALLOW','ROLE','employee'),(88,'ClientContact','*','*','ALLOW','ROLE','employee'),(89,'Sale','moveToNewTicket','*','ALLOW','ROLE','employee'),(90,'Sale','reserve','*','ALLOW','ROLE','employee'),(91,'TicketWeekly','*','READ','ALLOW','ROLE','employee'),(94,'Agency','landsThatDay','*','ALLOW','ROLE','employee'),(96,'ClaimEnd','*','READ','ALLOW','ROLE','employee'),(97,'ClaimEnd','*','WRITE','ALLOW','ROLE','claimManager'),(98,'ClaimBeginning','*','*','ALLOW','ROLE','employee'),(99,'ClaimDevelopment','*','READ','ALLOW','ROLE','employee'),(100,'ClaimDevelopment','*','WRITE','ALLOW','ROLE','claimManager'),(102,'Claim','createFromSales','*','ALLOW','ROLE','employee'),(104,'Item','*','WRITE','ALLOW','ROLE','marketingBoss'),(105,'ItemBarcode','*','WRITE','ALLOW','ROLE','marketingBoss'),(106,'ItemBotanical','*','WRITE','ALLOW','ROLE','marketingBoss'),(108,'ItemPlacement','*','WRITE','ALLOW','ROLE','marketingBoss'),(109,'UserConfig','*','*','ALLOW','ROLE','employee'),(110,'Bank','*','READ','ALLOW','ROLE','trainee'),(111,'ClientLog','*','READ','ALLOW','ROLE','trainee'),(112,'Defaulter','*','READ','ALLOW','ROLE','employee'),(113,'ClientRisk','*','READ','ALLOW','ROLE','trainee'),(114,'Receipt','*','READ','ALLOW','ROLE','trainee'),(115,'Receipt','*','WRITE','ALLOW','ROLE','administrative'),(116,'BankEntity','*','*','ALLOW','ROLE','employee'),(117,'ClientSample','*','*','ALLOW','ROLE','employee'),(118,'WorkerTeam','*','*','ALLOW','ROLE','salesPerson'),(119,'Travel','*','READ','ALLOW','ROLE','employee'),(120,'Travel','*','WRITE','ALLOW','ROLE','buyer'),(121,'Item','regularize','*','ALLOW','ROLE','employee'),(122,'TicketRequest','*','*','ALLOW','ROLE','employee'),(124,'Client','confirmTransaction','WRITE','ALLOW','ROLE','administrative'),(125,'Agency','getAgenciesWithWarehouse','*','ALLOW','ROLE','employee'),(126,'Client','activeWorkersWithRole','*','ALLOW','ROLE','employee'),(127,'TicketLog','*','READ','ALLOW','ROLE','employee'),(129,'TicketService','*','*','ALLOW','ROLE','employee'),(130,'Expedition','*','WRITE','ALLOW','ROLE','packager'),(131,'CreditInsurance','*','READ','ALLOW','ROLE','trainee'),(132,'CreditClassification','*','READ','ALLOW','ROLE','trainee'),(133,'ItemTag','*','WRITE','ALLOW','ROLE','marketingBoss'),(135,'ZoneGeo','*','READ','ALLOW','ROLE','employee'),(136,'ZoneCalendar','*','READ','ALLOW','ROLE','employee'),(137,'ZoneIncluded','*','READ','ALLOW','ROLE','employee'),(138,'LabourHoliday','*','READ','ALLOW','ROLE','employee'),(139,'LabourHolidayLegend','*','READ','ALLOW','ROLE','employee'),(140,'LabourHolidayType','*','READ','ALLOW','ROLE','employee'),(141,'Zone','*','*','ALLOW','ROLE','logisticBoss'),(142,'ZoneCalendar','*','WRITE','ALLOW','ROLE','deliveryBoss'),(143,'ZoneIncluded','*','*','ALLOW','ROLE','deliveryBoss'),(144,'Stowaway','*','*','ALLOW','ROLE','employee'),(145,'Ticket','getPossibleStowaways','READ','ALLOW','ROLE','employee'),(147,'UserConfigView','*','*','ALLOW','ROLE','employee'),(148,'UserConfigView','*','*','ALLOW','ROLE','employee'),(149,'Sip','*','READ','ALLOW','ROLE','employee'),(150,'Sip','*','WRITE','ALLOW','ROLE','hr'),(151,'Department','*','READ','ALLOW','ROLE','employee'),(152,'Department','*','WRITE','ALLOW','ROLE','hr'),(153,'Route','*','READ','ALLOW','ROLE','employee'),(154,'Route','*','WRITE','ALLOW','ROLE','delivery'),(155,'Calendar','*','READ','ALLOW','ROLE','hr'),(156,'WorkerLabour','*','READ','ALLOW','ROLE','hr'),(157,'Calendar','absences','READ','ALLOW','ROLE','employee'),(158,'ItemTag','*','WRITE','ALLOW','ROLE','accessory'),(160,'TicketServiceType','*','READ','ALLOW','ROLE','employee'),(161,'TicketConfig','*','READ','ALLOW','ROLE','employee'),(162,'InvoiceOut','delete','WRITE','ALLOW','ROLE','invoicing'),(163,'InvoiceOut','book','WRITE','ALLOW','ROLE','invoicing'),(165,'TicketDms','*','*','ALLOW','ROLE','employee'),(167,'Worker','isSubordinate','READ','ALLOW','ROLE','employee'),(168,'Worker','mySubordinates','READ','ALLOW','ROLE','employee'),(169,'WorkerTimeControl','filter','READ','ALLOW','ROLE','employee'),(170,'WorkerTimeControl','addTime','WRITE','ALLOW','ROLE','employee'),(171,'TicketServiceType','*','WRITE','ALLOW','ROLE','administrative'),(172,'Sms','*','READ','ALLOW','ROLE','employee'),(173,'Sms','send','WRITE','ALLOW','ROLE','employee'),(176,'Device','*','*','ALLOW','ROLE','employee'),(177,'Device','*','*','ALLOW','ROLE','employee'),(178,'WorkerTimeControl','*','*','ALLOW','ROLE','employee'),(179,'ItemLog','*','READ','ALLOW','ROLE','employee'),(180,'RouteLog','*','READ','ALLOW','ROLE','employee'),(181,'Dms','removeFile','WRITE','ALLOW','ROLE','employee'),(182,'Dms','uploadFile','WRITE','ALLOW','ROLE','employee'),(183,'Dms','downloadFile','READ','ALLOW','ROLE','employee'),(184,'Client','uploadFile','WRITE','ALLOW','ROLE','employee'),(185,'ClientDms','removeFile','WRITE','ALLOW','ROLE','employee'),(186,'ClientDms','*','READ','ALLOW','ROLE','trainee'),(187,'Ticket','uploadFile','WRITE','ALLOW','ROLE','employee'),(190,'Route','updateVolume','WRITE','ALLOW','ROLE','deliveryBoss'),(191,'Agency','getLanded','READ','ALLOW','ROLE','employee'),(192,'Agency','getShipped','READ','ALLOW','ROLE','employee'),(194,'Postcode','*','WRITE','ALLOW','ROLE','deliveryBoss'),(195,'Ticket','addSale','WRITE','ALLOW','ROLE','employee'),(196,'Dms','updateFile','WRITE','ALLOW','ROLE','employee'),(197,'Dms','*','READ','ALLOW','ROLE','trainee'),(198,'ClaimDms','removeFile','WRITE','ALLOW','ROLE','employee'),(199,'ClaimDms','*','READ','ALLOW','ROLE','employee'),(200,'Claim','uploadFile','WRITE','ALLOW','ROLE','employee'),(201,'Sale','updateConcept','WRITE','ALLOW','ROLE','employee'),(202,'Claim','updateClaimAction','WRITE','ALLOW','ROLE','claimManager'),(203,'UserPhone','*','*','ALLOW','ROLE','employee'),(204,'WorkerDms','removeFile','WRITE','ALLOW','ROLE','hr'),(205,'WorkerDms','*','READ','ALLOW','ROLE','hr'),(206,'Chat','*','*','ALLOW','ROLE','employee'),(207,'Chat','sendMessage','*','ALLOW','ROLE','employee'),(208,'Sale','recalculatePrice','WRITE','ALLOW','ROLE','employee'),(209,'Ticket','recalculateComponents','WRITE','ALLOW','ROLE','employee'),(211,'TravelLog','*','READ','ALLOW','ROLE','buyer'),(212,'Thermograph','*','*','ALLOW','ROLE','buyer'),(213,'TravelThermograph','*','WRITE','ALLOW','ROLE','buyer'),(214,'Entry','*','*','ALLOW','ROLE','buyer'),(215,'TicketWeekly','*','WRITE','ALLOW','ROLE','buyer'),(216,'TravelThermograph','*','READ','ALLOW','ROLE','employee'),(218,'Intrastat','*','*','ALLOW','ROLE','buyer'),(221,'UserConfig','getUserConfig','READ','ALLOW','ROLE','account'),(222,'Client','*','READ','ALLOW','ROLE','trainee'),(226,'ClientObservation','*','READ','ALLOW','ROLE','trainee'),(227,'Address','*','READ','ALLOW','ROLE','trainee'),(228,'AddressObservation','*','READ','ALLOW','ROLE','trainee'),(230,'ClientCredit','*','READ','ALLOW','ROLE','trainee'),(231,'ClientContact','*','READ','ALLOW','ROLE','trainee'),(232,'ClientSample','*','READ','ALLOW','ROLE','trainee'),(233,'EntryLog','*','READ','ALLOW','ROLE','buyer'),(234,'WorkerLog','find','READ','ALLOW','ROLE','hr'),(235,'CustomsAgent','*','*','ALLOW','ROLE','employee'),(236,'Buy','*','*','ALLOW','ROLE','buyer'),(237,'WorkerDms','filter','*','ALLOW','ROLE','employee'),(238,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(239,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(240,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(241,'SupplierContact','*','WRITE','ALLOW','ROLE','administrative'),(242,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(244,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(248,'RoleMapping','*','READ','ALLOW','ROLE','account'),(249,'UserPassword','*','READ','ALLOW','ROLE','account'),(250,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(251,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(252,'Supplier','*','READ','ALLOW','ROLE','employee'),(253,'Supplier','*','WRITE','ALLOW','ROLE','administrative'),(254,'SupplierLog','*','READ','ALLOW','ROLE','employee'),(256,'Image','*','WRITE','ALLOW','ROLE','employee'),(257,'FixedPrice','*','*','ALLOW','ROLE','buyer'),(258,'PayDem','*','READ','ALLOW','ROLE','employee'),(259,'Client','createReceipt','*','ALLOW','ROLE','salesAssistant'),(260,'PrintServerQueue','*','WRITE','ALLOW','ROLE','employee'),(261,'SupplierAccount','*','*','ALLOW','ROLE','administrative'),(262,'Entry','*','*','ALLOW','ROLE','administrative'),(263,'InvoiceIn','*','*','ALLOW','ROLE','administrative'),(264,'StarredModule','*','*','ALLOW','ROLE','employee'),(265,'ItemBotanical','*','WRITE','ALLOW','ROLE','logisticBoss'),(266,'ZoneLog','*','READ','ALLOW','ROLE','employee'),(267,'Genus','*','WRITE','ALLOW','ROLE','logisticBoss'),(268,'Specie','*','WRITE','ALLOW','ROLE','logisticBoss'),(269,'InvoiceOut','createPdf','WRITE','ALLOW','ROLE','employee'),(270,'SupplierAddress','*','*','ALLOW','ROLE','employee'),(271,'SalesMonitor','*','*','ALLOW','ROLE','employee'),(272,'InvoiceInLog','*','READ','ALLOW','ROLE','employee'),(273,'InvoiceInTax','*','*','ALLOW','ROLE','administrative'),(274,'InvoiceInLog','*','READ','ALLOW','ROLE','administrative'),(275,'InvoiceOut','createManualInvoice','WRITE','ALLOW','ROLE','invoicing'),(276,'InvoiceOut','globalInvoicing','WRITE','ALLOW','ROLE','invoicing'),(278,'RoleInherit','*','WRITE','ALLOW','ROLE','grant'),(279,'MailAlias','*','*','ALLOW','ROLE','marketing'),(283,'EntryObservation','*','*','ALLOW','ROLE','buyer'),(284,'LdapConfig','*','*','ALLOW','ROLE','sysadmin'),(285,'SambaConfig','*','*','ALLOW','ROLE','sysadmin'),(286,'ACL','*','*','ALLOW','ROLE','developer'),(287,'AccessToken','*','*','ALLOW','ROLE','developer'),(293,'RoleInherit','*','*','ALLOW','ROLE','it'),(294,'RoleRole','*','*','ALLOW','ROLE','it'),(295,'AccountConfig','*','*','ALLOW','ROLE','sysadmin'),(296,'Collection','*','READ','ALLOW','ROLE','employee'),(297,'Sale','refund','WRITE','ALLOW','ROLE','invoicing'),(298,'InvoiceInDueDay','*','*','ALLOW','ROLE','administrative'),(299,'Collection','setSaleQuantity','*','ALLOW','ROLE','employee'),(302,'AgencyTerm','*','*','ALLOW','ROLE','administrative'),(303,'ClaimLog','*','READ','ALLOW','ROLE','claimManager'),(304,'Edi','updateData','WRITE','ALLOW','ROLE','employee'),(305,'EducationLevel','*','*','ALLOW','ROLE','employee'),(306,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(307,'SupplierAgencyTerm','*','*','ALLOW','ROLE','administrative'),(308,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(309,'Zone','getZoneClosing','*','ALLOW','ROLE','employee'),(310,'ExpeditionState','*','READ','ALLOW','ROLE','employee'),(311,'Expense','*','READ','ALLOW','ROLE','employee'),(312,'Expense','*','WRITE','ALLOW','ROLE','administrative'),(314,'SupplierActivity','*','READ','ALLOW','ROLE','employee'),(315,'SupplierActivity','*','WRITE','ALLOW','ROLE','administrative'),(316,'Dms','deleteTrashFiles','WRITE','ALLOW','ROLE','employee'),(317,'ClientUnpaid','*','*','ALLOW','ROLE','administrative'),(318,'MdbVersion','*','*','ALLOW','ROLE','developer'),(319,'ItemType','*','READ','ALLOW','ROLE','employee'),(320,'ItemType','*','WRITE','ALLOW','ROLE','buyer'),(321,'InvoiceOut','refund','WRITE','ALLOW','ROLE','invoicing'),(322,'InvoiceOut','refund','WRITE','ALLOW','ROLE','salesAssistant'),(323,'InvoiceOut','refund','WRITE','ALLOW','ROLE','claimManager'),(324,'Ticket','refund','WRITE','ALLOW','ROLE','invoicing'),(325,'Ticket','refund','WRITE','ALLOW','ROLE','salesAssistant'),(326,'Ticket','refund','WRITE','ALLOW','ROLE','claimManager'),(327,'Sale','refund','WRITE','ALLOW','ROLE','salesAssistant'),(328,'Sale','refund','WRITE','ALLOW','ROLE','claimManager'),(329,'TicketRefund','*','WRITE','ALLOW','ROLE','invoicing'),(330,'ClaimObservation','*','WRITE','ALLOW','ROLE','salesPerson'),(331,'ClaimObservation','*','READ','ALLOW','ROLE','salesPerson'),(332,'Client','setPassword','WRITE','ALLOW','ROLE','salesPerson'),(333,'Client','updateUser','WRITE','ALLOW','ROLE','salesPerson'),(334,'ShelvingLog','*','READ','ALLOW','ROLE','employee'),(335,'ZoneExclusionGeo','*','READ','ALLOW','ROLE','employee'),(336,'ZoneExclusionGeo','*','WRITE','ALLOW','ROLE','deliveryBoss'),(337,'Parking','*','*','ALLOW','ROLE','employee'),(338,'Shelving','*','*','ALLOW','ROLE','employee'),(339,'OsTicket','*','*','ALLOW','ROLE','employee'),(340,'OsTicketConfig','*','*','ALLOW','ROLE','it'),(341,'ClientConsumptionQueue','*','WRITE','ALLOW','ROLE','employee'),(342,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','employee'),(343,'Ticket','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(344,'Ticket','deliveryNoteCsvPdf','READ','ALLOW','ROLE','employee'),(345,'Ticket','deliveryNoteCsvEmail','READ','ALLOW','ROLE','employee'),(346,'Client','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(347,'Client','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(348,'Client','clientWelcomeHtml','READ','ALLOW','ROLE','employee'),(349,'Client','clientWelcomeEmail','WRITE','ALLOW','ROLE','employee'),(350,'Client','creditRequestPdf','READ','ALLOW','ROLE','employee'),(351,'Client','creditRequestHtml','READ','ALLOW','ROLE','employee'),(352,'Client','creditRequestEmail','WRITE','ALLOW','ROLE','employee'),(353,'Client','printerSetupHtml','READ','ALLOW','ROLE','employee'),(354,'Client','printerSetupEmail','WRITE','ALLOW','ROLE','employee'),(355,'Client','sepaCoreEmail','WRITE','ALLOW','ROLE','employee'),(356,'Client','letterDebtorPdf','READ','ALLOW','ROLE','employee'),(357,'Client','letterDebtorStHtml','READ','ALLOW','ROLE','employee'),(358,'Client','letterDebtorStEmail','WRITE','ALLOW','ROLE','employee'),(359,'Client','letterDebtorNdHtml','READ','ALLOW','ROLE','employee'),(360,'Client','letterDebtorNdEmail','WRITE','ALLOW','ROLE','employee'),(361,'Client','clientDebtStatementPdf','READ','ALLOW','ROLE','employee'),(362,'Client','clientDebtStatementHtml','READ','ALLOW','ROLE','employee'),(363,'Client','clientDebtStatementEmail','WRITE','ALLOW','ROLE','employee'),(364,'Client','incotermsAuthorizationPdf','READ','ALLOW','ROLE','employee'),(365,'Client','incotermsAuthorizationHtml','READ','ALLOW','ROLE','employee'),(366,'Client','incotermsAuthorizationEmail','WRITE','ALLOW','ROLE','employee'),(367,'Client','consumptionSendQueued','WRITE','ALLOW','ROLE','system'),(368,'InvoiceOut','invoiceEmail','WRITE','ALLOW','ROLE','employee'),(369,'InvoiceOut','exportationPdf','READ','ALLOW','ROLE','employee'),(370,'InvoiceOut','sendQueued','WRITE','ALLOW','ROLE','system'),(371,'Ticket','invoiceCsvPdf','READ','ALLOW','ROLE','employee'),(372,'Ticket','invoiceCsvEmail','WRITE','ALLOW','ROLE','employee'),(373,'Supplier','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(374,'Supplier','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(375,'Travel','extraCommunityPdf','READ','ALLOW','ROLE','employee'),(376,'Travel','extraCommunityEmail','WRITE','ALLOW','ROLE','employee'),(377,'Entry','entryOrderPdf','READ','ALLOW','ROLE','employee'),(378,'OsTicket','osTicketReportEmail','WRITE','ALLOW','ROLE','system'),(379,'Item','buyerWasteEmail','WRITE','ALLOW','ROLE','system'),(380,'Claim','claimPickupPdf','READ','ALLOW','ROLE','employee'),(381,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','claimManager'),(382,'Item','labelPdf','READ','ALLOW','ROLE','employee'),(383,'Sector','*','READ','ALLOW','ROLE','employee'),(384,'Sector','*','WRITE','ALLOW','ROLE','employee'),(385,'Route','driverRoutePdf','READ','ALLOW','ROLE','employee'),(386,'Route','driverRouteEmail','WRITE','ALLOW','ROLE','employee'),(387,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','customer'),(388,'Supplier','newSupplier','WRITE','ALLOW','ROLE','administrative'),(389,'ClaimRma','*','READ','ALLOW','ROLE','claimManager'),(390,'ClaimRma','*','WRITE','ALLOW','ROLE','claimManager'),(391,'Notification','*','WRITE','ALLOW','ROLE','system'),(392,'Boxing','*','*','ALLOW','ROLE','employee'),(393,'Url','*','READ','ALLOW','ROLE','employee'),(394,'Url','*','WRITE','ALLOW','ROLE','it'),(395,'ItemShelving','*','READ','ALLOW','ROLE','employee'),(396,'ItemShelving','*','WRITE','ALLOW','ROLE','production'),(397,'ItemShelvingPlacementSupplyStock','*','READ','ALLOW','ROLE','employee'),(398,'NotificationQueue','*','*','ALLOW','ROLE','employee'),(399,'InvoiceOut','clientsToInvoice','WRITE','ALLOW','ROLE','invoicing'),(400,'InvoiceOut','invoiceClient','WRITE','ALLOW','ROLE','invoicing'),(401,'Sale','editTracked','WRITE','ALLOW','ROLE','production'),(402,'Sale','editFloramondo','WRITE','ALLOW','ROLE','salesAssistant'),(403,'Receipt','balanceCompensationEmail','WRITE','ALLOW','ROLE','employee'),(404,'Receipt','balanceCompensationPdf','READ','ALLOW','ROLE','employee'),(405,'Ticket','getTicketsFuture','READ','ALLOW','ROLE','employee'),(406,'Ticket','merge','WRITE','ALLOW','ROLE','employee'),(407,'Sale','editFloramondo','WRITE','ALLOW','ROLE','logistic'),(408,'ZipConfig','*','*','ALLOW','ROLE','employee'),(409,'Item','*','WRITE','ALLOW','ROLE','administrative'),(410,'Sale','editCloned','WRITE','ALLOW','ROLE','buyer'),(411,'Sale','editCloned','WRITE','ALLOW','ROLE','salesAssistant'),(414,'MdbVersion','*','READ','ALLOW','ROLE','$everyone'),(416,'TicketLog','getChanges','READ','ALLOW','ROLE','employee'),(417,'Ticket','getTicketsAdvance','READ','ALLOW','ROLE','employee'),(418,'EntryLog','*','READ','ALLOW','ROLE','administrative'),(419,'Sale','editTracked','WRITE','ALLOW','ROLE','buyer'),(420,'MdbBranch','*','READ','ALLOW','ROLE','$everyone'),(421,'ItemShelvingSale','*','*','ALLOW','ROLE','employee'),(422,'Docuware','checkFile','READ','ALLOW','ROLE','employee'),(423,'Docuware','download','READ','ALLOW','ROLE','salesPerson'),(424,'Docuware','upload','WRITE','ALLOW','ROLE','productionAssi'),(425,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','salesPerson'),(426,'TpvTransaction','confirm','WRITE','ALLOW','ROLE','$everyone'),(427,'TpvTransaction','start','WRITE','ALLOW','ROLE','$authenticated'),(428,'TpvTransaction','end','WRITE','ALLOW','ROLE','$authenticated'),(429,'ItemConfig','*','READ','ALLOW','ROLE','employee'),(431,'Tag','onSubmit','WRITE','ALLOW','ROLE','employee'),(432,'Worker','updateAttributes','WRITE','ALLOW','ROLE','hr'),(433,'Worker','createAbsence','*','ALLOW','ROLE','employee'),(434,'Worker','updateAbsence','WRITE','ALLOW','ROLE','employee'),(435,'Worker','deleteAbsence','*','ALLOW','ROLE','employee'),(436,'Worker','new','WRITE','ALLOW','ROLE','hr'),(438,'Client','getClientOrSupplierReference','READ','ALLOW','ROLE','employee'),(439,'NotificationSubscription','*','*','ALLOW','ROLE','employee'),(440,'NotificationAcl','*','READ','ALLOW','ROLE','employee'),(441,'MdbApp','*','READ','ALLOW','ROLE','$everyone'),(442,'MdbApp','*','*','ALLOW','ROLE','developer'),(443,'ItemConfig','*','*','ALLOW','ROLE','employee'),(444,'DeviceProduction','*','*','ALLOW','ROLE','hr'),(445,'DeviceProductionModels','*','*','ALLOW','ROLE','hr'),(446,'DeviceProductionState','*','*','ALLOW','ROLE','hr'),(447,'DeviceProductionUser','*','*','ALLOW','ROLE','hr'),(448,'DeviceProduction','*','*','ALLOW','ROLE','productionAssi'),(449,'DeviceProductionModels','*','*','ALLOW','ROLE','productionAssi'),(450,'DeviceProductionState','*','*','ALLOW','ROLE','productionAssi'),(451,'DeviceProductionUser','*','*','ALLOW','ROLE','productionAssi'),(452,'Worker','deallocatePDA','*','ALLOW','ROLE','hr'),(453,'Worker','allocatePDA','*','ALLOW','ROLE','hr'),(454,'Worker','deallocatePDA','*','ALLOW','ROLE','productionAssi'),(455,'Worker','allocatePDA','*','ALLOW','ROLE','productionAssi'),(456,'Zone','*','*','ALLOW','ROLE','deliveryBoss'),(457,'Account','setPassword','WRITE','ALLOW','ROLE','itManagement'),(458,'Operator','*','READ','ALLOW','ROLE','employee'),(459,'Operator','*','WRITE','ALLOW','ROLE','employee'),(460,'InvoiceIn','getSerial','READ','ALLOW','ROLE','administrative'),(461,'Ticket','saveSign','WRITE','ALLOW','ROLE','employee'),(462,'InvoiceOut','negativeBases','READ','ALLOW','ROLE','administrative'),(463,'InvoiceOut','negativeBasesCsv','READ','ALLOW','ROLE','administrative'),(464,'WorkerObservation','*','*','ALLOW','ROLE','hr'),(465,'ClientInforma','*','READ','ALLOW','ROLE','employee'),(466,'ClientInforma','*','WRITE','ALLOW','ROLE','financial'),(467,'Receipt','receiptEmail','*','ALLOW','ROLE','salesAssistant'),(468,'Client','setRating','WRITE','ALLOW','ROLE','financial'),(469,'Client','*','READ','ALLOW','ROLE','employee'),(470,'Client','addressesPropagateRe','*','ALLOW','ROLE','employee'),(471,'Client','canBeInvoiced','*','ALLOW','ROLE','employee'),(472,'Client','canCreateTicket','*','ALLOW','ROLE','employee'),(473,'Client','consumption','*','ALLOW','ROLE','employee'),(474,'Client','createAddress','*','ALLOW','ROLE','employee'),(475,'Client','createWithUser','*','ALLOW','ROLE','employee'),(476,'Client','extendedListFilter','*','ALLOW','ROLE','employee'),(477,'Client','getAverageInvoiced','*','ALLOW','ROLE','employee'),(478,'Client','getCard','*','ALLOW','ROLE','employee'),(479,'Client','getDebt','*','ALLOW','ROLE','employee'),(480,'Client','getMana','*','ALLOW','ROLE','employee'),(481,'Client','transactions','*','ALLOW','ROLE','employee'),(482,'Client','hasCustomerRole','*','ALLOW','ROLE','employee'),(483,'Client','isValidClient','*','ALLOW','ROLE','employee'),(484,'Client','lastActiveTickets','*','ALLOW','ROLE','employee'),(485,'Client','sendSms','*','ALLOW','ROLE','employee'),(486,'Client','setPassword','*','ALLOW','ROLE','employee'),(487,'Client','summary','*','ALLOW','ROLE','employee'),(488,'Client','updateAddress','*','ALLOW','ROLE','employee'),(489,'Client','updateFiscalData','*','ALLOW','ROLE','employee'),(491,'Client','uploadFile','*','ALLOW','ROLE','employee'),(492,'Client','campaignMetricsPdf','*','ALLOW','ROLE','employee'),(493,'Client','campaignMetricsEmail','*','ALLOW','ROLE','employee'),(494,'Client','clientWelcomeHtml','*','ALLOW','ROLE','employee'),(495,'Client','clientWelcomeEmail','*','ALLOW','ROLE','employee'),(496,'Client','printerSetupHtml','*','ALLOW','ROLE','employee'),(497,'Client','printerSetupEmail','*','ALLOW','ROLE','employee'),(498,'Client','sepaCoreEmail','*','ALLOW','ROLE','employee'),(499,'Client','letterDebtorPdf','*','ALLOW','ROLE','employee'),(500,'Client','letterDebtorStHtml','*','ALLOW','ROLE','employee'),(501,'Client','letterDebtorStEmail','*','ALLOW','ROLE','employee'),(502,'Client','letterDebtorNdHtml','*','ALLOW','ROLE','employee'),(503,'Client','letterDebtorNdEmail','*','ALLOW','ROLE','employee'),(504,'Client','clientDebtStatementPdf','*','ALLOW','ROLE','employee'),(505,'Client','clientDebtStatementHtml','*','ALLOW','ROLE','employee'),(506,'Client','clientDebtStatementEmail','*','ALLOW','ROLE','employee'),(507,'Client','creditRequestPdf','*','ALLOW','ROLE','employee'),(508,'Client','creditRequestHtml','*','ALLOW','ROLE','employee'),(509,'Client','creditRequestEmail','*','ALLOW','ROLE','employee'),(510,'Client','incotermsAuthorizationPdf','*','ALLOW','ROLE','employee'),(511,'Client','incotermsAuthorizationHtml','*','ALLOW','ROLE','employee'),(512,'Client','incotermsAuthorizationEmail','*','ALLOW','ROLE','employee'),(513,'Client','consumptionSendQueued','*','ALLOW','ROLE','employee'),(514,'Client','filter','*','ALLOW','ROLE','employee'),(515,'Client','getClientOrSupplierReference','*','ALLOW','ROLE','employee'),(516,'Client','upsert','*','ALLOW','ROLE','employee'),(517,'Client','create','*','ALLOW','ROLE','employee'),(518,'Client','replaceById','*','ALLOW','ROLE','employee'),(519,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(520,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(521,'Client','deleteById','*','ALLOW','ROLE','employee'),(522,'Client','replaceOrCreate','*','ALLOW','ROLE','employee'),(523,'Client','updateAll','*','ALLOW','ROLE','employee'),(524,'Client','upsertWithWhere','*','ALLOW','ROLE','employee'),(525,'Defaulter','observationEmail','WRITE','ALLOW','ROLE','employee'),(527,'VnUser','acl','READ','ALLOW','ROLE','account'),(528,'VnUser','getCurrentUserData','READ','ALLOW','ROLE','account'),(530,'Account','exists','READ','ALLOW','ROLE','account'),(531,'Account','exists','READ','ALLOW','ROLE','account'),(532,'UserLog','*','READ','ALLOW','ROLE','employee'),(533,'RoleLog','*','READ','ALLOW','ROLE','employee'),(534,'WagonType','*','*','ALLOW','ROLE','productionAssi'),(535,'WagonTypeColor','*','*','ALLOW','ROLE','productionAssi'),(536,'WagonTypeTray','*','*','ALLOW','ROLE','productionAssi'),(537,'WagonConfig','*','*','ALLOW','ROLE','productionAssi'),(538,'CollectionWagon','*','*','ALLOW','ROLE','productionAssi'),(539,'CollectionWagonTicket','*','*','ALLOW','ROLE','productionAssi'),(540,'Wagon','*','*','ALLOW','ROLE','productionAssi'),(541,'WagonType','createWagonType','*','ALLOW','ROLE','productionAssi'),(542,'WagonType','deleteWagonType','*','ALLOW','ROLE','productionAssi'),(543,'WagonType','editWagonType','*','ALLOW','ROLE','productionAssi'),(544,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(545,'Agency','find','READ','ALLOW','ROLE','employee'),(546,'Agency','seeExpired','READ','ALLOW','ROLE','coolerAssist'),(547,'WorkerLog','models','READ','ALLOW','ROLE','hr'),(548,'Ticket','editDiscount','WRITE','ALLOW','ROLE','claimManager'),(549,'Ticket','editDiscount','WRITE','ALLOW','ROLE','salesPerson'),(550,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','salesAssistant'),(551,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','deliveryBoss'),(552,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','buyer'),(553,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','claimManager'),(554,'Ticket','deleteTicketWithPartPrepared','WRITE','ALLOW','ROLE','salesAssistant'),(555,'Ticket','editZone','WRITE','ALLOW','ROLE','deliveryBoss'),(556,'State','editableStates','READ','ALLOW','ROLE','employee'),(557,'State','seeEditableStates','READ','ALLOW','ROLE','administrative'),(558,'State','seeEditableStates','READ','ALLOW','ROLE','production'),(559,'State','isSomeEditable','READ','ALLOW','ROLE','salesPerson'),(560,'State','isAllEditable','READ','ALLOW','ROLE','production'),(561,'State','isAllEditable','READ','ALLOW','ROLE','administrative'),(562,'Agency','seeExpired','READ','ALLOW','ROLE','administrative'),(563,'Agency','seeExpired','READ','ALLOW','ROLE','productionBoss'),(564,'Claim','createAfterDeadline','WRITE','ALLOW','ROLE','claimManager'),(565,'Client','editAddressLogifloraAllowed','WRITE','ALLOW','ROLE','salesAssistant'),(566,'Client','editFiscalDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(567,'Client','editVerifiedDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(568,'Client','editCredit','WRITE','ALLOW','ROLE','financialBoss'),(569,'Client','zeroCreditEditor','WRITE','ALLOW','ROLE','financialBoss'),(570,'InvoiceOut','canCreatePdf','WRITE','ALLOW','ROLE','invoicing'),(571,'Supplier','editPayMethodCheck','WRITE','ALLOW','ROLE','financial'),(572,'Worker','isTeamBoss','WRITE','ALLOW','ROLE','teamBoss'),(573,'Worker','forceIsSubordinate','READ','ALLOW','ROLE','hr'),(574,'Claim','editState','WRITE','ALLOW','ROLE','claimManager'),(575,'Claim','find','READ','ALLOW','ROLE','salesPerson'),(576,'Claim','findById','READ','ALLOW','ROLE','salesPerson'),(577,'Claim','findOne','READ','ALLOW','ROLE','salesPerson'),(578,'Claim','getSummary','READ','ALLOW','ROLE','salesPerson'),(579,'Claim','updateClaim','WRITE','ALLOW','ROLE','salesPerson'),(580,'Claim','regularizeClaim','WRITE','ALLOW','ROLE','claimManager'),(581,'Claim','updateClaimDestination','WRITE','ALLOW','ROLE','claimManager'),(582,'Claim','downloadFile','READ','ALLOW','ROLE','claimManager'),(583,'Claim','deleteById','WRITE','ALLOW','ROLE','claimManager'),(584,'Claim','filter','READ','ALLOW','ROLE','salesPerson'),(585,'Claim','logs','READ','ALLOW','ROLE','claimManager'),(586,'Ticket','find','READ','ALLOW','ROLE','employee'),(587,'Ticket','findById','READ','ALLOW','ROLE','employee'),(588,'Ticket','findOne','READ','ALLOW','ROLE','employee'),(589,'Ticket','getVolume','READ','ALLOW','ROLE','employee'),(590,'Ticket','getTotalVolume','READ','ALLOW','ROLE','employee'),(591,'Ticket','summary','READ','ALLOW','ROLE','employee'),(592,'Ticket','priceDifference','READ','ALLOW','ROLE','employee'),(593,'Ticket','componentUpdate','WRITE','ALLOW','ROLE','employee'),(594,'Ticket','new','WRITE','ALLOW','ROLE','employee'),(595,'Ticket','isEditable','READ','ALLOW','ROLE','employee'),(596,'Ticket','setDeleted','WRITE','ALLOW','ROLE','salesPerson'),(597,'Ticket','restore','WRITE','ALLOW','ROLE','employee'),(598,'Ticket','getSales','READ','ALLOW','ROLE','employee'),(599,'Ticket','getSalesPersonMana','READ','ALLOW','ROLE','employee'),(600,'Ticket','filter','READ','ALLOW','ROLE','employee'),(601,'Ticket','makeInvoice','WRITE','ALLOW','ROLE','employee'),(602,'Ticket','updateEditableTicket','WRITE','ALLOW','ROLE','employee'),(603,'Ticket','updateDiscount','WRITE','ALLOW','ROLE','employee'),(604,'Ticket','transferSales','WRITE','ALLOW','ROLE','employee'),(605,'Ticket','sendSms','WRITE','ALLOW','ROLE','employee'),(606,'Ticket','isLocked','READ','ALLOW','ROLE','employee'),(607,'Ticket','freightCost','READ','ALLOW','ROLE','employee'),(608,'Ticket','getComponentsSum','READ','ALLOW','ROLE','employee'),(609,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','delivery'),(610,'Ticket','deliveryNoteCsv','READ','ALLOW','ROLE','employee'),(611,'State','find','READ','ALLOW','ROLE','employee'),(612,'State','findById','READ','ALLOW','ROLE','employee'),(613,'State','findOne','READ','ALLOW','ROLE','employee'),(614,'Worker','find','READ','ALLOW','ROLE','employee'),(615,'Worker','findById','READ','ALLOW','ROLE','employee'),(616,'Worker','findOne','READ','ALLOW','ROLE','employee'),(617,'Worker','filter','READ','ALLOW','ROLE','employee'),(618,'Worker','getWorkedHours','READ','ALLOW','ROLE','employee'),(619,'Worker','active','READ','ALLOW','ROLE','employee'),(620,'Worker','activeWithRole','READ','ALLOW','ROLE','employee'),(621,'Worker','uploadFile','WRITE','ALLOW','ROLE','hr'),(622,'Worker','contracts','READ','ALLOW','ROLE','employee'),(623,'Worker','holidays','READ','ALLOW','ROLE','employee'),(624,'Worker','activeContract','READ','ALLOW','ROLE','employee'),(625,'Worker','activeWithInheritedRole','READ','ALLOW','ROLE','employee'),(626,'Ticket','collectionLabel','READ','ALLOW','ROLE','employee'),(628,'Ticket','expeditionPalletLabel','READ','ALLOW','ROLE','employee'),(629,'Ticket','editDiscount','WRITE','ALLOW','ROLE','artificialBoss'),(630,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesTeamBoss'),(635,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','administrative'),(636,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesPerson'),(637,'Claim','downloadFile','READ','ALLOW','ROLE','salesPerson'),(638,'Agency','seeExpired','READ','ALLOW','ROLE','artificialBoss'),(639,'Agency','seeExpired','READ','ALLOW','ROLE','logisticAssistant'),(640,'Claim','filter','READ','ALLOW','ROLE','buyer'),(641,'Claim','find','READ','ALLOW','ROLE','buyer'),(642,'Claim','findById','READ','ALLOW','ROLE','buyer'),(643,'Claim','getSummary','READ','ALLOW','ROLE','buyer'),(644,'Claim','filter','READ','ALLOW','ROLE','handmadeBoss'),(645,'Claim','find','READ','ALLOW','ROLE','handmadeBoss'),(646,'Claim','findById','READ','ALLOW','ROLE','handmadeBoss'),(647,'Claim','getSummary','READ','ALLOW','ROLE','handmadeBoss'),(648,'Claim','__get__lines','READ','ALLOW','ROLE','claimManager'),(649,'Claim','__get__lines','READ','ALLOW','ROLE','salesPerson'),(650,'Claim','getSummary','READ','ALLOW','ROLE','deliveryBoss'),(651,'Claim','findById','READ','ALLOW','ROLE','deliveryBoss'),(652,'Claim','find','READ','ALLOW','ROLE','deliveryBoss'),(653,'Claim','filter','READ','ALLOW','ROLE','deliveryBoss'),(654,'Ticket','editZone','WRITE','ALLOW','ROLE','logisticAssistant'),(655,'Entry','addFromPackaging','WRITE','ALLOW','ROLE','production'),(656,'Entry','addFromBuy','WRITE','ALLOW','ROLE','production'),(657,'Supplier','getItemsPackaging','READ','ALLOW','ROLE','production'),(658,'Ticket','closeAll','WRITE','ALLOW','ROLE','system'),(659,'Account','*','*','ALLOW','ROLE','itManagement'),(660,'Account','*','READ','ALLOW','ROLE','employee'),(664,'MailForward','*','*','ALLOW','ROLE','itManagement'),(665,'Role','*','READ','ALLOW','ROLE','employee'),(666,'Role','*','WRITE','ALLOW','ROLE','it'),(667,'VnUser','*','*','ALLOW','ROLE','itManagement'),(668,'VnUser','__get__preview','READ','ALLOW','ROLE','employee'),(669,'VnUser','preview','*','ALLOW','ROLE','employee'),(670,'VnUser','create','*','ALLOW','ROLE','itManagement'),(671,'VnUser','renewToken','WRITE','ALLOW','ROLE','employee'),(672,'PackingSiteAdvanced','*','*','ALLOW','ROLE','production'),(673,'InvoiceOut','makePdfAndNotify','WRITE','ALLOW','ROLE','invoicing'),(674,'InvoiceOutConfig','*','READ','ALLOW','ROLE','invoicing'),(676,'Ticket','invoiceTickets','WRITE','ALLOW','ROLE','employee'),(680,'MailAliasAccount','*','READ','ALLOW','ROLE','employee'),(681,'MailAliasAccount','create','WRITE','ALLOW','ROLE','employee'),(682,'MailAliasAccount','deleteById','WRITE','ALLOW','ROLE','employee'),(683,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','itManagement'),(684,'WorkerDisableExcluded','*','READ','ALLOW','ROLE','itManagement'),(685,'WorkerDisableExcluded','*','WRITE','ALLOW','ROLE','itManagement'),(686,'MailForward','*','*','ALLOW','ROLE','hr'),(687,'ClientSms','find','READ','ALLOW','ROLE','employee'),(688,'ClientSms','create','WRITE','ALLOW','ROLE','employee'),(689,'Vehicle','sorted','WRITE','ALLOW','ROLE','employee'),(690,'Roadmap','*','*','ALLOW','ROLE','palletizerBoss'),(691,'Roadmap','*','*','ALLOW','ROLE','productionBoss'),(692,'ExpeditionTruck','*','*','ALLOW','ROLE','palletizerBoss'),(693,'ExpeditionTruck','*','*','ALLOW','ROLE','productionBoss'),(694,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','marketingBoss'),(695,'ViaexpressConfig','internationalExpedition','WRITE','ALLOW','ROLE','employee'),(696,'ViaexpressConfig','renderer','READ','ALLOW','ROLE','employee'),(697,'Ticket','transferClient','WRITE','ALLOW','ROLE','administrative'),(698,'Ticket','canEditWeekly','WRITE','ALLOW','ROLE','buyer'),(699,'TicketSms','find','READ','ALLOW','ROLE','salesPerson'),(701,'Docuware','upload','WRITE','ALLOW','ROLE','deliveryBoss'),(702,'Ticket','docuwareDownload','READ','ALLOW','ROLE','salesPerson'); +INSERT INTO `ACL` VALUES (3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','trainee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','trainee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','trainee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','trainee'),(30,'GreugeType','*','READ','ALLOW','ROLE','trainee'),(31,'Mandate','*','READ','ALLOW','ROLE','trainee'),(32,'MandateType','*','READ','ALLOW','ROLE','trainee'),(33,'Company','*','READ','ALLOW','ROLE','trainee'),(34,'Greuge','*','READ','ALLOW','ROLE','trainee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer'),(55,'Recovery','*','READ','ALLOW','ROLE','trainee'),(56,'Recovery','*','WRITE','ALLOW','ROLE','administrative'),(58,'CreditClassification','*','*','ALLOW','ROLE','insurance'),(60,'CreditInsurance','*','*','ALLOW','ROLE','insurance'),(61,'InvoiceOut','*','READ','ALLOW','ROLE','employee'),(63,'TicketObservation','*','*','ALLOW','ROLE','employee'),(64,'Route','*','READ','ALLOW','ROLE','employee'),(65,'Sale','*','READ','ALLOW','ROLE','employee'),(66,'TicketTracking','*','READ','ALLOW','ROLE','employee'),(68,'TicketPackaging','*','*','ALLOW','ROLE','employee'),(69,'Packaging','*','READ','ALLOW','ROLE','employee'),(70,'Packaging','*','WRITE','ALLOW','ROLE','logistic'),(72,'SaleComponent','*','READ','ALLOW','ROLE','employee'),(73,'Expedition','*','READ','ALLOW','ROLE','employee'),(74,'Expedition','*','WRITE','ALLOW','ROLE','deliveryBoss'),(75,'Expedition','*','WRITE','ALLOW','ROLE','production'),(76,'AnnualAverageInvoiced','*','READ','ALLOW','ROLE','employee'),(77,'WorkerMana','*','READ','ALLOW','ROLE','employee'),(78,'TicketTracking','*','WRITE','ALLOW','ROLE','production'),(79,'TicketTracking','state','*','ALLOW','ROLE','employee'),(80,'Sale','deleteSales','*','ALLOW','ROLE','employee'),(81,'Sale','moveToTicket','*','ALLOW','ROLE','employee'),(82,'Sale','updateQuantity','*','ALLOW','ROLE','employee'),(83,'Sale','updatePrice','*','ALLOW','ROLE','employee'),(84,'Sale','updateDiscount','*','ALLOW','ROLE','employee'),(85,'SaleTracking','*','READ','ALLOW','ROLE','employee'),(86,'Order','*','*','ALLOW','ROLE','employee'),(87,'OrderRow','*','*','ALLOW','ROLE','employee'),(88,'ClientContact','*','*','ALLOW','ROLE','employee'),(89,'Sale','moveToNewTicket','*','ALLOW','ROLE','employee'),(90,'Sale','reserve','*','ALLOW','ROLE','employee'),(91,'TicketWeekly','*','READ','ALLOW','ROLE','employee'),(94,'Agency','landsThatDay','*','ALLOW','ROLE','employee'),(96,'ClaimEnd','*','READ','ALLOW','ROLE','employee'),(97,'ClaimEnd','*','WRITE','ALLOW','ROLE','claimManager'),(98,'ClaimBeginning','*','*','ALLOW','ROLE','employee'),(99,'ClaimDevelopment','*','READ','ALLOW','ROLE','employee'),(100,'ClaimDevelopment','*','WRITE','ALLOW','ROLE','claimManager'),(102,'Claim','createFromSales','*','ALLOW','ROLE','employee'),(104,'Item','*','WRITE','ALLOW','ROLE','marketingBoss'),(105,'ItemBarcode','*','WRITE','ALLOW','ROLE','marketingBoss'),(106,'ItemBotanical','*','WRITE','ALLOW','ROLE','marketingBoss'),(108,'ItemPlacement','*','WRITE','ALLOW','ROLE','marketingBoss'),(109,'UserConfig','*','*','ALLOW','ROLE','employee'),(110,'Bank','*','READ','ALLOW','ROLE','trainee'),(111,'ClientLog','*','READ','ALLOW','ROLE','trainee'),(112,'Defaulter','*','READ','ALLOW','ROLE','employee'),(113,'ClientRisk','*','READ','ALLOW','ROLE','trainee'),(114,'Receipt','*','READ','ALLOW','ROLE','trainee'),(115,'Receipt','*','WRITE','ALLOW','ROLE','administrative'),(116,'BankEntity','*','*','ALLOW','ROLE','employee'),(117,'ClientSample','*','*','ALLOW','ROLE','employee'),(118,'WorkerTeam','*','*','ALLOW','ROLE','salesPerson'),(119,'Travel','*','READ','ALLOW','ROLE','employee'),(120,'Travel','*','WRITE','ALLOW','ROLE','buyer'),(121,'Item','regularize','*','ALLOW','ROLE','employee'),(122,'TicketRequest','*','*','ALLOW','ROLE','employee'),(124,'Client','confirmTransaction','WRITE','ALLOW','ROLE','administrative'),(125,'Agency','getAgenciesWithWarehouse','*','ALLOW','ROLE','employee'),(126,'Client','activeWorkersWithRole','*','ALLOW','ROLE','employee'),(127,'TicketLog','*','READ','ALLOW','ROLE','employee'),(129,'TicketService','*','*','ALLOW','ROLE','employee'),(130,'Expedition','*','WRITE','ALLOW','ROLE','packager'),(131,'CreditInsurance','*','READ','ALLOW','ROLE','trainee'),(132,'CreditClassification','*','READ','ALLOW','ROLE','trainee'),(133,'ItemTag','*','WRITE','ALLOW','ROLE','marketingBoss'),(135,'ZoneGeo','*','READ','ALLOW','ROLE','employee'),(136,'ZoneCalendar','*','READ','ALLOW','ROLE','employee'),(137,'ZoneIncluded','*','READ','ALLOW','ROLE','employee'),(138,'LabourHoliday','*','READ','ALLOW','ROLE','employee'),(139,'LabourHolidayLegend','*','READ','ALLOW','ROLE','employee'),(140,'LabourHolidayType','*','READ','ALLOW','ROLE','employee'),(141,'Zone','*','*','ALLOW','ROLE','logisticBoss'),(142,'ZoneCalendar','*','WRITE','ALLOW','ROLE','deliveryBoss'),(143,'ZoneIncluded','*','*','ALLOW','ROLE','deliveryBoss'),(144,'Stowaway','*','*','ALLOW','ROLE','employee'),(145,'Ticket','getPossibleStowaways','READ','ALLOW','ROLE','employee'),(147,'UserConfigView','*','*','ALLOW','ROLE','employee'),(148,'UserConfigView','*','*','ALLOW','ROLE','employee'),(149,'Sip','*','READ','ALLOW','ROLE','employee'),(150,'Sip','*','WRITE','ALLOW','ROLE','hr'),(151,'Department','*','READ','ALLOW','ROLE','employee'),(152,'Department','*','WRITE','ALLOW','ROLE','hr'),(153,'Route','*','READ','ALLOW','ROLE','employee'),(154,'Route','*','WRITE','ALLOW','ROLE','delivery'),(155,'Calendar','*','READ','ALLOW','ROLE','hr'),(156,'WorkerLabour','*','READ','ALLOW','ROLE','hr'),(157,'Calendar','absences','READ','ALLOW','ROLE','employee'),(158,'ItemTag','*','WRITE','ALLOW','ROLE','accessory'),(160,'TicketServiceType','*','READ','ALLOW','ROLE','employee'),(161,'TicketConfig','*','READ','ALLOW','ROLE','employee'),(162,'InvoiceOut','delete','WRITE','ALLOW','ROLE','invoicing'),(163,'InvoiceOut','book','WRITE','ALLOW','ROLE','invoicing'),(165,'TicketDms','*','*','ALLOW','ROLE','employee'),(167,'Worker','isSubordinate','READ','ALLOW','ROLE','employee'),(168,'Worker','mySubordinates','READ','ALLOW','ROLE','employee'),(169,'WorkerTimeControl','filter','READ','ALLOW','ROLE','employee'),(170,'WorkerTimeControl','addTime','WRITE','ALLOW','ROLE','employee'),(171,'TicketServiceType','*','WRITE','ALLOW','ROLE','administrative'),(172,'Sms','*','READ','ALLOW','ROLE','employee'),(173,'Sms','send','WRITE','ALLOW','ROLE','employee'),(176,'Device','*','*','ALLOW','ROLE','employee'),(177,'Device','*','*','ALLOW','ROLE','employee'),(178,'WorkerTimeControl','*','*','ALLOW','ROLE','employee'),(179,'ItemLog','*','READ','ALLOW','ROLE','employee'),(180,'RouteLog','*','READ','ALLOW','ROLE','employee'),(181,'Dms','removeFile','WRITE','ALLOW','ROLE','employee'),(182,'Dms','uploadFile','WRITE','ALLOW','ROLE','employee'),(183,'Dms','downloadFile','READ','ALLOW','ROLE','employee'),(184,'Client','uploadFile','WRITE','ALLOW','ROLE','employee'),(185,'ClientDms','removeFile','WRITE','ALLOW','ROLE','employee'),(186,'ClientDms','*','READ','ALLOW','ROLE','trainee'),(187,'Ticket','uploadFile','WRITE','ALLOW','ROLE','employee'),(190,'Route','updateVolume','WRITE','ALLOW','ROLE','deliveryBoss'),(191,'Agency','getLanded','READ','ALLOW','ROLE','employee'),(192,'Agency','getShipped','READ','ALLOW','ROLE','employee'),(194,'Postcode','*','WRITE','ALLOW','ROLE','deliveryBoss'),(195,'Ticket','addSale','WRITE','ALLOW','ROLE','employee'),(196,'Dms','updateFile','WRITE','ALLOW','ROLE','employee'),(197,'Dms','*','READ','ALLOW','ROLE','trainee'),(198,'ClaimDms','removeFile','WRITE','ALLOW','ROLE','employee'),(199,'ClaimDms','*','READ','ALLOW','ROLE','employee'),(200,'Claim','uploadFile','WRITE','ALLOW','ROLE','employee'),(201,'Sale','updateConcept','WRITE','ALLOW','ROLE','employee'),(202,'Claim','updateClaimAction','WRITE','ALLOW','ROLE','claimManager'),(203,'UserPhone','*','*','ALLOW','ROLE','employee'),(204,'WorkerDms','removeFile','WRITE','ALLOW','ROLE','hr'),(205,'WorkerDms','*','READ','ALLOW','ROLE','hr'),(206,'Chat','*','*','ALLOW','ROLE','employee'),(207,'Chat','sendMessage','*','ALLOW','ROLE','employee'),(208,'Sale','recalculatePrice','WRITE','ALLOW','ROLE','employee'),(209,'Ticket','recalculateComponents','WRITE','ALLOW','ROLE','employee'),(211,'TravelLog','*','READ','ALLOW','ROLE','buyer'),(212,'Thermograph','*','*','ALLOW','ROLE','buyer'),(213,'TravelThermograph','*','WRITE','ALLOW','ROLE','buyer'),(214,'Entry','*','*','ALLOW','ROLE','buyer'),(215,'TicketWeekly','*','WRITE','ALLOW','ROLE','buyer'),(216,'TravelThermograph','*','READ','ALLOW','ROLE','employee'),(218,'Intrastat','*','*','ALLOW','ROLE','buyer'),(221,'UserConfig','getUserConfig','READ','ALLOW','ROLE','account'),(222,'Client','*','READ','ALLOW','ROLE','trainee'),(226,'ClientObservation','*','READ','ALLOW','ROLE','trainee'),(227,'Address','*','READ','ALLOW','ROLE','trainee'),(228,'AddressObservation','*','READ','ALLOW','ROLE','trainee'),(230,'ClientCredit','*','READ','ALLOW','ROLE','trainee'),(231,'ClientContact','*','READ','ALLOW','ROLE','trainee'),(232,'ClientSample','*','READ','ALLOW','ROLE','trainee'),(233,'EntryLog','*','READ','ALLOW','ROLE','buyer'),(234,'WorkerLog','find','READ','ALLOW','ROLE','hr'),(235,'CustomsAgent','*','*','ALLOW','ROLE','employee'),(236,'Buy','*','*','ALLOW','ROLE','buyer'),(237,'WorkerDms','filter','*','ALLOW','ROLE','employee'),(238,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(239,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(240,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(241,'SupplierContact','*','WRITE','ALLOW','ROLE','administrative'),(242,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(244,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(248,'RoleMapping','*','READ','ALLOW','ROLE','account'),(249,'UserPassword','*','READ','ALLOW','ROLE','account'),(250,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(251,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(252,'Supplier','*','READ','ALLOW','ROLE','employee'),(253,'Supplier','*','WRITE','ALLOW','ROLE','administrative'),(254,'SupplierLog','*','READ','ALLOW','ROLE','employee'),(256,'Image','*','WRITE','ALLOW','ROLE','employee'),(257,'FixedPrice','*','*','ALLOW','ROLE','buyer'),(258,'PayDem','*','READ','ALLOW','ROLE','employee'),(259,'Client','createReceipt','*','ALLOW','ROLE','salesAssistant'),(260,'PrintServerQueue','*','WRITE','ALLOW','ROLE','employee'),(261,'SupplierAccount','*','*','ALLOW','ROLE','administrative'),(262,'Entry','*','*','ALLOW','ROLE','administrative'),(263,'InvoiceIn','*','*','ALLOW','ROLE','administrative'),(264,'StarredModule','*','*','ALLOW','ROLE','employee'),(265,'ItemBotanical','*','WRITE','ALLOW','ROLE','logisticBoss'),(266,'ZoneLog','*','READ','ALLOW','ROLE','employee'),(267,'Genus','*','WRITE','ALLOW','ROLE','logisticBoss'),(268,'Specie','*','WRITE','ALLOW','ROLE','logisticBoss'),(269,'InvoiceOut','createPdf','WRITE','ALLOW','ROLE','employee'),(270,'SupplierAddress','*','*','ALLOW','ROLE','employee'),(271,'SalesMonitor','*','*','ALLOW','ROLE','employee'),(272,'InvoiceInLog','*','READ','ALLOW','ROLE','employee'),(273,'InvoiceInTax','*','*','ALLOW','ROLE','administrative'),(274,'InvoiceInLog','*','READ','ALLOW','ROLE','administrative'),(275,'InvoiceOut','createManualInvoice','WRITE','ALLOW','ROLE','invoicing'),(276,'InvoiceOut','globalInvoicing','WRITE','ALLOW','ROLE','invoicing'),(278,'RoleInherit','*','WRITE','ALLOW','ROLE','grant'),(279,'MailAlias','*','*','ALLOW','ROLE','marketing'),(283,'EntryObservation','*','*','ALLOW','ROLE','buyer'),(284,'LdapConfig','*','*','ALLOW','ROLE','sysadmin'),(285,'SambaConfig','*','*','ALLOW','ROLE','sysadmin'),(286,'ACL','*','*','ALLOW','ROLE','developer'),(287,'AccessToken','*','*','ALLOW','ROLE','developer'),(293,'RoleInherit','*','*','ALLOW','ROLE','it'),(294,'RoleRole','*','*','ALLOW','ROLE','it'),(295,'AccountConfig','*','*','ALLOW','ROLE','sysadmin'),(296,'Collection','*','READ','ALLOW','ROLE','employee'),(297,'Sale','refund','WRITE','ALLOW','ROLE','invoicing'),(298,'InvoiceInDueDay','*','*','ALLOW','ROLE','administrative'),(299,'Collection','setSaleQuantity','*','ALLOW','ROLE','employee'),(302,'AgencyTerm','*','*','ALLOW','ROLE','administrative'),(303,'ClaimLog','*','READ','ALLOW','ROLE','claimManager'),(304,'Edi','updateData','WRITE','ALLOW','ROLE','employee'),(305,'EducationLevel','*','*','ALLOW','ROLE','employee'),(306,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(307,'SupplierAgencyTerm','*','*','ALLOW','ROLE','administrative'),(308,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(309,'Zone','getZoneClosing','*','ALLOW','ROLE','employee'),(310,'ExpeditionState','*','READ','ALLOW','ROLE','employee'),(311,'Expense','*','READ','ALLOW','ROLE','employee'),(312,'Expense','*','WRITE','ALLOW','ROLE','administrative'),(314,'SupplierActivity','*','READ','ALLOW','ROLE','employee'),(315,'SupplierActivity','*','WRITE','ALLOW','ROLE','administrative'),(316,'Dms','deleteTrashFiles','WRITE','ALLOW','ROLE','employee'),(317,'ClientUnpaid','*','*','ALLOW','ROLE','administrative'),(318,'MdbVersion','*','*','ALLOW','ROLE','developer'),(319,'ItemType','*','READ','ALLOW','ROLE','employee'),(320,'ItemType','*','WRITE','ALLOW','ROLE','buyer'),(321,'InvoiceOut','refund','WRITE','ALLOW','ROLE','invoicing'),(322,'InvoiceOut','refund','WRITE','ALLOW','ROLE','salesAssistant'),(323,'InvoiceOut','refund','WRITE','ALLOW','ROLE','claimManager'),(324,'Ticket','refund','WRITE','ALLOW','ROLE','invoicing'),(325,'Ticket','refund','WRITE','ALLOW','ROLE','salesAssistant'),(326,'Ticket','refund','WRITE','ALLOW','ROLE','claimManager'),(327,'Sale','refund','WRITE','ALLOW','ROLE','salesAssistant'),(328,'Sale','refund','WRITE','ALLOW','ROLE','claimManager'),(329,'TicketRefund','*','WRITE','ALLOW','ROLE','invoicing'),(330,'ClaimObservation','*','WRITE','ALLOW','ROLE','salesPerson'),(331,'ClaimObservation','*','READ','ALLOW','ROLE','salesPerson'),(332,'Client','setPassword','WRITE','ALLOW','ROLE','salesPerson'),(333,'Client','updateUser','WRITE','ALLOW','ROLE','salesPerson'),(334,'ShelvingLog','*','READ','ALLOW','ROLE','employee'),(335,'ZoneExclusionGeo','*','READ','ALLOW','ROLE','employee'),(336,'ZoneExclusionGeo','*','WRITE','ALLOW','ROLE','deliveryBoss'),(337,'Parking','*','*','ALLOW','ROLE','employee'),(338,'Shelving','*','*','ALLOW','ROLE','employee'),(339,'OsTicket','*','*','ALLOW','ROLE','employee'),(340,'OsTicketConfig','*','*','ALLOW','ROLE','it'),(341,'ClientConsumptionQueue','*','WRITE','ALLOW','ROLE','employee'),(342,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','employee'),(343,'Ticket','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(344,'Ticket','deliveryNoteCsvPdf','READ','ALLOW','ROLE','employee'),(345,'Ticket','deliveryNoteCsvEmail','READ','ALLOW','ROLE','employee'),(346,'Client','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(347,'Client','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(348,'Client','clientWelcomeHtml','READ','ALLOW','ROLE','employee'),(349,'Client','clientWelcomeEmail','WRITE','ALLOW','ROLE','employee'),(350,'Client','creditRequestPdf','READ','ALLOW','ROLE','employee'),(351,'Client','creditRequestHtml','READ','ALLOW','ROLE','employee'),(352,'Client','creditRequestEmail','WRITE','ALLOW','ROLE','employee'),(353,'Client','printerSetupHtml','READ','ALLOW','ROLE','employee'),(354,'Client','printerSetupEmail','WRITE','ALLOW','ROLE','employee'),(355,'Client','sepaCoreEmail','WRITE','ALLOW','ROLE','employee'),(356,'Client','letterDebtorPdf','READ','ALLOW','ROLE','employee'),(357,'Client','letterDebtorStHtml','READ','ALLOW','ROLE','employee'),(358,'Client','letterDebtorStEmail','WRITE','ALLOW','ROLE','employee'),(359,'Client','letterDebtorNdHtml','READ','ALLOW','ROLE','employee'),(360,'Client','letterDebtorNdEmail','WRITE','ALLOW','ROLE','employee'),(361,'Client','clientDebtStatementPdf','READ','ALLOW','ROLE','employee'),(362,'Client','clientDebtStatementHtml','READ','ALLOW','ROLE','employee'),(363,'Client','clientDebtStatementEmail','WRITE','ALLOW','ROLE','employee'),(364,'Client','incotermsAuthorizationPdf','READ','ALLOW','ROLE','employee'),(365,'Client','incotermsAuthorizationHtml','READ','ALLOW','ROLE','employee'),(366,'Client','incotermsAuthorizationEmail','WRITE','ALLOW','ROLE','employee'),(367,'Client','consumptionSendQueued','WRITE','ALLOW','ROLE','system'),(368,'InvoiceOut','invoiceEmail','WRITE','ALLOW','ROLE','employee'),(369,'InvoiceOut','exportationPdf','READ','ALLOW','ROLE','employee'),(370,'InvoiceOut','sendQueued','WRITE','ALLOW','ROLE','system'),(371,'Ticket','invoiceCsvPdf','READ','ALLOW','ROLE','employee'),(372,'Ticket','invoiceCsvEmail','WRITE','ALLOW','ROLE','employee'),(373,'Supplier','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(374,'Supplier','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(375,'Travel','extraCommunityPdf','READ','ALLOW','ROLE','employee'),(376,'Travel','extraCommunityEmail','WRITE','ALLOW','ROLE','employee'),(377,'Entry','entryOrderPdf','READ','ALLOW','ROLE','employee'),(378,'OsTicket','osTicketReportEmail','WRITE','ALLOW','ROLE','system'),(379,'Item','buyerWasteEmail','WRITE','ALLOW','ROLE','system'),(380,'Claim','claimPickupPdf','READ','ALLOW','ROLE','employee'),(381,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','claimManager'),(382,'Item','labelPdf','READ','ALLOW','ROLE','employee'),(383,'Sector','*','READ','ALLOW','ROLE','employee'),(384,'Sector','*','WRITE','ALLOW','ROLE','employee'),(385,'Route','driverRoutePdf','READ','ALLOW','ROLE','employee'),(386,'Route','driverRouteEmail','WRITE','ALLOW','ROLE','employee'),(387,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','customer'),(388,'Supplier','newSupplier','WRITE','ALLOW','ROLE','administrative'),(389,'ClaimRma','*','READ','ALLOW','ROLE','claimManager'),(390,'ClaimRma','*','WRITE','ALLOW','ROLE','claimManager'),(391,'Notification','*','WRITE','ALLOW','ROLE','system'),(392,'Boxing','*','*','ALLOW','ROLE','employee'),(393,'Url','*','READ','ALLOW','ROLE','employee'),(394,'Url','*','WRITE','ALLOW','ROLE','it'),(395,'ItemShelving','*','READ','ALLOW','ROLE','employee'),(396,'ItemShelving','*','WRITE','ALLOW','ROLE','production'),(397,'ItemShelvingPlacementSupplyStock','*','READ','ALLOW','ROLE','employee'),(398,'NotificationQueue','*','*','ALLOW','ROLE','employee'),(399,'InvoiceOut','clientsToInvoice','WRITE','ALLOW','ROLE','invoicing'),(400,'InvoiceOut','invoiceClient','WRITE','ALLOW','ROLE','invoicing'),(401,'Sale','editTracked','WRITE','ALLOW','ROLE','production'),(402,'Sale','editFloramondo','WRITE','ALLOW','ROLE','salesAssistant'),(403,'Receipt','balanceCompensationEmail','WRITE','ALLOW','ROLE','employee'),(404,'Receipt','balanceCompensationPdf','READ','ALLOW','ROLE','employee'),(405,'Ticket','getTicketsFuture','READ','ALLOW','ROLE','employee'),(406,'Ticket','merge','WRITE','ALLOW','ROLE','employee'),(407,'Sale','editFloramondo','WRITE','ALLOW','ROLE','logistic'),(408,'ZipConfig','*','*','ALLOW','ROLE','employee'),(409,'Item','*','WRITE','ALLOW','ROLE','administrative'),(410,'Sale','editCloned','WRITE','ALLOW','ROLE','buyer'),(411,'Sale','editCloned','WRITE','ALLOW','ROLE','salesAssistant'),(414,'MdbVersion','*','READ','ALLOW','ROLE','$everyone'),(416,'TicketLog','getChanges','READ','ALLOW','ROLE','employee'),(417,'Ticket','getTicketsAdvance','READ','ALLOW','ROLE','employee'),(418,'EntryLog','*','READ','ALLOW','ROLE','administrative'),(419,'Sale','editTracked','WRITE','ALLOW','ROLE','buyer'),(420,'MdbBranch','*','READ','ALLOW','ROLE','$everyone'),(421,'ItemShelvingSale','*','*','ALLOW','ROLE','employee'),(422,'Docuware','checkFile','READ','ALLOW','ROLE','employee'),(423,'Docuware','download','READ','ALLOW','ROLE','salesPerson'),(424,'Docuware','upload','WRITE','ALLOW','ROLE','productionAssi'),(425,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','salesPerson'),(426,'TpvTransaction','confirm','WRITE','ALLOW','ROLE','$everyone'),(427,'TpvTransaction','start','WRITE','ALLOW','ROLE','$authenticated'),(428,'TpvTransaction','end','WRITE','ALLOW','ROLE','$authenticated'),(429,'ItemConfig','*','READ','ALLOW','ROLE','employee'),(431,'Tag','onSubmit','WRITE','ALLOW','ROLE','employee'),(432,'Worker','updateAttributes','WRITE','ALLOW','ROLE','hr'),(433,'Worker','createAbsence','*','ALLOW','ROLE','employee'),(434,'Worker','updateAbsence','WRITE','ALLOW','ROLE','employee'),(435,'Worker','deleteAbsence','*','ALLOW','ROLE','employee'),(436,'Worker','new','WRITE','ALLOW','ROLE','hr'),(438,'Client','getClientOrSupplierReference','READ','ALLOW','ROLE','employee'),(439,'NotificationSubscription','*','*','ALLOW','ROLE','employee'),(440,'NotificationAcl','*','READ','ALLOW','ROLE','employee'),(441,'MdbApp','*','READ','ALLOW','ROLE','$everyone'),(442,'MdbApp','*','*','ALLOW','ROLE','developer'),(443,'ItemConfig','*','*','ALLOW','ROLE','employee'),(444,'DeviceProduction','*','*','ALLOW','ROLE','hr'),(445,'DeviceProductionModels','*','*','ALLOW','ROLE','hr'),(446,'DeviceProductionState','*','*','ALLOW','ROLE','hr'),(447,'DeviceProductionUser','*','*','ALLOW','ROLE','hr'),(448,'DeviceProduction','*','*','ALLOW','ROLE','productionAssi'),(449,'DeviceProductionModels','*','*','ALLOW','ROLE','productionAssi'),(450,'DeviceProductionState','*','*','ALLOW','ROLE','productionAssi'),(451,'DeviceProductionUser','*','*','ALLOW','ROLE','productionAssi'),(452,'Worker','deallocatePDA','*','ALLOW','ROLE','hr'),(453,'Worker','allocatePDA','*','ALLOW','ROLE','hr'),(454,'Worker','deallocatePDA','*','ALLOW','ROLE','productionAssi'),(455,'Worker','allocatePDA','*','ALLOW','ROLE','productionAssi'),(456,'Zone','*','*','ALLOW','ROLE','deliveryBoss'),(457,'Account','setPassword','WRITE','ALLOW','ROLE','itManagement'),(458,'Operator','*','READ','ALLOW','ROLE','employee'),(459,'Operator','*','WRITE','ALLOW','ROLE','employee'),(460,'InvoiceIn','getSerial','READ','ALLOW','ROLE','administrative'),(461,'Ticket','saveSign','WRITE','ALLOW','ROLE','employee'),(462,'InvoiceOut','negativeBases','READ','ALLOW','ROLE','administrative'),(463,'InvoiceOut','negativeBasesCsv','READ','ALLOW','ROLE','administrative'),(464,'WorkerObservation','*','*','ALLOW','ROLE','hr'),(465,'ClientInforma','*','READ','ALLOW','ROLE','employee'),(466,'ClientInforma','*','WRITE','ALLOW','ROLE','financial'),(467,'Receipt','receiptEmail','*','ALLOW','ROLE','salesAssistant'),(468,'Client','setRating','WRITE','ALLOW','ROLE','financial'),(469,'Client','*','READ','ALLOW','ROLE','employee'),(470,'Client','addressesPropagateRe','*','ALLOW','ROLE','employee'),(471,'Client','canBeInvoiced','*','ALLOW','ROLE','employee'),(472,'Client','canCreateTicket','*','ALLOW','ROLE','employee'),(473,'Client','consumption','*','ALLOW','ROLE','employee'),(474,'Client','createAddress','*','ALLOW','ROLE','employee'),(475,'Client','createWithUser','*','ALLOW','ROLE','employee'),(476,'Client','extendedListFilter','*','ALLOW','ROLE','employee'),(477,'Client','getAverageInvoiced','*','ALLOW','ROLE','employee'),(478,'Client','getCard','*','ALLOW','ROLE','employee'),(479,'Client','getDebt','*','ALLOW','ROLE','employee'),(480,'Client','getMana','*','ALLOW','ROLE','employee'),(481,'Client','transactions','*','ALLOW','ROLE','employee'),(482,'Client','hasCustomerRole','*','ALLOW','ROLE','employee'),(483,'Client','isValidClient','*','ALLOW','ROLE','employee'),(484,'Client','lastActiveTickets','*','ALLOW','ROLE','employee'),(485,'Client','sendSms','*','ALLOW','ROLE','employee'),(486,'Client','setPassword','*','ALLOW','ROLE','employee'),(487,'Client','summary','*','ALLOW','ROLE','employee'),(488,'Client','updateAddress','*','ALLOW','ROLE','employee'),(489,'Client','updateFiscalData','*','ALLOW','ROLE','employee'),(491,'Client','uploadFile','*','ALLOW','ROLE','employee'),(492,'Client','campaignMetricsPdf','*','ALLOW','ROLE','employee'),(493,'Client','campaignMetricsEmail','*','ALLOW','ROLE','employee'),(494,'Client','clientWelcomeHtml','*','ALLOW','ROLE','employee'),(495,'Client','clientWelcomeEmail','*','ALLOW','ROLE','employee'),(496,'Client','printerSetupHtml','*','ALLOW','ROLE','employee'),(497,'Client','printerSetupEmail','*','ALLOW','ROLE','employee'),(498,'Client','sepaCoreEmail','*','ALLOW','ROLE','employee'),(499,'Client','letterDebtorPdf','*','ALLOW','ROLE','employee'),(500,'Client','letterDebtorStHtml','*','ALLOW','ROLE','employee'),(501,'Client','letterDebtorStEmail','*','ALLOW','ROLE','employee'),(502,'Client','letterDebtorNdHtml','*','ALLOW','ROLE','employee'),(503,'Client','letterDebtorNdEmail','*','ALLOW','ROLE','employee'),(504,'Client','clientDebtStatementPdf','*','ALLOW','ROLE','employee'),(505,'Client','clientDebtStatementHtml','*','ALLOW','ROLE','employee'),(506,'Client','clientDebtStatementEmail','*','ALLOW','ROLE','employee'),(507,'Client','creditRequestPdf','*','ALLOW','ROLE','employee'),(508,'Client','creditRequestHtml','*','ALLOW','ROLE','employee'),(509,'Client','creditRequestEmail','*','ALLOW','ROLE','employee'),(510,'Client','incotermsAuthorizationPdf','*','ALLOW','ROLE','employee'),(511,'Client','incotermsAuthorizationHtml','*','ALLOW','ROLE','employee'),(512,'Client','incotermsAuthorizationEmail','*','ALLOW','ROLE','employee'),(513,'Client','consumptionSendQueued','*','ALLOW','ROLE','employee'),(514,'Client','filter','*','ALLOW','ROLE','employee'),(515,'Client','getClientOrSupplierReference','*','ALLOW','ROLE','employee'),(516,'Client','upsert','*','ALLOW','ROLE','employee'),(517,'Client','create','*','ALLOW','ROLE','employee'),(518,'Client','replaceById','*','ALLOW','ROLE','employee'),(519,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(520,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(521,'Client','deleteById','*','ALLOW','ROLE','employee'),(522,'Client','replaceOrCreate','*','ALLOW','ROLE','employee'),(523,'Client','updateAll','*','ALLOW','ROLE','employee'),(524,'Client','upsertWithWhere','*','ALLOW','ROLE','employee'),(525,'Defaulter','observationEmail','WRITE','ALLOW','ROLE','employee'),(527,'VnUser','acl','READ','ALLOW','ROLE','account'),(528,'VnUser','getCurrentUserData','READ','ALLOW','ROLE','account'),(530,'Account','exists','READ','ALLOW','ROLE','account'),(531,'Account','exists','READ','ALLOW','ROLE','account'),(532,'UserLog','*','READ','ALLOW','ROLE','employee'),(533,'RoleLog','*','READ','ALLOW','ROLE','employee'),(534,'WagonType','*','*','ALLOW','ROLE','productionAssi'),(535,'WagonTypeColor','*','*','ALLOW','ROLE','productionAssi'),(536,'WagonTypeTray','*','*','ALLOW','ROLE','productionAssi'),(537,'WagonConfig','*','*','ALLOW','ROLE','productionAssi'),(538,'CollectionWagon','*','*','ALLOW','ROLE','productionAssi'),(539,'CollectionWagonTicket','*','*','ALLOW','ROLE','productionAssi'),(540,'Wagon','*','*','ALLOW','ROLE','productionAssi'),(541,'WagonType','createWagonType','*','ALLOW','ROLE','productionAssi'),(542,'WagonType','deleteWagonType','*','ALLOW','ROLE','productionAssi'),(543,'WagonType','editWagonType','*','ALLOW','ROLE','productionAssi'),(544,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(545,'Agency','find','READ','ALLOW','ROLE','employee'),(546,'Agency','seeExpired','READ','ALLOW','ROLE','coolerAssist'),(547,'WorkerLog','models','READ','ALLOW','ROLE','hr'),(548,'Ticket','editDiscount','WRITE','ALLOW','ROLE','claimManager'),(549,'Ticket','editDiscount','WRITE','ALLOW','ROLE','salesPerson'),(550,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','salesAssistant'),(551,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','deliveryBoss'),(552,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','buyer'),(553,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','claimManager'),(554,'Ticket','deleteTicketWithPartPrepared','WRITE','ALLOW','ROLE','salesAssistant'),(555,'Ticket','editZone','WRITE','ALLOW','ROLE','deliveryBoss'),(556,'State','editableStates','READ','ALLOW','ROLE','employee'),(557,'State','seeEditableStates','READ','ALLOW','ROLE','administrative'),(558,'State','seeEditableStates','READ','ALLOW','ROLE','production'),(559,'State','isSomeEditable','READ','ALLOW','ROLE','salesPerson'),(560,'State','isAllEditable','READ','ALLOW','ROLE','production'),(561,'State','isAllEditable','READ','ALLOW','ROLE','administrative'),(562,'Agency','seeExpired','READ','ALLOW','ROLE','administrative'),(563,'Agency','seeExpired','READ','ALLOW','ROLE','productionBoss'),(564,'Claim','createAfterDeadline','WRITE','ALLOW','ROLE','claimManager'),(565,'Client','editAddressLogifloraAllowed','WRITE','ALLOW','ROLE','salesAssistant'),(566,'Client','editFiscalDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(567,'Client','editVerifiedDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(568,'Client','editCredit','WRITE','ALLOW','ROLE','financialBoss'),(569,'Client','zeroCreditEditor','WRITE','ALLOW','ROLE','financialBoss'),(570,'InvoiceOut','canCreatePdf','WRITE','ALLOW','ROLE','invoicing'),(571,'Supplier','editPayMethodCheck','WRITE','ALLOW','ROLE','financial'),(572,'Worker','isTeamBoss','WRITE','ALLOW','ROLE','teamBoss'),(573,'Worker','forceIsSubordinate','READ','ALLOW','ROLE','hr'),(574,'Claim','editState','WRITE','ALLOW','ROLE','claimManager'),(575,'Claim','find','READ','ALLOW','ROLE','salesPerson'),(576,'Claim','findById','READ','ALLOW','ROLE','salesPerson'),(577,'Claim','findOne','READ','ALLOW','ROLE','salesPerson'),(578,'Claim','getSummary','READ','ALLOW','ROLE','salesPerson'),(579,'Claim','updateClaim','WRITE','ALLOW','ROLE','salesPerson'),(580,'Claim','regularizeClaim','WRITE','ALLOW','ROLE','claimManager'),(581,'Claim','updateClaimDestination','WRITE','ALLOW','ROLE','claimManager'),(582,'Claim','downloadFile','READ','ALLOW','ROLE','claimManager'),(583,'Claim','deleteById','WRITE','ALLOW','ROLE','claimManager'),(584,'Claim','filter','READ','ALLOW','ROLE','salesPerson'),(585,'Claim','logs','READ','ALLOW','ROLE','claimManager'),(586,'Ticket','find','READ','ALLOW','ROLE','employee'),(587,'Ticket','findById','READ','ALLOW','ROLE','employee'),(588,'Ticket','findOne','READ','ALLOW','ROLE','employee'),(589,'Ticket','getVolume','READ','ALLOW','ROLE','employee'),(590,'Ticket','getTotalVolume','READ','ALLOW','ROLE','employee'),(591,'Ticket','summary','READ','ALLOW','ROLE','employee'),(592,'Ticket','priceDifference','READ','ALLOW','ROLE','employee'),(593,'Ticket','componentUpdate','WRITE','ALLOW','ROLE','employee'),(594,'Ticket','new','WRITE','ALLOW','ROLE','employee'),(595,'Ticket','isEditable','READ','ALLOW','ROLE','employee'),(596,'Ticket','setDeleted','WRITE','ALLOW','ROLE','salesPerson'),(597,'Ticket','restore','WRITE','ALLOW','ROLE','employee'),(598,'Ticket','getSales','READ','ALLOW','ROLE','employee'),(599,'Ticket','getSalesPersonMana','READ','ALLOW','ROLE','employee'),(600,'Ticket','filter','READ','ALLOW','ROLE','employee'),(601,'Ticket','makeInvoice','WRITE','ALLOW','ROLE','employee'),(602,'Ticket','updateEditableTicket','WRITE','ALLOW','ROLE','employee'),(603,'Ticket','updateDiscount','WRITE','ALLOW','ROLE','employee'),(604,'Ticket','transferSales','WRITE','ALLOW','ROLE','employee'),(605,'Ticket','sendSms','WRITE','ALLOW','ROLE','employee'),(606,'Ticket','isLocked','READ','ALLOW','ROLE','employee'),(607,'Ticket','freightCost','READ','ALLOW','ROLE','employee'),(608,'Ticket','getComponentsSum','READ','ALLOW','ROLE','employee'),(609,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','delivery'),(610,'Ticket','deliveryNoteCsv','READ','ALLOW','ROLE','employee'),(611,'State','find','READ','ALLOW','ROLE','employee'),(612,'State','findById','READ','ALLOW','ROLE','employee'),(613,'State','findOne','READ','ALLOW','ROLE','employee'),(614,'Worker','find','READ','ALLOW','ROLE','employee'),(615,'Worker','findById','READ','ALLOW','ROLE','employee'),(616,'Worker','findOne','READ','ALLOW','ROLE','employee'),(617,'Worker','filter','READ','ALLOW','ROLE','employee'),(618,'Worker','getWorkedHours','READ','ALLOW','ROLE','employee'),(619,'Worker','active','READ','ALLOW','ROLE','employee'),(620,'Worker','activeWithRole','READ','ALLOW','ROLE','employee'),(621,'Worker','uploadFile','WRITE','ALLOW','ROLE','hr'),(622,'Worker','contracts','READ','ALLOW','ROLE','employee'),(623,'Worker','holidays','READ','ALLOW','ROLE','employee'),(624,'Worker','activeContract','READ','ALLOW','ROLE','employee'),(625,'Worker','activeWithInheritedRole','READ','ALLOW','ROLE','employee'),(626,'Ticket','collectionLabel','READ','ALLOW','ROLE','employee'),(628,'Ticket','expeditionPalletLabel','READ','ALLOW','ROLE','employee'),(629,'Ticket','editDiscount','WRITE','ALLOW','ROLE','artificialBoss'),(630,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesTeamBoss'),(635,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','administrative'),(636,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesPerson'),(637,'Claim','downloadFile','READ','ALLOW','ROLE','salesPerson'),(638,'Agency','seeExpired','READ','ALLOW','ROLE','artificialBoss'),(639,'Agency','seeExpired','READ','ALLOW','ROLE','logisticAssistant'),(640,'Claim','filter','READ','ALLOW','ROLE','buyer'),(641,'Claim','find','READ','ALLOW','ROLE','buyer'),(642,'Claim','findById','READ','ALLOW','ROLE','buyer'),(643,'Claim','getSummary','READ','ALLOW','ROLE','buyer'),(644,'Claim','filter','READ','ALLOW','ROLE','handmadeBoss'),(645,'Claim','find','READ','ALLOW','ROLE','handmadeBoss'),(646,'Claim','findById','READ','ALLOW','ROLE','handmadeBoss'),(647,'Claim','getSummary','READ','ALLOW','ROLE','handmadeBoss'),(648,'Claim','__get__lines','READ','ALLOW','ROLE','claimManager'),(649,'Claim','__get__lines','READ','ALLOW','ROLE','salesPerson'),(650,'Claim','getSummary','READ','ALLOW','ROLE','deliveryBoss'),(651,'Claim','findById','READ','ALLOW','ROLE','deliveryBoss'),(652,'Claim','find','READ','ALLOW','ROLE','deliveryBoss'),(653,'Claim','filter','READ','ALLOW','ROLE','deliveryBoss'),(654,'Ticket','editZone','WRITE','ALLOW','ROLE','logisticAssistant'),(655,'Entry','addFromPackaging','WRITE','ALLOW','ROLE','production'),(656,'Entry','addFromBuy','WRITE','ALLOW','ROLE','production'),(657,'Supplier','getItemsPackaging','READ','ALLOW','ROLE','production'),(658,'Ticket','closeAll','WRITE','ALLOW','ROLE','system'),(659,'Account','*','*','ALLOW','ROLE','itManagement'),(660,'Account','*','READ','ALLOW','ROLE','employee'),(664,'MailForward','*','*','ALLOW','ROLE','itManagement'),(665,'Role','*','READ','ALLOW','ROLE','employee'),(666,'Role','*','WRITE','ALLOW','ROLE','it'),(667,'VnUser','*','*','ALLOW','ROLE','itManagement'),(668,'VnUser','__get__preview','READ','ALLOW','ROLE','employee'),(669,'VnUser','preview','*','ALLOW','ROLE','employee'),(670,'VnUser','create','*','ALLOW','ROLE','itManagement'),(671,'VnUser','renewToken','WRITE','ALLOW','ROLE','employee'),(672,'PackingSiteAdvanced','*','*','ALLOW','ROLE','production'),(673,'InvoiceOut','makePdfAndNotify','WRITE','ALLOW','ROLE','invoicing'),(674,'InvoiceOutConfig','*','READ','ALLOW','ROLE','invoicing'),(676,'Ticket','invoiceTickets','WRITE','ALLOW','ROLE','employee'),(680,'MailAliasAccount','*','READ','ALLOW','ROLE','employee'),(681,'MailAliasAccount','create','WRITE','ALLOW','ROLE','employee'),(682,'MailAliasAccount','deleteById','WRITE','ALLOW','ROLE','employee'),(683,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','itManagement'),(684,'WorkerDisableExcluded','*','READ','ALLOW','ROLE','itManagement'),(685,'WorkerDisableExcluded','*','WRITE','ALLOW','ROLE','itManagement'),(686,'MailForward','*','*','ALLOW','ROLE','hr'),(687,'ClientSms','find','READ','ALLOW','ROLE','employee'),(688,'ClientSms','create','WRITE','ALLOW','ROLE','employee'),(689,'Vehicle','sorted','WRITE','ALLOW','ROLE','employee'),(690,'Roadmap','*','*','ALLOW','ROLE','palletizerBoss'),(691,'Roadmap','*','*','ALLOW','ROLE','productionBoss'),(692,'ExpeditionTruck','*','*','ALLOW','ROLE','palletizerBoss'),(693,'ExpeditionTruck','*','*','ALLOW','ROLE','productionBoss'),(694,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','marketingBoss'),(695,'ViaexpressConfig','internationalExpedition','WRITE','ALLOW','ROLE','employee'),(696,'ViaexpressConfig','renderer','READ','ALLOW','ROLE','employee'),(697,'Ticket','transferClient','WRITE','ALLOW','ROLE','administrative'),(698,'Ticket','canEditWeekly','WRITE','ALLOW','ROLE','buyer'),(699,'TicketSms','find','READ','ALLOW','ROLE','salesPerson'),(701,'Docuware','upload','WRITE','ALLOW','ROLE','deliveryBoss'),(702,'Ticket','docuwareDownload','READ','ALLOW','ROLE','salesPerson'); /*!40000 ALTER TABLE `ACL` ENABLE KEYS */; UNLOCK TABLES; diff --git a/front/core/directives/anchor.js b/front/core/directives/anchor.js index b460b3ada9..81e252e04d 100644 --- a/front/core/directives/anchor.js +++ b/front/core/directives/anchor.js @@ -8,7 +8,7 @@ export function stringifyParams(data) { return params; } -export function changeState($state, event, data) { +export function state($state, event, data) { const params = stringifyParams(data); $state.go(data.state, params); @@ -53,7 +53,7 @@ export function directive($state, $window) { if (ctrlPressed || data.target == '_blank') openNewTab($state, $window, event, data); else - changeState($state, event, data); + state($state, event, data); }); $element.on('mousedown', event => { diff --git a/modules/claim/front/summary/index.html b/modules/claim/front/summary/index.html index 3115cb4514..877a8c0f2b 100644 --- a/modules/claim/front/summary/index.html +++ b/modules/claim/front/summary/index.html @@ -21,7 +21,7 @@ value-field="id" show-field="description" url="claimStates" - on-change="$ctrl.changeState(value)"> + on-change="$ctrl.state(value)"> diff --git a/modules/claim/front/summary/index.js b/modules/claim/front/summary/index.js index 7cd4805e9f..f1310c298c 100644 --- a/modules/claim/front/summary/index.js +++ b/modules/claim/front/summary/index.js @@ -71,7 +71,7 @@ class Controller extends Summary { return this.vnFile.getPath(`/api/dms/${dmsId}/downloadFile`); } - changeState(value) { + state(value) { const params = { id: this.claim.id, claimStateFk: value diff --git a/modules/claim/front/summary/index.spec.js b/modules/claim/front/summary/index.spec.js index 8540a3a974..04a270c5f9 100644 --- a/modules/claim/front/summary/index.spec.js +++ b/modules/claim/front/summary/index.spec.js @@ -28,14 +28,14 @@ describe('Claim', () => { }); }); - describe('changeState()', () => { + describe('state()', () => { it('should make an HTTP post query, then call the showSuccess()', () => { jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); const expectedParams = {id: 1, claimStateFk: 1}; $httpBackend.when('GET', `Claims/1/getSummary`).respond(200, 24); $httpBackend.expect('PATCH', `Claims/updateClaim/1`, expectedParams).respond(200); - controller.changeState(1); + controller.state(1); $httpBackend.flush(); expect(controller.vnApp.showSuccess).toHaveBeenCalled(); diff --git a/modules/ticket/back/methods/ticket-tracking/setDelivered.js b/modules/ticket/back/methods/ticket-tracking/setDelivered.js index bd6e32dcff..bfbc719423 100644 --- a/modules/ticket/back/methods/ticket-tracking/setDelivered.js +++ b/modules/ticket/back/methods/ticket-tracking/setDelivered.js @@ -47,7 +47,7 @@ module.exports = Self => { const promises = []; for (const id of ticketIds) { - const promise = models.TicketTracking.changeState(ctx, { + const promise = models.TicketTracking.state(ctx, { stateFk: state.id, workerFk: worker.id, ticketFk: id diff --git a/modules/ticket/back/methods/ticket-tracking/specs/changeState.spec.js b/modules/ticket/back/methods/ticket-tracking/specs/changeState.spec.js index 175bc4e4b7..b01d023897 100644 --- a/modules/ticket/back/methods/ticket-tracking/specs/changeState.spec.js +++ b/modules/ticket/back/methods/ticket-tracking/specs/changeState.spec.js @@ -1,7 +1,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); -describe('ticket changeState()', () => { +describe('ticket state()', () => { const salesPersonId = 18; const employeeId = 1; const productionId = 49; @@ -47,7 +47,7 @@ describe('ticket changeState()', () => { activeCtx.accessToken.userId = salesPersonId; const params = {ticketFk: 2, stateFk: 3}; - await models.TicketTracking.changeState(ctx, params, options); + await models.TicketTracking.state(ctx, params, options); await tx.rollback(); } catch (e) { @@ -69,7 +69,7 @@ describe('ticket changeState()', () => { activeCtx.accessToken.userId = employeeId; const params = {ticketFk: 11, stateFk: 13}; - await models.TicketTracking.changeState(ctx, params, options); + await models.TicketTracking.state(ctx, params, options); await tx.rollback(); } catch (e) { @@ -91,7 +91,7 @@ describe('ticket changeState()', () => { activeCtx.accessToken.userId = productionId; const params = {ticketFk: ticket.id, stateFk: 3}; - const ticketTracking = await models.TicketTracking.changeState(ctx, params, options); + const ticketTracking = await models.TicketTracking.state(ctx, params, options); expect(ticketTracking.__data.ticketFk).toBe(params.ticketFk); expect(ticketTracking.__data.stateFk).toBe(params.stateFk); @@ -115,7 +115,7 @@ describe('ticket changeState()', () => { const ctx = {req: {accessToken: {userId: 18}}}; const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options); const params = {ticketFk: ticket.id, stateFk: assignedState.id, workerFk: 1}; - const res = await models.TicketTracking.changeState(ctx, params, options); + const res = await models.TicketTracking.state(ctx, params, options); expect(res.__data.ticketFk).toBe(params.ticketFk); expect(res.__data.stateFk).toBe(params.stateFk); diff --git a/modules/ticket/back/methods/ticket-tracking/changeState.js b/modules/ticket/back/methods/ticket-tracking/state.js similarity index 94% rename from modules/ticket/back/methods/ticket-tracking/changeState.js rename to modules/ticket/back/methods/ticket-tracking/state.js index 4ae9ab40c5..cfc69b20cb 100644 --- a/modules/ticket/back/methods/ticket-tracking/changeState.js +++ b/modules/ticket/back/methods/ticket-tracking/state.js @@ -1,7 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethodCtx('changeState', { + Self.remoteMethodCtx('state', { description: 'Change the state of a ticket', accessType: 'WRITE', accepts: [ @@ -18,12 +18,12 @@ module.exports = Self => { root: true }, http: { - path: `/changeState`, + path: `/state`, verb: 'POST' } }); - Self.changeState = async(ctx, params, options) => { + Self.state = async(ctx, params, options) => { const models = Self.app.models; const myOptions = {}; let tx; diff --git a/modules/ticket/back/models/ticket-tracking.js b/modules/ticket/back/models/ticket-tracking.js index 2e6d3403ea..48e4c93d76 100644 --- a/modules/ticket/back/models/ticket-tracking.js +++ b/modules/ticket/back/models/ticket-tracking.js @@ -1,5 +1,5 @@ module.exports = function(Self) { - require('../methods/ticket-tracking/changeState')(Self); + require('../methods/ticket-tracking/state')(Self); require('../methods/ticket-tracking/setDelivered')(Self); Self.validatesPresenceOf('stateFk', {message: 'State cannot be blank'}); diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index be9e819646..a3bb861fe7 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -15,7 +15,7 @@ + on-change="$ctrl.state(value)"> { + return this.$http.post('TicketTrackings/state', params).then(() => { this.vnApp.showSuccess(this.$t('Data saved!')); this.card.reload(); }).finally(() => this.resetChanges()); diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 9da8e6e7cb..a0906dd000 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -230,15 +230,15 @@ describe('Ticket', () => { }); }); - describe('changeState()', () => { + describe('state()', () => { it('should make an HTTP post query, then call the showSuccess(), reload() and resetChanges() methods', () => { jest.spyOn(controller.card, 'reload').mockReturnThis(); jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); jest.spyOn(controller, 'resetChanges').mockReturnThis(); const expectedParams = {ticketFk: 1, code: 'OK'}; - $httpBackend.expect('POST', `TicketTrackings/changeState`, expectedParams).respond(200); - controller.changeState('OK'); + $httpBackend.expect('POST', `TicketTrackings/state`, expectedParams).respond(200); + controller.state('OK'); $httpBackend.flush(); expect(controller.card.reload).toHaveBeenCalledWith(); diff --git a/modules/ticket/front/summary/index.html b/modules/ticket/front/summary/index.html index dd0e94f421..c35e5b1182 100644 --- a/modules/ticket/front/summary/index.html +++ b/modules/ticket/front/summary/index.html @@ -18,7 +18,7 @@ value-field="code" fields="['id', 'name', 'alertLevel', 'code']" url="States/editableStates" - on-change="$ctrl.changeState(value)"> + on-change="$ctrl.state(value)"> { if ('id' in this.$params) this.reload(); }) diff --git a/modules/ticket/front/summary/index.spec.js b/modules/ticket/front/summary/index.spec.js index 599da73aec..b8c6f0513f 100644 --- a/modules/ticket/front/summary/index.spec.js +++ b/modules/ticket/front/summary/index.spec.js @@ -43,15 +43,15 @@ describe('Ticket', () => { }); }); - describe('changeState()', () => { + describe('state()', () => { it('should change the state', () => { jest.spyOn(controller.vnApp, 'showSuccess'); const value = 'myTicketState'; let res = {id: 1, nickname: 'myNickname'}; $httpBackend.when('GET', `Tickets/1/summary`).respond(200, res); - $httpBackend.expectPOST(`TicketTrackings/changeState`).respond(200, 'ok'); - controller.changeState(value); + $httpBackend.expectPOST(`TicketTrackings/state`).respond(200, 'ok'); + controller.state(value); $httpBackend.flush(); expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!'); diff --git a/modules/ticket/front/tracking/edit/index.html b/modules/ticket/front/tracking/edit/index.html index bff8e71b12..90f045813b 100644 --- a/modules/ticket/front/tracking/edit/index.html +++ b/modules/ticket/front/tracking/edit/index.html @@ -1,4 +1,4 @@ - + { + this.$http.post(`TicketTrackings/state`, this.params).then(() => { this.$.watcher.updateOriginalData(); this.card.reload(); this.vnApp.showSuccess(this.$t('Data saved!')); diff --git a/modules/ticket/front/tracking/edit/index.spec.js b/modules/ticket/front/tracking/edit/index.spec.js index 1ba5912b53..e97dc1337f 100644 --- a/modules/ticket/front/tracking/edit/index.spec.js +++ b/modules/ticket/front/tracking/edit/index.spec.js @@ -61,7 +61,7 @@ describe('Ticket', () => { jest.spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.$state, 'go'); - $httpBackend.expectPOST(`TicketTrackings/changeState`, controller.params).respond({}); + $httpBackend.expectPOST(`TicketTrackings/state`, controller.params).respond({}); controller.onSubmit(); $httpBackend.flush(); diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index 38e6721d65..dae2a950b6 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -385,7 +385,7 @@ class Controller extends Section { }); } - changeState(state, reason) { + state(state, reason) { this.state = state; this.reason = reason; this.repaint(); From 747ba0124c988287192526635cc3f5b4be3d2776 Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 18 Sep 2023 13:53:56 +0200 Subject: [PATCH 029/449] refs #4131 dumpedFixtures --- db/dump/dumpedFixtures.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/dump/dumpedFixtures.sql b/db/dump/dumpedFixtures.sql index 5ff2e03efb..2e1511b590 100644 --- a/db/dump/dumpedFixtures.sql +++ b/db/dump/dumpedFixtures.sql @@ -164,7 +164,7 @@ USE `salix`; LOCK TABLES `ACL` WRITE; /*!40000 ALTER TABLE `ACL` DISABLE KEYS */; -INSERT INTO `ACL` VALUES (3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','trainee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','trainee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','trainee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','trainee'),(30,'GreugeType','*','READ','ALLOW','ROLE','trainee'),(31,'Mandate','*','READ','ALLOW','ROLE','trainee'),(32,'MandateType','*','READ','ALLOW','ROLE','trainee'),(33,'Company','*','READ','ALLOW','ROLE','trainee'),(34,'Greuge','*','READ','ALLOW','ROLE','trainee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer'),(55,'Recovery','*','READ','ALLOW','ROLE','trainee'),(56,'Recovery','*','WRITE','ALLOW','ROLE','administrative'),(58,'CreditClassification','*','*','ALLOW','ROLE','insurance'),(60,'CreditInsurance','*','*','ALLOW','ROLE','insurance'),(61,'InvoiceOut','*','READ','ALLOW','ROLE','employee'),(63,'TicketObservation','*','*','ALLOW','ROLE','employee'),(64,'Route','*','READ','ALLOW','ROLE','employee'),(65,'Sale','*','READ','ALLOW','ROLE','employee'),(66,'TicketTracking','*','READ','ALLOW','ROLE','employee'),(68,'TicketPackaging','*','*','ALLOW','ROLE','employee'),(69,'Packaging','*','READ','ALLOW','ROLE','employee'),(70,'Packaging','*','WRITE','ALLOW','ROLE','logistic'),(72,'SaleComponent','*','READ','ALLOW','ROLE','employee'),(73,'Expedition','*','READ','ALLOW','ROLE','employee'),(74,'Expedition','*','WRITE','ALLOW','ROLE','deliveryBoss'),(75,'Expedition','*','WRITE','ALLOW','ROLE','production'),(76,'AnnualAverageInvoiced','*','READ','ALLOW','ROLE','employee'),(77,'WorkerMana','*','READ','ALLOW','ROLE','employee'),(78,'TicketTracking','*','WRITE','ALLOW','ROLE','production'),(79,'TicketTracking','state','*','ALLOW','ROLE','employee'),(80,'Sale','deleteSales','*','ALLOW','ROLE','employee'),(81,'Sale','moveToTicket','*','ALLOW','ROLE','employee'),(82,'Sale','updateQuantity','*','ALLOW','ROLE','employee'),(83,'Sale','updatePrice','*','ALLOW','ROLE','employee'),(84,'Sale','updateDiscount','*','ALLOW','ROLE','employee'),(85,'SaleTracking','*','READ','ALLOW','ROLE','employee'),(86,'Order','*','*','ALLOW','ROLE','employee'),(87,'OrderRow','*','*','ALLOW','ROLE','employee'),(88,'ClientContact','*','*','ALLOW','ROLE','employee'),(89,'Sale','moveToNewTicket','*','ALLOW','ROLE','employee'),(90,'Sale','reserve','*','ALLOW','ROLE','employee'),(91,'TicketWeekly','*','READ','ALLOW','ROLE','employee'),(94,'Agency','landsThatDay','*','ALLOW','ROLE','employee'),(96,'ClaimEnd','*','READ','ALLOW','ROLE','employee'),(97,'ClaimEnd','*','WRITE','ALLOW','ROLE','claimManager'),(98,'ClaimBeginning','*','*','ALLOW','ROLE','employee'),(99,'ClaimDevelopment','*','READ','ALLOW','ROLE','employee'),(100,'ClaimDevelopment','*','WRITE','ALLOW','ROLE','claimManager'),(102,'Claim','createFromSales','*','ALLOW','ROLE','employee'),(104,'Item','*','WRITE','ALLOW','ROLE','marketingBoss'),(105,'ItemBarcode','*','WRITE','ALLOW','ROLE','marketingBoss'),(106,'ItemBotanical','*','WRITE','ALLOW','ROLE','marketingBoss'),(108,'ItemPlacement','*','WRITE','ALLOW','ROLE','marketingBoss'),(109,'UserConfig','*','*','ALLOW','ROLE','employee'),(110,'Bank','*','READ','ALLOW','ROLE','trainee'),(111,'ClientLog','*','READ','ALLOW','ROLE','trainee'),(112,'Defaulter','*','READ','ALLOW','ROLE','employee'),(113,'ClientRisk','*','READ','ALLOW','ROLE','trainee'),(114,'Receipt','*','READ','ALLOW','ROLE','trainee'),(115,'Receipt','*','WRITE','ALLOW','ROLE','administrative'),(116,'BankEntity','*','*','ALLOW','ROLE','employee'),(117,'ClientSample','*','*','ALLOW','ROLE','employee'),(118,'WorkerTeam','*','*','ALLOW','ROLE','salesPerson'),(119,'Travel','*','READ','ALLOW','ROLE','employee'),(120,'Travel','*','WRITE','ALLOW','ROLE','buyer'),(121,'Item','regularize','*','ALLOW','ROLE','employee'),(122,'TicketRequest','*','*','ALLOW','ROLE','employee'),(124,'Client','confirmTransaction','WRITE','ALLOW','ROLE','administrative'),(125,'Agency','getAgenciesWithWarehouse','*','ALLOW','ROLE','employee'),(126,'Client','activeWorkersWithRole','*','ALLOW','ROLE','employee'),(127,'TicketLog','*','READ','ALLOW','ROLE','employee'),(129,'TicketService','*','*','ALLOW','ROLE','employee'),(130,'Expedition','*','WRITE','ALLOW','ROLE','packager'),(131,'CreditInsurance','*','READ','ALLOW','ROLE','trainee'),(132,'CreditClassification','*','READ','ALLOW','ROLE','trainee'),(133,'ItemTag','*','WRITE','ALLOW','ROLE','marketingBoss'),(135,'ZoneGeo','*','READ','ALLOW','ROLE','employee'),(136,'ZoneCalendar','*','READ','ALLOW','ROLE','employee'),(137,'ZoneIncluded','*','READ','ALLOW','ROLE','employee'),(138,'LabourHoliday','*','READ','ALLOW','ROLE','employee'),(139,'LabourHolidayLegend','*','READ','ALLOW','ROLE','employee'),(140,'LabourHolidayType','*','READ','ALLOW','ROLE','employee'),(141,'Zone','*','*','ALLOW','ROLE','logisticBoss'),(142,'ZoneCalendar','*','WRITE','ALLOW','ROLE','deliveryBoss'),(143,'ZoneIncluded','*','*','ALLOW','ROLE','deliveryBoss'),(144,'Stowaway','*','*','ALLOW','ROLE','employee'),(145,'Ticket','getPossibleStowaways','READ','ALLOW','ROLE','employee'),(147,'UserConfigView','*','*','ALLOW','ROLE','employee'),(148,'UserConfigView','*','*','ALLOW','ROLE','employee'),(149,'Sip','*','READ','ALLOW','ROLE','employee'),(150,'Sip','*','WRITE','ALLOW','ROLE','hr'),(151,'Department','*','READ','ALLOW','ROLE','employee'),(152,'Department','*','WRITE','ALLOW','ROLE','hr'),(153,'Route','*','READ','ALLOW','ROLE','employee'),(154,'Route','*','WRITE','ALLOW','ROLE','delivery'),(155,'Calendar','*','READ','ALLOW','ROLE','hr'),(156,'WorkerLabour','*','READ','ALLOW','ROLE','hr'),(157,'Calendar','absences','READ','ALLOW','ROLE','employee'),(158,'ItemTag','*','WRITE','ALLOW','ROLE','accessory'),(160,'TicketServiceType','*','READ','ALLOW','ROLE','employee'),(161,'TicketConfig','*','READ','ALLOW','ROLE','employee'),(162,'InvoiceOut','delete','WRITE','ALLOW','ROLE','invoicing'),(163,'InvoiceOut','book','WRITE','ALLOW','ROLE','invoicing'),(165,'TicketDms','*','*','ALLOW','ROLE','employee'),(167,'Worker','isSubordinate','READ','ALLOW','ROLE','employee'),(168,'Worker','mySubordinates','READ','ALLOW','ROLE','employee'),(169,'WorkerTimeControl','filter','READ','ALLOW','ROLE','employee'),(170,'WorkerTimeControl','addTime','WRITE','ALLOW','ROLE','employee'),(171,'TicketServiceType','*','WRITE','ALLOW','ROLE','administrative'),(172,'Sms','*','READ','ALLOW','ROLE','employee'),(173,'Sms','send','WRITE','ALLOW','ROLE','employee'),(176,'Device','*','*','ALLOW','ROLE','employee'),(177,'Device','*','*','ALLOW','ROLE','employee'),(178,'WorkerTimeControl','*','*','ALLOW','ROLE','employee'),(179,'ItemLog','*','READ','ALLOW','ROLE','employee'),(180,'RouteLog','*','READ','ALLOW','ROLE','employee'),(181,'Dms','removeFile','WRITE','ALLOW','ROLE','employee'),(182,'Dms','uploadFile','WRITE','ALLOW','ROLE','employee'),(183,'Dms','downloadFile','READ','ALLOW','ROLE','employee'),(184,'Client','uploadFile','WRITE','ALLOW','ROLE','employee'),(185,'ClientDms','removeFile','WRITE','ALLOW','ROLE','employee'),(186,'ClientDms','*','READ','ALLOW','ROLE','trainee'),(187,'Ticket','uploadFile','WRITE','ALLOW','ROLE','employee'),(190,'Route','updateVolume','WRITE','ALLOW','ROLE','deliveryBoss'),(191,'Agency','getLanded','READ','ALLOW','ROLE','employee'),(192,'Agency','getShipped','READ','ALLOW','ROLE','employee'),(194,'Postcode','*','WRITE','ALLOW','ROLE','deliveryBoss'),(195,'Ticket','addSale','WRITE','ALLOW','ROLE','employee'),(196,'Dms','updateFile','WRITE','ALLOW','ROLE','employee'),(197,'Dms','*','READ','ALLOW','ROLE','trainee'),(198,'ClaimDms','removeFile','WRITE','ALLOW','ROLE','employee'),(199,'ClaimDms','*','READ','ALLOW','ROLE','employee'),(200,'Claim','uploadFile','WRITE','ALLOW','ROLE','employee'),(201,'Sale','updateConcept','WRITE','ALLOW','ROLE','employee'),(202,'Claim','updateClaimAction','WRITE','ALLOW','ROLE','claimManager'),(203,'UserPhone','*','*','ALLOW','ROLE','employee'),(204,'WorkerDms','removeFile','WRITE','ALLOW','ROLE','hr'),(205,'WorkerDms','*','READ','ALLOW','ROLE','hr'),(206,'Chat','*','*','ALLOW','ROLE','employee'),(207,'Chat','sendMessage','*','ALLOW','ROLE','employee'),(208,'Sale','recalculatePrice','WRITE','ALLOW','ROLE','employee'),(209,'Ticket','recalculateComponents','WRITE','ALLOW','ROLE','employee'),(211,'TravelLog','*','READ','ALLOW','ROLE','buyer'),(212,'Thermograph','*','*','ALLOW','ROLE','buyer'),(213,'TravelThermograph','*','WRITE','ALLOW','ROLE','buyer'),(214,'Entry','*','*','ALLOW','ROLE','buyer'),(215,'TicketWeekly','*','WRITE','ALLOW','ROLE','buyer'),(216,'TravelThermograph','*','READ','ALLOW','ROLE','employee'),(218,'Intrastat','*','*','ALLOW','ROLE','buyer'),(221,'UserConfig','getUserConfig','READ','ALLOW','ROLE','account'),(222,'Client','*','READ','ALLOW','ROLE','trainee'),(226,'ClientObservation','*','READ','ALLOW','ROLE','trainee'),(227,'Address','*','READ','ALLOW','ROLE','trainee'),(228,'AddressObservation','*','READ','ALLOW','ROLE','trainee'),(230,'ClientCredit','*','READ','ALLOW','ROLE','trainee'),(231,'ClientContact','*','READ','ALLOW','ROLE','trainee'),(232,'ClientSample','*','READ','ALLOW','ROLE','trainee'),(233,'EntryLog','*','READ','ALLOW','ROLE','buyer'),(234,'WorkerLog','find','READ','ALLOW','ROLE','hr'),(235,'CustomsAgent','*','*','ALLOW','ROLE','employee'),(236,'Buy','*','*','ALLOW','ROLE','buyer'),(237,'WorkerDms','filter','*','ALLOW','ROLE','employee'),(238,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(239,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(240,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(241,'SupplierContact','*','WRITE','ALLOW','ROLE','administrative'),(242,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(244,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(248,'RoleMapping','*','READ','ALLOW','ROLE','account'),(249,'UserPassword','*','READ','ALLOW','ROLE','account'),(250,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(251,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(252,'Supplier','*','READ','ALLOW','ROLE','employee'),(253,'Supplier','*','WRITE','ALLOW','ROLE','administrative'),(254,'SupplierLog','*','READ','ALLOW','ROLE','employee'),(256,'Image','*','WRITE','ALLOW','ROLE','employee'),(257,'FixedPrice','*','*','ALLOW','ROLE','buyer'),(258,'PayDem','*','READ','ALLOW','ROLE','employee'),(259,'Client','createReceipt','*','ALLOW','ROLE','salesAssistant'),(260,'PrintServerQueue','*','WRITE','ALLOW','ROLE','employee'),(261,'SupplierAccount','*','*','ALLOW','ROLE','administrative'),(262,'Entry','*','*','ALLOW','ROLE','administrative'),(263,'InvoiceIn','*','*','ALLOW','ROLE','administrative'),(264,'StarredModule','*','*','ALLOW','ROLE','employee'),(265,'ItemBotanical','*','WRITE','ALLOW','ROLE','logisticBoss'),(266,'ZoneLog','*','READ','ALLOW','ROLE','employee'),(267,'Genus','*','WRITE','ALLOW','ROLE','logisticBoss'),(268,'Specie','*','WRITE','ALLOW','ROLE','logisticBoss'),(269,'InvoiceOut','createPdf','WRITE','ALLOW','ROLE','employee'),(270,'SupplierAddress','*','*','ALLOW','ROLE','employee'),(271,'SalesMonitor','*','*','ALLOW','ROLE','employee'),(272,'InvoiceInLog','*','READ','ALLOW','ROLE','employee'),(273,'InvoiceInTax','*','*','ALLOW','ROLE','administrative'),(274,'InvoiceInLog','*','READ','ALLOW','ROLE','administrative'),(275,'InvoiceOut','createManualInvoice','WRITE','ALLOW','ROLE','invoicing'),(276,'InvoiceOut','globalInvoicing','WRITE','ALLOW','ROLE','invoicing'),(278,'RoleInherit','*','WRITE','ALLOW','ROLE','grant'),(279,'MailAlias','*','*','ALLOW','ROLE','marketing'),(283,'EntryObservation','*','*','ALLOW','ROLE','buyer'),(284,'LdapConfig','*','*','ALLOW','ROLE','sysadmin'),(285,'SambaConfig','*','*','ALLOW','ROLE','sysadmin'),(286,'ACL','*','*','ALLOW','ROLE','developer'),(287,'AccessToken','*','*','ALLOW','ROLE','developer'),(293,'RoleInherit','*','*','ALLOW','ROLE','it'),(294,'RoleRole','*','*','ALLOW','ROLE','it'),(295,'AccountConfig','*','*','ALLOW','ROLE','sysadmin'),(296,'Collection','*','READ','ALLOW','ROLE','employee'),(297,'Sale','refund','WRITE','ALLOW','ROLE','invoicing'),(298,'InvoiceInDueDay','*','*','ALLOW','ROLE','administrative'),(299,'Collection','setSaleQuantity','*','ALLOW','ROLE','employee'),(302,'AgencyTerm','*','*','ALLOW','ROLE','administrative'),(303,'ClaimLog','*','READ','ALLOW','ROLE','claimManager'),(304,'Edi','updateData','WRITE','ALLOW','ROLE','employee'),(305,'EducationLevel','*','*','ALLOW','ROLE','employee'),(306,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(307,'SupplierAgencyTerm','*','*','ALLOW','ROLE','administrative'),(308,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(309,'Zone','getZoneClosing','*','ALLOW','ROLE','employee'),(310,'ExpeditionState','*','READ','ALLOW','ROLE','employee'),(311,'Expense','*','READ','ALLOW','ROLE','employee'),(312,'Expense','*','WRITE','ALLOW','ROLE','administrative'),(314,'SupplierActivity','*','READ','ALLOW','ROLE','employee'),(315,'SupplierActivity','*','WRITE','ALLOW','ROLE','administrative'),(316,'Dms','deleteTrashFiles','WRITE','ALLOW','ROLE','employee'),(317,'ClientUnpaid','*','*','ALLOW','ROLE','administrative'),(318,'MdbVersion','*','*','ALLOW','ROLE','developer'),(319,'ItemType','*','READ','ALLOW','ROLE','employee'),(320,'ItemType','*','WRITE','ALLOW','ROLE','buyer'),(321,'InvoiceOut','refund','WRITE','ALLOW','ROLE','invoicing'),(322,'InvoiceOut','refund','WRITE','ALLOW','ROLE','salesAssistant'),(323,'InvoiceOut','refund','WRITE','ALLOW','ROLE','claimManager'),(324,'Ticket','refund','WRITE','ALLOW','ROLE','invoicing'),(325,'Ticket','refund','WRITE','ALLOW','ROLE','salesAssistant'),(326,'Ticket','refund','WRITE','ALLOW','ROLE','claimManager'),(327,'Sale','refund','WRITE','ALLOW','ROLE','salesAssistant'),(328,'Sale','refund','WRITE','ALLOW','ROLE','claimManager'),(329,'TicketRefund','*','WRITE','ALLOW','ROLE','invoicing'),(330,'ClaimObservation','*','WRITE','ALLOW','ROLE','salesPerson'),(331,'ClaimObservation','*','READ','ALLOW','ROLE','salesPerson'),(332,'Client','setPassword','WRITE','ALLOW','ROLE','salesPerson'),(333,'Client','updateUser','WRITE','ALLOW','ROLE','salesPerson'),(334,'ShelvingLog','*','READ','ALLOW','ROLE','employee'),(335,'ZoneExclusionGeo','*','READ','ALLOW','ROLE','employee'),(336,'ZoneExclusionGeo','*','WRITE','ALLOW','ROLE','deliveryBoss'),(337,'Parking','*','*','ALLOW','ROLE','employee'),(338,'Shelving','*','*','ALLOW','ROLE','employee'),(339,'OsTicket','*','*','ALLOW','ROLE','employee'),(340,'OsTicketConfig','*','*','ALLOW','ROLE','it'),(341,'ClientConsumptionQueue','*','WRITE','ALLOW','ROLE','employee'),(342,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','employee'),(343,'Ticket','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(344,'Ticket','deliveryNoteCsvPdf','READ','ALLOW','ROLE','employee'),(345,'Ticket','deliveryNoteCsvEmail','READ','ALLOW','ROLE','employee'),(346,'Client','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(347,'Client','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(348,'Client','clientWelcomeHtml','READ','ALLOW','ROLE','employee'),(349,'Client','clientWelcomeEmail','WRITE','ALLOW','ROLE','employee'),(350,'Client','creditRequestPdf','READ','ALLOW','ROLE','employee'),(351,'Client','creditRequestHtml','READ','ALLOW','ROLE','employee'),(352,'Client','creditRequestEmail','WRITE','ALLOW','ROLE','employee'),(353,'Client','printerSetupHtml','READ','ALLOW','ROLE','employee'),(354,'Client','printerSetupEmail','WRITE','ALLOW','ROLE','employee'),(355,'Client','sepaCoreEmail','WRITE','ALLOW','ROLE','employee'),(356,'Client','letterDebtorPdf','READ','ALLOW','ROLE','employee'),(357,'Client','letterDebtorStHtml','READ','ALLOW','ROLE','employee'),(358,'Client','letterDebtorStEmail','WRITE','ALLOW','ROLE','employee'),(359,'Client','letterDebtorNdHtml','READ','ALLOW','ROLE','employee'),(360,'Client','letterDebtorNdEmail','WRITE','ALLOW','ROLE','employee'),(361,'Client','clientDebtStatementPdf','READ','ALLOW','ROLE','employee'),(362,'Client','clientDebtStatementHtml','READ','ALLOW','ROLE','employee'),(363,'Client','clientDebtStatementEmail','WRITE','ALLOW','ROLE','employee'),(364,'Client','incotermsAuthorizationPdf','READ','ALLOW','ROLE','employee'),(365,'Client','incotermsAuthorizationHtml','READ','ALLOW','ROLE','employee'),(366,'Client','incotermsAuthorizationEmail','WRITE','ALLOW','ROLE','employee'),(367,'Client','consumptionSendQueued','WRITE','ALLOW','ROLE','system'),(368,'InvoiceOut','invoiceEmail','WRITE','ALLOW','ROLE','employee'),(369,'InvoiceOut','exportationPdf','READ','ALLOW','ROLE','employee'),(370,'InvoiceOut','sendQueued','WRITE','ALLOW','ROLE','system'),(371,'Ticket','invoiceCsvPdf','READ','ALLOW','ROLE','employee'),(372,'Ticket','invoiceCsvEmail','WRITE','ALLOW','ROLE','employee'),(373,'Supplier','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(374,'Supplier','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(375,'Travel','extraCommunityPdf','READ','ALLOW','ROLE','employee'),(376,'Travel','extraCommunityEmail','WRITE','ALLOW','ROLE','employee'),(377,'Entry','entryOrderPdf','READ','ALLOW','ROLE','employee'),(378,'OsTicket','osTicketReportEmail','WRITE','ALLOW','ROLE','system'),(379,'Item','buyerWasteEmail','WRITE','ALLOW','ROLE','system'),(380,'Claim','claimPickupPdf','READ','ALLOW','ROLE','employee'),(381,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','claimManager'),(382,'Item','labelPdf','READ','ALLOW','ROLE','employee'),(383,'Sector','*','READ','ALLOW','ROLE','employee'),(384,'Sector','*','WRITE','ALLOW','ROLE','employee'),(385,'Route','driverRoutePdf','READ','ALLOW','ROLE','employee'),(386,'Route','driverRouteEmail','WRITE','ALLOW','ROLE','employee'),(387,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','customer'),(388,'Supplier','newSupplier','WRITE','ALLOW','ROLE','administrative'),(389,'ClaimRma','*','READ','ALLOW','ROLE','claimManager'),(390,'ClaimRma','*','WRITE','ALLOW','ROLE','claimManager'),(391,'Notification','*','WRITE','ALLOW','ROLE','system'),(392,'Boxing','*','*','ALLOW','ROLE','employee'),(393,'Url','*','READ','ALLOW','ROLE','employee'),(394,'Url','*','WRITE','ALLOW','ROLE','it'),(395,'ItemShelving','*','READ','ALLOW','ROLE','employee'),(396,'ItemShelving','*','WRITE','ALLOW','ROLE','production'),(397,'ItemShelvingPlacementSupplyStock','*','READ','ALLOW','ROLE','employee'),(398,'NotificationQueue','*','*','ALLOW','ROLE','employee'),(399,'InvoiceOut','clientsToInvoice','WRITE','ALLOW','ROLE','invoicing'),(400,'InvoiceOut','invoiceClient','WRITE','ALLOW','ROLE','invoicing'),(401,'Sale','editTracked','WRITE','ALLOW','ROLE','production'),(402,'Sale','editFloramondo','WRITE','ALLOW','ROLE','salesAssistant'),(403,'Receipt','balanceCompensationEmail','WRITE','ALLOW','ROLE','employee'),(404,'Receipt','balanceCompensationPdf','READ','ALLOW','ROLE','employee'),(405,'Ticket','getTicketsFuture','READ','ALLOW','ROLE','employee'),(406,'Ticket','merge','WRITE','ALLOW','ROLE','employee'),(407,'Sale','editFloramondo','WRITE','ALLOW','ROLE','logistic'),(408,'ZipConfig','*','*','ALLOW','ROLE','employee'),(409,'Item','*','WRITE','ALLOW','ROLE','administrative'),(410,'Sale','editCloned','WRITE','ALLOW','ROLE','buyer'),(411,'Sale','editCloned','WRITE','ALLOW','ROLE','salesAssistant'),(414,'MdbVersion','*','READ','ALLOW','ROLE','$everyone'),(416,'TicketLog','getChanges','READ','ALLOW','ROLE','employee'),(417,'Ticket','getTicketsAdvance','READ','ALLOW','ROLE','employee'),(418,'EntryLog','*','READ','ALLOW','ROLE','administrative'),(419,'Sale','editTracked','WRITE','ALLOW','ROLE','buyer'),(420,'MdbBranch','*','READ','ALLOW','ROLE','$everyone'),(421,'ItemShelvingSale','*','*','ALLOW','ROLE','employee'),(422,'Docuware','checkFile','READ','ALLOW','ROLE','employee'),(423,'Docuware','download','READ','ALLOW','ROLE','salesPerson'),(424,'Docuware','upload','WRITE','ALLOW','ROLE','productionAssi'),(425,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','salesPerson'),(426,'TpvTransaction','confirm','WRITE','ALLOW','ROLE','$everyone'),(427,'TpvTransaction','start','WRITE','ALLOW','ROLE','$authenticated'),(428,'TpvTransaction','end','WRITE','ALLOW','ROLE','$authenticated'),(429,'ItemConfig','*','READ','ALLOW','ROLE','employee'),(431,'Tag','onSubmit','WRITE','ALLOW','ROLE','employee'),(432,'Worker','updateAttributes','WRITE','ALLOW','ROLE','hr'),(433,'Worker','createAbsence','*','ALLOW','ROLE','employee'),(434,'Worker','updateAbsence','WRITE','ALLOW','ROLE','employee'),(435,'Worker','deleteAbsence','*','ALLOW','ROLE','employee'),(436,'Worker','new','WRITE','ALLOW','ROLE','hr'),(438,'Client','getClientOrSupplierReference','READ','ALLOW','ROLE','employee'),(439,'NotificationSubscription','*','*','ALLOW','ROLE','employee'),(440,'NotificationAcl','*','READ','ALLOW','ROLE','employee'),(441,'MdbApp','*','READ','ALLOW','ROLE','$everyone'),(442,'MdbApp','*','*','ALLOW','ROLE','developer'),(443,'ItemConfig','*','*','ALLOW','ROLE','employee'),(444,'DeviceProduction','*','*','ALLOW','ROLE','hr'),(445,'DeviceProductionModels','*','*','ALLOW','ROLE','hr'),(446,'DeviceProductionState','*','*','ALLOW','ROLE','hr'),(447,'DeviceProductionUser','*','*','ALLOW','ROLE','hr'),(448,'DeviceProduction','*','*','ALLOW','ROLE','productionAssi'),(449,'DeviceProductionModels','*','*','ALLOW','ROLE','productionAssi'),(450,'DeviceProductionState','*','*','ALLOW','ROLE','productionAssi'),(451,'DeviceProductionUser','*','*','ALLOW','ROLE','productionAssi'),(452,'Worker','deallocatePDA','*','ALLOW','ROLE','hr'),(453,'Worker','allocatePDA','*','ALLOW','ROLE','hr'),(454,'Worker','deallocatePDA','*','ALLOW','ROLE','productionAssi'),(455,'Worker','allocatePDA','*','ALLOW','ROLE','productionAssi'),(456,'Zone','*','*','ALLOW','ROLE','deliveryBoss'),(457,'Account','setPassword','WRITE','ALLOW','ROLE','itManagement'),(458,'Operator','*','READ','ALLOW','ROLE','employee'),(459,'Operator','*','WRITE','ALLOW','ROLE','employee'),(460,'InvoiceIn','getSerial','READ','ALLOW','ROLE','administrative'),(461,'Ticket','saveSign','WRITE','ALLOW','ROLE','employee'),(462,'InvoiceOut','negativeBases','READ','ALLOW','ROLE','administrative'),(463,'InvoiceOut','negativeBasesCsv','READ','ALLOW','ROLE','administrative'),(464,'WorkerObservation','*','*','ALLOW','ROLE','hr'),(465,'ClientInforma','*','READ','ALLOW','ROLE','employee'),(466,'ClientInforma','*','WRITE','ALLOW','ROLE','financial'),(467,'Receipt','receiptEmail','*','ALLOW','ROLE','salesAssistant'),(468,'Client','setRating','WRITE','ALLOW','ROLE','financial'),(469,'Client','*','READ','ALLOW','ROLE','employee'),(470,'Client','addressesPropagateRe','*','ALLOW','ROLE','employee'),(471,'Client','canBeInvoiced','*','ALLOW','ROLE','employee'),(472,'Client','canCreateTicket','*','ALLOW','ROLE','employee'),(473,'Client','consumption','*','ALLOW','ROLE','employee'),(474,'Client','createAddress','*','ALLOW','ROLE','employee'),(475,'Client','createWithUser','*','ALLOW','ROLE','employee'),(476,'Client','extendedListFilter','*','ALLOW','ROLE','employee'),(477,'Client','getAverageInvoiced','*','ALLOW','ROLE','employee'),(478,'Client','getCard','*','ALLOW','ROLE','employee'),(479,'Client','getDebt','*','ALLOW','ROLE','employee'),(480,'Client','getMana','*','ALLOW','ROLE','employee'),(481,'Client','transactions','*','ALLOW','ROLE','employee'),(482,'Client','hasCustomerRole','*','ALLOW','ROLE','employee'),(483,'Client','isValidClient','*','ALLOW','ROLE','employee'),(484,'Client','lastActiveTickets','*','ALLOW','ROLE','employee'),(485,'Client','sendSms','*','ALLOW','ROLE','employee'),(486,'Client','setPassword','*','ALLOW','ROLE','employee'),(487,'Client','summary','*','ALLOW','ROLE','employee'),(488,'Client','updateAddress','*','ALLOW','ROLE','employee'),(489,'Client','updateFiscalData','*','ALLOW','ROLE','employee'),(491,'Client','uploadFile','*','ALLOW','ROLE','employee'),(492,'Client','campaignMetricsPdf','*','ALLOW','ROLE','employee'),(493,'Client','campaignMetricsEmail','*','ALLOW','ROLE','employee'),(494,'Client','clientWelcomeHtml','*','ALLOW','ROLE','employee'),(495,'Client','clientWelcomeEmail','*','ALLOW','ROLE','employee'),(496,'Client','printerSetupHtml','*','ALLOW','ROLE','employee'),(497,'Client','printerSetupEmail','*','ALLOW','ROLE','employee'),(498,'Client','sepaCoreEmail','*','ALLOW','ROLE','employee'),(499,'Client','letterDebtorPdf','*','ALLOW','ROLE','employee'),(500,'Client','letterDebtorStHtml','*','ALLOW','ROLE','employee'),(501,'Client','letterDebtorStEmail','*','ALLOW','ROLE','employee'),(502,'Client','letterDebtorNdHtml','*','ALLOW','ROLE','employee'),(503,'Client','letterDebtorNdEmail','*','ALLOW','ROLE','employee'),(504,'Client','clientDebtStatementPdf','*','ALLOW','ROLE','employee'),(505,'Client','clientDebtStatementHtml','*','ALLOW','ROLE','employee'),(506,'Client','clientDebtStatementEmail','*','ALLOW','ROLE','employee'),(507,'Client','creditRequestPdf','*','ALLOW','ROLE','employee'),(508,'Client','creditRequestHtml','*','ALLOW','ROLE','employee'),(509,'Client','creditRequestEmail','*','ALLOW','ROLE','employee'),(510,'Client','incotermsAuthorizationPdf','*','ALLOW','ROLE','employee'),(511,'Client','incotermsAuthorizationHtml','*','ALLOW','ROLE','employee'),(512,'Client','incotermsAuthorizationEmail','*','ALLOW','ROLE','employee'),(513,'Client','consumptionSendQueued','*','ALLOW','ROLE','employee'),(514,'Client','filter','*','ALLOW','ROLE','employee'),(515,'Client','getClientOrSupplierReference','*','ALLOW','ROLE','employee'),(516,'Client','upsert','*','ALLOW','ROLE','employee'),(517,'Client','create','*','ALLOW','ROLE','employee'),(518,'Client','replaceById','*','ALLOW','ROLE','employee'),(519,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(520,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(521,'Client','deleteById','*','ALLOW','ROLE','employee'),(522,'Client','replaceOrCreate','*','ALLOW','ROLE','employee'),(523,'Client','updateAll','*','ALLOW','ROLE','employee'),(524,'Client','upsertWithWhere','*','ALLOW','ROLE','employee'),(525,'Defaulter','observationEmail','WRITE','ALLOW','ROLE','employee'),(527,'VnUser','acl','READ','ALLOW','ROLE','account'),(528,'VnUser','getCurrentUserData','READ','ALLOW','ROLE','account'),(530,'Account','exists','READ','ALLOW','ROLE','account'),(531,'Account','exists','READ','ALLOW','ROLE','account'),(532,'UserLog','*','READ','ALLOW','ROLE','employee'),(533,'RoleLog','*','READ','ALLOW','ROLE','employee'),(534,'WagonType','*','*','ALLOW','ROLE','productionAssi'),(535,'WagonTypeColor','*','*','ALLOW','ROLE','productionAssi'),(536,'WagonTypeTray','*','*','ALLOW','ROLE','productionAssi'),(537,'WagonConfig','*','*','ALLOW','ROLE','productionAssi'),(538,'CollectionWagon','*','*','ALLOW','ROLE','productionAssi'),(539,'CollectionWagonTicket','*','*','ALLOW','ROLE','productionAssi'),(540,'Wagon','*','*','ALLOW','ROLE','productionAssi'),(541,'WagonType','createWagonType','*','ALLOW','ROLE','productionAssi'),(542,'WagonType','deleteWagonType','*','ALLOW','ROLE','productionAssi'),(543,'WagonType','editWagonType','*','ALLOW','ROLE','productionAssi'),(544,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(545,'Agency','find','READ','ALLOW','ROLE','employee'),(546,'Agency','seeExpired','READ','ALLOW','ROLE','coolerAssist'),(547,'WorkerLog','models','READ','ALLOW','ROLE','hr'),(548,'Ticket','editDiscount','WRITE','ALLOW','ROLE','claimManager'),(549,'Ticket','editDiscount','WRITE','ALLOW','ROLE','salesPerson'),(550,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','salesAssistant'),(551,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','deliveryBoss'),(552,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','buyer'),(553,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','claimManager'),(554,'Ticket','deleteTicketWithPartPrepared','WRITE','ALLOW','ROLE','salesAssistant'),(555,'Ticket','editZone','WRITE','ALLOW','ROLE','deliveryBoss'),(556,'State','editableStates','READ','ALLOW','ROLE','employee'),(557,'State','seeEditableStates','READ','ALLOW','ROLE','administrative'),(558,'State','seeEditableStates','READ','ALLOW','ROLE','production'),(559,'State','isSomeEditable','READ','ALLOW','ROLE','salesPerson'),(560,'State','isAllEditable','READ','ALLOW','ROLE','production'),(561,'State','isAllEditable','READ','ALLOW','ROLE','administrative'),(562,'Agency','seeExpired','READ','ALLOW','ROLE','administrative'),(563,'Agency','seeExpired','READ','ALLOW','ROLE','productionBoss'),(564,'Claim','createAfterDeadline','WRITE','ALLOW','ROLE','claimManager'),(565,'Client','editAddressLogifloraAllowed','WRITE','ALLOW','ROLE','salesAssistant'),(566,'Client','editFiscalDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(567,'Client','editVerifiedDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(568,'Client','editCredit','WRITE','ALLOW','ROLE','financialBoss'),(569,'Client','zeroCreditEditor','WRITE','ALLOW','ROLE','financialBoss'),(570,'InvoiceOut','canCreatePdf','WRITE','ALLOW','ROLE','invoicing'),(571,'Supplier','editPayMethodCheck','WRITE','ALLOW','ROLE','financial'),(572,'Worker','isTeamBoss','WRITE','ALLOW','ROLE','teamBoss'),(573,'Worker','forceIsSubordinate','READ','ALLOW','ROLE','hr'),(574,'Claim','editState','WRITE','ALLOW','ROLE','claimManager'),(575,'Claim','find','READ','ALLOW','ROLE','salesPerson'),(576,'Claim','findById','READ','ALLOW','ROLE','salesPerson'),(577,'Claim','findOne','READ','ALLOW','ROLE','salesPerson'),(578,'Claim','getSummary','READ','ALLOW','ROLE','salesPerson'),(579,'Claim','updateClaim','WRITE','ALLOW','ROLE','salesPerson'),(580,'Claim','regularizeClaim','WRITE','ALLOW','ROLE','claimManager'),(581,'Claim','updateClaimDestination','WRITE','ALLOW','ROLE','claimManager'),(582,'Claim','downloadFile','READ','ALLOW','ROLE','claimManager'),(583,'Claim','deleteById','WRITE','ALLOW','ROLE','claimManager'),(584,'Claim','filter','READ','ALLOW','ROLE','salesPerson'),(585,'Claim','logs','READ','ALLOW','ROLE','claimManager'),(586,'Ticket','find','READ','ALLOW','ROLE','employee'),(587,'Ticket','findById','READ','ALLOW','ROLE','employee'),(588,'Ticket','findOne','READ','ALLOW','ROLE','employee'),(589,'Ticket','getVolume','READ','ALLOW','ROLE','employee'),(590,'Ticket','getTotalVolume','READ','ALLOW','ROLE','employee'),(591,'Ticket','summary','READ','ALLOW','ROLE','employee'),(592,'Ticket','priceDifference','READ','ALLOW','ROLE','employee'),(593,'Ticket','componentUpdate','WRITE','ALLOW','ROLE','employee'),(594,'Ticket','new','WRITE','ALLOW','ROLE','employee'),(595,'Ticket','isEditable','READ','ALLOW','ROLE','employee'),(596,'Ticket','setDeleted','WRITE','ALLOW','ROLE','salesPerson'),(597,'Ticket','restore','WRITE','ALLOW','ROLE','employee'),(598,'Ticket','getSales','READ','ALLOW','ROLE','employee'),(599,'Ticket','getSalesPersonMana','READ','ALLOW','ROLE','employee'),(600,'Ticket','filter','READ','ALLOW','ROLE','employee'),(601,'Ticket','makeInvoice','WRITE','ALLOW','ROLE','employee'),(602,'Ticket','updateEditableTicket','WRITE','ALLOW','ROLE','employee'),(603,'Ticket','updateDiscount','WRITE','ALLOW','ROLE','employee'),(604,'Ticket','transferSales','WRITE','ALLOW','ROLE','employee'),(605,'Ticket','sendSms','WRITE','ALLOW','ROLE','employee'),(606,'Ticket','isLocked','READ','ALLOW','ROLE','employee'),(607,'Ticket','freightCost','READ','ALLOW','ROLE','employee'),(608,'Ticket','getComponentsSum','READ','ALLOW','ROLE','employee'),(609,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','delivery'),(610,'Ticket','deliveryNoteCsv','READ','ALLOW','ROLE','employee'),(611,'State','find','READ','ALLOW','ROLE','employee'),(612,'State','findById','READ','ALLOW','ROLE','employee'),(613,'State','findOne','READ','ALLOW','ROLE','employee'),(614,'Worker','find','READ','ALLOW','ROLE','employee'),(615,'Worker','findById','READ','ALLOW','ROLE','employee'),(616,'Worker','findOne','READ','ALLOW','ROLE','employee'),(617,'Worker','filter','READ','ALLOW','ROLE','employee'),(618,'Worker','getWorkedHours','READ','ALLOW','ROLE','employee'),(619,'Worker','active','READ','ALLOW','ROLE','employee'),(620,'Worker','activeWithRole','READ','ALLOW','ROLE','employee'),(621,'Worker','uploadFile','WRITE','ALLOW','ROLE','hr'),(622,'Worker','contracts','READ','ALLOW','ROLE','employee'),(623,'Worker','holidays','READ','ALLOW','ROLE','employee'),(624,'Worker','activeContract','READ','ALLOW','ROLE','employee'),(625,'Worker','activeWithInheritedRole','READ','ALLOW','ROLE','employee'),(626,'Ticket','collectionLabel','READ','ALLOW','ROLE','employee'),(628,'Ticket','expeditionPalletLabel','READ','ALLOW','ROLE','employee'),(629,'Ticket','editDiscount','WRITE','ALLOW','ROLE','artificialBoss'),(630,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesTeamBoss'),(635,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','administrative'),(636,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesPerson'),(637,'Claim','downloadFile','READ','ALLOW','ROLE','salesPerson'),(638,'Agency','seeExpired','READ','ALLOW','ROLE','artificialBoss'),(639,'Agency','seeExpired','READ','ALLOW','ROLE','logisticAssistant'),(640,'Claim','filter','READ','ALLOW','ROLE','buyer'),(641,'Claim','find','READ','ALLOW','ROLE','buyer'),(642,'Claim','findById','READ','ALLOW','ROLE','buyer'),(643,'Claim','getSummary','READ','ALLOW','ROLE','buyer'),(644,'Claim','filter','READ','ALLOW','ROLE','handmadeBoss'),(645,'Claim','find','READ','ALLOW','ROLE','handmadeBoss'),(646,'Claim','findById','READ','ALLOW','ROLE','handmadeBoss'),(647,'Claim','getSummary','READ','ALLOW','ROLE','handmadeBoss'),(648,'Claim','__get__lines','READ','ALLOW','ROLE','claimManager'),(649,'Claim','__get__lines','READ','ALLOW','ROLE','salesPerson'),(650,'Claim','getSummary','READ','ALLOW','ROLE','deliveryBoss'),(651,'Claim','findById','READ','ALLOW','ROLE','deliveryBoss'),(652,'Claim','find','READ','ALLOW','ROLE','deliveryBoss'),(653,'Claim','filter','READ','ALLOW','ROLE','deliveryBoss'),(654,'Ticket','editZone','WRITE','ALLOW','ROLE','logisticAssistant'),(655,'Entry','addFromPackaging','WRITE','ALLOW','ROLE','production'),(656,'Entry','addFromBuy','WRITE','ALLOW','ROLE','production'),(657,'Supplier','getItemsPackaging','READ','ALLOW','ROLE','production'),(658,'Ticket','closeAll','WRITE','ALLOW','ROLE','system'),(659,'Account','*','*','ALLOW','ROLE','itManagement'),(660,'Account','*','READ','ALLOW','ROLE','employee'),(664,'MailForward','*','*','ALLOW','ROLE','itManagement'),(665,'Role','*','READ','ALLOW','ROLE','employee'),(666,'Role','*','WRITE','ALLOW','ROLE','it'),(667,'VnUser','*','*','ALLOW','ROLE','itManagement'),(668,'VnUser','__get__preview','READ','ALLOW','ROLE','employee'),(669,'VnUser','preview','*','ALLOW','ROLE','employee'),(670,'VnUser','create','*','ALLOW','ROLE','itManagement'),(671,'VnUser','renewToken','WRITE','ALLOW','ROLE','employee'),(672,'PackingSiteAdvanced','*','*','ALLOW','ROLE','production'),(673,'InvoiceOut','makePdfAndNotify','WRITE','ALLOW','ROLE','invoicing'),(674,'InvoiceOutConfig','*','READ','ALLOW','ROLE','invoicing'),(676,'Ticket','invoiceTickets','WRITE','ALLOW','ROLE','employee'),(680,'MailAliasAccount','*','READ','ALLOW','ROLE','employee'),(681,'MailAliasAccount','create','WRITE','ALLOW','ROLE','employee'),(682,'MailAliasAccount','deleteById','WRITE','ALLOW','ROLE','employee'),(683,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','itManagement'),(684,'WorkerDisableExcluded','*','READ','ALLOW','ROLE','itManagement'),(685,'WorkerDisableExcluded','*','WRITE','ALLOW','ROLE','itManagement'),(686,'MailForward','*','*','ALLOW','ROLE','hr'),(687,'ClientSms','find','READ','ALLOW','ROLE','employee'),(688,'ClientSms','create','WRITE','ALLOW','ROLE','employee'),(689,'Vehicle','sorted','WRITE','ALLOW','ROLE','employee'),(690,'Roadmap','*','*','ALLOW','ROLE','palletizerBoss'),(691,'Roadmap','*','*','ALLOW','ROLE','productionBoss'),(692,'ExpeditionTruck','*','*','ALLOW','ROLE','palletizerBoss'),(693,'ExpeditionTruck','*','*','ALLOW','ROLE','productionBoss'),(694,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','marketingBoss'),(695,'ViaexpressConfig','internationalExpedition','WRITE','ALLOW','ROLE','employee'),(696,'ViaexpressConfig','renderer','READ','ALLOW','ROLE','employee'),(697,'Ticket','transferClient','WRITE','ALLOW','ROLE','administrative'),(698,'Ticket','canEditWeekly','WRITE','ALLOW','ROLE','buyer'),(699,'TicketSms','find','READ','ALLOW','ROLE','salesPerson'),(701,'Docuware','upload','WRITE','ALLOW','ROLE','deliveryBoss'),(702,'Ticket','docuwareDownload','READ','ALLOW','ROLE','salesPerson'); +INSERT INTO `ACL` VALUES (3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','trainee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','trainee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','trainee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','trainee'),(30,'GreugeType','*','READ','ALLOW','ROLE','trainee'),(31,'Mandate','*','READ','ALLOW','ROLE','trainee'),(32,'MandateType','*','READ','ALLOW','ROLE','trainee'),(33,'Company','*','READ','ALLOW','ROLE','trainee'),(34,'Greuge','*','READ','ALLOW','ROLE','trainee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer'),(55,'Recovery','*','READ','ALLOW','ROLE','trainee'),(56,'Recovery','*','WRITE','ALLOW','ROLE','administrative'),(58,'CreditClassification','*','*','ALLOW','ROLE','insurance'),(60,'CreditInsurance','*','*','ALLOW','ROLE','insurance'),(61,'InvoiceOut','*','READ','ALLOW','ROLE','employee'),(63,'TicketObservation','*','*','ALLOW','ROLE','employee'),(64,'Route','*','READ','ALLOW','ROLE','employee'),(65,'Sale','*','READ','ALLOW','ROLE','employee'),(66,'TicketTracking','*','READ','ALLOW','ROLE','employee'),(68,'TicketPackaging','*','*','ALLOW','ROLE','employee'),(69,'Packaging','*','READ','ALLOW','ROLE','employee'),(70,'Packaging','*','WRITE','ALLOW','ROLE','logistic'),(72,'SaleComponent','*','READ','ALLOW','ROLE','employee'),(73,'Expedition','*','READ','ALLOW','ROLE','employee'),(74,'Expedition','*','WRITE','ALLOW','ROLE','deliveryBoss'),(75,'Expedition','*','WRITE','ALLOW','ROLE','production'),(76,'AnnualAverageInvoiced','*','READ','ALLOW','ROLE','employee'),(77,'WorkerMana','*','READ','ALLOW','ROLE','employee'),(78,'TicketTracking','*','WRITE','ALLOW','ROLE','production'),(79,'TicketTracking','changeState','*','ALLOW','ROLE','employee'),(80,'Sale','deleteSales','*','ALLOW','ROLE','employee'),(81,'Sale','moveToTicket','*','ALLOW','ROLE','employee'),(82,'Sale','updateQuantity','*','ALLOW','ROLE','employee'),(83,'Sale','updatePrice','*','ALLOW','ROLE','employee'),(84,'Sale','updateDiscount','*','ALLOW','ROLE','employee'),(85,'SaleTracking','*','READ','ALLOW','ROLE','employee'),(86,'Order','*','*','ALLOW','ROLE','employee'),(87,'OrderRow','*','*','ALLOW','ROLE','employee'),(88,'ClientContact','*','*','ALLOW','ROLE','employee'),(89,'Sale','moveToNewTicket','*','ALLOW','ROLE','employee'),(90,'Sale','reserve','*','ALLOW','ROLE','employee'),(91,'TicketWeekly','*','READ','ALLOW','ROLE','employee'),(94,'Agency','landsThatDay','*','ALLOW','ROLE','employee'),(96,'ClaimEnd','*','READ','ALLOW','ROLE','employee'),(97,'ClaimEnd','*','WRITE','ALLOW','ROLE','claimManager'),(98,'ClaimBeginning','*','*','ALLOW','ROLE','employee'),(99,'ClaimDevelopment','*','READ','ALLOW','ROLE','employee'),(100,'ClaimDevelopment','*','WRITE','ALLOW','ROLE','claimManager'),(102,'Claim','createFromSales','*','ALLOW','ROLE','employee'),(104,'Item','*','WRITE','ALLOW','ROLE','marketingBoss'),(105,'ItemBarcode','*','WRITE','ALLOW','ROLE','marketingBoss'),(106,'ItemBotanical','*','WRITE','ALLOW','ROLE','marketingBoss'),(108,'ItemPlacement','*','WRITE','ALLOW','ROLE','marketingBoss'),(109,'UserConfig','*','*','ALLOW','ROLE','employee'),(110,'Bank','*','READ','ALLOW','ROLE','trainee'),(111,'ClientLog','*','READ','ALLOW','ROLE','trainee'),(112,'Defaulter','*','READ','ALLOW','ROLE','employee'),(113,'ClientRisk','*','READ','ALLOW','ROLE','trainee'),(114,'Receipt','*','READ','ALLOW','ROLE','trainee'),(115,'Receipt','*','WRITE','ALLOW','ROLE','administrative'),(116,'BankEntity','*','*','ALLOW','ROLE','employee'),(117,'ClientSample','*','*','ALLOW','ROLE','employee'),(118,'WorkerTeam','*','*','ALLOW','ROLE','salesPerson'),(119,'Travel','*','READ','ALLOW','ROLE','employee'),(120,'Travel','*','WRITE','ALLOW','ROLE','buyer'),(121,'Item','regularize','*','ALLOW','ROLE','employee'),(122,'TicketRequest','*','*','ALLOW','ROLE','employee'),(124,'Client','confirmTransaction','WRITE','ALLOW','ROLE','administrative'),(125,'Agency','getAgenciesWithWarehouse','*','ALLOW','ROLE','employee'),(126,'Client','activeWorkersWithRole','*','ALLOW','ROLE','employee'),(127,'TicketLog','*','READ','ALLOW','ROLE','employee'),(129,'TicketService','*','*','ALLOW','ROLE','employee'),(130,'Expedition','*','WRITE','ALLOW','ROLE','packager'),(131,'CreditInsurance','*','READ','ALLOW','ROLE','trainee'),(132,'CreditClassification','*','READ','ALLOW','ROLE','trainee'),(133,'ItemTag','*','WRITE','ALLOW','ROLE','marketingBoss'),(135,'ZoneGeo','*','READ','ALLOW','ROLE','employee'),(136,'ZoneCalendar','*','READ','ALLOW','ROLE','employee'),(137,'ZoneIncluded','*','READ','ALLOW','ROLE','employee'),(138,'LabourHoliday','*','READ','ALLOW','ROLE','employee'),(139,'LabourHolidayLegend','*','READ','ALLOW','ROLE','employee'),(140,'LabourHolidayType','*','READ','ALLOW','ROLE','employee'),(141,'Zone','*','*','ALLOW','ROLE','logisticBoss'),(142,'ZoneCalendar','*','WRITE','ALLOW','ROLE','deliveryBoss'),(143,'ZoneIncluded','*','*','ALLOW','ROLE','deliveryBoss'),(144,'Stowaway','*','*','ALLOW','ROLE','employee'),(145,'Ticket','getPossibleStowaways','READ','ALLOW','ROLE','employee'),(147,'UserConfigView','*','*','ALLOW','ROLE','employee'),(148,'UserConfigView','*','*','ALLOW','ROLE','employee'),(149,'Sip','*','READ','ALLOW','ROLE','employee'),(150,'Sip','*','WRITE','ALLOW','ROLE','hr'),(151,'Department','*','READ','ALLOW','ROLE','employee'),(152,'Department','*','WRITE','ALLOW','ROLE','hr'),(153,'Route','*','READ','ALLOW','ROLE','employee'),(154,'Route','*','WRITE','ALLOW','ROLE','delivery'),(155,'Calendar','*','READ','ALLOW','ROLE','hr'),(156,'WorkerLabour','*','READ','ALLOW','ROLE','hr'),(157,'Calendar','absences','READ','ALLOW','ROLE','employee'),(158,'ItemTag','*','WRITE','ALLOW','ROLE','accessory'),(160,'TicketServiceType','*','READ','ALLOW','ROLE','employee'),(161,'TicketConfig','*','READ','ALLOW','ROLE','employee'),(162,'InvoiceOut','delete','WRITE','ALLOW','ROLE','invoicing'),(163,'InvoiceOut','book','WRITE','ALLOW','ROLE','invoicing'),(165,'TicketDms','*','*','ALLOW','ROLE','employee'),(167,'Worker','isSubordinate','READ','ALLOW','ROLE','employee'),(168,'Worker','mySubordinates','READ','ALLOW','ROLE','employee'),(169,'WorkerTimeControl','filter','READ','ALLOW','ROLE','employee'),(170,'WorkerTimeControl','addTime','WRITE','ALLOW','ROLE','employee'),(171,'TicketServiceType','*','WRITE','ALLOW','ROLE','administrative'),(172,'Sms','*','READ','ALLOW','ROLE','employee'),(173,'Sms','send','WRITE','ALLOW','ROLE','employee'),(176,'Device','*','*','ALLOW','ROLE','employee'),(177,'Device','*','*','ALLOW','ROLE','employee'),(178,'WorkerTimeControl','*','*','ALLOW','ROLE','employee'),(179,'ItemLog','*','READ','ALLOW','ROLE','employee'),(180,'RouteLog','*','READ','ALLOW','ROLE','employee'),(181,'Dms','removeFile','WRITE','ALLOW','ROLE','employee'),(182,'Dms','uploadFile','WRITE','ALLOW','ROLE','employee'),(183,'Dms','downloadFile','READ','ALLOW','ROLE','employee'),(184,'Client','uploadFile','WRITE','ALLOW','ROLE','employee'),(185,'ClientDms','removeFile','WRITE','ALLOW','ROLE','employee'),(186,'ClientDms','*','READ','ALLOW','ROLE','trainee'),(187,'Ticket','uploadFile','WRITE','ALLOW','ROLE','employee'),(190,'Route','updateVolume','WRITE','ALLOW','ROLE','deliveryBoss'),(191,'Agency','getLanded','READ','ALLOW','ROLE','employee'),(192,'Agency','getShipped','READ','ALLOW','ROLE','employee'),(194,'Postcode','*','WRITE','ALLOW','ROLE','deliveryBoss'),(195,'Ticket','addSale','WRITE','ALLOW','ROLE','employee'),(196,'Dms','updateFile','WRITE','ALLOW','ROLE','employee'),(197,'Dms','*','READ','ALLOW','ROLE','trainee'),(198,'ClaimDms','removeFile','WRITE','ALLOW','ROLE','employee'),(199,'ClaimDms','*','READ','ALLOW','ROLE','employee'),(200,'Claim','uploadFile','WRITE','ALLOW','ROLE','employee'),(201,'Sale','updateConcept','WRITE','ALLOW','ROLE','employee'),(202,'Claim','updateClaimAction','WRITE','ALLOW','ROLE','claimManager'),(203,'UserPhone','*','*','ALLOW','ROLE','employee'),(204,'WorkerDms','removeFile','WRITE','ALLOW','ROLE','hr'),(205,'WorkerDms','*','READ','ALLOW','ROLE','hr'),(206,'Chat','*','*','ALLOW','ROLE','employee'),(207,'Chat','sendMessage','*','ALLOW','ROLE','employee'),(208,'Sale','recalculatePrice','WRITE','ALLOW','ROLE','employee'),(209,'Ticket','recalculateComponents','WRITE','ALLOW','ROLE','employee'),(211,'TravelLog','*','READ','ALLOW','ROLE','buyer'),(212,'Thermograph','*','*','ALLOW','ROLE','buyer'),(213,'TravelThermograph','*','WRITE','ALLOW','ROLE','buyer'),(214,'Entry','*','*','ALLOW','ROLE','buyer'),(215,'TicketWeekly','*','WRITE','ALLOW','ROLE','buyer'),(216,'TravelThermograph','*','READ','ALLOW','ROLE','employee'),(218,'Intrastat','*','*','ALLOW','ROLE','buyer'),(221,'UserConfig','getUserConfig','READ','ALLOW','ROLE','account'),(222,'Client','*','READ','ALLOW','ROLE','trainee'),(226,'ClientObservation','*','READ','ALLOW','ROLE','trainee'),(227,'Address','*','READ','ALLOW','ROLE','trainee'),(228,'AddressObservation','*','READ','ALLOW','ROLE','trainee'),(230,'ClientCredit','*','READ','ALLOW','ROLE','trainee'),(231,'ClientContact','*','READ','ALLOW','ROLE','trainee'),(232,'ClientSample','*','READ','ALLOW','ROLE','trainee'),(233,'EntryLog','*','READ','ALLOW','ROLE','buyer'),(234,'WorkerLog','find','READ','ALLOW','ROLE','hr'),(235,'CustomsAgent','*','*','ALLOW','ROLE','employee'),(236,'Buy','*','*','ALLOW','ROLE','buyer'),(237,'WorkerDms','filter','*','ALLOW','ROLE','employee'),(238,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(239,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(240,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(241,'SupplierContact','*','WRITE','ALLOW','ROLE','administrative'),(242,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(244,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(248,'RoleMapping','*','READ','ALLOW','ROLE','account'),(249,'UserPassword','*','READ','ALLOW','ROLE','account'),(250,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(251,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(252,'Supplier','*','READ','ALLOW','ROLE','employee'),(253,'Supplier','*','WRITE','ALLOW','ROLE','administrative'),(254,'SupplierLog','*','READ','ALLOW','ROLE','employee'),(256,'Image','*','WRITE','ALLOW','ROLE','employee'),(257,'FixedPrice','*','*','ALLOW','ROLE','buyer'),(258,'PayDem','*','READ','ALLOW','ROLE','employee'),(259,'Client','createReceipt','*','ALLOW','ROLE','salesAssistant'),(260,'PrintServerQueue','*','WRITE','ALLOW','ROLE','employee'),(261,'SupplierAccount','*','*','ALLOW','ROLE','administrative'),(262,'Entry','*','*','ALLOW','ROLE','administrative'),(263,'InvoiceIn','*','*','ALLOW','ROLE','administrative'),(264,'StarredModule','*','*','ALLOW','ROLE','employee'),(265,'ItemBotanical','*','WRITE','ALLOW','ROLE','logisticBoss'),(266,'ZoneLog','*','READ','ALLOW','ROLE','employee'),(267,'Genus','*','WRITE','ALLOW','ROLE','logisticBoss'),(268,'Specie','*','WRITE','ALLOW','ROLE','logisticBoss'),(269,'InvoiceOut','createPdf','WRITE','ALLOW','ROLE','employee'),(270,'SupplierAddress','*','*','ALLOW','ROLE','employee'),(271,'SalesMonitor','*','*','ALLOW','ROLE','employee'),(272,'InvoiceInLog','*','READ','ALLOW','ROLE','employee'),(273,'InvoiceInTax','*','*','ALLOW','ROLE','administrative'),(274,'InvoiceInLog','*','READ','ALLOW','ROLE','administrative'),(275,'InvoiceOut','createManualInvoice','WRITE','ALLOW','ROLE','invoicing'),(276,'InvoiceOut','globalInvoicing','WRITE','ALLOW','ROLE','invoicing'),(278,'RoleInherit','*','WRITE','ALLOW','ROLE','grant'),(279,'MailAlias','*','*','ALLOW','ROLE','marketing'),(283,'EntryObservation','*','*','ALLOW','ROLE','buyer'),(284,'LdapConfig','*','*','ALLOW','ROLE','sysadmin'),(285,'SambaConfig','*','*','ALLOW','ROLE','sysadmin'),(286,'ACL','*','*','ALLOW','ROLE','developer'),(287,'AccessToken','*','*','ALLOW','ROLE','developer'),(293,'RoleInherit','*','*','ALLOW','ROLE','it'),(294,'RoleRole','*','*','ALLOW','ROLE','it'),(295,'AccountConfig','*','*','ALLOW','ROLE','sysadmin'),(296,'Collection','*','READ','ALLOW','ROLE','employee'),(297,'Sale','refund','WRITE','ALLOW','ROLE','invoicing'),(298,'InvoiceInDueDay','*','*','ALLOW','ROLE','administrative'),(299,'Collection','setSaleQuantity','*','ALLOW','ROLE','employee'),(302,'AgencyTerm','*','*','ALLOW','ROLE','administrative'),(303,'ClaimLog','*','READ','ALLOW','ROLE','claimManager'),(304,'Edi','updateData','WRITE','ALLOW','ROLE','employee'),(305,'EducationLevel','*','*','ALLOW','ROLE','employee'),(306,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(307,'SupplierAgencyTerm','*','*','ALLOW','ROLE','administrative'),(308,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(309,'Zone','getZoneClosing','*','ALLOW','ROLE','employee'),(310,'ExpeditionState','*','READ','ALLOW','ROLE','employee'),(311,'Expense','*','READ','ALLOW','ROLE','employee'),(312,'Expense','*','WRITE','ALLOW','ROLE','administrative'),(314,'SupplierActivity','*','READ','ALLOW','ROLE','employee'),(315,'SupplierActivity','*','WRITE','ALLOW','ROLE','administrative'),(316,'Dms','deleteTrashFiles','WRITE','ALLOW','ROLE','employee'),(317,'ClientUnpaid','*','*','ALLOW','ROLE','administrative'),(318,'MdbVersion','*','*','ALLOW','ROLE','developer'),(319,'ItemType','*','READ','ALLOW','ROLE','employee'),(320,'ItemType','*','WRITE','ALLOW','ROLE','buyer'),(321,'InvoiceOut','refund','WRITE','ALLOW','ROLE','invoicing'),(322,'InvoiceOut','refund','WRITE','ALLOW','ROLE','salesAssistant'),(323,'InvoiceOut','refund','WRITE','ALLOW','ROLE','claimManager'),(324,'Ticket','refund','WRITE','ALLOW','ROLE','invoicing'),(325,'Ticket','refund','WRITE','ALLOW','ROLE','salesAssistant'),(326,'Ticket','refund','WRITE','ALLOW','ROLE','claimManager'),(327,'Sale','refund','WRITE','ALLOW','ROLE','salesAssistant'),(328,'Sale','refund','WRITE','ALLOW','ROLE','claimManager'),(329,'TicketRefund','*','WRITE','ALLOW','ROLE','invoicing'),(330,'ClaimObservation','*','WRITE','ALLOW','ROLE','salesPerson'),(331,'ClaimObservation','*','READ','ALLOW','ROLE','salesPerson'),(332,'Client','setPassword','WRITE','ALLOW','ROLE','salesPerson'),(333,'Client','updateUser','WRITE','ALLOW','ROLE','salesPerson'),(334,'ShelvingLog','*','READ','ALLOW','ROLE','employee'),(335,'ZoneExclusionGeo','*','READ','ALLOW','ROLE','employee'),(336,'ZoneExclusionGeo','*','WRITE','ALLOW','ROLE','deliveryBoss'),(337,'Parking','*','*','ALLOW','ROLE','employee'),(338,'Shelving','*','*','ALLOW','ROLE','employee'),(339,'OsTicket','*','*','ALLOW','ROLE','employee'),(340,'OsTicketConfig','*','*','ALLOW','ROLE','it'),(341,'ClientConsumptionQueue','*','WRITE','ALLOW','ROLE','employee'),(342,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','employee'),(343,'Ticket','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(344,'Ticket','deliveryNoteCsvPdf','READ','ALLOW','ROLE','employee'),(345,'Ticket','deliveryNoteCsvEmail','READ','ALLOW','ROLE','employee'),(346,'Client','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(347,'Client','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(348,'Client','clientWelcomeHtml','READ','ALLOW','ROLE','employee'),(349,'Client','clientWelcomeEmail','WRITE','ALLOW','ROLE','employee'),(350,'Client','creditRequestPdf','READ','ALLOW','ROLE','employee'),(351,'Client','creditRequestHtml','READ','ALLOW','ROLE','employee'),(352,'Client','creditRequestEmail','WRITE','ALLOW','ROLE','employee'),(353,'Client','printerSetupHtml','READ','ALLOW','ROLE','employee'),(354,'Client','printerSetupEmail','WRITE','ALLOW','ROLE','employee'),(355,'Client','sepaCoreEmail','WRITE','ALLOW','ROLE','employee'),(356,'Client','letterDebtorPdf','READ','ALLOW','ROLE','employee'),(357,'Client','letterDebtorStHtml','READ','ALLOW','ROLE','employee'),(358,'Client','letterDebtorStEmail','WRITE','ALLOW','ROLE','employee'),(359,'Client','letterDebtorNdHtml','READ','ALLOW','ROLE','employee'),(360,'Client','letterDebtorNdEmail','WRITE','ALLOW','ROLE','employee'),(361,'Client','clientDebtStatementPdf','READ','ALLOW','ROLE','employee'),(362,'Client','clientDebtStatementHtml','READ','ALLOW','ROLE','employee'),(363,'Client','clientDebtStatementEmail','WRITE','ALLOW','ROLE','employee'),(364,'Client','incotermsAuthorizationPdf','READ','ALLOW','ROLE','employee'),(365,'Client','incotermsAuthorizationHtml','READ','ALLOW','ROLE','employee'),(366,'Client','incotermsAuthorizationEmail','WRITE','ALLOW','ROLE','employee'),(367,'Client','consumptionSendQueued','WRITE','ALLOW','ROLE','system'),(368,'InvoiceOut','invoiceEmail','WRITE','ALLOW','ROLE','employee'),(369,'InvoiceOut','exportationPdf','READ','ALLOW','ROLE','employee'),(370,'InvoiceOut','sendQueued','WRITE','ALLOW','ROLE','system'),(371,'Ticket','invoiceCsvPdf','READ','ALLOW','ROLE','employee'),(372,'Ticket','invoiceCsvEmail','WRITE','ALLOW','ROLE','employee'),(373,'Supplier','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(374,'Supplier','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(375,'Travel','extraCommunityPdf','READ','ALLOW','ROLE','employee'),(376,'Travel','extraCommunityEmail','WRITE','ALLOW','ROLE','employee'),(377,'Entry','entryOrderPdf','READ','ALLOW','ROLE','employee'),(378,'OsTicket','osTicketReportEmail','WRITE','ALLOW','ROLE','system'),(379,'Item','buyerWasteEmail','WRITE','ALLOW','ROLE','system'),(380,'Claim','claimPickupPdf','READ','ALLOW','ROLE','employee'),(381,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','claimManager'),(382,'Item','labelPdf','READ','ALLOW','ROLE','employee'),(383,'Sector','*','READ','ALLOW','ROLE','employee'),(384,'Sector','*','WRITE','ALLOW','ROLE','employee'),(385,'Route','driverRoutePdf','READ','ALLOW','ROLE','employee'),(386,'Route','driverRouteEmail','WRITE','ALLOW','ROLE','employee'),(387,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','customer'),(388,'Supplier','newSupplier','WRITE','ALLOW','ROLE','administrative'),(389,'ClaimRma','*','READ','ALLOW','ROLE','claimManager'),(390,'ClaimRma','*','WRITE','ALLOW','ROLE','claimManager'),(391,'Notification','*','WRITE','ALLOW','ROLE','system'),(392,'Boxing','*','*','ALLOW','ROLE','employee'),(393,'Url','*','READ','ALLOW','ROLE','employee'),(394,'Url','*','WRITE','ALLOW','ROLE','it'),(395,'ItemShelving','*','READ','ALLOW','ROLE','employee'),(396,'ItemShelving','*','WRITE','ALLOW','ROLE','production'),(397,'ItemShelvingPlacementSupplyStock','*','READ','ALLOW','ROLE','employee'),(398,'NotificationQueue','*','*','ALLOW','ROLE','employee'),(399,'InvoiceOut','clientsToInvoice','WRITE','ALLOW','ROLE','invoicing'),(400,'InvoiceOut','invoiceClient','WRITE','ALLOW','ROLE','invoicing'),(401,'Sale','editTracked','WRITE','ALLOW','ROLE','production'),(402,'Sale','editFloramondo','WRITE','ALLOW','ROLE','salesAssistant'),(403,'Receipt','balanceCompensationEmail','WRITE','ALLOW','ROLE','employee'),(404,'Receipt','balanceCompensationPdf','READ','ALLOW','ROLE','employee'),(405,'Ticket','getTicketsFuture','READ','ALLOW','ROLE','employee'),(406,'Ticket','merge','WRITE','ALLOW','ROLE','employee'),(407,'Sale','editFloramondo','WRITE','ALLOW','ROLE','logistic'),(408,'ZipConfig','*','*','ALLOW','ROLE','employee'),(409,'Item','*','WRITE','ALLOW','ROLE','administrative'),(410,'Sale','editCloned','WRITE','ALLOW','ROLE','buyer'),(411,'Sale','editCloned','WRITE','ALLOW','ROLE','salesAssistant'),(414,'MdbVersion','*','READ','ALLOW','ROLE','$everyone'),(416,'TicketLog','getChanges','READ','ALLOW','ROLE','employee'),(417,'Ticket','getTicketsAdvance','READ','ALLOW','ROLE','employee'),(418,'EntryLog','*','READ','ALLOW','ROLE','administrative'),(419,'Sale','editTracked','WRITE','ALLOW','ROLE','buyer'),(420,'MdbBranch','*','READ','ALLOW','ROLE','$everyone'),(421,'ItemShelvingSale','*','*','ALLOW','ROLE','employee'),(422,'Docuware','checkFile','READ','ALLOW','ROLE','employee'),(423,'Docuware','download','READ','ALLOW','ROLE','salesPerson'),(424,'Docuware','upload','WRITE','ALLOW','ROLE','productionAssi'),(425,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','salesPerson'),(426,'TpvTransaction','confirm','WRITE','ALLOW','ROLE','$everyone'),(427,'TpvTransaction','start','WRITE','ALLOW','ROLE','$authenticated'),(428,'TpvTransaction','end','WRITE','ALLOW','ROLE','$authenticated'),(429,'ItemConfig','*','READ','ALLOW','ROLE','employee'),(431,'Tag','onSubmit','WRITE','ALLOW','ROLE','employee'),(432,'Worker','updateAttributes','WRITE','ALLOW','ROLE','hr'),(433,'Worker','createAbsence','*','ALLOW','ROLE','employee'),(434,'Worker','updateAbsence','WRITE','ALLOW','ROLE','employee'),(435,'Worker','deleteAbsence','*','ALLOW','ROLE','employee'),(436,'Worker','new','WRITE','ALLOW','ROLE','hr'),(438,'Client','getClientOrSupplierReference','READ','ALLOW','ROLE','employee'),(439,'NotificationSubscription','*','*','ALLOW','ROLE','employee'),(440,'NotificationAcl','*','READ','ALLOW','ROLE','employee'),(441,'MdbApp','*','READ','ALLOW','ROLE','$everyone'),(442,'MdbApp','*','*','ALLOW','ROLE','developer'),(443,'ItemConfig','*','*','ALLOW','ROLE','employee'),(444,'DeviceProduction','*','*','ALLOW','ROLE','hr'),(445,'DeviceProductionModels','*','*','ALLOW','ROLE','hr'),(446,'DeviceProductionState','*','*','ALLOW','ROLE','hr'),(447,'DeviceProductionUser','*','*','ALLOW','ROLE','hr'),(448,'DeviceProduction','*','*','ALLOW','ROLE','productionAssi'),(449,'DeviceProductionModels','*','*','ALLOW','ROLE','productionAssi'),(450,'DeviceProductionState','*','*','ALLOW','ROLE','productionAssi'),(451,'DeviceProductionUser','*','*','ALLOW','ROLE','productionAssi'),(452,'Worker','deallocatePDA','*','ALLOW','ROLE','hr'),(453,'Worker','allocatePDA','*','ALLOW','ROLE','hr'),(454,'Worker','deallocatePDA','*','ALLOW','ROLE','productionAssi'),(455,'Worker','allocatePDA','*','ALLOW','ROLE','productionAssi'),(456,'Zone','*','*','ALLOW','ROLE','deliveryBoss'),(457,'Account','setPassword','WRITE','ALLOW','ROLE','itManagement'),(458,'Operator','*','READ','ALLOW','ROLE','employee'),(459,'Operator','*','WRITE','ALLOW','ROLE','employee'),(460,'InvoiceIn','getSerial','READ','ALLOW','ROLE','administrative'),(461,'Ticket','saveSign','WRITE','ALLOW','ROLE','employee'),(462,'InvoiceOut','negativeBases','READ','ALLOW','ROLE','administrative'),(463,'InvoiceOut','negativeBasesCsv','READ','ALLOW','ROLE','administrative'),(464,'WorkerObservation','*','*','ALLOW','ROLE','hr'),(465,'ClientInforma','*','READ','ALLOW','ROLE','employee'),(466,'ClientInforma','*','WRITE','ALLOW','ROLE','financial'),(467,'Receipt','receiptEmail','*','ALLOW','ROLE','salesAssistant'),(468,'Client','setRating','WRITE','ALLOW','ROLE','financial'),(469,'Client','*','READ','ALLOW','ROLE','employee'),(470,'Client','addressesPropagateRe','*','ALLOW','ROLE','employee'),(471,'Client','canBeInvoiced','*','ALLOW','ROLE','employee'),(472,'Client','canCreateTicket','*','ALLOW','ROLE','employee'),(473,'Client','consumption','*','ALLOW','ROLE','employee'),(474,'Client','createAddress','*','ALLOW','ROLE','employee'),(475,'Client','createWithUser','*','ALLOW','ROLE','employee'),(476,'Client','extendedListFilter','*','ALLOW','ROLE','employee'),(477,'Client','getAverageInvoiced','*','ALLOW','ROLE','employee'),(478,'Client','getCard','*','ALLOW','ROLE','employee'),(479,'Client','getDebt','*','ALLOW','ROLE','employee'),(480,'Client','getMana','*','ALLOW','ROLE','employee'),(481,'Client','transactions','*','ALLOW','ROLE','employee'),(482,'Client','hasCustomerRole','*','ALLOW','ROLE','employee'),(483,'Client','isValidClient','*','ALLOW','ROLE','employee'),(484,'Client','lastActiveTickets','*','ALLOW','ROLE','employee'),(485,'Client','sendSms','*','ALLOW','ROLE','employee'),(486,'Client','setPassword','*','ALLOW','ROLE','employee'),(487,'Client','summary','*','ALLOW','ROLE','employee'),(488,'Client','updateAddress','*','ALLOW','ROLE','employee'),(489,'Client','updateFiscalData','*','ALLOW','ROLE','employee'),(491,'Client','uploadFile','*','ALLOW','ROLE','employee'),(492,'Client','campaignMetricsPdf','*','ALLOW','ROLE','employee'),(493,'Client','campaignMetricsEmail','*','ALLOW','ROLE','employee'),(494,'Client','clientWelcomeHtml','*','ALLOW','ROLE','employee'),(495,'Client','clientWelcomeEmail','*','ALLOW','ROLE','employee'),(496,'Client','printerSetupHtml','*','ALLOW','ROLE','employee'),(497,'Client','printerSetupEmail','*','ALLOW','ROLE','employee'),(498,'Client','sepaCoreEmail','*','ALLOW','ROLE','employee'),(499,'Client','letterDebtorPdf','*','ALLOW','ROLE','employee'),(500,'Client','letterDebtorStHtml','*','ALLOW','ROLE','employee'),(501,'Client','letterDebtorStEmail','*','ALLOW','ROLE','employee'),(502,'Client','letterDebtorNdHtml','*','ALLOW','ROLE','employee'),(503,'Client','letterDebtorNdEmail','*','ALLOW','ROLE','employee'),(504,'Client','clientDebtStatementPdf','*','ALLOW','ROLE','employee'),(505,'Client','clientDebtStatementHtml','*','ALLOW','ROLE','employee'),(506,'Client','clientDebtStatementEmail','*','ALLOW','ROLE','employee'),(507,'Client','creditRequestPdf','*','ALLOW','ROLE','employee'),(508,'Client','creditRequestHtml','*','ALLOW','ROLE','employee'),(509,'Client','creditRequestEmail','*','ALLOW','ROLE','employee'),(510,'Client','incotermsAuthorizationPdf','*','ALLOW','ROLE','employee'),(511,'Client','incotermsAuthorizationHtml','*','ALLOW','ROLE','employee'),(512,'Client','incotermsAuthorizationEmail','*','ALLOW','ROLE','employee'),(513,'Client','consumptionSendQueued','*','ALLOW','ROLE','employee'),(514,'Client','filter','*','ALLOW','ROLE','employee'),(515,'Client','getClientOrSupplierReference','*','ALLOW','ROLE','employee'),(516,'Client','upsert','*','ALLOW','ROLE','employee'),(517,'Client','create','*','ALLOW','ROLE','employee'),(518,'Client','replaceById','*','ALLOW','ROLE','employee'),(519,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(520,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(521,'Client','deleteById','*','ALLOW','ROLE','employee'),(522,'Client','replaceOrCreate','*','ALLOW','ROLE','employee'),(523,'Client','updateAll','*','ALLOW','ROLE','employee'),(524,'Client','upsertWithWhere','*','ALLOW','ROLE','employee'),(525,'Defaulter','observationEmail','WRITE','ALLOW','ROLE','employee'),(527,'VnUser','acl','READ','ALLOW','ROLE','account'),(528,'VnUser','getCurrentUserData','READ','ALLOW','ROLE','account'),(530,'Account','exists','READ','ALLOW','ROLE','account'),(531,'Account','exists','READ','ALLOW','ROLE','account'),(532,'UserLog','*','READ','ALLOW','ROLE','employee'),(533,'RoleLog','*','READ','ALLOW','ROLE','employee'),(534,'WagonType','*','*','ALLOW','ROLE','productionAssi'),(535,'WagonTypeColor','*','*','ALLOW','ROLE','productionAssi'),(536,'WagonTypeTray','*','*','ALLOW','ROLE','productionAssi'),(537,'WagonConfig','*','*','ALLOW','ROLE','productionAssi'),(538,'CollectionWagon','*','*','ALLOW','ROLE','productionAssi'),(539,'CollectionWagonTicket','*','*','ALLOW','ROLE','productionAssi'),(540,'Wagon','*','*','ALLOW','ROLE','productionAssi'),(541,'WagonType','createWagonType','*','ALLOW','ROLE','productionAssi'),(542,'WagonType','deleteWagonType','*','ALLOW','ROLE','productionAssi'),(543,'WagonType','editWagonType','*','ALLOW','ROLE','productionAssi'),(544,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(545,'Agency','find','READ','ALLOW','ROLE','employee'),(546,'Agency','seeExpired','READ','ALLOW','ROLE','coolerAssist'),(547,'WorkerLog','models','READ','ALLOW','ROLE','hr'),(548,'Ticket','editDiscount','WRITE','ALLOW','ROLE','claimManager'),(549,'Ticket','editDiscount','WRITE','ALLOW','ROLE','salesPerson'),(550,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','salesAssistant'),(551,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','deliveryBoss'),(552,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','buyer'),(553,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','claimManager'),(554,'Ticket','deleteTicketWithPartPrepared','WRITE','ALLOW','ROLE','salesAssistant'),(555,'Ticket','editZone','WRITE','ALLOW','ROLE','deliveryBoss'),(556,'State','editableStates','READ','ALLOW','ROLE','employee'),(557,'State','seeEditableStates','READ','ALLOW','ROLE','administrative'),(558,'State','seeEditableStates','READ','ALLOW','ROLE','production'),(559,'State','isSomeEditable','READ','ALLOW','ROLE','salesPerson'),(560,'State','isAllEditable','READ','ALLOW','ROLE','production'),(561,'State','isAllEditable','READ','ALLOW','ROLE','administrative'),(562,'Agency','seeExpired','READ','ALLOW','ROLE','administrative'),(563,'Agency','seeExpired','READ','ALLOW','ROLE','productionBoss'),(564,'Claim','createAfterDeadline','WRITE','ALLOW','ROLE','claimManager'),(565,'Client','editAddressLogifloraAllowed','WRITE','ALLOW','ROLE','salesAssistant'),(566,'Client','editFiscalDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(567,'Client','editVerifiedDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(568,'Client','editCredit','WRITE','ALLOW','ROLE','financialBoss'),(569,'Client','zeroCreditEditor','WRITE','ALLOW','ROLE','financialBoss'),(570,'InvoiceOut','canCreatePdf','WRITE','ALLOW','ROLE','invoicing'),(571,'Supplier','editPayMethodCheck','WRITE','ALLOW','ROLE','financial'),(572,'Worker','isTeamBoss','WRITE','ALLOW','ROLE','teamBoss'),(573,'Worker','forceIsSubordinate','READ','ALLOW','ROLE','hr'),(574,'Claim','editState','WRITE','ALLOW','ROLE','claimManager'),(575,'Claim','find','READ','ALLOW','ROLE','salesPerson'),(576,'Claim','findById','READ','ALLOW','ROLE','salesPerson'),(577,'Claim','findOne','READ','ALLOW','ROLE','salesPerson'),(578,'Claim','getSummary','READ','ALLOW','ROLE','salesPerson'),(579,'Claim','updateClaim','WRITE','ALLOW','ROLE','salesPerson'),(580,'Claim','regularizeClaim','WRITE','ALLOW','ROLE','claimManager'),(581,'Claim','updateClaimDestination','WRITE','ALLOW','ROLE','claimManager'),(582,'Claim','downloadFile','READ','ALLOW','ROLE','claimManager'),(583,'Claim','deleteById','WRITE','ALLOW','ROLE','claimManager'),(584,'Claim','filter','READ','ALLOW','ROLE','salesPerson'),(585,'Claim','logs','READ','ALLOW','ROLE','claimManager'),(586,'Ticket','find','READ','ALLOW','ROLE','employee'),(587,'Ticket','findById','READ','ALLOW','ROLE','employee'),(588,'Ticket','findOne','READ','ALLOW','ROLE','employee'),(589,'Ticket','getVolume','READ','ALLOW','ROLE','employee'),(590,'Ticket','getTotalVolume','READ','ALLOW','ROLE','employee'),(591,'Ticket','summary','READ','ALLOW','ROLE','employee'),(592,'Ticket','priceDifference','READ','ALLOW','ROLE','employee'),(593,'Ticket','componentUpdate','WRITE','ALLOW','ROLE','employee'),(594,'Ticket','new','WRITE','ALLOW','ROLE','employee'),(595,'Ticket','isEditable','READ','ALLOW','ROLE','employee'),(596,'Ticket','setDeleted','WRITE','ALLOW','ROLE','salesPerson'),(597,'Ticket','restore','WRITE','ALLOW','ROLE','employee'),(598,'Ticket','getSales','READ','ALLOW','ROLE','employee'),(599,'Ticket','getSalesPersonMana','READ','ALLOW','ROLE','employee'),(600,'Ticket','filter','READ','ALLOW','ROLE','employee'),(601,'Ticket','makeInvoice','WRITE','ALLOW','ROLE','employee'),(602,'Ticket','updateEditableTicket','WRITE','ALLOW','ROLE','employee'),(603,'Ticket','updateDiscount','WRITE','ALLOW','ROLE','employee'),(604,'Ticket','transferSales','WRITE','ALLOW','ROLE','employee'),(605,'Ticket','sendSms','WRITE','ALLOW','ROLE','employee'),(606,'Ticket','isLocked','READ','ALLOW','ROLE','employee'),(607,'Ticket','freightCost','READ','ALLOW','ROLE','employee'),(608,'Ticket','getComponentsSum','READ','ALLOW','ROLE','employee'),(609,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','delivery'),(610,'Ticket','deliveryNoteCsv','READ','ALLOW','ROLE','employee'),(611,'State','find','READ','ALLOW','ROLE','employee'),(612,'State','findById','READ','ALLOW','ROLE','employee'),(613,'State','findOne','READ','ALLOW','ROLE','employee'),(614,'Worker','find','READ','ALLOW','ROLE','employee'),(615,'Worker','findById','READ','ALLOW','ROLE','employee'),(616,'Worker','findOne','READ','ALLOW','ROLE','employee'),(617,'Worker','filter','READ','ALLOW','ROLE','employee'),(618,'Worker','getWorkedHours','READ','ALLOW','ROLE','employee'),(619,'Worker','active','READ','ALLOW','ROLE','employee'),(620,'Worker','activeWithRole','READ','ALLOW','ROLE','employee'),(621,'Worker','uploadFile','WRITE','ALLOW','ROLE','hr'),(622,'Worker','contracts','READ','ALLOW','ROLE','employee'),(623,'Worker','holidays','READ','ALLOW','ROLE','employee'),(624,'Worker','activeContract','READ','ALLOW','ROLE','employee'),(625,'Worker','activeWithInheritedRole','READ','ALLOW','ROLE','employee'),(626,'Ticket','collectionLabel','READ','ALLOW','ROLE','employee'),(628,'Ticket','expeditionPalletLabel','READ','ALLOW','ROLE','employee'),(629,'Ticket','editDiscount','WRITE','ALLOW','ROLE','artificialBoss'),(630,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesTeamBoss'),(635,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','administrative'),(636,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesPerson'),(637,'Claim','downloadFile','READ','ALLOW','ROLE','salesPerson'),(638,'Agency','seeExpired','READ','ALLOW','ROLE','artificialBoss'),(639,'Agency','seeExpired','READ','ALLOW','ROLE','logisticAssistant'),(640,'Claim','filter','READ','ALLOW','ROLE','buyer'),(641,'Claim','find','READ','ALLOW','ROLE','buyer'),(642,'Claim','findById','READ','ALLOW','ROLE','buyer'),(643,'Claim','getSummary','READ','ALLOW','ROLE','buyer'),(644,'Claim','filter','READ','ALLOW','ROLE','handmadeBoss'),(645,'Claim','find','READ','ALLOW','ROLE','handmadeBoss'),(646,'Claim','findById','READ','ALLOW','ROLE','handmadeBoss'),(647,'Claim','getSummary','READ','ALLOW','ROLE','handmadeBoss'),(648,'Claim','__get__lines','READ','ALLOW','ROLE','claimManager'),(649,'Claim','__get__lines','READ','ALLOW','ROLE','salesPerson'),(650,'Claim','getSummary','READ','ALLOW','ROLE','deliveryBoss'),(651,'Claim','findById','READ','ALLOW','ROLE','deliveryBoss'),(652,'Claim','find','READ','ALLOW','ROLE','deliveryBoss'),(653,'Claim','filter','READ','ALLOW','ROLE','deliveryBoss'),(654,'Ticket','editZone','WRITE','ALLOW','ROLE','logisticAssistant'),(655,'Entry','addFromPackaging','WRITE','ALLOW','ROLE','production'),(656,'Entry','addFromBuy','WRITE','ALLOW','ROLE','production'),(657,'Supplier','getItemsPackaging','READ','ALLOW','ROLE','production'),(658,'Ticket','closeAll','WRITE','ALLOW','ROLE','system'),(659,'Account','*','*','ALLOW','ROLE','itManagement'),(660,'Account','*','READ','ALLOW','ROLE','employee'),(664,'MailForward','*','*','ALLOW','ROLE','itManagement'),(665,'Role','*','READ','ALLOW','ROLE','employee'),(666,'Role','*','WRITE','ALLOW','ROLE','it'),(667,'VnUser','*','*','ALLOW','ROLE','itManagement'),(668,'VnUser','__get__preview','READ','ALLOW','ROLE','employee'),(669,'VnUser','preview','*','ALLOW','ROLE','employee'),(670,'VnUser','create','*','ALLOW','ROLE','itManagement'),(671,'VnUser','renewToken','WRITE','ALLOW','ROLE','employee'),(672,'PackingSiteAdvanced','*','*','ALLOW','ROLE','production'),(673,'InvoiceOut','makePdfAndNotify','WRITE','ALLOW','ROLE','invoicing'),(674,'InvoiceOutConfig','*','READ','ALLOW','ROLE','invoicing'),(676,'Ticket','invoiceTickets','WRITE','ALLOW','ROLE','employee'),(680,'MailAliasAccount','*','READ','ALLOW','ROLE','employee'),(681,'MailAliasAccount','create','WRITE','ALLOW','ROLE','employee'),(682,'MailAliasAccount','deleteById','WRITE','ALLOW','ROLE','employee'),(683,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','itManagement'),(684,'WorkerDisableExcluded','*','READ','ALLOW','ROLE','itManagement'),(685,'WorkerDisableExcluded','*','WRITE','ALLOW','ROLE','itManagement'),(686,'MailForward','*','*','ALLOW','ROLE','hr'),(687,'ClientSms','find','READ','ALLOW','ROLE','employee'),(688,'ClientSms','create','WRITE','ALLOW','ROLE','employee'),(689,'Vehicle','sorted','WRITE','ALLOW','ROLE','employee'),(690,'Roadmap','*','*','ALLOW','ROLE','palletizerBoss'),(691,'Roadmap','*','*','ALLOW','ROLE','productionBoss'),(692,'ExpeditionTruck','*','*','ALLOW','ROLE','palletizerBoss'),(693,'ExpeditionTruck','*','*','ALLOW','ROLE','productionBoss'),(694,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','marketingBoss'),(695,'ViaexpressConfig','internationalExpedition','WRITE','ALLOW','ROLE','employee'),(696,'ViaexpressConfig','renderer','READ','ALLOW','ROLE','employee'),(697,'Ticket','transferClient','WRITE','ALLOW','ROLE','administrative'),(698,'Ticket','canEditWeekly','WRITE','ALLOW','ROLE','buyer'),(699,'TicketSms','find','READ','ALLOW','ROLE','salesPerson'),(701,'Docuware','upload','WRITE','ALLOW','ROLE','deliveryBoss'),(702,'Ticket','docuwareDownload','READ','ALLOW','ROLE','salesPerson'); /*!40000 ALTER TABLE `ACL` ENABLE KEYS */; UNLOCK TABLES; From aef34165d276edad2e12556d43ea2fad276f7c7c Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 18 Sep 2023 13:57:17 +0200 Subject: [PATCH 030/449] refs #4131 reverse claim changes --- front/core/directives/anchor.js | 4 ++-- modules/claim/front/summary/index.html | 2 +- modules/claim/front/summary/index.js | 2 +- modules/claim/front/summary/index.spec.js | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/front/core/directives/anchor.js b/front/core/directives/anchor.js index 81e252e04d..b460b3ada9 100644 --- a/front/core/directives/anchor.js +++ b/front/core/directives/anchor.js @@ -8,7 +8,7 @@ export function stringifyParams(data) { return params; } -export function state($state, event, data) { +export function changeState($state, event, data) { const params = stringifyParams(data); $state.go(data.state, params); @@ -53,7 +53,7 @@ export function directive($state, $window) { if (ctrlPressed || data.target == '_blank') openNewTab($state, $window, event, data); else - state($state, event, data); + changeState($state, event, data); }); $element.on('mousedown', event => { diff --git a/modules/claim/front/summary/index.html b/modules/claim/front/summary/index.html index 877a8c0f2b..3115cb4514 100644 --- a/modules/claim/front/summary/index.html +++ b/modules/claim/front/summary/index.html @@ -21,7 +21,7 @@ value-field="id" show-field="description" url="claimStates" - on-change="$ctrl.state(value)"> + on-change="$ctrl.changeState(value)"> diff --git a/modules/claim/front/summary/index.js b/modules/claim/front/summary/index.js index f1310c298c..7cd4805e9f 100644 --- a/modules/claim/front/summary/index.js +++ b/modules/claim/front/summary/index.js @@ -71,7 +71,7 @@ class Controller extends Summary { return this.vnFile.getPath(`/api/dms/${dmsId}/downloadFile`); } - state(value) { + changeState(value) { const params = { id: this.claim.id, claimStateFk: value diff --git a/modules/claim/front/summary/index.spec.js b/modules/claim/front/summary/index.spec.js index 04a270c5f9..8540a3a974 100644 --- a/modules/claim/front/summary/index.spec.js +++ b/modules/claim/front/summary/index.spec.js @@ -28,14 +28,14 @@ describe('Claim', () => { }); }); - describe('state()', () => { + describe('changeState()', () => { it('should make an HTTP post query, then call the showSuccess()', () => { jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); const expectedParams = {id: 1, claimStateFk: 1}; $httpBackend.when('GET', `Claims/1/getSummary`).respond(200, 24); $httpBackend.expect('PATCH', `Claims/updateClaim/1`, expectedParams).respond(200); - controller.state(1); + controller.changeState(1); $httpBackend.flush(); expect(controller.vnApp.showSuccess).toHaveBeenCalled(); From 90b3107537db966d037d727b6593e838e2dcb340 Mon Sep 17 00:00:00 2001 From: pablone Date: Tue, 19 Sep 2023 07:07:52 +0200 Subject: [PATCH 031/449] refs #4131 grant and revoke --- db/changes/233801/00-ACLticketTrackingState.sql | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/db/changes/233801/00-ACLticketTrackingState.sql b/db/changes/233801/00-ACLticketTrackingState.sql index a0e3824db3..ddd838e7ea 100644 --- a/db/changes/233801/00-ACLticketTrackingState.sql +++ b/db/changes/233801/00-ACLticketTrackingState.sql @@ -1,3 +1,11 @@ UPDATE `salix`.`ACL` SET property = 'state' - WHERE property = 'changeState'; \ No newline at end of file + WHERE property = 'changeState'; + +REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'productionboss'@; +REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'productionAssi'@; +REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'hr'@; +REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'salesPerson'@; +REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'deliveryPerson'@; +REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'employee'@; +REVOKE EXECUTE ON `vn`.`ticket_setState` FROM 'employee'@; From 4870b0830b720ba609afe4880d2b8f3813759aa6 Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 20 Sep 2023 11:06:30 +0200 Subject: [PATCH 032/449] ref #5914 fix refund and change method name --- .../00-transferInvoiceACL.sql} | 2 +- loopback/locale/es.json | 304 +----------------- .../methods/invoiceOut/transferInvoice.js | 2 +- modules/invoiceOut/back/models/invoice-out.js | 2 +- modules/ticket/back/methods/sale/refund.js | 83 +---- 5 files changed, 13 insertions(+), 380 deletions(-) rename db/changes/{233201/00-transferInvoiceOutACL.sql => 233601/00-transferInvoiceACL.sql} (80%) diff --git a/db/changes/233201/00-transferInvoiceOutACL.sql b/db/changes/233601/00-transferInvoiceACL.sql similarity index 80% rename from db/changes/233201/00-transferInvoiceOutACL.sql rename to db/changes/233601/00-transferInvoiceACL.sql index 6e8d88c5d9..a45e3f4791 100644 --- a/db/changes/233201/00-transferInvoiceOutACL.sql +++ b/db/changes/233601/00-transferInvoiceACL.sql @@ -3,4 +3,4 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp ('CplusRectificationType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), ('CplusInvoiceType477', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), ('InvoiceCorrectionType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('InvoiceOut', 'transferInvoiceOut', 'WRITE', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file + ('InvoiceOut', 'transferInvoice', 'WRITE', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index b2c6ae3e96..d436ec1971 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -8,7 +8,6 @@ "Invalid email": "Invalid email", "Phone cannot be blank": "Phone cannot be blank", "The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero", -<<<<<<< HEAD "The grade must be an integer greater than or equal to zero": "The grade must be an integer greater than or equal to zero", "Description should have maximum of 45 characters": "Description should have maximum of 45 characters", "Amount cannot be zero": "Amount cannot be zero", @@ -22,304 +21,5 @@ "State cannot be blank": "State cannot be blank", "Worker cannot be blank": "Worker cannot be blank", "Description cannot be blank": "Description cannot be blank", - "Agency cannot be blank": "Agency cannot be blank", - "The renew period has not been exceeded": "The renew period has not been exceeded" -} -======= - "The grade must be similar to the last one": "El grade debe ser similar al último", - "Only manager can change the credit": "Solo el gerente puede cambiar el credito de este cliente", - "Name cannot be blank": "El nombre no puede estar en blanco", - "Phone cannot be blank": "El teléfono no puede estar en blanco", - "Period cannot be blank": "El periodo no puede estar en blanco", - "Choose a company": "Selecciona una empresa", - "Se debe rellenar el campo de texto": "Se debe rellenar el campo de texto", - "Description should have maximum of 45 characters": "La descripción debe tener maximo 45 caracteres", - "Cannot be blank": "El campo no puede estar en blanco", - "The grade must be an integer greater than or equal to zero": "El grade debe ser un entero mayor o igual a cero", - "Sample type cannot be blank": "El tipo de plantilla no puede quedar en blanco", - "Description cannot be blank": "Se debe rellenar el campo de texto", - "The new quantity should be smaller than the old one": "La nueva cantidad debe de ser menor que la anterior", - "The value should not be greater than 100%": "El valor no debe de ser mayor de 100%", - "The value should be a number": "El valor debe ser un numero", - "This order is not editable": "Esta orden no se puede modificar", - "You can't create an order for a frozen client": "No puedes crear una orden para un cliente congelado", - "You can't create an order for a client that has a debt": "No puedes crear una orden para un cliente con deuda", - "is not a valid date": "No es una fecha valida", - "Barcode must be unique": "El código de barras debe ser único", - "The warehouse can't be repeated": "El almacén no puede repetirse", - "The tag or priority can't be repeated for an item": "El tag o prioridad no puede repetirse para un item", - "The observation type can't be repeated": "El tipo de observación no puede repetirse", - "A claim with that sale already exists": "Ya existe una reclamación para esta línea", - "You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo", - "Warehouse cannot be blank": "El almacén no puede quedar en blanco", - "Agency cannot be blank": "La agencia no puede quedar en blanco", - "Not enough privileges to edit a client with verified data": "No tienes permisos para hacer cambios en un cliente con datos comprobados", - "This address doesn't exist": "Este consignatario no existe", - "You must delete the claim id %d first": "Antes debes borrar la reclamación %d", - "You don't have enough privileges": "No tienes suficientes permisos", - "Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF", - "You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos basicos de una orden con artículos", - "INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no esta permitido el uso de la letra ñ", - "You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado", - "You can't create a ticket for a inactive client": "No puedes crear un ticket para un cliente inactivo", - "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", - "ORDER_EMPTY": "Cesta vacía", - "You don't have enough privileges to do that": "No tienes permisos para cambiar esto", - "NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT", - "Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido", - "Street cannot be empty": "Dirección no puede estar en blanco", - "City cannot be empty": "Cuidad no puede estar en blanco", - "Code cannot be blank": "Código no puede estar en blanco", - "You cannot remove this department": "No puedes eliminar este departamento", - "The extension must be unique": "La extensión debe ser unica", - "The secret can't be blank": "La contraseña no puede estar en blanco", - "We weren't able to send this SMS": "No hemos podido enviar el SMS", - "This client can't be invoiced": "Este cliente no puede ser facturado", - "This ticket can't be invoiced": "Este ticket no puede ser facturado", - "You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado", - "This ticket can not be modified": "Este ticket no puede ser modificado", - "The introduced hour already exists": "Esta hora ya ha sido introducida", - "INFINITE_LOOP": "Existe una dependencia entre dos Jefes", - "The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas", - "NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros", - "ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado", - "The current ticket can't be modified": "El ticket actual no puede ser modificado", - "The current claim can't be modified": "La reclamación actual no puede ser modificada", - "The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", - "The sales do not exists": "La(s) línea(s) seleccionada(s) no existe(n)", - "Please select at least one sale": "Por favor selecciona al menos una linea", - "All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket", - "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", - "This item doesn't exists": "El artículo no existe", - "NOT_ZONE_WITH_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", - "Extension format is invalid": "El formato de la extensión es inválido", - "Invalid parameters to create a new ticket": "Parámetros inválidos para crear un nuevo ticket", - "This item is not available": "Este artículo no está disponible", - "This postcode already exists": "Este código postal ya existe", - "Concept cannot be blank": "El concepto no puede quedar en blanco", - "File doesn't exists": "El archivo no existe", - "You don't have privileges to change the zone": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias", - "This ticket is already on weekly tickets": "Este ticket ya está en tickets programados", - "Ticket id cannot be blank": "El id de ticket no puede quedar en blanco", - "Weekday cannot be blank": "El día de la semana no puede quedar en blanco", - "You can't delete a confirmed order": "No puedes borrar un pedido confirmado", - "The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto", - "Invalid quantity": "Cantidad invalida", - "This postal code is not valid": "This postal code is not valid", - "is invalid": "is invalid", - "The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto", - "The department name can't be repeated": "El nombre del departamento no puede repetirse", - "This phone already exists": "Este teléfono ya existe", - "You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos", - "You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado", - "You cannot delete a ticket that part of it is being prepared": "No puedes eliminar un ticket en el que una parte que está siendo preparada", - "You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero", - "You should specify a date": "Debes especificar una fecha", - "You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín", - "Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín", - "You should mark at least one week day": "Debes marcar al menos un día de la semana", - "Swift / BIC can't be empty": "Swift / BIC no puede estar vacío", - "Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios", - "Incoterms is required for a non UEE member": "El incoterms es requerido para los clientes extracomunitarios", - "Deleted sales from ticket": "He eliminado las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{deletions}}}", - "Added sale to ticket": "He añadido la siguiente linea al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}", - "Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})", - "Changed sale quantity": "He cambiado la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* del ticket [{{ticketId}}]({{{ticketUrl}}})", - "State": "Estado", - "regular": "normal", - "reserved": "reservado", - "Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})", - "Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}", - "MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*", - "Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})", - "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})", - "Change quantity": "{{concept}} cambia de {{oldQuantity}} a {{newQuantity}}", - "Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*", - "Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*", - "Claim state has changed to canceled": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *anulado*", - "Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}", - "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", - "Distance must be lesser than 1000": "La distancia debe ser inferior a 1000", - "This ticket is deleted": "Este ticket está eliminado", - "Unable to clone this travel": "No ha sido posible clonar este travel", - "This thermograph id already exists": "La id del termógrafo ya existe", - "Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante", - "ORDER_ALREADY_CONFIRMED": "ORDER_ALREADY_CONFIRMED", - "Invalid password": "Invalid password", - "Password does not meet requirements": "La contraseña no cumple los requisitos", - "Role already assigned": "Role already assigned", - "Invalid role name": "Invalid role name", - "Role name must be written in camelCase": "Role name must be written in camelCase", - "Email already exists": "Email already exists", - "User already exists": "User already exists", - "Absence change notification on the labour calendar": "Notificacion de cambio de ausencia en el calendario laboral", - "Record of hours week": "Registro de horas semana {{week}} año {{year}} ", - "Created absence": "El empleado {{author}} ha añadido una ausencia de tipo '{{absenceType}}' a {{employee}} para el día {{dated}}.", - "Deleted absence": "El empleado {{author}} ha eliminado una ausencia de tipo '{{absenceType}}' a {{employee}} del día {{dated}}.", - "I have deleted the ticket id": "He eliminado el ticket id [{{id}}]({{{url}}})", - "I have restored the ticket id": "He restaurado el ticket id [{{id}}]({{{url}}})", - "You can only restore a ticket within the first hour after deletion": "Únicamente puedes restaurar el ticket dentro de la primera hora después de su eliminación", - "Changed this data from the ticket": "He cambiado estos datos del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "agencyModeFk": "Agencia", - "clientFk": "Cliente", - "zoneFk": "Zona", - "warehouseFk": "Almacén", - "shipped": "F. envío", - "landed": "F. entrega", - "addressFk": "Consignatario", - "companyFk": "Empresa", - "The social name cannot be empty": "La razón social no puede quedar en blanco", - "The nif cannot be empty": "El NIF no puede quedar en blanco", - "You need to fill sage information before you check verified data": "Debes rellenar la información de sage antes de marcar datos comprobados", - "ASSIGN_ZONE_FIRST": "Asigna una zona primero", - "Amount cannot be zero": "El importe no puede ser cero", - "Company has to be official": "Empresa inválida", - "You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria", - "Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas", - "The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta", - "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*", - "New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*", - "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", - "This BIC already exist.": "Este BIC ya existe.", - "That item doesn't exists": "Ese artículo no existe", - "There's a new urgent ticket:": "Hay un nuevo ticket urgente:", - "Invalid account": "Cuenta inválida", - "Compensation account is empty": "La cuenta para compensar está vacia", - "This genus already exist": "Este genus ya existe", - "This specie already exist": "Esta especie ya existe", - "Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})", - "None": "Ninguno", - "The contract was not active during the selected date": "El contrato no estaba activo durante la fecha seleccionada", - "Cannot add more than one '1/2 day vacation'": "No puedes añadir más de un 'Vacaciones 1/2 dia'", - "This document already exists on this ticket": "Este documento ya existe en el ticket", - "Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables", - "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", - "nickname": "nickname", - "INACTIVE_PROVIDER": "Proveedor inactivo", - "This client is not invoiceable": "Este cliente no es facturable", - "serial non editable": "Esta serie no permite asignar la referencia", - "Max shipped required": "La fecha límite es requerida", - "Can't invoice to future": "No se puede facturar a futuro", - "Can't invoice to past": "No se puede facturar a pasado", - "This ticket is already invoiced": "Este ticket ya está facturado", - "A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero", - "A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa", - "Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes", - "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes", - "Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio", - "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito", - "You can't change the credit set to zero from a financialBoss": "No puedes cambiar el cŕedito establecido a cero por un jefe de finanzas", - "Amounts do not match": "Las cantidades no coinciden", - "The PDF document does not exist": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'", - "The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos", - "You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días", - "The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día", - "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", - "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", - "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", - "You don't have privileges to create refund": "No tienes permisos para crear un abono", - "The item is required": "El artículo es requerido", - "The agency is already assigned to another autonomous": "La agencia ya está asignada a otro autónomo", - "date in the future": "Fecha en el futuro", - "reference duplicated": "Referencia duplicada", - "This ticket is already a refund": "Este ticket ya es un abono", - "isWithoutNegatives": "isWithoutNegatives", - "routeFk": "routeFk", - "Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador", - "No hay un contrato en vigor": "No hay un contrato en vigor", - "No se permite fichar a futuro": "No se permite fichar a futuro", - "No está permitido trabajar": "No está permitido trabajar", - "Fichadas impares": "Fichadas impares", - "Descanso diario 12h.": "Descanso diario 12h.", - "Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.", - "Dirección incorrecta": "Dirección incorrecta", - "Modifiable user details only by an administrator": "Detalles de usuario modificables solo por un administrador", - "Modifiable password only via recovery or by an administrator": "Contraseña modificable solo a través de la recuperación o por un administrador", - "Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente", - "This route does not exists": "Esta ruta no existe", - "Claim pickup order sent": "Reclamación Orden de recogida enviada [{{claimId}}]({{{claimUrl}}}) al cliente *{{clientName}}*", - "You don't have grant privilege": "No tienes privilegios para dar privilegios", - "You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario", - "Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) fusionado con [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})", - "Already has this status": "Ya tiene este estado", - "There aren't records for this week": "No existen registros para esta semana", - "Empty data source": "Origen de datos vacio", - "App locked": "Aplicación bloqueada por el usuario {{userId}}", - "Email verify": "Correo de verificación", - "Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment", - "Receipt's bank was not found": "No se encontró el banco del recibo", - "This receipt was not compensated": "Este recibo no ha sido compensado", - "Client's email was not found": "No se encontró el email del cliente", - "Negative basis": "Base negativa", - "This worker code already exists": "Este codigo de trabajador ya existe", - "This personal mail already exists": "Este correo personal ya existe", - "This worker already exists": "Este trabajador ya existe", - "App name does not exist": "El nombre de aplicación no es válido", - "Try again": "Vuelve a intentarlo", - "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9", - "Failed to upload delivery note": "Error al subir albarán {{id}}", - "The DOCUWARE PDF document does not exists": "El documento PDF Docuware no existe", - "It is not possible to modify tracked sales": "No es posible modificar líneas de pedido que se hayan empezado a preparar", - "It is not possible to modify sales that their articles are from Floramondo": "No es posible modificar líneas de pedido cuyos artículos sean de Floramondo", - "It is not possible to modify cloned sales": "No es posible modificar líneas de pedido clonadas", - "A supplier with the same name already exists. Change the country.": "Un proveedor con el mismo nombre ya existe. Cambie el país.", - "There is no assigned email for this client": "No hay correo asignado para este cliente", - "Exists an invoice with a future date": "Existe una factura con fecha posterior", - "Invoice date can't be less than max date": "La fecha de factura no puede ser inferior a la fecha límite", - "Warehouse inventory not set": "El almacén inventario no está establecido", - "This locker has already been assigned": "Esta taquilla ya ha sido asignada", - "Tickets with associated refunds": "No se pueden borrar tickets con abonos asociados. Este ticket está asociado al abono Nº %d", - "Not exist this branch": "La rama no existe", - "This ticket cannot be signed because it has not been boxed": "Este ticket no puede firmarse porque no ha sido encajado", - "Collection does not exist": "La colección no existe", - "Cannot obtain exclusive lock": "No se puede obtener un bloqueo exclusivo", - "Insert a date range": "Inserte un rango de fechas", - "Added observation": "{{user}} añadió esta observacion: {{text}}", - "Comment added to client": "Observación añadida al cliente {{clientFk}}", - "Invalid auth code": "Código de verificación incorrecto", - "Invalid or expired verification code": "Código de verificación incorrecto o expirado", - "Cannot create a new claimBeginning from a different ticket": "No se puede crear una línea de reclamación de un ticket diferente al origen", - "company": "Compañía", - "country": "País", - "clientId": "Id cliente", - "clientSocialName": "Cliente", - "amount": "Importe", - "taxableBase": "Base", - "ticketFk": "Id ticket", - "isActive": "Activo", - "hasToInvoice": "Facturar", - "isTaxDataChecked": "Datos comprobados", - "comercialId": "Id comercial", - "comercialName": "Comercial", - "Pass expired": "La contraseña ha caducado, cambiela desde Salix", - "Invalid NIF for VIES": "Invalid NIF for VIES", - "Ticket does not exist": "Este ticket no existe", - "Ticket is already signed": "Este ticket ya ha sido firmado", - "Authentication failed": "Autenticación fallida", - "You can't use the same password": "No puedes usar la misma contraseña", - "You can only add negative amounts in refund tickets": "Solo se puede añadir cantidades negativas en tickets abono", - "Fecha fuera de rango": "Fecha fuera de rango", - "Error while generating PDF": "Error al generar PDF", - "Error when sending mail to client": "Error al enviar el correo al cliente", - "Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico", - "The renew period has not been exceeded": "El periodo de renovación no ha sido superado", - "Valid priorities": "Prioridades válidas: %d", - "Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}", - "You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado", - "This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s", - "The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias", - "You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado", - "This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado", - "You don't have enough privileges.": "No tienes suficientes permisos.", - "This ticket is locked.": "Este ticket está bloqueado.", - "This ticket is not editable.": "Este ticket no es editable.", - "The ticket doesn't exist.": "No existe el ticket.", - "Social name should be uppercase": "La razón social debe ir en mayúscula", - "Street should be uppercase": "La dirección fiscal debe ir en mayúscula", - "The response is not a PDF": "La respuesta no es un PDF", - "Ticket without Route": "Ticket sin ruta" -} ->>>>>>> 72a8256aee7bff0be1dd68c8d4cfbe2edcf8ce60 + "Agency cannot be blank": "Agency cannot be blank" +} \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js index c590ff9eab..0b123dd3da 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js @@ -44,7 +44,7 @@ module.exports = Self => { } }); - Self.transferInvoiceOut = async(ctx, id, ref, newClientFk, cplusRectificationId, cplusInvoiceType477Id, invoiceCorrectionTypeId, options) => { + Self.transferInvoice = async(ctx, id, ref, newClientFk, cplusRectificationId, cplusInvoiceType477Id, invoiceCorrectionTypeId, options) => { const models = Self.app.models; const myOptions = {userId: ctx.req.accessToken.userId}; diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js index 0bb31ce12b..ca77c856f6 100644 --- a/modules/invoiceOut/back/models/invoice-out.js +++ b/modules/invoiceOut/back/models/invoice-out.js @@ -23,7 +23,7 @@ module.exports = Self => { require('../methods/invoiceOut/getInvoiceDate')(Self); require('../methods/invoiceOut/negativeBases')(Self); require('../methods/invoiceOut/negativeBasesCsv')(Self); - require('../methods/invoiceOut/transferInvoiceOut')(Self); + require('../methods/invoiceOut/transferInvoice')(Self); Self.filePath = async function(id, options) { const fields = ['ref', 'issued']; diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 303d830b64..3f7e1cd217 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -5,7 +5,8 @@ module.exports = Self => { accepts: [ { arg: 'salesIds', - type: ['number'] + type: ['number'], + required: true }, { arg: 'servicesIds', @@ -40,7 +41,6 @@ module.exports = Self => { myOptions.transaction = tx; } - let refundTicket = null; try { const refundAgencyMode = await models.AgencyMode.findOne({ include: { @@ -55,42 +55,14 @@ module.exports = Self => { const refoundZoneId = refundAgencyMode.zones()[0].id; - if (salesIds) { - const salesFilter = { - where: {id: {inq: salesIds}}, - include: { - relation: 'components', - scope: { - fields: ['saleFk', 'componentFk', 'value'] - } + const salesFilter = { + where: {id: {inq: salesIds}}, + include: { + relation: 'components', + scope: { + fields: ['saleFk', 'componentFk', 'value'] } - }; - const sales = await models.Sale.find(salesFilter, myOptions); - const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; - - const now = Date.vnNew(); - const [firstTicketId] = ticketsIds; - - // eslint-disable-next-line max-len - refundTicket = await createTicketRefund(firstTicketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions); - - for (const sale of sales) { - const createdSale = await models.Sale.create({ - ticketFk: refundTicket.id, - itemFk: sale.itemFk, - quantity: - sale.quantity, - concept: sale.concept, - price: sale.price, - discount: sale.discount, - }, myOptions); - - const components = sale.components(); - for (const component of components) - component.saleFk = createdSale.id; - - await models.SaleComponent.create(components, myOptions); } -<<<<<<< HEAD }; // const sales = await models.Sale.find(salesFilter, myOptions); const refundTicket = await models.Sale.clone( @@ -105,45 +77,6 @@ module.exports = Self => { ); if (tx && !options) await tx.commit(); -======= - } - - if (!refundTicket) { - const servicesFilter = { - where: {id: {inq: servicesIds}} - }; - const services = await models.TicketService.find(servicesFilter, myOptions); - const ticketsIds = [...new Set(services.map(service => service.ticketFk))]; - - const now = Date.vnNew(); - const [firstTicketId] = ticketsIds; - - // eslint-disable-next-line max-len - refundTicket = await createTicketRefund(firstTicketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions); - } - - if (servicesIds && servicesIds.length > 0) { - const servicesFilter = { - where: {id: {inq: servicesIds}} - }; - const services = await models.TicketService.find(servicesFilter, myOptions); - for (const service of services) { - await models.TicketService.create({ - description: service.description, - quantity: service.quantity, - price: - service.price, - taxClassFk: service.taxClassFk, - ticketFk: refundTicket.id, - ticketServiceTypeFk: service.ticketServiceTypeFk, - }, myOptions); - } - } - - const query = `CALL vn.ticket_recalc(?, NULL)`; - await Self.rawSql(query, [refundTicket.id], myOptions); - - if (tx) await tx.commit(); ->>>>>>> 72a8256aee7bff0be1dd68c8d4cfbe2edcf8ce60 return refundTicket; } catch (e) { From 3b90d7e5e5927c063cd806fcbb29ea706d61fe5a Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 20 Sep 2023 15:10:28 +0200 Subject: [PATCH 033/449] refs #6067 refactor: vnUser and mailForward privileges. fix: emailVerification --- back/models/vn-user.js | 92 ++++++++++++------- back/models/vn-user.json | 12 ++- db/changes/234001/00-account_acl.sql | 12 +++ modules/account/back/models/mail-forward.js | 14 +++ modules/account/back/models/mail-forward.json | 16 +++- modules/account/front/routes.json | 3 +- 6 files changed, 107 insertions(+), 42 deletions(-) create mode 100644 db/changes/234001/00-account_acl.sql create mode 100644 modules/account/back/models/mail-forward.js diff --git a/back/models/vn-user.js b/back/models/vn-user.js index cf210b61b8..642d3fdf31 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -1,6 +1,7 @@ const vnModel = require('vn-loopback/common/models/vn-model'); const LoopBackContext = require('loopback-context'); const {Email} = require('vn-print'); +const UserError = require('vn-loopback/util/user-error'); module.exports = function(Self) { vnModel(Self); @@ -178,45 +179,68 @@ module.exports = function(Self) { Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls .filter(acl => acl.property != 'changePassword'); + Self.observe('before save', async ctx => { + const instance = ctx.currentInstance || ctx.instance; + console.log(ctx); + await Self.userSecurity(ctx, instance.id); + }); + + Self.userSecurity = async(ctx, userId) => { + const models = Self.app.models; + const accessToken = ctx.options.accessToken || LoopBackContext.getCurrentContext().active.accessToken; + console.log(accessToken, LoopBackContext.getCurrentContext().active.http.req); + const ctxToken = {req: {accessToken}}; + + const hasHigherPrivileges = await models.ACL.checkAccessAcl(ctxToken, 'VnUser', 'higherPrivileges'); + if (hasHigherPrivileges) return; + + const hasMediumPrivileges = await models.ACL.checkAccessAcl(ctxToken, 'VnUser', 'mediumPrivileges'); + const user = await models.VnUser.findById(userId, {fields: ['id', 'emailVerified']}); + if (!user.emailVerified && hasMediumPrivileges) return; + + if (userId != accessToken.userId) + throw new UserError(`You don't have enough privileges`); + }; + // FIXME: https://redmine.verdnatura.es/issues/5761 - // Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => { - // if (!ctx.args || !ctx.args.data.email) return; + Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => { + if (!ctx.args || !ctx.args.data.email) 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 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(':'); - // class Mailer { - // async send(verifyOptions, cb) { - // const params = { - // url: verifyOptions.verifyHref, - // recipient: verifyOptions.to, - // lang: ctx.req.getLocale() - // }; + 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(); + const email = new Email('email-verify', params); + email.send(); - // cb(null, verifyOptions.to); - // } - // } + cb(null, verifyOptions.to); + } + } - // 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 - // }; + 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 instance.verify(options); - // }); + await instance.verify(options); + }); }; diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 9131c9134a..23df2241f1 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -13,10 +13,6 @@ "type": "number", "id": true }, - "name": { - "type": "string", - "required": true - }, "username": { "type": "string", "mysql": { @@ -127,7 +123,13 @@ "principalType": "ROLE", "principalId": "$authenticated", "permission": "ALLOW" - } + }, + { + "principalType": "ROLE", + "principalId": "$authenticated", + "permission": "ALLOW", + "property": "patchAttributes" + } ], "scopes": { "preview": { diff --git a/db/changes/234001/00-account_acl.sql b/db/changes/234001/00-account_acl.sql new file mode 100644 index 0000000000..23f47b99f5 --- /dev/null +++ b/db/changes/234001/00-account_acl.sql @@ -0,0 +1,12 @@ +DELETE FROM `salix`.`ACL` + WHERE + model = 'MailForward' + AND accessType = '*' + AND property = '*' + AND principalId = 'hr'; + + +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('VnUser', 'higherPrivileges', '*', 'ALLOW', 'ROLE', 'itManagement'), + ('VnUser', 'mediumPrivileges', '*', 'ALLOW', 'ROLE', 'hr'); diff --git a/modules/account/back/models/mail-forward.js b/modules/account/back/models/mail-forward.js new file mode 100644 index 0000000000..d55f5ddbc4 --- /dev/null +++ b/modules/account/back/models/mail-forward.js @@ -0,0 +1,14 @@ + +module.exports = Self => { + Self.observe('loaded', async ctx => { + if (!ctx.data.account) return; + await Self.app.models.VnUser.userSecurity(ctx, ctx.data.account); + }); + Self.observe('before save', async ctx => { + const instance = ctx.currentInstance || ctx.instance; + await Self.app.models.VnUser.userSecurity(ctx, instance.account); + }); + Self.observe('before delete', async ctx => { + await Self.app.models.VnUser.userSecurity(ctx, ctx.where.account); + }); +}; diff --git a/modules/account/back/models/mail-forward.json b/modules/account/back/models/mail-forward.json index edef1bf08d..af4de32181 100644 --- a/modules/account/back/models/mail-forward.json +++ b/modules/account/back/models/mail-forward.json @@ -21,5 +21,19 @@ "model": "VnUser", "foreignKey": "account" } - } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$authenticated", + "permission": "ALLOW" + }, + { + "accessType": "WRITE", + "principalType": "ROLE", + "principalId": "$authenticated", + "permission": "ALLOW" + } + ] } diff --git a/modules/account/front/routes.json b/modules/account/front/routes.json index fd33e7122b..8472c35746 100644 --- a/modules/account/front/routes.json +++ b/modules/account/front/routes.json @@ -77,8 +77,7 @@ "url": "/basic-data?emailConfirmed", "state": "account.card.basicData", "component": "vn-user-basic-data", - "description": "Basic data", - "acl": ["itManagement"] + "description": "Basic data" }, { "url" : "/log", From ac4aea7d38f6d0492561606818af213c3ef1698f Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 21 Sep 2023 09:14:46 +0200 Subject: [PATCH 034/449] ref #5914 created transfer issued invoice --- db/dump/fixtures.sql | 17 +- loopback/locale/en.json | 10 +- loopback/locale/es.json | 341 ++++++++++++++++-- .../methods/invoiceOut/transferInvoice.js | 39 +- modules/ticket/back/methods/sale/clone.js | 1 - modules/ticket/back/methods/sale/refund.js | 55 +-- .../back/methods/sale/specs/refund.spec.js | 2 +- 7 files changed, 351 insertions(+), 114 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 691f7e6df4..bb46880bd1 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -604,7 +604,7 @@ INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaF INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`) VALUES - (1, 'T', 1014.24, util.VN_CURDATE(), 1101, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0), + (1, 'T', 1026.24, util.VN_CURDATE(), 1101, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0), (2, 'T', 121.36, util.VN_CURDATE(), 1102, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0), (3, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0), (4, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0), @@ -2966,20 +2966,6 @@ INSERT INTO `hedera`.`imageConfig` (`id`, `maxSize`, `useXsendfile`, `url`) VALUES (1, 0, 0, 'marvel.com'); -<<<<<<< HEAD -INSERT INTO `vn`.`cplusCorrectingType` (`description`) - VALUES - ('Embalajes'), - ('Anulación'), - ('Impagado'), - ('Moroso'); - -INSERT INTO `vn`.`invoiceCorrectionType` (`description`) - VALUES - ('Error en el cálculo del IVA'), - ('Error en el detalle de las ventas'), - ('Error en los datos del cliente'); -======= INSERT INTO vn.XDiario (id, ASIEN, FECHA, SUBCTA, CONTRA, CONCEPTO, EURODEBE, EUROHABER, BASEEURO, SERIE, FACTURA, IVA, RECEQUIV, CLAVE, CAMBIO, DEBEME, HABERME, AUXILIAR, MONEDAUSO, TIPOOPE, NFACTICK, TERIDNIF, TERNIF, TERNOM, OPBIENES, L340, enlazado, FECHA_EX, LRECT349, empresa_id, LDIFADUAN, METAL, METALIMP, CLIENTE, METALEJE, FECHA_OP, FACTURAEX, TIPOCLAVE, TIPOEXENCI, TIPONOSUJE, TIPOFACT, TIPORECTIF, SERIE_RT, FACTU_RT, BASEIMP_RT, BASEIMP_RF, RECTIFICA, FECHA_RT, FECREGCON, enlazadoSage) VALUES (1, 1.0, util.VN_CURDATE(), '4300001104', NULL, 'n/fra T3333333', 8.88, NULL, NULL, NULL, '0', NULL, 0.00, NULL, NULL, NULL, NULL, NULL, '2', NULL, 1, 2, 'I.F.', 'Nombre Importador', 1, 0, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 1), @@ -2988,4 +2974,3 @@ INSERT INTO vn.XDiario (id, ASIEN, FECHA, SUBCTA, CONTRA, CONCEPTO, EURODEBE, EU (4, 2.0, util.VN_CURDATE(), '4300001104', NULL, 'n/fra T4444444', 8.88, NULL, NULL, NULL, '0', NULL, 0.00, NULL, NULL, NULL, NULL, NULL, '2', NULL, 1, 2, 'I.F.', 'Nombre Importador', 1, 0, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0), (5, 2.0, util.VN_CURDATE(), '2000000000', '4300001104', 'n/fra T4444444 Tony Stark', NULL, 8.07, NULL, NULL, '0', NULL, 0.00, NULL, NULL, NULL, NULL, NULL, '2', NULL, 1, 2, 'I.F.', 'Nombre Importador', 1, 0, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0), (6, 2.0, util.VN_CURDATE(), '4770000010', '4300001104', 'Inmovilizado pendiente : n/fra T4444444 Tony Stark', NULL, 0.81, 8.07, 'T', '4444444', 10.00, NULL, NULL, NULL, NULL, NULL, '', '2', '', 1, 1, '06089160W', 'IRON MAN', 1, 1, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, 1, 1, 1, 1, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0); ->>>>>>> 72a8256aee7bff0be1dd68c8d4cfbe2edcf8ce60 diff --git a/loopback/locale/en.json b/loopback/locale/en.json index fb4e72bd64..3755c4a67e 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -187,5 +187,11 @@ "This ticket is not editable.": "This ticket is not editable.", "The ticket doesn't exist.": "The ticket doesn't exist.", "The sales do not exists": "The sales do not exists", - "Ticket without Route": "Ticket without route" -} + "Ticket without Route": "Ticket without route", + "Select a different customer": "Select a different customer", + "Fill all the fields": "Fill all the fields", + "Error while generating PDF": "Error while generating PDF", + "Can't invoice to future": "Can't invoice to future", + "This ticket is already invoiced": "This ticket is already invoiced", + "Negative basis of tickets: 23": "Negative basis of tickets: 23" +} \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index d436ec1971..f5973dcb70 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -1,25 +1,322 @@ { - "Name cannot be blank": "Name cannot be blank", - "Swift / BIC cannot be empty": "Swift / BIC cannot be empty", - "Social name should be uppercase": "Social name should be uppercase", - "Street cannot be empty": "Street cannot be empty", - "Street should be uppercase": "Street should be uppercase", - "City cannot be empty": "City cannot be empty", - "Invalid email": "Invalid email", - "Phone cannot be blank": "Phone cannot be blank", + "Phone format is invalid": "El formato del teléfono no es correcto", + "You are not allowed to change the credit": "No tienes privilegios para modificar el crédito", + "Unable to mark the equivalence surcharge": "No se puede marcar el recargo de equivalencia", + "The default consignee can not be unchecked": "No se puede desmarcar el consignatario predeterminado", + "Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado", + "Can't be blank": "No puede estar en blanco", + "Invalid TIN": "NIF/CIF invalido", + "TIN must be unique": "El NIF/CIF debe ser único", + "A client with that Web User name already exists": "Ya existe un cliente con ese Usuario Web", + "Is invalid": "Is invalid", + "Quantity cannot be zero": "La cantidad no puede ser cero", + "Enter an integer different to zero": "Introduce un entero distinto de cero", + "Package cannot be blank": "El embalaje no puede estar en blanco", + "The company name must be unique": "La razón social debe ser única", + "Invalid email": "Correo electrónico inválido", + "The IBAN does not have the correct format": "El IBAN no tiene el formato correcto", + "That payment method requires an IBAN": "El método de pago seleccionado requiere un IBAN", + "That payment method requires a BIC": "El método de pago seleccionado requiere un BIC", + "State cannot be blank": "El estado no puede estar en blanco", + "Worker cannot be blank": "El trabajador no puede estar en blanco", + "Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado", + "can't be blank": "El campo no puede estar vacío", + "Observation type must be unique": "El tipo de observación no puede repetirse", "The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero", - "The grade must be an integer greater than or equal to zero": "The grade must be an integer greater than or equal to zero", - "Description should have maximum of 45 characters": "Description should have maximum of 45 characters", - "Amount cannot be zero": "Amount cannot be zero", - "Period cannot be blank": "Period cannot be blank", - "Sample type cannot be blank": "Sample type cannot be blank", - "Cannot be blank": "Cannot be blank", - "The social name cannot be empty": "The social name cannot be empty", - "Concept cannot be blank": "Concept cannot be blank", - "Enter an integer different to zero": "Enter an integer different to zero", - "Package cannot be blank": "Package cannot be blank", - "State cannot be blank": "State cannot be blank", - "Worker cannot be blank": "Worker cannot be blank", - "Description cannot be blank": "Description cannot be blank", - "Agency cannot be blank": "Agency cannot be blank" + "The grade must be similar to the last one": "El grade debe ser similar al último", + "Only manager can change the credit": "Solo el gerente puede cambiar el credito de este cliente", + "Name cannot be blank": "El nombre no puede estar en blanco", + "Phone cannot be blank": "El teléfono no puede estar en blanco", + "Period cannot be blank": "El periodo no puede estar en blanco", + "Choose a company": "Selecciona una empresa", + "Se debe rellenar el campo de texto": "Se debe rellenar el campo de texto", + "Description should have maximum of 45 characters": "La descripción debe tener maximo 45 caracteres", + "Cannot be blank": "El campo no puede estar en blanco", + "The grade must be an integer greater than or equal to zero": "El grade debe ser un entero mayor o igual a cero", + "Sample type cannot be blank": "El tipo de plantilla no puede quedar en blanco", + "Description cannot be blank": "Se debe rellenar el campo de texto", + "The new quantity should be smaller than the old one": "La nueva cantidad debe de ser menor que la anterior", + "The value should not be greater than 100%": "El valor no debe de ser mayor de 100%", + "The value should be a number": "El valor debe ser un numero", + "This order is not editable": "Esta orden no se puede modificar", + "You can't create an order for a frozen client": "No puedes crear una orden para un cliente congelado", + "You can't create an order for a client that has a debt": "No puedes crear una orden para un cliente con deuda", + "is not a valid date": "No es una fecha valida", + "Barcode must be unique": "El código de barras debe ser único", + "The warehouse can't be repeated": "El almacén no puede repetirse", + "The tag or priority can't be repeated for an item": "El tag o prioridad no puede repetirse para un item", + "The observation type can't be repeated": "El tipo de observación no puede repetirse", + "A claim with that sale already exists": "Ya existe una reclamación para esta línea", + "You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo", + "Warehouse cannot be blank": "El almacén no puede quedar en blanco", + "Agency cannot be blank": "La agencia no puede quedar en blanco", + "Not enough privileges to edit a client with verified data": "No tienes permisos para hacer cambios en un cliente con datos comprobados", + "This address doesn't exist": "Este consignatario no existe", + "You must delete the claim id %d first": "Antes debes borrar la reclamación %d", + "You don't have enough privileges": "No tienes suficientes permisos", + "Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF", + "You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos basicos de una orden con artículos", + "INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no esta permitido el uso de la letra ñ", + "You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado", + "You can't create a ticket for a inactive client": "No puedes crear un ticket para un cliente inactivo", + "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", + "ORDER_EMPTY": "Cesta vacía", + "You don't have enough privileges to do that": "No tienes permisos para cambiar esto", + "NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT", + "Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido", + "Street cannot be empty": "Dirección no puede estar en blanco", + "City cannot be empty": "Cuidad no puede estar en blanco", + "Code cannot be blank": "Código no puede estar en blanco", + "You cannot remove this department": "No puedes eliminar este departamento", + "The extension must be unique": "La extensión debe ser unica", + "The secret can't be blank": "La contraseña no puede estar en blanco", + "We weren't able to send this SMS": "No hemos podido enviar el SMS", + "This client can't be invoiced": "Este cliente no puede ser facturado", + "This ticket can't be invoiced": "Este ticket no puede ser facturado", + "You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado", + "This ticket can not be modified": "Este ticket no puede ser modificado", + "The introduced hour already exists": "Esta hora ya ha sido introducida", + "INFINITE_LOOP": "Existe una dependencia entre dos Jefes", + "The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas", + "NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros", + "ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado", + "The current ticket can't be modified": "El ticket actual no puede ser modificado", + "The current claim can't be modified": "La reclamación actual no puede ser modificada", + "The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", + "The sales do not exists": "La(s) línea(s) seleccionada(s) no existe(n)", + "Please select at least one sale": "Por favor selecciona al menos una linea", + "All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket", + "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", + "This item doesn't exists": "El artículo no existe", + "NOT_ZONE_WITH_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", + "Extension format is invalid": "El formato de la extensión es inválido", + "Invalid parameters to create a new ticket": "Parámetros inválidos para crear un nuevo ticket", + "This item is not available": "Este artículo no está disponible", + "This postcode already exists": "Este código postal ya existe", + "Concept cannot be blank": "El concepto no puede quedar en blanco", + "File doesn't exists": "El archivo no existe", + "You don't have privileges to change the zone": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias", + "This ticket is already on weekly tickets": "Este ticket ya está en tickets programados", + "Ticket id cannot be blank": "El id de ticket no puede quedar en blanco", + "Weekday cannot be blank": "El día de la semana no puede quedar en blanco", + "You can't delete a confirmed order": "No puedes borrar un pedido confirmado", + "The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto", + "Invalid quantity": "Cantidad invalida", + "This postal code is not valid": "This postal code is not valid", + "is invalid": "is invalid", + "The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto", + "The department name can't be repeated": "El nombre del departamento no puede repetirse", + "This phone already exists": "Este teléfono ya existe", + "You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos", + "You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado", + "You cannot delete a ticket that part of it is being prepared": "No puedes eliminar un ticket en el que una parte que está siendo preparada", + "You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero", + "You should specify a date": "Debes especificar una fecha", + "You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín", + "Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín", + "You should mark at least one week day": "Debes marcar al menos un día de la semana", + "Swift / BIC can't be empty": "Swift / BIC no puede estar vacío", + "Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios", + "Incoterms is required for a non UEE member": "El incoterms es requerido para los clientes extracomunitarios", + "Deleted sales from ticket": "He eliminado las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{deletions}}}", + "Added sale to ticket": "He añadido la siguiente linea al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}", + "Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})", + "Changed sale quantity": "He cambiado la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* del ticket [{{ticketId}}]({{{ticketUrl}}})", + "State": "Estado", + "regular": "normal", + "reserved": "reservado", + "Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})", + "Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}", + "MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*", + "Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})", + "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})", + "Change quantity": "{{concept}} cambia de {{oldQuantity}} a {{newQuantity}}", + "Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*", + "Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*", + "Claim state has changed to canceled": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *anulado*", + "Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}", + "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", + "Distance must be lesser than 1000": "La distancia debe ser inferior a 1000", + "This ticket is deleted": "Este ticket está eliminado", + "Unable to clone this travel": "No ha sido posible clonar este travel", + "This thermograph id already exists": "La id del termógrafo ya existe", + "Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante", + "ORDER_ALREADY_CONFIRMED": "ORDER_ALREADY_CONFIRMED", + "Invalid password": "Invalid password", + "Password does not meet requirements": "La contraseña no cumple los requisitos", + "Role already assigned": "Role already assigned", + "Invalid role name": "Invalid role name", + "Role name must be written in camelCase": "Role name must be written in camelCase", + "Email already exists": "Email already exists", + "User already exists": "User already exists", + "Absence change notification on the labour calendar": "Notificacion de cambio de ausencia en el calendario laboral", + "Record of hours week": "Registro de horas semana {{week}} año {{year}} ", + "Created absence": "El empleado {{author}} ha añadido una ausencia de tipo '{{absenceType}}' a {{employee}} para el día {{dated}}.", + "Deleted absence": "El empleado {{author}} ha eliminado una ausencia de tipo '{{absenceType}}' a {{employee}} del día {{dated}}.", + "I have deleted the ticket id": "He eliminado el ticket id [{{id}}]({{{url}}})", + "I have restored the ticket id": "He restaurado el ticket id [{{id}}]({{{url}}})", + "You can only restore a ticket within the first hour after deletion": "Únicamente puedes restaurar el ticket dentro de la primera hora después de su eliminación", + "Changed this data from the ticket": "He cambiado estos datos del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "agencyModeFk": "Agencia", + "clientFk": "Cliente", + "zoneFk": "Zona", + "warehouseFk": "Almacén", + "shipped": "F. envío", + "landed": "F. entrega", + "addressFk": "Consignatario", + "companyFk": "Empresa", + "The social name cannot be empty": "La razón social no puede quedar en blanco", + "The nif cannot be empty": "El NIF no puede quedar en blanco", + "You need to fill sage information before you check verified data": "Debes rellenar la información de sage antes de marcar datos comprobados", + "ASSIGN_ZONE_FIRST": "Asigna una zona primero", + "Amount cannot be zero": "El importe no puede ser cero", + "Company has to be official": "Empresa inválida", + "You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria", + "Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas", + "The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta", + "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*", + "New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*", + "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", + "This BIC already exist.": "Este BIC ya existe.", + "That item doesn't exists": "Ese artículo no existe", + "There's a new urgent ticket:": "Hay un nuevo ticket urgente:", + "Invalid account": "Cuenta inválida", + "Compensation account is empty": "La cuenta para compensar está vacia", + "This genus already exist": "Este genus ya existe", + "This specie already exist": "Esta especie ya existe", + "Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})", + "None": "Ninguno", + "The contract was not active during the selected date": "El contrato no estaba activo durante la fecha seleccionada", + "Cannot add more than one '1/2 day vacation'": "No puedes añadir más de un 'Vacaciones 1/2 dia'", + "This document already exists on this ticket": "Este documento ya existe en el ticket", + "Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables", + "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", + "nickname": "nickname", + "INACTIVE_PROVIDER": "Proveedor inactivo", + "This client is not invoiceable": "Este cliente no es facturable", + "serial non editable": "Esta serie no permite asignar la referencia", + "Max shipped required": "La fecha límite es requerida", + "Can't invoice to future": "No se puede facturar a futuro", + "Can't invoice to past": "No se puede facturar a pasado", + "This ticket is already invoiced": "Este ticket ya está facturado", + "A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero", + "A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa", + "Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes", + "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes", + "Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio", + "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito", + "You can't change the credit set to zero from a financialBoss": "No puedes cambiar el cŕedito establecido a cero por un jefe de finanzas", + "Amounts do not match": "Las cantidades no coinciden", + "The PDF document does not exist": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'", + "The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos", + "You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días", + "The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día", + "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", + "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", + "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", + "You don't have privileges to create refund": "No tienes permisos para crear un abono", + "The item is required": "El artículo es requerido", + "The agency is already assigned to another autonomous": "La agencia ya está asignada a otro autónomo", + "date in the future": "Fecha en el futuro", + "reference duplicated": "Referencia duplicada", + "This ticket is already a refund": "Este ticket ya es un abono", + "isWithoutNegatives": "isWithoutNegatives", + "routeFk": "routeFk", + "Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador", + "No hay un contrato en vigor": "No hay un contrato en vigor", + "No se permite fichar a futuro": "No se permite fichar a futuro", + "No está permitido trabajar": "No está permitido trabajar", + "Fichadas impares": "Fichadas impares", + "Descanso diario 12h.": "Descanso diario 12h.", + "Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.", + "Dirección incorrecta": "Dirección incorrecta", + "Modifiable user details only by an administrator": "Detalles de usuario modificables solo por un administrador", + "Modifiable password only via recovery or by an administrator": "Contraseña modificable solo a través de la recuperación o por un administrador", + "Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente", + "This route does not exists": "Esta ruta no existe", + "Claim pickup order sent": "Reclamación Orden de recogida enviada [{{claimId}}]({{{claimUrl}}}) al cliente *{{clientName}}*", + "You don't have grant privilege": "No tienes privilegios para dar privilegios", + "You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario", + "Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) fusionado con [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})", + "Already has this status": "Ya tiene este estado", + "There aren't records for this week": "No existen registros para esta semana", + "Empty data source": "Origen de datos vacio", + "App locked": "Aplicación bloqueada por el usuario {{userId}}", + "Email verify": "Correo de verificación", + "Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment", + "Receipt's bank was not found": "No se encontró el banco del recibo", + "This receipt was not compensated": "Este recibo no ha sido compensado", + "Client's email was not found": "No se encontró el email del cliente", + "Negative basis": "Base negativa", + "This worker code already exists": "Este codigo de trabajador ya existe", + "This personal mail already exists": "Este correo personal ya existe", + "This worker already exists": "Este trabajador ya existe", + "App name does not exist": "El nombre de aplicación no es válido", + "Try again": "Vuelve a intentarlo", + "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9", + "Failed to upload delivery note": "Error al subir albarán {{id}}", + "The DOCUWARE PDF document does not exists": "El documento PDF Docuware no existe", + "It is not possible to modify tracked sales": "No es posible modificar líneas de pedido que se hayan empezado a preparar", + "It is not possible to modify sales that their articles are from Floramondo": "No es posible modificar líneas de pedido cuyos artículos sean de Floramondo", + "It is not possible to modify cloned sales": "No es posible modificar líneas de pedido clonadas", + "A supplier with the same name already exists. Change the country.": "Un proveedor con el mismo nombre ya existe. Cambie el país.", + "There is no assigned email for this client": "No hay correo asignado para este cliente", + "Exists an invoice with a future date": "Existe una factura con fecha posterior", + "Invoice date can't be less than max date": "La fecha de factura no puede ser inferior a la fecha límite", + "Warehouse inventory not set": "El almacén inventario no está establecido", + "This locker has already been assigned": "Esta taquilla ya ha sido asignada", + "Tickets with associated refunds": "No se pueden borrar tickets con abonos asociados. Este ticket está asociado al abono Nº %d", + "Not exist this branch": "La rama no existe", + "This ticket cannot be signed because it has not been boxed": "Este ticket no puede firmarse porque no ha sido encajado", + "Collection does not exist": "La colección no existe", + "Cannot obtain exclusive lock": "No se puede obtener un bloqueo exclusivo", + "Insert a date range": "Inserte un rango de fechas", + "Added observation": "{{user}} añadió esta observacion: {{text}}", + "Comment added to client": "Observación añadida al cliente {{clientFk}}", + "Invalid auth code": "Código de verificación incorrecto", + "Invalid or expired verification code": "Código de verificación incorrecto o expirado", + "Cannot create a new claimBeginning from a different ticket": "No se puede crear una línea de reclamación de un ticket diferente al origen", + "company": "Compañía", + "country": "País", + "clientId": "Id cliente", + "clientSocialName": "Cliente", + "amount": "Importe", + "taxableBase": "Base", + "ticketFk": "Id ticket", + "isActive": "Activo", + "hasToInvoice": "Facturar", + "isTaxDataChecked": "Datos comprobados", + "comercialId": "Id comercial", + "comercialName": "Comercial", + "Pass expired": "La contraseña ha caducado, cambiela desde Salix", + "Invalid NIF for VIES": "Invalid NIF for VIES", + "Ticket does not exist": "Este ticket no existe", + "Ticket is already signed": "Este ticket ya ha sido firmado", + "Authentication failed": "Autenticación fallida", + "You can't use the same password": "No puedes usar la misma contraseña", + "You can only add negative amounts in refund tickets": "Solo se puede añadir cantidades negativas en tickets abono", + "Fecha fuera de rango": "Fecha fuera de rango", + "Error while generating PDF": "Error al generar PDF", + "Error when sending mail to client": "Error al enviar el correo al cliente", + "Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico", + "The renew period has not been exceeded": "El periodo de renovación no ha sido superado", + "Valid priorities": "Prioridades válidas: %d", + "Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}", + "You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado", + "This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s", + "The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias", + "You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado", + "This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado", + "You don't have enough privileges.": "No tienes suficientes permisos.", + "This ticket is locked.": "Este ticket está bloqueado.", + "This ticket is not editable.": "Este ticket no es editable.", + "The ticket doesn't exist.": "No existe el ticket.", + "Social name should be uppercase": "La razón social debe ir en mayúscula", + "Street should be uppercase": "La dirección fiscal debe ir en mayúscula", + "Ticket without Route": "Ticket sin ruta", + "Select a different customer": "Seleccione un cliente distinto", + "Fill all the fields": "Rellene todos los campos" } \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js index 0b123dd3da..65b671716a 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js @@ -1,3 +1,5 @@ +const UserError = require('vn-loopback/util/user-error'); + module.exports = Self => { Self.remoteMethodCtx('transferInvoice', { description: 'Transfer an issued invoice to another client', @@ -6,7 +8,8 @@ module.exports = Self => { { arg: 'id', type: 'number', - required: true + required: true, + description: 'Issued invoice id' }, { arg: 'ref', @@ -16,22 +19,18 @@ module.exports = Self => { { arg: 'newClientFk', type: 'number', - required: true }, { arg: 'cplusRectificationId', type: 'number', - required: true }, { arg: 'cplusInvoiceType477Id', type: 'number', - required: true }, { arg: 'invoiceCorrectionTypeId', type: 'number', - required: true }, ], returns: { @@ -44,26 +43,32 @@ module.exports = Self => { } }); - Self.transferInvoice = async(ctx, id, ref, newClientFk, cplusRectificationId, cplusInvoiceType477Id, invoiceCorrectionTypeId, options) => { + Self.transferInvoice = async(ctx, options) => { const models = Self.app.models; const myOptions = {userId: ctx.req.accessToken.userId}; - + const args = ctx.args; let tx; if (typeof options == 'object') Object.assign(myOptions, options); + const {clientFk} = await models.InvoiceOut.findById(args.id); + + if (clientFk == args.newClientFk) + throw new UserError(`Select a different customer`); + + if (!args.newClientFk || !args.cplusRectificationId || !args.cplusInvoiceType477Id || !args.invoiceCorrectionTypeId) + throw new UserError(`Fill all the fields`); + if (!myOptions.transaction) { tx = await Self.beginTransaction({}); myOptions.transaction = tx; } try { - // Refund tickets and group - const filterRef = {where: {refFk: ref}}; + const filterRef = {where: {refFk: args.ref}}; const tickets = await models.Ticket.find(filterRef, myOptions); const ticketsIds = tickets.map(ticket => ticket.id); await models.Ticket.refund(ctx, ticketsIds, null, myOptions); - // Clone tickets const filterTicket = {where: {ticketFk: {inq: ticketsIds}}}; const services = await models.TicketService.find(filterTicket, myOptions); @@ -75,28 +80,24 @@ module.exports = Self => { const clonedTickets = await models.Sale.clone(salesIds, servicesIds, null, false, false, myOptions); const clonedTicketIds = []; - // Update client for (const clonedTicket of clonedTickets) { - await clonedTicket.updateAttribute('clientFk', newClientFk, myOptions); + await clonedTicket.updateAttribute('clientFk', args.newClientFk, myOptions); clonedTicketIds.push(clonedTicket.id); } - // Quick invoice const invoiceIds = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); const [invoiceId] = invoiceIds; - // Insert InvoiceCorrection await models.InvoiceCorrection.create({ correctingFk: invoiceId, - correctedFk: id, - cplusRectificationTypeFk: cplusRectificationId, - cplusInvoiceType477Fk: cplusInvoiceType477Id, - invoiceCorrectionType: invoiceCorrectionTypeId + correctedFk: args.id, + cplusRectificationTypeFk: args.cplusRectificationId, + cplusInvoiceType477Fk: args.cplusInvoiceType477Id, + invoiceCorrectionType: args.invoiceCorrectionTypeId }, myOptions); if (tx) await tx.commit(); - // Crear PDF await models.InvoiceOut.makePdfAndNotify(ctx, invoiceId, null); return invoiceId; diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index 9a3b5fedc9..d899b3c449 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -28,7 +28,6 @@ module.exports = Self => { const refundTickets = []; const mappedTickets = new Map(); const now = Date.vnNew(); - const [firstTicketId] = ticketsIds; if (group) { await createTicketRefund( diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 3f7e1cd217..ba7d712539 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -42,35 +42,10 @@ module.exports = Self => { } try { - const refundAgencyMode = await models.AgencyMode.findOne({ - include: { - relation: 'zones', - scope: { - limit: 1, - field: ['id', 'name'] - } - }, - where: {code: 'refund'} - }, myOptions); - - const refoundZoneId = refundAgencyMode.zones()[0].id; - - const salesFilter = { - where: {id: {inq: salesIds}}, - include: { - relation: 'components', - scope: { - fields: ['saleFk', 'componentFk', 'value'] - } - } - }; - // const sales = await models.Sale.find(salesFilter, myOptions); - const refundTicket = await models.Sale.clone( + const refundsTicket = await models.Sale.clone( salesIds, servicesIds, withWarehouse, - // refundAgencyMode, - // refoundZoneId, true, true, myOptions @@ -78,36 +53,10 @@ module.exports = Self => { if (tx && !options) await tx.commit(); - return refundTicket; + return refundsTicket[0]; } catch (e) { if (tx) await tx.rollback(); throw e; } }; - - /* async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions) { - const models = Self.app.models; - - const filter = {include: {relation: 'address'}}; - const ticket = await models.Ticket.findById(ticketId, filter, myOptions); - - const refundTicket = await models.Ticket.create({ - clientFk: ticket.clientFk, - shipped: now, - addressFk: ticket.address().id, - agencyModeFk: refundAgencyMode.id, - nickname: ticket.address().nickname, - warehouseFk: withWarehouse ? ticket.warehouseFk : null, - companyFk: ticket.companyFk, - landed: now, - zoneFk: refoundZoneId - }, myOptions); - - await models.TicketRefund.create({ - refundTicketFk: refundTicket.id, - originalTicketFk: ticket.id, - }, myOptions); - - return refundTicket; - } */ }; diff --git a/modules/ticket/back/methods/sale/specs/refund.spec.js b/modules/ticket/back/methods/sale/specs/refund.spec.js index 727ce2face..b81f7f84d8 100644 --- a/modules/ticket/back/methods/sale/specs/refund.spec.js +++ b/modules/ticket/back/methods/sale/specs/refund.spec.js @@ -1,7 +1,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); -fdescribe('Sale refund()', () => { +describe('Sale refund()', () => { const userId = 5; const ctx = {req: {accessToken: userId}}; const activeCtx = { From a78348f2de7624b3e44b004ede1f055659c256c0 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 21 Sep 2023 15:06:14 +0200 Subject: [PATCH 035/449] refs #6067 feat(account_basicData): use vnUser/preview --- modules/account/front/basic-data/index.html | 14 ++++++++------ modules/account/front/basic-data/index.js | 7 +++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/modules/account/front/basic-data/index.html b/modules/account/front/basic-data/index.html index 6f757753e1..1f7ce1a05e 100644 --- a/modules/account/front/basic-data/index.html +++ b/modules/account/front/basic-data/index.html @@ -1,9 +1,11 @@ + + where="{id: $ctrl.$params.id}" + form="form" + save="post">
diff --git a/modules/account/front/basic-data/index.js b/modules/account/front/basic-data/index.js index 77d3eab26c..43d1c0468d 100644 --- a/modules/account/front/basic-data/index.js +++ b/modules/account/front/basic-data/index.js @@ -2,6 +2,13 @@ import ngModule from '../module'; import Section from 'salix/components/section'; export default class Controller extends Section { + set user(value) { + this._user = value; + console.log(value); + } + get user() { + return this._user; + } $onInit() { if (this.$params.emailConfirmed) this.vnApp.showSuccess(this.$t('Email verified successfully!')); From 82f14e62ade80aed1df3ebd0e45bebba603def3b Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 21 Sep 2023 16:08:55 +0200 Subject: [PATCH 036/449] ref #5914 tests fixed --- modules/invoiceOut/back/models/invoice-out.js | 1 + modules/ticket/back/methods/sale/refund.js | 2 +- modules/ticket/back/methods/ticket/invoiceTickets.js | 2 +- print/templates/reports/invoice/invoice.js | 2 -- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js index ca77c856f6..34b4dc7980 100644 --- a/modules/invoiceOut/back/models/invoice-out.js +++ b/modules/invoiceOut/back/models/invoice-out.js @@ -44,6 +44,7 @@ module.exports = Self => { Self.makePdf = async function(id, options) { const fields = ['id', 'hasPdf', 'ref']; const invoiceOut = await Self.findById(id, {fields}, options); + console.log('Recoge invoiceOut?'); const invoiceReport = new print.Report('invoice', { reference: invoiceOut.ref }); diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index ba7d712539..5d8297a4e0 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -51,7 +51,7 @@ module.exports = Self => { myOptions ); - if (tx && !options) await tx.commit(); + if (tx) await tx.commit(); return refundsTicket[0]; } catch (e) { diff --git a/modules/ticket/back/methods/ticket/invoiceTickets.js b/modules/ticket/back/methods/ticket/invoiceTickets.js index e65c14e9a3..fa3ee93af2 100644 --- a/modules/ticket/back/methods/ticket/invoiceTickets.js +++ b/modules/ticket/back/methods/ticket/invoiceTickets.js @@ -79,7 +79,7 @@ module.exports = function(Self) { } if (tx) { for (const invoiceId of invoicesIds) - await models.InvoiceOut.makePdfAndNotify(ctx, invoiceId, null, myOptions); + await models.InvoiceOut.makePdfAndNotify(ctx, invoiceId, null); } return invoicesIds; diff --git a/print/templates/reports/invoice/invoice.js b/print/templates/reports/invoice/invoice.js index 4424c8ea35..b26472b08b 100755 --- a/print/templates/reports/invoice/invoice.js +++ b/print/templates/reports/invoice/invoice.js @@ -6,9 +6,7 @@ module.exports = { name: 'invoice', mixins: [vnReport], async serverPrefetch() { - console.log(this.reference); this.invoice = await this.findOneFromDef('invoice', [this.reference]); - console.log(this.invoice); this.checkMainEntity(this.invoice); this.client = await this.findOneFromDef('client', [this.reference]); From a854fff94f8db16786ae10232098e1ef4e17b242 Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 22 Sep 2023 10:59:48 +0200 Subject: [PATCH 037/449] refs #3126 changes --- db/.archive/231001/00-packagingFk.sql | 2 + db/.archive/231001/00-packagingFkviews.sql | 146 ++++ db/.archive/231001/02-packagingFktrigger.sql | 57 ++ db/.archive/231001/03-packagingFkProc.sql | 669 ++++++++++++++++++ db/dump/fixtures.sql | 2 +- e2e/helpers/selectors.js | 2 +- e2e/paths/13-supplier/03_fiscal_data.spec.js | 25 +- modules/entry/back/locale/buy/en.yml | 2 +- modules/entry/back/locale/buy/es.yml | 2 +- .../entry/back/methods/entry/addFromBuy.js | 2 +- modules/entry/back/methods/entry/getBuys.js | 2 +- .../entry/back/methods/entry/importBuys.js | 2 +- .../back/methods/entry/importBuysPreview.js | 2 +- .../back/methods/entry/latestBuysFilter.js | 115 ++- .../methods/entry/specs/importBuys.spec.js | 4 +- .../entry/specs/importBuysPreview.spec.js | 6 +- modules/entry/back/models/buy.json | 2 +- modules/entry/front/buy/import/index.html | 4 +- modules/entry/front/buy/index/index.html | 4 +- modules/entry/front/buy/index/index.js | 2 +- modules/entry/front/buy/index/index.spec.js | 2 +- modules/entry/front/latest-buys/index.html | 4 +- modules/entry/front/latest-buys/index.js | 4 +- modules/entry/front/summary/index.html | 4 +- .../back/methods/item/lastEntriesFilter.js | 76 +- modules/item/front/last-entries/index.html | 4 +- modules/item/front/last-entries/index.js | 2 +- .../methods/travel/extraCommunityFilter.js | 20 +- .../travel/back/methods/travel/getEntries.js | 2 +- 29 files changed, 1020 insertions(+), 150 deletions(-) create mode 100644 db/.archive/231001/00-packagingFk.sql create mode 100644 db/.archive/231001/00-packagingFkviews.sql create mode 100644 db/.archive/231001/02-packagingFktrigger.sql create mode 100644 db/.archive/231001/03-packagingFkProc.sql diff --git a/db/.archive/231001/00-packagingFk.sql b/db/.archive/231001/00-packagingFk.sql new file mode 100644 index 0000000000..5ed1d95129 --- /dev/null +++ b/db/.archive/231001/00-packagingFk.sql @@ -0,0 +1,2 @@ + ALTER TABLE vn.buy CHANGE packageFk packagingFk varchar(10) + CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT '--' NULL; \ No newline at end of file diff --git a/db/.archive/231001/00-packagingFkviews.sql b/db/.archive/231001/00-packagingFkviews.sql new file mode 100644 index 0000000000..f355325f3e --- /dev/null +++ b/db/.archive/231001/00-packagingFkviews.sql @@ -0,0 +1,146 @@ +CREATE OR REPLACE DEFINER=`root`@`localhost` + SQL SECURITY DEFINER + VIEW `vn2008`.`Compres` +AS SELECT `c`.`id` AS `Id_Compra`, + `c`.`entryFk` AS `Id_Entrada`, + `c`.`itemFk` AS `Id_Article`, + `c`.`buyingValue` AS `Costefijo`, + `c`.`quantity` AS `Cantidad`, + `c`.`packagingFk` AS `Id_Cubo`, + `c`.`stickers` AS `Etiquetas`, + `c`.`freightValue` AS `Portefijo`, + `c`.`packageValue` AS `Embalajefijo`, + `c`.`comissionValue` AS `Comisionfija`, + `c`.`packing` AS `Packing`, + `c`.`grouping` AS `grouping`, + `c`.`groupingMode` AS `caja`, + `c`.`location` AS `Nicho`, + `c`.`price1` AS `Tarifa1`, + `c`.`price2` AS `Tarifa2`, + `c`.`price3` AS `Tarifa3`, + `c`.`minPrice` AS `PVP`, + `c`.`printedStickers` AS `Vida`, + `c`.`isChecked` AS `punteo`, + `c`.`ektFk` AS `buy_edi_id`, + `c`.`created` AS `odbc_date`, + `c`.`isIgnored` AS `Novincular`, + `c`.`isPickedOff` AS `isPickedOff`, + `c`.`workerFk` AS `Id_Trabajador`, + `c`.`weight` AS `weight`, + `c`.`dispatched` AS `dispatched`, + `c`.`containerFk` AS `container_id`, + `c`.`itemOriginalFk` AS `itemOriginalFk` +FROM `vn`.`buy` `c`; + +CREATE OR REPLACE DEFINER=`root`@`localhost` + SQL SECURITY DEFINER + VIEW `vn2008`.`buySource` +AS SELECT `b`.`entryFk` AS `Id_Entrada`, + `b`.`isPickedOff` AS `isPickedOff`, + NULL AS `tarifa0`, + `e`.`kop` AS `kop`, + `b`.`id` AS `Id_Compra`, + `i`.`typeFk` AS `tipo_id`, + `b`.`itemFk` AS `Id_Article`, + `i`.`size` AS `Medida`, + `i`.`stems` AS `Tallos`, + `b`.`stickers` AS `Etiquetas`, + `b`.`packagingFk` AS `Id_Cubo`, + `b`.`buyingValue` AS `Costefijo`, + `b`.`packing` AS `Packing`, + `b`.`grouping` AS `Grouping`, + `b`.`quantity` AS `Cantidad`, + `b`.`price2` AS `Tarifa2`, + `b`.`price3` AS `Tarifa3`, + `b`.`isChecked` AS `Punteo`, + `b`.`groupingMode` AS `Caja`, + `i`.`isToPrint` AS `Imprimir`, + `i`.`name` AS `Article`, + `vn`.`ink`.`picture` AS `Tinta`, + `i`.`originFk` AS `id_origen`, + `i`.`minPrice` AS `PVP`, + NULL AS `Id_Accion`, + `s`.`company_name` AS `pro`, + `i`.`hasMinPrice` AS `Min`, + `b`.`isIgnored` AS `Novincular`, + `b`.`freightValue` AS `Portefijo`, + round(`b`.`buyingValue` * `b`.`quantity`, 2) AS `Importe`, + `b`.`printedStickers` AS `Vida`, + `i`.`comment` AS `reference`, + `b`.`workerFk` AS `Id_Trabajador`, + `e`.`s1` AS `S1`, + `e`.`s2` AS `S2`, + `e`.`s3` AS `S3`, + `e`.`s4` AS `S4`, + `e`.`s5` AS `S5`, + `e`.`s6` AS `S6`, + 0 AS `price_fixed`, + `i`.`producerFk` AS `producer_id`, + `i`.`subName` AS `tag1`, + `i`.`value5` AS `tag2`, + `i`.`value6` AS `tag3`, + `i`.`value7` AS `tag4`, + `i`.`value8` AS `tag5`, + `i`.`value9` AS `tag6`, + `s`.`company_name` AS `company_name`, + `b`.`weight` AS `weightPacking`, + `i`.`packingOut` AS `packingOut`, + `b`.`itemOriginalFk` AS `itemOriginalFk`, + `io`.`longName` AS `itemOriginalName`, + `it`.`gramsMax` AS `gramsMax` +FROM ( + ( + ( + ( + ( + ( + `vn`.`item` `i` + JOIN `vn`.`itemType` `it` ON(`it`.`id` = `i`.`typeFk`) + ) + LEFT JOIN `vn`.`ink` ON(`vn`.`ink`.`id` = `i`.`inkFk`) + ) + LEFT JOIN `vn`.`buy` `b` ON(`b`.`itemFk` = `i`.`id`) + ) + LEFT JOIN `vn`.`item` `io` ON(`io`.`id` = `b`.`itemOriginalFk`) + ) + LEFT JOIN `edi`.`ekt` `e` ON(`e`.`id` = `b`.`ektFk`) + ) + LEFT JOIN `edi`.`supplier` `s` ON(`e`.`pro` = `s`.`supplier_id`) + ); + +CREATE OR REPLACE DEFINER=`root`@`localhost` + SQL SECURITY DEFINER + VIEW `vn`.`awbVolume` +AS SELECT `d`.`awbFk` AS `awbFk`, + `b`.`stickers` * `i`.`density` * IF( + `p`.`volume` > 0, + `p`.`volume`, + `p`.`width` * `p`.`depth` * IF(`p`.`height` = 0, `i`.`size` + 10, `p`.`height`) + ) / (`vc`.`aerealVolumetricDensity` * 1000) AS `volume`, + `b`.`id` AS `buyFk` +FROM ( + ( + ( + ( + ( + ( + ( + ( + `vn`.`buy` `b` + JOIN `vn`.`item` `i` ON(`b`.`itemFk` = `i`.`id`) + ) + JOIN `vn`.`itemType` `it` ON(`i`.`typeFk` = `it`.`id`) + ) + JOIN `vn`.`packaging` `p` ON(`p`.`id` = `b`.`packagingFk`) + ) + JOIN `vn`.`entry` `e` ON(`b`.`entryFk` = `e`.`id`) + ) + JOIN `vn`.`travel` `t` ON(`t`.`id` = `e`.`travelFk`) + ) + JOIN `vn`.`duaEntry` `de` ON(`de`.`entryFk` = `e`.`id`) + ) + JOIN `vn`.`dua` `d` ON(`d`.`id` = `de`.`duaFk`) + ) + JOIN `vn`.`volumeConfig` `vc` + ) +WHERE `t`.`shipped` > makedate(year(`util`.`VN_CURDATE`()) - 1, 1); \ No newline at end of file diff --git a/db/.archive/231001/02-packagingFktrigger.sql b/db/.archive/231001/02-packagingFktrigger.sql new file mode 100644 index 0000000000..4edcd3f3ee --- /dev/null +++ b/db/.archive/231001/02-packagingFktrigger.sql @@ -0,0 +1,57 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`buy_afterUpdate` + AFTER UPDATE ON `buy` + FOR EACH ROW +trig: BEGIN + DECLARE vLanded DATE; + DECLARE vBuyerFk INT; + DECLARE vIsBuyerToBeEmailed BOOL; + DECLARE vItemName VARCHAR(50); + + IF @isModeInventory OR @isTriggerDisabled THEN + LEAVE trig; + END IF; + + IF !(NEW.id <=> OLD.id) + OR !(NEW.entryFk <=> OLD.entryFk) + OR !(NEW.itemFk <=> OLD.itemFk) + OR !(NEW.quantity <=> OLD.quantity) + OR !(NEW.created <=> OLD.created) THEN + CALL stock.log_add('buy', NEW.id, OLD.id); + END IF; + + CALL buy_afterUpsert(NEW.id); + + SELECT w.isBuyerToBeEmailed, t.landed + INTO vIsBuyerToBeEmailed, vLanded + FROM entry e + JOIN travel t ON t.id = e.travelFk + JOIN warehouse w ON w.id = t.warehouseInFk + WHERE e.id = NEW.entryFk; + + SELECT it.workerFk, i.longName + INTO vBuyerFk, vItemName + FROM itemCategory k + JOIN itemType it ON it.categoryFk = k.id + JOIN item i ON i.typeFk = it.id + WHERE i.id = OLD.itemFk; + + IF vIsBuyerToBeEmailed AND + vBuyerFk != account.myUser_getId() AND + vLanded = util.VN_CURDATE() THEN + IF !(NEW.itemFk <=> OLD.itemFk) OR + !(NEW.quantity <=> OLD.quantity) OR + !(NEW.packing <=> OLD.packing) OR + !(NEW.grouping <=> OLD.grouping) OR + !(NEW.packagingFk <=> OLD.packagingFk) OR + !(NEW.weight <=> OLD.weight) THEN + CALL vn.mail_insert( + CONCAT(account.user_getNameFromId(vBuyerFk),'@verdnatura.es'), + CONCAT(account.myUser_getName(),'@verdnatura.es'), + CONCAT('E ', NEW.entryFk ,' Se ha modificado item ', NEW.itemFk, ' ', vItemName), + 'Este email se ha generado automáticamente' + ); + END IF; + END IF; +END$$ +DELIMITER ; \ No newline at end of file diff --git a/db/.archive/231001/03-packagingFkProc.sql b/db/.archive/231001/03-packagingFkProc.sql new file mode 100644 index 0000000000..acbf54a763 --- /dev/null +++ b/db/.archive/231001/03-packagingFkProc.sql @@ -0,0 +1,669 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`travelVolume`(vTravelFk INT) +BEGIN + + SELECT w1.name AS ORI, + w2.name AS DES, + tr.shipped shipment, + tr.landed landing, + a.name Agencia, + s.name Proveedor, + e.id Id_Entrada, + e.invoiceNumber Referencia, + CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * + vn.item_getVolume(b.itemFk ,b.packagingFk)) / vc.trolleyM3 / 1000000 ,1) AS DECIMAL(10,2)) AS CC, + CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * + vn.item_getVolume(b.itemFk ,b.packagingFk)) / vc.palletM3 / 1000000,1) AS DECIMAL(10,2)) AS espais + FROM vn.buy b + JOIN vn.entry e ON e.id = b.entryFk + JOIN vn.supplier s ON s.id = e.supplierFk + JOIN vn.travel tr ON tr.id = e.travelFk + JOIN vn.agencyMode a ON a.id = tr.agencyModeFk + JOIN vn.warehouse w1 ON w1.id = tr.warehouseInFk + JOIN vn.warehouse w2 ON w2.id = tr.warehouseOutFk + JOIN vn.volumeConfig vc + JOIN vn.item i ON i.id = b.itemFk + JOIN vn.itemType it ON it.id = i.typeFk + WHERE tr.id = vTravelFk; + +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`travelVolume_get`(vFromDated DATE, vToDated DATE, vWarehouseFk INT) +BEGIN + SELECT tr.landed Fecha, + a.name Agencia, + count(DISTINCT e.id) numEntradas, + FLOOR(sum(item_getVolume(b.itemFk, b.packagingFk) * b.stickers / 1000000 )) AS m3 + FROM vn.travel tr + JOIN vn.agencyMode a ON a.id = tr.agencyModeFk + JOIN vn.entry e ON e.travelFk = tr.id + JOIN vn.buy b ON b.entryFk = e.id + WHERE tr.landed BETWEEN vFromDated AND vToDated + AND e.isRaid = FALSE + AND tr.warehouseInFk = vWarehouseFk + GROUP BY tr.landed , a.name ; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`travel_getEntriesMissingPackage`(vSelf INT) +BEGIN + DECLARE vpackageOrPackingNull INT; + DECLARE vTravelFk INT; + + SELECT travelfk INTO vTravelFk + FROM entry + WHERE id = vSelf; + + SELECT e.id entryFk + FROM travel t + JOIN entry e ON e.travelFk = t.id + JOIN buy b ON b.entryFk = e.id + WHERE t.id = vTravelFk + AND (b.packing IS NULL OR b.packagingFk IS NULL); +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticketBoxesView`(IN vTicketFk INT) +BEGIN + + SELECT s.id, + s.itemFk, + s.concept, + floor(s.quantity / b.packing) as Cajas, + b.packing, + s.isPicked, + i.size + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN cache.last_buy lb on lb.warehouse_id = t.warehouseFk AND lb.item_id = s.itemFk + JOIN buy b on b.id = lb.buy_id + JOIN packaging p on p.id = b.packagingFk + WHERE s.quantity >= b.packing + AND t.id = vTicketFk + AND p.isBox + GROUP BY s.itemFk; + + +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`stockBuyedByWorker`( + vDate DATE, + vWorker INT) +BEGIN +/** + * Calculates the space reserved by buyers of the same container + * + * @param vdate date of container delivery + * @param vWorker buyer reserving space in the container + */ + DECLARE vVolume DECIMAL(10, 2); + DECLARE vWarehouseFk INT; + DECLARE vCompressionRatio DECIMAL(1, 1); + + CALL stockTraslation(vDate); + + SELECT warehouseFk, conversionCoefficient INTO vWarehouseFk, vCompressionRatio + FROM auctionConfig; + + SELECT volume INTO vVolume + FROM vn.packaging WHERE id = 'cc'; + + SELECT b.entryFk Id_Entrada, + i.id Id_Article, + i.name Article, + ti.amount Cantidad, + (vCompressionRatio * (ti.amount / b.packing) * vn.buy_getVolume(b.id)) + / vVolume buyed, + b.packagingFk id_cubo, + b.packing + FROM tmp.item ti + JOIN item i ON i.id = ti.item_id + JOIN itemType it ON i.typeFk = it.id + JOIN itemCategory ic ON ic.id = it.categoryFk + JOIN worker w ON w.id = it.workerFk + JOIN tmp.buyUltimate bu ON bu.itemFk = i.id + AND bu.warehouseFk = vWarehouseFk + JOIN buy b ON b.id = bu.buyFk + WHERE ic.display AND w.id = vWorker; + + DROP TEMPORARY TABLE + tmp.buyUltimate, + tmp.item; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingMakeFromDate`(IN `vShelvingFk` VARCHAR(8), IN `vBarcode` VARCHAR(22), IN `vQuantity` INT, IN `vPackagingFk` VARCHAR(10), IN `vGrouping` INT, IN `vPacking` INT, IN `vWarehouseFk` INT, `vCreated` VARCHAR(22)) +BEGIN + + DECLARE vItemFk INT; + + SELECT vn.barcodeToItem(vBarcode) INTO vItemFk; + + SELECT itemFk INTO vItemFk + FROM vn.buy b + WHERE b.id = vItemFk; + + IF (SELECT COUNT(*) FROM vn.shelving WHERE code = vShelvingFk COLLATE utf8_unicode_ci) = 0 THEN + + INSERT IGNORE INTO vn.parking(`code`) VALUES(vShelvingFk); + INSERT INTO vn.shelving(`code`, parkingFk) + SELECT vShelvingFk, id + FROM vn.parking + WHERE `code` = vShelvingFk COLLATE utf8_unicode_ci; + + END IF; + + IF (SELECT COUNT(*) FROM vn.itemShelving + WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk + AND itemFk = vItemFk + AND packing = vPacking) = 1 THEN + + UPDATE vn.itemShelving + SET visible = visible+vQuantity, + created = vCreated + WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk + AND itemFk = vItemFk + AND packing = vPacking; + + ELSE + CALL cache.last_buy_refresh(FALSE); + INSERT INTO itemShelving( itemFk, + shelvingFk, + visible, + created, + `grouping`, + packing, + packagingFk) + SELECT vItemFk, + vShelvingFk, + vQuantity, + vCreated, + IF(vGrouping = 0, IFNULL(b.packing, vPacking), vGrouping) `grouping`, + IF(vPacking = 0, b.packing, vPacking) packing, + IF(vPackagingFk = '', b.packagingFk, vPackagingFk) packaging + FROM vn.item i + LEFT JOIN cache.last_buy lb ON i.id = lb.item_id AND lb.warehouse_id = vWarehouseFk + LEFT JOIN vn.buy b ON b.id = lb.buy_id + WHERE i.id = vItemFk; + END IF; + +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelving_add`(IN vShelvingFk VARCHAR(8), IN vBarcode VARCHAR(22), IN vQuantity INT, IN vPackagingFk VARCHAR(10), IN vGrouping INT, IN vPacking INT, IN vWarehouseFk INT) +BEGIN + + +/** + * Añade registro o lo actualiza si ya existe. + * + * @param vShelvingFk matrícula del carro + * @param vBarcode el id del registro + * @param vQuantity indica la cantidad del producto + * @param vPackagingFk el packaging del producto en itemShelving, NULL para coger el de la ultima compra + * @param vGrouping el grouping del producto en itemShelving, NULL para coger el de la ultima compra + * @param vPacking el packing del producto, NULL para coger el de la ultima compra + * @param vWarehouseFk indica el sector + * + **/ + + DECLARE vItemFk INT; + + SELECT barcodeToItem(vBarcode) INTO vItemFk; + + IF (SELECT COUNT(*) FROM shelving WHERE code = vShelvingFk COLLATE utf8_unicode_ci) = 0 THEN + + INSERT IGNORE INTO parking(code) VALUES(vShelvingFk); + INSERT INTO shelving(code, parkingFk) + SELECT vShelvingFk, id + FROM parking + WHERE `code` = vShelvingFk COLLATE utf8_unicode_ci; + + END IF; + + IF (SELECT COUNT(*) FROM itemShelving + WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk + AND itemFk = vItemFk + AND packing = vPacking) = 1 THEN + + UPDATE itemShelving + SET visible = visible+vQuantity + WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk AND itemFk = vItemFk AND packing = vPacking; + + ELSE + CALL cache.last_buy_refresh(FALSE); + INSERT INTO itemShelving( itemFk, + shelvingFk, + visible, + grouping, + packing, + packagingFk) + + SELECT vItemFk, + vShelvingFk, + vQuantity, + IFNULL(vGrouping, b.grouping), + IFNULL(vPacking, b.packing), + IFNULL(vPackagingFk, b.packagingFk) + FROM item i + LEFT JOIN cache.last_buy lb ON i.id = lb.item_id AND lb.warehouse_id = vWarehouseFk + LEFT JOIN buy b ON b.id = lb.buy_id + WHERE i.id = vItemFk; + END IF; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemFreight_Show`(vItemFk INT, vWarehouseFk INT) +BEGIN + + SELECT cm3 Volumen_Entrada, + cm3delivery Volumen_Salida, + p.volume Volumen_del_embalaje, + p.width Ancho_del_embalaje, + p.`depth` Largo_del_embalaje, + b.packagingFk , + IFNULL(p.height, i.`size`) + 10 Altura, + b.packing Packing_Entrada, + i.packingOut Packing_Salida, + i.id itemFk, + b.id buyFk, + b.entryFk, + w.name warehouseFk + FROM vn.itemCost ic + JOIN vn.item i ON i.id = ic.itemFk + LEFT JOIN cache.last_buy lb ON lb.item_id = ic.itemFk AND lb.warehouse_id = ic.warehouseFk + LEFT JOIN vn.buy b ON b.id = lb.buy_id + LEFT JOIN vn.packaging p ON p.id = b.packagingFk + LEFT JOIN vn.warehouse w ON w.id = ic.warehouseFk + WHERE ic.itemFk = vItemFk + AND ic.warehouseFk = vWarehouseFk; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`inventoryMake`(vDate DATE, vWh INT) +proc: BEGIN +/** +* Recalcula los inventarios de todos los almacenes, si vWh = 0 +* +* @param vDate Fecha de los nuevos inventarios +* @param vWh almacen al cual hacer el inventario +*/ + + DECLARE vDone BOOL; + DECLARE vEntryFk INT; + DECLARE vTravelFk INT; + DECLARE vDateLastInventory DATE; + DECLARE vDateYesterday DATETIME DEFAULT vDate - INTERVAL 1 SECOND; + DECLARE vWarehouseOutFkInventory INT; + DECLARE vInventorySupplierFk INT; + DECLARE vAgencyModeFkInventory INT; + + DECLARE cWarehouses CURSOR FOR + SELECT id + FROM warehouse + WHERE isInventory + AND vWh IN (0,id); + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + + OPEN cWarehouses; + SET @isModeInventory := TRUE; + l: LOOP + + SET vDone = FALSE; + FETCH cWarehouses INTO vWh; + + IF vDone THEN + LEAVE l; + END IF; + + SELECT w.id INTO vWarehouseOutFkInventory + FROM warehouse w + WHERE w.code = 'inv'; + + SELECT inventorySupplierFk INTO vInventorySupplierFk + FROM entryConfig; + + SELECT am.id INTO vAgencyModeFkInventory + FROM agencyMode am + where code = 'inv'; + + SELECT MAX(landed) INTO vDateLastInventory + FROM travel tr + JOIN entry e ON e.travelFk = tr.id + JOIN buy b ON b.entryFk = e.id + WHERE warehouseOutFk = vWarehouseOutFkInventory + AND landed < vDate + AND e.supplierFk = vInventorySupplierFk + AND warehouseInFk = vWh + AND NOT isRaid; + + IF vDateLastInventory IS NULL THEN + SELECT inventoried INTO vDateLastInventory FROM config; + END IF; + + -- Generamos travel, si no existe. + SET vTravelFK = 0; + + SELECT id INTO vTravelFk + FROM travel + WHERE warehouseOutFk = vWarehouseOutFkInventory + AND warehouseInFk = vWh + AND landed = vDate + AND agencyModeFk = vAgencyModeFkInventory + AND ref = 'inventario' + LIMIT 1; + + IF NOT vTravelFK THEN + + INSERT INTO travel SET + warehouseOutFk = vWarehouseOutFkInventory, + warehouseInFk = vWh, + shipped = vDate, + landed = vDate, + agencyModeFk = vAgencyModeFkInventory, + ref = 'inventario', + isDelivered = TRUE, + isReceived = TRUE; + + SELECT LAST_INSERT_ID() INTO vTravelFk; + + END IF; + + -- Generamos entrada si no existe, o la vaciamos. + SET vEntryFk = 0; + + SELECT id INTO vEntryFk + FROM entry + WHERE supplierFk = vInventorySupplierFk + AND travelFk = vTravelFk; + + IF NOT vEntryFk THEN + + INSERT INTO entry SET + supplierFk = vInventorySupplierFk, + isConfirmed = TRUE, + isOrdered = TRUE, + travelFk = vTravelFk; + + SELECT LAST_INSERT_ID() INTO vEntryFk; + + ELSE + + DELETE FROM buy WHERE entryFk = vEntryFk; + + END IF; + + -- Preparamos tabla auxilar + CREATE OR REPLACE TEMPORARY TABLE tmp.inventory ( + itemFk INT(11) NOT NULL PRIMARY KEY, + quantity int(11) DEFAULT '0', + buyingValue decimal(10,3) DEFAULT '0.000', + freightValue decimal(10,3) DEFAULT '0.000', + packing int(11) DEFAULT '0', + `grouping` smallint(5) unsigned NOT NULL DEFAULT '1', + groupingMode tinyint(4) NOT NULL DEFAULT 0 , + comissionValue decimal(10,3) DEFAULT '0.000', + packageValue decimal(10,3) DEFAULT '0.000', + packageFk varchar(10) COLLATE utf8_unicode_ci DEFAULT '--', + price1 decimal(10,2) DEFAULT '0.00', + price2 decimal(10,2) DEFAULT '0.00', + price3 decimal(10,2) DEFAULT '0.00', + minPrice decimal(10,2) DEFAULT '0.00', + producer varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, + INDEX (itemFK)) ENGINE = MEMORY; + + -- Compras + INSERT INTO tmp.inventory(itemFk,quantity) + SELECT b.itemFk, SUM(b.quantity) + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel tr ON tr.id = e.travelFk + WHERE tr.warehouseInFk = vWh + AND tr.landed BETWEEN vDateLastInventory + AND vDateYesterday + AND NOT isRaid + GROUP BY b.itemFk; + SELECT vDateLastInventory , vDateYesterday; + + -- Traslados + INSERT INTO tmp.inventory(itemFk, quantity) + SELECT itemFk, quantityOut + FROM ( + SELECT b.itemFk,- SUM(b.quantity) quantityOut + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel tr ON tr.id = e.travelFk + WHERE tr.warehouseOutFk = vWh + AND tr.shipped BETWEEN vDateLastInventory + AND vDateYesterday + AND NOT isRaid + GROUP BY b.itemFk + ) sub + ON DUPLICATE KEY UPDATE quantity = IFNULL(quantity, 0) + sub.quantityOut; + + -- Ventas + INSERT INTO tmp.inventory(itemFk,quantity) + SELECT itemFk, saleOut + FROM ( + SELECT s.itemFk, - SUM(s.quantity) saleOut + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + WHERE t.warehouseFk = vWh + AND t.shipped BETWEEN vDateLastInventory AND vDateYesterday + GROUP BY s.itemFk + ) sub + ON DUPLICATE KEY UPDATE quantity = IFNULL(quantity,0) + sub.saleOut; + + -- Actualiza valores de la ultima compra + UPDATE tmp.inventory inv + JOIN cache.last_buy lb ON lb.item_id = inv.itemFk AND lb.warehouse_id = vWh + JOIN buy b ON b.id = lb.buy_id + JOIN item i ON i.id = b.itemFk + LEFT JOIN producer p ON p.id = i.producerFk + SET inv.buyingValue = b.buyingValue, + inv.freightValue = b.freightValue, + inv.packing = b.packing, + inv.`grouping`= b.`grouping`, + inv.groupingMode = b.groupingMode, + inv.comissionValue = b.comissionValue, + inv.packageValue = b.packageValue, + inv.packageFk = b.packagingFk, + inv.price1 = b.price1, + inv.price2 = b.price2, + inv.price3 = b.price3, + inv.minPrice = b.minPrice, + inv.producer = p.name; + + INSERT INTO buy( itemFk, + quantity, + buyingValue, + freightValue, + packing, + `grouping`, + groupingMode, + comissionValue, + packageValue, + packagingFk, + price1, + price2, + price3, + minPrice, + entryFk) + SELECT itemFk, + GREATEST(quantity, 0), + buyingValue, + freightValue, + packing, + `grouping`, + groupingMode, + comissionValue, + packageValue, + packagingFk, + price1, + price2, + price3, + minPrice, + vEntryFk + FROM tmp.inventory; + + SELECT vWh, COUNT(*), util.VN_NOW() FROM tmp.inventory; + + -- Actualizamos el campo lastUsed de item + UPDATE item i + JOIN tmp.inventory i2 ON i2.itemFk = i.id + SET i.lastUsed = NOW() + WHERE i2.quantity; + + -- DROP TEMPORARY TABLE tmp.inventory; + + END LOOP; + + CLOSE cWarehouses; + + UPDATE config SET inventoried = vDate; + SET @isModeInventory := FALSE; + + DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete; + CREATE TEMPORARY TABLE tmp.entryToDelete + (INDEX(entryId) USING BTREE) ENGINE = MEMORY + SELECT e.id as entryId, + t.id as travelId + FROM travel t + JOIN `entry` e ON e.travelFk = t.id + WHERE e.supplierFk = vInventorySupplierFk + AND t.shipped <= util.VN_CURDATE() - INTERVAL 12 DAY + AND (DAY(t.shipped) <> 1 OR shipped < util.VN_CURDATE() - INTERVAL 12 DAY); + + DELETE e + FROM `entry` e + JOIN tmp.entryToDelete tmp ON tmp.entryId = e.id; + + DELETE IGNORE t + FROM travel t + JOIN tmp.entryToDelete tmp ON tmp.travelId = t.id; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`inventory_repair`() +BEGIN + + DROP TEMPORARY TABLE IF EXISTS tmp.lastEntry; + CREATE TEMPORARY TABLE tmp.lastEntry + (PRIMARY KEY (buyFk)) + SELECT + i.id AS itemFk, + w.id AS warehouseFk, + w.name AS warehouse, + tr.landed, + b.id AS buyFk, + b.entryFk, + b.isIgnored, + b.price2, + b.price3, + b.stickers, + b.packing, + b.grouping, + b.groupingMode, + b.weight, + i.stems, + b.quantity, + b.buyingValue, + b.packagingFk , + s.id AS supplierFk, + s.name AS supplier + FROM itemType it + RIGHT JOIN (entry e + LEFT JOIN supplier s ON s.id = e.supplierFk + RIGHT JOIN buy b ON b.entryFk = e.id + LEFT JOIN item i ON i.id = b.itemFk + LEFT JOIN ink ON ink.id = i.inkFk + LEFT JOIN travel tr ON tr.id = e.travelFk + LEFT JOIN warehouse w ON w.id = tr.warehouseInFk + LEFT JOIN origin o ON o.id = i.originFk + ) ON it.id = i.typeFk + LEFT JOIN edi.ekt ek ON b.ektFk = ek.id + WHERE (b.packagingFk = "--" OR b.price2 = 0 OR b.packing = 0 OR b.buyingValue = 0) AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-1,util.VN_CURDATE())) AND s.name = 'INVENTARIO'; + + DROP TEMPORARY TABLE IF EXISTS tmp.lastEntryOk; + CREATE TEMPORARY TABLE tmp.lastEntryOk + (PRIMARY KEY (buyFk)) + SELECT + i.id AS itemFk, + w.id AS warehouseFk, + w.name AS warehouse, + tr.landed, + b.id AS buyFk, + b.entryFk, + b.isIgnored, + b.price2, + b.price3, + b.stickers, + b.packing, + b.grouping, + b.groupingMode, + b.weight, + i.stems, + b.quantity, + b.buyingValue, + b.packagingFk, + s.id AS supplierFk, + s.name AS supplier + FROM itemType it + RIGHT JOIN (entry e + LEFT JOIN supplier s ON s.id = e.supplierFk + RIGHT JOIN buy b ON b.entryFk = e.id + LEFT JOIN item i ON i.id = b.itemFk + LEFT JOIN ink ON ink.id = i.inkFk + LEFT JOIN travel tr ON tr.id = e.travelFk + LEFT JOIN warehouse w ON w.id = tr.warehouseInFk + LEFT JOIN origin o ON o.id = i.originFk + ) ON it.id = i.typeFk + LEFT JOIN edi.ekt ek ON b.ektFk = ek.id + WHERE b.packagingFk != "--" AND b.price2 != 0 AND b.packing != 0 AND b.buyingValue > 0 AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-2,util.VN_CURDATE())) + ORDER BY tr.landed DESC; + + DROP TEMPORARY TABLE IF EXISTS tmp.lastEntryOkGroup; + CREATE TEMPORARY TABLE tmp.lastEntryOkGroup + (INDEX (warehouseFk,itemFk)) + SELECT * + FROM tmp.lastEntryOk tmp + GROUP BY tmp.itemFk,tmp.warehouseFk; + + UPDATE buy b + JOIN tmp.lastEntry lt ON lt.buyFk = b.id + JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk + SET b.packagingFk = eo.packagingFk WHERE b.packagingFk = "--"; + + UPDATE buy b + JOIN tmp.lastEntry lt ON lt.buyFk = b.id + JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk + SET b.price2 = eo.price2 WHERE b.price2 = 0 ; + + UPDATE buy b + JOIN tmp.lastEntry lt ON lt.buyFk = b.id + JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk + SET b.packing = eo.packing WHERE b.packing = 0; + + UPDATE buy b + JOIN tmp.lastEntry lt ON lt.buyFk = b.id + JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk + SET b.buyingValue = eo.buyingValue WHERE b.buyingValue = 0; + + DROP TEMPORARY TABLE tmp.lastEntry; + DROP TEMPORARY TABLE tmp.lastEntryOk; + DROP TEMPORARY TABLE tmp.lastEntryOkGroup; +END$$ +DELIMITER ; \ No newline at end of file diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 36400b0d74..bd5bed897b 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1456,7 +1456,7 @@ INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeF ('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Miscellaneous Accessories', 6, 1, '186', '0', '0.0'), ('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Adhesives', 7, 1, '277', '0', '0.0'); -INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`, `printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`) +INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packagingFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`, `printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`) VALUES (1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)), (2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)), diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 1b18eb8668..5c0caffe42 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -1193,7 +1193,7 @@ export default { secondBuyPacking: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.packing"]', secondBuyWeight: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.weight"]', secondBuyStickers: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.stickers"]', - secondBuyPackage: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-autocomplete[ng-model="buy.packageFk"]', + secondBuyPackage: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-autocomplete[ng-model="buy.packagingFk"]', secondBuyQuantity: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.quantity"]', secondBuyItem: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-autocomplete[ng-model="buy.itemFk"]', importButton: 'vn-entry-buy-index vn-icon[icon="publish"]', diff --git a/e2e/paths/13-supplier/03_fiscal_data.spec.js b/e2e/paths/13-supplier/03_fiscal_data.spec.js index 891b769c92..96977e7085 100644 --- a/e2e/paths/13-supplier/03_fiscal_data.spec.js +++ b/e2e/paths/13-supplier/03_fiscal_data.spec.js @@ -1,20 +1,5 @@ import getBrowser from '../../helpers/puppeteer'; -const $ = { - saveButton: 'vn-supplier-fiscal-data button[type="submit"]', -}; -const $inputs = { - province: 'vn-supplier-fiscal-data [name="province"]', - country: 'vn-supplier-fiscal-data [name="country"]', - postcode: 'vn-supplier-fiscal-data [name="postcode"]', - city: 'vn-supplier-fiscal-data [name="city"]', - socialName: 'vn-supplier-fiscal-data [name="socialName"]', - taxNumber: 'vn-supplier-fiscal-data [name="taxNumber"]', - account: 'vn-supplier-fiscal-data [name="account"]', - sageWithholding: 'vn-supplier-fiscal-data [ng-model="$ctrl.supplier.sageWithholdingFk"]', - sageTaxType: 'vn-supplier-fiscal-data [ng-model="$ctrl.supplier.sageTaxTypeFk"]' -}; - describe('Supplier fiscal data path', () => { let browser; let page; @@ -30,7 +15,7 @@ describe('Supplier fiscal data path', () => { await browser.close(); }); - it('should attempt to edit the fiscal data and check data is saved', async() => { + it('should attempt to edit the fiscal data and check data iss saved', async() => { await page.accessToSection('supplier.card.fiscalData'); const form = 'vn-supplier-fiscal-data form'; @@ -40,16 +25,16 @@ describe('Supplier fiscal data path', () => { postcode: null, city: 'Valencia', socialName: 'Farmer King SL', - taxNumber: 'Wrong tax number', + taxNumber: '12345678Z', account: '0123456789', sageWithholding: 'retencion estimacion objetiva', sageTaxType: 'operaciones no sujetas' }; - const errorMessage = await page.sendForm(form, values); - const message = await page.sendForm(form, { - taxNumber: '12345678Z' + const errorMessage = await page.sendForm(form, { + taxNumber: 'Wrong tax number' }); + const message = await page.sendForm(form, values); await page.reloadSection('supplier.card.fiscalData'); const formValues = await page.fetchForm(form, Object.keys(values)); diff --git a/modules/entry/back/locale/buy/en.yml b/modules/entry/back/locale/buy/en.yml index 2db7c7be5b..949aa8ed03 100644 --- a/modules/entry/back/locale/buy/en.yml +++ b/modules/entry/back/locale/buy/en.yml @@ -15,4 +15,4 @@ columns: weight: weight entryFk: entry itemFk: item - packageFk: package + packagingFk: package diff --git a/modules/entry/back/locale/buy/es.yml b/modules/entry/back/locale/buy/es.yml index 666bf7640c..2aa7688eb5 100644 --- a/modules/entry/back/locale/buy/es.yml +++ b/modules/entry/back/locale/buy/es.yml @@ -15,4 +15,4 @@ columns: weight: peso entryFk: entrada itemFk: artículo - packageFk: paquete + packagingFk: paquete diff --git a/modules/entry/back/methods/entry/addFromBuy.js b/modules/entry/back/methods/entry/addFromBuy.js index 82645b1669..307c04b97e 100644 --- a/modules/entry/back/methods/entry/addFromBuy.js +++ b/modules/entry/back/methods/entry/addFromBuy.js @@ -80,7 +80,7 @@ module.exports = Self => { comissionValue: buyUltimate.comissionValue, packageValue: buyUltimate.packageValue, location: buyUltimate.location, - packageFk: buyUltimate.packageFk, + packagingFk: buyUltimate.packagingFk, price1: buyUltimate.price1, price2: buyUltimate.price2, price3: buyUltimate.price3, diff --git a/modules/entry/back/methods/entry/getBuys.js b/modules/entry/back/methods/entry/getBuys.js index ebb271df1a..90c1bb9d0d 100644 --- a/modules/entry/back/methods/entry/getBuys.js +++ b/modules/entry/back/methods/entry/getBuys.js @@ -44,7 +44,7 @@ module.exports = Self => { 'grouping', 'groupingMode', 'quantity', - 'packageFk', + 'packagingFk', 'weight', 'buyingValue', 'price2', diff --git a/modules/entry/back/methods/entry/importBuys.js b/modules/entry/back/methods/entry/importBuys.js index 1e6f01a5ed..812775a1be 100644 --- a/modules/entry/back/methods/entry/importBuys.js +++ b/modules/entry/back/methods/entry/importBuys.js @@ -108,7 +108,7 @@ module.exports = Self => { packing: buy.packing, grouping: buy.grouping, buyingValue: buy.buyingValue, - packageFk: buy.packageFk, + packagingFk: buy.packagingFk, groupingMode: lastBuy.groupingMode, weight: lastBuy.weight }); diff --git a/modules/entry/back/methods/entry/importBuysPreview.js b/modules/entry/back/methods/entry/importBuysPreview.js index 730ecab0ad..de8fa732d2 100644 --- a/modules/entry/back/methods/entry/importBuysPreview.js +++ b/modules/entry/back/methods/entry/importBuysPreview.js @@ -39,7 +39,7 @@ module.exports = Self => { }, myOptions); if (packaging) - buy.packageFk = packaging.id; + buy.packagingFk = packaging.id; const reference = await models.ItemMatchProperties.findOne({ fields: ['itemFk'], diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js index 30d47a2a39..dbf7d2b17c 100644 --- a/modules/entry/back/methods/entry/latestBuysFilter.js +++ b/modules/entry/back/methods/entry/latestBuysFilter.js @@ -153,64 +153,63 @@ module.exports = Self => { const date = Date.vnNew(); date.setHours(0, 0, 0, 0); stmt = new ParameterizedSQL(` - SELECT - i.image, - i.id AS itemFk, - i.size, - i.weightByPiece, - it.code, - i.typeFk, - i.family, - i.isActive, - i.minPrice, - i.description, - i.name, - i.subName, - i.packingOut, - i.tag5, - i.value5, - i.tag6, - i.value6, - i.tag7, - i.value7, - i.tag8, - i.value8, - i.tag9, - i.value9, - i.tag10, - i.value10, - t.name AS type, - intr.description AS intrastat, - ori.code AS origin, - b.entryFk, - b.id, - b.quantity, - b.buyingValue, - b.freightValue, - b.isIgnored, - b.packing, - b.grouping, - b.groupingMode, - b.comissionValue, - b.packageValue, - b.price2, - b.price3, - b.ektFk, - b.weight, - b.packageFk, - lb.landing - FROM cache.last_buy lb - LEFT JOIN cache.visible v ON v.item_id = lb.item_id - AND v.calc_id = @calc_id - JOIN item i ON i.id = lb.item_id - JOIN itemType it ON it.id = i.typeFk AND lb.warehouse_id = ? - JOIN buy b ON b.id = lb.buy_id - LEFT JOIN itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN itemType t ON t.id = i.typeFk - LEFT JOIN intrastat intr ON intr.id = i.intrastatFk - LEFT JOIN origin ori ON ori.id = i.originFk - LEFT JOIN entry e ON e.id = b.entryFk AND e.created >= DATE_SUB(? ,INTERVAL 1 YEAR) - LEFT JOIN supplier s ON s.id = e.supplierFk` + SELECT i.image, + i.id AS itemFk, + i.size, + i.weightByPiece, + it.code, + i.typeFk, + i.family, + i.isActive, + i.minPrice, + i.description, + i.name, + i.subName, + i.packingOut, + i.tag5, + i.value5, + i.tag6, + i.value6, + i.tag7, + i.value7, + i.tag8, + i.value8, + i.tag9, + i.value9, + i.tag10, + i.value10, + t.name AS type, + intr.description AS intrastat, + ori.code AS origin, + b.entryFk, + b.id, + b.quantity, + b.buyingValue, + b.freightValue, + b.isIgnored, + b.packing, + b.grouping, + b.groupingMode, + b.comissionValue, + b.packageValue, + b.price2, + b.price3, + b.ektFk, + b.weight, + b.packagingFk, + lb.landing + FROM cache.last_buy lb + LEFT JOIN cache.visible v ON v.item_id = lb.item_id + AND v.calc_id = @calc_id + JOIN item i ON i.id = lb.item_id + JOIN itemType it ON it.id = i.typeFk AND lb.warehouse_id = ? + JOIN buy b ON b.id = lb.buy_id + LEFT JOIN itemCategory ic ON ic.id = it.categoryFk + LEFT JOIN itemType t ON t.id = i.typeFk + LEFT JOIN intrastat intr ON intr.id = i.intrastatFk + LEFT JOIN origin ori ON ori.id = i.originFk + LEFT JOIN entry e ON e.id = b.entryFk AND e.created >= DATE_SUB(? ,INTERVAL 1 YEAR) + LEFT JOIN supplier s ON s.id = e.supplierFk` , [userConfig.warehouseFk, date]); if (ctx.args.tags) { diff --git a/modules/entry/back/methods/entry/specs/importBuys.spec.js b/modules/entry/back/methods/entry/specs/importBuys.spec.js index 4f9204c6a3..a352294b97 100644 --- a/modules/entry/back/methods/entry/specs/importBuys.spec.js +++ b/modules/entry/back/methods/entry/specs/importBuys.spec.js @@ -33,7 +33,7 @@ describe('entry import()', () => { packing: 1, size: 1, volume: 1200, - packageFk: '94' + packagingFk: '94' }, { itemFk: 4, @@ -43,7 +43,7 @@ describe('entry import()', () => { packing: 1, size: 25, volume: 1125, - packageFk: '94' + packagingFk: '94' } ] } diff --git a/modules/entry/back/methods/entry/specs/importBuysPreview.spec.js b/modules/entry/back/methods/entry/specs/importBuysPreview.spec.js index 41971a64c0..c860e228e0 100644 --- a/modules/entry/back/methods/entry/specs/importBuysPreview.spec.js +++ b/modules/entry/back/methods/entry/specs/importBuysPreview.spec.js @@ -10,12 +10,12 @@ describe('entry importBuysPreview()', () => { }); }); - it('should return the buys with the calculated packageFk', async() => { + it('should return the buys with the calculated packagingFk', async() => { const tx = await models.Entry.beginTransaction({}); const options = {transaction: tx}; try { - const expectedPackageFk = '3'; + const expectedPackagingFk = '3'; const buys = [ { itemFk: 1, @@ -39,7 +39,7 @@ describe('entry importBuysPreview()', () => { const randomIndex = Math.floor(Math.random() * result.length); const buy = result[randomIndex]; - expect(buy.packageFk).toEqual(expectedPackageFk); + expect(buy.packagingFk).toEqual(expectedPackagingFk); await tx.rollback(); } catch (e) { diff --git a/modules/entry/back/models/buy.json b/modules/entry/back/models/buy.json index af205533fe..30379eaf68 100644 --- a/modules/entry/back/models/buy.json +++ b/modules/entry/back/models/buy.json @@ -103,7 +103,7 @@ "package": { "type": "belongsTo", "model": "Packaging", - "foreignKey": "packageFk" + "foreignKey": "packagingFk" }, "worker": { "type": "belongsTo", diff --git a/modules/entry/front/buy/import/index.html b/modules/entry/front/buy/import/index.html index ccb1a5dacd..28396434c2 100644 --- a/modules/entry/front/buy/import/index.html +++ b/modules/entry/front/buy/import/index.html @@ -83,14 +83,14 @@ {{::buy.packing | dashIfEmpty}} {{::buy.grouping | dashIfEmpty}} {{::buy.buyingValue | currency: 'EUR':2}} - + + ng-model="buy.packagingFk"> diff --git a/modules/entry/front/buy/index/index.html b/modules/entry/front/buy/index/index.html index 28fdabdb4c..203d6c522d 100644 --- a/modules/entry/front/buy/index/index.html +++ b/modules/entry/front/buy/index/index.html @@ -88,12 +88,12 @@ diff --git a/modules/entry/front/buy/index/index.js b/modules/entry/front/buy/index/index.js index 649e692866..c991b745b9 100644 --- a/modules/entry/front/buy/index/index.js +++ b/modules/entry/front/buy/index/index.js @@ -4,7 +4,7 @@ import Section from 'salix/components/section'; export default class Controller extends Section { saveBuy(buy) { - const missingData = !buy.itemFk || !buy.quantity || !buy.packageFk; + const missingData = !buy.itemFk || !buy.quantity || !buy.packagingFk; if (missingData) return; let options; diff --git a/modules/entry/front/buy/index/index.spec.js b/modules/entry/front/buy/index/index.spec.js index 0e221302cc..b9d5fab513 100644 --- a/modules/entry/front/buy/index/index.spec.js +++ b/modules/entry/front/buy/index/index.spec.js @@ -17,7 +17,7 @@ describe('Entry buy', () => { describe('saveBuy()', () => { it(`should call the buys patch route if the received buy has an ID`, () => { - const buy = {id: 1, itemFk: 1, quantity: 1, packageFk: 1}; + const buy = {id: 1, itemFk: 1, quantity: 1, packagingFk: 1}; const query = `Buys/${buy.id}`; diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html index a2cf62da26..16e039cf0a 100644 --- a/modules/entry/front/latest-buys/index.html +++ b/modules/entry/front/latest-buys/index.html @@ -104,7 +104,7 @@ Weight - + Package @@ -207,7 +207,7 @@ {{::buy.minPrice | currency: 'EUR':3}} {{::buy.ektFk | dashIfEmpty}} {{::buy.weight}} - {{::buy.packageFk}} + {{::buy.packagingFk}} {{::buy.packingOut}} {{::buy.landing | date: 'dd/MM/yyyy'}} diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js index d9065193ea..292c5b8051 100644 --- a/modules/entry/front/latest-buys/index.js +++ b/modules/entry/front/latest-buys/index.js @@ -48,7 +48,7 @@ export default class Controller extends Section { } }, { - field: 'packageFk', + field: 'packagingFk', autocomplete: { url: 'Packagings', showField: 'id' @@ -133,7 +133,7 @@ export default class Controller extends Section { case 'price3': case 'ektFk': case 'weight': - case 'packageFk': + case 'packagingFk': return {[`b.${param}`]: value}; } } diff --git a/modules/entry/front/summary/index.html b/modules/entry/front/summary/index.html index d5d3ebf1e1..655dcd66f6 100644 --- a/modules/entry/front/summary/index.html +++ b/modules/entry/front/summary/index.html @@ -105,7 +105,7 @@ Quantity Stickers - Package + Package Weight Packing Grouping @@ -118,7 +118,7 @@ {{::line.quantity}} {{::line.stickers | dashIfEmpty}} - {{::line.packageFk | dashIfEmpty}} + {{::line.packagingFk | dashIfEmpty}} {{::line.weight}} diff --git a/modules/item/back/methods/item/lastEntriesFilter.js b/modules/item/back/methods/item/lastEntriesFilter.js index 83a8fe7a28..5aafbb4f65 100644 --- a/modules/item/back/methods/item/lastEntriesFilter.js +++ b/modules/item/back/methods/item/lastEntriesFilter.js @@ -29,44 +29,44 @@ module.exports = Self => { Object.assign(myOptions, options); const stmt = new ParameterizedSQL( - `SELECT - w.id AS warehouseFk, - w.name AS warehouse, - tr.landed, - b.id AS buyFk, - b.entryFk, - b.isIgnored, - b.price2, - b.price3, - b.stickers, - b.packing, - b.grouping, - b.groupingMode, - b.weight, - i.stems, - b.quantity, - b.buyingValue + - b.freightValue + - b.comissionValue + - b.packageValue AS cost, - b.buyingValue, - b.freightValue, - b.comissionValue, - b.packageValue, - b.packageFk , - s.id AS supplierFk, - s.name AS supplier - FROM itemType it - RIGHT JOIN (entry e - LEFT JOIN supplier s ON s.id = e.supplierFk - RIGHT JOIN buy b ON b.entryFk = e.id - LEFT JOIN item i ON i.id = b.itemFk - LEFT JOIN ink ON ink.id = i.inkFk - LEFT JOIN travel tr ON tr.id = e.travelFk - LEFT JOIN warehouse w ON w.id = tr.warehouseInFk - LEFT JOIN origin o ON o.id = i.originFk - ) ON it.id = i.typeFk - LEFT JOIN edi.ekt ek ON b.ektFk = ek.id`); + `SELECT w.id AS warehouseFk, + w.name AS warehouse, + tr.landed, + b.id AS buyFk, + b.entryFk, + b.isIgnored, + b.price2, + b.price3, + b.stickers, + b.packing, + b.grouping, + b.groupingMode, + b.weight, + i.stems, + b.quantity, + b.buyingValue + + b.freightValue + + b.comissionValue + + b.packageValue AS cost, + b.buyingValue, + b.freightValue, + b.comissionValue, + b.packageValue, + b.packagingFk , + s.id AS supplierFk, + s.name AS supplier + FROM itemType it + RIGHT JOIN (entry e + LEFT JOIN supplier s ON s.id = e.supplierFk + RIGHT JOIN buy b ON b.entryFk = e.id + LEFT JOIN item i ON i.id = b.itemFk + LEFT JOIN ink ON ink.id = i.inkFk + LEFT JOIN travel tr ON tr.id = e.travelFk + LEFT JOIN warehouse w ON w.id = tr.warehouseInFk + LEFT JOIN origin o ON o.id = i.originFk + ) ON it.id = i.typeFk + LEFT JOIN edi.ekt ek ON b.ektFk = ek.id` + ); stmt.merge(conn.makeSuffix(filter)); return conn.executeStmt(stmt, myOptions); diff --git a/modules/item/front/last-entries/index.html b/modules/item/front/last-entries/index.html index 609cdb7fa3..429955ef58 100644 --- a/modules/item/front/last-entries/index.html +++ b/modules/item/front/last-entries/index.html @@ -45,7 +45,7 @@ Quantity Cost Kg. - Cube + Cube Provider @@ -94,7 +94,7 @@ {{::entry.weight | dashIfEmpty}} - {{::entry.packageFk | dashIfEmpty}} + {{::entry.packagingFk | dashIfEmpty}} {{::entry.supplier | dashIfEmpty}} diff --git a/modules/item/front/last-entries/index.js b/modules/item/front/last-entries/index.js index 0c68048388..31616f8a7e 100644 --- a/modules/item/front/last-entries/index.js +++ b/modules/item/front/last-entries/index.js @@ -71,7 +71,7 @@ class Controller extends Section { switch (param) { case 'id': case 'quantity': - case 'packageFk': + case 'packagingFk': return {[`b.${param}`]: value}; case 'supplierFk': return {[`s.id`]: value}; diff --git a/modules/travel/back/methods/travel/extraCommunityFilter.js b/modules/travel/back/methods/travel/extraCommunityFilter.js index 388ba52a18..4882973181 100644 --- a/modules/travel/back/methods/travel/extraCommunityFilter.js +++ b/modules/travel/back/methods/travel/extraCommunityFilter.js @@ -132,12 +132,18 @@ module.exports = Self => { s.nickname AS cargoSupplierNickname, s.name AS supplierName, CAST(SUM(b.weight * b.stickers) as DECIMAL(10,0)) as loadedKg, - CAST(SUM(vc.aerealVolumetricDensity * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000) as DECIMAL(10,0)) as volumeKg + CAST( + SUM( + vc.aerealVolumetricDensity * + b.stickers * + IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 + ) as DECIMAL(10,0) + ) as volumeKg FROM travel t LEFT JOIN supplier s ON s.id = t.cargoSupplierFk LEFT JOIN entry e ON e.travelFk = t.id LEFT JOIN buy b ON b.entryFk = e.id - LEFT JOIN packaging pkg ON pkg.id = b.packageFk + LEFT JOIN packaging pkg ON pkg.id = b.packagingFk LEFT JOIN item i ON i.id = b.itemFk LEFT JOIN itemType it ON it.id = i.typeFk JOIN warehouse w ON w.id = t.warehouseInFk @@ -169,11 +175,17 @@ module.exports = Self => { e.evaNotes, e.invoiceAmount, CAST(SUM(b.weight * b.stickers) AS DECIMAL(10,0)) as loadedkg, - CAST(SUM(vc.aerealVolumetricDensity * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000) AS DECIMAL(10,0)) as volumeKg + CAST( + SUM( + vc.aerealVolumetricDensity * + b.stickers * + IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 + ) AS DECIMAL(10,0) + ) as volumeKg FROM tmp.travel tr JOIN entry e ON e.travelFk = tr.id JOIN buy b ON b.entryFk = e.id - JOIN packaging pkg ON pkg.id = b.packageFk + JOIN packaging pkg ON pkg.id = b.packagingFk JOIN item i ON i.id = b.itemFk JOIN itemType it ON it.id = i.typeFk JOIN supplier s ON s.id = e.supplierFk diff --git a/modules/travel/back/methods/travel/getEntries.js b/modules/travel/back/methods/travel/getEntries.js index 71bb0d8fb3..50088ccfaf 100644 --- a/modules/travel/back/methods/travel/getEntries.js +++ b/modules/travel/back/methods/travel/getEntries.js @@ -47,7 +47,7 @@ module.exports = Self => { LEFT JOIN vn.buy b ON b.entryFk = e.id LEFT JOIN vn.supplier s ON e.supplierFk = s.id JOIN vn.item i ON i.id = b.itemFk - LEFT JOIN vn.packaging p ON p.id = b.packageFk + LEFT JOIN vn.packaging p ON p.id = b.packagingFk JOIN vn.packaging pcc ON pcc.id = 'cc' JOIN vn.packaging ppallet ON ppallet.id = 'pallet 100' JOIN vn.packagingConfig pconfig From 731bad59818e3d1e8adb3cef2238561ccaa8400f Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 22 Sep 2023 14:52:56 +0200 Subject: [PATCH 038/449] ref #5914 create ticket with new and refactor --- .../00-transferInvoiceACL.sql | 8 +-- loopback/locale/en.json | 2 +- loopback/locale/es.json | 34 +++++----- .../methods/invoiceOut/transferInvoice.js | 13 ++-- modules/invoiceOut/back/models/invoice-out.js | 1 - .../front/descriptor-menu/style.scss | 2 +- modules/ticket/back/methods/sale/clone.js | 67 ++++++------------- modules/ticket/back/methods/sale/refund.js | 3 +- .../methods/ticket/invoiceTicketsWithPdf.js | 0 modules/ticket/back/models/ticket.json | 5 -- 10 files changed, 51 insertions(+), 84 deletions(-) rename db/changes/{233601 => 234001}/00-transferInvoiceACL.sql (67%) delete mode 100644 modules/ticket/back/methods/ticket/invoiceTicketsWithPdf.js diff --git a/db/changes/233601/00-transferInvoiceACL.sql b/db/changes/234001/00-transferInvoiceACL.sql similarity index 67% rename from db/changes/233601/00-transferInvoiceACL.sql rename to db/changes/234001/00-transferInvoiceACL.sql index a45e3f4791..2bf4ec6888 100644 --- a/db/changes/233601/00-transferInvoiceACL.sql +++ b/db/changes/234001/00-transferInvoiceACL.sql @@ -1,6 +1,6 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) VALUES - ('CplusRectificationType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('CplusInvoiceType477', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('InvoiceCorrectionType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('InvoiceOut', 'transferInvoice', 'WRITE', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file + ('CplusRectificationType', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('CplusInvoiceType477', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('InvoiceCorrectionType', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('InvoiceOut', 'transferInvoice', 'WRITE', 'ALLOW', 'ROLE', 'administrative'); \ No newline at end of file diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 3755c4a67e..95e5ebc1cc 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -188,7 +188,7 @@ "The ticket doesn't exist.": "The ticket doesn't exist.", "The sales do not exists": "The sales do not exists", "Ticket without Route": "Ticket without route", - "Select a different customer": "Select a different customer", + "Select a different client": "Select a different client", "Fill all the fields": "Fill all the fields", "Error while generating PDF": "Error while generating PDF", "Can't invoice to future": "Can't invoice to future", diff --git a/loopback/locale/es.json b/loopback/locale/es.json index f5973dcb70..18f51d7f8e 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -5,10 +5,10 @@ "The default consignee can not be unchecked": "No se puede desmarcar el consignatario predeterminado", "Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado", "Can't be blank": "No puede estar en blanco", - "Invalid TIN": "NIF/CIF invalido", + "Invalid TIN": "NIF/CIF inválido", "TIN must be unique": "El NIF/CIF debe ser único", "A client with that Web User name already exists": "Ya existe un cliente con ese Usuario Web", - "Is invalid": "Is invalid", + "Is invalid": "Es inválido", "Quantity cannot be zero": "La cantidad no puede ser cero", "Enter an integer different to zero": "Introduce un entero distinto de cero", "Package cannot be blank": "El embalaje no puede estar en blanco", @@ -55,8 +55,8 @@ "You must delete the claim id %d first": "Antes debes borrar la reclamación %d", "You don't have enough privileges": "No tienes suficientes permisos", "Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF", - "You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos basicos de una orden con artículos", - "INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no esta permitido el uso de la letra ñ", + "You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos básicos de una orden con artículos", + "INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no está permitido el uso de la letra ñ", "You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado", "You can't create a ticket for a inactive client": "No puedes crear un ticket para un cliente inactivo", "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", @@ -65,7 +65,7 @@ "NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT", "Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido", "Street cannot be empty": "Dirección no puede estar en blanco", - "City cannot be empty": "Cuidad no puede estar en blanco", + "City cannot be empty": "Ciudad no puede estar en blanco", "Code cannot be blank": "Código no puede estar en blanco", "You cannot remove this department": "No puedes eliminar este departamento", "The extension must be unique": "La extensión debe ser unica", @@ -102,8 +102,8 @@ "You can't delete a confirmed order": "No puedes borrar un pedido confirmado", "The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto", "Invalid quantity": "Cantidad invalida", - "This postal code is not valid": "This postal code is not valid", - "is invalid": "is invalid", + "This postal code is not valid": "Este código postal no es válido", + "is invalid": "es inválido", "The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto", "The department name can't be repeated": "El nombre del departamento no puede repetirse", "This phone already exists": "Este teléfono ya existe", @@ -112,8 +112,8 @@ "You cannot delete a ticket that part of it is being prepared": "No puedes eliminar un ticket en el que una parte que está siendo preparada", "You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero", "You should specify a date": "Debes especificar una fecha", - "You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín", - "Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín", + "You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fin", + "Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fin", "You should mark at least one week day": "Debes marcar al menos un día de la semana", "Swift / BIC can't be empty": "Swift / BIC no puede estar vacío", "Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios", @@ -144,15 +144,15 @@ "Unable to clone this travel": "No ha sido posible clonar este travel", "This thermograph id already exists": "La id del termógrafo ya existe", "Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante", - "ORDER_ALREADY_CONFIRMED": "ORDER_ALREADY_CONFIRMED", + "ORDER_ALREADY_CONFIRMED": "ORDEN YA CONFIRMADA", "Invalid password": "Invalid password", "Password does not meet requirements": "La contraseña no cumple los requisitos", - "Role already assigned": "Role already assigned", - "Invalid role name": "Invalid role name", - "Role name must be written in camelCase": "Role name must be written in camelCase", - "Email already exists": "Email already exists", - "User already exists": "User already exists", - "Absence change notification on the labour calendar": "Notificacion de cambio de ausencia en el calendario laboral", + "Role already assigned": "Rol ya asignado", + "Invalid role name": "Nombre de rol no válido", + "Role name must be written in camelCase": "El nombre del rol debe escribirse en camelCase", + "Email already exists": "El correo ya existe", + "User already exists": "El/La usuario/a ya existe", + "Absence change notification on the labour calendar": "Notificación de cambio de ausencia en el calendario laboral", "Record of hours week": "Registro de horas semana {{week}} año {{year}} ", "Created absence": "El empleado {{author}} ha añadido una ausencia de tipo '{{absenceType}}' a {{employee}} para el día {{dated}}.", "Deleted absence": "El empleado {{author}} ha eliminado una ausencia de tipo '{{absenceType}}' a {{employee}} del día {{dated}}.", @@ -317,6 +317,6 @@ "Social name should be uppercase": "La razón social debe ir en mayúscula", "Street should be uppercase": "La dirección fiscal debe ir en mayúscula", "Ticket without Route": "Ticket sin ruta", - "Select a different customer": "Seleccione un cliente distinto", + "Select a different client": "Seleccione un cliente distinto", "Fill all the fields": "Rellene todos los campos" } \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js index 65b671716a..c4f6e9445d 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js @@ -19,18 +19,22 @@ module.exports = Self => { { arg: 'newClientFk', type: 'number', + required: true }, { arg: 'cplusRectificationId', type: 'number', + required: true }, { arg: 'cplusInvoiceType477Id', type: 'number', + required: true }, { arg: 'invoiceCorrectionTypeId', type: 'number', + required: true }, ], returns: { @@ -54,10 +58,7 @@ module.exports = Self => { const {clientFk} = await models.InvoiceOut.findById(args.id); if (clientFk == args.newClientFk) - throw new UserError(`Select a different customer`); - - if (!args.newClientFk || !args.cplusRectificationId || !args.cplusInvoiceType477Id || !args.invoiceCorrectionTypeId) - throw new UserError(`Fill all the fields`); + throw new UserError(`Select a different client`); if (!myOptions.transaction) { tx = await Self.beginTransaction({}); @@ -77,7 +78,7 @@ module.exports = Self => { const sales = await models.Sale.find(filterTicket, myOptions); const salesIds = sales.map(sale => sale.id); - const clonedTickets = await models.Sale.clone(salesIds, servicesIds, null, false, false, myOptions); + const clonedTickets = await models.Sale.clone(ctx, salesIds, servicesIds, null, false, false, myOptions); const clonedTicketIds = []; for (const clonedTicket of clonedTickets) { @@ -93,7 +94,7 @@ module.exports = Self => { correctedFk: args.id, cplusRectificationTypeFk: args.cplusRectificationId, cplusInvoiceType477Fk: args.cplusInvoiceType477Id, - invoiceCorrectionType: args.invoiceCorrectionTypeId + invoiceCorrectionTypeFk: args.invoiceCorrectionTypeId }, myOptions); if (tx) await tx.commit(); diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js index 34b4dc7980..ca77c856f6 100644 --- a/modules/invoiceOut/back/models/invoice-out.js +++ b/modules/invoiceOut/back/models/invoice-out.js @@ -44,7 +44,6 @@ module.exports = Self => { Self.makePdf = async function(id, options) { const fields = ['id', 'hasPdf', 'ref']; const invoiceOut = await Self.findById(id, {fields}, options); - console.log('Recoge invoiceOut?'); const invoiceReport = new print.Report('invoice', { reference: invoiceOut.ref }); diff --git a/modules/invoiceOut/front/descriptor-menu/style.scss b/modules/invoiceOut/front/descriptor-menu/style.scss index 25c02c80c1..9e4cf42973 100644 --- a/modules/invoiceOut/front/descriptor-menu/style.scss +++ b/modules/invoiceOut/front/descriptor-menu/style.scss @@ -25,6 +25,6 @@ vn-invoice-out-descriptor-menu { } @media screen and (min-width: 1000px) { .transferInvoice { - min-width: 900px; + min-width: $width-md; } } diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index d899b3c449..7ce7675da1 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.clone = async(salesIds, servicesIds, withWarehouse, group, negative, options) => { + Self.clone = async(ctx, salesIds, servicesIds, withWarehouse, group, negative, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -23,32 +23,24 @@ module.exports = Self => { } }; const sales = await models.Sale.find(salesFilter, myOptions); - const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; + let ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; const refundTickets = []; const mappedTickets = new Map(); const now = Date.vnNew(); - const [firstTicketId] = ticketsIds; - if (group) { + + if (group) ticketsIds = [ticketsIds[0]]; + + for (let ticketId in ticketsIds) { await createTicketRefund( - firstTicketId, + ctx, + ticketsIds[ticketId], withWarehouse, refundTickets, - mappedTickets, now, myOptions ); - } else { - for (let ticketId of ticketsIds) { - await createTicketRefund( - ticketId, - withWarehouse, - refundTickets, - mappedTickets, - now, - myOptions - ); - } + mappedTickets.set(ticketsIds[ticketId], refundTickets[ticketId].id); } for (const sale of sales) { @@ -100,47 +92,26 @@ module.exports = Self => { }; async function createTicketRefund( + ctx, ticketId, withWarehouse, refundTickets, - mappedTickets, now, myOptions ) { const models = Self.app.models; - const filter = { - include: [ - { - relation: 'address' - }, - { - relation: 'agencyMode' - }, - { - relation: 'zone' - } - ] - }; - const ticket = await models.Ticket.findById(ticketId, filter, myOptions); - const refundTicket = await models.Ticket.create({ - clientFk: ticket.clientFk, - shipped: now, - addressFk: ticket.address().id, - agencyModeFk: ticket.agencyMode().id, - nickname: ticket.address().nickname, - warehouseFk: withWarehouse ? ticket.warehouseFk : null, - companyFk: ticket.companyFk, - zonePrice: ticket.zonePrice, - zoneBonus: ticket.zoneBonus, - weight: ticket.weight, - landed: now, - zoneFk: ticket.zone().id, - }, myOptions); + const ticket = await models.Ticket.findById(ticketId, myOptions); + ctx.args.clientId = ticket.clientFk; + ctx.args.shipped = now; + ctx.args.landed = now; + ctx.args.warehouseId = withWarehouse ? ticket.warehouseFk : null; + ctx.args.companyId = ticket.companyFk; + ctx.args.addressId = ticket.addressFk; + + const refundTicket = await models.Ticket.new(ctx, myOptions); refundTickets.push(refundTicket); - - mappedTickets.set(ticketId, refundTicket.id); } async function getTicketRefundId(group, ticketId, refundTickets, mappedTickets) { diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 5d8297a4e0..17b70f12bd 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -43,10 +43,11 @@ module.exports = Self => { try { const refundsTicket = await models.Sale.clone( + ctx, salesIds, servicesIds, withWarehouse, - true, + false, true, myOptions ); diff --git a/modules/ticket/back/methods/ticket/invoiceTicketsWithPdf.js b/modules/ticket/back/methods/ticket/invoiceTicketsWithPdf.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/modules/ticket/back/models/ticket.json b/modules/ticket/back/models/ticket.json index 1c5610a2a1..ec4193bed7 100644 --- a/modules/ticket/back/models/ticket.json +++ b/modules/ticket/back/models/ticket.json @@ -136,11 +136,6 @@ "type": "belongsTo", "model": "Zone", "foreignKey": "zoneFk" - }, - "sale": { - "type": "hasMany", - "model": "Sale", - "foreignKey": "ticketFk" } } } From 6cf1095b100fca4169ac71a4debd9cfdb644ded4 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 25 Sep 2023 08:33:16 +0200 Subject: [PATCH 039/449] refs #6067 feat: vnUser use verify() and more security when update user and mailForward --- back/methods/vn-user/update-user.js | 41 ++++++++++++++++++ back/models/specs/vn-user.spec.js | 38 ++++++++++++++++ back/models/vn-user.js | 43 +++++++++---------- back/models/vn-user.json | 17 +++----- db/changes/234001/00-account_acl.sql | 13 ++---- modules/account/back/models/mail-forward.js | 4 -- modules/account/back/models/mail-forward.json | 16 +------ modules/account/front/basic-data/index.html | 6 +-- modules/account/front/basic-data/index.js | 10 ++--- modules/account/front/routes.json | 5 ++- 10 files changed, 120 insertions(+), 73 deletions(-) create mode 100644 back/methods/vn-user/update-user.js diff --git a/back/methods/vn-user/update-user.js b/back/methods/vn-user/update-user.js new file mode 100644 index 0000000000..85f6df7620 --- /dev/null +++ b/back/methods/vn-user/update-user.js @@ -0,0 +1,41 @@ +module.exports = Self => { + Self.remoteMethodCtx('updateUser', { + description: 'Update user data', + accepts: [ + { + arg: 'id', + type: 'integer', + description: 'The user id', + required: true, + http: {source: 'path'} + }, { + arg: 'name', + type: 'string', + description: 'The user name', + }, { + arg: 'nickname', + type: 'string', + description: 'The user nickname', + }, { + arg: 'email', + type: 'string', + description: 'The user email' + }, { + arg: 'lang', + type: 'string', + description: 'The user lang' + } + ], + http: { + path: `/:id/update-user`, + verb: 'PATCH' + } + }); + + Self.updateUser = async(ctx, id) => { + await Self.userSecurity(ctx, id); + const user = await Self.app.models.VnUser.findById(id, + {fields: ['id', 'name', 'nickname', 'email', 'lang', 'password']}); + await user.updateAttributes(ctx.args); + }; +}; diff --git a/back/models/specs/vn-user.spec.js b/back/models/specs/vn-user.spec.js index 3700b919a9..5638942fbb 100644 --- a/back/models/specs/vn-user.spec.js +++ b/back/models/specs/vn-user.spec.js @@ -12,4 +12,42 @@ describe('loopback model VnUser', () => { expect(result).toBeFalsy(); }); + + describe('userSecurity', () => { + const itManagementId = 115; + const hrId = 37; + const employeeId = 1; + + it('should check if you are the same user', async() => { + const ctx = {options: {accessToken: {userId: employeeId}}}; + await models.VnUser.userSecurity(ctx, employeeId); + }); + + it('should check for higher privileges', async() => { + const ctx = {options: {accessToken: {userId: itManagementId}}}; + await models.VnUser.userSecurity(ctx, employeeId); + }); + + it('should check if you have medium privileges and the user email is not verified', async() => { + const ctx = {options: {accessToken: {userId: hrId}}}; + await models.VnUser.userSecurity(ctx, employeeId); + }); + + it('should throw an error if you have medium privileges and the users email is verified', async() => { + const tx = await models.VnUser.beginTransaction({}); + const ctx = {options: {accessToken: {userId: hrId}}}; + try { + const options = {transaction: tx}; + const userToUpdate = await models.VnUser.findById(1, null, options); + userToUpdate.updateAttribute('emailVerified', 1, options); + + await models.VnUser.userSecurity(ctx, employeeId, options); + await tx.rollback(); + } catch (error) { + await tx.rollback(); + + expect(error.message).toEqual(`You don't have enough privileges`); + } + }); + }); }); diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 642d3fdf31..6aac215617 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -13,6 +13,7 @@ module.exports = function(Self) { require('../methods/vn-user/privileges')(Self); require('../methods/vn-user/validate-auth')(Self); require('../methods/vn-user/renew-token')(Self); + require('../methods/vn-user/update-user')(Self); Self.definition.settings.acls = Self.definition.settings.acls.filter(acl => acl.property !== 'create'); @@ -179,32 +180,31 @@ module.exports = function(Self) { Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls .filter(acl => acl.property != 'changePassword'); - Self.observe('before save', async ctx => { - const instance = ctx.currentInstance || ctx.instance; - console.log(ctx); - await Self.userSecurity(ctx, instance.id); - }); - - Self.userSecurity = async(ctx, userId) => { + Self.userSecurity = async(ctx, userId, options) => { const models = Self.app.models; - const accessToken = ctx.options.accessToken || LoopBackContext.getCurrentContext().active.accessToken; - console.log(accessToken, LoopBackContext.getCurrentContext().active.http.req); + const accessToken = ctx?.options?.accessToken || LoopBackContext.getCurrentContext().active.accessToken; const ctxToken = {req: {accessToken}}; - const hasHigherPrivileges = await models.ACL.checkAccessAcl(ctxToken, 'VnUser', 'higherPrivileges'); + if (userId === accessToken.userId) return; + + const myOptions = {}; + if (typeof options == 'object') + Object.assign(myOptions, options); + + const hasHigherPrivileges = await models.ACL.checkAccessAcl(ctxToken, 'VnUser', 'higherPrivileges', myOptions); if (hasHigherPrivileges) return; - const hasMediumPrivileges = await models.ACL.checkAccessAcl(ctxToken, 'VnUser', 'mediumPrivileges'); - const user = await models.VnUser.findById(userId, {fields: ['id', 'emailVerified']}); + const hasMediumPrivileges = await models.ACL.checkAccessAcl(ctxToken, 'VnUser', 'mediumPrivileges', myOptions); + const user = await models.VnUser.findById(userId, {fields: ['id', 'emailVerified']}, myOptions); if (!user.emailVerified && hasMediumPrivileges) return; - if (userId != accessToken.userId) - throw new UserError(`You don't have enough privileges`); + throw new UserError(`You don't have enough privileges`); }; - // FIXME: https://redmine.verdnatura.es/issues/5761 - Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => { - if (!ctx.args || !ctx.args.data.email) return; + Self.observe('after save', async ctx => { + const newEmail = ctx?.instance?.email; + const oldEmail = ctx?.hookState?.oldInstance?.email; + if (!ctx.isNewInstance && (!newEmail || !oldEmail || newEmail == oldEmail)) return; const loopBackContext = LoopBackContext.getCurrentContext(); const httpCtx = {req: loopBackContext.active}; @@ -217,8 +217,7 @@ module.exports = function(Self) { async send(verifyOptions, cb) { const params = { url: verifyOptions.verifyHref, - recipient: verifyOptions.to, - lang: ctx.req.getLocale() + recipient: verifyOptions.to }; const email = new Email('email-verify', params); @@ -230,9 +229,9 @@ module.exports = function(Self) { const options = { type: 'email', - to: instance.email, + to: newEmail, from: {}, - redirect: `${origin}/#!/account/${instance.id}/basic-data?emailConfirmed`, + redirect: `${origin}/#!/account/${ctx.instance.id}/basic-data?emailConfirmed`, template: false, mailer: new Mailer, host: url[1].split('/')[2], @@ -241,6 +240,6 @@ module.exports = function(Self) { user: Self }; - await instance.verify(options); + await ctx.instance.verify(options, ctx.options); }); }; diff --git a/back/models/vn-user.json b/back/models/vn-user.json index d233bf7b42..3ae9429587 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -13,11 +13,12 @@ "type": "number", "id": true }, - "username": { + "name": { "type": "string", - "mysql": { - "columnName": "name" - } + "required": true + }, + "username": { + "type": "string" }, "password": { "type": "string", @@ -123,13 +124,7 @@ "principalType": "ROLE", "principalId": "$authenticated", "permission": "ALLOW" - }, - { - "principalType": "ROLE", - "principalId": "$authenticated", - "permission": "ALLOW", - "property": "patchAttributes" - } + } ], "scopes": { "preview": { diff --git a/db/changes/234001/00-account_acl.sql b/db/changes/234001/00-account_acl.sql index 23f47b99f5..8dfe1d1eca 100644 --- a/db/changes/234001/00-account_acl.sql +++ b/db/changes/234001/00-account_acl.sql @@ -1,12 +1,7 @@ -DELETE FROM `salix`.`ACL` - WHERE - model = 'MailForward' - AND accessType = '*' - AND property = '*' - AND principalId = 'hr'; - - INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) VALUES ('VnUser', 'higherPrivileges', '*', 'ALLOW', 'ROLE', 'itManagement'), - ('VnUser', 'mediumPrivileges', '*', 'ALLOW', 'ROLE', 'hr'); + ('VnUser', 'mediumPrivileges', '*', 'ALLOW', 'ROLE', 'hr'), + ('VnUser', 'updateUser', '*', 'ALLOW', 'ROLE', 'employee'); + +ALTER TABLE `account`.`user` ADD `username` varchar(30) AS (name) VIRTUAL; diff --git a/modules/account/back/models/mail-forward.js b/modules/account/back/models/mail-forward.js index d55f5ddbc4..adc282155c 100644 --- a/modules/account/back/models/mail-forward.js +++ b/modules/account/back/models/mail-forward.js @@ -1,9 +1,5 @@ module.exports = Self => { - Self.observe('loaded', async ctx => { - if (!ctx.data.account) return; - await Self.app.models.VnUser.userSecurity(ctx, ctx.data.account); - }); Self.observe('before save', async ctx => { const instance = ctx.currentInstance || ctx.instance; await Self.app.models.VnUser.userSecurity(ctx, instance.account); diff --git a/modules/account/back/models/mail-forward.json b/modules/account/back/models/mail-forward.json index af4de32181..edef1bf08d 100644 --- a/modules/account/back/models/mail-forward.json +++ b/modules/account/back/models/mail-forward.json @@ -21,19 +21,5 @@ "model": "VnUser", "foreignKey": "account" } - }, - "acls": [ - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$authenticated", - "permission": "ALLOW" - }, - { - "accessType": "WRITE", - "principalType": "ROLE", - "principalId": "$authenticated", - "permission": "ALLOW" - } - ] + } } diff --git a/modules/account/front/basic-data/index.html b/modules/account/front/basic-data/index.html index 1f7ce1a05e..9fd3506fe1 100644 --- a/modules/account/front/basic-data/index.html +++ b/modules/account/front/basic-data/index.html @@ -1,11 +1,9 @@ - + + save="patch"> Date: Mon, 25 Sep 2023 10:49:47 +0200 Subject: [PATCH 040/449] ref #5914 fixed tests e2e --- e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js | 6 +++--- loopback/locale/en.json | 2 +- loopback/locale/es.json | 2 +- .../back/methods/invoiceOut/specs/refund.spec.js | 2 +- modules/ticket/back/methods/sale/specs/refund.spec.js | 8 +++++--- modules/ticket/back/methods/ticket/new.js | 2 +- modules/ticket/back/methods/ticket/specs/new.spec.js | 2 +- modules/ticket/back/methods/ticket/transferSales.js | 2 +- 8 files changed, 14 insertions(+), 12 deletions(-) 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 6264073f63..da4b2c92ba 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 @@ -220,7 +220,7 @@ describe('Ticket Edit sale path', () => { it('should log in as salesAssistant and navigate to ticket sales', async() => { await page.loginAndModule('salesAssistant', 'ticket'); - await page.accessToSearchResult('17'); + await page.accessToSearchResult('15'); await page.accessToSection('ticket.card.sale'); }); @@ -324,7 +324,7 @@ describe('Ticket Edit sale path', () => { }); it('should confirm the transfered quantity is the correct one', async() => { - const result = await page.waitToGetProperty(selectors.ticketSales.secondSaleQuantityCell, 'innerText'); + const result = await page.waitToGetProperty(selectors.ticketSales.firstSaleQuantityCell, 'innerText'); expect(result).toContain('20'); }); @@ -378,7 +378,7 @@ describe('Ticket Edit sale path', () => { await page.waitToClick(selectors.ticketSales.moveToNewTicketButton); const message = await page.waitForSnackbar(); - expect(message.text).toContain(`You can't create a ticket for a inactive client`); + expect(message.text).toContain(`You can't create a ticket for an inactive client`); await page.closePopup(); }); diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 95e5ebc1cc..b56c3de77b 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -23,7 +23,7 @@ "Agency cannot be blank": "Agency cannot be blank", "The IBAN does not have the correct format": "The IBAN does not have the correct format", "You can't make changes on the basic data of an confirmed order or with rows": "You can't make changes on the basic data of an confirmed order or with rows", - "You can't create a ticket for a inactive client": "You can't create a ticket for a inactive client", + "You can't create a ticket for an inactive client": "You can't create a ticket for an inactive client", "Worker cannot be blank": "Worker cannot be blank", "You must delete the claim id %d first": "You must delete the claim id %d first", "You don't have enough privileges": "You don't have enough privileges", diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 18f51d7f8e..568c9a3064 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -58,7 +58,7 @@ "You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos básicos de una orden con artículos", "INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no está permitido el uso de la letra ñ", "You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado", - "You can't create a ticket for a inactive client": "No puedes crear un ticket para un cliente inactivo", + "You can't create a ticket for an inactive client": "No puedes crear un ticket para un cliente inactivo", "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", "ORDER_EMPTY": "Cesta vacía", "You don't have enough privileges to do that": "No tienes permisos para cambiar esto", diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js index 6ecfe60151..22891f1618 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js @@ -3,7 +3,7 @@ const LoopBackContext = require('loopback-context'); describe('InvoiceOut refund()', () => { const userId = 5; - const ctx = {req: {accessToken: userId}}; + const ctx = {req: {accessToken: userId}, args: {}}; const withWarehouse = true; const activeCtx = { accessToken: {userId: userId}, diff --git a/modules/ticket/back/methods/sale/specs/refund.spec.js b/modules/ticket/back/methods/sale/specs/refund.spec.js index b81f7f84d8..08eb1fabd2 100644 --- a/modules/ticket/back/methods/sale/specs/refund.spec.js +++ b/modules/ticket/back/methods/sale/specs/refund.spec.js @@ -3,7 +3,7 @@ const LoopBackContext = require('loopback-context'); describe('Sale refund()', () => { const userId = 5; - const ctx = {req: {accessToken: userId}}; + const ctx = {req: {accessToken: userId}, args: {}}; const activeCtx = { accessToken: {userId}, }; @@ -40,6 +40,7 @@ describe('Sale refund()', () => { try { const options = {transaction: tx}; + const ticketsBefore = await models.Ticket.find({}, options); const ticket = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options); @@ -61,12 +62,13 @@ describe('Sale refund()', () => { } ] }, options); - + const ticketsAfter = await models.Ticket.find({}, options); const salesLength = refundedTicket.ticketSales().length; const componentsLength = refundedTicket.ticketSales()[0].components().length; expect(refundedTicket).toBeDefined(); - expect(salesLength).toEqual(2); + expect(salesLength).toEqual(1); + expect(ticketsBefore.length).toEqual(ticketsAfter.length - 2); expect(componentsLength).toEqual(4); await tx.rollback(); diff --git a/modules/ticket/back/methods/ticket/new.js b/modules/ticket/back/methods/ticket/new.js index b461fb26d3..65bc76c5df 100644 --- a/modules/ticket/back/methods/ticket/new.js +++ b/modules/ticket/back/methods/ticket/new.js @@ -96,7 +96,7 @@ module.exports = Self => { if (address.client().type().code === 'normal' && (!agencyMode || agencyMode.code != 'refund')) { const canCreateTicket = await models.Client.canCreateTicket(args.clientId, myOptions); if (!canCreateTicket) - throw new UserError(`You can't create a ticket for a inactive client`); + throw new UserError(`You can't create a ticket for an inactive client`); } if (!args.shipped && args.landed) { diff --git a/modules/ticket/back/methods/ticket/specs/new.spec.js b/modules/ticket/back/methods/ticket/specs/new.spec.js index 0a2f93bc41..9aa073a7ba 100644 --- a/modules/ticket/back/methods/ticket/specs/new.spec.js +++ b/modules/ticket/back/methods/ticket/specs/new.spec.js @@ -30,7 +30,7 @@ describe('ticket new()', () => { await tx.rollback(); } - expect(error).toEqual(new UserError(`You can't create a ticket for a inactive client`)); + expect(error).toEqual(new UserError(`You can't create a ticket for an inactive client`)); }); it('should throw an error if the address doesnt exist', async() => { diff --git a/modules/ticket/back/methods/ticket/transferSales.js b/modules/ticket/back/methods/ticket/transferSales.js index 1124f7ec70..f2cb89205d 100644 --- a/modules/ticket/back/methods/ticket/transferSales.js +++ b/modules/ticket/back/methods/ticket/transferSales.js @@ -66,7 +66,7 @@ module.exports = Self => { const ticket = await models.Ticket.findById(id); const canCreateTicket = await models.Client.canCreateTicket(ticket.clientFk); if (!canCreateTicket) - throw new UserError(`You can't create a ticket for a inactive client`); + throw new UserError(`You can't create a ticket for an inactive client`); ticketId = await cloneTicket(originalTicket, myOptions); } From 98ee9bbaf320684102e08f91fee8813abf5c7417 Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 25 Sep 2023 12:54:31 +0200 Subject: [PATCH 041/449] ref #5914 back test added --- ...rInvoiceACL.sql => 00-transferInvoice.sql} | 6 ++- .../invoiceOut/specs/transferinvoice.spec.js | 43 +++++++++++++++++++ .../methods/invoiceOut/transferInvoice.js | 7 +-- 3 files changed, 52 insertions(+), 4 deletions(-) rename db/changes/234001/{00-transferInvoiceACL.sql => 00-transferInvoice.sql} (76%) create mode 100644 modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js diff --git a/db/changes/234001/00-transferInvoiceACL.sql b/db/changes/234001/00-transferInvoice.sql similarity index 76% rename from db/changes/234001/00-transferInvoiceACL.sql rename to db/changes/234001/00-transferInvoice.sql index 2bf4ec6888..f0608327a7 100644 --- a/db/changes/234001/00-transferInvoiceACL.sql +++ b/db/changes/234001/00-transferInvoice.sql @@ -3,4 +3,8 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp ('CplusRectificationType', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('CplusInvoiceType477', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('InvoiceCorrectionType', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), - ('InvoiceOut', 'transferInvoice', 'WRITE', 'ALLOW', 'ROLE', 'administrative'); \ No newline at end of file + ('InvoiceOut', 'transferInvoice', 'WRITE', 'ALLOW', 'ROLE', 'administrative'); + +INSERT INTO `vn`.`invoiceCorrectionType` (description) + VALUES + ('Error en el cálculo del IVA') \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js new file mode 100644 index 0000000000..cea4ffaccd --- /dev/null +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js @@ -0,0 +1,43 @@ +const models = require('vn-loopback/server/server').models; + +describe('InvoiceOut tranferInvoice()', () => { + const userId = 5; + const ctx = {req: {accessToken: userId}}; + ctx.args = { + id: '1', + ref: 'T1111111', + newClientFk: 1, + cplusRectificationId: 1, + cplusInvoiceType477Id: 1, + invoiceCorrectionTypeId: 1 + }; + it('should return the id of the created issued invoice', async() => { + const tx = await models.InvoiceOut.beginTransaction({}); + const options = {transaction: tx}; + try { + const result = await models.InvoiceOut.transferInvoice( + ctx, + options); + + expect(result).toBeDefined(); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw an UserError when it is the same client', async() => { + const tx = await models.InvoiceOut.beginTransaction({}); + const options = {transaction: tx}; + try { + ctx.args.newClientFk = 1101; + await models.InvoiceOut.transferInvoice( + ctx, + options); + } catch (e) { + expect(e.message).toBe(`Select a different client`); + await tx.rollback(); + } + }); +}); diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js index c4f6e9445d..8a0609b8d2 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js @@ -97,9 +97,10 @@ module.exports = Self => { invoiceCorrectionTypeFk: args.invoiceCorrectionTypeId }, myOptions); - if (tx) await tx.commit(); - - await models.InvoiceOut.makePdfAndNotify(ctx, invoiceId, null); + if (tx) { + await tx.commit(); + await models.InvoiceOut.makePdfAndNotify(ctx, invoiceId, null); + } return invoiceId; } catch (e) { From 64eb216367d6702ad1e0d2a672df05e9103d28c2 Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 25 Sep 2023 14:01:40 +0200 Subject: [PATCH 042/449] ref #5914 fixed back test --- .../invoiceOut/specs/transferinvoice.spec.js | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js index cea4ffaccd..75bf649ecb 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js @@ -3,17 +3,18 @@ const models = require('vn-loopback/server/server').models; describe('InvoiceOut tranferInvoice()', () => { const userId = 5; const ctx = {req: {accessToken: userId}}; - ctx.args = { - id: '1', - ref: 'T1111111', - newClientFk: 1, - cplusRectificationId: 1, - cplusInvoiceType477Id: 1, - invoiceCorrectionTypeId: 1 - }; it('should return the id of the created issued invoice', async() => { const tx = await models.InvoiceOut.beginTransaction({}); const options = {transaction: tx}; + const args = { + id: '1', + ref: 'T1111111', + newClientFk: 1, + cplusRectificationId: 1, + cplusInvoiceType477Id: 1, + invoiceCorrectionTypeId: 1 + }; + ctx.args = args; try { const result = await models.InvoiceOut.transferInvoice( ctx, @@ -30,8 +31,16 @@ describe('InvoiceOut tranferInvoice()', () => { it('should throw an UserError when it is the same client', async() => { const tx = await models.InvoiceOut.beginTransaction({}); const options = {transaction: tx}; + const args = { + id: '1', + ref: 'T1111111', + newClientFk: 1101, + cplusRectificationId: 1, + cplusInvoiceType477Id: 1, + invoiceCorrectionTypeId: 1 + }; + ctx.args = args; try { - ctx.args.newClientFk = 1101; await models.InvoiceOut.transferInvoice( ctx, options); From 474399b383cefa9c6d9a715082222cc4d8ada3b9 Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 25 Sep 2023 15:23:51 +0200 Subject: [PATCH 043/449] ref #5914 refactor --- db/changes/234001/00-transferInvoice.sql | 4 ---- db/dump/fixtures.sql | 6 ++++++ modules/ticket/back/methods/sale/clone.js | 13 +++---------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/db/changes/234001/00-transferInvoice.sql b/db/changes/234001/00-transferInvoice.sql index f0608327a7..7a9890ae45 100644 --- a/db/changes/234001/00-transferInvoice.sql +++ b/db/changes/234001/00-transferInvoice.sql @@ -4,7 +4,3 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp ('CplusInvoiceType477', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('InvoiceCorrectionType', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('InvoiceOut', 'transferInvoice', 'WRITE', 'ALLOW', 'ROLE', 'administrative'); - -INSERT INTO `vn`.`invoiceCorrectionType` (description) - VALUES - ('Error en el cálculo del IVA') \ No newline at end of file diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 1d115af0dc..15d78adff9 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2974,3 +2974,9 @@ INSERT INTO vn.XDiario (id, ASIEN, FECHA, SUBCTA, CONTRA, CONCEPTO, EURODEBE, EU (4, 2.0, util.VN_CURDATE(), '4300001104', NULL, 'n/fra T4444444', 8.88, NULL, NULL, NULL, '0', NULL, 0.00, NULL, NULL, NULL, NULL, NULL, '2', NULL, 1, 2, 'I.F.', 'Nombre Importador', 1, 0, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0), (5, 2.0, util.VN_CURDATE(), '2000000000', '4300001104', 'n/fra T4444444 Tony Stark', NULL, 8.07, NULL, NULL, '0', NULL, 0.00, NULL, NULL, NULL, NULL, NULL, '2', NULL, 1, 2, 'I.F.', 'Nombre Importador', 1, 0, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0), (6, 2.0, util.VN_CURDATE(), '4770000010', '4300001104', 'Inmovilizado pendiente : n/fra T4444444 Tony Stark', NULL, 0.81, 8.07, 'T', '4444444', 10.00, NULL, NULL, NULL, NULL, NULL, '', '2', '', 1, 1, '06089160W', 'IRON MAN', 1, 1, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, 1, 1, 1, 1, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0); + +INSERT INTO `vn`.`invoiceCorrectionType` (`id`, `description`) + VALUES + (1, 'Error en el cálculo del IVA'), + (2, 'Error en el detalle de las ventas'), + (3, 'Error en los datos del cliente'); \ No newline at end of file diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index 7ce7675da1..84f0e02f86 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -44,7 +44,7 @@ module.exports = Self => { } for (const sale of sales) { - const refundTicketId = await getTicketRefundId(group, sale.ticketFk, refundTickets, mappedTickets); + const refundTicketId = mappedTickets.get(sale.ticketFk); const createdSale = await models.Sale.create({ ticketFk: refundTicketId, @@ -62,14 +62,14 @@ module.exports = Self => { await models.SaleComponent.create(components, myOptions); } - if (servicesIds && servicesIds.length > 0) { + if (servicesIds && servicesIds.length) { const servicesFilter = { where: {id: {inq: servicesIds}} }; const services = await models.TicketService.find(servicesFilter, myOptions); for (const service of services) { - const refundTicketId = await getTicketRefundId(group, service.ticketFk, refundTickets, mappedTickets); + const refundTicketId = mappedTickets.get(service.ticketFk); await models.TicketService.create({ description: service.description, @@ -113,11 +113,4 @@ module.exports = Self => { refundTickets.push(refundTicket); } - - async function getTicketRefundId(group, ticketId, refundTickets, mappedTickets) { - if (group) { - const [firstRefundTicket] = refundTickets; - return firstRefundTicket.id; - } else return mappedTickets.get(ticketId); - } }; From 50543963c104dc1adf421f4c25f4dbf3480254aa Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 26 Sep 2023 12:42:45 +0200 Subject: [PATCH 044/449] ref #5914 refactor createTicketRefund --- modules/ticket/back/methods/sale/clone.js | 57 +++++++++++------------ 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index 84f0e02f86..dd1b108b22 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -3,6 +3,7 @@ module.exports = Self => { const models = Self.app.models; const myOptions = {}; let tx; + const refundTickets = []; if (typeof options == 'object') Object.assign(myOptions, options); @@ -25,22 +26,19 @@ module.exports = Self => { const sales = await models.Sale.find(salesFilter, myOptions); let ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))]; - const refundTickets = []; const mappedTickets = new Map(); - const now = Date.vnNew(); if (group) ticketsIds = [ticketsIds[0]]; - for (let ticketId in ticketsIds) { - await createTicketRefund( + for (let ticketId of ticketsIds) { + const ticketRefund = await createTicketRefund( ctx, - ticketsIds[ticketId], + ticketId, withWarehouse, - refundTickets, - now, myOptions ); - mappedTickets.set(ticketsIds[ticketId], refundTickets[ticketId].id); + refundTickets.push(ticketRefund); + mappedTickets.set(ticketId, ticketRefund.id); } for (const sale of sales) { @@ -89,28 +87,25 @@ module.exports = Self => { if (tx) await tx.rollback(); throw e; } + + async function createTicketRefund( + ctx, + ticketId, + withWarehouse, + myOptions + ) { + const models = Self.app.models; + const now = Date.vnNew(); + + const ticket = await models.Ticket.findById(ticketId, null, myOptions); + ctx.args.clientId = ticket.clientFk; + ctx.args.shipped = now; + ctx.args.landed = now; + ctx.args.warehouseId = withWarehouse ? ticket.warehouseFk : null; + ctx.args.companyId = ticket.companyFk; + ctx.args.addressId = ticket.addressFk; + + return models.Ticket.new(ctx, myOptions); + } }; - - async function createTicketRefund( - ctx, - ticketId, - withWarehouse, - refundTickets, - now, - myOptions - ) { - const models = Self.app.models; - - const ticket = await models.Ticket.findById(ticketId, myOptions); - ctx.args.clientId = ticket.clientFk; - ctx.args.shipped = now; - ctx.args.landed = now; - ctx.args.warehouseId = withWarehouse ? ticket.warehouseFk : null; - ctx.args.companyId = ticket.companyFk; - ctx.args.addressId = ticket.addressFk; - - const refundTicket = await models.Ticket.new(ctx, myOptions); - - refundTickets.push(refundTicket); - } }; From 463fc8ae958d8ebe7c388636575636c0ad5ded1b Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 28 Sep 2023 08:20:59 +0200 Subject: [PATCH 045/449] ref #5914 added fixtures in English --- db/dump/fixtures.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 15d78adff9..31ec9b138f 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2977,6 +2977,6 @@ INSERT INTO vn.XDiario (id, ASIEN, FECHA, SUBCTA, CONTRA, CONCEPTO, EURODEBE, EU INSERT INTO `vn`.`invoiceCorrectionType` (`id`, `description`) VALUES - (1, 'Error en el cálculo del IVA'), - (2, 'Error en el detalle de las ventas'), - (3, 'Error en los datos del cliente'); \ No newline at end of file + (1, 'Error in VAT calculation'), + (2, 'Error in sales details'), + (3, 'Error in customer data'); \ No newline at end of file From 0fa56149d7b03697fe60c1efdefb1531c57452d5 Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 29 Sep 2023 09:47:22 +0200 Subject: [PATCH 046/449] refs #6266 smsfix --- modules/ticket/front/descriptor-menu/index.js | 2 +- modules/ticket/front/descriptor/locale/en.yml | 2 +- modules/ticket/front/descriptor/locale/es.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index d1f39fd19f..18db8c1474 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -201,7 +201,7 @@ class Controller extends Section { sendImportSms() { const params = { ticketId: this.id, - created: this.ticket.updated + shipped: this.ticket.shipped }; this.showSMSDialog({ message: this.$t('Minimum is needed', params) diff --git a/modules/ticket/front/descriptor/locale/en.yml b/modules/ticket/front/descriptor/locale/en.yml index 8eed2265db..698d699d7f 100644 --- a/modules/ticket/front/descriptor/locale/en.yml +++ b/modules/ticket/front/descriptor/locale/en.yml @@ -1,3 +1,3 @@ Make a payment: "Verdnatura communicates:\rYour order is pending of payment.\rPlease, enter the web page and make the payment with card.\rThank you." -Minimum is needed: "Verdnatura communicates:\rA minimum import of 50€ (Without BAT) is needed for your order {{ticketId}} from date {{created | date: 'dd/MM/yyyy'}} to receive it with no extra fees." +Minimum is needed: "Verdnatura communicates:\rA minimum import of 50€ (Without BAT) is needed for your order {{ticketId}} from date {{shipped | date: 'dd/MM/yyyy'}} to receive it with no extra fees." Send changes: "Verdnatura communicates:\rOrder {{ticketId}} date {{created | date: 'dd/MM/yyyy'}}\r{{changes}}" diff --git a/modules/ticket/front/descriptor/locale/es.yml b/modules/ticket/front/descriptor/locale/es.yml index 86b1a6b57a..8e3b5e4733 100644 --- a/modules/ticket/front/descriptor/locale/es.yml +++ b/modules/ticket/front/descriptor/locale/es.yml @@ -4,7 +4,7 @@ Show pallet report: Ver hoja de pallet Change shipped hour: Cambiar hora de envío Shipped hour: Hora de envío Make a payment: "Verdnatura le comunica:\rSu pedido está pendiente de pago.\rPor favor, entre en la página web y efectue el pago con tarjeta.\rMuchas gracias." -Minimum is needed: "Verdnatura le recuerda:\rEs necesario un importe mínimo de 50€ (Sin IVA) en su pedido {{ticketId}} del día {{created | date: 'dd/MM/yyyy'}} para recibirlo sin portes adicionales." +Minimum is needed: "Verdnatura le recuerda:\rEs necesario un importe mínimo de 50€ (Sin IVA) en su pedido {{ticketId}} del día {{shipped | date: 'dd/MM/yyyy'}} para recibirlo sin portes adicionales." Ticket invoiced: Ticket facturado Make invoice: Crear factura Regenerate invoice PDF: Regenerar PDF factura From 6691cbf32f1285240b093f3ed24c720f3e380c98 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 29 Sep 2023 11:24:24 +0200 Subject: [PATCH 047/449] ref #5914 changes moved --- db/changes/{234001 => 234201}/00-transferInvoice.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{234001 => 234201}/00-transferInvoice.sql (100%) diff --git a/db/changes/234001/00-transferInvoice.sql b/db/changes/234201/00-transferInvoice.sql similarity index 100% rename from db/changes/234001/00-transferInvoice.sql rename to db/changes/234201/00-transferInvoice.sql From 6f4a12e50f37fff49c009e3d1a8cc08d34b85f92 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 29 Sep 2023 14:42:47 +0200 Subject: [PATCH 048/449] ref #5417 date filters added --- .../methods/client/specs/transactions.spec.js | 23 +++++++++++++++++++ .../back/methods/client/transactions.js | 20 ++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/modules/client/back/methods/client/specs/transactions.spec.js b/modules/client/back/methods/client/specs/transactions.spec.js index 45fffc1de9..679eb196cc 100644 --- a/modules/client/back/methods/client/specs/transactions.spec.js +++ b/modules/client/back/methods/client/specs/transactions.spec.js @@ -63,4 +63,27 @@ describe('Client transactions', () => { throw e; } }); + + it('should call transactions() method filtering by date', async() => { + const tx = await models.Client.beginTransaction({}); + + try { + const options = {transaction: tx}; + const ctx = {args: {from: '2000/12/31'}}; + const filter = {}; + const withResults = await models.Client.transactions(ctx, filter, options); + + expect(withResults.length).toEqual(6); + + ctx.args.from = '2099/12/31'; + const noResults = await models.Client.transactions(ctx, filter, options); + + expect(noResults.length).toEqual(0); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); diff --git a/modules/client/back/methods/client/transactions.js b/modules/client/back/methods/client/transactions.js index 6919107212..3ef61dd83d 100644 --- a/modules/client/back/methods/client/transactions.js +++ b/modules/client/back/methods/client/transactions.js @@ -28,6 +28,16 @@ module.exports = Self => { arg: 'amount', type: 'number', http: {source: 'query'} + }, + { + arg: 'from', + type: 'date', + http: {source: 'query'} + }, + { + arg: 'to', + type: 'date', + http: {source: 'query'} } ], returns: { @@ -47,6 +57,11 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); + if (ctx.args && args.to) { + const dateTo = args.to; + dateTo.setHours(23, 59, 0, 0); + } + const where = buildFilter(args, (param, value) => { switch (param) { case 'orderFk': @@ -55,6 +70,11 @@ module.exports = Self => { return {'t.clientFk': value}; case 'amount': return {'t.amount': (value * 100)}; + case 'from': + return {'t.created': {gte: value}}; + + case 'to': + return {'t.created': {lte: value}}; } }); From a7128b8187d1c8d5c006dfe25de6398342ea882c Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 2 Oct 2023 09:04:43 +0200 Subject: [PATCH 049/449] ref #5417 fix transactions --- modules/client/back/methods/client/transactions.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/client/back/methods/client/transactions.js b/modules/client/back/methods/client/transactions.js index 3ef61dd83d..174ca4c4ea 100644 --- a/modules/client/back/methods/client/transactions.js +++ b/modules/client/back/methods/client/transactions.js @@ -59,7 +59,7 @@ module.exports = Self => { if (ctx.args && args.to) { const dateTo = args.to; - dateTo.setHours(23, 59, 0, 0); + dateTo.setHours(23, 59, 59, 999); } const where = buildFilter(args, (param, value) => { @@ -72,7 +72,6 @@ module.exports = Self => { return {'t.amount': (value * 100)}; case 'from': return {'t.created': {gte: value}}; - case 'to': return {'t.created': {lte: value}}; } From c59b119a4a2b04b2a0e37ef996802e5a9bdad08b Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 2 Oct 2023 10:06:04 +0200 Subject: [PATCH 050/449] ref #5417 fix transactions --- modules/client/back/methods/client/transactions.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/client/back/methods/client/transactions.js b/modules/client/back/methods/client/transactions.js index 174ca4c4ea..d08df4ab60 100644 --- a/modules/client/back/methods/client/transactions.js +++ b/modules/client/back/methods/client/transactions.js @@ -32,12 +32,10 @@ module.exports = Self => { { arg: 'from', type: 'date', - http: {source: 'query'} }, { arg: 'to', type: 'date', - http: {source: 'query'} } ], returns: { From 99d65804e8ff9717d7813736864510d65fe54fe9 Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 2 Oct 2023 13:29:39 +0200 Subject: [PATCH 051/449] refs #6278 fixFilter --- .../234201/00-alterTableTicketRequest.sql | 1 + modules/item/front/request/index.html | 8 ++++++ .../back/methods/ticket-request/filter.js | 25 +++++++++++-------- 3 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 db/changes/234201/00-alterTableTicketRequest.sql diff --git a/db/changes/234201/00-alterTableTicketRequest.sql b/db/changes/234201/00-alterTableTicketRequest.sql new file mode 100644 index 0000000000..2a08137b98 --- /dev/null +++ b/db/changes/234201/00-alterTableTicketRequest.sql @@ -0,0 +1 @@ +ALTER TABLE `vn`.`ticketRequest` MODIFY COLUMN `itemFk` double DEFAULT NULL NOT NULL; diff --git a/modules/item/front/request/index.html b/modules/item/front/request/index.html index c505b3a097..571ad49af4 100644 --- a/modules/item/front/request/index.html +++ b/modules/item/front/request/index.html @@ -26,6 +26,7 @@ Ticket ID Shipped Description + Requester Requested Price Atender @@ -51,6 +52,13 @@ {{::request.description}} + + + {{::request.requesterName}} + + {{::request.quantity}} {{::request.price | currency: 'EUR':2}} diff --git a/modules/ticket/back/methods/ticket-request/filter.js b/modules/ticket/back/methods/ticket-request/filter.js index f27ea50184..47e5719889 100644 --- a/modules/ticket/back/methods/ticket-request/filter.js +++ b/modules/ticket/back/methods/ticket-request/filter.js @@ -99,6 +99,8 @@ module.exports = Self => { switch (value) { case 'pending': return {'tr.isOk': null}; + case 'accepted': + return {'tr.isOk': 1}; default: return {'tr.isOk': value}; } @@ -122,8 +124,7 @@ module.exports = Self => { filter = mergeFilters(filter, {where}); const stmt = new ParameterizedSQL( - `SELECT - tr.id, + `SELECT tr.id, tr.ticketFk, tr.quantity, tr.price, @@ -133,18 +134,19 @@ module.exports = Self => { tr.saleFk, tr.requesterFk, tr.isOk, - s.quantity AS saleQuantity, + s.quantity saleQuantity, s.itemFk, - i.name AS itemDescription, + i.name itemDescription, t.shipped, - DATE(t.shipped) AS shippedDate, + DATE(t.shipped) shippedDate, t.nickname, t.warehouseFk, t.clientFk, - w.name AS warehouse, - u.nickname AS salesPersonNickname, - ua.name AS attenderName, - c.salesPersonFk + w.name warehouse, + u.nickname salesPersonNickname, + ua.name attenderName, + c.salesPersonFk, + ua2.name requesterName FROM ticketRequest tr LEFT JOIN ticketWeekly tw on tw.ticketFk = tr.ticketFk LEFT JOIN ticket t ON t.id = tr.ticketFk @@ -155,9 +157,12 @@ module.exports = Self => { LEFT JOIN worker wk ON wk.id = c.salesPersonFk LEFT JOIN account.user u ON u.id = wk.id LEFT JOIN worker wka ON wka.id = tr.attenderFk - LEFT JOIN account.user ua ON ua.id = wka.id`); + LEFT JOIN account.user ua ON ua.id = wka.id + LEFT JOIN account.user ua2 ON ua2.id = tr.requesterFk`); stmt.merge(conn.makeSuffix(filter)); + console.log(stmt); + return conn.executeStmt(stmt, myOptions); }; }; From 4545a6321455c8d3acdef0eac2320dd840b602e0 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 2 Oct 2023 14:51:19 +0200 Subject: [PATCH 052/449] refs #6067 feat(vnUser): verifyEmail redirect to lilium --- back/methods/vn-user/update-user.js | 6 ++--- back/models/specs/vn-user.spec.js | 3 ++- back/models/vn-user.js | 27 ++++++++++++++----- db/changes/234201/00-aclUrlHedera.sql | 4 +++ db/dump/fixtures.sql | 1 + modules/account/back/models/mail-forward.js | 10 ------- modules/account/back/models/mail-forward.json | 13 ++++++++- modules/worker/back/methods/worker/new.js | 1 + 8 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 db/changes/234201/00-aclUrlHedera.sql delete mode 100644 modules/account/back/models/mail-forward.js diff --git a/back/methods/vn-user/update-user.js b/back/methods/vn-user/update-user.js index 85f6df7620..ddaae8548e 100644 --- a/back/methods/vn-user/update-user.js +++ b/back/methods/vn-user/update-user.js @@ -32,10 +32,8 @@ module.exports = Self => { } }); - Self.updateUser = async(ctx, id) => { + Self.updateUser = async(ctx, id, name, nickname, email, lang) => { await Self.userSecurity(ctx, id); - const user = await Self.app.models.VnUser.findById(id, - {fields: ['id', 'name', 'nickname', 'email', 'lang', 'password']}); - await user.updateAttributes(ctx.args); + await Self.upsertWithWhere({id}, {name, nickname, email, lang}); }; }; diff --git a/back/models/specs/vn-user.spec.js b/back/models/specs/vn-user.spec.js index 5638942fbb..8689a78544 100644 --- a/back/models/specs/vn-user.spec.js +++ b/back/models/specs/vn-user.spec.js @@ -1,4 +1,5 @@ const models = require('vn-loopback/server/server').models; +const ForbiddenError = require('vn-loopback/util/forbiddenError'); describe('loopback model VnUser', () => { it('should return true if the user has the given role', async() => { @@ -46,7 +47,7 @@ describe('loopback model VnUser', () => { } catch (error) { await tx.rollback(); - expect(error.message).toEqual(`You don't have enough privileges`); + expect(error).toEqual(new ForbiddenError()); } }); }); diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 6aac215617..e910ee33c5 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -1,7 +1,7 @@ const vnModel = require('vn-loopback/common/models/vn-model'); const LoopBackContext = require('loopback-context'); const {Email} = require('vn-print'); -const UserError = require('vn-loopback/util/user-error'); +const ForbiddenError = require('vn-loopback/util/forbiddenError'); module.exports = function(Self) { vnModel(Self); @@ -198,11 +198,12 @@ module.exports = function(Self) { const user = await models.VnUser.findById(userId, {fields: ['id', 'emailVerified']}, myOptions); if (!user.emailVerified && hasMediumPrivileges) return; - throw new UserError(`You don't have enough privileges`); + throw new ForbiddenError(); }; Self.observe('after save', async ctx => { - const newEmail = ctx?.instance?.email; + const instance = ctx?.instance; + const newEmail = instance?.email; const oldEmail = ctx?.hookState?.oldInstance?.email; if (!ctx.isNewInstance && (!newEmail || !oldEmail || newEmail == oldEmail)) return; @@ -213,6 +214,21 @@ module.exports = function(Self) { const origin = headers.origin; const url = origin.split(':'); + const env = process.env.NODE_ENV; + const liliumUrl = await Self.app.models.Url.findOne({ + where: {and: [ + {appName: 'lilium'}, + {environment: env} + ]} + }); + const hederaUrl = await Self.app.models.Url.findOne({ + where: {and: [ + {appName: 'hedera'}, + {environment: env} + ]} + }); + + const isWorker = instance.isWorker || await Self.app.models.Account.findById(instance.id, null, ctx.options); class Mailer { async send(verifyOptions, cb) { const params = { @@ -226,12 +242,11 @@ module.exports = function(Self) { cb(null, verifyOptions.to); } } - const options = { type: 'email', to: newEmail, from: {}, - redirect: `${origin}/#!/account/${ctx.instance.id}/basic-data?emailConfirmed`, + redirect: `${liliumUrl.url}verifyEmail?isWorker=${!!isWorker}&url=${hederaUrl.url}`, template: false, mailer: new Mailer, host: url[1].split('/')[2], @@ -240,6 +255,6 @@ module.exports = function(Self) { user: Self }; - await ctx.instance.verify(options, ctx.options); + await instance.verify(options, ctx.options); }); }; diff --git a/db/changes/234201/00-aclUrlHedera.sql b/db/changes/234201/00-aclUrlHedera.sql new file mode 100644 index 0000000000..438f581783 --- /dev/null +++ b/db/changes/234201/00-aclUrlHedera.sql @@ -0,0 +1,4 @@ +INSERT INTO `salix`.`url` (`appName`, `environment`, `url`) + VALUES + ('hedera', 'test', 'https://test-shop.verdnatura.es/'), + ('hedera', 'production', 'https://shop.verdnatura.es/'); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index eb28c4a01b..41f999dafe 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2869,6 +2869,7 @@ INSERT INTO `vn`.`profileType` (`id`, `name`) INSERT INTO `salix`.`url` (`appName`, `environment`, `url`) VALUES ('lilium', 'development', 'http://localhost:9000/#/'), + ('hedera', 'development', 'http://localhost:9090/'), ('salix', 'development', 'http://localhost:5000/#!/'); INSERT INTO `vn`.`report` (`id`, `name`, `paperSizeFk`, `method`) diff --git a/modules/account/back/models/mail-forward.js b/modules/account/back/models/mail-forward.js deleted file mode 100644 index adc282155c..0000000000 --- a/modules/account/back/models/mail-forward.js +++ /dev/null @@ -1,10 +0,0 @@ - -module.exports = Self => { - Self.observe('before save', async ctx => { - const instance = ctx.currentInstance || ctx.instance; - await Self.app.models.VnUser.userSecurity(ctx, instance.account); - }); - Self.observe('before delete', async ctx => { - await Self.app.models.VnUser.userSecurity(ctx, ctx.where.account); - }); -}; diff --git a/modules/account/back/models/mail-forward.json b/modules/account/back/models/mail-forward.json index edef1bf08d..874810b7a0 100644 --- a/modules/account/back/models/mail-forward.json +++ b/modules/account/back/models/mail-forward.json @@ -21,5 +21,16 @@ "model": "VnUser", "foreignKey": "account" } - } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$owner", + "permission": "ALLOW" + }, { + "accessType": "WRITE", + "principalType": "ROLE", + "principalId": "$owner", + "permission": "ALLOW" + }] } diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 199a3be620..7c8978ec6f 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -155,6 +155,7 @@ module.exports = Self => { password: randomPassword.password, email: args.email, roleFk: workerConfig.roleFk, + isWorker: true // to verifyEmail }, myOptions ); From 8c39f65dc31f0658ac1e692693c59117699e2f61 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 3 Oct 2023 09:36:11 +0200 Subject: [PATCH 053/449] refs #6067 feat: url model to everyone --- back/models/url.json | 9 ++++++++- back/models/vn-user.js | 8 +------- db/changes/{234001 => 234201}/00-account_acl.sql | 0 db/changes/234201/00-aclUrlHedera.sql | 5 +++++ 4 files changed, 14 insertions(+), 8 deletions(-) rename db/changes/{234001 => 234201}/00-account_acl.sql (100%) diff --git a/back/models/url.json b/back/models/url.json index 8610ff28b6..13f50b0993 100644 --- a/back/models/url.json +++ b/back/models/url.json @@ -21,5 +21,12 @@ "type": "string", "required": true } - } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] + } diff --git a/back/models/vn-user.js b/back/models/vn-user.js index e910ee33c5..8e9b59aab4 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -221,12 +221,6 @@ module.exports = function(Self) { {environment: env} ]} }); - const hederaUrl = await Self.app.models.Url.findOne({ - where: {and: [ - {appName: 'hedera'}, - {environment: env} - ]} - }); const isWorker = instance.isWorker || await Self.app.models.Account.findById(instance.id, null, ctx.options); class Mailer { @@ -246,7 +240,7 @@ module.exports = function(Self) { type: 'email', to: newEmail, from: {}, - redirect: `${liliumUrl.url}verifyEmail?isWorker=${!!isWorker}&url=${hederaUrl.url}`, + redirect: `${liliumUrl.url}verifyEmail?isWorker=${!!isWorker}`, template: false, mailer: new Mailer, host: url[1].split('/')[2], diff --git a/db/changes/234001/00-account_acl.sql b/db/changes/234201/00-account_acl.sql similarity index 100% rename from db/changes/234001/00-account_acl.sql rename to db/changes/234201/00-account_acl.sql diff --git a/db/changes/234201/00-aclUrlHedera.sql b/db/changes/234201/00-aclUrlHedera.sql index 438f581783..0d38a2ae81 100644 --- a/db/changes/234201/00-aclUrlHedera.sql +++ b/db/changes/234201/00-aclUrlHedera.sql @@ -2,3 +2,8 @@ INSERT INTO `salix`.`url` (`appName`, `environment`, `url`) VALUES ('hedera', 'test', 'https://test-shop.verdnatura.es/'), ('hedera', 'production', 'https://shop.verdnatura.es/'); + +DELETE FROM `salix`.`ACL` + WHERE model = 'Url' + AND 'accessType' = 'READ' + AND principalId = 'employee'; From 45e41de9a9a47ebdc0e75577763795b1f38b24bf Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 3 Oct 2023 14:03:52 +0200 Subject: [PATCH 054/449] refs #5918 fix(worker_time-control): isMailSended --- .../00-ACL_workerDepartment.sql | 0 .../updateWorkerTimeControlMail.js | 16 ++++++++-------- modules/worker/front/time-control/index.js | 11 ++++++----- 3 files changed, 14 insertions(+), 13 deletions(-) rename db/changes/{233601 => 234201}/00-ACL_workerDepartment.sql (100%) diff --git a/db/changes/233601/00-ACL_workerDepartment.sql b/db/changes/234201/00-ACL_workerDepartment.sql similarity index 100% rename from db/changes/233601/00-ACL_workerDepartment.sql rename to db/changes/234201/00-ACL_workerDepartment.sql diff --git a/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js b/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js index 6fe30de91d..e12cf9c592 100644 --- a/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js +++ b/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js @@ -37,9 +37,8 @@ module.exports = Self => { } }); - Self.updateWorkerTimeControlMail = async(ctx, options) => { + Self.updateWorkerTimeControlMail = async(ctx, workerId, year, week, state, reason, options) => { const models = Self.app.models; - const args = ctx.args; const myOptions = {}; @@ -48,20 +47,21 @@ module.exports = Self => { const workerTimeControlMail = await models.WorkerTimeControlMail.findOne({ where: { - workerFk: args.workerId, - year: args.year, - week: args.week + workerFk: workerId, + year, + week } }, myOptions); + console.log('workerTimeControlMail: ', workerTimeControlMail); if (!workerTimeControlMail) throw new UserError(`There aren't records for this week`); await workerTimeControlMail.updateAttributes({ - state: args.state, - reason: args.reason || null + state, + reason: reason || null }, myOptions); - if (args.state == 'SENDED') { + if (state == 'SENDED') { await workerTimeControlMail.updateAttributes({ sendedCounter: workerTimeControlMail.sendedCounter + 1 }, myOptions); diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index 0b427a10d5..4bf25886fa 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -143,21 +143,22 @@ class Controller extends Section { } isMailSended() { - const filterTimeControl = { + const filter = { where: { year: this._date.getFullYear(), week: this.getWeekNumber(this._date) }, limit: 1 }; - this.$http.get('WorkerTimeControlMails', {filterTimeControl}) + // no repeat request + this.$http.get('WorkerTimeControlMails', {filter}) .then(res => { if (!res.data.length) { this.canResend = false; return; } - const filterDepartment = { + const filter = { where: { workerFk: this.$params.id }, @@ -165,9 +166,9 @@ class Controller extends Section { relation: 'department' } }; - this.$http.get('WorkerDepartments', {filterDepartment}) + this.$http.get('WorkerDepartments/findOne', {filter}) .then(res => { - const department = res.data[0].department; + const department = res.data.department; if (department.isTeleworking) this.canResend = true; }); }); From df6d10e514b4b1a54b382392b32fc6458ef7d2ab Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 4 Oct 2023 12:17:24 +0200 Subject: [PATCH 055/449] refs #5918 fix(workerTimeControl): resend mail --- .../updateWorkerTimeControlMail.js | 37 +++++++---- .../weeklyHourRecordEmail.js | 5 +- modules/worker/front/time-control/index.html | 2 +- modules/worker/front/time-control/index.js | 64 +++++++------------ 4 files changed, 49 insertions(+), 59 deletions(-) diff --git a/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js b/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js index e12cf9c592..4e41a5bdd0 100644 --- a/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js +++ b/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js @@ -37,31 +37,40 @@ module.exports = Self => { } }); - Self.updateWorkerTimeControlMail = async(ctx, workerId, year, week, state, reason, options) => { + Self.updateWorkerTimeControlMail = async(ctx, options) => { const models = Self.app.models; - + const args = ctx.args; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const workerTimeControlMail = await models.WorkerTimeControlMail.findOne({ + const [sent] = await models.WorkerTimeControlMail.find({ where: { - workerFk: workerId, - year, - week - } + year: args.year, + week: args.week, + }, + limit: 1 }, myOptions); - console.log('workerTimeControlMail: ', workerTimeControlMail); - if (!workerTimeControlMail) throw new UserError(`There aren't records for this week`); + if (!sent) throw new UserError(`There aren't records for this week`); - await workerTimeControlMail.updateAttributes({ - state, - reason: reason || null - }, myOptions); + const workerTimeControlMail = await models.WorkerTimeControlMail.upsertWithWhere( + { + year: args.year, + week: args.week, + workerFk: args.workerId + }, + { + state: args.state, + reason: args.workerId, + year: args.year, + week: args.week, + workerFk: args.workerId + }, + myOptions); - if (state == 'SENDED') { + if (args.state == 'SENDED') { await workerTimeControlMail.updateAttributes({ sendedCounter: workerTimeControlMail.sendedCounter + 1 }, myOptions); diff --git a/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js b/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js index 3203dea827..816a1d22b5 100644 --- a/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js +++ b/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js @@ -61,9 +61,8 @@ module.exports = Self => { const url = `${salix.url}worker/${args.workerId}/time-control?timestamp=${timestamp}`; ctx.args.url = url; - await Self.sendTemplate(ctx, 'weekly-hour-record'); - - return models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, myOptions); + await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, myOptions); + return Self.sendTemplate(ctx, 'weekly-hour-record'); }; function getMondayDateFromYearWeek(yearNumber, weekNumber) { diff --git a/modules/worker/front/time-control/index.html b/modules/worker/front/time-control/index.html index 847eb95056..ce8a663560 100644 --- a/modules/worker/front/time-control/index.html +++ b/modules/worker/front/time-control/index.html @@ -102,7 +102,7 @@ ng-click="sendEmailConfirmation.show()" class="right" vn-tooltip="Resend email of this week to the user" - ng-show="$ctrl.isHr && $ctrl.canResend"> + ng-show="$ctrl.isHr && $ctrl.state != 'CONFIRMED' && $ctrl.canResend"> diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index 4bf25886fa..9137d78393 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -53,6 +53,8 @@ class Controller extends Section { set worker(value) { this._worker = value; this.fetchHours(); + if (this.date) + this.getWeekData(); } /** @@ -110,8 +112,8 @@ class Controller extends Section { } if (!this.weekTotalHours) this.fetchHours(); - this.getWeekData(); - this.isMailSended(); + if (this.worker) + this.getWeekData(); } set weekTotalHours(totalHours) { @@ -128,21 +130,23 @@ class Controller extends Section { workerFk: this.$params.id, year: this._date.getFullYear(), week: this.getWeekNumber(this._date) - } + }, }; this.$http.get('WorkerTimeControlMails', {filter}) .then(res => { - const mail = res.data; - if (!mail.length) { + if (!res.data.length) { this.state = null; return; } - this.state = mail[0].state; - this.reason = mail[0].reason; + const [mail] = res.data; + this.state = mail.state; + this.reason = mail.reason; }); + this.canBeResend(); } - isMailSended() { + canBeResend() { + this.canResend = false; const filter = { where: { year: this._date.getFullYear(), @@ -150,27 +154,10 @@ class Controller extends Section { }, limit: 1 }; - // no repeat request this.$http.get('WorkerTimeControlMails', {filter}) .then(res => { - if (!res.data.length) { - this.canResend = false; - return; - } - - const filter = { - where: { - workerFk: this.$params.id - }, - include: { - relation: 'department' - } - }; - this.$http.get('WorkerDepartments/findOne', {filter}) - .then(res => { - const department = res.data.department; - if (department.isTeleworking) this.canResend = true; - }); + if (res.data.length) + this.canResend = true; }); } @@ -389,30 +376,25 @@ class Controller extends Section { } isSatisfied() { - const params = { - workerId: this.worker.id, - year: this.date.getFullYear(), - week: this.weekNumber, - state: 'CONFIRMED' - }; - const query = `WorkerTimeControls/updateWorkerTimeControlMail`; - this.$http.post(query, params).then(() => { - this.getMailStates(this.date); - this.getWeekData(); - this.vnApp.showSuccess(this.$t('Data saved!')); - }); + this.updateWorkerTimeControlMail('CONFIRMED'); } isUnsatisfied() { if (!this.reason) throw new UserError(`You must indicate a reason`); + this.updateWorkerTimeControlMail('REVISE', this.reason); + } + updateWorkerTimeControlMail(state, reason) { const params = { workerId: this.worker.id, year: this.date.getFullYear(), week: this.weekNumber, - state: 'REVISE', - reason: this.reason + state }; + + if (reason) + params.reason = reason; + const query = `WorkerTimeControls/updateWorkerTimeControlMail`; this.$http.post(query, params).then(() => { this.getMailStates(this.date); From f8a510b330e6dc331ab986bbc7bfc79ce68530d4 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 4 Oct 2023 12:31:46 +0200 Subject: [PATCH 056/449] refs #5918 fix(workerTimeControl): update(workerTimeControl --- .../methods/worker-time-control/updateWorkerTimeControlMail.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js b/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js index 4e41a5bdd0..3594f05fe0 100644 --- a/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js +++ b/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js @@ -72,7 +72,7 @@ module.exports = Self => { if (args.state == 'SENDED') { await workerTimeControlMail.updateAttributes({ - sendedCounter: workerTimeControlMail.sendedCounter + 1 + sendedCounter: workerTimeControlMail.sendedCounter ? workerTimeControlMail.sendedCounter + 1 : 1 }, myOptions); } }; From 8d7eda5af3307004d6dc2bdc9f42d585032282a5 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 5 Oct 2023 09:12:54 +0200 Subject: [PATCH 057/449] refs #5673 fix: add development translation --- modules/claim/front/locale/es.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/claim/front/locale/es.yml b/modules/claim/front/locale/es.yml index f6dac2b838..83ccf1e7bf 100644 --- a/modules/claim/front/locale/es.yml +++ b/modules/claim/front/locale/es.yml @@ -17,6 +17,7 @@ Search claim by id or client name: Buscar reclamaciones por identificador o nomb Claim deleted!: Reclamación eliminada! claim: reclamación Photos: Fotos +Development: Trazabilidad Go to the claim: Ir a la reclamación Sale tracking: Líneas preparadas Ticket tracking: Estados del ticket From 726bc26a7529434b574cda5dc6c08f08b064b38e Mon Sep 17 00:00:00 2001 From: jgallego Date: Thu, 5 Oct 2023 09:40:05 +0200 Subject: [PATCH 058/449] fixes #6260 vn-user quito campos redundantes --- back/models/vn-user.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 9e3f8df891..f5eb3ae0f0 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -23,10 +23,6 @@ "columnName": "name" } }, - "password": { - "type": "string", - "required": true - }, "roleFk": { "type": "number", "mysql": { @@ -42,9 +38,6 @@ "active": { "type": "boolean" }, - "email": { - "type": "string" - }, "created": { "type": "date" }, From f40185c2d4577dc61e792d5c69cd0942c28a3ecb Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 5 Oct 2023 14:24:52 +0200 Subject: [PATCH 059/449] refs #4764 hotfix --- modules/ticket/front/services/index.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/ticket/front/services/index.html b/modules/ticket/front/services/index.html index bc288a8a23..5128873c44 100644 --- a/modules/ticket/front/services/index.html +++ b/modules/ticket/front/services/index.html @@ -29,7 +29,7 @@ disabled="watcher.dataChanged() || !$ctrl.checkeds.length" label="Pay" ng-click="$ctrl.createRefund()" - vn-acl="invoicing, claimManager, salesAssistant" + vn-acl="invoicing, claimManager, salesAssistant, buyer" vn-acl-action="remove"> @@ -37,7 +37,9 @@ + disabled="!service.id" + vn-acl="invoicing, claimManager, salesAssistant, buyer" + vn-acl-action="remove"> + step="0.01" + min="0"> Date: Thu, 5 Oct 2023 15:04:39 +0200 Subject: [PATCH 060/449] refs #4764 fixReport --- print/templates/reports/delivery-note/delivery-note.html | 2 +- print/templates/reports/delivery-note/sql/services.sql | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/print/templates/reports/delivery-note/delivery-note.html b/print/templates/reports/delivery-note/delivery-note.html index 0be5a30f0f..92dd1b126e 100644 --- a/print/templates/reports/delivery-note/delivery-note.html +++ b/print/templates/reports/delivery-note/delivery-note.html @@ -117,7 +117,7 @@ {{service.price | currency('EUR', $i18n.locale)}} {{service.taxDescription}} - {{service.price | currency('EUR', $i18n.locale)}} + {{service.total | currency('EUR', $i18n.locale)}} diff --git a/print/templates/reports/delivery-note/sql/services.sql b/print/templates/reports/delivery-note/sql/services.sql index d64e8dc26d..ec8a3e7aca 100644 --- a/print/templates/reports/delivery-note/sql/services.sql +++ b/print/templates/reports/delivery-note/sql/services.sql @@ -1,8 +1,9 @@ SELECT tc.code taxDescription, ts.description, - ts.quantity, - ts.price + ts.quantity, + ts.price, + ts.quantity * ts.price total FROM ticketService ts JOIN taxClass tc ON tc.id = ts.taxClassFk WHERE ts.ticketFk = ? \ No newline at end of file From 2c2fa97631466ebd06e52955b5507071d392b569 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 5 Oct 2023 15:35:59 +0200 Subject: [PATCH 061/449] refs #4764 ticketRefound --- db/changes/234002/00-saleRefundACL.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 db/changes/234002/00-saleRefundACL.sql diff --git a/db/changes/234002/00-saleRefundACL.sql b/db/changes/234002/00-saleRefundACL.sql new file mode 100644 index 0000000000..62a8113d3b --- /dev/null +++ b/db/changes/234002/00-saleRefundACL.sql @@ -0,0 +1,2 @@ +INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) + VALUES ('Sale','refund','WRITE','ALLOW','ROLE','buyer'); From 674fefeab5eabc02f8371fe7296cbbeb93e19fc8 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 5 Oct 2023 15:43:02 +0200 Subject: [PATCH 062/449] refs #4764 ticket --- db/changes/234002/00-saleRefundACL.sql | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 db/changes/234002/00-saleRefundACL.sql diff --git a/db/changes/234002/00-saleRefundACL.sql b/db/changes/234002/00-saleRefundACL.sql deleted file mode 100644 index 62a8113d3b..0000000000 --- a/db/changes/234002/00-saleRefundACL.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) - VALUES ('Sale','refund','WRITE','ALLOW','ROLE','buyer'); From 62c7dc9db567160d2e750e18dca3ca266b8d6732 Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 6 Oct 2023 06:16:42 +0200 Subject: [PATCH 063/449] hotfix-change minus --- modules/ticket/back/methods/sale/refund.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 3c41aab1ed..67172f3aca 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -114,8 +114,8 @@ module.exports = Self => { for (const service of services) { await models.TicketService.create({ description: service.description, - quantity: service.quantity, - price: - service.price, + quantity: - service.quantity, + price: service.price, taxClassFk: service.taxClassFk, ticketFk: refundTicket.id, ticketServiceTypeFk: service.ticketServiceTypeFk, From 05812c3f35dab91bc898bd57a592e15f3634c456 Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 6 Oct 2023 07:14:30 +0200 Subject: [PATCH 064/449] refs #6282 left join --- modules/worker/back/methods/worker/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/methods/worker/search.js b/modules/worker/back/methods/worker/search.js index cd0a466ea7..7fe9e0666d 100644 --- a/modules/worker/back/methods/worker/search.js +++ b/modules/worker/back/methods/worker/search.js @@ -46,7 +46,7 @@ module.exports = Self => { SELECT DISTINCT w.id, w.code, u.name, u.nickname, u.active, b.departmentFk FROM worker w JOIN account.user u ON u.id = w.id - JOIN business b ON b.workerFk = w.id + LEFT JOIN business b ON b.workerFk = w.id ) w`); stmt.merge(conn.makeSuffix(filter)); From 1adfa33a9a893b8ed17b3a815290598249e3ce0b Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 6 Oct 2023 14:52:30 +0200 Subject: [PATCH 065/449] hotfix length sales --- modules/ticket/back/methods/sale/refund.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 67172f3aca..03302550ee 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -55,7 +55,7 @@ module.exports = Self => { const refoundZoneId = refundAgencyMode.zones()[0].id; - if (salesIds) { + if (salesIds.length) { const salesFilter = { where: {id: {inq: salesIds}}, include: { @@ -91,16 +91,14 @@ module.exports = Self => { await models.SaleComponent.create(components, myOptions); } } - if (!refundTicket) { const servicesFilter = { where: {id: {inq: servicesIds}} }; const services = await models.TicketService.find(servicesFilter, myOptions); - const ticketsIds = [...new Set(services.map(service => service.ticketFk))]; + const firstTicketId = services[0].ticketFk; const now = Date.vnNew(); - const [firstTicketId] = ticketsIds; // eslint-disable-next-line max-len refundTicket = await createTicketRefund(firstTicketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions); From 03afea3b8e633ed668a7d38bb299054bf4f056f1 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 10 Oct 2023 10:51:02 +0200 Subject: [PATCH 066/449] refs #6199 Added minQuantity in item --- modules/item/back/models/item.json | 3 +++ modules/item/front/basic-data/index.html | 9 +++++++++ modules/item/front/summary/index.html | 3 +++ 3 files changed, 15 insertions(+) diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json index e99dcd9961..8a635ea7e8 100644 --- a/modules/item/back/models/item.json +++ b/modules/item/back/models/item.json @@ -131,6 +131,9 @@ "nonRecycledPlastic": { "type": "number" }, + "minQuantity": { + "type": "number" + }, "packingOut": { "type": "number" }, diff --git a/modules/item/front/basic-data/index.html b/modules/item/front/basic-data/index.html index fba4d679c1..d3b30a7c27 100644 --- a/modules/item/front/basic-data/index.html +++ b/modules/item/front/basic-data/index.html @@ -183,6 +183,15 @@ rule> + + + + + +

From d2ce920f13ea8aa2e7857de2951b43a38654fad3 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 10 Oct 2023 13:49:11 +0200 Subject: [PATCH 067/449] refs #6199 Added minQuantity in catalog and more --- modules/item/front/basic-data/index.html | 2 +- modules/item/front/basic-data/locale/es.yml | 3 +- modules/item/front/summary/locale/es.yml | 1 + .../order/back/methods/order/catalogFilter.js | 43 ++++++++++--------- modules/order/front/catalog-view/index.html | 13 ++++++ .../order/front/catalog-view/locale/es.yml | 1 + 6 files changed, 40 insertions(+), 23 deletions(-) diff --git a/modules/item/front/basic-data/index.html b/modules/item/front/basic-data/index.html index d3b30a7c27..f412626bf0 100644 --- a/modules/item/front/basic-data/index.html +++ b/modules/item/front/basic-data/index.html @@ -185,7 +185,7 @@ { )); stmt = new ParameterizedSQL(` - SELECT - i.id, - i.name, - i.subName, - i.image, - i.tag5, - i.value5, - i.tag6, - i.value6, - i.tag7, - i.value7, - i.tag8, - i.value8, - i.stars, - tci.price, - tci.available, - w.lastName AS lastName, - w.firstName, - tci.priceKg, - ink.hex + SELECT i.id, + i.name, + i.subName, + i.image, + i.tag5, + i.value5, + i.tag6, + i.value6, + i.tag7, + i.value7, + i.tag8, + i.value8, + i.stars, + tci.price, + tci.available, + w.lastName lastName, + w.firstName, + tci.priceKg, + ink.hex, + i.minQuantity FROM tmp.ticketCalculateItem tci JOIN vn.item i ON i.id = tci.itemFk JOIN vn.itemType it ON it.id = i.typeFk JOIN vn.worker w on w.id = it.workerFk - LEFT JOIN vn.ink ON ink.id = i.inkFk`); + LEFT JOIN vn.ink ON ink.id = i.inkFk + `); // Apply order by tag if (orderBy.isTag) { diff --git a/modules/order/front/catalog-view/index.html b/modules/order/front/catalog-view/index.html index fca7288555..9333e923bc 100644 --- a/modules/order/front/catalog-view/index.html +++ b/modules/order/front/catalog-view/index.html @@ -37,6 +37,19 @@ value="{{::item.value7}}"> +
+ + + {{::item.minQuantity}} +
diff --git a/modules/order/front/catalog-view/locale/es.yml b/modules/order/front/catalog-view/locale/es.yml index 82fe5e9e8a..8fb3c78960 100644 --- a/modules/order/front/catalog-view/locale/es.yml +++ b/modules/order/front/catalog-view/locale/es.yml @@ -1 +1,2 @@ Order created: Orden creada +Minimal quantity: Cantidad mínima \ No newline at end of file From 2b41bf7eb14744a618119e878f9ca302633e7c74 Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 11 Oct 2023 07:39:41 +0200 Subject: [PATCH 068/449] refs #6199 Requested changes --- modules/item/front/basic-data/locale/es.yml | 2 +- modules/order/back/methods/order/catalogFilter.js | 2 +- modules/order/front/catalog-view/index.html | 12 +++++------- modules/order/front/catalog-view/style.scss | 10 ++++++++++ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/modules/item/front/basic-data/locale/es.yml b/modules/item/front/basic-data/locale/es.yml index 51cbdabd91..fc490e4481 100644 --- a/modules/item/front/basic-data/locale/es.yml +++ b/modules/item/front/basic-data/locale/es.yml @@ -15,5 +15,5 @@ Generic: Genérico This item does need a photo: Este artículo necesita una foto Do photo: Hacer foto Recycled Plastic: Plástico reciclado -Non recycled plastic: Plástico no +Non recycled plastic: Plástico no reciclado Minimum sales quantity: Cantidad mínima de venta diff --git a/modules/order/back/methods/order/catalogFilter.js b/modules/order/back/methods/order/catalogFilter.js index dca82322a7..722f3e0966 100644 --- a/modules/order/back/methods/order/catalogFilter.js +++ b/modules/order/back/methods/order/catalogFilter.js @@ -115,7 +115,7 @@ module.exports = Self => { i.stars, tci.price, tci.available, - w.lastName lastName, + w.lastName, w.firstName, tci.priceKg, ink.hex, diff --git a/modules/order/front/catalog-view/index.html b/modules/order/front/catalog-view/index.html index 9333e923bc..c9375aab55 100644 --- a/modules/order/front/catalog-view/index.html +++ b/modules/order/front/catalog-view/index.html @@ -37,16 +37,14 @@ value="{{::item.value7}}"> -
+
+ ng-class="'min-quantity-icon'"> {{::item.minQuantity}}
diff --git a/modules/order/front/catalog-view/style.scss b/modules/order/front/catalog-view/style.scss index 87f70cde56..8288855a44 100644 --- a/modules/order/front/catalog-view/style.scss +++ b/modules/order/front/catalog-view/style.scss @@ -44,4 +44,14 @@ vn-order-catalog { height: 30px; position: relative; } + .text-caption-reduced { + display: flex; + align-items: center; + justify-content: flex-end; + color: tomato; + } + .min-quantity-icon { + font-size: 18px; + margin-right: 3px; + } } \ No newline at end of file From d41233efaf9da5fb7b8065085ede26fe38c4ecee Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 11 Oct 2023 07:59:05 +0200 Subject: [PATCH 069/449] refs #6199 Requested change, name of color --- modules/order/front/catalog-view/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/order/front/catalog-view/style.scss b/modules/order/front/catalog-view/style.scss index 8288855a44..abfde3589f 100644 --- a/modules/order/front/catalog-view/style.scss +++ b/modules/order/front/catalog-view/style.scss @@ -48,7 +48,7 @@ vn-order-catalog { display: flex; align-items: center; justify-content: flex-end; - color: tomato; + color: $color-alert; } .min-quantity-icon { font-size: 18px; From 6b1dded2225645da60e45cda1a8be567af8cb4a1 Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 11 Oct 2023 08:28:52 +0200 Subject: [PATCH 070/449] refs #6199 Requested change, position of input --- modules/item/front/basic-data/index.html | 66 ++++++++++++------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/modules/item/front/basic-data/index.html b/modules/item/front/basic-data/index.html index f412626bf0..426c178006 100644 --- a/modules/item/front/basic-data/index.html +++ b/modules/item/front/basic-data/index.html @@ -33,6 +33,8 @@ rule info="Full name calculates based on tags 1-3. Is not recommended to change it manually"> + + + + +
{{::name}}
+
+ #{{::id}} +
+
+ + + + +
- - -
{{::name}}
-
- #{{::id}} -
-
- - - - -
+ +
- - - - Date: Wed, 11 Oct 2023 12:04:12 +0200 Subject: [PATCH 071/449] =?UTF-8?q?refs=20#6293=20traducci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ticket/front/index/locale/es.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/ticket/front/index/locale/es.yml b/modules/ticket/front/index/locale/es.yml index afa3d654e9..89828d4d96 100644 --- a/modules/ticket/front/index/locale/es.yml +++ b/modules/ticket/front/index/locale/es.yml @@ -18,3 +18,4 @@ Multiple invoice: Factura múltiple Make invoice...: Crear factura... Invoice selected tickets: Facturar tickets seleccionados Are you sure to invoice tickets: ¿Seguro que quieres facturar {{ticketsAmount}} tickets? +Rounding: Redondeo From 104d11ac3c1d3a2c39174782c1bc0b7f76847a78 Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 13 Oct 2023 08:52:28 +0200 Subject: [PATCH 072/449] refs #3126 procReplace --- db/.archive/231001/03-packagingFkProc.sql | 669 -------- .../234001}/00-packagingFk.sql | 0 .../234001}/00-packagingFkviews.sql | 0 .../234001}/02-packagingFktrigger.sql | 0 db/changes/234001/03-packagingFkProc.sql | 1381 +++++++++++++++++ 5 files changed, 1381 insertions(+), 669 deletions(-) delete mode 100644 db/.archive/231001/03-packagingFkProc.sql rename db/{.archive/231001 => changes/234001}/00-packagingFk.sql (100%) rename db/{.archive/231001 => changes/234001}/00-packagingFkviews.sql (100%) rename db/{.archive/231001 => changes/234001}/02-packagingFktrigger.sql (100%) create mode 100644 db/changes/234001/03-packagingFkProc.sql diff --git a/db/.archive/231001/03-packagingFkProc.sql b/db/.archive/231001/03-packagingFkProc.sql deleted file mode 100644 index acbf54a763..0000000000 --- a/db/.archive/231001/03-packagingFkProc.sql +++ /dev/null @@ -1,669 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`travelVolume`(vTravelFk INT) -BEGIN - - SELECT w1.name AS ORI, - w2.name AS DES, - tr.shipped shipment, - tr.landed landing, - a.name Agencia, - s.name Proveedor, - e.id Id_Entrada, - e.invoiceNumber Referencia, - CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * - vn.item_getVolume(b.itemFk ,b.packagingFk)) / vc.trolleyM3 / 1000000 ,1) AS DECIMAL(10,2)) AS CC, - CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * - vn.item_getVolume(b.itemFk ,b.packagingFk)) / vc.palletM3 / 1000000,1) AS DECIMAL(10,2)) AS espais - FROM vn.buy b - JOIN vn.entry e ON e.id = b.entryFk - JOIN vn.supplier s ON s.id = e.supplierFk - JOIN vn.travel tr ON tr.id = e.travelFk - JOIN vn.agencyMode a ON a.id = tr.agencyModeFk - JOIN vn.warehouse w1 ON w1.id = tr.warehouseInFk - JOIN vn.warehouse w2 ON w2.id = tr.warehouseOutFk - JOIN vn.volumeConfig vc - JOIN vn.item i ON i.id = b.itemFk - JOIN vn.itemType it ON it.id = i.typeFk - WHERE tr.id = vTravelFk; - -END$$ -DELIMITER ; - -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`travelVolume_get`(vFromDated DATE, vToDated DATE, vWarehouseFk INT) -BEGIN - SELECT tr.landed Fecha, - a.name Agencia, - count(DISTINCT e.id) numEntradas, - FLOOR(sum(item_getVolume(b.itemFk, b.packagingFk) * b.stickers / 1000000 )) AS m3 - FROM vn.travel tr - JOIN vn.agencyMode a ON a.id = tr.agencyModeFk - JOIN vn.entry e ON e.travelFk = tr.id - JOIN vn.buy b ON b.entryFk = e.id - WHERE tr.landed BETWEEN vFromDated AND vToDated - AND e.isRaid = FALSE - AND tr.warehouseInFk = vWarehouseFk - GROUP BY tr.landed , a.name ; -END$$ -DELIMITER ; - -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`travel_getEntriesMissingPackage`(vSelf INT) -BEGIN - DECLARE vpackageOrPackingNull INT; - DECLARE vTravelFk INT; - - SELECT travelfk INTO vTravelFk - FROM entry - WHERE id = vSelf; - - SELECT e.id entryFk - FROM travel t - JOIN entry e ON e.travelFk = t.id - JOIN buy b ON b.entryFk = e.id - WHERE t.id = vTravelFk - AND (b.packing IS NULL OR b.packagingFk IS NULL); -END$$ -DELIMITER ; - -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticketBoxesView`(IN vTicketFk INT) -BEGIN - - SELECT s.id, - s.itemFk, - s.concept, - floor(s.quantity / b.packing) as Cajas, - b.packing, - s.isPicked, - i.size - FROM ticket t - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - JOIN cache.last_buy lb on lb.warehouse_id = t.warehouseFk AND lb.item_id = s.itemFk - JOIN buy b on b.id = lb.buy_id - JOIN packaging p on p.id = b.packagingFk - WHERE s.quantity >= b.packing - AND t.id = vTicketFk - AND p.isBox - GROUP BY s.itemFk; - - -END$$ -DELIMITER ; - -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`stockBuyedByWorker`( - vDate DATE, - vWorker INT) -BEGIN -/** - * Calculates the space reserved by buyers of the same container - * - * @param vdate date of container delivery - * @param vWorker buyer reserving space in the container - */ - DECLARE vVolume DECIMAL(10, 2); - DECLARE vWarehouseFk INT; - DECLARE vCompressionRatio DECIMAL(1, 1); - - CALL stockTraslation(vDate); - - SELECT warehouseFk, conversionCoefficient INTO vWarehouseFk, vCompressionRatio - FROM auctionConfig; - - SELECT volume INTO vVolume - FROM vn.packaging WHERE id = 'cc'; - - SELECT b.entryFk Id_Entrada, - i.id Id_Article, - i.name Article, - ti.amount Cantidad, - (vCompressionRatio * (ti.amount / b.packing) * vn.buy_getVolume(b.id)) - / vVolume buyed, - b.packagingFk id_cubo, - b.packing - FROM tmp.item ti - JOIN item i ON i.id = ti.item_id - JOIN itemType it ON i.typeFk = it.id - JOIN itemCategory ic ON ic.id = it.categoryFk - JOIN worker w ON w.id = it.workerFk - JOIN tmp.buyUltimate bu ON bu.itemFk = i.id - AND bu.warehouseFk = vWarehouseFk - JOIN buy b ON b.id = bu.buyFk - WHERE ic.display AND w.id = vWorker; - - DROP TEMPORARY TABLE - tmp.buyUltimate, - tmp.item; -END$$ -DELIMITER ; - -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingMakeFromDate`(IN `vShelvingFk` VARCHAR(8), IN `vBarcode` VARCHAR(22), IN `vQuantity` INT, IN `vPackagingFk` VARCHAR(10), IN `vGrouping` INT, IN `vPacking` INT, IN `vWarehouseFk` INT, `vCreated` VARCHAR(22)) -BEGIN - - DECLARE vItemFk INT; - - SELECT vn.barcodeToItem(vBarcode) INTO vItemFk; - - SELECT itemFk INTO vItemFk - FROM vn.buy b - WHERE b.id = vItemFk; - - IF (SELECT COUNT(*) FROM vn.shelving WHERE code = vShelvingFk COLLATE utf8_unicode_ci) = 0 THEN - - INSERT IGNORE INTO vn.parking(`code`) VALUES(vShelvingFk); - INSERT INTO vn.shelving(`code`, parkingFk) - SELECT vShelvingFk, id - FROM vn.parking - WHERE `code` = vShelvingFk COLLATE utf8_unicode_ci; - - END IF; - - IF (SELECT COUNT(*) FROM vn.itemShelving - WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk - AND itemFk = vItemFk - AND packing = vPacking) = 1 THEN - - UPDATE vn.itemShelving - SET visible = visible+vQuantity, - created = vCreated - WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk - AND itemFk = vItemFk - AND packing = vPacking; - - ELSE - CALL cache.last_buy_refresh(FALSE); - INSERT INTO itemShelving( itemFk, - shelvingFk, - visible, - created, - `grouping`, - packing, - packagingFk) - SELECT vItemFk, - vShelvingFk, - vQuantity, - vCreated, - IF(vGrouping = 0, IFNULL(b.packing, vPacking), vGrouping) `grouping`, - IF(vPacking = 0, b.packing, vPacking) packing, - IF(vPackagingFk = '', b.packagingFk, vPackagingFk) packaging - FROM vn.item i - LEFT JOIN cache.last_buy lb ON i.id = lb.item_id AND lb.warehouse_id = vWarehouseFk - LEFT JOIN vn.buy b ON b.id = lb.buy_id - WHERE i.id = vItemFk; - END IF; - -END$$ -DELIMITER ; - -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelving_add`(IN vShelvingFk VARCHAR(8), IN vBarcode VARCHAR(22), IN vQuantity INT, IN vPackagingFk VARCHAR(10), IN vGrouping INT, IN vPacking INT, IN vWarehouseFk INT) -BEGIN - - -/** - * Añade registro o lo actualiza si ya existe. - * - * @param vShelvingFk matrícula del carro - * @param vBarcode el id del registro - * @param vQuantity indica la cantidad del producto - * @param vPackagingFk el packaging del producto en itemShelving, NULL para coger el de la ultima compra - * @param vGrouping el grouping del producto en itemShelving, NULL para coger el de la ultima compra - * @param vPacking el packing del producto, NULL para coger el de la ultima compra - * @param vWarehouseFk indica el sector - * - **/ - - DECLARE vItemFk INT; - - SELECT barcodeToItem(vBarcode) INTO vItemFk; - - IF (SELECT COUNT(*) FROM shelving WHERE code = vShelvingFk COLLATE utf8_unicode_ci) = 0 THEN - - INSERT IGNORE INTO parking(code) VALUES(vShelvingFk); - INSERT INTO shelving(code, parkingFk) - SELECT vShelvingFk, id - FROM parking - WHERE `code` = vShelvingFk COLLATE utf8_unicode_ci; - - END IF; - - IF (SELECT COUNT(*) FROM itemShelving - WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk - AND itemFk = vItemFk - AND packing = vPacking) = 1 THEN - - UPDATE itemShelving - SET visible = visible+vQuantity - WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk AND itemFk = vItemFk AND packing = vPacking; - - ELSE - CALL cache.last_buy_refresh(FALSE); - INSERT INTO itemShelving( itemFk, - shelvingFk, - visible, - grouping, - packing, - packagingFk) - - SELECT vItemFk, - vShelvingFk, - vQuantity, - IFNULL(vGrouping, b.grouping), - IFNULL(vPacking, b.packing), - IFNULL(vPackagingFk, b.packagingFk) - FROM item i - LEFT JOIN cache.last_buy lb ON i.id = lb.item_id AND lb.warehouse_id = vWarehouseFk - LEFT JOIN buy b ON b.id = lb.buy_id - WHERE i.id = vItemFk; - END IF; -END$$ -DELIMITER ; - -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemFreight_Show`(vItemFk INT, vWarehouseFk INT) -BEGIN - - SELECT cm3 Volumen_Entrada, - cm3delivery Volumen_Salida, - p.volume Volumen_del_embalaje, - p.width Ancho_del_embalaje, - p.`depth` Largo_del_embalaje, - b.packagingFk , - IFNULL(p.height, i.`size`) + 10 Altura, - b.packing Packing_Entrada, - i.packingOut Packing_Salida, - i.id itemFk, - b.id buyFk, - b.entryFk, - w.name warehouseFk - FROM vn.itemCost ic - JOIN vn.item i ON i.id = ic.itemFk - LEFT JOIN cache.last_buy lb ON lb.item_id = ic.itemFk AND lb.warehouse_id = ic.warehouseFk - LEFT JOIN vn.buy b ON b.id = lb.buy_id - LEFT JOIN vn.packaging p ON p.id = b.packagingFk - LEFT JOIN vn.warehouse w ON w.id = ic.warehouseFk - WHERE ic.itemFk = vItemFk - AND ic.warehouseFk = vWarehouseFk; -END$$ -DELIMITER ; - -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`inventoryMake`(vDate DATE, vWh INT) -proc: BEGIN -/** -* Recalcula los inventarios de todos los almacenes, si vWh = 0 -* -* @param vDate Fecha de los nuevos inventarios -* @param vWh almacen al cual hacer el inventario -*/ - - DECLARE vDone BOOL; - DECLARE vEntryFk INT; - DECLARE vTravelFk INT; - DECLARE vDateLastInventory DATE; - DECLARE vDateYesterday DATETIME DEFAULT vDate - INTERVAL 1 SECOND; - DECLARE vWarehouseOutFkInventory INT; - DECLARE vInventorySupplierFk INT; - DECLARE vAgencyModeFkInventory INT; - - DECLARE cWarehouses CURSOR FOR - SELECT id - FROM warehouse - WHERE isInventory - AND vWh IN (0,id); - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - - OPEN cWarehouses; - SET @isModeInventory := TRUE; - l: LOOP - - SET vDone = FALSE; - FETCH cWarehouses INTO vWh; - - IF vDone THEN - LEAVE l; - END IF; - - SELECT w.id INTO vWarehouseOutFkInventory - FROM warehouse w - WHERE w.code = 'inv'; - - SELECT inventorySupplierFk INTO vInventorySupplierFk - FROM entryConfig; - - SELECT am.id INTO vAgencyModeFkInventory - FROM agencyMode am - where code = 'inv'; - - SELECT MAX(landed) INTO vDateLastInventory - FROM travel tr - JOIN entry e ON e.travelFk = tr.id - JOIN buy b ON b.entryFk = e.id - WHERE warehouseOutFk = vWarehouseOutFkInventory - AND landed < vDate - AND e.supplierFk = vInventorySupplierFk - AND warehouseInFk = vWh - AND NOT isRaid; - - IF vDateLastInventory IS NULL THEN - SELECT inventoried INTO vDateLastInventory FROM config; - END IF; - - -- Generamos travel, si no existe. - SET vTravelFK = 0; - - SELECT id INTO vTravelFk - FROM travel - WHERE warehouseOutFk = vWarehouseOutFkInventory - AND warehouseInFk = vWh - AND landed = vDate - AND agencyModeFk = vAgencyModeFkInventory - AND ref = 'inventario' - LIMIT 1; - - IF NOT vTravelFK THEN - - INSERT INTO travel SET - warehouseOutFk = vWarehouseOutFkInventory, - warehouseInFk = vWh, - shipped = vDate, - landed = vDate, - agencyModeFk = vAgencyModeFkInventory, - ref = 'inventario', - isDelivered = TRUE, - isReceived = TRUE; - - SELECT LAST_INSERT_ID() INTO vTravelFk; - - END IF; - - -- Generamos entrada si no existe, o la vaciamos. - SET vEntryFk = 0; - - SELECT id INTO vEntryFk - FROM entry - WHERE supplierFk = vInventorySupplierFk - AND travelFk = vTravelFk; - - IF NOT vEntryFk THEN - - INSERT INTO entry SET - supplierFk = vInventorySupplierFk, - isConfirmed = TRUE, - isOrdered = TRUE, - travelFk = vTravelFk; - - SELECT LAST_INSERT_ID() INTO vEntryFk; - - ELSE - - DELETE FROM buy WHERE entryFk = vEntryFk; - - END IF; - - -- Preparamos tabla auxilar - CREATE OR REPLACE TEMPORARY TABLE tmp.inventory ( - itemFk INT(11) NOT NULL PRIMARY KEY, - quantity int(11) DEFAULT '0', - buyingValue decimal(10,3) DEFAULT '0.000', - freightValue decimal(10,3) DEFAULT '0.000', - packing int(11) DEFAULT '0', - `grouping` smallint(5) unsigned NOT NULL DEFAULT '1', - groupingMode tinyint(4) NOT NULL DEFAULT 0 , - comissionValue decimal(10,3) DEFAULT '0.000', - packageValue decimal(10,3) DEFAULT '0.000', - packageFk varchar(10) COLLATE utf8_unicode_ci DEFAULT '--', - price1 decimal(10,2) DEFAULT '0.00', - price2 decimal(10,2) DEFAULT '0.00', - price3 decimal(10,2) DEFAULT '0.00', - minPrice decimal(10,2) DEFAULT '0.00', - producer varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, - INDEX (itemFK)) ENGINE = MEMORY; - - -- Compras - INSERT INTO tmp.inventory(itemFk,quantity) - SELECT b.itemFk, SUM(b.quantity) - FROM buy b - JOIN entry e ON e.id = b.entryFk - JOIN travel tr ON tr.id = e.travelFk - WHERE tr.warehouseInFk = vWh - AND tr.landed BETWEEN vDateLastInventory - AND vDateYesterday - AND NOT isRaid - GROUP BY b.itemFk; - SELECT vDateLastInventory , vDateYesterday; - - -- Traslados - INSERT INTO tmp.inventory(itemFk, quantity) - SELECT itemFk, quantityOut - FROM ( - SELECT b.itemFk,- SUM(b.quantity) quantityOut - FROM buy b - JOIN entry e ON e.id = b.entryFk - JOIN travel tr ON tr.id = e.travelFk - WHERE tr.warehouseOutFk = vWh - AND tr.shipped BETWEEN vDateLastInventory - AND vDateYesterday - AND NOT isRaid - GROUP BY b.itemFk - ) sub - ON DUPLICATE KEY UPDATE quantity = IFNULL(quantity, 0) + sub.quantityOut; - - -- Ventas - INSERT INTO tmp.inventory(itemFk,quantity) - SELECT itemFk, saleOut - FROM ( - SELECT s.itemFk, - SUM(s.quantity) saleOut - FROM sale s - JOIN ticket t ON t.id = s.ticketFk - WHERE t.warehouseFk = vWh - AND t.shipped BETWEEN vDateLastInventory AND vDateYesterday - GROUP BY s.itemFk - ) sub - ON DUPLICATE KEY UPDATE quantity = IFNULL(quantity,0) + sub.saleOut; - - -- Actualiza valores de la ultima compra - UPDATE tmp.inventory inv - JOIN cache.last_buy lb ON lb.item_id = inv.itemFk AND lb.warehouse_id = vWh - JOIN buy b ON b.id = lb.buy_id - JOIN item i ON i.id = b.itemFk - LEFT JOIN producer p ON p.id = i.producerFk - SET inv.buyingValue = b.buyingValue, - inv.freightValue = b.freightValue, - inv.packing = b.packing, - inv.`grouping`= b.`grouping`, - inv.groupingMode = b.groupingMode, - inv.comissionValue = b.comissionValue, - inv.packageValue = b.packageValue, - inv.packageFk = b.packagingFk, - inv.price1 = b.price1, - inv.price2 = b.price2, - inv.price3 = b.price3, - inv.minPrice = b.minPrice, - inv.producer = p.name; - - INSERT INTO buy( itemFk, - quantity, - buyingValue, - freightValue, - packing, - `grouping`, - groupingMode, - comissionValue, - packageValue, - packagingFk, - price1, - price2, - price3, - minPrice, - entryFk) - SELECT itemFk, - GREATEST(quantity, 0), - buyingValue, - freightValue, - packing, - `grouping`, - groupingMode, - comissionValue, - packageValue, - packagingFk, - price1, - price2, - price3, - minPrice, - vEntryFk - FROM tmp.inventory; - - SELECT vWh, COUNT(*), util.VN_NOW() FROM tmp.inventory; - - -- Actualizamos el campo lastUsed de item - UPDATE item i - JOIN tmp.inventory i2 ON i2.itemFk = i.id - SET i.lastUsed = NOW() - WHERE i2.quantity; - - -- DROP TEMPORARY TABLE tmp.inventory; - - END LOOP; - - CLOSE cWarehouses; - - UPDATE config SET inventoried = vDate; - SET @isModeInventory := FALSE; - - DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete; - CREATE TEMPORARY TABLE tmp.entryToDelete - (INDEX(entryId) USING BTREE) ENGINE = MEMORY - SELECT e.id as entryId, - t.id as travelId - FROM travel t - JOIN `entry` e ON e.travelFk = t.id - WHERE e.supplierFk = vInventorySupplierFk - AND t.shipped <= util.VN_CURDATE() - INTERVAL 12 DAY - AND (DAY(t.shipped) <> 1 OR shipped < util.VN_CURDATE() - INTERVAL 12 DAY); - - DELETE e - FROM `entry` e - JOIN tmp.entryToDelete tmp ON tmp.entryId = e.id; - - DELETE IGNORE t - FROM travel t - JOIN tmp.entryToDelete tmp ON tmp.travelId = t.id; -END$$ -DELIMITER ; - -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`inventory_repair`() -BEGIN - - DROP TEMPORARY TABLE IF EXISTS tmp.lastEntry; - CREATE TEMPORARY TABLE tmp.lastEntry - (PRIMARY KEY (buyFk)) - SELECT - i.id AS itemFk, - w.id AS warehouseFk, - w.name AS warehouse, - tr.landed, - b.id AS buyFk, - b.entryFk, - b.isIgnored, - b.price2, - b.price3, - b.stickers, - b.packing, - b.grouping, - b.groupingMode, - b.weight, - i.stems, - b.quantity, - b.buyingValue, - b.packagingFk , - s.id AS supplierFk, - s.name AS supplier - FROM itemType it - RIGHT JOIN (entry e - LEFT JOIN supplier s ON s.id = e.supplierFk - RIGHT JOIN buy b ON b.entryFk = e.id - LEFT JOIN item i ON i.id = b.itemFk - LEFT JOIN ink ON ink.id = i.inkFk - LEFT JOIN travel tr ON tr.id = e.travelFk - LEFT JOIN warehouse w ON w.id = tr.warehouseInFk - LEFT JOIN origin o ON o.id = i.originFk - ) ON it.id = i.typeFk - LEFT JOIN edi.ekt ek ON b.ektFk = ek.id - WHERE (b.packagingFk = "--" OR b.price2 = 0 OR b.packing = 0 OR b.buyingValue = 0) AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-1,util.VN_CURDATE())) AND s.name = 'INVENTARIO'; - - DROP TEMPORARY TABLE IF EXISTS tmp.lastEntryOk; - CREATE TEMPORARY TABLE tmp.lastEntryOk - (PRIMARY KEY (buyFk)) - SELECT - i.id AS itemFk, - w.id AS warehouseFk, - w.name AS warehouse, - tr.landed, - b.id AS buyFk, - b.entryFk, - b.isIgnored, - b.price2, - b.price3, - b.stickers, - b.packing, - b.grouping, - b.groupingMode, - b.weight, - i.stems, - b.quantity, - b.buyingValue, - b.packagingFk, - s.id AS supplierFk, - s.name AS supplier - FROM itemType it - RIGHT JOIN (entry e - LEFT JOIN supplier s ON s.id = e.supplierFk - RIGHT JOIN buy b ON b.entryFk = e.id - LEFT JOIN item i ON i.id = b.itemFk - LEFT JOIN ink ON ink.id = i.inkFk - LEFT JOIN travel tr ON tr.id = e.travelFk - LEFT JOIN warehouse w ON w.id = tr.warehouseInFk - LEFT JOIN origin o ON o.id = i.originFk - ) ON it.id = i.typeFk - LEFT JOIN edi.ekt ek ON b.ektFk = ek.id - WHERE b.packagingFk != "--" AND b.price2 != 0 AND b.packing != 0 AND b.buyingValue > 0 AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-2,util.VN_CURDATE())) - ORDER BY tr.landed DESC; - - DROP TEMPORARY TABLE IF EXISTS tmp.lastEntryOkGroup; - CREATE TEMPORARY TABLE tmp.lastEntryOkGroup - (INDEX (warehouseFk,itemFk)) - SELECT * - FROM tmp.lastEntryOk tmp - GROUP BY tmp.itemFk,tmp.warehouseFk; - - UPDATE buy b - JOIN tmp.lastEntry lt ON lt.buyFk = b.id - JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk - SET b.packagingFk = eo.packagingFk WHERE b.packagingFk = "--"; - - UPDATE buy b - JOIN tmp.lastEntry lt ON lt.buyFk = b.id - JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk - SET b.price2 = eo.price2 WHERE b.price2 = 0 ; - - UPDATE buy b - JOIN tmp.lastEntry lt ON lt.buyFk = b.id - JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk - SET b.packing = eo.packing WHERE b.packing = 0; - - UPDATE buy b - JOIN tmp.lastEntry lt ON lt.buyFk = b.id - JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk - SET b.buyingValue = eo.buyingValue WHERE b.buyingValue = 0; - - DROP TEMPORARY TABLE tmp.lastEntry; - DROP TEMPORARY TABLE tmp.lastEntryOk; - DROP TEMPORARY TABLE tmp.lastEntryOkGroup; -END$$ -DELIMITER ; \ No newline at end of file diff --git a/db/.archive/231001/00-packagingFk.sql b/db/changes/234001/00-packagingFk.sql similarity index 100% rename from db/.archive/231001/00-packagingFk.sql rename to db/changes/234001/00-packagingFk.sql diff --git a/db/.archive/231001/00-packagingFkviews.sql b/db/changes/234001/00-packagingFkviews.sql similarity index 100% rename from db/.archive/231001/00-packagingFkviews.sql rename to db/changes/234001/00-packagingFkviews.sql diff --git a/db/.archive/231001/02-packagingFktrigger.sql b/db/changes/234001/02-packagingFktrigger.sql similarity index 100% rename from db/.archive/231001/02-packagingFktrigger.sql rename to db/changes/234001/02-packagingFktrigger.sql diff --git a/db/changes/234001/03-packagingFkProc.sql b/db/changes/234001/03-packagingFkProc.sql new file mode 100644 index 0000000000..4876c270ec --- /dev/null +++ b/db/changes/234001/03-packagingFkProc.sql @@ -0,0 +1,1381 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`travelVolume`(vTravelFk INT) +BEGIN + + SELECT w1.name AS ORI, + w2.name AS DES, + tr.shipped shipment, + tr.landed landing, + a.name Agencia, + s.name Proveedor, + e.id Id_Entrada, + e.invoiceNumber Referencia, + CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * + vn.item_getVolume(b.itemFk ,b.packagingFk)) / vc.trolleyM3 / 1000000 ,1) AS DECIMAL(10,2)) AS CC, + CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * + vn.item_getVolume(b.itemFk ,b.packagingFk)) / vc.palletM3 / 1000000,1) AS DECIMAL(10,2)) AS espais + FROM vn.buy b + JOIN vn.entry e ON e.id = b.entryFk + JOIN vn.supplier s ON s.id = e.supplierFk + JOIN vn.travel tr ON tr.id = e.travelFk + JOIN vn.agencyMode a ON a.id = tr.agencyModeFk + JOIN vn.warehouse w1 ON w1.id = tr.warehouseInFk + JOIN vn.warehouse w2 ON w2.id = tr.warehouseOutFk + JOIN vn.volumeConfig vc + JOIN vn.item i ON i.id = b.itemFk + JOIN vn.itemType it ON it.id = i.typeFk + WHERE tr.id = vTravelFk; + +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`travelVolume_get`(vFromDated DATE, vToDated DATE, vWarehouseFk INT) +BEGIN + SELECT tr.landed Fecha, + a.name Agencia, + count(DISTINCT e.id) numEntradas, + FLOOR(sum(item_getVolume(b.itemFk, b.packagingFk) * b.stickers / 1000000 )) AS m3 + FROM vn.travel tr + JOIN vn.agencyMode a ON a.id = tr.agencyModeFk + JOIN vn.entry e ON e.travelFk = tr.id + JOIN vn.buy b ON b.entryFk = e.id + WHERE tr.landed BETWEEN vFromDated AND vToDated + AND e.isRaid = FALSE + AND tr.warehouseInFk = vWarehouseFk + GROUP BY tr.landed , a.name ; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`travel_getEntriesMissingPackage`(vSelf INT) +BEGIN + DECLARE vpackageOrPackingNull INT; + DECLARE vTravelFk INT; + + SELECT travelfk INTO vTravelFk + FROM entry + WHERE id = vSelf; + + SELECT e.id entryFk + FROM travel t + JOIN entry e ON e.travelFk = t.id + JOIN buy b ON b.entryFk = e.id + WHERE t.id = vTravelFk + AND (b.packing IS NULL OR b.packagingFk IS NULL); +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticketBoxesView`(IN vTicketFk INT) +BEGIN + + SELECT s.id, + s.itemFk, + s.concept, + floor(s.quantity / b.packing) as Cajas, + b.packing, + s.isPicked, + i.size + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN cache.last_buy lb on lb.warehouse_id = t.warehouseFk AND lb.item_id = s.itemFk + JOIN buy b on b.id = lb.buy_id + JOIN packaging p on p.id = b.packagingFk + WHERE s.quantity >= b.packing + AND t.id = vTicketFk + AND p.isBox + GROUP BY s.itemFk; + + +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`stockBuyedByWorker`( + vDated DATE, + vWorker INT +) +BEGIN +/** + * Inserta el volumen de compra de un comprador + * en stockBuyed de acuerdo con la fecha. + * + * @param vDated Fecha de compra + * @param vWorker Id de trabajador + */ + CREATE OR REPLACE TEMPORARY TABLE tStockBuyed + (INDEX (userFk)) + ENGINE = MEMORY + SELECT requested, reserved, userFk + FROM stockBuyed + WHERE dated = vDated + AND userFk = vWorker; + + DELETE FROM stockBuyed + WHERE dated = vDated + AND userFk = vWorker; + + CALL stockTraslation(vDated); + + INSERT INTO stockBuyed(userFk, buyed, `dated`, reserved, requested, description) + SELECT it.workerFk, + SUM((ti.quantity / b.packing) * buy_getVolume(b.id)) / vc.palletM3 / 1000000, + vDated, + sb.reserved, + sb.requested, + u.name + FROM itemType it + JOIN item i ON i.typeFk = it.id + LEFT JOIN tmp.item ti ON ti.itemFk = i.id + JOIN itemCategory ic ON ic.id = it.categoryFk + JOIN warehouse wh ON wh.code = 'VNH' + JOIN tmp.buyUltimate bu ON bu.itemFk = i.id + AND bu.warehouseFk = wh.id + JOIN buy b ON b.id = bu.buyFk + JOIN volumeConfig vc + JOIN account.`user` u ON u.id = it.workerFk + LEFT JOIN tStockBuyed sb ON sb.userFk = it.workerFk + WHERE ic.display + AND it.workerFk = vWorker; + + SELECT b.entryFk Id_Entrada, + i.id Id_Article, + i.name Article, + ti.quantity Cantidad, + (ac.conversionCoefficient * (ti.quantity / b.packing) * buy_getVolume(b.id)) + / (vc.trolleyM3 * 1000000) buyed, + b.packagingFk id_cubo, + b.packing + FROM tmp.item ti + JOIN item i ON i.id = ti.itemFk + JOIN itemType it ON i.typeFk = it.id + JOIN itemCategory ic ON ic.id = it.categoryFk + JOIN worker w ON w.id = it.workerFk + JOIN auctionConfig ac + JOIN tmp.buyUltimate bu ON bu.itemFk = i.id + AND bu.warehouseFk = ac.warehouseFk + JOIN buy b ON b.id = bu.buyFk + JOIN volumeConfig vc + WHERE ic.display + AND w.id = vWorker; + + DROP TEMPORARY TABLE tmp.buyUltimate, + tmp.item, + tStockBuyed; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingMakeFromDate`(IN `vShelvingFk` VARCHAR(8), IN `vBarcode` VARCHAR(22), IN `vQuantity` INT, IN `vPackagingFk` VARCHAR(10), IN `vGrouping` INT, IN `vPacking` INT, IN `vWarehouseFk` INT, `vCreated` VARCHAR(22)) +BEGIN + + DECLARE vItemFk INT; + + SELECT vn.barcodeToItem(vBarcode) INTO vItemFk; + + SELECT itemFk INTO vItemFk + FROM vn.buy b + WHERE b.id = vItemFk; + + IF (SELECT COUNT(*) FROM vn.shelving WHERE code = vShelvingFk COLLATE utf8_unicode_ci) = 0 THEN + + INSERT IGNORE INTO vn.parking(`code`) VALUES(vShelvingFk); + INSERT INTO vn.shelving(`code`, parkingFk) + SELECT vShelvingFk, id + FROM vn.parking + WHERE `code` = vShelvingFk COLLATE utf8_unicode_ci; + + END IF; + + IF (SELECT COUNT(*) FROM vn.itemShelving + WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk + AND itemFk = vItemFk + AND packing = vPacking) = 1 THEN + + UPDATE vn.itemShelving + SET visible = visible+vQuantity, + created = vCreated + WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk + AND itemFk = vItemFk + AND packing = vPacking; + + ELSE + CALL cache.last_buy_refresh(FALSE); + INSERT INTO itemShelving( itemFk, + shelvingFk, + visible, + created, + `grouping`, + packing, + packagingFk) + SELECT vItemFk, + vShelvingFk, + vQuantity, + vCreated, + IF(vGrouping = 0, IFNULL(b.packing, vPacking), vGrouping) `grouping`, + IF(vPacking = 0, b.packing, vPacking) packing, + IF(vPackagingFk = '', b.packagingFk, vPackagingFk) packaging + FROM vn.item i + LEFT JOIN cache.last_buy lb ON i.id = lb.item_id AND lb.warehouse_id = vWarehouseFk + LEFT JOIN vn.buy b ON b.id = lb.buy_id + WHERE i.id = vItemFk; + END IF; + +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelving_add`(IN vShelvingFk VARCHAR(8), IN vBarcode VARCHAR(22), IN vQuantity INT, IN vPackagingFk VARCHAR(10), IN vGrouping INT, IN vPacking INT, IN vWarehouseFk INT) +BEGIN + + +/** + * Añade registro o lo actualiza si ya existe. + * + * @param vShelvingFk matrícula del carro + * @param vBarcode el id del registro + * @param vQuantity indica la cantidad del producto + * @param vPackagingFk el packaging del producto en itemShelving, NULL para coger el de la ultima compra + * @param vGrouping el grouping del producto en itemShelving, NULL para coger el de la ultima compra + * @param vPacking el packing del producto, NULL para coger el de la ultima compra + * @param vWarehouseFk indica el sector + * + **/ + + DECLARE vItemFk INT; + + SELECT barcodeToItem(vBarcode) INTO vItemFk; + + IF (SELECT COUNT(*) FROM shelving WHERE code = vShelvingFk COLLATE utf8_unicode_ci) = 0 THEN + + INSERT IGNORE INTO parking(code) VALUES(vShelvingFk); + INSERT INTO shelving(code, parkingFk) + SELECT vShelvingFk, id + FROM parking + WHERE `code` = vShelvingFk COLLATE utf8_unicode_ci; + + END IF; + + IF (SELECT COUNT(*) FROM itemShelving + WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk + AND itemFk = vItemFk + AND packing = vPacking) = 1 THEN + + UPDATE itemShelving + SET visible = visible+vQuantity + WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk AND itemFk = vItemFk AND packing = vPacking; + + ELSE + CALL cache.last_buy_refresh(FALSE); + INSERT INTO itemShelving( itemFk, + shelvingFk, + visible, + grouping, + packing, + packagingFk) + + SELECT vItemFk, + vShelvingFk, + vQuantity, + IFNULL(vGrouping, b.grouping), + IFNULL(vPacking, b.packing), + IFNULL(vPackagingFk, b.packagingFk) + FROM item i + LEFT JOIN cache.last_buy lb ON i.id = lb.item_id AND lb.warehouse_id = vWarehouseFk + LEFT JOIN buy b ON b.id = lb.buy_id + WHERE i.id = vItemFk; + END IF; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemFreight_Show`(vItemFk INT, vWarehouseFk INT) +BEGIN + + SELECT cm3 Volumen_Entrada, + cm3delivery Volumen_Salida, + p.volume Volumen_del_embalaje, + p.width Ancho_del_embalaje, + p.`depth` Largo_del_embalaje, + b.packagingFk , + IFNULL(p.height, i.`size`) + 10 Altura, + b.packing Packing_Entrada, + i.packingOut Packing_Salida, + i.id itemFk, + b.id buyFk, + b.entryFk, + w.name warehouseFk + FROM vn.itemCost ic + JOIN vn.item i ON i.id = ic.itemFk + LEFT JOIN cache.last_buy lb ON lb.item_id = ic.itemFk AND lb.warehouse_id = ic.warehouseFk + LEFT JOIN vn.buy b ON b.id = lb.buy_id + LEFT JOIN vn.packaging p ON p.id = b.packagingFk + LEFT JOIN vn.warehouse w ON w.id = ic.warehouseFk + WHERE ic.itemFk = vItemFk + AND ic.warehouseFk = vWarehouseFk; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`inventoryMake`(vDate DATE, vWh INT) +proc: BEGIN +/** +* Recalcula los inventarios de todos los almacenes, si vWh = 0 +* +* @param vDate Fecha de los nuevos inventarios +* @param vWh almacen al cual hacer el inventario +*/ + + DECLARE vDone BOOL; + DECLARE vEntryFk INT; + DECLARE vTravelFk INT; + DECLARE vDateLastInventory DATE; + DECLARE vDateYesterday DATETIME DEFAULT vDate - INTERVAL 1 SECOND; + DECLARE vWarehouseOutFkInventory INT; + DECLARE vInventorySupplierFk INT; + DECLARE vAgencyModeFkInventory INT; + + DECLARE cWarehouses CURSOR FOR + SELECT id + FROM warehouse + WHERE isInventory + AND vWh IN (0,id); + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + + OPEN cWarehouses; + SET @isModeInventory := TRUE; + l: LOOP + + SET vDone = FALSE; + FETCH cWarehouses INTO vWh; + + IF vDone THEN + LEAVE l; + END IF; + + SELECT w.id INTO vWarehouseOutFkInventory + FROM warehouse w + WHERE w.code = 'inv'; + + SELECT inventorySupplierFk INTO vInventorySupplierFk + FROM entryConfig; + + SELECT am.id INTO vAgencyModeFkInventory + FROM agencyMode am + where code = 'inv'; + + SELECT MAX(landed) INTO vDateLastInventory + FROM travel tr + JOIN entry e ON e.travelFk = tr.id + JOIN buy b ON b.entryFk = e.id + WHERE warehouseOutFk = vWarehouseOutFkInventory + AND landed < vDate + AND e.supplierFk = vInventorySupplierFk + AND warehouseInFk = vWh + AND NOT isRaid; + + IF vDateLastInventory IS NULL THEN + SELECT inventoried INTO vDateLastInventory FROM config; + END IF; + + -- Generamos travel, si no existe. + SET vTravelFK = 0; + + SELECT id INTO vTravelFk + FROM travel + WHERE warehouseOutFk = vWarehouseOutFkInventory + AND warehouseInFk = vWh + AND landed = vDate + AND agencyModeFk = vAgencyModeFkInventory + AND ref = 'inventario' + LIMIT 1; + + IF NOT vTravelFK THEN + + INSERT INTO travel SET + warehouseOutFk = vWarehouseOutFkInventory, + warehouseInFk = vWh, + shipped = vDate, + landed = vDate, + agencyModeFk = vAgencyModeFkInventory, + ref = 'inventario', + isDelivered = TRUE, + isReceived = TRUE; + + SELECT LAST_INSERT_ID() INTO vTravelFk; + + END IF; + + -- Generamos entrada si no existe, o la vaciamos. + SET vEntryFk = 0; + + SELECT id INTO vEntryFk + FROM entry + WHERE supplierFk = vInventorySupplierFk + AND travelFk = vTravelFk; + + IF NOT vEntryFk THEN + + INSERT INTO entry SET + supplierFk = vInventorySupplierFk, + isConfirmed = TRUE, + isOrdered = TRUE, + travelFk = vTravelFk; + + SELECT LAST_INSERT_ID() INTO vEntryFk; + + ELSE + + DELETE FROM buy WHERE entryFk = vEntryFk; + + END IF; + + -- Preparamos tabla auxilar + CREATE OR REPLACE TEMPORARY TABLE tmp.inventory ( + itemFk INT(11) NOT NULL PRIMARY KEY, + quantity int(11) DEFAULT '0', + buyingValue decimal(10,3) DEFAULT '0.000', + freightValue decimal(10,3) DEFAULT '0.000', + packing int(11) DEFAULT '0', + `grouping` smallint(5) unsigned NOT NULL DEFAULT '1', + groupingMode tinyint(4) NOT NULL DEFAULT 0 , + comissionValue decimal(10,3) DEFAULT '0.000', + packageValue decimal(10,3) DEFAULT '0.000', + packageFk varchar(10) COLLATE utf8_unicode_ci DEFAULT '--', + price1 decimal(10,2) DEFAULT '0.00', + price2 decimal(10,2) DEFAULT '0.00', + price3 decimal(10,2) DEFAULT '0.00', + minPrice decimal(10,2) DEFAULT '0.00', + producer varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, + INDEX (itemFK)) ENGINE = MEMORY; + + -- Compras + INSERT INTO tmp.inventory(itemFk,quantity) + SELECT b.itemFk, SUM(b.quantity) + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel tr ON tr.id = e.travelFk + WHERE tr.warehouseInFk = vWh + AND tr.landed BETWEEN vDateLastInventory + AND vDateYesterday + AND NOT isRaid + GROUP BY b.itemFk; + SELECT vDateLastInventory , vDateYesterday; + + -- Traslados + INSERT INTO tmp.inventory(itemFk, quantity) + SELECT itemFk, quantityOut + FROM ( + SELECT b.itemFk,- SUM(b.quantity) quantityOut + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel tr ON tr.id = e.travelFk + WHERE tr.warehouseOutFk = vWh + AND tr.shipped BETWEEN vDateLastInventory + AND vDateYesterday + AND NOT isRaid + GROUP BY b.itemFk + ) sub + ON DUPLICATE KEY UPDATE quantity = IFNULL(quantity, 0) + sub.quantityOut; + + -- Ventas + INSERT INTO tmp.inventory(itemFk,quantity) + SELECT itemFk, saleOut + FROM ( + SELECT s.itemFk, - SUM(s.quantity) saleOut + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + WHERE t.warehouseFk = vWh + AND t.shipped BETWEEN vDateLastInventory AND vDateYesterday + GROUP BY s.itemFk + ) sub + ON DUPLICATE KEY UPDATE quantity = IFNULL(quantity,0) + sub.saleOut; + + -- Actualiza valores de la ultima compra + UPDATE tmp.inventory inv + JOIN cache.last_buy lb ON lb.item_id = inv.itemFk AND lb.warehouse_id = vWh + JOIN buy b ON b.id = lb.buy_id + JOIN item i ON i.id = b.itemFk + LEFT JOIN producer p ON p.id = i.producerFk + SET inv.buyingValue = b.buyingValue, + inv.freightValue = b.freightValue, + inv.packing = b.packing, + inv.`grouping`= b.`grouping`, + inv.groupingMode = b.groupingMode, + inv.comissionValue = b.comissionValue, + inv.packageValue = b.packageValue, + inv.packageFk = b.packagingFk, + inv.price1 = b.price1, + inv.price2 = b.price2, + inv.price3 = b.price3, + inv.minPrice = b.minPrice, + inv.producer = p.name; + + INSERT INTO buy( itemFk, + quantity, + buyingValue, + freightValue, + packing, + `grouping`, + groupingMode, + comissionValue, + packageValue, + packagingFk, + price1, + price2, + price3, + minPrice, + entryFk) + SELECT itemFk, + GREATEST(quantity, 0), + buyingValue, + freightValue, + packing, + `grouping`, + groupingMode, + comissionValue, + packageValue, + packagingFk, + price1, + price2, + price3, + minPrice, + vEntryFk + FROM tmp.inventory; + + SELECT vWh, COUNT(*), util.VN_NOW() FROM tmp.inventory; + + -- Actualizamos el campo lastUsed de item + UPDATE item i + JOIN tmp.inventory i2 ON i2.itemFk = i.id + SET i.lastUsed = NOW() + WHERE i2.quantity; + + -- DROP TEMPORARY TABLE tmp.inventory; + + END LOOP; + + CLOSE cWarehouses; + + UPDATE config SET inventoried = vDate; + SET @isModeInventory := FALSE; + + DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete; + CREATE TEMPORARY TABLE tmp.entryToDelete + (INDEX(entryId) USING BTREE) ENGINE = MEMORY + SELECT e.id as entryId, + t.id as travelId + FROM travel t + JOIN `entry` e ON e.travelFk = t.id + WHERE e.supplierFk = vInventorySupplierFk + AND t.shipped <= util.VN_CURDATE() - INTERVAL 12 DAY + AND (DAY(t.shipped) <> 1 OR shipped < util.VN_CURDATE() - INTERVAL 12 DAY); + + DELETE e + FROM `entry` e + JOIN tmp.entryToDelete tmp ON tmp.entryId = e.id; + + DELETE IGNORE t + FROM travel t + JOIN tmp.entryToDelete tmp ON tmp.travelId = t.id; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`inventory_repair`() +BEGIN + + DROP TEMPORARY TABLE IF EXISTS tmp.lastEntry; + CREATE TEMPORARY TABLE tmp.lastEntry + (PRIMARY KEY (buyFk)) + SELECT + i.id AS itemFk, + w.id AS warehouseFk, + w.name AS warehouse, + tr.landed, + b.id AS buyFk, + b.entryFk, + b.isIgnored, + b.price2, + b.price3, + b.stickers, + b.packing, + b.grouping, + b.groupingMode, + b.weight, + i.stems, + b.quantity, + b.buyingValue, + b.packagingFk , + s.id AS supplierFk, + s.name AS supplier + FROM itemType it + RIGHT JOIN (entry e + LEFT JOIN supplier s ON s.id = e.supplierFk + RIGHT JOIN buy b ON b.entryFk = e.id + LEFT JOIN item i ON i.id = b.itemFk + LEFT JOIN ink ON ink.id = i.inkFk + LEFT JOIN travel tr ON tr.id = e.travelFk + LEFT JOIN warehouse w ON w.id = tr.warehouseInFk + LEFT JOIN origin o ON o.id = i.originFk + ) ON it.id = i.typeFk + LEFT JOIN edi.ekt ek ON b.ektFk = ek.id + WHERE (b.packagingFk = "--" OR b.price2 = 0 OR b.packing = 0 OR b.buyingValue = 0) AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-1,util.VN_CURDATE())) AND s.name = 'INVENTARIO'; + + DROP TEMPORARY TABLE IF EXISTS tmp.lastEntryOk; + CREATE TEMPORARY TABLE tmp.lastEntryOk + (PRIMARY KEY (buyFk)) + SELECT + i.id AS itemFk, + w.id AS warehouseFk, + w.name AS warehouse, + tr.landed, + b.id AS buyFk, + b.entryFk, + b.isIgnored, + b.price2, + b.price3, + b.stickers, + b.packing, + b.grouping, + b.groupingMode, + b.weight, + i.stems, + b.quantity, + b.buyingValue, + b.packagingFk, + s.id AS supplierFk, + s.name AS supplier + FROM itemType it + RIGHT JOIN (entry e + LEFT JOIN supplier s ON s.id = e.supplierFk + RIGHT JOIN buy b ON b.entryFk = e.id + LEFT JOIN item i ON i.id = b.itemFk + LEFT JOIN ink ON ink.id = i.inkFk + LEFT JOIN travel tr ON tr.id = e.travelFk + LEFT JOIN warehouse w ON w.id = tr.warehouseInFk + LEFT JOIN origin o ON o.id = i.originFk + ) ON it.id = i.typeFk + LEFT JOIN edi.ekt ek ON b.ektFk = ek.id + WHERE b.packagingFk != "--" AND b.price2 != 0 AND b.packing != 0 AND b.buyingValue > 0 AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-2,util.VN_CURDATE())) + ORDER BY tr.landed DESC; + + DROP TEMPORARY TABLE IF EXISTS tmp.lastEntryOkGroup; + CREATE TEMPORARY TABLE tmp.lastEntryOkGroup + (INDEX (warehouseFk,itemFk)) + SELECT * + FROM tmp.lastEntryOk tmp + GROUP BY tmp.itemFk,tmp.warehouseFk; + + UPDATE buy b + JOIN tmp.lastEntry lt ON lt.buyFk = b.id + JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk + SET b.packagingFk = eo.packagingFk WHERE b.packagingFk = "--"; + + UPDATE buy b + JOIN tmp.lastEntry lt ON lt.buyFk = b.id + JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk + SET b.price2 = eo.price2 WHERE b.price2 = 0 ; + + UPDATE buy b + JOIN tmp.lastEntry lt ON lt.buyFk = b.id + JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk + SET b.packing = eo.packing WHERE b.packing = 0; + + UPDATE buy b + JOIN tmp.lastEntry lt ON lt.buyFk = b.id + JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk + SET b.buyingValue = eo.buyingValue WHERE b.buyingValue = 0; + + DROP TEMPORARY TABLE tmp.lastEntry; + DROP TEMPORARY TABLE tmp.lastEntryOk; + DROP TEMPORARY TABLE tmp.lastEntryOkGroup; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`buy_afterUpsert`(vSelf INT) +BEGIN +/** + * Triggered actions when a buy is updated or inserted. + * + * @param vSelf The buy reference + */ + DECLARE vEntryFk INT; + DECLARE vItemFk INT; + DECLARE vPackingOut DECIMAL(10,2); + DECLARE vWarehouse INT; + DECLARE vStandardFlowerBox INT; + DECLARE vWarehouseOut INT; + DECLARE vIsMerchandise BOOL; + DECLARE vIsFeedStock BOOL; + DECLARE vWeight DECIMAL(10,2); + DECLARE vPacking INT; + + SELECT b.entryFk, + b.itemFk, + i.packingOut, + ic.merchandise, + vc.standardFlowerBox, + b.weight, + b.packing + INTO + vEntryFk, + vItemFk, + vPackingOut, + vIsMerchandise, + vStandardFlowerBox, + vWeight, + vPacking + FROM buy b + LEFT JOIN item i ON i.id = b.itemFk + LEFT JOIN itemType it ON it.id = i.typeFk + LEFT JOIN itemCategory ic ON ic.id = it.categoryFk + LEFT JOIN packaging p ON p.id = b.packagingFk AND NOT p.isBox + JOIN volumeConfig vc ON TRUE + WHERE b.id = vSelf; + + SELECT t.warehouseInFk, t.warehouseOutFk + INTO vWarehouse, vWarehouseOut + FROM entry e + JOIN travel t ON t.id = e.travelFk + WHERE e.id = vEntryFk; + + IF vIsMerchandise THEN + + REPLACE itemCost SET + itemFk = vItemFk, + warehouseFk = vWarehouse, + cm3 = buy_getUnitVolume(vSelf), + cm3Delivery = IFNULL((vStandardFlowerBox * 1000) / vPackingOut, buy_getUnitVolume(vSelf)); + + IF vWeight AND vPacking THEN + UPDATE itemCost SET + grams = vWeight * 1000 / vPacking + WHERE itemFk = vItemFk + AND warehouseFk = vWarehouse; + END IF; + END IF; + + SELECT isFeedStock INTO vIsFeedStock + FROM warehouse WHERE id = vWarehouseOut; + + IF vIsFeedStock THEN + INSERT IGNORE INTO producer(`name`) + SELECT es.company_name + FROM buy b + JOIN edi.ekt be ON be.id = b.ektFk + JOIN edi.supplier es ON es.supplier_id = be.pro + WHERE b.id = vSelf; + + END IF; + +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`buy_getUnitVolume`(vSelf INT) + RETURNS int(11) + DETERMINISTIC +BEGIN +/** + * Calculates the unit volume occupied by a buy. + * + * @param vSelf The buy id + * @return The unit volume in cubic centimeters + */ + DECLARE vItem INT; + DECLARE vPackaging VARCHAR(10); + DECLARE vPacking INT; + + SELECT itemFk, packagingFk, packing + INTO vItem, vPackaging, vPacking + FROM buy + WHERE id = vSelf; + + RETURN IFNULL(ROUND(item_getVolume(vItem, vPackaging) / vPacking), 0); +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`buy_recalcPrices`() +BEGIN +/** + * Recalcula los precios para las compras insertadas en tmp.buyRecalc + * + * @param tmp.buyRecalc (id) + */ + DECLARE vLanded DATE; + DECLARE vWarehouseFk INT; + DECLARE vHasNotPrice BOOL; + DECLARE vBuyingValue DECIMAL(10,3); + DECLARE vPackagingFk VARCHAR(10); + DECLARE vIsWarehouseFloramondo BOOL; + + SELECT t.landed, t.warehouseInFk, (w.`name` = 'Floramondo') + INTO vLanded, vWarehouseFk, vIsWarehouseFloramondo + FROM tmp.buyRecalc br + JOIN buy b ON b.id = br.id + JOIN entry e ON e.id = b.entryFk + JOIN travel t ON t.id = e.travelFk + JOIN warehouse w ON w.id = t.warehouseInFk + LIMIT 1; + + CALL rate_getPrices(vLanded, vWarehouseFk); + + UPDATE buy b + JOIN tmp.buyRecalc br ON br.id = b.id AND (@buyId := b.id) + LEFT JOIN packaging p ON p.id = b.packagingFk + JOIN item i ON i.id = b.itemFk + JOIN entry e ON e.id = b.entryFk + JOIN itemType it ON it.id = i.typeFk + JOIN travel tr ON tr.id = e.travelFk + JOIN agencyMode am ON am.id = tr.agencyModeFk + JOIN tmp.rate r + JOIN volumeConfig vc + SET b.freightValue = @PF:= IFNULL(((am.m3 * @m3:= item_getVolume(b.itemFk, b.packagingFk) / 1000000) + / b.packing) * IF(am.hasWeightVolumetric, GREATEST(b.weight / @m3 / vc.aerealVolumetricDensity, 1), 1), 0), + b.comissionValue = @CF:= ROUND(IFNULL(e.commission * b.buyingValue / 100, 0), 3), + b.packageValue = @EF:= IF(vIsWarehouseFloramondo, 0, IFNULL(ROUND(IF(p.isPackageReturnable, p.returnCost / b.packing , p.`value` / b.packing), 3),0)), + b.price3 = @t3:= IF(r.rate3 = 0, b.buyingValue,ROUND((b.buyingValue + @CF + @EF + @PF) / ((100 - r.rate3 - it.promo ) /100) ,2)), -- He añadido que el coste sea igual a tarifa3 si t3 = 0 + b.price2 = @t2:= round(@t3 * (1 + ((r.rate2 - r.rate3)/100)),2), + b.price2 = @t2:= IF(@t2 <= @t3,@t3 , @t2); + + SELECT (b.buyingValue = b.price2), b.buyingValue, b.packagingFk + INTO vHasNotPrice, vBuyingValue, vPackagingFk + FROM vn.buy b + WHERE b.id = @buyId AND b.buyingValue <> 0.01; + + DROP TEMPORARY TABLE tmp.rate; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `edi`.`ekt_load`(IN `vSelf` INT) +proc:BEGIN + + DECLARE vRef INT; + DECLARE vBuy INT; + DECLARE vItem INT; + DECLARE vQty INT; + DECLARE vPackage INT; + DECLARE vPutOrderFk INT; + DECLARE vIsLot BOOLEAN; + DECLARE vForceToPacking INT DEFAULT 2; + DECLARE vEntryFk INT; + DECLARE vHasToChangePackagingFk BOOLEAN; + DECLARE vIsFloramondoDirect BOOLEAN; + DECLARE vTicketFk INT; + DECLARE vHasItemGroup BOOL; + DECLARE vDescription VARCHAR(255); + DECLARE vSaleFk INT; + + -- Carga los datos necesarios del EKT + + SELECT e.ref, qty, package, putOrderFk MOD 1000000, i2.id , NOT ISNULL(eea.addressFk), NOT ISNULL(igto.group_code), + CONCAT(e.`ref`, ' ', e.item, ' ', e.sub, ' EktFk:', e.id) + INTO vRef, vQty, vPackage, vPutOrderFk, vItem, vIsFloramondoDirect, vHasItemGroup, vDescription + FROM edi.ekt e + LEFT JOIN edi.item i ON e.ref = i.id + LEFT JOIN edi.putOrder po ON po.id = e.putOrderFk + LEFT JOIN vn.item i2 ON i2.supplyResponseFk = po.supplyResponseID + LEFT JOIN vn.ektEntryAssign eea ON eea.sub = e.sub + LEFT JOIN edi.item_groupToOffer igto ON igto.group_code = i.group_id + WHERE e.id = vSelf + LIMIT 1; + + IF NOT vHasItemGroup THEN + + CALL vn.mail_insert('logistica@verdnatura.es', 'nocontestar@verdnatura.es', 'Nuevo grupo en Floramondo', vDescription); + + CALL vn.mail_insert('pako@verdnatura.es', 'nocontestar@verdnatura.es', CONCAT('Nuevo grupo en Floramondo: ', vDescription), vDescription); + + LEAVE proc; + + END IF; + + -- Asigna la entrada + SELECT vn.ekt_getEntry(vSelf) INTO vEntryFk; + + -- Inserta el cubo si no existe + + IF vPackage = 800 THEN + + SET vHasToChangePackagingFk = TRUE; + + IF vItem THEN + + SELECT vn.item_getPackage(vItem) INTO vPackage ; + + ELSE + + SET vPackage = 8000 + vQty; + + INSERT IGNORE INTO vn.packaging(id, width, `depth`) + SELECT vPackage, vc.ccLength / vQty, vc.ccWidth + FROM vn.volumeConfig vc; + + END IF; + + ELSE + + INSERT IGNORE INTO vn2008.Cubos (Id_Cubo, X, Y, Z) + SELECT bucket_id, ROUND(x_size/10), ROUND(y_size/10), ROUND(z_size/10) + FROM bucket WHERE bucket_id = vPackage; + + IF ROW_COUNT() > 0 + THEN + INSERT INTO vn2008.mail SET + `subject` = 'Cubo añadido', + `text` = CONCAT('Se ha añadido el cubo: ', vPackage), + `to` = 'ekt@verdnatura.es'; + END IF; + END IF; + + -- Si es una compra de Logiflora obtiene el articulo + IF vPutOrderFk THEN + + SELECT i.id INTO vItem + FROM edi.putOrder po + JOIN vn.item i ON i.supplyResponseFk = po.supplyResponseID + WHERE po.id = vPutOrderFk + LIMIT 1; + + END IF; + + INSERT IGNORE INTO item_track SET + item_id = vRef; + + IF IFNULL(vItem,0) = 0 THEN + + -- Intenta obtener el artículo en base a los atributos holandeses + + SELECT b.id, IFNULL(b.itemOriginalFk ,b.itemFk) INTO vBuy, vItem + FROM edi.ekt e + JOIN edi.item_track t ON t.item_id = e.ref + LEFT JOIN edi.ekt l ON l.ref = e.ref + LEFT JOIN vn.buy b ON b.ektFk = l.id + LEFT JOIN vn.item i ON i.id = b.itemFk + JOIN vn2008.config cfg + WHERE e.id = vSelf + AND l.id != vSelf + AND b.itemFk != cfg.generic_item + AND IF(t.s1, l.s1 = e.s1, TRUE) + AND IF(t.s2, l.s2 = e.s2, TRUE) + AND IF(t.s3, l.s3 = e.s3, TRUE) + AND IF(t.s4, l.s4 = e.s4, TRUE) + AND IF(t.s5, l.s5 = e.s5, TRUE) + AND IF(t.s6, l.s6 = e.s6, TRUE) + AND IF(t.pac, l.pac = e.pac, TRUE) + AND IF(t.cat, l.cat = e.cat, TRUE) + AND IF(t.ori, l.ori = e.ori, TRUE) + AND IF(t.pro, l.pro = e.pro, TRUE) + AND IF(t.package, l.package = e.package, TRUE) + AND IF(t.item, l.item = e.item, TRUE) + AND i.isFloramondo = vIsFloramondoDirect + ORDER BY l.now DESC, b.id ASC + LIMIT 1; + + END IF; + + -- Si no encuentra el articulo lo crea en el caso de las compras directas en Floramondo + IF ISNULL(vItem) AND vIsFloramondoDirect THEN + + CALL edi.item_getNewByEkt(vSelf, vItem); + + END IF; + + INSERT INTO vn.buy + ( + entryFk + ,ektFk + ,buyingValue + ,itemFk + ,stickers + ,packing + ,`grouping` + ,quantity + ,groupingMode + ,packagingFk + ,weight + ) + SELECT + vEntryFk + ,vSelf + ,(@t := IF(i.stems, i.stems, 1)) * e.pri / IFNULL(i.stemMultiplier, 1) buyingValue + ,IFNULL(vItem, cfg.generic_item) itemFk + ,e.qty stickers + ,@pac := IFNULL(i.stemMultiplier, 1) * e.pac / @t packing + ,IFNULL(b.`grouping`, e.pac) + ,@pac * e.qty + ,vForceToPacking + ,IF(vHasToChangePackagingFk OR ISNULL(b.packagingFk), vPackage, b.packagingFk) + ,(IFNULL(i.weightByPiece,0) * @pac)/1000 + FROM edi.ekt e + LEFT JOIN vn.buy b ON b.id = vBuy + LEFT JOIN vn.item i ON i.id = b.itemFk + LEFT JOIN vn.supplier s ON e.pro = s.id + JOIN vn2008.config cfg + WHERE e.id = vSelf + LIMIT 1; + + DROP TEMPORARY TABLE IF EXISTS tmp.buyRecalc; + + CREATE TEMPORARY TABLE tmp.buyRecalc + SELECT buy.id + FROM vn.buy + WHERE ektFk = vSelf; + + CALL vn.buy_recalcPrices(); + + -- Si es una compra de Logiflora hay que informar la tabla vn.saleBuy + IF vPutOrderFk THEN + + REPLACE vn.saleBuy(saleFk, buyFk, workerFk) + SELECT po.saleFk, b.id, account.myUser_getId() + FROM edi.putOrder po + JOIN vn.buy b ON b.ektFk = vSelf + WHERE po.id = vPutOrderFk; + + END IF; + -- Si es una compra directa en Floramondo hay que añadirlo al ticket + + IF vIsFloramondoDirect THEN + + SELECT t.id INTO vTicketFk + FROM vn.ticket t + JOIN vn.ektEntryAssign eea + ON eea.addressFk = t.addressFk + AND t.warehouseFk = eea.warehouseInFk + JOIN edi.ekt e + ON e.sub = eea.sub + AND e.id = vSelf + WHERE e.fec = t.shipped + LIMIT 1; + + IF ISNULL(vTicketFk) THEN + + INSERT INTO vn.ticket ( + clientFk, + shipped, + addressFk, + agencyModeFk, + nickname, + warehouseFk, + companyFk, + landed, + zoneFk, + zonePrice, + zoneBonus + ) + SELECT + a.clientFk, + e.fec, + a.id, + a.agencyModeFk, + a.nickname, + eea.warehouseInFk, + c.id, + e.fec, + z.id, + z.price, + z.bonus + FROM edi.ekt e + JOIN vn.ektEntryAssign eea ON eea.sub = e.sub + JOIN vn.address a ON a.id = eea.addressFk + JOIN vn.company c ON c.code = 'VNL' + JOIN vn.`zone` z ON z.code = 'FLORAMONDO' + WHERE e.id = vSelf + LIMIT 1; + + SET vTicketFk = LAST_INSERT_ID(); + + INSERT INTO vn.ticketLog + SET originFk = vTicketFk, + userFk = account.myUser_getId(), + `action` = 'insert', + description = CONCAT('EktLoad ha creado el ticket:', ' ', vTicketFk); + + END IF; + + INSERT INTO vn.sale (itemFk, ticketFk, concept, quantity, price) + SELECT vItem, vTicketFk, e.item, e.qty * e.pac, e.pri * ( 1 + fhc.floramondoMargin ) + FROM edi.ekt e + JOIN edi.floraHollandConfig fhc + WHERE e.id = vSelf; + + SELECT LAST_INSERT_ID() INTO vSaleFk; + + REPLACE vn.saleBuy(saleFk, buyFk, workerFk) + SELECT vSaleFk, b.id, account.myUser_getId() + FROM vn.buy b + WHERE b.ektFk = vSelf; + + INSERT INTO vn.saleComponent(saleFk, componentFk, value) + SELECT vSaleFk, c.id, e.pri + FROM edi.ekt e + JOIN vn.component c ON c.code = 'purchaseValue' + WHERE e.id = vSelf; + + INSERT INTO vn.saleComponent(saleFk, componentFk, value) + SELECT vSaleFk, c.id, e.pri * fhc.floramondoMargin + FROM edi.ekt e + JOIN edi.floraHollandConfig fhc + JOIN vn.component c ON c.code = 'margin' + WHERE e.id = vSelf; + END IF; + DROP TEMPORARY TABLE tmp.buyRecalc; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `hedera`.`item_getVisible`( + vWarehouse TINYINT, + vDate DATE, + vType INT, + vPrefix VARCHAR(255)) +BEGIN + +/** + * Gets visible items of the specified type at specified date. + * + * @param vWarehouse The warehouse id + * @param vDate The visible date + * @param vType The type id + * @param vPrefix The article prefix to filter or %NULL for all + * @return tmp.itemVisible Visible items + */ + DECLARE vPrefixLen SMALLINT; + DECLARE vFilter VARCHAR(255) DEFAULT NULL; + DECLARE vDateInv DATE DEFAULT vn2008.date_inv(); + DECLARE EXIT HANDLER FOR 1114 + BEGIN + GET DIAGNOSTICS CONDITION 1 + @message = MESSAGE_TEXT; + CALL vn.mail_insert( + 'cau@verdnatura.es', + NULL, + CONCAT('hedera.item_getVisible error: ', @message), + CONCAT( + 'warehouse: ', IFNULL(vWarehouse, ''), + ', Fecha:', IFNULL(vDate, ''), + ', tipo: ', IFNULL(vType,''), + ', prefijo: ', IFNULL(vPrefix,''))); + RESIGNAL; + END; + SET vPrefixLen = IFNULL(LENGTH(vPrefix), 0) + 1; + + IF vPrefixLen > 1 THEN + SET vFilter = CONCAT(vPrefix, '%'); + END IF; + + DROP TEMPORARY TABLE IF EXISTS `filter`; + CREATE TEMPORARY TABLE `filter` + (INDEX (itemFk)) + ENGINE = MEMORY + SELECT id itemFk FROM vn.item + WHERE typeFk = vType + AND (vFilter IS NULL OR `name` LIKE vFilter); + + DROP TEMPORARY TABLE IF EXISTS currentStock; + CREATE TEMPORARY TABLE currentStock + (INDEX (itemFk)) + ENGINE = MEMORY + SELECT itemFk, SUM(quantity) quantity + FROM ( + SELECT b.itemFk, b.quantity + FROM vn.buy b + JOIN vn.entry e ON e.id = b.entryFk + JOIN vn.travel t ON t.id = e.travelFk + WHERE t.landed BETWEEN vDateInv AND vDate + AND t.warehouseInFk = vWarehouse + AND NOT e.isRaid + UNION ALL + SELECT b.itemFk, -b.quantity + FROM vn.buy b + JOIN vn.entry e ON e.id = b.entryFk + JOIN vn.travel t ON t.id = e.travelFk + WHERE t.shipped BETWEEN vDateInv AND util.VN_CURDATE() + AND t.warehouseOutFk = vWarehouse + AND NOT e.isRaid + AND t.isDelivered + UNION ALL + SELECT m.itemFk, -m.quantity + FROM vn.sale m + JOIN vn.ticket t ON t.id = m.ticketFk + JOIN vn.ticketState s ON s.ticket = t.id + WHERE t.shipped BETWEEN vDateInv AND util.VN_CURDATE() + AND t.warehouseFk = vWarehouse + AND s.alertLevel = 3 + ) t + GROUP BY itemFk + HAVING quantity > 0; + + DROP TEMPORARY TABLE IF EXISTS tmp; + CREATE TEMPORARY TABLE tmp + (INDEX (itemFk)) + ENGINE = MEMORY + SELECT * + FROM ( + SELECT b.itemFk, b.packagingFk, b.packing + FROM vn.buy b + JOIN vn.entry e ON e.id = b.entryFk + JOIN vn.travel t ON t.id = e.travelFk + WHERE t.landed BETWEEN vDateInv AND vDate + AND NOT b.isIgnored + AND b.price2 >= 0 + AND b.packagingFk IS NOT NULL + ORDER BY t.warehouseInFk = vWarehouse DESC, t.landed DESC + LIMIT 10000000000000000000 + ) t GROUP BY itemFk; + + DROP TEMPORARY TABLE IF EXISTS tmp.itemVisible; + CREATE TEMPORARY TABLE tmp.itemVisible + ENGINE = MEMORY + SELECT i.id Id_Article, + SUBSTRING(i.`name`, vPrefixLen) Article, + t.packing, p.id Id_Cubo, + IF(p.depth > 0, p.depth, 0) depth, p.width, p.height, + CEIL(s.quantity / t.packing) etiquetas + FROM vn.item i + JOIN `filter` f ON f.itemFk = i.id + JOIN currentStock s ON s.itemFk = i.id + LEFT JOIN tmp t ON t.itemFk = i.id + LEFT JOIN vn.packaging p ON p.id = t.packagingFk + WHERE CEIL(s.quantity / t.packing) > 0 + -- FIXME: Column Cubos.box not included in view vn.packaging + /* AND p.box */; + + DROP TEMPORARY TABLE + `filter`, + currentStock, + tmp; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`buy_getVolume`() +BEGIN +/** + * Cálculo de volumen en líneas de compra + * @table tmp.buy(buyFk) + */ + SELECT t.name Temp, + CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * + item_getVolume(b.itemFk, b.packagingFk)) / vc.trolleyM3 / 1000000 ,1) AS DECIMAL(10,2)) carros , + CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * + item_getVolume(b.itemFk, b.packagingFk)) / vc.palletM3 / 1000000,1) AS DECIMAL(10,2)) espais + FROM buy b + JOIN tmp.buy tb ON tb.buyFk = b.id + JOIN volumeConfig vc + JOIN item i ON i.id = b.itemFk + JOIN itemType it ON it.id = i.typeFk + LEFT JOIN temperature t ON t.code = it.temperatureFk + GROUP BY Temp; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`entry_checkPackaging`(vEntryFk INT) +BEGIN +/** + * Comprueba que los campos package y packaging no sean nulos + * + * @param vEntryFk Id de entrada + */ + DECLARE vpackageOrPackingNull INT; + + SELECT count(*) INTO vpackageOrPackingNull + FROM buy b + WHERE b.entryFk = vEntryFk + AND (b.packing IS NULL OR b.packagingFk IS NULL); + + IF vpackageOrPackingNull THEN + CALL util.throw("packageOrPackingNull"); + END IF; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`fustControl`(vFromDated DATE, vToDated DATE) +BEGIN + + DECLARE vSijsnerClientFk INT DEFAULT 19752; + + DECLARE vDateStart DATETIME; + DECLARE vDateEnd DATETIME; + + SET vDateStart = vFromDated; + SET vDateEnd = util.Dayend(vToDated); + + SELECT p.id FustCode, + CAST(sent.stucks AS DECIMAL(10,0)) FH, + CAST(tp.stucks AS DECIMAL(10,0)) Tickets, + CAST(-sj.stucks AS DECIMAL(10,0)) Sijsner, + CAST(IFNULL(sent.stucks,0) - IFNULL(tp.stucks,0) + IFNULL(sj.stucks,0) AS DECIMAL(10,0)) saldo + FROM vn.packaging p + LEFT JOIN ( + SELECT FustCode, sum(fustQuantity) stucks + FROM ( + SELECT IFNULL(pe.equivalentFk ,b.packagingFk) FustCode, s.quantity / b.packing AS fustQuantity + FROM vn.sale s + JOIN vn.ticket t ON t.id = s.ticketFk + JOIN vn.warehouse w ON w.id = t.warehouseFk + JOIN vn.warehouseAlias wa ON wa.id = w.aliasFk + JOIN cache.last_buy lb ON lb.item_id = s.itemFk AND lb.warehouse_id = t.warehouseFk + JOIN vn.buy b ON b.id = lb.buy_id + JOIN vn.packaging p ON p.id = b.packagingFk + LEFT JOIN vn.packageEquivalent pe ON pe.packagingFk = p.id + JOIN vn.address a ON a.id = t.addressFk + JOIN vn.province p2 ON p2.id = a.provinceFk + JOIN vn.country c ON c.id = p2.countryFk + WHERE t.shipped BETWEEN vDateStart AND vDateEnd + AND wa.name = 'VNH' + AND p.isPackageReturnable + AND c.country = 'FRANCIA') sub + GROUP BY FustCode) sent ON sent.FustCode = p.id + LEFT JOIN ( + SELECT FustCode, sum(quantity) stucks + FROM ( + SELECT IFNULL(pe.equivalentFk ,tp.packagingFk) FustCode, tp.quantity + FROM vn.ticketPackaging tp + JOIN vn.ticket t ON t.id = tp.ticketFk + JOIN vn.warehouse w ON w.id = t.warehouseFk + JOIN vn.warehouseAlias wa ON wa.id = w.aliasFk + JOIN vn.packaging p ON p.id = tp.packagingFk + LEFT JOIN vn.packageEquivalent pe ON pe.packagingFk = p.id + JOIN vn.address a ON a.id = t.addressFk + JOIN vn.province p2 ON p2.id = a.provinceFk + JOIN vn.country c ON c.id = p2.countryFk + WHERE t.shipped BETWEEN vDateStart AND vDateEnd + AND wa.name = 'VNH' + AND p.isPackageReturnable + AND c.country = 'FRANCIA' + AND t.clientFk != vSijsnerClientFk + AND tp.quantity > 0) sub + GROUP BY FustCode) tp ON tp.FustCode = p.id + LEFT JOIN ( + SELECT FustCode, sum(quantity) stucks + FROM ( + SELECT IFNULL(pe.equivalentFk ,tp.packagingFk) FustCode, tp.quantity + FROM vn.ticketPackaging tp + JOIN vn.ticket t ON t.id = tp.ticketFk + JOIN vn.warehouse w ON w.id = t.warehouseFk + JOIN vn.warehouseAlias wa ON wa.id = w.aliasFk + JOIN vn.packaging p ON p.id = tp.packagingFk + LEFT JOIN vn.packageEquivalent pe ON pe.packagingFk = p.id + WHERE t.shipped BETWEEN TIMESTAMPADD(DAY, 1, vDateStart ) AND TIMESTAMPADD(DAY, 1, vDateEnd ) + AND wa.name = 'VNH' + AND p.isPackageReturnable + AND t.clientFk = vSijsnerClientFk) sub + GROUP BY FustCode) sj ON sj.FustCode = p.id + WHERE sent.stucks + OR tp.stucks + OR sj.stucks; + +END$$ +DELIMITER ; + From 7367656a354d7e1e53305782d62b59f1b2c861f2 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 13 Oct 2023 09:02:40 +0200 Subject: [PATCH 073/449] refs #6199 Requested changes --- modules/order/front/catalog-view/index.html | 21 +++++++++++---------- modules/order/front/catalog-view/style.scss | 6 +----- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/modules/order/front/catalog-view/index.html b/modules/order/front/catalog-view/index.html index c9375aab55..907882a06b 100644 --- a/modules/order/front/catalog-view/index.html +++ b/modules/order/front/catalog-view/index.html @@ -37,17 +37,18 @@ value="{{::item.value7}}">
-
- - - {{::item.minQuantity}} -
+ ng-if="::item.minQuantity"> +
+ + + {{::item.minQuantity}} +
+
diff --git a/modules/order/front/catalog-view/style.scss b/modules/order/front/catalog-view/style.scss index abfde3589f..a7a2a815c0 100644 --- a/modules/order/front/catalog-view/style.scss +++ b/modules/order/front/catalog-view/style.scss @@ -45,13 +45,9 @@ vn-order-catalog { position: relative; } .text-caption-reduced { + color: $color-alert; display: flex; align-items: center; justify-content: flex-end; - color: $color-alert; - } - .min-quantity-icon { - font-size: 18px; - margin-right: 3px; } } \ No newline at end of file From fa901329347b91d04c5c430aae6fdbe4eb424c2a Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 13 Oct 2023 10:23:48 +0200 Subject: [PATCH 074/449] refs #6199 fix(orderCatalogView): html and css --- modules/order/front/catalog-view/index.html | 41 +++++++++++---------- modules/order/front/catalog-view/style.scss | 7 +--- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/modules/order/front/catalog-view/index.html b/modules/order/front/catalog-view/index.html index 907882a06b..5d60211ed7 100644 --- a/modules/order/front/catalog-view/index.html +++ b/modules/order/front/catalog-view/index.html @@ -8,12 +8,12 @@
- @@ -37,25 +37,28 @@ value="{{::item.value7}}">
- -
- - - {{::item.minQuantity}} -
+ + + + + + + + + + {{::item.minQuantity}} + - - @@ -81,4 +84,4 @@ - \ No newline at end of file + diff --git a/modules/order/front/catalog-view/style.scss b/modules/order/front/catalog-view/style.scss index a7a2a815c0..1e48745ca9 100644 --- a/modules/order/front/catalog-view/style.scss +++ b/modules/order/front/catalog-view/style.scss @@ -44,10 +44,7 @@ vn-order-catalog { height: 30px; position: relative; } - .text-caption-reduced { + .alert { color: $color-alert; - display: flex; - align-items: center; - justify-content: flex-end; } -} \ No newline at end of file +} From 9c0334619d628ff419780642c77b335231f1c9e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Fri, 13 Oct 2023 11:56:50 +0200 Subject: [PATCH 075/449] refs #6199 --- loopback/locale/es.json | 3 ++- modules/item/back/models/item.json | 4 ++++ modules/ticket/back/methods/sale/updateQuantity.js | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 8c50cd9d8d..d34c97d210 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -319,5 +319,6 @@ "The response is not a PDF": "La respuesta no es un PDF", "Ticket without Route": "Ticket sin ruta", "Booking completed": "Reserva completada", - "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación" + "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", + "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mímina" } diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json index e99dcd9961..28f9648fbf 100644 --- a/modules/item/back/models/item.json +++ b/modules/item/back/models/item.json @@ -154,6 +154,10 @@ "mysql":{ "columnName": "doPhoto" } + }, + "minQuantity": { + "type": "number", + "description": "Min quantity" } }, "relations": { diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index edbc34e421..3759285068 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -72,6 +72,15 @@ module.exports = Self => { where: {refundTicketFk: sale.ticketFk}, fields: ['id']} , myOptions); + + const item = await models.Item.findOne({ + where: {id: sale.itemFk}, + fields: ['minQuantity']} + , myOptions); + + if (newQuantity < item.minQuantity && !ticketRefund) + throw new UserError('The amount cannot be less than the minimum'); + if (newQuantity < 0 && !ticketRefund) throw new UserError('You can only add negative amounts in refund tickets'); From e1c1d1a556e62ebcf94e9e62026e45e772697910 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 13 Oct 2023 12:33:39 +0200 Subject: [PATCH 076/449] refs #6199 Fixed tests --- db/dump/structure.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 08df0541c5..b242821fc6 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -30434,6 +30434,7 @@ CREATE TABLE `item` ( `editorFk` int(10) unsigned DEFAULT NULL, `recycledPlastic` int(11) DEFAULT NULL, `nonRecycledPlastic` int(11) DEFAULT NULL, + `minQuantity` int(10) unsigned DEFAULT NULL COMMENT 'Cantidad mínima para una línea de venta', PRIMARY KEY (`id`), UNIQUE KEY `item_supplyResponseFk_idx` (`supplyResponseFk`), KEY `Color` (`inkFk`), From 03687cb48279acf4777b6554ba59bc4cd09838f7 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 13 Oct 2023 14:56:56 +0200 Subject: [PATCH 077/449] hotFix: delete getCurrentWorkerMana --- modules/ticket/front/sale/index.html | 2 +- modules/ticket/front/sale/index.js | 8 ------ modules/ticket/front/sale/index.spec.js | 2 -- .../worker-mana/getCurrentWorkerMana.js | 26 ------------------- .../specs/getCurrentWorkerMana.spec.js | 15 ----------- modules/worker/back/models/worker-mana.js | 3 --- 6 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 modules/worker/back/methods/worker-mana/getCurrentWorkerMana.js delete mode 100644 modules/worker/back/methods/worker-mana/specs/getCurrentWorkerMana.spec.js delete mode 100644 modules/worker/back/models/worker-mana.js diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index be9e819646..b8e64cf287 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -318,7 +318,7 @@ clear-disabled="true" suffix="%"> - + { - this.currentWorkerMana = res.data; - }); } getUsesMana() { diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 9da8e6e7cb..b36e788936 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -120,12 +120,10 @@ describe('Ticket', () => { const expectedAmount = 250; $httpBackend.expect('GET', 'Tickets/1/getSalesPersonMana').respond(200, expectedAmount); $httpBackend.expect('GET', 'Sales/usesMana').respond(200); - $httpBackend.expect('GET', 'WorkerManas/getCurrentWorkerMana').respond(200, expectedAmount); controller.getMana(); $httpBackend.flush(); expect(controller.edit.mana).toEqual(expectedAmount); - expect(controller.currentWorkerMana).toEqual(expectedAmount); }); }); diff --git a/modules/worker/back/methods/worker-mana/getCurrentWorkerMana.js b/modules/worker/back/methods/worker-mana/getCurrentWorkerMana.js deleted file mode 100644 index fa34af4750..0000000000 --- a/modules/worker/back/methods/worker-mana/getCurrentWorkerMana.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = Self => { - Self.remoteMethodCtx('getCurrentWorkerMana', { - description: 'Returns the mana of the logged worker', - accessType: 'READ', - accepts: [], - returns: { - type: 'number', - root: true - }, - http: { - path: `/getCurrentWorkerMana`, - verb: 'GET' - } - }); - - Self.getCurrentWorkerMana = async ctx => { - let userId = ctx.req.accessToken.userId; - - let workerMana = await Self.app.models.WorkerMana.findOne({ - where: {workerFk: userId}, - fields: 'amount' - }); - - return workerMana ? workerMana.amount : 0; - }; -}; diff --git a/modules/worker/back/methods/worker-mana/specs/getCurrentWorkerMana.spec.js b/modules/worker/back/methods/worker-mana/specs/getCurrentWorkerMana.spec.js deleted file mode 100644 index 8d626e7204..0000000000 --- a/modules/worker/back/methods/worker-mana/specs/getCurrentWorkerMana.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -const app = require('vn-loopback/server/server'); - -describe('workerMana getCurrentWorkerMana()', () => { - it('should get the mana of the logged worker', async() => { - let mana = await app.models.WorkerMana.getCurrentWorkerMana({req: {accessToken: {userId: 18}}}); - - expect(mana).toEqual(124); - }); - - it('should return 0 if the user doesnt uses mana', async() => { - let mana = await app.models.WorkerMana.getCurrentWorkerMana({req: {accessToken: {userId: 9}}}); - - expect(mana).toEqual(0); - }); -}); diff --git a/modules/worker/back/models/worker-mana.js b/modules/worker/back/models/worker-mana.js deleted file mode 100644 index 99a0f76948..0000000000 --- a/modules/worker/back/models/worker-mana.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = Self => { - require('../methods/worker-mana/getCurrentWorkerMana')(Self); -}; From ab1cc34015686624bcb53a8b7eac620191cd52ca Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 13 Oct 2023 15:14:48 +0200 Subject: [PATCH 078/449] refs #6199 feat(sale): best quantity restriction --- .../back/methods/sale/updateQuantity.js | 22 +--------- modules/ticket/back/models/sale.js | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index 3759285068..ce7db5ffd8 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -1,4 +1,4 @@ -let UserError = require('vn-loopback/util/user-error'); +const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('updateQuantity', { @@ -64,26 +64,6 @@ module.exports = Self => { const sale = await models.Sale.findById(id, filter, myOptions); - const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); - if (newQuantity > sale.quantity && !isRoleAdvanced) - throw new UserError('The new quantity should be smaller than the old one'); - - const ticketRefund = await models.TicketRefund.findOne({ - where: {refundTicketFk: sale.ticketFk}, - fields: ['id']} - , myOptions); - - const item = await models.Item.findOne({ - where: {id: sale.itemFk}, - fields: ['minQuantity']} - , myOptions); - - if (newQuantity < item.minQuantity && !ticketRefund) - throw new UserError('The amount cannot be less than the minimum'); - - if (newQuantity < 0 && !ticketRefund) - throw new UserError('You can only add negative amounts in refund tickets'); - const oldQuantity = sale.quantity; const result = await sale.updateAttributes({quantity: newQuantity}, myOptions); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index ae247fc242..556f35d606 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -1,3 +1,5 @@ +const UserError = require('vn-loopback/util/user-error'); + module.exports = Self => { require('../methods/sale/getClaimableFromTicket')(Self); require('../methods/sale/reserve')(Self); @@ -13,4 +15,43 @@ module.exports = Self => { Self.validatesPresenceOf('concept', { message: `Concept cannot be blank` }); + + Self.observe('before save', async ctx => { + const models = Self.app.models; + const changes = ctx.data || ctx.instance; + const instance = ctx.currentInstance; + console.log(ctx?.req?.accessToken, instance, changes); + const newQuantity = changes?.quantity; + if (newQuantity === null) return; + + const canEditQuantity = await models.ACL.checkAccessAcl(ctx, 'Sale', 'canForceQuantity', 'WRITE'); + if (canEditQuantity) return; + + const ticketId = changes?.ticketFk || instance?.ticketFk; + const itemId = changes?.itemFk || instance?.itemFk; + + const ticketRefund = await models.TicketRefund.findOne({ + where: {refundTicketFk: ticketId}, + fields: ['id']} + , ctx.options); + + const item = await models.Item.findOne({ + where: {id: itemId}, + fields: ['minQuantity']} + , ctx.options); + + if (newQuantity < item.minQuantity && !ticketRefund) + throw new UserError('The amount cannot be less than the minimum'); + + if (newQuantity < 0 && !ticketRefund) + throw new UserError('You can only add negative amounts in refund tickets'); + + const oldQuantity = instance?.quantity; + if (oldQuantity === null) return; + + const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); + if (newQuantity > oldQuantity && !isRoleAdvanced) + throw new UserError('The new quantity should be smaller than the old one'); + }); }; + From f832c1d9eceba58e63530197e54a6716809f2a09 Mon Sep 17 00:00:00 2001 From: pablone Date: Sun, 15 Oct 2023 11:08:33 +0200 Subject: [PATCH 079/449] refs #5979 getUrl --- back/methods/collection/getTickets.js | 21 ++++---------- loopback/common/methods/application/getUrl.js | 29 +++++++++++++++++++ loopback/common/models/application.js | 1 + loopback/common/models/application.json | 8 ++++- .../back/methods/claim/claimPickupEmail.js | 7 ++--- .../claim/back/methods/claim/updateClaim.js | 9 +++--- .../back/methods/sale/updateQuantity.js | 7 +++-- 7 files changed, 54 insertions(+), 28 deletions(-) create mode 100644 loopback/common/methods/application/getUrl.js diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js index 445fc070d3..8509edadf5 100644 --- a/back/methods/collection/getTickets.js +++ b/back/methods/collection/getTickets.js @@ -26,7 +26,7 @@ module.exports = Self => { Self.getTickets = async(ctx, id, print, options) => { const userId = ctx.req.accessToken.userId; - const origin = ctx.req.headers.origin; + const url = Self.app.models.Application.getUrl(); const $t = ctx.req.__; const myOptions = {}; @@ -36,7 +36,6 @@ module.exports = Self => { myOptions.userId = userId; const promises = []; - const [tickets] = await Self.rawSql(`CALL vn.collection_getTickets(?)`, [id], myOptions); const sales = await Self.rawSql(` SELECT s.ticketFk, @@ -46,11 +45,11 @@ module.exports = Self => { i.longName, i.size, ic.color, - o.code origin, + o.code url, ish.packing, ish.grouping, s.isAdded, - s.originalQuantity, + s.urlalQuantity, s.quantity saleQuantity, iss.quantity reservedQuantity, SUM(iss.quantity) OVER (PARTITION BY s.id ORDER BY ish.id) accumulatedQuantity, @@ -74,7 +73,7 @@ module.exports = Self => { LEFT JOIN shelving sh ON sh.code = ish.shelvingFk LEFT JOIN parking p ON p.id = sh.parkingFk LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk - LEFT JOIN origin o ON o.id = i.originFk + LEFT JOIN url o ON o.id = i.urlFk WHERE tc.collectionFk = ? GROUP BY ish.id, p.code, p2.code ORDER BY pickingOrder;`, [id], myOptions); @@ -86,24 +85,19 @@ module.exports = Self => { if (tickets && tickets.length) { for (const ticket of tickets) { const ticketId = ticket.ticketFk; - - // SEND ROCKET if (ticket.observaciones != '') { for (observation of ticket.observaciones.split(' ')) { if (['#', '@'].includes(observation.charAt(0))) { promises.push(Self.app.models.Chat.send(ctx, observation, $t('The ticket is in preparation', { ticketId: ticketId, - ticketUrl: `${origin}/#!/ticket/${ticketId}/summary`, + ticketUrl: `${url}/#!/ticket/${ticketId}/summary`, salesPersonId: ticket.salesPersonFk }))); } } } - - // SET COLLECTION if (sales && sales.length) { - // GET BARCODES const barcodes = await Self.rawSql(` SELECT s.id saleFk, b.code, c.id FROM vn.sale s @@ -114,13 +108,10 @@ module.exports = Self => { WHERE s.ticketFk = ? AND tr.landed >= util.VN_CURDATE() - INTERVAL 1 YEAR`, [ticketId], myOptions); - - // BINDINGS ticket.sales = []; for (const sale of sales) { if (sale.ticketFk === ticketId) { sale.Barcodes = []; - if (barcodes && barcodes.length) { for (const barcode of barcodes) { if (barcode.saleFk === sale.saleFk) { @@ -131,7 +122,6 @@ module.exports = Self => { } } } - ticket.sales.push(sale); } } @@ -140,7 +130,6 @@ module.exports = Self => { } } await Promise.all(promises); - return collection; }; }; diff --git a/loopback/common/methods/application/getUrl.js b/loopback/common/methods/application/getUrl.js new file mode 100644 index 0000000000..57aed0b848 --- /dev/null +++ b/loopback/common/methods/application/getUrl.js @@ -0,0 +1,29 @@ +module.exports = Self => { + Self.remoteMethodCtx('getUrl', { + description: 'Returns the colling app name', + accepts: [ + { + arg: 'appName', + type: 'string', + required: false + } + ], + returns: { + type: 'object', + root: true + }, + http: { + path: `/getUrl`, + verb: 'get' + } + }); + Self.getUrl = async(appName = 'salix') => { + const {url} = Self.app.models.Url.findOne({ + where: { + appName, + enviroment: process.env.NODE_ENV || 'development' + } + }); + return url; + }; +}; diff --git a/loopback/common/models/application.js b/loopback/common/models/application.js index 5e767fdc11..b3841d34a3 100644 --- a/loopback/common/models/application.js +++ b/loopback/common/models/application.js @@ -2,4 +2,5 @@ module.exports = function(Self) { require('../methods/application/status')(Self); require('../methods/application/post')(Self); + require('../methods/application/getUrl')(Self); }; diff --git a/loopback/common/models/application.json b/loopback/common/models/application.json index bc72df315a..6343c3421f 100644 --- a/loopback/common/models/application.json +++ b/loopback/common/models/application.json @@ -13,6 +13,12 @@ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" - } + }, + { + "property": "getUrl", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } ] } diff --git a/modules/claim/back/methods/claim/claimPickupEmail.js b/modules/claim/back/methods/claim/claimPickupEmail.js index 1fd8eb99e3..f4cd0fc206 100644 --- a/modules/claim/back/methods/claim/claimPickupEmail.js +++ b/modules/claim/back/methods/claim/claimPickupEmail.js @@ -43,9 +43,8 @@ module.exports = Self => { Self.claimPickupEmail = async ctx => { const models = Self.app.models; - const userId = ctx.req.accessToken.userId; const $t = ctx.req.__; // $translate - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const args = Object.assign({}, ctx.args); const params = { @@ -70,9 +69,9 @@ module.exports = Self => { const message = $t('Claim pickup order sent', { claimId: args.id, clientName: claim.client().name, - claimUrl: `${origin}/#!/claim/${args.id}/summary`, + claimUrl: `${url}/claim/${args.id}/summary`, }); - + console.log(message); const salesPersonId = claim.client().salesPersonFk; if (salesPersonId) await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index 5486b8efff..b7ffa9ff5b 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -115,27 +115,28 @@ module.exports = Self => { async function notifyStateChange(ctx, workerId, claim, state) { const models = Self.app.models; - const origin = ctx.req.headers.origin; + const url = await models.Application.getUrl(); const $t = ctx.req.__; // $translate const message = $t(`Claim state has changed to ${state}`, { claimId: claim.id, clientName: claim.client().name, - claimUrl: `${origin}/#!/claim/${claim.id}/summary` + claimUrl: `${url}/claim/${claim.id}/summary` }); await models.Chat.sendCheckingPresence(ctx, workerId, message); } async function notifyPickUp(ctx, workerId, claim) { - const origin = ctx.req.headers.origin; const models = Self.app.models; + const url = await models.Application.getUrl(); const $t = ctx.req.__; // $translate const message = $t('Claim will be picked', { claimId: claim.id, clientName: claim.client().name, - claimUrl: `${origin}/#!/claim/${claim.id}/summary` + claimUrl: `${url}/claim/${claim.id}/summary` }); + console.log(message); await models.Chat.sendCheckingPresence(ctx, workerId, message); } }; diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index edbc34e421..3cbd9255f6 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -80,16 +80,17 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await models.Application.getUrl(); const message = $t('Changed sale quantity', { ticketId: sale.ticket().id, itemId: sale.itemFk, concept: sale.concept, oldQuantity: oldQuantity, newQuantity: newQuantity, - ticketUrl: `${origin}/#!/ticket/${sale.ticket().id}/sale`, - itemUrl: `${origin}/#!/item/${sale.itemFk}/summary` + ticketUrl: `${url}/ticket/${sale.ticket().id}/sale`, + itemUrl: `${url}/item/${sale.itemFk}/summary` }); + await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); } From b769fa9bcf5ad8c99d2365742c78918783758c0d Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 16 Oct 2023 10:10:57 +0200 Subject: [PATCH 080/449] refs #6199 fix(sale_updateQuantity): if clientType is loses skip test: fix updateQuantity activeCtx and add test for minQuantity --- loopback/locale/en.json | 5 +- .../claim/specs/regularizeClaim.spec.js | 2 +- .../methods/sale/specs/updateQuantity.spec.js | 62 ++++++++++++++----- .../back/methods/sale/updateQuantity.js | 1 - modules/ticket/back/models/sale.js | 35 +++++++++-- 5 files changed, 81 insertions(+), 24 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 645a874e89..f61226e9ee 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -189,5 +189,6 @@ "The sales do not exists": "The sales do not exists", "Ticket without Route": "Ticket without route", "Booking completed": "Booking complete", - "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation" -} + "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation", + "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets" +} \ No newline at end of file diff --git a/modules/claim/back/methods/claim/specs/regularizeClaim.spec.js b/modules/claim/back/methods/claim/specs/regularizeClaim.spec.js index 276843c32a..95c356374e 100644 --- a/modules/claim/back/methods/claim/specs/regularizeClaim.spec.js +++ b/modules/claim/back/methods/claim/specs/regularizeClaim.spec.js @@ -64,7 +64,7 @@ describe('claim regularizeClaim()', () => { claimEnds = await importTicket(ticketId, claimId, userId, options); - for (claimEnd of claimEnds) + for (const claimEnd of claimEnds) await claimEnd.updateAttributes({claimDestinationFk: trashDestination}, options); let claimBefore = await models.Claim.findById(claimId, null, options); diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index 8064ea30b2..bb58780e37 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -2,20 +2,6 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('sale updateQuantity()', () => { - beforeAll(async() => { - const activeCtx = { - accessToken: {userId: 9}, - http: { - req: { - headers: {origin: 'http://localhost'} - } - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ - active: activeCtx - }); - }); - const ctx = { req: { accessToken: {userId: 9}, @@ -23,6 +9,18 @@ describe('sale updateQuantity()', () => { __: () => {} } }; + function getActiveCtx(userId) { + return { + active: { + accessToken: {userId}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + } + }; + } it('should throw an error if the quantity is greater than it should be', async() => { const ctx = { @@ -32,6 +30,8 @@ describe('sale updateQuantity()', () => { __: () => {} } }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + const tx = await models.Sale.beginTransaction({}); let error; @@ -50,6 +50,8 @@ describe('sale updateQuantity()', () => { }); it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); + const tx = await models.Sale.beginTransaction({}); const saleId = 17; const buyerId = 35; @@ -87,6 +89,8 @@ describe('sale updateQuantity()', () => { }); it('should update the quantity of a given sale current line', async() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); + const tx = await models.Sale.beginTransaction({}); const saleId = 25; const newQuantity = 4; @@ -119,6 +123,8 @@ describe('sale updateQuantity()', () => { __: () => {} } }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + const saleId = 17; const newQuantity = -10; @@ -140,6 +146,8 @@ describe('sale updateQuantity()', () => { }); it('should update a negative quantity when is a ticket refund', async() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); + const tx = await models.Sale.beginTransaction({}); const saleId = 13; const newQuantity = -10; @@ -159,4 +167,30 @@ describe('sale updateQuantity()', () => { throw e; } }); + + it('should throw an error if the quantity is less than the minimum quantity of the item', async() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const newQuantity = 29; + + let error; + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', 30, options); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('The amount cannot be less than the minimum')); + }); }); diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index ce7db5ffd8..55106f0533 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -1,4 +1,3 @@ -const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('updateQuantity', { diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 556f35d606..bacc5ef447 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -1,4 +1,5 @@ const UserError = require('vn-loopback/util/user-error'); +const LoopBackContext = require('loopback-context'); module.exports = Self => { require('../methods/sale/getClaimableFromTicket')(Self); @@ -20,21 +21,46 @@ module.exports = Self => { const models = Self.app.models; const changes = ctx.data || ctx.instance; const instance = ctx.currentInstance; - console.log(ctx?.req?.accessToken, instance, changes); - const newQuantity = changes?.quantity; - if (newQuantity === null) return; + const newQuantity = changes?.quantity; + if (newQuantity == null) return; + + const loopBackContext = LoopBackContext.getCurrentContext(); + ctx.req = loopBackContext.active; const canEditQuantity = await models.ACL.checkAccessAcl(ctx, 'Sale', 'canForceQuantity', 'WRITE'); if (canEditQuantity) return; const ticketId = changes?.ticketFk || instance?.ticketFk; const itemId = changes?.itemFk || instance?.itemFk; + const ticket = await models.Ticket.findById( + ticketId, + { + fields: ['id', 'clientFk'], + include: { + relation: 'client', + scope: { + fields: ['id', 'clientTypeFk'], + include: { + relation: 'type', + scope: { + fields: ['code', 'description'] + } + } + } + } + }, + ctx.options); + if (ticket.client().type().code === 'loses') return; + const ticketRefund = await models.TicketRefund.findOne({ where: {refundTicketFk: ticketId}, fields: ['id']} , ctx.options); + if (newQuantity < 0 && !ticketRefund) + throw new UserError('You can only add negative amounts in refund tickets'); + const item = await models.Item.findOne({ where: {id: itemId}, fields: ['minQuantity']} @@ -43,9 +69,6 @@ module.exports = Self => { if (newQuantity < item.minQuantity && !ticketRefund) throw new UserError('The amount cannot be less than the minimum'); - if (newQuantity < 0 && !ticketRefund) - throw new UserError('You can only add negative amounts in refund tickets'); - const oldQuantity = instance?.quantity; if (oldQuantity === null) return; From f79e71161744cce480b88b1e07ec3cd1946ebe17 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 16 Oct 2023 10:19:33 +0200 Subject: [PATCH 081/449] refs #6199 test: updateQuantity refactor --- .../ticket/back/methods/sale/specs/updateQuantity.spec.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index bb58780e37..6bf0a0d7eb 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -174,14 +174,15 @@ describe('sale updateQuantity()', () => { const tx = await models.Sale.beginTransaction({}); const itemId = 2; const saleId = 17; - const newQuantity = 29; + const minQuantity = 30; + const newQuantity = minQuantity - 1; let error; try { const options = {transaction: tx}; const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', 30, options); + await item.updateAttribute('minQuantity', minQuantity, options); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); From 9e39e96cf4c43cf6e3810e2e85771947103bd94a Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 16 Oct 2023 15:22:33 +0200 Subject: [PATCH 082/449] hotFix: workerTimeControl --- .../methods/worker-time-control/sendMail.js | 64 ++++++++----------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/modules/worker/back/methods/worker-time-control/sendMail.js b/modules/worker/back/methods/worker-time-control/sendMail.js index 2c51436127..6f67bbea34 100644 --- a/modules/worker/back/methods/worker-time-control/sendMail.js +++ b/modules/worker/back/methods/worker-time-control/sendMail.js @@ -66,46 +66,36 @@ module.exports = Self => { stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.timeControlCalculate'); stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.timeBusinessCalculate'); + const destroyAllWhere = { + timed: {between: [started, ended]}, + isSendMail: true + }; + const updateAllWhere = { + year: args.year, + week: args.week + }; + + const tmpUserSQL = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.user + SELECT id as userFk + FROM vn.worker`; + let tmpUser = new ParameterizedSQL(tmpUserSQL); + if (args.workerId) { - await models.WorkerTimeControl.destroyAll({ - userFk: args.workerId, - timed: {between: [started, ended]}, - isSendMail: true - }, myOptions); - - const where = { - workerFk: args.workerId, - year: args.year, - week: args.week - }; - await models.WorkerTimeControlMail.updateAll(where, { - updated: Date.vnNew(), state: 'SENDED' - }, myOptions); - - stmt = new ParameterizedSQL('DROP TEMPORARY TABLE IF EXISTS tmp.`user`'); - stmts.push(stmt); - stmt = new ParameterizedSQL('CREATE TEMPORARY TABLE tmp.`user` SELECT id userFk FROM account.user WHERE id = ?', [args.workerId]); - stmts.push(stmt); - } else { - await models.WorkerTimeControl.destroyAll({ - timed: {between: [started, ended]}, - isSendMail: true - }, myOptions); - - const where = { - year: args.year, - week: args.week - }; - await models.WorkerTimeControlMail.updateAll(where, { - updated: Date.vnNew(), state: 'SENDED' - }, myOptions); - - stmt = new ParameterizedSQL('DROP TEMPORARY TABLE IF EXISTS tmp.`user`'); - stmts.push(stmt); - stmt = new ParameterizedSQL('CREATE TEMPORARY TABLE IF NOT EXISTS tmp.`user` SELECT id as userFk FROM vn.worker w JOIN account.`user` u ON u.id = w.id WHERE id IS NOT NULL'); - stmts.push(stmt); + destroyAllWhere.userFk = args.workerId; + updateAllWhere.workerFk = args.workerId; + tmpUser = new ParameterizedSQL(tmpUserSQL + ' WHERE id = ?', [args.workerId]); } + await models.WorkerTimeControl.destroyAll(destroyAllWhere, myOptions); + + await models.WorkerTimeControlMail.updateAll(updateAllWhere, { + updated: Date.vnNew(), + state: 'SENDED' + }, myOptions); + + stmts.push(tmpUser); + stmt = new ParameterizedSQL( `CALL vn.timeControl_calculate(?, ?) `, [started, ended]); From 093431ecdfb84f306e4a833c7b908782452130fd Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 16 Oct 2023 15:27:10 +0200 Subject: [PATCH 083/449] refs #6119 fix(sale_hook): fix quantity case --- modules/ticket/back/methods/ticket/addSale.js | 11 ----- modules/ticket/back/models/sale.js | 44 ++++++++++++------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/modules/ticket/back/methods/ticket/addSale.js b/modules/ticket/back/methods/ticket/addSale.js index cbf884273b..21fea1c81c 100644 --- a/modules/ticket/back/methods/ticket/addSale.js +++ b/modules/ticket/back/methods/ticket/addSale.js @@ -63,17 +63,6 @@ module.exports = Self => { } }, myOptions); - const itemInfo = await models.Item.getVisibleAvailable( - itemId, - ticket.warehouseFk, - ticket.shipped, - myOptions - ); - - const isPackaging = item.family == 'EMB'; - if (!isPackaging && itemInfo.available < quantity) - throw new UserError(`This item is not available`); - const newSale = await models.Sale.create({ ticketFk: id, itemFk: item.id, diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index bacc5ef447..378ff3490c 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -27,8 +27,7 @@ module.exports = Self => { const loopBackContext = LoopBackContext.getCurrentContext(); ctx.req = loopBackContext.active; - const canEditQuantity = await models.ACL.checkAccessAcl(ctx, 'Sale', 'canForceQuantity', 'WRITE'); - if (canEditQuantity) return; + if (await models.ACL.checkAccessAcl(ctx, 'Sale', 'canForceQuantity', 'WRITE')) return; const ticketId = changes?.ticketFk || instance?.ticketFk; const itemId = changes?.itemFk || instance?.itemFk; @@ -36,7 +35,7 @@ module.exports = Self => { const ticket = await models.Ticket.findById( ticketId, { - fields: ['id', 'clientFk'], + fields: ['id', 'clientFk', 'warehouseFk', 'shipped'], include: { relation: 'client', scope: { @@ -51,29 +50,42 @@ module.exports = Self => { } }, ctx.options); - if (ticket.client().type().code === 'loses') return; + if (ticket?.client()?.type()?.code === 'loses') return; - const ticketRefund = await models.TicketRefund.findOne({ - where: {refundTicketFk: ticketId}, - fields: ['id']} - , ctx.options); + const isRefund = await models.TicketRefund.findOne({ + fields: ['id'], + where: {refundTicketFk: ticketId} + }, ctx.options); + if (isRefund) return; - if (newQuantity < 0 && !ticketRefund) + if (newQuantity < 0) throw new UserError('You can only add negative amounts in refund tickets'); const item = await models.Item.findOne({ + fields: ['family', 'minQuantity'], where: {id: itemId}, - fields: ['minQuantity']} - , ctx.options); + }, ctx.options); - if (newQuantity < item.minQuantity && !ticketRefund) - throw new UserError('The amount cannot be less than the minimum'); + if (item.family == 'EMB') return; + + const itemInfo = await models.Item.getVisibleAvailable( + itemId, + ticket.warehouseFk, + ticket.shipped, + ctx.options + ); const oldQuantity = instance?.quantity; - if (oldQuantity === null) return; + const quantityAdded = newQuantity - oldQuantity; + if (itemInfo.available < quantityAdded) + throw new UserError(`This item is not available`); - const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); - if (newQuantity > oldQuantity && !isRoleAdvanced) + if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; + + if (newQuantity < item.minQuantity && itemInfo.available != newQuantity) + throw new UserError('The amount cannot be less than the minimum'); + + if (!ctx.isNewInstance && newQuantity > oldQuantity) throw new UserError('The new quantity should be smaller than the old one'); }); }; From bd535374d8bf197066a2a3949acbf5e3e6b5644a Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 16 Oct 2023 15:58:25 +0200 Subject: [PATCH 084/449] ref #6138 setPasword created --- back/models/vn-user.json | 6 +- db/changes/234201/00-aclSetPassword.sql | 4 ++ .../worker/back/methods/worker/setPassword.js | 48 +++++++++++++++ .../methods/worker/specs/setPassword.spec.js | 61 +++++++++++++++++++ modules/worker/back/models/worker.js | 1 + modules/worker/front/card/index.js | 2 +- modules/worker/front/descriptor/index.html | 30 ++++++++- modules/worker/front/descriptor/index.js | 29 ++++++++- modules/worker/front/descriptor/index.spec.js | 20 ++++++ 9 files changed, 195 insertions(+), 6 deletions(-) create mode 100644 db/changes/234201/00-aclSetPassword.sql create mode 100644 modules/worker/back/methods/worker/setPassword.js create mode 100644 modules/worker/back/methods/worker/specs/setPassword.spec.js diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 9e3f8df891..01d83e421a 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -45,6 +45,9 @@ "email": { "type": "string" }, + "emailVerified": { + "type": "boolean" + }, "created": { "type": "date" }, @@ -144,7 +147,8 @@ "image", "hasGrant", "realm", - "email" + "email", + "emailVerified" ] } } diff --git a/db/changes/234201/00-aclSetPassword.sql b/db/changes/234201/00-aclSetPassword.sql new file mode 100644 index 0000000000..44b3e9de04 --- /dev/null +++ b/db/changes/234201/00-aclSetPassword.sql @@ -0,0 +1,4 @@ +INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) + VALUES ('Worker','setPassword','*','ALLOW','ROLE','employee'); + + diff --git a/modules/worker/back/methods/worker/setPassword.js b/modules/worker/back/methods/worker/setPassword.js new file mode 100644 index 0000000000..fcfb5e7334 --- /dev/null +++ b/modules/worker/back/methods/worker/setPassword.js @@ -0,0 +1,48 @@ +const UserError = require('vn-loopback/util/user-error'); +module.exports = Self => { + Self.remoteMethodCtx('setPassword', { + description: 'Set a new password', + accepts: [ + { + arg: 'workerFk', + type: 'number', + required: true, + description: 'The worker id', + }, + { + arg: 'newPass', + type: 'String', + required: true, + description: 'The new worker password' + } + ], + http: { + path: `/:id/setPassword`, + verb: 'PATCH' + } + }); + Self.setPassword = async(ctx, options) => { + const models = Self.app.models; + const myOptions = {}; + const {args} = ctx; + let tx; + if (typeof options == 'object') + Object.assign(myOptions, options); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + try { + const isSubordinate = await models.Worker.isSubordinate(ctx, args.workerFk, myOptions); + if (!isSubordinate) throw new UserError('You don\'t have enough privileges.'); + + await models.VnUser.setPassword(args.workerFk, args.newPass, myOptions); + await models.VnUser.updateAll({id: args.workerFk}, {emailVerified: 1}, myOptions); + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/worker/back/methods/worker/specs/setPassword.spec.js b/modules/worker/back/methods/worker/specs/setPassword.spec.js new file mode 100644 index 0000000000..fbb403b24c --- /dev/null +++ b/modules/worker/back/methods/worker/specs/setPassword.spec.js @@ -0,0 +1,61 @@ +const UserError = require('vn-loopback/util/user-error'); + +const models = require('vn-loopback/server/server').models; + +describe('worker setPassword()', () => { + let ctx; + beforeAll(() => { + ctx = { + req: { + accessToken: {}, + headers: {origin: 'http://localhost'} + }, + args: {workerFk: 9} + }; + }); + + beforeEach(() => { + ctx.req.accessToken.userId = 20; + ctx.args.newPass = 'H3rn4d3z#'; + }); + + it('should change the password', async() => { + const tx = await models.Worker.beginTransaction({}); + + try { + const options = {transaction: tx}; + await models.Worker.setPassword(ctx, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw an error: Password does not meet requirements', async() => { + const tx = await models.Collection.beginTransaction({}); + ctx.args.newPass = 'Hi'; + try { + const options = {transaction: tx}; + await models.Worker.setPassword(ctx, options); + await tx.rollback(); + } catch (e) { + expect(e.sqlMessage).toEqual('Password does not meet requirements'); + await tx.rollback(); + } + }); + + it('should throw an error: You don\'t have enough privileges.', async() => { + ctx.req.accessToken.userId = 5; + const tx = await models.Collection.beginTransaction({}); + try { + const options = {transaction: tx}; + await models.Worker.setPassword(ctx, options); + await tx.rollback(); + } catch (e) { + expect(e).toEqual(new UserError(`You don't have enough privileges.`)); + await tx.rollback(); + } + }); +}); diff --git a/modules/worker/back/models/worker.js b/modules/worker/back/models/worker.js index ccae3a6e6f..985d83e9f7 100644 --- a/modules/worker/back/models/worker.js +++ b/modules/worker/back/models/worker.js @@ -18,6 +18,7 @@ module.exports = Self => { require('../methods/worker/allocatePDA')(Self); require('../methods/worker/search')(Self); require('../methods/worker/isAuthorized')(Self); + require('../methods/worker/setPassword')(Self); Self.validatesUniquenessOf('locker', { message: 'This locker has already been assigned' diff --git a/modules/worker/front/card/index.js b/modules/worker/front/card/index.js index b8b533c5d2..9a40e31c2e 100644 --- a/modules/worker/front/card/index.js +++ b/modules/worker/front/card/index.js @@ -8,7 +8,7 @@ class Controller extends ModuleCard { { relation: 'user', scope: { - fields: ['name'], + fields: ['name', 'emailVerified'], include: { relation: 'emailUser', scope: { diff --git a/modules/worker/front/descriptor/index.html b/modules/worker/front/descriptor/index.html index 758f639ff4..aa6b803003 100644 --- a/modules/worker/front/descriptor/index.html +++ b/modules/worker/front/descriptor/index.html @@ -11,6 +11,9 @@ ? 'Click to allow the user to be disabled' : 'Click to exclude the user from getting disabled'}} + + Change password +
@@ -72,4 +75,29 @@ - + + + + + + + + + + + + diff --git a/modules/worker/front/descriptor/index.js b/modules/worker/front/descriptor/index.js index 07e16c0d66..fe337974c7 100644 --- a/modules/worker/front/descriptor/index.js +++ b/modules/worker/front/descriptor/index.js @@ -1,5 +1,6 @@ import ngModule from '../module'; import Descriptor from 'salix/components/descriptor'; +const UserError = require('vn-loopback/util/user-error'); class Controller extends Descriptor { constructor($element, $, $rootScope) { super($element, $); @@ -12,9 +13,11 @@ class Controller extends Descriptor { set worker(value) { this.entity = value; - if (value) this.getIsExcluded(); + + if (this.entity && !this.entity.user.emailVerified) + this.getPassRequirements(); } getIsExcluded() { @@ -38,7 +41,7 @@ class Controller extends Descriptor { { relation: 'user', scope: { - fields: ['name'], + fields: ['name', 'emailVerified'], include: { relation: 'emailUser', scope: { @@ -66,10 +69,30 @@ class Controller extends Descriptor { } ] }; - + // Añadir filter para sacar user return this.getData(`Workers/${this.id}`, {filter}) .then(res => this.entity = res.data); } + + getPassRequirements() { + this.$http.get('UserPasswords/findOne') + .then(res => { + this.passRequirements = res.data; + }); + } + + setPassword() { + if (!this.newPassword) + throw new UserError(`You must enter a new password`); + if (this.newPassword != this.repeatPassword) + throw new UserError(`Passwords don't match`); + this.$http.patch( + `Workers/${this.entity.id}/setPassword`, + {workerFk: this.entity.id, newPass: this.newPassword} + ) .then(() => { + this.vnApp.showSuccess(this.$translate.instant('Password changed!')); + }); + } } Controller.$inject = ['$element', '$scope', '$rootScope']; diff --git a/modules/worker/front/descriptor/index.spec.js b/modules/worker/front/descriptor/index.spec.js index dfb8004154..d158a9e8e1 100644 --- a/modules/worker/front/descriptor/index.spec.js +++ b/modules/worker/front/descriptor/index.spec.js @@ -23,4 +23,24 @@ describe('vnWorkerDescriptor', () => { expect(controller.worker).toEqual(response); }); }); + + describe('setPassword()', () => { + it('should throw an error: You must enter a new password', () => { + try { + controller.setPassword(); + } catch (error) { + expect(error.message).toEqual('You must enter a new password'); + } + }); + + it('should throw an error: Passwords don\'t match', () => { + controller.newPassword = 'aaa'; + controller.repeatPassword = 'bbb'; + try { + controller.setPassword(); + } catch (error) { + expect(error.message).toEqual('Passwords don\'t match'); + } + }); + }); }); From 033c02750b48106e25000fb77a35b7b48db7da77 Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 16 Oct 2023 18:24:58 +0200 Subject: [PATCH 085/449] refactor(origin): .origin por getUrl() --- back/methods/collection/getTickets.js | 8 +-- back/models/vn-user.js | 51 +------------------ db/tests/vn/ticketCalculateClon.spec.js | 3 +- loopback/common/methods/application/getUrl.js | 3 +- .../back/methods/claim/createFromSales.js | 6 +-- .../back/methods/claim/regularizeClaim.js | 6 +-- modules/client/back/models/client.js | 21 +++++--- .../client/back/models/credit-insurance.js | 4 +- .../methods/invoiceOut/makePdfAndNotify.js | 4 +- .../ticket/back/methods/sale/deleteSales.js | 6 +-- modules/ticket/back/methods/sale/reserve.js | 10 ++-- .../ticket/back/methods/sale/updatePrice.js | 8 ++- .../back/methods/sale/updateQuantity.js | 7 +-- .../back/methods/ticket-request/confirm.js | 6 +-- .../back/methods/ticket-request/deny.js | 4 +- modules/ticket/back/methods/ticket/addSale.js | 4 +- .../back/methods/ticket/componentUpdate.js | 4 +- modules/ticket/back/methods/ticket/merge.js | 6 +-- modules/ticket/back/methods/ticket/restore.js | 4 +- .../ticket/back/methods/ticket/setDeleted.js | 7 +-- .../back/methods/ticket/updateDiscount.js | 5 +- .../back/methods/worker/createAbsence.js | 4 +- .../back/methods/worker/deleteAbsence.js | 4 +- 23 files changed, 70 insertions(+), 115 deletions(-) diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js index 8509edadf5..dbb286b4f6 100644 --- a/back/methods/collection/getTickets.js +++ b/back/methods/collection/getTickets.js @@ -45,11 +45,11 @@ module.exports = Self => { i.longName, i.size, ic.color, - o.code url, + o.code origin, ish.packing, ish.grouping, s.isAdded, - s.urlalQuantity, + s.originalQuantity, s.quantity saleQuantity, iss.quantity reservedQuantity, SUM(iss.quantity) OVER (PARTITION BY s.id ORDER BY ish.id) accumulatedQuantity, @@ -73,7 +73,7 @@ module.exports = Self => { LEFT JOIN shelving sh ON sh.code = ish.shelvingFk LEFT JOIN parking p ON p.id = sh.parkingFk LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk - LEFT JOIN url o ON o.id = i.urlFk + LEFT JOIN origin o ON o.id = i.originFk WHERE tc.collectionFk = ? GROUP BY ish.id, p.code, p2.code ORDER BY pickingOrder;`, [id], myOptions); @@ -91,7 +91,7 @@ module.exports = Self => { promises.push(Self.app.models.Chat.send(ctx, observation, $t('The ticket is in preparation', { ticketId: ticketId, - ticketUrl: `${url}/#!/ticket/${ticketId}/summary`, + ticketUrl: `${url}ticket/${ticketId}/summary`, salesPersonId: ticket.salesPersonFk }))); } diff --git a/back/models/vn-user.js b/back/models/vn-user.js index cf210b61b8..a38139bc7d 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -1,5 +1,4 @@ const vnModel = require('vn-loopback/common/models/vn-model'); -const LoopBackContext = require('loopback-context'); const {Email} = require('vn-print'); module.exports = function(Self) { @@ -90,11 +89,7 @@ module.exports = function(Self) { }; Self.on('resetPasswordRequest', async function(info) { - 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 = await Self.app.models.Application.getUrl(); const defaultHash = '/reset-password?access_token=$token$'; const recoverHashes = { @@ -110,7 +105,7 @@ module.exports = function(Self) { const params = { recipient: info.email, lang: user.lang, - url: origin + '/#!' + recoverHash + url: url.slice(0, -1) + recoverHash }; const options = Object.assign({}, info.options); @@ -177,46 +172,4 @@ module.exports = function(Self) { Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls = Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls .filter(acl => acl.property != 'changePassword'); - - // FIXME: https://redmine.verdnatura.es/issues/5761 - // Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => { - // if (!ctx.args || !ctx.args.data.email) 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(':'); - - // 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); - // } - // } - - // 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 instance.verify(options); - // }); }; diff --git a/db/tests/vn/ticketCalculateClon.spec.js b/db/tests/vn/ticketCalculateClon.spec.js index 9116d805fb..665d52ed09 100644 --- a/db/tests/vn/ticketCalculateClon.spec.js +++ b/db/tests/vn/ticketCalculateClon.spec.js @@ -53,7 +53,8 @@ describe('ticket ticketCalculateClon()', () => { expect(result[orderIndex][0].ticketFk).toBeGreaterThan(newestTicketIdInFixtures); }); - it('should add the ticket to the order containing the original ticket and generate landed value if it was null', async() => { + it('should add the ticket to the order containing the original ' + + 'ticket and generate landed value if it was null', async() => { let stmts = []; let stmt; diff --git a/loopback/common/methods/application/getUrl.js b/loopback/common/methods/application/getUrl.js index 57aed0b848..4e51b0776c 100644 --- a/loopback/common/methods/application/getUrl.js +++ b/loopback/common/methods/application/getUrl.js @@ -18,7 +18,8 @@ module.exports = Self => { } }); Self.getUrl = async(appName = 'salix') => { - const {url} = Self.app.models.Url.findOne({ + const {url} = await Self.app.models.Url.findOne({ + where: { appName, enviroment: process.env.NODE_ENV || 'development' diff --git a/modules/claim/back/methods/claim/createFromSales.js b/modules/claim/back/methods/claim/createFromSales.js index 07bdb30aa7..7ea26f9cc8 100644 --- a/modules/claim/back/methods/claim/createFromSales.js +++ b/modules/claim/back/methods/claim/createFromSales.js @@ -94,13 +94,13 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Created claim', { claimId: newClaim.id, ticketId: ticketId, - ticketUrl: `${origin}/#!/ticket/${ticketId}/sale`, - claimUrl: `${origin}/#!/claim/${newClaim.id}/summary`, + ticketUrl: `${url}/ticket/${ticketId}/sale`, + claimUrl: `${url}/claim/${newClaim.id}/summary`, changes: changesMade }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message); diff --git a/modules/claim/back/methods/claim/regularizeClaim.js b/modules/claim/back/methods/claim/regularizeClaim.js index 672c94947d..4ac500e2fd 100644 --- a/modules/claim/back/methods/claim/regularizeClaim.js +++ b/modules/claim/back/methods/claim/regularizeClaim.js @@ -56,15 +56,15 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { const nickname = address && address.nickname || destination.description; - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Sent units from ticket', { quantity: sale.quantity, concept: sale.concept, itemId: sale.itemFk, ticketId: sale.ticketFk, nickname: nickname, - ticketUrl: `${origin}/#!/ticket/${sale.ticketFk}/sale`, - itemUrl: `${origin}/#!/item/${sale.itemFk}/summary` + ticketUrl: `${url}ticket/${sale.ticketFk}/sale`, + itemUrl: `${url}item/${sale.itemFk}/summary` }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message); } diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 8e720484ff..1b60b13296 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -250,7 +250,12 @@ module.exports = Self => { const loopBackContext = LoopBackContext.getCurrentContext(); const accessToken = {req: loopBackContext.active.accessToken}; - const editVerifiedDataWithoutTaxDataChecked = models.ACL.checkAccessAcl(accessToken, 'Client', 'editVerifiedDataWithoutTaxDataCheck', 'WRITE'); + const editVerifiedDataWithoutTaxDataChecked = models.ACL.checkAccessAcl( + accessToken, + 'Client', + 'editVerifiedDataWithoutTaxDataCheck', + 'WRITE' + ); const hasChanges = orgData && changes; const isTaxDataChecked = hasChanges && (changes.isTaxDataChecked || orgData.isTaxDataChecked); @@ -263,7 +268,9 @@ module.exports = Self => { const sageTransactionTypeChanged = hasChanges && orgData.sageTransactionTypeFk != sageTransactionType; const cantEditVerifiedData = isTaxDataCheckedChanged && !editVerifiedDataWithoutTaxDataChecked; - const cantChangeSageData = (sageTaxTypeChanged || sageTransactionTypeChanged) && !editVerifiedDataWithoutTaxDataChecked; + const cantChangeSageData = (sageTaxTypeChanged || + sageTransactionTypeChanged + ) && !editVerifiedDataWithoutTaxDataChecked; if (cantEditVerifiedData || cantChangeSageData) throw new UserError(`You don't have enough privileges`); @@ -346,8 +353,7 @@ module.exports = Self => { const httpCtx = {req: loopBackContext.active}; const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const headers = httpRequest.headers; - const origin = headers.origin; + const url = await Self.app.models.Application.getUrl(); const salesPersonId = instance.salesPersonFk; @@ -366,7 +372,7 @@ module.exports = Self => { await email.send(); } - const fullUrl = `${origin}/#!/client/${instance.id}/billing-data`; + const fullUrl = `${url}client/${instance.id}/billing-data`; const message = $t('Changed client paymethod', { clientId: instance.id, clientName: instance.name, @@ -389,8 +395,7 @@ module.exports = Self => { const httpCtx = {req: loopBackContext.active}; const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const headers = httpRequest.headers; - const origin = headers.origin; + const url = await Self.app.models.Application.getUrl(); const models = Self.app.models; let previousWorker = {name: $t('None')}; @@ -411,7 +416,7 @@ module.exports = Self => { currentWorker.name = worker && worker.user().nickname; } - const fullUrl = `${origin}/#!/client/${client.id}/basic-data`; + const fullUrl = `${url}client/${client.id}/basic-data`; const message = $t('Client assignment has changed', { clientId: client.id, clientName: client.name, diff --git a/modules/client/back/models/credit-insurance.js b/modules/client/back/models/credit-insurance.js index 6f656d3829..619904612c 100644 --- a/modules/client/back/models/credit-insurance.js +++ b/modules/client/back/models/credit-insurance.js @@ -57,8 +57,8 @@ module.exports = function(Self) { const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const origin = httpRequest.headers.origin; - const fullPath = `${origin}/#!/client/${client.id}/credit-insurance/index`; + const url = await Self.app.models.Application.getUrl(); + const fullPath = `${url}client/${client.id}/credit-insurance/index`; const message = $t('MESSAGE_INSURANCE_CHANGE', { clientId: client.id, clientName: client.name, diff --git a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js index a48664b302..49c7850139 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js +++ b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js @@ -59,10 +59,10 @@ module.exports = Self => { }; await Self.invoiceEmail(ctx, ref); } catch (err) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = ctx.req.__('Mail not sent', { clientId: client.id, - clientUrl: `${origin}/#!/claim/${id}/summary` + clientUrl: `${url}claim/${id}/summary` }); const salesPersonId = client.salesPersonFk; diff --git a/modules/ticket/back/methods/sale/deleteSales.js b/modules/ticket/back/methods/sale/deleteSales.js index 5d1463a666..c71f8d5e13 100644 --- a/modules/ticket/back/methods/sale/deleteSales.js +++ b/modules/ticket/back/methods/sale/deleteSales.js @@ -1,5 +1,3 @@ -let UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethodCtx('deleteSales', { description: 'Deletes the selected sales', @@ -70,11 +68,11 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Deleted sales from ticket', { ticketId: ticketId, - ticketUrl: `${origin}/#!/ticket/${ticketId}/sale`, + ticketUrl: `${url}ticket/${ticketId}/sale`, deletions: deletions }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); diff --git a/modules/ticket/back/methods/sale/reserve.js b/modules/ticket/back/methods/sale/reserve.js index 2dc368af69..b111a04582 100644 --- a/modules/ticket/back/methods/sale/reserve.js +++ b/modules/ticket/back/methods/sale/reserve.js @@ -1,6 +1,3 @@ - -let UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethodCtx('reserve', { description: 'Change the state of a ticket', @@ -65,7 +62,8 @@ module.exports = Self => { promises.push(reservedSale); - changesMade += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity}) ${$t('State')}: ${$t(oldState)} ➔ *${$t(newState)}*`; + changesMade += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity}) + ${$t('State')}: ${$t(oldState)} ➔ *${$t(newState)}*`; } } @@ -87,11 +85,11 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Changed sale reserved state', { ticketId: ticketId, - ticketUrl: `${origin}/#!/ticket/${ticketId}/sale`, + ticketUrl: `${url}ticket/${ticketId}/sale`, changes: changesMade }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); diff --git a/modules/ticket/back/methods/sale/updatePrice.js b/modules/ticket/back/methods/sale/updatePrice.js index 62e4ebd42e..3cae2a3333 100644 --- a/modules/ticket/back/methods/sale/updatePrice.js +++ b/modules/ticket/back/methods/sale/updatePrice.js @@ -1,5 +1,3 @@ -let UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethodCtx('updatePrice', { description: 'Changes the price of a sale', @@ -100,7 +98,7 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Changed sale price', { ticketId: sale.ticket().id, itemId: sale.itemFk, @@ -108,8 +106,8 @@ module.exports = Self => { quantity: sale.quantity, oldPrice: oldPrice, newPrice: newPrice, - ticketUrl: `${origin}/#!/ticket/${sale.ticket().id}/sale`, - itemUrl: `${origin}/#!/item/${sale.itemFk}/summary` + ticketUrl: `${url}ticket/${sale.ticket().id}/sale`, + itemUrl: `${url}item/${sale.itemFk}/summary` }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); } diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index 3cbd9255f6..27c1f529e2 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -80,15 +80,16 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { - const url = await models.Application.getUrl(); + const url = await Self.app.models.Application.getUrl(); + console.log(url); const message = $t('Changed sale quantity', { ticketId: sale.ticket().id, itemId: sale.itemFk, concept: sale.concept, oldQuantity: oldQuantity, newQuantity: newQuantity, - ticketUrl: `${url}/ticket/${sale.ticket().id}/sale`, - itemUrl: `${url}/item/${sale.itemFk}/summary` + ticketUrl: `${url}ticket/${sale.ticket().id}/sale`, + itemUrl: `${url}item/${sale.itemFk}/summary` }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); diff --git a/modules/ticket/back/methods/ticket-request/confirm.js b/modules/ticket/back/methods/ticket-request/confirm.js index 9cd7f4d682..a69fc7fd76 100644 --- a/modules/ticket/back/methods/ticket-request/confirm.js +++ b/modules/ticket/back/methods/ticket-request/confirm.js @@ -84,7 +84,7 @@ module.exports = Self => { const query = `CALL vn.sale_calculateComponent(?, NULL)`; await Self.rawSql(query, [sale.id], myOptions); - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const requesterId = request.requesterFk; const message = $t('Bought units from buy request', { @@ -92,8 +92,8 @@ module.exports = Self => { concept: sale.concept, itemId: sale.itemFk, ticketId: sale.ticketFk, - url: `${origin}/#!/ticket/${sale.ticketFk}/summary`, - urlItem: `${origin}/#!/item/${sale.itemFk}/summary` + url: `${url}ticket/${sale.ticketFk}/summary`, + urlItem: `${url}item/${sale.itemFk}/summary` }); await models.Chat.sendCheckingPresence(ctx, requesterId, message, myOptions); diff --git a/modules/ticket/back/methods/ticket-request/deny.js b/modules/ticket/back/methods/ticket-request/deny.js index 92f020083b..9ec11d755b 100644 --- a/modules/ticket/back/methods/ticket-request/deny.js +++ b/modules/ticket/back/methods/ticket-request/deny.js @@ -50,12 +50,12 @@ module.exports = Self => { const request = await Self.app.models.TicketRequest.findById(ctx.args.id, null, myOptions); await request.updateAttributes(params, myOptions); - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const requesterId = request.requesterFk; const message = $t('Deny buy request', { ticketId: request.ticketFk, - url: `${origin}/#!/ticket/${request.ticketFk}/request/index`, + url: `${url}ticket/${request.ticketFk}/request/index`, observation: params.response }); diff --git a/modules/ticket/back/methods/ticket/addSale.js b/modules/ticket/back/methods/ticket/addSale.js index cbf884273b..29e49d8e6e 100644 --- a/modules/ticket/back/methods/ticket/addSale.js +++ b/modules/ticket/back/methods/ticket/addSale.js @@ -94,11 +94,11 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Added sale to ticket', { ticketId: id, - ticketUrl: `${origin}/#!/ticket/${id}/sale`, + ticketUrl: `${url}ticket/${id}/sale`, addition: addition }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message); diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 8aad8959bb..fc8b3a40c8 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -237,7 +237,7 @@ module.exports = Self => { const salesPersonId = originalTicket.client().salesPersonFk; if (salesPersonId) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); let changesMade = ''; for (let change in newProperties) { @@ -249,7 +249,7 @@ module.exports = Self => { const message = $t('Changed this data from the ticket', { ticketId: args.id, - ticketUrl: `${origin}/#!/ticket/${args.id}/sale`, + ticketUrl: `${url}ticket/${args.id}/sale`, changes: changesMade }); await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); diff --git a/modules/ticket/back/methods/ticket/merge.js b/modules/ticket/back/methods/ticket/merge.js index 3c0da077f3..19c7f9fa0d 100644 --- a/modules/ticket/back/methods/ticket/merge.js +++ b/modules/ticket/back/methods/ticket/merge.js @@ -25,7 +25,7 @@ module.exports = Self => { Self.merge = async(ctx, tickets, options) => { const httpRequest = ctx.req; const $t = httpRequest.__; - const origin = httpRequest.headers.origin; + const url = await Self.app.models.Application.getUrl(); const models = Self.app.models; const myOptions = {}; let tx; @@ -40,8 +40,8 @@ module.exports = Self => { try { for (let ticket of tickets) { - const originFullPath = `${origin}/#!/ticket/${ticket.originId}/summary`; - const destinationFullPath = `${origin}/#!/ticket/${ticket.destinationId}/summary`; + const originFullPath = `${url}ticket/${ticket.originId}/summary`; + const destinationFullPath = `${url}ticket/${ticket.destinationId}/summary`; const message = $t('Ticket merged', { originDated: dateUtil.toString(new Date(ticket.originShipped)), destinationDated: dateUtil.toString(new Date(ticket.destinationShipped)), diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 722c3294e8..0aaef0418e 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -48,10 +48,10 @@ module.exports = Self => { // Send notification to salesPerson const salesPersonId = ticket.client().salesPersonFk; if (salesPersonId) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t(`I have restored the ticket id`, { id: id, - url: `${origin}/#!/ticket/${id}/summary` + url: `${url}ticket/${id}/summary` }); await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); } diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js index fcd9972fe2..a6fd295f17 100644 --- a/modules/ticket/back/methods/ticket/setDeleted.js +++ b/modules/ticket/back/methods/ticket/setDeleted.js @@ -119,10 +119,10 @@ module.exports = Self => { // Send notification to salesPerson const salesPersonUser = ticket.client().salesPersonUser(); if (salesPersonUser && sales.length) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t(`I have deleted the ticket id`, { id: id, - url: `${origin}/#!/ticket/${id}/summary` + url: `${url}ticket/${id}/summary` }); await models.Chat.send(ctx, `@${salesPersonUser.name}`, message); } @@ -146,7 +146,8 @@ module.exports = Self => { JOIN vn.sectorCollection sc ON sc.id = scsg.sectorCollectionFk JOIN vn.saleGroupDetail sgd ON sgd.saleGroupFk = sg.id JOIN vn.sale s ON s.id = sgd.saleFk - WHERE s.ticketFk = ?;`, [ticket.id], myOptions); + WHERE s.ticketFk = ?;`, [ticket.id], myOptions + ); if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/updateDiscount.js b/modules/ticket/back/methods/ticket/updateDiscount.js index e092ee4ed4..05ade4f01b 100644 --- a/modules/ticket/back/methods/ticket/updateDiscount.js +++ b/modules/ticket/back/methods/ticket/updateDiscount.js @@ -165,11 +165,10 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; - + const url = await Self.app.models.Application.getUrl(); const message = $t('Changed sale discount', { ticketId: id, - ticketUrl: `${origin}/#!/ticket/${id}/sale`, + ticketUrl: `${url}ticket/${id}/sale`, changes: changesMade }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); diff --git a/modules/worker/back/methods/worker/createAbsence.js b/modules/worker/back/methods/worker/createAbsence.js index cb2cf83305..10992f91ff 100644 --- a/modules/worker/back/methods/worker/createAbsence.js +++ b/modules/worker/back/methods/worker/createAbsence.js @@ -109,13 +109,13 @@ module.exports = Self => { const absenceType = await models.AbsenceType.findById(args.absenceTypeId, null, myOptions); const account = await models.VnUser.findById(userId, null, myOptions); const subordinated = await models.VnUser.findById(id, null, myOptions); - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const body = $t('Created absence', { author: account.nickname, employee: subordinated.nickname, absenceType: absenceType.name, dated: formatDate(args.dated), - workerUrl: `${origin}/#!/worker/${id}/calendar` + workerUrl: `${url}worker/${id}/calendar` }); await models.Mail.create({ subject: $t('Absence change notification on the labour calendar'), diff --git a/modules/worker/back/methods/worker/deleteAbsence.js b/modules/worker/back/methods/worker/deleteAbsence.js index c315f51785..2912e6db48 100644 --- a/modules/worker/back/methods/worker/deleteAbsence.js +++ b/modules/worker/back/methods/worker/deleteAbsence.js @@ -60,13 +60,13 @@ module.exports = Self => { const absenceType = await models.AbsenceType.findById(absence.dayOffTypeFk, null, myOptions); const account = await models.VnUser.findById(userId, null, myOptions); const subordinated = await models.VnUser.findById(labour.workerFk, null, myOptions); - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const body = $t('Deleted absence', { author: account.nickname, employee: subordinated.nickname, absenceType: absenceType.name, dated: formatDate(absence.dated), - workerUrl: `${origin}/#!/worker/${id}/calendar` + workerUrl: `${url}worker/${id}/calendar` }); await models.Mail.create({ subject: $t('Absence change notification on the labour calendar'), From afe4c676fc0a254f26795d15477fa1059b99891d Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 16 Oct 2023 18:38:33 +0200 Subject: [PATCH 086/449] =?UTF-8?q?fix(url):=20la=20ulr=20termina=20con=20?= =?UTF-8?q?/=20no=20es=20necesario=20a=C3=B1adir=20el=20texto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/claim/back/methods/claim/claimPickupEmail.js | 2 +- modules/claim/back/methods/claim/createFromSales.js | 4 ++-- modules/claim/back/methods/claim/updateClaim.js | 7 +++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/claim/back/methods/claim/claimPickupEmail.js b/modules/claim/back/methods/claim/claimPickupEmail.js index f4cd0fc206..5f33260997 100644 --- a/modules/claim/back/methods/claim/claimPickupEmail.js +++ b/modules/claim/back/methods/claim/claimPickupEmail.js @@ -69,7 +69,7 @@ module.exports = Self => { const message = $t('Claim pickup order sent', { claimId: args.id, clientName: claim.client().name, - claimUrl: `${url}/claim/${args.id}/summary`, + claimUrl: `${url}claim/${args.id}/summary`, }); console.log(message); const salesPersonId = claim.client().salesPersonFk; diff --git a/modules/claim/back/methods/claim/createFromSales.js b/modules/claim/back/methods/claim/createFromSales.js index 7ea26f9cc8..24ba74c6d5 100644 --- a/modules/claim/back/methods/claim/createFromSales.js +++ b/modules/claim/back/methods/claim/createFromSales.js @@ -99,8 +99,8 @@ module.exports = Self => { const message = $t('Created claim', { claimId: newClaim.id, ticketId: ticketId, - ticketUrl: `${url}/ticket/${ticketId}/sale`, - claimUrl: `${url}/claim/${newClaim.id}/summary`, + ticketUrl: `${url}ticket/${ticketId}/sale`, + claimUrl: `${url}claim/${newClaim.id}/summary`, changes: changesMade }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message); diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index b7ffa9ff5b..b5c576440a 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -121,22 +121,21 @@ module.exports = Self => { const message = $t(`Claim state has changed to ${state}`, { claimId: claim.id, clientName: claim.client().name, - claimUrl: `${url}/claim/${claim.id}/summary` + claimUrl: `${url}claim/${claim.id}/summary` }); await models.Chat.sendCheckingPresence(ctx, workerId, message); } async function notifyPickUp(ctx, workerId, claim) { const models = Self.app.models; - const url = await models.Application.getUrl(); + const url = await models.Application.getUrl('lilium'); const $t = ctx.req.__; // $translate const message = $t('Claim will be picked', { claimId: claim.id, clientName: claim.client().name, - claimUrl: `${url}/claim/${claim.id}/summary` + claimUrl: `${url}claim/${claim.id}/summary` }); - console.log(message); await models.Chat.sendCheckingPresence(ctx, workerId, message); } }; From 4f911e644c4f03086cfcb03469fc10096b8edaa8 Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 16 Oct 2023 18:43:03 +0200 Subject: [PATCH 087/449] fix: remove console.log refs #5979 --- modules/claim/back/methods/claim/claimPickupEmail.js | 1 - modules/ticket/back/methods/sale/updateQuantity.js | 1 - 2 files changed, 2 deletions(-) diff --git a/modules/claim/back/methods/claim/claimPickupEmail.js b/modules/claim/back/methods/claim/claimPickupEmail.js index 5f33260997..aea571a61e 100644 --- a/modules/claim/back/methods/claim/claimPickupEmail.js +++ b/modules/claim/back/methods/claim/claimPickupEmail.js @@ -71,7 +71,6 @@ module.exports = Self => { clientName: claim.client().name, claimUrl: `${url}claim/${args.id}/summary`, }); - console.log(message); const salesPersonId = claim.client().salesPersonFk; if (salesPersonId) await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index 27c1f529e2..acccc6c2f9 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -81,7 +81,6 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { const url = await Self.app.models.Application.getUrl(); - console.log(url); const message = $t('Changed sale quantity', { ticketId: sale.ticket().id, itemId: sale.itemFk, From 48003b5d03541ef7e19a8e703dc5609bbc3647b2 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 17 Oct 2023 08:28:15 +0200 Subject: [PATCH 088/449] ref #6138 --- modules/worker/front/descriptor/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/worker/front/descriptor/index.js b/modules/worker/front/descriptor/index.js index fe337974c7..13ffa6f2f0 100644 --- a/modules/worker/front/descriptor/index.js +++ b/modules/worker/front/descriptor/index.js @@ -69,7 +69,6 @@ class Controller extends Descriptor { } ] }; - // Añadir filter para sacar user return this.getData(`Workers/${this.id}`, {filter}) .then(res => this.entity = res.data); } From fa08ebf416846166cdd665607ce7c7912a54232d Mon Sep 17 00:00:00 2001 From: sergiodt Date: Tue, 17 Oct 2023 08:57:45 +0200 Subject: [PATCH 089/449] refs #5867 fix: tickets sql --- print/templates/reports/driver-route/sql/tickets.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/print/templates/reports/driver-route/sql/tickets.sql b/print/templates/reports/driver-route/sql/tickets.sql index 09e73819be..9d548c2b31 100644 --- a/print/templates/reports/driver-route/sql/tickets.sql +++ b/print/templates/reports/driver-route/sql/tickets.sql @@ -20,7 +20,7 @@ SELECT u.nickName salesPersonName, ipkg.itemPackingTypes FROM route r - LEFT JOIN ticket t ON t.routeFk = r.id + JOIN ticket t ON t.routeFk = r.id LEFT JOIN address a ON a.id = t.addressFk LEFT JOIN client c ON c.id = t.clientFk LEFT JOIN worker w ON w.id = client_getSalesPerson(t.clientFk, CURDATE()) From d4770c525ef1d0e27095cbe46e64fca3c58b7c7d Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 17 Oct 2023 11:00:41 +0200 Subject: [PATCH 090/449] refs #6199 test(sale): fix test --- .../collection/spec/setSaleQuantity.spec.js | 1 + .../methods/sale/specs/updateQuantity.spec.js | 52 +++++++++++++++++-- modules/ticket/back/models/sale.js | 2 +- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/back/methods/collection/spec/setSaleQuantity.spec.js b/back/methods/collection/spec/setSaleQuantity.spec.js index fdc1bce1a4..8cd73205f1 100644 --- a/back/methods/collection/spec/setSaleQuantity.spec.js +++ b/back/methods/collection/spec/setSaleQuantity.spec.js @@ -18,6 +18,7 @@ describe('setSaleQuantity()', () => { it('should change quantity sale', async() => { const tx = await models.Ticket.beginTransaction({}); + spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: 100})))); try { const options = {transaction: tx}; diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index 6bf0a0d7eb..0fde997fa7 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -1,3 +1,5 @@ +/* eslint max-len: ["error", { "code": 150 }]*/ + const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); @@ -31,6 +33,7 @@ describe('sale updateQuantity()', () => { } }; spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: 100})))); const tx = await models.Sale.beginTransaction({}); @@ -38,7 +41,7 @@ describe('sale updateQuantity()', () => { try { const options = {transaction: tx}; - await models.Sale.updateQuantity(ctx, 17, 99, options); + await models.Sale.updateQuantity(ctx, 17, 31, options); await tx.rollback(); } catch (e) { @@ -50,9 +53,6 @@ describe('sale updateQuantity()', () => { }); it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); - - const tx = await models.Sale.beginTransaction({}); const saleId = 17; const buyerId = 35; const ctx = { @@ -62,6 +62,9 @@ describe('sale updateQuantity()', () => { __: () => {} } }; + const tx = await models.Sale.beginTransaction({}); + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(buyerId)); + spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: 100})))); try { const options = {transaction: tx}; @@ -169,7 +172,14 @@ describe('sale updateQuantity()', () => { }); it('should throw an error if the quantity is less than the minimum quantity of the item', async() => { - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); const tx = await models.Sale.beginTransaction({}); const itemId = 2; @@ -194,4 +204,36 @@ describe('sale updateQuantity()', () => { expect(error).toEqual(new Error('The amount cannot be less than the minimum')); }); + + it('should change quantity if has minimum quantity and new quantity is equal than item available', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = minQuantity - 1; + + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: newQuantity})))); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 378ff3490c..fe63072704 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -75,7 +75,7 @@ module.exports = Self => { ctx.options ); - const oldQuantity = instance?.quantity; + const oldQuantity = instance?.quantity ?? null; const quantityAdded = newQuantity - oldQuantity; if (itemInfo.available < quantityAdded) throw new UserError(`This item is not available`); From 9870a0e60adfd6bb82bfeece882a706087a5b810 Mon Sep 17 00:00:00 2001 From: pablone Date: Tue, 17 Oct 2023 13:56:49 +0200 Subject: [PATCH 091/449] feat(origin): create method url_/geturl redf #5979 --- back/methods/chat/sendCheckingPresence.js | 24 +++++++++++-------- back/models/chat.js | 9 +++++-- loopback/common/models/application.json | 5 ++++ .../methods/claim/specs/updateClaim.spec.js | 9 +++---- .../claim/back/methods/claim/updateClaim.js | 5 +++- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/back/methods/chat/sendCheckingPresence.js b/back/methods/chat/sendCheckingPresence.js index 274ec3a5b3..0bae87a359 100644 --- a/back/methods/chat/sendCheckingPresence.js +++ b/back/methods/chat/sendCheckingPresence.js @@ -25,22 +25,24 @@ module.exports = Self => { }); Self.sendCheckingPresence = async(ctx, recipientId, message) => { + console.log('recipientId: ', recipientId); if (!recipientId) return false; - const models = Self.app.models; - const userId = ctx.req.accessToken.userId; - const sender = await models.VnUser.findById(userId, {fields: ['id']}); - const recipient = await models.VnUser.findById(recipientId, null); + console.log('sender: ', ctx.req.accessToken.userId); + const sender = ctx.req.accessToken.userId; + console.log('sender: ', sender); + const recipient = recipientId; + console.log('recipient: ', recipient); + + console.log('recipientId == sender: ', recipientId == sender); // Prevent sending messages to yourself - if (recipientId == userId) return false; - + if (recipientId == sender) return false; if (!recipient) - throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`); - + throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${sender}`); if (process.env.NODE_ENV == 'test') - message = `[Test:Environment to user ${userId}] ` + message; - + message = `[Test:Environment to user ${sender}] ` + message; + console.log('chat create'); const chat = await models.Chat.create({ senderFk: sender.id, recipient: `@${recipient.name}`, @@ -51,6 +53,8 @@ module.exports = Self => { attempts: 0 }); + console.log('chat: '); + try { await Self.sendCheckingUserStatus(chat); await Self.updateChat(chat, 'sent'); diff --git a/back/models/chat.js b/back/models/chat.js index a18edbd3fb..240ec2c261 100644 --- a/back/models/chat.js +++ b/back/models/chat.js @@ -6,6 +6,10 @@ module.exports = Self => { require('../methods/chat/sendQueued')(Self); Self.observe('before save', async function(ctx) { + console.log('chat start 1'); + + console.log('ctx.isNewInstance: ', ctx.isNewInstance); + console.log('message: ', ctx.instance); if (!ctx.isNewInstance) return; let {message} = ctx.instance; @@ -13,14 +17,15 @@ module.exports = Self => { const parts = message.match(/(?<=\[)[a-zA-Z0-9_\-+!@#$%^&*()={};':"\\|,.<>/?\s]*(?=])/g); if (!parts) return; - + console.log('chat start 2'); const replacedParts = parts.map(part => { return part.replace(/[!$%^&*()={};':"\\,.<>/?]/g, ''); }); - + console.log('chat start 3'); for (const [index, part] of parts.entries()) message = message.replace(part, replacedParts[index]); ctx.instance.message = message; + console.log('chat end'); }); }; diff --git a/loopback/common/models/application.json b/loopback/common/models/application.json index 6343c3421f..cf0653fbb1 100644 --- a/loopback/common/models/application.json +++ b/loopback/common/models/application.json @@ -19,6 +19,11 @@ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" + },{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" } ] } diff --git a/modules/claim/back/methods/claim/specs/updateClaim.spec.js b/modules/claim/back/methods/claim/specs/updateClaim.spec.js index d367fb89f6..e7be8e9c6c 100644 --- a/modules/claim/back/methods/claim/specs/updateClaim.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaim.spec.js @@ -2,7 +2,9 @@ const app = require('vn-loopback/server/server'); const LoopBackContext = require('loopback-context'); describe('Update Claim', () => { + let url; beforeAll(async() => { + url = await app.models.Application.getUrl(); const activeCtx = { accessToken: {userId: 9}, http: { @@ -29,7 +31,6 @@ describe('Update Claim', () => { it(`should throw an error as the user doesn't have rights`, async() => { const tx = await app.models.Claim.beginTransaction({}); - let error; try { @@ -61,7 +62,7 @@ describe('Update Claim', () => { expect(error.message).toEqual(`You don't have enough privileges to change that field`); }); - it(`should success to update the claimState to 'canceled' and send a rocket message`, async() => { + fit(`should success to update the claimState to 'canceled' and send a rocket message`, async() => { const tx = await app.models.Claim.beginTransaction({}); try { @@ -77,7 +78,7 @@ describe('Update Claim', () => { const ctx = { req: { accessToken: {userId: claimManagerId}, - headers: {origin: 'http://localhost'} + headers: {origin: url} }, args: { observation: 'valid observation', @@ -118,7 +119,7 @@ describe('Update Claim', () => { const ctx = { req: { accessToken: {userId: claimManagerId}, - headers: {origin: 'http://localhost'} + headers: {origin: url} }, args: { observation: 'valid observation', diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index b5c576440a..534f0c7abf 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -92,7 +92,6 @@ module.exports = Self => { // When hasToPickUp has been changed if (salesPerson && changedHasToPickUp && updatedClaim.hasToPickUp) notifyPickUp(ctx, salesPerson.id, claim); - // When claimState has been changed if (args.claimStateFk) { const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions); @@ -123,6 +122,7 @@ module.exports = Self => { clientName: claim.client().name, claimUrl: `${url}claim/${claim.id}/summary` }); + console.log(`${url}claim/${claim.id}/summary`); await models.Chat.sendCheckingPresence(ctx, workerId, message); } @@ -136,6 +136,9 @@ module.exports = Self => { clientName: claim.client().name, claimUrl: `${url}claim/${claim.id}/summary` }); + console.log('url', `${url}claim/${claim.id}/summary`); + console.log('claim client', claim.client().name); + console.log('claim id', claim.id); await models.Chat.sendCheckingPresence(ctx, workerId, message); } }; From 69a54be1a9fe4e6e858f1837d249b8dc1d92cb4b Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 17 Oct 2023 14:02:08 +0200 Subject: [PATCH 092/449] ref #5947 refactorWorkerCreate --- modules/worker/back/methods/worker/new.js | 23 ++++++++++------------- modules/worker/back/models/worker.json | 6 ++++++ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 199a3be620..5316daf016 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -223,19 +223,16 @@ module.exports = Self => { const user = await models.VnUser.findById(client.id, null, myOptions); await user.updateAttribute('email', args.email, myOptions); - await models.Worker.rawSql( - 'CALL vn.workerCreate(?, ?, ?, ?, ?, ?, ?)', - [ - args.firstName, - args.lastNames, - args.code, - args.bossFk, - client.id, - args.fi, - args.birth, - ], - myOptions - ); + await models.Worker.create({ + id: client.id, + code: args.code, + firstName: args.firstName, + lastName: args.lastNames, + bossFk: args.bossFk, + fi: args.fi, + birth: args.birth, + + }, myOptions); if (tx) await tx.commit(); } catch (error) { diff --git a/modules/worker/back/models/worker.json b/modules/worker/back/models/worker.json index ea4aecf674..1a777fffeb 100644 --- a/modules/worker/back/models/worker.json +++ b/modules/worker/back/models/worker.json @@ -48,6 +48,12 @@ "locker": { "type" : "number" }, + "fi": { + "type" : "string" + }, + "birth": { + "type" : "date" + }, "isF11Allowed": { "type" : "boolean" } From fdfa481d212eccb7eb28891e3fcdcabbc0a86193 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 17 Oct 2023 14:52:47 +0200 Subject: [PATCH 093/449] ref #5947 drop procedure --- db/changes/234201/00-dropWorkerCreate.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 db/changes/234201/00-dropWorkerCreate.sql diff --git a/db/changes/234201/00-dropWorkerCreate.sql b/db/changes/234201/00-dropWorkerCreate.sql new file mode 100644 index 0000000000..be2761c3d1 --- /dev/null +++ b/db/changes/234201/00-dropWorkerCreate.sql @@ -0,0 +1 @@ +DROP PROCEDURE IF EXISTS vn.workerCreate; \ No newline at end of file From 8d44bb8867f159f3cc3d648d0025e112a6f79fe4 Mon Sep 17 00:00:00 2001 From: pablone Date: Tue, 17 Oct 2023 15:05:48 +0200 Subject: [PATCH 094/449] =?UTF-8?q?refactor(toggleIsIcluded):=20actualizo?= =?UTF-8?q?=20la=20versi=C3=B3n=20y=20modifico=20el=20proc=20refs=20#5749?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{232401 => 234201}/00-zoneIncluded.sql | 7 +++--- .../back/methods/zone/toggleIsIncluded.js | 24 +++++++++---------- 2 files changed, 14 insertions(+), 17 deletions(-) rename db/changes/{232401 => 234201}/00-zoneIncluded.sql (83%) diff --git a/db/changes/232401/00-zoneIncluded.sql b/db/changes/234201/00-zoneIncluded.sql similarity index 83% rename from db/changes/232401/00-zoneIncluded.sql rename to db/changes/234201/00-zoneIncluded.sql index 592350629c..12d4058cfc 100644 --- a/db/changes/232401/00-zoneIncluded.sql +++ b/db/changes/234201/00-zoneIncluded.sql @@ -13,15 +13,14 @@ DROP TRIGGER IF EXISTS `vn`.`zoneIncluded_afterDelete`; USE `vn`; DELIMITER $$ -$$ -CREATE DEFINER=`root`@`localhost` TRIGGER `vn`.`zoneIncluded_afterDelete` +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`zoneIncluded_afterDelete` AFTER DELETE ON `zoneIncluded` FOR EACH ROW BEGIN INSERT INTO zoneLog SET `action` = 'delete', - `changedModel` = 'ZoneIncluded', - `changedModelId` = OLD.id, + `changedModel` = 'zoneIncluded', + `changedModelId` = OLD.zoneFk, `userFk` = account.myUser_getId(); END$$ DELIMITER ; diff --git a/modules/zone/back/methods/zone/toggleIsIncluded.js b/modules/zone/back/methods/zone/toggleIsIncluded.js index 06532e5c05..98c64c4a00 100644 --- a/modules/zone/back/methods/zone/toggleIsIncluded.js +++ b/modules/zone/back/methods/zone/toggleIsIncluded.js @@ -30,23 +30,21 @@ module.exports = Self => { Self.toggleIsIncluded = async(id, geoId, isIncluded, options) => { const models = Self.app.models; const myOptions = {}; - if (typeof options == 'object') Object.assign(myOptions, options); if (isIncluded === undefined) return models.ZoneIncluded.destroyAll({zoneFk: id, geoFk: geoId}, myOptions); - else { - const zoneIncluded = await models.ZoneIncluded.findOne({where: {zoneFk: id, geoFk: geoId}}, myOptions); - if (zoneIncluded) - return zoneIncluded.updateAttribute('isIncluded', isIncluded, myOptions); - else { - return models.ZoneIncluded.create({ - zoneFk: id, - geoFk: geoId, - isIncluded: isIncluded - }, myOptions); - } - } + + const zoneIncluded = await models.ZoneIncluded.findOne({where: {zoneFk: id, geoFk: geoId}}, myOptions); + + if (zoneIncluded) + return zoneIncluded.updateAttribute('isIncluded', isIncluded, myOptions); + + return models.ZoneIncluded.create({ + zoneFk: id, + geoFk: geoId, + isIncluded: isIncluded + }, myOptions); }; }; From b3c7511e59277a081e8cc2480ed36bf6aeff1fc8 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 18 Oct 2023 08:52:06 +0200 Subject: [PATCH 095/449] refs #6067 feat(url): getByUser --- back/methods/url/getByUser.js | 40 +++++++++++++++++++++++ back/methods/url/specs/getByUser.spec.js | 19 +++++++++++ back/models/url.js | 3 ++ back/models/url.json | 9 +---- back/models/vn-user.js | 4 +-- db/changes/234201/00-aclUrlHedera.sql | 6 ++-- modules/worker/back/methods/worker/new.js | 1 - 7 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 back/methods/url/getByUser.js create mode 100644 back/methods/url/specs/getByUser.spec.js create mode 100644 back/models/url.js diff --git a/back/methods/url/getByUser.js b/back/methods/url/getByUser.js new file mode 100644 index 0000000000..dd4805182d --- /dev/null +++ b/back/methods/url/getByUser.js @@ -0,0 +1,40 @@ +module.exports = function(Self) { + Self.remoteMethod('getByUser', { + description: 'returns the starred modules for the current user', + accessType: 'READ', + accepts: [{ + arg: 'userId', + type: 'number', + description: 'The user id', + required: true, + http: {source: 'path'} + }], + returns: { + type: 'object', + root: true + }, + http: { + path: `/:userId/get-by-user`, + verb: 'GET' + } + }); + + Self.getByUser = async userId => { + const models = Self.app.models; + const appNames = ['hedera']; + const filter = { + fields: ['appName', 'url'], + where: { + appName: {inq: appNames}, + environment: process.env.NODE_ENV ?? 'development', + } + }; + + const isWorker = await models.Account.findById(userId, {fields: ['id']}); + if (!isWorker) + return models.Url.find(filter); + + appNames.push('salix'); + return models.Url.find(filter); + }; +}; diff --git a/back/methods/url/specs/getByUser.spec.js b/back/methods/url/specs/getByUser.spec.js new file mode 100644 index 0000000000..f6af6ec001 --- /dev/null +++ b/back/methods/url/specs/getByUser.spec.js @@ -0,0 +1,19 @@ +const {models} = require('vn-loopback/server/server'); + +describe('getByUser()', () => { + const worker = 1; + const notWorker = 2; + it(`should return only hedera url if not is worker`, async() => { + const urls = await models.Url.getByUser(notWorker); + + expect(urls.length).toEqual(1); + expect(urls[0].appName).toEqual('hedera'); + }); + + it(`should return more than hedera url`, async() => { + const urls = await models.Url.getByUser(worker); + + expect(urls.length).toBeGreaterThan(1); + expect(urls.find(url => url.appName == 'salix').appName).toEqual('salix'); + }); +}); diff --git a/back/models/url.js b/back/models/url.js new file mode 100644 index 0000000000..216d149ba1 --- /dev/null +++ b/back/models/url.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/url/getByUser')(Self); +}; diff --git a/back/models/url.json b/back/models/url.json index 13f50b0993..8610ff28b6 100644 --- a/back/models/url.json +++ b/back/models/url.json @@ -21,12 +21,5 @@ "type": "string", "required": true } - }, - "acls": [{ - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - }] - + } } diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 8e9b59aab4..66af807b84 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -222,7 +222,6 @@ module.exports = function(Self) { ]} }); - const isWorker = instance.isWorker || await Self.app.models.Account.findById(instance.id, null, ctx.options); class Mailer { async send(verifyOptions, cb) { const params = { @@ -236,11 +235,12 @@ module.exports = function(Self) { cb(null, verifyOptions.to); } } + console.log('instance.id', instance.id); const options = { type: 'email', to: newEmail, from: {}, - redirect: `${liliumUrl.url}verifyEmail?isWorker=${!!isWorker}`, + redirect: `${liliumUrl.url}verifyEmail?userId=${instance.id}`, template: false, mailer: new Mailer, host: url[1].split('/')[2], diff --git a/db/changes/234201/00-aclUrlHedera.sql b/db/changes/234201/00-aclUrlHedera.sql index 0d38a2ae81..79d9fb4c81 100644 --- a/db/changes/234201/00-aclUrlHedera.sql +++ b/db/changes/234201/00-aclUrlHedera.sql @@ -3,7 +3,5 @@ INSERT INTO `salix`.`url` (`appName`, `environment`, `url`) ('hedera', 'test', 'https://test-shop.verdnatura.es/'), ('hedera', 'production', 'https://shop.verdnatura.es/'); -DELETE FROM `salix`.`ACL` - WHERE model = 'Url' - AND 'accessType' = 'READ' - AND principalId = 'employee'; +INSERT INTO `salix`.`ACL` ( model, property, accessType, permission, principalType, principalId) + VALUES('Url', 'getByUser', 'READ', 'ALLOW', 'ROLE', '$everyone'); diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 7c8978ec6f..199a3be620 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -155,7 +155,6 @@ module.exports = Self => { password: randomPassword.password, email: args.email, roleFk: workerConfig.roleFk, - isWorker: true // to verifyEmail }, myOptions ); From b1c931a510674e856731a2f0409f856c8a1a7188 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 18 Oct 2023 08:52:17 +0200 Subject: [PATCH 096/449] remove console.log --- back/models/vn-user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 66af807b84..d7f54521f1 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -235,7 +235,7 @@ module.exports = function(Self) { cb(null, verifyOptions.to); } } - console.log('instance.id', instance.id); + const options = { type: 'email', to: newEmail, From d1cb2a1d9a0ca13861b7c704391a789ebe39db35 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 18 Oct 2023 10:30:36 +0200 Subject: [PATCH 097/449] refs #5918 test: add updateWorkerTimeControlMail --- .../specs/updateWorkerTimeControlMail.spec.js | 103 ++++++++++++++++++ modules/worker/front/time-control/index.html | 6 +- 2 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 modules/worker/back/methods/worker-time-control/specs/updateWorkerTimeControlMail.spec.js diff --git a/modules/worker/back/methods/worker-time-control/specs/updateWorkerTimeControlMail.spec.js b/modules/worker/back/methods/worker-time-control/specs/updateWorkerTimeControlMail.spec.js new file mode 100644 index 0000000000..e510210247 --- /dev/null +++ b/modules/worker/back/methods/worker-time-control/specs/updateWorkerTimeControlMail.spec.js @@ -0,0 +1,103 @@ +const models = require('vn-loopback/server/server').models; + +describe('workerTimeControl getMailStates()', () => { + it('should update WorkerTimeControlMail if exist record', async() => { + const tx = await models.WorkerTimeControlMail.beginTransaction({}); + const args = { + workerId: 9, + week: 50, + year: 2000, + state: 'CONFIRMED' + }; + const ctx = {args}; + + try { + const options = {transaction: tx}; + const beforeMail = await models.WorkerTimeControlMail.findOne({ + where: { + workerFk: args.workerId, + year: args.year, + week: args.week, + } + }, options); + await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, options); + const afterMail = await models.WorkerTimeControlMail.findOne({ + where: { + workerFk: args.workerId, + year: args.year, + week: args.week, + } + }, options); + + expect(beforeMail.state).toEqual('SENDED'); + expect(afterMail.state).toEqual(args.state); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should insert WorkerTimeControlMail if exist record', async() => { + const tx = await models.WorkerTimeControlMail.beginTransaction({}); + const args = { + workerId: 1, + week: 51, + year: 2000, + state: 'SENDED' + }; + const ctx = {args}; + + try { + const options = {transaction: tx}; + const beforeMail = await models.WorkerTimeControlMail.find({ + where: { + workerFk: args.workerId, + year: args.year, + week: args.week, + } + }, options); + await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, options); + const afterMail = await models.WorkerTimeControlMail.find({ + where: { + workerFk: args.workerId, + year: args.year, + week: args.week, + } + }, options); + + expect(beforeMail).toEqual([]); + expect(afterMail.length).toEqual(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw error if not exist any record in this week', async() => { + const tx = await models.WorkerTimeControlMail.beginTransaction({}); + const ctx = {args: { + workerId: 1, + week: 1, + year: 0, + state: 'SENDED' + }}; + + let error; + try { + const options = {transaction: tx}; + await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toEqual(`There aren't records for this week`); + }); +}); + diff --git a/modules/worker/front/time-control/index.html b/modules/worker/front/time-control/index.html index ce8a663560..f147b759be 100644 --- a/modules/worker/front/time-control/index.html +++ b/modules/worker/front/time-control/index.html @@ -98,11 +98,11 @@ ng-click="reason.show()"> + vn-tooltip="{{$ctrl.state ? 'Resend' : 'Send'}} email of this week to the user" + ng-if="$ctrl.isHr && $ctrl.state != 'CONFIRMED' && $ctrl.canResend">
From 4300b24c1437a7fe78c20e2919da755720eae276 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 18 Oct 2023 10:45:15 +0200 Subject: [PATCH 098/449] refs #5918 refactor(worker_timeControl): simplify ng-show --- .../specs/updateWorkerTimeControlMail.spec.js | 2 +- modules/worker/front/time-control/index.html | 36 ++++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/modules/worker/back/methods/worker-time-control/specs/updateWorkerTimeControlMail.spec.js b/modules/worker/back/methods/worker-time-control/specs/updateWorkerTimeControlMail.spec.js index e510210247..3b5b2b73f5 100644 --- a/modules/worker/back/methods/worker-time-control/specs/updateWorkerTimeControlMail.spec.js +++ b/modules/worker/back/methods/worker-time-control/specs/updateWorkerTimeControlMail.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; -describe('workerTimeControl getMailStates()', () => { +describe('updateWorkerTimeControlMail()', () => { it('should update WorkerTimeControlMail if exist record', async() => { const tx = await models.WorkerTimeControlMail.beginTransaction({}); const args = { diff --git a/modules/worker/front/time-control/index.html b/modules/worker/front/time-control/index.html index f147b759be..c34a1e3ca6 100644 --- a/modules/worker/front/time-control/index.html +++ b/modules/worker/front/time-control/index.html @@ -80,23 +80,25 @@ - - - - - - +
+ + + + + + +
Date: Wed, 18 Oct 2023 12:04:37 +0200 Subject: [PATCH 099/449] refs 6199 add quantityLessThanMin translation --- loopback/locale/es.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index d34c97d210..dd3c92378a 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -320,5 +320,6 @@ "Ticket without Route": "Ticket sin ruta", "Booking completed": "Reserva completada", "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", - "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mímina" + "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mímina", + "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina" } From 251d71a437e37f32380e56f12573b191012ed728 Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 18 Oct 2023 12:05:33 +0200 Subject: [PATCH 100/449] ref #5417 refactor transactions --- modules/client/back/methods/client/transactions.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/modules/client/back/methods/client/transactions.js b/modules/client/back/methods/client/transactions.js index d08df4ab60..a643d69f4d 100644 --- a/modules/client/back/methods/client/transactions.js +++ b/modules/client/back/methods/client/transactions.js @@ -12,22 +12,18 @@ module.exports = Self => { arg: 'filter', type: 'object', description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', - http: {source: 'query'} }, { arg: 'orderFk', type: 'number', - http: {source: 'query'} }, { arg: 'clientFk', type: 'number', - http: {source: 'query'} }, { arg: 'amount', type: 'number', - http: {source: 'query'} }, { arg: 'from', @@ -48,19 +44,15 @@ module.exports = Self => { } }); - Self.transactions = async(ctx, filter, options) => { - const args = ctx.args; + Self.transactions = async(ctx, filter, orderFk, clientFk, amount, from, to, options) => { const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - if (ctx.args && args.to) { - const dateTo = args.to; - dateTo.setHours(23, 59, 59, 999); - } + if (to) to.setHours(23, 59, 59, 999); - const where = buildFilter(args, (param, value) => { + const where = buildFilter({orderFk, clientFk, amount, from, to}, (param, value) => { switch (param) { case 'orderFk': return {'t.id': value}; From 5f49a4fe1d3e8eb9b5edca9c33515c7aa189aa6b Mon Sep 17 00:00:00 2001 From: pablone Date: Wed, 18 Oct 2023 12:24:35 +0200 Subject: [PATCH 101/449] fix: created -> shipped refs #6266 --- modules/ticket/front/descriptor/locale/es.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/front/descriptor/locale/es.yml b/modules/ticket/front/descriptor/locale/es.yml index e1006bed43..b809c1b839 100644 --- a/modules/ticket/front/descriptor/locale/es.yml +++ b/modules/ticket/front/descriptor/locale/es.yml @@ -4,7 +4,7 @@ Show pallet report: Ver hoja de pallet Change shipped hour: Cambiar hora de envío Shipped hour: Hora de envío Make a payment: "Verdnatura le comunica:\rSu pedido está pendiente de pago.\rPor favor, entre en la página web y efectúe el pago con tarjeta.\rMuchas gracias." -Minimum is needed: "Verdnatura le recuerda:\rEs necesario un importe mínimo de 50€ (Sin IVA) en su pedido {{ticketId}} del día {{created | date: 'dd/MM/yyyy'}} para recibirlo sin portes adicionales." +Minimum is needed: "Verdnatura le recuerda:\rEs necesario un importe mínimo de 50€ (Sin IVA) en su pedido {{ticketId}} del día {{shipped | date: 'dd/MM/yyyy'}} para recibirlo sin portes adicionales." Ticket invoiced: Ticket facturado Make invoice: Crear factura Regenerate invoice PDF: Regenerar PDF factura From 2bb4300e1b26d3a344e58b3ab39d1e8dabb8bc54 Mon Sep 17 00:00:00 2001 From: pablone Date: Wed, 18 Oct 2023 12:35:45 +0200 Subject: [PATCH 102/449] remove: se quita el console log refs #6278 --- db/changes/234201/00-alterTableTicketRequest.sql | 1 - modules/ticket/back/methods/ticket-request/filter.js | 2 -- 2 files changed, 3 deletions(-) delete mode 100644 db/changes/234201/00-alterTableTicketRequest.sql diff --git a/db/changes/234201/00-alterTableTicketRequest.sql b/db/changes/234201/00-alterTableTicketRequest.sql deleted file mode 100644 index 2a08137b98..0000000000 --- a/db/changes/234201/00-alterTableTicketRequest.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `vn`.`ticketRequest` MODIFY COLUMN `itemFk` double DEFAULT NULL NOT NULL; diff --git a/modules/ticket/back/methods/ticket-request/filter.js b/modules/ticket/back/methods/ticket-request/filter.js index 47e5719889..10aaf02e58 100644 --- a/modules/ticket/back/methods/ticket-request/filter.js +++ b/modules/ticket/back/methods/ticket-request/filter.js @@ -161,8 +161,6 @@ module.exports = Self => { LEFT JOIN account.user ua2 ON ua2.id = tr.requesterFk`); stmt.merge(conn.makeSuffix(filter)); - console.log(stmt); - return conn.executeStmt(stmt, myOptions); }; }; From 330fb08aac7ca8578bcdcd86e41930f911701f01 Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 18 Oct 2023 13:23:00 +0200 Subject: [PATCH 103/449] ref #5417 fix back test --- .../methods/client/specs/transactions.spec.js | 64 +++++++++++++++---- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/modules/client/back/methods/client/specs/transactions.spec.js b/modules/client/back/methods/client/specs/transactions.spec.js index 679eb196cc..54e0889293 100644 --- a/modules/client/back/methods/client/specs/transactions.spec.js +++ b/modules/client/back/methods/client/specs/transactions.spec.js @@ -1,15 +1,24 @@ const models = require('vn-loopback/server/server').models; describe('Client transactions', () => { + const ctx = {}; + it('should call transactions() method to receive a list of Web Payments from BRUCE WAYNE', async() => { const tx = await models.Client.beginTransaction({}); - try { const options = {transaction: tx}; - const ctx = {}; const filter = {where: {clientFk: 1101}}; - const result = await models.Client.transactions(ctx, filter, options); + const result = await models.Client.transactions( + ctx, + filter, + undefined, + undefined, + undefined, + undefined, + undefined, + options + ); expect(result[1].id).toBeTruthy(); @@ -26,9 +35,17 @@ describe('Client transactions', () => { try { const options = {transaction: tx}; - const ctx = {args: {orderFk: 6}}; const filter = {}; - const result = await models.Client.transactions(ctx, filter, options); + const result = await models.Client.transactions( + ctx, + filter, + 6, + undefined, + undefined, + undefined, + undefined, + options + ); const firstRow = result[0]; @@ -47,10 +64,17 @@ describe('Client transactions', () => { try { const options = {transaction: tx}; - - const ctx = {args: {amount: 40}}; const filter = {}; - const result = await models.Client.transactions(ctx, filter, options); + const result = await models.Client.transactions( + ctx, + filter, + undefined, + undefined, + 40, + undefined, + undefined, + options + ); const randomIndex = Math.floor(Math.random() * result.length); const transaction = result[randomIndex]; @@ -69,14 +93,30 @@ describe('Client transactions', () => { try { const options = {transaction: tx}; - const ctx = {args: {from: '2000/12/31'}}; const filter = {}; - const withResults = await models.Client.transactions(ctx, filter, options); + const withResults = await models.Client.transactions( + ctx, + filter, + undefined, + undefined, + undefined, + '2000/12/31', + undefined, + options + ); expect(withResults.length).toEqual(6); - ctx.args.from = '2099/12/31'; - const noResults = await models.Client.transactions(ctx, filter, options); + const noResults = await models.Client.transactions( + ctx, + filter, + undefined, + undefined, + undefined, + '2099/12/31', + undefined, + options + ); expect(noResults.length).toEqual(0); From 44ce0a87304a2d1e83c31890482ff343d9e2a8eb Mon Sep 17 00:00:00 2001 From: jgallego Date: Wed, 18 Oct 2023 13:46:41 +0200 Subject: [PATCH 104/449] refs #6312 no inserta el originalquantity --- modules/ticket/back/methods/ticket/transferSales.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/ticket/back/methods/ticket/transferSales.js b/modules/ticket/back/methods/ticket/transferSales.js index 1124f7ec70..a2e92d524e 100644 --- a/modules/ticket/back/methods/ticket/transferSales.js +++ b/modules/ticket/back/methods/ticket/transferSales.js @@ -138,14 +138,15 @@ module.exports = Self => { // Update original sale const rest = originalSale.quantity - sale.quantity; query = `UPDATE sale - SET quantity = ? + SET quantity = ?, + originalQuantity = ? WHERE id = ?`; - await Self.rawSql(query, [rest, sale.id], options); + await Self.rawSql(query, [rest, rest, sale.id], options); // Clone sale with new quantity - query = `INSERT INTO sale (itemFk, ticketFk, concept, quantity, originalQuantity, price, discount, priceFixed, + query = `INSERT INTO sale (itemFk, ticketFk, concept, quantity, price, discount, priceFixed, reserved, isPicked, isPriceFixed, isAdded) - SELECT itemFk, ?, concept, ?, originalQuantity, price, discount, priceFixed, + SELECT itemFk, ?, concept, ?, price, discount, priceFixed, reserved, isPicked, isPriceFixed, isAdded FROM sale WHERE id = ?`; From da20697052b71c724ab99abf1d798246288a4435 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 18 Oct 2023 15:19:26 +0200 Subject: [PATCH 105/449] refs #6199 feat(sale_updateQuantity): can upload --- .../05-ticket/01-sale/02_edit_sale.spec.js | 2 +- loopback/locale/en.json | 4 +- loopback/locale/es.json | 2 +- .../methods/sale/specs/updateQuantity.spec.js | 2 +- modules/ticket/back/models/sale.js | 47 ++++++++++++++----- 5 files changed, 39 insertions(+), 18 deletions(-) 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 6264073f63..b89254ddab 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 @@ -139,7 +139,7 @@ describe('Ticket Edit sale path', () => { await page.type(selectors.ticketSales.firstSaleQuantity, '11\u000d'); const message = await page.waitForSnackbar(); - expect(message.text).toContain('The new quantity should be smaller than the old one'); + expect(message.text).toContain('The price of the item changed'); }); it('should remove 1 from the first sale quantity', async() => { diff --git a/loopback/locale/en.json b/loopback/locale/en.json index f61226e9ee..8dfed66f62 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -14,7 +14,7 @@ "The default consignee can not be unchecked": "The default consignee can not be unchecked", "Enter an integer different to zero": "Enter an integer different to zero", "Package cannot be blank": "Package cannot be blank", - "The new quantity should be smaller than the old one": "The new quantity should be smaller than the old one", + "The price of the item changed": "The price of the item changed", "The sales of this ticket can't be modified": "The sales of this ticket can't be modified", "Cannot check Equalization Tax in this NIF/CIF": "Cannot check Equalization Tax in this NIF/CIF", "You can't create an order for a frozen client": "You can't create an order for a frozen client", @@ -191,4 +191,4 @@ "Booking completed": "Booking complete", "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation", "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets" -} \ No newline at end of file +} diff --git a/loopback/locale/es.json b/loopback/locale/es.json index dd3c92378a..525e3806f3 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -35,7 +35,7 @@ "The grade must be an integer greater than or equal to zero": "El grade debe ser un entero mayor o igual a cero", "Sample type cannot be blank": "El tipo de plantilla no puede quedar en blanco", "Description cannot be blank": "Se debe rellenar el campo de texto", - "The new quantity should be smaller than the old one": "La nueva cantidad debe de ser menor que la anterior", + "The price of the item changed": "El precio del artículo cambió", "The value should not be greater than 100%": "El valor no debe de ser mayor de 100%", "The value should be a number": "El valor debe ser un numero", "This order is not editable": "Esta orden no se puede modificar", diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index 0fde997fa7..74be352d17 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -49,7 +49,7 @@ describe('sale updateQuantity()', () => { error = e; } - expect(error).toEqual(new Error('The new quantity should be smaller than the old one')); + expect(error).toEqual(new Error('The price of the item changed')); }); it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index fe63072704..c1b3f3990d 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -35,7 +35,7 @@ module.exports = Self => { const ticket = await models.Ticket.findById( ticketId, { - fields: ['id', 'clientFk', 'warehouseFk', 'shipped'], + fields: ['id', 'clientFk', 'warehouseFk', 'addressFk', 'agencyModeFk', 'shipped', 'landed'], include: { relation: 'client', scope: { @@ -68,25 +68,46 @@ module.exports = Self => { if (item.family == 'EMB') return; - const itemInfo = await models.Item.getVisibleAvailable( - itemId, - ticket.warehouseFk, - ticket.shipped, - ctx.options - ); + if (newQuantity < item.minQuantity) + throw new UserError('The amount cannot be less than the minimum'); const oldQuantity = instance?.quantity ?? null; const quantityAdded = newQuantity - oldQuantity; - if (itemInfo.available < quantityAdded) - throw new UserError(`This item is not available`); if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; - if (newQuantity < item.minQuantity && itemInfo.available != newQuantity) - throw new UserError('The amount cannot be less than the minimum'); + if (ctx.isNewInstance || newQuantity <= oldQuantity) return; - if (!ctx.isNewInstance && newQuantity > oldQuantity) - throw new UserError('The new quantity should be smaller than the old one'); + await Self.rawSql(`CALL catalog_calcFromItem(?,?,?,?)`, [ + ticket.landed, + ticket.addressFk, + ticket.agencyModeFk, + itemId + ], + ctx.options); + + const [itemInfo] = await Self.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); + if (itemInfo?.available < quantityAdded) + throw new UserError(`This item is not available`); + + const [saleGrouping] = await Self.rawSql(` + SELECT MAX(t.grouping), t.price newPrice + FROM tmp.ticketComponentPrice t + WHERE t.grouping <= ?`, + [quantityAdded], + ctx.options); + + await Self.rawSql(` + DROP TEMPORARY TABLE + tmp.ticketCalculateItem, + tmp.ticketComponentPrice, + tmp.ticketComponent, + tmp.ticketLot, + tmp.zoneGetShipped; + `, null, ctx.options); + + if (!saleGrouping?.newPrice || instance.price < saleGrouping.newPrice) + throw new UserError('The price of the item changed'); }); }; From 4d3d38ebe301bdd62a7cc252ab7bbbb8cba7a3ce Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 18 Oct 2023 15:22:04 +0200 Subject: [PATCH 106/449] refs #6014 feat: executeRoutine --- .../methods/application/executeRoutine.js | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 loopback/common/methods/application/executeRoutine.js diff --git a/loopback/common/methods/application/executeRoutine.js b/loopback/common/methods/application/executeRoutine.js new file mode 100644 index 0000000000..a5557bc617 --- /dev/null +++ b/loopback/common/methods/application/executeRoutine.js @@ -0,0 +1,61 @@ +module.exports = Self => { + Self.remoteMethodCtx('executeRoutine', { + description: 'Return the routes by worker', + accessType: '*', + accepts: [ + { + arg: 'routine', + type: 'string', + description: 'The routine sql', + required: true, + http: {source: 'path'} + }, + { + arg: 'params', + type: ['any'], + description: 'The array of params', + required: true, + } + ], + returns: { + type: 'any', + root: true + }, + http: { + path: `/:routine/execute-routine`, + verb: 'POST' + } + }); + + Self.executeRoutine = async(ctx, routine, params, options) => { + const userId = ctx.req.accessToken.userId; + + const myOptions = {}; + if (typeof options == 'object') + Object.assign(myOptions, options); + + const user = await Self.app.models.VnUser.findById(userId, { + fields: ['id', 'roleFk'], + include: { + relation: 'role', + scope: { + fields: ['id', 'name'] + } + } + }); + + const inherits = await Self.app.models.RoleRole.find({ + where: { + + } + }); + console.log(user.role.name); + + const checkACL = await models.ACL.checkAccessAcl(ctx, 'Application', routine, '*'); + if (!checkACL) throw error; + + const requestParams = [routine]; + requestParams.concat(params); + return Self.app.models.Route.rawSql(`CALL ?(...)`, requestParams, myOptions); + }; +}; From 488181e1b63593ba03de4a1adb15dcbf9a0ce9e1 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 19 Oct 2023 08:37:28 +0200 Subject: [PATCH 107/449] =?UTF-8?q?feat(getUrl):=20se=20a=C3=B1ade=20el=20?= =?UTF-8?q?metodo=20getUrl=20refs=20#5979?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/methods/collection/getTickets.js | 2 +- .../methods/application => back/methods/url}/getUrl.js | 8 +++++--- back/models/url.js | 3 +++ back/models/vn-user.js | 2 +- loopback/common/models/application.js | 1 - modules/claim/back/methods/claim/claimPickupEmail.js | 2 +- modules/claim/back/methods/claim/createFromSales.js | 2 +- modules/claim/back/methods/claim/regularizeClaim.js | 2 +- .../claim/back/methods/claim/specs/updateClaim.spec.js | 2 +- modules/claim/back/methods/claim/updateClaim.js | 4 ++-- modules/client/back/models/client.js | 4 ++-- modules/client/back/models/credit-insurance.js | 2 +- .../back/methods/invoiceOut/makePdfAndNotify.js | 2 +- modules/ticket/back/methods/sale/deleteSales.js | 2 +- modules/ticket/back/methods/sale/reserve.js | 2 +- modules/ticket/back/methods/sale/updatePrice.js | 2 +- modules/ticket/back/methods/sale/updateQuantity.js | 2 +- modules/ticket/back/methods/ticket-request/confirm.js | 2 +- modules/ticket/back/methods/ticket-request/deny.js | 2 +- modules/ticket/back/methods/ticket/addSale.js | 2 +- modules/ticket/back/methods/ticket/componentUpdate.js | 2 +- modules/ticket/back/methods/ticket/merge.js | 2 +- modules/ticket/back/methods/ticket/restore.js | 2 +- modules/ticket/back/methods/ticket/setDeleted.js | 2 +- modules/ticket/back/methods/ticket/updateDiscount.js | 2 +- modules/worker/back/methods/worker/createAbsence.js | 2 +- modules/worker/back/methods/worker/deleteAbsence.js | 2 +- 27 files changed, 34 insertions(+), 30 deletions(-) rename {loopback/common/methods/application => back/methods/url}/getUrl.js (79%) create mode 100644 back/models/url.js diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js index dbb286b4f6..82fbaf8b82 100644 --- a/back/methods/collection/getTickets.js +++ b/back/methods/collection/getTickets.js @@ -26,7 +26,7 @@ module.exports = Self => { Self.getTickets = async(ctx, id, print, options) => { const userId = ctx.req.accessToken.userId; - const url = Self.app.models.Application.getUrl(); + const url = Self.app.models.Url.getUrl(); const $t = ctx.req.__; const myOptions = {}; diff --git a/loopback/common/methods/application/getUrl.js b/back/methods/url/getUrl.js similarity index 79% rename from loopback/common/methods/application/getUrl.js rename to back/methods/url/getUrl.js index 4e51b0776c..f258503b16 100644 --- a/loopback/common/methods/application/getUrl.js +++ b/back/methods/url/getUrl.js @@ -1,9 +1,10 @@ module.exports = Self => { - Self.remoteMethodCtx('getUrl', { + Self.remoteMethod('getUrl', { description: 'Returns the colling app name', + accessType: 'READ', accepts: [ { - arg: 'appName', + arg: 'app', type: 'string', required: false } @@ -18,13 +19,14 @@ module.exports = Self => { } }); Self.getUrl = async(appName = 'salix') => { + console.log('appName: ', appName); const {url} = await Self.app.models.Url.findOne({ - where: { appName, enviroment: process.env.NODE_ENV || 'development' } }); + console.log('url: ', url); return url; }; }; diff --git a/back/models/url.js b/back/models/url.js new file mode 100644 index 0000000000..af71ec1c49 --- /dev/null +++ b/back/models/url.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/url/getUrl')(Self); +}; diff --git a/back/models/vn-user.js b/back/models/vn-user.js index a38139bc7d..c65c625901 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -89,7 +89,7 @@ module.exports = function(Self) { }; Self.on('resetPasswordRequest', async function(info) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const defaultHash = '/reset-password?access_token=$token$'; const recoverHashes = { diff --git a/loopback/common/models/application.js b/loopback/common/models/application.js index b3841d34a3..5e767fdc11 100644 --- a/loopback/common/models/application.js +++ b/loopback/common/models/application.js @@ -2,5 +2,4 @@ module.exports = function(Self) { require('../methods/application/status')(Self); require('../methods/application/post')(Self); - require('../methods/application/getUrl')(Self); }; diff --git a/modules/claim/back/methods/claim/claimPickupEmail.js b/modules/claim/back/methods/claim/claimPickupEmail.js index aea571a61e..596102a246 100644 --- a/modules/claim/back/methods/claim/claimPickupEmail.js +++ b/modules/claim/back/methods/claim/claimPickupEmail.js @@ -44,7 +44,7 @@ module.exports = Self => { Self.claimPickupEmail = async ctx => { const models = Self.app.models; const $t = ctx.req.__; // $translate - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const args = Object.assign({}, ctx.args); const params = { diff --git a/modules/claim/back/methods/claim/createFromSales.js b/modules/claim/back/methods/claim/createFromSales.js index 24ba74c6d5..30093e43d8 100644 --- a/modules/claim/back/methods/claim/createFromSales.js +++ b/modules/claim/back/methods/claim/createFromSales.js @@ -94,7 +94,7 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Created claim', { claimId: newClaim.id, diff --git a/modules/claim/back/methods/claim/regularizeClaim.js b/modules/claim/back/methods/claim/regularizeClaim.js index 4ac500e2fd..a51b114ef2 100644 --- a/modules/claim/back/methods/claim/regularizeClaim.js +++ b/modules/claim/back/methods/claim/regularizeClaim.js @@ -56,7 +56,7 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { const nickname = address && address.nickname || destination.description; - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Sent units from ticket', { quantity: sale.quantity, concept: sale.concept, diff --git a/modules/claim/back/methods/claim/specs/updateClaim.spec.js b/modules/claim/back/methods/claim/specs/updateClaim.spec.js index e7be8e9c6c..fff4d7ac65 100644 --- a/modules/claim/back/methods/claim/specs/updateClaim.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaim.spec.js @@ -4,7 +4,7 @@ const LoopBackContext = require('loopback-context'); describe('Update Claim', () => { let url; beforeAll(async() => { - url = await app.models.Application.getUrl(); + url = await app.models.Url.getUrl(); const activeCtx = { accessToken: {userId: 9}, http: { diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index 534f0c7abf..e418af9507 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -114,7 +114,7 @@ module.exports = Self => { async function notifyStateChange(ctx, workerId, claim, state) { const models = Self.app.models; - const url = await models.Application.getUrl(); + const url = await models.Url.getUrl(); const $t = ctx.req.__; // $translate const message = $t(`Claim state has changed to ${state}`, { @@ -128,7 +128,7 @@ module.exports = Self => { async function notifyPickUp(ctx, workerId, claim) { const models = Self.app.models; - const url = await models.Application.getUrl('lilium'); + const url = await models.Url.getUrl('lilium'); const $t = ctx.req.__; // $translate const message = $t('Claim will be picked', { diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 1b60b13296..e16e884cc5 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -353,7 +353,7 @@ module.exports = Self => { const httpCtx = {req: loopBackContext.active}; const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const salesPersonId = instance.salesPersonFk; @@ -395,7 +395,7 @@ module.exports = Self => { const httpCtx = {req: loopBackContext.active}; const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const models = Self.app.models; let previousWorker = {name: $t('None')}; diff --git a/modules/client/back/models/credit-insurance.js b/modules/client/back/models/credit-insurance.js index 619904612c..84bd90424c 100644 --- a/modules/client/back/models/credit-insurance.js +++ b/modules/client/back/models/credit-insurance.js @@ -57,7 +57,7 @@ module.exports = function(Self) { const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const fullPath = `${url}client/${client.id}/credit-insurance/index`; const message = $t('MESSAGE_INSURANCE_CHANGE', { clientId: client.id, diff --git a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js index 49c7850139..1de15b6661 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js +++ b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js @@ -59,7 +59,7 @@ module.exports = Self => { }; await Self.invoiceEmail(ctx, ref); } catch (err) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = ctx.req.__('Mail not sent', { clientId: client.id, clientUrl: `${url}claim/${id}/summary` diff --git a/modules/ticket/back/methods/sale/deleteSales.js b/modules/ticket/back/methods/sale/deleteSales.js index c71f8d5e13..0207815a94 100644 --- a/modules/ticket/back/methods/sale/deleteSales.js +++ b/modules/ticket/back/methods/sale/deleteSales.js @@ -68,7 +68,7 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Deleted sales from ticket', { ticketId: ticketId, diff --git a/modules/ticket/back/methods/sale/reserve.js b/modules/ticket/back/methods/sale/reserve.js index b111a04582..36db791fc2 100644 --- a/modules/ticket/back/methods/sale/reserve.js +++ b/modules/ticket/back/methods/sale/reserve.js @@ -85,7 +85,7 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Changed sale reserved state', { ticketId: ticketId, diff --git a/modules/ticket/back/methods/sale/updatePrice.js b/modules/ticket/back/methods/sale/updatePrice.js index 3cae2a3333..191fd09e3d 100644 --- a/modules/ticket/back/methods/sale/updatePrice.js +++ b/modules/ticket/back/methods/sale/updatePrice.js @@ -98,7 +98,7 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Changed sale price', { ticketId: sale.ticket().id, itemId: sale.itemFk, diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index acccc6c2f9..28754e50ce 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -80,7 +80,7 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Changed sale quantity', { ticketId: sale.ticket().id, itemId: sale.itemFk, diff --git a/modules/ticket/back/methods/ticket-request/confirm.js b/modules/ticket/back/methods/ticket-request/confirm.js index a69fc7fd76..00310f33c3 100644 --- a/modules/ticket/back/methods/ticket-request/confirm.js +++ b/modules/ticket/back/methods/ticket-request/confirm.js @@ -84,7 +84,7 @@ module.exports = Self => { const query = `CALL vn.sale_calculateComponent(?, NULL)`; await Self.rawSql(query, [sale.id], myOptions); - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const requesterId = request.requesterFk; const message = $t('Bought units from buy request', { diff --git a/modules/ticket/back/methods/ticket-request/deny.js b/modules/ticket/back/methods/ticket-request/deny.js index 9ec11d755b..44f1e48a1e 100644 --- a/modules/ticket/back/methods/ticket-request/deny.js +++ b/modules/ticket/back/methods/ticket-request/deny.js @@ -50,7 +50,7 @@ module.exports = Self => { const request = await Self.app.models.TicketRequest.findById(ctx.args.id, null, myOptions); await request.updateAttributes(params, myOptions); - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const requesterId = request.requesterFk; const message = $t('Deny buy request', { diff --git a/modules/ticket/back/methods/ticket/addSale.js b/modules/ticket/back/methods/ticket/addSale.js index 29e49d8e6e..59f1190fa0 100644 --- a/modules/ticket/back/methods/ticket/addSale.js +++ b/modules/ticket/back/methods/ticket/addSale.js @@ -94,7 +94,7 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Added sale to ticket', { ticketId: id, diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index fc8b3a40c8..f7c36f1088 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -237,7 +237,7 @@ module.exports = Self => { const salesPersonId = originalTicket.client().salesPersonFk; if (salesPersonId) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); let changesMade = ''; for (let change in newProperties) { diff --git a/modules/ticket/back/methods/ticket/merge.js b/modules/ticket/back/methods/ticket/merge.js index 19c7f9fa0d..1106cef06f 100644 --- a/modules/ticket/back/methods/ticket/merge.js +++ b/modules/ticket/back/methods/ticket/merge.js @@ -25,7 +25,7 @@ module.exports = Self => { Self.merge = async(ctx, tickets, options) => { const httpRequest = ctx.req; const $t = httpRequest.__; - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const models = Self.app.models; const myOptions = {}; let tx; diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 0aaef0418e..e268c38919 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -48,7 +48,7 @@ module.exports = Self => { // Send notification to salesPerson const salesPersonId = ticket.client().salesPersonFk; if (salesPersonId) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t(`I have restored the ticket id`, { id: id, url: `${url}ticket/${id}/summary` diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js index a6fd295f17..9a9fd9056d 100644 --- a/modules/ticket/back/methods/ticket/setDeleted.js +++ b/modules/ticket/back/methods/ticket/setDeleted.js @@ -119,7 +119,7 @@ module.exports = Self => { // Send notification to salesPerson const salesPersonUser = ticket.client().salesPersonUser(); if (salesPersonUser && sales.length) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t(`I have deleted the ticket id`, { id: id, url: `${url}ticket/${id}/summary` diff --git a/modules/ticket/back/methods/ticket/updateDiscount.js b/modules/ticket/back/methods/ticket/updateDiscount.js index 05ade4f01b..2e8bec27a8 100644 --- a/modules/ticket/back/methods/ticket/updateDiscount.js +++ b/modules/ticket/back/methods/ticket/updateDiscount.js @@ -165,7 +165,7 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Changed sale discount', { ticketId: id, ticketUrl: `${url}ticket/${id}/sale`, diff --git a/modules/worker/back/methods/worker/createAbsence.js b/modules/worker/back/methods/worker/createAbsence.js index 10992f91ff..d628d0a2b4 100644 --- a/modules/worker/back/methods/worker/createAbsence.js +++ b/modules/worker/back/methods/worker/createAbsence.js @@ -109,7 +109,7 @@ module.exports = Self => { const absenceType = await models.AbsenceType.findById(args.absenceTypeId, null, myOptions); const account = await models.VnUser.findById(userId, null, myOptions); const subordinated = await models.VnUser.findById(id, null, myOptions); - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const body = $t('Created absence', { author: account.nickname, employee: subordinated.nickname, diff --git a/modules/worker/back/methods/worker/deleteAbsence.js b/modules/worker/back/methods/worker/deleteAbsence.js index 2912e6db48..b71d077a40 100644 --- a/modules/worker/back/methods/worker/deleteAbsence.js +++ b/modules/worker/back/methods/worker/deleteAbsence.js @@ -60,7 +60,7 @@ module.exports = Self => { const absenceType = await models.AbsenceType.findById(absence.dayOffTypeFk, null, myOptions); const account = await models.VnUser.findById(userId, null, myOptions); const subordinated = await models.VnUser.findById(labour.workerFk, null, myOptions); - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const body = $t('Deleted absence', { author: account.nickname, employee: subordinated.nickname, From f8889df90354660fbeb3160e4f1a4e6416bc9a40 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 19 Oct 2023 08:40:25 +0200 Subject: [PATCH 108/449] remove(console.log): se quitan console.log que se utilizaron para dbuggear refs #5979 --- back/methods/chat/sendCheckingPresence.js | 9 --------- back/methods/url/getUrl.js | 2 -- back/models/chat.js | 8 -------- modules/claim/back/methods/claim/updateClaim.js | 3 --- 4 files changed, 22 deletions(-) diff --git a/back/methods/chat/sendCheckingPresence.js b/back/methods/chat/sendCheckingPresence.js index 0bae87a359..7bba96d594 100644 --- a/back/methods/chat/sendCheckingPresence.js +++ b/back/methods/chat/sendCheckingPresence.js @@ -25,16 +25,10 @@ module.exports = Self => { }); Self.sendCheckingPresence = async(ctx, recipientId, message) => { - console.log('recipientId: ', recipientId); if (!recipientId) return false; const models = Self.app.models; - console.log('sender: ', ctx.req.accessToken.userId); const sender = ctx.req.accessToken.userId; - console.log('sender: ', sender); const recipient = recipientId; - console.log('recipient: ', recipient); - - console.log('recipientId == sender: ', recipientId == sender); // Prevent sending messages to yourself if (recipientId == sender) return false; @@ -42,7 +36,6 @@ module.exports = Self => { throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${sender}`); if (process.env.NODE_ENV == 'test') message = `[Test:Environment to user ${sender}] ` + message; - console.log('chat create'); const chat = await models.Chat.create({ senderFk: sender.id, recipient: `@${recipient.name}`, @@ -53,8 +46,6 @@ module.exports = Self => { attempts: 0 }); - console.log('chat: '); - try { await Self.sendCheckingUserStatus(chat); await Self.updateChat(chat, 'sent'); diff --git a/back/methods/url/getUrl.js b/back/methods/url/getUrl.js index f258503b16..f30719b9f1 100644 --- a/back/methods/url/getUrl.js +++ b/back/methods/url/getUrl.js @@ -19,14 +19,12 @@ module.exports = Self => { } }); Self.getUrl = async(appName = 'salix') => { - console.log('appName: ', appName); const {url} = await Self.app.models.Url.findOne({ where: { appName, enviroment: process.env.NODE_ENV || 'development' } }); - console.log('url: ', url); return url; }; }; diff --git a/back/models/chat.js b/back/models/chat.js index 240ec2c261..882db747e3 100644 --- a/back/models/chat.js +++ b/back/models/chat.js @@ -6,26 +6,18 @@ module.exports = Self => { require('../methods/chat/sendQueued')(Self); Self.observe('before save', async function(ctx) { - console.log('chat start 1'); - - console.log('ctx.isNewInstance: ', ctx.isNewInstance); - console.log('message: ', ctx.instance); if (!ctx.isNewInstance) return; - let {message} = ctx.instance; if (!message) return; const parts = message.match(/(?<=\[)[a-zA-Z0-9_\-+!@#$%^&*()={};':"\\|,.<>/?\s]*(?=])/g); if (!parts) return; - console.log('chat start 2'); const replacedParts = parts.map(part => { return part.replace(/[!$%^&*()={};':"\\,.<>/?]/g, ''); }); - console.log('chat start 3'); for (const [index, part] of parts.entries()) message = message.replace(part, replacedParts[index]); ctx.instance.message = message; - console.log('chat end'); }); }; diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index e418af9507..8210f7a83e 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -136,9 +136,6 @@ module.exports = Self => { clientName: claim.client().name, claimUrl: `${url}claim/${claim.id}/summary` }); - console.log('url', `${url}claim/${claim.id}/summary`); - console.log('claim client', claim.client().name); - console.log('claim id', claim.id); await models.Chat.sendCheckingPresence(ctx, workerId, message); } }; From d3a7b4ecb996aff3f9eaae374a96ab42366aeada Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 19 Oct 2023 08:41:26 +0200 Subject: [PATCH 109/449] remove: console.log from updateClaim refs #5979 --- modules/claim/back/methods/claim/updateClaim.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index 8210f7a83e..7f7ccb299a 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -122,7 +122,6 @@ module.exports = Self => { clientName: claim.client().name, claimUrl: `${url}claim/${claim.id}/summary` }); - console.log(`${url}claim/${claim.id}/summary`); await models.Chat.sendCheckingPresence(ctx, workerId, message); } From 52b14cf8b4fb8c4f0f19337c4ef56148b403c8c6 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 19 Oct 2023 09:51:10 +0200 Subject: [PATCH 110/449] ref #6138 fix emailVerified --- modules/worker/back/methods/worker/setPassword.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/methods/worker/setPassword.js b/modules/worker/back/methods/worker/setPassword.js index fcfb5e7334..43d3d946f5 100644 --- a/modules/worker/back/methods/worker/setPassword.js +++ b/modules/worker/back/methods/worker/setPassword.js @@ -37,7 +37,7 @@ module.exports = Self => { if (!isSubordinate) throw new UserError('You don\'t have enough privileges.'); await models.VnUser.setPassword(args.workerFk, args.newPass, myOptions); - await models.VnUser.updateAll({id: args.workerFk}, {emailVerified: 1}, myOptions); + await models.VnUser.updateAll({id: args.workerFk}, {emailVerified: true}, myOptions); if (tx) await tx.commit(); } catch (e) { From a5b6921592ac1f24c66a60c524dd924d34ad5dee Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 19 Oct 2023 10:44:34 +0200 Subject: [PATCH 111/449] refactor(changes): se mueven los sql a la ultima carpeta refs #3126 --- db/changes/{234001 => 234201}/00-packagingFk.sql | 0 db/changes/{234001 => 234201}/00-packagingFkviews.sql | 0 db/changes/{234001 => 234201}/02-packagingFktrigger.sql | 0 db/changes/{234001 => 234201}/03-packagingFkProc.sql | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename db/changes/{234001 => 234201}/00-packagingFk.sql (100%) rename db/changes/{234001 => 234201}/00-packagingFkviews.sql (100%) rename db/changes/{234001 => 234201}/02-packagingFktrigger.sql (100%) rename db/changes/{234001 => 234201}/03-packagingFkProc.sql (100%) diff --git a/db/changes/234001/00-packagingFk.sql b/db/changes/234201/00-packagingFk.sql similarity index 100% rename from db/changes/234001/00-packagingFk.sql rename to db/changes/234201/00-packagingFk.sql diff --git a/db/changes/234001/00-packagingFkviews.sql b/db/changes/234201/00-packagingFkviews.sql similarity index 100% rename from db/changes/234001/00-packagingFkviews.sql rename to db/changes/234201/00-packagingFkviews.sql diff --git a/db/changes/234001/02-packagingFktrigger.sql b/db/changes/234201/02-packagingFktrigger.sql similarity index 100% rename from db/changes/234001/02-packagingFktrigger.sql rename to db/changes/234201/02-packagingFktrigger.sql diff --git a/db/changes/234001/03-packagingFkProc.sql b/db/changes/234201/03-packagingFkProc.sql similarity index 100% rename from db/changes/234001/03-packagingFkProc.sql rename to db/changes/234201/03-packagingFkProc.sql From 1b8f227c473152f02dd6ce0c673292838183b5c6 Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 19 Oct 2023 11:58:15 +0200 Subject: [PATCH 112/449] ticket #125321 filter advance tickets fix --- .../ticket/front/advance-search-panel/index.js | 4 ++-- modules/ticket/front/advance/index.js | 18 ++++-------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/modules/ticket/front/advance-search-panel/index.js b/modules/ticket/front/advance-search-panel/index.js index 8ddbe78d4a..218fb14d3a 100644 --- a/modules/ticket/front/advance-search-panel/index.js +++ b/modules/ticket/front/advance-search-panel/index.js @@ -16,8 +16,8 @@ class Controller extends SearchPanel { this.$http.get('ItemPackingTypes', {filter}).then(res => { for (let ipt of res.data) { itemPackingTypes.push({ - code: ipt.code, - description: this.$t(ipt.description) + description: this.$t(ipt.description), + code: ipt.code }); } this.itemPackingTypes = itemPackingTypes; diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index 0cec41227a..6f8a92ebe2 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -163,26 +163,16 @@ export default class Controller extends Section { return {'futureId': value}; case 'liters': return {'liters': value}; - case 'lines': - return {'lines': value}; case 'futureLiters': return {'futureLiters': value}; + case 'lines': + return {'lines': value}; case 'futureLines': return {'futureLines': value}; case 'ipt': - return {or: - [ - {'ipt': {like: `%${value}%`}}, - {'ipt': null} - ] - }; + return {'ipt': {like: `%${value}%`}}; case 'futureIpt': - return {or: - [ - {'futureIpt': {like: `%${value}%`}}, - {'futureIpt': null} - ] - }; + return {'futureIpt': {like: `%${value}%`}}; case 'totalWithVat': return {'totalWithVat': value}; case 'futureTotalWithVat': From d9ab607126385e9cf99bab9529b8f0bfdb2a7954 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 19 Oct 2023 13:03:11 +0200 Subject: [PATCH 113/449] refs #6199 feat(sale): increase quantity if newPrice is higher --- .../collection/spec/setSaleQuantity.spec.js | 9 +- .../05-ticket/01-sale/02_edit_sale.spec.js | 8 - .../methods/sale/specs/updateQuantity.spec.js | 138 ++++++++++++++---- modules/ticket/back/models/sale.js | 35 +++-- 4 files changed, 133 insertions(+), 57 deletions(-) diff --git a/back/methods/collection/spec/setSaleQuantity.spec.js b/back/methods/collection/spec/setSaleQuantity.spec.js index 8cd73205f1..b563f5b198 100644 --- a/back/methods/collection/spec/setSaleQuantity.spec.js +++ b/back/methods/collection/spec/setSaleQuantity.spec.js @@ -18,7 +18,14 @@ describe('setSaleQuantity()', () => { it('should change quantity sale', async() => { const tx = await models.Ticket.beginTransaction({}); - spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: 100})))); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT 100 as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); try { const options = {transaction: tx}; 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 b89254ddab..23983a9c88 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 @@ -134,14 +134,6 @@ describe('Ticket Edit sale path', () => { await page.accessToSection('ticket.card.sale'); }); - it('should try to add a higher quantity value and then receive an error', async() => { - await page.waitToClick(selectors.ticketSales.firstSaleQuantityCell); - await page.type(selectors.ticketSales.firstSaleQuantity, '11\u000d'); - const message = await page.waitForSnackbar(); - - expect(message.text).toContain('The price of the item changed'); - }); - it('should remove 1 from the first sale quantity', async() => { await page.waitToClick(selectors.ticketSales.firstSaleQuantityCell); await page.waitForSelector(selectors.ticketSales.firstSaleQuantity); diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index 74be352d17..34c58ef98c 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -24,34 +24,6 @@ describe('sale updateQuantity()', () => { }; } - it('should throw an error if the quantity is greater than it should be', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: 100})))); - - const tx = await models.Sale.beginTransaction({}); - - let error; - try { - const options = {transaction: tx}; - - await models.Sale.updateQuantity(ctx, 17, 31, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).toEqual(new Error('The price of the item changed')); - }); - it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { const saleId = 17; const buyerId = 35; @@ -64,7 +36,14 @@ describe('sale updateQuantity()', () => { }; const tx = await models.Sale.beginTransaction({}); spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(buyerId)); - spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: 100})))); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT 100 as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); try { const options = {transaction: tx}; @@ -193,6 +172,14 @@ describe('sale updateQuantity()', () => { const item = await models.Item.findById(itemId, null, options); await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT 100 as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); @@ -226,7 +213,15 @@ describe('sale updateQuantity()', () => { const item = await models.Item.findById(itemId, null, options); await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: newQuantity})))); + + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT ${newQuantity} as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); @@ -236,4 +231,87 @@ describe('sale updateQuantity()', () => { throw e; } }); + + it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 8 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw error when increase quantity and the new price is lower than the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + let error; + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('The price of the item changed')); + }); }); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index c1b3f3990d..23cf90353f 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -31,6 +31,8 @@ module.exports = Self => { const ticketId = changes?.ticketFk || instance?.ticketFk; const itemId = changes?.itemFk || instance?.itemFk; + const oldQuantity = instance?.quantity ?? null; + const quantityAdded = newQuantity - oldQuantity; const ticket = await models.Ticket.findById( ticketId, @@ -65,20 +67,9 @@ module.exports = Self => { fields: ['family', 'minQuantity'], where: {id: itemId}, }, ctx.options); - if (item.family == 'EMB') return; - if (newQuantity < item.minQuantity) - throw new UserError('The amount cannot be less than the minimum'); - - const oldQuantity = instance?.quantity ?? null; - const quantityAdded = newQuantity - oldQuantity; - - if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; - - if (ctx.isNewInstance || newQuantity <= oldQuantity) return; - - await Self.rawSql(`CALL catalog_calcFromItem(?,?,?,?)`, [ + await models.Sale.rawSql(`CALL catalog_calcFromItem(?,?,?,?)`, [ ticket.landed, ticket.addressFk, ticket.agencyModeFk, @@ -86,19 +77,27 @@ module.exports = Self => { ], ctx.options); - const [itemInfo] = await Self.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); - if (itemInfo?.available < quantityAdded) + const [itemInfo] = await models.Sale.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); + + if (!itemInfo?.available || itemInfo.available < quantityAdded) throw new UserError(`This item is not available`); - const [saleGrouping] = await Self.rawSql(` + if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; + + if (newQuantity < item.minQuantity && newQuantity != itemInfo?.available) + throw new UserError('The amount cannot be less than the minimum'); + + if (ctx.isNewInstance || newQuantity <= oldQuantity) return; + + const [saleGrouping] = await models.Sale.rawSql(` SELECT MAX(t.grouping), t.price newPrice FROM tmp.ticketComponentPrice t WHERE t.grouping <= ?`, [quantityAdded], ctx.options); - await Self.rawSql(` - DROP TEMPORARY TABLE + await models.Sale.rawSql(` + DROP TEMPORARY TABLE IF EXISTS tmp.ticketCalculateItem, tmp.ticketComponentPrice, tmp.ticketComponent, @@ -106,7 +105,7 @@ module.exports = Self => { tmp.zoneGetShipped; `, null, ctx.options); - if (!saleGrouping?.newPrice || instance.price < saleGrouping.newPrice) + if (!saleGrouping?.newPrice || saleGrouping.newPrice < instance.price) throw new UserError('The price of the item changed'); }); }; From 37209a223a8f7cd116356cf6d645ef9703afe558 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 19 Oct 2023 15:05:19 +0200 Subject: [PATCH 114/449] feat(db): packagefk virtual column refs #3126 --- db/changes/234201/00-packagingFk.sql | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/db/changes/234201/00-packagingFk.sql b/db/changes/234201/00-packagingFk.sql index 5ed1d95129..9a775ada95 100644 --- a/db/changes/234201/00-packagingFk.sql +++ b/db/changes/234201/00-packagingFk.sql @@ -1,2 +1,5 @@ - ALTER TABLE vn.buy CHANGE packageFk packagingFk varchar(10) - CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT '--' NULL; \ No newline at end of file +ALTER TABLE `vn`.`buy` CHANGE `packageFk` `packagingFk` varchar(10) +CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT '--' NULL; + +ALTER TABLE `vn`.`buy` +ADD COLUMN `packageFk` varchar(10) AS (`packagingFk`) VIRTUAL; \ No newline at end of file From 16f20cea70c278cc1112b6c66a77efe0022c91fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 19 Oct 2023 15:12:06 +0200 Subject: [PATCH 115/449] refs #6199 fix(sale): get minim price without grouping --- modules/ticket/back/models/sale.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 23cf90353f..ef3dd8ef72 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -90,9 +90,10 @@ module.exports = Self => { if (ctx.isNewInstance || newQuantity <= oldQuantity) return; const [saleGrouping] = await models.Sale.rawSql(` - SELECT MAX(t.grouping), t.price newPrice + SELECT t.price newPrice FROM tmp.ticketComponentPrice t - WHERE t.grouping <= ?`, + ORDER BY (t.grouping <= ?) DESC, t.grouping ASC + LIMIT 1`, [quantityAdded], ctx.options); From 07fa01103524ddfd35dc3adaca540641a8fb4af7 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 19 Oct 2023 18:24:03 +0200 Subject: [PATCH 116/449] fix(updateClaim): el spec daba error refs #5979 --- modules/claim/back/methods/claim/specs/updateClaim.spec.js | 2 +- modules/claim/back/methods/claim/updateClaim.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/claim/back/methods/claim/specs/updateClaim.spec.js b/modules/claim/back/methods/claim/specs/updateClaim.spec.js index fff4d7ac65..85ada869a9 100644 --- a/modules/claim/back/methods/claim/specs/updateClaim.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaim.spec.js @@ -62,7 +62,7 @@ describe('Update Claim', () => { expect(error.message).toEqual(`You don't have enough privileges to change that field`); }); - fit(`should success to update the claimState to 'canceled' and send a rocket message`, async() => { + it(`should success to update the claimState to 'canceled' and send a rocket message`, async() => { const tx = await app.models.Claim.beginTransaction({}); try { diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index 7f7ccb299a..f18e3a8123 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -92,6 +92,7 @@ module.exports = Self => { // When hasToPickUp has been changed if (salesPerson && changedHasToPickUp && updatedClaim.hasToPickUp) notifyPickUp(ctx, salesPerson.id, claim); + // When claimState has been changed if (args.claimStateFk) { const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions); @@ -114,7 +115,7 @@ module.exports = Self => { async function notifyStateChange(ctx, workerId, claim, state) { const models = Self.app.models; - const url = await models.Url.getUrl(); + const url = models.Url.getUrl(); const $t = ctx.req.__; // $translate const message = $t(`Claim state has changed to ${state}`, { @@ -127,7 +128,7 @@ module.exports = Self => { async function notifyPickUp(ctx, workerId, claim) { const models = Self.app.models; - const url = await models.Url.getUrl('lilium'); + const url = models.Url.getUrl(); const $t = ctx.req.__; // $translate const message = $t('Claim will be picked', { From d5f98700e7da329dd24501902cd70c0d7bb57c9a Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 20 Oct 2023 08:32:35 +0200 Subject: [PATCH 117/449] refs #6287 fix: ticket new correct return type --- modules/ticket/back/methods/ticket/new.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket/new.js b/modules/ticket/back/methods/ticket/new.js index b461fb26d3..0f5c323ed2 100644 --- a/modules/ticket/back/methods/ticket/new.js +++ b/modules/ticket/back/methods/ticket/new.js @@ -48,7 +48,7 @@ module.exports = Self => { description: `The route id filter` }], returns: { - type: 'number', + type: 'object', root: true }, http: { From 84aed7ca21c5523ea0441a46c96b7ce037080036 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 20 Oct 2023 09:26:56 +0200 Subject: [PATCH 118/449] refs #6257 fix(saleQuantity): newPrice correct restricction --- .../methods/sale/specs/updateQuantity.spec.js | 180 +++++++++++------- modules/ticket/back/models/sale.js | 2 +- 2 files changed, 112 insertions(+), 70 deletions(-) diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index 34c58ef98c..0669711e79 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -232,86 +232,128 @@ describe('sale updateQuantity()', () => { } }); - it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + describe('newPrice', () => { + it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = 31; + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; - try { - const options = {transaction: tx}; + try { + const options = {transaction: tx}; - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = ` + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 8 as price;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 7.07 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should throw error when increase quantity and the new price is lower than the previous one', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + }); - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = 31; - - let error; - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = ` - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; - params = null; + it('should increase quantity when the new price is lower than the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} } - return models.Ticket.rawSql(sqlStatement, params, options); - }); + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } + try { + const options = {transaction: tx}; - expect(error).toEqual(new Error('The price of the item changed')); + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw error when increase quantity and the new price is higher than the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + let error; + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 100000 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('The price of the item changed')); + }); }); }); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index ef3dd8ef72..4b7ed1043e 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -106,7 +106,7 @@ module.exports = Self => { tmp.zoneGetShipped; `, null, ctx.options); - if (!saleGrouping?.newPrice || saleGrouping.newPrice < instance.price) + if (!saleGrouping?.newPrice || saleGrouping.newPrice > instance.price) throw new UserError('The price of the item changed'); }); }; From 243a32dff553fa4422b26391d04f9c569fc6b01f Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 20 Oct 2023 11:36:11 +0200 Subject: [PATCH 119/449] remove(expand): quito expand de la columna requester refs #6278 --- modules/item/front/request/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/item/front/request/index.html b/modules/item/front/request/index.html index 571ad49af4..200ce3902b 100644 --- a/modules/item/front/request/index.html +++ b/modules/item/front/request/index.html @@ -26,7 +26,7 @@ Ticket ID Shipped Description - Requester + Requester Requested Price Atender From 1eabad7f4b21ea358dce4cc39a5ea94b93666d3f Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 20 Oct 2023 12:37:44 +0200 Subject: [PATCH 120/449] refs #6257 fix(saleQuantity): add isInPreparing restriction --- .../methods/sale/specs/updateQuantity.spec.js | 359 ----------------- modules/ticket/back/models/sale.js | 2 + modules/ticket/back/models/specs/sale.spec.js | 361 ++++++++++++++++++ 3 files changed, 363 insertions(+), 359 deletions(-) delete mode 100644 modules/ticket/back/methods/sale/specs/updateQuantity.spec.js create mode 100644 modules/ticket/back/models/specs/sale.spec.js diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js deleted file mode 100644 index 0669711e79..0000000000 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ /dev/null @@ -1,359 +0,0 @@ -/* eslint max-len: ["error", { "code": 150 }]*/ - -const models = require('vn-loopback/server/server').models; -const LoopBackContext = require('loopback-context'); - -describe('sale updateQuantity()', () => { - const ctx = { - req: { - accessToken: {userId: 9}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - function getActiveCtx(userId) { - return { - active: { - accessToken: {userId}, - http: { - req: { - headers: {origin: 'http://localhost'} - } - } - } - }; - } - - it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { - const saleId = 17; - const buyerId = 35; - const ctx = { - req: { - accessToken: {userId: buyerId}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - const tx = await models.Sale.beginTransaction({}); - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(buyerId)); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY - SELECT 100 as available;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - try { - const options = {transaction: tx}; - - const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); - - expect(isRoleAdvanced).toEqual(true); - - const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); - - expect(originalLine.quantity).toEqual(30); - - const newQuantity = originalLine.quantity + 1; - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); - - expect(modifiedLine.quantity).toEqual(newQuantity); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should update the quantity of a given sale current line', async() => { - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); - - const tx = await models.Sale.beginTransaction({}); - const saleId = 25; - const newQuantity = 4; - - try { - const options = {transaction: tx}; - - const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); - - expect(originalLine.quantity).toEqual(20); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); - - expect(modifiedLine.quantity).toEqual(newQuantity); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should throw an error if the quantity is negative and it is not a refund ticket', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const saleId = 17; - const newQuantity = -10; - - const tx = await models.Sale.beginTransaction({}); - - let error; - try { - const options = {transaction: tx}; - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).toEqual(new Error('You can only add negative amounts in refund tickets')); - }); - - it('should update a negative quantity when is a ticket refund', async() => { - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); - - const tx = await models.Sale.beginTransaction({}); - const saleId = 13; - const newQuantity = -10; - - try { - const options = {transaction: tx}; - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); - - expect(modifiedLine.quantity).toEqual(newQuantity); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should throw an error if the quantity is less than the minimum quantity of the item', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = minQuantity - 1; - - let error; - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY - SELECT 100 as available;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).toEqual(new Error('The amount cannot be less than the minimum')); - }); - - it('should change quantity if has minimum quantity and new quantity is equal than item available', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = minQuantity - 1; - - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY - SELECT ${newQuantity} as available;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - describe('newPrice', () => { - it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = 31; - - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = ` - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 7.07 as price;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should increase quantity when the new price is lower than the previous one', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = 31; - - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = ` - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should throw error when increase quantity and the new price is higher than the previous one', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = 31; - - let error; - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = ` - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 100000 as price;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).toEqual(new Error('The price of the item changed')); - }); - }); -}); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 4b7ed1043e..1c86ddc0cc 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -69,6 +69,8 @@ module.exports = Self => { }, ctx.options); if (item.family == 'EMB') return; + if (await models.ACL.checkAccessAcl(ctx, 'Sale', 'isInPreparing', '*')) return; + await models.Sale.rawSql(`CALL catalog_calcFromItem(?,?,?,?)`, [ ticket.landed, ticket.addressFk, diff --git a/modules/ticket/back/models/specs/sale.spec.js b/modules/ticket/back/models/specs/sale.spec.js new file mode 100644 index 0000000000..4af44c991a --- /dev/null +++ b/modules/ticket/back/models/specs/sale.spec.js @@ -0,0 +1,361 @@ +/* eslint max-len: ["error", { "code": 150 }]*/ + +const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); + +describe('sale model ', () => { + const ctx = { + req: { + accessToken: {userId: 9}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + function getActiveCtx(userId) { + return { + active: { + accessToken: {userId}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + } + }; + } + + describe('quantity field ', () => { + it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { + const saleId = 17; + const buyerId = 35; + const ctx = { + req: { + accessToken: {userId: buyerId}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + const tx = await models.Sale.beginTransaction({}); + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(buyerId)); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT 100 as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + try { + const options = {transaction: tx}; + + const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); + + expect(isRoleAdvanced).toEqual(true); + + const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); + + expect(originalLine.quantity).toEqual(30); + + const newQuantity = originalLine.quantity + 1; + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); + + expect(modifiedLine.quantity).toEqual(newQuantity); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should update the quantity of a given sale current line', async() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); + + const tx = await models.Sale.beginTransaction({}); + const saleId = 25; + const newQuantity = 4; + + try { + const options = {transaction: tx}; + + const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); + + expect(originalLine.quantity).toEqual(20); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); + + expect(modifiedLine.quantity).toEqual(newQuantity); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw an error if the quantity is negative and it is not a refund ticket', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const saleId = 17; + const newQuantity = -10; + + const tx = await models.Sale.beginTransaction({}); + + let error; + try { + const options = {transaction: tx}; + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('You can only add negative amounts in refund tickets')); + }); + + it('should update a negative quantity when is a ticket refund', async() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); + + const tx = await models.Sale.beginTransaction({}); + const saleId = 13; + const newQuantity = -10; + + try { + const options = {transaction: tx}; + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); + + expect(modifiedLine.quantity).toEqual(newQuantity); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw an error if the quantity is less than the minimum quantity of the item', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = minQuantity - 1; + + let error; + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT 100 as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('The amount cannot be less than the minimum')); + }); + + it('should change quantity if has minimum quantity and new quantity is equal than item available', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = minQuantity - 1; + + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT ${newQuantity} as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + describe('newPrice', () => { + it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 7.07 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should increase quantity when the new price is lower than the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw error when increase quantity and the new price is higher than the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + let error; + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 100000 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('The price of the item changed')); + }); + }); + }); +}); From 5c69d9c7f01e38c1e8e07e4abb9e27efc383fbe5 Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 20 Oct 2023 12:53:54 +0200 Subject: [PATCH 121/449] fix: add await in async functions refs #5979 --- back/methods/collection/getTickets.js | 2 +- loopback/common/models/application.json | 6 ------ modules/claim/back/methods/claim/updateClaim.js | 10 +++++----- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js index 82fbaf8b82..f04822697c 100644 --- a/back/methods/collection/getTickets.js +++ b/back/methods/collection/getTickets.js @@ -26,7 +26,7 @@ module.exports = Self => { Self.getTickets = async(ctx, id, print, options) => { const userId = ctx.req.accessToken.userId; - const url = Self.app.models.Url.getUrl(); + const url = await Self.app.models.Url.getUrl(); const $t = ctx.req.__; const myOptions = {}; diff --git a/loopback/common/models/application.json b/loopback/common/models/application.json index cf0653fbb1..3e6a742e2a 100644 --- a/loopback/common/models/application.json +++ b/loopback/common/models/application.json @@ -13,12 +13,6 @@ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" - }, - { - "property": "getUrl", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" },{ "accessType": "READ", "principalType": "ROLE", diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index f18e3a8123..d99528413c 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -91,16 +91,16 @@ module.exports = Self => { // When hasToPickUp has been changed if (salesPerson && changedHasToPickUp && updatedClaim.hasToPickUp) - notifyPickUp(ctx, salesPerson.id, claim); + await notifyPickUp(ctx, salesPerson.id, claim); // When claimState has been changed if (args.claimStateFk) { const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions); if (newState.hasToNotify) { if (newState.code == 'incomplete') - notifyStateChange(ctx, salesPerson.id, claim, newState.code); + await notifyStateChange(ctx, salesPerson.id, claim, newState.code); if (newState.code == 'canceled') - notifyStateChange(ctx, claim.workerFk, claim, newState.code); + await notifyStateChange(ctx, claim.workerFk, claim, newState.code); } } @@ -115,7 +115,7 @@ module.exports = Self => { async function notifyStateChange(ctx, workerId, claim, state) { const models = Self.app.models; - const url = models.Url.getUrl(); + const url = await models.Url.getUrl(); const $t = ctx.req.__; // $translate const message = $t(`Claim state has changed to ${state}`, { @@ -128,7 +128,7 @@ module.exports = Self => { async function notifyPickUp(ctx, workerId, claim) { const models = Self.app.models; - const url = models.Url.getUrl(); + const url = await models.Url.getUrl(); const $t = ctx.req.__; // $translate const message = $t('Claim will be picked', { From 4df39272d69b78930e2cb019baf959e6c186e9d8 Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 20 Oct 2023 13:08:39 +0200 Subject: [PATCH 122/449] remove: appiclation config refs #5979 --- loopback/common/models/application.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/loopback/common/models/application.json b/loopback/common/models/application.json index 3e6a742e2a..f790015852 100644 --- a/loopback/common/models/application.json +++ b/loopback/common/models/application.json @@ -13,11 +13,6 @@ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" - },{ - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" } ] } From 2edfacb91c4c14e3120b82e9c84fe10a3e995577 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 23 Oct 2023 07:33:52 +0200 Subject: [PATCH 123/449] refs #5979 fix(sendCheckingPresence)! --- back/methods/chat/sendCheckingPresence.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/back/methods/chat/sendCheckingPresence.js b/back/methods/chat/sendCheckingPresence.js index 7bba96d594..85b66e94be 100644 --- a/back/methods/chat/sendCheckingPresence.js +++ b/back/methods/chat/sendCheckingPresence.js @@ -27,15 +27,19 @@ module.exports = Self => { Self.sendCheckingPresence = async(ctx, recipientId, message) => { if (!recipientId) return false; const models = Self.app.models; - const sender = ctx.req.accessToken.userId; - const recipient = recipientId; + + const userId = ctx.req.accessToken.userId; + const sender = await models.VnUser.findById(userId, {fields: ['id']}); + const recipient = await models.VnUser.findById(recipientId, null); // Prevent sending messages to yourself - if (recipientId == sender) return false; + if (recipientId == userId) return false; if (!recipient) - throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${sender}`); + throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`); + if (process.env.NODE_ENV == 'test') - message = `[Test:Environment to user ${sender}] ` + message; + message = `[Test:Environment to user ${userId}] ` + message; + const chat = await models.Chat.create({ senderFk: sender.id, recipient: `@${recipient.name}`, From cf856a585bba1be47c63e66794df6ffef4f5467a Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 23 Oct 2023 09:50:00 +0200 Subject: [PATCH 124/449] refs #6199 fix(sale_quantity): add isReduction --- modules/ticket/back/models/sale.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 1c86ddc0cc..cce6343ecf 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -33,6 +33,7 @@ module.exports = Self => { const itemId = changes?.itemFk || instance?.itemFk; const oldQuantity = instance?.quantity ?? null; const quantityAdded = newQuantity - oldQuantity; + const isReduction = oldQuantity && newQuantity <= oldQuantity; const ticket = await models.Ticket.findById( ticketId, @@ -81,7 +82,7 @@ module.exports = Self => { const [itemInfo] = await models.Sale.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); - if (!itemInfo?.available || itemInfo.available < quantityAdded) + if ((!isReduction && !itemInfo?.available) || itemInfo.available < quantityAdded) throw new UserError(`This item is not available`); if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; @@ -89,7 +90,7 @@ module.exports = Self => { if (newQuantity < item.minQuantity && newQuantity != itemInfo?.available) throw new UserError('The amount cannot be less than the minimum'); - if (ctx.isNewInstance || newQuantity <= oldQuantity) return; + if (ctx.isNewInstance || isReduction) return; const [saleGrouping] = await models.Sale.rawSql(` SELECT t.price newPrice From 247aa5af2a9a1ffd4ba829d1ecfe776ceb8feb48 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 23 Oct 2023 09:52:06 +0200 Subject: [PATCH 125/449] refs #6199 fix(sale_quantity): add isReduction --- modules/ticket/back/models/sale.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index cce6343ecf..99cfeeeea8 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -81,13 +81,14 @@ module.exports = Self => { ctx.options); const [itemInfo] = await models.Sale.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); + const available = itemInfo?.available; - if ((!isReduction && !itemInfo?.available) || itemInfo.available < quantityAdded) + if ((!isReduction && !available) || available < quantityAdded) throw new UserError(`This item is not available`); if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; - if (newQuantity < item.minQuantity && newQuantity != itemInfo?.available) + if (newQuantity < item.minQuantity && newQuantity != available) throw new UserError('The amount cannot be less than the minimum'); if (ctx.isNewInstance || isReduction) return; From ae27aa5b1e61c74bfbbc1b7b8af63642072acc6d Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 23 Oct 2023 10:08:26 +0200 Subject: [PATCH 126/449] fix: test to dev --- back/models/vn-user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index ccc60fe868..de5bf7b63e 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -1,6 +1,7 @@ const vnModel = require('vn-loopback/common/models/vn-model'); const {Email} = require('vn-print'); const ForbiddenError = require('vn-loopback/util/forbiddenError'); +const LoopBackContext = require('loopback-context'); module.exports = function(Self) { vnModel(Self); From 6e3517b40f3e3e0ae7162b10a4616622b93c25e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Mon, 23 Oct 2023 14:51:09 +0200 Subject: [PATCH 127/449] refs #4707 fix: problemas fichadas y test --- db/changes/234003/.gitkeep | 0 db/changes/234003/00-workerTimeControl.sql | 42 ++ .../234003/01-timeControl_calculate.sql | 194 ++++++ .../234003/02-workerTimeControl_clockIn.sql | 286 +++++++++ db/dump/fixtures.sql | 40 +- .../vn/timeControl_calculateByUser.spec.js | 91 --- db/tests/vn/workerTimeControlCheck.spec.js | 580 ------------------ .../specs/timeEntry.spec.js | 443 ++++++++----- 8 files changed, 844 insertions(+), 832 deletions(-) create mode 100644 db/changes/234003/.gitkeep create mode 100644 db/changes/234003/00-workerTimeControl.sql create mode 100644 db/changes/234003/01-timeControl_calculate.sql create mode 100644 db/changes/234003/02-workerTimeControl_clockIn.sql delete mode 100644 db/tests/vn/timeControl_calculateByUser.spec.js delete mode 100644 db/tests/vn/workerTimeControlCheck.spec.js diff --git a/db/changes/234003/.gitkeep b/db/changes/234003/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/db/changes/234003/00-workerTimeControl.sql b/db/changes/234003/00-workerTimeControl.sql new file mode 100644 index 0000000000..7b41278b0f --- /dev/null +++ b/db/changes/234003/00-workerTimeControl.sql @@ -0,0 +1,42 @@ +UPDATE `vn`.`workerTimeControlConfig` + SET `timeToBreakTime` = 18000; + +ALTER TABLE `vn`.`workerTimeControlConfig` + DROP COLUMN IF EXISTS `maxTimeToBreak`; +ALTER TABLE `vn`.`workerTimeControlConfig` + ADD COLUMN maxTimeToBreak INT DEFAULT 3600 NULL; + +ALTER TABLE `vn`.`workerTimeControlConfig` + DROP COLUMN IF EXISTS `maxWorkShortCycle`; + +ALTER TABLE `vn`.`workerTimeControlConfig` + ADD COLUMN `maxWorkShortCycle` INT(10) UNSIGNED DEFAULT 561600 + COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descando semanal corto'; + +ALTER TABLE `vn`.`workerTimeControlConfig` + DROP COLUMN IF EXISTS `maxWorkLongCycle`; + +ALTER TABLE `vn`.`workerTimeControlConfig` + ADD COLUMN `maxWorkLongCycle` INT(10) UNSIGNED DEFAULT 950400 + COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descando semanal largo'; + +CREATE TABLE IF NOT EXISTS `vn`.`workerTimeControlError` ( + `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `code` char(35) NOT NULL, + `description` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `code` (`code`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + + +INSERT IGNORE INTO `vn`.`workerTimeControlError` (`code`, `description`) + VALUES + ('IS_NOT_ALLOWED_FUTURE', 'No se permite fichar a futuro'), + ('INACTIVE_BUSINESS', 'No hay un contrato en vigor'), + ('IS_NOT_ALLOWED_WORK', 'No está permitido trabajar'), + ('ODD_WORKERTIMECONTROL', 'Fichadas impares'), + ('DAY_MAX_TIME', 'Superado el tiempo máximo entre entrada y salida'), + ('BREAK_DAY', 'Descanso diario'), + ('BREAK_WEEK', 'Descanso semanal'), + ('WRONG_DIRECTION', 'Dirección incorrecta'), + ('UNDEFINED_ERROR', 'Error sin definir'); \ No newline at end of file diff --git a/db/changes/234003/01-timeControl_calculate.sql b/db/changes/234003/01-timeControl_calculate.sql new file mode 100644 index 0000000000..93d88c0479 --- /dev/null +++ b/db/changes/234003/01-timeControl_calculate.sql @@ -0,0 +1,194 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`timeControl_calculate`( + vDatedFrom DATETIME, + vDatedTo DATETIME) +BEGIN +/* + * Agrupa por trabajador y día, el tiempo de trabajo y descanso retribuido(si tiene). + * Los registros horarios incorrectos (tmp.timeControlError) no se considerarán. + * Si un trabajador ha trabajado más de un cierto umbral de tiempo (vTimeToBreakTime) + * y no ha tenido descansos que superen un parámetro determinado(vMaxTimeToBreak), + * se le añadirá un tiempo de descanso (vBreakTime) a sus horas trabajadas. + * El tiempo de descanso solo se añade si el trabajador realmente disfrutó del descanso. + * Si disfrutó de menos tiempo de descanso, solo se añade el tiempo que disfrutó. + * + * @param vDatedFrom + * @param vDatedTo + * + * @return tmp.timeControlCalculate + * (workerFk, dated, timeWorkSeconds, timeWorkSexagesimal, timeWorkDecimal, timed) + */ + DECLARE vHourSeconds INTEGER; + DECLARE vDatedFromYesterday DATETIME; + DECLARE vDatedToTomorrow DATETIME; + DECLARE vTimeToBreakTime INT; + DECLARE vBreakTime INT; + DECLARE vMaxTimeToBreak INT; + + SELECT DATE_SUB(vDatedFrom, INTERVAL 1 DAY), DATE_ADD(vDatedTo, INTERVAL 1 DAY) + INTO vDatedFromYesterday, vDatedToTomorrow; + + SELECT timeToBreakTime, breakTime, maxTimeToBreak, TIME_TO_SEC('01:00:00') + INTO vTimeToBreakTime, vBreakTime, vMaxTimeToBreak, vHourSeconds + FROM workerTimeControlConfig + LIMIT 1; + + CALL timeControl_getError(vDatedFromYesterday, vDatedToTomorrow); + + CREATE OR REPLACE TEMPORARY TABLE tmp.workerTimeControl + (INDEX(userFk, timed), INDEX(timed), INDEX(direction)) + ENGINE = MEMORY + SELECT wtc.userFk, + wtc.timed, + DATE(wtc.timed) dated, + wtc.direction, + TRUE isReal + FROM workerTimeControl wtc + JOIN tmp.`user` u ON u.userFk = wtc.userFk + LEFT JOIN ( + SELECT wtc.userFk, MIN(wtc.timed) firstIn + FROM workerTimeControl wtc + JOIN tmp.`user` u ON u.userFk = wtc.userFk + LEFT JOIN tmp.timeControlError tce ON tce.id = wtc.id + WHERE wtc.timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + AND wtc.direction = 'in' + AND tce.id IS NULL + GROUP BY userFk + ) fi ON wtc.userFk = fi.userFk + LEFT JOIN ( + SELECT wtc.userFk, MAX(wtc.timed) lastOut + FROM workerTimeControl wtc + JOIN tmp.`user` u ON u.userFk = wtc.userFk + LEFT JOIN tmp.timeControlError tce ON tce.id = wtc.id + WHERE wtc.timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + AND wtc.direction = 'out' + AND tce.id IS NULL + GROUP BY userFk + ) lo ON wtc.userFk = lo.userFk + LEFT JOIN tmp.timeControlError tce ON tce.id = wtc.id + WHERE wtc.timed BETWEEN fi.firstIn AND lo.lastOut + AND tce.id IS NULL + ORDER BY wtc.userFk, wtc.timed; + + CREATE OR REPLACE TEMPORARY TABLE tmp.wtcToinsert + (INDEX(timed)) + ENGINE = MEMORY + WITH wtc AS( + SELECT timed, + userFk, + dated, + direction, + LEAD(dated) OVER + (PARTITION BY userFk, dated ORDER BY timed) nextDay, + LEAD(userFk) OVER + (PARTITION BY userFk ORDER BY timed) nextUserFk, + ROW_NUMBER() OVER (ORDER BY userFk, timed) MOD 2 isOdd + FROM tmp.workerTimeControl + WHERE timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + ORDER BY userFk, timed + ), wtcToinsert AS( + SELECT userFk, + dated, + IF(userFk = nextUserFk + AND nextDay IS NULL + AND isOdd + AND direction <> 'out', TRUE, FALSE) outNextDay, + IF(userFk = nextUserFk + AND nextDay IS NULL + AND NOT isOdd + AND direction <> 'out', TRUE, FALSE) outNextDayWhitBreak + FROM wtc + HAVING outNextDay OR outNextDayWhitBreak + )SELECT userFk, util.dayEnd(dated) timed, 'out' direction + FROM wtcToinsert + WHERE outNextDay + UNION ALL + SELECT userFk, dated + INTERVAL 1 DAY, 'in' + FROM wtcToinsert + WHERE outNextDay + UNION ALL + SELECT userFk, util.dayEnd(dated) - INTERVAL 1 SECOND, 'middle' + FROM wtcToinsert + WHERE outNextDayWhitBreak + UNION ALL + SELECT userFk, util.dayEnd(dated), 'out' + FROM wtcToinsert + WHERE outNextDayWhitBreak + UNION ALL + SELECT userFk, dated + INTERVAL 1 DAY, 'in' + FROM wtcToinsert + WHERE outNextDayWhitBreak + UNION ALL + SELECT userFk, dated + INTERVAL 1 DAY + INTERVAL 1 SECOND, 'middle' + FROM wtcToinsert + WHERE outNextDayWhitBreak; + + INSERT INTO tmp.workerTimeControl (userFk, timed, dated, direction, isReal) + SELECT userFk, timed, DATE(timed), direction, FALSE + FROM tmp.wtcToinsert; + + SET @accumulatedForBreakTime = 0; + SET @oldrealDay = NULL; + CREATE OR REPLACE TEMPORARY TABLE tmp.timeControlCalculate + WITH workerTimed AS ( + SELECT + userFk, + dated, + timed, + (direction ='in' AND isReal) breakPoint, + SUM(CASE WHEN (direction ='in' AND isReal) THEN TRUE ELSE FALSE END) + OVER (ORDER BY userFk, timed) AS realDay, + TIMESTAMPDIFF(SECOND, LAG(timed) + OVER (PARTITION BY userFk, dated ORDER BY timed), timed) gapTime, + ROW_NUMBER() + OVER (PARTITION BY userFk, dated ORDER BY timed) MOD 2 isOdd + FROM tmp.workerTimeControl + WHERE timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + ), accumulated AS ( + SELECT SUM(IF(isOdd, 0, gapTime)) + OVER (PARTITION BY userFk,dated ORDER BY userFk,timed) accumulatedWorkTime, + SUM(IF(NOT isOdd OR breakPoint, 0, IFNULL(gapTime, 0))) + OVER (PARTITION BY realDay ORDER BY realDay,timed) accumulatedBreakTime, + IF(realDay <> @oldrealDay OR (isOdd AND gapTime >= vMaxTimeToBreak), + @accumulatedForBreakTime := 0, + @accumulatedForBreakTime := @accumulatedForBreakTime + + IF(isOdd, 0, gapTime )) accumulatedForBreakTime, + @oldrealDay := realDay, + userFk, + dated, + realDay + FROM workerTimed + ), totalWorked AS ( + SELECT userFk, + dated, + MAX(accumulatedWorkTime) + + IF(MAX(accumulatedForBreakTime) >= vTimeToBreakTime, + LEAST(vBreakTime, MAX(accumulatedBreakTime)), + 0) timeWorkSeconds + FROM accumulated + GROUP BY userFk, dated + )SELECT tw.userFk, + tw.dated, + timeWorkSeconds, + SEC_TO_TIME(timeWorkSeconds) timeWorkSexagesimal, + timeWorkSeconds / vHourSeconds timeWorkDecimal, + sub.tableTimed + FROM totalWorked tw + JOIN ( + SELECT userFk, + dated, + GROUP_CONCAT(DATE_FORMAT(timed, "%H:%i") ORDER BY timed ASC + SEPARATOR ' - ')tableTimed + FROM tmp.workerTimeControl + WHERE timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + AND isReal + GROUP BY userFk, dated + )sub ON sub.dated = tw.dated + AND sub.userFk = tw.userFk + WHERE tw.dated BETWEEN vDatedFrom AND vDatedTo; + + DROP TEMPORARY TABLE tmp.timeControlError; + DROP TEMPORARY TABLE tmp.wtcToinsert; + DROP TEMPORARY TABLE tmp.workerTimeControl; +END$$ +DELIMITER ; \ No newline at end of file diff --git a/db/changes/234003/02-workerTimeControl_clockIn.sql b/db/changes/234003/02-workerTimeControl_clockIn.sql new file mode 100644 index 0000000000..7cc9e7831e --- /dev/null +++ b/db/changes/234003/02-workerTimeControl_clockIn.sql @@ -0,0 +1,286 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`workerTimeControl_clockIn`( + vWorkerFk INT, + vTimed DATETIME, + vDirection VARCHAR(10) +) +BEGIN +/** + * Verifica si el empleado puede fichar + * @param vWorkerFk Identificador del trabajador + * @param vTimed valor de la fichada, IF vTimed IS NULL vTimed = NOW + * @param vDirection solo se pueden pasa los valores del campo + * workerTimeControl.direction ENUM('in', 'out', 'middle') + * @return Si todo es correcto, retorna el número de id la tabla workerTimeControl. + * Si hay algún problema, devuelve el mesaje a que se debe mostrar al usuario + * Solo retorna el primer problema, en caso de no ocurrir ningún error se añadirá + * fichada a la tabla vn.workerTimeControl + */ + + DECLARE vLastIn DATETIME; + DECLARE vLastOut DATETIME; + DECLARE vNextIn DATETIME; + DECLARE vNextOut DATETIME; + DECLARE vNextDirection ENUM('in', 'out'); + DECLARE vLastDirection ENUM('in', 'out'); + DECLARE vDayMaxTime INTEGER; + DECLARE vDayBreak INT; + DECLARE vShortWeekBreak INT; + DECLARE vLongWeekBreak INT; + DECLARE vWeekScope INT; + DECLARE vMailTo VARCHAR(50) DEFAULT NULL; + DECLARE vUserName VARCHAR(50) DEFAULT NULL; + DECLARE vIsError BOOLEAN DEFAULT FALSE; + DECLARE vErrorMessage VARCHAR(255) DEFAULT NULL; + DECLARE vErrorCode VARCHAR(50); + DECLARE vDated DATE; + DECLARE vIsAllowedToWork VARCHAR(50); + DECLARE vIsManual BOOLEAN DEFAULT TRUE; + DECLARE vMaxWorkShortCycle INT; + DECLARE vMaxWorkLongCycle INT; + + DECLARE EXIT HANDLER FOR SQLSTATE '45000' + BEGIN + + SELECT CONCAT(u.name, '@verdnatura.es'), + CONCAT(w.firstName, ' ', w.lastName) + INTO vMailTo, vUserName + FROM account.user u + JOIN worker w ON w.bossFk = u.id + WHERE w.id = vWorkerFk; + + SELECT `description` INTO vErrorMessage + FROM workerTimeControlError + WHERE `code` = vErrorCode; + + IF vErrorMessage IS NULL THEN + SET vErrorMessage = 'Error sin definir'; + END IF; + + SELECT vErrorMessage `error`; + SELECT CONCAT(vUserName, + ' no ha podido fichar por el siguiente problema: ', + vErrorMessage) + INTO vErrorMessage; + + CALL mail_insert( vMailTo, vMailTo, 'Error al fichar', vErrorMessage); + END; + + IF (vTimed IS NULL) THEN + SET vTimed = util.VN_NOW(); + SET vIsManual = FALSE; + END IF; + + SET vDated = DATE(vTimed); + + SELECT IF(pc.name = 'Conductor +3500kg', + wc.dayBreakDriver, + wc.dayBreak), + wc.shortWeekBreak, + wc.longWeekBreak, + wc.weekScope, + wc.dayMaxTime, + wc.maxWorkShortCycle, + wc.maxWorkLongCycle + INTO vDayBreak, + vShortWeekBreak, + vLongWeekBreak, + vWeekScope, + vDayMaxTime, + vMaxWorkShortCycle, + vMaxWorkLongCycle + FROM business b + JOIN professionalCategory pc + ON pc.id = b.workerBusinessProfessionalCategoryFk + JOIN workerTimeControlConfig wc + WHERE b.workerFk = vWorkerFk + AND vDated BETWEEN b.started AND IFNULL(b.ended, vDated); + + -- CONTRATO EN VIGOR + IF vDayBreak IS NULL THEN + SET vErrorCode = 'INACTIVE_BUSINESS'; + CALL util.throw(vErrorCode); + END IF; + + -- FICHADAS A FUTURO + IF vTimed > util.VN_NOW() + INTERVAL 1 MINUTE THEN + SET vErrorCode = 'IS_NOT_ALLOWED_FUTURE'; + CALL util.throw(vErrorCode); + END IF; + + -- VERIFICAR SI ESTÁ PERMITIDO TRABAJAR + CALL timeBusiness_calculateByWorker(vWorkerFk, vDated, vDated); + SELECT isAllowedToWork INTO vIsAllowedToWork + FROM tmp.timeBusinessCalculate; + DROP TEMPORARY TABLE tmp.timeBusinessCalculate; + + IF NOT vIsAllowedToWork THEN + SET vErrorCode = 'IS_NOT_ALLOWED_WORK'; + CALL util.throw(vErrorCode); + END IF; + + -- DIRECCION CORRECTA + CALL workerTimeControl_direction(vWorkerFk, vTimed); + IF (SELECT + IF(IF(option1 IN ('inMiddle', 'outMiddle'), + 'middle', + option1) <> vDirection + AND IF(option2 IN ('inMiddle', 'outMiddle'), + 'middle', + IFNULL(option2, '')) <> vDirection, + TRUE , + FALSE) + FROM tmp.workerTimeControlDirection + ) THEN + SET vIsError = TRUE; + END IF; + + DROP TEMPORARY TABLE tmp.workerTimeControlDirection; + IF vIsError THEN + SET vErrorCode = 'WRONG_DIRECTION'; + CALL util.throw(vErrorCode); + END IF; + + -- FICHADAS IMPARES + SELECT timed INTO vLastIn + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction = 'in' + AND timed < vTimed + ORDER BY timed DESC + LIMIT 1; + + IF (SELECT IF(vDirection = 'in', + MOD(COUNT(*), 2) , + IF (vDirection = 'out', NOT MOD(COUNT(*), 2), FALSE)) + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND timed BETWEEN vLastIn AND vTimed + ) THEN + SET vErrorCode = 'ODD_WORKERTIMECONTROL'; + CALL util.throw(vErrorCode); + END IF; + + -- DESCANSO DIARIO + SELECT timed INTO vLastOut + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction = 'out' + AND timed < vTimed + ORDER BY timed DESC + LIMIT 1; + + SELECT timed INTO vNextIn + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction = 'in' + AND timed > vTimed + ORDER BY timed ASC + LIMIT 1; + + CASE vDirection + WHEN 'in' THEN + IF UNIX_TIMESTAMP(vTimed) - UNIX_TIMESTAMP(vLastOut) <= vDayBreak THEN + SET vIsError = TRUE; + END IF; + WHEN 'out' THEN + IF UNIX_TIMESTAMP(vNextIn) - UNIX_TIMESTAMP(vTimed) <= vDayBreak THEN + SET vIsError = TRUE; + END IF; + ELSE BEGIN END; + END CASE; + + IF vIsError THEN + SET vErrorCode = 'BREAK_DAY'; + CALL util.throw(vErrorCode); + END IF; + + + + IF (vDirection IN('in', 'out')) THEN + -- VERIFICA MAXIMO TIEMPO DESDE ENTRADA HASTA LA SALIDA + + SELECT timed INTO vNextOut + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction = 'out' + AND timed > vTimed + ORDER BY timed ASC + LIMIT 1; + + SELECT direction INTO vNextDirection + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction IN('in','out') + AND timed > vTimed + ORDER BY timed ASC + LIMIT 1; + + SELECT direction INTO vLastDirection + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction IN('in', 'out') + AND timed < vTimed + ORDER BY timed ASC + LIMIT 1; + + IF (vDirection ='in' + AND vNextDirection = 'out' + AND UNIX_TIMESTAMP(vNextOut) - UNIX_TIMESTAMP(vTimed) > vDayMaxTime) OR + (vDirection ='out' + AND vLastDirection = 'in' + AND UNIX_TIMESTAMP(vTimed) -UNIX_TIMESTAMP(vLastIn) > vDayMaxTime) THEN + SET vErrorCode = 'DAY_MAX_TIME'; + CALL util.throw(vErrorCode); + END IF; + + -- VERIFICA DESCANSO SEMANAL + + WITH wtc AS( + (SELECT timed + FROM vn.workerTimeControl + WHERE userFk = vWorkerFk + AND direction IN ('in', 'out') + AND timed BETWEEN vTimed - INTERVAL (vWeekScope * 2) SECOND + AND vTimed + INTERVAL (vWeekScope * 2) SECOND ) + UNION + (SELECT vTimed) + ), wtcGap AS( + SELECT timed, + TIMESTAMPDIFF(SECOND, LAG(timed) OVER (ORDER BY timed), timed) gap + FROM wtc + ORDER BY timed + ), wtcBreak AS( + SELECT timed, + IF(IFNULL(gap, 0) > vShortWeekBreak, TRUE, FALSE) hasShortBreak, + IF(IFNULL(gap, 0) > vLongWeekBreak, TRUE, FALSE) hasLongBreak + FROM wtcGap + ORDER BY timed + ), wtcBreakCounter AS( + SELECT timed, + SUM(hasShortBreak) OVER (ORDER BY timed) breakCounter , + LEAD(hasLongBreak) OVER (ORDER BY timed) nextHasLongBreak + FROM wtcBreak + )SELECT TIMESTAMPDIFF(SECOND, MIN(timed), MAX(timed)) > vMaxWorkLongCycle OR + (TIMESTAMPDIFF(SECOND, MIN(timed), MAX(timed))> vMaxWorkShortCycle + AND NOT SUM(IFNULL(nextHasLongBreak, 1))) + hasError INTO vIsError + FROM wtcBreakCounter + GROUP BY breakCounter + HAVING hasError + LIMIT 1; + + IF vIsError THEN + SET vErrorCode = 'BREAK_WEEK'; + CALL util.throw(vErrorCode); + END IF; + END IF; + + -- SE PERMITE FICHAR + INSERT INTO workerTimeControl(userFk, timed, direction, `manual`) + VALUES(vWorkerFk, vTimed, vDirection, vIsManual); + + SELECT LAST_INSERT_ID() id; + +END$$ +DELIMITER ; \ No newline at end of file diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index ab76155916..ee13234fae 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2003,6 +2003,10 @@ UPDATE `vn`.`business` b SET b.`departmentFk` = 43 WHERE b.id IN(18, 19); +UPDATE `vn`.`business` b + SET b.`started` = b.`started` - INTERVAL 100 DAY + WHERE b.id = 1107; + INSERT INTO `vn`.`workCenterHoliday` (`workCenterFk`, `days`, `year`) VALUES ('1', '27.5', YEAR(util.VN_CURDATE())), @@ -2051,22 +2055,22 @@ INSERT INTO `vn`.`absenceType` (`id`, `name`, `rgb`, `code`, `holidayEntitlement INSERT INTO `vn`.`calendar` (`businessFk`, `dayOffTypeFk`, `dated`) VALUES - (1, 6, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -10 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 10 DAY))), - (1106, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -10 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 10 DAY))), - (1106, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -11 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 11 DAY))), - (1106, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -12 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 12 DAY))), - (1106, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -20 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 20 DAY))), - (1106, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -13 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 8 DAY))), - (1106, 1, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -14 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 9 DAY))), - (1106, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -15 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 7 DAY))), - (1107, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -10 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 10 DAY))), - (1107, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -11 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 11 DAY))), - (1107, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -12 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 12 DAY))), - (1107, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, DATE_ADD(util.VN_CURDATE(), INTERVAL -20 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 20 DAY))), - (1107, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -13 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 8 DAY))), - (1107, 1, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -14 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 9 DAY))), - (1107, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, DATE_ADD(util.VN_CURDATE(), INTERVAL -15 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL 7 DAY))), - (1107, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL - 16 DAY)); + (1, 6, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, util.VN_CURDATE() - INTERVAL 10 DAY, util.VN_CURDATE() + INTERVAL 10 DAY)), + (1106, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, util.VN_CURDATE() - INTERVAL 10 DAY, util.VN_CURDATE() + INTERVAL 10 DAY)), + (1106, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, util.VN_CURDATE() - INTERVAL 11 DAY, util.VN_CURDATE() + INTERVAL 11 DAY)), + (1106, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, util.VN_CURDATE() - INTERVAL 12 DAY, util.VN_CURDATE() + INTERVAL 12 DAY)), + (1106, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, util.VN_CURDATE() - INTERVAL 20 DAY, util.VN_CURDATE() + INTERVAL 20 DAY)), + (1106, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, util.VN_CURDATE() - INTERVAL 13 DAY, util.VN_CURDATE() + INTERVAL 8 DAY)), + (1106, 1, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, util.VN_CURDATE() - INTERVAL 14 DAY, util.VN_CURDATE() + INTERVAL 9 DAY)), + (1106, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, util.VN_CURDATE() - INTERVAL 15 DAY, util.VN_CURDATE() + INTERVAL 7 DAY)), + (1107, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, util.VN_CURDATE() - INTERVAL 10 DAY, util.VN_CURDATE() + INTERVAL 10 DAY)), + (1107, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, util.VN_CURDATE() - INTERVAL 11 DAY, util.VN_CURDATE() + INTERVAL 11 DAY)), + (1107, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, util.VN_CURDATE() - INTERVAL 12 DAY, util.VN_CURDATE() + INTERVAL 12 DAY)), + (1107, 1, IF(MONTH(util.VN_CURDATE()) = 12 AND DAY(util.VN_CURDATE()) > 10, util.VN_CURDATE() - INTERVAL 20 DAY, util.VN_CURDATE() + INTERVAL 20 DAY)), + (1107, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, util.VN_CURDATE() - INTERVAL 13 DAY, util.VN_CURDATE() + INTERVAL 8 DAY)), + (1107, 1, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, util.VN_CURDATE() - INTERVAL 14 DAY, util.VN_CURDATE() + INTERVAL 9 DAY)), + (1107, 2, IF(MONTH(util.VN_CURDATE()) >= 1 AND DAY(util.VN_CURDATE()) > 20, util.VN_CURDATE() - INTERVAL 15 DAY, util.VN_CURDATE() + INTERVAL 7 DAY)), + (1107, 2, util.VN_CURDATE() - INTERVAL 16 DAY); INSERT INTO `vn`.`smsConfig` (`id`, `uri`, `title`, `apiKey`) VALUES @@ -2754,9 +2758,9 @@ INSERT INTO `vn`.`sectorCollectionSaleGroup` (`sectorCollectionFk`, `saleGroupFk VALUES (1, 1); -INSERT INTO `vn`.`workerTimeControlConfig` (`id`, `dayBreak`, `dayBreakDriver`, `shortWeekBreak`, `longWeekBreak`, `weekScope`, `mailPass`, `mailHost`, `mailSuccessFolder`, `mailErrorFolder`, `mailUser`, `minHoursToBreak`, `breakHours`, `hoursCompleteWeek`, `startNightlyHours`, `endNightlyHours`, `maxTimePerDay`, `breakTime`, `timeToBreakTime`, `dayMaxTime`, `shortWeekDays`, `longWeekDays`, `teleworkingStart`, `teleworkingStartBreakTime`) +INSERT INTO `vn`.`workerTimeControlConfig` (`id`, `dayBreak`, `dayBreakDriver`, `shortWeekBreak`, `longWeekBreak`, `weekScope`, `mailPass`, `mailHost`, `mailSuccessFolder`, `mailErrorFolder`, `mailUser`, `minHoursToBreak`, `breakHours`, `hoursCompleteWeek`, `startNightlyHours`, `endNightlyHours`, `maxTimePerDay`, `breakTime`, `timeToBreakTime`, `dayMaxTime`, `shortWeekDays`, `longWeekDays`, `teleworkingStart`, `teleworkingStartBreakTime`, `maxTimeToBreak`, `maxWorkShortCycle`, `maxWorkLongCycle`) VALUES - (1, 43200, 32400, 129600, 259200, 604800, '', '', 'Leidos.exito', 'Leidos.error', 'timeControl', 5.33, 0.33, 40, '22:00:00', '06:00:00', 57600, 1200, 18000, 57600, 6, 13, 28800, 32400); + (1, 43200, 32400, 129600, 259200, 1080000, '', 'imap.verdnatura.es', 'Leidos.exito', 'Leidos.error', 'timeControl', 5.00, 0.33, 40, '22:00:00', '06:00:00', 72000, 1200, 18000, 72000, 6, 13, 28800, 32400, 3600, 561600, 950400); INSERT INTO `vn`.`host` (`id`, `code`, `description`, `warehouseFk`, `bankFk`) VALUES diff --git a/db/tests/vn/timeControl_calculateByUser.spec.js b/db/tests/vn/timeControl_calculateByUser.spec.js deleted file mode 100644 index 0b385d2c9f..0000000000 --- a/db/tests/vn/timeControl_calculateByUser.spec.js +++ /dev/null @@ -1,91 +0,0 @@ -const app = require('vn-loopback/server/server'); -const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; - -describe('timeControl_calculateByUser()', () => { - it(`should return today's worked hours`, async() => { - let start = Date.vnNew(); - start.setHours(0, 0, 0, 0); - start.setDate(start.getDate() - 1); - - let end = Date.vnNew(); - end.setHours(0, 0, 0, 0); - end.setDate(end.getDate() + 1); - - let stmts = []; - let stmt; - - let params = { - workerID: 1106, - start: start, - end: end - }; - - stmt = new ParameterizedSQL('CALL vn.timeControl_calculateByUser(?, ?, ?)', [ - params.workerID, - params.start, - params.end - ]); - stmts.push(stmt); - - let tableIndex = stmts.push('SELECT * FROM tmp.timeControlCalculate') - 1; - - let sql = ParameterizedSQL.join(stmts, ';'); - let result = await app.models.Ticket.rawStmt(sql); - - let [timeControlCalculateTable] = result[tableIndex]; - - expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28200); - }); - // #2261 - xit(`should return the worked hours between last sunday and monday`, async() => { - let lastSunday = Date.vnNew(); - let daysSinceSunday = lastSunday.getDay(); - if (daysSinceSunday === 0) // this means today is sunday but you need the previous sunday :) - daysSinceSunday = 7; - lastSunday.setHours(23, 0, 0, 0); - lastSunday.setDate(lastSunday.getDate() - daysSinceSunday); - - let monday = Date.vnNew(); - let daysSinceMonday = daysSinceSunday - 1; // aiming for monday (today could be monday) - monday.setHours(7, 0, 0, 0); - monday.setDate(monday.getDate() - daysSinceMonday); - - let stmts = []; - let stmt; - - stmts.push('START TRANSACTION'); - - const workerID = 1108; - - stmt = new ParameterizedSQL(` - INSERT INTO vn.workerTimeControl(userFk, timed, manual, direction) - VALUES - (?, ?, 1, 'in'), - (?, ?, 1, 'out') - `, [ - workerID, - lastSunday, - workerID, - monday - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.timeControl_calculateByUser(?, ?, ?)', [ - workerID, - lastSunday, - monday - ]); - stmts.push(stmt); - - let tableIndex = stmts.push('SELECT * FROM tmp.timeControlCalculate') - 1; - - stmts.push('ROLLBACK'); - - let sql = ParameterizedSQL.join(stmts, ';'); - let result = await app.models.Ticket.rawStmt(sql); - - let [timeControlCalculateTable] = result[tableIndex]; - - expect(timeControlCalculateTable.timeWorkSeconds).toEqual(30000); - }); -}); diff --git a/db/tests/vn/workerTimeControlCheck.spec.js b/db/tests/vn/workerTimeControlCheck.spec.js deleted file mode 100644 index 0ca1429d4a..0000000000 --- a/db/tests/vn/workerTimeControlCheck.spec.js +++ /dev/null @@ -1,580 +0,0 @@ -const app = require('vn-loopback/server/server'); -const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; - -// #2261 xdescribe dbtest workerTimeControl_check() -xdescribe('worker workerTimeControl_check()', () => { - it(`should throw an error if the worker can't sign on that tablet`, async() => { - let stmts = []; - let stmt; - const workerId = 1110; - const tabletId = 2; - let err; - stmts.push('START TRANSACTION'); - try { - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - - stmts.push('ROLLBACK'); - - let sql = ParameterizedSQL.join(stmts, ';'); - await app.models.Worker.rawStmt(sql); - } catch (e) { - err = e; - } - - expect(err.sqlMessage).toEqual('No perteneces a este departamento.'); - }); - - it('should check that the worker can sign on that tablet', async() => { - let stmts = []; - let stmt; - const workerId = 1110; - const tabletId = 1; - let err; - stmts.push('START TRANSACTION'); - try { - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - - stmts.push('ROLLBACK'); - - let sql = ParameterizedSQL.join(stmts, ';'); - await app.models.Worker.rawStmt(sql); - } catch (e) { - err = e; - } - - expect(err).not.toBeDefined(); - }); - - it('should throw an error if the worker with a special category has not finished the 9h break', async() => { - const workerId = 1110; - const tabletId = 1; - let stmts = []; - let stmt; - let sql; - let error; - - stmts.push('START TRANSACTION'); - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-17,NOW()),0,"in"), - (?,TIMESTAMPADD(SECOND,-32399,NOW()),0,"out")`, [ - workerId, - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - stmts.push('ROLLBACK'); - sql = ParameterizedSQL.join(stmts, ';'); - - try { - await app.models.Worker.rawStmt(sql); - } catch (e) { - await app.models.Worker.rawSql('ROLLBACK'); - error = e; - } - - expect(error.sqlMessage).toEqual('Descansos 9 h'); - }); - - it('should check f the worker with a special category has finished the 9h break', async() => { - const workerId = 1110; - const tabletId = 1; - let stmts = []; - let stmt; - let err; - stmts.push('START TRANSACTION'); - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-17,NOW()),0,"in"), - (?,TIMESTAMPADD(SECOND,-32401,NOW()),0,"out")`, [ - workerId, - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - stmts.push('ROLLBACK'); - - let sql = ParameterizedSQL.join(stmts, ';'); - - try { - await app.models.Worker.rawStmt(sql); - } catch (e) { - await app.models.Worker.rawSql('ROLLBACK'); - err = e; - } - - expect(err).not.toBeDefined(); - }); - - it('should throw an error if the worker has not finished the 12h break', async() => { - const workerId = 1109; - const tabletId = 1; - let stmts = []; - let stmt; - let sql; - let error; - - stmts.push('START TRANSACTION'); - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-20,NOW()),0,"in"), - (?,TIMESTAMPADD(SECOND,-43199,NOW()),0,"out")`, [ - workerId, - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - stmts.push('ROLLBACK'); - sql = ParameterizedSQL.join(stmts, ';'); - - try { - await app.models.Worker.rawStmt(sql); - } catch (e) { - await app.models.Worker.rawSql('ROLLBACK'); - error = e; - } - - expect(error.sqlMessage).toEqual('Descansos 12 h'); - }); - - it('should throw an error if the worker has finished the 12h break', async() => { - const workerId = 1109; - const tabletId = 1; - let stmts = []; - let stmt; - let err; - stmts.push('START TRANSACTION'); - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-20,NOW()),0,"in"), - (?,TIMESTAMPADD(SECOND,-43201,NOW()),0,"out")`, [ - workerId, - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - stmts.push('ROLLBACK'); - - let sql = ParameterizedSQL.join(stmts, ';'); - - try { - await app.models.Worker.rawStmt(sql); - } catch (e) { - await app.models.Worker.rawSql('ROLLBACK'); - err = e; - } - - expect(err).not.toBeDefined(); - }); - - it('should throw an error if the worker has odd entry records', async() => { - const workerId = 1109; - const tabletId = 1; - let stmts = []; - let stmt; - let err; - stmts.push('START TRANSACTION'); - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-24,NOW()),0,"in")`, [ - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - stmts.push('ROLLBACK'); - - let sql = ParameterizedSQL.join(stmts, ';'); - - try { - await app.models.Worker.rawStmt(sql); - } catch (e) { - await app.models.Worker.rawSql('ROLLBACK'); - err = e; - } - - expect(err.sqlMessage).toEqual('Dias con fichadas impares'); - }); - - it('should throw an error if the worker try to sign on a holiday day', async() => { - const workerId = 1109; - const tabletId = 1; - let stmts = []; - let stmt; - let err; - - stmts.push('START TRANSACTION'); - - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-24,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-20,NOW()),0,"out")`, [ - workerId, - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - stmts.push('ROLLBACK'); - - let sql = ParameterizedSQL.join(stmts, ';'); - - try { - await app.models.Worker.rawStmt(sql); - } catch (e) { - await app.models.Worker.rawSql('ROLLBACK'); - err = e; - } - - expect(err.sqlMessage).toEqual('Holidays'); - }); - - it('should throw an error if the worker try to sign with your contract ended', async() => { - const workerId = 1109; - const tabletId = 1; - let stmts = []; - let stmt; - let err; - - stmts.push('START TRANSACTION'); - - stmt = new ParameterizedSQL(`UPDATE vn.business SET ended = DATE_ADD(CURDATE(), INTERVAL -1 DAY) WHERE id = ?`, [ - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-24,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-20,NOW()),0,"out")`, [ - workerId, - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - stmts.push('ROLLBACK'); - - let sql = ParameterizedSQL.join(stmts, ';'); - - try { - await app.models.Worker.rawStmt(sql); - } catch (e) { - await app.models.Worker.rawSql('ROLLBACK'); - err = e; - } - - expect(err.sqlMessage).toEqual('No hay un contrato en vigor'); - }); - - it('should throw an error if the worker has not finished the 36h weekly break', async() => { - const workerId = 1109; - const tabletId = 1; - let stmts = []; - let stmt; - - stmts.push('SET @warn := NULL'); - - stmts.push('START TRANSACTION'); - - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-24,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-16,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-48,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-40,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-72,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-64,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-96,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-88,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-120,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-112,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-144,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-136,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-168,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-160,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-192,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-184,NOW()),0,"out")`, [ - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - - let warningMessageIndex = stmts.push('SELECT @warn AS warning') - 1; - stmts.push('ROLLBACK'); - let sql = ParameterizedSQL.join(stmts, ';'); - let result = await app.models.Worker.rawStmt(sql); - - expect(result[warningMessageIndex][0].warning).toEqual('Descansos 36 h'); - }); - - it('should check if the worker has finished the 36h weekly break', async() => { - const workerId = 1109; - const tabletId = 1; - let stmts = []; - let stmt; - - stmts.push('SET @warn := NULL'); - - stmts.push('START TRANSACTION'); - - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-24,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-16,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-48,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-40,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-72,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-64,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-96,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-88,NOW()),0,"out")`, [ - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - stmts.push('ROLLBACK'); - - let warningMessageIndex = stmts.push('SELECT @warn AS warning') - 1; - - let sql = ParameterizedSQL.join(stmts, ';'); - let result = await app.models.Worker.rawStmt(sql); - - expect(result[warningMessageIndex][0].warning).toBe(null); - }); - - it('should throw an error if the worker has not finished the 72h biweekly break', async() => { - const workerId = 1109; - const tabletId = 1; - let stmts = []; - let stmt; - let err; - stmts.push('START TRANSACTION'); - - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-24,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-16,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-48,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-40,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-72,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-64,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-96,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-88,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-120,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-112,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-144,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-136,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-168,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-160,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-192,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-184,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-216,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-208,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-240,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-232,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-264,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-256,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-289,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-280,NOW()),0,"out")`, [ - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - stmts.push('ROLLBACK'); - - stmts.push('SELECT @warn AS warning') - 1; - - let sql = ParameterizedSQL.join(stmts, ';'); - - try { - await app.models.Worker.rawStmt(sql); - } catch (e) { - await app.models.Worker.rawSql('ROLLBACK'); - err = e; - } - - expect(err.sqlMessage).toEqual('Descansos 72 h'); - }); - - it('should check if the worker has finished the 72h biweekly break', async() => { - const workerId = 1109; - const tabletId = 1; - let stmts = []; - let stmt; - let err; - stmts.push('START TRANSACTION'); - - stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction) - VALUES - (?,TIMESTAMPADD(HOUR,-24,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-16,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-48,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-40,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-72,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-64,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-96,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-88,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-120,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-112,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-144,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-136,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-168,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-160,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-192,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-184,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-216,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-208,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-240,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-232,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-264,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-256,NOW()),0,"out"), - (?,TIMESTAMPADD(HOUR,-288,NOW()),0,"in"), - (?,TIMESTAMPADD(HOUR,-280,NOW()),0,"out")`, [ - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId, - workerId - ]); - stmts.push(stmt); - - stmt = new ParameterizedSQL('CALL vn.workerTimeControl_check(?, ?, NULL)', [ - workerId, - tabletId - ]); - stmts.push(stmt); - stmts.push('ROLLBACK'); - - stmts.push('SELECT @warn AS warning') - 1; - - let sql = ParameterizedSQL.join(stmts, ';'); - - try { - await app.models.Worker.rawStmt(sql); - } catch (e) { - await app.models.Worker.rawSql('ROLLBACK'); - err = e; - } - - expect(err).not.toBeDefined(); - }); -}); diff --git a/modules/worker/back/methods/worker-time-control/specs/timeEntry.spec.js b/modules/worker/back/methods/worker-time-control/specs/timeEntry.spec.js index e90c849b78..42ec6290a2 100644 --- a/modules/worker/back/methods/worker-time-control/specs/timeEntry.spec.js +++ b/modules/worker/back/methods/worker-time-control/specs/timeEntry.spec.js @@ -14,7 +14,6 @@ describe('workerTimeControl add/delete timeEntry()', () => { const tuesday = 2; const thursday = 4; const friday = 5; - const saturday = 6; const sunday = 7; const activeCtx = { accessToken: {userId: 50}, @@ -200,15 +199,15 @@ describe('workerTimeControl add/delete timeEntry()', () => { }); describe('WorkerTimeControl_clockIn calls', () => { - it('should fail to add a time entry if the target user has an absence that day', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); + let workerId; + beforeEach(() => { activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; + workerId = hankPymId; + }); + it('should fail to add a time entry if the target user has an absence that day', async() => { const date = Date.vnNew(); - date.setDate(date.getDate() - 16); date.setHours(8, 0, 0); - let error; - + date.setDate(date.getDate() - 16); const tx = await models.WorkerTimeControl.beginTransaction({}); const options = {transaction: tx}; try { @@ -225,15 +224,12 @@ describe('workerTimeControl add/delete timeEntry()', () => { }); it('should fail to add a time entry for a worker without an existing contract', async() => { - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; const date = Date.vnNew(); date.setFullYear(date.getFullYear() - 2); - let error; const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; try { - const options = {transaction: tx}; ctx.args = {timed: date, direction: 'in'}; await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); @@ -246,19 +242,39 @@ describe('workerTimeControl add/delete timeEntry()', () => { expect(error.message).toBe(`No hay un contrato en vigor`); }); + it('should fail to add a time entry for a worker without an existing contract', async() => { + let date = Date.vnNew(); + date.setDate(date.getDate() - 2); + let error; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + date.setHours(0, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date.setHours(20,0, 1); + ctx.args = {timed: date, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Superado el tiempo máximo entre entrada y salida`); + }); + describe('direction errors', () => { + let date = Date.vnNew(); + date.setDate(date.getDate() - 1); + let error; it('should throw an error when trying "in" direction twice', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; - - let date = Date.vnNew(); - date.setDate(date.getDate() - 21); - date = weekDay(date, monday); - let error; - const tx = await models.WorkerTimeControl.beginTransaction({}); const options = {transaction: tx}; + date.setHours(8, 0, 0); ctx.args = {timed: date, direction: 'in'}; await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); @@ -278,21 +294,13 @@ describe('workerTimeControl add/delete timeEntry()', () => { }); it('should throw an error when trying "in" direction after insert "in" and "middle"', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; - - let date = Date.vnNew(); - date.setDate(date.getDate() - 21); - date = weekDay(date, monday); - let error; - const tx = await models.WorkerTimeControl.beginTransaction({}); const options = {transaction: tx}; date.setHours(8, 0, 0); ctx.args = {timed: date, direction: 'in'}; await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + date.setHours(9, 0, 0); ctx.args = {timed: date, direction: 'middle'}; await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); @@ -312,15 +320,6 @@ describe('workerTimeControl add/delete timeEntry()', () => { }); it('Should throw an error when trying "out" before closing a "middle" couple', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; - - let date = Date.vnNew(); - date.setDate(date.getDate() - 21); - date = weekDay(date, monday); - let error; - const tx = await models.WorkerTimeControl.beginTransaction({}); const options = {transaction: tx}; @@ -346,15 +345,6 @@ describe('workerTimeControl add/delete timeEntry()', () => { }); it('should throw an error when trying "middle" after "out"', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; - - let date = Date.vnNew(); - date.setDate(date.getDate() - 21); - date = weekDay(date, monday); - let error; - const tx = await models.WorkerTimeControl.beginTransaction({}); const options = {transaction: tx}; @@ -380,15 +370,6 @@ describe('workerTimeControl add/delete timeEntry()', () => { }); it('should throw an error when trying "out" direction twice', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; - - let date = Date.vnNew(); - date.setDate(date.getDate() - 21); - date = weekDay(date, monday); - let error; - const tx = await models.WorkerTimeControl.beginTransaction({}); const options = {transaction: tx}; @@ -415,14 +396,12 @@ describe('workerTimeControl add/delete timeEntry()', () => { }); describe('12h rest', () => { + activeCtx.accessToken.userId = salesBossId; + const workerId = hankPymId; it('should throw an error when the 12h rest is not fulfilled yet', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; let date = Date.vnNew(); - date.setDate(date.getDate() - 21); + date.setDate(date.getDate() - 2); date = weekDay(date, monday); let error; @@ -448,16 +427,12 @@ describe('workerTimeControl add/delete timeEntry()', () => { error = e; } - expect(error.message).toBe(`Descanso diario 12h.`); + expect(error.message).toBe(`Descanso diario`); }); it('should not fail as the 12h rest is fulfilled', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; - let date = Date.vnNew(); - date.setDate(date.getDate() - 21); + date.setDate(date.getDate() - 2); date = weekDay(date, monday); let error; @@ -488,13 +463,12 @@ describe('workerTimeControl add/delete timeEntry()', () => { }); describe('for 3500kg drivers with enforced 9h rest', () => { + activeCtx.accessToken.userId = salesBossId; + const workerId = jessicaJonesId; it('should throw an error when the 9h enforced rest is not fulfilled', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = jessicaJonesId; let date = Date.vnNew(); - date.setDate(date.getDate() - 21); + date.setDate(date.getDate() - 2); date = weekDay(date, monday); let error; @@ -520,16 +494,13 @@ describe('workerTimeControl add/delete timeEntry()', () => { error = e; } - expect(error.message).toBe(`Descanso diario 9h.`); + expect(error.message).toBe(`Descanso diario`); }); it('should not fail when the 9h enforced rest is fulfilled', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = jessicaJonesId; - + let date = Date.vnNew(); - date.setDate(date.getDate() - 21); + date.setDate(date.getDate() - 2); date = weekDay(date, monday); let error; @@ -559,14 +530,11 @@ describe('workerTimeControl add/delete timeEntry()', () => { }); }); - describe('for 36h weekly rest', () => { - it('should throw an error when the 36h weekly rest is not fulfilled', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; - + describe('for 72h weekly rest', () => { + + it('should throw an error when work 11 consecutive days', async() => { let date = Date.vnNew(); - date.setMonth(date.getMonth() - 2); + date.setMonth(date.getMonth() - 1); date.setDate(1); let error; @@ -576,66 +544,24 @@ describe('workerTimeControl add/delete timeEntry()', () => { await populateWeek(date, monday, sunday, ctx, workerId, options); date = nextWeek(date); await populateWeek(date, monday, thursday, ctx, workerId, options); - date = weekDay(date, friday); - date.setHours(7, 59, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - try { - date.setHours(8, 1, 0); - ctx.args = {timed: date, direction: 'out'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Descanso semanal 36h. / 72h.`); - }); - - it('should throw an error when the 36h weekly rest is not fulfilled again', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; - - let date = Date.vnNew(); - date.setMonth(date.getMonth() - 2); - date.setDate(1); - let error; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - await populateWeek(date, monday, sunday, ctx, workerId, options); - date = nextWeek(date); - await populateWeek(date, monday, thursday, ctx, workerId, options); - - try { - date = weekDay(date, saturday); - date.setHours(3, 59, 0); + date = weekDay(date, friday); + date.setHours(10, 0, 1); ctx.args = {timed: date, direction: 'in'}; await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - await tx.rollback(); } catch (e) { await tx.rollback(); error = e; } - expect(error.message).toBe(`Descanso semanal 36h. / 72h.`); + expect(error.message).toBe(`Descanso semanal`); }); - }); - describe('for 72h weekly rest', () => { - it('should throw when the 72h weekly rest is not fulfilled yet', async() => { - pending('https://redmine.verdnatura.es/issues/4707'); - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; + it('should throw an error when the 72h weekly rest is not fulfilled', async() => { let date = Date.vnNew(); - date.setMonth(date.getMonth() - 2); + date.setMonth(date.getMonth() - 1); date.setDate(1); let error; @@ -645,32 +571,263 @@ describe('workerTimeControl add/delete timeEntry()', () => { await populateWeek(date, monday, sunday, ctx, workerId, options); date = nextWeek(date); await populateWeek(date, monday, thursday, ctx, workerId, options); - date = nextWeek(date); - await populateWeek(date, monday, friday, ctx, workerId, options); - date = nextWeek(date); - await populateWeek(date, monday, saturday, ctx, workerId, options); - date = nextWeek(date); - await populateWeek(date, monday, saturday, ctx, workerId, options); - date = lastWeek(date); try { date = weekDay(date, sunday); - date.setHours(8, 0, 0); + date.setHours(17, 59, 0); ctx.args = {timed: date, direction: 'in'}; await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - await tx.rollback(); } catch (e) { await tx.rollback(); error = e; } - expect(error.message).toBe(`Descanso semanal 36h. / 72h.`); + expect(error.message).toBe(`Descanso semanal`); + }); + + it('should throw an error when the 72h weekly rest is fulfilled', async() => { + + let date = Date.vnNew(); + date.setMonth(date.getMonth() - 1); + date.setDate(1); + let error; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + await populateWeek(date, monday, sunday, ctx, workerId, options); + date = nextWeek(date); + await populateWeek(date, monday, thursday, ctx, workerId, options); + + try { + date = weekDay(date, sunday); + date.setHours(18, 00, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).not.toBeDefined; + }); + }); + + describe('WorkerTimeControl_calculate calls', () => { + let dated = Date.vnNew(); + dated.setDate(dated.getDate() - 7); + dated = new Date(weekDay(dated, monday)); + const end = new Date(dated); + end.setDate(end.getDate() + 1); + + it(`should return today's worked 8 hours without break`, async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + try { + await populateWeek(dated, monday, monday, ctx, hankPymId, options); + const start = new Date(dated - 1); + start.setHours(0, 0, 0); + await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [ + hankPymId, + start, + end + ], options); + + let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options); + + expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28800); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it(`should return today's worked hours with 15min break and work time consecutive less than 5h`, async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + try { + await populateWeek(dated, monday, monday, ctx, hankPymId, options); + dated.setHours(14, 59, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + dated.setHours(15, 14, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + + const start = new Date(dated - 1); + start.setHours(0, 0, 0); + await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [ + hankPymId, + start, + end + ], options); + + let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options); + + expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28800); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it(`should return today's worked hours with 15min break and work time consecutive greater than 5h`, async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + try { + await populateWeek(dated, monday, monday, ctx, hankPymId, options); + dated.setHours(15, 0, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + dated.setHours(15, 15, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + + const start = new Date(dated - 1); + start.setHours(0, 0, 0); + await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [ + hankPymId, + start, + end + ], options); + + let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options); + + expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28800); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it(`should return today's worked hours with 25min break and work time consecutive less than 5h`, async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + try { + await populateWeek(dated, monday, monday, ctx, hankPymId, options); + dated.setHours(14, 59, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + dated.setHours(15, 24, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + + const start = new Date(dated - 1); + start.setHours(0, 0, 0); + await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [ + hankPymId, + start, + end + ], options); + + let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options); + + expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28500); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it(`should return today's worked hours with 25min break and work time consecutive greater than 5h`, async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + try { + await populateWeek(dated, monday, monday, ctx, hankPymId, options); + dated.setHours(15, 0, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + dated.setHours(15, 25, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + + const start = new Date(dated - 1); + start.setHours(0, 0, 0); + await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [ + hankPymId, + start, + end + ], options); + + let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options); + + expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28500); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it(`should return today's worked hours with 60min break and work time consecutive less than 5h`, async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + try { + await populateWeek(dated, monday, monday, ctx, hankPymId, options); + dated.setHours(14, 59, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + dated.setHours(15, 59, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + + const start = new Date(dated - 1); + start.setHours(0, 0, 0); + await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [ + hankPymId, + start, + end + ], options); + + let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options); + + expect(timeControlCalculateTable.timeWorkSeconds).toEqual(25200); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it(`should return today's worked hours with 60min break and work time consecutive greater than 5h`, async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + try { + await populateWeek(dated, monday, monday, ctx, hankPymId, options); + dated.setHours(15, 0, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + dated.setHours(16, 0, 0); + await addTimeEntry(ctx, dated, 'middle', hankPymId, options); + + const start = new Date(dated - 1); + start.setHours(0, 0, 0); + await models.WorkerTimeControl.rawSql('CALL vn.timeControl_calculateByUser(?, ?, ?)', [ + hankPymId, + start, + end + ], options); + + let [timeControlCalculateTable] = await models.WorkerTimeControl.rawSql('SELECT * FROM tmp.timeControlCalculate', null, options); + + expect(timeControlCalculateTable.timeWorkSeconds).toEqual(26400); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); }); }); +async function addTimeEntry(ctx, dated, direction, userId, option) { + ctx.args = {timed: dated, direction}; + await models.WorkerTimeControl.addTimeEntry(ctx, userId, option); +} + function weekDay(date, dayToSet) { const currentDay = date.getDay(); const distance = dayToSet - currentDay; @@ -704,10 +861,10 @@ async function populateWeek(date, dayStart, dayEnd, ctx, workerId, options) { dateEnd.setDate(dateStart.getDate() + dayEnd); for (let i = dayStart; i <= dayEnd; i++) { - dateStart.setHours(8, 0, 0); + dateStart.setHours(10, 0, 0); ctx.args = {timed: dateStart, direction: 'in'}; await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - dateStart.setHours(16, 0, 0); + dateStart.setHours(18, 0, 0); ctx.args = {timed: dateStart, direction: 'out'}; await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); dateStart.setDate(dateStart.getDate() + 1); From 483526c9702fe03ddd2fcc18586cb6b62cc36102 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 23 Oct 2023 15:03:05 +0200 Subject: [PATCH 128/449] refs #6015 feat(executeRoutine): check db restrictions. test: add executeRoutine tests --- db/changes/234201/00-ACL_executeRoutine.sql | 3 + .../methods/application/executeRoutine.js | 67 +++++++-- .../application/spec/executeRoutine.spec.js | 138 ++++++++++++++++++ loopback/common/models/application.js | 1 + loopback/common/models/procs-priv.json | 44 ++++++ loopback/server/model-config.json | 10 +- 6 files changed, 248 insertions(+), 15 deletions(-) create mode 100644 db/changes/234201/00-ACL_executeRoutine.sql create mode 100644 loopback/common/methods/application/spec/executeRoutine.spec.js create mode 100644 loopback/common/models/procs-priv.json diff --git a/db/changes/234201/00-ACL_executeRoutine.sql b/db/changes/234201/00-ACL_executeRoutine.sql new file mode 100644 index 0000000000..dd112171a3 --- /dev/null +++ b/db/changes/234201/00-ACL_executeRoutine.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('Application', 'executeRoutine', '*', 'ALLOW', 'ROLE', 'employee'); diff --git a/loopback/common/methods/application/executeRoutine.js b/loopback/common/methods/application/executeRoutine.js index a5557bc617..eed34b3441 100644 --- a/loopback/common/methods/application/executeRoutine.js +++ b/loopback/common/methods/application/executeRoutine.js @@ -1,3 +1,5 @@ +const UserError = require('vn-loopback/util/user-error'); + module.exports = Self => { Self.remoteMethodCtx('executeRoutine', { description: 'Return the routes by worker', @@ -6,15 +8,24 @@ module.exports = Self => { { arg: 'routine', type: 'string', - description: 'The routine sql', + description: 'The routine name', required: true, http: {source: 'path'} }, { arg: 'params', type: ['any'], - description: 'The array of params', - required: true, + description: 'The params array', + }, + { + arg: 'schema', + type: 'string', + description: 'The routine schema', + }, + { + arg: 'type', + type: 'string', + description: 'The routine type', } ], returns: { @@ -27,14 +38,23 @@ module.exports = Self => { } }); - Self.executeRoutine = async(ctx, routine, params, options) => { + Self.executeRoutine = async(ctx, routine, params, schema, type, options) => { const userId = ctx.req.accessToken.userId; + const models = Self.app.models; + const isFunction = type == 'function'; + params = params ?? []; + schema = schema ?? 'vn'; + type = type ?? 'procedure'; + let caller = 'CALL'; - const myOptions = {}; + if (isFunction) + caller = 'SELECT'; + + const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); - const user = await Self.app.models.VnUser.findById(userId, { + const user = await models.VnUser.findById(userId, { fields: ['id', 'roleFk'], include: { relation: 'role', @@ -44,18 +64,37 @@ module.exports = Self => { } }); - const inherits = await Self.app.models.RoleRole.find({ + const inherits = await models.RoleRole.find({ + include: { + relation: 'inherits', + scope: { + fields: ['id', 'name'] + } + }, where: { - + role: user.role().id } }); - console.log(user.role.name); - const checkACL = await models.ACL.checkAccessAcl(ctx, 'Application', routine, '*'); - if (!checkACL) throw error; + const roles = inherits.map(inherit => inherit.inherits().name); - const requestParams = [routine]; - requestParams.concat(params); - return Self.app.models.Route.rawSql(`CALL ?(...)`, requestParams, myOptions); + const canExecute = await models.ProcsPriv.findOne({ + where: { + schema, + type: type.toUpperCase(), + name: routine, + host: process.env.NODE_ENV ? '' : '%', + role: {inq: roles} + } + }); + + if (!canExecute) throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED'); + + let argString = params.map(() => '?').join(','); + + const query = `${caller} ${schema}.${routine}(${argString})`; + + const [response] = await models.ProcsPriv.rawSql(query, params, myOptions); + return isFunction ? Object.values(response)[0] : response; }; }; diff --git a/loopback/common/methods/application/spec/executeRoutine.spec.js b/loopback/common/methods/application/spec/executeRoutine.spec.js new file mode 100644 index 0000000000..150c5d416d --- /dev/null +++ b/loopback/common/methods/application/spec/executeRoutine.spec.js @@ -0,0 +1,138 @@ +const models = require('vn-loopback/server/server').models; + +describe('Application executeRoutine()', () => { + const userWithoutPrivileges = 1; + const userWithPrivileges = 9; + const userWithInheritedPrivileges = 120; + let tx; + + function getCtx(userId) { + return { + req: { + accessToken: {userId}, + headers: {origin: 'http://localhost'} + } + }; + } + + beforeEach(async() => { + tx = await models.Application.beginTransaction({}); + const options = {transaction: tx}; + + await models.Application.rawSql(` + CREATE OR REPLACE PROCEDURE vn.myProcedure(vMyParam INT) + BEGIN + SELECT vMyParam myParam, t.* + FROM ticket t + LIMIT 2; + END + `, null, options); + + await models.Application.rawSql(` + CREATE OR REPLACE FUNCTION bs.myFunction(vMyParam INT) RETURNS int(11) + BEGIN + RETURN vMyParam; + END + `, null, options); + + await models.Application.rawSql(` + GRANT EXECUTE ON PROCEDURE vn.myProcedure TO developer; + GRANT EXECUTE ON FUNCTION bs.myFunction TO developer; + `, null, options); + }); + + it('should throw error when execute procedure and not have privileges', async() => { + const ctx = getCtx(userWithoutPrivileges); + + let error; + try { + const options = {transaction: tx}; + + await models.Application.executeRoutine( + ctx, + 'myProcedure', + [1], + null, + null, + options + ); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toEqual(`You don't have enough privileges`); + }); + + it('should execute procedure and get data', async() => { + const ctx = getCtx(userWithPrivileges); + try { + const options = {transaction: tx}; + + const response = await models.Application.executeRoutine( + ctx, + 'myProcedure', + [1], + null, + null, + options + ); + + expect(response.length).toEqual(2); + expect(response[0].myParam).toEqual(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should execute function and get data', async() => { + const ctx = getCtx(userWithPrivileges); + try { + const options = {transaction: tx}; + + const response = await models.Application.executeRoutine( + ctx, + 'myFunction', + [1], + 'bs', + 'function', + options + ); + + expect(response).toEqual(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should execute function and get data with user with inherited privileges', async() => { + const ctx = getCtx(userWithInheritedPrivileges); + try { + const options = {transaction: tx}; + + const response = await models.Application.executeRoutine( + ctx, + 'myFunction', + [1], + 'bs', + 'function', + options + ); + + expect(response).toEqual(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/loopback/common/models/application.js b/loopback/common/models/application.js index 5e767fdc11..b9e639b1be 100644 --- a/loopback/common/models/application.js +++ b/loopback/common/models/application.js @@ -2,4 +2,5 @@ module.exports = function(Self) { require('../methods/application/status')(Self); require('../methods/application/post')(Self); + require('../methods/application/executeRoutine')(Self); }; diff --git a/loopback/common/models/procs-priv.json b/loopback/common/models/procs-priv.json new file mode 100644 index 0000000000..25221d586c --- /dev/null +++ b/loopback/common/models/procs-priv.json @@ -0,0 +1,44 @@ +{ + "name": "ProcsPriv", + "base": "VnModel", + "options": { + "mysql": { + "table": "mysql.procs_priv" + } + }, + "properties": { + "name": { + "id": 1, + "type": "string", + "mysql": { + "columnName": "Routine_name" + } + }, + "schema": { + "id": 3, + "type": "string", + "mysql": { + "columnName": "Db" + } + }, + "role": { + "type": "string", + "mysql": { + "columnName": "user" + } + }, + "type": { + "id": 2, + "type": "string", + "mysql": { + "columnName": "Routine_type" + } + }, + "host": { + "type": "string", + "mysql": { + "columnName": "Host" + } + } + } +} diff --git a/loopback/server/model-config.json b/loopback/server/model-config.json index 52b539f60e..33ef3797d6 100644 --- a/loopback/server/model-config.json +++ b/loopback/server/model-config.json @@ -49,5 +49,13 @@ }, "Container": { "dataSource": "vn" + }, + "ProcsPriv": { + "dataSource": "vn", + "options": { + "mysql": { + "table": "mysql.procs_priv" + } + } } -} \ No newline at end of file +} From 0055abc0a8064f8a0fbc12473243a566e727590d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Mon, 23 Oct 2023 15:52:05 +0200 Subject: [PATCH 129/449] refs #4707 fix: problemas fichadas y test --- db/changes/234003/00-workerTimeControl.sql | 4 ++-- db/changes/234003/02-workerTimeControl_clockIn.sql | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/db/changes/234003/00-workerTimeControl.sql b/db/changes/234003/00-workerTimeControl.sql index 7b41278b0f..73d57d1db7 100644 --- a/db/changes/234003/00-workerTimeControl.sql +++ b/db/changes/234003/00-workerTimeControl.sql @@ -11,14 +11,14 @@ ALTER TABLE `vn`.`workerTimeControlConfig` ALTER TABLE `vn`.`workerTimeControlConfig` ADD COLUMN `maxWorkShortCycle` INT(10) UNSIGNED DEFAULT 561600 - COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descando semanal corto'; + COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descando'; ALTER TABLE `vn`.`workerTimeControlConfig` DROP COLUMN IF EXISTS `maxWorkLongCycle`; ALTER TABLE `vn`.`workerTimeControlConfig` ADD COLUMN `maxWorkLongCycle` INT(10) UNSIGNED DEFAULT 950400 - COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descando semanal largo'; + COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descando'; CREATE TABLE IF NOT EXISTS `vn`.`workerTimeControlError` ( `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, diff --git a/db/changes/234003/02-workerTimeControl_clockIn.sql b/db/changes/234003/02-workerTimeControl_clockIn.sql index 7cc9e7831e..69091e51cd 100644 --- a/db/changes/234003/02-workerTimeControl_clockIn.sql +++ b/db/changes/234003/02-workerTimeControl_clockIn.sql @@ -12,7 +12,7 @@ BEGIN * @param vDirection solo se pueden pasa los valores del campo * workerTimeControl.direction ENUM('in', 'out', 'middle') * @return Si todo es correcto, retorna el número de id la tabla workerTimeControl. - * Si hay algún problema, devuelve el mesaje a que se debe mostrar al usuario + * Si hay algún problema, devuelve el mesaje que se debe mostrar al usuario * Solo retorna el primer problema, en caso de no ocurrir ningún error se añadirá * fichada a la tabla vn.workerTimeControl */ From 4ff0bb94c08759a624af93202a7ba06ede0300ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Mon, 23 Oct 2023 16:58:56 +0200 Subject: [PATCH 130/449] refs #4707 --- db/changes/234003/00-workerTimeControl.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/changes/234003/00-workerTimeControl.sql b/db/changes/234003/00-workerTimeControl.sql index 73d57d1db7..c96fafcdd8 100644 --- a/db/changes/234003/00-workerTimeControl.sql +++ b/db/changes/234003/00-workerTimeControl.sql @@ -11,14 +11,14 @@ ALTER TABLE `vn`.`workerTimeControlConfig` ALTER TABLE `vn`.`workerTimeControlConfig` ADD COLUMN `maxWorkShortCycle` INT(10) UNSIGNED DEFAULT 561600 - COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descando'; + COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descanso semanal corto'; ALTER TABLE `vn`.`workerTimeControlConfig` DROP COLUMN IF EXISTS `maxWorkLongCycle`; ALTER TABLE `vn`.`workerTimeControlConfig` ADD COLUMN `maxWorkLongCycle` INT(10) UNSIGNED DEFAULT 950400 - COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descando'; + COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descanso semanal largo'; CREATE TABLE IF NOT EXISTS `vn`.`workerTimeControlError` ( `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, From 5529f08ce6f949a922954e67f52157e52547cca3 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 24 Oct 2023 08:35:45 +0200 Subject: [PATCH 131/449] ref #5914 fix locale --- loopback/locale/en.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index fec1c85668..26650175d6 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -188,19 +188,14 @@ "The ticket doesn't exist.": "The ticket doesn't exist.", "The sales do not exists": "The sales do not exists", "Ticket without Route": "Ticket without route", -<<<<<<< HEAD "Select a different client": "Select a different client", "Fill all the fields": "Fill all the fields", "Error while generating PDF": "Error while generating PDF", "Can't invoice to future": "Can't invoice to future", "This ticket is already invoiced": "This ticket is already invoiced", "Negative basis of tickets: 23": "Negative basis of tickets: 23", - "Booking completed": "Booking completed", - "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation" -======= "Booking completed": "Booking complete", "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation", "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets" ->>>>>>> ae27aa5b1e61c74bfbbc1b7b8af63642072acc6d } From 22b7c5981294dcf5573c4f23b92a7f3010f5e98c Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 24 Oct 2023 09:23:03 +0200 Subject: [PATCH 132/449] refs #6335 feat(ticketAdvance): add zone field --- .../234003/00-ticket_canAdvance_zone.sql | 132 ++++++++++++++++++ .../back/methods/ticket/getTicketsAdvance.js | 15 +- modules/ticket/front/advance/index.html | 4 + modules/ticket/front/advance/index.js | 44 +++--- 4 files changed, 159 insertions(+), 36 deletions(-) create mode 100644 db/changes/234003/00-ticket_canAdvance_zone.sql diff --git a/db/changes/234003/00-ticket_canAdvance_zone.sql b/db/changes/234003/00-ticket_canAdvance_zone.sql new file mode 100644 index 0000000000..c11cdc49ad --- /dev/null +++ b/db/changes/234003/00-ticket_canAdvance_zone.sql @@ -0,0 +1,132 @@ +DELIMITER $$ +$$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_canAdvance`(vDateFuture DATE, vDateToAdvance DATE, vWarehouseFk INT) +BEGIN +/** + * Devuelve los tickets y la cantidad de lineas de venta que se pueden adelantar. + * + * @param vDateFuture Fecha de los tickets que se quieren adelantar. + * @param vDateToAdvance Fecha a cuando se quiere adelantar. + * @param vWarehouseFk Almacén + */ + DECLARE vDateInventory DATE; + + SELECT inventoried INTO vDateInventory FROM config; + + DROP TEMPORARY TABLE IF EXISTS tmp.stock; + CREATE TEMPORARY TABLE tmp.stock + (itemFk INT PRIMARY KEY, + amount INT) + ENGINE = MEMORY; + + INSERT INTO tmp.stock(itemFk, amount) + SELECT itemFk, SUM(quantity) amount FROM + ( + SELECT itemFk, quantity + FROM itemTicketOut + WHERE shipped >= vDateInventory + AND shipped < vDateFuture + AND warehouseFk = vWarehouseFk + UNION ALL + SELECT itemFk, quantity + FROM itemEntryIn + WHERE landed >= vDateInventory + AND landed < vDateFuture + AND isVirtualStock = FALSE + AND warehouseInFk = vWarehouseFk + UNION ALL + SELECT itemFk, quantity + FROM itemEntryOut + WHERE shipped >= vDateInventory + AND shipped < vDateFuture + AND warehouseOutFk = vWarehouseFk + ) t + GROUP BY itemFk HAVING amount != 0; + + CREATE OR REPLACE TEMPORARY TABLE tmp.filter + (INDEX (id)) + SELECT + origin.ticketFk futureId, + dest.ticketFk id, + dest.state, + origin.futureState, + origin.futureIpt, + dest.ipt, + origin.workerFk, + origin.futureLiters, + origin.futureLines, + dest.shipped, + origin.shipped futureShipped, + dest.totalWithVat, + origin.totalWithVat futureTotalWithVat, + dest.agency, + origin.futureAgency, + dest.lines, + dest.liters, + origin.futureLines - origin.hasStock AS notMovableLines, + (origin.futureLines = origin.hasStock) AS isFullMovable, + origin.futureZoneFk, + origin.futureZoneName, + origin.classColor futureClassColor, + dest.classColor + FROM ( + SELECT + s.ticketFk, + t.workerFk, + t.shipped, + t.totalWithVat, + st.name futureState, + t.addressFk, + am.name futureAgency, + count(s.id) futureLines, + GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) futureIpt, + CAST(SUM(litros) AS DECIMAL(10,0)) futureLiters, + SUM((s.quantity <= IFNULL(st.amount,0))) hasStock, + z.id futureZoneFk, + z.name futureZoneName, + st.classColor + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN saleVolume sv ON sv.saleFk = s.id + JOIN item i ON i.id = s.itemFk + JOIN ticketState ts ON ts.ticketFk = t.id + JOIN state st ON st.id = ts.stateFk + JOIN agencyMode am ON t.agencyModeFk = am.id + JOIN zone z ON t.zoneFk = z.id + LEFT JOIN itemPackingType ipt ON ipt.code = i.itemPackingTypeFk + LEFT JOIN tmp.stock st ON st.itemFk = i.id + WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture) + AND t.warehouseFk = vWarehouseFk + GROUP BY t.id + ) origin + JOIN ( + SELECT + t.id ticketFk, + t.addressFk, + st.name state, + GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt, + t.shipped, + t.totalWithVat, + am.name agency, + CAST(SUM(litros) AS DECIMAL(10,0)) liters, + CAST(COUNT(*) AS DECIMAL(10,0)) `lines`, + st.classColor + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN saleVolume sv ON sv.saleFk = s.id + JOIN item i ON i.id = s.itemFk + JOIN ticketState ts ON ts.ticketFk = t.id + JOIN state st ON st.id = ts.stateFk + JOIN agencyMode am ON t.agencyModeFk = am.id + LEFT JOIN itemPackingType ipt ON ipt.code = i.itemPackingTypeFk + WHERE t.shipped BETWEEN vDateToAdvance AND util.dayend(vDateToAdvance) + AND t.warehouseFk = vWarehouseFk + AND st.order <= 5 + GROUP BY t.id + ) dest ON dest.addressFk = origin.addressFk + WHERE origin.hasStock != 0; + + DROP TEMPORARY TABLE tmp.stock; +END$$ +DELIMITER ; + diff --git a/modules/ticket/back/methods/ticket/getTicketsAdvance.js b/modules/ticket/back/methods/ticket/getTicketsAdvance.js index ec9314db2b..ab40b95599 100644 --- a/modules/ticket/back/methods/ticket/getTicketsAdvance.js +++ b/modules/ticket/back/methods/ticket/getTicketsAdvance.js @@ -28,32 +28,27 @@ module.exports = Self => { { arg: 'ipt', type: 'string', - description: 'Origin Item Packaging Type', - required: false + description: 'Origin Item Packaging Type' }, { arg: 'futureIpt', type: 'string', - description: 'Destination Item Packaging Type', - required: false + description: 'Destination Item Packaging Type' }, { arg: 'id', type: 'number', - description: 'Origin id', - required: false + description: 'Origin id' }, { arg: 'futureId', type: 'number', - description: 'Destination id', - required: false + description: 'Destination id' }, { arg: 'isFullMovable', type: 'boolean', - description: 'True when lines and stock of origin are equal', - required: false + description: 'True when lines and stock of origin are equal' }, { arg: 'filter', diff --git a/modules/ticket/front/advance/index.html b/modules/ticket/front/advance/index.html index e6f16c9651..a6cf8facea 100644 --- a/modules/ticket/front/advance/index.html +++ b/modules/ticket/front/advance/index.html @@ -81,6 +81,9 @@ Liters + + Zone + Not Movable @@ -155,6 +158,7 @@ {{::ticket.futureLiters | dashIfEmpty}} + {{::ticket.futureZoneName | dashIfEmpty}} {{::ticket.notMovableLines | dashIfEmpty}} {{::ticket.futureLines | dashIfEmpty}} diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index 6f8a92ebe2..389bcdf14a 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -15,28 +15,22 @@ export default class Controller extends Section { { field: 'state', searchable: false - }, - { + }, { field: 'futureState', searchable: false - }, - { + }, { field: 'totalWithVat', searchable: false - }, - { + }, { field: 'futureTotalWithVat', searchable: false - }, - { + }, { field: 'shipped', searchable: false - }, - { + }, { field: 'futureShipped', searchable: false - }, - { + }, { field: 'ipt', autocomplete: { url: 'ItemPackingTypes', @@ -44,8 +38,7 @@ export default class Controller extends Section { showField: 'description', valueField: 'code' } - }, - { + }, { field: 'futureIpt', autocomplete: { url: 'ItemPackingTypes', @@ -53,6 +46,11 @@ export default class Controller extends Section { showField: 'description', valueField: 'code' } + }, { + field: 'futureZoneFk', + autocomplete: { + url: 'Zones', + } }, ] }; @@ -158,27 +156,21 @@ export default class Controller extends Section { exprBuilder(param, value) { switch (param) { case 'id': - return {'id': value}; case 'futureId': - return {'futureId': value}; case 'liters': - return {'liters': value}; case 'futureLiters': - return {'futureLiters': value}; case 'lines': - return {'lines': value}; case 'futureLines': - return {'futureLines': value}; + case 'totalWithVat': + case 'futureTotalWithVat': + case 'futureZone': + case 'notMovableLines': + case 'futureZoneFk': + return {[param]: value}; case 'ipt': return {'ipt': {like: `%${value}%`}}; case 'futureIpt': return {'futureIpt': {like: `%${value}%`}}; - case 'totalWithVat': - return {'totalWithVat': value}; - case 'futureTotalWithVat': - return {'futureTotalWithVat': value}; - case 'notMovableLines': - return {'notMovableLines': value}; } } } From f1deeb69cabfc11210f24173a8d683e9e99ab27c Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 24 Oct 2023 09:34:04 +0200 Subject: [PATCH 133/449] ref #5914 add ticketrefund and fix text --- .../invoiceOut/specs/transferinvoice.spec.js | 22 ++++++++++++++++--- modules/ticket/back/methods/sale/clone.js | 8 ++++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js index 75bf649ecb..04f6df2995 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js @@ -1,14 +1,30 @@ + const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('InvoiceOut tranferInvoice()', () => { - const userId = 5; - const ctx = {req: {accessToken: userId}}; + const activeCtx = { + accessToken: {userId: 5}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + const ctx = {req: activeCtx}; + + beforeEach(() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should return the id of the created issued invoice', async() => { const tx = await models.InvoiceOut.beginTransaction({}); const options = {transaction: tx}; const args = { id: '1', - ref: 'T1111111', + ref: 'T4444444', newClientFk: 1, cplusRectificationId: 1, cplusInvoiceType477Id: 1, diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index dd1b108b22..a72f17af64 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -105,7 +105,13 @@ module.exports = Self => { ctx.args.companyId = ticket.companyFk; ctx.args.addressId = ticket.addressFk; - return models.Ticket.new(ctx, myOptions); + const newTicket = await models.Ticket.new(ctx, myOptions); + await models.TicketRefund.create({ + originalTicketFk: ticketId, + refundTicketFk: newTicket.id + }, myOptions); + + return newTicket; } }; }; From 9f141238bc13223f6b760625e3e1985de71ceac5 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 24 Oct 2023 11:47:54 +0200 Subject: [PATCH 134/449] ref #5216 add userFk --- .../methods/expedition-state/addExpeditionState.js | 10 ++++------ .../expedition-state/specs/addExpeditionState.spec.js | 8 ++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/modules/ticket/back/methods/expedition-state/addExpeditionState.js b/modules/ticket/back/methods/expedition-state/addExpeditionState.js index f1199f1888..8eab1a8386 100644 --- a/modules/ticket/back/methods/expedition-state/addExpeditionState.js +++ b/modules/ticket/back/methods/expedition-state/addExpeditionState.js @@ -1,7 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethod('addExpeditionState', { + Self.remoteMethodCtx('addExpeditionState', { description: 'Update an expedition state', accessType: 'WRITE', accepts: [ @@ -12,18 +12,15 @@ module.exports = Self => { description: 'Array of objects containing expeditionFk and stateCode' } ], - returns: { - type: 'boolean', - root: true - }, http: { path: `/addExpeditionState`, verb: 'post' } }); - Self.addExpeditionState = async(expeditions, options) => { + Self.addExpeditionState = async(ctx, expeditions, options) => { const models = Self.app.models; + const userId = ctx.req.accessToken.userId; let tx; const myOptions = {}; if (typeof options == 'object') @@ -51,6 +48,7 @@ module.exports = Self => { await models.ExpeditionState.create({ expeditionFk: expedition.expeditionFk, typeFk, + userFk: userId, }, myOptions); } diff --git a/modules/ticket/back/methods/expedition-state/specs/addExpeditionState.spec.js b/modules/ticket/back/methods/expedition-state/specs/addExpeditionState.spec.js index 819a43a605..6c7739006d 100644 --- a/modules/ticket/back/methods/expedition-state/specs/addExpeditionState.spec.js +++ b/modules/ticket/back/methods/expedition-state/specs/addExpeditionState.spec.js @@ -1,9 +1,9 @@ const models = require('vn-loopback/server/server').models; describe('expeditionState addExpeditionState()', () => { + const ctx = {req: {accessToken: {userId: 9}}}; it('should update the expedition states', async() => { const tx = await models.ExpeditionState.beginTransaction({}); - try { const options = {transaction: tx}; const payload = [ @@ -13,7 +13,7 @@ describe('expeditionState addExpeditionState()', () => { }, ]; - await models.ExpeditionState.addExpeditionState(payload, options); + await models.ExpeditionState.addExpeditionState(ctx, payload, options); const expeditionState = await models.ExpeditionState.findOne({ where: {id: 5} @@ -39,7 +39,7 @@ describe('expeditionState addExpeditionState()', () => { stateCode: 'DUMMY' } ]; - await models.ExpeditionState.addExpeditionState(payload, options); + await models.ExpeditionState.addExpeditionState(ctx, payload, options); await tx.rollback(); } catch (e) { @@ -62,7 +62,7 @@ describe('expeditionState addExpeditionState()', () => { } ]; - await models.ExpeditionState.addExpeditionState(payload, options); + await models.ExpeditionState.addExpeditionState(ctx, payload, options); await tx.rollback(); } catch (e) { From 589d7cbbb82dce802cf30096ed1e47e85dd157e0 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 24 Oct 2023 12:02:21 +0200 Subject: [PATCH 135/449] fix: ticket_canAdvance correct worker. fix(dockerFIle)! dockerFile debian version --- Dockerfile | 2 +- db/changes/234003/00-ticket_canAdvance_zone.sql | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index e1173ad738..c82b20b31e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bullseye-slim +FROM debian:bookworm-slim ENV TZ Europe/Madrid ARG DEBIAN_FRONTEND=noninteractive diff --git a/db/changes/234003/00-ticket_canAdvance_zone.sql b/db/changes/234003/00-ticket_canAdvance_zone.sql index c11cdc49ad..ee07ce9788 100644 --- a/db/changes/234003/00-ticket_canAdvance_zone.sql +++ b/db/changes/234003/00-ticket_canAdvance_zone.sql @@ -72,7 +72,7 @@ BEGIN FROM ( SELECT s.ticketFk, - t.workerFk, + c.salesPersonFk workerFk, t.shipped, t.totalWithVat, st.name futureState, @@ -86,6 +86,7 @@ BEGIN z.name futureZoneName, st.classColor FROM ticket t + JOIN client c ON c.id = t.clientFk JOIN sale s ON s.ticketFk = t.id JOIN saleVolume sv ON sv.saleFk = s.id JOIN item i ON i.id = s.itemFk From 22fdcef7bb2faa0f9737d6fa01d3e51487924607 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 24 Oct 2023 14:07:05 +0200 Subject: [PATCH 136/449] fix(dockerFIle)! front debian version --- Dockerfile | 2 +- front/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index c82b20b31e..e1173ad738 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim +FROM debian:bullseye-slim ENV TZ Europe/Madrid ARG DEBIAN_FRONTEND=noninteractive diff --git a/front/Dockerfile b/front/Dockerfile index 098ee161ea..d0ee269041 100644 --- a/front/Dockerfile +++ b/front/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:stretch-slim +FROM debian:bookworm-slim EXPOSE 80 ENV TZ Europe/Madrid From efa9f1645213124f7575c9d3be6e6d2216d8c4e1 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 25 Oct 2023 09:22:44 +0200 Subject: [PATCH 137/449] fix: remove unnecessary UserError --- modules/ticket/back/methods/ticket/addSale.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/ticket/back/methods/ticket/addSale.js b/modules/ticket/back/methods/ticket/addSale.js index 3455ec2c46..826de6e129 100644 --- a/modules/ticket/back/methods/ticket/addSale.js +++ b/modules/ticket/back/methods/ticket/addSale.js @@ -1,5 +1,3 @@ -const UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethodCtx('addSale', { description: 'Inserts a new sale for the current ticket', From b461f63e2cd9c2d64a96513960336b32b06eb97e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Wed, 25 Oct 2023 11:02:53 +0200 Subject: [PATCH 138/449] refs #4707 fix: correct sqlVersion --- db/changes/{234003 => 234004}/.gitkeep | 0 db/changes/{234003 => 234004}/00-workerTimeControl.sql | 1 - db/changes/{234003 => 234004}/01-timeControl_calculate.sql | 0 db/changes/{234003 => 234004}/02-workerTimeControl_clockIn.sql | 0 4 files changed, 1 deletion(-) rename db/changes/{234003 => 234004}/.gitkeep (100%) rename db/changes/{234003 => 234004}/00-workerTimeControl.sql (97%) rename db/changes/{234003 => 234004}/01-timeControl_calculate.sql (100%) rename db/changes/{234003 => 234004}/02-workerTimeControl_clockIn.sql (100%) diff --git a/db/changes/234003/.gitkeep b/db/changes/234004/.gitkeep similarity index 100% rename from db/changes/234003/.gitkeep rename to db/changes/234004/.gitkeep diff --git a/db/changes/234003/00-workerTimeControl.sql b/db/changes/234004/00-workerTimeControl.sql similarity index 97% rename from db/changes/234003/00-workerTimeControl.sql rename to db/changes/234004/00-workerTimeControl.sql index c96fafcdd8..8f6263533c 100644 --- a/db/changes/234003/00-workerTimeControl.sql +++ b/db/changes/234004/00-workerTimeControl.sql @@ -28,7 +28,6 @@ CREATE TABLE IF NOT EXISTS `vn`.`workerTimeControlError` ( UNIQUE KEY `code` (`code`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; - INSERT IGNORE INTO `vn`.`workerTimeControlError` (`code`, `description`) VALUES ('IS_NOT_ALLOWED_FUTURE', 'No se permite fichar a futuro'), diff --git a/db/changes/234003/01-timeControl_calculate.sql b/db/changes/234004/01-timeControl_calculate.sql similarity index 100% rename from db/changes/234003/01-timeControl_calculate.sql rename to db/changes/234004/01-timeControl_calculate.sql diff --git a/db/changes/234003/02-workerTimeControl_clockIn.sql b/db/changes/234004/02-workerTimeControl_clockIn.sql similarity index 100% rename from db/changes/234003/02-workerTimeControl_clockIn.sql rename to db/changes/234004/02-workerTimeControl_clockIn.sql From 26bdbabff5c7b4f6720214715b14d19ac7cc0888 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 25 Oct 2023 15:48:19 +0200 Subject: [PATCH 139/449] refs #6335 feat(ticketAdvanced): show all tickets --- .../234201/00-ticket_canAdvance_leftJoin.sql | 132 ++++++++++++++++++ loopback/server/boot/date.js | 4 +- modules/ticket/front/advance/index.html | 10 +- 3 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 db/changes/234201/00-ticket_canAdvance_leftJoin.sql diff --git a/db/changes/234201/00-ticket_canAdvance_leftJoin.sql b/db/changes/234201/00-ticket_canAdvance_leftJoin.sql new file mode 100644 index 0000000000..b26c3a102c --- /dev/null +++ b/db/changes/234201/00-ticket_canAdvance_leftJoin.sql @@ -0,0 +1,132 @@ +DELIMITER $$ +$$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_canAdvance`(vDateFuture DATE, vDateToAdvance DATE, vWarehouseFk INT) +BEGIN +/** + * Devuelve los tickets y la cantidad de lineas de venta que se pueden adelantar. + * + * @param vDateFuture Fecha de los tickets que se quieren adelantar. + * @param vDateToAdvance Fecha a cuando se quiere adelantar. + * @param vWarehouseFk Almacén + */ + DECLARE vDateInventory DATE; + + SELECT inventoried INTO vDateInventory FROM config; + + DROP TEMPORARY TABLE IF EXISTS tmp.stock; + CREATE TEMPORARY TABLE tmp.stock + (itemFk INT PRIMARY KEY, + amount INT) + ENGINE = MEMORY; + + INSERT INTO tmp.stock(itemFk, amount) + SELECT itemFk, SUM(quantity) amount FROM + ( + SELECT itemFk, quantity + FROM itemTicketOut + WHERE shipped >= vDateInventory + AND shipped < vDateFuture + AND warehouseFk = vWarehouseFk + UNION ALL + SELECT itemFk, quantity + FROM itemEntryIn + WHERE landed >= vDateInventory + AND landed < vDateFuture + AND isVirtualStock = FALSE + AND warehouseInFk = vWarehouseFk + UNION ALL + SELECT itemFk, quantity + FROM itemEntryOut + WHERE shipped >= vDateInventory + AND shipped < vDateFuture + AND warehouseOutFk = vWarehouseFk + ) t + GROUP BY itemFk HAVING amount != 0; + + CREATE OR REPLACE TEMPORARY TABLE tmp.filter + (INDEX (id)) + SELECT + origin.ticketFk futureId, + dest.ticketFk id, + dest.state, + origin.futureState, + origin.futureIpt, + dest.ipt, + origin.workerFk, + origin.futureLiters, + origin.futureLines, + dest.shipped, + origin.shipped futureShipped, + dest.totalWithVat, + origin.totalWithVat futureTotalWithVat, + dest.agency, + origin.futureAgency, + dest.lines, + dest.liters, + origin.futureLines - origin.hasStock AS notMovableLines, + (origin.futureLines = origin.hasStock) AS isFullMovable, + origin.futureZoneFk, + origin.futureZoneName, + origin.classColor futureClassColor, + dest.classColor + FROM ( + SELECT + s.ticketFk, + c.salesPersonFk workerFk, + t.shipped, + t.totalWithVat, + st.name futureState, + t.addressFk, + am.name futureAgency, + count(s.id) futureLines, + GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) futureIpt, + CAST(SUM(litros) AS DECIMAL(10,0)) futureLiters, + SUM((s.quantity <= IFNULL(st.amount,0))) hasStock, + z.id futureZoneFk, + z.name futureZoneName, + st.classColor + FROM ticket t + JOIN client c ON c.id = t.clientFk + JOIN sale s ON s.ticketFk = t.id + JOIN saleVolume sv ON sv.saleFk = s.id + JOIN item i ON i.id = s.itemFk + JOIN ticketState ts ON ts.ticketFk = t.id + JOIN state st ON st.id = ts.stateFk + JOIN agencyMode am ON t.agencyModeFk = am.id + JOIN zone z ON t.zoneFk = z.id + LEFT JOIN itemPackingType ipt ON ipt.code = i.itemPackingTypeFk + LEFT JOIN tmp.stock st ON st.itemFk = i.id + WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture) + AND t.warehouseFk = vWarehouseFk + GROUP BY t.id + ) origin + LEFT JOIN ( + SELECT + t.id ticketFk, + t.addressFk, + st.name state, + GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt, + t.shipped, + t.totalWithVat, + am.name agency, + CAST(SUM(litros) AS DECIMAL(10,0)) liters, + CAST(COUNT(*) AS DECIMAL(10,0)) `lines`, + st.classColor + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN saleVolume sv ON sv.saleFk = s.id + JOIN item i ON i.id = s.itemFk + JOIN ticketState ts ON ts.ticketFk = t.id + JOIN state st ON st.id = ts.stateFk + JOIN agencyMode am ON t.agencyModeFk = am.id + LEFT JOIN itemPackingType ipt ON ipt.code = i.itemPackingTypeFk + WHERE t.shipped BETWEEN vDateToAdvance AND util.dayend(vDateToAdvance) + AND t.warehouseFk = vWarehouseFk + AND st.order <= 5 + GROUP BY t.id + ) dest ON dest.addressFk = origin.addressFk + WHERE origin.hasStock != 0; + + DROP TEMPORARY TABLE tmp.stock; +END$$ +DELIMITER ; diff --git a/loopback/server/boot/date.js b/loopback/server/boot/date.js index 8107455625..88505cf62c 100644 --- a/loopback/server/boot/date.js +++ b/loopback/server/boot/date.js @@ -1,8 +1,8 @@ module.exports = () => { Date.vnUTC = () => { const env = process.env.NODE_ENV; - if (!env || env === 'development') - return new Date(Date.UTC(2001, 0, 1, 11)); + // if (!env || env === 'development') + // return new Date(Date.UTC(2001, 0, 1, 11)); return new Date(); }; diff --git a/modules/ticket/front/advance/index.html b/modules/ticket/front/advance/index.html index a6cf8facea..af5b8f7044 100644 --- a/modules/ticket/front/advance/index.html +++ b/modules/ticket/front/advance/index.html @@ -105,7 +105,7 @@ @@ -159,7 +159,13 @@ {{::ticket.futureLiters | dashIfEmpty}} {{::ticket.futureZoneName | dashIfEmpty}} - {{::ticket.notMovableLines | dashIfEmpty}} + + + {{::ticket.notMovableLines | dashIfEmpty}} + + {{::ticket.futureLines | dashIfEmpty}} Date: Thu, 26 Oct 2023 07:56:57 +0200 Subject: [PATCH 140/449] refs #6278 test(itemRequest): fix e2e, correct selector --- e2e/helpers/selectors.js | 10 +++++----- modules/item/front/request/index.html | 28 +++++++++++++-------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 5e071911eb..cec0545a01 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -409,11 +409,11 @@ export default { inactiveIcon: 'vn-item-descriptor vn-icon[icon="icon-unavailable"]' }, itemRequest: { - firstRequestItemID: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td-editable:nth-child(7)', - firstRequestQuantity: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td-editable:nth-child(8)', - firstRequestConcept: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(9)', - firstRequestStatus: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(10)', - secondRequestStatus: 'vn-item-request vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(10)', + firstRequestItemID: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td-editable:nth-child(8)', + firstRequestQuantity: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td-editable:nth-child(9)', + firstRequestConcept: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(10)', + firstRequestStatus: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(11)', + secondRequestStatus: 'vn-item-request vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(11)', secondRequestDecline: 'vn-item-request vn-tr:nth-child(2) vn-icon-button[icon="thumb_down"]', declineReason: 'vn-textarea[ng-model="$ctrl.denyObservation"]' }, diff --git a/modules/item/front/request/index.html b/modules/item/front/request/index.html index 200ce3902b..03c8db8eca 100644 --- a/modules/item/front/request/index.html +++ b/modules/item/front/request/index.html @@ -26,7 +26,7 @@ Ticket ID Shipped Description - Requester + Requester Requested Price Atender @@ -86,8 +86,8 @@ - {{request.itemDescription}} @@ -114,13 +114,13 @@ - - - @@ -149,24 +149,24 @@ ng-click="contextmenu.filterBySelection()"> Filter by selection - Exclude selection - Remove filter - Remove all filters - Copy value - \ No newline at end of file + From 83cff374227dc893ddd5e7ae405260ab8411079e Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 26 Oct 2023 08:23:18 +0200 Subject: [PATCH 141/449] refs #6350 fix: 00-dropWorkerCreate.sql --- db/changes/234201/00-dropWorkerCreate.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/changes/234201/00-dropWorkerCreate.sql b/db/changes/234201/00-dropWorkerCreate.sql index be2761c3d1..b903909b6b 100644 --- a/db/changes/234201/00-dropWorkerCreate.sql +++ b/db/changes/234201/00-dropWorkerCreate.sql @@ -1 +1 @@ -DROP PROCEDURE IF EXISTS vn.workerCreate; \ No newline at end of file +DROP PROCEDURE IF EXISTS `vn`.`workerCreate`; From 3a1227bdc225545d46c3ee47191759e2ba4d9bba Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 26 Oct 2023 09:20:25 +0200 Subject: [PATCH 142/449] ref #5914 fix ticketrefund --- modules/ticket/back/methods/sale/clone.js | 33 +++++++++++++---------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/modules/ticket/back/methods/sale/clone.js b/modules/ticket/back/methods/sale/clone.js index a72f17af64..a5ccb6de4e 100644 --- a/modules/ticket/back/methods/sale/clone.js +++ b/modules/ticket/back/methods/sale/clone.js @@ -3,7 +3,7 @@ module.exports = Self => { const models = Self.app.models; const myOptions = {}; let tx; - const refundTickets = []; + const newTickets = []; if (typeof options == 'object') Object.assign(myOptions, options); @@ -31,21 +31,22 @@ module.exports = Self => { if (group) ticketsIds = [ticketsIds[0]]; for (let ticketId of ticketsIds) { - const ticketRefund = await createTicketRefund( + const newTicket = await createTicket( ctx, ticketId, withWarehouse, + negative, myOptions ); - refundTickets.push(ticketRefund); - mappedTickets.set(ticketId, ticketRefund.id); + newTickets.push(newTicket); + mappedTickets.set(ticketId, newTicket.id); } for (const sale of sales) { - const refundTicketId = mappedTickets.get(sale.ticketFk); + const newTicketId = mappedTickets.get(sale.ticketFk); const createdSale = await models.Sale.create({ - ticketFk: refundTicketId, + ticketFk: newTicketId, itemFk: sale.itemFk, quantity: negative ? - sale.quantity : sale.quantity, concept: sale.concept, @@ -67,14 +68,14 @@ module.exports = Self => { const services = await models.TicketService.find(servicesFilter, myOptions); for (const service of services) { - const refundTicketId = mappedTickets.get(service.ticketFk); + const newTicketId = mappedTickets.get(service.ticketFk); await models.TicketService.create({ description: service.description, quantity: negative ? - service.quantity : service.quantity, price: service.price, taxClassFk: service.taxClassFk, - ticketFk: refundTicketId, + ticketFk: newTicketId, ticketServiceTypeFk: service.ticketServiceTypeFk, }, myOptions); } @@ -82,16 +83,17 @@ module.exports = Self => { if (tx) await tx.commit(); - return refundTickets; + return newTickets; } catch (e) { if (tx) await tx.rollback(); throw e; } - async function createTicketRefund( + async function createTicket( ctx, ticketId, withWarehouse, + negative, myOptions ) { const models = Self.app.models; @@ -106,10 +108,13 @@ module.exports = Self => { ctx.args.addressId = ticket.addressFk; const newTicket = await models.Ticket.new(ctx, myOptions); - await models.TicketRefund.create({ - originalTicketFk: ticketId, - refundTicketFk: newTicket.id - }, myOptions); + + if (negative) { + await models.TicketRefund.create({ + originalTicketFk: ticketId, + refundTicketFk: newTicket.id + }, myOptions); + } return newTicket; } From cecdf8633cea829928b37608f14ea7e97e29184f Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 26 Oct 2023 09:27:32 +0200 Subject: [PATCH 143/449] refs #6350 deploy: init version 23.46 --- CHANGELOG.md | 8 +++++++- db/{changes => .archive}/231201/00-ACL.sql | 0 db/{changes => .archive}/231201/00-chatRefactor.sql | 0 db/{changes => .archive}/231201/00-invoiceInSerial.sql | 0 db/{changes => .archive}/231201/00-itemType_isFragile.sql | 0 db/{changes => .archive}/231201/00-mailACL.sql | 0 db/{changes => .archive}/231201/00-operator.sql | 0 .../231201/00-supplierAccount_deleteTriggers.sql | 0 db/{changes => .archive}/231201/00-ticket_getWarnings.sql | 0 db/{changes => .archive}/231201/00-wagon.sql | 0 db/{changes => .archive}/231202/00-delivery.sql | 0 db/{changes => .archive}/231203/00-delivery.sql | 0 db/{changes => .archive}/231204/00-rollbackDelivery.sql | 0 db/{changes => .archive}/231205/00-printQueueArgs.sql | 0 .../231401/00-claimBeginningAfterInsert.sql | 0 db/{changes => .archive}/231401/00-clientBeforeUpdate.sql | 0 db/{changes => .archive}/231401/00-hotfixDelivery.sql | 0 .../231401/00-invoiceOutAfterInsert.sql | 0 db/{changes => .archive}/231401/00-negativeBases.sql | 0 db/{changes => .archive}/231401/00-workerNotes.sql | 0 db/{changes => .archive}/231402/00-negativeBases.sql | 0 db/{changes => .archive}/231801/00-aclClientInforma.sql | 0 db/{changes => .archive}/231801/00-acl_receiptEmail.sql | 0 db/{changes => .archive}/231801/00-clientInforma.sql | 0 .../231801/00-client_setRatingAcl.sql | 0 db/{changes => .archive}/231801/00-deleteProcs_refund.sql | 0 db/{changes => .archive}/231801/00-deviceProduction.sql | 0 db/{changes => .archive}/231801/00-kkearEntryNotes.sql | 0 db/{changes => .archive}/231801/00-newCompanyI18n.sql | 0 db/{changes => .archive}/231801/00-newTableWeb.sql | 0 .../231801/00-observationEmailACL.sql | 0 .../231801/00-optimiceZoneEstimatedDelivery.sql | 0 db/{changes => .archive}/231801/00-saleTracking.sql | 0 db/{changes => .archive}/231801/00-ticketConfig.sql | 0 db/{changes => .archive}/231801/00-updateIsVies.sql | 0 db/{changes => .archive}/231801/00-updateisViesClient.sql | 0 db/{changes => .archive}/231801/00-userAcl.sql | 0 db/{changes => .archive}/231801/00-userRoleLog.sql | 0 db/{changes => .archive}/231801/01-viewCompany10L.sql | 0 db/{changes => .archive}/232001/00-clientWorkerName.sql | 0 db/{changes => .archive}/232001/00-createWorker.sql | 0 db/{changes => .archive}/232001/00-invoiceOut_new.sql | 0 db/{changes => .archive}/232001/00-wagon.sql | 0 db/{changes => .archive}/232201/00-defaulterView.sql | 0 .../232201/00-procedurecanAdvance.sql | 0 .../232201/00-procedurecanbePostponed.sql | 0 .../232201/00-workerConfigPayMethod.sql | 0 .../232202/00-procedurecanAdvance.sql | 0 .../232202/00-procedurecanbePostponed.sql | 0 db/{changes => .archive}/232401/.gitkeep | 0 .../232401/00-buyConfig_travelConfig.sql | 0 db/{changes => .archive}/232401/00-printer.sql | 0 db/{changes => .archive}/232401/00-ticket_warehouse.sql | 0 db/{changes => .archive}/232401/00-userPassExpired.sql | 0 .../232402/00-hotFix_travelConfig.sql | 0 db/{changes => .archive}/232601/00-aclAccount.sql | 0 db/{changes => .archive}/232601/00-aclInvoiceTickets.sql | 0 .../232601/00-aclMailAliasAccount.sql | 0 db/{changes => .archive}/232601/00-aclMailForward.sql | 0 db/{changes => .archive}/232601/00-aclRole.sql | 0 db/{changes => .archive}/232601/00-aclVnUser.sql | 0 .../232601/00-aclVnUser_renewToken.sql | 0 .../232601/00-entry_updateComission.sql | 0 .../232601/00-packingSiteAdvanced.sql | 0 db/{changes => .archive}/232601/00-salix.sql | 0 db/{changes => .archive}/232601/00-useSpecificsAcls.sql | 0 db/{changes => .archive}/232601/01-invoiceOutPdf.sql | 0 db/{changes => .archive}/232602/01-aclAddAlias.sql | 0 db/{changes => .archive}/232801/00-authCode.sql | 0 db/{changes => .archive}/232801/00-client_create.sql | 0 db/{changes => .archive}/232801/00-client_create2.sql | 0 db/{changes => .archive}/232801/00-department.sql | 0 db/{changes => .archive}/232801/00-fix_editCredit.sql | 0 db/{changes => .archive}/232801/00-user.sql | 0 db/{changes => .archive}/232802/01-aclWorkerDisable.sql | 0 db/changes/234601/.gitkeep | 0 package-lock.json | 4 ++-- package.json | 2 +- 78 files changed, 10 insertions(+), 4 deletions(-) rename db/{changes => .archive}/231201/00-ACL.sql (100%) rename db/{changes => .archive}/231201/00-chatRefactor.sql (100%) rename db/{changes => .archive}/231201/00-invoiceInSerial.sql (100%) rename db/{changes => .archive}/231201/00-itemType_isFragile.sql (100%) rename db/{changes => .archive}/231201/00-mailACL.sql (100%) rename db/{changes => .archive}/231201/00-operator.sql (100%) rename db/{changes => .archive}/231201/00-supplierAccount_deleteTriggers.sql (100%) rename db/{changes => .archive}/231201/00-ticket_getWarnings.sql (100%) rename db/{changes => .archive}/231201/00-wagon.sql (100%) rename db/{changes => .archive}/231202/00-delivery.sql (100%) rename db/{changes => .archive}/231203/00-delivery.sql (100%) rename db/{changes => .archive}/231204/00-rollbackDelivery.sql (100%) rename db/{changes => .archive}/231205/00-printQueueArgs.sql (100%) rename db/{changes => .archive}/231401/00-claimBeginningAfterInsert.sql (100%) rename db/{changes => .archive}/231401/00-clientBeforeUpdate.sql (100%) rename db/{changes => .archive}/231401/00-hotfixDelivery.sql (100%) rename db/{changes => .archive}/231401/00-invoiceOutAfterInsert.sql (100%) rename db/{changes => .archive}/231401/00-negativeBases.sql (100%) rename db/{changes => .archive}/231401/00-workerNotes.sql (100%) rename db/{changes => .archive}/231402/00-negativeBases.sql (100%) rename db/{changes => .archive}/231801/00-aclClientInforma.sql (100%) rename db/{changes => .archive}/231801/00-acl_receiptEmail.sql (100%) rename db/{changes => .archive}/231801/00-clientInforma.sql (100%) rename db/{changes => .archive}/231801/00-client_setRatingAcl.sql (100%) rename db/{changes => .archive}/231801/00-deleteProcs_refund.sql (100%) rename db/{changes => .archive}/231801/00-deviceProduction.sql (100%) rename db/{changes => .archive}/231801/00-kkearEntryNotes.sql (100%) rename db/{changes => .archive}/231801/00-newCompanyI18n.sql (100%) rename db/{changes => .archive}/231801/00-newTableWeb.sql (100%) rename db/{changes => .archive}/231801/00-observationEmailACL.sql (100%) rename db/{changes => .archive}/231801/00-optimiceZoneEstimatedDelivery.sql (100%) rename db/{changes => .archive}/231801/00-saleTracking.sql (100%) rename db/{changes => .archive}/231801/00-ticketConfig.sql (100%) rename db/{changes => .archive}/231801/00-updateIsVies.sql (100%) rename db/{changes => .archive}/231801/00-updateisViesClient.sql (100%) rename db/{changes => .archive}/231801/00-userAcl.sql (100%) rename db/{changes => .archive}/231801/00-userRoleLog.sql (100%) rename db/{changes => .archive}/231801/01-viewCompany10L.sql (100%) rename db/{changes => .archive}/232001/00-clientWorkerName.sql (100%) rename db/{changes => .archive}/232001/00-createWorker.sql (100%) rename db/{changes => .archive}/232001/00-invoiceOut_new.sql (100%) rename db/{changes => .archive}/232001/00-wagon.sql (100%) rename db/{changes => .archive}/232201/00-defaulterView.sql (100%) rename db/{changes => .archive}/232201/00-procedurecanAdvance.sql (100%) rename db/{changes => .archive}/232201/00-procedurecanbePostponed.sql (100%) rename db/{changes => .archive}/232201/00-workerConfigPayMethod.sql (100%) rename db/{changes => .archive}/232202/00-procedurecanAdvance.sql (100%) rename db/{changes => .archive}/232202/00-procedurecanbePostponed.sql (100%) rename db/{changes => .archive}/232401/.gitkeep (100%) rename db/{changes => .archive}/232401/00-buyConfig_travelConfig.sql (100%) rename db/{changes => .archive}/232401/00-printer.sql (100%) rename db/{changes => .archive}/232401/00-ticket_warehouse.sql (100%) rename db/{changes => .archive}/232401/00-userPassExpired.sql (100%) rename db/{changes => .archive}/232402/00-hotFix_travelConfig.sql (100%) rename db/{changes => .archive}/232601/00-aclAccount.sql (100%) rename db/{changes => .archive}/232601/00-aclInvoiceTickets.sql (100%) rename db/{changes => .archive}/232601/00-aclMailAliasAccount.sql (100%) rename db/{changes => .archive}/232601/00-aclMailForward.sql (100%) rename db/{changes => .archive}/232601/00-aclRole.sql (100%) rename db/{changes => .archive}/232601/00-aclVnUser.sql (100%) rename db/{changes => .archive}/232601/00-aclVnUser_renewToken.sql (100%) rename db/{changes => .archive}/232601/00-entry_updateComission.sql (100%) rename db/{changes => .archive}/232601/00-packingSiteAdvanced.sql (100%) rename db/{changes => .archive}/232601/00-salix.sql (100%) rename db/{changes => .archive}/232601/00-useSpecificsAcls.sql (100%) rename db/{changes => .archive}/232601/01-invoiceOutPdf.sql (100%) rename db/{changes => .archive}/232602/01-aclAddAlias.sql (100%) rename db/{changes => .archive}/232801/00-authCode.sql (100%) rename db/{changes => .archive}/232801/00-client_create.sql (100%) rename db/{changes => .archive}/232801/00-client_create2.sql (100%) rename db/{changes => .archive}/232801/00-department.sql (100%) rename db/{changes => .archive}/232801/00-fix_editCredit.sql (100%) rename db/{changes => .archive}/232801/00-user.sql (100%) rename db/{changes => .archive}/232802/01-aclWorkerDisable.sql (100%) create mode 100644 db/changes/234601/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index d677b80e34..cd6ed45222 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,13 @@ 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). -## [2342.01] - 2023-10-19 +## [2346.01] - 2023-11-16 + +### Added +### Changed +### Fixed + +## [2342.01] - 2023-11-02 ### Added ### Changed diff --git a/db/changes/231201/00-ACL.sql b/db/.archive/231201/00-ACL.sql similarity index 100% rename from db/changes/231201/00-ACL.sql rename to db/.archive/231201/00-ACL.sql diff --git a/db/changes/231201/00-chatRefactor.sql b/db/.archive/231201/00-chatRefactor.sql similarity index 100% rename from db/changes/231201/00-chatRefactor.sql rename to db/.archive/231201/00-chatRefactor.sql diff --git a/db/changes/231201/00-invoiceInSerial.sql b/db/.archive/231201/00-invoiceInSerial.sql similarity index 100% rename from db/changes/231201/00-invoiceInSerial.sql rename to db/.archive/231201/00-invoiceInSerial.sql diff --git a/db/changes/231201/00-itemType_isFragile.sql b/db/.archive/231201/00-itemType_isFragile.sql similarity index 100% rename from db/changes/231201/00-itemType_isFragile.sql rename to db/.archive/231201/00-itemType_isFragile.sql diff --git a/db/changes/231201/00-mailACL.sql b/db/.archive/231201/00-mailACL.sql similarity index 100% rename from db/changes/231201/00-mailACL.sql rename to db/.archive/231201/00-mailACL.sql diff --git a/db/changes/231201/00-operator.sql b/db/.archive/231201/00-operator.sql similarity index 100% rename from db/changes/231201/00-operator.sql rename to db/.archive/231201/00-operator.sql diff --git a/db/changes/231201/00-supplierAccount_deleteTriggers.sql b/db/.archive/231201/00-supplierAccount_deleteTriggers.sql similarity index 100% rename from db/changes/231201/00-supplierAccount_deleteTriggers.sql rename to db/.archive/231201/00-supplierAccount_deleteTriggers.sql diff --git a/db/changes/231201/00-ticket_getWarnings.sql b/db/.archive/231201/00-ticket_getWarnings.sql similarity index 100% rename from db/changes/231201/00-ticket_getWarnings.sql rename to db/.archive/231201/00-ticket_getWarnings.sql diff --git a/db/changes/231201/00-wagon.sql b/db/.archive/231201/00-wagon.sql similarity index 100% rename from db/changes/231201/00-wagon.sql rename to db/.archive/231201/00-wagon.sql diff --git a/db/changes/231202/00-delivery.sql b/db/.archive/231202/00-delivery.sql similarity index 100% rename from db/changes/231202/00-delivery.sql rename to db/.archive/231202/00-delivery.sql diff --git a/db/changes/231203/00-delivery.sql b/db/.archive/231203/00-delivery.sql similarity index 100% rename from db/changes/231203/00-delivery.sql rename to db/.archive/231203/00-delivery.sql diff --git a/db/changes/231204/00-rollbackDelivery.sql b/db/.archive/231204/00-rollbackDelivery.sql similarity index 100% rename from db/changes/231204/00-rollbackDelivery.sql rename to db/.archive/231204/00-rollbackDelivery.sql diff --git a/db/changes/231205/00-printQueueArgs.sql b/db/.archive/231205/00-printQueueArgs.sql similarity index 100% rename from db/changes/231205/00-printQueueArgs.sql rename to db/.archive/231205/00-printQueueArgs.sql diff --git a/db/changes/231401/00-claimBeginningAfterInsert.sql b/db/.archive/231401/00-claimBeginningAfterInsert.sql similarity index 100% rename from db/changes/231401/00-claimBeginningAfterInsert.sql rename to db/.archive/231401/00-claimBeginningAfterInsert.sql diff --git a/db/changes/231401/00-clientBeforeUpdate.sql b/db/.archive/231401/00-clientBeforeUpdate.sql similarity index 100% rename from db/changes/231401/00-clientBeforeUpdate.sql rename to db/.archive/231401/00-clientBeforeUpdate.sql diff --git a/db/changes/231401/00-hotfixDelivery.sql b/db/.archive/231401/00-hotfixDelivery.sql similarity index 100% rename from db/changes/231401/00-hotfixDelivery.sql rename to db/.archive/231401/00-hotfixDelivery.sql diff --git a/db/changes/231401/00-invoiceOutAfterInsert.sql b/db/.archive/231401/00-invoiceOutAfterInsert.sql similarity index 100% rename from db/changes/231401/00-invoiceOutAfterInsert.sql rename to db/.archive/231401/00-invoiceOutAfterInsert.sql diff --git a/db/changes/231401/00-negativeBases.sql b/db/.archive/231401/00-negativeBases.sql similarity index 100% rename from db/changes/231401/00-negativeBases.sql rename to db/.archive/231401/00-negativeBases.sql diff --git a/db/changes/231401/00-workerNotes.sql b/db/.archive/231401/00-workerNotes.sql similarity index 100% rename from db/changes/231401/00-workerNotes.sql rename to db/.archive/231401/00-workerNotes.sql diff --git a/db/changes/231402/00-negativeBases.sql b/db/.archive/231402/00-negativeBases.sql similarity index 100% rename from db/changes/231402/00-negativeBases.sql rename to db/.archive/231402/00-negativeBases.sql diff --git a/db/changes/231801/00-aclClientInforma.sql b/db/.archive/231801/00-aclClientInforma.sql similarity index 100% rename from db/changes/231801/00-aclClientInforma.sql rename to db/.archive/231801/00-aclClientInforma.sql diff --git a/db/changes/231801/00-acl_receiptEmail.sql b/db/.archive/231801/00-acl_receiptEmail.sql similarity index 100% rename from db/changes/231801/00-acl_receiptEmail.sql rename to db/.archive/231801/00-acl_receiptEmail.sql diff --git a/db/changes/231801/00-clientInforma.sql b/db/.archive/231801/00-clientInforma.sql similarity index 100% rename from db/changes/231801/00-clientInforma.sql rename to db/.archive/231801/00-clientInforma.sql diff --git a/db/changes/231801/00-client_setRatingAcl.sql b/db/.archive/231801/00-client_setRatingAcl.sql similarity index 100% rename from db/changes/231801/00-client_setRatingAcl.sql rename to db/.archive/231801/00-client_setRatingAcl.sql diff --git a/db/changes/231801/00-deleteProcs_refund.sql b/db/.archive/231801/00-deleteProcs_refund.sql similarity index 100% rename from db/changes/231801/00-deleteProcs_refund.sql rename to db/.archive/231801/00-deleteProcs_refund.sql diff --git a/db/changes/231801/00-deviceProduction.sql b/db/.archive/231801/00-deviceProduction.sql similarity index 100% rename from db/changes/231801/00-deviceProduction.sql rename to db/.archive/231801/00-deviceProduction.sql diff --git a/db/changes/231801/00-kkearEntryNotes.sql b/db/.archive/231801/00-kkearEntryNotes.sql similarity index 100% rename from db/changes/231801/00-kkearEntryNotes.sql rename to db/.archive/231801/00-kkearEntryNotes.sql diff --git a/db/changes/231801/00-newCompanyI18n.sql b/db/.archive/231801/00-newCompanyI18n.sql similarity index 100% rename from db/changes/231801/00-newCompanyI18n.sql rename to db/.archive/231801/00-newCompanyI18n.sql diff --git a/db/changes/231801/00-newTableWeb.sql b/db/.archive/231801/00-newTableWeb.sql similarity index 100% rename from db/changes/231801/00-newTableWeb.sql rename to db/.archive/231801/00-newTableWeb.sql diff --git a/db/changes/231801/00-observationEmailACL.sql b/db/.archive/231801/00-observationEmailACL.sql similarity index 100% rename from db/changes/231801/00-observationEmailACL.sql rename to db/.archive/231801/00-observationEmailACL.sql diff --git a/db/changes/231801/00-optimiceZoneEstimatedDelivery.sql b/db/.archive/231801/00-optimiceZoneEstimatedDelivery.sql similarity index 100% rename from db/changes/231801/00-optimiceZoneEstimatedDelivery.sql rename to db/.archive/231801/00-optimiceZoneEstimatedDelivery.sql diff --git a/db/changes/231801/00-saleTracking.sql b/db/.archive/231801/00-saleTracking.sql similarity index 100% rename from db/changes/231801/00-saleTracking.sql rename to db/.archive/231801/00-saleTracking.sql diff --git a/db/changes/231801/00-ticketConfig.sql b/db/.archive/231801/00-ticketConfig.sql similarity index 100% rename from db/changes/231801/00-ticketConfig.sql rename to db/.archive/231801/00-ticketConfig.sql diff --git a/db/changes/231801/00-updateIsVies.sql b/db/.archive/231801/00-updateIsVies.sql similarity index 100% rename from db/changes/231801/00-updateIsVies.sql rename to db/.archive/231801/00-updateIsVies.sql diff --git a/db/changes/231801/00-updateisViesClient.sql b/db/.archive/231801/00-updateisViesClient.sql similarity index 100% rename from db/changes/231801/00-updateisViesClient.sql rename to db/.archive/231801/00-updateisViesClient.sql diff --git a/db/changes/231801/00-userAcl.sql b/db/.archive/231801/00-userAcl.sql similarity index 100% rename from db/changes/231801/00-userAcl.sql rename to db/.archive/231801/00-userAcl.sql diff --git a/db/changes/231801/00-userRoleLog.sql b/db/.archive/231801/00-userRoleLog.sql similarity index 100% rename from db/changes/231801/00-userRoleLog.sql rename to db/.archive/231801/00-userRoleLog.sql diff --git a/db/changes/231801/01-viewCompany10L.sql b/db/.archive/231801/01-viewCompany10L.sql similarity index 100% rename from db/changes/231801/01-viewCompany10L.sql rename to db/.archive/231801/01-viewCompany10L.sql diff --git a/db/changes/232001/00-clientWorkerName.sql b/db/.archive/232001/00-clientWorkerName.sql similarity index 100% rename from db/changes/232001/00-clientWorkerName.sql rename to db/.archive/232001/00-clientWorkerName.sql diff --git a/db/changes/232001/00-createWorker.sql b/db/.archive/232001/00-createWorker.sql similarity index 100% rename from db/changes/232001/00-createWorker.sql rename to db/.archive/232001/00-createWorker.sql diff --git a/db/changes/232001/00-invoiceOut_new.sql b/db/.archive/232001/00-invoiceOut_new.sql similarity index 100% rename from db/changes/232001/00-invoiceOut_new.sql rename to db/.archive/232001/00-invoiceOut_new.sql diff --git a/db/changes/232001/00-wagon.sql b/db/.archive/232001/00-wagon.sql similarity index 100% rename from db/changes/232001/00-wagon.sql rename to db/.archive/232001/00-wagon.sql diff --git a/db/changes/232201/00-defaulterView.sql b/db/.archive/232201/00-defaulterView.sql similarity index 100% rename from db/changes/232201/00-defaulterView.sql rename to db/.archive/232201/00-defaulterView.sql diff --git a/db/changes/232201/00-procedurecanAdvance.sql b/db/.archive/232201/00-procedurecanAdvance.sql similarity index 100% rename from db/changes/232201/00-procedurecanAdvance.sql rename to db/.archive/232201/00-procedurecanAdvance.sql diff --git a/db/changes/232201/00-procedurecanbePostponed.sql b/db/.archive/232201/00-procedurecanbePostponed.sql similarity index 100% rename from db/changes/232201/00-procedurecanbePostponed.sql rename to db/.archive/232201/00-procedurecanbePostponed.sql diff --git a/db/changes/232201/00-workerConfigPayMethod.sql b/db/.archive/232201/00-workerConfigPayMethod.sql similarity index 100% rename from db/changes/232201/00-workerConfigPayMethod.sql rename to db/.archive/232201/00-workerConfigPayMethod.sql diff --git a/db/changes/232202/00-procedurecanAdvance.sql b/db/.archive/232202/00-procedurecanAdvance.sql similarity index 100% rename from db/changes/232202/00-procedurecanAdvance.sql rename to db/.archive/232202/00-procedurecanAdvance.sql diff --git a/db/changes/232202/00-procedurecanbePostponed.sql b/db/.archive/232202/00-procedurecanbePostponed.sql similarity index 100% rename from db/changes/232202/00-procedurecanbePostponed.sql rename to db/.archive/232202/00-procedurecanbePostponed.sql diff --git a/db/changes/232401/.gitkeep b/db/.archive/232401/.gitkeep similarity index 100% rename from db/changes/232401/.gitkeep rename to db/.archive/232401/.gitkeep diff --git a/db/changes/232401/00-buyConfig_travelConfig.sql b/db/.archive/232401/00-buyConfig_travelConfig.sql similarity index 100% rename from db/changes/232401/00-buyConfig_travelConfig.sql rename to db/.archive/232401/00-buyConfig_travelConfig.sql diff --git a/db/changes/232401/00-printer.sql b/db/.archive/232401/00-printer.sql similarity index 100% rename from db/changes/232401/00-printer.sql rename to db/.archive/232401/00-printer.sql diff --git a/db/changes/232401/00-ticket_warehouse.sql b/db/.archive/232401/00-ticket_warehouse.sql similarity index 100% rename from db/changes/232401/00-ticket_warehouse.sql rename to db/.archive/232401/00-ticket_warehouse.sql diff --git a/db/changes/232401/00-userPassExpired.sql b/db/.archive/232401/00-userPassExpired.sql similarity index 100% rename from db/changes/232401/00-userPassExpired.sql rename to db/.archive/232401/00-userPassExpired.sql diff --git a/db/changes/232402/00-hotFix_travelConfig.sql b/db/.archive/232402/00-hotFix_travelConfig.sql similarity index 100% rename from db/changes/232402/00-hotFix_travelConfig.sql rename to db/.archive/232402/00-hotFix_travelConfig.sql diff --git a/db/changes/232601/00-aclAccount.sql b/db/.archive/232601/00-aclAccount.sql similarity index 100% rename from db/changes/232601/00-aclAccount.sql rename to db/.archive/232601/00-aclAccount.sql diff --git a/db/changes/232601/00-aclInvoiceTickets.sql b/db/.archive/232601/00-aclInvoiceTickets.sql similarity index 100% rename from db/changes/232601/00-aclInvoiceTickets.sql rename to db/.archive/232601/00-aclInvoiceTickets.sql diff --git a/db/changes/232601/00-aclMailAliasAccount.sql b/db/.archive/232601/00-aclMailAliasAccount.sql similarity index 100% rename from db/changes/232601/00-aclMailAliasAccount.sql rename to db/.archive/232601/00-aclMailAliasAccount.sql diff --git a/db/changes/232601/00-aclMailForward.sql b/db/.archive/232601/00-aclMailForward.sql similarity index 100% rename from db/changes/232601/00-aclMailForward.sql rename to db/.archive/232601/00-aclMailForward.sql diff --git a/db/changes/232601/00-aclRole.sql b/db/.archive/232601/00-aclRole.sql similarity index 100% rename from db/changes/232601/00-aclRole.sql rename to db/.archive/232601/00-aclRole.sql diff --git a/db/changes/232601/00-aclVnUser.sql b/db/.archive/232601/00-aclVnUser.sql similarity index 100% rename from db/changes/232601/00-aclVnUser.sql rename to db/.archive/232601/00-aclVnUser.sql diff --git a/db/changes/232601/00-aclVnUser_renewToken.sql b/db/.archive/232601/00-aclVnUser_renewToken.sql similarity index 100% rename from db/changes/232601/00-aclVnUser_renewToken.sql rename to db/.archive/232601/00-aclVnUser_renewToken.sql diff --git a/db/changes/232601/00-entry_updateComission.sql b/db/.archive/232601/00-entry_updateComission.sql similarity index 100% rename from db/changes/232601/00-entry_updateComission.sql rename to db/.archive/232601/00-entry_updateComission.sql diff --git a/db/changes/232601/00-packingSiteAdvanced.sql b/db/.archive/232601/00-packingSiteAdvanced.sql similarity index 100% rename from db/changes/232601/00-packingSiteAdvanced.sql rename to db/.archive/232601/00-packingSiteAdvanced.sql diff --git a/db/changes/232601/00-salix.sql b/db/.archive/232601/00-salix.sql similarity index 100% rename from db/changes/232601/00-salix.sql rename to db/.archive/232601/00-salix.sql diff --git a/db/changes/232601/00-useSpecificsAcls.sql b/db/.archive/232601/00-useSpecificsAcls.sql similarity index 100% rename from db/changes/232601/00-useSpecificsAcls.sql rename to db/.archive/232601/00-useSpecificsAcls.sql diff --git a/db/changes/232601/01-invoiceOutPdf.sql b/db/.archive/232601/01-invoiceOutPdf.sql similarity index 100% rename from db/changes/232601/01-invoiceOutPdf.sql rename to db/.archive/232601/01-invoiceOutPdf.sql diff --git a/db/changes/232602/01-aclAddAlias.sql b/db/.archive/232602/01-aclAddAlias.sql similarity index 100% rename from db/changes/232602/01-aclAddAlias.sql rename to db/.archive/232602/01-aclAddAlias.sql diff --git a/db/changes/232801/00-authCode.sql b/db/.archive/232801/00-authCode.sql similarity index 100% rename from db/changes/232801/00-authCode.sql rename to db/.archive/232801/00-authCode.sql diff --git a/db/changes/232801/00-client_create.sql b/db/.archive/232801/00-client_create.sql similarity index 100% rename from db/changes/232801/00-client_create.sql rename to db/.archive/232801/00-client_create.sql diff --git a/db/changes/232801/00-client_create2.sql b/db/.archive/232801/00-client_create2.sql similarity index 100% rename from db/changes/232801/00-client_create2.sql rename to db/.archive/232801/00-client_create2.sql diff --git a/db/changes/232801/00-department.sql b/db/.archive/232801/00-department.sql similarity index 100% rename from db/changes/232801/00-department.sql rename to db/.archive/232801/00-department.sql diff --git a/db/changes/232801/00-fix_editCredit.sql b/db/.archive/232801/00-fix_editCredit.sql similarity index 100% rename from db/changes/232801/00-fix_editCredit.sql rename to db/.archive/232801/00-fix_editCredit.sql diff --git a/db/changes/232801/00-user.sql b/db/.archive/232801/00-user.sql similarity index 100% rename from db/changes/232801/00-user.sql rename to db/.archive/232801/00-user.sql diff --git a/db/changes/232802/01-aclWorkerDisable.sql b/db/.archive/232802/01-aclWorkerDisable.sql similarity index 100% rename from db/changes/232802/01-aclWorkerDisable.sql rename to db/.archive/232802/01-aclWorkerDisable.sql diff --git a/db/changes/234601/.gitkeep b/db/changes/234601/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package-lock.json b/package-lock.json index c3f88bc2c7..5bf7a2cb1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "salix-back", - "version": "23.42.01", + "version": "23.46.01", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "salix-back", - "version": "23.42.01", + "version": "23.46.01", "license": "GPL-3.0", "dependencies": { "axios": "^1.2.2", diff --git a/package.json b/package.json index 3320705f56..b1539f9a06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.42.01", + "version": "23.46.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From e0b4ac733e32e44225931b38d2f0a16236dfc12c Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 26 Oct 2023 09:30:48 +0200 Subject: [PATCH 144/449] ref #5914 move changes --- db/changes/{234201 => 234601}/00-transferInvoice.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{234201 => 234601}/00-transferInvoice.sql (100%) diff --git a/db/changes/234201/00-transferInvoice.sql b/db/changes/234601/00-transferInvoice.sql similarity index 100% rename from db/changes/234201/00-transferInvoice.sql rename to db/changes/234601/00-transferInvoice.sql From 55d80458ccf644085d471080de1bd4c7957a8e09 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 26 Oct 2023 14:37:42 +0200 Subject: [PATCH 145/449] refs #6065 warmFix(workerTimeControl): set date --- modules/worker/front/time-control/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index 9137d78393..a60c715899 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -111,9 +111,10 @@ class Controller extends Section { dayIndex.setDate(dayIndex.getDate() + 1); } - if (!this.weekTotalHours) this.fetchHours(); - if (this.worker) + if (this.worker) { + this.fetchHours(); this.getWeekData(); + } } set weekTotalHours(totalHours) { From 9708f66cefa8cc23fee424202a1659810041d51a Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 27 Oct 2023 12:36:28 +0200 Subject: [PATCH 146/449] merge(dev): refs #4131 merge dev move sql files --- .../00-ACLticketTrackingState.sql | 0 .../00-ticketSetStateRefactor.sql | 18 ++---------------- 2 files changed, 2 insertions(+), 16 deletions(-) rename db/changes/{233801 => 234601}/00-ACLticketTrackingState.sql (100%) rename db/changes/{233801 => 234601}/00-ticketSetStateRefactor.sql (73%) diff --git a/db/changes/233801/00-ACLticketTrackingState.sql b/db/changes/234601/00-ACLticketTrackingState.sql similarity index 100% rename from db/changes/233801/00-ACLticketTrackingState.sql rename to db/changes/234601/00-ACLticketTrackingState.sql diff --git a/db/changes/233801/00-ticketSetStateRefactor.sql b/db/changes/234601/00-ticketSetStateRefactor.sql similarity index 73% rename from db/changes/233801/00-ticketSetStateRefactor.sql rename to db/changes/234601/00-ticketSetStateRefactor.sql index 1ad4532994..9078ffb0e4 100644 --- a/db/changes/233801/00-ticketSetStateRefactor.sql +++ b/db/changes/234601/00-ticketSetStateRefactor.sql @@ -14,37 +14,23 @@ BEGIN DECLARE vTicketStateCode VARCHAR(255); DECLARE vCanChangeState BOOL; DECLARE vPackedAlertLevel INT; - DECLARE vOnPreparationAlertLevel INT; - DECLARE vNextAlertLevel INT; DECLARE vZoneFk INT; - SELECT s.alertLevel, s.`code`, s2.alertLevel, t.zoneFk - INTO vticketAlertLevel, vTicketStateCode, vNextAlertLevel , vZoneFk + SELECT s.alertLevel, s.`code`, t.zoneFk + INTO vticketAlertLevel, vTicketStateCode, vZoneFk FROM state s JOIN ticketTracking tt ON tt.stateFk = s.id - JOIN state s2 ON s2.code = vStateCode JOIN ticket t ON t.id = tt.ticketFk WHERE tt.ticketFk = vSelf ORDER BY tt.created DESC LIMIT 1; SELECT id INTO vPackedAlertLevel FROM alertLevel WHERE code = 'PACKED'; - SELECT id INTO vOnPreparationAlertLevel - FROM alertLevel - WHERE code = 'ON_PREPARATION'; IF vStateCode = 'OK' AND vZoneFk IS NULL THEN CALL util.throw('ASSIGN_ZONE_FIRST'); END IF; - IF vNextAlertLevel > vticketAlertLevel && - vticketAlertLevel < vOnPreparationAlertLevel - THEN - UPDATE sale - SET originalQuantity = quantity - WHERE ticketFk = vSelf; - END IF; - SET vCanChangeState = ( vStateCode <> 'ON_CHECKING' OR vticketAlertLevel < vPackedAlertLevel From 42bbdf9814b8b3593c15616dff1f69d8e2cc405b Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 27 Oct 2023 13:41:32 +0200 Subject: [PATCH 147/449] feat(ticket.state): refs #4131 convert changeState to State --- .../back/methods/ticket-tracking/setDelivered.js | 2 +- .../specs/state.spec.js} | 14 ++++++++------ .../methods/{ticket-tracking => ticket}/state.js | 0 modules/ticket/back/models/ticket-tracking.js | 1 - modules/ticket/back/models/ticket.js | 1 + 5 files changed, 10 insertions(+), 8 deletions(-) rename modules/ticket/back/methods/{ticket-tracking/specs/changeState.spec.js => ticket/specs/state.spec.js} (89%) rename modules/ticket/back/methods/{ticket-tracking => ticket}/state.js (100%) diff --git a/modules/ticket/back/methods/ticket-tracking/setDelivered.js b/modules/ticket/back/methods/ticket-tracking/setDelivered.js index ac267eb1aa..d3cdb192f1 100644 --- a/modules/ticket/back/methods/ticket-tracking/setDelivered.js +++ b/modules/ticket/back/methods/ticket-tracking/setDelivered.js @@ -47,7 +47,7 @@ module.exports = Self => { const promises = []; for (const id of ticketIds) { - const promise = models.TicketTracking.state(ctx, { + const promise = await models.Ticket.state(ctx, { stateFk: state.id, workerFk: worker.id, ticketFk: id diff --git a/modules/ticket/back/methods/ticket-tracking/specs/changeState.spec.js b/modules/ticket/back/methods/ticket/specs/state.spec.js similarity index 89% rename from modules/ticket/back/methods/ticket-tracking/specs/changeState.spec.js rename to modules/ticket/back/methods/ticket/specs/state.spec.js index b01d023897..9b5e801653 100644 --- a/modules/ticket/back/methods/ticket-tracking/specs/changeState.spec.js +++ b/modules/ticket/back/methods/ticket/specs/state.spec.js @@ -47,7 +47,7 @@ describe('ticket state()', () => { activeCtx.accessToken.userId = salesPersonId; const params = {ticketFk: 2, stateFk: 3}; - await models.TicketTracking.state(ctx, params, options); + await models.Ticket.state(ctx, params, options); await tx.rollback(); } catch (e) { @@ -69,7 +69,7 @@ describe('ticket state()', () => { activeCtx.accessToken.userId = employeeId; const params = {ticketFk: 11, stateFk: 13}; - await models.TicketTracking.state(ctx, params, options); + await models.Ticket.state(ctx, params, options); await tx.rollback(); } catch (e) { @@ -80,7 +80,8 @@ describe('ticket state()', () => { expect(error.code).toBe('ACCESS_DENIED'); }); - it('should be able to create a ticket tracking line for a not editable ticket if the user has the production role', async() => { + it('should be able to create a ticket tracking line for a not' + + ' editable ticket if the user has the production role', async() => { const tx = await models.TicketTracking.beginTransaction({}); try { @@ -91,7 +92,7 @@ describe('ticket state()', () => { activeCtx.accessToken.userId = productionId; const params = {ticketFk: ticket.id, stateFk: 3}; - const ticketTracking = await models.TicketTracking.state(ctx, params, options); + const ticketTracking = await models.Ticket.state(ctx, params, options); expect(ticketTracking.__data.ticketFk).toBe(params.ticketFk); expect(ticketTracking.__data.stateFk).toBe(params.stateFk); @@ -105,7 +106,8 @@ describe('ticket state()', () => { } }); - it('should update the ticket tracking line when the user is salesperson, uses the state assigned and a valid worker id', async() => { + it('should update the ticket tracking line when the user is salesperson,' + + ' uses the state assigned and a valid worker id', async() => { const tx = await models.TicketTracking.beginTransaction({}); try { @@ -115,7 +117,7 @@ describe('ticket state()', () => { const ctx = {req: {accessToken: {userId: 18}}}; const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options); const params = {ticketFk: ticket.id, stateFk: assignedState.id, workerFk: 1}; - const res = await models.TicketTracking.state(ctx, params, options); + const res = await models.Ticket.state(ctx, params, options); expect(res.__data.ticketFk).toBe(params.ticketFk); expect(res.__data.stateFk).toBe(params.stateFk); diff --git a/modules/ticket/back/methods/ticket-tracking/state.js b/modules/ticket/back/methods/ticket/state.js similarity index 100% rename from modules/ticket/back/methods/ticket-tracking/state.js rename to modules/ticket/back/methods/ticket/state.js diff --git a/modules/ticket/back/models/ticket-tracking.js b/modules/ticket/back/models/ticket-tracking.js index 48e4c93d76..92e046d3e1 100644 --- a/modules/ticket/back/models/ticket-tracking.js +++ b/modules/ticket/back/models/ticket-tracking.js @@ -1,5 +1,4 @@ module.exports = function(Self) { - require('../methods/ticket-tracking/state')(Self); require('../methods/ticket-tracking/setDelivered')(Self); Self.validatesPresenceOf('stateFk', {message: 'State cannot be blank'}); diff --git a/modules/ticket/back/models/ticket.js b/modules/ticket/back/models/ticket.js index ea068ef8a4..a265c9cbb3 100644 --- a/modules/ticket/back/models/ticket.js +++ b/modules/ticket/back/models/ticket.js @@ -1,4 +1,5 @@ module.exports = Self => { // Methods require('./ticket-methods')(Self); + require('../methods/ticket/state')(Self); }; From ae160890a8a3badfaf86f2af7ad428f451d88d6d Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 27 Oct 2023 15:06:20 +0200 Subject: [PATCH 148/449] refs #6335 feat(ticketAdvance): use componentUpdate --- .../00-ticket_canAdvance_leftJoin.sql | 30 +++++-- .../back/methods/ticket/componentUpdate.js | 76 ++++++++++------ .../ticket/specs/componentUpdate.spec.js | 2 +- modules/ticket/front/advance/index.html | 67 +++++++++----- modules/ticket/front/advance/index.js | 87 +++++++++++++++---- .../ticket/front/basic-data/step-two/index.js | 4 +- 6 files changed, 198 insertions(+), 68 deletions(-) rename db/changes/{234201 => 234601}/00-ticket_canAdvance_leftJoin.sql (85%) diff --git a/db/changes/234201/00-ticket_canAdvance_leftJoin.sql b/db/changes/234601/00-ticket_canAdvance_leftJoin.sql similarity index 85% rename from db/changes/234201/00-ticket_canAdvance_leftJoin.sql rename to db/changes/234601/00-ticket_canAdvance_leftJoin.sql index b26c3a102c..31472afd8e 100644 --- a/db/changes/234201/00-ticket_canAdvance_leftJoin.sql +++ b/db/changes/234601/00-ticket_canAdvance_leftJoin.sql @@ -68,7 +68,15 @@ BEGIN origin.futureZoneFk, origin.futureZoneName, origin.classColor futureClassColor, - dest.classColor + dest.classColor, + IFNULL(dest.clientFk, origin.clientFk) clientFk, + IFNULL(dest.nickname, origin.nickname) nickname, + IFNULL(dest.addressFk, origin.addressFk) addressFk, + IFNULL(dest.zoneFk, origin.futureZoneFk) zoneFk, + IFNULL(dest.warehouseFk, origin.warehouseFk) warehouseFk, + IFNULL(dest.companyFk, origin.companyFk) companyFk, + IFNULL(dest.agencyModeFk, origin.agencyModeFk) agencyModeFk, + dest.landed FROM ( SELECT s.ticketFk, @@ -76,7 +84,6 @@ BEGIN t.shipped, t.totalWithVat, st.name futureState, - t.addressFk, am.name futureAgency, count(s.id) futureLines, GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) futureIpt, @@ -84,7 +91,13 @@ BEGIN SUM((s.quantity <= IFNULL(st.amount,0))) hasStock, z.id futureZoneFk, z.name futureZoneName, - st.classColor + st.classColor, + t.clientFk, + t.nickname, + t.addressFk, + t.warehouseFk, + t.companyFk, + t.agencyModeFk FROM ticket t JOIN client c ON c.id = t.clientFk JOIN sale s ON s.ticketFk = t.id @@ -103,7 +116,6 @@ BEGIN LEFT JOIN ( SELECT t.id ticketFk, - t.addressFk, st.name state, GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt, t.shipped, @@ -111,7 +123,15 @@ BEGIN am.name agency, CAST(SUM(litros) AS DECIMAL(10,0)) liters, CAST(COUNT(*) AS DECIMAL(10,0)) `lines`, - st.classColor + st.classColor, + t.clientFk, + t.nickname, + t.addressFk, + t.zoneFk, + t.warehouseFk, + t.companyFk, + t.landed, + t.agencyModeFk FROM ticket t JOIN sale s ON s.ticketFk = t.id JOIN saleVolume sv ON sv.saleFk = s.id diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index f7c36f1088..483afdaeee 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -75,8 +75,7 @@ module.exports = Self => { { arg: 'option', type: 'number', - description: 'Action id', - required: true + description: 'Action id' }, { arg: 'isWithoutNegatives', @@ -88,7 +87,18 @@ module.exports = Self => { arg: 'withWarningAccept', type: 'boolean', description: 'Has pressed in confirm message', - }], + }, + { + arg: 'newTicket', + type: 'number', + description: 'Ticket id you want to move the lines to, if applicable', + }, + { + arg: 'keepPrice', + type: 'boolean', + description: 'If prices should be maintained', + } + ], returns: { type: ['object'], root: true @@ -101,6 +111,7 @@ module.exports = Self => { Self.componentUpdate = async(ctx, options) => { const args = ctx.args; + const originalTicketId = args.id; const myOptions = {userId: ctx.req.accessToken.userId}; let tx; @@ -141,7 +152,13 @@ module.exports = Self => { const salesNewTicketLength = salesNewTicket.length; if (salesNewTicketLength && sales.length != salesNewTicketLength) { - const newTicket = await models.Ticket.transferSales(ctx, args.id, null, salesNewTicket, myOptions); + const newTicket = await models.Ticket.transferSales( + ctx, + args.id, + args.newTicket, + salesNewTicket, + myOptions + ); args.id = newTicket.id; } } @@ -186,24 +203,32 @@ module.exports = Self => { delete updatedTicket.ctx; delete updatedTicket.option; - // Force to unroute ticket - const hasToBeUnrouted = true; - const query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; - const res = await Self.rawSql(query, [ - args.id, - args.clientFk, - args.nickname, - args.agencyModeFk, - args.addressFk, - args.zoneFk, - args.warehouseFk, - args.companyFk, - args.shipped, - args.landed, - args.isDeleted, - hasToBeUnrouted, - args.option - ], myOptions); + const ticketChages = { + clientFk: args.clientFk, + nickname: args.nickname, + agencyModeFk: args.agencyModeFk, + addressFk: args.addressFk, + zoneFk: args.zoneFk, + warehouseFk: args.warehouseFk, + companyFk: args.companyFk, + shipped: args.shipped, + landed: args.landed, + isDeleted: args.isDeleted + }; + + let response; + if (args.keepPrice) { + ticketChages.routeFk = null; + response = await originalTicket.updateAttributes(ticketChages, myOptions); + } else { + const hasToBeUnrouted = true; + const query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; + response = await Self.rawSql( + query, + [args.id].concat(Object.values(ticketChages), [hasToBeUnrouted, args.option]), + myOptions + ); + } if (originalTicket.addressFk != updatedTicket.addressFk && args.id) { await models.TicketObservation.destroyAll({ @@ -256,10 +281,11 @@ module.exports = Self => { } } - res.id = args.id; - if (tx) await tx.commit(); + response.id = args.id; + console.log(originalTicketId, args.newTicket ? ` TRANSFER TO → ` : ` CREATE NEW TICKET → `, args.id); + if (tx) await tx.rollback(); - return res; + return response; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js index ef6422be2b..b51e1b47b8 100644 --- a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js +++ b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js @@ -1,7 +1,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); -describe('ticket componentUpdate()', () => { +fdescribe('ticket componentUpdate()', () => { const userID = 1101; const ticketID = 11; const today = Date.vnNew(); diff --git a/modules/ticket/front/advance/index.html b/modules/ticket/front/advance/index.html index af5b8f7044..25664782ec 100644 --- a/modules/ticket/front/advance/index.html +++ b/modules/ticket/front/advance/index.html @@ -21,10 +21,17 @@ expr-builder="$ctrl.exprBuilder(param, value)" > - + vn-tooltip="Advance tickets with negatives"> + + @@ -32,8 +39,14 @@ - Destination - Origin + + Destination + {{model.userParams.dateToAdvance| date: 'dd/MM/yyyy'}} + + + Origin + {{model.userParams.dateFuture | date: 'dd/MM/yyyy'}} + @@ -48,9 +61,6 @@ ID - - Date - IPT @@ -69,9 +79,6 @@ ID - - Date - IPT @@ -117,11 +124,6 @@ {{::ticket.id | dashIfEmpty}} - - - {{::ticket.shipped | date: 'dd/MM/yyyy'}} - - {{::ticket.ipt | dashIfEmpty}} - - - {{::ticket.futureShipped | date: 'dd/MM/yyyy'}} - - {{::ticket.futureIpt | dashIfEmpty}} + + + + + + + + + + + + + + + + + + diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index 389bcdf14a..f98d0a6a9c 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -75,20 +75,6 @@ export default class Controller extends Section { }); } - compareDate(date) { - let today = Date.vnNew(); - today.setHours(0, 0, 0, 0); - let timeTicket = new Date(date); - timeTicket.setHours(0, 0, 0, 0); - - let comparation = today - timeTicket; - - if (comparation == 0) - return 'warning'; - if (comparation < 0) - return 'success'; - } - get checked() { const tickets = this.$.model.data || []; const checkedLines = []; @@ -136,7 +122,8 @@ export default class Controller extends Section { moveTicketsAdvance() { let ticketsToMove = []; - this.checked.forEach(ticket => { + // falta ver que hacer con los nulls + for (ticket of this.checked) { ticketsToMove.push({ originId: ticket.futureId, destinationId: ticket.id, @@ -144,7 +131,8 @@ export default class Controller extends Section { destinationShipped: ticket.shipped, workerFk: ticket.workerFk }); - }); + } + const params = {tickets: ticketsToMove}; return this.$http.post('Tickets/merge', params) .then(() => { @@ -152,6 +140,73 @@ export default class Controller extends Section { this.vnApp.showSuccess(this.$t('Success')); }); } + async getLanded(params) { + const query = `Agencies/getLanded`; + return this.$http.get(query, {params}).then(res => { + if (res.data) + return res.data; + else { + return this.vnApp.showError( + this.$t(`No delivery zone available for this landing date`) + ); + } + }); + } + + async splitTickets() { + this.progress = []; + this.splitErrors = []; + this.$.splitTickets.hide(); + this.$.splitProgress.enable = true; + this.$.splitProgress.cancel = false; + this.$.splitProgress.show(); + for (const ticket of this.checked) { + if (this.$.splitProgress.cancel) break; + try { + if (!ticket.landed) { + const newLanded = await this.getLanded({ + shipped: this.$.model.userParams.dateToAdvance, + addressFk: ticket.addressFk, + agencyModeFk: ticket.agencyModeFk, + warehouseFk: ticket.warehouseFk + }); + ticket.landed = newLanded?.landed; + ticket.zoneFk = newLanded?.zoneFk; + } + const query = `tickets/${ticket.futureId}/componentUpdate`; + const params = { + clientFk: ticket.clientFk, + nickname: ticket.nickname, + agencyModeFk: ticket.agencyModeFk, + addressFk: ticket.addressFk, + zoneFk: ticket.zoneFk, + warehouseFk: ticket.warehouseFk, + companyFk: ticket.companyFk, + shipped: this.$.model.userParams.dateToAdvance, + landed: ticket.landed, + isDeleted: false, + isWithoutNegatives: true, + withWarningAccept: false, + newTicket: ticket.id ?? undefined, + keepPrice: true + }; + + this.$http.post(query, params) + .catch(e => { + this.splitErrors.push({id: ticket.futureId, reason: e.message}); + }) + .finally(() => { + this.progress.push(ticket.futureId); + if (this.progress.length == this.checked.length) { + this.$.splitProgress.enable = false; + this.$.model.refresh(); + this.vnApp.showSuccess(this.$t('Success')); + this.$checkAll = null; + } + }); + } catch (e) {} + } + } exprBuilder(param, value) { switch (param) { diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index 74e2df074c..8ca9f053d7 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -114,7 +114,9 @@ class Controller extends Component { isDeleted: this.ticket.isDeleted, option: parseInt(this.ticket.option), isWithoutNegatives: this.ticket.withoutNegatives, - withWarningAccept: this.ticket.withWarningAccept + withWarningAccept: this.ticket.withWarningAccept, + newTicket: null, + keepPrice: false }; this.$http.post(query, params) From 7ae12327f5e8b81cae9a8c48f82dc938b9df8ed0 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Fri, 27 Oct 2023 16:16:22 +0200 Subject: [PATCH 149/449] refs #5134 fix: model ExpeditionScan --- modules/ticket/back/models/expeditionScan.json | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/ticket/back/models/expeditionScan.json b/modules/ticket/back/models/expeditionScan.json index 1db2c12389..7b95eff1e9 100644 --- a/modules/ticket/back/models/expeditionScan.json +++ b/modules/ticket/back/models/expeditionScan.json @@ -8,17 +8,16 @@ "properties": { "id": { "type": "number", - "description": "Identifier" + "description": "Identifier", + "id": true }, "expeditionFk": { "type": "number", - "description": "Identifier", - "id": true + "description": "Identifier" }, "palletFk": { "type": "number", - "description": "Identifier", - "id": true + "description": "Identifier" }, "scanned": { "type": "date", From 65a1d052dc0662da7d2a1004f9c7ed6493a3ac81 Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 27 Oct 2023 18:03:40 +0200 Subject: [PATCH 150/449] feat(ticket.state): refs #4131 to state --- .../234601/00-ACLticketTrackingState.sql | 3 +- .../ticket/back/methods/ticket/saveSign.js | 68 ++++++++++--------- modules/ticket/back/models/ticket.js | 1 - modules/ticket/front/sale/index.js | 2 +- modules/ticket/front/sale/index.spec.js | 17 +++-- modules/ticket/front/summary/index.js | 4 +- modules/ticket/front/summary/index.spec.js | 2 +- modules/ticket/front/tracking/edit/index.html | 2 +- modules/ticket/front/tracking/edit/index.js | 2 +- .../ticket/front/tracking/edit/index.spec.js | 2 +- 10 files changed, 55 insertions(+), 48 deletions(-) diff --git a/db/changes/234601/00-ACLticketTrackingState.sql b/db/changes/234601/00-ACLticketTrackingState.sql index ddd838e7ea..f84128b162 100644 --- a/db/changes/234601/00-ACLticketTrackingState.sql +++ b/db/changes/234601/00-ACLticketTrackingState.sql @@ -1,5 +1,6 @@ UPDATE `salix`.`ACL` - SET property = 'state' + SET property = 'state', + model = 'Ticket' WHERE property = 'changeState'; REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'productionboss'@; diff --git a/modules/ticket/back/methods/ticket/saveSign.js b/modules/ticket/back/methods/ticket/saveSign.js index 9888328e78..9667847d29 100644 --- a/modules/ticket/back/methods/ticket/saveSign.js +++ b/modules/ticket/back/methods/ticket/saveSign.js @@ -44,6 +44,40 @@ module.exports = Self => { myOptions.transaction = tx; } + try { + for (const ticketId of tickets) { + const ticketState = await models.TicketState.findOne( + {where: {ticketFk: ticketId}, + fields: ['alertLevel'] + }, myOptions); + + const packedAlertLevel = await models.AlertLevel.findOne({where: {code: 'PACKED'}, + fields: ['id'] + }, myOptions); + + if (!ticketState) + throw new UserError('Ticket does not exist'); + if (ticketState.alertLevel < packedAlertLevel.id) + throw new UserError('This ticket cannot be signed because it has not been boxed'); + if (await gestDocExists(ticketId)) + throw new UserError('Ticket is already signed'); + + if (location) setLocation(ticketId); + if (!gestDocCreated) await createGestDoc(ticketId); + await models.TicketDms.create({ticketFk: ticketId, dmsFk: dms[0].id}, myOptions); + const ticket = await models.Ticket.findById(ticketId, null, myOptions); + await ticket.updateAttribute('isSigned', true, myOptions); + const params = {ticketFk: ticketId, code: 'DELIVERED'}; + await models.Ticket.state(ctx, params, options); + } + + if (tx) await tx.commit(); + return; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + async function setLocation(ticketId) { await models.Delivery.create({ ticketFk: ticketId, @@ -103,41 +137,9 @@ module.exports = Self => { description: `Firma del cliente - Ruta ${ticket.route().id}`, hasFile: false }; + dms = await models.Dms.uploadFile(ctxUploadFile, myOptions); gestDocCreated = true; } - - try { - for (const ticketId of tickets) { - const ticketState = await models.TicketState.findOne( - {where: {ticketFk: ticketId}, - fields: ['alertLevel'] - }, myOptions); - - const packedAlertLevel = await models.AlertLevel.findOne({where: {code: 'PACKED'}, - fields: ['id'] - }, myOptions); - - if (!ticketState) - throw new UserError('Ticket does not exist'); - if (ticketState.alertLevel < packedAlertLevel.id) - throw new UserError('This ticket cannot be signed because it has not been boxed'); - if (await gestDocExists(ticketId)) - throw new UserError('Ticket is already signed'); - - if (location) setLocation(ticketId); - if (!gestDocCreated) await createGestDoc(ticketId); - await models.TicketDms.create({ticketFk: ticketId, dmsFk: dms[0].id}, myOptions); - const ticket = await models.Ticket.findById(ticketId, null, myOptions); - await ticket.updateAttribute('isSigned', true, myOptions); - await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticketId, 'DELIVERED'], myOptions); - } - - if (tx) await tx.commit(); - return; - } catch (e) { - if (tx) await tx.rollback(); - throw e; - } }; }; diff --git a/modules/ticket/back/models/ticket.js b/modules/ticket/back/models/ticket.js index a265c9cbb3..1930765fb7 100644 --- a/modules/ticket/back/models/ticket.js +++ b/modules/ticket/back/models/ticket.js @@ -1,5 +1,4 @@ module.exports = Self => { - // Methods require('./ticket-methods')(Self); require('../methods/ticket/state')(Self); }; diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index 1dd700b532..4f6a9e7573 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -173,7 +173,7 @@ class Controller extends Section { state(value) { const params = {ticketFk: this.$params.id, code: value}; - return this.$http.post('TicketTrackings/state', params).then(() => { + return this.$http.post('Tickets/state', params).then(() => { this.vnApp.showSuccess(this.$t('Data saved!')); this.card.reload(); }).finally(() => this.resetChanges()); diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 3ed18c0f11..70781eb581 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -229,13 +229,14 @@ describe('Ticket', () => { }); describe('state()', () => { - it('should make an HTTP post query, then call the showSuccess(), reload() and resetChanges() methods', () => { + it('should make an HTTP post query, then call the showSuccess(),' + + ' reload() and resetChanges() methods', () => { jest.spyOn(controller.card, 'reload').mockReturnThis(); jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); jest.spyOn(controller, 'resetChanges').mockReturnThis(); const expectedParams = {ticketFk: 1, code: 'OK'}; - $httpBackend.expect('POST', `TicketTrackings/state`, expectedParams).respond(200); + $httpBackend.expect('POST', `Tickets/state`, expectedParams).respond(200); controller.state('OK'); $httpBackend.flush(); @@ -246,7 +247,8 @@ describe('Ticket', () => { }); describe('removeSales()', () => { - it('should make an HTTP post query, then call the showSuccess(), removeSelectedSales() and resetChanges() methods', () => { + it('should make an HTTP post query, then call the showSuccess(),' + + ' removeSelectedSales() and resetChanges() methods', () => { jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); jest.spyOn(controller, 'removeSelectedSales').mockReturnThis(); jest.spyOn(controller, 'resetChanges').mockReturnThis(); @@ -352,7 +354,8 @@ describe('Ticket', () => { }); describe('updatePrice()', () => { - it('should make an HTTP POST query, update the sale price and then call to the resetChanges() method', () => { + it('should make an HTTP POST query, update the sale price ' + + 'and then call to the resetChanges() method', () => { jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); jest.spyOn(controller, 'resetChanges').mockReturnThis(); @@ -418,7 +421,8 @@ describe('Ticket', () => { expect(controller.$.editDiscount.hide).toHaveBeenCalledWith(); }); - it('should not call to the updateDiscount() method and then to the editDiscountDialog hide() method', () => { + it('should not call to the updateDiscount() method and then' + + ' to the editDiscountDialog hide() method', () => { jest.spyOn(controller, 'updateDiscount').mockReturnThis(); const firstSelectedSale = controller.sales[0]; @@ -444,7 +448,8 @@ describe('Ticket', () => { }); describe('updateDiscount()', () => { - it('should make an HTTP POST query, update the sales discount and then call to the resetChanges() method', () => { + it('should make an HTTP POST query, update the sales discount ' + + 'and then call to the resetChanges() method', () => { jest.spyOn(controller, 'resetChanges').mockReturnThis(); jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis(); diff --git a/modules/ticket/front/summary/index.js b/modules/ticket/front/summary/index.js index f4f36c3ed3..68718aaf2c 100644 --- a/modules/ticket/front/summary/index.js +++ b/modules/ticket/front/summary/index.js @@ -64,8 +64,8 @@ class Controller extends Summary { ticketFk: 'id' in this.ticket ? this.ticket.id : this.$params.id, code: value }; - - this.$http.post(`TicketTrackings/state`, params) + console.log('entra'); + this.$http.post(`Tickets/state`, params) .then(() => { if ('id' in this.$params) this.reload(); }) diff --git a/modules/ticket/front/summary/index.spec.js b/modules/ticket/front/summary/index.spec.js index b8c6f0513f..6837bfd549 100644 --- a/modules/ticket/front/summary/index.spec.js +++ b/modules/ticket/front/summary/index.spec.js @@ -50,7 +50,7 @@ describe('Ticket', () => { let res = {id: 1, nickname: 'myNickname'}; $httpBackend.when('GET', `Tickets/1/summary`).respond(200, res); - $httpBackend.expectPOST(`TicketTrackings/state`).respond(200, 'ok'); + $httpBackend.expectPOST(`Tickets/state`).respond(200, 'ok'); controller.state(value); $httpBackend.flush(); diff --git a/modules/ticket/front/tracking/edit/index.html b/modules/ticket/front/tracking/edit/index.html index 90f045813b..47f3670075 100644 --- a/modules/ticket/front/tracking/edit/index.html +++ b/modules/ticket/front/tracking/edit/index.html @@ -1,4 +1,4 @@ - + { + this.$http.post(`Tickets/state`, this.params).then(() => { this.$.watcher.updateOriginalData(); this.card.reload(); this.vnApp.showSuccess(this.$t('Data saved!')); diff --git a/modules/ticket/front/tracking/edit/index.spec.js b/modules/ticket/front/tracking/edit/index.spec.js index e97dc1337f..9d9aa7983e 100644 --- a/modules/ticket/front/tracking/edit/index.spec.js +++ b/modules/ticket/front/tracking/edit/index.spec.js @@ -61,7 +61,7 @@ describe('Ticket', () => { jest.spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.$state, 'go'); - $httpBackend.expectPOST(`TicketTrackings/state`, controller.params).respond({}); + $httpBackend.expectPOST(`Tickets/state`, controller.params).respond({}); controller.onSubmit(); $httpBackend.flush(); From 14753212bb09984c3bf465f6ab4960017c60946e Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 27 Oct 2023 18:07:17 +0200 Subject: [PATCH 151/449] fix(saveSign): refs #4131 remove call state on saveSign --- .../ticket/back/methods/ticket/saveSign.js | 68 +++++++++---------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/modules/ticket/back/methods/ticket/saveSign.js b/modules/ticket/back/methods/ticket/saveSign.js index 9667847d29..9888328e78 100644 --- a/modules/ticket/back/methods/ticket/saveSign.js +++ b/modules/ticket/back/methods/ticket/saveSign.js @@ -44,40 +44,6 @@ module.exports = Self => { myOptions.transaction = tx; } - try { - for (const ticketId of tickets) { - const ticketState = await models.TicketState.findOne( - {where: {ticketFk: ticketId}, - fields: ['alertLevel'] - }, myOptions); - - const packedAlertLevel = await models.AlertLevel.findOne({where: {code: 'PACKED'}, - fields: ['id'] - }, myOptions); - - if (!ticketState) - throw new UserError('Ticket does not exist'); - if (ticketState.alertLevel < packedAlertLevel.id) - throw new UserError('This ticket cannot be signed because it has not been boxed'); - if (await gestDocExists(ticketId)) - throw new UserError('Ticket is already signed'); - - if (location) setLocation(ticketId); - if (!gestDocCreated) await createGestDoc(ticketId); - await models.TicketDms.create({ticketFk: ticketId, dmsFk: dms[0].id}, myOptions); - const ticket = await models.Ticket.findById(ticketId, null, myOptions); - await ticket.updateAttribute('isSigned', true, myOptions); - const params = {ticketFk: ticketId, code: 'DELIVERED'}; - await models.Ticket.state(ctx, params, options); - } - - if (tx) await tx.commit(); - return; - } catch (e) { - if (tx) await tx.rollback(); - throw e; - } - async function setLocation(ticketId) { await models.Delivery.create({ ticketFk: ticketId, @@ -137,9 +103,41 @@ module.exports = Self => { description: `Firma del cliente - Ruta ${ticket.route().id}`, hasFile: false }; - dms = await models.Dms.uploadFile(ctxUploadFile, myOptions); gestDocCreated = true; } + + try { + for (const ticketId of tickets) { + const ticketState = await models.TicketState.findOne( + {where: {ticketFk: ticketId}, + fields: ['alertLevel'] + }, myOptions); + + const packedAlertLevel = await models.AlertLevel.findOne({where: {code: 'PACKED'}, + fields: ['id'] + }, myOptions); + + if (!ticketState) + throw new UserError('Ticket does not exist'); + if (ticketState.alertLevel < packedAlertLevel.id) + throw new UserError('This ticket cannot be signed because it has not been boxed'); + if (await gestDocExists(ticketId)) + throw new UserError('Ticket is already signed'); + + if (location) setLocation(ticketId); + if (!gestDocCreated) await createGestDoc(ticketId); + await models.TicketDms.create({ticketFk: ticketId, dmsFk: dms[0].id}, myOptions); + const ticket = await models.Ticket.findById(ticketId, null, myOptions); + await ticket.updateAttribute('isSigned', true, myOptions); + await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticketId, 'DELIVERED'], myOptions); + } + + if (tx) await tx.commit(); + return; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; From f250c084f797195258debd7e7e90f27e72971510 Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 30 Oct 2023 09:11:52 +0100 Subject: [PATCH 152/449] ref #5216 refactor expeditionState BeforeInsert --- .../234601/00-expeditionStateBeforeInsert.sql | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 db/changes/234601/00-expeditionStateBeforeInsert.sql diff --git a/db/changes/234601/00-expeditionStateBeforeInsert.sql b/db/changes/234601/00-expeditionStateBeforeInsert.sql new file mode 100644 index 0000000000..565b3ded34 --- /dev/null +++ b/db/changes/234601/00-expeditionStateBeforeInsert.sql @@ -0,0 +1,13 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`expeditionState_BeforeInsert` + BEFORE INSERT ON `expeditionState` + FOR EACH ROW +BEGIN + + SET NEW.userFk = IFNULL(NEW.userFk, account.myUser_getId()); + +END$$ +DELIMITER ; + + + From a80715583c0a7b7fae1c17f501cb178251d68253 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 30 Oct 2023 14:16:25 +0100 Subject: [PATCH 153/449] refs #6335 feat(ticketAdvance): change the date if you can --- CHANGELOG.md | 5 + loopback/locale/es.json | 14 ++- .../back/methods/ticket/componentUpdate.js | 32 ++--- modules/ticket/front/advance/index.html | 24 ++-- modules/ticket/front/advance/index.js | 116 +++++++++++------- modules/ticket/front/advance/locale/es.yml | 6 +- 6 files changed, 123 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd6ed45222..e236dc2396 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [2346.01] - 2023-11-16 ### Added +- (Ticket -> Adelantar) Permite mover lineas sin generar negativos +- (Ticket -> Adelantar) Permite modificar la fecha de los tickets + ### Changed ### Fixed +- (Ticket -> RocketChat) Arreglada detección de cambios + ## [2342.01] - 2023-11-02 diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 3cc9a96278..a796c44a72 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -224,7 +224,9 @@ "date in the future": "Fecha en el futuro", "reference duplicated": "Referencia duplicada", "This ticket is already a refund": "Este ticket ya es un abono", - "isWithoutNegatives": "isWithoutNegatives", + "isWithoutNegatives": "Sin negativos", + "newTicket": "Nuevo ticket", + "keepPrice": "Mantener precios", "routeFk": "routeFk", "Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador", "No hay un contrato en vigor": "No hay un contrato en vigor", @@ -321,9 +323,13 @@ "Select a different client": "Seleccione un cliente distinto", "Fill all the fields": "Rellene todos los campos", "The response is not a PDF": "La respuesta no es un PDF", - "Ticket without Route": "Ticket sin ruta", "Booking completed": "Reserva completada", "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mímina", - "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina" -} + "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina", + "__cachedRelations": "__cachedRelations", + "__data": "__data", + "__strict": "__strict", + "__persisted": "__persisted", + "client": "client" +} \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 483afdaeee..536166d7da 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -163,7 +163,7 @@ module.exports = Self => { } } - const originalTicket = await models.Ticket.findOne({ + const ticketToChange = await models.Ticket.findOne({ where: {id: args.id}, fields: [ 'id', @@ -196,13 +196,7 @@ module.exports = Self => { }, ] }, myOptions); - - args.routeFk = null; - if (args.isWithoutNegatives === false) delete args.isWithoutNegatives; - const updatedTicket = Object.assign({}, args); - delete updatedTicket.ctx; - delete updatedTicket.option; - + const originalTicket = JSON.parse(JSON.stringify(ticketToChange)); const ticketChages = { clientFk: args.clientFk, nickname: args.nickname, @@ -219,18 +213,21 @@ module.exports = Self => { let response; if (args.keepPrice) { ticketChages.routeFk = null; - response = await originalTicket.updateAttributes(ticketChages, myOptions); + response = await ticketToChange.updateAttributes(ticketChages, myOptions); } else { const hasToBeUnrouted = true; - const query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; response = await Self.rawSql( - query, + 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [args.id].concat(Object.values(ticketChages), [hasToBeUnrouted, args.option]), myOptions ); } + if (args.isWithoutNegatives === false) delete args.isWithoutNegatives; + const updatedTicket = Object.assign({}, args, JSON.parse(JSON.stringify(ticketToChange))); + delete updatedTicket.ctx; + delete updatedTicket.option; - if (originalTicket.addressFk != updatedTicket.addressFk && args.id) { + if (ticketToChange.addressFk != updatedTicket.addressFk && args.id) { await models.TicketObservation.destroyAll({ ticketFk: args.id }, myOptions); @@ -252,15 +249,20 @@ module.exports = Self => { await models.TicketObservation.create(clonedObservations, myOptions); } } - const changes = loggable.getChanges(originalTicket, updatedTicket); + const hasChanges = Object.keys(changes.old).length > 0 || Object.keys(changes.new).length > 0; if (hasChanges) { + delete changes.old.client; + delete changes.old.address; + delete changes.new.client; + delete changes.new.address; + const oldProperties = await loggable.translateValues(Self, changes.old); const newProperties = await loggable.translateValues(Self, changes.new); - const salesPersonId = originalTicket.client().salesPersonFk; + const salesPersonId = ticketToChange.client().salesPersonFk; if (salesPersonId) { const url = await Self.app.models.Url.getUrl(); @@ -283,7 +285,7 @@ module.exports = Self => { response.id = args.id; console.log(originalTicketId, args.newTicket ? ` TRANSFER TO → ` : ` CREATE NEW TICKET → `, args.id); - if (tx) await tx.rollback(); + if (tx) await tx.commit(); return response; } catch (e) { diff --git a/modules/ticket/front/advance/index.html b/modules/ticket/front/advance/index.html index 25664782ec..395fe7078e 100644 --- a/modules/ticket/front/advance/index.html +++ b/modules/ticket/front/advance/index.html @@ -29,7 +29,7 @@ @@ -121,7 +121,7 @@ - {{::ticket.id | dashIfEmpty}} + {{::ticket.id}} {{::ticket.ipt | dashIfEmpty}} @@ -137,7 +137,7 @@ - {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} + {{::ticket.totalWithVat | currency: 'EUR': 2}} @@ -193,21 +193,23 @@ + message="Progress"> - - + label="Total progress" + value="[{{$ctrl.progress.length}}/{{::$ctrl.checked.length}}]"> + Error list + + + + diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index f98d0a6a9c..5e41f0f23b 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -120,10 +120,16 @@ export default class Controller extends Section { '\n' + this.$t(`Destination agency`, {agency: agency}); } - moveTicketsAdvance() { + async moveTicketsAdvance() { let ticketsToMove = []; - // falta ver que hacer con los nulls - for (ticket of this.checked) { + for (const ticket of this.checked) { + if (!ticket.id) { + try { + const {query, params} = await this.requestComponentUpdate(ticket, false); + this.$http.post(query, params); + } catch (e) {} + continue; + } ticketsToMove.push({ originId: ticket.futureId, destinationId: ticket.id, @@ -136,10 +142,12 @@ export default class Controller extends Section { const params = {tickets: ticketsToMove}; return this.$http.post('Tickets/merge', params) .then(() => { - this.$.model.refresh(); - this.vnApp.showSuccess(this.$t('Success')); + this.refresh(); + if (ticketsToMove.length) + this.vnApp.showSuccess(this.$t('Success', {tickets: ticketsToMove.length})); }); } + async getLanded(params) { const query = `Agencies/getLanded`; return this.$http.get(query, {params}).then(res => { @@ -160,54 +168,76 @@ export default class Controller extends Section { this.$.splitProgress.enable = true; this.$.splitProgress.cancel = false; this.$.splitProgress.show(); + for (const ticket of this.checked) { if (this.$.splitProgress.cancel) break; try { - if (!ticket.landed) { - const newLanded = await this.getLanded({ - shipped: this.$.model.userParams.dateToAdvance, - addressFk: ticket.addressFk, - agencyModeFk: ticket.agencyModeFk, - warehouseFk: ticket.warehouseFk - }); - ticket.landed = newLanded?.landed; - ticket.zoneFk = newLanded?.zoneFk; - } - const query = `tickets/${ticket.futureId}/componentUpdate`; - const params = { - clientFk: ticket.clientFk, - nickname: ticket.nickname, - agencyModeFk: ticket.agencyModeFk, - addressFk: ticket.addressFk, - zoneFk: ticket.zoneFk, - warehouseFk: ticket.warehouseFk, - companyFk: ticket.companyFk, - shipped: this.$.model.userParams.dateToAdvance, - landed: ticket.landed, - isDeleted: false, - isWithoutNegatives: true, - withWarningAccept: false, - newTicket: ticket.id ?? undefined, - keepPrice: true - }; - + const {query, params} = await this.requestComponentUpdate(ticket, true); this.$http.post(query, params) .catch(e => { this.splitErrors.push({id: ticket.futureId, reason: e.message}); }) - .finally(() => { - this.progress.push(ticket.futureId); - if (this.progress.length == this.checked.length) { - this.$.splitProgress.enable = false; - this.$.model.refresh(); - this.vnApp.showSuccess(this.$t('Success')); - this.$checkAll = null; - } - }); - } catch (e) {} + .finally(() => this.progressAdd(ticket.futureId)); + } catch (e) { + this.splitErrors.push({id: ticket.futureId, reason: e.message}); + this.progressAdd(ticket.futureId); + } } } + progressAdd(ticketId) { + this.progress.push(ticketId); + if (this.progress.length == this.checked.length) { + this.$.splitProgress.enable = false; + this.refresh(); + if ((this.progress.length - this.splitErrors.length) > 0) { + this.vnApp.showSuccess(this.$t('Success', { + tickets: this.progress.length - this.splitErrors.length + })); + } + } + } + + async requestComponentUpdate(ticket, isWithoutNegatives) { + const query = `tickets/${ticket.futureId}/componentUpdate`; + if (!ticket.landed) { + console.log(ticket); + const newLanded = await this.getLanded({ + shipped: this.$.model.userParams.dateToAdvance, + addressFk: ticket.addressFk, + agencyModeFk: ticket.agencyModeFk, + warehouseFk: ticket.warehouseFk + }); + if (!newLanded) + throw new Error(this.$t(`No delivery zone available for this landing date`)); + + ticket.landed = newLanded.landed; + ticket.zoneFk = newLanded.zoneFk; + } + const params = { + clientFk: ticket.clientFk, + nickname: ticket.nickname, + agencyModeFk: ticket.agencyModeFk, + addressFk: ticket.addressFk, + zoneFk: ticket.zoneFk, + warehouseFk: ticket.warehouseFk, + companyFk: ticket.companyFk, + shipped: this.$.model.userParams.dateToAdvance, + landed: ticket.landed, + isDeleted: false, + isWithoutNegatives, + newTicket: ticket.id ?? undefined, + keepPrice: true + }; + console.log(params); + return {query, params}; + } + + refresh() { + this.$.model.refresh(); + this.$checkAll = null; + } + exprBuilder(param, value) { switch (param) { case 'id': diff --git a/modules/ticket/front/advance/locale/es.yml b/modules/ticket/front/advance/locale/es.yml index 3111d9afd3..520e82009a 100644 --- a/modules/ticket/front/advance/locale/es.yml +++ b/modules/ticket/front/advance/locale/es.yml @@ -1,7 +1,7 @@ Advance tickets: Adelantar tickets Search advance tickets by date: Busca tickets para adelantar por fecha Advance confirmation: ¿Desea adelantar {{checked}} tickets? -Success: Tickets movidos correctamente +Success: "{{tickets}} Tickets movidos correctamente" Lines: Líneas Liters: Litros Item Packing Type: Encajado @@ -9,3 +9,7 @@ Origin agency: "Agencia origen: {{agency}}" Destination agency: "Agencia destino: {{agency}}" Less than 50€: Menor a 50€ Not Movable: No movibles +Error list: Lista de errores +Progress: Progreso +Total progress: Progreso total +Advance tickets (without negatives): Adelantar tickets (sin negativos) From e504ad313c06747bd01a9365c6437ccaec59a3cd Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 30 Oct 2023 14:56:33 +0100 Subject: [PATCH 154/449] remove(console.log): refs #4131 quitar console log --- modules/ticket/front/summary/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/ticket/front/summary/index.js b/modules/ticket/front/summary/index.js index 68718aaf2c..9d161f63e9 100644 --- a/modules/ticket/front/summary/index.js +++ b/modules/ticket/front/summary/index.js @@ -64,7 +64,6 @@ class Controller extends Summary { ticketFk: 'id' in this.ticket ? this.ticket.id : this.$params.id, code: value }; - console.log('entra'); this.$http.post(`Tickets/state`, params) .then(() => { if ('id' in this.$params) this.reload(); From 37dce9944790dc1b2c6c342629a50e8ad52f2546 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 30 Oct 2023 15:00:05 +0100 Subject: [PATCH 155/449] refs #6335 test(ticketAdvance): add test to keep price --- loopback/locale/es.json | 9 +- loopback/server/boot/date.js | 4 +- .../back/methods/ticket/componentUpdate.js | 4 +- .../ticket/specs/componentUpdate.spec.js | 110 +++++++++++++++++- 4 files changed, 115 insertions(+), 12 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index a796c44a72..7e2000344a 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -326,10 +326,5 @@ "Booking completed": "Reserva completada", "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mímina", - "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina", - "__cachedRelations": "__cachedRelations", - "__data": "__data", - "__strict": "__strict", - "__persisted": "__persisted", - "client": "client" -} \ No newline at end of file + "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina" +} diff --git a/loopback/server/boot/date.js b/loopback/server/boot/date.js index 88505cf62c..8107455625 100644 --- a/loopback/server/boot/date.js +++ b/loopback/server/boot/date.js @@ -1,8 +1,8 @@ module.exports = () => { Date.vnUTC = () => { const env = process.env.NODE_ENV; - // if (!env || env === 'development') - // return new Date(Date.UTC(2001, 0, 1, 11)); + if (!env || env === 'development') + return new Date(Date.UTC(2001, 0, 1, 11)); return new Date(); }; diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 536166d7da..1b02fd201d 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -223,7 +223,7 @@ module.exports = Self => { ); } if (args.isWithoutNegatives === false) delete args.isWithoutNegatives; - const updatedTicket = Object.assign({}, args, JSON.parse(JSON.stringify(ticketToChange))); + const updatedTicket = Object.assign({}, args); delete updatedTicket.ctx; delete updatedTicket.option; @@ -249,8 +249,8 @@ module.exports = Self => { await models.TicketObservation.create(clonedObservations, myOptions); } } - const changes = loggable.getChanges(originalTicket, updatedTicket); + const changes = loggable.getChanges(originalTicket, updatedTicket); const hasChanges = Object.keys(changes.old).length > 0 || Object.keys(changes.new).length > 0; if (hasChanges) { diff --git a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js index b51e1b47b8..e124999c93 100644 --- a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js +++ b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js @@ -1,7 +1,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); -fdescribe('ticket componentUpdate()', () => { +describe('ticket componentUpdate()', () => { const userID = 1101; const ticketID = 11; const today = Date.vnNew(); @@ -209,4 +209,112 @@ fdescribe('ticket componentUpdate()', () => { throw e; } }); + + describe('ticket componentUpdate()', () => { + it('should change shipped and keep price', async() => { + const tx = await models.Ticket.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const saleId = 27; + const originDate = today; + const newDate = tomorrow; + const ticketID = 14; + newDate.setHours(0, 0, 0, 0, 0); + originDate.setHours(0, 0, 0, 0, 0); + + const args = { + id: ticketID, + clientFk: 1104, + agencyModeFk: 2, + addressFk: 4, + zoneFk: 9, + warehouseFk: 1, + companyFk: 442, + shipped: newDate, + landed: tomorrow, + isDeleted: false, + option: 1, + isWithoutNegatives: false, + keepPrice: true + }; + + const ctx = { + args: args, + req: { + accessToken: {userId: 9}, + headers: {origin: 'http://localhost'}, + __: value => { + return value; + } + } + }; + + const beforeSale = await models.Sale.findById(saleId, null, options); + await models.Ticket.componentUpdate(ctx, options); + const afterSale = await models.Sale.findById(saleId, null, options); + + expect(beforeSale.price).toEqual(afterSale.price); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should change shipped and not keep price', async() => { + const tx = await models.Ticket.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const saleId = 27; + const originDate = today; + const newDate = tomorrow; + const ticketID = 14; + newDate.setHours(0, 0, 0, 0, 0); + originDate.setHours(0, 0, 0, 0, 0); + + const args = { + id: ticketID, + clientFk: 1104, + agencyModeFk: 2, + addressFk: 4, + zoneFk: 9, + warehouseFk: 1, + companyFk: 442, + shipped: newDate, + landed: tomorrow, + isDeleted: false, + option: 1, + isWithoutNegatives: false, + keepPrice: false + }; + + const ctx = { + args: args, + req: { + accessToken: {userId: 9}, + headers: {origin: 'http://localhost'}, + __: value => { + return value; + } + } + }; + + const beforeSale = await models.Sale.findById(saleId, null, options); + await models.Ticket.componentUpdate(ctx, options); + const afterSale = await models.Sale.findById(saleId, null, options); + + expect(beforeSale.price).not.toEqual(afterSale.price); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + }); }); From e7da093fc1e647e3c8c322f47b8ca4472b72a3b7 Mon Sep 17 00:00:00 2001 From: pablone Date: Tue, 31 Oct 2023 07:49:27 +0100 Subject: [PATCH 156/449] =?UTF-8?q?fix(acl.sql):=20refs=20#4131=20=C3=B2ne?= =?UTF-8?q?r=20comillas=20en=20el=20sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/changes/234601/00-ACLticketTrackingState.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db/changes/234601/00-ACLticketTrackingState.sql b/db/changes/234601/00-ACLticketTrackingState.sql index f84128b162..0f7bd4f44d 100644 --- a/db/changes/234601/00-ACLticketTrackingState.sql +++ b/db/changes/234601/00-ACLticketTrackingState.sql @@ -1,7 +1,7 @@ UPDATE `salix`.`ACL` - SET property = 'state', - model = 'Ticket' - WHERE property = 'changeState'; + SET `property` = 'state', + `model` = 'Ticket' + WHERE `property` = 'changeState'; REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'productionboss'@; REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'productionAssi'@; From 6112c7ba5f234cd3ceb7727018c167231b7ed5f4 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 31 Oct 2023 09:59:34 +0100 Subject: [PATCH 157/449] refs #5637 saleGroup traducciones --- modules/ticket/back/locale/sale-group/en.yml | 10 ++++++++++ modules/ticket/back/locale/sale-group/es.yml | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 modules/ticket/back/locale/sale-group/en.yml create mode 100644 modules/ticket/back/locale/sale-group/es.yml diff --git a/modules/ticket/back/locale/sale-group/en.yml b/modules/ticket/back/locale/sale-group/en.yml new file mode 100644 index 0000000000..d882316476 --- /dev/null +++ b/modules/ticket/back/locale/sale-group/en.yml @@ -0,0 +1,10 @@ +name: saleGroup +columns: + id: id + created: created + userFk: user + parkingFk: parking + sectorFk: sector + ticketFk: ticket + editorFk: editor + diff --git a/modules/ticket/back/locale/sale-group/es.yml b/modules/ticket/back/locale/sale-group/es.yml new file mode 100644 index 0000000000..9efbe7148a --- /dev/null +++ b/modules/ticket/back/locale/sale-group/es.yml @@ -0,0 +1,10 @@ +name: saleGroup +columns: + id: id + created: creado + userFk: usuario + parkingFk: parking + sectorFk: sector + ticketFk: ticket + editorFk: editor + From d7542bcbb4c9c491a532b2345a0c8dda462ab4a2 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 31 Oct 2023 15:11:03 +0100 Subject: [PATCH 158/449] refs #6335 fix(ticketAdvance): procedure --- ..._canAdvance_leftJoin.sql => 00-ticket_canAdvance_update.sql} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename db/changes/234601/{00-ticket_canAdvance_leftJoin.sql => 00-ticket_canAdvance_update.sql} (99%) diff --git a/db/changes/234601/00-ticket_canAdvance_leftJoin.sql b/db/changes/234601/00-ticket_canAdvance_update.sql similarity index 99% rename from db/changes/234601/00-ticket_canAdvance_leftJoin.sql rename to db/changes/234601/00-ticket_canAdvance_update.sql index 31472afd8e..272a0618a1 100644 --- a/db/changes/234601/00-ticket_canAdvance_leftJoin.sql +++ b/db/changes/234601/00-ticket_canAdvance_update.sql @@ -31,7 +31,7 @@ BEGIN SELECT itemFk, quantity FROM itemEntryIn WHERE landed >= vDateInventory - AND landed < vDateFuture + AND landed <= vDateToAdvance AND isVirtualStock = FALSE AND warehouseInFk = vWarehouseFk UNION ALL From bf84863237e64040ebaec4b4fa933bd7bff88b72 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 2 Nov 2023 08:42:53 +0100 Subject: [PATCH 159/449] refs #6376 fix: changelog --- CHANGELOG.md | 7 +-- db/changes/234201/00-packagingFkviews.sql | 74 ++++++++++++----------- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d677b80e34..69f9f63b6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,20 +5,19 @@ 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). -## [2342.01] - 2023-10-19 +## [2342.01] - 2023-11-02 ### Added +- (Usuarios -> Foto) Se muestra la foto del trabajador ### Changed ### Fixed +- (Usuarios -> Historial) Abre el descriptor del usuario correctamente ## [2340.01] - 2023-10-05 ### Added -- (Usuarios -> Foto) Se muestra la foto del trabajador - ### Changed ### Fixed -- (Usuarios -> Historial) Abre el descriptor del usuario correctamente ## [2338.01] - 2023-09-21 diff --git a/db/changes/234201/00-packagingFkviews.sql b/db/changes/234201/00-packagingFkviews.sql index f355325f3e..abc7dc004f 100644 --- a/db/changes/234201/00-packagingFkviews.sql +++ b/db/changes/234201/00-packagingFkviews.sql @@ -1,3 +1,41 @@ +CREATE OR REPLACE DEFINER=`root`@`localhost` + SQL SECURITY DEFINER + VIEW `vn`.`awbVolume` +AS SELECT `d`.`awbFk` AS `awbFk`, + `b`.`stickers` * `i`.`density` * IF( + `p`.`volume` > 0, + `p`.`volume`, + `p`.`width` * `p`.`depth` * IF(`p`.`height` = 0, `i`.`size` + 10, `p`.`height`) + ) / (`vc`.`aerealVolumetricDensity` * 1000) AS `volume`, + `b`.`id` AS `buyFk` +FROM ( + ( + ( + ( + ( + ( + ( + ( + `vn`.`buy` `b` + JOIN `vn`.`item` `i` ON(`b`.`itemFk` = `i`.`id`) + ) + JOIN `vn`.`itemType` `it` ON(`i`.`typeFk` = `it`.`id`) + ) + JOIN `vn`.`packaging` `p` ON(`p`.`id` = `b`.`packagingFk`) + ) + JOIN `vn`.`entry` `e` ON(`b`.`entryFk` = `e`.`id`) + ) + JOIN `vn`.`travel` `t` ON(`t`.`id` = `e`.`travelFk`) + ) + JOIN `vn`.`duaEntry` `de` ON(`de`.`entryFk` = `e`.`id`) + ) + JOIN `vn`.`dua` `d` ON(`d`.`id` = `de`.`duaFk`) + ) + JOIN `vn`.`volumeConfig` `vc` + ) +WHERE `t`.`shipped` > makedate(year(`util`.`VN_CURDATE`()) - 1, 1); + + CREATE OR REPLACE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vn2008`.`Compres` @@ -108,39 +146,3 @@ FROM ( LEFT JOIN `edi`.`supplier` `s` ON(`e`.`pro` = `s`.`supplier_id`) ); -CREATE OR REPLACE DEFINER=`root`@`localhost` - SQL SECURITY DEFINER - VIEW `vn`.`awbVolume` -AS SELECT `d`.`awbFk` AS `awbFk`, - `b`.`stickers` * `i`.`density` * IF( - `p`.`volume` > 0, - `p`.`volume`, - `p`.`width` * `p`.`depth` * IF(`p`.`height` = 0, `i`.`size` + 10, `p`.`height`) - ) / (`vc`.`aerealVolumetricDensity` * 1000) AS `volume`, - `b`.`id` AS `buyFk` -FROM ( - ( - ( - ( - ( - ( - ( - ( - `vn`.`buy` `b` - JOIN `vn`.`item` `i` ON(`b`.`itemFk` = `i`.`id`) - ) - JOIN `vn`.`itemType` `it` ON(`i`.`typeFk` = `it`.`id`) - ) - JOIN `vn`.`packaging` `p` ON(`p`.`id` = `b`.`packagingFk`) - ) - JOIN `vn`.`entry` `e` ON(`b`.`entryFk` = `e`.`id`) - ) - JOIN `vn`.`travel` `t` ON(`t`.`id` = `e`.`travelFk`) - ) - JOIN `vn`.`duaEntry` `de` ON(`de`.`entryFk` = `e`.`id`) - ) - JOIN `vn`.`dua` `d` ON(`d`.`id` = `de`.`duaFk`) - ) - JOIN `vn`.`volumeConfig` `vc` - ) -WHERE `t`.`shipped` > makedate(year(`util`.`VN_CURDATE`()) - 1, 1); \ No newline at end of file From 03e2f5730621e6ca2f481e455a6f693b450f7469 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 2 Nov 2023 10:57:50 +0100 Subject: [PATCH 160/449] refs #6067 fix: emailVerify url --- back/models/vn-user.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index de5bf7b63e..970497e4e8 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -220,8 +220,11 @@ module.exports = function(Self) { class Mailer { async send(verifyOptions, cb) { + const url = new URL(verifyOptions.verifyHref); + if (process.env.NODE_ENV) url.port = ''; + const params = { - url: verifyOptions.verifyHref, + url: url.href, recipient: verifyOptions.to }; From 175e73e5659169d8ea79af2f76b5443f4b08800c Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 2 Nov 2023 14:05:14 +0100 Subject: [PATCH 161/449] fix(clientCredit): refs #6150 se arreglan los inserts en clientCredit --- db/changes/234601/00-clientAfterUpdate.sql | 77 +++++++++++++++++++ modules/client/back/models/client-config.json | 3 + modules/client/back/models/client.js | 20 ++--- .../client/back/models/specs/client.spec.js | 4 +- modules/ticket/front/summary/index.html | 2 +- modules/worker/back/methods/worker/new.js | 13 +++- 6 files changed, 102 insertions(+), 17 deletions(-) create mode 100644 db/changes/234601/00-clientAfterUpdate.sql diff --git a/db/changes/234601/00-clientAfterUpdate.sql b/db/changes/234601/00-clientAfterUpdate.sql new file mode 100644 index 0000000000..4ae594deb4 --- /dev/null +++ b/db/changes/234601/00-clientAfterUpdate.sql @@ -0,0 +1,77 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`client_beforeUpdate` + BEFORE UPDATE ON `client` + FOR EACH ROW +BEGIN + DECLARE vText VARCHAR(255) DEFAULT NULL; + DECLARE vPayMethodFk INT; + + SET NEW.editorFk = account.myUser_getId(); + + IF NOT(NEW.credit <=> OLD.credit) THEN + INSERT INTO clientCredit + SET clientFk = NEW.id, + amount = NEW.credit, + workerFk = NEW.editorFk; + END IF; + -- Comprueba que el formato de los teléfonos es válido + + IF !(NEW.phone <=> OLD.phone) AND (NEW.phone <> '') THEN + CALL pbx.phone_isValid(NEW.phone); + END IF; + + IF !(NEW.mobile <=> OLD.mobile) AND (NEW.mobile <> '')THEN + CALL pbx.phone_isValid(NEW.mobile); + END IF; + + SELECT id INTO vPayMethodFk + FROM vn.payMethod + WHERE code = 'bankDraft'; + + IF NEW.payMethodFk = vPayMethodFk AND NEW.dueDay = 0 THEN + SET NEW.dueDay = 5; + END IF; + + -- Avisar al comercial si ha llegado la documentación sepa/core + + IF NEW.hasSepaVnl AND !OLD.hasSepaVnl THEN + SET vText = 'Sepa de VNL'; + END IF; + + IF NEW.hasCoreVnl AND !OLD.hasCoreVnl THEN + SET vText = 'Core de VNL'; + END IF; + + IF vText IS NOT NULL + THEN + INSERT INTO mail(receiver, replyTo, `subject`, body) + SELECT + CONCAT(IF(ac.id,u.name, 'jgallego'), '@verdnatura.es'), + 'administracion@verdnatura.es', + CONCAT('Cliente ', NEW.id), + CONCAT('Recibida la documentación: ', vText) + FROM worker w + LEFT JOIN account.user u ON w.id = u.id AND u.active + LEFT JOIN account.account ac ON ac.id = u.id + WHERE w.id = NEW.salesPersonFk; + END IF; + + IF NEW.salespersonFk IS NULL AND OLD.salespersonFk IS NOT NULL THEN + IF (SELECT COUNT(clientFk) + FROM clientProtected + WHERE clientFk = NEW.id + ) > 0 THEN + CALL util.throw("HAS_CLIENT_PROTECTED"); + END IF; + END IF; + + IF !(NEW.salesPersonFk <=> OLD.salesPersonFk) THEN + SET NEW.lastSalesPersonFk = IFNULL(NEW.salesPersonFk, OLD.salesPersonFk); + END IF; + + IF !(NEW.businessTypeFk <=> OLD.businessTypeFk) AND (NEW.businessTypeFk = 'individual' OR OLD.businessTypeFk = 'individual') THEN + SET NEW.isTaxDataChecked = 0; + END IF; + +END$$ +DELIMITER ; diff --git a/modules/client/back/models/client-config.json b/modules/client/back/models/client-config.json index 90d47333dd..6c5eae7d73 100644 --- a/modules/client/back/models/client-config.json +++ b/modules/client/back/models/client-config.json @@ -17,6 +17,9 @@ }, "maxCreditRows": { "type": "number" + }, + "defaultCredit": { + "type": "number" } } } \ No newline at end of file diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index e16e884cc5..72b7027798 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -450,14 +450,14 @@ module.exports = Self => { if (lastCredit && lastCredit.amount == 0) { const zeroCreditEditor = - await models.ACL.checkAccessAcl(accessToken, 'Client', 'zeroCreditEditor', 'WRITE'); + await models.ACL.checkAccessAcl(accessToken, 'Client', 'zeroCreditEditor', 'WRITE'); const lastCreditIsNotEditable = - await models.ACL.checkAccessAcl( - {req: {accessToken: {userId: lastCredit.workerFk}}}, - 'Client', - 'zeroCreditEditor', - 'WRITE' - ); + await models.ACL.checkAccessAcl( + {req: {accessToken: {userId: lastCredit.workerFk}}}, + 'Client', + 'zeroCreditEditor', + 'WRITE' + ); if (lastCreditIsNotEditable && !zeroCreditEditor) throw new UserError(`You can't change the credit set to zero from a financialBoss`); @@ -483,12 +483,6 @@ module.exports = Self => { if (userRequiredRoles <= 0) throw new UserError(`You don't have enough privileges to set this credit amount`); } - - await models.ClientCredit.create({ - amount: changes.credit, - clientFk: finalState.id, - workerFk: userId - }, ctx.options); }; Self.changeCreditManagement = async function changeCreditManagement(ctx, finalState, changes) { diff --git a/modules/client/back/models/specs/client.spec.js b/modules/client/back/models/specs/client.spec.js index 201d14bb47..bf134fbf90 100644 --- a/modules/client/back/models/specs/client.spec.js +++ b/modules/client/back/models/specs/client.spec.js @@ -62,13 +62,13 @@ describe('Client Model', () => { const options = {transaction: tx}; const ctx = {options}; - // Set credit to zero by a financialBoss const financialBoss = await models.VnUser.findOne({ where: {name: 'financialBoss'} }, options); ctx.options.accessToken = {userId: financialBoss.id}; - await models.Client.changeCredit(ctx, instance, {credit: 0}); + const testClient = await models.Client.findById(instance.id, options); + await testClient.updateAttributes({credit: 0}, ctx.options); const salesAssistant = await models.VnUser.findOne({ where: {name: 'salesAssistant'} diff --git a/modules/ticket/front/summary/index.html b/modules/ticket/front/summary/index.html index 3c60352a74..4cf7ed11db 100644 --- a/modules/ticket/front/summary/index.html +++ b/modules/ticket/front/summary/index.html @@ -212,7 +212,7 @@ {{::sale.quantity}}
- {{::sale.item.name}} + {{::sale.concept}}

{{::sale.item.subName}}

diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 5316daf016..c9cebda7a1 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -119,7 +119,8 @@ module.exports = Self => { Self.new = async(ctx, options) => { const models = Self.app.models; - const myOptions = {userId: ctx.req.accessToken.userId}; + const {userId} = ctx.req.accessToken; + const myOptions = {userId}; const args = ctx.args; let tx; @@ -188,6 +189,16 @@ module.exports = Self => { myOptions ); + const {defaultCredit} = await models.ClientConfig.findOne(myOptions); + + await models.ClientCredit.create( + { + clientFk: user.id, + amount: defaultCredit, + workerFk: userId + }, myOptions + ); + const address = await models.Address.create( { clientFk: user.id, From 728838334cf427806ae42acaccbcd7e5944f1065 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Thu, 2 Nov 2023 14:42:22 +0100 Subject: [PATCH 162/449] hotFix_6312 fix originalQuantity --- modules/ticket/back/methods/sale/updateQuantity.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index 1a497da248..6108262838 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -64,7 +64,10 @@ module.exports = Self => { const sale = await models.Sale.findById(id, filter, myOptions); const oldQuantity = sale.quantity; - const result = await sale.updateAttributes({quantity: newQuantity}, myOptions); + const result = await sale.updateAttributes({ + quantity: newQuantity, + originalQuantity: newQuantity + }, myOptions); const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { From a523e323735587a8192c4814b646440f5a93a5e7 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 3 Nov 2023 07:57:53 +0100 Subject: [PATCH 163/449] refs #6335 style(ticketAdvance): fix with split-progress --- e2e/helpers/selectors.js | 2 +- loopback/locale/en.json | 5 ++-- .../back/methods/ticket/componentUpdate.js | 2 -- .../ticket/specs/componentUpdate.spec.js | 2 +- modules/ticket/front/advance/index.html | 10 ++------ modules/ticket/front/advance/index.js | 12 ++++----- modules/ticket/front/advance/index.spec.js | 25 ------------------- modules/ticket/front/advance/locale/es.yml | 2 ++ modules/ticket/front/advance/style.scss | 9 +++++++ .../ticket/front/basic-data/step-two/index.js | 1 - 10 files changed, 23 insertions(+), 47 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index cec0545a01..b5dbd42ac1 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -722,7 +722,7 @@ export default { isFullMovable: 'vn-check[ng-model="filter.isFullMovable"]', warehouseFk: 'vn-autocomplete[label="Warehouse"]', tableButtonSearch: 'vn-button[vn-tooltip="Search"]', - moveButton: 'vn-button[vn-tooltip="Advance tickets"]', + moveButton: 'vn-button[vn-tooltip="Advance tickets with negatives"]', acceptButton: '.vn-confirm.shown button[response="accept"]', firstCheck: 'tbody > tr:nth-child(2) > td > vn-check', tableId: 'vn-textfield[name="id"]', diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 26650175d6..9305c7f093 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -196,6 +196,7 @@ "Negative basis of tickets: 23": "Negative basis of tickets: 23", "Booking completed": "Booking complete", "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation", - "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets" + "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets", + "newTicket": "New ticket", + "keepPrice": "Keep prices" } - diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 1b02fd201d..d8d1163daf 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -111,7 +111,6 @@ module.exports = Self => { Self.componentUpdate = async(ctx, options) => { const args = ctx.args; - const originalTicketId = args.id; const myOptions = {userId: ctx.req.accessToken.userId}; let tx; @@ -284,7 +283,6 @@ module.exports = Self => { } response.id = args.id; - console.log(originalTicketId, args.newTicket ? ` TRANSFER TO → ` : ` CREATE NEW TICKET → `, args.id); if (tx) await tx.commit(); return response; diff --git a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js index e124999c93..40be4161c1 100644 --- a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js +++ b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js @@ -210,7 +210,7 @@ describe('ticket componentUpdate()', () => { } }); - describe('ticket componentUpdate()', () => { + describe('componentUpdate() keepPrice', () => { it('should change shipped and keep price', async() => { const tx = await models.Ticket.beginTransaction({}); diff --git a/modules/ticket/front/advance/index.html b/modules/ticket/front/advance/index.html index 395fe7078e..ca4d994d06 100644 --- a/modules/ticket/front/advance/index.html +++ b/modules/ticket/front/advance/index.html @@ -156,13 +156,7 @@ {{::ticket.futureLiters | dashIfEmpty}} {{::ticket.futureZoneName | dashIfEmpty}} - - - {{::ticket.notMovableLines | dashIfEmpty}} - - + {{::ticket.notMovableLines | dashIfEmpty}} {{::ticket.futureLines | dashIfEmpty}} - + diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index 5e41f0f23b..5ab6632569 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -153,11 +153,10 @@ export default class Controller extends Section { return this.$http.get(query, {params}).then(res => { if (res.data) return res.data; - else { - return this.vnApp.showError( - this.$t(`No delivery zone available for this landing date`) - ); - } + + return this.vnApp.showError( + this.$t(`No delivery zone available for this landing date`) + ); }); } @@ -201,7 +200,6 @@ export default class Controller extends Section { async requestComponentUpdate(ticket, isWithoutNegatives) { const query = `tickets/${ticket.futureId}/componentUpdate`; if (!ticket.landed) { - console.log(ticket); const newLanded = await this.getLanded({ shipped: this.$.model.userParams.dateToAdvance, addressFk: ticket.addressFk, @@ -229,7 +227,7 @@ export default class Controller extends Section { newTicket: ticket.id ?? undefined, keepPrice: true }; - console.log(params); + return {query, params}; } diff --git a/modules/ticket/front/advance/index.spec.js b/modules/ticket/front/advance/index.spec.js index da8614ca5d..883993c1cb 100644 --- a/modules/ticket/front/advance/index.spec.js +++ b/modules/ticket/front/advance/index.spec.js @@ -24,31 +24,6 @@ describe('Component vnTicketAdvance', () => { }]; })); - describe('compareDate()', () => { - it('should return warning when the date is the present', () => { - let today = Date.vnNew(); - let result = controller.compareDate(today); - - expect(result).toEqual('warning'); - }); - - it('should return sucess when the date is in the future', () => { - let futureDate = Date.vnNew(); - futureDate = futureDate.setDate(futureDate.getDate() + 10); - let result = controller.compareDate(futureDate); - - expect(result).toEqual('success'); - }); - - it('should return undefined when the date is in the past', () => { - let pastDate = Date.vnNew(); - pastDate = pastDate.setDate(pastDate.getDate() - 10); - let result = controller.compareDate(pastDate); - - expect(result).toEqual(undefined); - }); - }); - describe('checked()', () => { it('should return an array of checked tickets', () => { const result = controller.checked; diff --git a/modules/ticket/front/advance/locale/es.yml b/modules/ticket/front/advance/locale/es.yml index 520e82009a..e42e65b6e6 100644 --- a/modules/ticket/front/advance/locale/es.yml +++ b/modules/ticket/front/advance/locale/es.yml @@ -1,4 +1,6 @@ Advance tickets: Adelantar tickets +Advance tickets with negatives: Adelantar tickets con negativos +Advance tickets without negatives: Adelantar tickets sin negativos Search advance tickets by date: Busca tickets para adelantar por fecha Advance confirmation: ¿Desea adelantar {{checked}} tickets? Success: "{{tickets}} Tickets movidos correctamente" diff --git a/modules/ticket/front/advance/style.scss b/modules/ticket/front/advance/style.scss index 8fa9de4381..82ae901cd7 100644 --- a/modules/ticket/front/advance/style.scss +++ b/modules/ticket/front/advance/style.scss @@ -5,3 +5,12 @@ vn-ticket-advance{ color: #f7931e } } +.split-progress { + width: 40em; +} + +@media screen and (max-width: 600px) { + .split-progress { + width: 100%; + } +} diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index 8ca9f053d7..8c8a3a079e 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -115,7 +115,6 @@ class Controller extends Component { option: parseInt(this.ticket.option), isWithoutNegatives: this.ticket.withoutNegatives, withWarningAccept: this.ticket.withWarningAccept, - newTicket: null, keepPrice: false }; From 8c5e40c27fb8477027294feefb65cb6076e02a80 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 3 Nov 2023 15:16:03 +0100 Subject: [PATCH 164/449] refs #4797 fix: correct sql folder --- db/changes/{232201 => 234601}/00-notificationSubscription.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{232201 => 234601}/00-notificationSubscription.sql (100%) diff --git a/db/changes/232201/00-notificationSubscription.sql b/db/changes/234601/00-notificationSubscription.sql similarity index 100% rename from db/changes/232201/00-notificationSubscription.sql rename to db/changes/234601/00-notificationSubscription.sql From 98f237b4bd9ae2b0c213d9804969c8ccb1c6d57b Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Fri, 3 Nov 2023 16:10:46 +0100 Subject: [PATCH 165/449] new middleware for auth:before --- loopback/server/middleware.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/loopback/server/middleware.json b/loopback/server/middleware.json index 31a2f113b5..45e8ada23d 100644 --- a/loopback/server/middleware.json +++ b/loopback/server/middleware.json @@ -34,12 +34,15 @@ } } }, + "auth:before": { + "./middleware/renew-token": {} + }, "auth:after": { "./middleware/current-user": {}, "./middleware/salix-version": {} }, "parse": { - "body-parser#json":{} + "body-parser#json":{} }, "routes": { "loopback#rest": { From 38d1e2b14fb2babad9453313b7cc54ed55fdf5c9 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Fri, 3 Nov 2023 16:11:35 +0100 Subject: [PATCH 166/449] renew-token middleware definition --- loopback/server/middleware/renew-token.js | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 loopback/server/middleware/renew-token.js diff --git a/loopback/server/middleware/renew-token.js b/loopback/server/middleware/renew-token.js new file mode 100644 index 0000000000..ab58259426 --- /dev/null +++ b/loopback/server/middleware/renew-token.js @@ -0,0 +1,24 @@ +const {models} = require('vn-loopback/server/server'); + +module.exports = function(options) { + return async function(req, res, next) { + const token = req.headers.authorization; + if (!token) return next(); + + const accessToken = await models.AccessToken.findById(token); + if (!accessToken) return next(); + const maxDate = accessToken.created.setSeconds(accessToken.ttl); + if (new Date().getTime() > new Date(maxDate)) return next(); + + const vnUser = await models.VnUser.findById(accessToken.userId); + if (!vnUser) return next(); + const newToken = await vnUser.createAccessToken(accessToken.ttl); + + // console.log(accessToken, newToken); + // req.accessToken = newToken; + // res.headers.authorization = newToken; + res.setHeader('Authorization', newToken.id); + // const removed = await accessToken.delete({id: token}); + next(); + }; +}; From 82ee4f6e5b344e11111c5684182ca7ab7d5a649f Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Sat, 4 Nov 2023 14:38:21 +0100 Subject: [PATCH 167/449] remove auth:before middleware --- loopback/server/middleware.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/loopback/server/middleware.json b/loopback/server/middleware.json index 45e8ada23d..cfc6932175 100644 --- a/loopback/server/middleware.json +++ b/loopback/server/middleware.json @@ -34,9 +34,6 @@ } } }, - "auth:before": { - "./middleware/renew-token": {} - }, "auth:after": { "./middleware/current-user": {}, "./middleware/salix-version": {} From 8c6eab23e5ab76d5bf2516c9291a32fe8a1b1dc9 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Sat, 4 Nov 2023 14:39:26 +0100 Subject: [PATCH 168/449] handle expired token and return new token --- back/methods/vn-user/is-token-valid.js | 7 +++++++ back/methods/vn-user/renew-token.js | 26 ++++++++++++++++---------- back/methods/vn-user/validate-token.js | 9 +++++++-- 3 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 back/methods/vn-user/is-token-valid.js diff --git a/back/methods/vn-user/is-token-valid.js b/back/methods/vn-user/is-token-valid.js new file mode 100644 index 0000000000..1104b55e2b --- /dev/null +++ b/back/methods/vn-user/is-token-valid.js @@ -0,0 +1,7 @@ + +module.exports = async(token, accessTokenConfig) => { + const now = new Date(); + const differenceMilliseconds = now - token.created; + const differenceSeconds = Math.floor(differenceMilliseconds / 1000); + return differenceSeconds > accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime; +}; diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index 9850267d6b..1206e537ff 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -1,5 +1,12 @@ const UserError = require('vn-loopback/util/user-error'); - +const handlePromiseLogout = (Self, {id}, courtesyTime = 60) => { + new Promise(res => { + setTimeout(() => { + res(Self.logout(id)); + } + , courtesyTime * 1000); + }); +}; module.exports = Self => { Self.remoteMethodCtx('renewToken', { description: 'Checks if the token has more than renewPeriod seconds to live and if so, renews it', @@ -19,17 +26,16 @@ module.exports = Self => { const models = Self.app.models; const token = ctx.req.accessToken; - const now = new Date(); - const differenceMilliseconds = now - token.created; - const differenceSeconds = Math.floor(differenceMilliseconds / 1000); + // Check if current token is valid + const isValid = await Self.validateToken(token); + if (!isValid) throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded'); + const fields = ['courtesyTime']; + const {courtesyTime} = await models.AccessTokenConfig.findOne({fields}); - const fields = ['renewPeriod', 'courtesyTime']; - const accessTokenConfig = await models.AccessTokenConfig.findOne({fields}); + // Schedule to remove current token + handlePromiseLogout(Self, token, courtesyTime); - if (differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime) - throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded'); - - await Self.logout(token.id); + // Create new accessToken const user = await Self.findById(token.userId); const accessToken = await user.createAccessToken(); diff --git a/back/methods/vn-user/validate-token.js b/back/methods/vn-user/validate-token.js index 7bccfe0b1d..5cbbbf0e88 100644 --- a/back/methods/vn-user/validate-token.js +++ b/back/methods/vn-user/validate-token.js @@ -1,3 +1,5 @@ +const isTokenValid = require('./is-token-valid'); + module.exports = Self => { Self.remoteMethod('validateToken', { description: 'Validates the current logged user token', @@ -11,7 +13,10 @@ module.exports = Self => { } }); - Self.validateToken = async function() { - return true; + Self.validateToken = async function(token) { + const fields = ['renewPeriod', 'courtesyTime']; + const accessTokenConfig = await Self.app.models.AccessTokenConfig.findOne({fields}); + const isValid = await isTokenValid(token, accessTokenConfig); + return isValid; }; }; From b02e1f000ef61d4ba0c2156c66fccdb2d5582c31 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Sat, 4 Nov 2023 14:39:59 +0100 Subject: [PATCH 169/449] handle expired token while exists in BD --- loopback/server/middleware/current-user.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/loopback/server/middleware/current-user.js b/loopback/server/middleware/current-user.js index a6624351e7..8ff4bb618b 100644 --- a/loopback/server/middleware/current-user.js +++ b/loopback/server/middleware/current-user.js @@ -1,7 +1,16 @@ +const {models} = require('vn-loopback/server/server'); + module.exports = function(options) { - return function(req, res, next) { - if (!req.accessToken) + return async function(req, res, next) { + if (!req.accessToken) { + const token = req.headers.authorization; + if (!token) return next(); + + const accessToken = await models.AccessToken.findById(token); + if (!accessToken) return next(); + return next(); + } let LoopBackContext = require('loopback-context'); let loopbackContext = LoopBackContext.getCurrentContext(); From 67faf076d267af7a88a7b93ae48bee7f7f9b5c8c Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Sat, 4 Nov 2023 16:51:25 +0100 Subject: [PATCH 170/449] refs '#6264' feat: memoization accessTokenConfig --- back/methods/vn-user/is-token-valid.js | 5 ++++- back/methods/vn-user/renew-token.js | 11 ++++++----- back/methods/vn-user/token-config.js | 9 +++++++++ back/methods/vn-user/validate-token.js | 4 +--- 4 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 back/methods/vn-user/token-config.js diff --git a/back/methods/vn-user/is-token-valid.js b/back/methods/vn-user/is-token-valid.js index 1104b55e2b..e40c2765aa 100644 --- a/back/methods/vn-user/is-token-valid.js +++ b/back/methods/vn-user/is-token-valid.js @@ -1,5 +1,8 @@ +const tokenConfig = require('./token-config'); + +module.exports = async token => { + const accessTokenConfig = await tokenConfig(); -module.exports = async(token, accessTokenConfig) => { const now = new Date(); const differenceMilliseconds = now - token.created; const differenceSeconds = Math.floor(differenceMilliseconds / 1000); diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index 1206e537ff..4226886fc2 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -1,5 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); -const handlePromiseLogout = (Self, {id}, courtesyTime = 60) => { +const tokenConfig = require('./token-config'); +const DEFAULT_COURTESY_TIME = 60; +const handlePromiseLogout = (Self, {id}, courtesyTime = DEFAULT_COURTESY_TIME) => { new Promise(res => { setTimeout(() => { res(Self.logout(id)); @@ -23,14 +25,13 @@ module.exports = Self => { }); Self.renewToken = async function(ctx) { - const models = Self.app.models; - const token = ctx.req.accessToken; + const {accessToken: token} = ctx.req; // Check if current token is valid const isValid = await Self.validateToken(token); if (!isValid) throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded'); - const fields = ['courtesyTime']; - const {courtesyTime} = await models.AccessTokenConfig.findOne({fields}); + + const {courtesyTime} = await tokenConfig(); // Schedule to remove current token handlePromiseLogout(Self, token, courtesyTime); diff --git a/back/methods/vn-user/token-config.js b/back/methods/vn-user/token-config.js new file mode 100644 index 0000000000..0936e0b896 --- /dev/null +++ b/back/methods/vn-user/token-config.js @@ -0,0 +1,9 @@ +const DEFAULT_FIELDS = ['renewPeriod', 'courtesyTime']; +const {models} = require('vn-loopback/server/server'); +let currentAccessTokenConfig = null; +module.exports = async(fields = DEFAULT_FIELDS) => { + if (currentAccessTokenConfig) return currentAccessTokenConfig; + const accessTokenConfig = await models.AccessTokenConfig.findOne({fields}); + if (!accessTokenConfig) currentAccessTokenConfig = accessTokenConfig; + return accessTokenConfig; +}; diff --git a/back/methods/vn-user/validate-token.js b/back/methods/vn-user/validate-token.js index 5cbbbf0e88..fadaed43b9 100644 --- a/back/methods/vn-user/validate-token.js +++ b/back/methods/vn-user/validate-token.js @@ -14,9 +14,7 @@ module.exports = Self => { }); Self.validateToken = async function(token) { - const fields = ['renewPeriod', 'courtesyTime']; - const accessTokenConfig = await Self.app.models.AccessTokenConfig.findOne({fields}); - const isValid = await isTokenValid(token, accessTokenConfig); + const isValid = await isTokenValid(token); return isValid; }; }; From 21028e3b79be1e5d8afccd9c8df9bd4dca52979a Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Sat, 4 Nov 2023 17:23:44 +0100 Subject: [PATCH 171/449] refs #6264 feat: db changes --- db/changes/234601/00-updateCourtesyTime.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 db/changes/234601/00-updateCourtesyTime.sql diff --git a/db/changes/234601/00-updateCourtesyTime.sql b/db/changes/234601/00-updateCourtesyTime.sql new file mode 100644 index 0000000000..4751b2e032 --- /dev/null +++ b/db/changes/234601/00-updateCourtesyTime.sql @@ -0,0 +1,4 @@ +-- Auto-generated SQL script #202311061003 +UPDATE salix.accessTokenConfig + SET courtesyTime=60 + WHERE id=1; From 43366d1ba825dfcd32f13278aceb805b048a0ca5 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Sat, 4 Nov 2023 17:24:04 +0100 Subject: [PATCH 172/449] refs #6264 feat: update fixture.sql --- db/dump/fixtures.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index d70279e7de..9bc3e102a1 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2758,7 +2758,7 @@ INSERT INTO `vn`.`sectorCollectionSaleGroup` (`sectorCollectionFk`, `saleGroupFk VALUES (1, 1); -INSERT INTO `vn`.`workerTimeControlConfig` (`id`, `dayBreak`, `dayBreakDriver`, `shortWeekBreak`, `longWeekBreak`, `weekScope`, `mailPass`, `mailHost`, `mailSuccessFolder`, `mailErrorFolder`, `mailUser`, `minHoursToBreak`, `breakHours`, `hoursCompleteWeek`, `startNightlyHours`, `endNightlyHours`, `maxTimePerDay`, `breakTime`, `timeToBreakTime`, `dayMaxTime`, `shortWeekDays`, `longWeekDays`, `teleworkingStart`, `teleworkingStartBreakTime`, `maxTimeToBreak`, `maxWorkShortCycle`, `maxWorkLongCycle`) +INSERT INTO `vn`.`workerTimeControlConfig` (`id`, `dayBreak`, `dayBreakDriver`, `shortWeekBreak`, `longWeekBreak`, `weekScope`, `mailPass`, `mailHost`, `mailSuccessFolder`, `mailErrorFolder`, `mailUser`, `minHoursToBreak`, `breakHours`, `hoursCompleteWeek`, `startNightlyHours`, `endNightlyHours`, `maxTimePerDay`, `breakTime`, `timeToBreakTime`, `dayMaxTime`, `shortWeekDays`, `longWeekDays`, `teleworkingStart`, `teleworkingStartBreakTime`, `maxTimeToBreak`, `maxWorkShortCycle`, `maxWorkLongCycle`) VALUES (1, 43200, 32400, 129600, 259200, 1080000, '', 'imap.verdnatura.es', 'Leidos.exito', 'Leidos.error', 'timeControl', 5.00, 0.33, 40, '22:00:00', '06:00:00', 72000, 1200, 18000, 72000, 6, 13, 28800, 32400, 3600, 561600, 950400); @@ -2945,9 +2945,9 @@ INSERT INTO `vn`.`wagonTypeTray` (`id`, `typeFk`, `height`, `colorFk`) (2, 1, 50, 2), (3, 1, 0, 3); -INSERT INTO `salix`.`accessTokenConfig` (`id`, `renewPeriod`, `renewInterval`) +INSERT INTO `salix`.`accessTokenConfig` (`id`, `renewPeriod`, `courtesyTime`, `renewInterval`) VALUES - (1, 21600, 300); + (1, 21600, 60, 300); INSERT INTO `vn`.`travelConfig` (`id`, `warehouseInFk`, `warehouseOutFk`, `agencyFk`, `companyFk`) VALUES @@ -2986,4 +2986,4 @@ INSERT INTO `vn`.`invoiceCorrectionType` (`id`, `description`) VALUES (1, 'Error in VAT calculation'), (2, 'Error in sales details'), - (3, 'Error in customer data'); \ No newline at end of file + (3, 'Error in customer data'); From 5601ce5dac7ddd8f155961f4ea0d333a391bed04 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Sat, 4 Nov 2023 17:25:30 +0100 Subject: [PATCH 173/449] refs #6264 fix: rename variable --- front/core/services/token.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/front/core/services/token.js b/front/core/services/token.js index 426fe2b731..f1408f7e3e 100644 --- a/front/core/services/token.js +++ b/front/core/services/token.js @@ -82,7 +82,7 @@ export default class Token { if (!data) return; this.renewPeriod = data.renewPeriod; this.stopRenewer(); - this.inservalId = setInterval(() => this.checkValidity(), data.renewInterval * 1000); + this.intervalId = setInterval(() => this.checkValidity(), data.renewInterval * 1000); }); } @@ -113,7 +113,7 @@ export default class Token { } stopRenewer() { - clearInterval(this.inservalId); + clearInterval(this.intervalId); } } Token.$inject = ['vnInterceptor', '$http', '$rootScope']; From 0c2b2b25b741d62e54d4cae526199a338a734836 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Sat, 4 Nov 2023 18:07:37 +0100 Subject: [PATCH 174/449] refs #6264 fix: remove unnecessary file --- loopback/server/middleware/renew-token.js | 24 ----------------------- 1 file changed, 24 deletions(-) delete mode 100644 loopback/server/middleware/renew-token.js diff --git a/loopback/server/middleware/renew-token.js b/loopback/server/middleware/renew-token.js deleted file mode 100644 index ab58259426..0000000000 --- a/loopback/server/middleware/renew-token.js +++ /dev/null @@ -1,24 +0,0 @@ -const {models} = require('vn-loopback/server/server'); - -module.exports = function(options) { - return async function(req, res, next) { - const token = req.headers.authorization; - if (!token) return next(); - - const accessToken = await models.AccessToken.findById(token); - if (!accessToken) return next(); - const maxDate = accessToken.created.setSeconds(accessToken.ttl); - if (new Date().getTime() > new Date(maxDate)) return next(); - - const vnUser = await models.VnUser.findById(accessToken.userId); - if (!vnUser) return next(); - const newToken = await vnUser.createAccessToken(accessToken.ttl); - - // console.log(accessToken, newToken); - // req.accessToken = newToken; - // res.headers.authorization = newToken; - res.setHeader('Authorization', newToken.id); - // const removed = await accessToken.delete({id: token}); - next(); - }; -}; From 99c88e6f5ddea89ac38bc385ee47bae4cef0b445 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 5 Nov 2023 09:33:18 +0100 Subject: [PATCH 175/449] fix: refs #6390 Loggable set as base for ItemShelving --- modules/item/back/models/item-shelving.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/item/back/models/item-shelving.json b/modules/item/back/models/item-shelving.json index 61d05539e1..bb1a141c42 100644 --- a/modules/item/back/models/item-shelving.json +++ b/modules/item/back/models/item-shelving.json @@ -1,6 +1,6 @@ { "name": "ItemShelving", - "base": "VnModel", + "base": "Loggable", "options": { "mysql": { "table": "itemShelving" From 7ca3ea156cc1937564056c350da526fc121f7d4d Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 6 Nov 2023 09:16:10 +0100 Subject: [PATCH 176/449] feat(claimViewer): refs #5881 nuevo rol claimViewer --- db/changes/234601/00-claimViewweAcl.sql | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 db/changes/234601/00-claimViewweAcl.sql diff --git a/db/changes/234601/00-claimViewweAcl.sql b/db/changes/234601/00-claimViewweAcl.sql new file mode 100644 index 0000000000..e913c0ed91 --- /dev/null +++ b/db/changes/234601/00-claimViewweAcl.sql @@ -0,0 +1,31 @@ +INSERT INTO `account`.`role` (`name`, `description`, `hasLogin`) + VALUES ('claimViewer','Trabajadores que consulta las reclamaciones ',1); + +INSERT INTO `account`.`roleInherit` (`role`,`inheritsFrom`) + SELECT `r`.`id`, `r2`.`id` + FROM `account`.`role` `r` + JOIN `account`.`role` `r2` ON `r2`.`name` = 'claimViewer' + WHERE `r`.`name` IN ( + 'salesPerson', + 'buyer', + 'deliveryBoss', + 'handmadeBoss' + ); + +DELETE FROM `salix`.`ACL` + WHERE `model`= 'claim' + AND `property` IN ( + 'filter', + 'find', + 'findById', + 'getSummary' + ); + +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) + VALUES ('Claim','filter','READ','ALLOW','ROLE','claimViewer'); +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) + VALUES ('Claim','find','READ','ALLOW','ROLE','claimViewer'); +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) + VALUES ('Claim','findById','READ','ALLOW','ROLE','claimViewer'); +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) + VALUES ('Claim','getSummary','READ','ALLOW','ROLE','claimViewer'); \ No newline at end of file From a75565f2ce3e549355ee9601958acec07f9697a1 Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 6 Nov 2023 14:23:36 +0100 Subject: [PATCH 177/449] feat(client.create): refs #6150 clientCredit update fix --- db/changes/234601/00-clientAfterUpdate.sql | 48 +++++++++++++++++++++- db/dump/fixtures.sql | 3 +- modules/worker/back/methods/worker/new.js | 10 ----- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/db/changes/234601/00-clientAfterUpdate.sql b/db/changes/234601/00-clientAfterUpdate.sql index 4ae594deb4..49854ebcda 100644 --- a/db/changes/234601/00-clientAfterUpdate.sql +++ b/db/changes/234601/00-clientAfterUpdate.sql @@ -1,3 +1,7 @@ +ALTER TABLE `vn`.`client` MODIFY COLUMN `credit` decimal(10,2) unsigned DEFAULT 0.00 NOT NULL; + +DELETE FROM `salix`.`ACL` WHERE `model` = 'Client' AND `property` = 'create'; + DELIMITER $$ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`client_beforeUpdate` BEFORE UPDATE ON `client` @@ -72,6 +76,48 @@ BEGIN IF !(NEW.businessTypeFk <=> OLD.businessTypeFk) AND (NEW.businessTypeFk = 'individual' OR OLD.businessTypeFk = 'individual') THEN SET NEW.isTaxDataChecked = 0; END IF; - END$$ DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`ticket_afterInsert` + AFTER INSERT ON `ticket` + FOR EACH ROW +BEGIN + DECLARE vClientType VARCHAR(255); + DECLARE vStateCode VARCHAR(255); + DECLARE vTransferorFirstShipped DATE; + + IF NEW.credit NOT NULL AND NEW.credit <> 0 THEN + INSERT INTO clientCredit + SET clientFk = NEW.id, + workerFk = NEW.editorFk, + amount = NEW.credit; + END IF; + + -- Borrar cuando se cambie el insert ticket en la APP móvil + + SELECT typeFk INTO vClientType + FROM vn.`client` WHERE id = NEW.clientFk; + + IF vClientType = 'loses' THEN + SET vStateCode = 'DELIVERED'; + ELSE + SET vStateCode = 'FREE'; + END IF; + + CALL ticket_setState(NEW.id, vStateCode); + + IF YEAR(NEW.shipped) > 2000 THEN + SELECT cnb.firstShipped INTO vTransferorFirstShipped + FROM bs.clientNewBorn cnb + JOIN `client` c ON c.transferorFk = cnb.clientFk + WHERE c.id = NEW.clientFk; + + INSERT INTO bs.clientNewBorn(clientFk, firstShipped, lastShipped) + VALUES(NEW.clientFk, IFNULL(vTransferorFirstShipped, util.VN_CURDATE()), util.VN_CURDATE()) + ON DUPLICATE KEY UPDATE lastShipped = util.VN_CURDATE(); + END IF; +END$$ +DELIMITER ; + diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index faf58fd78d..1dd8a7bd85 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -491,7 +491,8 @@ INSERT INTO `vn`.`clientCreditLimit`(`id`, `maxAmount`, `roleFk`) VALUES (1, 9999999, 20), (2, 10000, 21), - (3, 600, 13); + (3, 600, 13), + (4, 300, 37); INSERT INTO `vn`.`clientObservation`(`id`, `clientFk`, `workerFk`, `text`, `created`) VALUES diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index c9cebda7a1..6610e69196 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -189,16 +189,6 @@ module.exports = Self => { myOptions ); - const {defaultCredit} = await models.ClientConfig.findOne(myOptions); - - await models.ClientCredit.create( - { - clientFk: user.id, - amount: defaultCredit, - workerFk: userId - }, myOptions - ); - const address = await models.Address.create( { clientFk: user.id, From b442c9f5ed2a5b09389c3be63af8bd8261494e0a Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 6 Nov 2023 14:54:56 +0100 Subject: [PATCH 178/449] fix: refs #6150 ticket to client trigger --- db/changes/234601/00-clientAfterUpdate.sql | 38 +++++++--------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/db/changes/234601/00-clientAfterUpdate.sql b/db/changes/234601/00-clientAfterUpdate.sql index 49854ebcda..90ff5d52a4 100644 --- a/db/changes/234601/00-clientAfterUpdate.sql +++ b/db/changes/234601/00-clientAfterUpdate.sql @@ -80,44 +80,30 @@ END$$ DELIMITER ; DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`ticket_afterInsert` - AFTER INSERT ON `ticket` +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`client_beforeInsert` + BEFORE INSERT ON `client` FOR EACH ROW BEGIN - DECLARE vClientType VARCHAR(255); - DECLARE vStateCode VARCHAR(255); - DECLARE vTransferorFirstShipped DATE; - - IF NEW.credit NOT NULL AND NEW.credit <> 0 THEN + IF NEW.credit NOT NULL AND NEW.credit THEN INSERT INTO clientCredit SET clientFk = NEW.id, workerFk = NEW.editorFk, amount = NEW.credit; END IF; - -- Borrar cuando se cambie el insert ticket en la APP móvil + SET NEW.editorFk = account.myUser_getId(); - SELECT typeFk INTO vClientType - FROM vn.`client` WHERE id = NEW.clientFk; - - IF vClientType = 'loses' THEN - SET vStateCode = 'DELIVERED'; - ELSE - SET vStateCode = 'FREE'; + IF (NEW.phone <> '') THEN + CALL pbx.phone_isValid(NEW.phone); END IF; - CALL ticket_setState(NEW.id, vStateCode); - - IF YEAR(NEW.shipped) > 2000 THEN - SELECT cnb.firstShipped INTO vTransferorFirstShipped - FROM bs.clientNewBorn cnb - JOIN `client` c ON c.transferorFk = cnb.clientFk - WHERE c.id = NEW.clientFk; - - INSERT INTO bs.clientNewBorn(clientFk, firstShipped, lastShipped) - VALUES(NEW.clientFk, IFNULL(vTransferorFirstShipped, util.VN_CURDATE()), util.VN_CURDATE()) - ON DUPLICATE KEY UPDATE lastShipped = util.VN_CURDATE(); + IF (NEW.mobile <> '') THEN + CALL pbx.phone_isValid(NEW.mobile); END IF; + + SET NEW.accountingAccount = 4300000000 + NEW.id; + + SET NEW.lastSalesPersonFk = NEW.salesPersonFk; END$$ DELIMITER ; From 1c6618d49432d07ff59ec49b7676bd7d78e302d9 Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 6 Nov 2023 14:56:48 +0100 Subject: [PATCH 179/449] fix(new): refs #6150 revert chabges in worker new method --- modules/worker/back/methods/worker/new.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 6610e69196..5316daf016 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -119,8 +119,7 @@ module.exports = Self => { Self.new = async(ctx, options) => { const models = Self.app.models; - const {userId} = ctx.req.accessToken; - const myOptions = {userId}; + const myOptions = {userId: ctx.req.accessToken.userId}; const args = ctx.args; let tx; From 0818efaa9936c8eb7244c5df83887852cb97cd2b Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 6 Nov 2023 14:58:39 +0100 Subject: [PATCH 180/449] fix(fixtures): refs #6150 clientCredit --- db/dump/fixtures.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index d0afa8d818..d70279e7de 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -491,8 +491,7 @@ INSERT INTO `vn`.`clientCreditLimit`(`id`, `maxAmount`, `roleFk`) VALUES (1, 9999999, 20), (2, 10000, 21), - (3, 600, 13), - (4, 300, 37); + (3, 600, 13); INSERT INTO `vn`.`clientObservation`(`id`, `clientFk`, `workerFk`, `text`, `created`) VALUES From d30c4e446379ae2adbb2112cb84ae205ad252b3a Mon Sep 17 00:00:00 2001 From: sergiodt Date: Tue, 7 Nov 2023 16:13:21 +0100 Subject: [PATCH 181/449] refs #5652 feat:addressShortage --- db/changes/234601/00-addressShortage.sql | 97 +++++++++++++++++++ modules/client/back/model-config.json | 3 + .../client/back/models/addressShortage.json | 22 +++++ 3 files changed, 122 insertions(+) create mode 100644 db/changes/234601/00-addressShortage.sql create mode 100644 modules/client/back/models/addressShortage.json diff --git a/db/changes/234601/00-addressShortage.sql b/db/changes/234601/00-addressShortage.sql new file mode 100644 index 0000000000..dd8ef8e4b8 --- /dev/null +++ b/db/changes/234601/00-addressShortage.sql @@ -0,0 +1,97 @@ + +-- Place your SQL code here + +ALTER TABLE `vn`.`productionConfig` ADD shortageAddressFk int(11) COMMENT 'Address por defecto para añadir un item de alta'; +ALTER TABLE `vn`.`productionConfig` ADD CONSTRAINT productionConfig_FK FOREIGN KEY (shortageAddressFk) REFERENCES vn.address(id) ON DELETE CASCADE ON UPDATE CASCADE; + +ALTER TABLE `vn`.`sale` MODIFY COLUMN originalQuantity double(9,1) DEFAULT NULL NULL COMMENT 'Se utiliza para notificar a través de rocket los cambios de quantity'; + +INSERT INTO `salix`.`ACL` ( model, property, accessType, permission, principalType, principalId) VALUES( 'AddressShortage', '*', 'READ', 'ALLOW', 'ROLE', 'production'); + +-- vn.addressShortage definition + +CREATE TABLE `vn`.`addressShortage` ( + `addressFk` int(11) NOT NULL, + PRIMARY KEY (`addressFk`), + CONSTRAINT `addressShortage_FK` FOREIGN KEY (`addressFk`) REFERENCES `address` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + + +DELIMITER $$ + +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_setVisibleDiscard`( + vItemFk INT, + vWarehouseFk INT, + vQuantity INT, + vAddressFk INT) +BEGIN +/** + * Procedimiento para dar dar de baja/alta un item, si vAddressFk es NULL se entiende que se da de alta y se toma el addressFk de la configuración + * + * @param vItemFk Identificador del ítem + * @param vWarehouseFk id del warehouse + * @param vQuantity a dar de alta/baja + * @param vAddressFk id address + */ + DECLARE vTicketFk INT; + DECLARE vClientFk INT; + DECLARE vCompanyVnlFk INT; + DECLARE vCalc INT; + DECLARE vAddressShortage INT; + + SELECT barcodeToItem(vItemFk) INTO vItemFk; + + SELECT DEFAULT(companyFk) INTO vCompanyVnlFk + FROM vn.ticket LIMIT 1; + + IF vAddressFk IS NULL THEN + SELECT pc.shortageAddressFk FROM productionConfig pc INTO vAddressShortage; + ELSE + SET vAddressShortage = vAddressFk; + END IF; + + SELECT a.clientFk INTO vClientFk + FROM address a + WHERE a.id = vAddressFk; + + SELECT t.id INTO vTicketFk + FROM ticket t + JOIN address a ON a.id = t.addressFk + JOIN ticketState ts ON ts.ticketFk = t.id + WHERE t.warehouseFk = vWarehouseFk + AND a.id = vAddressShortage + AND DATE(t.shipped) = util.VN_CURDATE() + AND ts.code = 'DELIVERED' + LIMIT 1; + + CALL cache.visible_refresh(vCalc, TRUE, vWarehouseFk); + + IF vTicketFk IS NULL THEN + CALL ticket_add( + vClientFk, + util.VN_CURDATE(), + vWarehouseFk, + vCompanyVnlFk, + vAddressFk, + NULL, + NULL, + util.VN_CURDATE(), + account.myUser_getId(), + FALSE, + vTicketFk); + END IF; + + INSERT INTO sale(ticketFk, itemFk, concept, quantity) + SELECT vTicketFk, + vItemFk, + CONCAT(longName,' ', worker_getCode(), ' ', LEFT(CAST(util.VN_NOW() AS TIME),5)), + vQuantity + FROM item + WHERE id = vItemFk; + + UPDATE cache.visible + SET visible = visible - vQuantity + WHERE calc_id = vCalc + AND item_id = vItemFk; +END$$ +DELIMITER ; diff --git a/modules/client/back/model-config.json b/modules/client/back/model-config.json index 296b5e6a7b..0cc5df9a2f 100644 --- a/modules/client/back/model-config.json +++ b/modules/client/back/model-config.json @@ -5,6 +5,9 @@ "AddressObservation": { "dataSource": "vn" }, + "AddressShortage": { + "dataSource": "vn" + }, "BankEntity": { "dataSource": "vn" }, diff --git a/modules/client/back/models/addressShortage.json b/modules/client/back/models/addressShortage.json new file mode 100644 index 0000000000..1ae8d986c8 --- /dev/null +++ b/modules/client/back/models/addressShortage.json @@ -0,0 +1,22 @@ +{ + "name": "AddressShortage", + "base": "VnModel", + "options": { + "mysql": { + "table": "addressShortage" + } + }, + "properties": { + "addressFk": { + "type": "number", + "id": true + } + }, + "relations": { + "address": { + "type": "belongsTo", + "model": "Address", + "foreignKey": "addressFk" + } + } +} \ No newline at end of file From 784f5bb7f92f5b7df876b722fcc645972938faac Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 7 Nov 2023 23:23:02 +0100 Subject: [PATCH 182/449] refs #6264 perf: replace now with vnNew --- back/methods/vn-user/is-token-valid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/methods/vn-user/is-token-valid.js b/back/methods/vn-user/is-token-valid.js index e40c2765aa..f4c2a9ea80 100644 --- a/back/methods/vn-user/is-token-valid.js +++ b/back/methods/vn-user/is-token-valid.js @@ -3,7 +3,7 @@ const tokenConfig = require('./token-config'); module.exports = async token => { const accessTokenConfig = await tokenConfig(); - const now = new Date(); + const now = Date.vnNew(); const differenceMilliseconds = now - token.created; const differenceSeconds = Math.floor(differenceMilliseconds / 1000); return differenceSeconds > accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime; From 9d5461862026731a490f6a04aa11219e994379b0 Mon Sep 17 00:00:00 2001 From: jgallego Date: Wed, 8 Nov 2023 10:01:02 +0100 Subject: [PATCH 183/449] fix: refs: #6207 impide facturar si no tienes incoterm --- db/dump/fixtures.sql | 8 +++--- loopback/locale/es.json | 4 +-- .../ticket/back/methods/ticket/makeInvoice.js | 13 ++++++--- .../methods/ticket/specs/makeInvoice.spec.js | 27 +++++++++++++++++++ .../invoice-incoterms/sql/incoterms.sql | 4 +-- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index faf58fd78d..164723de12 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -367,7 +367,7 @@ INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city (1105, 'Max Eisenhardt', '251628698', 'MAGNETO', 'Rogue', 'UNKNOWN WHEREABOUTS', 'Gotham', 46460, 1111111111, 222222222, 1, 'MaxEisenhardt@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 300, 8, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1, 'florist','normal'), (1106, 'DavidCharlesHaller', '53136686Q', 'LEGION', 'Charles Xavier', 'CITY OF NEW YORK, NEW YORK, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 19, 0, 1, 'florist','normal'), (1107, 'Hank Pym', '09854837G', 'ANT MAN', 'Hawk', 'ANTHILL, SAN FRANCISCO, CALIFORNIA', 'Gotham', 46460, 1111111111, 222222222, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1, 'florist','normal'), - (1108, 'Charles Xavier', '22641921P', 'PROFESSOR X', 'Beast', '3800 VICTORY PKWY, CINCINNATI, OH 45207, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1, 'florist','normal'), + (1108, 'Charles Xavier', '22641921P', 'PROFESSOR X', 'Beast', '3800 VICTORY PKWY, CINCINNATI, OH 45207, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 5, 1, 300, 13, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1, 'florist','normal'), (1109, 'Bruce Banner', '16104829E', 'HULK', 'Black widow', 'SOMEWHERE IN NEW YORK', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, 9, 0, 1, 'florist','normal'), (1110, 'Jessica Jones', '58282869H', 'JESSICA JONES', 'Luke Cage', 'NYCC 2015 POSTER', 'Gotham', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, NULL, 0, 1, 'florist','normal'), (1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','normal'), @@ -405,7 +405,7 @@ INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `pr (5, 'Max Eisenhardt', 'Unknown Whereabouts', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1105, 2, NULL, NULL, 0, 1), (6, 'DavidCharlesHaller', 'Evil hideout', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1106, 2, NULL, NULL, 0, 1), (7, 'Hank Pym', 'Anthill', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1107, 2, NULL, NULL, 0, 1), - (8, 'Charles Xavier', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 1), + (8, 'Charles Xavier', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Gotham', 46460, 5, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 1), (9, 'Bruce Banner', 'Somewhere in New York', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 1), (10, 'Jessica Jones', 'NYCC 2015 Poster', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1110, 2, NULL, NULL, 0, 1), (11, 'Missing', 'The space', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1111, 10, NULL, NULL, 0, 1), @@ -437,7 +437,7 @@ INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `pr (125, 'The plastic cell', 'address 25', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1105, 2, NULL, NULL, 0, 0), (126, 'Many places', 'address 26', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1106, 2, NULL, NULL, 0, 0), (127, 'Your pocket', 'address 27', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1107, 2, NULL, NULL, 0, 0), - (128, 'Cerebro', 'address 28', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 0), + (128, 'Cerebro', 'address 28', 'Gotham', 46460, 5, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 0), (129, 'Luke Cages Bar', 'address 29', 'Gotham', 'EC170150', 1, 1111111111, 222222222, 1, 1110, 2, NULL, NULL, 0, 0), (130, 'Non valid address', 'address 30', 'Gotham', 46460, 1, 1111111111, 222222222, 0, 1101, 2, NULL, NULL, 0, 0); @@ -2982,4 +2982,4 @@ INSERT INTO `vn`.`invoiceCorrectionType` (`id`, `description`) VALUES (1, 'Error in VAT calculation'), (2, 'Error in sales details'), - (3, 'Error in customer data'); \ No newline at end of file + (3, 'Error in customer data'); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 3cc9a96278..e3e19d7e8a 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -321,9 +321,9 @@ "Select a different client": "Seleccione un cliente distinto", "Fill all the fields": "Rellene todos los campos", "The response is not a PDF": "La respuesta no es un PDF", - "Ticket without Route": "Ticket sin ruta", "Booking completed": "Reserva completada", "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mímina", - "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina" + "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina", + "Incoterms data for consignee is missing": "Faltan los datos de los Incoterms para el consignatario" } diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js index e18e58e0b4..e7ee806c79 100644 --- a/modules/ticket/back/methods/ticket/makeInvoice.js +++ b/modules/ticket/back/methods/ticket/makeInvoice.js @@ -49,7 +49,6 @@ module.exports = function(Self) { myOptions.transaction = tx; } - let serial; try { const ticketToInvoice = await Self.rawSql(` SELECT id @@ -60,7 +59,7 @@ module.exports = function(Self) { where: { id: {inq: ticketsIds} }, - fields: ['id', 'clientFk'] + fields: ['id', 'clientFk', 'addressFk'] }, myOptions); await models.Ticket.canBeInvoiced(ctx, ticketsIds, myOptions); @@ -72,13 +71,19 @@ module.exports = function(Self) { throw new UserError(`This client can't be invoiced`); const query = `SELECT vn.invoiceSerial(?, ?, ?) AS serial`; - const [result] = await Self.rawSql(query, [ + const [{serial}] = await Self.rawSql(query, [ clientId, companyFk, invoiceType, ], myOptions); - serial = result.serial; + const invoiceOutSerial = await models.InvoiceOutSerial.findById(serial); + if (invoiceOutSerial?.taxAreaFk == 'WORLD') { + const address = await models.Address.findById(firstTicket.addressFk); + + if (!address || !address.customsAgentFk || !address.incotermsFk) + throw new UserError('Incoterms data for consignee is missing'); + } await Self.rawSql('CALL invoiceOut_new(?, ?, null, @invoiceId)', [serial, invoiceDate], myOptions); const [resultInvoice] = await Self.rawSql('SELECT @invoiceId id', [], myOptions); diff --git a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js index 9af6ad557e..9b1fd8f6f3 100644 --- a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js +++ b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js @@ -52,4 +52,31 @@ describe('ticket makeInvoice()', () => { throw e; } }); + + it('should throw an error when invoicing a client without incoterms', async() => { + const tx = await models.Ticket.beginTransaction({}); + let error; + try { + const options = {transaction: tx}; + + const ticketsId = [18]; + await models.Ticket.rawSql(` + DROP TEMPORARY TABLE IF EXISTS tmp.ticketToInvoice; + CREATE TEMPORARY TABLE tmp.ticketToInvoice + (PRIMARY KEY (id)) + ENGINE = MEMORY + SELECT id + FROM vn.ticket + WHERE id IN (?) + `, [ticketsId], options); + + await models.Ticket.makeInvoice(ctx, invoiceType, companyFk, invoiceDate, options); + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toEqual(`Incoterms data for consignee is missing`); + }); }); diff --git a/print/templates/reports/invoice-incoterms/sql/incoterms.sql b/print/templates/reports/invoice-incoterms/sql/incoterms.sql index 435b3a51ac..0c4af803d8 100644 --- a/print/templates/reports/invoice-incoterms/sql/incoterms.sql +++ b/print/templates/reports/invoice-incoterms/sql/incoterms.sql @@ -1,7 +1,7 @@ SELECT io.issued, c.socialName, c.street postalAddress, - IF (ios.taxAreaFk IS NOT NULL, CONCAT(cty.code, c.fi), c.fi) fi, + c.fi, io.clientFk, c.postcode, c.city, @@ -50,7 +50,7 @@ SELECT io.issued, ) sub2 ON TRUE JOIN vn.itemTaxCountry itc ON itc.countryFk = su.countryFk AND itc.itemFk = s.itemFk JOIN vn.taxClass tc ON tc.id = itc.taxClassFk - LEFT JOIN vn.invoiceOutSerial ios ON ios.code = io.serial AND ios.taxAreaFk = 'CEE' + JOIN vn.invoiceOutSerial ios ON ios.code = io.serial AND ios.taxAreaFk = 'WORLD' JOIN vn.country cty ON cty.id = c.countryFk JOIN vn.payMethod pm ON pm.id = c .payMethodFk JOIN vn.company co ON co.id=io.companyFk From 5751065e6a0f14d27314ec1cad944b52ddc57d83 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Wed, 8 Nov 2023 11:50:04 +0100 Subject: [PATCH 184/449] refs #5652 feat:addressShortage --- db/changes/234601/00-addressShortage.sql | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/db/changes/234601/00-addressShortage.sql b/db/changes/234601/00-addressShortage.sql index dd8ef8e4b8..57c07d4809 100644 --- a/db/changes/234601/00-addressShortage.sql +++ b/db/changes/234601/00-addressShortage.sql @@ -1,8 +1,8 @@ -- Place your SQL code here -ALTER TABLE `vn`.`productionConfig` ADD shortageAddressFk int(11) COMMENT 'Address por defecto para añadir un item de alta'; -ALTER TABLE `vn`.`productionConfig` ADD CONSTRAINT productionConfig_FK FOREIGN KEY (shortageAddressFk) REFERENCES vn.address(id) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `vn`.`productionConfig` ADD shortageAddressFk int(11) COMMENT 'Consignatario por defecto para añadir un item de alta'; +ALTER TABLE `vn`.`productionConfig` ADD CONSTRAINT productionConfig_FK FOREIGN KEY (shortageAddressFk) REFERENCES vn.address(id) ON DELETE RESTRICT ON UPDATE CASCADE; ALTER TABLE `vn`.`sale` MODIFY COLUMN originalQuantity double(9,1) DEFAULT NULL NULL COMMENT 'Se utiliza para notificar a través de rocket los cambios de quantity'; @@ -35,17 +35,18 @@ BEGIN */ DECLARE vTicketFk INT; DECLARE vClientFk INT; - DECLARE vCompanyVnlFk INT; + DECLARE vDefaultCompanyFk INT; DECLARE vCalc INT; DECLARE vAddressShortage INT; SELECT barcodeToItem(vItemFk) INTO vItemFk; - SELECT DEFAULT(companyFk) INTO vCompanyVnlFk + SELECT DEFAULT(companyFk) INTO vDefaultCompanyFk FROM vn.ticket LIMIT 1; IF vAddressFk IS NULL THEN - SELECT pc.shortageAddressFk FROM productionConfig pc INTO vAddressShortage; + SELECT pc.shortageAddressFk INTO vAddressShortage + FROM productionConfig pc ; ELSE SET vAddressShortage = vAddressFk; END IF; @@ -71,7 +72,7 @@ BEGIN vClientFk, util.VN_CURDATE(), vWarehouseFk, - vCompanyVnlFk, + vDefaultCompanyFk, vAddressFk, NULL, NULL, From 0de5bc510935f985078ca364d809f0ac75456f85 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 8 Nov 2023 14:56:47 +0100 Subject: [PATCH 185/449] refs #4797 refactor: getList & notificationSubscription method --- .vscode/settings.json | 5 ++- back/methods/notification/getList.js | 51 ++++++++----------------- back/models/notificationSubscription.js | 40 ++++++++++++++++++- 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 05d23f3bbc..9ed1c8fc2a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,5 +10,8 @@ "eslint.format.enable": true, "[javascript]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint" - } + }, + "cSpell.words": [ + "salix" + ] } diff --git a/back/methods/notification/getList.js b/back/methods/notification/getList.js index 780b8eb746..3881f0f63a 100644 --- a/back/methods/notification/getList.js +++ b/back/methods/notification/getList.js @@ -21,55 +21,34 @@ module.exports = Self => { }); Self.getList = async(id, options) => { - const notifications = new Map(); - const models = Self.app.models; + const activeNotificationsMap = new Map(); const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const roles = await models.RoleMapping.find({ - fields: ['roleId'], - where: {principalId: id} - }, myOptions); - - const availableNotifications = await models.NotificationAcl.find({ - fields: ['notificationFk', 'roleFk'], - include: {relation: 'notification'}, - where: { - roleFk: { - inq: roles.map(role => role.roleId), - }, - } - }, myOptions); - - const activeNotifications = await models.NotificationSubscription.find({ + const availableNotificationsMap = await Self.getAvailable(id, myOptions); + const activeNotifications = await Self.app.models.NotificationSubscription.find({ fields: ['id', 'notificationFk'], include: {relation: 'notification'}, where: {userFk: id} }, myOptions); - for (acl of availableNotifications) { - notifications.set(acl.notificationFk, { - id: null, - notificationFk: acl.notificationFk, - name: acl.notification().name, - description: acl.notification().description, - active: false, + for (active of activeNotifications) { + activeNotificationsMap.set(active.notificationFk, { + id: active.id, + notificationFk: active.notificationFk, + name: active.notification().name, + description: active.notification().description, + active: true }); + availableNotificationsMap.delete(active.notificationFk); } - for (subscription of activeNotifications) { - notifications.set(subscription.notificationFk, { - id: subscription.id, - notificationFk: subscription.notificationFk, - name: subscription.notification().name, - description: subscription.notification().description, - active: true, - }); - } - - return [...notifications.values()]; + return { + active: [...activeNotificationsMap.entries()], + available: [...availableNotificationsMap.entries()] + }; }; }; diff --git a/back/models/notificationSubscription.js b/back/models/notificationSubscription.js index f750a0528a..8efb83e7dc 100644 --- a/back/models/notificationSubscription.js +++ b/back/models/notificationSubscription.js @@ -29,10 +29,46 @@ module.exports = Self => { } const worker = await models.Worker.findById(workerId, {fields: ['id', 'bossFk']}); - const notificationsAvailables = await models.NotificationSubscription.getList(workerId); - const hasAcl = notificationsAvailables.some(available => available.notificationFk === notificationFk); + const available = await Self.getAvailable(workerId); + const hasAcl = available.has(notificationFk); if (!hasAcl || (userId != worker.id && userId != worker.bossFk)) throw new UserError('The notification subscription of this worker cant be modified'); } + + Self.getAvailable = async function(userId, options) { + const availableNotificationsMap = new Map(); + const models = Self.app.models; + + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const roles = await models.RoleMapping.find({ + fields: ['roleId'], + where: {principalId: userId} + }, myOptions); + + const availableNotifications = await models.NotificationAcl.find({ + fields: ['notificationFk', 'roleFk'], + include: {relation: 'notification'}, + where: { + roleFk: { + inq: roles.map(role => role.roleId), + }, + } + }, myOptions); + + for (available of availableNotifications) { + availableNotificationsMap.set(available.notificationFk, { + id: null, + notificationFk: available.notificationFk, + name: available.notification().name, + description: available.notification().description, + active: false + }); + } + return availableNotificationsMap; + }; }; From 204323ac69f448988f93d81ba22206d1500b1027 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 8 Nov 2023 14:57:07 +0100 Subject: [PATCH 186/449] test(notification_getList): fix --- .../notification/specs/getList.spec.js | 30 ++++--------------- db/dump/fixtures.sql | 2 ++ 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/back/methods/notification/specs/getList.spec.js b/back/methods/notification/specs/getList.spec.js index 7c986eba2d..52ac497a56 100644 --- a/back/methods/notification/specs/getList.spec.js +++ b/back/methods/notification/specs/getList.spec.js @@ -2,30 +2,12 @@ const models = require('vn-loopback/server/server').models; describe('NotificationSubscription getList()', () => { it('should return a list of available and active notifications of a user', async() => { - const userId = 1109; - const activeNotifications = await models.NotificationSubscription.find({ - where: {userFk: userId} - }); - const roles = await models.RoleMapping.find({ - fields: ['roleId'], - where: {principalId: userId} - }); - const availableNotifications = await models.NotificationAcl.find({ - where: { - roleFk: { - inq: roles.map(role => { - return role.roleId; - }), - }, - } - }); + const userId = 9; + const {active, available} = await models.NotificationSubscription.getList(userId); + const notifications = await models.Notification.find({}); + const totalAvailable = notifications.length - active.length; - const result = await models.NotificationSubscription.getList(userId); - - expect(result.filter(notification => notification.active == true).length) - .toEqual(activeNotifications.length); - - expect(result.filter(notification => notification.active == false).length) - .toEqual(availableNotifications.length - activeNotifications.length); + expect(active.length).toEqual(2); + expect(available.length).toEqual(totalAvailable); }); }); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 77440ab9f9..efee3bd282 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2790,7 +2790,9 @@ INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`) (1, 9), (1, 1), (2, 1), + (3, 9), (4, 1), + (5, 9), (6, 9); INSERT INTO `util`.`notificationQueue` (`id`, `notificationFk`, `params`, `authorFk`, `status`, `created`) From 4258015c07336fbb7182d8e86e8b5ebc2809a802 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Thu, 9 Nov 2023 08:04:38 +0100 Subject: [PATCH 187/449] refs #5870 feat:fixModel --- modules/worker/back/models/operator.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/worker/back/models/operator.json b/modules/worker/back/models/operator.json index 2417078e1a..6da3945fc3 100644 --- a/modules/worker/back/models/operator.json +++ b/modules/worker/back/models/operator.json @@ -33,6 +33,16 @@ "type": "belongsTo", "model": "Sector", "foreignKey": "sectorFk" + }, + "train": { + "type": "belongsTo", + "model": "Train", + "foreignKey": "trainFk" + }, + "printer": { + "type": "belongsTo", + "model": "Printer", + "foreignKey": "labelerFk" } } } From 973eff4520c526bebad43daad9b4e97dd795792b Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 9 Nov 2023 09:05:56 +0100 Subject: [PATCH 188/449] refs #6415 fix. sql files --- db/changes/234201/00-packagingFkviews.sql | 2 ++ .../234601/00-ACLticketTrackingState.sql | 8 ----- .../00-claimViewerAcl.sql} | 10 +++--- db/changes/234601/00-claimViewweAcl.sql | 31 ----------------- db/changes/234601/00-clientAfterUpdate.sql | 20 ++--------- db/dump/fixtures.sql | 34 +++++++++---------- 6 files changed, 27 insertions(+), 78 deletions(-) rename db/changes/{233601/00-createClaimReader.sql => 234601/00-claimViewerAcl.sql} (86%) delete mode 100644 db/changes/234601/00-claimViewweAcl.sql diff --git a/db/changes/234201/00-packagingFkviews.sql b/db/changes/234201/00-packagingFkviews.sql index abc7dc004f..49d41c26ca 100644 --- a/db/changes/234201/00-packagingFkviews.sql +++ b/db/changes/234201/00-packagingFkviews.sql @@ -1,3 +1,5 @@ +CREATE SCHEMA IF NOT EXISTS `vn2008`; + CREATE OR REPLACE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vn`.`awbVolume` diff --git a/db/changes/234601/00-ACLticketTrackingState.sql b/db/changes/234601/00-ACLticketTrackingState.sql index 0f7bd4f44d..ca6dce0c9d 100644 --- a/db/changes/234601/00-ACLticketTrackingState.sql +++ b/db/changes/234601/00-ACLticketTrackingState.sql @@ -2,11 +2,3 @@ UPDATE `salix`.`ACL` SET `property` = 'state', `model` = 'Ticket' WHERE `property` = 'changeState'; - -REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'productionboss'@; -REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'productionAssi'@; -REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'hr'@; -REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'salesPerson'@; -REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'deliveryPerson'@; -REVOKE INSERT, UPDATE, DELETE ON `vn`.`ticketTracking` FROM 'employee'@; -REVOKE EXECUTE ON `vn`.`ticket_setState` FROM 'employee'@; diff --git a/db/changes/233601/00-createClaimReader.sql b/db/changes/234601/00-claimViewerAcl.sql similarity index 86% rename from db/changes/233601/00-createClaimReader.sql rename to db/changes/234601/00-claimViewerAcl.sql index e913c0ed91..17d8d4ce04 100644 --- a/db/changes/233601/00-createClaimReader.sql +++ b/db/changes/234601/00-claimViewerAcl.sql @@ -21,11 +21,11 @@ DELETE FROM `salix`.`ACL` 'getSummary' ); -INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`) VALUES ('Claim','filter','READ','ALLOW','ROLE','claimViewer'); -INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`) VALUES ('Claim','find','READ','ALLOW','ROLE','claimViewer'); -INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`) VALUES ('Claim','findById','READ','ALLOW','ROLE','claimViewer'); -INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) - VALUES ('Claim','getSummary','READ','ALLOW','ROLE','claimViewer'); \ No newline at end of file +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`) + VALUES ('Claim','getSummary','READ','ALLOW','ROLE','claimViewer'); diff --git a/db/changes/234601/00-claimViewweAcl.sql b/db/changes/234601/00-claimViewweAcl.sql deleted file mode 100644 index e913c0ed91..0000000000 --- a/db/changes/234601/00-claimViewweAcl.sql +++ /dev/null @@ -1,31 +0,0 @@ -INSERT INTO `account`.`role` (`name`, `description`, `hasLogin`) - VALUES ('claimViewer','Trabajadores que consulta las reclamaciones ',1); - -INSERT INTO `account`.`roleInherit` (`role`,`inheritsFrom`) - SELECT `r`.`id`, `r2`.`id` - FROM `account`.`role` `r` - JOIN `account`.`role` `r2` ON `r2`.`name` = 'claimViewer' - WHERE `r`.`name` IN ( - 'salesPerson', - 'buyer', - 'deliveryBoss', - 'handmadeBoss' - ); - -DELETE FROM `salix`.`ACL` - WHERE `model`= 'claim' - AND `property` IN ( - 'filter', - 'find', - 'findById', - 'getSummary' - ); - -INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) - VALUES ('Claim','filter','READ','ALLOW','ROLE','claimViewer'); -INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) - VALUES ('Claim','find','READ','ALLOW','ROLE','claimViewer'); -INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) - VALUES ('Claim','findById','READ','ALLOW','ROLE','claimViewer'); -INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`) - VALUES ('Claim','getSummary','READ','ALLOW','ROLE','claimViewer'); \ No newline at end of file diff --git a/db/changes/234601/00-clientAfterUpdate.sql b/db/changes/234601/00-clientAfterUpdate.sql index 90ff5d52a4..c6483813fd 100644 --- a/db/changes/234601/00-clientAfterUpdate.sql +++ b/db/changes/234601/00-clientAfterUpdate.sql @@ -80,30 +80,16 @@ END$$ DELIMITER ; DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`client_beforeInsert` - BEFORE INSERT ON `client` +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`client_AfterInsert` + AFTER INSERT ON `client` FOR EACH ROW BEGIN - IF NEW.credit NOT NULL AND NEW.credit THEN + IF NEW.credit IS NOT NULL AND NEW.credit THEN INSERT INTO clientCredit SET clientFk = NEW.id, workerFk = NEW.editorFk, amount = NEW.credit; END IF; - - SET NEW.editorFk = account.myUser_getId(); - - IF (NEW.phone <> '') THEN - CALL pbx.phone_isValid(NEW.phone); - END IF; - - IF (NEW.mobile <> '') THEN - CALL pbx.phone_isValid(NEW.mobile); - END IF; - - SET NEW.accountingAccount = 4300000000 + NEW.id; - - SET NEW.lastSalesPersonFk = NEW.salesPersonFk; END$$ DELIMITER ; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index d70279e7de..ae47a1eef9 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -470,22 +470,22 @@ CREATE TEMPORARY TABLE tmp.address WHERE `defaultAddressFk` IS NULL; DROP TEMPORARY TABLE tmp.address; -INSERT INTO `vn`.`clientCredit`(`id`, `clientFk`, `workerFk`, `amount`, `created`) +INSERT INTO `vn`.`clientCredit`(`clientFk`, `workerFk`, `amount`, `created`) VALUES - (1 , 1101, 5, 300, DATE_ADD(util.VN_CURDATE(), INTERVAL -11 MONTH)), - (2 , 1101, 5, 900, DATE_ADD(util.VN_CURDATE(), INTERVAL -10 MONTH)), - (3 , 1101, 5, 800, DATE_ADD(util.VN_CURDATE(), INTERVAL -9 MONTH)), - (4 , 1101, 5, 700, DATE_ADD(util.VN_CURDATE(), INTERVAL -8 MONTH)), - (5 , 1101, 5, 600, DATE_ADD(util.VN_CURDATE(), INTERVAL -7 MONTH)), - (6 , 1101, 5, 500, DATE_ADD(util.VN_CURDATE(), INTERVAL -6 MONTH)), - (7 , 1101, 5, 400, DATE_ADD(util.VN_CURDATE(), INTERVAL -5 MONTH)), - (8 , 1101, 9, 300, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH)), - (9 , 1101, 9, 200, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH)), - (10, 1101, 9, 100, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)), - (11, 1101, 9, 50 , DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)), - (12, 1102, 9, 800, util.VN_CURDATE()), - (14, 1104, 9, 90 , util.VN_CURDATE()), - (15, 1105, 9, 90 , util.VN_CURDATE()); + (1101, 5, 300, DATE_ADD(util.VN_CURDATE(), INTERVAL -11 MONTH)), + (1101, 5, 900, DATE_ADD(util.VN_CURDATE(), INTERVAL -10 MONTH)), + (1101, 5, 800, DATE_ADD(util.VN_CURDATE(), INTERVAL -9 MONTH)), + (1101, 5, 700, DATE_ADD(util.VN_CURDATE(), INTERVAL -8 MONTH)), + (1101, 5, 600, DATE_ADD(util.VN_CURDATE(), INTERVAL -7 MONTH)), + (1101, 5, 500, DATE_ADD(util.VN_CURDATE(), INTERVAL -6 MONTH)), + (1101, 5, 400, DATE_ADD(util.VN_CURDATE(), INTERVAL -5 MONTH)), + (1101, 9, 300, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH)), + (1101, 9, 200, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH)), + (1101, 9, 100, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)), + (1101, 9, 50 , DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)), + (1102, 9, 800, util.VN_CURDATE()), + (1104, 9, 90 , util.VN_CURDATE()), + (1105, 9, 90 , util.VN_CURDATE()); INSERT INTO `vn`.`clientCreditLimit`(`id`, `maxAmount`, `roleFk`) VALUES @@ -2758,7 +2758,7 @@ INSERT INTO `vn`.`sectorCollectionSaleGroup` (`sectorCollectionFk`, `saleGroupFk VALUES (1, 1); -INSERT INTO `vn`.`workerTimeControlConfig` (`id`, `dayBreak`, `dayBreakDriver`, `shortWeekBreak`, `longWeekBreak`, `weekScope`, `mailPass`, `mailHost`, `mailSuccessFolder`, `mailErrorFolder`, `mailUser`, `minHoursToBreak`, `breakHours`, `hoursCompleteWeek`, `startNightlyHours`, `endNightlyHours`, `maxTimePerDay`, `breakTime`, `timeToBreakTime`, `dayMaxTime`, `shortWeekDays`, `longWeekDays`, `teleworkingStart`, `teleworkingStartBreakTime`, `maxTimeToBreak`, `maxWorkShortCycle`, `maxWorkLongCycle`) +INSERT INTO `vn`.`workerTimeControlConfig` (`id`, `dayBreak`, `dayBreakDriver`, `shortWeekBreak`, `longWeekBreak`, `weekScope`, `mailPass`, `mailHost`, `mailSuccessFolder`, `mailErrorFolder`, `mailUser`, `minHoursToBreak`, `breakHours`, `hoursCompleteWeek`, `startNightlyHours`, `endNightlyHours`, `maxTimePerDay`, `breakTime`, `timeToBreakTime`, `dayMaxTime`, `shortWeekDays`, `longWeekDays`, `teleworkingStart`, `teleworkingStartBreakTime`, `maxTimeToBreak`, `maxWorkShortCycle`, `maxWorkLongCycle`) VALUES (1, 43200, 32400, 129600, 259200, 1080000, '', 'imap.verdnatura.es', 'Leidos.exito', 'Leidos.error', 'timeControl', 5.00, 0.33, 40, '22:00:00', '06:00:00', 72000, 1200, 18000, 72000, 6, 13, 28800, 32400, 3600, 561600, 950400); @@ -2986,4 +2986,4 @@ INSERT INTO `vn`.`invoiceCorrectionType` (`id`, `description`) VALUES (1, 'Error in VAT calculation'), (2, 'Error in sales details'), - (3, 'Error in customer data'); \ No newline at end of file + (3, 'Error in customer data'); From dbe684441950b10151e7d9085e4024200571e397 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 9 Nov 2023 09:31:32 +0100 Subject: [PATCH 189/449] refs #6415 feat: init version 23.48 --- CHANGELOG.md | 6 ++++++ db/changes/234801/.gitkeep | 0 package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 db/changes/234801/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index 29d270a3ed..30afaa69b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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). +## [2348.01] - 2023-11-30 + +### Added +### Changed +### Fixed + ## [2346.01] - 2023-11-16 ### Added diff --git a/db/changes/234801/.gitkeep b/db/changes/234801/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package-lock.json b/package-lock.json index 5bf7a2cb1e..b66279ae36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "salix-back", - "version": "23.46.01", + "version": "23.48.01", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "salix-back", - "version": "23.46.01", + "version": "23.48.01", "license": "GPL-3.0", "dependencies": { "axios": "^1.2.2", diff --git a/package.json b/package.json index b1539f9a06..04fcb008bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.46.01", + "version": "23.48.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From a0c4573f4d09f16e21e8d043a04bea17d4092d1d Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 9 Nov 2023 09:34:37 +0100 Subject: [PATCH 190/449] refs #4797 fix: correct sql folder --- db/changes/{234601 => 234801}/00-notificationSubscription.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{234601 => 234801}/00-notificationSubscription.sql (100%) diff --git a/db/changes/234601/00-notificationSubscription.sql b/db/changes/234801/00-notificationSubscription.sql similarity index 100% rename from db/changes/234601/00-notificationSubscription.sql rename to db/changes/234801/00-notificationSubscription.sql From 01d3c23cf0bcb3d716be9e7a8a7b90fdfe75968b Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 9 Nov 2023 11:57:52 +0100 Subject: [PATCH 191/449] ref #5914 renameTable --- db/changes/234601/00-transferInvoice.sql | 2 +- .../invoiceOut/back/methods/invoiceOut/transferInvoice.js | 4 ++-- modules/invoiceOut/back/model-config.json | 2 +- ...us-invoice-type-477.json => sii-type-invoice-out.json} | 7 +++++-- modules/invoiceOut/front/descriptor-menu/index.html | 8 ++++---- modules/invoiceOut/front/descriptor-menu/index.js | 2 +- 6 files changed, 14 insertions(+), 11 deletions(-) rename modules/invoiceOut/back/models/{cplus-invoice-type-477.json => sii-type-invoice-out.json} (68%) diff --git a/db/changes/234601/00-transferInvoice.sql b/db/changes/234601/00-transferInvoice.sql index 7a9890ae45..d9ae394641 100644 --- a/db/changes/234601/00-transferInvoice.sql +++ b/db/changes/234601/00-transferInvoice.sql @@ -1,6 +1,6 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) VALUES ('CplusRectificationType', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), - ('CplusInvoiceType477', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('SiiTypeInvoiceOut', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('InvoiceCorrectionType', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('InvoiceOut', 'transferInvoice', 'WRITE', 'ALLOW', 'ROLE', 'administrative'); diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js index 8a0609b8d2..dde535c998 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js @@ -27,7 +27,7 @@ module.exports = Self => { required: true }, { - arg: 'cplusInvoiceType477Id', + arg: 'siiTypeInvoiceOutId', type: 'number', required: true }, @@ -93,7 +93,7 @@ module.exports = Self => { correctingFk: invoiceId, correctedFk: args.id, cplusRectificationTypeFk: args.cplusRectificationId, - cplusInvoiceType477Fk: args.cplusInvoiceType477Id, + siiTypeInvoiceOutFk: args.siiTypeInvoiceOutId, invoiceCorrectionTypeFk: args.invoiceCorrectionTypeId }, myOptions); diff --git a/modules/invoiceOut/back/model-config.json b/modules/invoiceOut/back/model-config.json index 23246893b4..9c7512429f 100644 --- a/modules/invoiceOut/back/model-config.json +++ b/modules/invoiceOut/back/model-config.json @@ -41,7 +41,7 @@ "InvoiceCorrection": { "dataSource": "vn" }, - "CplusInvoiceType477": { + "SiiTypeInvoiceOut": { "dataSource": "vn" } } diff --git a/modules/invoiceOut/back/models/cplus-invoice-type-477.json b/modules/invoiceOut/back/models/sii-type-invoice-out.json similarity index 68% rename from modules/invoiceOut/back/models/cplus-invoice-type-477.json rename to modules/invoiceOut/back/models/sii-type-invoice-out.json index 840a9a7e4e..89f01bd749 100644 --- a/modules/invoiceOut/back/models/cplus-invoice-type-477.json +++ b/modules/invoiceOut/back/models/sii-type-invoice-out.json @@ -1,9 +1,9 @@ { - "name": "CplusInvoiceType477", + "name": "SiiTypeInvoiceOut", "base": "VnModel", "options": { "mysql": { - "table": "cplusInvoiceType477" + "table": "siiTypeInvoiceOut" } }, "properties": { @@ -12,6 +12,9 @@ "type": "number", "description": "Identifier" }, + "code": { + "type": "string" + }, "description": { "type": "string" } diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index 7d465f4ea5..d7537bc0a7 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -6,8 +6,8 @@ + url="SiiTypeInvoiceOuts" + data="siiTypeInvoiceOuts"> diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index 7d2644158e..d3862a753c 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -132,7 +132,7 @@ class Controller extends Section { ref: this.invoiceOut.ref, newClientFk: this.invoiceOut.client.id, cplusRectificationId: this.cplusRectificationType, - cplusInvoiceType477Id: this.cplusInvoiceType477, + siiTypeInvoiceOutId: this.siiTypeInvoiceOut, invoiceCorrectionTypeId: this.invoiceCorrectionType }; this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => { From b07858fddbaf04dc79f96799468cff2e528a2c6c Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 9 Nov 2023 14:33:46 +0100 Subject: [PATCH 192/449] ref #5914 replace name --- db/.archive/225201/00-invoiceOut_new.sql | 2 +- db/.archive/231001/02-invoiceOut_new.sql | 2 +- db/.archive/232001/00-invoiceOut_new.sql | 2 +- db/dump/dumpedFixtures.sql | 10 ++++---- db/dump/structure.sql | 25 +++++++++---------- db/export-data.sh | 2 +- .../invoiceOut/specs/transferinvoice.spec.js | 8 +++--- .../back/models/invoice-correction.json | 2 +- .../back/models/sii-type-invoice-out.json | 3 --- 9 files changed, 26 insertions(+), 30 deletions(-) diff --git a/db/.archive/225201/00-invoiceOut_new.sql b/db/.archive/225201/00-invoiceOut_new.sql index 4c60b50bcb..8e23fb43b7 100644 --- a/db/.archive/225201/00-invoiceOut_new.sql +++ b/db/.archive/225201/00-invoiceOut_new.sql @@ -74,7 +74,7 @@ BEGIN clientFk, dued, companyFk, - cplusInvoiceType477Fk + siiTypeInvoiceOutFk ) SELECT 1, diff --git a/db/.archive/231001/02-invoiceOut_new.sql b/db/.archive/231001/02-invoiceOut_new.sql index d2b96eff78..d570dfb726 100644 --- a/db/.archive/231001/02-invoiceOut_new.sql +++ b/db/.archive/231001/02-invoiceOut_new.sql @@ -96,7 +96,7 @@ BEGIN clientFk, dued, companyFk, - cplusInvoiceType477Fk + siiTypeInvoiceOutFk ) SELECT 1, diff --git a/db/.archive/232001/00-invoiceOut_new.sql b/db/.archive/232001/00-invoiceOut_new.sql index b4fc5c824e..b497dffda6 100644 --- a/db/.archive/232001/00-invoiceOut_new.sql +++ b/db/.archive/232001/00-invoiceOut_new.sql @@ -96,7 +96,7 @@ BEGIN clientFk, dued, companyFk, - cplusInvoiceType477Fk + siiTypeInvoiceOutFk ) SELECT 1, diff --git a/db/dump/dumpedFixtures.sql b/db/dump/dumpedFixtures.sql index 2e1511b590..43eba7f241 100644 --- a/db/dump/dumpedFixtures.sql +++ b/db/dump/dumpedFixtures.sql @@ -275,13 +275,13 @@ INSERT INTO `cplusInvoiceType472` VALUES (1,'F1 - Factura'),(2,'F2 - Factura sim UNLOCK TABLES; -- --- Dumping data for table `cplusInvoiceType477` +-- Dumping data for table `siiTypeInvoiceOut` -- -LOCK TABLES `cplusInvoiceType477` WRITE; -/*!40000 ALTER TABLE `cplusInvoiceType477` DISABLE KEYS */; -INSERT INTO `cplusInvoiceType477` VALUES (1,'F1 - Factura'),(2,'F2 - Factura simplificada (ticket)'),(3,'F3 - Factura emitida en sustitución de facturas simplificadas facturadas y declaradas'),(4,'F4 - Asiento resumen de facturas'),(5,'R1 - Factura rectificativa (Art. 80.1, 80.2 y error fundado en derecho)'),(6,'R2 - Factura rectificativa (Art. 80.3)'),(7,'R3 - Factura rectificativa (Art. 80.4)'),(8,'R4 - Factura rectificativa (Resto)'),(9,'R5 - Factura rectificativa en facturas simplificadas'); -/*!40000 ALTER TABLE `cplusInvoiceType477` ENABLE KEYS */; +LOCK TABLES `siiTypeInvoiceOut` WRITE; +/*!40000 ALTER TABLE `siiTypeInvoiceOut` DISABLE KEYS */; +INSERT INTO `siiTypeInvoiceOut` VALUES (1,'F1 - Factura'),(2,'F2 - Factura simplificada (ticket)'),(3,'F3 - Factura emitida en sustitución de facturas simplificadas facturadas y declaradas'),(4,'F4 - Asiento resumen de facturas'),(5,'R1 - Factura rectificativa (Art. 80.1, 80.2 y error fundado en derecho)'),(6,'R2 - Factura rectificativa (Art. 80.3)'),(7,'R3 - Factura rectificativa (Art. 80.4)'),(8,'R4 - Factura rectificativa (Resto)'),(9,'R5 - Factura rectificativa en facturas simplificadas'); +/*!40000 ALTER TABLE `siiTypeInvoiceOut` ENABLE KEYS */; UNLOCK TABLES; -- diff --git a/db/dump/structure.sql b/db/dump/structure.sql index b242821fc6..f50868b195 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -25993,13 +25993,12 @@ CREATE TABLE `cplusInvoiceType472` ( /*!40101 SET character_set_client = @saved_cs_client */; -- --- Table structure for table `cplusInvoiceType477` +-- Table structure for table `siiTypeInvoiceOut` -- - -DROP TABLE IF EXISTS `cplusInvoiceType477`; +DROP TABLE IF EXISTS `siiTypeInvoiceOut`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE `cplusInvoiceType477` ( +CREATE TABLE `siiTypeInvoiceOut` ( `id` int(10) unsigned NOT NULL, `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, PRIMARY KEY (`id`) @@ -29450,16 +29449,16 @@ CREATE TABLE `invoiceCorrection` ( `correctingFk` int(10) unsigned NOT NULL COMMENT 'Factura rectificativa', `correctedFk` int(10) unsigned NOT NULL COMMENT 'Factura rectificada', `cplusRectificationTypeFk` int(10) unsigned NOT NULL, - `cplusInvoiceType477Fk` int(10) unsigned NOT NULL, + `siiTypeInvoiceOutFk` int(10) unsigned NOT NULL, `invoiceCorrectionTypeFk` int(11) NOT NULL DEFAULT 3, PRIMARY KEY (`correctingFk`), KEY `correctedFk_idx` (`correctedFk`), KEY `invoiceCorrection_ibfk_1_idx` (`cplusRectificationTypeFk`), - KEY `cplusInvoiceTyoeFk_idx` (`cplusInvoiceType477Fk`), + KEY `cplusInvoiceTyoeFk_idx` (`siiTypeInvoiceOutFk`), KEY `invoiceCorrectionTypeFk_idx` (`invoiceCorrectionTypeFk`), CONSTRAINT `corrected_fk` FOREIGN KEY (`correctedFk`) REFERENCES `invoiceOut` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `correcting_fk` FOREIGN KEY (`correctingFk`) REFERENCES `invoiceOut` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `cplusInvoiceTyoeFk` FOREIGN KEY (`cplusInvoiceType477Fk`) REFERENCES `cplusInvoiceType477` (`id`) ON UPDATE CASCADE, + CONSTRAINT `cplusInvoiceTyoeFk` FOREIGN KEY (`siiTypeInvoiceOutFk`) REFERENCES `siiTypeInvoiceOut` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceCorrectionType_Fk33` FOREIGN KEY (`invoiceCorrectionTypeFk`) REFERENCES `invoiceCorrectionType` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceCorrection_ibfk_1` FOREIGN KEY (`cplusRectificationTypeFk`) REFERENCES `cplusRectificationType` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Relacion entre las facturas rectificativas y las rectificadas.'; @@ -30130,7 +30129,7 @@ CREATE TABLE `invoiceOut` ( `companyFk` int(10) unsigned NOT NULL DEFAULT 442, `hasPdf` tinyint(3) unsigned NOT NULL DEFAULT 0, `booked` date DEFAULT NULL, - `cplusInvoiceType477Fk` int(10) unsigned NOT NULL DEFAULT 1, + `siiTypeInvoiceOutFk` int(10) unsigned NOT NULL DEFAULT 1, `cplusTaxBreakFk` int(10) unsigned NOT NULL DEFAULT 1, `cplusSubjectOpFk` int(10) unsigned NOT NULL DEFAULT 1, `cplusTrascendency477Fk` int(10) unsigned NOT NULL DEFAULT 1, @@ -30140,13 +30139,13 @@ CREATE TABLE `invoiceOut` ( KEY `Id_Cliente` (`clientFk`), KEY `empresa_id` (`companyFk`), KEY `Fecha` (`issued`), - KEY `Facturas_ibfk_2_idx` (`cplusInvoiceType477Fk`), + KEY `Facturas_ibfk_2_idx` (`siiTypeInvoiceOutFk`), KEY `Facturas_ibfk_3_idx` (`cplusSubjectOpFk`), KEY `Facturas_ibfk_4_idx` (`cplusTaxBreakFk`), KEY `Facturas_ibfk_5_idx` (`cplusTrascendency477Fk`), KEY `Facturas_idx_Vencimiento` (`dued`), KEY `invoiceOut_serial` (`serial`), - CONSTRAINT `invoiceOut_ibfk_2` FOREIGN KEY (`cplusInvoiceType477Fk`) REFERENCES `cplusInvoiceType477` (`id`) ON UPDATE CASCADE, + CONSTRAINT `invoiceOut_ibfk_2` FOREIGN KEY (`siiTypeInvoiceOutFk`) REFERENCES `siiTypeInvoiceOut` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceOut_ibfk_3` FOREIGN KEY (`cplusSubjectOpFk`) REFERENCES `cplusSubjectOp` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceOut_ibfk_4` FOREIGN KEY (`cplusTaxBreakFk`) REFERENCES `cplusTaxBreak` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceOut_serial` FOREIGN KEY (`serial`) REFERENCES `invoiceOutSerial` (`code`), @@ -30308,7 +30307,7 @@ CREATE TABLE `invoiceOutSerial` ( `isTaxed` tinyint(1) NOT NULL DEFAULT 1, `taxAreaFk` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'NATIONAL', `isCEE` tinyint(1) NOT NULL DEFAULT 0, - `cplusInvoiceType477Fk` int(10) unsigned DEFAULT 1, + `siiTypeInvoiceOutFk` int(10) unsigned DEFAULT 1, `footNotes` longtext DEFAULT NULL, `isRefEditable` tinyint(4) NOT NULL DEFAULT 0, `type` enum('global','quick') DEFAULT NULL, @@ -58288,7 +58287,7 @@ BEGIN io.cplusTrascendency477Fk AS TIPOCLAVE, io.cplusTaxBreakFk AS TIPOEXENCI, io.cplusSubjectOpFk AS TIPONOSUJE, - io.cplusInvoiceType477Fk AS TIPOFACT, + io.siiTypeInvoiceOutFk AS TIPOFACT, ic.cplusRectificationTypeFk AS TIPORECTIF, io.companyFk, RIGHT(io.ref, LENGTH(io.ref) - 1) AS invoiceNum, @@ -58868,7 +58867,7 @@ BEGIN clientFk, dued, companyFk, - cplusInvoiceType477Fk + siiTypeInvoiceOutFk ) SELECT 1, diff --git a/db/export-data.sh b/db/export-data.sh index 7d346b235e..a516992d34 100755 --- a/db/export-data.sh +++ b/db/export-data.sh @@ -46,7 +46,7 @@ TABLES=( bookingPlanner businessType cplusInvoiceType472 - cplusInvoiceType477 + siiTypeInvoiceOut cplusRectificationType cplusSubjectOp cplusTaxBreak diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js index 04f6df2995..8769484194 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js @@ -2,7 +2,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); -describe('InvoiceOut tranferInvoice()', () => { +fdescribe('InvoiceOut tranferInvoice()', () => { const activeCtx = { accessToken: {userId: 5}, http: { @@ -19,7 +19,7 @@ describe('InvoiceOut tranferInvoice()', () => { }); }); - it('should return the id of the created issued invoice', async() => { + fit('should return the id of the created issued invoice', async() => { const tx = await models.InvoiceOut.beginTransaction({}); const options = {transaction: tx}; const args = { @@ -27,7 +27,7 @@ describe('InvoiceOut tranferInvoice()', () => { ref: 'T4444444', newClientFk: 1, cplusRectificationId: 1, - cplusInvoiceType477Id: 1, + siiTypeInvoiceOutId: 1, invoiceCorrectionTypeId: 1 }; ctx.args = args; @@ -52,7 +52,7 @@ describe('InvoiceOut tranferInvoice()', () => { ref: 'T1111111', newClientFk: 1101, cplusRectificationId: 1, - cplusInvoiceType477Id: 1, + siiTypeInvoiceOutId: 1, invoiceCorrectionTypeId: 1 }; ctx.args = args; diff --git a/modules/invoiceOut/back/models/invoice-correction.json b/modules/invoiceOut/back/models/invoice-correction.json index 48bd172a6d..7c6f015713 100644 --- a/modules/invoiceOut/back/models/invoice-correction.json +++ b/modules/invoiceOut/back/models/invoice-correction.json @@ -18,7 +18,7 @@ "cplusRectificationTypeFk": { "type": "number" }, - "cplusInvoiceType477Fk": { + "siiTypeInvoiceOutFk": { "type": "number" }, "invoiceCorrectionTypeFk": { diff --git a/modules/invoiceOut/back/models/sii-type-invoice-out.json b/modules/invoiceOut/back/models/sii-type-invoice-out.json index 89f01bd749..06934b1ccd 100644 --- a/modules/invoiceOut/back/models/sii-type-invoice-out.json +++ b/modules/invoiceOut/back/models/sii-type-invoice-out.json @@ -12,9 +12,6 @@ "type": "number", "description": "Identifier" }, - "code": { - "type": "string" - }, "description": { "type": "string" } From 0baa9c5a983ad2660e66ef0570cde9e74d05deb7 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 9 Nov 2023 14:34:53 +0100 Subject: [PATCH 193/449] ref #5914 fix summary --- modules/invoiceOut/front/descriptor-menu/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index d7537bc0a7..09bb4a2abe 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -7,7 +7,7 @@ + data="siiTypeInvoiceOut"> Date: Thu, 9 Nov 2023 15:00:49 +0100 Subject: [PATCH 194/449] ref #5835 due day new and fixtures --- db/dump/fixtures.sql | 4 +- .../back/methods/invoice-in-due-day/new.js | 37 +++++++++++++++++++ .../back/models/invoice-in-due-day.js | 3 ++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 modules/invoiceIn/back/methods/invoice-in-due-day/new.js create mode 100644 modules/invoiceIn/back/models/invoice-in-due-day.js diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index d70279e7de..f57b302f3c 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2880,7 +2880,9 @@ INSERT INTO `vn`.`report` (`id`, `name`, `paperSizeFk`, `method`) INSERT INTO `vn`.`payDemDetail` (`id`, `detail`) VALUES - (1, 1); + (1, 1), + (2, 20), + (7, 1); INSERT INTO `vn`.`workerConfig` (`id`, `businessUpdated`, `roleFk`, `payMethodFk`, `businessTypeFk`) VALUES diff --git a/modules/invoiceIn/back/methods/invoice-in-due-day/new.js b/modules/invoiceIn/back/methods/invoice-in-due-day/new.js new file mode 100644 index 0000000000..37d2f6d054 --- /dev/null +++ b/modules/invoiceIn/back/methods/invoice-in-due-day/new.js @@ -0,0 +1,37 @@ +module.exports = Self => { + Self.remoteMethodCtx('new', { + description: 'Creates a new invoiceIn due day', + accessType: 'WRITE', + accepts: { + arg: 'id', + type: 'number', + required: true, + description: 'The invoiceIn id', + }, + http: { + path: '/new', + verb: 'POST' + } + }); + + Self.new = async(ctx, id, options) => { + let tx; + const myOptions = {userId: ctx.req.accessToken.userId}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + await Self.rawSql(`CALL vn.invoiceInDueDay_calculate(?)`, [id], myOptions); + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/invoiceIn/back/models/invoice-in-due-day.js b/modules/invoiceIn/back/models/invoice-in-due-day.js new file mode 100644 index 0000000000..2375c6566a --- /dev/null +++ b/modules/invoiceIn/back/models/invoice-in-due-day.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/invoice-in-due-day/new')(Self); +}; From fd142b9f23ba6ef4ab4adaed693f47e95eed476f Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 9 Nov 2023 15:05:36 +0100 Subject: [PATCH 195/449] refs #5881 warmFix: roleSync --- db/changes/234602/00-roleSync.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 db/changes/234602/00-roleSync.sql diff --git a/db/changes/234602/00-roleSync.sql b/db/changes/234602/00-roleSync.sql new file mode 100644 index 0000000000..7ce2777480 --- /dev/null +++ b/db/changes/234602/00-roleSync.sql @@ -0,0 +1 @@ +CALL `account`.`role_sync`(); From 513562955b1d7b11aef24d4e348f83250c70490b Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 9 Nov 2023 15:53:41 +0100 Subject: [PATCH 196/449] ref #5835 test back --- .../invoice-in-due-day/specs/new.spec.js | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js diff --git a/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js b/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js new file mode 100644 index 0000000000..f2f04b993e --- /dev/null +++ b/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js @@ -0,0 +1,51 @@ +const LoopBackContext = require('loopback-context'); +const models = require('vn-loopback/server/server').models; + +describe('invoiceInDueDay new()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + + it('should correctly create a new due day', async() => { + const userId = 9; + const invoiceInFk = 6; + + const ctx = { + req: { + + accessToken: {userId: userId}, + headers: {origin: 'http://localhost:5000'}, + } + }; + + const tx = await models.InvoiceIn.beginTransaction({}); + const options = {transaction: tx}; + + try { + await models.InvoiceInDueDay.destroyAll({ + invoiceInFk + }, options); + + await models.InvoiceInDueDay.new(ctx, invoiceInFk, options); + + const result = await models.InvoiceInDueDay.find({where: {invoiceInFk}}, options); + + expect(result).toBeDefined(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); From 8d94a94e14f1396cd79737d0304c1af1b98ff7d0 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 9 Nov 2023 15:56:50 +0100 Subject: [PATCH 197/449] ref #5914 fix test back --- .../back/methods/invoiceOut/specs/transferinvoice.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js index 8769484194..800a4ea835 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js @@ -2,7 +2,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); -fdescribe('InvoiceOut tranferInvoice()', () => { +describe('InvoiceOut tranferInvoice()', () => { const activeCtx = { accessToken: {userId: 5}, http: { @@ -19,7 +19,7 @@ fdescribe('InvoiceOut tranferInvoice()', () => { }); }); - fit('should return the id of the created issued invoice', async() => { + it('should return the id of the created issued invoice', async() => { const tx = await models.InvoiceOut.beginTransaction({}); const options = {transaction: tx}; const args = { From 2eacf7391ea1d03fdf441277b0c73ac37ddf54ce Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 10 Nov 2023 08:46:49 +0100 Subject: [PATCH 198/449] refs #6335 fix(db_ticket_canAdvance): not use unnecessary ifnulls --- CHANGELOG.md | 12 ++++++------ .../00-ticket_canAdvance_update.sql | 18 +++++++++--------- .../back/methods/ticket/componentUpdate.js | 8 ++++---- modules/ticket/front/advance/index.js | 4 ++-- 4 files changed, 21 insertions(+), 21 deletions(-) rename db/changes/{234601 => 234801}/00-ticket_canAdvance_update.sql (90%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09379e91ce..08a62f0449 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [2348.01] - 2023-11-30 -### Added -### Changed -### Fixed - -## [2346.01] - 2023-11-16 - ### Added - (Ticket -> Adelantar) Permite mover lineas sin generar negativos - (Ticket -> Adelantar) Permite modificar la fecha de los tickets @@ -22,6 +16,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - (Ticket -> RocketChat) Arreglada detección de cambios +## [2346.01] - 2023-11-16 + +### Added +### Changed +### Fixed + ## [2342.01] - 2023-11-02 diff --git a/db/changes/234601/00-ticket_canAdvance_update.sql b/db/changes/234801/00-ticket_canAdvance_update.sql similarity index 90% rename from db/changes/234601/00-ticket_canAdvance_update.sql rename to db/changes/234801/00-ticket_canAdvance_update.sql index 272a0618a1..afe0a4dc6d 100644 --- a/db/changes/234601/00-ticket_canAdvance_update.sql +++ b/db/changes/234801/00-ticket_canAdvance_update.sql @@ -13,8 +13,7 @@ BEGIN SELECT inventoried INTO vDateInventory FROM config; - DROP TEMPORARY TABLE IF EXISTS tmp.stock; - CREATE TEMPORARY TABLE tmp.stock + CREATE OR REPLACE TEMPORARY TABLE tmp.stock (itemFk INT PRIMARY KEY, amount INT) ENGINE = MEMORY; @@ -60,22 +59,23 @@ BEGIN dest.totalWithVat, origin.totalWithVat futureTotalWithVat, dest.agency, + dest.agencyModeFk, origin.futureAgency, + origin.agencyModeFk futureAgencyModeFk, dest.lines, dest.liters, origin.futureLines - origin.hasStock AS notMovableLines, (origin.futureLines = origin.hasStock) AS isFullMovable, + dest.zoneFk, origin.futureZoneFk, origin.futureZoneName, origin.classColor futureClassColor, dest.classColor, - IFNULL(dest.clientFk, origin.clientFk) clientFk, + origin.clientFk futureClientFk, + origin.addressFk futureAddressFk, + origin.warehouseFk futureWarehouseFk, + origin.companyFk futureCompanyFk, IFNULL(dest.nickname, origin.nickname) nickname, - IFNULL(dest.addressFk, origin.addressFk) addressFk, - IFNULL(dest.zoneFk, origin.futureZoneFk) zoneFk, - IFNULL(dest.warehouseFk, origin.warehouseFk) warehouseFk, - IFNULL(dest.companyFk, origin.companyFk) companyFk, - IFNULL(dest.agencyModeFk, origin.agencyModeFk) agencyModeFk, dest.landed FROM ( SELECT @@ -145,7 +145,7 @@ BEGIN AND st.order <= 5 GROUP BY t.id ) dest ON dest.addressFk = origin.addressFk - WHERE origin.hasStock != 0; + WHERE origin.hasStock; DROP TEMPORARY TABLE tmp.stock; END$$ diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index d8d1163daf..3acd68cfb1 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -196,7 +196,7 @@ module.exports = Self => { ] }, myOptions); const originalTicket = JSON.parse(JSON.stringify(ticketToChange)); - const ticketChages = { + const ticketChanges = { clientFk: args.clientFk, nickname: args.nickname, agencyModeFk: args.agencyModeFk, @@ -211,13 +211,13 @@ module.exports = Self => { let response; if (args.keepPrice) { - ticketChages.routeFk = null; - response = await ticketToChange.updateAttributes(ticketChages, myOptions); + ticketChanges.routeFk = null; + response = await ticketToChange.updateAttributes(ticketChanges, myOptions); } else { const hasToBeUnrouted = true; response = await Self.rawSql( 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - [args.id].concat(Object.values(ticketChages), [hasToBeUnrouted, args.option]), + [args.id].concat(Object.values(ticketChanges), [hasToBeUnrouted, args.option]), myOptions ); } diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index 5ab6632569..fb539311f7 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -215,9 +215,9 @@ export default class Controller extends Section { const params = { clientFk: ticket.clientFk, nickname: ticket.nickname, - agencyModeFk: ticket.agencyModeFk, + agencyModeFk: ticket.agencyModeFk ?? ticket.futureAgencyModeFk, addressFk: ticket.addressFk, - zoneFk: ticket.zoneFk, + zoneFk: ticket.zoneFk ?? ticket.futureZoneFk, warehouseFk: ticket.warehouseFk, companyFk: ticket.companyFk, shipped: this.$.model.userParams.dateToAdvance, From 69255fe2fcacd1dc716b26dcf0c60b8face6882d Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 10 Nov 2023 10:58:58 +0100 Subject: [PATCH 199/449] refs #6014 feat(execute): use user_hasRoutinePriv. feat(execute): split in executeProc & executeFunc --- .vscode/settings.json | 3 +- db/changes/234201/00-ACL_executeRoutine.sql | 3 - db/changes/234801/00-ACL_executeRoutine.sql | 4 + db/dump/structure.sql | 84 ++++++++++++++ .../common/methods/application/execute.js | 34 ++++++ .../common/methods/application/executeFunc.js | 38 +++++++ .../common/methods/application/executeProc.js | 36 ++++++ .../methods/application/executeRoutine.js | 100 ----------------- ...executeRoutine.spec.js => execute.spec.js} | 103 +++++++++++------- loopback/common/models/application.js | 4 +- 10 files changed, 265 insertions(+), 144 deletions(-) delete mode 100644 db/changes/234201/00-ACL_executeRoutine.sql create mode 100644 db/changes/234801/00-ACL_executeRoutine.sql create mode 100644 loopback/common/methods/application/execute.js create mode 100644 loopback/common/methods/application/executeFunc.js create mode 100644 loopback/common/methods/application/executeProc.js delete mode 100644 loopback/common/methods/application/executeRoutine.js rename loopback/common/methods/application/spec/{executeRoutine.spec.js => execute.spec.js} (51%) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9ed1c8fc2a..899dfc7884 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,7 @@ "editor.defaultFormatter": "dbaeumer.vscode-eslint" }, "cSpell.words": [ - "salix" + "salix", + "fdescribe" ] } diff --git a/db/changes/234201/00-ACL_executeRoutine.sql b/db/changes/234201/00-ACL_executeRoutine.sql deleted file mode 100644 index dd112171a3..0000000000 --- a/db/changes/234201/00-ACL_executeRoutine.sql +++ /dev/null @@ -1,3 +0,0 @@ -INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) - VALUES - ('Application', 'executeRoutine', '*', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/234801/00-ACL_executeRoutine.sql b/db/changes/234801/00-ACL_executeRoutine.sql new file mode 100644 index 0000000000..cfe7018e91 --- /dev/null +++ b/db/changes/234801/00-ACL_executeRoutine.sql @@ -0,0 +1,4 @@ +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('Application', 'executeProc', '*', 'ALLOW', 'ROLE', 'employee'), + ('Application', 'executeFunc', '*', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/dump/structure.sql b/db/dump/structure.sql index b242821fc6..a8280dc1db 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -2352,6 +2352,90 @@ BEGIN END IF; END ;; DELIMITER ; + + +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` FUNCTION `account`.`user_hasRoutinePriv`(vType ENUM('PROCEDURE', 'FUNCTION'), + vChain VARCHAR(100), + vUserFk INT +) RETURNS tinyint(1) + READS SQL DATA +BEGIN + +/** + * Search if the user has privileges on routines. + * + * @param vType procedure or function + * @param vChain string passed with this syntax dbName.tableName + * @param vUserFk user to ckeck + * @return vHasPrivilege + */ + DECLARE vHasPrivilege BOOL DEFAULT FALSE; + DECLARE vDb VARCHAR(50); + DECLARE vObject VARCHAR(50); + DECLARE vChainExists BOOL; + DECLARE vExecutePriv INT DEFAULT 262144; + -- 262144 = CONV(1000000000000000000, 2, 10) + -- 1000000000000000000 execution permission expressed in binary base + + SET vDb = SUBSTRING_INDEX(vChain, '.', 1); + SET vChain = SUBSTRING(vChain, LENGTH(vDb) + 2); + SET vObject = SUBSTRING_INDEX(vChain, '.', 1); + + SELECT COUNT(*) INTO vChainExists + FROM mysql.proc + WHERE db = vDb + AND `name` = vObject + AND `type` = vType + LIMIT 1; + + IF NOT vChainExists THEN + RETURN FALSE; + END IF; + + DROP TEMPORARY TABLE IF EXISTS tRole; + CREATE TEMPORARY TABLE tRole + (INDEX (`name`)) + ENGINE = MEMORY + SELECT r.`name` + FROM user u + JOIN roleRole rr ON rr.role = u.role + JOIN `role` r ON r.id = rr.inheritsFrom + WHERE u.id = vUserFk; + + SELECT TRUE INTO vHasPrivilege + FROM mysql.global_priv gp + JOIN tRole tr ON tr.name = gp.`User` + OR CONCAT('$', tr.name) = gp.`User` + WHERE JSON_VALUE(gp.Priv, '$.access') >= vExecutePriv + AND gp.Host = '' + LIMIT 1; + + IF NOT vHasPrivilege THEN + SELECT TRUE INTO vHasPrivilege + FROM mysql.db db + JOIN tRole tr ON tr.name = db.`User` + WHERE db.Db = vDb + AND db.Execute_priv = 'Y'; + END IF; + + IF NOT vHasPrivilege THEN + SELECT TRUE INTO vHasPrivilege + FROM mysql.procs_priv pp + JOIN tRole tr ON tr.name = pp.`User` + WHERE pp.Db = vDb + AND pp.Routine_name = vObject + AND pp.Routine_type = vType + AND pp.Proc_priv = 'Execute' + LIMIT 1; + END IF; + + DROP TEMPORARY TABLE tRole; + RETURN vHasPrivilege; +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/loopback/common/methods/application/execute.js b/loopback/common/methods/application/execute.js new file mode 100644 index 0000000000..7a24df0d40 --- /dev/null +++ b/loopback/common/methods/application/execute.js @@ -0,0 +1,34 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.execute = async(ctx, routine, params, schema, type, options) => { + const userId = ctx.req.accessToken.userId; + const models = Self.app.models; + let caller = 'CALL'; + + params = params ?? []; + schema = schema ?? 'vn'; + type = type ?? 'procedure'; + + const myOptions = {userId: ctx.req.accessToken.userId}; + if (typeof options == 'object') + Object.assign(myOptions, options); + + const chain = `${schema}.${routine}`; + const [canExecute] = await models.ProcsPriv.rawSql( + 'SELECT account.user_hasRoutinePriv(?,?,?)', + [type.toUpperCase(), chain, userId], + myOptions); + if (!Object.values(canExecute)[0]) throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED'); + + const isFunction = type == 'function'; + let argString = params.map(() => '?').join(','); + + if (isFunction) + caller = 'SELECT'; + const query = `${caller} ${chain}(${argString})`; + + const [response] = await models.ProcsPriv.rawSql(query, params, myOptions); + return response; + }; +}; diff --git a/loopback/common/methods/application/executeFunc.js b/loopback/common/methods/application/executeFunc.js new file mode 100644 index 0000000000..0a90e8639b --- /dev/null +++ b/loopback/common/methods/application/executeFunc.js @@ -0,0 +1,38 @@ +module.exports = Self => { + Self.remoteMethodCtx('executeFunc', { + description: 'Return result of function', + accessType: '*', + accepts: [ + { + arg: 'routine', + type: 'string', + description: 'The routine name', + required: true, + http: {source: 'path'} + }, + { + arg: 'params', + type: ['any'], + description: 'The params array', + }, + { + arg: 'schema', + type: 'string', + description: 'The routine schema', + } + ], + returns: { + type: 'any', + root: true + }, + http: { + path: `/:routine/execute-func`, + verb: 'POST' + } + }); + + Self.executeFunc = async(ctx, routine, params, schema, options) => { + const response = await Self.execute(ctx, routine, params, schema, 'function', options); + return Object.values(response)[0]; + }; +}; diff --git a/loopback/common/methods/application/executeProc.js b/loopback/common/methods/application/executeProc.js new file mode 100644 index 0000000000..635944eb74 --- /dev/null +++ b/loopback/common/methods/application/executeProc.js @@ -0,0 +1,36 @@ +module.exports = Self => { + Self.remoteMethodCtx('executeProc', { + description: 'Return result of procedure', + accessType: '*', + accepts: [ + { + arg: 'routine', + type: 'string', + description: 'The routine name', + required: true, + http: {source: 'path'} + }, + { + arg: 'params', + type: ['any'], + description: 'The params array', + }, + { + arg: 'schema', + type: 'string', + description: 'The routine schema', + } + ], + returns: { + type: 'any', + root: true + }, + http: { + path: `/:routine/execute-proc`, + verb: 'POST' + } + }); + + Self.executeProc = async(ctx, routine, params, schema, options) => + Self.execute(ctx, routine, params, schema, 'procedure', options); +}; diff --git a/loopback/common/methods/application/executeRoutine.js b/loopback/common/methods/application/executeRoutine.js deleted file mode 100644 index eed34b3441..0000000000 --- a/loopback/common/methods/application/executeRoutine.js +++ /dev/null @@ -1,100 +0,0 @@ -const UserError = require('vn-loopback/util/user-error'); - -module.exports = Self => { - Self.remoteMethodCtx('executeRoutine', { - description: 'Return the routes by worker', - accessType: '*', - accepts: [ - { - arg: 'routine', - type: 'string', - description: 'The routine name', - required: true, - http: {source: 'path'} - }, - { - arg: 'params', - type: ['any'], - description: 'The params array', - }, - { - arg: 'schema', - type: 'string', - description: 'The routine schema', - }, - { - arg: 'type', - type: 'string', - description: 'The routine type', - } - ], - returns: { - type: 'any', - root: true - }, - http: { - path: `/:routine/execute-routine`, - verb: 'POST' - } - }); - - Self.executeRoutine = async(ctx, routine, params, schema, type, options) => { - const userId = ctx.req.accessToken.userId; - const models = Self.app.models; - const isFunction = type == 'function'; - params = params ?? []; - schema = schema ?? 'vn'; - type = type ?? 'procedure'; - let caller = 'CALL'; - - if (isFunction) - caller = 'SELECT'; - - const myOptions = {userId: ctx.req.accessToken.userId}; - if (typeof options == 'object') - Object.assign(myOptions, options); - - const user = await models.VnUser.findById(userId, { - fields: ['id', 'roleFk'], - include: { - relation: 'role', - scope: { - fields: ['id', 'name'] - } - } - }); - - const inherits = await models.RoleRole.find({ - include: { - relation: 'inherits', - scope: { - fields: ['id', 'name'] - } - }, - where: { - role: user.role().id - } - }); - - const roles = inherits.map(inherit => inherit.inherits().name); - - const canExecute = await models.ProcsPriv.findOne({ - where: { - schema, - type: type.toUpperCase(), - name: routine, - host: process.env.NODE_ENV ? '' : '%', - role: {inq: roles} - } - }); - - if (!canExecute) throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED'); - - let argString = params.map(() => '?').join(','); - - const query = `${caller} ${schema}.${routine}(${argString})`; - - const [response] = await models.ProcsPriv.rawSql(query, params, myOptions); - return isFunction ? Object.values(response)[0] : response; - }; -}; diff --git a/loopback/common/methods/application/spec/executeRoutine.spec.js b/loopback/common/methods/application/spec/execute.spec.js similarity index 51% rename from loopback/common/methods/application/spec/executeRoutine.spec.js rename to loopback/common/methods/application/spec/execute.spec.js index 150c5d416d..26e648531f 100644 --- a/loopback/common/methods/application/spec/executeRoutine.spec.js +++ b/loopback/common/methods/application/spec/execute.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; -describe('Application executeRoutine()', () => { +describe('Application execute()/executeProc()/executeFunc()', () => { const userWithoutPrivileges = 1; const userWithPrivileges = 9; const userWithInheritedPrivileges = 120; @@ -48,7 +48,7 @@ describe('Application executeRoutine()', () => { try { const options = {transaction: tx}; - await models.Application.executeRoutine( + await models.Application.execute( ctx, 'myProcedure', [1], @@ -71,7 +71,7 @@ describe('Application executeRoutine()', () => { try { const options = {transaction: tx}; - const response = await models.Application.executeRoutine( + const response = await models.Application.execute( ctx, 'myProcedure', [1], @@ -90,49 +90,74 @@ describe('Application executeRoutine()', () => { } }); - it('should execute function and get data', async() => { - const ctx = getCtx(userWithPrivileges); - try { - const options = {transaction: tx}; + describe('Application executeProc()', () => { + it('should execute procedure and get data (executeProc)', async() => { + const ctx = getCtx(userWithPrivileges); + try { + const options = {transaction: tx}; - const response = await models.Application.executeRoutine( - ctx, - 'myFunction', - [1], - 'bs', - 'function', - options - ); + const response = await models.Application.executeProc( + ctx, + 'myProcedure', + [1], + null, + options + ); - expect(response).toEqual(1); + expect(response.length).toEqual(2); + expect(response[0].myParam).toEqual(1); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); - it('should execute function and get data with user with inherited privileges', async() => { - const ctx = getCtx(userWithInheritedPrivileges); - try { - const options = {transaction: tx}; + describe('Application executeFunc()', () => { + it('should execute function and get data', async() => { + const ctx = getCtx(userWithPrivileges); + try { + const options = {transaction: tx}; - const response = await models.Application.executeRoutine( - ctx, - 'myFunction', - [1], - 'bs', - 'function', - options - ); + const response = await models.Application.executeFunc( + ctx, + 'myFunction', + [1], + 'bs', + options + ); - expect(response).toEqual(1); + expect(response).toEqual(1); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should execute function and get data with user with inherited privileges', async() => { + const ctx = getCtx(userWithInheritedPrivileges); + try { + const options = {transaction: tx}; + + const response = await models.Application.executeFunc( + ctx, + 'myFunction', + [1], + 'bs', + options + ); + + expect(response).toEqual(1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); }); diff --git a/loopback/common/models/application.js b/loopback/common/models/application.js index b9e639b1be..ac8ae78f0d 100644 --- a/loopback/common/models/application.js +++ b/loopback/common/models/application.js @@ -2,5 +2,7 @@ module.exports = function(Self) { require('../methods/application/status')(Self); require('../methods/application/post')(Self); - require('../methods/application/executeRoutine')(Self); + require('../methods/application/execute')(Self); + require('../methods/application/executeProc')(Self); + require('../methods/application/executeFunc')(Self); }; From a1c8bba4a56e3d0d2907755e6060be55237f24fd Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 10 Nov 2023 11:29:18 +0100 Subject: [PATCH 200/449] hotfix addressId --- modules/ticket/back/methods/ticket/closure.js | 289 +++++++++--------- 1 file changed, 145 insertions(+), 144 deletions(-) diff --git a/modules/ticket/back/methods/ticket/closure.js b/modules/ticket/back/methods/ticket/closure.js index 9f9aec9bd1..1d04679d3a 100644 --- a/modules/ticket/back/methods/ticket/closure.js +++ b/modules/ticket/back/methods/ticket/closure.js @@ -5,177 +5,178 @@ const config = require('vn-print/core/config'); const storage = require('vn-print/core/storage'); module.exports = async function(ctx, Self, tickets, reqArgs = {}) { - const userId = ctx.req.accessToken.userId; - if (tickets.length == 0) return; + 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], {userId}); + const failedtickets = []; + for (const ticket of tickets) { + try { + 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 - FROM ticket t - JOIN invoiceOut io ON io.ref = t.refFk - JOIN company cny ON cny.id = io.companyFk - WHERE t.id = ? - `, [ticket.id]); + const [invoiceOut] = await Self.rawSql(` + SELECT io.id, io.ref, io.serial, cny.code companyCode, io.issued + FROM ticket t + JOIN invoiceOut io ON io.ref = t.refFk + JOIN company cny ON cny.id = io.companyFk + WHERE t.id = ? + `, [ticket.id]); - const mailOptions = { - overrideAttachments: true, - attachments: [] - }; + const mailOptions = { + overrideAttachments: true, + attachments: [] + }; - const isToBeMailed = ticket.recipient && ticket.salesPersonFk && ticket.isToBeMailed; + const isToBeMailed = ticket.recipient && ticket.salesPersonFk && ticket.isToBeMailed; - if (invoiceOut) { - const args = { - reference: invoiceOut.ref, - recipientId: ticket.clientFk, - recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail - }; + if (invoiceOut) { + const args = { + reference: invoiceOut.ref, + recipientId: ticket.clientFk, + recipient: ticket.recipient, + replyTo: ticket.salesPersonEmail + }; - const invoiceReport = new Report('invoice', args); - const stream = await invoiceReport.toPdfStream(); + const invoiceReport = new Report('invoice', args); + const stream = await invoiceReport.toPdfStream(); - const issued = invoiceOut.issued; - const year = issued.getFullYear().toString(); - const month = (issued.getMonth() + 1).toString(); - const day = issued.getDate().toString(); + 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`; + const fileName = `${year}${invoiceOut.ref}.pdf`; - // Store invoice - await storage.write(stream, { - type: 'invoice', - path: `${year}/${month}/${day}`, - fileName: fileName - }); + // Store invoice + await storage.write(stream, { + type: 'invoice', + path: `${year}/${month}/${day}`, + fileName: fileName + }); - await Self.rawSql('UPDATE invoiceOut SET hasPdf = true WHERE id = ?', [invoiceOut.id], {userId}); + await Self.rawSql('UPDATE invoiceOut SET hasPdf = true WHERE id = ?', [invoiceOut.id], {userId}); - if (isToBeMailed) { - const invoiceAttachment = { - filename: fileName, - content: stream - }; + if (isToBeMailed) { + const invoiceAttachment = { + filename: fileName, + content: stream + }; - if (invoiceOut.serial == 'E' && invoiceOut.companyCode == 'VNL') { - const exportation = new Report('exportation', args); - const stream = await exportation.toPdfStream(); - const fileName = `CITES-${invoiceOut.ref}.pdf`; + if (invoiceOut.serial == 'E' && invoiceOut.companyCode == 'VNL') { + const exportation = new Report('exportation', args); + const stream = await exportation.toPdfStream(); + const fileName = `CITES-${invoiceOut.ref}.pdf`; - mailOptions.attachments.push({ - filename: fileName, - content: stream - }); - } + mailOptions.attachments.push({ + filename: fileName, + content: stream + }); + } - mailOptions.attachments.push(invoiceAttachment); + mailOptions.attachments.push(invoiceAttachment); - const email = new Email('invoice', args); - await email.send(mailOptions); - } - } else if (isToBeMailed) { - const args = { - id: ticket.id, - recipientId: ticket.clientFk, - recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail - }; + const email = new Email('invoice', args); + await email.send(mailOptions); + } + } else if (isToBeMailed) { + const args = { + id: ticket.id, + recipientId: ticket.clientFk, + recipient: ticket.recipient, + replyTo: ticket.salesPersonEmail + }; - const email = new Email('delivery-note-link', args); - await email.send(); - } + const email = new Email('delivery-note-link', args); + await email.send(); + } - // Incoterms authorization - const [{firstOrder}] = await Self.rawSql(` - SELECT COUNT(*) as firstOrder - FROM ticket t - JOIN client c ON c.id = t.clientFk - WHERE t.clientFk = ? - AND NOT t.isDeleted - AND c.isVies - `, [ticket.clientFk]); + // Incoterms authorization + const [{firstOrder}] = await Self.rawSql(` + SELECT COUNT(*) as firstOrder + FROM ticket t + JOIN client c ON c.id = t.clientFk + WHERE t.clientFk = ? + AND NOT t.isDeleted + AND c.isVies + `, [ticket.clientFk]); - if (firstOrder == 1) { - const args = { - id: ticket.clientFk, - companyId: ticket.companyFk, - recipientId: ticket.clientFk, - recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail - }; + if (firstOrder == 1) { + const args = { + id: ticket.clientFk, + companyId: ticket.companyFk, + recipientId: ticket.clientFk, + recipient: ticket.recipient, + replyTo: ticket.salesPersonEmail, + addressId: ticket.addressFk + }; - const email = new Email('incoterms-authorization', args); - await email.send(); + const email = new Email('incoterms-authorization', args); + await email.send(); - const [sample] = await Self.rawSql( - `SELECT id - FROM sample - WHERE code = 'incoterms-authorization' - `); + const [sample] = await Self.rawSql( + `SELECT id + FROM sample + WHERE code = 'incoterms-authorization' + `); - await Self.rawSql(` - INSERT INTO clientSample (clientFk, typeFk, companyFk) VALUES(?, ?, ?) - `, [ticket.clientFk, sample.id, ticket.companyFk], {userId}); - }; - } catch (error) { - // Domain not found - if (error.responseCode == 450) - return invalidEmail(ticket); + await Self.rawSql(` + INSERT INTO clientSample (clientFk, typeFk, companyFk) VALUES(?, ?, ?) + `, [ticket.clientFk, sample.id, ticket.companyFk], {userId}); + } + } catch (error) { + // Domain not found + if (error.responseCode == 450) + return invalidEmail(ticket); - // Save tickets on a list of failed ids - failedtickets.push({ - id: ticket.id, - stacktrace: error - }); - } - } + // Save tickets on a list of failed ids + failedtickets.push({ + id: ticket.id, + stacktrace: error + }); + } + } - // Send email with failed tickets - if (failedtickets.length > 0) { - let body = 'This following tickets have failed:

'; + // Send email with failed tickets + if (failedtickets.length > 0) { + let body = 'This following tickets have failed:

'; - for (const ticket of failedtickets) { - body += `Ticket: ${ticket.id} -
${ticket.stacktrace}

`; - } + for (const ticket of failedtickets) { + body += `Ticket: ${ticket.id} +
${ticket.stacktrace}

`; + } - smtp.send({ - to: config.app.reportEmail, - subject: '[API] Nightly ticket closure report', - html: body - }); - } + smtp.send({ + to: config.app.reportEmail, + subject: '[API] Nightly ticket closure report', + html: body + }); + } - async function invalidEmail(ticket) { - await Self.rawSql(`UPDATE client SET email = NULL WHERE id = ?`, [ - ticket.clientFk - ], {userId}); + 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) - VALUES (?, NULL, 'UPDATE', 'Client', ?, ?)`, [ - ticket.clientFk, - oldInstance, - newInstance - ], {userId}); + const oldInstance = `{"email": "${ticket.recipient}"}`; + const newInstance = `{"email": ""}`; + await Self.rawSql(` + 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 - o no está disponible.

- 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.`; + 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. + Actualiza la dirección de email con una correcta.`; - smtp.send({ - to: ticket.salesPersonEmail, - subject: 'No se ha podido enviar el albarán', - html: body - }); - } + smtp.send({ + to: ticket.salesPersonEmail, + subject: 'No se ha podido enviar el albarán', + html: body + }); + } }; From 9f92bc4b4c5e72bc63385605a115f6d464416dac Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 10 Nov 2023 11:43:42 +0100 Subject: [PATCH 201/449] fix: refs #6023 Rollback privileges.js --- back/methods/vn-user/privileges.js | 66 ++++++++++++------------------ 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/back/methods/vn-user/privileges.js b/back/methods/vn-user/privileges.js index 0520fd5c2c..08cfaaae88 100644 --- a/back/methods/vn-user/privileges.js +++ b/back/methods/vn-user/privileges.js @@ -40,56 +40,44 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; const myOptions = {}; - let tx; if (typeof options == 'object') Object.assign(myOptions, options); - if (!myOptions.transaction) { - tx = await Self.beginTransaction({}); - myOptions.transaction = tx; - }; + const user = await Self.findById(userId, {fields: ['hasGrant']}, myOptions); - try { - const user = await Self.findById(userId, {fields: ['hasGrant']}, myOptions); - - const userToUpdate = await Self.findById(id, { - fields: ['id', 'name', 'hasGrant', 'roleFk', 'password', 'email'], - include: { - relation: 'role', - scope: { - fields: ['name'] - } + const userToUpdate = await Self.findById(id, { + fields: ['id', 'name', 'hasGrant', 'roleFk', 'password', 'email'], + include: { + relation: 'role', + scope: { + fields: ['name'] } - }, myOptions); + } + }, myOptions); - if (!user.hasGrant) - throw new UserError(`You don't have grant privilege`); + if (!user.hasGrant) + throw new UserError(`You don't have grant privilege`); - const hasRoleFromUser = await Self.hasRole(userId, userToUpdate.role().name, myOptions); + const hasRoleFromUser = await Self.hasRole(userId, userToUpdate.role().name, myOptions); - if (!hasRoleFromUser) + if (!hasRoleFromUser) + throw new UserError(`You don't own the role and you can't assign it to another user`); + + if (hasGrant != null) + userToUpdate.hasGrant = hasGrant; + + if (roleFk) { + const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions); + const hasRole = await Self.hasRole(userId, role.name, myOptions); + + if (!hasRole) throw new UserError(`You don't own the role and you can't assign it to another user`); - if (hasGrant != null) - userToUpdate.hasGrant = hasGrant; + userToUpdate.roleFk = roleFk; + } - if (roleFk) { - const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions); - const hasRole = await Self.hasRole(userId, role.name, myOptions); - - if (!hasRole) - throw new UserError(`You don't own the role and you can't assign it to another user`); - - userToUpdate.roleFk = roleFk; - } - - await userToUpdate.save(myOptions); - await models.Account.sync(userToUpdate.name, null, null, myOptions); - if (tx) await tx.commit(); - } catch (err) { - if (tx) await tx.rollback(); - throw err; - }; + await userToUpdate.save(userToUpdate); + await models.Account.sync(userToUpdate.name); }; }; From b7da144967c5c34cdcd937ae39169fcae8001df1 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 10 Nov 2023 11:55:37 +0100 Subject: [PATCH 202/449] feat: refs #6023 Added SELECT FOR UPDATE --- modules/account/back/methods/account/sync.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/account/back/methods/account/sync.js b/modules/account/back/methods/account/sync.js index c4f9cb181b..8548e71f3d 100644 --- a/modules/account/back/methods/account/sync.js +++ b/modules/account/back/methods/account/sync.js @@ -48,6 +48,13 @@ module.exports = Self => { if (tx) await tx.rollback(); return; } + + await Self.rawSql(` + SELECT id + FROM account.user + WHERE id = ? + FOR UPDATE`, [user.id], myOptions); + await models.AccountConfig.syncUser(userName, password); await models.UserSync.destroyById(userName, myOptions); if (tx) await tx.commit(); From bcccd1894c555706f115c1fe670ce1c40dfe2b4b Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Fri, 10 Nov 2023 13:13:17 +0100 Subject: [PATCH 203/449] refs #6264 test: init test --- .../methods/vn-user/specs/renew-token.spec.js | 22 +++++++++++++++++++ .../vn-user/specs/validate-token.spec.js | 9 ++++++++ 2 files changed, 31 insertions(+) create mode 100644 back/methods/vn-user/specs/renew-token.spec.js create mode 100644 back/methods/vn-user/specs/validate-token.spec.js diff --git a/back/methods/vn-user/specs/renew-token.spec.js b/back/methods/vn-user/specs/renew-token.spec.js new file mode 100644 index 0000000000..cae91f3107 --- /dev/null +++ b/back/methods/vn-user/specs/renew-token.spec.js @@ -0,0 +1,22 @@ +describe('Renew Token', () => { + it('Token is valid', async() => { + let login = await VnUser.signIn(unauthCtx, 'salesAssistant', 'nightmare'); + let accessToken = await AccessToken.findById(login.token); + let ctx = {req: {accessToken: accessToken}}; + + expect(login.token).toBeDefined(); + }); + + it('Token is is invalid', async() => { + let error; + try { + await models.VnUser.validateCode('developer', '123456'); + } catch (e) { + error = e; + } + + expect(error).toBeDefined(); + expect(error.statusCode).toBe(400); + expect(error.message).toEqual('Invalid or expired verification code'); + }); +}); diff --git a/back/methods/vn-user/specs/validate-token.spec.js b/back/methods/vn-user/specs/validate-token.spec.js new file mode 100644 index 0000000000..0d0af689f4 --- /dev/null +++ b/back/methods/vn-user/specs/validate-token.spec.js @@ -0,0 +1,9 @@ +describe('Validate Token', () => { + it('Token is not expired', async() => { + + }); + + it('Token is expired', async() => { + + }); +}); From 5dbfe31a60d129f2d076c548096f5e653050b218 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Fri, 10 Nov 2023 15:12:03 +0100 Subject: [PATCH 204/449] refs #5666 feat: define VnRole --- .vscode/settings.json | 6 ++++++ back/model-config.json | 3 +++ back/models/vn-role.json | 13 +++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 back/models/vn-role.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 05d23f3bbc..4c2761987b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,5 +10,11 @@ "eslint.format.enable": true, "[javascript]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint" + }, + "cSpell.words": [ + "Loggable" + ], + "[json]": { + "editor.defaultFormatter": "vscode.json-language-features" } } diff --git a/back/model-config.json b/back/model-config.json index ebc0e321b0..84dd9eebd2 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -142,6 +142,9 @@ "VnUser": { "dataSource": "vn" }, + "VnRole": { + "dataSource": "vn" + }, "OsTicket": { "dataSource": "osticket" }, diff --git a/back/models/vn-role.json b/back/models/vn-role.json new file mode 100644 index 0000000000..e841f8a885 --- /dev/null +++ b/back/models/vn-role.json @@ -0,0 +1,13 @@ +{ + "name": "VnRole", + "base": "Role", + "validateUpsert": true, + "options": { + "mysql": { + "table": "account.role" + } + }, + "mixins": { + "RegisterLog": true + } +} From cf3cc37d97f61372dd9072492b60ffce5ad35cfd Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Fri, 10 Nov 2023 15:12:24 +0100 Subject: [PATCH 205/449] refs #5666 feat: create mixin --- back/mixins/register-log.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 back/mixins/register-log.js diff --git a/back/mixins/register-log.js b/back/mixins/register-log.js new file mode 100644 index 0000000000..555191e575 --- /dev/null +++ b/back/mixins/register-log.js @@ -0,0 +1,20 @@ + +const loggable = require('vn-loopback/util/log'); + +module.exports = function(Self, options) { + Self.once('attached', function(ctx) { + }); + + Self.observe('before save', async function(ctx, next) { + await loggable.translateValues(Self, ctx.currentInstance); + }); + + let Mixin = { + + }; + + for (let method in Mixin) { + if (!Self.prototype[method]) + Self.prototype[method] = Mixin[method]; + } +}; From 3c5af184bbc6458ca3963b7a561b187577a1509f Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Fri, 10 Nov 2023 15:12:49 +0100 Subject: [PATCH 206/449] refs #5666 feat: use mixin for this models --- back/models/vn-user.json | 3 +++ modules/account/back/models/account.json | 3 +++ 2 files changed, 6 insertions(+) diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 0f6daff5ac..28fca8fe89 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -7,6 +7,9 @@ "table": "account.user" } }, + "mixins": { + "RegisterLog": true + }, "resetPasswordTokenTTL": "604800", "properties": { "id": { diff --git a/modules/account/back/models/account.json b/modules/account/back/models/account.json index 3c22521cbe..3c76c85c37 100644 --- a/modules/account/back/models/account.json +++ b/modules/account/back/models/account.json @@ -6,6 +6,9 @@ "table": "account.account" } }, + "mixins": { + "RegisterLog": true + }, "properties": { "id": { "id": true From 59d2da24eb6d5329b0700453abaabb3215105f79 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 13 Nov 2023 09:36:20 +0100 Subject: [PATCH 207/449] refs #6014 refactor(execute): split code --- .../common/methods/application/execute.js | 19 +++++++------------ .../common/methods/application/executeFunc.js | 6 +++++- .../common/methods/application/executeProc.js | 9 +++++++-- .../methods/application/spec/execute.spec.js | 8 ++------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/loopback/common/methods/application/execute.js b/loopback/common/methods/application/execute.js index 7a24df0d40..c0475dbfed 100644 --- a/loopback/common/methods/application/execute.js +++ b/loopback/common/methods/application/execute.js @@ -1,32 +1,27 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.execute = async(ctx, routine, params, schema, type, options) => { + Self.execute = async(ctx, query, params, options) => { const userId = ctx.req.accessToken.userId; const models = Self.app.models; - let caller = 'CALL'; - params = params ?? []; - schema = schema ?? 'vn'; - type = type ?? 'procedure'; const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); - const chain = `${schema}.${routine}`; + let [caller, chain] = query.split(' '); + if (!chain.includes('.')) chain = 'vn.' + chain; + const [canExecute] = await models.ProcsPriv.rawSql( 'SELECT account.user_hasRoutinePriv(?,?,?)', - [type.toUpperCase(), chain, userId], + [caller == 'CALL' ? 'PROCEDURE' : 'FUNCTION', chain, userId], myOptions); + if (!Object.values(canExecute)[0]) throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED'); - const isFunction = type == 'function'; let argString = params.map(() => '?').join(','); - - if (isFunction) - caller = 'SELECT'; - const query = `${caller} ${chain}(${argString})`; + query = `${query}(${argString})`; const [response] = await models.ProcsPriv.rawSql(query, params, myOptions); return response; diff --git a/loopback/common/methods/application/executeFunc.js b/loopback/common/methods/application/executeFunc.js index 0a90e8639b..49e2cdc21c 100644 --- a/loopback/common/methods/application/executeFunc.js +++ b/loopback/common/methods/application/executeFunc.js @@ -32,7 +32,11 @@ module.exports = Self => { }); Self.executeFunc = async(ctx, routine, params, schema, options) => { - const response = await Self.execute(ctx, routine, params, schema, 'function', options); + if (schema) + routine = schema + '.' + routine; + + const query = `SELECT ${routine}`; + const response = await Self.execute(ctx, query, params, options); return Object.values(response)[0]; }; }; diff --git a/loopback/common/methods/application/executeProc.js b/loopback/common/methods/application/executeProc.js index 635944eb74..524831e86d 100644 --- a/loopback/common/methods/application/executeProc.js +++ b/loopback/common/methods/application/executeProc.js @@ -31,6 +31,11 @@ module.exports = Self => { } }); - Self.executeProc = async(ctx, routine, params, schema, options) => - Self.execute(ctx, routine, params, schema, 'procedure', options); + Self.executeProc = async(ctx, routine, params, schema, options) => { + if (schema) + routine = schema + '.' + routine; + + const query = `CALL ${routine}`; + return Self.execute(ctx, query, params, options); + }; }; diff --git a/loopback/common/methods/application/spec/execute.spec.js b/loopback/common/methods/application/spec/execute.spec.js index 26e648531f..4c57279847 100644 --- a/loopback/common/methods/application/spec/execute.spec.js +++ b/loopback/common/methods/application/spec/execute.spec.js @@ -50,10 +50,8 @@ describe('Application execute()/executeProc()/executeFunc()', () => { await models.Application.execute( ctx, - 'myProcedure', + 'CALL myProcedure', [1], - null, - null, options ); @@ -73,10 +71,8 @@ describe('Application execute()/executeProc()/executeFunc()', () => { const response = await models.Application.execute( ctx, - 'myProcedure', + 'CALL myProcedure', [1], - null, - null, options ); From a102c3f3a952da468734039c1e133e4470270842 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 13 Nov 2023 09:53:35 +0100 Subject: [PATCH 208/449] refs #5666 perf: loggable to mixin --- loopback/common/mixins/loggable.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 loopback/common/mixins/loggable.js diff --git a/loopback/common/mixins/loggable.js b/loopback/common/mixins/loggable.js new file mode 100644 index 0000000000..760fdf60a0 --- /dev/null +++ b/loopback/common/mixins/loggable.js @@ -0,0 +1,12 @@ +const LoopBackContext = require('loopback-context'); +async function handleObserve(ctx) { + ctx.options.httpCtx = LoopBackContext.getCurrentContext(); +} +module.exports = function(Self) { + let Mixin = { + 'before save': handleObserve, + 'before delete': handleObserve, + }; + for (const [listener, handler] of Object.entries(Mixin)) + Self.observe(listener, handler); +}; From aab88dc7dede9b31d733b5ff647224fc3b93d3f4 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 13 Nov 2023 09:54:12 +0100 Subject: [PATCH 209/449] refs #5666 perf: use use loggable as mixin --- back/models/vn-role.json | 2 +- back/models/vn-user.json | 2 +- loopback/common/models/loggable.json | 13 ++++++++----- modules/account/back/models/account.json | 5 +---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/back/models/vn-role.json b/back/models/vn-role.json index e841f8a885..c7d7e172b8 100644 --- a/back/models/vn-role.json +++ b/back/models/vn-role.json @@ -8,6 +8,6 @@ } }, "mixins": { - "RegisterLog": true + "Loggable": true } } diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 28fca8fe89..bda0a6ec3d 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -8,7 +8,7 @@ } }, "mixins": { - "RegisterLog": true + "Loggable": true }, "resetPasswordTokenTTL": "604800", "properties": { diff --git a/loopback/common/models/loggable.json b/loopback/common/models/loggable.json index 9101532a34..62822d0af3 100644 --- a/loopback/common/models/loggable.json +++ b/loopback/common/models/loggable.json @@ -1,5 +1,8 @@ -{ - "name": "Loggable", - "base": "VnModel", - "validateUpsert": true -} +{ + "name": "Loggable", + "base": "VnModel", + "validateUpsert": true, + "mixins": { + "Loggable": true + } +} diff --git a/modules/account/back/models/account.json b/modules/account/back/models/account.json index 3c76c85c37..3e43716046 100644 --- a/modules/account/back/models/account.json +++ b/modules/account/back/models/account.json @@ -6,10 +6,7 @@ "table": "account.account" } }, - "mixins": { - "RegisterLog": true - }, - "properties": { + "properties": { "id": { "id": true } From 384b5eb7c7705cc1603bebaa67d09d58afbe4c91 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 13 Nov 2023 09:56:16 +0100 Subject: [PATCH 210/449] refs #5666 remove old file --- back/mixins/register-log.js | 20 ------ modules/account/back/models/account.json | 86 ++++++++++++------------ 2 files changed, 43 insertions(+), 63 deletions(-) delete mode 100644 back/mixins/register-log.js diff --git a/back/mixins/register-log.js b/back/mixins/register-log.js deleted file mode 100644 index 555191e575..0000000000 --- a/back/mixins/register-log.js +++ /dev/null @@ -1,20 +0,0 @@ - -const loggable = require('vn-loopback/util/log'); - -module.exports = function(Self, options) { - Self.once('attached', function(ctx) { - }); - - Self.observe('before save', async function(ctx, next) { - await loggable.translateValues(Self, ctx.currentInstance); - }); - - let Mixin = { - - }; - - for (let method in Mixin) { - if (!Self.prototype[method]) - Self.prototype[method] = Mixin[method]; - } -}; diff --git a/modules/account/back/models/account.json b/modules/account/back/models/account.json index 3e43716046..6c27846966 100644 --- a/modules/account/back/models/account.json +++ b/modules/account/back/models/account.json @@ -1,49 +1,49 @@ { - "name": "Account", - "base": "VnModel", - "options": { - "mysql": { - "table": "account.account" - } - }, + "name": "Account", + "base": "VnModel", + "options": { + "mysql": { + "table": "account.account" + } + }, "properties": { - "id": { - "id": true - } - }, - "relations": { - "user": { - "type": "belongsTo", - "model": "VnUser", - "foreignKey": "id" - }, - "aliases": { - "type": "hasMany", - "model": "MailAliasAccount", - "foreignKey": "account" - } - }, - "acls": [ - { - "property": "login", - "accessType": "EXECUTE", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" + "id": { + "id": true + } + }, + "relations": { + "user": { + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "id" }, - { + "aliases": { + "type": "hasMany", + "model": "MailAliasAccount", + "foreignKey": "account" + } + }, + "acls": [ + { + "property": "login", + "accessType": "EXECUTE", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }, + { "property": "logout", - "accessType": "EXECUTE", - "principalType": "ROLE", - "principalId": "$authenticated", - "permission": "ALLOW" - }, - { + "accessType": "EXECUTE", + "principalType": "ROLE", + "principalId": "$authenticated", + "permission": "ALLOW" + }, + { "property": "changePassword", - "accessType": "EXECUTE", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - } - ] + "accessType": "EXECUTE", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] } From 1a66987cd0ff298ff392ad27d43a81bed410eb14 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 13 Nov 2023 12:26:31 +0100 Subject: [PATCH 211/449] refs #5979 fix(vn-user): resetPassword url --- back/models/vn-user.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 970497e4e8..712ed7d167 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -92,7 +92,11 @@ module.exports = function(Self) { }; Self.on('resetPasswordRequest', async function(info) { - const url = await Self.app.models.Url.getUrl(); + const loopBackContext = LoopBackContext.getCurrentContext(); + const httpCtx = {req: loopBackContext.active}; + const httpRequest = httpCtx.req.http.req; + const headers = httpRequest.headers; + const origin = headers.origin; const defaultHash = '/reset-password?access_token=$token$'; const recoverHashes = { @@ -108,7 +112,7 @@ module.exports = function(Self) { const params = { recipient: info.email, lang: user.lang, - url: url.slice(0, -1) + recoverHash + url: origin + '/#!' + recoverHash }; const options = Object.assign({}, info.options); From 47d85c4c616f7decd460e4f8a3fca755f9e2587f Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 13 Nov 2023 12:54:02 +0100 Subject: [PATCH 212/449] refs #6335 fix: remove unnecessary translations --- loopback/locale/en.json | 4 +--- loopback/locale/es.json | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 9305c7f093..82cf5b40b8 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -196,7 +196,5 @@ "Negative basis of tickets: 23": "Negative basis of tickets: 23", "Booking completed": "Booking complete", "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation", - "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets", - "newTicket": "New ticket", - "keepPrice": "Keep prices" + "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 933a354680..0ee6194e4f 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -225,8 +225,6 @@ "reference duplicated": "Referencia duplicada", "This ticket is already a refund": "Este ticket ya es un abono", "isWithoutNegatives": "Sin negativos", - "newTicket": "Nuevo ticket", - "keepPrice": "Mantener precios", "routeFk": "routeFk", "Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador", "No hay un contrato en vigor": "No hay un contrato en vigor", From 6527cae72a2e725166049af6001d5382253f9330 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 14 Nov 2023 07:58:33 +0100 Subject: [PATCH 213/449] refactor: refs #6172 Added real message error --- front/salix/locale/es.yml | 1 + front/salix/module.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/front/salix/locale/es.yml b/front/salix/locale/es.yml index bed41c63b4..8ed58a4e4a 100644 --- a/front/salix/locale/es.yml +++ b/front/salix/locale/es.yml @@ -18,6 +18,7 @@ Show summary: Mostrar vista previa What is new: Novedades de la versión Settings: Ajustes There is a new version, click here to reload: Hay una nueva versión, pulse aquí para recargar +This ticket is locked.: Este ticket está bloqueado # Actions diff --git a/front/salix/module.js b/front/salix/module.js index 5025eec22e..bb7e189a9a 100644 --- a/front/salix/module.js +++ b/front/salix/module.js @@ -120,7 +120,7 @@ function $exceptionHandler(vnApp, $window, $state, $injector) { messageT = 'Invalid login'; break; case 403: - messageT = (exception.data.error.message) ? exception.data.error.message : 'Access denied'; + messageT = exception.data.error.message || 'Access denied'; break; case 502: messageT = 'It seems that the server has fall down'; From cce61ae8ccf9b7d747a0f934a187b9adcfb8bc59 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 14 Nov 2023 09:17:46 +0100 Subject: [PATCH 214/449] refs #6014 refactor(execute): schema required --- .../common/methods/application/execute.js | 12 +++++------ .../common/methods/application/executeFunc.js | 19 +++++++++--------- .../common/methods/application/executeProc.js | 20 +++++++++---------- .../methods/application/spec/execute.spec.js | 12 ++++++----- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/loopback/common/methods/application/execute.js b/loopback/common/methods/application/execute.js index c0475dbfed..7995b12e35 100644 --- a/loopback/common/methods/application/execute.js +++ b/loopback/common/methods/application/execute.js @@ -1,7 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.execute = async(ctx, query, params, options) => { + Self.execute = async(ctx, type, query, params, options) => { const userId = ctx.req.accessToken.userId; const models = Self.app.models; params = params ?? []; @@ -10,20 +10,18 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - let [caller, chain] = query.split(' '); - if (!chain.includes('.')) chain = 'vn.' + chain; + const chain = query.split(' ')[1]; const [canExecute] = await models.ProcsPriv.rawSql( 'SELECT account.user_hasRoutinePriv(?,?,?)', - [caller == 'CALL' ? 'PROCEDURE' : 'FUNCTION', chain, userId], + [type, chain, userId], myOptions); if (!Object.values(canExecute)[0]) throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED'); - let argString = params.map(() => '?').join(','); - query = `${query}(${argString})`; + const argString = params.map(() => '?').join(','); - const [response] = await models.ProcsPriv.rawSql(query, params, myOptions); + const [response] = await models.ProcsPriv.rawSql(query + `(${argString})`, params, myOptions); return response; }; }; diff --git a/loopback/common/methods/application/executeFunc.js b/loopback/common/methods/application/executeFunc.js index 49e2cdc21c..f915f44829 100644 --- a/loopback/common/methods/application/executeFunc.js +++ b/loopback/common/methods/application/executeFunc.js @@ -10,16 +10,17 @@ module.exports = Self => { required: true, http: {source: 'path'} }, + { + arg: 'schema', + type: 'string', + description: 'The routine schema', + required: true, + }, { arg: 'params', type: ['any'], description: 'The params array', }, - { - arg: 'schema', - type: 'string', - description: 'The routine schema', - } ], returns: { type: 'any', @@ -31,12 +32,10 @@ module.exports = Self => { } }); - Self.executeFunc = async(ctx, routine, params, schema, options) => { - if (schema) - routine = schema + '.' + routine; + Self.executeFunc = async(ctx, routine, schema, params, options) => { + const query = `SELECT ${schema}.${routine}`; - const query = `SELECT ${routine}`; - const response = await Self.execute(ctx, query, params, options); + const response = await Self.execute(ctx, 'FUNCTION', query, params, options); return Object.values(response)[0]; }; }; diff --git a/loopback/common/methods/application/executeProc.js b/loopback/common/methods/application/executeProc.js index 524831e86d..5859611d98 100644 --- a/loopback/common/methods/application/executeProc.js +++ b/loopback/common/methods/application/executeProc.js @@ -10,16 +10,17 @@ module.exports = Self => { required: true, http: {source: 'path'} }, + { + arg: 'schema', + type: 'string', + description: 'The routine schema', + required: true, + }, { arg: 'params', type: ['any'], description: 'The params array', }, - { - arg: 'schema', - type: 'string', - description: 'The routine schema', - } ], returns: { type: 'any', @@ -31,11 +32,8 @@ module.exports = Self => { } }); - Self.executeProc = async(ctx, routine, params, schema, options) => { - if (schema) - routine = schema + '.' + routine; - - const query = `CALL ${routine}`; - return Self.execute(ctx, query, params, options); + Self.executeProc = async(ctx, routine, schema, params, options) => { + const query = `CALL ${schema}.${routine}`; + return Self.execute(ctx, 'PROCEDURE', query, params, options); }; }; diff --git a/loopback/common/methods/application/spec/execute.spec.js b/loopback/common/methods/application/spec/execute.spec.js index 4c57279847..1a0a8ace9b 100644 --- a/loopback/common/methods/application/spec/execute.spec.js +++ b/loopback/common/methods/application/spec/execute.spec.js @@ -50,7 +50,8 @@ describe('Application execute()/executeProc()/executeFunc()', () => { await models.Application.execute( ctx, - 'CALL myProcedure', + 'PROCEDURE', + 'CALL vn.myProcedure', [1], options ); @@ -71,7 +72,8 @@ describe('Application execute()/executeProc()/executeFunc()', () => { const response = await models.Application.execute( ctx, - 'CALL myProcedure', + 'PROCEDURE', + 'CALL vn.myProcedure', [1], options ); @@ -95,8 +97,8 @@ describe('Application execute()/executeProc()/executeFunc()', () => { const response = await models.Application.executeProc( ctx, 'myProcedure', + 'vn', [1], - null, options ); @@ -120,8 +122,8 @@ describe('Application execute()/executeProc()/executeFunc()', () => { const response = await models.Application.executeFunc( ctx, 'myFunction', - [1], 'bs', + [1], options ); @@ -142,8 +144,8 @@ describe('Application execute()/executeProc()/executeFunc()', () => { const response = await models.Application.executeFunc( ctx, 'myFunction', - [1], 'bs', + [1], options ); From aec1c9d4475bfb0605145b3617af9acf4ec522f2 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 14 Nov 2023 09:54:07 +0100 Subject: [PATCH 215/449] fix: correct align --- modules/ticket/back/methods/ticket/closure.js | 288 +++++++++--------- 1 file changed, 144 insertions(+), 144 deletions(-) diff --git a/modules/ticket/back/methods/ticket/closure.js b/modules/ticket/back/methods/ticket/closure.js index 9f9aec9bd1..7a2825a4d6 100644 --- a/modules/ticket/back/methods/ticket/closure.js +++ b/modules/ticket/back/methods/ticket/closure.js @@ -5,177 +5,177 @@ const config = require('vn-print/core/config'); const storage = require('vn-print/core/storage'); module.exports = async function(ctx, Self, tickets, reqArgs = {}) { - const userId = ctx.req.accessToken.userId; - if (tickets.length == 0) return; + 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], {userId}); + const failedtickets = []; + for (const ticket of tickets) { + try { + 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 - FROM ticket t - JOIN invoiceOut io ON io.ref = t.refFk - JOIN company cny ON cny.id = io.companyFk - WHERE t.id = ? - `, [ticket.id]); + const [invoiceOut] = await Self.rawSql(` + SELECT io.id, io.ref, io.serial, cny.code companyCode, io.issued + FROM ticket t + JOIN invoiceOut io ON io.ref = t.refFk + JOIN company cny ON cny.id = io.companyFk + WHERE t.id = ? + `, [ticket.id]); - const mailOptions = { - overrideAttachments: true, - attachments: [] - }; + const mailOptions = { + overrideAttachments: true, + attachments: [] + }; - const isToBeMailed = ticket.recipient && ticket.salesPersonFk && ticket.isToBeMailed; + const isToBeMailed = ticket.recipient && ticket.salesPersonFk && ticket.isToBeMailed; - if (invoiceOut) { - const args = { - reference: invoiceOut.ref, - recipientId: ticket.clientFk, - recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail - }; + if (invoiceOut) { + const args = { + reference: invoiceOut.ref, + recipientId: ticket.clientFk, + recipient: ticket.recipient, + replyTo: ticket.salesPersonEmail + }; - const invoiceReport = new Report('invoice', args); - const stream = await invoiceReport.toPdfStream(); + const invoiceReport = new Report('invoice', args); + const stream = await invoiceReport.toPdfStream(); - const issued = invoiceOut.issued; - const year = issued.getFullYear().toString(); - const month = (issued.getMonth() + 1).toString(); - const day = issued.getDate().toString(); + 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`; + const fileName = `${year}${invoiceOut.ref}.pdf`; - // Store invoice - await storage.write(stream, { - type: 'invoice', - path: `${year}/${month}/${day}`, - fileName: fileName - }); + // Store invoice + await storage.write(stream, { + type: 'invoice', + path: `${year}/${month}/${day}`, + fileName: fileName + }); - await Self.rawSql('UPDATE invoiceOut SET hasPdf = true WHERE id = ?', [invoiceOut.id], {userId}); + await Self.rawSql('UPDATE invoiceOut SET hasPdf = true WHERE id = ?', [invoiceOut.id], {userId}); - if (isToBeMailed) { - const invoiceAttachment = { - filename: fileName, - content: stream - }; + if (isToBeMailed) { + const invoiceAttachment = { + filename: fileName, + content: stream + }; - if (invoiceOut.serial == 'E' && invoiceOut.companyCode == 'VNL') { - const exportation = new Report('exportation', args); - const stream = await exportation.toPdfStream(); - const fileName = `CITES-${invoiceOut.ref}.pdf`; + if (invoiceOut.serial == 'E' && invoiceOut.companyCode == 'VNL') { + const exportation = new Report('exportation', args); + const stream = await exportation.toPdfStream(); + const fileName = `CITES-${invoiceOut.ref}.pdf`; - mailOptions.attachments.push({ - filename: fileName, - content: stream - }); - } + mailOptions.attachments.push({ + filename: fileName, + content: stream + }); + } - mailOptions.attachments.push(invoiceAttachment); + mailOptions.attachments.push(invoiceAttachment); - const email = new Email('invoice', args); - await email.send(mailOptions); - } - } else if (isToBeMailed) { - const args = { - id: ticket.id, - recipientId: ticket.clientFk, - recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail - }; + const email = new Email('invoice', args); + await email.send(mailOptions); + } + } else if (isToBeMailed) { + const args = { + id: ticket.id, + recipientId: ticket.clientFk, + recipient: ticket.recipient, + replyTo: ticket.salesPersonEmail + }; - const email = new Email('delivery-note-link', args); - await email.send(); - } + const email = new Email('delivery-note-link', args); + await email.send(); + } - // Incoterms authorization - const [{firstOrder}] = await Self.rawSql(` - SELECT COUNT(*) as firstOrder - FROM ticket t - JOIN client c ON c.id = t.clientFk - WHERE t.clientFk = ? - AND NOT t.isDeleted - AND c.isVies - `, [ticket.clientFk]); + // Incoterms authorization + const [{firstOrder}] = await Self.rawSql(` + SELECT COUNT(*) as firstOrder + FROM ticket t + JOIN client c ON c.id = t.clientFk + WHERE t.clientFk = ? + AND NOT t.isDeleted + AND c.isVies + `, [ticket.clientFk]); - if (firstOrder == 1) { - const args = { - id: ticket.clientFk, - companyId: ticket.companyFk, - recipientId: ticket.clientFk, - recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail - }; + if (firstOrder == 1) { + const args = { + id: ticket.clientFk, + companyId: ticket.companyFk, + recipientId: ticket.clientFk, + recipient: ticket.recipient, + replyTo: ticket.salesPersonEmail + }; - const email = new Email('incoterms-authorization', args); - await email.send(); + const email = new Email('incoterms-authorization', args); + await email.send(); - const [sample] = await Self.rawSql( - `SELECT id - FROM sample - WHERE code = 'incoterms-authorization' - `); + const [sample] = await Self.rawSql( + `SELECT id + FROM sample + WHERE code = 'incoterms-authorization' + `); - await Self.rawSql(` - INSERT INTO clientSample (clientFk, typeFk, companyFk) VALUES(?, ?, ?) - `, [ticket.clientFk, sample.id, ticket.companyFk], {userId}); - }; - } catch (error) { - // Domain not found - if (error.responseCode == 450) - return invalidEmail(ticket); + await Self.rawSql(` + INSERT INTO clientSample (clientFk, typeFk, companyFk) VALUES(?, ?, ?) + `, [ticket.clientFk, sample.id, ticket.companyFk], {userId}); + } + } catch (error) { + // Domain not found + if (error.responseCode == 450) + return invalidEmail(ticket); - // Save tickets on a list of failed ids - failedtickets.push({ - id: ticket.id, - stacktrace: error - }); - } - } + // Save tickets on a list of failed ids + failedtickets.push({ + id: ticket.id, + stacktrace: error + }); + } + } - // Send email with failed tickets - if (failedtickets.length > 0) { - let body = 'This following tickets have failed:

'; + // Send email with failed tickets + if (failedtickets.length > 0) { + let body = 'This following tickets have failed:

'; - for (const ticket of failedtickets) { - body += `Ticket: ${ticket.id} -
${ticket.stacktrace}

`; - } + for (const ticket of failedtickets) { + body += `Ticket: ${ticket.id} +
${ticket.stacktrace}

`; + } - smtp.send({ - to: config.app.reportEmail, - subject: '[API] Nightly ticket closure report', - html: body - }); - } + smtp.send({ + to: config.app.reportEmail, + subject: '[API] Nightly ticket closure report', + html: body + }); + } - async function invalidEmail(ticket) { - await Self.rawSql(`UPDATE client SET email = NULL WHERE id = ?`, [ - ticket.clientFk - ], {userId}); + 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) - VALUES (?, NULL, 'UPDATE', 'Client', ?, ?)`, [ - ticket.clientFk, - oldInstance, - newInstance - ], {userId}); + const oldInstance = `{"email": "${ticket.recipient}"}`; + const newInstance = `{"email": ""}`; + await Self.rawSql(` + 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 - o no está disponible.

- 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.`; + 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. + Actualiza la dirección de email con una correcta.`; - smtp.send({ - to: ticket.salesPersonEmail, - subject: 'No se ha podido enviar el albarán', - html: body - }); - } + smtp.send({ + to: ticket.salesPersonEmail, + subject: 'No se ha podido enviar el albarán', + html: body + }); + } }; From f3faf37e1a0e77227402a2c41fa54b5fdd2f5f7c Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 14 Nov 2023 12:34:00 +0100 Subject: [PATCH 216/449] hotfix addressFk --- .../ticket/back/methods/ticket/closeAll.js | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/modules/ticket/back/methods/ticket/closeAll.js b/modules/ticket/back/methods/ticket/closeAll.js index 660c168937..46c45aa927 100644 --- a/modules/ticket/back/methods/ticket/closeAll.js +++ b/modules/ticket/back/methods/ticket/closeAll.js @@ -32,31 +32,30 @@ module.exports = Self => { throw new UserError('You cannot close tickets for today'); const tickets = await Self.rawSql(` - SELECT - t.id, - t.clientFk, - t.companyFk, - c.name clientName, - c.email recipient, - c.salesPersonFk, - c.isToBeMailed, - c.hasToInvoice, - co.hasDailyInvoice, - eu.email salesPersonEmail - FROM ticket t - JOIN agencyMode am ON am.id = t.agencyModeFk - JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission - JOIN ticketState ts ON ts.ticketFk = t.id - JOIN alertLevel al ON al.id = ts.alertLevel - JOIN client c ON c.id = t.clientFk - JOIN province p ON p.id = c.provinceFk - JOIN country co ON co.id = p.countryFk - LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk - WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code != 'delivered')) - AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY) - AND util.dayEnd(?) - AND t.refFk IS NULL - GROUP BY t.id + SELECT t.id, + t.clientFk, + t.companyFk, + c.name clientName, + c.email recipient, + c.salesPersonFk, + c.isToBeMailed, + c.hasToInvoice, + co.hasDailyInvoice, + eu.email salesPersonEmail, + t.addressFk + FROM ticket t + JOIN agencyMode am ON am.id = t.agencyModeFk + JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission + JOIN ticketState ts ON ts.ticketFk = t.id + JOIN alertLevel al ON al.id = ts.alertLevel + JOIN client c ON c.id = t.clientFk + JOIN province p ON p.id = c.provinceFk + JOIN country co ON co.id = p.countryFk + LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk + WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code != 'delivered')) + AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY) AND util.dayEnd(?) + AND t.refFk IS NULL + GROUP BY t.id `, [toDate, toDate]); await closure(ctx, Self, tickets); From 5c777c705feecca80213dd5a7ef4d70d246e4c26 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 14 Nov 2023 13:00:20 +0100 Subject: [PATCH 217/449] refs #6434 feat: add new error message --- back/methods/vn-user/sign-in.js | 28 +++++++++++++++------------- back/models/vn-user.js | 13 +++++++++++-- loopback/locale/es.json | 4 +++- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/back/methods/vn-user/sign-in.js b/back/methods/vn-user/sign-in.js index b9e0d2f705..5c84b654e9 100644 --- a/back/methods/vn-user/sign-in.js +++ b/back/methods/vn-user/sign-in.js @@ -26,7 +26,7 @@ module.exports = Self => { } }); - Self.signIn = async function(ctx, user, password, options) { + Self.signIn = async function (ctx, user, password, options) { const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); @@ -40,15 +40,17 @@ module.exports = Self => { const validCredentials = vnUser && await vnUser.hasPassword(password); - if (validCredentials) { - if (!vnUser.active) - throw new UserError('User disabled'); - await Self.sendTwoFactor(ctx, vnUser, myOptions); - await Self.passExpired(vnUser, myOptions); + if (!validCredentials) + throw new UserError('Invalid credentials'); - if (vnUser.twoFactor) - throw new ForbiddenError(null, 'REQUIRES_2FA'); - } + if (!vnUser.active) + throw new UserError('User disabled'); + + await Self.sendTwoFactor(ctx, vnUser, myOptions); + await Self.passExpired(vnUser, myOptions); + + if (vnUser.twoFactor) + throw new ForbiddenError(null, 'REQUIRES_2FA'); return Self.validateLogin(user, password); }; @@ -59,18 +61,18 @@ module.exports = Self => { if (vnUser.passExpired && vnUser.passExpired.getTime() <= today.getTime()) { const err = new UserError('Pass expired', 'passExpired'); - err.details = {userId: vnUser.id, twoFactor: vnUser.twoFactor ? true : false}; + err.details = { userId: vnUser.id, twoFactor: vnUser.twoFactor ? true : false }; throw err; } }; - Self.sendTwoFactor = async(ctx, vnUser, myOptions) => { + Self.sendTwoFactor = async (ctx, vnUser, myOptions) => { if (vnUser.twoFactor === 'email') { const $ = Self.app.models; const code = String(Math.floor(Math.random() * 999999)); const maxTTL = ((60 * 1000) * 5); // 5 min - await $.AuthCode.upsertWithWhere({userFk: vnUser.id}, { + await $.AuthCode.upsertWithWhere({ userFk: vnUser.id }, { userFk: vnUser.id, code: code, expires: Date.vnNow() + maxTTL @@ -87,7 +89,7 @@ module.exports = Self => { ip: ctx.req?.connection?.remoteAddress, device: platform && browser ? platform + ', ' + browser : headers['user-agent'], }, - req: {getLocale: ctx.req.getLocale}, + req: { getLocale: ctx.req.getLocale }, }; await Self.sendTemplate(params, 'auth-code', true); diff --git a/back/models/vn-user.js b/back/models/vn-user.js index de5bf7b63e..5c6e4a30f7 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -2,6 +2,7 @@ const vnModel = require('vn-loopback/common/models/vn-model'); const {Email} = require('vn-print'); const ForbiddenError = require('vn-loopback/util/forbiddenError'); const LoopBackContext = require('loopback-context'); +const UserError = require('vn-loopback/util/user-error'); module.exports = function(Self) { vnModel(Self); @@ -121,10 +122,18 @@ module.exports = function(Self) { }); Self.validateLogin = async function(user, password) { - let loginInfo = Object.assign({password}, Self.userUses(user)); - token = await Self.login(loginInfo, 'user'); + const loginInfo = Object.assign({password}, Self.userUses(user)); + const token = await Self.login(loginInfo, 'user'); const userToken = await token.user.get(); + + if (userToken.username !== user) { + console.error('ERROR!!! - Signin with other user', userToken, user); + throw new UserError('Try again'); + } + + const userCheck = await Self.app.models.VnUser.findOne({where: {name: user}}); + if (userToken.id != userCheck.id) await Self.validateLogin(user, password); try { await Self.app.models.Account.sync(userToken.name, password); } catch (err) { diff --git a/loopback/locale/es.json b/loopback/locale/es.json index b427204587..7cccc0fd0a 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -325,5 +325,7 @@ "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mímina", "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina", - "The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada" + "The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada", + "User disabled": "User disabled", + "Invalid credentials": "Invalid credentials" } From 2bec1a2bed8fb261fe85ecf898467d78542de2ab Mon Sep 17 00:00:00 2001 From: sergiodt Date: Tue, 14 Nov 2023 14:02:40 +0100 Subject: [PATCH 218/449] refs #6014 fix: response type. fix: accessType EXECUTE --- loopback/common/methods/application/execute.js | 5 +++-- loopback/common/methods/application/executeFunc.js | 2 +- loopback/common/methods/application/executeProc.js | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/loopback/common/methods/application/execute.js b/loopback/common/methods/application/execute.js index 7995b12e35..a468dcd700 100644 --- a/loopback/common/methods/application/execute.js +++ b/loopback/common/methods/application/execute.js @@ -21,7 +21,8 @@ module.exports = Self => { const argString = params.map(() => '?').join(','); - const [response] = await models.ProcsPriv.rawSql(query + `(${argString})`, params, myOptions); - return response; + const response = await models.ProcsPriv.rawSql(query + `(${argString})`, params, myOptions); + if (!Array.isArray(response)) return; + return response[0]; }; }; diff --git a/loopback/common/methods/application/executeFunc.js b/loopback/common/methods/application/executeFunc.js index f915f44829..a42fdae677 100644 --- a/loopback/common/methods/application/executeFunc.js +++ b/loopback/common/methods/application/executeFunc.js @@ -1,7 +1,7 @@ module.exports = Self => { Self.remoteMethodCtx('executeFunc', { description: 'Return result of function', - accessType: '*', + accessType: 'EXECUTE', accepts: [ { arg: 'routine', diff --git a/loopback/common/methods/application/executeProc.js b/loopback/common/methods/application/executeProc.js index 5859611d98..a8825da0fc 100644 --- a/loopback/common/methods/application/executeProc.js +++ b/loopback/common/methods/application/executeProc.js @@ -1,7 +1,7 @@ module.exports = Self => { Self.remoteMethodCtx('executeProc', { description: 'Return result of procedure', - accessType: '*', + accessType: 'EXECUTE', accepts: [ { arg: 'routine', From 7f82243ce6000176d9b9eeab03f81d68c781530f Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 14 Nov 2023 15:00:03 +0100 Subject: [PATCH 219/449] refs #6434 feat: create signInLog table --- back/methods/vn-user/sign-in.js | 19 ++++++---- db/changes/234801/00-createSignInLogTable.sql | 19 ++++++++++ modules/account/back/model-config.json | 3 ++ modules/account/back/models/sign_in-log.json | 35 +++++++++++++++++++ 4 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 db/changes/234801/00-createSignInLogTable.sql create mode 100644 modules/account/back/models/sign_in-log.json diff --git a/back/methods/vn-user/sign-in.js b/back/methods/vn-user/sign-in.js index 5c84b654e9..78d74b147f 100644 --- a/back/methods/vn-user/sign-in.js +++ b/back/methods/vn-user/sign-in.js @@ -26,7 +26,7 @@ module.exports = Self => { } }); - Self.signIn = async function (ctx, user, password, options) { + Self.signIn = async function(ctx, user, password, options) { const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); @@ -51,8 +51,13 @@ module.exports = Self => { if (vnUser.twoFactor) throw new ForbiddenError(null, 'REQUIRES_2FA'); - - return Self.validateLogin(user, password); + const validateLogin = await Self.validateLogin(user, password); + await Self.app.models.SignInLog.create({ + id: validateLogin.token, + userFk: vnUser.id, + ip: ctx.req.ip + }); + return validateLogin; }; Self.passExpired = async vnUser => { @@ -61,18 +66,18 @@ module.exports = Self => { if (vnUser.passExpired && vnUser.passExpired.getTime() <= today.getTime()) { const err = new UserError('Pass expired', 'passExpired'); - err.details = { userId: vnUser.id, twoFactor: vnUser.twoFactor ? true : false }; + err.details = {userId: vnUser.id, twoFactor: vnUser.twoFactor ? true : false}; throw err; } }; - Self.sendTwoFactor = async (ctx, vnUser, myOptions) => { + Self.sendTwoFactor = async(ctx, vnUser, myOptions) => { if (vnUser.twoFactor === 'email') { const $ = Self.app.models; const code = String(Math.floor(Math.random() * 999999)); const maxTTL = ((60 * 1000) * 5); // 5 min - await $.AuthCode.upsertWithWhere({ userFk: vnUser.id }, { + await $.AuthCode.upsertWithWhere({userFk: vnUser.id}, { userFk: vnUser.id, code: code, expires: Date.vnNow() + maxTTL @@ -89,7 +94,7 @@ module.exports = Self => { ip: ctx.req?.connection?.remoteAddress, device: platform && browser ? platform + ', ' + browser : headers['user-agent'], }, - req: { getLocale: ctx.req.getLocale }, + req: {getLocale: ctx.req.getLocale}, }; await Self.sendTemplate(params, 'auth-code', true); diff --git a/db/changes/234801/00-createSignInLogTable.sql b/db/changes/234801/00-createSignInLogTable.sql new file mode 100644 index 0000000000..977de46463 --- /dev/null +++ b/db/changes/234801/00-createSignInLogTable.sql @@ -0,0 +1,19 @@ + + +-- +-- Table structure for table `signInLog` +-- + +DROP TABLE IF EXISTS `account`.`signInLog`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `account`.`signInLog` ( + `id` varchar(10) NOT NULL , + `userFk` int(10) unsigned DEFAULT NULL, + `creationDate` timestamp NULL DEFAULT current_timestamp(), + `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + PRIMARY KEY (`id`), + KEY `userFk` (`userFk`), + CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +); + diff --git a/modules/account/back/model-config.json b/modules/account/back/model-config.json index a4eb9fa571..b4bd6dbafd 100644 --- a/modules/account/back/model-config.json +++ b/modules/account/back/model-config.json @@ -35,6 +35,9 @@ "SambaConfig": { "dataSource": "vn" }, + "SignInLog": { + "dataSource": "vn" + }, "Sip": { "dataSource": "vn" }, diff --git a/modules/account/back/models/sign_in-log.json b/modules/account/back/models/sign_in-log.json new file mode 100644 index 0000000000..df9ad8153e --- /dev/null +++ b/modules/account/back/models/sign_in-log.json @@ -0,0 +1,35 @@ +{ + "name": "SignInLog", + "base": "VnModel", + "options": { + "mysql": { + "table": "account.signInLog" + } + }, + "properties": { + "id": { + "id": true, + "type": "string", + "forceId": false + }, + "creationDate": { + "type": "date" + }, + "userFk": { + "type": "number" + }, + "ip": { + "type": "string" + } + }, + "relations": { + "user": { + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "userFk" + } + }, + "scope": { + "order": ["creationDate DESC", "id DESC"] + } +} From a5682e9a0d663637c6f5b726569cd364e8b8a933 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Tue, 14 Nov 2023 15:39:50 +0100 Subject: [PATCH 220/449] doc: refs #6062 README abbreviation --- README.md | 40 ++-------------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 59f5dbcf78..b420bc44f6 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 >= 16.x LTS +* Node.js * Docker * Git @@ -17,20 +17,7 @@ You will need to install globally the following items. $ sudo npm install -g jest gulp-cli ``` -For the usage of jest --watch on macOs. -``` -$ brew install watchman -``` -* [watchman](https://facebook.github.io/watchman/) - -## Linux Only Prerequisites - -Your user must be on the docker group to use it so you will need to run this command: -``` -$ sudo usermod -a -G docker yourusername -``` - -## Getting Started // Installing +## Installing dependencies and launching Pull from repository. @@ -76,29 +63,6 @@ In Visual Studio Code we use the ESLint extension. ext install dbaeumer.vscode-eslint ``` -Gitlens for visualization of code authorship -``` -ext install eamodio.gitlens -``` - -Spanish language pack -``` -ext install ms-ceintl.vscode-language-pack-es -``` - -### Recommended extensions - -Material icon Theme -``` -ext install pkief.material-icon-theme -``` - -Material UI Themes -``` -ext install equinusocio.vsc-material-theme -``` - - ## Built With * [angularjs](https://angularjs.org/) From 88ec0f24c3cf61c5b160ab4351c4519406fa4857 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 14 Nov 2023 15:45:52 +0100 Subject: [PATCH 221/449] ref #5914 rename table --- db/.archive/225201/00-invoiceOut_new.sql | 2 +- db/.archive/231001/02-invoiceOut_new.sql | 2 +- db/.archive/232001/00-invoiceOut_new.sql | 2 +- db/changes/234601/00-transferInvoice.sql | 2 +- db/dump/dumpedFixtures.sql | 10 ++++---- db/dump/structure.sql | 24 +++++++++---------- db/export-data.sh | 2 +- .../invoiceOut/specs/transferinvoice.spec.js | 4 ++-- .../methods/invoiceOut/transferInvoice.js | 4 ++-- modules/invoiceOut/back/model-config.json | 2 +- .../back/models/cplus-invoice-type-477.json | 6 ++--- .../back/models/invoice-correction.json | 4 ++-- .../front/descriptor-menu/index.html | 14 +++++------ .../invoiceOut/front/descriptor-menu/index.js | 2 +- 14 files changed, 40 insertions(+), 40 deletions(-) diff --git a/db/.archive/225201/00-invoiceOut_new.sql b/db/.archive/225201/00-invoiceOut_new.sql index 4c60b50bcb..8e23fb43b7 100644 --- a/db/.archive/225201/00-invoiceOut_new.sql +++ b/db/.archive/225201/00-invoiceOut_new.sql @@ -74,7 +74,7 @@ BEGIN clientFk, dued, companyFk, - cplusInvoiceType477Fk + siiTypeInvoiceOutFk ) SELECT 1, diff --git a/db/.archive/231001/02-invoiceOut_new.sql b/db/.archive/231001/02-invoiceOut_new.sql index d2b96eff78..d570dfb726 100644 --- a/db/.archive/231001/02-invoiceOut_new.sql +++ b/db/.archive/231001/02-invoiceOut_new.sql @@ -96,7 +96,7 @@ BEGIN clientFk, dued, companyFk, - cplusInvoiceType477Fk + siiTypeInvoiceOutFk ) SELECT 1, diff --git a/db/.archive/232001/00-invoiceOut_new.sql b/db/.archive/232001/00-invoiceOut_new.sql index b4fc5c824e..b497dffda6 100644 --- a/db/.archive/232001/00-invoiceOut_new.sql +++ b/db/.archive/232001/00-invoiceOut_new.sql @@ -96,7 +96,7 @@ BEGIN clientFk, dued, companyFk, - cplusInvoiceType477Fk + siiTypeInvoiceOutFk ) SELECT 1, diff --git a/db/changes/234601/00-transferInvoice.sql b/db/changes/234601/00-transferInvoice.sql index 7a9890ae45..d9ae394641 100644 --- a/db/changes/234601/00-transferInvoice.sql +++ b/db/changes/234601/00-transferInvoice.sql @@ -1,6 +1,6 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) VALUES ('CplusRectificationType', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), - ('CplusInvoiceType477', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('SiiTypeInvoiceOut', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('InvoiceCorrectionType', '*', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('InvoiceOut', 'transferInvoice', 'WRITE', 'ALLOW', 'ROLE', 'administrative'); diff --git a/db/dump/dumpedFixtures.sql b/db/dump/dumpedFixtures.sql index 2e1511b590..43eba7f241 100644 --- a/db/dump/dumpedFixtures.sql +++ b/db/dump/dumpedFixtures.sql @@ -275,13 +275,13 @@ INSERT INTO `cplusInvoiceType472` VALUES (1,'F1 - Factura'),(2,'F2 - Factura sim UNLOCK TABLES; -- --- Dumping data for table `cplusInvoiceType477` +-- Dumping data for table `siiTypeInvoiceOut` -- -LOCK TABLES `cplusInvoiceType477` WRITE; -/*!40000 ALTER TABLE `cplusInvoiceType477` DISABLE KEYS */; -INSERT INTO `cplusInvoiceType477` VALUES (1,'F1 - Factura'),(2,'F2 - Factura simplificada (ticket)'),(3,'F3 - Factura emitida en sustitución de facturas simplificadas facturadas y declaradas'),(4,'F4 - Asiento resumen de facturas'),(5,'R1 - Factura rectificativa (Art. 80.1, 80.2 y error fundado en derecho)'),(6,'R2 - Factura rectificativa (Art. 80.3)'),(7,'R3 - Factura rectificativa (Art. 80.4)'),(8,'R4 - Factura rectificativa (Resto)'),(9,'R5 - Factura rectificativa en facturas simplificadas'); -/*!40000 ALTER TABLE `cplusInvoiceType477` ENABLE KEYS */; +LOCK TABLES `siiTypeInvoiceOut` WRITE; +/*!40000 ALTER TABLE `siiTypeInvoiceOut` DISABLE KEYS */; +INSERT INTO `siiTypeInvoiceOut` VALUES (1,'F1 - Factura'),(2,'F2 - Factura simplificada (ticket)'),(3,'F3 - Factura emitida en sustitución de facturas simplificadas facturadas y declaradas'),(4,'F4 - Asiento resumen de facturas'),(5,'R1 - Factura rectificativa (Art. 80.1, 80.2 y error fundado en derecho)'),(6,'R2 - Factura rectificativa (Art. 80.3)'),(7,'R3 - Factura rectificativa (Art. 80.4)'),(8,'R4 - Factura rectificativa (Resto)'),(9,'R5 - Factura rectificativa en facturas simplificadas'); +/*!40000 ALTER TABLE `siiTypeInvoiceOut` ENABLE KEYS */; UNLOCK TABLES; -- diff --git a/db/dump/structure.sql b/db/dump/structure.sql index b242821fc6..3dab0c5a49 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -25993,13 +25993,13 @@ CREATE TABLE `cplusInvoiceType472` ( /*!40101 SET character_set_client = @saved_cs_client */; -- --- Table structure for table `cplusInvoiceType477` +-- Table structure for table `siiTypeInvoiceOut` -- -DROP TABLE IF EXISTS `cplusInvoiceType477`; +DROP TABLE IF EXISTS `siiTypeInvoiceOut`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE `cplusInvoiceType477` ( +CREATE TABLE `siiTypeInvoiceOut` ( `id` int(10) unsigned NOT NULL, `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, PRIMARY KEY (`id`) @@ -29450,16 +29450,16 @@ CREATE TABLE `invoiceCorrection` ( `correctingFk` int(10) unsigned NOT NULL COMMENT 'Factura rectificativa', `correctedFk` int(10) unsigned NOT NULL COMMENT 'Factura rectificada', `cplusRectificationTypeFk` int(10) unsigned NOT NULL, - `cplusInvoiceType477Fk` int(10) unsigned NOT NULL, + `siiTypeInvoiceOutFk` int(10) unsigned NOT NULL, `invoiceCorrectionTypeFk` int(11) NOT NULL DEFAULT 3, PRIMARY KEY (`correctingFk`), KEY `correctedFk_idx` (`correctedFk`), KEY `invoiceCorrection_ibfk_1_idx` (`cplusRectificationTypeFk`), - KEY `cplusInvoiceTyoeFk_idx` (`cplusInvoiceType477Fk`), + KEY `cplusInvoiceTyoeFk_idx` (`siiTypeInvoiceOutFk`), KEY `invoiceCorrectionTypeFk_idx` (`invoiceCorrectionTypeFk`), CONSTRAINT `corrected_fk` FOREIGN KEY (`correctedFk`) REFERENCES `invoiceOut` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `correcting_fk` FOREIGN KEY (`correctingFk`) REFERENCES `invoiceOut` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `cplusInvoiceTyoeFk` FOREIGN KEY (`cplusInvoiceType477Fk`) REFERENCES `cplusInvoiceType477` (`id`) ON UPDATE CASCADE, + CONSTRAINT `cplusInvoiceTyoeFk` FOREIGN KEY (`siiTypeInvoiceOutFk`) REFERENCES `siiTypeInvoiceOut` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceCorrectionType_Fk33` FOREIGN KEY (`invoiceCorrectionTypeFk`) REFERENCES `invoiceCorrectionType` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceCorrection_ibfk_1` FOREIGN KEY (`cplusRectificationTypeFk`) REFERENCES `cplusRectificationType` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Relacion entre las facturas rectificativas y las rectificadas.'; @@ -30130,7 +30130,7 @@ CREATE TABLE `invoiceOut` ( `companyFk` int(10) unsigned NOT NULL DEFAULT 442, `hasPdf` tinyint(3) unsigned NOT NULL DEFAULT 0, `booked` date DEFAULT NULL, - `cplusInvoiceType477Fk` int(10) unsigned NOT NULL DEFAULT 1, + `siiTypeInvoiceOutFk` int(10) unsigned NOT NULL DEFAULT 1, `cplusTaxBreakFk` int(10) unsigned NOT NULL DEFAULT 1, `cplusSubjectOpFk` int(10) unsigned NOT NULL DEFAULT 1, `cplusTrascendency477Fk` int(10) unsigned NOT NULL DEFAULT 1, @@ -30140,13 +30140,13 @@ CREATE TABLE `invoiceOut` ( KEY `Id_Cliente` (`clientFk`), KEY `empresa_id` (`companyFk`), KEY `Fecha` (`issued`), - KEY `Facturas_ibfk_2_idx` (`cplusInvoiceType477Fk`), + KEY `Facturas_ibfk_2_idx` (`siiTypeInvoiceOutFk`), KEY `Facturas_ibfk_3_idx` (`cplusSubjectOpFk`), KEY `Facturas_ibfk_4_idx` (`cplusTaxBreakFk`), KEY `Facturas_ibfk_5_idx` (`cplusTrascendency477Fk`), KEY `Facturas_idx_Vencimiento` (`dued`), KEY `invoiceOut_serial` (`serial`), - CONSTRAINT `invoiceOut_ibfk_2` FOREIGN KEY (`cplusInvoiceType477Fk`) REFERENCES `cplusInvoiceType477` (`id`) ON UPDATE CASCADE, + CONSTRAINT `invoiceOut_ibfk_2` FOREIGN KEY (`siiTypeInvoiceOutFk`) REFERENCES `siiTypeInvoiceOut` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceOut_ibfk_3` FOREIGN KEY (`cplusSubjectOpFk`) REFERENCES `cplusSubjectOp` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceOut_ibfk_4` FOREIGN KEY (`cplusTaxBreakFk`) REFERENCES `cplusTaxBreak` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceOut_serial` FOREIGN KEY (`serial`) REFERENCES `invoiceOutSerial` (`code`), @@ -30308,7 +30308,7 @@ CREATE TABLE `invoiceOutSerial` ( `isTaxed` tinyint(1) NOT NULL DEFAULT 1, `taxAreaFk` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'NATIONAL', `isCEE` tinyint(1) NOT NULL DEFAULT 0, - `cplusInvoiceType477Fk` int(10) unsigned DEFAULT 1, + `siiTypeInvoiceOutFk` int(10) unsigned DEFAULT 1, `footNotes` longtext DEFAULT NULL, `isRefEditable` tinyint(4) NOT NULL DEFAULT 0, `type` enum('global','quick') DEFAULT NULL, @@ -58288,7 +58288,7 @@ BEGIN io.cplusTrascendency477Fk AS TIPOCLAVE, io.cplusTaxBreakFk AS TIPOEXENCI, io.cplusSubjectOpFk AS TIPONOSUJE, - io.cplusInvoiceType477Fk AS TIPOFACT, + io.siiTypeInvoiceOutFk AS TIPOFACT, ic.cplusRectificationTypeFk AS TIPORECTIF, io.companyFk, RIGHT(io.ref, LENGTH(io.ref) - 1) AS invoiceNum, @@ -58868,7 +58868,7 @@ BEGIN clientFk, dued, companyFk, - cplusInvoiceType477Fk + siiTypeInvoiceOutFk ) SELECT 1, diff --git a/db/export-data.sh b/db/export-data.sh index 7d346b235e..a516992d34 100755 --- a/db/export-data.sh +++ b/db/export-data.sh @@ -46,7 +46,7 @@ TABLES=( bookingPlanner businessType cplusInvoiceType472 - cplusInvoiceType477 + siiTypeInvoiceOut cplusRectificationType cplusSubjectOp cplusTaxBreak diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js index 04f6df2995..800a4ea835 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js @@ -27,7 +27,7 @@ describe('InvoiceOut tranferInvoice()', () => { ref: 'T4444444', newClientFk: 1, cplusRectificationId: 1, - cplusInvoiceType477Id: 1, + siiTypeInvoiceOutId: 1, invoiceCorrectionTypeId: 1 }; ctx.args = args; @@ -52,7 +52,7 @@ describe('InvoiceOut tranferInvoice()', () => { ref: 'T1111111', newClientFk: 1101, cplusRectificationId: 1, - cplusInvoiceType477Id: 1, + siiTypeInvoiceOutId: 1, invoiceCorrectionTypeId: 1 }; ctx.args = args; diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js index 8a0609b8d2..dde535c998 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js @@ -27,7 +27,7 @@ module.exports = Self => { required: true }, { - arg: 'cplusInvoiceType477Id', + arg: 'siiTypeInvoiceOutId', type: 'number', required: true }, @@ -93,7 +93,7 @@ module.exports = Self => { correctingFk: invoiceId, correctedFk: args.id, cplusRectificationTypeFk: args.cplusRectificationId, - cplusInvoiceType477Fk: args.cplusInvoiceType477Id, + siiTypeInvoiceOutFk: args.siiTypeInvoiceOutId, invoiceCorrectionTypeFk: args.invoiceCorrectionTypeId }, myOptions); diff --git a/modules/invoiceOut/back/model-config.json b/modules/invoiceOut/back/model-config.json index 23246893b4..9c7512429f 100644 --- a/modules/invoiceOut/back/model-config.json +++ b/modules/invoiceOut/back/model-config.json @@ -41,7 +41,7 @@ "InvoiceCorrection": { "dataSource": "vn" }, - "CplusInvoiceType477": { + "SiiTypeInvoiceOut": { "dataSource": "vn" } } diff --git a/modules/invoiceOut/back/models/cplus-invoice-type-477.json b/modules/invoiceOut/back/models/cplus-invoice-type-477.json index 840a9a7e4e..17b3126178 100644 --- a/modules/invoiceOut/back/models/cplus-invoice-type-477.json +++ b/modules/invoiceOut/back/models/cplus-invoice-type-477.json @@ -1,9 +1,9 @@ { - "name": "CplusInvoiceType477", + "name": "SiiTypeInvoiceOut", "base": "VnModel", "options": { "mysql": { - "table": "cplusInvoiceType477" + "table": "siiTypeInvoiceOut" } }, "properties": { @@ -16,4 +16,4 @@ "type": "string" } } -} \ No newline at end of file +} diff --git a/modules/invoiceOut/back/models/invoice-correction.json b/modules/invoiceOut/back/models/invoice-correction.json index 48bd172a6d..43e4f07ef5 100644 --- a/modules/invoiceOut/back/models/invoice-correction.json +++ b/modules/invoiceOut/back/models/invoice-correction.json @@ -18,11 +18,11 @@ "cplusRectificationTypeFk": { "type": "number" }, - "cplusInvoiceType477Fk": { + "siiTypeInvoiceOutFk": { "type": "number" }, "invoiceCorrectionTypeFk": { "type": "number" } } -} \ No newline at end of file +} diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index 7d465f4ea5..0052f0c037 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -6,8 +6,8 @@
+ url="SiiTypeInvoiceOuts" + data="siiTypeInvoiceOut"> Transfer invoice to... @@ -223,15 +223,15 @@ - - \ No newline at end of file + diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index 7d2644158e..d3862a753c 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -132,7 +132,7 @@ class Controller extends Section { ref: this.invoiceOut.ref, newClientFk: this.invoiceOut.client.id, cplusRectificationId: this.cplusRectificationType, - cplusInvoiceType477Id: this.cplusInvoiceType477, + siiTypeInvoiceOutId: this.siiTypeInvoiceOut, invoiceCorrectionTypeId: this.invoiceCorrectionType }; this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => { From add3a81032aae8ecfa41e3fad37179c6b1dacac4 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 15 Nov 2023 09:29:26 +0100 Subject: [PATCH 222/449] refs #6434 feat: remove recursively fn --- back/methods/vn-user/sign-in.js | 2 ++ back/models/vn-user.js | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/back/methods/vn-user/sign-in.js b/back/methods/vn-user/sign-in.js index 78d74b147f..e51cf8d8ee 100644 --- a/back/methods/vn-user/sign-in.js +++ b/back/methods/vn-user/sign-in.js @@ -51,7 +51,9 @@ module.exports = Self => { if (vnUser.twoFactor) throw new ForbiddenError(null, 'REQUIRES_2FA'); + const validateLogin = await Self.validateLogin(user, password); + await Self.app.models.SignInLog.create({ id: validateLogin.token, userFk: vnUser.id, diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 5c6e4a30f7..00f5cd0b87 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -132,8 +132,6 @@ module.exports = function(Self) { throw new UserError('Try again'); } - const userCheck = await Self.app.models.VnUser.findOne({where: {name: user}}); - if (userToken.id != userCheck.id) await Self.validateLogin(user, password); try { await Self.app.models.Account.sync(userToken.name, password); } catch (err) { From 4061241650352d430082a5fdf1f29000df51df96 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 15 Nov 2023 09:37:03 +0100 Subject: [PATCH 223/449] refs #6434 feat: create signInLog table --- db/changes/234801/00-createSignInLogTable.sql | 19 ++++++++++ modules/account/back/model-config.json | 3 ++ modules/account/back/models/sign_in-log.json | 35 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 db/changes/234801/00-createSignInLogTable.sql create mode 100644 modules/account/back/models/sign_in-log.json diff --git a/db/changes/234801/00-createSignInLogTable.sql b/db/changes/234801/00-createSignInLogTable.sql new file mode 100644 index 0000000000..977de46463 --- /dev/null +++ b/db/changes/234801/00-createSignInLogTable.sql @@ -0,0 +1,19 @@ + + +-- +-- Table structure for table `signInLog` +-- + +DROP TABLE IF EXISTS `account`.`signInLog`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `account`.`signInLog` ( + `id` varchar(10) NOT NULL , + `userFk` int(10) unsigned DEFAULT NULL, + `creationDate` timestamp NULL DEFAULT current_timestamp(), + `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + PRIMARY KEY (`id`), + KEY `userFk` (`userFk`), + CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +); + diff --git a/modules/account/back/model-config.json b/modules/account/back/model-config.json index a4eb9fa571..b4bd6dbafd 100644 --- a/modules/account/back/model-config.json +++ b/modules/account/back/model-config.json @@ -35,6 +35,9 @@ "SambaConfig": { "dataSource": "vn" }, + "SignInLog": { + "dataSource": "vn" + }, "Sip": { "dataSource": "vn" }, diff --git a/modules/account/back/models/sign_in-log.json b/modules/account/back/models/sign_in-log.json new file mode 100644 index 0000000000..df9ad8153e --- /dev/null +++ b/modules/account/back/models/sign_in-log.json @@ -0,0 +1,35 @@ +{ + "name": "SignInLog", + "base": "VnModel", + "options": { + "mysql": { + "table": "account.signInLog" + } + }, + "properties": { + "id": { + "id": true, + "type": "string", + "forceId": false + }, + "creationDate": { + "type": "date" + }, + "userFk": { + "type": "number" + }, + "ip": { + "type": "string" + } + }, + "relations": { + "user": { + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "userFk" + } + }, + "scope": { + "order": ["creationDate DESC", "id DESC"] + } +} From e25b7d0a12638801f7ab21eb80b70c252fdff668 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 15 Nov 2023 09:39:51 +0100 Subject: [PATCH 224/449] refs #6434 feat: show error for wrong login --- back/models/vn-user.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index de5bf7b63e..00f5cd0b87 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -2,6 +2,7 @@ const vnModel = require('vn-loopback/common/models/vn-model'); const {Email} = require('vn-print'); const ForbiddenError = require('vn-loopback/util/forbiddenError'); const LoopBackContext = require('loopback-context'); +const UserError = require('vn-loopback/util/user-error'); module.exports = function(Self) { vnModel(Self); @@ -121,10 +122,16 @@ module.exports = function(Self) { }); Self.validateLogin = async function(user, password) { - let loginInfo = Object.assign({password}, Self.userUses(user)); - token = await Self.login(loginInfo, 'user'); + const loginInfo = Object.assign({password}, Self.userUses(user)); + const token = await Self.login(loginInfo, 'user'); const userToken = await token.user.get(); + + if (userToken.username !== user) { + console.error('ERROR!!! - Signin with other user', userToken, user); + throw new UserError('Try again'); + } + try { await Self.app.models.Account.sync(userToken.name, password); } catch (err) { From 11352798f09da689ab275f670ce2c55e426f00b1 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 15 Nov 2023 09:41:12 +0100 Subject: [PATCH 225/449] refs #6434 feat: save token in db for each login --- back/methods/vn-user/sign-in.js | 9 +++++++-- loopback/locale/es.json | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/back/methods/vn-user/sign-in.js b/back/methods/vn-user/sign-in.js index b9e0d2f705..25f708b8e5 100644 --- a/back/methods/vn-user/sign-in.js +++ b/back/methods/vn-user/sign-in.js @@ -49,8 +49,13 @@ module.exports = Self => { if (vnUser.twoFactor) throw new ForbiddenError(null, 'REQUIRES_2FA'); } - - return Self.validateLogin(user, password); + const validateLogin = await Self.validateLogin(user, password); + await Self.app.models.SignInLog.create({ + id: validateLogin.token, + userFk: vnUser.id, + ip: ctx.req.ip + }); + return validateLogin; }; Self.passExpired = async vnUser => { diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 3cc9a96278..da37d4005f 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -321,9 +321,10 @@ "Select a different client": "Seleccione un cliente distinto", "Fill all the fields": "Rellene todos los campos", "The response is not a PDF": "La respuesta no es un PDF", - "Ticket without Route": "Ticket sin ruta", "Booking completed": "Reserva completada", "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mímina", - "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina" + "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina", + "The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada", + "User disabled": "Usuario desactivado" } From 4d677ccc899faec445f423339e937e71e4014d25 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 15 Nov 2023 10:02:48 +0100 Subject: [PATCH 226/449] refs #6434 perf: rename folder db/changes version --- db/changes/{234801 => 234603}/00-createSignInLogTable.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{234801 => 234603}/00-createSignInLogTable.sql (100%) diff --git a/db/changes/234801/00-createSignInLogTable.sql b/db/changes/234603/00-createSignInLogTable.sql similarity index 100% rename from db/changes/234801/00-createSignInLogTable.sql rename to db/changes/234603/00-createSignInLogTable.sql From 3f7663da976c32d4b171311e4ce7800652be038d Mon Sep 17 00:00:00 2001 From: jgallego Date: Wed, 15 Nov 2023 10:09:04 +0100 Subject: [PATCH 227/449] feat: refs #6275 crea back etExpeditionSummary --- .vscode/settings.json | 3 + .../methods/route/getExpeditionSummary.js | 64 +++++++++++++++++++ modules/route/back/models/route.js | 3 +- .../ticket/back/models/expedition-state.json | 7 ++ modules/ticket/back/models/expedition.json | 2 +- 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 modules/route/back/methods/route/getExpeditionSummary.js diff --git a/.vscode/settings.json b/.vscode/settings.json index 05d23f3bbc..020c3ae7cc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,5 +10,8 @@ "eslint.format.enable": true, "[javascript]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint" + }, + "[json]": { + "editor.defaultFormatter": "vscode.json-language-features" } } diff --git a/modules/route/back/methods/route/getExpeditionSummary.js b/modules/route/back/methods/route/getExpeditionSummary.js new file mode 100644 index 0000000000..d35ab86115 --- /dev/null +++ b/modules/route/back/methods/route/getExpeditionSummary.js @@ -0,0 +1,64 @@ +module.exports = Self => { + Self.remoteMethod('getExpeditionSummary', { + description: 'Get summary of expeditions for a given route', + accepts: [ + { + arg: 'routeFk', + type: 'number', + required: true, + description: 'Foreign key for Route' + } + ], + returns: { + type: 'object', + root: true + }, + http: { + path: '/getExpeditionSummary', + verb: 'get' + } + }); + + Self.getExpeditionSummary = async(routeFk, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const query = ` + SELECT routeFk, + addressFk, + SUM(total) total, + SUM(delivery) delivery, + SUM(lost) lost, + SUM(delivered) delivered, + GROUP_CONCAT(totalPacking ORDER BY total DESC SEPARATOR ' ') itemPackingType + FROM ( + SELECT r.id AS routeFk, + t.addressFk, + CONCAT (IFNULL(e.itemPackingTypeFk,'-'), '', COUNT(*)) totalPacking, + COUNT(*) total, + SUM(est.code = 'ON DELIVERY') delivery, + SUM(est.code = 'LOST') lost, + SUM(est.code = 'DELIVERED') delivered, + t.priority + FROM vn.ticket t + JOIN vn.route r ON r.id = t.routeFk + JOIN vn.expedition e ON e.ticketFk = t.id + LEFT JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk + JOIN vn.agencyMode am ON am.id = r.agencyModeFk + JOIN vn.agency ag ON ag.id = am.agencyFk + LEFT JOIN vn.userConfig uc ON uc.userFk = account.myUser_getId() + WHERE (r.created = util.VN_CURDATE() OR r.created = TIMESTAMPADD(day,-1, util.VN_CURDATE())) + AND t.routeFk = ? + GROUP BY t.addressFk, e.itemPackingTypeFk + ) sub + GROUP BY addressFk + ORDER BY priority DESC + `; + + const results = await Self.rawSql(query, [routeFk], options); + return results; + }; +}; + diff --git a/modules/route/back/models/route.js b/modules/route/back/models/route.js index 65fa43ab54..53440fc232 100644 --- a/modules/route/back/models/route.js +++ b/modules/route/back/models/route.js @@ -17,6 +17,7 @@ module.exports = Self => { require('../methods/route/cmr')(Self); require('../methods/route/getExternalCmrs')(Self); require('../methods/route/downloadCmrsZip')(Self); + require('../methods/route/getExpeditionSummary')(Self); Self.validate('kmStart', validateDistance, { message: 'Distance must be lesser than 1000' @@ -31,5 +32,5 @@ module.exports = Self => { const routeMaxKm = 1000; if (routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd) err(); - }; + } }; diff --git a/modules/ticket/back/models/expedition-state.json b/modules/ticket/back/models/expedition-state.json index 262eb2e385..eda0f79fda 100644 --- a/modules/ticket/back/models/expedition-state.json +++ b/modules/ticket/back/models/expedition-state.json @@ -24,5 +24,12 @@ "userFk": { "type": "number" } + }, + "relations": { + "expeditionStateType": { + "type": "belongsTo", + "model": "ExpeditionStateType", + "foreignKey": "typeFk" + } } } diff --git a/modules/ticket/back/models/expedition.json b/modules/ticket/back/models/expedition.json index e32a3b23d1..08950d0d16 100644 --- a/modules/ticket/back/models/expedition.json +++ b/modules/ticket/back/models/expedition.json @@ -30,7 +30,7 @@ }, "agencyMode": { "type": "belongsTo", - "model": "agency-mode", + "model": "AgencyMode", "foreignKey": "agencyModeFk" }, "worker": { From f7b088297874d1a15aeb0175bb5cd1cf486da70e Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 15 Nov 2023 11:50:56 +0100 Subject: [PATCH 228/449] refs #6434 feat: remove forceId property --- modules/account/back/models/sign_in-log.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/account/back/models/sign_in-log.json b/modules/account/back/models/sign_in-log.json index df9ad8153e..44575b0137 100644 --- a/modules/account/back/models/sign_in-log.json +++ b/modules/account/back/models/sign_in-log.json @@ -9,8 +9,7 @@ "properties": { "id": { "id": true, - "type": "string", - "forceId": false + "type": "string" }, "creationDate": { "type": "date" From 692c5eb164279ae0a964bbceb70007f61db46fbc Mon Sep 17 00:00:00 2001 From: sergiodt Date: Wed, 15 Nov 2023 12:38:08 +0100 Subject: [PATCH 229/449] refs #5652 fix: setVisibleDiscard add parameter null --- modules/item/back/methods/item/setVisibleDiscard.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/item/back/methods/item/setVisibleDiscard.js b/modules/item/back/methods/item/setVisibleDiscard.js index 08cc507c32..16cef6baf7 100644 --- a/modules/item/back/methods/item/setVisibleDiscard.js +++ b/modules/item/back/methods/item/setVisibleDiscard.js @@ -20,8 +20,7 @@ module.exports = Self => { }, { arg: 'addressFk', - type: 'Number', - required: true, + type: 'Any', description: 'The address id' }], http: { From 89967b85383fd53c5232b1a0cfc92b670ab6bf56 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 15 Nov 2023 13:16:31 +0100 Subject: [PATCH 230/449] fix(workerDescriptor): show account button --- modules/worker/front/descriptor/index.html | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/worker/front/descriptor/index.html b/modules/worker/front/descriptor/index.html index aa6b803003..8290e2a155 100644 --- a/modules/worker/front/descriptor/index.html +++ b/modules/worker/front/descriptor/index.html @@ -38,7 +38,7 @@ + > @@ -61,8 +61,6 @@
@@ -75,13 +73,13 @@ - - Date: Wed, 15 Nov 2023 13:49:41 +0100 Subject: [PATCH 231/449] refs #6434 feat: create signInLog table --- db/changes/234202/00-createSignInLogTable.sql | 19 +++++++++++ modules/account/back/model-config.json | 3 ++ modules/account/back/models/sign_in-log.json | 34 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 db/changes/234202/00-createSignInLogTable.sql create mode 100644 modules/account/back/models/sign_in-log.json diff --git a/db/changes/234202/00-createSignInLogTable.sql b/db/changes/234202/00-createSignInLogTable.sql new file mode 100644 index 0000000000..977de46463 --- /dev/null +++ b/db/changes/234202/00-createSignInLogTable.sql @@ -0,0 +1,19 @@ + + +-- +-- Table structure for table `signInLog` +-- + +DROP TABLE IF EXISTS `account`.`signInLog`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `account`.`signInLog` ( + `id` varchar(10) NOT NULL , + `userFk` int(10) unsigned DEFAULT NULL, + `creationDate` timestamp NULL DEFAULT current_timestamp(), + `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + PRIMARY KEY (`id`), + KEY `userFk` (`userFk`), + CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +); + diff --git a/modules/account/back/model-config.json b/modules/account/back/model-config.json index a4eb9fa571..b4bd6dbafd 100644 --- a/modules/account/back/model-config.json +++ b/modules/account/back/model-config.json @@ -35,6 +35,9 @@ "SambaConfig": { "dataSource": "vn" }, + "SignInLog": { + "dataSource": "vn" + }, "Sip": { "dataSource": "vn" }, diff --git a/modules/account/back/models/sign_in-log.json b/modules/account/back/models/sign_in-log.json new file mode 100644 index 0000000000..44575b0137 --- /dev/null +++ b/modules/account/back/models/sign_in-log.json @@ -0,0 +1,34 @@ +{ + "name": "SignInLog", + "base": "VnModel", + "options": { + "mysql": { + "table": "account.signInLog" + } + }, + "properties": { + "id": { + "id": true, + "type": "string" + }, + "creationDate": { + "type": "date" + }, + "userFk": { + "type": "number" + }, + "ip": { + "type": "string" + } + }, + "relations": { + "user": { + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "userFk" + } + }, + "scope": { + "order": ["creationDate DESC", "id DESC"] + } +} From 0a31968cc7ad7b6883ec184dd5e3457760072807 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 15 Nov 2023 13:49:54 +0100 Subject: [PATCH 232/449] refs #6434 feat: show error for wrong login --- back/models/vn-user.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 712ed7d167..62bdfa2da2 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -2,6 +2,7 @@ const vnModel = require('vn-loopback/common/models/vn-model'); const {Email} = require('vn-print'); const ForbiddenError = require('vn-loopback/util/forbiddenError'); const LoopBackContext = require('loopback-context'); +const UserError = require('vn-loopback/util/user-error'); module.exports = function(Self) { vnModel(Self); @@ -125,10 +126,16 @@ module.exports = function(Self) { }); Self.validateLogin = async function(user, password) { - let loginInfo = Object.assign({password}, Self.userUses(user)); - token = await Self.login(loginInfo, 'user'); + const loginInfo = Object.assign({password}, Self.userUses(user)); + const token = await Self.login(loginInfo, 'user'); const userToken = await token.user.get(); + + if (userToken.username !== user) { + console.error('ERROR!!! - Signin with other user', userToken, user); + throw new UserError('Try again'); + } + try { await Self.app.models.Account.sync(userToken.name, password); } catch (err) { From 58edcb9055c56b84f08384aa135119b608158518 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 15 Nov 2023 13:50:06 +0100 Subject: [PATCH 233/449] refs #6434 feat: save token in db for each login --- back/methods/vn-user/sign-in.js | 9 +++++++-- loopback/locale/es.json | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/back/methods/vn-user/sign-in.js b/back/methods/vn-user/sign-in.js index b9e0d2f705..25f708b8e5 100644 --- a/back/methods/vn-user/sign-in.js +++ b/back/methods/vn-user/sign-in.js @@ -49,8 +49,13 @@ module.exports = Self => { if (vnUser.twoFactor) throw new ForbiddenError(null, 'REQUIRES_2FA'); } - - return Self.validateLogin(user, password); + const validateLogin = await Self.validateLogin(user, password); + await Self.app.models.SignInLog.create({ + id: validateLogin.token, + userFk: vnUser.id, + ip: ctx.req.ip + }); + return validateLogin; }; Self.passExpired = async vnUser => { diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 4b297144fa..ce56a67291 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -318,9 +318,10 @@ "Social name should be uppercase": "La razón social debe ir en mayúscula", "Street should be uppercase": "La dirección fiscal debe ir en mayúscula", "The response is not a PDF": "La respuesta no es un PDF", - "Ticket without Route": "Ticket sin ruta", "Booking completed": "Reserva completada", "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mímina", - "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina" + "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina", + "The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada", + "User disabled": "Usuario desactivado" } From 13720291b2802826ba55a06c2dc8ee0aa778e6d4 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 15 Nov 2023 15:18:02 +0100 Subject: [PATCH 234/449] refs #6434 perf: remove unique in token column --- modules/account/back/models/sign_in-log.json | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/account/back/models/sign_in-log.json b/modules/account/back/models/sign_in-log.json index 44575b0137..3cd971cb87 100644 --- a/modules/account/back/models/sign_in-log.json +++ b/modules/account/back/models/sign_in-log.json @@ -8,7 +8,6 @@ }, "properties": { "id": { - "id": true, "type": "string" }, "creationDate": { From 4896be51ef6516cf8ef430fa0d4ae475b5c6e250 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 16 Nov 2023 07:27:42 +0100 Subject: [PATCH 235/449] fix: translation --- loopback/locale/es.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 4b297144fa..74dc2f15ad 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -321,6 +321,6 @@ "Ticket without Route": "Ticket sin ruta", "Booking completed": "Reserva completada", "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación", - "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mímina", - "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mímina" + "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", + "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima" } From bfd6e1f39843abb02694fa2ebdb52e95df4f2bd4 Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 16 Nov 2023 08:29:00 +0100 Subject: [PATCH 236/449] refactor: refs #4502 Deleted zoneEstimatedDelivery --- .../back/methods/sales-monitor/salesFilter.js | 71 ++++++++----- modules/order/back/methods/order/filter.js | 99 ++++++++++++------- modules/zone/back/model-config.json | 3 - .../back/models/zone-estimated-delivery.json | 44 --------- 4 files changed, 112 insertions(+), 105 deletions(-) delete mode 100644 modules/zone/back/models/zone-estimated-delivery.json diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 693ae122fc..85945a57d6 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -163,17 +163,14 @@ module.exports = Self => { const stmts = []; let stmt; - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.filter'); - stmts.push(`SET @_optimizer_search_depth = @@optimizer_search_depth`); stmts.push(`SET SESSION optimizer_search_depth = 0`); - stmt = new ParameterizedSQL( - `CREATE TEMPORARY TABLE tmp.filter + stmt = new ParameterizedSQL(` + CREATE OR REPLACE TEMPORARY TABLE tmp.filter (PRIMARY KEY (id)) ENGINE = MEMORY - SELECT - t.id, + SELECT t.id, t.shipped, CAST(DATE(t.shipped) AS CHAR) AS shippedDate, t.nickname, @@ -183,27 +180,27 @@ module.exports = Self => { t.clientFk, t.totalWithoutVat, t.totalWithVat, - io.id AS invoiceOutId, + io.id invoiceOutId, a.provinceFk, - p.name AS province, - w.name AS warehouse, - am.name AS agencyMode, - am.id AS agencyModeFk, - st.name AS state, - wk.lastName AS salesPerson, - ts.stateFk AS stateFk, - ts.alertLevel AS alertLevel, - ts.code AS alertLevelCode, - u.name AS userName, + p.name province, + w.name warehouse, + am.name agencyMode, + am.id agencyModeFk, + st.name state, + wk.lastName salesPerson, + ts.stateFk stateFk, + ts.alertLevel alertLevel, + ts.code alertLevelCode, + u.name userName, c.salesPersonFk, c.credit, - z.hour AS zoneLanding, - z.name AS zoneName, - z.id AS zoneFk, + z.hour zoneLanding, + z.name zoneName, + z.id zoneFk, st.classColor, - TIME_FORMAT(t.shipped, '%H:%i') AS preparationHour, - TIME_FORMAT(z.hour, '%H:%i') AS theoreticalhour, - TIME_FORMAT(zed.etc, '%H:%i') AS practicalHour + TIME_FORMAT(t.shipped, '%H:%i') preparationHour, + TIME_FORMAT(z.hour, '%H:%i') theoreticalhour, + TIME_FORMAT(zed.etc, '%H:%i') practicalHour FROM ticket t LEFT JOIN invoiceOut io ON t.refFk = io.ref LEFT JOIN zone z ON z.id = t.zoneFk @@ -216,7 +213,33 @@ module.exports = Self => { LEFT JOIN client c ON c.id = t.clientFk LEFT JOIN worker wk ON wk.id = c.salesPersonFk LEFT JOIN account.user u ON u.id = wk.id - LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`); + LEFT JOIN ( + SELECT zoneFk, + CAST(zoneHour + remainingVolume * 60 / speed AS time) etc + FROM ( + SELECT t.zoneFk, + IFNULL(zc.hour, z.hour) zoneHour, + SUM(IF(al.hasToRecalcPrice, sv.volume, 0)) remainingVolume, + GREATEST(IFNULL(lhp.m3, 0), IFNULL(dl.minSpeed, 0)) speed + FROM ticket t + JOIN ticketStateToday tst ON tst.ticket = t.id + JOIN state s ON s.id = tst.state + JOIN saleVolume sv ON sv.ticketFk = t.id + LEFT JOIN lastHourProduction lhp ON lhp.warehouseFk = t.warehouseFk + JOIN warehouse w ON w.id = t.warehouseFk + JOIN warehouseAlias wa ON wa.id = w.aliasFk + STRAIGHT_JOIN zone z ON z.id = t.zoneFk + LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk + AND zc.dated = util.VN_CURDATE() + LEFT JOIN cache.departure_limit dl ON dl.warehouse_id = t.warehouseFk + AND dl.fecha = util.VN_CURDATE() + JOIN alertLevel al ON al.id = s.alertLevel + WHERE w.hasProduction + AND DATE(t.shipped) = util.VN_CURDATE() + GROUP BY t.zoneFk + ) sub + ) zed ON zed.zoneFk = t.zoneFk` + ); if (args.orderFk) { stmt.merge({ diff --git a/modules/order/back/methods/order/filter.js b/modules/order/back/methods/order/filter.js index 44d8ccb107..27484acb92 100644 --- a/modules/order/back/methods/order/filter.js +++ b/modules/order/back/methods/order/filter.js @@ -140,40 +140,71 @@ module.exports = Self => { const stmts = []; let stmt; - stmt = new ParameterizedSQL( - `CREATE OR REPLACE TEMPORARY TABLE tmp.filter - (INDEX (id)) - ENGINE = MEMORY - SELECT - o.id, - o.total, - o.date_send landed, - o.date_make created, - o.customer_id clientFk, - o.agency_id agencyModeFk, - o.address_id addressFk, - o.company_id companyFk, - o.source_app sourceApp, - o.confirmed isConfirmed, - c.name clientName, - c.salesPersonFk, - u.nickname workerNickname, - u.name name, - co.code companyCode, - zed.zoneFk, - zed.hourTheoretical, - zed.hourEffective, - am.name AS agencyName - FROM hedera.order o - LEFT JOIN address a ON a.id = o.address_id - LEFT JOIN agencyMode am ON am.id = o.agency_id - LEFT JOIN client c ON c.id = o.customer_id - LEFT JOIN worker wk ON wk.id = c.salesPersonFk - LEFT JOIN account.user u ON u.id = wk.id - LEFT JOIN company co ON co.id = o.company_id - LEFT JOIN orderTicket ot ON ot.orderFk = o.id - LEFT JOIN ticket t ON t.id = ot.ticketFk - LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`); + stmt = new ParameterizedSQL(` + CREATE OR REPLACE TEMPORARY TABLE tmp.filter + (INDEX (id)) + ENGINE = MEMORY + SELECT o.id, + o.total, + o.date_send landed, + o.date_make created, + o.customer_id clientFk, + o.agency_id agencyModeFk, + o.address_id addressFk, + o.company_id companyFk, + o.source_app sourceApp, + o.confirmed isConfirmed, + c.name clientName, + c.salesPersonFk, + u.nickname workerNickname, + u.name name, + co.code companyCode, + zed.zoneFk, + zed.hourTheoretical, + zed.hourEffective, + am.name agencyName + FROM hedera.order o + LEFT JOIN address a ON a.id = o.address_id + LEFT JOIN agencyMode am ON am.id = o.agency_id + LEFT JOIN client c ON c.id = o.customer_id + LEFT JOIN worker wk ON wk.id = c.salesPersonFk + LEFT JOIN account.user u ON u.id = wk.id + LEFT JOIN company co ON co.id = o.company_id + LEFT JOIN orderTicket ot ON ot.orderFk = o.id + LEFT JOIN ticket t ON t.id = ot.ticketFk + LEFT JOIN ( + SELECT zoneFk, + CAST( + util.VN_CURDATE() + + INTERVAL HOUR(zoneHour) * 60 + MINUTE(zoneHour) MINUTE + AS time + ) hourTheoretical, + CAST(zoneHour + remainingVolume * 60 / speed AS time) hourEffective + FROM ( + SELECT t.zoneFk, + IFNULL(zc.hour, z.hour) zoneHour, + CAST(SUM(sv.volume) AS DECIMAL(5, 1)) totalVolume, + SUM(IF(al.hasToRecalcPrice, sv.volume, 0)) remainingVolume, + GREATEST(IFNULL(lhp.m3, 0), IFNULL(dl.minSpeed, 0)) speed + FROM ticket t + JOIN ticketStateToday tst ON tst.ticket = t.id + JOIN state s ON s.id = tst.state + JOIN saleVolume sv ON sv.ticketFk = t.id + LEFT JOIN lastHourProduction lhp ON lhp.warehouseFk = t.warehouseFk + JOIN warehouse w ON w.id = t.warehouseFk + JOIN warehouseAlias wa ON wa.id = w.aliasFk + STRAIGHT_JOIN zone z ON z.id = t.zoneFk + LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk + AND zc.dated = util.VN_CURDATE() + LEFT JOIN cache.departure_limit dl ON dl.warehouse_id = t.warehouseFk + AND dl.fecha = util.VN_CURDATE() + JOIN alertLevel al ON al.id = s.alertLevel + WHERE w.hasProduction + AND DATE(t.shipped) = util.VN_CURDATE() + GROUP BY t.zoneFk + ) sub + ) zed ON zed.zoneFk = t.zoneFk + `); stmt.merge(conn.makeWhere(filter.where)); stmt.merge(`GROUP BY id`); diff --git a/modules/zone/back/model-config.json b/modules/zone/back/model-config.json index 261a89902a..43d2cb570a 100644 --- a/modules/zone/back/model-config.json +++ b/modules/zone/back/model-config.json @@ -35,9 +35,6 @@ "ZoneWarehouse": { "dataSource": "vn" }, - "ZoneEstimatedDelivery": { - "dataSource": "vn" - }, "ZoneLog": { "dataSource": "vn" } diff --git a/modules/zone/back/models/zone-estimated-delivery.json b/modules/zone/back/models/zone-estimated-delivery.json deleted file mode 100644 index 399de8f58a..0000000000 --- a/modules/zone/back/models/zone-estimated-delivery.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "ZoneEstimatedDelivery", - "base": "VnModel", - "options": { - "mysql": { - "table": "zoneEstimatedDelivery" - } - }, - "properties": { - "zoneFk": { - "id": true, - "type": "number" - }, - "hourTheoretical": { - "type": "date" - }, - "totalVolume": { - "type": "number" - }, - "remainingVolume": { - "type": "number" - }, - "speed": { - "type": "number" - }, - "hourEffective": { - "type": "date" - }, - "minutesLess": { - "type": "date" - }, - "etc": { - "type": "date" - } - - }, - "relations": { - "zone": { - "type": "belongsTo", - "model": "Zone", - "foreignKey": "zoneFk" - } - } -} \ No newline at end of file From c6b5d7f5a4a291dbfbcdc4d6187fb92bb0052912 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 16 Nov 2023 08:30:01 +0100 Subject: [PATCH 237/449] refs #6434 feat: rename id key by token --- back/methods/vn-user/sign-in.js | 2 +- db/changes/234202/00-createSignInLogTable.sql | 2 +- modules/account/back/models/sign_in-log.json | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/back/methods/vn-user/sign-in.js b/back/methods/vn-user/sign-in.js index 25f708b8e5..9c2d568f4f 100644 --- a/back/methods/vn-user/sign-in.js +++ b/back/methods/vn-user/sign-in.js @@ -51,7 +51,7 @@ module.exports = Self => { } const validateLogin = await Self.validateLogin(user, password); await Self.app.models.SignInLog.create({ - id: validateLogin.token, + token: validateLogin.token, userFk: vnUser.id, ip: ctx.req.ip }); diff --git a/db/changes/234202/00-createSignInLogTable.sql b/db/changes/234202/00-createSignInLogTable.sql index 977de46463..6a648bb517 100644 --- a/db/changes/234202/00-createSignInLogTable.sql +++ b/db/changes/234202/00-createSignInLogTable.sql @@ -8,7 +8,7 @@ DROP TABLE IF EXISTS `account`.`signInLog`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `account`.`signInLog` ( - `id` varchar(10) NOT NULL , + `token` varchar(255) NOT NULL , `userFk` int(10) unsigned DEFAULT NULL, `creationDate` timestamp NULL DEFAULT current_timestamp(), `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, diff --git a/modules/account/back/models/sign_in-log.json b/modules/account/back/models/sign_in-log.json index 3cd971cb87..9e6df2da57 100644 --- a/modules/account/back/models/sign_in-log.json +++ b/modules/account/back/models/sign_in-log.json @@ -7,13 +7,16 @@ } }, "properties": { - "id": { - "type": "string" + "token": { + "required": true, + "type": "string", + "description": "Token's user" }, "creationDate": { - "type": "date" + "type": "date" }, "userFk": { + "required": true, "type": "number" }, "ip": { From 3c8ed3ff51c7d80551cb068095f86d044fb3037d Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 16 Nov 2023 08:30:27 +0100 Subject: [PATCH 238/449] refs #6434 feat: username.toLowerCase() --- back/models/vn-user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 62bdfa2da2..5845c2192c 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -131,7 +131,7 @@ module.exports = function(Self) { const userToken = await token.user.get(); - if (userToken.username !== user) { + if (userToken.username.toLowerCase() !== user.toLowerCase()) { console.error('ERROR!!! - Signin with other user', userToken, user); throw new UserError('Try again'); } From e73836cbdb551ee1f850955a7d99c768ede44d7c Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 16 Nov 2023 08:31:01 +0100 Subject: [PATCH 239/449] refs #6434 feat: remove primary key constraint --- db/changes/234202/00-createSignInLogTable.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/db/changes/234202/00-createSignInLogTable.sql b/db/changes/234202/00-createSignInLogTable.sql index 6a648bb517..168c7b33fa 100644 --- a/db/changes/234202/00-createSignInLogTable.sql +++ b/db/changes/234202/00-createSignInLogTable.sql @@ -12,8 +12,7 @@ CREATE TABLE `account`.`signInLog` ( `userFk` int(10) unsigned DEFAULT NULL, `creationDate` timestamp NULL DEFAULT current_timestamp(), `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - PRIMARY KEY (`id`), - KEY `userFk` (`userFk`), + CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ); From d032b3a527da098541818cde90cb600188ec4189 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 16 Nov 2023 08:42:17 +0100 Subject: [PATCH 240/449] refs #6434 perf: add description to signInLog table --- db/changes/234202/00-createSignInLogTable.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/db/changes/234202/00-createSignInLogTable.sql b/db/changes/234202/00-createSignInLogTable.sql index 168c7b33fa..918b871376 100644 --- a/db/changes/234202/00-createSignInLogTable.sql +++ b/db/changes/234202/00-createSignInLogTable.sql @@ -2,6 +2,7 @@ -- -- Table structure for table `signInLog` +-- Description: log to debug cross-login error -- DROP TABLE IF EXISTS `account`.`signInLog`; From 144b26cf4cd8f9fe17f5d4e435247930250c343c Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 16 Nov 2023 08:47:08 +0100 Subject: [PATCH 241/449] refs #6434 perf: signInLog table id column AI --- db/changes/234202/00-createSignInLogTable.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/changes/234202/00-createSignInLogTable.sql b/db/changes/234202/00-createSignInLogTable.sql index 918b871376..5253481357 100644 --- a/db/changes/234202/00-createSignInLogTable.sql +++ b/db/changes/234202/00-createSignInLogTable.sql @@ -9,11 +9,12 @@ DROP TABLE IF EXISTS `account`.`signInLog`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `account`.`signInLog` ( + id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `token` varchar(255) NOT NULL , `userFk` int(10) unsigned DEFAULT NULL, `creationDate` timestamp NULL DEFAULT current_timestamp(), `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - + KEY `userFk` (`userFk`), CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ); From 54e8e6a27d60884a86b58256a722b08ccb0f7a21 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 16 Nov 2023 09:10:45 +0100 Subject: [PATCH 242/449] refs #6417 fix(vnUser): toLowerCase --- back/models/vn-user.js | 2 +- loopback/locale/en.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 62bdfa2da2..5845c2192c 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -131,7 +131,7 @@ module.exports = function(Self) { const userToken = await token.user.get(); - if (userToken.username !== user) { + if (userToken.username.toLowerCase() !== user.toLowerCase()) { console.error('ERROR!!! - Signin with other user', userToken, user); throw new UserError('Try again'); } diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 26650175d6..9f9961f57b 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -196,6 +196,6 @@ "Negative basis of tickets: 23": "Negative basis of tickets: 23", "Booking completed": "Booking complete", "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation", - "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets" -} - + "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets", + "Try again": "Try again" +} \ No newline at end of file From 67f5be474d44956fd3e7c2f7088cf7845d855559 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 16 Nov 2023 09:21:22 +0100 Subject: [PATCH 243/449] refs #6434 perf: rename db/changes current folder --- db/changes/234603/00-createSignInLogTable.sql | 5 +++-- db/changes/{234202 => 234604}/00-createSignInLogTable.sql | 0 2 files changed, 3 insertions(+), 2 deletions(-) rename db/changes/{234202 => 234604}/00-createSignInLogTable.sql (100%) diff --git a/db/changes/234603/00-createSignInLogTable.sql b/db/changes/234603/00-createSignInLogTable.sql index 977de46463..5253481357 100644 --- a/db/changes/234603/00-createSignInLogTable.sql +++ b/db/changes/234603/00-createSignInLogTable.sql @@ -2,17 +2,18 @@ -- -- Table structure for table `signInLog` +-- Description: log to debug cross-login error -- DROP TABLE IF EXISTS `account`.`signInLog`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `account`.`signInLog` ( - `id` varchar(10) NOT NULL , + id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `token` varchar(255) NOT NULL , `userFk` int(10) unsigned DEFAULT NULL, `creationDate` timestamp NULL DEFAULT current_timestamp(), `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - PRIMARY KEY (`id`), KEY `userFk` (`userFk`), CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ); diff --git a/db/changes/234202/00-createSignInLogTable.sql b/db/changes/234604/00-createSignInLogTable.sql similarity index 100% rename from db/changes/234202/00-createSignInLogTable.sql rename to db/changes/234604/00-createSignInLogTable.sql From 9c6b59442684085d6ab3a519de1afadcb4571fb3 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 16 Nov 2023 10:04:34 +0100 Subject: [PATCH 244/449] hotFix: comment error logIn --- back/models/vn-user.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 5845c2192c..2ab97fce69 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -131,10 +131,10 @@ module.exports = function(Self) { const userToken = await token.user.get(); - if (userToken.username.toLowerCase() !== user.toLowerCase()) { - console.error('ERROR!!! - Signin with other user', userToken, user); - throw new UserError('Try again'); - } + // if (userToken.username.toLowerCase() !== user.toLowerCase()) { + // console.error('ERROR!!! - Signin with other user', userToken, user); + // throw new UserError('Try again'); + // } try { await Self.app.models.Account.sync(userToken.name, password); From 386b556216ec86e4c91a756b9f2c1e3f835c3c31 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 16 Nov 2023 10:29:57 +0100 Subject: [PATCH 245/449] refs #6434 feat: new test user signIn with email --- back/methods/vn-user/specs/sign-in.spec.js | 10 ++++++++++ back/models/vn-user.js | 13 ++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/back/methods/vn-user/specs/sign-in.spec.js b/back/methods/vn-user/specs/sign-in.spec.js index f4cad88b9c..26abe7eda1 100644 --- a/back/methods/vn-user/specs/sign-in.spec.js +++ b/back/methods/vn-user/specs/sign-in.spec.js @@ -14,6 +14,16 @@ describe('VnUser Sign-in()', () => { }; const {VnUser, AccessToken} = models; describe('when credentials are correct', () => { + it('should return the token if user uses email', async() => { + let login = await VnUser.signIn(unauthCtx, 'salesAssistant@mydomain.com', 'nightmare'); + let accessToken = await AccessToken.findById(login.token); + let ctx = {req: {accessToken: accessToken}}; + + expect(login.token).toBeDefined(); + + await VnUser.logout(ctx.req.accessToken.id); + }); + it('should return the token', async() => { let login = await VnUser.signIn(unauthCtx, 'salesAssistant', 'nightmare'); let accessToken = await AccessToken.findById(login.token); diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 2ab97fce69..bbfee4c515 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -124,17 +124,20 @@ module.exports = function(Self) { return email.send(); }); + Self.signInValidate = (user, userToken) => { + const [[key, value]] = Object.entries(Self.userUses(user)); + if (userToken[key].toLowerCase() !== value.toLowerCase()) { + console.error('ERROR!!! - Signin with other user', _userToken, _user); + throw new UserError('Try again'); + } + }; Self.validateLogin = async function(user, password) { const loginInfo = Object.assign({password}, Self.userUses(user)); const token = await Self.login(loginInfo, 'user'); const userToken = await token.user.get(); - - // if (userToken.username.toLowerCase() !== user.toLowerCase()) { - // console.error('ERROR!!! - Signin with other user', userToken, user); - // throw new UserError('Try again'); - // } + Self.signInValidate(user, userToken); try { await Self.app.models.Account.sync(userToken.name, password); From abf772ae870e238a4df0b42bfb082724ebf76dd1 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 16 Nov 2023 10:43:00 +0100 Subject: [PATCH 246/449] refs #6434 feat: check if signIn inserts signInLog --- back/methods/vn-user/specs/sign-in.spec.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/back/methods/vn-user/specs/sign-in.spec.js b/back/methods/vn-user/specs/sign-in.spec.js index 26abe7eda1..ac2dfe2b23 100644 --- a/back/methods/vn-user/specs/sign-in.spec.js +++ b/back/methods/vn-user/specs/sign-in.spec.js @@ -12,13 +12,16 @@ describe('VnUser Sign-in()', () => { }, args: {} }; - const {VnUser, AccessToken} = models; + const {VnUser, AccessToken, SignInLog} = models; describe('when credentials are correct', () => { it('should return the token if user uses email', async() => { let login = await VnUser.signIn(unauthCtx, 'salesAssistant@mydomain.com', 'nightmare'); let accessToken = await AccessToken.findById(login.token); let ctx = {req: {accessToken: accessToken}}; + let signInLog = await SignInLog.find({where: {token: accessToken.id}}); + expect(signInLog.length).toEqual(1); + expect(signInLog[0].userFk).toEqual(accessToken.userId); expect(login.token).toBeDefined(); await VnUser.logout(ctx.req.accessToken.id); From 9e649398101ffff980ff7471fa375d885e8c5972 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 16 Nov 2023 11:56:48 +0100 Subject: [PATCH 247/449] refs #6434 feat: add Id property in model --- modules/account/back/models/sign_in-log.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/account/back/models/sign_in-log.json b/modules/account/back/models/sign_in-log.json index 9e6df2da57..c5c014e60a 100644 --- a/modules/account/back/models/sign_in-log.json +++ b/modules/account/back/models/sign_in-log.json @@ -7,6 +7,11 @@ } }, "properties": { + "id": { + "type": "number", + "id": true, + "description": "Identifier" + }, "token": { "required": true, "type": "string", From a73453e9ed29736cbb35fd370ad29ae38068d071 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 16 Nov 2023 11:56:59 +0100 Subject: [PATCH 248/449] refs #6434 feat: remove old sql file --- db/changes/234603/00-createSignInLogTable.sql | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 db/changes/234603/00-createSignInLogTable.sql diff --git a/db/changes/234603/00-createSignInLogTable.sql b/db/changes/234603/00-createSignInLogTable.sql deleted file mode 100644 index 5253481357..0000000000 --- a/db/changes/234603/00-createSignInLogTable.sql +++ /dev/null @@ -1,20 +0,0 @@ - - --- --- Table structure for table `signInLog` --- Description: log to debug cross-login error --- - -DROP TABLE IF EXISTS `account`.`signInLog`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `account`.`signInLog` ( - id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, - `token` varchar(255) NOT NULL , - `userFk` int(10) unsigned DEFAULT NULL, - `creationDate` timestamp NULL DEFAULT current_timestamp(), - `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - KEY `userFk` (`userFk`), - CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -); - From 83ae0379b5feeb7922075fbbba14c7c1406a09de Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 16 Nov 2023 12:28:35 +0100 Subject: [PATCH 249/449] refs #6434 fix: console.log --- back/models/vn-user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index bbfee4c515..e73c04bc00 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -127,7 +127,7 @@ module.exports = function(Self) { Self.signInValidate = (user, userToken) => { const [[key, value]] = Object.entries(Self.userUses(user)); if (userToken[key].toLowerCase() !== value.toLowerCase()) { - console.error('ERROR!!! - Signin with other user', _userToken, _user); + console.error('ERROR!!! - Signin with other user', userToken, user); throw new UserError('Try again'); } }; From aea3f7b2b9bbecaa6f16d0ff241c57a0c766ba32 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 16 Nov 2023 15:10:47 +0100 Subject: [PATCH 250/449] refs #6434 fix: use trim --- back/models/vn-user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index e73c04bc00..719e96cbf7 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -126,7 +126,7 @@ module.exports = function(Self) { }); Self.signInValidate = (user, userToken) => { const [[key, value]] = Object.entries(Self.userUses(user)); - if (userToken[key].toLowerCase() !== value.toLowerCase()) { + if (userToken[key].toLowerCase().trim() !== value.toLowerCase().trim()) { console.error('ERROR!!! - Signin with other user', userToken, user); throw new UserError('Try again'); } From 4f5242e3ae30d0e9b2ef35d7368ce0aab1052595 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Thu, 16 Nov 2023 23:07:26 +0100 Subject: [PATCH 251/449] fix: refs #6432 account sync fixes --- Dockerfile | 10 +- db/changes/234604/00-sambaConfigUserDn.sql | 2 + modules/account/back/methods/account/sync.js | 8 +- modules/account/back/models/ldap-config.js | 3 +- modules/account/back/models/role-config.js | 20 ++- modules/account/back/models/samba-config.js | 149 +++++++++++------- modules/account/back/models/samba-config.json | 4 + modules/account/front/accounts/index.html | 40 +---- modules/account/front/accounts/index.js | 18 --- modules/account/front/accounts/locale/es.yml | 2 - modules/account/front/descriptor/index.html | 35 ++++ modules/account/front/descriptor/index.js | 14 ++ .../account/front/descriptor/locale/es.yml | 4 + 13 files changed, 186 insertions(+), 123 deletions(-) create mode 100644 db/changes/234604/00-sambaConfigUserDn.sql diff --git a/Dockerfile b/Dockerfile index e1173ad738..814a5e1d81 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,15 +17,19 @@ RUN apt-get update \ # Puppeteer -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ +RUN apt-get install -y --no-install-recommends \ libfontconfig lftp xvfb gconf-service libasound2 libatk1.0-0 libc6 \ libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 \ libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 \ libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 \ libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 \ libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \ - fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget \ + fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget + +# Extra dependencies + +RUN apt-get install -y --no-install-recommends \ + samba-common-bin \ && rm -rf /var/lib/apt/lists/* \ && npm -g install pm2 diff --git a/db/changes/234604/00-sambaConfigUserDn.sql b/db/changes/234604/00-sambaConfigUserDn.sql new file mode 100644 index 0000000000..cacb30e975 --- /dev/null +++ b/db/changes/234604/00-sambaConfigUserDn.sql @@ -0,0 +1,2 @@ +ALTER TABLE account.sambaConfig + ADD userDn varchar(255) NOT NULL COMMENT 'Base DN for users without domain DN part'; diff --git a/modules/account/back/methods/account/sync.js b/modules/account/back/methods/account/sync.js index a5befc22c5..0eab0ef63a 100644 --- a/modules/account/back/methods/account/sync.js +++ b/modules/account/back/methods/account/sync.js @@ -1,3 +1,4 @@ +const ForbiddenError = require('vn-loopback/util/forbiddenError'); module.exports = Self => { Self.remoteMethod('sync', { @@ -32,9 +33,13 @@ module.exports = Self => { const models = Self.app.models; const user = await models.VnUser.findOne({ - fields: ['id'], + fields: ['id', 'password'], where: {name: userName} }, myOptions); + + if (user && password && !await user.hasPassword(password)) + throw new ForbiddenError('Wrong password'); + const isSync = !await models.UserSync.exists(userName, myOptions); if (!force && isSync && user) return; @@ -42,4 +47,3 @@ module.exports = Self => { await models.UserSync.destroyById(userName, myOptions); }; }; - diff --git a/modules/account/back/models/ldap-config.js b/modules/account/back/models/ldap-config.js index f9ae7562b6..9dcc4136d3 100644 --- a/modules/account/back/models/ldap-config.js +++ b/modules/account/back/models/ldap-config.js @@ -5,7 +5,7 @@ const crypto = require('crypto'); const nthash = require('smbhash').nthash; module.exports = Self => { - const shouldSync = process.env.NODE_ENV === 'production'; + const shouldSync = process.env.NODE_ENV !== 'test'; Self.getSynchronizer = async function() { return await Self.findOne({ @@ -140,6 +140,7 @@ module.exports = Self => { try { if (shouldSync) await client.del(dn); + // eslint-disable-next-line no-console console.log(` -> User '${userName}' removed from LDAP`); } catch (e) { if (e.name !== 'NoSuchObjectError') throw e; diff --git a/modules/account/back/models/role-config.js b/modules/account/back/models/role-config.js index ba7bf9d523..b90ef75fb6 100644 --- a/modules/account/back/models/role-config.js +++ b/modules/account/back/models/role-config.js @@ -27,8 +27,7 @@ module.exports = Self => { const [row] = await Self.rawSql( `SELECT COUNT(*) AS nRows FROM mysql.user - WHERE User = ? - AND Host = ?`, + WHERE User = ? AND Host = ?`, [mysqlUser, this.userHost] ); let userExists = row.nRows > 0; @@ -38,8 +37,7 @@ module.exports = Self => { const [row] = await Self.rawSql( `SELECT Priv AS priv FROM mysql.global_priv - WHERE User = ? - AND Host = ?`, + WHERE User = ? AND Host = ?`, [mysqlUser, this.userHost] ); const priv = row && JSON.parse(row.priv); @@ -88,10 +86,18 @@ module.exports = Self => { else throw err; } - await Self.rawSql('GRANT ? TO ?@?', - [role, mysqlUser, this.userHost]); - if (role) { + const [row] = await Self.rawSql( + `SELECT COUNT(*) AS nRows + FROM mysql.user + WHERE User = ? AND Host = ''`, + [role] + ); + const roleExists = row.nRows > 0; + + if (roleExists) { + await Self.rawSql('GRANT ? TO ?@?', + [role, mysqlUser, this.userHost]); await Self.rawSql('SET DEFAULT ROLE ? FOR ?@?', [role, mysqlUser, this.userHost]); } else { diff --git a/modules/account/back/models/samba-config.js b/modules/account/back/models/samba-config.js index 168b5ffb47..1abac489c8 100644 --- a/modules/account/back/models/samba-config.js +++ b/modules/account/back/models/samba-config.js @@ -1,6 +1,6 @@ const ldap = require('../util/ldapjs-extra'); -const ssh = require('node-ssh'); +const execFile = require('child_process').execFile; /** * Summary of userAccountControl flags: @@ -11,6 +11,8 @@ const UserAccountControlFlags = { }; module.exports = Self => { + const shouldSync = process.env.NODE_ENV !== 'test'; + Self.getSynchronizer = async function() { return await Self.findOne({ fields: [ @@ -19,6 +21,7 @@ module.exports = Self => { 'adController', 'adUser', 'adPassword', + 'userDn', 'verifyCert' ] }); @@ -26,88 +29,119 @@ module.exports = Self => { Object.assign(Self.prototype, { async init() { - let sshClient = new ssh.NodeSSH(); - await sshClient.connect({ - host: this.adController, - username: this.adUser, - password: this.adPassword - }); + const baseDn = this.adDomain + .split('.') + .map(part => `dc=${part}`) + .join(','); + const ldapUser = `cn=${this.adUser},cn=Users,${baseDn}`; - let adUser = `cn=${this.adUser},${this.usersDn()}`; - - let adClient = ldap.createClient({ + const adClient = ldap.createClient({ url: `ldaps://${this.adController}:636`, tlsOptions: {rejectUnauthorized: this.verifyCert} }); - await adClient.bind(adUser, this.adPassword); - + await adClient.bind(ldapUser, this.adPassword); Object.assign(this, { - sshClient, - adClient + adClient, + fullUsersDn: `${this.userDn},${baseDn}` }); }, async deinit() { - await this.sshClient.dispose(); await this.adClient.unbind(); }, - usersDn() { - let dnBase = this.adDomain - .split('.') - .map(part => `dc=${part}`) - .join(','); - return `cn=Users,${dnBase}`; + async sambaTool(command, args = []) { + const authArgs = [ + '--URL', `ldap://${this.adController}`, + '--username', this.adUser, + '--password', this.adPassword + ]; + const allArgs = [command].concat( + args, authArgs + ); + + if (!shouldSync) return; + return await new Promise((resolve, reject) => { + execFile('samba-tool', allArgs, (err, stdout, stderr) => { + if (err) + reject(err); + else + resolve({stdout, stderr}); + }); + }); }, - async syncUser(userName, info, password) { - let {sshClient} = this; - - let sambaUser = await this.adClient.searchOne(this.usersDn(), { + async getAdUser(userName) { + const sambaUser = await this.adClient.searchOne(this.fullUsersDn, { scope: 'sub', - attributes: ['userAccountControl'], + attributes: [ + 'dn', + 'userAccountControl', + 'uidNumber', + 'accountExpires', + 'mail' + ], filter: `(&(objectClass=user)(sAMAccountName=${userName}))` }); - let isEnabled = sambaUser - && !(sambaUser.userAccountControl & UserAccountControlFlags.ACCOUNTDISABLE); - - if (process.env.NODE_ENV === 'test') - return; + if (sambaUser) { + for (const intProp of ['uidNumber', 'userAccountControl']) { + if (sambaUser[intProp] != null) + sambaUser[intProp] = parseInt(sambaUser[intProp]); + } + } + return sambaUser; + }, + + async syncUser(userName, info, password) { + let sambaUser = await this.getAdUser(userName); + let entry; if (info.hasAccount) { if (!sambaUser) { - await sshClient.exec('samba-tool user create', [ - userName, - '--uid-number', `${info.uidNumber}`, - '--mail-address', info.corporateMail, + await this.sambaTool('user', [ + 'create', userName, + '--userou', this.userDn, '--random-password' ]); - await sshClient.exec('samba-tool user setexpiry', [ - userName, - '--noexpiry' - ]); - await sshClient.exec('mkhomedir_helper', [ - userName, - '0027' - ]); - } - if (!isEnabled) { - await sshClient.exec('samba-tool user enable', [ - userName - ]); + sambaUser = await this.getAdUser(userName); } if (password) { - await sshClient.exec('samba-tool user setpassword', [ - userName, + await this.sambaTool('user', [ + 'setpassword', userName, '--newpassword', password ]); } - } else if (isEnabled) { - await sshClient.exec('samba-tool user disable', [ - userName - ]); + + entry = { + userAccountControl: sambaUser.userAccountControl + & ~UserAccountControlFlags.ACCOUNTDISABLE, + uidNumber: info.uidNumber, + accountExpires: 0, + mail: info.corporateMail + }; + } else if (sambaUser) { + entry = { + userAccountControl: sambaUser.userAccountControl + | UserAccountControlFlags.ACCOUNTDISABLE + }; + // eslint-disable-next-line no-console console.log(` -> User '${userName}' disabled on Samba`); } + + if (sambaUser && entry) { + const changes = []; + for (const prop in entry) { + if (sambaUser[prop] == entry[prop]) continue; + changes.push(new ldap.Change({ + operation: 'replace', + modification: { + [prop]: entry[prop] + } + })); + } + if (changes.length) + await this.adClient.modify(sambaUser.dn, changes); + } }, /** @@ -117,14 +151,15 @@ module.exports = Self => { */ async getUsers(usersToSync) { const LDAP_MATCHING_RULE_BIT_AND = '1.2.840.113556.1.4.803'; - let filter = `!(userAccountControl:${LDAP_MATCHING_RULE_BIT_AND}:=${UserAccountControlFlags.ACCOUNTDISABLE})`; + // eslint-disable-next-line max-len + const filter = `!(userAccountControl:${LDAP_MATCHING_RULE_BIT_AND}:=${UserAccountControlFlags.ACCOUNTDISABLE})`; - let opts = { + const opts = { scope: 'sub', attributes: ['sAMAccountName'], filter: `(&(objectClass=user)(${filter}))` }; - await this.adClient.searchForeach(this.usersDn(), opts, + await this.adClient.searchForeach(this.fullUsersDn, opts, o => usersToSync.add(o.sAMAccountName)); } }); diff --git a/modules/account/back/models/samba-config.json b/modules/account/back/models/samba-config.json index 732c9b071c..28cbb26890 100644 --- a/modules/account/back/models/samba-config.json +++ b/modules/account/back/models/samba-config.json @@ -28,6 +28,10 @@ "adPassword": { "type": "string" }, + "userDn": { + "type": "string", + "required": true + }, "verifyCert": { "type": "boolean" } diff --git a/modules/account/front/accounts/index.html b/modules/account/front/accounts/index.html index 6941bb15b5..6847e68d11 100644 --- a/modules/account/front/accounts/index.html +++ b/modules/account/front/accounts/index.html @@ -12,40 +12,40 @@ @@ -61,10 +61,6 @@ label="Synchronize all" ng-click="$ctrl.onSynchronizeAll()"> - - @@ -77,25 +73,3 @@ - - - - - - - - - - - - diff --git a/modules/account/front/accounts/index.js b/modules/account/front/accounts/index.js index 0e78ab8d6d..ab19126a1b 100644 --- a/modules/account/front/accounts/index.js +++ b/modules/account/front/accounts/index.js @@ -1,6 +1,5 @@ import ngModule from '../module'; import Section from 'salix/components/section'; -import UserError from 'core/lib/user-error'; export default class Controller extends Section { onSynchronizeAll() { @@ -8,27 +7,10 @@ export default class Controller extends Section { this.$http.patch(`Accounts/syncAll`); } - onUserSync() { - if (!this.syncUser) - throw new UserError('Please enter the username'); - - let params = { - password: this.syncPassword, - force: true - }; - return this.$http.patch(`Accounts/${this.syncUser}/sync`, params) - .then(() => this.vnApp.showSuccess(this.$t('User synchronized!'))); - } - onSynchronizeRoles() { this.$http.patch(`RoleInherits/sync`) .then(() => this.vnApp.showSuccess(this.$t('Roles synchronized!'))); } - - onSyncClose() { - this.syncUser = ''; - this.syncPassword = ''; - } } ngModule.component('vnAccountAccounts', { diff --git a/modules/account/front/accounts/locale/es.yml b/modules/account/front/accounts/locale/es.yml index 9a6bb50737..614ade3eb0 100644 --- a/modules/account/front/accounts/locale/es.yml +++ b/modules/account/front/accounts/locale/es.yml @@ -3,7 +3,6 @@ Homedir base: Directorio base para carpetas de usuario Shell: Intérprete de línea de comandos User and role base id: Id base usuarios y roles Synchronize all: Sincronizar todo -Synchronize user: Sincronizar usuario Synchronize roles: Sincronizar roles If password is not specified, just user attributes are synchronized: >- Si la contraseña no se especifica solo se sincronizarán lo atributos del usuario @@ -12,5 +11,4 @@ Users synchronized!: ¡Usuarios sincronizados! Username: Nombre de usuario Synchronize: Sincronizar Please enter the username: Por favor introduce el nombre de usuario -User synchronized!: ¡Usuario sincronizado! Roles synchronized!: ¡Roles sincronizados! diff --git a/modules/account/front/descriptor/index.html b/modules/account/front/descriptor/index.html index 94497aaa93..b0a70edd11 100644 --- a/modules/account/front/descriptor/index.html +++ b/modules/account/front/descriptor/index.html @@ -67,6 +67,15 @@ translate> Deactivate user + + Synchronize +
@@ -153,6 +162,32 @@ + + + Do you want to synchronize user? + + + + + + + + + + + + diff --git a/modules/account/front/descriptor/index.js b/modules/account/front/descriptor/index.js index 786870d366..c327b0836c 100644 --- a/modules/account/front/descriptor/index.js +++ b/modules/account/front/descriptor/index.js @@ -120,6 +120,20 @@ class Controller extends Descriptor { this.vnApp.showSuccess(this.$t(message)); }); } + + onSync() { + let params = { + password: this.syncPassword, + force: true + }; + return this.$http.patch(`Accounts/${this.user.name}/sync`, params) + .then(() => this.vnApp.showSuccess(this.$t('User synchronized!'))); + } + + onSyncClose() { + this.shouldSyncPassword = false; + this.syncPassword = undefined; + } } ngModule.component('vnUserDescriptor', { diff --git a/modules/account/front/descriptor/locale/es.yml b/modules/account/front/descriptor/locale/es.yml index 5e82428193..98ced7694a 100644 --- a/modules/account/front/descriptor/locale/es.yml +++ b/modules/account/front/descriptor/locale/es.yml @@ -22,6 +22,10 @@ Old password: Contraseña antigua New password: Nueva contraseña Repeat password: Repetir contraseña Password changed succesfully!: ¡Contraseña modificada correctamente! +Synchronize: Sincronizar +Do you want to synchronize user?: ¿Quieres sincronizar el usuario? +Synchronize password: Sincronizar contraseña +User synchronized!: ¡Usuario sincronizado! Role changed succesfully!: ¡Rol modificado correctamente! Password requirements: > La contraseña debe tener al menos {{ length }} caracteres de longitud, From ea5a881d1f4f35473e3984d161908fd3029f9000 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Thu, 16 Nov 2023 23:10:30 +0100 Subject: [PATCH 252/449] fix: refs #6432 account sync fixes --- modules/account/back/models/samba-config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/account/back/models/samba-config.js b/modules/account/back/models/samba-config.js index 1abac489c8..b6692be023 100644 --- a/modules/account/back/models/samba-config.js +++ b/modules/account/back/models/samba-config.js @@ -139,7 +139,7 @@ module.exports = Self => { } })); } - if (changes.length) + if (changes.length && shouldSync) await this.adClient.modify(sambaUser.dn, changes); } }, From 6930c2d52e1e068e1437ed89f511e9d1b8d616d1 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Thu, 16 Nov 2023 23:13:16 +0100 Subject: [PATCH 253/449] fix: #6432 account sync fixes --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 814a5e1d81..d46a1a84ce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,8 @@ RUN apt-get update \ # Puppeteer -RUN apt-get install -y --no-install-recommends \ +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ libfontconfig lftp xvfb gconf-service libasound2 libatk1.0-0 libc6 \ libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 \ libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 \ @@ -28,7 +29,8 @@ RUN apt-get install -y --no-install-recommends \ # Extra dependencies -RUN apt-get install -y --no-install-recommends \ +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ samba-common-bin \ && rm -rf /var/lib/apt/lists/* \ && npm -g install pm2 From 14eb14ad3f2540fd89fc4172e85d90f3b34bf8ae Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 17 Nov 2023 00:00:36 +0100 Subject: [PATCH 254/449] fix: refs #6432 bookworm upgrade --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d46a1a84ce..ce63da8ab7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bullseye-slim +FROM debian:bookworm-slim ENV TZ Europe/Madrid ARG DEBIAN_FRONTEND=noninteractive From c2e295f777026ae621864b1d31936a228997b2ce Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 17 Nov 2023 00:08:29 +0100 Subject: [PATCH 255/449] fix: refs #6432 account sync fixes --- modules/account/front/descriptor/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/account/front/descriptor/index.js b/modules/account/front/descriptor/index.js index c327b0836c..18d93b9240 100644 --- a/modules/account/front/descriptor/index.js +++ b/modules/account/front/descriptor/index.js @@ -122,10 +122,10 @@ class Controller extends Descriptor { } onSync() { - let params = { - password: this.syncPassword, - force: true - }; + const params = {force: true}; + if (this.shouldSyncPassword) + params.password = this.syncPassword; + return this.$http.patch(`Accounts/${this.user.name}/sync`, params) .then(() => this.vnApp.showSuccess(this.$t('User synchronized!'))); } From 2f611391b98c39e3d5b0480dbc634f659d961535 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 17 Nov 2023 07:17:29 +0100 Subject: [PATCH 256/449] Revert "refactor: refs #4502 Deleted zoneEstimatedDelivery" This reverts commit bfd6e1f39843abb02694fa2ebdb52e95df4f2bd4. --- .../back/methods/sales-monitor/salesFilter.js | 71 +++++-------- modules/order/back/methods/order/filter.js | 99 +++++++------------ modules/zone/back/model-config.json | 3 + .../back/models/zone-estimated-delivery.json | 44 +++++++++ 4 files changed, 105 insertions(+), 112 deletions(-) create mode 100644 modules/zone/back/models/zone-estimated-delivery.json diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 85945a57d6..693ae122fc 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -163,14 +163,17 @@ module.exports = Self => { const stmts = []; let stmt; + stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.filter'); + stmts.push(`SET @_optimizer_search_depth = @@optimizer_search_depth`); stmts.push(`SET SESSION optimizer_search_depth = 0`); - stmt = new ParameterizedSQL(` - CREATE OR REPLACE TEMPORARY TABLE tmp.filter + stmt = new ParameterizedSQL( + `CREATE TEMPORARY TABLE tmp.filter (PRIMARY KEY (id)) ENGINE = MEMORY - SELECT t.id, + SELECT + t.id, t.shipped, CAST(DATE(t.shipped) AS CHAR) AS shippedDate, t.nickname, @@ -180,27 +183,27 @@ module.exports = Self => { t.clientFk, t.totalWithoutVat, t.totalWithVat, - io.id invoiceOutId, + io.id AS invoiceOutId, a.provinceFk, - p.name province, - w.name warehouse, - am.name agencyMode, - am.id agencyModeFk, - st.name state, - wk.lastName salesPerson, - ts.stateFk stateFk, - ts.alertLevel alertLevel, - ts.code alertLevelCode, - u.name userName, + p.name AS province, + w.name AS warehouse, + am.name AS agencyMode, + am.id AS agencyModeFk, + st.name AS state, + wk.lastName AS salesPerson, + ts.stateFk AS stateFk, + ts.alertLevel AS alertLevel, + ts.code AS alertLevelCode, + u.name AS userName, c.salesPersonFk, c.credit, - z.hour zoneLanding, - z.name zoneName, - z.id zoneFk, + z.hour AS zoneLanding, + z.name AS zoneName, + z.id AS zoneFk, st.classColor, - TIME_FORMAT(t.shipped, '%H:%i') preparationHour, - TIME_FORMAT(z.hour, '%H:%i') theoreticalhour, - TIME_FORMAT(zed.etc, '%H:%i') practicalHour + TIME_FORMAT(t.shipped, '%H:%i') AS preparationHour, + TIME_FORMAT(z.hour, '%H:%i') AS theoreticalhour, + TIME_FORMAT(zed.etc, '%H:%i') AS practicalHour FROM ticket t LEFT JOIN invoiceOut io ON t.refFk = io.ref LEFT JOIN zone z ON z.id = t.zoneFk @@ -213,33 +216,7 @@ module.exports = Self => { LEFT JOIN client c ON c.id = t.clientFk LEFT JOIN worker wk ON wk.id = c.salesPersonFk LEFT JOIN account.user u ON u.id = wk.id - LEFT JOIN ( - SELECT zoneFk, - CAST(zoneHour + remainingVolume * 60 / speed AS time) etc - FROM ( - SELECT t.zoneFk, - IFNULL(zc.hour, z.hour) zoneHour, - SUM(IF(al.hasToRecalcPrice, sv.volume, 0)) remainingVolume, - GREATEST(IFNULL(lhp.m3, 0), IFNULL(dl.minSpeed, 0)) speed - FROM ticket t - JOIN ticketStateToday tst ON tst.ticket = t.id - JOIN state s ON s.id = tst.state - JOIN saleVolume sv ON sv.ticketFk = t.id - LEFT JOIN lastHourProduction lhp ON lhp.warehouseFk = t.warehouseFk - JOIN warehouse w ON w.id = t.warehouseFk - JOIN warehouseAlias wa ON wa.id = w.aliasFk - STRAIGHT_JOIN zone z ON z.id = t.zoneFk - LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk - AND zc.dated = util.VN_CURDATE() - LEFT JOIN cache.departure_limit dl ON dl.warehouse_id = t.warehouseFk - AND dl.fecha = util.VN_CURDATE() - JOIN alertLevel al ON al.id = s.alertLevel - WHERE w.hasProduction - AND DATE(t.shipped) = util.VN_CURDATE() - GROUP BY t.zoneFk - ) sub - ) zed ON zed.zoneFk = t.zoneFk` - ); + LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`); if (args.orderFk) { stmt.merge({ diff --git a/modules/order/back/methods/order/filter.js b/modules/order/back/methods/order/filter.js index 27484acb92..44d8ccb107 100644 --- a/modules/order/back/methods/order/filter.js +++ b/modules/order/back/methods/order/filter.js @@ -140,71 +140,40 @@ module.exports = Self => { const stmts = []; let stmt; - stmt = new ParameterizedSQL(` - CREATE OR REPLACE TEMPORARY TABLE tmp.filter - (INDEX (id)) - ENGINE = MEMORY - SELECT o.id, - o.total, - o.date_send landed, - o.date_make created, - o.customer_id clientFk, - o.agency_id agencyModeFk, - o.address_id addressFk, - o.company_id companyFk, - o.source_app sourceApp, - o.confirmed isConfirmed, - c.name clientName, - c.salesPersonFk, - u.nickname workerNickname, - u.name name, - co.code companyCode, - zed.zoneFk, - zed.hourTheoretical, - zed.hourEffective, - am.name agencyName - FROM hedera.order o - LEFT JOIN address a ON a.id = o.address_id - LEFT JOIN agencyMode am ON am.id = o.agency_id - LEFT JOIN client c ON c.id = o.customer_id - LEFT JOIN worker wk ON wk.id = c.salesPersonFk - LEFT JOIN account.user u ON u.id = wk.id - LEFT JOIN company co ON co.id = o.company_id - LEFT JOIN orderTicket ot ON ot.orderFk = o.id - LEFT JOIN ticket t ON t.id = ot.ticketFk - LEFT JOIN ( - SELECT zoneFk, - CAST( - util.VN_CURDATE() + - INTERVAL HOUR(zoneHour) * 60 + MINUTE(zoneHour) MINUTE - AS time - ) hourTheoretical, - CAST(zoneHour + remainingVolume * 60 / speed AS time) hourEffective - FROM ( - SELECT t.zoneFk, - IFNULL(zc.hour, z.hour) zoneHour, - CAST(SUM(sv.volume) AS DECIMAL(5, 1)) totalVolume, - SUM(IF(al.hasToRecalcPrice, sv.volume, 0)) remainingVolume, - GREATEST(IFNULL(lhp.m3, 0), IFNULL(dl.minSpeed, 0)) speed - FROM ticket t - JOIN ticketStateToday tst ON tst.ticket = t.id - JOIN state s ON s.id = tst.state - JOIN saleVolume sv ON sv.ticketFk = t.id - LEFT JOIN lastHourProduction lhp ON lhp.warehouseFk = t.warehouseFk - JOIN warehouse w ON w.id = t.warehouseFk - JOIN warehouseAlias wa ON wa.id = w.aliasFk - STRAIGHT_JOIN zone z ON z.id = t.zoneFk - LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk - AND zc.dated = util.VN_CURDATE() - LEFT JOIN cache.departure_limit dl ON dl.warehouse_id = t.warehouseFk - AND dl.fecha = util.VN_CURDATE() - JOIN alertLevel al ON al.id = s.alertLevel - WHERE w.hasProduction - AND DATE(t.shipped) = util.VN_CURDATE() - GROUP BY t.zoneFk - ) sub - ) zed ON zed.zoneFk = t.zoneFk - `); + stmt = new ParameterizedSQL( + `CREATE OR REPLACE TEMPORARY TABLE tmp.filter + (INDEX (id)) + ENGINE = MEMORY + SELECT + o.id, + o.total, + o.date_send landed, + o.date_make created, + o.customer_id clientFk, + o.agency_id agencyModeFk, + o.address_id addressFk, + o.company_id companyFk, + o.source_app sourceApp, + o.confirmed isConfirmed, + c.name clientName, + c.salesPersonFk, + u.nickname workerNickname, + u.name name, + co.code companyCode, + zed.zoneFk, + zed.hourTheoretical, + zed.hourEffective, + am.name AS agencyName + FROM hedera.order o + LEFT JOIN address a ON a.id = o.address_id + LEFT JOIN agencyMode am ON am.id = o.agency_id + LEFT JOIN client c ON c.id = o.customer_id + LEFT JOIN worker wk ON wk.id = c.salesPersonFk + LEFT JOIN account.user u ON u.id = wk.id + LEFT JOIN company co ON co.id = o.company_id + LEFT JOIN orderTicket ot ON ot.orderFk = o.id + LEFT JOIN ticket t ON t.id = ot.ticketFk + LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`); stmt.merge(conn.makeWhere(filter.where)); stmt.merge(`GROUP BY id`); diff --git a/modules/zone/back/model-config.json b/modules/zone/back/model-config.json index 43d2cb570a..261a89902a 100644 --- a/modules/zone/back/model-config.json +++ b/modules/zone/back/model-config.json @@ -35,6 +35,9 @@ "ZoneWarehouse": { "dataSource": "vn" }, + "ZoneEstimatedDelivery": { + "dataSource": "vn" + }, "ZoneLog": { "dataSource": "vn" } diff --git a/modules/zone/back/models/zone-estimated-delivery.json b/modules/zone/back/models/zone-estimated-delivery.json new file mode 100644 index 0000000000..399de8f58a --- /dev/null +++ b/modules/zone/back/models/zone-estimated-delivery.json @@ -0,0 +1,44 @@ +{ + "name": "ZoneEstimatedDelivery", + "base": "VnModel", + "options": { + "mysql": { + "table": "zoneEstimatedDelivery" + } + }, + "properties": { + "zoneFk": { + "id": true, + "type": "number" + }, + "hourTheoretical": { + "type": "date" + }, + "totalVolume": { + "type": "number" + }, + "remainingVolume": { + "type": "number" + }, + "speed": { + "type": "number" + }, + "hourEffective": { + "type": "date" + }, + "minutesLess": { + "type": "date" + }, + "etc": { + "type": "date" + } + + }, + "relations": { + "zone": { + "type": "belongsTo", + "model": "Zone", + "foreignKey": "zoneFk" + } + } +} \ No newline at end of file From 3d1c69be5618abd37848dee6d20986840d193806 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 17 Nov 2023 07:43:32 +0100 Subject: [PATCH 257/449] refactor: refs #4502 zoneEstimatedDelivery --- .../back/methods/sales-monitor/salesFilter.js | 104 ++++++++++-------- modules/order/back/methods/order/filter.js | 84 ++++++++------ .../back/models/zone-estimated-delivery.json | 24 ++-- 3 files changed, 117 insertions(+), 95 deletions(-) diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 693ae122fc..2c62977f39 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -168,55 +168,65 @@ module.exports = Self => { stmts.push(`SET @_optimizer_search_depth = @@optimizer_search_depth`); stmts.push(`SET SESSION optimizer_search_depth = 0`); - stmt = new ParameterizedSQL( - `CREATE TEMPORARY TABLE tmp.filter + stmt = new ParameterizedSQL(` + CREATE TEMPORARY TABLE tmp.filter (PRIMARY KEY (id)) ENGINE = MEMORY - SELECT - t.id, - t.shipped, - CAST(DATE(t.shipped) AS CHAR) AS shippedDate, - t.nickname, - t.refFk, - t.routeFk, - t.warehouseFk, - t.clientFk, - t.totalWithoutVat, - t.totalWithVat, - io.id AS invoiceOutId, - a.provinceFk, - p.name AS province, - w.name AS warehouse, - am.name AS agencyMode, - am.id AS agencyModeFk, - st.name AS state, - wk.lastName AS salesPerson, - ts.stateFk AS stateFk, - ts.alertLevel AS alertLevel, - ts.code AS alertLevelCode, - u.name AS userName, - c.salesPersonFk, - c.credit, - z.hour AS zoneLanding, - z.name AS zoneName, - z.id AS zoneFk, - st.classColor, - TIME_FORMAT(t.shipped, '%H:%i') AS preparationHour, - TIME_FORMAT(z.hour, '%H:%i') AS theoreticalhour, - TIME_FORMAT(zed.etc, '%H:%i') AS practicalHour - FROM ticket t - LEFT JOIN invoiceOut io ON t.refFk = io.ref - LEFT JOIN zone z ON z.id = t.zoneFk - LEFT JOIN address a ON a.id = t.addressFk - LEFT JOIN province p ON p.id = a.provinceFk - LEFT JOIN warehouse w ON w.id = t.warehouseFk - LEFT JOIN agencyMode am ON am.id = t.agencyModeFk - LEFT JOIN ticketState ts ON ts.ticketFk = t.id - LEFT JOIN state st ON st.id = ts.stateFk - LEFT JOIN client c ON c.id = t.clientFk - LEFT JOIN worker wk ON wk.id = c.salesPersonFk - LEFT JOIN account.user u ON u.id = wk.id - LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`); + SELECT t.id, + t.shipped, + CAST(DATE(t.shipped) AS CHAR) shippedDate, + t.nickname, + t.refFk, + t.routeFk, + t.warehouseFk, + t.clientFk, + t.totalWithoutVat, + t.totalWithVat, + io.id invoiceOutId, + a.provinceFk, + p.name province, + w.name warehouse, + am.name agencyMode, + am.id agencyModeFk, + st.name state, + wk.lastName salesPerson, + ts.stateFk stateFk, + ts.alertLevel alertLevel, + ts.code alertLevelCode, + u.name userName, + c.salesPersonFk, + c.credit, + z.hour zoneLanding, + z.name zoneName, + z.id zoneFk, + st.classColor, + TIME_FORMAT(t.shipped, '%H:%i') preparationHour, + TIME_FORMAT(z.hour, '%H:%i') theoreticalhour, + TIME_FORMAT(zed.etc, '%H:%i') practicalHour + FROM ticket t + LEFT JOIN invoiceOut io ON t.refFk = io.ref + LEFT JOIN zone z ON z.id = t.zoneFk + LEFT JOIN address a ON a.id = t.addressFk + LEFT JOIN province p ON p.id = a.provinceFk + LEFT JOIN warehouse w ON w.id = t.warehouseFk + LEFT JOIN agencyMode am ON am.id = t.agencyModeFk + LEFT JOIN ticketState ts ON ts.ticketFk = t.id + LEFT JOIN state st ON st.id = ts.stateFk + LEFT JOIN client c ON c.id = t.clientFk + LEFT JOIN worker wk ON wk.id = c.salesPersonFk + LEFT JOIN account.user u ON u.id = wk.id + LEFT JOIN ( + SELECT zoneFk, + CAST( + IFNULL(zoneClosureHour, zoneHour) + + SUM(IF(hasToRecalcPrice, volume, 0)) * 60 / + GREATEST(IFNULL(m3, 0), IFNULL(minSpeed, 0)) + AS time + ) etc + FROM zoneEstimatedDelivery + GROUP BY zoneFk + ) zed ON zed.zoneFk = t.zoneFk + `); if (args.orderFk) { stmt.merge({ diff --git a/modules/order/back/methods/order/filter.js b/modules/order/back/methods/order/filter.js index 44d8ccb107..97fca5c10f 100644 --- a/modules/order/back/methods/order/filter.js +++ b/modules/order/back/methods/order/filter.js @@ -140,40 +140,56 @@ module.exports = Self => { const stmts = []; let stmt; - stmt = new ParameterizedSQL( - `CREATE OR REPLACE TEMPORARY TABLE tmp.filter - (INDEX (id)) - ENGINE = MEMORY - SELECT - o.id, - o.total, - o.date_send landed, - o.date_make created, - o.customer_id clientFk, - o.agency_id agencyModeFk, - o.address_id addressFk, - o.company_id companyFk, - o.source_app sourceApp, - o.confirmed isConfirmed, - c.name clientName, - c.salesPersonFk, - u.nickname workerNickname, - u.name name, - co.code companyCode, - zed.zoneFk, - zed.hourTheoretical, - zed.hourEffective, - am.name AS agencyName - FROM hedera.order o - LEFT JOIN address a ON a.id = o.address_id - LEFT JOIN agencyMode am ON am.id = o.agency_id - LEFT JOIN client c ON c.id = o.customer_id - LEFT JOIN worker wk ON wk.id = c.salesPersonFk - LEFT JOIN account.user u ON u.id = wk.id - LEFT JOIN company co ON co.id = o.company_id - LEFT JOIN orderTicket ot ON ot.orderFk = o.id - LEFT JOIN ticket t ON t.id = ot.ticketFk - LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`); + stmt = new ParameterizedSQL(` + CREATE OR REPLACE TEMPORARY TABLE tmp.filter + (INDEX (id)) + ENGINE = MEMORY + SELECT o.id, + o.total, + o.date_send landed, + o.date_make created, + o.customer_id clientFk, + o.agency_id agencyModeFk, + o.address_id addressFk, + o.company_id companyFk, + o.source_app sourceApp, + o.confirmed isConfirmed, + c.name clientName, + c.salesPersonFk, + u.nickname workerNickname, + u.name name, + co.code companyCode, + zed.zoneFk, + zed.hourTheoretical, + zed.hourEffective, + am.name agencyName + FROM hedera.order o + LEFT JOIN address a ON a.id = o.address_id + LEFT JOIN agencyMode am ON am.id = o.agency_id + LEFT JOIN client c ON c.id = o.customer_id + LEFT JOIN worker wk ON wk.id = c.salesPersonFk + LEFT JOIN account.user u ON u.id = wk.id + LEFT JOIN company co ON co.id = o.company_id + LEFT JOIN orderTicket ot ON ot.orderFk = o.id + LEFT JOIN ticket t ON t.id = ot.ticketFk + LEFT JOIN ( + SELECT zoneFk, + CAST( + util.VN_CURDATE() + + INTERVAL HOUR(IFNULL(zoneClosureHour, zoneHour)) * 60 + + MINUTE(IFNULL(zoneClosureHour, zoneHour)) MINUTE + AS time + ) hourTheoretical, + CAST( + IFNULL(zoneClosureHour, zoneHour) + + SUM(IF(hasToRecalcPrice, volume, 0)) * 60 / + GREATEST(IFNULL(m3, 0), IFNULL(minSpeed, 0)) + AS time + ) hourEffective + FROM zoneEstimatedDelivery + GROUP BY zoneFk + ) zed ON zed.zoneFk = t.zoneFk + `); stmt.merge(conn.makeWhere(filter.where)); stmt.merge(`GROUP BY id`); diff --git a/modules/zone/back/models/zone-estimated-delivery.json b/modules/zone/back/models/zone-estimated-delivery.json index 399de8f58a..a017544849 100644 --- a/modules/zone/back/models/zone-estimated-delivery.json +++ b/modules/zone/back/models/zone-estimated-delivery.json @@ -11,28 +11,24 @@ "id": true, "type": "number" }, - "hourTheoretical": { + "zoneClosureHour": { "type": "date" }, - "totalVolume": { + "zoneHour": { + "type": "date" + }, + "volume": { "type": "number" }, - "remainingVolume": { + "hasToRecalcPrice": { + "type": "boolean" + }, + "m3": { "type": "number" }, - "speed": { + "minSpeed": { "type": "number" - }, - "hourEffective": { - "type": "date" - }, - "minutesLess": { - "type": "date" - }, - "etc": { - "type": "date" } - }, "relations": { "zone": { From 8da36569f77ca87810a97d7cf2b3e742a4265c45 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 17 Nov 2023 07:44:43 +0100 Subject: [PATCH 258/449] refactor: refs #4502 zoneEstimatedDelivery --- modules/monitor/back/methods/sales-monitor/salesFilter.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 2c62977f39..301e4ac35e 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -162,14 +162,12 @@ module.exports = Self => { const stmts = []; let stmt; - - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.filter'); - + stmts.push(`SET @_optimizer_search_depth = @@optimizer_search_depth`); stmts.push(`SET SESSION optimizer_search_depth = 0`); stmt = new ParameterizedSQL(` - CREATE TEMPORARY TABLE tmp.filter + CREATE OR REPLACE TEMPORARY TABLE tmp.filter (PRIMARY KEY (id)) ENGINE = MEMORY SELECT t.id, From bb6f3b4cfde1f3bf7608384d8987371c39bcb9ee Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 17 Nov 2023 08:56:25 +0100 Subject: [PATCH 259/449] fix: refs #6432 account sync fixes --- Dockerfile | 2 +- modules/account/back/models/samba-config.js | 20 ++++++++++++-------- modules/account/front/samba/index.html | 19 ++++++++++++------- modules/account/front/samba/locale/es.yml | 1 + 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index ce63da8ab7..61dd758b8b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,7 +31,7 @@ RUN apt-get update \ RUN apt-get update \ && apt-get install -y --no-install-recommends \ - samba-common-bin \ + samba-common-bin samba-dsdb-modules\ && rm -rf /var/lib/apt/lists/* \ && npm -g install pm2 diff --git a/modules/account/back/models/samba-config.js b/modules/account/back/models/samba-config.js index b6692be023..7714fb01cc 100644 --- a/modules/account/back/models/samba-config.js +++ b/modules/account/back/models/samba-config.js @@ -33,16 +33,17 @@ module.exports = Self => { .split('.') .map(part => `dc=${part}`) .join(','); - const ldapUser = `cn=${this.adUser},cn=Users,${baseDn}`; + const bindDn = `cn=${this.adUser},cn=Users,${baseDn}`; const adClient = ldap.createClient({ url: `ldaps://${this.adController}:636`, tlsOptions: {rejectUnauthorized: this.verifyCert} }); - await adClient.bind(ldapUser, this.adPassword); + await adClient.bind(bindDn, this.adPassword); Object.assign(this, { adClient, - fullUsersDn: `${this.userDn},${baseDn}` + fullUsersDn: `${this.userDn},${baseDn}`, + bindDn }); }, @@ -51,11 +52,14 @@ module.exports = Self => { }, async sambaTool(command, args = []) { - const authArgs = [ - '--URL', `ldap://${this.adController}`, - '--username', this.adUser, + let authArgs = [ + '--URL', `ldaps://${this.adController}`, + '--simple-bind-dn', this.bindDn, '--password', this.adPassword ]; + if (!this.verifyCert) + authArgs.push('--option', 'tls verify peer = no_check'); + const allArgs = [command].concat( args, authArgs ); @@ -151,8 +155,8 @@ module.exports = Self => { */ async getUsers(usersToSync) { const LDAP_MATCHING_RULE_BIT_AND = '1.2.840.113556.1.4.803'; - // eslint-disable-next-line max-len - const filter = `!(userAccountControl:${LDAP_MATCHING_RULE_BIT_AND}:=${UserAccountControlFlags.ACCOUNTDISABLE})`; + const filter = `!(userAccountControl:${LDAP_MATCHING_RULE_BIT_AND}` + + `:=${UserAccountControlFlags.ACCOUNTDISABLE})`; const opts = { scope: 'sub', diff --git a/modules/account/front/samba/index.html b/modules/account/front/samba/index.html index 4379f10a28..0186cac7c8 100644 --- a/modules/account/front/samba/index.html +++ b/modules/account/front/samba/index.html @@ -12,7 +12,7 @@ @@ -20,28 +20,33 @@ ng-if="watcher.hasData" class="vn-mt-md"> + + @@ -63,4 +68,4 @@ ng-click="watcher.loadOriginalData()"> - \ No newline at end of file + diff --git a/modules/account/front/samba/locale/es.yml b/modules/account/front/samba/locale/es.yml index d098a4fbec..efa3b15979 100644 --- a/modules/account/front/samba/locale/es.yml +++ b/modules/account/front/samba/locale/es.yml @@ -3,6 +3,7 @@ Domain controller: Controlador de dominio AD domain: Dominio AD AD user: Usuario AD AD password: Contraseña AD +User DN (without domain part): DN usuarios (sin la parte del dominio) Verify certificate: Verificar certificado Test connection: Probar conexión Samba connection established!: ¡Conexión con Samba establecida! From dc100f795989f449c60344040ec96eecb715963c Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 17 Nov 2023 11:29:57 +0100 Subject: [PATCH 260/449] fix(filter): refs #6461 now is mockDate in local --- modules/invoiceOut/front/negative-bases/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/invoiceOut/front/negative-bases/index.js b/modules/invoiceOut/front/negative-bases/index.js index f60668b200..7ce6105135 100644 --- a/modules/invoiceOut/front/negative-bases/index.js +++ b/modules/invoiceOut/front/negative-bases/index.js @@ -7,7 +7,7 @@ export default class Controller extends Section { super($element, $); this.vnReport = vnReport; - const now = new Date(); + const now = Date.vnNew(); const firstDayOfMonth = new Date(now.getFullYear(), now.getMonth(), 1); const lastDayOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0); this.params = { From 0ddfb28327a2723fe394eec50482f3669a6bf274 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 20 Nov 2023 07:56:15 +0100 Subject: [PATCH 261/449] refs #5914 fix: transferInvoice --- db/dump/dumpedFixtures.sql | 13 +- db/dump/structure.sql | 6 +- loopback/locale/es.json | 15 ++- .../invoiceOut/specs/transferinvoice.spec.js | 4 +- .../methods/invoiceOut/transferInvoice.js | 34 +++-- .../back/models/invoice-correction.json | 9 +- ...ype-477.json => sii-type-invoice-out.json} | 3 + .../front/descriptor-menu/index.html | 120 +++++++++--------- .../invoiceOut/front/descriptor-menu/index.js | 10 +- .../front/descriptor-menu/locale/es.yml | 2 +- modules/ticket/back/methods/sale/refund.js | 4 +- .../back/methods/ticket/invoiceTickets.js | 19 ++- .../ticket/back/methods/ticket/makeInvoice.js | 18 ++- modules/ticket/back/methods/ticket/refund.js | 2 +- 14 files changed, 155 insertions(+), 104 deletions(-) rename modules/invoiceOut/back/models/{cplus-invoice-type-477.json => sii-type-invoice-out.json} (86%) diff --git a/db/dump/dumpedFixtures.sql b/db/dump/dumpedFixtures.sql index 43eba7f241..5e3438dbfc 100644 --- a/db/dump/dumpedFixtures.sql +++ b/db/dump/dumpedFixtures.sql @@ -280,7 +280,18 @@ UNLOCK TABLES; LOCK TABLES `siiTypeInvoiceOut` WRITE; /*!40000 ALTER TABLE `siiTypeInvoiceOut` DISABLE KEYS */; -INSERT INTO `siiTypeInvoiceOut` VALUES (1,'F1 - Factura'),(2,'F2 - Factura simplificada (ticket)'),(3,'F3 - Factura emitida en sustitución de facturas simplificadas facturadas y declaradas'),(4,'F4 - Asiento resumen de facturas'),(5,'R1 - Factura rectificativa (Art. 80.1, 80.2 y error fundado en derecho)'),(6,'R2 - Factura rectificativa (Art. 80.3)'),(7,'R3 - Factura rectificativa (Art. 80.4)'),(8,'R4 - Factura rectificativa (Resto)'),(9,'R5 - Factura rectificativa en facturas simplificadas'); + +INSERT INTO `siiTypeInvoiceOut` (id, code, description) VALUES + (1, 'F1', 'Factura'), + (2, 'F2', 'Factura simplificada (ticket)'), + (3, 'F3', 'Factura emitida en sustitución de facturas simplificadas facturadas y declaradas'), + (4, 'F4', 'Asiento resumen de facturas'), + (5, 'R1', 'Factura rectificativa (Art. 80.1, 80.2 y error fundado en derecho)'), + (6, 'R2', 'Factura rectificativa (Art. 80.3)'), + (7, 'R3', 'Factura rectificativa (Art. 80.4)'), + (8, 'R4', 'Factura rectificativa (Resto)'), + (9, 'R5', 'Factura rectificativa en facturas simplificadas'); + /*!40000 ALTER TABLE `siiTypeInvoiceOut` ENABLE KEYS */; UNLOCK TABLES; diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 3dab0c5a49..2eecf6c30a 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -26001,9 +26001,11 @@ DROP TABLE IF EXISTS `siiTypeInvoiceOut`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `siiTypeInvoiceOut` ( `id` int(10) unsigned NOT NULL, + `code` varchar(2) NOT NULL, `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='(*18) TIPO FACTURA (Asientos)REPERCUTIDO - DEVENGADO (477)'; + PRIMARY KEY (`id`), + UNIQUE KEY `code_UNIQUE` (`code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Tipo de Factura Emitidas en el suministro de inmediato'; /*!40101 SET character_set_client = @saved_cs_client */; -- diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 239faff349..0dcbe0dc25 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -326,5 +326,16 @@ "The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada", "User disabled": "Usuario desactivado", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", - "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima" -} + "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", + "Base negativa para los tickets: 65": "Base negativa para los tickets: 65", + "Base negativa para los tickets: 67": "Base negativa para los tickets: 67", + "Base negativa para los tickets: 70": "Base negativa para los tickets: 70", + "Base negativa para los tickets: 72": "Base negativa para los tickets: 72", + "Base negativa para los tickets: 74": "Base negativa para los tickets: 74", + "Base negativa para los tickets: 33": "Base negativa para los tickets: 33", + "Base negativa para los tickets: 35": "Base negativa para los tickets: 35", + "Base negativa para los tickets: 37": "Base negativa para los tickets: 37", + "Base negativa para los tickets: 39": "Base negativa para los tickets: 39", + "Base negativa para los tickets: 41": "Base negativa para los tickets: 41", + "Base negativa para los tickets: 43": "Base negativa para los tickets: 43" +} \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js index 800a4ea835..dea4b6d007 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js @@ -24,7 +24,7 @@ describe('InvoiceOut tranferInvoice()', () => { const options = {transaction: tx}; const args = { id: '1', - ref: 'T4444444', + refFk: 'T4444444', newClientFk: 1, cplusRectificationId: 1, siiTypeInvoiceOutId: 1, @@ -49,7 +49,7 @@ describe('InvoiceOut tranferInvoice()', () => { const options = {transaction: tx}; const args = { id: '1', - ref: 'T1111111', + refFk: 'T1111111', newClientFk: 1101, cplusRectificationId: 1, siiTypeInvoiceOutId: 1, diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js index dde535c998..dcdd9b9b15 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js @@ -12,7 +12,7 @@ module.exports = Self => { description: 'Issued invoice id' }, { - arg: 'ref', + arg: 'refFk', type: 'string', required: true }, @@ -22,17 +22,17 @@ module.exports = Self => { required: true }, { - arg: 'cplusRectificationId', + arg: 'cplusRectificationFk', type: 'number', required: true }, { - arg: 'siiTypeInvoiceOutId', + arg: 'siiTypeInvoiceOutFk', type: 'number', required: true }, { - arg: 'invoiceCorrectionTypeId', + arg: 'invoiceCorrectionTypeFk', type: 'number', required: true }, @@ -50,14 +50,14 @@ module.exports = Self => { Self.transferInvoice = async(ctx, options) => { const models = Self.app.models; const myOptions = {userId: ctx.req.accessToken.userId}; - const args = ctx.args; + const {id, refFk, newClientFk, cplusRectificationFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk} = ctx.args; let tx; if (typeof options == 'object') Object.assign(myOptions, options); - const {clientFk} = await models.InvoiceOut.findById(args.id); + const {clientFk} = await models.InvoiceOut.findById(id); - if (clientFk == args.newClientFk) + if (clientFk == newClientFk) throw new UserError(`Select a different client`); if (!myOptions.transaction) { @@ -65,10 +65,10 @@ module.exports = Self => { myOptions.transaction = tx; } try { - const filterRef = {where: {refFk: args.ref}}; + const filterRef = {where: {refFk: refFk}}; const tickets = await models.Ticket.find(filterRef, myOptions); const ticketsIds = tickets.map(ticket => ticket.id); - await models.Ticket.refund(ctx, ticketsIds, null, myOptions); + const refundTickets = await models.Ticket.refund(ctx, ticketsIds, null, myOptions); const filterTicket = {where: {ticketFk: {inq: ticketsIds}}}; @@ -82,20 +82,16 @@ module.exports = Self => { const clonedTicketIds = []; for (const clonedTicket of clonedTickets) { - await clonedTicket.updateAttribute('clientFk', args.newClientFk, myOptions); + await clonedTicket.updateAttribute('clientFk', newClientFk, myOptions); clonedTicketIds.push(clonedTicket.id); } - const invoiceIds = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); - const [invoiceId] = invoiceIds; + const invoiceCorrection = + {correctedFk: id, cplusRectificationFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk}; + const refundTicketIds = refundTickets.map(ticket => ticket.id); - await models.InvoiceCorrection.create({ - correctingFk: invoiceId, - correctedFk: args.id, - cplusRectificationTypeFk: args.cplusRectificationId, - siiTypeInvoiceOutFk: args.siiTypeInvoiceOutId, - invoiceCorrectionTypeFk: args.invoiceCorrectionTypeId - }, myOptions); + await models.Ticket.invoiceTickets(ctx, refundTicketIds, invoiceCorrection, myOptions); + const [[invoiceId]] = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); if (tx) { await tx.commit(); diff --git a/modules/invoiceOut/back/models/invoice-correction.json b/modules/invoiceOut/back/models/invoice-correction.json index 43e4f07ef5..5924c9232f 100644 --- a/modules/invoiceOut/back/models/invoice-correction.json +++ b/modules/invoiceOut/back/models/invoice-correction.json @@ -16,13 +16,16 @@ "type": "number" }, "cplusRectificationTypeFk": { - "type": "number" + "type": "number", + "required": true }, "siiTypeInvoiceOutFk": { - "type": "number" + "type": "number", + "required": true }, "invoiceCorrectionTypeFk": { - "type": "number" + "type": "number", + "required": true } } } diff --git a/modules/invoiceOut/back/models/cplus-invoice-type-477.json b/modules/invoiceOut/back/models/sii-type-invoice-out.json similarity index 86% rename from modules/invoiceOut/back/models/cplus-invoice-type-477.json rename to modules/invoiceOut/back/models/sii-type-invoice-out.json index 17b3126178..58d50a12c5 100644 --- a/modules/invoiceOut/back/models/cplus-invoice-type-477.json +++ b/modules/invoiceOut/back/models/sii-type-invoice-out.json @@ -12,6 +12,9 @@ "type": "number", "description": "Identifier" }, + "code": { + "type": "string" + }, "description": { "type": "string" } diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index 0052f0c037..267aa0b153 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -7,7 +7,8 @@ + data="siiTypeInvoiceOuts" + where="{code: {like: 'R%'}}"> + + transferInvoice +
- - - - #{{id}} - {{::name}} - - - - - {{::description}} - - - - - - - - - -
+ + + + #{{id}} - {{::name}} + + + + + {{::description}} + + + + + + + {{::code}} - {{::description}} + + + + + +
diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index d3862a753c..f9d436092c 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -129,11 +129,11 @@ class Controller extends Section { transferInvoice() { const params = { id: this.invoiceOut.id, - ref: this.invoiceOut.ref, - newClientFk: this.invoiceOut.client.id, - cplusRectificationId: this.cplusRectificationType, - siiTypeInvoiceOutId: this.siiTypeInvoiceOut, - invoiceCorrectionTypeId: this.invoiceCorrectionType + refFk: this.invoiceOut.ref, + newClientFk: this.clientId, + cplusRectificationFk: this.cplusRectificationType, + siiTypeInvoiceOutFk: this.siiTypeInvoiceOut, + invoiceCorrectionTypeFk: this.invoiceCorrectionType }; this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => { const invoiceId = res.data; diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml index 0f74b5fece..9456646afc 100644 --- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml +++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml @@ -22,4 +22,4 @@ The email can't be empty: El correo no puede estar vacío The following refund tickets have been created: "Se han creado los siguientes tickets de abono: {{ticketIds}}" Refund...: Abono... Transfer invoice to...: Transferir factura a... -Cplus Type: Cplus Tipo +Rectificative type: Tipo rectificativa diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 17b70f12bd..a7831e7e35 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -19,7 +19,7 @@ module.exports = Self => { } ], returns: { - type: ['number'], + type: ['object'], root: true }, http: { @@ -54,7 +54,7 @@ module.exports = Self => { if (tx) await tx.commit(); - return refundsTicket[0]; + return refundsTicket; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/ticket/back/methods/ticket/invoiceTickets.js b/modules/ticket/back/methods/ticket/invoiceTickets.js index fa3ee93af2..29fb1769b7 100644 --- a/modules/ticket/back/methods/ticket/invoiceTickets.js +++ b/modules/ticket/back/methods/ticket/invoiceTickets.js @@ -10,7 +10,13 @@ module.exports = function(Self) { description: 'The tickets id', type: ['number'], required: true + }, + { + arg: 'invoiceCorrection', + description: 'The invoice correction', + type: 'object', } + ], returns: { type: ['object'], @@ -22,7 +28,7 @@ module.exports = function(Self) { } }); - Self.invoiceTickets = async(ctx, ticketsIds, options) => { + Self.invoiceTickets = async(ctx, ticketsIds, invoiceCorrection, options) => { const models = Self.app.models; const date = Date.vnNew(); date.setHours(0, 0, 0, 0); @@ -68,9 +74,9 @@ module.exports = function(Self) { const addressIds = result.map(address => address.addressFk); for (const address of addressIds) - await createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, myOptions); + await createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, invoiceCorrection, myOptions); } else - await createInvoice(ctx, companyId, ticketsIds, null, invoicesIds, myOptions); + await createInvoice(ctx, companyId, ticketsIds, null, invoicesIds, invoiceCorrection, myOptions); if (tx) await tx.commit(); } catch (e) { @@ -85,9 +91,9 @@ module.exports = function(Self) { return invoicesIds; }; - async function createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, myOptions) { + async function createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, invoiceCorrection, myOptions) { const models = Self.app.models; - + console.log(ticketsIds, address); await models.Ticket.rawSql(` CREATE OR REPLACE TEMPORARY TABLE tmp.ticketToInvoice (PRIMARY KEY (id)) @@ -98,7 +104,8 @@ module.exports = function(Self) { ${address ? `AND addressFk = ${address}` : ''} `, [ticketsIds], myOptions); - const invoiceId = await models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), myOptions); + const invoiceId = + await models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), invoiceCorrection, myOptions); invoicesIds.push(invoiceId); } }; diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js index e18e58e0b4..9618e49e0b 100644 --- a/modules/ticket/back/methods/ticket/makeInvoice.js +++ b/modules/ticket/back/methods/ticket/makeInvoice.js @@ -22,6 +22,11 @@ module.exports = function(Self) { description: 'The invoice date', type: 'date', required: true + }, + { + arg: 'invoiceCorrection', + description: 'The invoice correction', + type: 'object', } ], returns: { @@ -34,7 +39,7 @@ module.exports = function(Self) { } }); - Self.makeInvoice = async(ctx, invoiceType, companyFk, invoiceDate, options) => { + Self.makeInvoice = async(ctx, invoiceType, companyFk, invoiceDate, invoiceCorrection, options) => { const models = Self.app.models; invoiceDate.setHours(0, 0, 0, 0); @@ -67,8 +72,8 @@ module.exports = function(Self) { const [firstTicket] = tickets; const clientId = firstTicket.clientFk; - const clientCanBeInvoiced = await models.Client.canBeInvoiced(clientId, companyFk, myOptions); - if (!clientCanBeInvoiced) + const clientCanBeInvoiced = await models.Client.canBeInvoiced(clientId, companyFk, invoiceCorrection, myOptions); + if (!clientCanBeInvoiced && !invoiceCorrection) throw new UserError(`This client can't be invoiced`); const query = `SELECT vn.invoiceSerial(?, ?, ?) AS serial`; @@ -85,6 +90,13 @@ module.exports = function(Self) { if (!resultInvoice) throw new UserError('No tickets to invoice', 'notInvoiced'); + if (invoiceCorrection) { + await models.InvoiceCorrection.create( + Object.assign(invoiceCorrection, {correctingFk: resultInvoice.id}), + myOptions + ); + } + if (serial != 'R' && resultInvoice.id) await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions); diff --git a/modules/ticket/back/methods/ticket/refund.js b/modules/ticket/back/methods/ticket/refund.js index 758384ae2b..4fed022606 100644 --- a/modules/ticket/back/methods/ticket/refund.js +++ b/modules/ticket/back/methods/ticket/refund.js @@ -15,7 +15,7 @@ module.exports = Self => { } ], returns: { - type: ['number'], + type: ['object'], root: true }, http: { From 61b2d4c5fdc06d0e7fdb312a3b1e3d71de51d9dc Mon Sep 17 00:00:00 2001 From: guillermo Date: Mon, 20 Nov 2023 09:47:57 +0100 Subject: [PATCH 262/449] refactor: refs #4502 zoneEstimatedDelivery --- db/dump/structure.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 3d6156580a..e903676828 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -82151,7 +82151,7 @@ USE `vn`; /*!50001 SET collation_connection = utf8mb4_unicode_ci */; /*!50001 CREATE ALGORITHM=UNDEFINED */ /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ -/*!50001 VIEW `zoneEstimatedDelivery` AS select `t`.`zoneFk` AS `zoneFk`,cast(`util`.`VN_CURDATE`() + interval hour(ifnull(`zc`.`hour`,`z`.`hour`)) * 60 + minute(ifnull(`zc`.`hour`,`z`.`hour`)) minute as time) AS `hourTheoretical`,cast(sum(`sv`.`volume`) as decimal(5,1)) AS `totalVolume`,cast(sum(if(`s`.`alertLevel` < 2,`sv`.`volume`,0)) as decimal(5,1)) AS `remainingVolume`,greatest(ifnull(`lhp`.`m3`,0),ifnull(`dl`.`minSpeed`,0)) AS `speed`,cast(`zc`.`hour` + interval -sum(if(`s`.`alertLevel` < 2,`sv`.`volume`,0)) * 60 / greatest(ifnull(`lhp`.`m3`,0),ifnull(`dl`.`minSpeed`,0)) minute as time) AS `hourEffective`,floor(-sum(if(`s`.`alertLevel` < 2,`sv`.`volume`,0)) * 60 / greatest(ifnull(`lhp`.`m3`,0),ifnull(`dl`.`minSpeed`,0))) AS `minutesLess`,cast(`zc`.`hour` + interval -sum(if(`s`.`alertLevel` < 2,`sv`.`volume`,0)) * 60 / greatest(ifnull(`lhp`.`m3`,0),ifnull(`dl`.`minSpeed`,0)) minute as time) AS `etc` from (((((((((`vn`.`ticket` `t` join `vn`.`ticketStateToday` `tst` on(`tst`.`ticket` = `t`.`id`)) join `vn`.`state` `s` on(`s`.`id` = `tst`.`state`)) join `vn`.`saleVolume` `sv` on(`sv`.`ticketFk` = `t`.`id`)) left join `vn`.`lastHourProduction` `lhp` on(`lhp`.`warehouseFk` = `t`.`warehouseFk`)) join `vn`.`warehouse` `w` on(`w`.`id` = `t`.`warehouseFk`)) join `vn`.`warehouseAlias` `wa` on(`wa`.`id` = `w`.`aliasFk`)) straight_join `vn`.`zone` `z` on(`z`.`id` = `t`.`zoneFk`)) left join `vn`.`zoneClosure` `zc` on(`zc`.`zoneFk` = `t`.`zoneFk` and `zc`.`dated` = `util`.`VN_CURDATE`())) left join `cache`.`departure_limit` `dl` on(`dl`.`warehouse_id` = `t`.`warehouseFk` and `dl`.`fecha` = `util`.`VN_CURDATE`())) where `w`.`hasProduction` <> 0 and cast(`t`.`shipped` as date) = `util`.`VN_CURDATE`() group by `t`.`zoneFk` */; +/*!50001 VIEW `zoneEstimatedDelivery` AS SELECT `t`.`zoneFk` AS `zoneFk`, `zc`.`hour` AS `zoneClosureHour`, `z`.`hour` AS `zoneHour`, `sv`.`volume` AS `volume`, `al`.`hasToRecalcPrice` AS `hasToRecalcPrice`, `lhp`.`m3` AS `m3`, `dl`.`minSpeed` AS `minSpeed` FROM ((((((((((`vn`.`ticket` `t` JOIN `vn`.`ticketStateToday` `tst` ON (`tst`.`ticket` = `t`.`id`)) JOIN `vn`.`state` `s` ON (`s`.`id` = `tst`.`state`)) JOIN `vn`.`saleVolume` `sv` ON (`sv`.`ticketFk` = `t`.`id`)) LEFT JOIN `vn`.`lastHourProduction` `lhp` ON (`lhp`.`warehouseFk` = `t`.`warehouseFk`)) JOIN `vn`.`warehouse` `w` ON (`w`.`id` = `t`.`warehouseFk`)) JOIN `vn`.`warehouseAlias` `wa` ON (`wa`.`id` = `w`.`aliasFk`)) STRAIGHT_JOIN `vn`.`zone` `z` ON (`z`.`id` = `t`.`zoneFk`)) LEFT JOIN `vn`.`zoneClosure` `zc` ON (`zc`.`zoneFk` = `t`.`zoneFk` AND `zc`.`dated` = `util`.`VN_CURDATE`())) LEFT JOIN `cache`.`departure_limit` `dl` ON (`dl`.`warehouse_id` = `t`.`warehouseFk` AND `dl`.`fecha` = `util`.`VN_CURDATE`())) JOIN `vn`.`alertLevel` `al` ON (`al`.`id` = `s`.`alertLevel`)) WHERE `w`.`hasProduction` <> 0 AND CAST(`t`.`shipped` AS date) = `util`.`VN_CURDATE`() */; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; From ee1a0c15eeb615463dd7ae86aa4d0cf6a7cacb42 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 20 Nov 2023 15:09:55 +0100 Subject: [PATCH 263/449] refs #6454 feat: dump db --- db/dump/dumpedFixtures.sql | 84 +- db/dump/fixtures.sql | 36 +- db/dump/structure.sql | 6508 ++++++++++------- db/export-data.sh | 6 +- loopback/locale/en.json | 6 +- modules/client/back/methods/client/filter.js | 9 +- .../ticket/specs/getSalespersonMana.spec.js | 2 +- 7 files changed, 3867 insertions(+), 2784 deletions(-) diff --git a/db/dump/dumpedFixtures.sql b/db/dump/dumpedFixtures.sql index 43eba7f241..3e46c8e04e 100644 --- a/db/dump/dumpedFixtures.sql +++ b/db/dump/dumpedFixtures.sql @@ -22,7 +22,7 @@ USE `util`; LOCK TABLES `config` WRITE; /*!40000 ALTER TABLE `config` DISABLE KEYS */; -INSERT INTO `config` VALUES (1,'233401',0,'production',NULL,'2001-01-01 11:00:00',NULL,0); +INSERT INTO `config` VALUES (1,'234604',0,'production',NULL,'2001-01-01 11:00:00',NULL,0); /*!40000 ALTER TABLE `config` ENABLE KEYS */; UNLOCK TABLES; @@ -32,7 +32,7 @@ UNLOCK TABLES; LOCK TABLES `version` WRITE; /*!40000 ALTER TABLE `version` DISABLE KEYS */; -INSERT INTO `version` VALUES ('salix','10230','53f69ae8e526a4a5d827c237a5b076d38507b392','2020-11-09 11:06:43',NULL),('vn-database','10714','aeb89a7b54f62398ddbcf3a48c8d387f275fee47','2023-08-29 12:49:52','10716'); +INSERT INTO `version` VALUES ('salix','10230','53f69ae8e526a4a5d827c237a5b076d38507b392','2020-11-09 11:06:43',NULL),('vn-database','10761','6c1146271aa71f7c3332e11d50d6812752391ea4','2023-11-20 11:55:47','10778'); /*!40000 ALTER TABLE `version` ENABLE KEYS */; UNLOCK TABLES; @@ -42,7 +42,7 @@ UNLOCK TABLES; LOCK TABLES `versionLog` WRITE; /*!40000 ALTER TABLE `versionLog` DISABLE KEYS */; -INSERT INTO `versionLog` VALUES ('vn-database','00001','00-test.sql','juan@10.5.1.3','2022-01-31 10:12:26',NULL,NULL),('vn-database','00003','00-sage.sql','juan@10.5.1.3','2022-01-31 10:12:26',NULL,NULL),('vn-database','10008','00-alterRoleConfig.sql','juan@10.5.1.3','2022-01-31 10:12:26',NULL,NULL),('vn-database','10014','00-rolePrefix.sql','jenkins@10.0.2.68','2022-02-11 00:13:25',NULL,NULL),('vn-database','10017','01-firstScript.sql','jenkins@10.0.2.70','2022-03-09 11:36:54',NULL,NULL),('vn-database','10021','00-bankAccount.sql','jenkins@10.0.2.69','2022-03-16 14:11:22',NULL,NULL),('vn-database','10023','00-firstScript.sql','jenkins@10.0.2.69','2022-03-16 15:05:29',NULL,NULL),('vn-database','10026','00-invoiceInIntrastat.sql','jenkins@10.0.2.69','2022-03-21 15:10:53',NULL,NULL),('vn-database','10027','00-Clientes_cedidos.sql','jenkins@10.0.2.69','2022-03-22 15:58:12',NULL,NULL),('vn-database','10028','00-item_last_buy_.sql','jenkins@10.0.2.69','2022-03-22 15:58:12',NULL,NULL),('vn-database','10029','00-bankToViewAccountingToTable.sql','jenkins@10.0.2.69','2022-03-22 15:58:12',NULL,NULL),('vn-database','10030','00-KkejarNiche.sql','jenkins@10.0.2.69','2022-03-22 15:58:12',NULL,NULL),('vn-database','10036','00-updateBuyConfig.sql','jenkins@10.0.2.69','2022-03-29 12:36:54',NULL,NULL),('vn-database','10037','00-firstScript.sql','jenkins@10.0.2.69','2022-03-28 11:14:26',NULL,NULL),('vn-database','10038','00-printServerQueue.sql','jenkins@10.0.2.69','2022-03-29 08:13:24',NULL,NULL),('vn-database','10048','00-firstScript.sql','jenkins@10.0.2.69','2022-03-30 12:29:06',NULL,NULL),('vn-database','10058','00-vehicleAddFields.sql','jenkins@10.0.2.69','2022-04-06 08:48:34',NULL,NULL),('vn-database','10060','00-firstScript.sql','jenkins@10.0.2.69','2022-04-07 08:50:11',NULL,NULL),('vn-database','10062','00-firstScript.sql','jenkins@10.0.2.69','2022-04-06 10:51:45',NULL,NULL),('vn-database','10064','00-firstScript.sql','jenkins@10.0.2.69','2022-04-06 13:57:11',NULL,NULL),('vn-database','10066','00-firstScript.sql','jenkins@10.0.2.69','2022-04-07 08:50:12',NULL,NULL),('vn-database','10067','00-firstScript.sql','jenkins@10.0.2.69','2022-04-08 10:18:20',NULL,NULL),('vn-database','10071','00-packingSiteLog.sql','jenkins@10.0.2.69','2022-04-08 09:37:30',NULL,NULL),('vn-database','10072','00-firstScript.sql','jenkins@10.0.2.69','2022-04-08 11:01:46',NULL,NULL),('vn-database','10073','00-firstScript.sql','jenkins@10.0.2.69','2022-04-08 13:40:56',NULL,NULL),('vn-database','10074','00-firstScript.sql','jenkins@10.0.2.69','2022-04-10 13:15:05',NULL,NULL),('vn-database','10077','00-firstScript.sql','jenkins@10.0.2.69','2022-04-12 08:07:15',NULL,NULL),('vn-database','10078','00-firstScript.sql','jenkins@10.0.2.69','2022-04-13 07:44:21',NULL,NULL),('vn-database','10079','00-firstScript.sql','jenkins@10.0.2.69','2022-04-12 12:01:37',NULL,NULL),('vn-database','10086','00-firstScript.sql','jenkins@10.0.2.69','2022-04-13 08:58:34',NULL,NULL),('vn-database','10087','00-firstScript.sql','jenkins@10.0.2.69','2022-04-13 09:39:49',NULL,NULL),('vn-database','10088','00-firstScript.sql','jenkins@10.0.2.69','2022-04-13 15:05:12',NULL,NULL),('vn-database','10089','00-firstScript.sql','jenkins@10.0.2.69','2022-04-18 14:12:52',NULL,NULL),('vn-database','10090','00-firstScript.sql','jenkins@10.0.2.69','2022-04-18 14:34:46',NULL,NULL),('vn-database','10092','00-firstScript.sql','jenkins@10.0.2.69','2022-04-19 14:45:46',NULL,NULL),('vn-database','10093','00-autoradioConfig.sql','jenkins@10.0.2.69','2022-05-03 09:16:47',NULL,NULL),('vn-database','10094','00-firstScript.sql','jenkins@10.0.2.69','2022-04-20 10:57:30',NULL,NULL),('vn-database','10097','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 10:12:59',NULL,NULL),('vn-database','10099','00-firstScript.sql','jenkins@10.0.2.69','2022-04-20 14:35:27',NULL,NULL),('vn-database','10100','00-firstScript.sql','jenkins@10.0.2.69','2022-04-20 14:35:27',NULL,NULL),('vn-database','10101','00-firstScript.sql','jenkins@10.0.2.69','2022-04-21 14:59:31',NULL,NULL),('vn-database','10103','00-awbVolume.sql','jenkins@10.0.2.69','2022-05-05 10:12:59',NULL,NULL),('vn-database','10104','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 10:12:59',NULL,NULL),('vn-database','10105','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 10:13:00',NULL,NULL),('vn-database','10107','00-firstScript.sql','jenkins@10.0.2.69','2022-04-23 10:53:53',NULL,NULL),('vn-database','10112','00-firstScript.sql','jenkins@10.0.2.69','2022-05-09 09:14:53',NULL,NULL),('vn-database','10113','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 10:13:00',NULL,NULL),('vn-database','10114','00-updateConfig.sql','jenkins@10.0.2.69','2022-04-27 13:37:25',NULL,NULL),('vn-database','10116','00-firstScript.sql','jenkins@10.0.2.69','2022-04-28 11:10:14',NULL,NULL),('vn-database','10118','00-firstScript.sql','jenkins@10.0.2.69','2022-04-29 08:10:15',NULL,NULL),('vn-database','10119','00-AfegirFKPart1.sql','jenkins@10.0.2.69','2022-05-05 10:13:00',NULL,NULL),('vn-database','10119','01-AfegirFkPart2.sql','jenkins@10.0.2.69','2022-05-05 10:22:25',NULL,NULL),('vn-database','10125','00-firstScript.sql','jenkins@10.0.2.68','2022-05-18 18:44:30',NULL,NULL),('vn-database','10127','00-firstScript.sql','jenkins@10.0.2.69','2022-05-02 11:04:46',NULL,NULL),('vn-database','10128','00-firstScript.sql','jenkins@10.0.2.69','2022-05-02 13:04:31',NULL,NULL),('vn-database','10129','00-firstScript.sql','jenkins@10.0.2.69','2022-05-03 08:21:01',NULL,NULL),('vn-database','10132','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 10:22:25',NULL,NULL),('vn-database','10133','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 14:32:30',NULL,NULL),('vn-database','10134','00-firstScript.sql','jenkins@10.0.2.69','2022-05-06 07:45:25',NULL,NULL),('vn-database','10135','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 08:46:17',NULL,NULL),('vn-database','10136','00-workerTimeControl.sql','jenkins@10.0.2.69','2022-05-09 13:51:12',NULL,NULL),('vn-database','10138','00-firstScript.sql','jenkins@10.0.2.69','2022-05-10 13:58:05',NULL,NULL),('vn-database','10139','00-firstScript.sql','jenkins@10.0.2.68','2022-05-16 14:32:37',NULL,NULL),('vn-database','10139','01-secondScript.sql','jenkins@10.0.2.68','2022-05-17 12:16:13',NULL,NULL),('vn-database','10141','00-firstScript.sql','jenkins@10.0.2.70','2022-05-12 08:27:31',NULL,NULL),('vn-database','10142','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:20:31',NULL,NULL),('vn-database','10143','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:20:31',NULL,NULL),('vn-database','10144','00-AfegirFKPArt1.sql','jenkins@10.0.2.68','2022-05-20 09:22:33',NULL,NULL),('vn-database','10144','00-firstScript.sql','jenkins@10.0.2.68','2022-05-13 09:44:25',NULL,NULL),('vn-database','10147','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:22:33',NULL,NULL),('vn-database','10149','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:22:33',NULL,NULL),('vn-database','10150','00-firstScript.sql','jenkins@10.0.2.68','2022-05-17 09:57:16',NULL,NULL),('vn-database','10152','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:22:34',NULL,NULL),('vn-database','10153','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:22:34',NULL,NULL),('vn-database','10154','00-compressionKk.sql','jenkins@10.0.2.68','2022-05-20 09:22:34',NULL,NULL),('vn-database','10157','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:22:35',NULL,NULL),('vn-database','10158','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:21',NULL,NULL),('vn-database','10160','00-firstScript.sql','jenkins@10.0.2.69','2022-06-30 09:30:50',NULL,NULL),('vn-database','10163','00-firstScript.sql','jenkins@10.0.2.68','2022-05-23 08:17:14',NULL,NULL),('vn-database','10164','00-borrarSectorsDesus.sql','jenkins@10.0.2.68','2022-06-02 12:47:21',NULL,NULL),('vn-database','10165','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10166','00-firstScript.sql','jenkins@10.0.2.68','2022-05-24 16:11:21',NULL,NULL),('vn-database','10167','00-renameVnActiveContrat.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10168','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10169','00-createTableBankEntityConfig.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10169','02-addNotNullToBankEntityBic.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10171','00-volumeConfig.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-18 14:11:11',NULL,NULL),('vn-database','10171','01-itemWeight.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-18 16:01:34',NULL,NULL),('vn-database','10171','02-agencymode.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-18 16:01:34',NULL,NULL),('vn-database','10172','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10174','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 08:46:17',NULL,NULL),('vn-database','10175','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:03:41',NULL,NULL),('vn-database','10177','00-crearTablaSpecialLabels.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10178','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:24',NULL,NULL),('vn-database','10179','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:24',NULL,NULL),('vn-database','10183','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:24',NULL,NULL),('vn-database','10184','00-firstScript.sql','jenkins@10.0.2.68','2022-06-03 08:05:34',NULL,NULL),('vn-database','10185','00-firstScript.sql','jenkins@10.0.2.68','2022-06-06 09:07:45',NULL,NULL),('vn-database','10186','00-desactivar_trigger.sql','jenkins@10.0.2.68','2022-06-07 09:31:23',NULL,NULL),('vn-database','10186','01-alter_Table_buy.sql','jenkins@10.0.2.68','2022-06-07 09:34:47',NULL,NULL),('vn-database','10186','02-alter_table_entryConfig.sql','jenkins@10.0.2.68','2022-06-07 09:34:47',NULL,NULL),('vn-database','10186','04-regularizar_Sticker_Inventario.sql','jenkins@10.0.2.68','2022-06-07 09:34:51',NULL,NULL),('vn-database','10186','09-reactivar_trigger.sql','jenkins@10.0.2.68','2022-06-07 09:34:51',NULL,NULL),('vn-database','10187','00-firstScript.sql','jenkins@10.0.2.68','2022-06-06 12:37:31',NULL,NULL),('vn-database','10188','00-firstScript.sql','jenkins@10.0.2.68','2022-06-06 14:03:36',NULL,NULL),('vn-database','10189','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:03:41',NULL,NULL),('vn-database','10191','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:03:41',NULL,NULL),('vn-database','10193','00-delete.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:35',NULL,NULL),('vn-database','10193','01-botanicExport.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:43',NULL,NULL),('vn-database','10193','02-item.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:44',NULL,NULL),('vn-database','10193','03-autonomy.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:44',NULL,NULL),('vn-database','10193','03-turn.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:44',NULL,NULL),('vn-database','10193','04-country.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:44',NULL,NULL),('vn-database','10194','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:03:41',NULL,NULL),('vn-database','10195','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:03:41',NULL,NULL),('vn-database','10200','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:04:00',NULL,NULL),('vn-database','10201','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:04:00',NULL,NULL),('vn-database','10202','00-Remove_FK_to_ediGenus.sql','jenkins@10.0.2.69','2022-06-17 09:04:00',NULL,NULL),('vn-database','10203','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:04:01',NULL,NULL),('vn-database','10204','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:04:01',NULL,NULL),('vn-database','10205','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:04:21',NULL,NULL),('vn-database','10207','00-Alter_table_entry.sql','jenkins@10.0.2.69','2022-06-16 07:22:50',NULL,NULL),('vn-database','10207','01-Update_invoiceAmount.sql','jenkins@10.0.2.69','2022-06-16 07:23:00',NULL,NULL),('vn-database','10208','00-firstScript.sql','jenkins@10.0.2.69','2022-06-30 09:31:26',NULL,NULL),('vn-database','10209','00-firstScript.sql','jenkins@10.0.2.69','2022-06-16 08:47:40',NULL,NULL),('vn-database','10210','00-firstScript.sql','jenkins@10.0.2.69','2022-06-16 17:39:17',1046,'Base de datos no seleccionada'),('vn-database','10211','01-firstScript.sql','jenkins@10.0.2.69','2022-06-17 07:11:27',NULL,NULL),('vn-database','10215','00-renameIsInventory.sql','jenkins@10.0.2.69','2022-06-30 09:31:26',NULL,NULL),('vn-database','10216','00-firstScript.sql','jenkins@10.0.2.69','2022-06-23 11:15:28',NULL,NULL),('vn-database','10216','01-batchIndex.sql','jenkins@10.0.2.70','2022-06-27 18:10:55',NULL,NULL),('vn-database','10219','00-AddCollectionFkOnPackingSite.sql','jenkins@10.0.2.70','2022-06-29 09:23:42',NULL,NULL),('vn-database','10219','01-AddFkToCollectionFk.sql','jenkins@10.0.2.70','2022-06-29 09:23:43',NULL,NULL),('vn-database','10220','00-createPersonalProtectionEquipment.sql','jenkins@10.0.2.69','2022-06-30 09:31:26',NULL,NULL),('vn-database','10222','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:12:40',NULL,NULL),('vn-database','10223','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:13:52',NULL,NULL),('vn-database','10224','00-cosetes.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-21 12:03:45',NULL,NULL),('vn-database','10229','00-firstScript.sql','jenkins@10.0.2.69','2022-07-01 11:59:34',NULL,NULL),('vn-database','10231','01-tablaEktConfig.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:25:39',NULL,NULL),('vn-database','10233','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:13:53',NULL,NULL),('vn-database','10235','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:13:53',NULL,NULL),('vn-database','10236','00-firstScript.sql','jenkins@10.0.2.69','2022-07-05 12:11:40',NULL,NULL),('vn-database','10237','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:13:53',NULL,NULL),('vn-database','10238','00-worker_mobileExtension.sql','jenkins@10.0.2.69','2022-07-14 09:14:09',NULL,NULL),('vn-database','10239','00-firstScript.sql','jenkins@10.0.2.69','2022-07-07 21:51:58',NULL,NULL),('vn-database','10241','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-29 08:14:01',NULL,NULL),('vn-database','10242','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:14:32',NULL,NULL),('vn-database','10243','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:14:32',NULL,NULL),('vn-database','10245','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:34:51',NULL,NULL),('vn-database','10247','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:34:51',NULL,NULL),('vn-database','10248','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-20 17:27:51',NULL,NULL),('vn-database','10250','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:36:40',NULL,NULL),('vn-database','10253','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:36:57',NULL,NULL),('vn-database','10254','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:38:48',NULL,NULL),('vn-database','10256','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:38:48',NULL,NULL),('vn-database','10258','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-12-16 09:14:48',NULL,NULL),('vn-database','10259','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-02 08:54:56',NULL,NULL),('vn-database','10261','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-22 08:42:20',NULL,NULL),('vn-database','10262','00-createTablepackagingWithFreight.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:13',NULL,NULL),('vn-database','10262','01-alterTablePackagingConfig.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:13',NULL,NULL),('vn-database','10262','02-insertsInicials.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:13',NULL,NULL),('vn-database','10262','03-createTablepackingWithoutFreight.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:14',NULL,NULL),('vn-database','10263','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:38:48',NULL,NULL),('vn-database','10265','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:38:48',NULL,NULL),('vn-database','10267','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:17',NULL,NULL),('vn-database','10267','01-fixMerge.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:17',NULL,NULL),('vn-database','10275','00-improvedGeneralLog.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-01 09:55:56',NULL,NULL),('vn-database','10277','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:26:32',NULL,NULL),('vn-database','10278','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-01 17:51:41',NULL,NULL),('vn-database','10279','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:17',NULL,NULL),('vn-database','10281','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:18',NULL,NULL),('vn-database','10282','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:18',NULL,NULL),('vn-database','10283','00-alterTable.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:18',NULL,NULL),('vn-database','10284','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-04 16:59:08',NULL,NULL),('vn-database','10285','00-firstScript.sql','jenkins@swarm-worker3.static.verdnatura.es','2022-08-05 09:19:33',NULL,NULL),('vn-database','10287','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:35:24',NULL,NULL),('vn-database','10288','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:35:24',NULL,NULL),('vn-database','10289','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:36',NULL,NULL),('vn-database','10291','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-10 14:19:34',NULL,NULL),('vn-database','10293','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:26:32',NULL,NULL),('vn-database','10297','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-16 12:43:36',NULL,NULL),('vn-database','10298','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-13 21:04:13',NULL,NULL),('vn-database','10299','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:14',NULL,NULL),('vn-database','10301','00-productionConfig.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:14',NULL,NULL),('vn-database','10301','01-drop.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:14',NULL,NULL),('vn-database','10301','02-collection.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:15',NULL,NULL),('vn-database','10302','00-CreateTableEntryType.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:15',NULL,NULL),('vn-database','10302','01-insertDataEntryType.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:15',NULL,NULL),('vn-database','10302','02-alterTableEntry.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:22',NULL,NULL),('vn-database','10303','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:23',NULL,NULL),('vn-database','10304','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:23:48',NULL,NULL),('vn-database','10304','01-altertableticket.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:23:51',NULL,NULL),('vn-database','10305','00-ektAssign.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:24:52',NULL,NULL),('vn-database','10306','00-deliveryInformation.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:25:25',NULL,NULL),('vn-database','10307','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:25:26',NULL,NULL),('vn-database','10308','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:26:43',NULL,NULL),('vn-database','10309','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-06 11:37:54',NULL,NULL),('vn-database','10310','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:26:33',NULL,NULL),('vn-database','10311','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-06 11:37:55',NULL,NULL),('vn-database','10312','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:26:33',NULL,NULL),('vn-database','10313','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:27:21',NULL,NULL),('vn-database','10314','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-20 12:37:19',NULL,NULL),('vn-database','10315','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:31:43',NULL,NULL),('vn-database','10317','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:31:43',NULL,NULL),('vn-database','10318','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:31:43',NULL,NULL),('vn-database','10319','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-20 12:37:41',NULL,NULL),('vn-database','10320','00-operator.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:37',NULL,NULL),('vn-database','10320','01-collection.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:37',NULL,NULL),('vn-database','10320','02-productionConfig.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:38',NULL,NULL),('vn-database','10321','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 11:11:12',NULL,NULL),('vn-database','10322','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-09 09:19:05',NULL,NULL),('vn-database','10326','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:38',NULL,NULL),('vn-database','10328','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:38',NULL,NULL),('vn-database','10329','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:38',NULL,NULL),('vn-database','10330','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:30',NULL,NULL),('vn-database','10332','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:30',NULL,NULL),('vn-database','10334','00-collectionHotbed.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:30',NULL,NULL),('vn-database','10334','01-saleGroupDetail.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:32',NULL,NULL),('vn-database','10335','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:38',NULL,NULL),('vn-database','10336','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:32',NULL,NULL),('vn-database','10337','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:32',NULL,NULL),('vn-database','10339','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-19 09:41:19',NULL,NULL),('vn-database','10340','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-29 11:08:03',NULL,NULL),('vn-database','10341','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:32',NULL,NULL),('vn-database','10342','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-29 11:08:03',NULL,NULL),('vn-database','10343','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:35:30',NULL,NULL),('vn-database','10345','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-11-04 08:25:16',NULL,NULL),('vn-database','10347','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-29 11:08:03',NULL,NULL),('vn-database','10347','01-addVirtualField.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-29 11:08:03',NULL,NULL),('vn-database','10349','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:38',NULL,NULL),('vn-database','10350','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-30 10:11:56',NULL,NULL),('vn-database','10352','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-11-04 08:25:16',NULL,NULL),('vn-database','10353','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:38',NULL,NULL),('vn-database','10354','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:38',NULL,NULL),('vn-database','10356','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-10 22:35:00',NULL,NULL),('vn-database','10356','01-orderConfigFk.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-10 22:35:00',NULL,NULL),('vn-database','10356','02-orderConfigDrop.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-10 22:35:00',NULL,NULL),('vn-database','10357','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:38',NULL,NULL),('vn-database','10359','00-improvedGeneralLog_collate.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:39',NULL,NULL),('vn-database','10360','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:39',NULL,NULL),('vn-database','10361','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 11:16:07',NULL,NULL),('vn-database','10362','00-dropUdfs.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-10 11:01:15',NULL,NULL),('vn-database','10363','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-11-04 08:25:17',NULL,NULL),('vn-database','10365','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-13 19:30:46',NULL,NULL),('vn-database','10368','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-11-04 08:25:17',NULL,NULL),('vn-database','10369','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-14 13:38:06',NULL,NULL),('vn-database','10370','00-deleteForeignKey.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:41',NULL,NULL),('vn-database','10370','01-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:47',NULL,NULL),('vn-database','10370','02-deleteTable.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:49',NULL,NULL),('vn-database','10370','03-accion.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:49',NULL,NULL),('vn-database','10370','04-inter.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:53',NULL,NULL),('vn-database','10371','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:23',NULL,NULL),('vn-database','10372','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-12-16 09:14:48',NULL,NULL),('vn-database','10373','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-19 08:31:58',NULL,NULL),('vn-database','10378','00-rename_routeUserPercentage.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-11-04 08:25:17',NULL,NULL),('vn-database','10379','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:16',NULL,NULL),('vn-database','10382','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:47:20',NULL,NULL),('vn-database','10383','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:53',NULL,NULL),('vn-database','10384','00-business_workcenterFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:18:01',NULL,NULL),('vn-database','10385','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:54',NULL,NULL),('vn-database','10386','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:54',NULL,NULL),('vn-database','10387','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-16 14:05:33',NULL,NULL),('vn-database','10388','00-resizeUtilVerionLogCode.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:47:20',NULL,NULL),('vn-database','10388','01-resizeUtilVersionCode.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:47:20',NULL,NULL),('vn-database','10390','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:16',NULL,NULL),('vn-database','10391','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:23',NULL,NULL),('vn-database','10394','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:24',NULL,NULL),('vn-database','10395','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:29',NULL,NULL),('vn-database','10396','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 15:36:38',NULL,NULL),('vn-database','10397','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:29',NULL,NULL),('vn-database','10399','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:29',NULL,NULL),('vn-database','10400','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:29',NULL,NULL),('vn-database','10402','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-21 14:11:31',NULL,NULL),('vn-database','10404','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:29',NULL,NULL),('vn-database','10405','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:58:22',NULL,NULL),('vn-database','10407','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-12-16 09:14:49',NULL,NULL),('vn-database','10408','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:23',NULL,NULL),('vn-database','10409','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-12-16 09:14:49',NULL,NULL),('vn-database','10412','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-30 12:45:44',NULL,NULL),('vn-database','10413','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:24',NULL,NULL),('vn-database','10416','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:24',NULL,NULL),('vn-database','10420','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:25',NULL,NULL),('vn-database','10421','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:26',NULL,NULL),('vn-database','10426','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:40',NULL,NULL),('vn-database','10428','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-26 13:27:05',NULL,NULL),('vn-database','10431','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:22',NULL,NULL),('vn-database','10433','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-26 13:27:05',NULL,NULL),('vn-database','10434','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-26 13:27:05',NULL,NULL),('vn-database','10435','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-13 07:30:10',NULL,NULL),('vn-database','10436','00-createFkWorker.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:58:59',NULL,NULL),('vn-database','10436','01-addStateToWorkerProductivity.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:00',NULL,NULL),('vn-database','10436','02-DeprecateVnSaleTrackingState.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:00',NULL,NULL),('vn-database','10436','03-DeprecateColumnVnSaleTrackingActionFk.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:01',NULL,NULL),('vn-database','10436','04-DropSchemaVnControl.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:01',NULL,NULL),('vn-database','10436','05-RemoveFkWorkerProductivity.sql','jenkins@db-proxy2.static.verdnatura.es','2023-02-17 14:51:19',NULL,NULL),('vn-database','10439','00-fixRole.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-25 09:13:26',NULL,NULL),('vn-database','10440','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10444','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:01',NULL,NULL),('vn-database','10445','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10448','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10450','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-27 08:28:04',NULL,NULL),('vn-database','10451','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-06 08:08:32',NULL,NULL),('vn-database','10452','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 12:30:04',NULL,NULL),('vn-database','10453','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 14:04:37',NULL,NULL),('vn-database','10454','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 12:30:04',NULL,NULL),('vn-database','10455','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 12:30:04',NULL,NULL),('vn-database','10456','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 12:00:30',NULL,NULL),('vn-database','10457','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 12:00:33',NULL,NULL),('vn-database','10458','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:17',NULL,NULL),('vn-database','10459','00-alterTableUtilConfig.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10459','01-createFunctionCurdate.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10459','02-createFunctionMockTime.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10459','03-createFunctionMockTimeBase.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10459','04-createFunctionNow.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10460','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10461','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10463','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-03 12:59:26',NULL,NULL),('vn-database','10468','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10469','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10470','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:54',NULL,NULL),('vn-database','10471','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:54',NULL,NULL),('vn-database','10472','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:54',NULL,NULL),('vn-database','10477','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:31',NULL,NULL),('vn-database','10478','00-dropBasket.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:54',NULL,NULL),('vn-database','10478','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:54',NULL,NULL),('vn-database','10478','01-orderConfigured.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:29:16',NULL,NULL),('vn-database','10478','02-configuredUpdate.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:29:53',NULL,NULL),('vn-database','10478','99-privileges.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:29:53',NULL,NULL),('vn-database','10480','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-17 15:09:26',NULL,NULL),('vn-database','10481','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-17 16:37:22',NULL,NULL),('vn-database','10482','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-02-21 10:00:28',NULL,NULL),('vn-database','10485','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:17',NULL,NULL),('vn-database','10488','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:17',NULL,NULL),('vn-database','10491','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:18',NULL,NULL),('vn-database','10492','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:18',NULL,NULL),('vn-database','10493','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:18:01',NULL,NULL),('vn-database','10495','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:19',NULL,NULL),('vn-database','10498','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:38',NULL,NULL),('vn-database','10500','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-03-03 07:06:03',NULL,NULL),('vn-database','10501','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-03-03 10:52:24',NULL,NULL),('vn-database','10502','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:48',NULL,NULL),('vn-database','10504','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-25 09:13:27',NULL,NULL),('vn-database','10506','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:48',NULL,NULL),('vn-database','10506','01-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10506','02-secondScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10506','03-thirdScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10507','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:35:23',NULL,NULL),('vn-database','10508','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:43',NULL,NULL),('vn-database','10510','00-dropBusinessFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:47',NULL,NULL),('vn-database','10510','01-createTableProfessionalCategory.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:47',NULL,NULL),('vn-database','10510','02-exportToNewTable.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:47',NULL,NULL),('vn-database','10510','03-RecreateFK.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:51',NULL,NULL),('vn-database','10510','04-kkPostgresqlTable.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:51',NULL,NULL),('vn-database','10511','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10512','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:52',NULL,NULL),('vn-database','10513','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:56',NULL,NULL),('vn-database','10514','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10516','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:48',NULL,NULL),('vn-database','10521','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-21 06:58:13',NULL,NULL),('vn-database','10522','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10523','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10524','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:12',NULL,NULL),('vn-database','10524','01-rateEditorFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:12',NULL,NULL),('vn-database','10525','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-21 12:42:50',NULL,NULL),('vn-database','10526','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:57',NULL,NULL),('vn-database','10528','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:37:00',NULL,NULL),('vn-database','10530','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-03-23 14:49:30',NULL,NULL),('vn-database','10531','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-24 11:47:10',NULL,NULL),('vn-database','10532','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-24 11:17:38',NULL,NULL),('vn-database','10533','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:37:04',NULL,NULL),('vn-database','10537','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-29 15:18:36',NULL,NULL),('vn-database','10538','00-createChronopostConfig.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10538','01-createChronopostService.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10538','02-createChronopostExpedition.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10538','03-createChronopostSenderAddress.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10538','04-addgrantPrivilegies.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10538','05-updateChronopostConfig.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 11:54:57',NULL,NULL),('vn-database','10539','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:37:07',NULL,NULL),('vn-database','10540','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:18:01',NULL,NULL),('vn-database','10545','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-11 08:31:03',NULL,NULL),('vn-database','10546','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:08:10',NULL,NULL),('vn-database','10547','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:21:58',NULL,NULL),('vn-database','10549','00-updateUpdateLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 07:29:22',NULL,NULL),('vn-database','10549','01-updateInsertLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 07:30:11',NULL,NULL),('vn-database','10549','02-updateDeleteLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 07:30:51',NULL,NULL),('vn-database','10549','03-deleteEmptyLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 07:31:34',NULL,NULL),('vn-database','10549','04-optimizeLogTables.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 07:33:58',NULL,NULL),('vn-database','10550','00-editorFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:42:33',NULL,NULL),('vn-database','10550','01-originFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10552','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-13 08:25:10',NULL,NULL),('vn-database','10554','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:08:10',NULL,NULL),('vn-database','10557','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-17 07:45:56',NULL,NULL),('vn-database','10559','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-18 10:53:50',NULL,NULL),('vn-database','10560','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-17 09:19:31',NULL,NULL),('vn-database','10562','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10563','00-delivery_ticketFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-20 09:30:53',NULL,NULL),('vn-database','10566','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-20 10:08:41',NULL,NULL),('vn-database','10567','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-20 10:18:06',NULL,NULL),('vn-database','10568','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10569','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-24 09:14:35',NULL,NULL),('vn-database','10570','00-createSendingConfig.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10570','01-createSendingServiceWeekday.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10570','02-createSendingService.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10570','03-permisos.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10571','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-25 09:13:27',NULL,NULL),('vn-database','10573','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:23',NULL,NULL),('vn-database','10575','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-26 11:27:32',NULL,NULL),('vn-database','10577','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-27 14:00:12',NULL,NULL),('vn-database','10578','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10579','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-28 11:27:36',NULL,NULL),('vn-database','10580','00-itemTypeDropConstraint.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-28 18:18:52',NULL,NULL),('vn-database','10580','01-itemTypeAddConstraint.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-28 18:19:10',NULL,NULL),('vn-database','10581','00-itemTypeAutoIncrement.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-28 19:06:46',NULL,NULL),('vn-database','10582','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10583','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10584','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10585','00-ticketLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-25 09:20:10',NULL,NULL),('vn-database','10585','01-entryLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-25 09:21:12',NULL,NULL),('vn-database','10585','02-claimLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:28:36',NULL,NULL),('vn-database','10585','03-clientLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:28:54',NULL,NULL),('vn-database','10585','04-invoiceInLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:28:55',NULL,NULL),('vn-database','10585','05-itemLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:29:46',NULL,NULL),('vn-database','10585','06-routeLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:18',NULL,NULL),('vn-database','10585','07-shelvingLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:32',NULL,NULL),('vn-database','10585','08-supplierLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:32',NULL,NULL),('vn-database','10585','09-travelLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:41',NULL,NULL),('vn-database','10585','10-workerLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:42',NULL,NULL),('vn-database','10585','11-zoneLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:43',NULL,NULL),('vn-database','10585','12-userLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10585','13-roleLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10587','00-arcRead_addMinimum.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-16 13:13:15',NULL,NULL),('vn-database','10593','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10596','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10597','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10598','00-workerLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:29',NULL,NULL),('vn-database','10598','01-supplierLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:29',NULL,NULL),('vn-database','10598','02-workerTimeControlLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:29',NULL,NULL),('vn-database','10598','03-workerClockLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:29',NULL,NULL),('vn-database','10599','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10601','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-17 09:26:26',NULL,NULL),('vn-database','10602','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-18 08:52:15',NULL,NULL),('vn-database','10606','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-18 09:26:00',NULL,NULL),('vn-database','10608','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-18 12:36:31',NULL,NULL),('vn-database','10609','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-01 08:28:07',NULL,NULL),('vn-database','10610','00-updateCompanyId.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-01 09:11:07',NULL,NULL),('vn-database','10610','01-updateSupplierId.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-01 09:11:39',NULL,NULL),('vn-database','10610','02-invoiceOutCompany.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-01 09:49:55',NULL,NULL),('vn-database','10611','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-19 14:39:41',NULL,NULL),('vn-database','10613','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10614','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-01 09:11:40',NULL,NULL),('vn-database','10615','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-01 09:11:40',NULL,NULL),('vn-database','10616','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:18:55',NULL,NULL),('vn-database','10616','01-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:18:55',NULL,NULL),('vn-database','10617','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-01 09:11:41',NULL,NULL),('vn-database','10618','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 12:55:56',NULL,NULL),('vn-database','10619','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10620','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:20:53',NULL,NULL),('vn-database','10624','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-30 19:01:10',NULL,NULL),('vn-database','10626','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-29 13:32:32',NULL,NULL),('vn-database','10628','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10630','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-02 13:30:58',NULL,NULL),('vn-database','10631','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-05 08:37:25',NULL,NULL),('vn-database','10632','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10633','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10634','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-06 12:15:55',NULL,NULL),('vn-database','10637','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:19',NULL,NULL),('vn-database','10640','00-companyFkDrop.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 14:43:23',NULL,NULL),('vn-database','10640','00-updateCompany.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-07 14:22:13',1205,'Tiempo de espera de bloqueo excedido; intente rearrancar la transacción'),('vn-database','10640','01-companyFkAi.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 14:43:23',NULL,NULL),('vn-database','10640','02-companyFkCreate.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 14:47:04',NULL,NULL),('vn-database','10640','04-supplierFkDrop.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 14:48:30',NULL,NULL),('vn-database','10640','05-supplierFkAi.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 14:53:17',NULL,NULL),('vn-database','10640','06-supplierFkCreate.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 15:06:00',NULL,NULL),('vn-database','10642','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-29 14:04:13',NULL,NULL),('vn-database','10643','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-09 15:04:35',NULL,NULL),('vn-database','10644','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:18',NULL,NULL),('vn-database','10647','00-renombrarTabla.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-29 14:04:13',NULL,NULL),('vn-database','10648','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10649','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-16 10:59:06',NULL,NULL),('vn-database','10652','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-29 14:04:13',NULL,NULL),('vn-database','10653','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:20',NULL,NULL),('vn-database','10655','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:24',NULL,NULL),('vn-database','10656','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10658','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:27',NULL,NULL),('vn-database','10659','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10662','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:33',NULL,NULL),('vn-database','10663','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:34',NULL,NULL),('vn-database','10665','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-30 08:52:51',NULL,NULL),('vn-database','10666','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:34',NULL,NULL),('vn-database','10667','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10668','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:13',NULL,NULL),('vn-database','10671','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-25 14:56:50',NULL,NULL),('vn-database','10675','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10676','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10679','00-tables.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10680','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-07-18 14:58:36',NULL,NULL),('vn-database','10682','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:13',NULL,NULL),('vn-database','10690','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-07-27 10:52:26',NULL,NULL),('vn-database','10691','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-07-31 13:37:21',NULL,NULL),('vn-database','10692','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:13',NULL,NULL),('vn-database','10693','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:13',NULL,NULL),('vn-database','10694','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-08-02 09:50:53',NULL,NULL),('vn-database','10695','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-08-02 13:40:16',NULL,NULL),('vn-database','10696','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-03 16:54:57',NULL,NULL),('vn-database','10698','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-08-03 08:53:12',NULL,NULL),('vn-database','10699','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-03 15:24:30',NULL,NULL),('vn-database','10700','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-29 09:42:11',NULL,NULL),('vn-database','10702','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 12:50:46',NULL,NULL),('vn-database','10704','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-29 09:42:14',NULL,NULL),('vn-database','10705','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-08-16 14:16:05',NULL,NULL),('vn-database','10707','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-08-21 12:31:18',NULL,NULL),('vn-database','10714','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-28 13:01:45',NULL,NULL); +INSERT INTO `versionLog` VALUES ('vn-database','00001','00-test.sql','juan@10.5.1.3','2022-01-31 10:12:26',NULL,NULL),('vn-database','00003','00-sage.sql','juan@10.5.1.3','2022-01-31 10:12:26',NULL,NULL),('vn-database','10008','00-alterRoleConfig.sql','juan@10.5.1.3','2022-01-31 10:12:26',NULL,NULL),('vn-database','10014','00-rolePrefix.sql','jenkins@10.0.2.68','2022-02-11 00:13:25',NULL,NULL),('vn-database','10017','01-firstScript.sql','jenkins@10.0.2.70','2022-03-09 11:36:54',NULL,NULL),('vn-database','10021','00-bankAccount.sql','jenkins@10.0.2.69','2022-03-16 14:11:22',NULL,NULL),('vn-database','10023','00-firstScript.sql','jenkins@10.0.2.69','2022-03-16 15:05:29',NULL,NULL),('vn-database','10026','00-invoiceInIntrastat.sql','jenkins@10.0.2.69','2022-03-21 15:10:53',NULL,NULL),('vn-database','10027','00-Clientes_cedidos.sql','jenkins@10.0.2.69','2022-03-22 15:58:12',NULL,NULL),('vn-database','10028','00-item_last_buy_.sql','jenkins@10.0.2.69','2022-03-22 15:58:12',NULL,NULL),('vn-database','10029','00-bankToViewAccountingToTable.sql','jenkins@10.0.2.69','2022-03-22 15:58:12',NULL,NULL),('vn-database','10030','00-KkejarNiche.sql','jenkins@10.0.2.69','2022-03-22 15:58:12',NULL,NULL),('vn-database','10036','00-updateBuyConfig.sql','jenkins@10.0.2.69','2022-03-29 12:36:54',NULL,NULL),('vn-database','10037','00-firstScript.sql','jenkins@10.0.2.69','2022-03-28 11:14:26',NULL,NULL),('vn-database','10038','00-printServerQueue.sql','jenkins@10.0.2.69','2022-03-29 08:13:24',NULL,NULL),('vn-database','10048','00-firstScript.sql','jenkins@10.0.2.69','2022-03-30 12:29:06',NULL,NULL),('vn-database','10058','00-vehicleAddFields.sql','jenkins@10.0.2.69','2022-04-06 08:48:34',NULL,NULL),('vn-database','10060','00-firstScript.sql','jenkins@10.0.2.69','2022-04-07 08:50:11',NULL,NULL),('vn-database','10062','00-firstScript.sql','jenkins@10.0.2.69','2022-04-06 10:51:45',NULL,NULL),('vn-database','10064','00-firstScript.sql','jenkins@10.0.2.69','2022-04-06 13:57:11',NULL,NULL),('vn-database','10066','00-firstScript.sql','jenkins@10.0.2.69','2022-04-07 08:50:12',NULL,NULL),('vn-database','10067','00-firstScript.sql','jenkins@10.0.2.69','2022-04-08 10:18:20',NULL,NULL),('vn-database','10071','00-packingSiteLog.sql','jenkins@10.0.2.69','2022-04-08 09:37:30',NULL,NULL),('vn-database','10072','00-firstScript.sql','jenkins@10.0.2.69','2022-04-08 11:01:46',NULL,NULL),('vn-database','10073','00-firstScript.sql','jenkins@10.0.2.69','2022-04-08 13:40:56',NULL,NULL),('vn-database','10074','00-firstScript.sql','jenkins@10.0.2.69','2022-04-10 13:15:05',NULL,NULL),('vn-database','10077','00-firstScript.sql','jenkins@10.0.2.69','2022-04-12 08:07:15',NULL,NULL),('vn-database','10078','00-firstScript.sql','jenkins@10.0.2.69','2022-04-13 07:44:21',NULL,NULL),('vn-database','10079','00-firstScript.sql','jenkins@10.0.2.69','2022-04-12 12:01:37',NULL,NULL),('vn-database','10086','00-firstScript.sql','jenkins@10.0.2.69','2022-04-13 08:58:34',NULL,NULL),('vn-database','10087','00-firstScript.sql','jenkins@10.0.2.69','2022-04-13 09:39:49',NULL,NULL),('vn-database','10088','00-firstScript.sql','jenkins@10.0.2.69','2022-04-13 15:05:12',NULL,NULL),('vn-database','10089','00-firstScript.sql','jenkins@10.0.2.69','2022-04-18 14:12:52',NULL,NULL),('vn-database','10090','00-firstScript.sql','jenkins@10.0.2.69','2022-04-18 14:34:46',NULL,NULL),('vn-database','10092','00-firstScript.sql','jenkins@10.0.2.69','2022-04-19 14:45:46',NULL,NULL),('vn-database','10093','00-autoradioConfig.sql','jenkins@10.0.2.69','2022-05-03 09:16:47',NULL,NULL),('vn-database','10094','00-firstScript.sql','jenkins@10.0.2.69','2022-04-20 10:57:30',NULL,NULL),('vn-database','10097','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 10:12:59',NULL,NULL),('vn-database','10099','00-firstScript.sql','jenkins@10.0.2.69','2022-04-20 14:35:27',NULL,NULL),('vn-database','10100','00-firstScript.sql','jenkins@10.0.2.69','2022-04-20 14:35:27',NULL,NULL),('vn-database','10101','00-firstScript.sql','jenkins@10.0.2.69','2022-04-21 14:59:31',NULL,NULL),('vn-database','10103','00-awbVolume.sql','jenkins@10.0.2.69','2022-05-05 10:12:59',NULL,NULL),('vn-database','10104','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 10:12:59',NULL,NULL),('vn-database','10105','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 10:13:00',NULL,NULL),('vn-database','10107','00-firstScript.sql','jenkins@10.0.2.69','2022-04-23 10:53:53',NULL,NULL),('vn-database','10112','00-firstScript.sql','jenkins@10.0.2.69','2022-05-09 09:14:53',NULL,NULL),('vn-database','10113','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 10:13:00',NULL,NULL),('vn-database','10114','00-updateConfig.sql','jenkins@10.0.2.69','2022-04-27 13:37:25',NULL,NULL),('vn-database','10116','00-firstScript.sql','jenkins@10.0.2.69','2022-04-28 11:10:14',NULL,NULL),('vn-database','10118','00-firstScript.sql','jenkins@10.0.2.69','2022-04-29 08:10:15',NULL,NULL),('vn-database','10119','00-AfegirFKPart1.sql','jenkins@10.0.2.69','2022-05-05 10:13:00',NULL,NULL),('vn-database','10119','01-AfegirFkPart2.sql','jenkins@10.0.2.69','2022-05-05 10:22:25',NULL,NULL),('vn-database','10125','00-firstScript.sql','jenkins@10.0.2.68','2022-05-18 18:44:30',NULL,NULL),('vn-database','10127','00-firstScript.sql','jenkins@10.0.2.69','2022-05-02 11:04:46',NULL,NULL),('vn-database','10128','00-firstScript.sql','jenkins@10.0.2.69','2022-05-02 13:04:31',NULL,NULL),('vn-database','10129','00-firstScript.sql','jenkins@10.0.2.69','2022-05-03 08:21:01',NULL,NULL),('vn-database','10132','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 10:22:25',NULL,NULL),('vn-database','10133','00-firstScript.sql','jenkins@10.0.2.69','2022-05-05 14:32:30',NULL,NULL),('vn-database','10134','00-firstScript.sql','jenkins@10.0.2.69','2022-05-06 07:45:25',NULL,NULL),('vn-database','10135','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 08:46:17',NULL,NULL),('vn-database','10136','00-workerTimeControl.sql','jenkins@10.0.2.69','2022-05-09 13:51:12',NULL,NULL),('vn-database','10138','00-firstScript.sql','jenkins@10.0.2.69','2022-05-10 13:58:05',NULL,NULL),('vn-database','10139','00-firstScript.sql','jenkins@10.0.2.68','2022-05-16 14:32:37',NULL,NULL),('vn-database','10139','01-secondScript.sql','jenkins@10.0.2.68','2022-05-17 12:16:13',NULL,NULL),('vn-database','10141','00-firstScript.sql','jenkins@10.0.2.70','2022-05-12 08:27:31',NULL,NULL),('vn-database','10142','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:20:31',NULL,NULL),('vn-database','10143','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:20:31',NULL,NULL),('vn-database','10144','00-AfegirFKPArt1.sql','jenkins@10.0.2.68','2022-05-20 09:22:33',NULL,NULL),('vn-database','10144','00-firstScript.sql','jenkins@10.0.2.68','2022-05-13 09:44:25',NULL,NULL),('vn-database','10147','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:22:33',NULL,NULL),('vn-database','10149','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:22:33',NULL,NULL),('vn-database','10150','00-firstScript.sql','jenkins@10.0.2.68','2022-05-17 09:57:16',NULL,NULL),('vn-database','10152','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:22:34',NULL,NULL),('vn-database','10153','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:22:34',NULL,NULL),('vn-database','10154','00-compressionKk.sql','jenkins@10.0.2.68','2022-05-20 09:22:34',NULL,NULL),('vn-database','10157','00-firstScript.sql','jenkins@10.0.2.68','2022-05-20 09:22:35',NULL,NULL),('vn-database','10158','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:21',NULL,NULL),('vn-database','10160','00-firstScript.sql','jenkins@10.0.2.69','2022-06-30 09:30:50',NULL,NULL),('vn-database','10163','00-firstScript.sql','jenkins@10.0.2.68','2022-05-23 08:17:14',NULL,NULL),('vn-database','10164','00-borrarSectorsDesus.sql','jenkins@10.0.2.68','2022-06-02 12:47:21',NULL,NULL),('vn-database','10165','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10166','00-firstScript.sql','jenkins@10.0.2.68','2022-05-24 16:11:21',NULL,NULL),('vn-database','10167','00-renameVnActiveContrat.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10168','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10169','00-createTableBankEntityConfig.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10169','02-addNotNullToBankEntityBic.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10171','00-volumeConfig.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-18 14:11:11',NULL,NULL),('vn-database','10171','01-itemWeight.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-18 16:01:34',NULL,NULL),('vn-database','10171','02-agencymode.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-18 16:01:34',NULL,NULL),('vn-database','10172','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10174','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 08:46:17',NULL,NULL),('vn-database','10175','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:03:41',NULL,NULL),('vn-database','10177','00-crearTablaSpecialLabels.sql','jenkins@10.0.2.68','2022-06-02 12:47:22',NULL,NULL),('vn-database','10178','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:24',NULL,NULL),('vn-database','10179','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:24',NULL,NULL),('vn-database','10183','00-firstScript.sql','jenkins@10.0.2.68','2022-06-02 12:47:24',NULL,NULL),('vn-database','10184','00-firstScript.sql','jenkins@10.0.2.68','2022-06-03 08:05:34',NULL,NULL),('vn-database','10185','00-firstScript.sql','jenkins@10.0.2.68','2022-06-06 09:07:45',NULL,NULL),('vn-database','10186','00-desactivar_trigger.sql','jenkins@10.0.2.68','2022-06-07 09:31:23',NULL,NULL),('vn-database','10186','01-alter_Table_buy.sql','jenkins@10.0.2.68','2022-06-07 09:34:47',NULL,NULL),('vn-database','10186','02-alter_table_entryConfig.sql','jenkins@10.0.2.68','2022-06-07 09:34:47',NULL,NULL),('vn-database','10186','04-regularizar_Sticker_Inventario.sql','jenkins@10.0.2.68','2022-06-07 09:34:51',NULL,NULL),('vn-database','10186','09-reactivar_trigger.sql','jenkins@10.0.2.68','2022-06-07 09:34:51',NULL,NULL),('vn-database','10187','00-firstScript.sql','jenkins@10.0.2.68','2022-06-06 12:37:31',NULL,NULL),('vn-database','10188','00-firstScript.sql','jenkins@10.0.2.68','2022-06-06 14:03:36',NULL,NULL),('vn-database','10189','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:03:41',NULL,NULL),('vn-database','10191','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:03:41',NULL,NULL),('vn-database','10193','00-delete.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:35',NULL,NULL),('vn-database','10193','01-botanicExport.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:43',NULL,NULL),('vn-database','10193','02-item.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:44',NULL,NULL),('vn-database','10193','03-autonomy.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:44',NULL,NULL),('vn-database','10193','03-turn.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:44',NULL,NULL),('vn-database','10193','04-country.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-15 12:14:44',NULL,NULL),('vn-database','10194','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:03:41',NULL,NULL),('vn-database','10195','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:03:41',NULL,NULL),('vn-database','10200','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:04:00',NULL,NULL),('vn-database','10201','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:04:00',NULL,NULL),('vn-database','10202','00-Remove_FK_to_ediGenus.sql','jenkins@10.0.2.69','2022-06-17 09:04:00',NULL,NULL),('vn-database','10203','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:04:01',NULL,NULL),('vn-database','10204','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:04:01',NULL,NULL),('vn-database','10205','00-firstScript.sql','jenkins@10.0.2.69','2022-06-17 09:04:21',NULL,NULL),('vn-database','10207','00-Alter_table_entry.sql','jenkins@10.0.2.69','2022-06-16 07:22:50',NULL,NULL),('vn-database','10207','01-Update_invoiceAmount.sql','jenkins@10.0.2.69','2022-06-16 07:23:00',NULL,NULL),('vn-database','10208','00-firstScript.sql','jenkins@10.0.2.69','2022-06-30 09:31:26',NULL,NULL),('vn-database','10209','00-firstScript.sql','jenkins@10.0.2.69','2022-06-16 08:47:40',NULL,NULL),('vn-database','10210','00-firstScript.sql','jenkins@10.0.2.69','2022-06-16 17:39:17',1046,'Base de datos no seleccionada'),('vn-database','10211','01-firstScript.sql','jenkins@10.0.2.69','2022-06-17 07:11:27',NULL,NULL),('vn-database','10215','00-renameIsInventory.sql','jenkins@10.0.2.69','2022-06-30 09:31:26',NULL,NULL),('vn-database','10216','00-firstScript.sql','jenkins@10.0.2.69','2022-06-23 11:15:28',NULL,NULL),('vn-database','10216','01-batchIndex.sql','jenkins@10.0.2.70','2022-06-27 18:10:55',NULL,NULL),('vn-database','10219','00-AddCollectionFkOnPackingSite.sql','jenkins@10.0.2.70','2022-06-29 09:23:42',NULL,NULL),('vn-database','10219','01-AddFkToCollectionFk.sql','jenkins@10.0.2.70','2022-06-29 09:23:43',NULL,NULL),('vn-database','10220','00-createPersonalProtectionEquipment.sql','jenkins@10.0.2.69','2022-06-30 09:31:26',NULL,NULL),('vn-database','10222','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:12:40',NULL,NULL),('vn-database','10223','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:13:52',NULL,NULL),('vn-database','10224','00-cosetes.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-21 12:03:45',NULL,NULL),('vn-database','10229','00-firstScript.sql','jenkins@10.0.2.69','2022-07-01 11:59:34',NULL,NULL),('vn-database','10231','01-tablaEktConfig.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:25:39',NULL,NULL),('vn-database','10233','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:13:53',NULL,NULL),('vn-database','10235','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:13:53',NULL,NULL),('vn-database','10236','00-firstScript.sql','jenkins@10.0.2.69','2022-07-05 12:11:40',NULL,NULL),('vn-database','10237','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:13:53',NULL,NULL),('vn-database','10238','00-worker_mobileExtension.sql','jenkins@10.0.2.69','2022-07-14 09:14:09',NULL,NULL),('vn-database','10239','00-firstScript.sql','jenkins@10.0.2.69','2022-07-07 21:51:58',NULL,NULL),('vn-database','10241','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-29 08:14:01',NULL,NULL),('vn-database','10242','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:14:32',NULL,NULL),('vn-database','10243','00-firstScript.sql','jenkins@10.0.2.69','2022-07-14 09:14:32',NULL,NULL),('vn-database','10245','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:34:51',NULL,NULL),('vn-database','10247','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:34:51',NULL,NULL),('vn-database','10248','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-20 17:27:51',NULL,NULL),('vn-database','10250','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:36:40',NULL,NULL),('vn-database','10253','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:36:57',NULL,NULL),('vn-database','10254','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:38:48',NULL,NULL),('vn-database','10256','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:38:48',NULL,NULL),('vn-database','10258','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-12-16 09:14:48',NULL,NULL),('vn-database','10259','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-02 08:54:56',NULL,NULL),('vn-database','10261','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-22 08:42:20',NULL,NULL),('vn-database','10262','00-createTablepackagingWithFreight.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:13',NULL,NULL),('vn-database','10262','01-alterTablePackagingConfig.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:13',NULL,NULL),('vn-database','10262','02-insertsInicials.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:13',NULL,NULL),('vn-database','10262','03-createTablepackingWithoutFreight.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:14',NULL,NULL),('vn-database','10263','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:38:48',NULL,NULL),('vn-database','10265','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-07-28 08:38:48',NULL,NULL),('vn-database','10267','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:17',NULL,NULL),('vn-database','10267','01-fixMerge.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:17',NULL,NULL),('vn-database','10275','00-improvedGeneralLog.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-01 09:55:56',NULL,NULL),('vn-database','10277','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:26:32',NULL,NULL),('vn-database','10278','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-01 17:51:41',NULL,NULL),('vn-database','10279','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:17',NULL,NULL),('vn-database','10281','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:18',NULL,NULL),('vn-database','10282','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:18',NULL,NULL),('vn-database','10283','00-alterTable.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:34:18',NULL,NULL),('vn-database','10284','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-04 16:59:08',NULL,NULL),('vn-database','10285','00-firstScript.sql','jenkins@swarm-worker3.static.verdnatura.es','2022-08-05 09:19:33',NULL,NULL),('vn-database','10287','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:35:24',NULL,NULL),('vn-database','10288','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-11 09:35:24',NULL,NULL),('vn-database','10289','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:36',NULL,NULL),('vn-database','10291','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-10 14:19:34',NULL,NULL),('vn-database','10293','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:26:32',NULL,NULL),('vn-database','10297','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-16 12:43:36',NULL,NULL),('vn-database','10298','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-08-13 21:04:13',NULL,NULL),('vn-database','10299','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:14',NULL,NULL),('vn-database','10301','00-productionConfig.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:14',NULL,NULL),('vn-database','10301','01-drop.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:14',NULL,NULL),('vn-database','10301','02-collection.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:15',NULL,NULL),('vn-database','10302','00-CreateTableEntryType.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:15',NULL,NULL),('vn-database','10302','01-insertDataEntryType.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:15',NULL,NULL),('vn-database','10302','02-alterTableEntry.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:22',NULL,NULL),('vn-database','10303','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:22:23',NULL,NULL),('vn-database','10304','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:23:48',NULL,NULL),('vn-database','10304','01-altertableticket.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:23:51',NULL,NULL),('vn-database','10305','00-ektAssign.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:24:52',NULL,NULL),('vn-database','10306','00-deliveryInformation.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:25:25',NULL,NULL),('vn-database','10307','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:25:26',NULL,NULL),('vn-database','10308','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-02 17:26:43',NULL,NULL),('vn-database','10309','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-06 11:37:54',NULL,NULL),('vn-database','10310','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:26:33',NULL,NULL),('vn-database','10311','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-06 11:37:55',NULL,NULL),('vn-database','10312','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:26:33',NULL,NULL),('vn-database','10313','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:27:21',NULL,NULL),('vn-database','10314','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-20 12:37:19',NULL,NULL),('vn-database','10315','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:31:43',NULL,NULL),('vn-database','10317','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:31:43',NULL,NULL),('vn-database','10318','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 10:31:43',NULL,NULL),('vn-database','10319','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-20 12:37:41',NULL,NULL),('vn-database','10320','00-operator.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:37',NULL,NULL),('vn-database','10320','01-collection.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:37',NULL,NULL),('vn-database','10320','02-productionConfig.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:38',NULL,NULL),('vn-database','10321','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-08 11:11:12',NULL,NULL),('vn-database','10322','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-09 09:19:05',NULL,NULL),('vn-database','10326','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:38',NULL,NULL),('vn-database','10328','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:38',NULL,NULL),('vn-database','10329','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:29:38',NULL,NULL),('vn-database','10330','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:30',NULL,NULL),('vn-database','10332','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:30',NULL,NULL),('vn-database','10334','00-collectionHotbed.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:30',NULL,NULL),('vn-database','10334','01-saleGroupDetail.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:32',NULL,NULL),('vn-database','10335','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:38',NULL,NULL),('vn-database','10336','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:32',NULL,NULL),('vn-database','10337','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:32',NULL,NULL),('vn-database','10339','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-19 09:41:19',NULL,NULL),('vn-database','10340','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-29 11:08:03',NULL,NULL),('vn-database','10341','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:34:32',NULL,NULL),('vn-database','10342','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-29 11:08:03',NULL,NULL),('vn-database','10343','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-22 08:35:30',NULL,NULL),('vn-database','10345','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-11-04 08:25:16',NULL,NULL),('vn-database','10347','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-29 11:08:03',NULL,NULL),('vn-database','10347','01-addVirtualField.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-29 11:08:03',NULL,NULL),('vn-database','10349','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:38',NULL,NULL),('vn-database','10350','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-09-30 10:11:56',NULL,NULL),('vn-database','10352','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-11-04 08:25:16',NULL,NULL),('vn-database','10353','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:38',NULL,NULL),('vn-database','10354','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:38',NULL,NULL),('vn-database','10356','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-10 22:35:00',NULL,NULL),('vn-database','10356','01-orderConfigFk.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-10 22:35:00',NULL,NULL),('vn-database','10356','02-orderConfigDrop.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-10 22:35:00',NULL,NULL),('vn-database','10357','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:38',NULL,NULL),('vn-database','10359','00-improvedGeneralLog_collate.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:39',NULL,NULL),('vn-database','10360','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 09:52:39',NULL,NULL),('vn-database','10361','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-06 11:16:07',NULL,NULL),('vn-database','10362','00-dropUdfs.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-10 11:01:15',NULL,NULL),('vn-database','10363','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-11-04 08:25:17',NULL,NULL),('vn-database','10365','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-13 19:30:46',NULL,NULL),('vn-database','10368','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-11-04 08:25:17',NULL,NULL),('vn-database','10369','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-14 13:38:06',NULL,NULL),('vn-database','10370','00-deleteForeignKey.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:41',NULL,NULL),('vn-database','10370','01-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:47',NULL,NULL),('vn-database','10370','02-deleteTable.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:49',NULL,NULL),('vn-database','10370','03-accion.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:49',NULL,NULL),('vn-database','10370','04-inter.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:53',NULL,NULL),('vn-database','10371','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:23',NULL,NULL),('vn-database','10372','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-12-16 09:14:48',NULL,NULL),('vn-database','10373','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-10-19 08:31:58',NULL,NULL),('vn-database','10378','00-rename_routeUserPercentage.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-11-04 08:25:17',NULL,NULL),('vn-database','10379','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:16',NULL,NULL),('vn-database','10382','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:47:20',NULL,NULL),('vn-database','10383','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:53',NULL,NULL),('vn-database','10384','00-business_workcenterFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:18:01',NULL,NULL),('vn-database','10385','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:54',NULL,NULL),('vn-database','10386','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 14:32:54',NULL,NULL),('vn-database','10387','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-16 14:05:33',NULL,NULL),('vn-database','10388','00-resizeUtilVerionLogCode.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:47:20',NULL,NULL),('vn-database','10388','01-resizeUtilVersionCode.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:47:20',NULL,NULL),('vn-database','10390','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:16',NULL,NULL),('vn-database','10391','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:23',NULL,NULL),('vn-database','10394','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:24',NULL,NULL),('vn-database','10395','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:29',NULL,NULL),('vn-database','10396','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-17 15:36:38',NULL,NULL),('vn-database','10397','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:29',NULL,NULL),('vn-database','10399','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:29',NULL,NULL),('vn-database','10400','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:29',NULL,NULL),('vn-database','10402','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-21 14:11:31',NULL,NULL),('vn-database','10404','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-12-01 08:50:29',NULL,NULL),('vn-database','10405','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:58:22',NULL,NULL),('vn-database','10407','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-12-16 09:14:49',NULL,NULL),('vn-database','10408','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:23',NULL,NULL),('vn-database','10409','00-firstScript.sql','jenkins@swarm-worker2.static.verdnatura.es','2022-12-16 09:14:49',NULL,NULL),('vn-database','10412','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2022-11-30 12:45:44',NULL,NULL),('vn-database','10413','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:24',NULL,NULL),('vn-database','10416','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:24',NULL,NULL),('vn-database','10420','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:25',NULL,NULL),('vn-database','10421','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-12 10:56:26',NULL,NULL),('vn-database','10426','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:40',NULL,NULL),('vn-database','10428','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-26 13:27:05',NULL,NULL),('vn-database','10431','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:22',NULL,NULL),('vn-database','10433','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-26 13:27:05',NULL,NULL),('vn-database','10434','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-26 13:27:05',NULL,NULL),('vn-database','10435','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-13 07:30:10',NULL,NULL),('vn-database','10436','00-createFkWorker.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:58:59',NULL,NULL),('vn-database','10436','01-addStateToWorkerProductivity.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:00',NULL,NULL),('vn-database','10436','02-DeprecateVnSaleTrackingState.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:00',NULL,NULL),('vn-database','10436','03-DeprecateColumnVnSaleTrackingActionFk.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:01',NULL,NULL),('vn-database','10436','04-DropSchemaVnControl.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:01',NULL,NULL),('vn-database','10436','05-RemoveFkWorkerProductivity.sql','jenkins@db-proxy2.static.verdnatura.es','2023-02-17 14:51:19',NULL,NULL),('vn-database','10439','00-fixRole.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-25 09:13:26',NULL,NULL),('vn-database','10440','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10444','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:01',NULL,NULL),('vn-database','10445','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10448','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10450','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-27 08:28:04',NULL,NULL),('vn-database','10451','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-06 08:08:32',NULL,NULL),('vn-database','10452','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 12:30:04',NULL,NULL),('vn-database','10453','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 14:04:37',NULL,NULL),('vn-database','10454','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 12:30:04',NULL,NULL),('vn-database','10455','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 12:30:04',NULL,NULL),('vn-database','10456','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 12:00:30',NULL,NULL),('vn-database','10457','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-01-31 12:00:33',NULL,NULL),('vn-database','10458','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:17',NULL,NULL),('vn-database','10459','00-alterTableUtilConfig.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10459','01-createFunctionCurdate.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10459','02-createFunctionMockTime.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10459','03-createFunctionMockTimeBase.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10459','04-createFunctionNow.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:41',NULL,NULL),('vn-database','10460','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10461','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10463','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-03 12:59:26',NULL,NULL),('vn-database','10468','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10469','00-firstScript.sql','jenkins@swarm-worker1.static.verdnatura.es','2023-02-16 09:59:31',NULL,NULL),('vn-database','10470','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:54',NULL,NULL),('vn-database','10471','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:54',NULL,NULL),('vn-database','10472','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:54',NULL,NULL),('vn-database','10477','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:31',NULL,NULL),('vn-database','10478','00-dropBasket.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:54',NULL,NULL),('vn-database','10478','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:28:54',NULL,NULL),('vn-database','10478','01-orderConfigured.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:29:16',NULL,NULL),('vn-database','10478','02-configuredUpdate.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:29:53',NULL,NULL),('vn-database','10478','99-privileges.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-23 10:29:53',NULL,NULL),('vn-database','10480','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-17 15:09:26',NULL,NULL),('vn-database','10481','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-02-17 16:37:22',NULL,NULL),('vn-database','10482','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-02-21 10:00:28',NULL,NULL),('vn-database','10485','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:17',NULL,NULL),('vn-database','10488','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:17',NULL,NULL),('vn-database','10491','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:18',NULL,NULL),('vn-database','10492','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:18',NULL,NULL),('vn-database','10493','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:18:01',NULL,NULL),('vn-database','10495','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-09 08:40:19',NULL,NULL),('vn-database','10498','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:38',NULL,NULL),('vn-database','10500','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-03-03 07:06:03',NULL,NULL),('vn-database','10501','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-03-03 10:52:24',NULL,NULL),('vn-database','10502','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:48',NULL,NULL),('vn-database','10504','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-25 09:13:27',NULL,NULL),('vn-database','10506','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:48',NULL,NULL),('vn-database','10506','01-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10506','02-secondScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10506','03-thirdScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10507','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:35:23',NULL,NULL),('vn-database','10508','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:43',NULL,NULL),('vn-database','10510','00-dropBusinessFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:47',NULL,NULL),('vn-database','10510','01-createTableProfessionalCategory.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:47',NULL,NULL),('vn-database','10510','02-exportToNewTable.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:47',NULL,NULL),('vn-database','10510','03-RecreateFK.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:51',NULL,NULL),('vn-database','10510','04-kkPostgresqlTable.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:51',NULL,NULL),('vn-database','10511','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10512','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:52',NULL,NULL),('vn-database','10513','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:56',NULL,NULL),('vn-database','10514','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10516','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-23 09:09:48',NULL,NULL),('vn-database','10521','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-21 06:58:13',NULL,NULL),('vn-database','10522','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10523','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10524','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:12',NULL,NULL),('vn-database','10524','01-rateEditorFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:12',NULL,NULL),('vn-database','10525','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-21 12:42:50',NULL,NULL),('vn-database','10526','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:36:57',NULL,NULL),('vn-database','10528','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:37:00',NULL,NULL),('vn-database','10530','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-03-23 14:49:30',NULL,NULL),('vn-database','10531','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-24 11:47:10',NULL,NULL),('vn-database','10532','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-24 11:17:38',NULL,NULL),('vn-database','10533','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:37:04',NULL,NULL),('vn-database','10537','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-03-29 15:18:36',NULL,NULL),('vn-database','10538','00-createChronopostConfig.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10538','01-createChronopostService.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10538','02-createChronopostExpedition.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10538','03-createChronopostSenderAddress.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10538','04-addgrantPrivilegies.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:07:41',NULL,NULL),('vn-database','10538','05-updateChronopostConfig.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 11:54:57',NULL,NULL),('vn-database','10539','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-05 10:37:07',NULL,NULL),('vn-database','10540','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:18:01',NULL,NULL),('vn-database','10545','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-11 08:31:03',NULL,NULL),('vn-database','10546','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:08:10',NULL,NULL),('vn-database','10547','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:21:58',NULL,NULL),('vn-database','10549','00-updateUpdateLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 07:29:22',NULL,NULL),('vn-database','10549','01-updateInsertLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 07:30:11',NULL,NULL),('vn-database','10549','02-updateDeleteLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 07:30:51',NULL,NULL),('vn-database','10549','03-deleteEmptyLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 07:31:34',NULL,NULL),('vn-database','10549','04-optimizeLogTables.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-21 07:33:58',NULL,NULL),('vn-database','10550','00-editorFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:42:33',NULL,NULL),('vn-database','10550','01-originFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10552','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-13 08:25:10',NULL,NULL),('vn-database','10554','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-20 09:08:10',NULL,NULL),('vn-database','10557','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-17 07:45:56',NULL,NULL),('vn-database','10559','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-18 10:53:50',NULL,NULL),('vn-database','10560','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-17 09:19:31',NULL,NULL),('vn-database','10562','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10563','00-delivery_ticketFk.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-20 09:30:53',NULL,NULL),('vn-database','10566','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-20 10:08:41',NULL,NULL),('vn-database','10567','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-20 10:18:06',NULL,NULL),('vn-database','10568','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10569','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-24 09:14:35',NULL,NULL),('vn-database','10570','00-createSendingConfig.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10570','01-createSendingServiceWeekday.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10570','02-createSendingService.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10570','03-permisos.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10571','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-25 09:13:27',NULL,NULL),('vn-database','10573','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:23',NULL,NULL),('vn-database','10575','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-26 11:27:32',NULL,NULL),('vn-database','10577','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-27 14:00:12',NULL,NULL),('vn-database','10578','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10579','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-04-28 11:27:36',NULL,NULL),('vn-database','10580','00-itemTypeDropConstraint.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-28 18:18:52',NULL,NULL),('vn-database','10580','01-itemTypeAddConstraint.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-28 18:19:10',NULL,NULL),('vn-database','10581','00-itemTypeAutoIncrement.sql','jenkins@db-proxy2.static.verdnatura.es','2023-04-28 19:06:46',NULL,NULL),('vn-database','10582','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10583','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10584','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:28',NULL,NULL),('vn-database','10585','00-ticketLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-25 09:20:10',NULL,NULL),('vn-database','10585','01-entryLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-25 09:21:12',NULL,NULL),('vn-database','10585','02-claimLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:28:36',NULL,NULL),('vn-database','10585','03-clientLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:28:54',NULL,NULL),('vn-database','10585','04-invoiceInLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:28:55',NULL,NULL),('vn-database','10585','05-itemLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:29:46',NULL,NULL),('vn-database','10585','06-routeLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:18',NULL,NULL),('vn-database','10585','07-shelvingLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:32',NULL,NULL),('vn-database','10585','08-supplierLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:32',NULL,NULL),('vn-database','10585','09-travelLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:41',NULL,NULL),('vn-database','10585','10-workerLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:42',NULL,NULL),('vn-database','10585','11-zoneLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:43',NULL,NULL),('vn-database','10585','12-userLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10585','13-roleLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10587','00-arcRead_addMinimum.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-16 13:13:15',NULL,NULL),('vn-database','10593','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10596','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10597','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10598','00-workerLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:29',NULL,NULL),('vn-database','10598','01-supplierLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:29',NULL,NULL),('vn-database','10598','02-workerTimeControlLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:29',NULL,NULL),('vn-database','10598','03-workerClockLog.sql','jenkins@db-proxy2.static.verdnatura.es','2023-05-12 09:45:29',NULL,NULL),('vn-database','10599','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 09:30:44',NULL,NULL),('vn-database','10601','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-17 09:26:26',NULL,NULL),('vn-database','10602','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-18 08:52:15',NULL,NULL),('vn-database','10606','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-18 09:26:00',NULL,NULL),('vn-database','10608','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-18 12:36:31',NULL,NULL),('vn-database','10609','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-01 08:28:07',NULL,NULL),('vn-database','10610','00-updateCompanyId.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-01 09:11:07',NULL,NULL),('vn-database','10610','01-updateSupplierId.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-01 09:11:39',NULL,NULL),('vn-database','10610','02-invoiceOutCompany.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-01 09:49:55',NULL,NULL),('vn-database','10611','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-19 14:39:41',NULL,NULL),('vn-database','10613','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10614','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-01 09:11:40',NULL,NULL),('vn-database','10615','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-01 09:11:40',NULL,NULL),('vn-database','10616','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:18:55',NULL,NULL),('vn-database','10616','01-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:18:55',NULL,NULL),('vn-database','10617','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-01 09:11:41',NULL,NULL),('vn-database','10618','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-25 12:55:56',NULL,NULL),('vn-database','10619','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10620','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:20:53',NULL,NULL),('vn-database','10624','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-05-30 19:01:10',NULL,NULL),('vn-database','10625','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:26',NULL,NULL),('vn-database','10626','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-29 13:32:32',NULL,NULL),('vn-database','10628','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10630','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-02 13:30:58',NULL,NULL),('vn-database','10631','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-05 08:37:25',NULL,NULL),('vn-database','10632','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10633','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:18',NULL,NULL),('vn-database','10634','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-06 12:15:55',NULL,NULL),('vn-database','10637','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-15 12:30:19',NULL,NULL),('vn-database','10640','00-companyFkDrop.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 14:43:23',NULL,NULL),('vn-database','10640','00-updateCompany.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-07 14:22:13',1205,'Tiempo de espera de bloqueo excedido; intente rearrancar la transacción'),('vn-database','10640','01-companyFkAi.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 14:43:23',NULL,NULL),('vn-database','10640','02-companyFkCreate.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 14:47:04',NULL,NULL),('vn-database','10640','04-supplierFkDrop.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 14:48:30',NULL,NULL),('vn-database','10640','05-supplierFkAi.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 14:53:17',NULL,NULL),('vn-database','10640','06-supplierFkCreate.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-07 15:06:00',NULL,NULL),('vn-database','10642','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-29 14:04:13',NULL,NULL),('vn-database','10643','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-09 15:04:35',NULL,NULL),('vn-database','10644','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:18',NULL,NULL),('vn-database','10645','00-addNewFields.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:11',NULL,NULL),('vn-database','10645','01-updateCollectionWagonPrimaryKey.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:11',NULL,NULL),('vn-database','10645','02-updateWagonPrimaryKey.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:12',NULL,NULL),('vn-database','10645','03-addFieldToPackingSite.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:12',NULL,NULL),('vn-database','10647','00-renombrarTabla.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-29 14:04:13',NULL,NULL),('vn-database','10648','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10649','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-16 10:59:06',NULL,NULL),('vn-database','10652','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-06-29 14:04:13',NULL,NULL),('vn-database','10653','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:20',NULL,NULL),('vn-database','10655','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:24',NULL,NULL),('vn-database','10656','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10657','00-renameErrorProduction.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:12',NULL,NULL),('vn-database','10657','01-changeNightTask.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:12',NULL,NULL),('vn-database','10657','02-addCodeToClaimResponsible.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:12',NULL,NULL),('vn-database','10657','03-grantSelectGrafana.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:12',NULL,NULL),('vn-database','10658','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:27',NULL,NULL),('vn-database','10659','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10661','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-16 09:27:50',NULL,NULL),('vn-database','10662','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:33',NULL,NULL),('vn-database','10663','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:34',NULL,NULL),('vn-database','10665','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-06-30 08:52:51',NULL,NULL),('vn-database','10666','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-13 11:22:34',NULL,NULL),('vn-database','10667','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10668','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:13',NULL,NULL),('vn-database','10671','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-25 14:56:50',NULL,NULL),('vn-database','10675','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10676','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10677','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:22',NULL,NULL),('vn-database','10678','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:12',NULL,NULL),('vn-database','10679','00-tables.sql','jenkins@db-proxy2.static.verdnatura.es','2023-07-27 09:17:24',NULL,NULL),('vn-database','10680','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-07-18 14:58:36',NULL,NULL),('vn-database','10682','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:13',NULL,NULL),('vn-database','10683','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:12',NULL,NULL),('vn-database','10684','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:26',NULL,NULL),('vn-database','10685','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-10-05 09:53:55',NULL,NULL),('vn-database','10690','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-07-27 10:52:26',NULL,NULL),('vn-database','10691','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-07-31 13:37:21',NULL,NULL),('vn-database','10692','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:13',NULL,NULL),('vn-database','10693','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 11:50:13',NULL,NULL),('vn-database','10694','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-08-02 09:50:53',NULL,NULL),('vn-database','10695','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-08-02 13:40:16',NULL,NULL),('vn-database','10696','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-03 16:54:57',NULL,NULL),('vn-database','10698','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-08-03 08:53:12',NULL,NULL),('vn-database','10699','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-03 15:24:30',NULL,NULL),('vn-database','10700','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-29 09:42:11',NULL,NULL),('vn-database','10701','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:12',NULL,NULL),('vn-database','10702','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-10 12:50:46',NULL,NULL),('vn-database','10704','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-29 09:42:14',NULL,NULL),('vn-database','10705','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-08-16 14:16:05',NULL,NULL),('vn-database','10707','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-08-21 12:31:18',NULL,NULL),('vn-database','10708','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:13',NULL,NULL),('vn-database','10712','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-07 10:43:13',NULL,NULL),('vn-database','10714','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-08-28 13:01:45',NULL,NULL),('vn-database','10716','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-16 09:27:50',NULL,NULL),('vn-database','10717','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-16 09:28:54',NULL,NULL),('vn-database','10718','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:26',NULL,NULL),('vn-database','10719','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-01 12:53:30',NULL,NULL),('vn-database','10720','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:22',NULL,NULL),('vn-database','10721','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:29',NULL,NULL),('vn-database','10722','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-09 13:00:29',NULL,NULL),('vn-database','10725','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-09-12 14:15:14',NULL,NULL),('vn-database','10726','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 15:32:20',NULL,NULL),('vn-database','10727','00-addPrinterField.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:29',NULL,NULL),('vn-database','10727','01-createTableScreenModel.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:29',NULL,NULL),('vn-database','10727','02-createTableScreen.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:29',NULL,NULL),('vn-database','10727','03-createTableScreenModel.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:29',NULL,NULL),('vn-database','10727','04-createTableScanner.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:29',NULL,NULL),('vn-database','10727','05-createTablePackingSiteDeviceLog.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:29',NULL,NULL),('vn-database','10727','06-alterTablePrinterModel.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:29',NULL,NULL),('vn-database','10727','07-AddFieldsToPackingSite.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-21 09:42:30',NULL,NULL),('vn-database','10730','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-15 11:42:48',NULL,NULL),('vn-database','10733','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-10-05 09:54:00',NULL,NULL),('vn-database','10736','00-workerBossNull.sql','jenkins@db-proxy1.static.verdnatura.es','2023-09-22 00:02:05',NULL,NULL),('vn-database','10739','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-10-10 10:19:07',NULL,NULL),('vn-database','10740','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:26',NULL,NULL),('vn-database','10741','01-refactorCplusTrascendency472.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:27',NULL,NULL),('vn-database','10741','02-refactorCplusTrascendency477.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:27',NULL,NULL),('vn-database','10741','03-refactorCplusInvoiceType477.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:27',NULL,NULL),('vn-database','10741','04-refactorCplusInvoiceType472.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:27',NULL,NULL),('vn-database','10741','05-fixes.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:27',NULL,NULL),('vn-database','10744','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-10-13 09:23:19',NULL,NULL),('vn-database','10746','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-10-16 18:22:46',NULL,NULL),('vn-database','10747','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:32',NULL,NULL),('vn-database','10748','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:32',NULL,NULL),('vn-database','10748','01-SecondScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:34',NULL,NULL),('vn-database','10749','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-10-22 16:08:17',NULL,NULL),('vn-database','10750','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-10-23 13:04:17',NULL,NULL),('vn-database','10750','00-ticket_addGrants.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:34',NULL,NULL),('vn-database','10751','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:34',NULL,NULL),('vn-database','10752','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-10-24 14:07:54',NULL,NULL),('vn-database','10753','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-10-24 14:37:21',NULL,NULL),('vn-database','10754','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:34',NULL,NULL),('vn-database','10755','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-02 09:13:35',NULL,NULL),('vn-database','10756','00-firstScript.sql','jenkins@db-proxy2.static.verdnatura.es','2023-11-03 07:14:38',NULL,NULL),('vn-database','10757','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-16 09:30:57',NULL,NULL),('vn-database','10761','00-firstScript.sql','jenkins@db-proxy1.static.verdnatura.es','2023-11-16 09:30:58',NULL,NULL); /*!40000 ALTER TABLE `versionLog` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; @@ -54,7 +54,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2023-08-30 15:53:14 +-- Dump completed on 2023-11-20 12:26:42 USE `account`; -- MariaDB dump 10.19 Distrib 10.5.19-MariaDB, for debian-linux-gnu (x86_64) -- @@ -78,7 +78,7 @@ USE `account`; LOCK TABLES `role` WRITE; /*!40000 ALTER TABLE `role` DISABLE KEYS */; -INSERT INTO `role` VALUES (1,'employee','Empleado básico',1,'2017-05-19 07:04:58','2023-06-08 16:47:57',NULL),(2,'customer','Privilegios básicos de un cliente',1,'2017-05-19 07:04:58','2023-06-02 20:33:28',NULL),(3,'agency','Consultar tablas de predicciones de bultos',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(5,'administrative','Tareas relacionadas con la contabilidad',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(6,'guest','Privilegios para usuarios sin cuenta',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(9,'developer','Desarrolladores del sistema',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(11,'account','Privilegios relacionados con el login',0,'2017-05-19 07:04:58','2017-09-20 17:06:35',NULL),(13,'teamBoss','Jefe de equipo/departamento',1,'2017-05-19 07:04:58','2021-06-30 13:29:30',NULL),(15,'logistic','Departamento de compras, responsables de la logistica',1,'2017-05-19 07:04:58','2018-02-12 10:50:10',NULL),(16,'logisticBoss','Jefe del departamento de logística',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(17,'adminBoss','Jefe del departamento de administración',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(18,'salesPerson','Departamento de ventas',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(19,'salesBoss','Jefe del departamento de ventas',1,'2017-05-19 07:04:58','2017-08-16 12:38:27',NULL),(20,'manager','Gerencia',1,'2017-06-01 14:57:02','2022-07-29 07:36:15',NULL),(21,'salesAssistant','Jefe auxiliar de ventas',1,'2017-08-16 12:40:52','2017-08-16 12:40:52',NULL),(22,'teamManager','Jefe de departamento con privilegios de auxiliar de venta.',1,'2017-09-07 09:08:12','2017-09-07 09:08:12',NULL),(30,'financialBoss','Director finaciero',1,'2017-09-21 11:05:36','2017-09-21 11:05:36',NULL),(31,'freelancer','Trabajadores por cuenta ajena',1,'2017-10-10 12:57:26','2017-10-10 12:59:27',NULL),(32,'ett','Trabajadores de empresa temporal',1,'2017-10-10 12:58:58','2017-10-10 12:59:20',NULL),(33,'invoicing','Personal con acceso a facturación',0,'2018-01-29 16:43:34','2018-01-29 16:43:34',NULL),(34,'agencyBoss','Jefe/a del departamento de agencias',1,'2018-01-29 16:44:39','2018-02-23 07:58:53',NULL),(35,'buyer','Departamento de compras',1,'2018-02-12 10:35:42','2018-02-12 10:35:42',NULL),(36,'replenisher','Trabajadores de camara',1,'2018-02-16 14:07:10','2019-04-12 05:38:08',NULL),(37,'hr','Gestor/a de recursos humanos',1,'2018-02-22 17:34:53','2018-02-22 17:34:53',NULL),(38,'hrBoss','Jefe/a de recursos humanos',1,'2018-02-22 17:35:09','2018-02-22 17:35:09',NULL),(39,'adminAssistant','Jefe auxiliar administrativo',1,'2018-02-23 10:37:36','2018-02-23 10:38:41',NULL),(40,'handmade','Departamento de confección',1,'2018-02-23 11:14:53','2018-02-23 11:39:12',NULL),(41,'handmadeBoss','Jefe de departamento de confección',1,'2018-02-23 11:15:09','2018-02-23 11:39:26',NULL),(42,'artificial','Departamento de artificial',1,'2018-02-23 11:39:59','2018-02-23 11:39:59',NULL),(43,'artificialBoss','Jefe del departamento de artificial',1,'2018-02-23 11:40:16','2018-02-23 11:40:16',NULL),(44,'accessory','Departamento de complementos',1,'2018-02-23 11:41:12','2018-02-23 11:41:12',NULL),(45,'accessoryBoss','Jefe del departamento de complementos',1,'2018-02-23 11:41:23','2018-02-23 11:41:23',NULL),(47,'cooler','Empleados de cámara',1,'2018-02-23 13:08:18','2018-02-23 13:08:18',NULL),(48,'coolerBoss','Jefe de cámara',1,'2018-02-23 13:12:01','2023-03-13 08:49:43',NULL),(49,'production','Empleado de producción',1,'2018-02-26 15:28:23','2021-02-12 09:42:35',NULL),(50,'productionBoss','Jefe de producción',1,'2018-02-26 15:34:12','2018-02-26 15:34:12',NULL),(51,'marketing','Departamento de marketing',1,'2018-03-01 07:28:39','2018-03-01 07:28:39',NULL),(52,'marketingBoss','Jefe del departamento de marketing',1,'2018-03-01 07:28:57','2018-03-01 07:28:57',NULL),(53,'insurance','Gestor de seguros de cambio',0,'2018-03-05 07:44:35','2019-02-01 13:47:57',NULL),(54,'itemPicker','Sacador en cámara',1,'2018-03-05 12:08:17','2018-03-05 12:08:17',NULL),(55,'itemPickerBoss','Jefe de sacadores',1,'2018-03-05 12:08:31','2018-03-05 12:08:31',NULL),(56,'delivery','Personal de reparto',1,'2018-05-30 06:07:02','2018-05-30 06:07:02',NULL),(57,'deliveryBoss','Jefe de personal de reparto',1,'2018-05-30 06:07:19','2018-05-30 06:07:19',NULL),(58,'packager','Departamento encajadores',1,'2019-01-21 12:43:45','2019-01-21 12:43:45',NULL),(59,'packagerBoss','Jefe departamento encajadores',1,'2019-01-21 12:44:10','2019-01-21 12:44:10',NULL),(60,'productionAssi','Tareas relacionadas con producción y administración',1,'2019-01-29 13:29:01','2019-01-29 13:29:01',NULL),(61,'replenisherBos','Jefe de Complementos/Camara',1,'2019-07-01 06:44:07','2019-07-01 06:44:07',NULL),(62,'noLogin','Role without login access to MySQL',0,'2019-07-01 06:50:19','2019-07-02 13:42:05',NULL),(64,'balanceSheet','Consulta de Balance',0,'2019-07-16 12:12:08','2019-07-16 12:12:08',NULL),(65,'officeBoss','Jefe de filial',1,'2019-08-02 06:54:26','2019-08-02 06:54:26',NULL),(66,'sysadmin','Administrador de sistema',1,'2019-08-08 06:58:56','2019-08-08 06:58:56',NULL),(67,'adminOfficer','categoria profesional oficial de administración',1,'2020-01-03 08:09:23','2020-01-03 08:09:23',NULL),(69,'coolerAssist','Asistente de cámara con permiso compras',1,'2020-02-05 12:36:09','2023-03-13 08:50:07',NULL),(70,'trainee','Alumno de prácticas',1,'2020-03-04 11:00:25','2020-03-04 11:00:25',NULL),(71,'checker','Rol de revisor con privilegios de itemPicker',1,'2020-10-02 10:50:07','2020-10-02 10:50:07',NULL),(72,'claimManager','Personal de reclamaciones',1,'2020-10-13 10:01:32','2020-10-26 07:29:46',NULL),(73,'financial','Departamento de finanzas',1,'2020-11-16 09:30:27','2020-11-16 09:30:27',NULL),(74,'userPhotos','Privilegios para subir fotos de usuario',1,'2021-02-03 10:24:27','2021-02-03 10:24:27',NULL),(75,'catalogPhotos','Privilegios para subir fotos del catálogo',1,'2021-02-03 10:24:27','2021-02-03 10:24:27',NULL),(76,'chat','Rol para utilizar el rocket chat',1,'2020-11-27 13:06:50','2020-12-17 07:49:41',NULL),(100,'root','Rol con todos los privilegios',0,'2018-04-23 14:33:36','2020-11-12 06:50:07',NULL),(101,'buyerBoss','Jefe del departamento de compras',1,'2021-06-16 09:53:17','2021-06-16 09:53:17',NULL),(102,'preservedBoss','Responsable preservado',1,'2021-09-14 13:45:37','2021-09-14 13:45:37',NULL),(103,'it','Departamento de informática',1,'2021-11-11 09:48:22','2021-11-11 09:48:22',NULL),(104,'itBoss','Jefe de departamento de informática',1,'2021-11-11 09:48:49','2021-11-11 09:48:49',NULL),(105,'grant','Adjudicar roles a usuarios',1,'2021-11-11 12:41:09','2021-11-11 12:41:09',NULL),(106,'ext','Usuarios externos de la Base de datos',1,'2021-11-23 14:51:16','2021-11-23 14:51:16',NULL),(107,'productionPlus','Creado para pepe por orden de Juanvi',1,'2022-02-08 06:47:10','2022-02-08 06:47:10',NULL),(108,'system','System user',1,'2022-05-16 08:09:51','2022-05-16 08:09:51',NULL),(109,'salesTeamBoss','Jefe de equipo de comerciales',1,'2022-06-14 13:45:56','2022-06-14 13:45:56',NULL),(110,'palletizer','Paletizadores',1,'2022-12-02 12:56:22','2022-12-02 12:56:30',NULL),(111,'entryEditor','Entry editor',1,'2023-01-13 11:21:55','2023-01-13 11:21:55',NULL),(112,'maintenance','Personal de mantenimiento',1,'2023-01-19 06:23:35','2023-01-19 06:23:35',NULL),(114,'maintenanceBos','Jefe de mantenimiento',1,'2023-01-19 06:31:16','2023-05-17 11:07:21',NULL),(115,'itManagement','TI management',1,'2023-03-29 07:27:55','2023-03-29 07:28:04',NULL),(119,'palletizerBoss','Jefe de paletizadores',1,'2023-06-07 11:51:54','2023-06-07 11:51:54',NULL),(120,'developerBoss','Jefe de proyecto de desarrollo',1,'2023-06-19 07:07:21','2023-06-19 07:07:21',21709),(121,'buyerSalesAssistant','Rol para compradores que también son responsables de ventas',1,'2023-06-23 14:48:19','2023-06-23 14:48:19',NULL),(122,'logisticAssistant','Jefe auxiliar de logística',1,'2023-06-26 07:21:15','2023-06-26 07:21:15',NULL); +INSERT INTO `role` VALUES (1,'employee','Empleado básico',1,'2017-05-19 07:04:58','2023-06-08 16:47:57',NULL),(2,'customer','Privilegios básicos de un cliente',1,'2017-05-19 07:04:58','2023-06-02 20:33:28',NULL),(3,'agency','Consultar tablas de predicciones de bultos',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(5,'administrative','Tareas relacionadas con la contabilidad',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(6,'guest','Privilegios para usuarios sin cuenta',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(9,'developer','Desarrolladores del sistema',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(11,'account','Privilegios relacionados con el login',0,'2017-05-19 07:04:58','2017-09-20 17:06:35',NULL),(13,'teamBoss','Jefe de equipo/departamento',1,'2017-05-19 07:04:58','2021-06-30 13:29:30',NULL),(15,'logistic','Departamento de compras, responsables de la logistica',1,'2017-05-19 07:04:58','2018-02-12 10:50:10',NULL),(16,'logisticBoss','Jefe del departamento de logística',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(17,'adminBoss','Jefe del departamento de administración',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(18,'salesPerson','Departamento de ventas',1,'2017-05-19 07:04:58','2017-05-19 07:04:58',NULL),(19,'salesBoss','Jefe del departamento de ventas',1,'2017-05-19 07:04:58','2017-08-16 12:38:27',NULL),(20,'manager','Gerencia',1,'2017-06-01 14:57:02','2022-07-29 07:36:15',NULL),(21,'salesAssistant','Jefe auxiliar de ventas',1,'2017-08-16 12:40:52','2017-08-16 12:40:52',NULL),(22,'teamManager','Jefe de departamento con privilegios de auxiliar de venta.',1,'2017-09-07 09:08:12','2017-09-07 09:08:12',NULL),(30,'financialBoss','Director finaciero',1,'2017-09-21 11:05:36','2017-09-21 11:05:36',NULL),(31,'freelancer','Trabajadores por cuenta ajena',1,'2017-10-10 12:57:26','2017-10-10 12:59:27',NULL),(32,'ett','Trabajadores de empresa temporal',1,'2017-10-10 12:58:58','2017-10-10 12:59:20',NULL),(33,'invoicing','Personal con acceso a facturación',0,'2018-01-29 16:43:34','2018-01-29 16:43:34',NULL),(34,'agencyBoss','Jefe/a del departamento de agencias',1,'2018-01-29 16:44:39','2018-02-23 07:58:53',NULL),(35,'buyer','Departamento de compras',1,'2018-02-12 10:35:42','2018-02-12 10:35:42',NULL),(36,'replenisher','Trabajadores de camara',1,'2018-02-16 14:07:10','2019-04-12 05:38:08',NULL),(37,'hr','Gestor/a de recursos humanos',1,'2018-02-22 17:34:53','2018-02-22 17:34:53',NULL),(38,'hrBoss','Jefe/a de recursos humanos',1,'2018-02-22 17:35:09','2018-02-22 17:35:09',NULL),(39,'adminAssistant','Jefe auxiliar administrativo',1,'2018-02-23 10:37:36','2018-02-23 10:38:41',NULL),(40,'handmade','Departamento de confección',1,'2018-02-23 11:14:53','2018-02-23 11:39:12',NULL),(41,'handmadeBoss','Jefe de departamento de confección',1,'2018-02-23 11:15:09','2018-02-23 11:39:26',NULL),(42,'artificial','Departamento de artificial',1,'2018-02-23 11:39:59','2018-02-23 11:39:59',NULL),(43,'artificialBoss','Jefe del departamento de artificial',1,'2018-02-23 11:40:16','2018-02-23 11:40:16',NULL),(44,'accessory','Departamento de complementos',1,'2018-02-23 11:41:12','2018-02-23 11:41:12',NULL),(45,'accessoryBoss','Jefe del departamento de complementos',1,'2018-02-23 11:41:23','2018-02-23 11:41:23',NULL),(47,'cooler','Empleados de cámara',1,'2018-02-23 13:08:18','2018-02-23 13:08:18',NULL),(48,'coolerBoss','Jefe de cámara',1,'2018-02-23 13:12:01','2023-03-13 08:49:43',NULL),(49,'production','Empleado de producción',1,'2018-02-26 15:28:23','2021-02-12 09:42:35',NULL),(50,'productionBoss','Jefe de producción',1,'2018-02-26 15:34:12','2018-02-26 15:34:12',NULL),(51,'marketing','Departamento de marketing',1,'2018-03-01 07:28:39','2018-03-01 07:28:39',NULL),(52,'marketingBoss','Jefe del departamento de marketing',1,'2018-03-01 07:28:57','2018-03-01 07:28:57',NULL),(53,'insurance','Gestor de seguros de cambio',0,'2018-03-05 07:44:35','2019-02-01 13:47:57',NULL),(54,'itemPicker','Sacador en cámara',1,'2018-03-05 12:08:17','2018-03-05 12:08:17',NULL),(55,'itemPickerBoss','Jefe de sacadores',1,'2018-03-05 12:08:31','2018-03-05 12:08:31',NULL),(56,'delivery','Personal de reparto',1,'2018-05-30 06:07:02','2018-05-30 06:07:02',NULL),(57,'deliveryBoss','Jefe de personal de reparto',1,'2018-05-30 06:07:19','2018-05-30 06:07:19',NULL),(58,'packager','Departamento encajadores',1,'2019-01-21 12:43:45','2019-01-21 12:43:45',NULL),(59,'packagerBoss','Jefe departamento encajadores',1,'2019-01-21 12:44:10','2019-01-21 12:44:10',NULL),(60,'productionAssi','Tareas relacionadas con producción y administración',1,'2019-01-29 13:29:01','2019-01-29 13:29:01',NULL),(61,'replenisherBos','Jefe de Complementos/Camara',1,'2019-07-01 06:44:07','2019-07-01 06:44:07',NULL),(62,'noLogin','Role without login access to MySQL',0,'2019-07-01 06:50:19','2019-07-02 13:42:05',NULL),(64,'balanceSheet','Consulta de Balance',0,'2019-07-16 12:12:08','2019-07-16 12:12:08',NULL),(65,'officeBoss','Jefe de filial',1,'2019-08-02 06:54:26','2019-08-02 06:54:26',NULL),(66,'sysadmin','Administrador de sistema',1,'2019-08-08 06:58:56','2019-08-08 06:58:56',NULL),(67,'adminOfficer','categoria profesional oficial de administración',1,'2020-01-03 08:09:23','2020-01-03 08:09:23',NULL),(69,'coolerAssist','Asistente de cámara con permiso compras',1,'2020-02-05 12:36:09','2023-03-13 08:50:07',NULL),(70,'trainee','Alumno de prácticas',1,'2020-03-04 11:00:25','2020-03-04 11:00:25',NULL),(71,'checker','Rol de revisor con privilegios de itemPicker',1,'2020-10-02 10:50:07','2020-10-02 10:50:07',NULL),(72,'claimManager','Personal de reclamaciones',1,'2020-10-13 10:01:32','2020-10-26 07:29:46',NULL),(73,'financial','Departamento de finanzas',1,'2020-11-16 09:30:27','2020-11-16 09:30:27',NULL),(74,'userPhotos','Privilegios para subir fotos de usuario',1,'2021-02-03 10:24:27','2021-02-03 10:24:27',NULL),(75,'catalogPhotos','Privilegios para subir fotos del catálogo',1,'2021-02-03 10:24:27','2021-02-03 10:24:27',NULL),(76,'chat','Rol para utilizar el rocket chat',1,'2020-11-27 13:06:50','2020-12-17 07:49:41',NULL),(100,'root','Rol con todos los privilegios',0,'2018-04-23 14:33:36','2020-11-12 06:50:07',NULL),(101,'buyerBoss','Jefe del departamento de compras',1,'2021-06-16 09:53:17','2021-06-16 09:53:17',NULL),(102,'preservedBoss','Responsable preservado',1,'2021-09-14 13:45:37','2021-09-14 13:45:37',NULL),(103,'it','Departamento de informática',1,'2021-11-11 09:48:22','2021-11-11 09:48:22',NULL),(104,'itBoss','Jefe de departamento de informática',1,'2021-11-11 09:48:49','2021-11-11 09:48:49',NULL),(105,'grant','Adjudicar roles a usuarios',1,'2021-11-11 12:41:09','2021-11-11 12:41:09',NULL),(106,'ext','Usuarios externos de la Base de datos',1,'2021-11-23 14:51:16','2021-11-23 14:51:16',NULL),(107,'productionPlus','Creado para pepe por orden de Juanvi',1,'2022-02-08 06:47:10','2022-02-08 06:47:10',NULL),(108,'system','System user',1,'2022-05-16 08:09:51','2022-05-16 08:09:51',NULL),(109,'salesTeamBoss','Jefe de equipo de comerciales',1,'2022-06-14 13:45:56','2022-06-14 13:45:56',NULL),(110,'palletizer','Paletizadores',1,'2022-12-02 12:56:22','2022-12-02 12:56:30',NULL),(111,'entryEditor','Entry editor',1,'2023-01-13 11:21:55','2023-01-13 11:21:55',NULL),(112,'maintenance','Personal de mantenimiento',1,'2023-01-19 06:23:35','2023-01-19 06:23:35',NULL),(114,'maintenanceBos','Jefe de mantenimiento',1,'2023-01-19 06:31:16','2023-05-17 11:07:21',NULL),(115,'itManagement','TI management',1,'2023-03-29 07:27:55','2023-03-29 07:28:04',NULL),(119,'palletizerBoss','Jefe de paletizadores',1,'2023-06-07 11:51:54','2023-06-07 11:51:54',NULL),(120,'developerBoss','Jefe de proyecto de desarrollo',1,'2023-06-19 07:07:21','2023-06-19 07:07:21',21709),(121,'buyerSalesAssistant','Rol para compradores que también son responsables de ventas',1,'2023-06-23 14:48:19','2023-06-23 14:48:19',NULL),(122,'logisticAssistant','Jefe auxiliar de logística',1,'2023-06-26 07:21:15','2023-06-26 07:21:15',NULL),(123,'deliveryAssistant','Jefe auxiliar repartos',1,'2023-10-05 06:47:48','2023-10-05 06:47:48',10578),(124,'hrBuyer','Recursos Humanos con Buyer',1,'2023-10-23 11:50:43','2023-10-23 11:50:43',NULL),(125,'claimViewer','Trabajadores que consulta las reclamaciones ',1,'2023-11-16 08:14:46','2023-11-16 08:14:46',10578),(126,'greenhouseBoss','Jefe de invernadero',1,'2023-11-16 13:32:13','2023-11-16 13:32:13',NULL); /*!40000 ALTER TABLE `role` ENABLE KEYS */; UNLOCK TABLES; @@ -88,7 +88,7 @@ UNLOCK TABLES; LOCK TABLES `roleInherit` WRITE; /*!40000 ALTER TABLE `roleInherit` DISABLE KEYS */; -INSERT INTO `roleInherit` VALUES (1,1,2,NULL),(2,1,3,NULL),(3,1,70,NULL),(4,2,11,NULL),(5,3,11,NULL),(6,5,1,NULL),(8,5,33,NULL),(10,11,6,NULL),(11,13,1,NULL),(12,15,35,NULL),(16,17,20,NULL),(17,17,37,NULL),(18,17,39,NULL),(19,17,64,NULL),(20,18,1,NULL),(21,19,21,NULL),(22,20,13,NULL),(23,20,16,NULL),(24,20,65,NULL),(25,21,13,NULL),(26,21,18,NULL),(27,21,53,NULL),(28,22,13,NULL),(29,22,21,NULL),(30,30,5,NULL),(31,30,20,NULL),(32,30,22,NULL),(33,30,53,NULL),(34,30,64,NULL),(35,31,1,NULL),(36,32,1,NULL),(37,34,1,NULL),(38,34,13,NULL),(39,34,33,NULL),(40,35,1,NULL),(41,36,44,NULL),(42,36,47,NULL),(43,37,1,NULL),(44,38,37,NULL),(45,38,64,NULL),(46,39,5,NULL),(47,39,21,NULL),(48,39,57,NULL),(49,40,1,NULL),(50,40,49,NULL),(51,41,13,NULL),(52,41,35,NULL),(53,41,40,NULL),(54,42,35,NULL),(55,42,49,NULL),(56,43,13,NULL),(57,43,42,NULL),(58,44,1,NULL),(59,45,13,NULL),(60,45,44,NULL),(61,47,1,NULL),(62,48,13,NULL),(63,48,47,NULL),(64,49,36,NULL),(65,49,58,NULL),(66,50,13,NULL),(67,50,21,NULL),(68,50,35,NULL),(69,50,49,NULL),(70,50,57,NULL),(72,51,1,NULL),(73,52,13,NULL),(74,52,19,NULL),(76,52,51,NULL),(77,53,1,NULL),(78,54,1,NULL),(79,55,13,NULL),(80,55,54,NULL),(81,56,1,NULL),(82,57,13,NULL),(83,57,56,NULL),(84,58,1,NULL),(85,59,13,NULL),(87,60,5,NULL),(91,61,13,NULL),(92,61,36,NULL),(94,65,35,NULL),(97,67,5,NULL),(98,67,37,NULL),(99,69,35,NULL),(101,70,11,NULL),(102,71,1,NULL),(103,71,58,NULL),(105,72,18,NULL),(106,73,5,NULL),(107,73,64,NULL),(108,73,19,NULL),(109,59,50,NULL),(115,39,76,NULL),(117,65,76,NULL),(118,30,76,NULL),(124,5,76,NULL),(125,37,76,NULL),(126,38,76,NULL),(128,42,76,NULL),(129,35,76,NULL),(130,60,76,NULL),(131,21,76,NULL),(132,18,76,NULL),(133,50,76,NULL),(134,20,76,NULL),(135,41,76,NULL),(136,17,76,NULL),(137,52,76,NULL),(138,57,76,NULL),(139,37,74,NULL),(140,51,74,NULL),(141,51,75,NULL),(142,35,75,NULL),(143,15,49,NULL),(145,17,67,NULL),(146,38,13,NULL),(147,101,35,NULL),(148,101,13,NULL),(150,15,56,NULL),(152,69,47,NULL),(153,48,35,NULL),(154,102,1,NULL),(167,9,103,NULL),(168,66,9,NULL),(169,104,100,NULL),(172,103,76,NULL),(173,103,1,NULL),(174,103,44,NULL),(175,103,45,NULL),(176,103,11,NULL),(177,103,39,NULL),(178,103,17,NULL),(179,103,5,NULL),(180,103,67,NULL),(181,103,3,NULL),(182,103,34,NULL),(183,103,42,NULL),(184,103,43,NULL),(185,103,64,NULL),(186,103,35,NULL),(187,103,101,NULL),(188,103,75,NULL),(189,103,71,NULL),(190,103,72,NULL),(191,103,47,NULL),(192,103,69,NULL),(193,103,48,NULL),(194,103,2,NULL),(195,103,56,NULL),(196,103,57,NULL),(197,103,32,NULL),(198,103,73,NULL),(199,103,30,NULL),(200,103,31,NULL),(201,103,6,NULL),(202,103,40,NULL),(203,103,41,NULL),(204,103,37,NULL),(205,103,38,NULL),(206,103,53,NULL),(207,103,33,NULL),(210,103,54,NULL),(211,103,55,NULL),(212,103,15,NULL),(213,103,16,NULL),(215,103,51,NULL),(216,103,52,NULL),(218,103,65,NULL),(219,103,58,NULL),(220,103,59,NULL),(221,103,102,NULL),(222,103,49,NULL),(223,103,60,NULL),(224,103,50,NULL),(225,103,36,NULL),(226,103,61,NULL),(228,103,21,NULL),(229,103,19,NULL),(230,103,18,NULL),(231,103,13,NULL),(232,103,22,NULL),(233,103,70,NULL),(234,103,74,NULL),(237,66,103,NULL),(238,103,20,NULL),(239,106,11,NULL),(240,107,60,NULL),(241,21,72,NULL),(242,20,9,NULL),(245,57,33,NULL),(246,102,35,NULL),(247,108,1,NULL),(248,102,13,NULL),(249,109,18,NULL),(250,109,13,NULL),(251,51,21,NULL),(253,48,49,NULL),(254,110,1,NULL),(255,110,76,NULL),(256,48,69,NULL),(257,47,111,NULL),(258,43,111,NULL),(259,72,111,NULL),(260,35,111,NULL),(261,5,111,NULL),(262,112,1,NULL),(263,114,112,NULL),(264,51,35,NULL),(265,72,49,NULL),(266,101,18,NULL),(268,65,57,NULL),(269,65,59,NULL),(270,65,49,NULL),(271,65,18,NULL),(272,65,13,NULL),(273,60,35,NULL),(275,50,59,NULL),(276,60,49,NULL),(280,5,53,NULL),(281,5,18,NULL),(282,50,60,NULL),(283,5,21,NULL),(284,60,57,NULL),(285,58,76,NULL),(287,69,58,NULL),(288,115,66,NULL),(290,104,115,NULL),(291,115,103,NULL),(297,21,33,NULL),(298,49,54,NULL),(299,112,49,NULL),(300,114,13,NULL),(302,5,35,NULL),(303,69,49,NULL),(306,119,110,NULL),(307,1,76,NULL),(309,120,9,NULL),(310,120,66,NULL),(311,120,13,25508),(312,115,120,NULL),(314,43,18,NULL),(315,121,35,NULL),(316,121,21,NULL),(317,122,15,NULL),(318,16,122,NULL),(319,37,49,NULL),(320,37,18,NULL); +INSERT INTO `roleInherit` VALUES (1,1,2,NULL),(2,1,3,NULL),(3,1,70,NULL),(4,2,11,NULL),(5,3,11,NULL),(6,5,1,NULL),(8,5,33,NULL),(10,11,6,NULL),(11,13,1,NULL),(12,15,35,NULL),(16,17,20,NULL),(17,17,37,NULL),(18,17,39,NULL),(19,17,64,NULL),(20,18,1,NULL),(21,19,21,NULL),(22,20,13,NULL),(23,20,16,NULL),(24,20,65,NULL),(25,21,13,NULL),(26,21,18,NULL),(27,21,53,NULL),(28,22,13,NULL),(29,22,21,NULL),(30,30,5,NULL),(31,30,20,NULL),(32,30,22,NULL),(33,30,53,NULL),(34,30,64,NULL),(35,31,1,NULL),(36,32,1,NULL),(37,34,1,NULL),(38,34,13,NULL),(39,34,33,NULL),(40,35,1,NULL),(41,36,44,NULL),(42,36,47,NULL),(43,37,1,NULL),(44,38,37,NULL),(45,38,64,NULL),(46,39,5,NULL),(47,39,21,NULL),(48,39,57,NULL),(49,40,1,NULL),(50,40,49,NULL),(51,41,13,NULL),(52,41,35,NULL),(53,41,40,NULL),(54,42,35,NULL),(55,42,49,NULL),(56,43,13,NULL),(57,43,42,NULL),(58,44,1,NULL),(59,45,13,NULL),(60,45,44,NULL),(61,47,1,NULL),(62,48,13,NULL),(63,48,47,NULL),(64,49,36,NULL),(65,49,58,NULL),(66,50,13,NULL),(67,50,21,NULL),(70,50,57,NULL),(72,51,1,NULL),(73,52,13,NULL),(74,52,19,NULL),(76,52,51,NULL),(77,53,1,NULL),(78,54,1,NULL),(79,55,13,NULL),(80,55,54,NULL),(81,56,1,NULL),(84,58,1,NULL),(85,59,13,NULL),(87,60,5,NULL),(91,61,13,NULL),(92,61,36,NULL),(94,65,35,NULL),(97,67,5,NULL),(98,67,37,NULL),(99,69,35,NULL),(101,70,11,NULL),(102,71,1,NULL),(103,71,58,NULL),(105,72,18,NULL),(106,73,5,NULL),(107,73,64,NULL),(108,73,19,NULL),(109,59,50,NULL),(115,39,76,NULL),(117,65,76,NULL),(118,30,76,NULL),(124,5,76,NULL),(125,37,76,NULL),(126,38,76,NULL),(128,42,76,NULL),(129,35,76,NULL),(130,60,76,NULL),(131,21,76,NULL),(132,18,76,NULL),(133,50,76,NULL),(134,20,76,NULL),(135,41,76,NULL),(136,17,76,NULL),(137,52,76,NULL),(139,37,74,NULL),(140,51,74,NULL),(141,51,75,NULL),(142,35,75,NULL),(143,15,49,NULL),(145,17,67,NULL),(146,38,13,NULL),(147,101,35,NULL),(148,101,13,NULL),(150,15,56,NULL),(152,69,47,NULL),(153,48,35,NULL),(154,102,1,NULL),(167,9,103,NULL),(168,66,9,NULL),(169,104,100,NULL),(172,103,76,NULL),(173,103,1,NULL),(174,103,44,NULL),(175,103,45,NULL),(176,103,11,NULL),(177,103,39,NULL),(178,103,17,NULL),(179,103,5,NULL),(180,103,67,NULL),(181,103,3,NULL),(182,103,34,NULL),(183,103,42,NULL),(184,103,43,NULL),(185,103,64,NULL),(186,103,35,NULL),(187,103,101,NULL),(188,103,75,NULL),(189,103,71,NULL),(190,103,72,NULL),(191,103,47,NULL),(192,103,69,NULL),(193,103,48,NULL),(194,103,2,NULL),(195,103,56,NULL),(196,103,57,NULL),(197,103,32,NULL),(198,103,73,NULL),(199,103,30,NULL),(200,103,31,NULL),(201,103,6,NULL),(202,103,40,NULL),(203,103,41,NULL),(204,103,37,NULL),(205,103,38,NULL),(206,103,53,NULL),(207,103,33,NULL),(210,103,54,NULL),(211,103,55,NULL),(212,103,15,NULL),(213,103,16,NULL),(215,103,51,NULL),(216,103,52,NULL),(218,103,65,NULL),(219,103,58,NULL),(220,103,59,NULL),(221,103,102,NULL),(222,103,49,NULL),(223,103,60,NULL),(224,103,50,NULL),(225,103,36,NULL),(226,103,61,NULL),(228,103,21,NULL),(229,103,19,NULL),(230,103,18,NULL),(231,103,13,NULL),(232,103,22,NULL),(233,103,70,NULL),(234,103,74,NULL),(237,66,103,NULL),(238,103,20,NULL),(239,106,11,NULL),(240,107,60,NULL),(241,21,72,NULL),(242,20,9,NULL),(246,102,35,NULL),(247,108,1,NULL),(248,102,13,NULL),(249,109,18,NULL),(250,109,13,NULL),(251,51,21,NULL),(253,48,49,NULL),(254,110,1,NULL),(255,110,76,NULL),(256,48,69,NULL),(257,47,111,NULL),(258,43,111,NULL),(259,72,111,NULL),(260,35,111,NULL),(261,5,111,NULL),(262,112,1,NULL),(263,114,112,NULL),(264,51,35,NULL),(265,72,49,NULL),(266,101,18,NULL),(268,65,57,NULL),(269,65,59,NULL),(270,65,49,NULL),(271,65,18,NULL),(272,65,13,NULL),(273,60,35,NULL),(275,50,59,NULL),(276,60,49,NULL),(280,5,53,NULL),(281,5,18,NULL),(282,50,60,NULL),(283,5,21,NULL),(285,58,76,NULL),(287,69,58,NULL),(288,115,66,NULL),(290,104,115,NULL),(291,115,103,NULL),(297,21,33,NULL),(298,49,54,NULL),(299,112,49,NULL),(300,114,13,NULL),(302,5,35,NULL),(303,69,49,NULL),(306,119,110,NULL),(307,1,76,NULL),(309,120,9,NULL),(310,120,66,NULL),(311,120,13,25508),(312,115,120,NULL),(314,43,18,NULL),(315,121,35,NULL),(316,121,21,NULL),(317,122,15,NULL),(318,16,122,NULL),(319,37,49,NULL),(320,37,18,NULL),(328,57,123,10578),(329,123,33,NULL),(330,123,56,NULL),(332,103,112,NULL),(333,57,13,NULL),(334,60,123,NULL),(335,124,37,NULL),(336,124,35,NULL),(337,103,124,NULL),(338,35,125,10578),(339,57,125,10578),(340,41,125,10578),(341,18,125,10578),(346,126,15,NULL),(347,102,49,NULL); /*!40000 ALTER TABLE `roleInherit` ENABLE KEYS */; UNLOCK TABLES; @@ -98,7 +98,7 @@ UNLOCK TABLES; LOCK TABLES `roleRole` WRITE; /*!40000 ALTER TABLE `roleRole` DISABLE KEYS */; -INSERT INTO `roleRole` VALUES (285864,1,1),(285865,1,2),(285866,1,3),(285870,1,6),(285869,1,11),(285867,1,70),(285868,1,76),(285871,2,2),(285873,2,6),(285872,2,11),(285874,3,3),(285876,3,6),(285875,3,11),(285878,5,1),(285891,5,2),(285890,5,3),(285877,5,5),(285897,5,6),(285893,5,11),(285888,5,13),(285879,5,18),(285880,5,21),(285881,5,33),(285882,5,35),(285896,5,36),(285899,5,44),(285898,5,47),(285892,5,49),(285883,5,53),(285895,5,54),(285894,5,58),(285889,5,70),(285887,5,72),(285886,5,75),(285884,5,76),(285885,5,111),(285900,6,6),(285903,9,1),(285904,9,2),(285905,9,3),(285906,9,5),(285907,9,6),(285901,9,9),(285908,9,11),(285909,9,13),(285910,9,15),(285911,9,16),(285912,9,17),(285913,9,18),(285914,9,19),(285915,9,20),(285916,9,21),(285917,9,22),(285918,9,30),(285919,9,31),(285920,9,32),(285921,9,33),(285922,9,34),(285923,9,35),(285924,9,36),(285925,9,37),(285926,9,38),(285927,9,39),(285928,9,40),(285929,9,41),(285930,9,42),(285931,9,43),(285932,9,44),(285933,9,45),(285934,9,47),(285935,9,48),(285936,9,49),(285937,9,50),(285938,9,51),(285939,9,52),(285940,9,53),(285941,9,54),(285942,9,55),(285943,9,56),(285944,9,57),(285945,9,58),(285946,9,59),(285947,9,60),(285948,9,61),(285949,9,64),(285950,9,65),(285951,9,67),(285952,9,69),(285953,9,70),(285954,9,71),(285955,9,72),(285956,9,73),(285957,9,74),(285958,9,75),(285959,9,76),(285960,9,101),(285961,9,102),(285902,9,103),(285963,9,111),(285962,9,122),(285965,11,6),(285964,11,11),(285967,13,1),(285968,13,2),(285969,13,3),(285973,13,6),(285972,13,11),(285966,13,13),(285970,13,70),(285971,13,76),(285980,15,1),(285989,15,2),(285988,15,3),(285991,15,6),(285990,15,11),(285974,15,15),(285975,15,35),(285982,15,36),(285986,15,44),(285985,15,47),(285976,15,49),(285983,15,54),(285977,15,56),(285984,15,58),(285987,15,70),(285979,15,75),(285978,15,76),(285981,15,111),(286000,16,1),(286009,16,2),(286008,16,3),(286011,16,6),(286010,16,11),(285994,16,15),(285992,16,16),(285995,16,35),(286002,16,36),(286006,16,44),(286005,16,47),(285996,16,49),(286003,16,54),(285997,16,56),(286004,16,58),(286007,16,70),(285999,16,75),(285998,16,76),(286001,16,111),(285993,16,122),(286020,17,1),(286036,17,2),(286035,17,3),(286027,17,5),(286059,17,6),(286024,17,9),(286058,17,11),(286023,17,13),(286057,17,15),(286022,17,16),(286012,17,17),(286019,17,18),(286056,17,19),(286013,17,20),(286028,17,21),(286055,17,22),(286054,17,30),(286053,17,31),(286052,17,32),(286030,17,33),(286051,17,34),(286038,17,35),(286033,17,36),(286014,17,37),(286050,17,38),(286015,17,39),(286049,17,40),(286048,17,41),(286047,17,42),(286046,17,43),(286045,17,44),(286060,17,45),(286061,17,47),(286062,17,48),(286025,17,49),(286063,17,50),(286064,17,51),(286065,17,52),(286041,17,53),(286032,17,54),(286066,17,55),(286044,17,56),(286029,17,57),(286031,17,58),(286037,17,59),(286067,17,60),(286068,17,61),(286016,17,64),(286021,17,65),(286017,17,67),(286069,17,69),(286034,17,70),(286070,17,71),(286043,17,72),(286071,17,73),(286026,17,74),(286072,17,75),(286018,17,76),(286073,17,101),(286074,17,102),(286040,17,103),(286042,17,111),(286039,17,122),(286076,18,1),(286079,18,2),(286078,18,3),(286082,18,6),(286081,18,11),(286075,18,18),(286080,18,70),(286077,18,76),(286093,19,1),(286099,19,2),(286098,19,3),(286103,19,6),(286102,19,11),(286085,19,13),(286086,19,18),(286083,19,19),(286084,19,21),(286087,19,33),(286096,19,36),(286101,19,44),(286100,19,47),(286092,19,49),(286088,19,53),(286095,19,54),(286094,19,58),(286097,19,70),(286089,19,72),(286090,19,76),(286091,19,111),(286113,20,1),(286125,20,2),(286124,20,3),(286123,20,5),(286122,20,6),(286105,20,9),(286121,20,11),(286106,20,13),(286120,20,15),(286107,20,16),(286119,20,17),(286111,20,18),(286118,20,19),(286104,20,20),(286126,20,21),(286127,20,22),(286128,20,30),(286129,20,31),(286130,20,32),(286131,20,33),(286132,20,34),(286110,20,35),(286133,20,36),(286134,20,37),(286135,20,38),(286136,20,39),(286137,20,40),(286138,20,41),(286139,20,42),(286140,20,43),(286141,20,44),(286142,20,45),(286143,20,47),(286144,20,48),(286115,20,49),(286145,20,50),(286146,20,51),(286147,20,52),(286148,20,53),(286149,20,54),(286150,20,55),(286151,20,56),(286116,20,57),(286152,20,58),(286117,20,59),(286153,20,60),(286154,20,61),(286155,20,64),(286108,20,65),(286156,20,67),(286157,20,69),(286158,20,70),(286159,20,71),(286160,20,72),(286161,20,73),(286162,20,74),(286163,20,75),(286109,20,76),(286164,20,101),(286165,20,102),(286114,20,103),(286166,20,111),(286112,20,122),(286176,21,1),(286182,21,2),(286181,21,3),(286186,21,6),(286185,21,11),(286168,21,13),(286169,21,18),(286167,21,21),(286170,21,33),(286179,21,36),(286184,21,44),(286183,21,47),(286175,21,49),(286171,21,53),(286178,21,54),(286177,21,58),(286180,21,70),(286172,21,72),(286173,21,76),(286174,21,111),(286191,22,1),(286200,22,2),(286199,22,3),(286207,22,6),(286204,22,11),(286188,22,13),(286190,22,18),(286189,22,21),(286187,22,22),(286192,22,33),(286203,22,36),(286206,22,44),(286205,22,47),(286197,22,49),(286193,22,53),(286202,22,54),(286201,22,58),(286198,22,70),(286194,22,72),(286195,22,76),(286196,22,111),(286220,30,1),(286234,30,2),(286233,30,3),(286209,30,5),(286243,30,6),(286221,30,9),(286244,30,11),(286222,30,13),(286242,30,15),(286223,30,16),(286241,30,17),(286219,30,18),(286240,30,19),(286210,30,20),(286218,30,21),(286211,30,22),(286208,30,30),(286239,30,31),(286238,30,32),(286217,30,33),(286237,30,34),(286216,30,35),(286236,30,36),(286235,30,37),(286245,30,38),(286246,30,39),(286247,30,40),(286248,30,41),(286249,30,42),(286250,30,43),(286251,30,44),(286252,30,45),(286253,30,47),(286254,30,48),(286227,30,49),(286255,30,50),(286256,30,51),(286257,30,52),(286212,30,53),(286258,30,54),(286259,30,55),(286260,30,56),(286226,30,57),(286261,30,58),(286225,30,59),(286262,30,60),(286263,30,61),(286213,30,64),(286224,30,65),(286264,30,67),(286265,30,69),(286232,30,70),(286266,30,71),(286231,30,72),(286267,30,73),(286268,30,74),(286230,30,75),(286214,30,76),(286269,30,101),(286270,30,102),(286229,30,103),(286215,30,111),(286228,30,122),(286272,31,1),(286273,31,2),(286274,31,3),(286278,31,6),(286277,31,11),(286271,31,31),(286275,31,70),(286276,31,76),(286280,32,1),(286281,32,2),(286282,32,3),(286286,32,6),(286285,32,11),(286279,32,32),(286283,32,70),(286284,32,76),(286287,33,33),(286289,34,1),(286294,34,2),(286293,34,3),(286297,34,6),(286296,34,11),(286290,34,13),(286291,34,33),(286288,34,34),(286292,34,70),(286295,34,76),(286299,35,1),(286305,35,2),(286304,35,3),(286307,35,6),(286306,35,11),(286298,35,35),(286303,35,70),(286300,35,75),(286301,35,76),(286302,35,111),(286312,36,1),(286314,36,2),(286313,36,3),(286318,36,6),(286317,36,11),(286308,36,36),(286309,36,44),(286310,36,47),(286315,36,70),(286316,36,76),(286311,36,111),(286320,37,1),(286329,37,2),(286328,37,3),(286335,37,6),(286333,37,11),(286321,37,18),(286326,37,36),(286319,37,37),(286332,37,44),(286331,37,47),(286322,37,49),(286325,37,54),(286330,37,58),(286327,37,70),(286323,37,74),(286324,37,76),(286334,37,111),(286344,38,1),(286348,38,2),(286347,38,3),(286355,38,6),(286353,38,11),(286337,38,13),(286343,38,18),(286345,38,36),(286338,38,37),(286336,38,38),(286352,38,44),(286351,38,47),(286342,38,49),(286349,38,54),(286350,38,58),(286339,38,64),(286346,38,70),(286341,38,74),(286340,38,76),(286354,38,111),(286364,39,1),(286374,39,2),(286373,39,3),(286357,39,5),(286381,39,6),(286378,39,11),(286367,39,13),(286363,39,18),(286358,39,21),(286362,39,33),(286361,39,35),(286377,39,36),(286356,39,39),(286380,39,44),(286379,39,47),(286370,39,49),(286365,39,53),(286376,39,54),(286369,39,56),(286359,39,57),(286375,39,58),(286372,39,70),(286368,39,72),(286371,39,75),(286360,39,76),(286366,39,111),(286383,40,1),(286386,40,2),(286385,40,3),(286396,40,6),(286394,40,11),(286389,40,36),(286382,40,40),(286393,40,44),(286392,40,47),(286384,40,49),(286390,40,54),(286391,40,58),(286387,40,70),(286388,40,76),(286395,40,111),(286405,41,1),(286409,41,2),(286408,41,3),(286415,41,6),(286414,41,11),(286398,41,13),(286399,41,35),(286406,41,36),(286400,41,40),(286397,41,41),(286413,41,44),(286412,41,47),(286402,41,49),(286410,41,54),(286411,41,58),(286407,41,70),(286404,41,75),(286401,41,76),(286403,41,111),(286422,42,1),(286430,42,2),(286429,42,3),(286432,42,6),(286431,42,11),(286417,42,35),(286423,42,36),(286416,42,42),(286427,42,44),(286426,42,47),(286418,42,49),(286424,42,54),(286425,42,58),(286428,42,70),(286421,42,75),(286419,42,76),(286420,42,111),(286441,43,1),(286445,43,2),(286444,43,3),(286452,43,6),(286451,43,11),(286434,43,13),(286435,43,18),(286439,43,35),(286446,43,36),(286436,43,42),(286433,43,43),(286450,43,44),(286449,43,47),(286438,43,49),(286447,43,54),(286448,43,58),(286443,43,70),(286442,43,75),(286440,43,76),(286437,43,111),(286454,44,1),(286455,44,2),(286456,44,3),(286460,44,6),(286459,44,11),(286453,44,44),(286457,44,70),(286458,44,76),(286464,45,1),(286466,45,2),(286465,45,3),(286470,45,6),(286469,45,11),(286462,45,13),(286463,45,44),(286461,45,45),(286467,45,70),(286468,45,76),(286472,47,1),(286475,47,2),(286474,47,3),(286479,47,6),(286478,47,11),(286471,47,47),(286476,47,70),(286477,47,76),(286473,47,111),(286490,48,1),(286496,48,2),(286495,48,3),(286498,48,6),(286497,48,11),(286481,48,13),(286482,48,35),(286486,48,36),(286493,48,44),(286483,48,47),(286480,48,48),(286484,48,49),(286491,48,54),(286492,48,58),(286485,48,69),(286494,48,70),(286489,48,75),(286488,48,76),(286487,48,111),(286503,49,1),(286509,49,2),(286508,49,3),(286512,49,6),(286511,49,11),(286500,49,36),(286505,49,44),(286504,49,47),(286499,49,49),(286501,49,54),(286502,49,58),(286507,49,70),(286506,49,76),(286510,49,111),(286529,50,1),(286538,50,2),(286537,50,3),(286533,50,5),(286540,50,6),(286539,50,11),(286514,50,13),(286528,50,18),(286515,50,21),(286527,50,33),(286516,50,35),(286522,50,36),(286535,50,44),(286534,50,47),(286517,50,49),(286513,50,50),(286526,50,53),(286530,50,54),(286532,50,56),(286518,50,57),(286531,50,58),(286519,50,59),(286520,50,60),(286536,50,70),(286525,50,72),(286524,50,75),(286521,50,76),(286523,50,111),(286542,51,1),(286551,51,2),(286550,51,3),(286562,51,6),(286558,51,11),(286547,51,13),(286552,51,18),(286543,51,21),(286553,51,33),(286544,51,35),(286561,51,36),(286564,51,44),(286563,51,47),(286557,51,49),(286541,51,51),(286554,51,53),(286560,51,54),(286559,51,58),(286549,51,70),(286555,51,72),(286545,51,74),(286546,51,75),(286548,51,76),(286556,51,111),(286573,52,1),(286579,52,2),(286578,52,3),(286588,52,6),(286584,52,11),(286566,52,13),(286576,52,18),(286567,52,19),(286572,52,21),(286575,52,33),(286571,52,35),(286587,52,36),(286590,52,44),(286589,52,47),(286583,52,49),(286568,52,51),(286565,52,52),(286580,52,53),(286586,52,54),(286585,52,58),(286577,52,70),(286581,52,72),(286570,52,74),(286574,52,75),(286569,52,76),(286582,52,111),(286592,53,1),(286593,53,2),(286594,53,3),(286598,53,6),(286597,53,11),(286591,53,53),(286595,53,70),(286596,53,76),(286600,54,1),(286601,54,2),(286602,54,3),(286606,54,6),(286605,54,11),(286599,54,54),(286603,54,70),(286604,54,76),(286610,55,1),(286612,55,2),(286611,55,3),(286616,55,6),(286615,55,11),(286608,55,13),(286609,55,54),(286607,55,55),(286613,55,70),(286614,55,76),(286618,56,1),(286619,56,2),(286620,56,3),(286624,56,6),(286623,56,11),(286617,56,56),(286621,56,70),(286622,56,76),(286630,57,1),(286633,57,2),(286632,57,3),(286635,57,6),(286634,57,11),(286626,57,13),(286627,57,33),(286628,57,56),(286625,57,57),(286631,57,70),(286629,57,76),(286637,58,1),(286640,58,2),(286639,58,3),(286643,58,6),(286642,58,11),(286636,58,58),(286641,58,70),(286638,58,76),(286648,59,1),(286660,59,2),(286659,59,3),(286667,59,5),(286671,59,6),(286670,59,11),(286645,59,13),(286657,59,18),(286647,59,21),(286656,59,33),(286649,59,35),(286663,59,36),(286669,59,44),(286668,59,47),(286650,59,49),(286646,59,50),(286655,59,53),(286664,59,54),(286666,59,56),(286651,59,57),(286665,59,58),(286644,59,59),(286652,59,60),(286658,59,70),(286654,59,72),(286661,59,75),(286653,59,76),(286662,59,111),(286682,60,1),(286695,60,2),(286694,60,3),(286673,60,5),(286697,60,6),(286696,60,11),(286688,60,13),(286681,60,18),(286680,60,21),(286679,60,33),(286674,60,35),(286685,60,36),(286691,60,44),(286690,60,47),(286675,60,49),(286678,60,53),(286686,60,54),(286689,60,56),(286676,60,57),(286687,60,58),(286672,60,60),(286693,60,70),(286692,60,72),(286684,60,75),(286677,60,76),(286683,60,111),(286702,61,1),(286706,61,2),(286705,61,3),(286710,61,6),(286709,61,11),(286699,61,13),(286700,61,36),(286701,61,44),(286703,61,47),(286698,61,61),(286704,61,70),(286707,61,76),(286708,61,111),(286711,62,62),(286712,64,64),(286727,65,1),(286736,65,2),(286735,65,3),(286737,65,5),(286741,65,6),(286740,65,11),(286714,65,13),(286715,65,18),(286731,65,21),(286721,65,33),(286716,65,35),(286724,65,36),(286733,65,44),(286732,65,47),(286717,65,49),(286729,65,50),(286739,65,53),(286723,65,54),(286728,65,56),(286718,65,57),(286722,65,58),(286719,65,59),(286730,65,60),(286713,65,65),(286734,65,70),(286738,65,72),(286726,65,75),(286720,65,76),(286725,65,111),(286746,66,1),(286745,66,2),(286747,66,3),(286748,66,5),(286749,66,6),(286743,66,9),(286750,66,11),(286751,66,13),(286752,66,15),(286753,66,16),(286754,66,17),(286755,66,18),(286756,66,19),(286757,66,20),(286758,66,21),(286759,66,22),(286760,66,30),(286761,66,31),(286762,66,32),(286763,66,33),(286764,66,34),(286765,66,35),(286766,66,36),(286767,66,37),(286768,66,38),(286769,66,39),(286770,66,40),(286771,66,41),(286772,66,42),(286773,66,43),(286774,66,44),(286775,66,45),(286776,66,47),(286777,66,48),(286778,66,49),(286779,66,50),(286780,66,51),(286781,66,52),(286782,66,53),(286783,66,54),(286784,66,55),(286785,66,56),(286786,66,57),(286787,66,58),(286788,66,59),(286789,66,60),(286790,66,61),(286791,66,64),(286792,66,65),(286742,66,66),(286793,66,67),(286794,66,69),(286795,66,70),(286796,66,71),(286797,66,72),(286798,66,73),(286799,66,74),(286800,66,75),(286801,66,76),(286802,66,101),(286803,66,102),(286744,66,103),(286805,66,111),(286804,66,122),(286810,67,1),(286827,67,2),(286826,67,3),(286807,67,5),(286831,67,6),(286830,67,11),(286824,67,13),(286809,67,18),(286811,67,21),(286812,67,33),(286813,67,35),(286821,67,36),(286808,67,37),(286829,67,44),(286828,67,47),(286817,67,49),(286814,67,53),(286820,67,54),(286819,67,58),(286806,67,67),(286825,67,70),(286823,67,72),(286818,67,74),(286822,67,75),(286815,67,76),(286816,67,111),(286840,69,1),(286846,69,2),(286845,69,3),(286848,69,6),(286847,69,11),(286833,69,35),(286841,69,36),(286843,69,44),(286834,69,47),(286835,69,49),(286842,69,54),(286836,69,58),(286832,69,69),(286844,69,70),(286839,69,75),(286838,69,76),(286837,69,111),(286851,70,6),(286850,70,11),(286849,70,70),(286853,71,1),(286856,71,2),(286855,71,3),(286860,71,6),(286859,71,11),(286854,71,58),(286857,71,70),(286852,71,71),(286858,71,76),(286867,72,1),(286874,72,2),(286873,72,3),(286876,72,6),(286875,72,11),(286862,72,18),(286865,72,36),(286871,72,44),(286870,72,47),(286863,72,49),(286868,72,54),(286869,72,58),(286872,72,70),(286861,72,72),(286866,72,76),(286864,72,111),(286883,73,1),(286894,73,2),(286893,73,3),(286878,73,5),(286900,73,6),(286896,73,11),(286891,73,13),(286882,73,18),(286879,73,19),(286881,73,21),(286884,73,33),(286885,73,35),(286899,73,36),(286902,73,44),(286901,73,47),(286895,73,49),(286886,73,53),(286898,73,54),(286897,73,58),(286880,73,64),(286892,73,70),(286890,73,72),(286877,73,73),(286889,73,75),(286887,73,76),(286888,73,111),(286903,74,74),(286904,75,75),(286905,76,76),(286907,100,1),(286908,100,2),(286909,100,3),(286910,100,5),(286911,100,6),(286912,100,9),(286913,100,11),(286914,100,13),(286915,100,15),(286916,100,16),(286917,100,17),(286918,100,18),(286919,100,19),(286920,100,20),(286921,100,21),(286922,100,22),(286923,100,30),(286924,100,31),(286925,100,32),(286926,100,33),(286927,100,34),(286928,100,35),(286929,100,36),(286930,100,37),(286931,100,38),(286932,100,39),(286933,100,40),(286934,100,41),(286935,100,42),(286936,100,43),(286937,100,44),(286938,100,45),(286939,100,47),(286940,100,48),(286941,100,49),(286942,100,50),(286943,100,51),(286944,100,52),(286945,100,53),(286946,100,54),(286947,100,55),(286948,100,56),(286949,100,57),(286950,100,58),(286951,100,59),(286952,100,60),(286953,100,61),(286954,100,62),(286955,100,64),(286956,100,65),(286957,100,66),(286958,100,67),(286959,100,69),(286960,100,70),(286961,100,71),(286962,100,72),(286963,100,73),(286964,100,74),(286965,100,75),(286966,100,76),(286906,100,100),(286967,100,101),(286968,100,102),(286969,100,103),(286970,100,104),(286971,100,105),(286972,100,106),(286973,100,107),(286974,100,108),(286975,100,109),(286976,100,110),(286977,100,111),(286978,100,112),(286979,100,114),(286980,100,115),(286981,100,119),(286984,100,120),(286982,100,121),(286983,100,122),(286991,101,1),(286995,101,2),(286994,101,3),(286997,101,6),(286996,101,11),(286986,101,13),(286987,101,18),(286988,101,35),(286993,101,70),(286989,101,75),(286990,101,76),(286985,101,101),(286992,101,111),(286999,102,1),(287004,102,2),(287003,102,3),(287009,102,6),(287008,102,11),(287000,102,13),(287001,102,35),(287002,102,70),(287006,102,75),(287005,102,76),(286998,102,102),(287007,102,111),(287011,103,1),(287012,103,2),(287013,103,3),(287014,103,5),(287015,103,6),(287070,103,9),(287016,103,11),(287017,103,13),(287018,103,15),(287019,103,16),(287020,103,17),(287021,103,18),(287022,103,19),(287023,103,20),(287024,103,21),(287025,103,22),(287026,103,30),(287027,103,31),(287028,103,32),(287029,103,33),(287030,103,34),(287031,103,35),(287032,103,36),(287033,103,37),(287034,103,38),(287035,103,39),(287036,103,40),(287037,103,41),(287038,103,42),(287039,103,43),(287040,103,44),(287041,103,45),(287042,103,47),(287043,103,48),(287044,103,49),(287045,103,50),(287046,103,51),(287047,103,52),(287048,103,53),(287049,103,54),(287050,103,55),(287051,103,56),(287052,103,57),(287053,103,58),(287054,103,59),(287055,103,60),(287056,103,61),(287057,103,64),(287058,103,65),(287059,103,67),(287060,103,69),(287061,103,70),(287062,103,71),(287063,103,72),(287064,103,73),(287065,103,74),(287066,103,75),(287067,103,76),(287068,103,101),(287069,103,102),(287010,103,103),(287072,103,111),(287071,103,122),(287080,104,1),(287079,104,2),(287082,104,3),(287083,104,5),(287084,104,6),(287081,104,9),(287085,104,11),(287086,104,13),(287087,104,15),(287088,104,16),(287089,104,17),(287090,104,18),(287091,104,19),(287092,104,20),(287093,104,21),(287094,104,22),(287095,104,30),(287096,104,31),(287097,104,32),(287098,104,33),(287099,104,34),(287100,104,35),(287101,104,36),(287102,104,37),(287103,104,38),(287104,104,39),(287105,104,40),(287106,104,41),(287107,104,42),(287108,104,43),(287109,104,44),(287110,104,45),(287111,104,47),(287112,104,48),(287113,104,49),(287114,104,50),(287115,104,51),(287116,104,52),(287117,104,53),(287118,104,54),(287119,104,55),(287120,104,56),(287121,104,57),(287122,104,58),(287123,104,59),(287124,104,60),(287125,104,61),(287146,104,62),(287126,104,64),(287127,104,65),(287077,104,66),(287128,104,67),(287129,104,69),(287130,104,70),(287131,104,71),(287132,104,72),(287133,104,73),(287134,104,74),(287135,104,75),(287136,104,76),(287074,104,100),(287137,104,101),(287138,104,102),(287076,104,103),(287073,104,104),(287143,104,105),(287142,104,106),(287149,104,107),(287151,104,108),(287150,104,109),(287147,104,110),(287140,104,111),(287144,104,112),(287145,104,114),(287075,104,115),(287148,104,119),(287078,104,120),(287141,104,121),(287139,104,122),(287152,105,105),(287155,106,6),(287154,106,11),(287153,106,106),(287167,107,1),(287180,107,2),(287179,107,3),(287158,107,5),(287182,107,6),(287181,107,11),(287173,107,13),(287166,107,18),(287165,107,21),(287164,107,33),(287159,107,35),(287170,107,36),(287176,107,44),(287175,107,47),(287160,107,49),(287163,107,53),(287171,107,54),(287174,107,56),(287161,107,57),(287172,107,58),(287157,107,60),(287178,107,70),(287177,107,72),(287169,107,75),(287162,107,76),(287156,107,107),(287168,107,111),(287184,108,1),(287185,108,2),(287186,108,3),(287190,108,6),(287189,108,11),(287187,108,70),(287188,108,76),(287183,108,108),(287195,109,1),(287197,109,2),(287196,109,3),(287200,109,6),(287199,109,11),(287192,109,13),(287193,109,18),(287198,109,70),(287194,109,76),(287191,109,109),(287202,110,1),(287205,110,2),(287204,110,3),(287208,110,6),(287207,110,11),(287206,110,70),(287203,110,76),(287201,110,110),(287209,111,111),(287211,112,1),(287214,112,2),(287213,112,3),(287224,112,6),(287222,112,11),(287217,112,36),(287221,112,44),(287220,112,47),(287212,112,49),(287218,112,54),(287219,112,58),(287215,112,70),(287216,112,76),(287223,112,111),(287210,112,112),(287229,114,1),(287231,114,2),(287230,114,3),(287241,114,6),(287239,114,11),(287226,114,13),(287234,114,36),(287238,114,44),(287237,114,47),(287228,114,49),(287235,114,54),(287236,114,58),(287232,114,70),(287233,114,76),(287240,114,111),(287227,114,112),(287225,114,114),(287247,115,1),(287246,115,2),(287249,115,3),(287250,115,5),(287251,115,6),(287248,115,9),(287252,115,11),(287253,115,13),(287254,115,15),(287255,115,16),(287256,115,17),(287257,115,18),(287258,115,19),(287259,115,20),(287260,115,21),(287261,115,22),(287262,115,30),(287263,115,31),(287264,115,32),(287265,115,33),(287266,115,34),(287267,115,35),(287268,115,36),(287269,115,37),(287270,115,38),(287271,115,39),(287272,115,40),(287273,115,41),(287274,115,42),(287275,115,43),(287276,115,44),(287277,115,45),(287278,115,47),(287279,115,48),(287280,115,49),(287281,115,50),(287282,115,51),(287283,115,52),(287284,115,53),(287285,115,54),(287286,115,55),(287287,115,56),(287288,115,57),(287289,115,58),(287290,115,59),(287291,115,60),(287292,115,61),(287293,115,64),(287294,115,65),(287243,115,66),(287295,115,67),(287296,115,69),(287297,115,70),(287298,115,71),(287299,115,72),(287300,115,73),(287301,115,74),(287302,115,75),(287303,115,76),(287304,115,101),(287305,115,102),(287244,115,103),(287307,115,111),(287242,115,115),(287245,115,120),(287306,115,122),(287310,119,1),(287313,119,2),(287312,119,3),(287316,119,6),(287315,119,11),(287314,119,70),(287311,119,76),(287309,119,110),(287308,119,119),(287363,120,1),(287367,120,2),(287366,120,3),(287365,120,5),(287368,120,6),(287360,120,9),(287369,120,11),(287361,120,13),(287370,120,15),(287371,120,16),(287372,120,17),(287373,120,18),(287374,120,19),(287375,120,20),(287376,120,21),(287377,120,22),(287378,120,30),(287379,120,31),(287380,120,32),(287381,120,33),(287382,120,34),(287383,120,35),(287384,120,36),(287385,120,37),(287386,120,38),(287387,120,39),(287388,120,40),(287389,120,41),(287390,120,42),(287391,120,43),(287392,120,44),(287393,120,45),(287394,120,47),(287395,120,48),(287396,120,49),(287397,120,50),(287398,120,51),(287399,120,52),(287400,120,53),(287401,120,54),(287402,120,55),(287403,120,56),(287404,120,57),(287405,120,58),(287406,120,59),(287407,120,60),(287408,120,61),(287409,120,64),(287410,120,65),(287362,120,66),(287411,120,67),(287412,120,69),(287413,120,70),(287414,120,71),(287415,120,72),(287416,120,73),(287417,120,74),(287418,120,75),(287419,120,76),(287420,120,101),(287421,120,102),(287364,120,103),(287423,120,111),(287359,120,120),(287422,120,122),(287326,121,1),(287331,121,2),(287330,121,3),(287337,121,6),(287333,121,11),(287321,121,13),(287320,121,18),(287318,121,21),(287322,121,33),(287319,121,35),(287336,121,36),(287339,121,44),(287338,121,47),(287332,121,49),(287323,121,53),(287335,121,54),(287334,121,58),(287329,121,70),(287324,121,72),(287327,121,75),(287325,121,76),(287328,121,111),(287317,121,121),(287347,122,1),(287356,122,2),(287355,122,3),(287358,122,6),(287357,122,11),(287341,122,15),(287342,122,35),(287349,122,36),(287353,122,44),(287352,122,47),(287343,122,49),(287350,122,54),(287344,122,56),(287351,122,58),(287354,122,70),(287346,122,75),(287345,122,76),(287348,122,111),(287340,122,122); +INSERT INTO `roleRole` VALUES (326595,1,1),(326596,1,2),(326597,1,3),(326601,1,6),(326600,1,11),(326598,1,70),(326599,1,76),(326602,2,2),(326604,2,6),(326603,2,11),(326605,3,3),(326607,3,6),(326606,3,11),(326609,5,1),(326623,5,2),(326622,5,3),(326608,5,5),(326629,5,6),(326625,5,11),(326619,5,13),(326610,5,18),(326611,5,21),(326612,5,33),(326613,5,35),(326628,5,36),(326631,5,44),(326630,5,47),(326624,5,49),(326614,5,53),(326627,5,54),(326626,5,58),(326621,5,70),(326618,5,72),(326617,5,75),(326615,5,76),(326616,5,111),(326620,5,125),(326632,6,6),(326635,9,1),(326636,9,2),(326637,9,3),(326638,9,5),(326639,9,6),(326633,9,9),(326640,9,11),(326641,9,13),(326642,9,15),(326643,9,16),(326644,9,17),(326645,9,18),(326646,9,19),(326647,9,20),(326648,9,21),(326649,9,22),(326650,9,30),(326651,9,31),(326652,9,32),(326653,9,33),(326654,9,34),(326655,9,35),(326656,9,36),(326657,9,37),(326658,9,38),(326659,9,39),(326660,9,40),(326661,9,41),(326662,9,42),(326663,9,43),(326664,9,44),(326665,9,45),(326666,9,47),(326667,9,48),(326668,9,49),(326669,9,50),(326670,9,51),(326671,9,52),(326672,9,53),(326673,9,54),(326674,9,55),(326675,9,56),(326676,9,57),(326677,9,58),(326678,9,59),(326679,9,60),(326680,9,61),(326681,9,64),(326682,9,65),(326683,9,67),(326684,9,69),(326685,9,70),(326686,9,71),(326687,9,72),(326688,9,73),(326689,9,74),(326690,9,75),(326691,9,76),(326692,9,101),(326693,9,102),(326634,9,103),(326699,9,111),(326694,9,112),(326698,9,122),(326696,9,123),(326695,9,124),(326697,9,125),(326701,11,6),(326700,11,11),(326703,13,1),(326704,13,2),(326705,13,3),(326709,13,6),(326708,13,11),(326702,13,13),(326706,13,70),(326707,13,76),(326716,15,1),(326726,15,2),(326725,15,3),(326728,15,6),(326727,15,11),(326710,15,15),(326711,15,35),(326719,15,36),(326723,15,44),(326722,15,47),(326712,15,49),(326720,15,54),(326713,15,56),(326721,15,58),(326724,15,70),(326715,15,75),(326714,15,76),(326717,15,111),(326718,15,125),(326737,16,1),(326747,16,2),(326746,16,3),(326749,16,6),(326748,16,11),(326731,16,15),(326729,16,16),(326732,16,35),(326740,16,36),(326744,16,44),(326743,16,47),(326733,16,49),(326741,16,54),(326734,16,56),(326742,16,58),(326745,16,70),(326736,16,75),(326735,16,76),(326738,16,111),(326730,16,122),(326739,16,125),(326758,17,1),(326774,17,2),(326773,17,3),(326765,17,5),(326799,17,6),(326762,17,9),(326798,17,11),(326761,17,13),(326797,17,15),(326760,17,16),(326750,17,17),(326757,17,18),(326796,17,19),(326751,17,20),(326766,17,21),(326795,17,22),(326794,17,30),(326793,17,31),(326792,17,32),(326779,17,33),(326791,17,34),(326776,17,35),(326770,17,36),(326752,17,37),(326790,17,38),(326753,17,39),(326789,17,40),(326788,17,41),(326787,17,42),(326786,17,43),(326785,17,44),(326784,17,45),(326800,17,47),(326801,17,48),(326763,17,49),(326802,17,50),(326803,17,51),(326804,17,52),(326780,17,53),(326769,17,54),(326805,17,55),(326806,17,56),(326767,17,57),(326768,17,58),(326775,17,59),(326807,17,60),(326808,17,61),(326754,17,64),(326759,17,65),(326755,17,67),(326809,17,69),(326772,17,70),(326810,17,71),(326782,17,72),(326811,17,73),(326764,17,74),(326812,17,75),(326756,17,76),(326813,17,101),(326814,17,102),(326778,17,103),(326781,17,111),(326815,17,112),(326777,17,122),(326783,17,123),(326816,17,124),(326771,17,125),(326818,18,1),(326823,18,2),(326822,18,3),(326825,18,6),(326824,18,11),(326817,18,18),(326821,18,70),(326819,18,76),(326820,18,125),(326837,19,1),(326843,19,2),(326842,19,3),(326847,19,6),(326846,19,11),(326828,19,13),(326829,19,18),(326826,19,19),(326827,19,21),(326830,19,33),(326840,19,36),(326845,19,44),(326844,19,47),(326835,19,49),(326831,19,53),(326839,19,54),(326838,19,58),(326841,19,70),(326832,19,72),(326833,19,76),(326834,19,111),(326836,19,125),(326857,20,1),(326869,20,2),(326868,20,3),(326867,20,5),(326866,20,6),(326849,20,9),(326865,20,11),(326850,20,13),(326864,20,15),(326851,20,16),(326863,20,17),(326855,20,18),(326862,20,19),(326848,20,20),(326870,20,21),(326871,20,22),(326872,20,30),(326873,20,31),(326874,20,32),(326875,20,33),(326876,20,34),(326854,20,35),(326877,20,36),(326878,20,37),(326879,20,38),(326880,20,39),(326881,20,40),(326882,20,41),(326883,20,42),(326884,20,43),(326885,20,44),(326886,20,45),(326887,20,47),(326888,20,48),(326859,20,49),(326889,20,50),(326890,20,51),(326891,20,52),(326892,20,53),(326893,20,54),(326894,20,55),(326895,20,56),(326860,20,57),(326896,20,58),(326861,20,59),(326897,20,60),(326898,20,61),(326899,20,64),(326852,20,65),(326900,20,67),(326901,20,69),(326902,20,70),(326903,20,71),(326904,20,72),(326905,20,73),(326906,20,74),(326907,20,75),(326853,20,76),(326908,20,101),(326909,20,102),(326858,20,103),(326913,20,111),(326910,20,112),(326856,20,122),(326914,20,123),(326911,20,124),(326912,20,125),(326925,21,1),(326931,21,2),(326930,21,3),(326935,21,6),(326934,21,11),(326916,21,13),(326917,21,18),(326915,21,21),(326918,21,33),(326928,21,36),(326933,21,44),(326932,21,47),(326923,21,49),(326919,21,53),(326927,21,54),(326926,21,58),(326929,21,70),(326920,21,72),(326921,21,76),(326922,21,111),(326924,21,125),(326940,22,1),(326950,22,2),(326949,22,3),(326957,22,6),(326954,22,11),(326937,22,13),(326939,22,18),(326938,22,21),(326936,22,22),(326941,22,33),(326953,22,36),(326956,22,44),(326955,22,47),(326946,22,49),(326942,22,53),(326952,22,54),(326951,22,58),(326948,22,70),(326943,22,72),(326944,22,76),(326945,22,111),(326947,22,125),(326970,30,1),(326984,30,2),(326983,30,3),(326959,30,5),(326995,30,6),(326971,30,9),(326996,30,11),(326972,30,13),(326994,30,15),(326973,30,16),(326993,30,17),(326969,30,18),(326992,30,19),(326960,30,20),(326968,30,21),(326961,30,22),(326958,30,30),(326991,30,31),(326990,30,32),(326967,30,33),(326989,30,34),(326966,30,35),(326988,30,36),(326987,30,37),(326986,30,38),(326997,30,39),(326998,30,40),(326999,30,41),(327000,30,42),(327001,30,43),(327002,30,44),(327003,30,45),(327004,30,47),(327005,30,48),(326976,30,49),(327006,30,50),(327007,30,51),(327008,30,52),(326962,30,53),(327009,30,54),(327010,30,55),(327011,30,56),(326975,30,57),(327012,30,58),(326985,30,59),(327013,30,60),(327014,30,61),(326963,30,64),(326974,30,65),(327015,30,67),(327016,30,69),(326982,30,70),(327017,30,71),(326980,30,72),(327018,30,73),(327019,30,74),(326979,30,75),(326964,30,76),(327020,30,101),(327021,30,102),(326978,30,103),(326965,30,111),(327022,30,112),(326977,30,122),(327024,30,123),(327023,30,124),(326981,30,125),(327026,31,1),(327027,31,2),(327028,31,3),(327032,31,6),(327031,31,11),(327025,31,31),(327029,31,70),(327030,31,76),(327034,32,1),(327035,32,2),(327036,32,3),(327040,32,6),(327039,32,11),(327033,32,32),(327037,32,70),(327038,32,76),(327041,33,33),(327043,34,1),(327048,34,2),(327047,34,3),(327051,34,6),(327050,34,11),(327044,34,13),(327045,34,33),(327042,34,34),(327046,34,70),(327049,34,76),(327053,35,1),(327060,35,2),(327059,35,3),(327062,35,6),(327061,35,11),(327052,35,35),(327058,35,70),(327054,35,75),(327055,35,76),(327056,35,111),(327057,35,125),(327067,36,1),(327069,36,2),(327068,36,3),(327073,36,6),(327072,36,11),(327063,36,36),(327064,36,44),(327065,36,47),(327070,36,70),(327071,36,76),(327066,36,111),(327075,37,1),(327084,37,2),(327083,37,3),(327091,37,6),(327089,37,11),(327076,37,18),(327080,37,36),(327074,37,37),(327088,37,44),(327087,37,47),(327077,37,49),(327085,37,54),(327086,37,58),(327082,37,70),(327078,37,74),(327079,37,76),(327090,37,111),(327081,37,125),(327100,38,1),(327104,38,2),(327103,38,3),(327112,38,6),(327110,38,11),(327093,38,13),(327099,38,18),(327105,38,36),(327094,38,37),(327092,38,38),(327109,38,44),(327108,38,47),(327098,38,49),(327106,38,54),(327107,38,58),(327095,38,64),(327102,38,70),(327097,38,74),(327096,38,76),(327111,38,111),(327101,38,125),(327121,39,1),(327133,39,2),(327132,39,3),(327114,39,5),(327140,39,6),(327137,39,11),(327124,39,13),(327120,39,18),(327115,39,21),(327119,39,33),(327118,39,35),(327136,39,36),(327113,39,39),(327139,39,44),(327138,39,47),(327129,39,49),(327122,39,53),(327135,39,54),(327128,39,56),(327116,39,57),(327134,39,58),(327131,39,70),(327125,39,72),(327130,39,75),(327117,39,76),(327123,39,111),(327126,39,123),(327127,39,125),(327142,40,1),(327145,40,2),(327144,40,3),(327155,40,6),(327153,40,11),(327148,40,36),(327141,40,40),(327152,40,44),(327151,40,47),(327143,40,49),(327149,40,54),(327150,40,58),(327146,40,70),(327147,40,76),(327154,40,111),(327165,41,1),(327170,41,2),(327169,41,3),(327175,41,6),(327174,41,11),(327157,41,13),(327158,41,35),(327167,41,36),(327159,41,40),(327156,41,41),(327173,41,44),(327172,41,47),(327162,41,49),(327166,41,54),(327171,41,58),(327168,41,70),(327164,41,75),(327160,41,76),(327163,41,111),(327161,41,125),(327182,42,1),(327191,42,2),(327190,42,3),(327193,42,6),(327192,42,11),(327177,42,35),(327184,42,36),(327176,42,42),(327188,42,44),(327187,42,47),(327178,42,49),(327185,42,54),(327186,42,58),(327189,42,70),(327181,42,75),(327179,42,76),(327180,42,111),(327183,42,125),(327202,43,1),(327208,43,2),(327207,43,3),(327214,43,6),(327213,43,11),(327195,43,13),(327196,43,18),(327199,43,35),(327204,43,36),(327197,43,42),(327194,43,43),(327212,43,44),(327211,43,47),(327203,43,49),(327209,43,54),(327210,43,58),(327206,43,70),(327205,43,75),(327201,43,76),(327198,43,111),(327200,43,125),(327216,44,1),(327217,44,2),(327218,44,3),(327222,44,6),(327221,44,11),(327215,44,44),(327219,44,70),(327220,44,76),(327226,45,1),(327228,45,2),(327227,45,3),(327232,45,6),(327231,45,11),(327224,45,13),(327225,45,44),(327223,45,45),(327229,45,70),(327230,45,76),(327234,47,1),(327237,47,2),(327236,47,3),(327241,47,6),(327240,47,11),(327233,47,47),(327238,47,70),(327239,47,76),(327235,47,111),(327252,48,1),(327259,48,2),(327258,48,3),(327261,48,6),(327260,48,11),(327243,48,13),(327244,48,35),(327253,48,36),(327256,48,44),(327245,48,47),(327242,48,48),(327246,48,49),(327254,48,54),(327255,48,58),(327247,48,69),(327257,48,70),(327251,48,75),(327250,48,76),(327249,48,111),(327248,48,125),(327266,49,1),(327272,49,2),(327271,49,3),(327275,49,6),(327274,49,11),(327263,49,36),(327268,49,44),(327267,49,47),(327262,49,49),(327264,49,54),(327265,49,58),(327270,49,70),(327269,49,76),(327273,49,111),(327288,50,1),(327301,50,2),(327300,50,3),(327290,50,5),(327305,50,6),(327304,50,11),(327277,50,13),(327287,50,18),(327278,50,21),(327286,50,33),(327291,50,35),(327295,50,36),(327303,50,44),(327302,50,47),(327292,50,49),(327276,50,50),(327285,50,53),(327294,50,54),(327297,50,56),(327279,50,57),(327293,50,58),(327280,50,59),(327281,50,60),(327299,50,70),(327284,50,72),(327296,50,75),(327282,50,76),(327298,50,111),(327283,50,123),(327289,50,125),(327307,51,1),(327316,51,2),(327315,51,3),(327328,51,6),(327324,51,11),(327312,51,13),(327317,51,18),(327308,51,21),(327318,51,33),(327309,51,35),(327327,51,36),(327330,51,44),(327329,51,47),(327323,51,49),(327306,51,51),(327319,51,53),(327326,51,54),(327325,51,58),(327314,51,70),(327320,51,72),(327310,51,74),(327311,51,75),(327313,51,76),(327321,51,111),(327322,51,125),(327339,52,1),(327345,52,2),(327344,52,3),(327355,52,6),(327351,52,11),(327332,52,13),(327342,52,18),(327333,52,19),(327338,52,21),(327341,52,33),(327337,52,35),(327354,52,36),(327357,52,44),(327356,52,47),(327350,52,49),(327334,52,51),(327331,52,52),(327346,52,53),(327353,52,54),(327352,52,58),(327343,52,70),(327347,52,72),(327336,52,74),(327340,52,75),(327335,52,76),(327348,52,111),(327349,52,125),(327359,53,1),(327360,53,2),(327361,53,3),(327365,53,6),(327364,53,11),(327358,53,53),(327362,53,70),(327363,53,76),(327367,54,1),(327368,54,2),(327369,54,3),(327373,54,6),(327372,54,11),(327366,54,54),(327370,54,70),(327371,54,76),(327377,55,1),(327379,55,2),(327378,55,3),(327383,55,6),(327382,55,11),(327375,55,13),(327376,55,54),(327374,55,55),(327380,55,70),(327381,55,76),(327385,56,1),(327386,56,2),(327387,56,3),(327391,56,6),(327390,56,11),(327384,56,56),(327388,56,70),(327389,56,76),(327398,57,1),(327401,57,2),(327400,57,3),(327404,57,6),(327403,57,11),(327393,57,13),(327397,57,33),(327396,57,56),(327392,57,57),(327399,57,70),(327402,57,76),(327394,57,123),(327395,57,125),(327406,58,1),(327409,58,2),(327408,58,3),(327412,58,6),(327411,58,11),(327405,58,58),(327410,58,70),(327407,58,76),(327417,59,1),(327425,59,2),(327424,59,3),(327430,59,5),(327442,59,6),(327439,59,11),(327414,59,13),(327422,59,18),(327416,59,21),(327421,59,33),(327431,59,35),(327435,59,36),(327441,59,44),(327440,59,47),(327432,59,49),(327415,59,50),(327426,59,53),(327434,59,54),(327437,59,56),(327418,59,57),(327433,59,58),(327413,59,59),(327419,59,60),(327423,59,70),(327427,59,72),(327436,59,75),(327420,59,76),(327438,59,111),(327428,59,123),(327429,59,125),(327453,60,1),(327467,60,2),(327466,60,3),(327444,60,5),(327469,60,6),(327468,60,11),(327464,60,13),(327452,60,18),(327451,60,21),(327450,60,33),(327445,60,35),(327457,60,36),(327462,60,44),(327461,60,47),(327446,60,49),(327449,60,53),(327458,60,54),(327460,60,56),(327459,60,58),(327443,60,60),(327465,60,70),(327463,60,72),(327455,60,75),(327447,60,76),(327454,60,111),(327448,60,123),(327456,60,125),(327474,61,1),(327478,61,2),(327477,61,3),(327482,61,6),(327481,61,11),(327471,61,13),(327472,61,36),(327473,61,44),(327475,61,47),(327470,61,61),(327476,61,70),(327479,61,76),(327480,61,111),(327483,62,62),(327484,64,64),(327499,65,1),(327510,65,2),(327509,65,3),(327511,65,5),(327515,65,6),(327514,65,11),(327486,65,13),(327487,65,18),(327503,65,21),(327505,65,33),(327488,65,35),(327495,65,36),(327507,65,44),(327506,65,47),(327489,65,49),(327501,65,50),(327513,65,53),(327494,65,54),(327504,65,56),(327490,65,57),(327493,65,58),(327491,65,59),(327502,65,60),(327485,65,65),(327508,65,70),(327512,65,72),(327497,65,75),(327492,65,76),(327496,65,111),(327500,65,123),(327498,65,125),(327520,66,1),(327519,66,2),(327521,66,3),(327522,66,5),(327523,66,6),(327517,66,9),(327524,66,11),(327525,66,13),(327526,66,15),(327527,66,16),(327528,66,17),(327529,66,18),(327530,66,19),(327531,66,20),(327532,66,21),(327533,66,22),(327534,66,30),(327535,66,31),(327536,66,32),(327537,66,33),(327538,66,34),(327539,66,35),(327540,66,36),(327541,66,37),(327542,66,38),(327543,66,39),(327544,66,40),(327545,66,41),(327546,66,42),(327547,66,43),(327548,66,44),(327549,66,45),(327550,66,47),(327551,66,48),(327552,66,49),(327553,66,50),(327554,66,51),(327555,66,52),(327556,66,53),(327557,66,54),(327558,66,55),(327559,66,56),(327560,66,57),(327561,66,58),(327562,66,59),(327563,66,60),(327564,66,61),(327565,66,64),(327566,66,65),(327516,66,66),(327567,66,67),(327568,66,69),(327569,66,70),(327570,66,71),(327571,66,72),(327572,66,73),(327573,66,74),(327574,66,75),(327575,66,76),(327576,66,101),(327577,66,102),(327518,66,103),(327583,66,111),(327578,66,112),(327582,66,122),(327580,66,123),(327579,66,124),(327581,66,125),(327588,67,1),(327606,67,2),(327605,67,3),(327585,67,5),(327610,67,6),(327609,67,11),(327602,67,13),(327587,67,18),(327589,67,21),(327590,67,33),(327591,67,35),(327599,67,36),(327586,67,37),(327608,67,44),(327607,67,47),(327595,67,49),(327592,67,53),(327598,67,54),(327597,67,58),(327584,67,67),(327604,67,70),(327601,67,72),(327596,67,74),(327600,67,75),(327593,67,76),(327594,67,111),(327603,67,125),(327619,69,1),(327626,69,2),(327625,69,3),(327628,69,6),(327627,69,11),(327612,69,35),(327621,69,36),(327623,69,44),(327613,69,47),(327614,69,49),(327622,69,54),(327615,69,58),(327611,69,69),(327624,69,70),(327618,69,75),(327617,69,76),(327616,69,111),(327620,69,125),(327631,70,6),(327630,70,11),(327629,70,70),(327633,71,1),(327636,71,2),(327635,71,3),(327640,71,6),(327639,71,11),(327634,71,58),(327637,71,70),(327632,71,71),(327638,71,76),(327647,72,1),(327655,72,2),(327654,72,3),(327657,72,6),(327656,72,11),(327642,72,18),(327648,72,36),(327652,72,44),(327651,72,47),(327643,72,49),(327649,72,54),(327650,72,58),(327653,72,70),(327641,72,72),(327646,72,76),(327644,72,111),(327645,72,125),(327664,73,1),(327676,73,2),(327675,73,3),(327659,73,5),(327682,73,6),(327678,73,11),(327672,73,13),(327663,73,18),(327660,73,19),(327662,73,21),(327665,73,33),(327666,73,35),(327681,73,36),(327684,73,44),(327683,73,47),(327677,73,49),(327667,73,53),(327680,73,54),(327679,73,58),(327661,73,64),(327674,73,70),(327671,73,72),(327658,73,73),(327670,73,75),(327668,73,76),(327669,73,111),(327673,73,125),(327685,74,74),(327686,75,75),(327687,76,76),(327689,100,1),(327690,100,2),(327691,100,3),(327692,100,5),(327693,100,6),(327694,100,9),(327695,100,11),(327696,100,13),(327697,100,15),(327698,100,16),(327699,100,17),(327700,100,18),(327701,100,19),(327702,100,20),(327703,100,21),(327704,100,22),(327705,100,30),(327706,100,31),(327707,100,32),(327708,100,33),(327709,100,34),(327710,100,35),(327711,100,36),(327712,100,37),(327713,100,38),(327714,100,39),(327715,100,40),(327716,100,41),(327717,100,42),(327718,100,43),(327719,100,44),(327720,100,45),(327721,100,47),(327722,100,48),(327723,100,49),(327724,100,50),(327725,100,51),(327726,100,52),(327727,100,53),(327728,100,54),(327729,100,55),(327730,100,56),(327731,100,57),(327732,100,58),(327733,100,59),(327734,100,60),(327735,100,61),(327736,100,62),(327737,100,64),(327738,100,65),(327739,100,66),(327740,100,67),(327741,100,69),(327742,100,70),(327743,100,71),(327744,100,72),(327745,100,73),(327746,100,74),(327747,100,75),(327748,100,76),(327688,100,100),(327749,100,101),(327750,100,102),(327751,100,103),(327752,100,104),(327753,100,105),(327754,100,106),(327755,100,107),(327756,100,108),(327757,100,109),(327758,100,110),(327759,100,111),(327760,100,112),(327761,100,114),(327762,100,115),(327763,100,119),(327770,100,120),(327764,100,121),(327765,100,122),(327768,100,123),(327766,100,124),(327769,100,125),(327767,100,126),(327777,101,1),(327782,101,2),(327781,101,3),(327784,101,6),(327783,101,11),(327772,101,13),(327773,101,18),(327774,101,35),(327780,101,70),(327778,101,75),(327776,101,76),(327771,101,101),(327779,101,111),(327775,101,125),(327786,102,1),(327793,102,2),(327792,102,3),(327803,102,6),(327802,102,11),(327787,102,13),(327788,102,35),(327797,102,36),(327801,102,44),(327800,102,47),(327789,102,49),(327798,102,54),(327799,102,58),(327791,102,70),(327794,102,75),(327790,102,76),(327785,102,102),(327795,102,111),(327796,102,125),(327805,103,1),(327806,103,2),(327807,103,3),(327808,103,5),(327809,103,6),(327867,103,9),(327810,103,11),(327811,103,13),(327812,103,15),(327813,103,16),(327814,103,17),(327815,103,18),(327816,103,19),(327817,103,20),(327818,103,21),(327819,103,22),(327820,103,30),(327821,103,31),(327822,103,32),(327823,103,33),(327824,103,34),(327825,103,35),(327826,103,36),(327827,103,37),(327828,103,38),(327829,103,39),(327830,103,40),(327831,103,41),(327832,103,42),(327833,103,43),(327834,103,44),(327835,103,45),(327836,103,47),(327837,103,48),(327838,103,49),(327839,103,50),(327840,103,51),(327841,103,52),(327842,103,53),(327843,103,54),(327844,103,55),(327845,103,56),(327846,103,57),(327847,103,58),(327848,103,59),(327849,103,60),(327850,103,61),(327851,103,64),(327852,103,65),(327853,103,67),(327854,103,69),(327855,103,70),(327856,103,71),(327857,103,72),(327858,103,73),(327859,103,74),(327860,103,75),(327861,103,76),(327862,103,101),(327863,103,102),(327804,103,103),(327870,103,111),(327864,103,112),(327869,103,122),(327866,103,123),(327865,103,124),(327868,103,125),(327878,104,1),(327877,104,2),(327880,104,3),(327881,104,5),(327882,104,6),(327879,104,9),(327883,104,11),(327884,104,13),(327885,104,15),(327886,104,16),(327887,104,17),(327888,104,18),(327889,104,19),(327890,104,20),(327891,104,21),(327892,104,22),(327893,104,30),(327894,104,31),(327895,104,32),(327896,104,33),(327897,104,34),(327898,104,35),(327899,104,36),(327900,104,37),(327901,104,38),(327902,104,39),(327903,104,40),(327904,104,41),(327905,104,42),(327906,104,43),(327907,104,44),(327908,104,45),(327909,104,47),(327910,104,48),(327911,104,49),(327912,104,50),(327913,104,51),(327914,104,52),(327915,104,53),(327916,104,54),(327917,104,55),(327918,104,56),(327919,104,57),(327920,104,58),(327921,104,59),(327922,104,60),(327923,104,61),(327948,104,62),(327924,104,64),(327925,104,65),(327875,104,66),(327926,104,67),(327927,104,69),(327928,104,70),(327929,104,71),(327930,104,72),(327931,104,73),(327932,104,74),(327933,104,75),(327934,104,76),(327872,104,100),(327935,104,101),(327936,104,102),(327874,104,103),(327871,104,104),(327945,104,105),(327944,104,106),(327951,104,107),(327953,104,108),(327952,104,109),(327949,104,110),(327942,104,111),(327937,104,112),(327947,104,114),(327873,104,115),(327950,104,119),(327876,104,120),(327943,104,121),(327941,104,122),(327939,104,123),(327938,104,124),(327940,104,125),(327946,104,126),(327954,105,105),(327957,106,6),(327956,106,11),(327955,106,106),(327969,107,1),(327983,107,2),(327982,107,3),(327960,107,5),(327985,107,6),(327984,107,11),(327980,107,13),(327968,107,18),(327967,107,21),(327966,107,33),(327961,107,35),(327973,107,36),(327978,107,44),(327977,107,47),(327962,107,49),(327965,107,53),(327974,107,54),(327976,107,56),(327975,107,58),(327959,107,60),(327981,107,70),(327979,107,72),(327971,107,75),(327963,107,76),(327958,107,107),(327970,107,111),(327964,107,123),(327972,107,125),(327987,108,1),(327988,108,2),(327989,108,3),(327993,108,6),(327992,108,11),(327990,108,70),(327991,108,76),(327986,108,108),(327998,109,1),(328002,109,2),(328001,109,3),(328004,109,6),(328003,109,11),(327995,109,13),(327996,109,18),(328000,109,70),(327997,109,76),(327994,109,109),(327999,109,125),(328006,110,1),(328009,110,2),(328008,110,3),(328012,110,6),(328011,110,11),(328010,110,70),(328007,110,76),(328005,110,110),(328013,111,111),(328015,112,1),(328018,112,2),(328017,112,3),(328028,112,6),(328026,112,11),(328021,112,36),(328025,112,44),(328024,112,47),(328016,112,49),(328022,112,54),(328023,112,58),(328019,112,70),(328020,112,76),(328027,112,111),(328014,112,112),(328033,114,1),(328035,114,2),(328034,114,3),(328045,114,6),(328043,114,11),(328030,114,13),(328038,114,36),(328042,114,44),(328041,114,47),(328032,114,49),(328039,114,54),(328040,114,58),(328036,114,70),(328037,114,76),(328044,114,111),(328031,114,112),(328029,114,114),(328051,115,1),(328050,115,2),(328053,115,3),(328054,115,5),(328055,115,6),(328052,115,9),(328056,115,11),(328057,115,13),(328058,115,15),(328059,115,16),(328060,115,17),(328061,115,18),(328062,115,19),(328063,115,20),(328064,115,21),(328065,115,22),(328066,115,30),(328067,115,31),(328068,115,32),(328069,115,33),(328070,115,34),(328071,115,35),(328072,115,36),(328073,115,37),(328074,115,38),(328075,115,39),(328076,115,40),(328077,115,41),(328078,115,42),(328079,115,43),(328080,115,44),(328081,115,45),(328082,115,47),(328083,115,48),(328084,115,49),(328085,115,50),(328086,115,51),(328087,115,52),(328088,115,53),(328089,115,54),(328090,115,55),(328091,115,56),(328092,115,57),(328093,115,58),(328094,115,59),(328095,115,60),(328096,115,61),(328097,115,64),(328098,115,65),(328047,115,66),(328099,115,67),(328100,115,69),(328101,115,70),(328102,115,71),(328103,115,72),(328104,115,73),(328105,115,74),(328106,115,75),(328107,115,76),(328108,115,101),(328109,115,102),(328048,115,103),(328115,115,111),(328110,115,112),(328046,115,115),(328049,115,120),(328114,115,122),(328112,115,123),(328111,115,124),(328113,115,125),(328118,119,1),(328121,119,2),(328120,119,3),(328124,119,6),(328123,119,11),(328122,119,70),(328119,119,76),(328117,119,110),(328116,119,119),(328225,120,1),(328229,120,2),(328228,120,3),(328227,120,5),(328230,120,6),(328222,120,9),(328231,120,11),(328223,120,13),(328232,120,15),(328233,120,16),(328234,120,17),(328235,120,18),(328236,120,19),(328237,120,20),(328238,120,21),(328239,120,22),(328240,120,30),(328241,120,31),(328242,120,32),(328243,120,33),(328244,120,34),(328245,120,35),(328246,120,36),(328247,120,37),(328248,120,38),(328249,120,39),(328250,120,40),(328251,120,41),(328252,120,42),(328253,120,43),(328254,120,44),(328255,120,45),(328256,120,47),(328257,120,48),(328258,120,49),(328259,120,50),(328260,120,51),(328261,120,52),(328262,120,53),(328263,120,54),(328264,120,55),(328265,120,56),(328266,120,57),(328267,120,58),(328268,120,59),(328269,120,60),(328270,120,61),(328271,120,64),(328272,120,65),(328224,120,66),(328273,120,67),(328274,120,69),(328275,120,70),(328276,120,71),(328277,120,72),(328278,120,73),(328279,120,74),(328280,120,75),(328281,120,76),(328282,120,101),(328283,120,102),(328226,120,103),(328289,120,111),(328284,120,112),(328221,120,120),(328288,120,122),(328286,120,123),(328285,120,124),(328287,120,125),(328134,121,1),(328140,121,2),(328139,121,3),(328146,121,6),(328142,121,11),(328129,121,13),(328128,121,18),(328126,121,21),(328130,121,33),(328127,121,35),(328145,121,36),(328148,121,44),(328147,121,47),(328141,121,49),(328131,121,53),(328144,121,54),(328143,121,58),(328138,121,70),(328132,121,72),(328135,121,75),(328133,121,76),(328136,121,111),(328125,121,121),(328137,121,125),(328156,122,1),(328166,122,2),(328165,122,3),(328168,122,6),(328167,122,11),(328150,122,15),(328151,122,35),(328159,122,36),(328163,122,44),(328162,122,47),(328152,122,49),(328160,122,54),(328153,122,56),(328161,122,58),(328164,122,70),(328155,122,75),(328154,122,76),(328157,122,111),(328149,122,122),(328158,122,125),(328213,123,1),(328215,123,2),(328214,123,3),(328219,123,6),(328218,123,11),(328211,123,33),(328212,123,56),(328216,123,70),(328217,123,76),(328210,123,123),(328173,124,1),(328185,124,2),(328184,124,3),(328189,124,6),(328188,124,11),(328177,124,18),(328170,124,35),(328182,124,36),(328171,124,37),(328187,124,44),(328186,124,47),(328178,124,49),(328181,124,54),(328180,124,58),(328183,124,70),(328179,124,74),(328172,124,75),(328174,124,76),(328175,124,111),(328169,124,124),(328176,124,125),(328220,125,125),(328197,126,1),(328207,126,2),(328206,126,3),(328209,126,6),(328208,126,11),(328191,126,15),(328192,126,35),(328200,126,36),(328204,126,44),(328203,126,47),(328193,126,49),(328201,126,54),(328194,126,56),(328202,126,58),(328205,126,70),(328196,126,75),(328195,126,76),(328198,126,111),(328199,126,125),(328190,126,126); /*!40000 ALTER TABLE `roleRole` ENABLE KEYS */; UNLOCK TABLES; @@ -140,7 +140,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2023-08-30 15:53:15 +-- Dump completed on 2023-11-20 12:26:42 USE `salix`; -- MariaDB dump 10.19 Distrib 10.5.19-MariaDB, for debian-linux-gnu (x86_64) -- @@ -164,7 +164,7 @@ USE `salix`; LOCK TABLES `ACL` WRITE; /*!40000 ALTER TABLE `ACL` DISABLE KEYS */; -INSERT INTO `ACL` VALUES (3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','trainee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','trainee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','trainee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','trainee'),(30,'GreugeType','*','READ','ALLOW','ROLE','trainee'),(31,'Mandate','*','READ','ALLOW','ROLE','trainee'),(32,'MandateType','*','READ','ALLOW','ROLE','trainee'),(33,'Company','*','READ','ALLOW','ROLE','trainee'),(34,'Greuge','*','READ','ALLOW','ROLE','trainee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer'),(55,'Recovery','*','READ','ALLOW','ROLE','trainee'),(56,'Recovery','*','WRITE','ALLOW','ROLE','administrative'),(58,'CreditClassification','*','*','ALLOW','ROLE','insurance'),(60,'CreditInsurance','*','*','ALLOW','ROLE','insurance'),(61,'InvoiceOut','*','READ','ALLOW','ROLE','employee'),(63,'TicketObservation','*','*','ALLOW','ROLE','employee'),(64,'Route','*','READ','ALLOW','ROLE','employee'),(65,'Sale','*','READ','ALLOW','ROLE','employee'),(66,'TicketTracking','*','READ','ALLOW','ROLE','employee'),(68,'TicketPackaging','*','*','ALLOW','ROLE','employee'),(69,'Packaging','*','READ','ALLOW','ROLE','employee'),(70,'Packaging','*','WRITE','ALLOW','ROLE','logistic'),(72,'SaleComponent','*','READ','ALLOW','ROLE','employee'),(73,'Expedition','*','READ','ALLOW','ROLE','employee'),(74,'Expedition','*','WRITE','ALLOW','ROLE','deliveryBoss'),(75,'Expedition','*','WRITE','ALLOW','ROLE','production'),(76,'AnnualAverageInvoiced','*','READ','ALLOW','ROLE','employee'),(77,'WorkerMana','*','READ','ALLOW','ROLE','employee'),(78,'TicketTracking','*','WRITE','ALLOW','ROLE','production'),(79,'TicketTracking','changeState','*','ALLOW','ROLE','employee'),(80,'Sale','deleteSales','*','ALLOW','ROLE','employee'),(81,'Sale','moveToTicket','*','ALLOW','ROLE','employee'),(82,'Sale','updateQuantity','*','ALLOW','ROLE','employee'),(83,'Sale','updatePrice','*','ALLOW','ROLE','employee'),(84,'Sale','updateDiscount','*','ALLOW','ROLE','employee'),(85,'SaleTracking','*','READ','ALLOW','ROLE','employee'),(86,'Order','*','*','ALLOW','ROLE','employee'),(87,'OrderRow','*','*','ALLOW','ROLE','employee'),(88,'ClientContact','*','*','ALLOW','ROLE','employee'),(89,'Sale','moveToNewTicket','*','ALLOW','ROLE','employee'),(90,'Sale','reserve','*','ALLOW','ROLE','employee'),(91,'TicketWeekly','*','READ','ALLOW','ROLE','employee'),(94,'Agency','landsThatDay','*','ALLOW','ROLE','employee'),(96,'ClaimEnd','*','READ','ALLOW','ROLE','employee'),(97,'ClaimEnd','*','WRITE','ALLOW','ROLE','claimManager'),(98,'ClaimBeginning','*','*','ALLOW','ROLE','employee'),(99,'ClaimDevelopment','*','READ','ALLOW','ROLE','employee'),(100,'ClaimDevelopment','*','WRITE','ALLOW','ROLE','claimManager'),(102,'Claim','createFromSales','*','ALLOW','ROLE','employee'),(104,'Item','*','WRITE','ALLOW','ROLE','marketingBoss'),(105,'ItemBarcode','*','WRITE','ALLOW','ROLE','marketingBoss'),(106,'ItemBotanical','*','WRITE','ALLOW','ROLE','marketingBoss'),(108,'ItemPlacement','*','WRITE','ALLOW','ROLE','marketingBoss'),(109,'UserConfig','*','*','ALLOW','ROLE','employee'),(110,'Bank','*','READ','ALLOW','ROLE','trainee'),(111,'ClientLog','*','READ','ALLOW','ROLE','trainee'),(112,'Defaulter','*','READ','ALLOW','ROLE','employee'),(113,'ClientRisk','*','READ','ALLOW','ROLE','trainee'),(114,'Receipt','*','READ','ALLOW','ROLE','trainee'),(115,'Receipt','*','WRITE','ALLOW','ROLE','administrative'),(116,'BankEntity','*','*','ALLOW','ROLE','employee'),(117,'ClientSample','*','*','ALLOW','ROLE','employee'),(118,'WorkerTeam','*','*','ALLOW','ROLE','salesPerson'),(119,'Travel','*','READ','ALLOW','ROLE','employee'),(120,'Travel','*','WRITE','ALLOW','ROLE','buyer'),(121,'Item','regularize','*','ALLOW','ROLE','employee'),(122,'TicketRequest','*','*','ALLOW','ROLE','employee'),(124,'Client','confirmTransaction','WRITE','ALLOW','ROLE','administrative'),(125,'Agency','getAgenciesWithWarehouse','*','ALLOW','ROLE','employee'),(126,'Client','activeWorkersWithRole','*','ALLOW','ROLE','employee'),(127,'TicketLog','*','READ','ALLOW','ROLE','employee'),(129,'TicketService','*','*','ALLOW','ROLE','employee'),(130,'Expedition','*','WRITE','ALLOW','ROLE','packager'),(131,'CreditInsurance','*','READ','ALLOW','ROLE','trainee'),(132,'CreditClassification','*','READ','ALLOW','ROLE','trainee'),(133,'ItemTag','*','WRITE','ALLOW','ROLE','marketingBoss'),(135,'ZoneGeo','*','READ','ALLOW','ROLE','employee'),(136,'ZoneCalendar','*','READ','ALLOW','ROLE','employee'),(137,'ZoneIncluded','*','READ','ALLOW','ROLE','employee'),(138,'LabourHoliday','*','READ','ALLOW','ROLE','employee'),(139,'LabourHolidayLegend','*','READ','ALLOW','ROLE','employee'),(140,'LabourHolidayType','*','READ','ALLOW','ROLE','employee'),(141,'Zone','*','*','ALLOW','ROLE','logisticBoss'),(142,'ZoneCalendar','*','WRITE','ALLOW','ROLE','deliveryBoss'),(143,'ZoneIncluded','*','*','ALLOW','ROLE','deliveryBoss'),(144,'Stowaway','*','*','ALLOW','ROLE','employee'),(145,'Ticket','getPossibleStowaways','READ','ALLOW','ROLE','employee'),(147,'UserConfigView','*','*','ALLOW','ROLE','employee'),(148,'UserConfigView','*','*','ALLOW','ROLE','employee'),(149,'Sip','*','READ','ALLOW','ROLE','employee'),(150,'Sip','*','WRITE','ALLOW','ROLE','hr'),(151,'Department','*','READ','ALLOW','ROLE','employee'),(152,'Department','*','WRITE','ALLOW','ROLE','hr'),(153,'Route','*','READ','ALLOW','ROLE','employee'),(154,'Route','*','WRITE','ALLOW','ROLE','delivery'),(155,'Calendar','*','READ','ALLOW','ROLE','hr'),(156,'WorkerLabour','*','READ','ALLOW','ROLE','hr'),(157,'Calendar','absences','READ','ALLOW','ROLE','employee'),(158,'ItemTag','*','WRITE','ALLOW','ROLE','accessory'),(160,'TicketServiceType','*','READ','ALLOW','ROLE','employee'),(161,'TicketConfig','*','READ','ALLOW','ROLE','employee'),(162,'InvoiceOut','delete','WRITE','ALLOW','ROLE','invoicing'),(163,'InvoiceOut','book','WRITE','ALLOW','ROLE','invoicing'),(165,'TicketDms','*','*','ALLOW','ROLE','employee'),(167,'Worker','isSubordinate','READ','ALLOW','ROLE','employee'),(168,'Worker','mySubordinates','READ','ALLOW','ROLE','employee'),(169,'WorkerTimeControl','filter','READ','ALLOW','ROLE','employee'),(170,'WorkerTimeControl','addTime','WRITE','ALLOW','ROLE','employee'),(171,'TicketServiceType','*','WRITE','ALLOW','ROLE','administrative'),(172,'Sms','*','READ','ALLOW','ROLE','employee'),(173,'Sms','send','WRITE','ALLOW','ROLE','employee'),(176,'Device','*','*','ALLOW','ROLE','employee'),(177,'Device','*','*','ALLOW','ROLE','employee'),(178,'WorkerTimeControl','*','*','ALLOW','ROLE','employee'),(179,'ItemLog','*','READ','ALLOW','ROLE','employee'),(180,'RouteLog','*','READ','ALLOW','ROLE','employee'),(181,'Dms','removeFile','WRITE','ALLOW','ROLE','employee'),(182,'Dms','uploadFile','WRITE','ALLOW','ROLE','employee'),(183,'Dms','downloadFile','READ','ALLOW','ROLE','employee'),(184,'Client','uploadFile','WRITE','ALLOW','ROLE','employee'),(185,'ClientDms','removeFile','WRITE','ALLOW','ROLE','employee'),(186,'ClientDms','*','READ','ALLOW','ROLE','trainee'),(187,'Ticket','uploadFile','WRITE','ALLOW','ROLE','employee'),(190,'Route','updateVolume','WRITE','ALLOW','ROLE','deliveryBoss'),(191,'Agency','getLanded','READ','ALLOW','ROLE','employee'),(192,'Agency','getShipped','READ','ALLOW','ROLE','employee'),(194,'Postcode','*','WRITE','ALLOW','ROLE','deliveryBoss'),(195,'Ticket','addSale','WRITE','ALLOW','ROLE','employee'),(196,'Dms','updateFile','WRITE','ALLOW','ROLE','employee'),(197,'Dms','*','READ','ALLOW','ROLE','trainee'),(198,'ClaimDms','removeFile','WRITE','ALLOW','ROLE','employee'),(199,'ClaimDms','*','READ','ALLOW','ROLE','employee'),(200,'Claim','uploadFile','WRITE','ALLOW','ROLE','employee'),(201,'Sale','updateConcept','WRITE','ALLOW','ROLE','employee'),(202,'Claim','updateClaimAction','WRITE','ALLOW','ROLE','claimManager'),(203,'UserPhone','*','*','ALLOW','ROLE','employee'),(204,'WorkerDms','removeFile','WRITE','ALLOW','ROLE','hr'),(205,'WorkerDms','*','READ','ALLOW','ROLE','hr'),(206,'Chat','*','*','ALLOW','ROLE','employee'),(207,'Chat','sendMessage','*','ALLOW','ROLE','employee'),(208,'Sale','recalculatePrice','WRITE','ALLOW','ROLE','employee'),(209,'Ticket','recalculateComponents','WRITE','ALLOW','ROLE','employee'),(211,'TravelLog','*','READ','ALLOW','ROLE','buyer'),(212,'Thermograph','*','*','ALLOW','ROLE','buyer'),(213,'TravelThermograph','*','WRITE','ALLOW','ROLE','buyer'),(214,'Entry','*','*','ALLOW','ROLE','buyer'),(215,'TicketWeekly','*','WRITE','ALLOW','ROLE','buyer'),(216,'TravelThermograph','*','READ','ALLOW','ROLE','employee'),(218,'Intrastat','*','*','ALLOW','ROLE','buyer'),(221,'UserConfig','getUserConfig','READ','ALLOW','ROLE','account'),(222,'Client','*','READ','ALLOW','ROLE','trainee'),(226,'ClientObservation','*','READ','ALLOW','ROLE','trainee'),(227,'Address','*','READ','ALLOW','ROLE','trainee'),(228,'AddressObservation','*','READ','ALLOW','ROLE','trainee'),(230,'ClientCredit','*','READ','ALLOW','ROLE','trainee'),(231,'ClientContact','*','READ','ALLOW','ROLE','trainee'),(232,'ClientSample','*','READ','ALLOW','ROLE','trainee'),(233,'EntryLog','*','READ','ALLOW','ROLE','buyer'),(234,'WorkerLog','find','READ','ALLOW','ROLE','hr'),(235,'CustomsAgent','*','*','ALLOW','ROLE','employee'),(236,'Buy','*','*','ALLOW','ROLE','buyer'),(237,'WorkerDms','filter','*','ALLOW','ROLE','employee'),(238,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(239,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(240,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(241,'SupplierContact','*','WRITE','ALLOW','ROLE','administrative'),(242,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(244,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(248,'RoleMapping','*','READ','ALLOW','ROLE','account'),(249,'UserPassword','*','READ','ALLOW','ROLE','account'),(250,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(251,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(252,'Supplier','*','READ','ALLOW','ROLE','employee'),(253,'Supplier','*','WRITE','ALLOW','ROLE','administrative'),(254,'SupplierLog','*','READ','ALLOW','ROLE','employee'),(256,'Image','*','WRITE','ALLOW','ROLE','employee'),(257,'FixedPrice','*','*','ALLOW','ROLE','buyer'),(258,'PayDem','*','READ','ALLOW','ROLE','employee'),(259,'Client','createReceipt','*','ALLOW','ROLE','salesAssistant'),(260,'PrintServerQueue','*','WRITE','ALLOW','ROLE','employee'),(261,'SupplierAccount','*','*','ALLOW','ROLE','administrative'),(262,'Entry','*','*','ALLOW','ROLE','administrative'),(263,'InvoiceIn','*','*','ALLOW','ROLE','administrative'),(264,'StarredModule','*','*','ALLOW','ROLE','employee'),(265,'ItemBotanical','*','WRITE','ALLOW','ROLE','logisticBoss'),(266,'ZoneLog','*','READ','ALLOW','ROLE','employee'),(267,'Genus','*','WRITE','ALLOW','ROLE','logisticBoss'),(268,'Specie','*','WRITE','ALLOW','ROLE','logisticBoss'),(269,'InvoiceOut','createPdf','WRITE','ALLOW','ROLE','employee'),(270,'SupplierAddress','*','*','ALLOW','ROLE','employee'),(271,'SalesMonitor','*','*','ALLOW','ROLE','employee'),(272,'InvoiceInLog','*','READ','ALLOW','ROLE','employee'),(273,'InvoiceInTax','*','*','ALLOW','ROLE','administrative'),(274,'InvoiceInLog','*','READ','ALLOW','ROLE','administrative'),(275,'InvoiceOut','createManualInvoice','WRITE','ALLOW','ROLE','invoicing'),(276,'InvoiceOut','globalInvoicing','WRITE','ALLOW','ROLE','invoicing'),(278,'RoleInherit','*','WRITE','ALLOW','ROLE','grant'),(279,'MailAlias','*','*','ALLOW','ROLE','marketing'),(283,'EntryObservation','*','*','ALLOW','ROLE','buyer'),(284,'LdapConfig','*','*','ALLOW','ROLE','sysadmin'),(285,'SambaConfig','*','*','ALLOW','ROLE','sysadmin'),(286,'ACL','*','*','ALLOW','ROLE','developer'),(287,'AccessToken','*','*','ALLOW','ROLE','developer'),(293,'RoleInherit','*','*','ALLOW','ROLE','it'),(294,'RoleRole','*','*','ALLOW','ROLE','it'),(295,'AccountConfig','*','*','ALLOW','ROLE','sysadmin'),(296,'Collection','*','READ','ALLOW','ROLE','employee'),(297,'Sale','refund','WRITE','ALLOW','ROLE','invoicing'),(298,'InvoiceInDueDay','*','*','ALLOW','ROLE','administrative'),(299,'Collection','setSaleQuantity','*','ALLOW','ROLE','employee'),(302,'AgencyTerm','*','*','ALLOW','ROLE','administrative'),(303,'ClaimLog','*','READ','ALLOW','ROLE','claimManager'),(304,'Edi','updateData','WRITE','ALLOW','ROLE','employee'),(305,'EducationLevel','*','*','ALLOW','ROLE','employee'),(306,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(307,'SupplierAgencyTerm','*','*','ALLOW','ROLE','administrative'),(308,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(309,'Zone','getZoneClosing','*','ALLOW','ROLE','employee'),(310,'ExpeditionState','*','READ','ALLOW','ROLE','employee'),(311,'Expense','*','READ','ALLOW','ROLE','employee'),(312,'Expense','*','WRITE','ALLOW','ROLE','administrative'),(314,'SupplierActivity','*','READ','ALLOW','ROLE','employee'),(315,'SupplierActivity','*','WRITE','ALLOW','ROLE','administrative'),(316,'Dms','deleteTrashFiles','WRITE','ALLOW','ROLE','employee'),(317,'ClientUnpaid','*','*','ALLOW','ROLE','administrative'),(318,'MdbVersion','*','*','ALLOW','ROLE','developer'),(319,'ItemType','*','READ','ALLOW','ROLE','employee'),(320,'ItemType','*','WRITE','ALLOW','ROLE','buyer'),(321,'InvoiceOut','refund','WRITE','ALLOW','ROLE','invoicing'),(322,'InvoiceOut','refund','WRITE','ALLOW','ROLE','salesAssistant'),(323,'InvoiceOut','refund','WRITE','ALLOW','ROLE','claimManager'),(324,'Ticket','refund','WRITE','ALLOW','ROLE','invoicing'),(325,'Ticket','refund','WRITE','ALLOW','ROLE','salesAssistant'),(326,'Ticket','refund','WRITE','ALLOW','ROLE','claimManager'),(327,'Sale','refund','WRITE','ALLOW','ROLE','salesAssistant'),(328,'Sale','refund','WRITE','ALLOW','ROLE','claimManager'),(329,'TicketRefund','*','WRITE','ALLOW','ROLE','invoicing'),(330,'ClaimObservation','*','WRITE','ALLOW','ROLE','salesPerson'),(331,'ClaimObservation','*','READ','ALLOW','ROLE','salesPerson'),(332,'Client','setPassword','WRITE','ALLOW','ROLE','salesPerson'),(333,'Client','updateUser','WRITE','ALLOW','ROLE','salesPerson'),(334,'ShelvingLog','*','READ','ALLOW','ROLE','employee'),(335,'ZoneExclusionGeo','*','READ','ALLOW','ROLE','employee'),(336,'ZoneExclusionGeo','*','WRITE','ALLOW','ROLE','deliveryBoss'),(337,'Parking','*','*','ALLOW','ROLE','employee'),(338,'Shelving','*','*','ALLOW','ROLE','employee'),(339,'OsTicket','*','*','ALLOW','ROLE','employee'),(340,'OsTicketConfig','*','*','ALLOW','ROLE','it'),(341,'ClientConsumptionQueue','*','WRITE','ALLOW','ROLE','employee'),(342,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','employee'),(343,'Ticket','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(344,'Ticket','deliveryNoteCsvPdf','READ','ALLOW','ROLE','employee'),(345,'Ticket','deliveryNoteCsvEmail','READ','ALLOW','ROLE','employee'),(346,'Client','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(347,'Client','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(348,'Client','clientWelcomeHtml','READ','ALLOW','ROLE','employee'),(349,'Client','clientWelcomeEmail','WRITE','ALLOW','ROLE','employee'),(350,'Client','creditRequestPdf','READ','ALLOW','ROLE','employee'),(351,'Client','creditRequestHtml','READ','ALLOW','ROLE','employee'),(352,'Client','creditRequestEmail','WRITE','ALLOW','ROLE','employee'),(353,'Client','printerSetupHtml','READ','ALLOW','ROLE','employee'),(354,'Client','printerSetupEmail','WRITE','ALLOW','ROLE','employee'),(355,'Client','sepaCoreEmail','WRITE','ALLOW','ROLE','employee'),(356,'Client','letterDebtorPdf','READ','ALLOW','ROLE','employee'),(357,'Client','letterDebtorStHtml','READ','ALLOW','ROLE','employee'),(358,'Client','letterDebtorStEmail','WRITE','ALLOW','ROLE','employee'),(359,'Client','letterDebtorNdHtml','READ','ALLOW','ROLE','employee'),(360,'Client','letterDebtorNdEmail','WRITE','ALLOW','ROLE','employee'),(361,'Client','clientDebtStatementPdf','READ','ALLOW','ROLE','employee'),(362,'Client','clientDebtStatementHtml','READ','ALLOW','ROLE','employee'),(363,'Client','clientDebtStatementEmail','WRITE','ALLOW','ROLE','employee'),(364,'Client','incotermsAuthorizationPdf','READ','ALLOW','ROLE','employee'),(365,'Client','incotermsAuthorizationHtml','READ','ALLOW','ROLE','employee'),(366,'Client','incotermsAuthorizationEmail','WRITE','ALLOW','ROLE','employee'),(367,'Client','consumptionSendQueued','WRITE','ALLOW','ROLE','system'),(368,'InvoiceOut','invoiceEmail','WRITE','ALLOW','ROLE','employee'),(369,'InvoiceOut','exportationPdf','READ','ALLOW','ROLE','employee'),(370,'InvoiceOut','sendQueued','WRITE','ALLOW','ROLE','system'),(371,'Ticket','invoiceCsvPdf','READ','ALLOW','ROLE','employee'),(372,'Ticket','invoiceCsvEmail','WRITE','ALLOW','ROLE','employee'),(373,'Supplier','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(374,'Supplier','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(375,'Travel','extraCommunityPdf','READ','ALLOW','ROLE','employee'),(376,'Travel','extraCommunityEmail','WRITE','ALLOW','ROLE','employee'),(377,'Entry','entryOrderPdf','READ','ALLOW','ROLE','employee'),(378,'OsTicket','osTicketReportEmail','WRITE','ALLOW','ROLE','system'),(379,'Item','buyerWasteEmail','WRITE','ALLOW','ROLE','system'),(380,'Claim','claimPickupPdf','READ','ALLOW','ROLE','employee'),(381,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','claimManager'),(382,'Item','labelPdf','READ','ALLOW','ROLE','employee'),(383,'Sector','*','READ','ALLOW','ROLE','employee'),(384,'Sector','*','WRITE','ALLOW','ROLE','employee'),(385,'Route','driverRoutePdf','READ','ALLOW','ROLE','employee'),(386,'Route','driverRouteEmail','WRITE','ALLOW','ROLE','employee'),(387,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','customer'),(388,'Supplier','newSupplier','WRITE','ALLOW','ROLE','administrative'),(389,'ClaimRma','*','READ','ALLOW','ROLE','claimManager'),(390,'ClaimRma','*','WRITE','ALLOW','ROLE','claimManager'),(391,'Notification','*','WRITE','ALLOW','ROLE','system'),(392,'Boxing','*','*','ALLOW','ROLE','employee'),(393,'Url','*','READ','ALLOW','ROLE','employee'),(394,'Url','*','WRITE','ALLOW','ROLE','it'),(395,'ItemShelving','*','READ','ALLOW','ROLE','employee'),(396,'ItemShelving','*','WRITE','ALLOW','ROLE','production'),(397,'ItemShelvingPlacementSupplyStock','*','READ','ALLOW','ROLE','employee'),(398,'NotificationQueue','*','*','ALLOW','ROLE','employee'),(399,'InvoiceOut','clientsToInvoice','WRITE','ALLOW','ROLE','invoicing'),(400,'InvoiceOut','invoiceClient','WRITE','ALLOW','ROLE','invoicing'),(401,'Sale','editTracked','WRITE','ALLOW','ROLE','production'),(402,'Sale','editFloramondo','WRITE','ALLOW','ROLE','salesAssistant'),(403,'Receipt','balanceCompensationEmail','WRITE','ALLOW','ROLE','employee'),(404,'Receipt','balanceCompensationPdf','READ','ALLOW','ROLE','employee'),(405,'Ticket','getTicketsFuture','READ','ALLOW','ROLE','employee'),(406,'Ticket','merge','WRITE','ALLOW','ROLE','employee'),(407,'Sale','editFloramondo','WRITE','ALLOW','ROLE','logistic'),(408,'ZipConfig','*','*','ALLOW','ROLE','employee'),(409,'Item','*','WRITE','ALLOW','ROLE','administrative'),(410,'Sale','editCloned','WRITE','ALLOW','ROLE','buyer'),(411,'Sale','editCloned','WRITE','ALLOW','ROLE','salesAssistant'),(414,'MdbVersion','*','READ','ALLOW','ROLE','$everyone'),(416,'TicketLog','getChanges','READ','ALLOW','ROLE','employee'),(417,'Ticket','getTicketsAdvance','READ','ALLOW','ROLE','employee'),(418,'EntryLog','*','READ','ALLOW','ROLE','administrative'),(419,'Sale','editTracked','WRITE','ALLOW','ROLE','buyer'),(420,'MdbBranch','*','READ','ALLOW','ROLE','$everyone'),(421,'ItemShelvingSale','*','*','ALLOW','ROLE','employee'),(422,'Docuware','checkFile','READ','ALLOW','ROLE','employee'),(423,'Docuware','download','READ','ALLOW','ROLE','salesPerson'),(424,'Docuware','upload','WRITE','ALLOW','ROLE','productionAssi'),(425,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','salesPerson'),(426,'TpvTransaction','confirm','WRITE','ALLOW','ROLE','$everyone'),(427,'TpvTransaction','start','WRITE','ALLOW','ROLE','$authenticated'),(428,'TpvTransaction','end','WRITE','ALLOW','ROLE','$authenticated'),(429,'ItemConfig','*','READ','ALLOW','ROLE','employee'),(431,'Tag','onSubmit','WRITE','ALLOW','ROLE','employee'),(432,'Worker','updateAttributes','WRITE','ALLOW','ROLE','hr'),(433,'Worker','createAbsence','*','ALLOW','ROLE','employee'),(434,'Worker','updateAbsence','WRITE','ALLOW','ROLE','employee'),(435,'Worker','deleteAbsence','*','ALLOW','ROLE','employee'),(436,'Worker','new','WRITE','ALLOW','ROLE','hr'),(438,'Client','getClientOrSupplierReference','READ','ALLOW','ROLE','employee'),(439,'NotificationSubscription','*','*','ALLOW','ROLE','employee'),(440,'NotificationAcl','*','READ','ALLOW','ROLE','employee'),(441,'MdbApp','*','READ','ALLOW','ROLE','$everyone'),(442,'MdbApp','*','*','ALLOW','ROLE','developer'),(443,'ItemConfig','*','*','ALLOW','ROLE','employee'),(444,'DeviceProduction','*','*','ALLOW','ROLE','hr'),(445,'DeviceProductionModels','*','*','ALLOW','ROLE','hr'),(446,'DeviceProductionState','*','*','ALLOW','ROLE','hr'),(447,'DeviceProductionUser','*','*','ALLOW','ROLE','hr'),(448,'DeviceProduction','*','*','ALLOW','ROLE','productionAssi'),(449,'DeviceProductionModels','*','*','ALLOW','ROLE','productionAssi'),(450,'DeviceProductionState','*','*','ALLOW','ROLE','productionAssi'),(451,'DeviceProductionUser','*','*','ALLOW','ROLE','productionAssi'),(452,'Worker','deallocatePDA','*','ALLOW','ROLE','hr'),(453,'Worker','allocatePDA','*','ALLOW','ROLE','hr'),(454,'Worker','deallocatePDA','*','ALLOW','ROLE','productionAssi'),(455,'Worker','allocatePDA','*','ALLOW','ROLE','productionAssi'),(456,'Zone','*','*','ALLOW','ROLE','deliveryBoss'),(457,'Account','setPassword','WRITE','ALLOW','ROLE','itManagement'),(458,'Operator','*','READ','ALLOW','ROLE','employee'),(459,'Operator','*','WRITE','ALLOW','ROLE','employee'),(460,'InvoiceIn','getSerial','READ','ALLOW','ROLE','administrative'),(461,'Ticket','saveSign','WRITE','ALLOW','ROLE','employee'),(462,'InvoiceOut','negativeBases','READ','ALLOW','ROLE','administrative'),(463,'InvoiceOut','negativeBasesCsv','READ','ALLOW','ROLE','administrative'),(464,'WorkerObservation','*','*','ALLOW','ROLE','hr'),(465,'ClientInforma','*','READ','ALLOW','ROLE','employee'),(466,'ClientInforma','*','WRITE','ALLOW','ROLE','financial'),(467,'Receipt','receiptEmail','*','ALLOW','ROLE','salesAssistant'),(468,'Client','setRating','WRITE','ALLOW','ROLE','financial'),(469,'Client','*','READ','ALLOW','ROLE','employee'),(470,'Client','addressesPropagateRe','*','ALLOW','ROLE','employee'),(471,'Client','canBeInvoiced','*','ALLOW','ROLE','employee'),(472,'Client','canCreateTicket','*','ALLOW','ROLE','employee'),(473,'Client','consumption','*','ALLOW','ROLE','employee'),(474,'Client','createAddress','*','ALLOW','ROLE','employee'),(475,'Client','createWithUser','*','ALLOW','ROLE','employee'),(476,'Client','extendedListFilter','*','ALLOW','ROLE','employee'),(477,'Client','getAverageInvoiced','*','ALLOW','ROLE','employee'),(478,'Client','getCard','*','ALLOW','ROLE','employee'),(479,'Client','getDebt','*','ALLOW','ROLE','employee'),(480,'Client','getMana','*','ALLOW','ROLE','employee'),(481,'Client','transactions','*','ALLOW','ROLE','employee'),(482,'Client','hasCustomerRole','*','ALLOW','ROLE','employee'),(483,'Client','isValidClient','*','ALLOW','ROLE','employee'),(484,'Client','lastActiveTickets','*','ALLOW','ROLE','employee'),(485,'Client','sendSms','*','ALLOW','ROLE','employee'),(486,'Client','setPassword','*','ALLOW','ROLE','employee'),(487,'Client','summary','*','ALLOW','ROLE','employee'),(488,'Client','updateAddress','*','ALLOW','ROLE','employee'),(489,'Client','updateFiscalData','*','ALLOW','ROLE','employee'),(491,'Client','uploadFile','*','ALLOW','ROLE','employee'),(492,'Client','campaignMetricsPdf','*','ALLOW','ROLE','employee'),(493,'Client','campaignMetricsEmail','*','ALLOW','ROLE','employee'),(494,'Client','clientWelcomeHtml','*','ALLOW','ROLE','employee'),(495,'Client','clientWelcomeEmail','*','ALLOW','ROLE','employee'),(496,'Client','printerSetupHtml','*','ALLOW','ROLE','employee'),(497,'Client','printerSetupEmail','*','ALLOW','ROLE','employee'),(498,'Client','sepaCoreEmail','*','ALLOW','ROLE','employee'),(499,'Client','letterDebtorPdf','*','ALLOW','ROLE','employee'),(500,'Client','letterDebtorStHtml','*','ALLOW','ROLE','employee'),(501,'Client','letterDebtorStEmail','*','ALLOW','ROLE','employee'),(502,'Client','letterDebtorNdHtml','*','ALLOW','ROLE','employee'),(503,'Client','letterDebtorNdEmail','*','ALLOW','ROLE','employee'),(504,'Client','clientDebtStatementPdf','*','ALLOW','ROLE','employee'),(505,'Client','clientDebtStatementHtml','*','ALLOW','ROLE','employee'),(506,'Client','clientDebtStatementEmail','*','ALLOW','ROLE','employee'),(507,'Client','creditRequestPdf','*','ALLOW','ROLE','employee'),(508,'Client','creditRequestHtml','*','ALLOW','ROLE','employee'),(509,'Client','creditRequestEmail','*','ALLOW','ROLE','employee'),(510,'Client','incotermsAuthorizationPdf','*','ALLOW','ROLE','employee'),(511,'Client','incotermsAuthorizationHtml','*','ALLOW','ROLE','employee'),(512,'Client','incotermsAuthorizationEmail','*','ALLOW','ROLE','employee'),(513,'Client','consumptionSendQueued','*','ALLOW','ROLE','employee'),(514,'Client','filter','*','ALLOW','ROLE','employee'),(515,'Client','getClientOrSupplierReference','*','ALLOW','ROLE','employee'),(516,'Client','upsert','*','ALLOW','ROLE','employee'),(517,'Client','create','*','ALLOW','ROLE','employee'),(518,'Client','replaceById','*','ALLOW','ROLE','employee'),(519,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(520,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(521,'Client','deleteById','*','ALLOW','ROLE','employee'),(522,'Client','replaceOrCreate','*','ALLOW','ROLE','employee'),(523,'Client','updateAll','*','ALLOW','ROLE','employee'),(524,'Client','upsertWithWhere','*','ALLOW','ROLE','employee'),(525,'Defaulter','observationEmail','WRITE','ALLOW','ROLE','employee'),(527,'VnUser','acl','READ','ALLOW','ROLE','account'),(528,'VnUser','getCurrentUserData','READ','ALLOW','ROLE','account'),(530,'Account','exists','READ','ALLOW','ROLE','account'),(531,'Account','exists','READ','ALLOW','ROLE','account'),(532,'UserLog','*','READ','ALLOW','ROLE','employee'),(533,'RoleLog','*','READ','ALLOW','ROLE','employee'),(534,'WagonType','*','*','ALLOW','ROLE','productionAssi'),(535,'WagonTypeColor','*','*','ALLOW','ROLE','productionAssi'),(536,'WagonTypeTray','*','*','ALLOW','ROLE','productionAssi'),(537,'WagonConfig','*','*','ALLOW','ROLE','productionAssi'),(538,'CollectionWagon','*','*','ALLOW','ROLE','productionAssi'),(539,'CollectionWagonTicket','*','*','ALLOW','ROLE','productionAssi'),(540,'Wagon','*','*','ALLOW','ROLE','productionAssi'),(541,'WagonType','createWagonType','*','ALLOW','ROLE','productionAssi'),(542,'WagonType','deleteWagonType','*','ALLOW','ROLE','productionAssi'),(543,'WagonType','editWagonType','*','ALLOW','ROLE','productionAssi'),(544,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(545,'Agency','find','READ','ALLOW','ROLE','employee'),(546,'Agency','seeExpired','READ','ALLOW','ROLE','coolerAssist'),(547,'WorkerLog','models','READ','ALLOW','ROLE','hr'),(548,'Ticket','editDiscount','WRITE','ALLOW','ROLE','claimManager'),(549,'Ticket','editDiscount','WRITE','ALLOW','ROLE','salesPerson'),(550,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','salesAssistant'),(551,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','deliveryBoss'),(552,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','buyer'),(553,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','claimManager'),(554,'Ticket','deleteTicketWithPartPrepared','WRITE','ALLOW','ROLE','salesAssistant'),(555,'Ticket','editZone','WRITE','ALLOW','ROLE','deliveryBoss'),(556,'State','editableStates','READ','ALLOW','ROLE','employee'),(557,'State','seeEditableStates','READ','ALLOW','ROLE','administrative'),(558,'State','seeEditableStates','READ','ALLOW','ROLE','production'),(559,'State','isSomeEditable','READ','ALLOW','ROLE','salesPerson'),(560,'State','isAllEditable','READ','ALLOW','ROLE','production'),(561,'State','isAllEditable','READ','ALLOW','ROLE','administrative'),(562,'Agency','seeExpired','READ','ALLOW','ROLE','administrative'),(563,'Agency','seeExpired','READ','ALLOW','ROLE','productionBoss'),(564,'Claim','createAfterDeadline','WRITE','ALLOW','ROLE','claimManager'),(565,'Client','editAddressLogifloraAllowed','WRITE','ALLOW','ROLE','salesAssistant'),(566,'Client','editFiscalDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(567,'Client','editVerifiedDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(568,'Client','editCredit','WRITE','ALLOW','ROLE','financialBoss'),(569,'Client','zeroCreditEditor','WRITE','ALLOW','ROLE','financialBoss'),(570,'InvoiceOut','canCreatePdf','WRITE','ALLOW','ROLE','invoicing'),(571,'Supplier','editPayMethodCheck','WRITE','ALLOW','ROLE','financial'),(572,'Worker','isTeamBoss','WRITE','ALLOW','ROLE','teamBoss'),(573,'Worker','forceIsSubordinate','READ','ALLOW','ROLE','hr'),(574,'Claim','editState','WRITE','ALLOW','ROLE','claimManager'),(575,'Claim','find','READ','ALLOW','ROLE','salesPerson'),(576,'Claim','findById','READ','ALLOW','ROLE','salesPerson'),(577,'Claim','findOne','READ','ALLOW','ROLE','salesPerson'),(578,'Claim','getSummary','READ','ALLOW','ROLE','salesPerson'),(579,'Claim','updateClaim','WRITE','ALLOW','ROLE','salesPerson'),(580,'Claim','regularizeClaim','WRITE','ALLOW','ROLE','claimManager'),(581,'Claim','updateClaimDestination','WRITE','ALLOW','ROLE','claimManager'),(582,'Claim','downloadFile','READ','ALLOW','ROLE','claimManager'),(583,'Claim','deleteById','WRITE','ALLOW','ROLE','claimManager'),(584,'Claim','filter','READ','ALLOW','ROLE','salesPerson'),(585,'Claim','logs','READ','ALLOW','ROLE','claimManager'),(586,'Ticket','find','READ','ALLOW','ROLE','employee'),(587,'Ticket','findById','READ','ALLOW','ROLE','employee'),(588,'Ticket','findOne','READ','ALLOW','ROLE','employee'),(589,'Ticket','getVolume','READ','ALLOW','ROLE','employee'),(590,'Ticket','getTotalVolume','READ','ALLOW','ROLE','employee'),(591,'Ticket','summary','READ','ALLOW','ROLE','employee'),(592,'Ticket','priceDifference','READ','ALLOW','ROLE','employee'),(593,'Ticket','componentUpdate','WRITE','ALLOW','ROLE','employee'),(594,'Ticket','new','WRITE','ALLOW','ROLE','employee'),(595,'Ticket','isEditable','READ','ALLOW','ROLE','employee'),(596,'Ticket','setDeleted','WRITE','ALLOW','ROLE','salesPerson'),(597,'Ticket','restore','WRITE','ALLOW','ROLE','employee'),(598,'Ticket','getSales','READ','ALLOW','ROLE','employee'),(599,'Ticket','getSalesPersonMana','READ','ALLOW','ROLE','employee'),(600,'Ticket','filter','READ','ALLOW','ROLE','employee'),(601,'Ticket','makeInvoice','WRITE','ALLOW','ROLE','employee'),(602,'Ticket','updateEditableTicket','WRITE','ALLOW','ROLE','employee'),(603,'Ticket','updateDiscount','WRITE','ALLOW','ROLE','employee'),(604,'Ticket','transferSales','WRITE','ALLOW','ROLE','employee'),(605,'Ticket','sendSms','WRITE','ALLOW','ROLE','employee'),(606,'Ticket','isLocked','READ','ALLOW','ROLE','employee'),(607,'Ticket','freightCost','READ','ALLOW','ROLE','employee'),(608,'Ticket','getComponentsSum','READ','ALLOW','ROLE','employee'),(609,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','delivery'),(610,'Ticket','deliveryNoteCsv','READ','ALLOW','ROLE','employee'),(611,'State','find','READ','ALLOW','ROLE','employee'),(612,'State','findById','READ','ALLOW','ROLE','employee'),(613,'State','findOne','READ','ALLOW','ROLE','employee'),(614,'Worker','find','READ','ALLOW','ROLE','employee'),(615,'Worker','findById','READ','ALLOW','ROLE','employee'),(616,'Worker','findOne','READ','ALLOW','ROLE','employee'),(617,'Worker','filter','READ','ALLOW','ROLE','employee'),(618,'Worker','getWorkedHours','READ','ALLOW','ROLE','employee'),(619,'Worker','active','READ','ALLOW','ROLE','employee'),(620,'Worker','activeWithRole','READ','ALLOW','ROLE','employee'),(621,'Worker','uploadFile','WRITE','ALLOW','ROLE','hr'),(622,'Worker','contracts','READ','ALLOW','ROLE','employee'),(623,'Worker','holidays','READ','ALLOW','ROLE','employee'),(624,'Worker','activeContract','READ','ALLOW','ROLE','employee'),(625,'Worker','activeWithInheritedRole','READ','ALLOW','ROLE','employee'),(626,'Ticket','collectionLabel','READ','ALLOW','ROLE','employee'),(628,'Ticket','expeditionPalletLabel','READ','ALLOW','ROLE','employee'),(629,'Ticket','editDiscount','WRITE','ALLOW','ROLE','artificialBoss'),(630,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesTeamBoss'),(635,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','administrative'),(636,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesPerson'),(637,'Claim','downloadFile','READ','ALLOW','ROLE','salesPerson'),(638,'Agency','seeExpired','READ','ALLOW','ROLE','artificialBoss'),(639,'Agency','seeExpired','READ','ALLOW','ROLE','logisticAssistant'),(640,'Claim','filter','READ','ALLOW','ROLE','buyer'),(641,'Claim','find','READ','ALLOW','ROLE','buyer'),(642,'Claim','findById','READ','ALLOW','ROLE','buyer'),(643,'Claim','getSummary','READ','ALLOW','ROLE','buyer'),(644,'Claim','filter','READ','ALLOW','ROLE','handmadeBoss'),(645,'Claim','find','READ','ALLOW','ROLE','handmadeBoss'),(646,'Claim','findById','READ','ALLOW','ROLE','handmadeBoss'),(647,'Claim','getSummary','READ','ALLOW','ROLE','handmadeBoss'),(648,'Claim','__get__lines','READ','ALLOW','ROLE','claimManager'),(649,'Claim','__get__lines','READ','ALLOW','ROLE','salesPerson'),(650,'Claim','getSummary','READ','ALLOW','ROLE','deliveryBoss'),(651,'Claim','findById','READ','ALLOW','ROLE','deliveryBoss'),(652,'Claim','find','READ','ALLOW','ROLE','deliveryBoss'),(653,'Claim','filter','READ','ALLOW','ROLE','deliveryBoss'),(654,'Ticket','editZone','WRITE','ALLOW','ROLE','logisticAssistant'),(655,'Entry','addFromPackaging','WRITE','ALLOW','ROLE','production'),(656,'Entry','addFromBuy','WRITE','ALLOW','ROLE','production'),(657,'Supplier','getItemsPackaging','READ','ALLOW','ROLE','production'),(658,'Ticket','closeAll','WRITE','ALLOW','ROLE','system'),(659,'Account','*','*','ALLOW','ROLE','itManagement'),(660,'Account','*','READ','ALLOW','ROLE','employee'),(664,'MailForward','*','*','ALLOW','ROLE','itManagement'),(665,'Role','*','READ','ALLOW','ROLE','employee'),(666,'Role','*','WRITE','ALLOW','ROLE','it'),(667,'VnUser','*','*','ALLOW','ROLE','itManagement'),(668,'VnUser','__get__preview','READ','ALLOW','ROLE','employee'),(669,'VnUser','preview','*','ALLOW','ROLE','employee'),(670,'VnUser','create','*','ALLOW','ROLE','itManagement'),(671,'VnUser','renewToken','WRITE','ALLOW','ROLE','employee'),(672,'PackingSiteAdvanced','*','*','ALLOW','ROLE','production'),(673,'InvoiceOut','makePdfAndNotify','WRITE','ALLOW','ROLE','invoicing'),(674,'InvoiceOutConfig','*','READ','ALLOW','ROLE','invoicing'),(676,'Ticket','invoiceTickets','WRITE','ALLOW','ROLE','employee'),(680,'MailAliasAccount','*','READ','ALLOW','ROLE','employee'),(681,'MailAliasAccount','create','WRITE','ALLOW','ROLE','employee'),(682,'MailAliasAccount','deleteById','WRITE','ALLOW','ROLE','employee'),(683,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','itManagement'),(684,'WorkerDisableExcluded','*','READ','ALLOW','ROLE','itManagement'),(685,'WorkerDisableExcluded','*','WRITE','ALLOW','ROLE','itManagement'),(686,'MailForward','*','*','ALLOW','ROLE','hr'),(687,'ClientSms','find','READ','ALLOW','ROLE','employee'),(688,'ClientSms','create','WRITE','ALLOW','ROLE','employee'),(689,'Vehicle','sorted','WRITE','ALLOW','ROLE','employee'),(690,'Roadmap','*','*','ALLOW','ROLE','palletizerBoss'),(691,'Roadmap','*','*','ALLOW','ROLE','productionBoss'),(692,'ExpeditionTruck','*','*','ALLOW','ROLE','palletizerBoss'),(693,'ExpeditionTruck','*','*','ALLOW','ROLE','productionBoss'),(694,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','marketingBoss'),(695,'ViaexpressConfig','internationalExpedition','WRITE','ALLOW','ROLE','employee'),(696,'ViaexpressConfig','renderer','READ','ALLOW','ROLE','employee'),(697,'Ticket','transferClient','WRITE','ALLOW','ROLE','administrative'),(698,'Ticket','canEditWeekly','WRITE','ALLOW','ROLE','buyer'),(699,'TicketSms','find','READ','ALLOW','ROLE','salesPerson'),(701,'Docuware','upload','WRITE','ALLOW','ROLE','deliveryBoss'),(702,'Ticket','docuwareDownload','READ','ALLOW','ROLE','salesPerson'); +INSERT INTO `ACL` VALUES (3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','trainee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','trainee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','trainee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','trainee'),(30,'GreugeType','*','READ','ALLOW','ROLE','trainee'),(31,'Mandate','*','READ','ALLOW','ROLE','trainee'),(32,'MandateType','*','READ','ALLOW','ROLE','trainee'),(33,'Company','*','READ','ALLOW','ROLE','trainee'),(34,'Greuge','*','READ','ALLOW','ROLE','trainee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer'),(55,'Recovery','*','READ','ALLOW','ROLE','trainee'),(56,'Recovery','*','WRITE','ALLOW','ROLE','administrative'),(58,'CreditClassification','*','*','ALLOW','ROLE','insurance'),(60,'CreditInsurance','*','*','ALLOW','ROLE','insurance'),(61,'InvoiceOut','*','READ','ALLOW','ROLE','employee'),(63,'TicketObservation','*','*','ALLOW','ROLE','employee'),(64,'Route','*','READ','ALLOW','ROLE','employee'),(65,'Sale','*','READ','ALLOW','ROLE','employee'),(66,'TicketTracking','*','READ','ALLOW','ROLE','employee'),(68,'TicketPackaging','*','*','ALLOW','ROLE','employee'),(69,'Packaging','*','READ','ALLOW','ROLE','employee'),(70,'Packaging','*','WRITE','ALLOW','ROLE','logistic'),(72,'SaleComponent','*','READ','ALLOW','ROLE','employee'),(73,'Expedition','*','READ','ALLOW','ROLE','employee'),(74,'Expedition','*','WRITE','ALLOW','ROLE','deliveryAssistant'),(75,'Expedition','*','WRITE','ALLOW','ROLE','production'),(76,'AnnualAverageInvoiced','*','READ','ALLOW','ROLE','employee'),(77,'WorkerMana','*','READ','ALLOW','ROLE','employee'),(78,'TicketTracking','*','WRITE','ALLOW','ROLE','production'),(79,'Ticket','state','*','ALLOW','ROLE','employee'),(80,'Sale','deleteSales','*','ALLOW','ROLE','employee'),(81,'Sale','moveToTicket','*','ALLOW','ROLE','employee'),(82,'Sale','updateQuantity','*','ALLOW','ROLE','employee'),(83,'Sale','updatePrice','*','ALLOW','ROLE','employee'),(84,'Sale','updateDiscount','*','ALLOW','ROLE','employee'),(85,'SaleTracking','*','READ','ALLOW','ROLE','employee'),(86,'Order','*','*','ALLOW','ROLE','employee'),(87,'OrderRow','*','*','ALLOW','ROLE','employee'),(88,'ClientContact','*','*','ALLOW','ROLE','employee'),(89,'Sale','moveToNewTicket','*','ALLOW','ROLE','employee'),(90,'Sale','reserve','*','ALLOW','ROLE','employee'),(91,'TicketWeekly','*','READ','ALLOW','ROLE','employee'),(94,'Agency','landsThatDay','*','ALLOW','ROLE','employee'),(96,'ClaimEnd','*','READ','ALLOW','ROLE','employee'),(97,'ClaimEnd','*','WRITE','ALLOW','ROLE','claimManager'),(98,'ClaimBeginning','*','*','ALLOW','ROLE','employee'),(99,'ClaimDevelopment','*','READ','ALLOW','ROLE','employee'),(100,'ClaimDevelopment','*','WRITE','ALLOW','ROLE','claimManager'),(102,'Claim','createFromSales','*','ALLOW','ROLE','employee'),(104,'Item','*','WRITE','ALLOW','ROLE','marketingBoss'),(105,'ItemBarcode','*','WRITE','ALLOW','ROLE','marketingBoss'),(106,'ItemBotanical','*','WRITE','ALLOW','ROLE','marketingBoss'),(108,'ItemPlacement','*','WRITE','ALLOW','ROLE','marketingBoss'),(109,'UserConfig','*','*','ALLOW','ROLE','employee'),(110,'Bank','*','READ','ALLOW','ROLE','trainee'),(111,'ClientLog','*','READ','ALLOW','ROLE','trainee'),(112,'Defaulter','*','READ','ALLOW','ROLE','employee'),(113,'ClientRisk','*','READ','ALLOW','ROLE','trainee'),(114,'Receipt','*','READ','ALLOW','ROLE','trainee'),(115,'Receipt','*','WRITE','ALLOW','ROLE','administrative'),(116,'BankEntity','*','*','ALLOW','ROLE','employee'),(117,'ClientSample','*','*','ALLOW','ROLE','employee'),(118,'WorkerTeam','*','*','ALLOW','ROLE','salesPerson'),(119,'Travel','*','READ','ALLOW','ROLE','employee'),(120,'Travel','*','WRITE','ALLOW','ROLE','buyer'),(121,'Item','regularize','*','ALLOW','ROLE','employee'),(122,'TicketRequest','*','*','ALLOW','ROLE','employee'),(124,'Client','confirmTransaction','WRITE','ALLOW','ROLE','administrative'),(125,'Agency','getAgenciesWithWarehouse','*','ALLOW','ROLE','employee'),(127,'TicketLog','*','READ','ALLOW','ROLE','employee'),(129,'TicketService','*','*','ALLOW','ROLE','employee'),(130,'Expedition','*','WRITE','ALLOW','ROLE','packager'),(131,'CreditInsurance','*','READ','ALLOW','ROLE','trainee'),(132,'CreditClassification','*','READ','ALLOW','ROLE','trainee'),(133,'ItemTag','*','WRITE','ALLOW','ROLE','marketingBoss'),(135,'ZoneGeo','*','READ','ALLOW','ROLE','employee'),(136,'ZoneCalendar','*','READ','ALLOW','ROLE','employee'),(137,'ZoneIncluded','*','READ','ALLOW','ROLE','employee'),(138,'LabourHoliday','*','READ','ALLOW','ROLE','employee'),(139,'LabourHolidayLegend','*','READ','ALLOW','ROLE','employee'),(140,'LabourHolidayType','*','READ','ALLOW','ROLE','employee'),(141,'Zone','*','*','ALLOW','ROLE','logisticBoss'),(142,'ZoneCalendar','*','WRITE','ALLOW','ROLE','deliveryAssistant'),(143,'ZoneIncluded','*','*','ALLOW','ROLE','deliveryAssistant'),(144,'Stowaway','*','*','ALLOW','ROLE','employee'),(145,'Ticket','getPossibleStowaways','READ','ALLOW','ROLE','employee'),(147,'UserConfigView','*','*','ALLOW','ROLE','employee'),(148,'UserConfigView','*','*','ALLOW','ROLE','employee'),(149,'Sip','*','READ','ALLOW','ROLE','employee'),(150,'Sip','*','WRITE','ALLOW','ROLE','hr'),(151,'Department','*','READ','ALLOW','ROLE','employee'),(152,'Department','*','WRITE','ALLOW','ROLE','hr'),(153,'Route','*','READ','ALLOW','ROLE','employee'),(154,'Route','*','WRITE','ALLOW','ROLE','delivery'),(155,'Calendar','*','READ','ALLOW','ROLE','hr'),(156,'WorkerLabour','*','READ','ALLOW','ROLE','hr'),(157,'Calendar','absences','READ','ALLOW','ROLE','employee'),(158,'ItemTag','*','WRITE','ALLOW','ROLE','accessory'),(160,'TicketServiceType','*','READ','ALLOW','ROLE','employee'),(161,'TicketConfig','*','READ','ALLOW','ROLE','employee'),(162,'InvoiceOut','delete','WRITE','ALLOW','ROLE','invoicing'),(163,'InvoiceOut','book','WRITE','ALLOW','ROLE','invoicing'),(165,'TicketDms','*','*','ALLOW','ROLE','employee'),(167,'Worker','isSubordinate','READ','ALLOW','ROLE','employee'),(168,'Worker','mySubordinates','READ','ALLOW','ROLE','employee'),(169,'WorkerTimeControl','filter','READ','ALLOW','ROLE','employee'),(170,'WorkerTimeControl','addTime','WRITE','ALLOW','ROLE','employee'),(171,'TicketServiceType','*','WRITE','ALLOW','ROLE','administrative'),(172,'Sms','*','READ','ALLOW','ROLE','employee'),(173,'Sms','send','WRITE','ALLOW','ROLE','employee'),(176,'Device','*','*','ALLOW','ROLE','employee'),(177,'Device','*','*','ALLOW','ROLE','employee'),(178,'WorkerTimeControl','*','*','ALLOW','ROLE','employee'),(179,'ItemLog','*','READ','ALLOW','ROLE','employee'),(180,'RouteLog','*','READ','ALLOW','ROLE','employee'),(181,'Dms','removeFile','WRITE','ALLOW','ROLE','employee'),(182,'Dms','uploadFile','WRITE','ALLOW','ROLE','employee'),(183,'Dms','downloadFile','READ','ALLOW','ROLE','employee'),(184,'Client','uploadFile','WRITE','ALLOW','ROLE','employee'),(185,'ClientDms','removeFile','WRITE','ALLOW','ROLE','employee'),(186,'ClientDms','*','READ','ALLOW','ROLE','trainee'),(187,'Ticket','uploadFile','WRITE','ALLOW','ROLE','employee'),(190,'Route','updateVolume','WRITE','ALLOW','ROLE','deliveryAssistant'),(191,'Agency','getLanded','READ','ALLOW','ROLE','employee'),(192,'Agency','getShipped','READ','ALLOW','ROLE','employee'),(194,'Postcode','*','WRITE','ALLOW','ROLE','deliveryAssistant'),(195,'Ticket','addSale','WRITE','ALLOW','ROLE','employee'),(196,'Dms','updateFile','WRITE','ALLOW','ROLE','employee'),(197,'Dms','*','READ','ALLOW','ROLE','trainee'),(198,'ClaimDms','removeFile','WRITE','ALLOW','ROLE','employee'),(199,'ClaimDms','*','READ','ALLOW','ROLE','employee'),(200,'Claim','uploadFile','WRITE','ALLOW','ROLE','employee'),(201,'Sale','updateConcept','WRITE','ALLOW','ROLE','employee'),(202,'Claim','updateClaimAction','WRITE','ALLOW','ROLE','claimManager'),(203,'UserPhone','*','*','ALLOW','ROLE','employee'),(204,'WorkerDms','removeFile','WRITE','ALLOW','ROLE','hr'),(205,'WorkerDms','*','READ','ALLOW','ROLE','hr'),(206,'Chat','*','*','ALLOW','ROLE','employee'),(207,'Chat','sendMessage','*','ALLOW','ROLE','employee'),(208,'Sale','recalculatePrice','WRITE','ALLOW','ROLE','employee'),(209,'Ticket','recalculateComponents','WRITE','ALLOW','ROLE','employee'),(211,'TravelLog','*','READ','ALLOW','ROLE','buyer'),(212,'Thermograph','*','*','ALLOW','ROLE','buyer'),(213,'TravelThermograph','*','WRITE','ALLOW','ROLE','buyer'),(214,'Entry','*','*','ALLOW','ROLE','buyer'),(215,'TicketWeekly','*','WRITE','ALLOW','ROLE','buyer'),(216,'TravelThermograph','*','READ','ALLOW','ROLE','employee'),(218,'Intrastat','*','*','ALLOW','ROLE','buyer'),(221,'UserConfig','getUserConfig','READ','ALLOW','ROLE','account'),(226,'ClientObservation','*','READ','ALLOW','ROLE','trainee'),(227,'Address','*','READ','ALLOW','ROLE','trainee'),(228,'AddressObservation','*','READ','ALLOW','ROLE','trainee'),(230,'ClientCredit','*','READ','ALLOW','ROLE','trainee'),(231,'ClientContact','*','READ','ALLOW','ROLE','trainee'),(232,'ClientSample','*','READ','ALLOW','ROLE','trainee'),(233,'EntryLog','*','READ','ALLOW','ROLE','buyer'),(234,'WorkerLog','find','READ','ALLOW','ROLE','hr'),(235,'CustomsAgent','*','*','ALLOW','ROLE','employee'),(236,'Buy','*','*','ALLOW','ROLE','buyer'),(237,'WorkerDms','filter','*','ALLOW','ROLE','employee'),(238,'Town','*','WRITE','ALLOW','ROLE','deliveryAssistant'),(239,'Province','*','WRITE','ALLOW','ROLE','deliveryAssistant'),(241,'SupplierContact','*','WRITE','ALLOW','ROLE','administrative'),(248,'RoleMapping','*','READ','ALLOW','ROLE','account'),(249,'UserPassword','*','READ','ALLOW','ROLE','account'),(250,'Town','*','WRITE','ALLOW','ROLE','deliveryAssistant'),(251,'Province','*','WRITE','ALLOW','ROLE','deliveryAssistant'),(252,'Supplier','*','READ','ALLOW','ROLE','employee'),(253,'Supplier','*','WRITE','ALLOW','ROLE','administrative'),(254,'SupplierLog','*','READ','ALLOW','ROLE','employee'),(256,'Image','*','WRITE','ALLOW','ROLE','employee'),(257,'FixedPrice','*','*','ALLOW','ROLE','buyer'),(258,'PayDem','*','READ','ALLOW','ROLE','employee'),(259,'Client','createReceipt','*','ALLOW','ROLE','salesAssistant'),(260,'PrintServerQueue','*','WRITE','ALLOW','ROLE','employee'),(261,'SupplierAccount','*','*','ALLOW','ROLE','administrative'),(262,'Entry','*','*','ALLOW','ROLE','administrative'),(263,'InvoiceIn','*','*','ALLOW','ROLE','administrative'),(264,'StarredModule','*','*','ALLOW','ROLE','employee'),(265,'ItemBotanical','*','WRITE','ALLOW','ROLE','logisticBoss'),(266,'ZoneLog','*','READ','ALLOW','ROLE','employee'),(267,'Genus','*','WRITE','ALLOW','ROLE','logisticBoss'),(268,'Specie','*','WRITE','ALLOW','ROLE','logisticBoss'),(269,'InvoiceOut','createPdf','WRITE','ALLOW','ROLE','employee'),(270,'SupplierAddress','*','*','ALLOW','ROLE','employee'),(271,'SalesMonitor','*','*','ALLOW','ROLE','employee'),(272,'InvoiceInLog','*','READ','ALLOW','ROLE','employee'),(273,'InvoiceInTax','*','*','ALLOW','ROLE','administrative'),(274,'InvoiceInLog','*','READ','ALLOW','ROLE','administrative'),(275,'InvoiceOut','createManualInvoice','WRITE','ALLOW','ROLE','invoicing'),(276,'InvoiceOut','globalInvoicing','WRITE','ALLOW','ROLE','invoicing'),(278,'RoleInherit','*','WRITE','ALLOW','ROLE','grant'),(279,'MailAlias','*','*','ALLOW','ROLE','marketing'),(283,'EntryObservation','*','*','ALLOW','ROLE','buyer'),(284,'LdapConfig','*','*','ALLOW','ROLE','sysadmin'),(285,'SambaConfig','*','*','ALLOW','ROLE','sysadmin'),(286,'ACL','*','*','ALLOW','ROLE','developer'),(287,'AccessToken','*','*','ALLOW','ROLE','developer'),(293,'RoleInherit','*','*','ALLOW','ROLE','it'),(294,'RoleRole','*','*','ALLOW','ROLE','it'),(295,'AccountConfig','*','*','ALLOW','ROLE','sysadmin'),(296,'Collection','*','READ','ALLOW','ROLE','employee'),(297,'Sale','refund','WRITE','ALLOW','ROLE','invoicing'),(298,'InvoiceInDueDay','*','*','ALLOW','ROLE','administrative'),(299,'Collection','setSaleQuantity','*','ALLOW','ROLE','employee'),(302,'AgencyTerm','*','*','ALLOW','ROLE','administrative'),(303,'ClaimLog','*','READ','ALLOW','ROLE','claimManager'),(304,'Edi','updateData','WRITE','ALLOW','ROLE','employee'),(305,'EducationLevel','*','*','ALLOW','ROLE','employee'),(306,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(307,'SupplierAgencyTerm','*','*','ALLOW','ROLE','administrative'),(308,'InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'),(309,'Zone','getZoneClosing','*','ALLOW','ROLE','employee'),(310,'ExpeditionState','*','READ','ALLOW','ROLE','employee'),(311,'Expense','*','READ','ALLOW','ROLE','employee'),(312,'Expense','*','WRITE','ALLOW','ROLE','administrative'),(314,'SupplierActivity','*','READ','ALLOW','ROLE','employee'),(315,'SupplierActivity','*','WRITE','ALLOW','ROLE','administrative'),(316,'Dms','deleteTrashFiles','WRITE','ALLOW','ROLE','employee'),(317,'ClientUnpaid','*','*','ALLOW','ROLE','administrative'),(318,'MdbVersion','*','*','ALLOW','ROLE','developer'),(319,'ItemType','*','READ','ALLOW','ROLE','employee'),(320,'ItemType','*','WRITE','ALLOW','ROLE','buyer'),(321,'InvoiceOut','refund','WRITE','ALLOW','ROLE','invoicing'),(322,'InvoiceOut','refund','WRITE','ALLOW','ROLE','salesAssistant'),(323,'InvoiceOut','refund','WRITE','ALLOW','ROLE','claimManager'),(324,'Ticket','refund','WRITE','ALLOW','ROLE','invoicing'),(325,'Ticket','refund','WRITE','ALLOW','ROLE','salesAssistant'),(326,'Ticket','refund','WRITE','ALLOW','ROLE','claimManager'),(327,'Sale','refund','WRITE','ALLOW','ROLE','salesAssistant'),(328,'Sale','refund','WRITE','ALLOW','ROLE','claimManager'),(329,'TicketRefund','*','WRITE','ALLOW','ROLE','invoicing'),(330,'ClaimObservation','*','WRITE','ALLOW','ROLE','salesPerson'),(331,'ClaimObservation','*','READ','ALLOW','ROLE','salesPerson'),(332,'Client','setPassword','WRITE','ALLOW','ROLE','salesPerson'),(333,'Client','updateUser','WRITE','ALLOW','ROLE','salesPerson'),(334,'ShelvingLog','*','READ','ALLOW','ROLE','employee'),(335,'ZoneExclusionGeo','*','READ','ALLOW','ROLE','employee'),(336,'ZoneExclusionGeo','*','WRITE','ALLOW','ROLE','deliveryAssistant'),(337,'Parking','*','*','ALLOW','ROLE','employee'),(338,'Shelving','*','*','ALLOW','ROLE','employee'),(339,'OsTicket','*','*','ALLOW','ROLE','employee'),(340,'OsTicketConfig','*','*','ALLOW','ROLE','it'),(341,'ClientConsumptionQueue','*','WRITE','ALLOW','ROLE','employee'),(342,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','employee'),(343,'Ticket','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(344,'Ticket','deliveryNoteCsvPdf','READ','ALLOW','ROLE','employee'),(345,'Ticket','deliveryNoteCsvEmail','READ','ALLOW','ROLE','employee'),(346,'Client','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(347,'Client','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(348,'Client','clientWelcomeHtml','READ','ALLOW','ROLE','employee'),(349,'Client','clientWelcomeEmail','WRITE','ALLOW','ROLE','employee'),(350,'Client','creditRequestPdf','READ','ALLOW','ROLE','employee'),(351,'Client','creditRequestHtml','READ','ALLOW','ROLE','employee'),(352,'Client','creditRequestEmail','WRITE','ALLOW','ROLE','employee'),(353,'Client','printerSetupHtml','READ','ALLOW','ROLE','employee'),(354,'Client','printerSetupEmail','WRITE','ALLOW','ROLE','employee'),(355,'Client','sepaCoreEmail','WRITE','ALLOW','ROLE','employee'),(356,'Client','letterDebtorPdf','READ','ALLOW','ROLE','employee'),(357,'Client','letterDebtorStHtml','READ','ALLOW','ROLE','employee'),(358,'Client','letterDebtorStEmail','WRITE','ALLOW','ROLE','employee'),(359,'Client','letterDebtorNdHtml','READ','ALLOW','ROLE','employee'),(360,'Client','letterDebtorNdEmail','WRITE','ALLOW','ROLE','employee'),(361,'Client','clientDebtStatementPdf','READ','ALLOW','ROLE','employee'),(362,'Client','clientDebtStatementHtml','READ','ALLOW','ROLE','employee'),(363,'Client','clientDebtStatementEmail','WRITE','ALLOW','ROLE','employee'),(364,'Client','incotermsAuthorizationPdf','READ','ALLOW','ROLE','employee'),(365,'Client','incotermsAuthorizationHtml','READ','ALLOW','ROLE','employee'),(366,'Client','incotermsAuthorizationEmail','WRITE','ALLOW','ROLE','employee'),(367,'Client','consumptionSendQueued','WRITE','ALLOW','ROLE','system'),(368,'InvoiceOut','invoiceEmail','WRITE','ALLOW','ROLE','employee'),(369,'InvoiceOut','exportationPdf','READ','ALLOW','ROLE','employee'),(370,'InvoiceOut','sendQueued','WRITE','ALLOW','ROLE','system'),(371,'Ticket','invoiceCsvPdf','READ','ALLOW','ROLE','employee'),(372,'Ticket','invoiceCsvEmail','WRITE','ALLOW','ROLE','employee'),(373,'Supplier','campaignMetricsPdf','READ','ALLOW','ROLE','employee'),(374,'Supplier','campaignMetricsEmail','WRITE','ALLOW','ROLE','employee'),(375,'Travel','extraCommunityPdf','READ','ALLOW','ROLE','employee'),(376,'Travel','extraCommunityEmail','WRITE','ALLOW','ROLE','employee'),(377,'Entry','entryOrderPdf','READ','ALLOW','ROLE','employee'),(378,'OsTicket','osTicketReportEmail','WRITE','ALLOW','ROLE','system'),(379,'Item','buyerWasteEmail','WRITE','ALLOW','ROLE','system'),(380,'Claim','claimPickupPdf','READ','ALLOW','ROLE','employee'),(381,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','claimManager'),(382,'Item','labelPdf','READ','ALLOW','ROLE','employee'),(383,'Sector','*','READ','ALLOW','ROLE','employee'),(384,'Sector','*','WRITE','ALLOW','ROLE','employee'),(385,'Route','driverRoutePdf','READ','ALLOW','ROLE','employee'),(386,'Route','driverRouteEmail','WRITE','ALLOW','ROLE','employee'),(387,'Ticket','deliveryNotePdf','READ','ALLOW','ROLE','customer'),(388,'Supplier','newSupplier','WRITE','ALLOW','ROLE','administrative'),(389,'ClaimRma','*','READ','ALLOW','ROLE','claimManager'),(390,'ClaimRma','*','WRITE','ALLOW','ROLE','claimManager'),(391,'Notification','*','WRITE','ALLOW','ROLE','system'),(392,'Boxing','*','*','ALLOW','ROLE','employee'),(393,'Url','*','READ','ALLOW','ROLE','employee'),(394,'Url','*','WRITE','ALLOW','ROLE','it'),(395,'ItemShelving','*','READ','ALLOW','ROLE','employee'),(396,'ItemShelving','*','WRITE','ALLOW','ROLE','production'),(397,'ItemShelvingPlacementSupplyStock','*','READ','ALLOW','ROLE','employee'),(398,'NotificationQueue','*','*','ALLOW','ROLE','employee'),(399,'InvoiceOut','clientsToInvoice','WRITE','ALLOW','ROLE','invoicing'),(400,'InvoiceOut','invoiceClient','WRITE','ALLOW','ROLE','invoicing'),(401,'Sale','editTracked','WRITE','ALLOW','ROLE','production'),(402,'Sale','editFloramondo','WRITE','ALLOW','ROLE','salesAssistant'),(403,'Receipt','balanceCompensationEmail','WRITE','ALLOW','ROLE','employee'),(404,'Receipt','balanceCompensationPdf','READ','ALLOW','ROLE','employee'),(405,'Ticket','getTicketsFuture','READ','ALLOW','ROLE','employee'),(406,'Ticket','merge','WRITE','ALLOW','ROLE','employee'),(407,'Sale','editFloramondo','WRITE','ALLOW','ROLE','logistic'),(408,'ZipConfig','*','*','ALLOW','ROLE','employee'),(409,'Item','*','WRITE','ALLOW','ROLE','administrative'),(410,'Sale','editCloned','WRITE','ALLOW','ROLE','buyer'),(411,'Sale','editCloned','WRITE','ALLOW','ROLE','salesAssistant'),(414,'MdbVersion','*','READ','ALLOW','ROLE','$everyone'),(416,'TicketLog','getChanges','READ','ALLOW','ROLE','employee'),(417,'Ticket','getTicketsAdvance','READ','ALLOW','ROLE','employee'),(418,'EntryLog','*','READ','ALLOW','ROLE','administrative'),(419,'Sale','editTracked','WRITE','ALLOW','ROLE','buyer'),(420,'MdbBranch','*','READ','ALLOW','ROLE','$everyone'),(421,'ItemShelvingSale','*','*','ALLOW','ROLE','employee'),(422,'Docuware','checkFile','READ','ALLOW','ROLE','employee'),(423,'Docuware','download','READ','ALLOW','ROLE','salesPerson'),(424,'Docuware','upload','WRITE','ALLOW','ROLE','productionAssi'),(425,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','salesPerson'),(426,'TpvTransaction','confirm','WRITE','ALLOW','ROLE','$everyone'),(427,'TpvTransaction','start','WRITE','ALLOW','ROLE','$authenticated'),(428,'TpvTransaction','end','WRITE','ALLOW','ROLE','$authenticated'),(429,'ItemConfig','*','READ','ALLOW','ROLE','employee'),(431,'Tag','onSubmit','WRITE','ALLOW','ROLE','employee'),(432,'Worker','updateAttributes','WRITE','ALLOW','ROLE','hr'),(433,'Worker','createAbsence','*','ALLOW','ROLE','employee'),(434,'Worker','updateAbsence','WRITE','ALLOW','ROLE','employee'),(435,'Worker','deleteAbsence','*','ALLOW','ROLE','employee'),(436,'Worker','new','WRITE','ALLOW','ROLE','hr'),(438,'Client','getClientOrSupplierReference','READ','ALLOW','ROLE','employee'),(439,'NotificationSubscription','*','*','ALLOW','ROLE','employee'),(440,'NotificationAcl','*','READ','ALLOW','ROLE','employee'),(441,'MdbApp','*','READ','ALLOW','ROLE','$everyone'),(442,'MdbApp','*','*','ALLOW','ROLE','developer'),(443,'ItemConfig','*','*','ALLOW','ROLE','employee'),(444,'DeviceProduction','*','*','ALLOW','ROLE','hr'),(445,'DeviceProductionModels','*','*','ALLOW','ROLE','hr'),(446,'DeviceProductionState','*','*','ALLOW','ROLE','hr'),(447,'DeviceProductionUser','*','*','ALLOW','ROLE','hr'),(448,'DeviceProduction','*','*','ALLOW','ROLE','productionAssi'),(449,'DeviceProductionModels','*','*','ALLOW','ROLE','productionAssi'),(450,'DeviceProductionState','*','*','ALLOW','ROLE','productionAssi'),(451,'DeviceProductionUser','*','*','ALLOW','ROLE','productionAssi'),(452,'Worker','deallocatePDA','*','ALLOW','ROLE','hr'),(453,'Worker','allocatePDA','*','ALLOW','ROLE','hr'),(454,'Worker','deallocatePDA','*','ALLOW','ROLE','productionAssi'),(455,'Worker','allocatePDA','*','ALLOW','ROLE','productionAssi'),(456,'Zone','*','*','ALLOW','ROLE','deliveryAssistant'),(458,'Operator','*','READ','ALLOW','ROLE','employee'),(459,'Operator','*','WRITE','ALLOW','ROLE','employee'),(460,'InvoiceIn','getSerial','READ','ALLOW','ROLE','administrative'),(461,'Ticket','saveSign','WRITE','ALLOW','ROLE','employee'),(462,'InvoiceOut','negativeBases','READ','ALLOW','ROLE','administrative'),(463,'InvoiceOut','negativeBasesCsv','READ','ALLOW','ROLE','administrative'),(464,'WorkerObservation','*','*','ALLOW','ROLE','hr'),(465,'ClientInforma','*','READ','ALLOW','ROLE','employee'),(466,'ClientInforma','*','WRITE','ALLOW','ROLE','financial'),(467,'Receipt','receiptEmail','*','ALLOW','ROLE','salesAssistant'),(468,'Client','setRating','WRITE','ALLOW','ROLE','financial'),(470,'Client','addressesPropagateRe','*','ALLOW','ROLE','employee'),(471,'Client','canBeInvoiced','*','ALLOW','ROLE','employee'),(472,'Client','canCreateTicket','*','ALLOW','ROLE','employee'),(473,'Client','consumption','*','ALLOW','ROLE','employee'),(474,'Client','createAddress','*','ALLOW','ROLE','employee'),(475,'Client','createWithUser','*','ALLOW','ROLE','employee'),(476,'Client','extendedListFilter','*','ALLOW','ROLE','employee'),(477,'Client','getAverageInvoiced','*','ALLOW','ROLE','employee'),(478,'Client','getCard','*','ALLOW','ROLE','employee'),(479,'Client','getDebt','*','ALLOW','ROLE','employee'),(480,'Client','getMana','*','ALLOW','ROLE','employee'),(481,'Client','transactions','*','ALLOW','ROLE','employee'),(482,'Client','hasCustomerRole','*','ALLOW','ROLE','employee'),(483,'Client','isValidClient','*','ALLOW','ROLE','employee'),(484,'Client','lastActiveTickets','*','ALLOW','ROLE','employee'),(485,'Client','sendSms','*','ALLOW','ROLE','employee'),(486,'Client','setPassword','*','ALLOW','ROLE','employee'),(487,'Client','summary','*','ALLOW','ROLE','employee'),(488,'Client','updateAddress','*','ALLOW','ROLE','employee'),(489,'Client','updateFiscalData','*','ALLOW','ROLE','employee'),(491,'Client','uploadFile','*','ALLOW','ROLE','employee'),(492,'Client','campaignMetricsPdf','*','ALLOW','ROLE','employee'),(493,'Client','campaignMetricsEmail','*','ALLOW','ROLE','employee'),(494,'Client','clientWelcomeHtml','*','ALLOW','ROLE','employee'),(495,'Client','clientWelcomeEmail','*','ALLOW','ROLE','employee'),(496,'Client','printerSetupHtml','*','ALLOW','ROLE','employee'),(497,'Client','printerSetupEmail','*','ALLOW','ROLE','employee'),(498,'Client','sepaCoreEmail','*','ALLOW','ROLE','employee'),(499,'Client','letterDebtorPdf','*','ALLOW','ROLE','employee'),(500,'Client','letterDebtorStHtml','*','ALLOW','ROLE','employee'),(501,'Client','letterDebtorStEmail','*','ALLOW','ROLE','employee'),(502,'Client','letterDebtorNdHtml','*','ALLOW','ROLE','employee'),(503,'Client','letterDebtorNdEmail','*','ALLOW','ROLE','employee'),(504,'Client','clientDebtStatementPdf','*','ALLOW','ROLE','employee'),(505,'Client','clientDebtStatementHtml','*','ALLOW','ROLE','employee'),(506,'Client','clientDebtStatementEmail','*','ALLOW','ROLE','employee'),(507,'Client','creditRequestPdf','*','ALLOW','ROLE','employee'),(508,'Client','creditRequestHtml','*','ALLOW','ROLE','employee'),(509,'Client','creditRequestEmail','*','ALLOW','ROLE','employee'),(510,'Client','incotermsAuthorizationPdf','*','ALLOW','ROLE','employee'),(511,'Client','incotermsAuthorizationHtml','*','ALLOW','ROLE','employee'),(512,'Client','incotermsAuthorizationEmail','*','ALLOW','ROLE','employee'),(513,'Client','consumptionSendQueued','*','ALLOW','ROLE','employee'),(514,'Client','filter','*','ALLOW','ROLE','employee'),(515,'Client','getClientOrSupplierReference','*','ALLOW','ROLE','employee'),(516,'Client','upsert','*','ALLOW','ROLE','employee'),(518,'Client','replaceById','*','ALLOW','ROLE','employee'),(519,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(520,'Client','updateAttributes','*','ALLOW','ROLE','employee'),(521,'Client','deleteById','*','ALLOW','ROLE','employee'),(522,'Client','replaceOrCreate','*','ALLOW','ROLE','employee'),(523,'Client','updateAll','*','ALLOW','ROLE','employee'),(524,'Client','upsertWithWhere','*','ALLOW','ROLE','employee'),(525,'Defaulter','observationEmail','WRITE','ALLOW','ROLE','employee'),(527,'VnUser','acl','READ','ALLOW','ROLE','account'),(528,'VnUser','getCurrentUserData','READ','ALLOW','ROLE','account'),(530,'Account','exists','READ','ALLOW','ROLE','account'),(531,'Account','exists','READ','ALLOW','ROLE','account'),(532,'UserLog','*','READ','ALLOW','ROLE','employee'),(533,'RoleLog','*','READ','ALLOW','ROLE','employee'),(534,'WagonType','*','*','ALLOW','ROLE','productionAssi'),(535,'WagonTypeColor','*','*','ALLOW','ROLE','productionAssi'),(536,'WagonTypeTray','*','*','ALLOW','ROLE','productionAssi'),(537,'WagonConfig','*','*','ALLOW','ROLE','productionAssi'),(538,'CollectionWagon','*','*','ALLOW','ROLE','productionAssi'),(539,'CollectionWagonTicket','*','*','ALLOW','ROLE','productionAssi'),(540,'Wagon','*','*','ALLOW','ROLE','productionAssi'),(541,'WagonType','createWagonType','*','ALLOW','ROLE','productionAssi'),(542,'WagonType','deleteWagonType','*','ALLOW','ROLE','productionAssi'),(543,'WagonType','editWagonType','*','ALLOW','ROLE','productionAssi'),(544,'Docuware','deliveryNoteEmail','WRITE','ALLOW','ROLE','employee'),(545,'Agency','find','READ','ALLOW','ROLE','employee'),(546,'Agency','seeExpired','READ','ALLOW','ROLE','coolerAssist'),(547,'WorkerLog','models','READ','ALLOW','ROLE','hr'),(548,'Ticket','editDiscount','WRITE','ALLOW','ROLE','claimManager'),(549,'Ticket','editDiscount','WRITE','ALLOW','ROLE','salesPerson'),(550,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','salesAssistant'),(551,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','deliveryAssistant'),(552,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','buyer'),(553,'Ticket','isRoleAdvanced','*','ALLOW','ROLE','claimManager'),(554,'Ticket','deleteTicketWithPartPrepared','WRITE','ALLOW','ROLE','salesAssistant'),(555,'Ticket','editZone','WRITE','ALLOW','ROLE','deliveryAssistant'),(556,'State','editableStates','READ','ALLOW','ROLE','employee'),(557,'State','seeEditableStates','READ','ALLOW','ROLE','administrative'),(558,'State','seeEditableStates','READ','ALLOW','ROLE','production'),(559,'State','isSomeEditable','READ','ALLOW','ROLE','salesPerson'),(560,'State','isAllEditable','READ','ALLOW','ROLE','production'),(561,'State','isAllEditable','READ','ALLOW','ROLE','administrative'),(562,'Agency','seeExpired','READ','ALLOW','ROLE','administrative'),(563,'Agency','seeExpired','READ','ALLOW','ROLE','productionBoss'),(564,'Claim','createAfterDeadline','WRITE','ALLOW','ROLE','claimManager'),(565,'Client','editAddressLogifloraAllowed','WRITE','ALLOW','ROLE','salesAssistant'),(566,'Client','editFiscalDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(567,'Client','editVerifiedDataWithoutTaxDataCheck','WRITE','ALLOW','ROLE','salesAssistant'),(568,'Client','editCredit','WRITE','ALLOW','ROLE','financialBoss'),(569,'Client','zeroCreditEditor','WRITE','ALLOW','ROLE','financialBoss'),(570,'InvoiceOut','canCreatePdf','WRITE','ALLOW','ROLE','invoicing'),(571,'Supplier','editPayMethodCheck','WRITE','ALLOW','ROLE','financial'),(572,'Worker','isTeamBoss','WRITE','ALLOW','ROLE','teamBoss'),(573,'Worker','forceIsSubordinate','READ','ALLOW','ROLE','hr'),(574,'Claim','editState','WRITE','ALLOW','ROLE','claimManager'),(577,'Claim','findOne','READ','ALLOW','ROLE','salesPerson'),(579,'Claim','updateClaim','WRITE','ALLOW','ROLE','salesPerson'),(580,'Claim','regularizeClaim','WRITE','ALLOW','ROLE','claimManager'),(581,'Claim','updateClaimDestination','WRITE','ALLOW','ROLE','claimManager'),(582,'Claim','downloadFile','READ','ALLOW','ROLE','claimManager'),(583,'Claim','deleteById','WRITE','ALLOW','ROLE','claimManager'),(585,'Claim','logs','READ','ALLOW','ROLE','claimManager'),(586,'Ticket','find','READ','ALLOW','ROLE','employee'),(587,'Ticket','findById','READ','ALLOW','ROLE','employee'),(588,'Ticket','findOne','READ','ALLOW','ROLE','employee'),(589,'Ticket','getVolume','READ','ALLOW','ROLE','employee'),(590,'Ticket','getTotalVolume','READ','ALLOW','ROLE','employee'),(591,'Ticket','summary','READ','ALLOW','ROLE','employee'),(592,'Ticket','priceDifference','READ','ALLOW','ROLE','employee'),(593,'Ticket','componentUpdate','WRITE','ALLOW','ROLE','employee'),(594,'Ticket','new','WRITE','ALLOW','ROLE','employee'),(595,'Ticket','isEditable','READ','ALLOW','ROLE','employee'),(596,'Ticket','setDeleted','WRITE','ALLOW','ROLE','salesPerson'),(597,'Ticket','restore','WRITE','ALLOW','ROLE','employee'),(598,'Ticket','getSales','READ','ALLOW','ROLE','employee'),(599,'Ticket','getSalesPersonMana','READ','ALLOW','ROLE','employee'),(600,'Ticket','filter','READ','ALLOW','ROLE','employee'),(601,'Ticket','makeInvoice','WRITE','ALLOW','ROLE','employee'),(602,'Ticket','updateEditableTicket','WRITE','ALLOW','ROLE','employee'),(603,'Ticket','updateDiscount','WRITE','ALLOW','ROLE','employee'),(604,'Ticket','transferSales','WRITE','ALLOW','ROLE','employee'),(605,'Ticket','sendSms','WRITE','ALLOW','ROLE','employee'),(606,'Ticket','isLocked','READ','ALLOW','ROLE','employee'),(607,'Ticket','freightCost','READ','ALLOW','ROLE','employee'),(608,'Ticket','getComponentsSum','READ','ALLOW','ROLE','employee'),(609,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','delivery'),(610,'Ticket','deliveryNoteCsv','READ','ALLOW','ROLE','employee'),(611,'State','find','READ','ALLOW','ROLE','employee'),(612,'State','findById','READ','ALLOW','ROLE','employee'),(613,'State','findOne','READ','ALLOW','ROLE','employee'),(614,'Worker','find','READ','ALLOW','ROLE','employee'),(615,'Worker','findById','READ','ALLOW','ROLE','employee'),(616,'Worker','findOne','READ','ALLOW','ROLE','employee'),(617,'Worker','filter','READ','ALLOW','ROLE','employee'),(618,'Worker','getWorkedHours','READ','ALLOW','ROLE','employee'),(619,'Worker','active','READ','ALLOW','ROLE','employee'),(620,'Worker','activeWithRole','READ','ALLOW','ROLE','employee'),(621,'Worker','uploadFile','WRITE','ALLOW','ROLE','hr'),(622,'Worker','contracts','READ','ALLOW','ROLE','employee'),(623,'Worker','holidays','READ','ALLOW','ROLE','employee'),(624,'Worker','activeContract','READ','ALLOW','ROLE','employee'),(625,'Worker','activeWithInheritedRole','READ','ALLOW','ROLE','employee'),(626,'Ticket','collectionLabel','READ','ALLOW','ROLE','employee'),(628,'Ticket','expeditionPalletLabel','READ','ALLOW','ROLE','employee'),(629,'Ticket','editDiscount','WRITE','ALLOW','ROLE','artificialBoss'),(630,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesTeamBoss'),(635,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','administrative'),(636,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','salesPerson'),(637,'Claim','downloadFile','READ','ALLOW','ROLE','salesPerson'),(638,'Agency','seeExpired','READ','ALLOW','ROLE','artificialBoss'),(639,'Agency','seeExpired','READ','ALLOW','ROLE','logisticAssistant'),(654,'Ticket','editZone','WRITE','ALLOW','ROLE','logisticAssistant'),(655,'Entry','addFromPackaging','WRITE','ALLOW','ROLE','production'),(656,'Entry','addFromBuy','WRITE','ALLOW','ROLE','production'),(657,'Supplier','getItemsPackaging','READ','ALLOW','ROLE','production'),(658,'Ticket','closeAll','WRITE','ALLOW','ROLE','system'),(659,'Account','*','*','ALLOW','ROLE','developerBoss'),(664,'MailForward','*','*','ALLOW','ROLE','itManagement'),(665,'Role','*','READ','ALLOW','ROLE','employee'),(666,'Role','*','WRITE','ALLOW','ROLE','it'),(667,'VnUser','*','*','ALLOW','ROLE','itManagement'),(668,'VnUser','__get__preview','READ','ALLOW','ROLE','employee'),(669,'VnUser','preview','*','ALLOW','ROLE','employee'),(670,'VnUser','create','*','ALLOW','ROLE','itManagement'),(671,'VnUser','renewToken','WRITE','ALLOW','ROLE','employee'),(672,'PackingSiteAdvanced','*','*','ALLOW','ROLE','production'),(673,'InvoiceOut','makePdfAndNotify','WRITE','ALLOW','ROLE','invoicing'),(674,'InvoiceOutConfig','*','READ','ALLOW','ROLE','invoicing'),(676,'Ticket','invoiceTickets','WRITE','ALLOW','ROLE','employee'),(680,'MailAliasAccount','*','READ','ALLOW','ROLE','employee'),(681,'MailAliasAccount','create','WRITE','ALLOW','ROLE','employee'),(682,'MailAliasAccount','deleteById','WRITE','ALLOW','ROLE','employee'),(683,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','itManagement'),(684,'WorkerDisableExcluded','*','READ','ALLOW','ROLE','itManagement'),(685,'WorkerDisableExcluded','*','WRITE','ALLOW','ROLE','itManagement'),(686,'MailForward','*','*','ALLOW','ROLE','hr'),(687,'ClientSms','find','READ','ALLOW','ROLE','employee'),(688,'ClientSms','create','WRITE','ALLOW','ROLE','employee'),(689,'Vehicle','sorted','WRITE','ALLOW','ROLE','employee'),(690,'Roadmap','*','*','ALLOW','ROLE','palletizerBoss'),(691,'Roadmap','*','*','ALLOW','ROLE','productionBoss'),(692,'ExpeditionTruck','*','*','ALLOW','ROLE','palletizerBoss'),(693,'ExpeditionTruck','*','*','ALLOW','ROLE','productionBoss'),(694,'MailAliasAccount','canEditAlias','WRITE','ALLOW','ROLE','marketingBoss'),(695,'ViaexpressConfig','internationalExpedition','WRITE','ALLOW','ROLE','employee'),(696,'ViaexpressConfig','renderer','READ','ALLOW','ROLE','employee'),(697,'Ticket','transferClient','WRITE','ALLOW','ROLE','administrative'),(698,'Ticket','canEditWeekly','WRITE','ALLOW','ROLE','buyer'),(699,'TicketSms','find','READ','ALLOW','ROLE','salesPerson'),(701,'Docuware','upload','WRITE','ALLOW','ROLE','deliveryAssistant'),(702,'Ticket','docuwareDownload','READ','ALLOW','ROLE','salesPerson'),(703,'Worker','search','READ','ALLOW','ROLE','employee'),(704,'ExpeditionState','addExpeditionState','WRITE','ALLOW','ROLE','delivery'),(705,'SaleGroupDetail','deleteById','WRITE','ALLOW','ROLE','employee'),(706,'Ticket','setDeleted','WRITE','ALLOW','ROLE','buyer'),(707,'DeviceLog','create','WRITE','ALLOW','ROLE','employee'),(708,'Collection','getTickets','WRITE','ALLOW','ROLE','employee'),(709,'Client','findOne','READ','ALLOW','ROLE','employee'),(710,'Client','findById','READ','ALLOW','ROLE','employee'),(711,'Client','find','READ','ALLOW','ROLE','employee'),(712,'Client','exists','READ','ALLOW','ROLE','employee'),(713,'Client','__get__addresses','READ','ALLOW','ROLE','employee'),(714,'ExpeditionMistakeType','*','READ','ALLOW','ROLE','employee'),(715,'WorkerMistakeType','*','READ','ALLOW','ROLE','employee'),(716,'ExpeditionMistake','*','WRITE','ALLOW','ROLE','employee'),(717,'WorkerMistake','*','WRITE','ALLOW','ROLE','coolerBoss'),(718,'MistakesTypes','*','WRITE','ALLOW','ROLE','coolerBoss'),(719,'MistakeType','*','READ','ALLOW','ROLE','employee'),(720,'MachineWorker','*','READ','ALLOW','ROLE','coolerAssist'),(721,'Printer','*','READ','ALLOW','ROLE','employee'),(722,'SaleMistake','*','WRITE','ALLOW','ROLE','production'),(723,'Item','setVisibleDiscard','WRITE','ALLOW','ROLE','employee'),(724,'Address','getAddress','READ','ALLOW','ROLE','employee'),(725,'Account','findOne','READ','ALLOW','ROLE','employee'),(726,'Account','findById','READ','ALLOW','ROLE','employee'),(727,'Account','find','READ','ALLOW','ROLE','employee'),(728,'Account','exists','READ','ALLOW','ROLE','employee'),(729,'Sale','refund','WRITE','ALLOW','ROLE','buyer'),(730,'Ticket','setDeleted','WRITE','ALLOW','ROLE','deliveryAssistant'),(732,'Sale','isInPreparing','*','ALLOW','ROLE','production'),(733,'Train','*','READ','ALLOW','ROLE','production'),(734,'WorkerDepartment','*','*','ALLOW','ROLE','employee'),(735,'VnUser','higherPrivileges','*','ALLOW','ROLE','itManagement'),(736,'VnUser','mediumPrivileges','*','ALLOW','ROLE','hr'),(737,'VnUser','updateUser','*','ALLOW','ROLE','employee'),(738,'TicketCollection','*','WRITE','ALLOW','ROLE','production'),(739,'Worker','setPassword','*','ALLOW','ROLE','employee'),(740,'Url','getByUser','READ','ALLOW','ROLE','$everyone'),(741,'Claim','__get__lines','READ','ALLOW','ROLE','claimViewer'),(742,'AddressShortage','*','READ','ALLOW','ROLE','production'),(743,'Claim','filter','READ','ALLOW','ROLE','claimViewer'),(744,'Claim','find','READ','ALLOW','ROLE','claimViewer'),(745,'Claim','findById','READ','ALLOW','ROLE','claimViewer'),(746,'Claim','getSummary','READ','ALLOW','ROLE','claimViewer'),(747,'CplusRectificationType','*','READ','ALLOW','ROLE','administrative'),(748,'SiiTypeInvoiceOut','*','READ','ALLOW','ROLE','administrative'),(749,'InvoiceCorrectionType','*','READ','ALLOW','ROLE','administrative'),(750,'InvoiceOut','transferInvoice','WRITE','ALLOW','ROLE','administrative'); /*!40000 ALTER TABLE `ACL` ENABLE KEYS */; UNLOCK TABLES; @@ -206,7 +206,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2023-08-30 15:53:15 +-- Dump completed on 2023-11-20 12:26:42 USE `vn`; -- MariaDB dump 10.19 Distrib 10.5.19-MariaDB, for debian-linux-gnu (x86_64) -- @@ -265,13 +265,13 @@ INSERT INTO `businessType` VALUES ('decoration','Decoración'),('events','Evento UNLOCK TABLES; -- --- Dumping data for table `cplusInvoiceType472` +-- Dumping data for table `siiTypeInvoiceIn` -- -LOCK TABLES `cplusInvoiceType472` WRITE; -/*!40000 ALTER TABLE `cplusInvoiceType472` DISABLE KEYS */; -INSERT INTO `cplusInvoiceType472` VALUES (1,'F1 - Factura'),(2,'F2 - Factura simplificada (ticket)'),(3,'F3 - Factura emitida en sustitución de facturas simplificadas facturadas y declaradas'),(4,'F4 - Asiento resumen de facturas'),(5,'F5 - Importaciones (DUA)'),(6,'F6 - Otros justificantes contables'),(7,'R1 - Factura rectificativa (Art. 80.1, 80.2 y error fundado en derecho)'),(8,'R2 - Factura rectificativa (Art. 80.3)'),(9,'R3 - Factura rectificativa (Art. 80.4)'),(10,'R4 - Factura rectificativa (Resto)'),(11,'R5 - Factura rectificativa en facturas simplificadas'); -/*!40000 ALTER TABLE `cplusInvoiceType472` ENABLE KEYS */; +LOCK TABLES `siiTypeInvoiceIn` WRITE; +/*!40000 ALTER TABLE `siiTypeInvoiceIn` DISABLE KEYS */; +INSERT INTO `siiTypeInvoiceIn` VALUES (1,'F1','Factura'),(2,'F2','Factura simplificada (ticket)'),(3,'F3','Factura emitida en sustitución de facturas simplificadas facturadas y declaradas'),(4,'F4','Asiento resumen de facturas'),(5,'F5','Importaciones (DUA)'),(6,'F6','Otros justificantes contables'),(7,'R1','Factura rectificativa (Art. 80.1, 80.2 y error fundado en derecho)'),(8,'R2','Factura rectificativa (Art. 80.3)'),(9,'R3','Factura rectificativa (Art. 80.4)'),(10,'R4','Factura rectificativa (Resto)'),(11,'R5','Factura rectificativa en facturas simplificadas'); +/*!40000 ALTER TABLE `siiTypeInvoiceIn` ENABLE KEYS */; UNLOCK TABLES; -- @@ -280,7 +280,7 @@ UNLOCK TABLES; LOCK TABLES `siiTypeInvoiceOut` WRITE; /*!40000 ALTER TABLE `siiTypeInvoiceOut` DISABLE KEYS */; -INSERT INTO `siiTypeInvoiceOut` VALUES (1,'F1 - Factura'),(2,'F2 - Factura simplificada (ticket)'),(3,'F3 - Factura emitida en sustitución de facturas simplificadas facturadas y declaradas'),(4,'F4 - Asiento resumen de facturas'),(5,'R1 - Factura rectificativa (Art. 80.1, 80.2 y error fundado en derecho)'),(6,'R2 - Factura rectificativa (Art. 80.3)'),(7,'R3 - Factura rectificativa (Art. 80.4)'),(8,'R4 - Factura rectificativa (Resto)'),(9,'R5 - Factura rectificativa en facturas simplificadas'); +INSERT INTO `siiTypeInvoiceOut` VALUES (1,'F1','Factura'),(2,'F2','Factura simplificada (ticket)'),(3,'F3','Factura emitida en sustitución de facturas simplificadas facturadas y declaradas'),(4,'F4','Asiento resumen de facturas'),(5,'R1','Factura rectificativa (Art. 80.1, 80.2 y error fundado en derecho)'),(6,'R2','Factura rectificativa (Art. 80.3)'),(7,'R3','Factura rectificativa (Art. 80.4)'),(8,'R4','Factura rectificativa (Resto)'),(9,'R5','Factura rectificativa en facturas simplificadas'); /*!40000 ALTER TABLE `siiTypeInvoiceOut` ENABLE KEYS */; UNLOCK TABLES; @@ -315,13 +315,13 @@ INSERT INTO `cplusTaxBreak` VALUES (1,'Campo vacio'),(2,'E1 - Exenta por el art UNLOCK TABLES; -- --- Dumping data for table `cplusTrascendency472` +-- Dumping data for table `siiTrascendencyInvoiceIn` -- -LOCK TABLES `cplusTrascendency472` WRITE; -/*!40000 ALTER TABLE `cplusTrascendency472` DISABLE KEYS */; -INSERT INTO `cplusTrascendency472` VALUES (1,'01 - Operación de régimen general'),(2,'02 - Operaciones por las que los empresarios satisfacen compensaciones REAGYP'),(3,'03 - Operaciones a las que se aplique el régimen especial de bienes usados, objetos de arte, antigüedades y objetos de colección (135 - 139 de LIVA)'),(4,'04 - Régimen especial oro de inversión'),(5,'05 - Régimen especial agencias de viajes'),(6,'06 - Régimen especial grupo de entidades en IVA (Nivel Avanzado)'),(7,'07 - Régimen especial criterio de caja'),(8,'08 - Operaciones sujetas al IPSI / IGIC'),(9,'09 - Adquisiciones intracomunitarias de bienes y prestaciones de servicios'),(10,'12 - Operaciones de arrendamiento de local de negocio'),(11,'13 - Factura correspondiente a una importación (informada sin asociar a un DUA)'),(12,'14 - Primer semestre 2017'); -/*!40000 ALTER TABLE `cplusTrascendency472` ENABLE KEYS */; +LOCK TABLES `siiTrascendencyInvoiceIn` WRITE; +/*!40000 ALTER TABLE `siiTrascendencyInvoiceIn` DISABLE KEYS */; +INSERT INTO `siiTrascendencyInvoiceIn` VALUES (1,'Operación de régimen general'),(2,'Operaciones por las que los empresarios satisfacen compensaciones REAGYP'),(3,'Operaciones a las que se aplique el régimen especial de bienes usados, objetos de arte, antigüedades y objetos de colección (135 - 139 de LIVA)'),(4,'Régimen especial oro de inversión'),(5,'Régimen especial agencias de viajes'),(6,'Régimen especial grupo de entidades en IVA (Nivel Avanzado)'),(7,'Régimen especial criterio de caja'),(8,'Operaciones sujetas al IPSI / IGIC'),(9,'Adquisiciones intracomunitarias de bienes y prestaciones de servicios'),(12,'Operaciones de arrendamiento de local de negocio'),(13,'Factura correspondiente a una importación (informada sin asociar a un DUA)'),(14,'Primer semestre 2017'); +/*!40000 ALTER TABLE `siiTrascendencyInvoiceIn` ENABLE KEYS */; UNLOCK TABLES; -- @@ -330,7 +330,7 @@ UNLOCK TABLES; LOCK TABLES `claimResponsible` WRITE; /*!40000 ALTER TABLE `claimResponsible` DISABLE KEYS */; -INSERT INTO `claimResponsible` VALUES (1,'Compradores',0),(2,'Proveedor',0),(3,'Entradores',0),(4,'Camareros',0),(6,'Sacadores',0),(7,'Revisadores',0),(8,'Calidad general',0),(9,'Encajadores',0),(10,'Clima',0),(11,'Comerciales',1),(12,'Clientes',1),(13,'Administración',0),(14,'Agencia',0),(15,'Repartidores',0),(16,'Informatica',0),(17,'Transp.origen',0),(18,'Confeccion',0),(19,'OTROS',0),(21,'Gerencia',0),(22,'Paletizadores',0),(23,'Preparación Previa',0),(24,'Almacén PCA',0),(25,'Huelga',0); +INSERT INTO `claimResponsible` VALUES (1,'Compradores',0,'buy'),(2,'Proveedor',0,'sup'),(3,'Entradores',0,'ent'),(4,'Camareros',0,'bar'),(6,'Sacadores',0,'pic'),(7,'Revisadores',0,'chk'),(8,'Calidad general',0,'qas'),(9,'Encajadores',0,'pck'),(10,'Clima',0,'wea'),(11,'Comerciales',1,'com'),(12,'Clientes',1,'cli'),(13,'Administración',0,'adm'),(14,'Agencia',0,'age'),(15,'Repartidores',0,'del'),(16,'Informatica',0,'ite'),(17,'Transp.origen',0,'tra'),(18,'Confeccion',0,'con'),(19,'OTROS',0,'oth'),(21,'Gerencia',0,'man'),(22,'Paletizadores',0,'pal'),(23,'Preparación Previa',0,'pre'),(24,'Almacén PCA',0,'war'),(25,'Huelga',0,'str'); /*!40000 ALTER TABLE `claimResponsible` ENABLE KEYS */; UNLOCK TABLES; @@ -400,7 +400,7 @@ UNLOCK TABLES; LOCK TABLES `department` WRITE; /*!40000 ALTER TABLE `department` DISABLE KEYS */; -INSERT INTO `department` VALUES (1,NULL,'VERDNATURA',1,104,763,0,0,0,0,30,NULL,'/',NULL,0,NULL,0,0,0,0,NULL,NULL),(22,'shopping','COMPRAS',2,3,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(23,'CMA','CAMARA',13,14,NULL,72,1,1,2,0,37,'/1/37/',NULL,0,NULL,0,1,1,1,NULL,NULL),(31,'it','INFORMATICA',4,5,NULL,72,0,0,1,0,1,'/1/','informatica-cau',1,NULL,1,0,0,0,NULL,NULL),(34,NULL,'CONTABILIDAD',6,7,NULL,0,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(35,NULL,'FINANZAS',8,9,NULL,0,0,0,1,0,1,'/1/',NULL,1,'begonya@verdnatura.es',1,0,0,0,NULL,NULL),(36,NULL,'LABORAL',10,11,NULL,0,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(37,'PROD','PRODUCCION',12,27,NULL,72,1,1,1,7,1,'/1/',NULL,0,NULL,0,1,1,1,NULL,NULL),(38,NULL,'SACADO',15,16,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,0,NULL,NULL),(39,NULL,'ENCAJADO',17,18,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,0,NULL,NULL),(41,NULL,'ADMINISTRACION',28,29,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(43,'VT','VENTAS',30,53,NULL,0,0,0,1,11,1,'/1/',NULL,1,'',1,0,0,0,NULL,NULL),(44,'management','GERENCIA',54,55,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(45,NULL,'LOGISTICA',56,57,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(46,'delivery','REPARTO',58,59,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,1,0,0,NULL,NULL),(48,NULL,'ALMACENAJE',60,61,NULL,0,1,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(49,NULL,'PROPIEDAD',62,63,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(52,NULL,'CARGA AEREA',64,65,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(53,NULL,'MARKETING Y COMUNICACIÓN',66,67,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(54,NULL,'ORNAMENTALES',68,69,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(55,NULL,'TALLER NATURAL',70,73,14548,72,0,0,1,1,1,'/1/',NULL,0,NULL,0,1,1,0,1118,NULL),(56,NULL,'TALLER ARTIFICIAL',71,72,8470,72,0,0,2,0,55,'/1/55/',NULL,0,NULL,0,1,1,0,1927,NULL),(58,'CMP','CAMPOS',74,77,NULL,72,0,0,1,1,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(59,NULL,'MANTENIMIENTO',78,79,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,1,0,0,NULL,NULL),(60,NULL,'RECLAMACIONES',80,81,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,1,0,0,NULL,NULL),(61,NULL,'VNH',82,85,NULL,73,0,0,1,1,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(66,NULL,'VERDNAMADRID',86,87,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(68,NULL,'COMPLEMENTOS',19,20,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,1,0,0,NULL,NULL),(69,NULL,'VERDNABARNA',88,89,NULL,74,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(80,NULL,'EQUIPO J VALLES',31,32,4250,72,0,0,2,0,43,'/1/43/','jvp_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(86,NULL,'LIMPIEZA',90,91,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(89,NULL,'COORDINACION',92,93,NULL,0,1,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(90,NULL,'TRAILER',83,84,NULL,0,0,0,2,0,61,'/1/61/',NULL,0,NULL,0,0,0,0,NULL,NULL),(91,NULL,'ARTIFICIAL',21,22,NULL,0,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,0,NULL,NULL),(92,NULL,'EQUIPO SILVERIO',33,34,1203,0,0,0,2,0,43,'/1/43/','sdc_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(93,NULL,'CONFECCION',94,95,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,1,0,NULL,NULL),(94,NULL,'EQUIPO J BROCAL',35,36,3797,0,0,0,2,0,43,'/1/43/','jes_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(95,NULL,'EQUIPO C ZAMBRANO',37,38,4667,0,0,0,2,0,43,'/1/43/','czg_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(96,NULL,'EQUIPO C LOPEZ',39,40,4661,0,0,0,2,0,43,'/1/43/','cla_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(115,NULL,'EQUIPO CLAUDI',41,42,3810,0,0,0,2,0,43,'/1/43/','csr_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(123,NULL,'EQUIPO ELENA BASCUÑANA',43,44,7102,0,0,0,2,0,43,'/1/43/','ebt_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(124,NULL,'CONTROL INTERNO',96,97,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,1,0,0,0,NULL,NULL),(125,NULL,'EQUIPO MIRIAM MAR',45,46,1118,0,0,0,2,0,43,'/1/43/','mir_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(126,NULL,'PRESERVADO',98,99,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,1,1,0,NULL,NULL),(128,NULL,'PALETIZADO',23,24,NULL,0,0,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,0,NULL,NULL),(130,NULL,'REVISION',25,26,NULL,0,0,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,0,NULL,NULL),(131,NULL,'INVERNADERO',75,76,NULL,0,0,0,2,0,58,'/1/58/',NULL,0,NULL,0,1,0,0,NULL,NULL),(132,NULL,'EQUIPO DC',47,48,1731,0,0,0,2,0,43,'/1/43/','dc_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(133,'franceTeam','EQUIPO FRANCIA',49,50,1731,72,0,0,2,0,43,'/1/43/','fra_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(134,NULL,'EQUIPO RODRI',51,52,6264,0,0,0,2,0,43,'/1/43/','rhr_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(135,'routers','ENRUTADORES',100,101,NULL,0,0,0,1,0,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL),(136,'heavyVehicles','VEHICULOS PESADOS',102,103,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL); +INSERT INTO `department` VALUES (1,'VN','VERDNATURA',1,106,763,0,0,0,0,31,NULL,'/',NULL,0,NULL,0,0,0,0,NULL,NULL),(22,'shopping','COMPRAS',2,3,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(23,'CMA','CAMARA',13,14,NULL,72,1,1,2,0,37,'/1/37/',NULL,0,NULL,0,1,1,1,NULL,NULL),(31,'it','INFORMATICA',4,5,NULL,72,0,0,1,0,1,'/1/','informatica-cau',1,NULL,1,0,0,0,NULL,NULL),(34,NULL,'CONTABILIDAD',6,7,NULL,0,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(35,NULL,'FINANZAS',8,9,NULL,0,0,0,1,0,1,'/1/',NULL,1,'begonya@verdnatura.es',1,0,0,0,NULL,NULL),(36,NULL,'LABORAL',10,11,NULL,0,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(37,'PROD','PRODUCCION',12,27,NULL,72,1,1,1,7,1,'/1/',NULL,0,NULL,0,1,1,1,NULL,NULL),(38,NULL,'SACADO',15,16,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,0,NULL,NULL),(39,NULL,'ENCAJADO',17,18,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,0,NULL,NULL),(41,NULL,'ADMINISTRACION',28,29,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(43,'VT','VENTAS',30,53,NULL,0,0,0,1,11,1,'/1/',NULL,1,'',1,0,0,0,NULL,NULL),(44,'management','GERENCIA',54,55,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(45,'logistic','LOGISTICA',56,57,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(46,'delivery','REPARTO',58,59,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,1,0,0,NULL,NULL),(48,NULL,'ALMACENAJE',60,61,NULL,0,1,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(49,NULL,'PROPIEDAD',62,63,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(52,NULL,'CARGA AEREA',64,65,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(53,NULL,'MARKETING Y COMUNICACIÓN',66,67,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL),(54,NULL,'ORNAMENTALES',68,69,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(55,NULL,'TALLER NATURAL',70,73,14548,72,0,0,1,1,1,'/1/',NULL,0,NULL,0,1,1,0,1118,NULL),(56,NULL,'TALLER ARTIFICIAL',71,72,8470,72,0,0,2,0,55,'/1/55/',NULL,0,NULL,0,1,1,0,1927,NULL),(58,'CMP','CAMPOS',74,77,NULL,72,0,0,1,1,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(59,NULL,'MANTENIMIENTO',78,79,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,1,0,0,NULL,NULL),(60,NULL,'RECLAMACIONES',80,81,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,1,0,0,NULL,NULL),(61,NULL,'VNH',82,85,NULL,73,0,0,1,1,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(66,NULL,'VERDNAMADRID',86,87,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(68,NULL,'COMPLEMENTOS',19,20,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,1,0,0,NULL,NULL),(69,NULL,'VERDNABARNA',88,89,NULL,74,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(80,NULL,'EQUIPO J VALLES',31,32,4250,72,0,0,2,0,43,'/1/43/','jvp_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(86,NULL,'LIMPIEZA',90,91,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(89,NULL,'COORDINACION',92,93,NULL,0,1,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(90,NULL,'TRAILER',83,84,NULL,0,0,0,2,0,61,'/1/61/',NULL,0,NULL,0,0,0,0,NULL,NULL),(91,NULL,'ARTIFICIAL',21,22,NULL,0,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,0,NULL,NULL),(92,NULL,'EQUIPO SILVERIO',33,34,1203,0,0,0,2,0,43,'/1/43/','sdc_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(93,NULL,'CONFECCION',94,95,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,1,0,NULL,NULL),(94,NULL,'EQUIPO J BROCAL',35,36,3797,0,0,0,2,0,43,'/1/43/','jes_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(95,NULL,'EQUIPO C ZAMBRANO',37,38,4667,0,0,0,2,0,43,'/1/43/','czg_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(96,NULL,'EQUIPO C LOPEZ',39,40,4661,0,0,0,2,0,43,'/1/43/','cla_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(115,NULL,'EQUIPO CLAUDI',41,42,3810,0,0,0,2,0,43,'/1/43/','csr_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(123,NULL,'EQUIPO ELENA BASCUÑANA',43,44,7102,0,0,0,2,0,43,'/1/43/','ebt_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(124,NULL,'CONTROL INTERNO',96,97,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,1,0,0,0,NULL,NULL),(125,NULL,'EQUIPO MIRIAM MAR',45,46,1118,0,0,0,2,0,43,'/1/43/','mir_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(126,NULL,'PRESERVADO',98,99,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,1,1,0,NULL,NULL),(128,NULL,'PALETIZADO',23,24,NULL,0,0,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,0,NULL,NULL),(130,NULL,'REVISION',25,26,NULL,0,0,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,0,NULL,NULL),(131,NULL,'INVERNADERO',75,76,NULL,0,0,0,2,0,58,'/1/58/',NULL,0,NULL,0,1,0,0,NULL,NULL),(132,NULL,'EQUIPO DC',47,48,1731,0,0,0,2,0,43,'/1/43/','dc_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(133,'franceTeam','EQUIPO FRANCIA',49,50,1731,72,0,0,2,0,43,'/1/43/','fra_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(134,NULL,'EQUIPO RODRI',51,52,6264,0,0,0,2,0,43,'/1/43/','rhr_equipo',1,'gestioncomercial@verdnatura.es',1,0,0,0,NULL,NULL),(135,'routers','ENRUTADORES',100,101,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(136,'heavyVehicles','VEHICULOS PESADOS',102,103,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL),(137,'sorter','SORTER',104,105,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL); /*!40000 ALTER TABLE `department` ENABLE KEYS */; UNLOCK TABLES; @@ -450,7 +450,7 @@ UNLOCK TABLES; LOCK TABLES `state` WRITE; /*!40000 ALTER TABLE `state` DISABLE KEYS */; -INSERT INTO `state` VALUES (1,'Arreglar',2,0,'FIXING',NULL,1,0,0,0,0,0,0,4,1,'alert'),(2,'Libre',2,0,'FREE',NULL,2,0,0,0,0,0,0,4,1,'notice'),(3,'OK',3,0,'OK',3,28,1,0,0,0,1,1,3,0,'success'),(4,'Impreso',4,0,'PRINTED',2,29,1,0,1,0,0,1,2,0,'success'),(5,'Preparación',6,1,'ON_PREPARATION',7,14,0,0,0,2,0,0,2,0,'warning'),(6,'En Revisión',7,1,'ON_CHECKING',NULL,6,0,1,0,3,0,0,1,0,'warning'),(7,'Sin Acabar',1,0,'NOT_READY',NULL,7,0,0,0,0,0,0,4,1,'alert'),(8,'Revisado',8,1,'CHECKED',NULL,8,0,1,0,3,0,0,1,0,'warning'),(9,'Encajando',9,2,'PACKING',NULL,9,0,1,0,0,0,0,1,0,NULL),(10,'Encajado',10,2,'PACKED',NULL,10,0,1,0,0,0,0,0,0,NULL),(11,'Facturado',0,3,'INVOICED',NULL,11,0,1,0,0,0,0,0,0,NULL),(12,'Bloqueado',0,0,'BLOCKED',NULL,12,0,0,0,0,0,0,4,1,'alert'),(13,'En Reparto',11,3,'ON_DELIVERY',NULL,13,0,1,0,0,0,0,0,0,NULL),(14,'Preparado',6,1,'PREPARED',NULL,14,0,1,0,2,0,0,1,0,'warning'),(15,'Pte Recogida',12,3,'WAITING_FOR_PICKUP',NULL,15,0,1,0,0,0,0,0,0,NULL),(16,'Entregado',13,3,'DELIVERED',NULL,16,0,1,0,0,0,0,0,0,NULL),(20,'Asignado',4,0,'PICKER_DESIGNED',NULL,20,1,0,0,0,0,0,2,0,'success'),(21,'Retornado',4,1,'PRINTED_BACK',6,21,0,0,0,0,0,0,2,0,'success'),(22,'Pte. Ampliar',2,0,'EXPANDABLE',NULL,22,0,0,0,0,0,0,4,1,'alert'),(23,'URGENTE',5,1,'LAST_CALL',NULL,23,1,0,1,0,0,0,4,1,'success'),(24,'Encadenado',4,0,'CHAINED',4,24,0,0,0,0,0,0,3,1,'success'),(25,'Embarcando',3,0,'BOARDING',5,25,1,0,0,0,0,0,3,0,'alert'),(26,'Prep Previa',5,1,'PREVIOUS_PREPARATION',1,28,1,0,0,1,0,0,2,0,'warning'),(27,'Prep Asistida',5,1,'ASSISTED_PREPARATION',7,27,0,0,0,0,0,0,2,0,'success'),(28,'Previa OK',3,0,'OK PREVIOUS',3,28,1,0,1,1,1,1,3,0,'warning'),(29,'Previa Impreso',4,0,'PRINTED PREVIOUS',2,29,1,0,1,0,0,1,2,0,'success'),(30,'Embarcado',4,1,'BOARD',5,30,0,0,0,2,0,0,3,0,'success'),(31,'Polizon Impreso',4,1,'PRINTED STOWAWAY',2,29,1,0,1,0,0,1,2,0,'success'),(32,'Polizon OK',3,1,'OK STOWAWAY',3,31,1,0,0,1,1,1,3,0,'warning'),(33,'Auto_Impreso',4,0,'PRINTED_AUTO',2,29,1,0,1,0,0,1,2,0,'success'),(34,'Pte Pago',3,0,'WAITING_FOR_PAYMENT',NULL,34,0,0,0,0,0,0,4,1,'alert'),(35,'Semi-Encajado',9,2,'HALF_PACKED',NULL,10,0,1,0,0,0,0,1,0,NULL),(36,'Previa Revisando',3,0,'PREVIOUS_CONTROL',2,37,1,0,0,4,0,1,2,0,'warning'),(37,'Previa Revisado',3,0,'PREVIOUS_CONTROLLED',2,29,1,0,1,0,0,1,2,0,'warning'),(38,'Prep Cámara',6,1,'COOLER_PREPARATION',7,14,0,0,0,2,0,0,2,0,'warning'),(41,'Prep Parcial',6,1,'PARTIAL_PREPARATION',7,14,0,0,0,2,0,0,2,0,'warning'); +INSERT INTO `state` VALUES (1,'Arreglar',2,0,'FIXING',NULL,1,0,0,0,0,0,0,4,1,'alert'),(2,'Libre',2,0,'FREE',NULL,2,0,0,0,0,0,0,4,1,'notice'),(3,'OK',3,0,'OK',3,28,1,0,0,0,1,1,3,0,'success'),(4,'Impreso',4,0,'PRINTED',2,29,1,0,1,0,0,1,2,0,'success'),(5,'Preparación',6,1,'ON_PREPARATION',7,14,0,0,0,2,0,0,2,0,'warning'),(6,'En Revisión',7,1,'ON_CHECKING',NULL,6,0,1,0,3,0,0,1,0,'warning'),(7,'Sin Acabar',1,0,'NOT_READY',NULL,7,0,0,0,0,0,0,4,1,'alert'),(8,'Revisado',8,1,'CHECKED',NULL,8,0,1,0,3,0,0,1,0,'warning'),(9,'Encajando',9,2,'PACKING',NULL,9,0,1,0,0,0,0,1,0,NULL),(10,'Encajado',10,2,'PACKED',NULL,10,0,1,0,0,0,0,0,0,NULL),(11,'Facturado',0,3,'INVOICED',NULL,11,0,1,0,0,0,0,0,0,NULL),(12,'Bloqueado',0,0,'BLOCKED',NULL,12,0,0,0,0,0,0,4,1,'alert'),(13,'En Reparto',11,3,'ON_DELIVERY',NULL,13,0,1,0,0,0,0,0,0,NULL),(14,'Preparado',6,1,'PREPARED',NULL,14,0,1,0,2,0,0,1,0,'warning'),(15,'Pte Recogida',12,3,'WAITING_FOR_PICKUP',NULL,15,0,1,0,0,0,0,0,0,NULL),(16,'Entregado',13,3,'DELIVERED',NULL,16,0,1,0,0,0,0,0,0,NULL),(20,'Asignado',4,0,'PICKER_DESIGNED',NULL,20,1,0,0,0,0,0,2,0,'success'),(21,'Retornado',4,1,'PRINTED_BACK',6,21,0,0,0,0,0,0,2,0,'success'),(22,'Pte. Ampliar',2,0,'EXPANDABLE',NULL,22,0,0,0,0,0,0,4,1,'alert'),(23,'URGENTE',5,1,'LAST_CALL',NULL,23,1,0,1,0,0,0,4,1,'success'),(24,'Encadenado',4,0,'CHAINED',4,24,0,0,0,0,0,0,3,1,'success'),(25,'Embarcando',3,0,'BOARDING',5,25,1,0,0,0,0,0,3,0,'alert'),(26,'Prep Previa',5,0,'PREVIOUS_PREPARATION',1,28,1,0,0,1,0,0,2,0,'warning'),(27,'Prep Asistida',5,1,'ASSISTED_PREPARATION',7,27,0,0,0,0,0,0,2,0,'success'),(28,'Previa OK',3,0,'OK PREVIOUS',3,28,1,0,1,1,1,1,3,0,'warning'),(29,'Previa Impreso',4,0,'PRINTED PREVIOUS',2,29,1,0,1,0,0,1,2,0,'success'),(30,'Embarcado',4,1,'BOARD',5,30,0,0,0,2,0,0,3,0,'success'),(31,'Polizon Impreso',4,1,'PRINTED STOWAWAY',2,29,1,0,1,0,0,1,2,0,'success'),(32,'Polizon OK',3,1,'OK STOWAWAY',3,31,1,0,0,1,1,1,3,0,'warning'),(33,'Auto_Impreso',4,0,'PRINTED_AUTO',2,29,1,0,1,0,0,1,2,0,'success'),(34,'Pte Pago',3,0,'WAITING_FOR_PAYMENT',NULL,34,0,0,0,0,0,0,4,1,'alert'),(35,'Semi-Encajado',9,2,'HALF_PACKED',NULL,10,0,1,0,0,0,0,1,0,NULL),(36,'Previa Revisando',3,0,'PREVIOUS_CONTROL',2,37,1,0,0,4,0,1,2,0,'warning'),(37,'Previa Revisado',3,0,'PREVIOUS_CONTROLLED',2,29,1,0,1,0,0,1,2,0,'warning'),(38,'Prep Cámara',6,1,'COOLER_PREPARATION',7,14,0,0,0,2,0,0,2,0,'warning'),(41,'Prep Parcial',6,1,'PARTIAL_PREPARATION',7,14,0,0,0,2,0,0,2,0,'warning'); /*!40000 ALTER TABLE `state` ENABLE KEYS */; UNLOCK TABLES; @@ -470,7 +470,7 @@ UNLOCK TABLES; LOCK TABLES `volumeConfig` WRITE; /*!40000 ALTER TABLE `volumeConfig` DISABLE KEYS */; -INSERT INTO `volumeConfig` VALUES (2.67,1.60,0.8,150,0.30,120,57,2.0,0,200,0,167.0); +INSERT INTO `volumeConfig` VALUES (2.67,1.60,0.8,150,0.30,120,57,2.0,50,200,10,167.0); /*!40000 ALTER TABLE `volumeConfig` ENABLE KEYS */; UNLOCK TABLES; @@ -480,7 +480,7 @@ UNLOCK TABLES; LOCK TABLES `workCenter` WRITE; /*!40000 ALTER TABLE `workCenter` DISABLE KEYS */; -INSERT INTO `workCenter` VALUES (1,'Silla',20,859,1,'Av espioca 100',552703,NULL),(2,'Mercaflor',19,NULL,NULL,NULL,NULL,NULL),(3,'Marjales',26,20008,NULL,NULL,NULL,NULL),(4,'VNH',NULL,NULL,NULL,NULL,NULL,NULL),(5,'Madrid',28,2869,5,'Av constitución 3',554145,0.50),(6,'Vilassar',88,88038,NULL,'Cami del Crist, 33',556412,NULL),(7,'Tenerife',NULL,NULL,NULL,NULL,NULL,NULL),(8,'Silla-Agrario',26,NULL,NULL,NULL,NULL,NULL),(9,'Algemesi',20,1354,60,'Fenollars, 2',523549,NULL); +INSERT INTO `workCenter` VALUES (1,'Silla',20,859,1,'Av espioca 100',552703,NULL),(2,'Mercaflor',19,NULL,NULL,NULL,NULL,NULL),(3,'Marjales',26,20008,NULL,NULL,NULL,NULL),(4,'VNH',NULL,NULL,NULL,NULL,NULL,NULL),(5,'Madrid',28,2869,5,'Av constitución 3',554145,0.50),(6,'Vilassar',88,88038,NULL,'Cami del Crist, 33',556412,NULL),(7,'Tenerife',NULL,NULL,NULL,NULL,NULL,NULL),(8,'Silla-Agrario',26,NULL,NULL,NULL,NULL,NULL),(9,'Algemesi',20,1354,60,'Fenollars, 2',523549,NULL),(10,'Rubi',88,NULL,84,'Av. de la Llana, 131',549722,0.50); /*!40000 ALTER TABLE `workCenter` ENABLE KEYS */; UNLOCK TABLES; @@ -493,6 +493,26 @@ LOCK TABLES `companyI18n` WRITE; INSERT INTO `companyI18n` VALUES (442,'en','In compliance with the provisions of Organic Law 15/1999, on the Protection of Personal Data, we inform you that the personal data you provide will be included in automated files of VERDNATURA LEVANTE SL, being able at all times to exercise the rights of access, rectification, cancellation and opposition, communicating it in writing to the registered office of the entity. The purpose of the file is administrative management, accounting, and billing.'),(442,'fr','Conformément aux dispositions de la loi organique 15/1999 sur la protection des données personnelles, nous vous informons que les données personnelles que vous fournissez seront incluses dans des dossiers. VERDNATURA LEVANTE S.L., vous pouvez à tout moment, exercer les droits d``accès, de rectification, d``annulation et d``opposition, en communiquant par écrit au siège social de la société. Le dossier a pour objet la gestion administrative, la comptabilité et la facturation.'),(442,'pt','Em cumprimento do disposto na lei Orgânica 15/1999, de Protecção de Dados de Carácter Pessoal, comunicamos que os dados pessoais que facilite se incluirão nos ficheiros automatizados de VERDNATURA LEVANTE S.L., podendo em todo momento exercer os direitos de acesso, rectificação, cancelação e oposição, comunicando por escrito ao domicílio social da entidade. A finalidade do ficheiro é a gestão administrativa, contabilidade e facturação.'); /*!40000 ALTER TABLE `companyI18n` ENABLE KEYS */; UNLOCK TABLES; + +-- +-- Dumping data for table `workerTimeControlError` +-- + +LOCK TABLES `workerTimeControlError` WRITE; +/*!40000 ALTER TABLE `workerTimeControlError` DISABLE KEYS */; +INSERT INTO `workerTimeControlError` VALUES (1,'IS_NOT_ALLOWED_FUTURE','No se permite fichar a futuro'),(2,'INACTIVE_BUSINESS','No hay un contrato en vigor'),(3,'IS_NOT_ALLOWED_WORK','No está permitido trabajar'),(4,'ODD_WORKERTIMECONTROL','Fichadas impares'),(5,'DAY_MAX_TIME','Superado el tiempo máximo entre entrada y salida'),(6,'BREAK_DAY','Descanso diario'),(7,'BREAK_WEEK','Descanso semanal'),(8,'WRONG_DIRECTION','Dirección incorrecta'),(9,'UNDEFINED_ERROR','Error sin definir'); +/*!40000 ALTER TABLE `workerTimeControlError` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `silexACL` +-- + +LOCK TABLES `silexACL` WRITE; +/*!40000 ALTER TABLE `silexACL` DISABLE KEYS */; +INSERT INTO `silexACL` VALUES (1,'workerTimeControl','clockIn','$everyone'),(2,'workerTimeControl','getClockIn','$everyone'),(3,'workerTimeControl','login','$everyone'),(4,'security','device_checkLogin','employee'),(5,'security','getVersion','employee'),(6,'security','login','employee'),(7,'delivery','addNote','employee'),(8,'delivery','expeditionState_add','employee'),(9,'delivery','expeditionState_addByExpedition','employee'),(10,'delivery','expeditionState_addByExpeditionMulti','employee'),(11,'delivery','expeditionState_addByRoute','employee'),(12,'delivery','expedition_getLog','employee'),(13,'delivery','getExpeditionFromRoute','employee'),(14,'delivery','getInfo','employee'),(15,'delivery','getInfoCompany','employee'),(16,'delivery','getInfoFreelance','employee'),(17,'delivery','getWorkers','employee'),(18,'delivery','get_routes','employee'),(19,'delivery','get_tickets','employee'),(20,'delivery','get_version','employee'),(21,'delivery','saveLoadersWorkers','employee'),(22,'delivery','save_sign','employee'),(23,'delivery','setRouteOk','employee'),(24,'delivery','updateExpeditionChecked','employee'),(25,'delivery','update_routes','employee'),(26,'almacennew','barcodes_edit','employee'),(27,'almacennew','barcodeToItem','employee'),(28,'almacennew','buffer_setTypeByName','employee'),(29,'almacennew','buy_updateGrouping','employee'),(30,'almacennew','buy_updatePacking','employee'),(31,'almacennew','checkRouteExpeditionScanPut','employee'),(32,'almacennew','clearShelvingList','employee'),(33,'almacennew','collectionAddItem','employee'),(34,'almacennew','collectionGet','employee'),(35,'almacennew','collectionIncreaseQuantity','employee'),(36,'almacennew','collectionMissingTrash','employee'),(37,'almacennew','collectionNew','employee'),(38,'almacennew','collectionStickerPrint','employee'),(39,'almacennew','collection_getTickets','employee'),(40,'almacennew','collection_printSticker','employee'),(41,'almacennew','department_getHasMistake','employee'),(42,'almacennew','deviceLog_add','employee'),(43,'almacennew','deviceProductionUser_getWorker','employee'),(44,'almacennew','deviceProduction_getnameDevice','employee'),(45,'almacennew','expeditionLoading_add','employee'),(46,'almacennew','expeditionPalletDel','employee'),(47,'almacennew','expeditionPalletList','employee'),(48,'almacennew','expeditionPalletPrintSet','employee'),(49,'almacennew','expeditionPalletView','employee'),(50,'almacennew','expeditionScanAdd','employee'),(51,'almacennew','expeditionScanDel','employee'),(52,'almacennew','expeditionScanList','employee'),(53,'almacennew','expeditionScanPut','employee'),(54,'almacennew','expeditionState_addByPallet','employee'),(55,'almacennew','expeditionTruckAdd','employee'),(56,'almacennew','expeditionTruckList','employee'),(57,'almacennew','expedition_getState','employee'),(58,'almacennew','expedition_scan','employee'),(59,'almacennew','faultsReview','employee'),(60,'almacennew','faultsReview_isChecked','employee'),(61,'almacennew','getItemUbication','employee'),(62,'almacennew','get_ItemPackingType','employee'),(63,'almacennew','itemDiary','employee'),(64,'almacennew','itemPlacementSupplyAiming','employee'),(65,'almacennew','itemPlacementSupplyCloseOrder','employee'),(66,'almacennew','itemPlacementSupplyGetOrder','employee'),(68,'almacennew','itemShelvingBuyerGet','employee'),(69,'almacennew','itemShelvingBuyerTask','employee'),(70,'almacennew','itemShelvingDelete','employee'),(71,'almacennew','itemShelvingList','employee'),(72,'almacennew','itemShelvingLog_get','employee'),(73,'almacennew','itemShelvingMake','employee'),(74,'almacennew','itemShelvingMakeEdit','employee'),(75,'almacennew','itemShelvingMake_multi','employee'),(76,'almacennew','itemShelvingPlacementSupplyAdd','employee'),(77,'almacennew','itemShelvingSaleSupplyAdd','employee'),(78,'almacennew','itemShelvingStarsUpdate','employee'),(79,'almacennew','itemShelvingTransfer','employee'),(80,'almacennew','itemShelving_addByClaim','employee'),(81,'almacennew','itemShelving_filterBuyer','employee'),(82,'almacennew','itemShelving_getSaleDate','employee'),(83,'almacennew','itemTrash','employee'),(84,'almacennew','item_card','employee'),(85,'almacennew','item_getSimilar','employee'),(86,'almacennew','item_placement_save','employee'),(87,'almacennew','item_saveReference','employee'),(88,'almacennew','item_updatePackingShelve','employee'),(89,'almacennew','machineWorker_add','employee'),(90,'almacennew','machineWorker_getHistorical','employee'),(91,'almacennew','machineWorker_update','employee'),(92,'almacennew','machineWorker_Worker','employee'),(93,'almacennew','machine_checkPlate','employee'),(94,'almacennew','machine_getWorkerPlate','employee'),(95,'almacennew','mistakeType','employee'),(96,'almacennew','printer_get','employee'),(97,'almacennew','qr_getCall','developer'),(98,'almacennew','saleMistakeAdd','employee'),(99,'almacennew','saleMove','employee'),(100,'almacennew','saleParking_add','employee'),(101,'almacennew','saleTrackingDel','employee'),(102,'almacennew','saleTrackingReplace','employee'),(103,'almacennew','saleTracking_add','employee'),(104,'almacennew','saleTracking_addPrevOK','employee'),(105,'almacennew','saleTracking_updateIsChecked','employee'),(106,'almacennew','sectorCollectionSaleGroup_add','employee'),(107,'almacennew','sectorCollection_get','employee'),(108,'almacennew','sectorCollection_getSale','employee'),(109,'almacennew','sectorCollection_new','employee'),(110,'almacennew','sector_get','employee'),(111,'almacennew','shelvingChange','employee'),(112,'almacennew','shelvingLog_get','employee'),(113,'almacennew','shelvingPark','employee'),(114,'almacennew','shelvingParking_get','employee'),(115,'almacennew','shelvingPriorityUpdate','employee'),(116,'almacennew','sip_getExtension','employee'),(117,'almacennew','ticketCollection_setUsedShelves','employee'),(118,'almacennew','ticketOrCollection_checkFullyControlled','employee'),(119,'almacennew','ticketToPrePrepare','employee'),(120,'almacennew','ticket_checkFullyControlled','employee'),(121,'almacennew','ticket_setState','employee'),(122,'almacennew','update_ItemPackingType','employee'),(123,'almacennew','workerMachinery_isRegistered','employee'),(124,'almacennew','workerMistakeType_get','employee'),(125,'almacennew','workerMistake_Add','coolerBoss'),(126,'almacennew','workerShelving_add','employee'),(127,'almacennew','workerShelving_delete','employee'),(128,'almacennew','worker_getFromHasMistake','employee'),(129,'almacennew','worker_getId','employee'),(130,'almacennew','worker_getPrinter','employee'),(131,'almacennew','worker_getSector','employee'),(132,'almacennew','worker_updatePrinter','employee'),(133,'almacennew','worker_updateSector','employee'),(134,'almacennew','itemShelving_updateFromSale','employee'),(135,'almacennew','collection_getUncheckedTicket','employee'),(136,'almacennew','itemShelving_return','employee'),(137,'almacennew','itemShelving_merge','employee'),(139,'delivery','get_expeditionsSummary','employee'),(140,'almacennew','cmrExpeditionPallet_add','employee'),(141,'delivery','route_getExpeditionSummary','employee'),(142,'almacennew','item_saveStems','employee'),(143,'almacennew','debug_add','employee'),(144,'almacennew','operator_getNumberOfWagons','employee'),(145,'almacennew','operator_add','employee'),(146,'almacennew','expeditionPallet_get','employee'),(147,'almacennew','worker_isF11Allowed','employee'),(148,'almacennew','train_get','employee'),(149,'almacennew','saleTracking_mark','employee'),(150,'almacennew','operator_updateItemPackingType','employee'),(151,'almacennew','operator_updateTrain','employee'),(152,'almacennew','operator_getTrain','employee'),(153,'almacennew','operator_getItemPackingType','employee'),(154,'almacennew','collection_assign','employee'),(155,'almacennew','itemPacking_get','employee'),(156,'almacennew','shelvingLog_add','employee'),(157,'almacennew','collection_get','employee'),(158,'delivery','get_routesFromExpedition','employee'),(160,'almacennew','expeditionMistakeType_get','employee'),(161,'almacennew','expeditionMistake_add','employee'),(162,'almacennew','itemShelving_addList','employee'),(163,'almacennew','cmrPallet_add','employee'),(164,'almacennew','ticket_isOutClosureZone','employee'),(165,'almacennew','itemShelving_selfConsumption','employee'),(166,'almacennew','ticket_printLabelPrevious','employee'),(167,'almacennew','travel_updatePacking','employee'),(168,'app','status','$everyone'); +/*!40000 ALTER TABLE `silexACL` ENABLE KEYS */; +UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -502,7 +522,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2023-08-30 15:53:19 +-- Dump completed on 2023-11-20 12:26:42 USE `cache`; -- MariaDB dump 10.19 Distrib 10.5.19-MariaDB, for debian-linux-gnu (x86_64) -- @@ -538,7 +558,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2023-08-30 15:53:20 +-- Dump completed on 2023-11-20 12:26:42 USE `hedera`; -- MariaDB dump 10.19 Distrib 10.5.19-MariaDB, for debian-linux-gnu (x86_64) -- @@ -602,7 +622,7 @@ UNLOCK TABLES; LOCK TABLES `link` WRITE; /*!40000 ALTER TABLE `link` DISABLE KEYS */; -INSERT INTO `link` VALUES (16,'Printing server','Manage the CUPS printing server','http://printnatura.verdnatura.es','printer'),(20,'Webmail','Verdnatura webmail','https://webmail.verdnatura.es/','mail'),(23,'Verdnatura Beta','Trial version of the web page','https://test-shop.verdnatura.es/','vn'),(25,'Shared folder','Shared folder','https://cdn.verdnatura.es/share','backup'),(29,'phpMyAdmin','Manage MySQL database','https://pma.verdnatura.es/','pma'),(30,'Nagios','Monitoring system','https://nagios.verdnatura.es/','nagios'),(33,'Gitea','Version control system','https://gitea.verdnatura.es/','git'),(34,'Wiknatura','Verdnatura wiki page','https://wiki.verdnatura.es/','wiki'),(35,'phpLDAPadmin','Manage the LDAP database','https://pla.verdnatura.es/','pla'),(36,'Applications','Access applications repository','https://cdn.verdnatura.es/vn-access','access'),(37,'Jenkins','CI and CD system','https://jenkins.verdnatura.es','jenkins'),(38,'osTicket','User service center','https://cau.verdnatura.es','osticket'),(39,'Redmine','Flexible project management','https://redmine.verdnatura.es','redmine'),(40,'Grafana','Analytics & monitoring solution','https://grafana.verdnatura.es','grafana'),(41,'Rocket.Chat','Communications platform','https://chat.verdnatura.es','rocketchat'),(42,'Salix','ERP software','https://salix.verdnatura.es','salix'),(43,'Docker','Container management','https://docker.verdnatura.es','docker'),(44,'Proxmox','Virtual environment','https://proxmox.verdnatura.es','proxmox'),(45,'Shinobi','Network video recorder','https://shinobi.verdnatura.es','shinobi'),(46,'DokuWiki','Internal documentation','https://doku.verdnatura.es','dokuwiki'); +INSERT INTO `link` VALUES (16,'Printing server','Manage the CUPS printing server','http://printnatura.verdnatura.es','printer'),(20,'Webmail','Verdnatura webmail','https://webmail.verdnatura.es/','mail'),(23,'Verdnatura Beta','Trial version of the web page','https://test-shop.verdnatura.es/','vn'),(25,'Shared folder','Shared folder','https://cdn.verdnatura.es/share','backup'),(29,'phpMyAdmin','Manage MySQL database','https://pma.verdnatura.es/','pma'),(30,'Nagios','Monitoring system','https://nagios.verdnatura.es/','nagios'),(33,'Gitea','Version control system','https://gitea.verdnatura.es/','git'),(34,'Wiknatura','Verdnatura wiki page','https://wiki.verdnatura.es/','wiki'),(35,'phpLDAPadmin','Manage the LDAP database','https://pla.verdnatura.es/','pla'),(36,'Applications','Access applications repository','https://cdn.verdnatura.es/vn-access','access'),(37,'Jenkins','CI and CD system','https://jenkins.verdnatura.es','jenkins'),(38,'osTicket','User service center','https://cau.verdnatura.es','osticket'),(39,'Redmine','Flexible project management','https://redmine.verdnatura.es','redmine'),(40,'Grafana','Analytics & monitoring solution','https://grafana.verdnatura.es','grafana'),(41,'Rocket.Chat','Communications platform','https://chat.verdnatura.es','rocketchat'),(42,'Salix','ERP software','https://salix.verdnatura.es','salix'),(43,'Docker','Container management','https://docker.verdnatura.es','docker'),(44,'Proxmox','Virtual environment','https://mox.verdnatura.es','proxmox'),(45,'Shinobi','Network video recorder','https://shinobi.verdnatura.es','shinobi'),(46,'DokuWiki','Internal documentation','https://doku.verdnatura.es','dokuwiki'); /*!40000 ALTER TABLE `link` ENABLE KEYS */; UNLOCK TABLES; @@ -632,7 +652,7 @@ UNLOCK TABLES; LOCK TABLES `message` WRITE; /*!40000 ALTER TABLE `message` DISABLE KEYS */; -INSERT INTO `message` VALUES (1,'ORDER_DATE_HOLIDAY','No es posible realizar pedidos para días festivos'),(2,'ORDER_EMPTY','El pedido esta vacío'),(3,'ORDER_UNAVAILABLE','Algunos artículos ya no están disponibles, verifica las cantidades resaltadas en rojo'),(4,'SURVEY_MAX_ONE_VOTE','Solo es posible realizar un voto por encuesta'),(5,'ORDER_MAX_EXCEEDED','Has excedido el número máximo de pedidos por confirmar, por favor elimina o confirma los pedidos iniciados'),(6,'LOGIN_INCORRECT','Usuario o contraseña incorrectos. Recuerda que se hace distinción entre mayúsculas y minúsculas.'),(7,'ORDER_DATE_PAST','La fecha de su pedido debe ser mayor o igual al día de hoy'),(8,'ORDER_DATE_LAST','No es posible realizar más para hoy, por favor atrasa la fecha de tu pedido a mañana o días posteriores'),(9,'ORDER_DATE_SUNDAY','No es posible confirmar pedidos para Domingo'),(10,'ORDER_DATE_SATURATED','Estamos saturados de pedidos, por favor selecciona otra fecha de envío o recogida '),(11,'USER_DISCONNECTED','Has sido desconectado del servidor, por favor vuelve a iniciar sesión'),(12,'UNAUTH_ACTION','Acción no permitida'),(13,'ORDER_INVALID_AGENCY','La agencia de envío no es válida'),(14,'ORDER_EMPTY_ADDRESS','Selecciona una dirección de envío'),(15,'ORDER_AMOUNT_ROUNDED','Este artículo se vende agrupado y la cantidad ha sido redondeada'),(17,'orderOutdated','La configuración del pedido es incorrecta, por favor vuelve a configurarlo para continuar comprando'),(18,'orderNotOwnedByUser','El pedido pertenece a otro usuario'),(19,'orderConfirmed','El pedido ya ha sido confirmado y no puede modificarse'),(20,'clientNotVerified','Datos fiscales incompletos, por favor contacte con su comercial'); +INSERT INTO `message` VALUES (1,'ORDER_DATE_HOLIDAY','Orders for holidays are not possible'),(2,'ORDER_EMPTY','The order is empty'),(3,'ORDER_UNAVAILABLE','Some items are no longer available, please check the quantities highlighted in red'),(4,'SURVEY_MAX_ONE_VOTE','Only one vote per survey is possible'),(5,'ORDER_MAX_EXCEEDED','You have exceeded the maximum number of unconfirmed orders, please delete or confirm started orders'),(6,'LOGIN_INCORRECT','Incorrect username or password. Case-sensitive.'),(7,'ORDER_DATE_PAST','The order date must be today or later'),(8,'ORDER_DATE_LAST','No more orders can be made for today, please postpone your order for tomorrow or later'),(9,'ORDER_DATE_SUNDAY','Orders for Sunday cannot be confirmed'),(10,'ORDER_DATE_SATURATED','We are overwhelmed with orders, please select another delivery or pick-up date'),(11,'USER_DISCONNECTED','You have been disconnected from the server, please log in again'),(12,'UNAUTH_ACTION','Action not allowed'),(13,'ORDER_INVALID_AGENCY','The shipping agency is not valid'),(14,'ORDER_EMPTY_ADDRESS','Please select a shipping address'),(15,'ORDER_AMOUNT_ROUNDED','This item is sold in bundles, the quantity has been rounded'),(17,'orderOutdated','The order configuration is incorrect, please reconfigure it to continue shopping'),(18,'orderNotOwnedByUser','The order belongs to another user'),(19,'orderConfirmed','The order has already been confirmed and cannot be modified'),(20,'clientNotVerified','Incomplete tax data, please contact your sales representative'),(21,'quantityLessThanMin','The quantity cannot be less than the minimum'); /*!40000 ALTER TABLE `message` ENABLE KEYS */; UNLOCK TABLES; @@ -704,7 +724,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2023-08-30 15:53:22 +-- Dump completed on 2023-11-20 12:26:42 USE `sage`; -- MariaDB dump 10.19 Distrib 10.5.19-MariaDB, for debian-linux-gnu (x86_64) -- @@ -770,4 +790,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2023-08-30 15:53:22 +-- Dump completed on 2023-11-20 12:26:42 diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index a3791f9f5c..307174f16e 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -59,10 +59,6 @@ INSERT IGNORE INTO `vn`.`greugeConfig`(`id`, `freightPickUpPrice`) VALUES ('1', '11'); -INSERT INTO `vn`.`packagingConfig`(`upperGap`) - VALUES - ('10'); - UPDATE `account`.`role` SET id = 100 WHERE id = 0; INSERT INTO `account`.`roleConfig`(`id`, `mysqlPassword`, `rolePrefix`, `userPrefix`, `userHost`, `tplUser`) @@ -73,7 +69,7 @@ CALL `account`.`role_sync`; INSERT INTO `account`.`user`(`id`,`name`, `nickname`, `role`,`active`,`email`, `lang`, `image`, `password`) SELECT id, name, CONCAT(name, 'Nick'), id, 1, CONCAT(name, '@mydomain.com'), 'en', '4fa3ada0-3ac4-11eb-9ab8-27f6fc3b85fd', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2' - FROM `account`.`role` WHERE id <> 20 + FROM `account`.`role` ORDER BY id; INSERT INTO `account`.`account`(`id`) @@ -87,9 +83,15 @@ INSERT INTO `vn`.`educationLevel` (`id`, `name`) (1, 'ESTUDIOS PRIMARIOS COMPLETOS'), (2, 'ENSEÑANZAS DE BACHILLERATO'); +INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `bossFk`) + SELECT id,UPPER(LPAD(role, 3, '0')), name, name, NULL + FROM `account`.`user` + WHERE `id` = 9; + INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `bossFk`) SELECT id,UPPER(LPAD(role, 3, '0')), name, name, 9 - FROM `account`.`user`; + FROM `account`.`user` + WHERE `id` <> 9; UPDATE `vn`.`worker` SET bossFk = NULL WHERE id = 20; UPDATE `vn`.`worker` SET bossFk = 20 WHERE id = 1 OR id = 9; @@ -549,15 +551,6 @@ INSERT INTO `vn`.`supplierActivity`(`code`, `name`) ('flowerPlants', 'Wholesale of flowers and plants'), ('vegetablesFruits', 'Fruit and vegetable trade'); -INSERT INTO `vn`.`supplierAddress`(`id`, `supplierFk`, `nickname`, `street`, `provinceFk`, `postalCode`, `city`, `phone`, `mobile`) - VALUES - (1, 1, 'Ace Chemicals', 'The Midtown', 1, '46000', 'Gotham', '111111111', '222222222'), - (2, 1, 'Arkham Asylum', 'Grand Avenue', 1, '46000', 'Gotham', '111111111', '222222222'), - (3, 2, 'Wayne Tower', 'Grand Avenue', 1, '46000', 'Gotham', '111111111', '222222222'), - (4, 2, 'Bank of Gotham', 'Founders Island', 1, '46000', 'Gotham', '111111111', '222222222'), - (5, 442, 'GCR building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222'), - (6, 442, 'The Gotham Tonight building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222'); - INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif`, `commission`, `created`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`, `payDay`, `taxTypeSageFk`, `withholdingSageFk`, `transactionTypeSageFk`, `workerFk`, `supplierActivityFk`, `isPayMethodChecked`, `healthRegister`) VALUES (1, 'Plants SL', 'Plants nick', 4100000001, 1, '06089160W', 0, util.VN_CURDATE(), 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants', 1, '400664487V'), @@ -568,6 +561,15 @@ INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif` (791, 'Bros SL', 'Bros nick', 5115000791, 1, '37718083S', 0, util.VN_CURDATE(), 1, 'supplier address 7', 'ASGARD', 3, 46600, 1, 2, 15, 6, 9, 3, 18, 'complements', 1, '400664487V'), (1381, 'Ornamentales', 'Ornamentales', 7185001381, 1, '07972486L', 0, util.VN_CURDATE(), 1, 'supplier address 4', 'GOTHAM', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'complements', 1, '400664487V'); +INSERT INTO `vn`.`supplierAddress`(`id`, `supplierFk`, `nickname`, `street`, `provinceFk`, `postalCode`, `city`, `phone`, `mobile`) + VALUES + (1, 1, 'Ace Chemicals', 'The Midtown', 1, '46000', 'Gotham', '111111111', '222222222'), + (2, 1, 'Arkham Asylum', 'Grand Avenue', 1, '46000', 'Gotham', '111111111', '222222222'), + (3, 2, 'Wayne Tower', 'Grand Avenue', 1, '46000', 'Gotham', '111111111', '222222222'), + (4, 2, 'Bank of Gotham', 'Founders Island', 1, '46000', 'Gotham', '111111111', '222222222'), + (5, 442, 'GCR building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222'), + (6, 442, 'The Gotham Tonight building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222'); + INSERT INTO `vn`.`supplierContact`(`id`, `supplierFk`, `phone`, `mobile`, `email`, `observation`, `name`) VALUES (1, 1, 123121212, 654789123, 'supplier1@email.es', 'observation1', 'the boss'), @@ -966,6 +968,10 @@ INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPack ('cc', 1640038.00, 56.00, 220.00, 128.00, 1, util.VN_CURDATE(), 15, 90.00), ('pallet 100', 2745600.00, 100.00, 220.00, 120.00, 1, util.VN_CURDATE(), 16, 0.00); +INSERT INTO `vn`.`packagingConfig`(`upperGap`, `defaultSmallPackageFk`, `defaultBigPackageFk`) + VALUES + ('10', 1, 'pallet 100'); + INSERT INTO `vn`.`expeditionStateType`(`id`, `description`, `code`) VALUES (1, 'En reparto', 'ON DELIVERY'), diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 3d6156580a..f427519eb6 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -315,20 +315,20 @@ CREATE TABLE `mailAliasAccount` ( /*!40101 SET character_set_client = @saved_cs_client */; -- --- Table structure for table `mailClientAccess` +-- Table structure for table `mailClientAccess__` -- -DROP TABLE IF EXISTS `mailClientAccess`; +DROP TABLE IF EXISTS `mailClientAccess__`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mailClientAccess` ( +CREATE TABLE `mailClientAccess__` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `client` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL, `action` set('OK','REJECT') CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL DEFAULT 'REJECT', `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `mailFrom` (`client`) -) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci COMMENT='@deprecated 2023-09-03'; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -428,20 +428,20 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; -- --- Table structure for table `mailSenderAccess` +-- Table structure for table `mailSenderAccess__` -- -DROP TABLE IF EXISTS `mailSenderAccess`; +DROP TABLE IF EXISTS `mailSenderAccess__`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE `mailSenderAccess` ( +CREATE TABLE `mailSenderAccess__` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `sender` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL, `action` set('OK','REJECT') NOT NULL DEFAULT 'REJECT', `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `mailFrom` (`sender`) -) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci COMMENT='@deprecated 2023-09-03'; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -727,10 +727,30 @@ CREATE TABLE `sambaConfig` ( `adUser` varchar(255) DEFAULT NULL COMMENT 'Active directory user', `adPassword` varchar(255) DEFAULT NULL COMMENT 'Active directory password', `verifyCert` tinyint(3) unsigned NOT NULL DEFAULT 1 COMMENT 'Whether to verify server certificate', + `userDn` varchar(255) NOT NULL COMMENT 'Base DN for users without domain DN part', PRIMARY KEY (`id`) ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Global configuration parameters for accounts'; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `signInLog` +-- + +DROP TABLE IF EXISTS `signInLog`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `signInLog` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `token` varchar(255) NOT NULL, + `userFk` int(10) unsigned DEFAULT NULL, + `creationDate` timestamp NULL DEFAULT current_timestamp(), + `ip` varchar(100) NOT NULL, + PRIMARY KEY (`id`), + KEY `userFk` (`userFk`), + CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `user` -- @@ -743,7 +763,7 @@ CREATE TABLE `user` ( `realm` varchar(512) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `name` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `nickname` varchar(127) NOT NULL, - `password` varchar(512) DEFAULT NULL, + `password` varchar(512) NOT NULL, `role` int(10) unsigned NOT NULL DEFAULT 2, `active` tinyint(1) NOT NULL DEFAULT 1, `email` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, @@ -761,6 +781,7 @@ CREATE TABLE `user` ( `editorFk` int(10) unsigned DEFAULT NULL, `passExpired` date DEFAULT NULL, `twoFactor` enum('email') DEFAULT NULL COMMENT 'Two-factor auth type', + `username` varchar(30) GENERATED ALWAYS AS (`name`) VIRTUAL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`), UNIQUE KEY `mail` (`email`), @@ -984,6 +1005,27 @@ CREATE TABLE `userSync` ( -- -- Dumping events for database 'account' -- +/*!50106 SET @save_time_zone= @@TIME_ZONE */ ; +/*!50106 DROP EVENT IF EXISTS `role_sync` */; +DELIMITER ;; +/*!50003 SET @saved_cs_client = @@character_set_client */ ;; +/*!50003 SET @saved_cs_results = @@character_set_results */ ;; +/*!50003 SET @saved_col_connection = @@collation_connection */ ;; +/*!50003 SET character_set_client = utf8mb3 */ ;; +/*!50003 SET character_set_results = utf8mb3 */ ;; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ;; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ;; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;; +/*!50003 SET @saved_time_zone = @@time_zone */ ;; +/*!50003 SET time_zone = 'SYSTEM' */ ;; +/*!50106 CREATE*/ /*!50117 DEFINER=`salix`@`10.0.%.%`*/ /*!50106 EVENT `role_sync` ON SCHEDULE AT '2023-11-16 14:32:48' ON COMPLETION NOT PRESERVE DISABLE ON SLAVE DO CALL role_sync */ ;; +/*!50003 SET time_zone = @saved_time_zone */ ;; +/*!50003 SET sql_mode = @saved_sql_mode */ ;; +/*!50003 SET character_set_client = @saved_cs_client */ ;; +/*!50003 SET character_set_results = @saved_cs_results */ ;; +/*!50003 SET collation_connection = @saved_col_connection */ ;; +DELIMITER ; +/*!50106 SET TIME_ZONE= @save_time_zone */ ; -- -- Dumping routines for database 'account' @@ -1100,6 +1142,35 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP FUNCTION IF EXISTS `myUser_hasPriv` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` FUNCTION `myUser_hasPriv`(vChain VARCHAR(100), + vPrivilege ENUM('SELECT','INSERT','UPDATE','DELETE') +) RETURNS tinyint(1) + READS SQL DATA +BEGIN +/** + * Search if my user has privileges on table or column + * + * @param vChain string passed with this syntax dbName.tableName[.columnName] + * @param vPrivilege privileges to check ('SELECT','INSERT','UPDATE','DELETE') + * @return vHasPrivilege + */ + RETURN user_hasPriv(vChain, vPrivilege, myUser_getId()); +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP FUNCTION IF EXISTS `myUser_hasRole` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -1152,6 +1223,35 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP FUNCTION IF EXISTS `myUser_hasRoutinePriv` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` FUNCTION `myUser_hasRoutinePriv`(vType ENUM('PROCEDURE', 'FUNCTION'), + vChain VARCHAR(100) +) RETURNS tinyint(1) + READS SQL DATA +BEGIN +/** + * Search if my user has privileges on routines + * + * @param vType procedure or function + * @param vChain string passed with this syntax dbName.tableName + * @return vHasPrivilege + */ + RETURN user_hasRoutinePriv(vType, vChain, myUser_getId()); +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP FUNCTION IF EXISTS `passwordGenerate` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -1309,6 +1409,122 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP FUNCTION IF EXISTS `user_hasPriv` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` FUNCTION `user_hasPriv`(vChain VARCHAR(100), + vPrivilege ENUM('SELECT','INSERT','UPDATE','DELETE'), + vUserFk INT +) RETURNS tinyint(1) + READS SQL DATA +BEGIN +/** + * Search if the user has privileges on table or column + * + * @param vChain string passed with this syntax dbName.tableName[.columnName] + * @param vPrivilege privileges to check('SELECT','INSERT','UPDATE','DELETE') + * @param vUserFk user to check + * @return vHasPrivilege + */ + DECLARE vHasPrivilege BOOL DEFAULT FALSE; + DECLARE vDb VARCHAR(50); + DECLARE vTableName VARCHAR(50); + DECLARE vColumnName VARCHAR(50); + DECLARE vPrivilegeFlag INT; + DECLARE vChainExists BOOL; + + SET vDb = SUBSTRING_INDEX(vChain, '.', 1); + SET vChain = SUBSTRING(vChain, LENGTH(vDb) + 2); + SET vTableName = SUBSTRING_INDEX(vChain, '.', 1); + SET vColumnName = SUBSTRING(vChain, LENGTH(vTableName) + 2); + + SELECT COUNT(*) INTO vChainExists + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = vDb + AND TABLE_NAME = vTableName + AND COLUMN_NAME = vColumnName + LIMIT 1; + + IF NOT vChainExists THEN + RETURN FALSE; + END IF; + + CASE vPrivilege + WHEN 'Select' THEN SET vPrivilegeFlag = 1; + WHEN 'Insert' THEN SET vPrivilegeFlag = 2; + WHEN 'Update' THEN SET vPrivilegeFlag = 4; + WHEN 'Delete' THEN SET vPrivilegeFlag = 8; + ELSE BEGIN END; + END CASE; + + DROP TEMPORARY TABLE IF EXISTS tRole; + CREATE TEMPORARY TABLE tRole + (INDEX (`name`)) + ENGINE = MEMORY + SELECT r.`name` + FROM user u + JOIN roleRole rr ON rr.role = u.role + JOIN `role` r ON r.id = rr.inheritsFrom + WHERE u.id = vUserFk; + + SELECT hasPrivilege INTO vHasPrivilege + FROM (SELECT JSON_VALUE(Priv, '$.access') & vPrivilegeFlag hasPrivilege + FROM mysql.global_priv gp + JOIN tRole tr ON CONCAT(tr.name) = gp.User + HAVING hasPrivilege + LIMIT 1)sub; + + IF NOT vHasPrivilege THEN + + SELECT sub.privilege = 'Y' INTO vHasPrivilege + FROM + (SELECT CASE vPrivilege + WHEN 'SELECT' THEN Select_priv + WHEN 'INSERT' THEN Insert_priv + WHEN 'UPDATE' THEN Update_priv + WHEN 'DELETE' THEN Delete_priv + END privilege + FROM mysql.db db + JOIN tRole tr ON tr.name = db.User + WHERE db.Db = vDb)sub; + + END IF; + + IF NOT vHasPrivilege THEN + + SELECT TRUE INTO vHasPrivilege + FROM tRole tr + LEFT JOIN ( + SELECT User, Table_priv privilege + FROM mysql.tables_priv + WHERE Db = vDb + AND Table_name = vTableName + UNION + SELECT User, Column_priv + FROM mysql.columns_priv + WHERE Db = vDb + AND Table_name = vTableName + AND Column_name = vColumnName + )sub ON sub.`User` = tr.name + WHERE sub.privilege = vPrivilege; + END IF; + + DROP TEMPORARY TABLE tRole; + + RETURN vHasPrivilege; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP FUNCTION IF EXISTS `user_hasRole` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -1381,6 +1597,135 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP FUNCTION IF EXISTS `user_hasRoutinePriv` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` FUNCTION `user_hasRoutinePriv`(vType ENUM('PROCEDURE', 'FUNCTION'), + vChain VARCHAR(100), + vUserFk INT +) RETURNS tinyint(1) + READS SQL DATA +BEGIN +/** + * Search if the user has privileges on routines. + * + * @param vType procedure or function + * @param vChain string passed with this syntax dbName.tableName + * @param vUserFk user to ckeck + * @return vHasPrivilege + */ + DECLARE vHasPrivilege BOOL DEFAULT FALSE; + DECLARE vDb VARCHAR(50); + DECLARE vObject VARCHAR(50); + DECLARE vChainExists BOOL; + DECLARE vExecutePriv INT DEFAULT 262144; + -- 262144 = CONV(1000000000000000000, 2, 10) + -- 1000000000000000000 execution permission expressed in binary base + + SET vDb = SUBSTRING_INDEX(vChain, '.', 1); + SET vChain = SUBSTRING(vChain, LENGTH(vDb) + 2); + SET vObject = SUBSTRING_INDEX(vChain, '.', 1); + + SELECT COUNT(*) INTO vChainExists + FROM mysql.proc + WHERE db = vDb + AND `name` = vObject + AND `type` = vType + LIMIT 1; + + IF NOT vChainExists THEN + RETURN FALSE; + END IF; + + DROP TEMPORARY TABLE IF EXISTS tRole; + CREATE TEMPORARY TABLE tRole + (INDEX (`name`)) + ENGINE = MEMORY + SELECT r.`name` + FROM user u + JOIN roleRole rr ON rr.role = u.role + JOIN `role` r ON r.id = rr.inheritsFrom + WHERE u.id = vUserFk; + + SELECT TRUE INTO vHasPrivilege + FROM mysql.global_priv gp + JOIN tRole tr ON tr.name = gp.`User` + OR CONCAT('$', tr.name) = gp.`User` + WHERE JSON_VALUE(gp.Priv, '$.access') >= vExecutePriv + AND gp.Host = '' + LIMIT 1; + + IF NOT vHasPrivilege THEN + SELECT TRUE INTO vHasPrivilege + FROM mysql.db db + JOIN tRole tr ON tr.name = db.`User` + WHERE db.Db = vDb + AND db.Execute_priv = 'Y'; + END IF; + + IF NOT vHasPrivilege THEN + SELECT TRUE INTO vHasPrivilege + FROM mysql.procs_priv pp + JOIN tRole tr ON tr.name = pp.`User` + WHERE pp.Db = vDb + AND pp.Routine_name = vObject + AND pp.Routine_type = vType + AND pp.Proc_priv = 'Execute' + LIMIT 1; + END IF; + + DROP TEMPORARY TABLE tRole; + RETURN vHasPrivilege; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `account_enable` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `account_enable`(vSelf INT) +BEGIN +/** + * Enables an account and sets up email configuration. + */ + UPDATE user + SET active = TRUE + WHERE id = vSelf; + + INSERT IGNORE INTO account + SET id = vSelf; + + INSERT IGNORE INTO mailAliasAccount (mailAlias, account) + SELECT id, vSelf + FROM mailAlias + WHERE alias = 'general'; + + INSERT IGNORE INTO mailForward (account, forwardTo) + SELECT vSelf, email + FROM user + WHERE id = vSelf; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `myUser_login` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -2352,90 +2697,6 @@ BEGIN END IF; END ;; DELIMITER ; - - -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` FUNCTION `account`.`user_hasRoutinePriv`(vType ENUM('PROCEDURE', 'FUNCTION'), - vChain VARCHAR(100), - vUserFk INT -) RETURNS tinyint(1) - READS SQL DATA -BEGIN - -/** - * Search if the user has privileges on routines. - * - * @param vType procedure or function - * @param vChain string passed with this syntax dbName.tableName - * @param vUserFk user to ckeck - * @return vHasPrivilege - */ - DECLARE vHasPrivilege BOOL DEFAULT FALSE; - DECLARE vDb VARCHAR(50); - DECLARE vObject VARCHAR(50); - DECLARE vChainExists BOOL; - DECLARE vExecutePriv INT DEFAULT 262144; - -- 262144 = CONV(1000000000000000000, 2, 10) - -- 1000000000000000000 execution permission expressed in binary base - - SET vDb = SUBSTRING_INDEX(vChain, '.', 1); - SET vChain = SUBSTRING(vChain, LENGTH(vDb) + 2); - SET vObject = SUBSTRING_INDEX(vChain, '.', 1); - - SELECT COUNT(*) INTO vChainExists - FROM mysql.proc - WHERE db = vDb - AND `name` = vObject - AND `type` = vType - LIMIT 1; - - IF NOT vChainExists THEN - RETURN FALSE; - END IF; - - DROP TEMPORARY TABLE IF EXISTS tRole; - CREATE TEMPORARY TABLE tRole - (INDEX (`name`)) - ENGINE = MEMORY - SELECT r.`name` - FROM user u - JOIN roleRole rr ON rr.role = u.role - JOIN `role` r ON r.id = rr.inheritsFrom - WHERE u.id = vUserFk; - - SELECT TRUE INTO vHasPrivilege - FROM mysql.global_priv gp - JOIN tRole tr ON tr.name = gp.`User` - OR CONCAT('$', tr.name) = gp.`User` - WHERE JSON_VALUE(gp.Priv, '$.access') >= vExecutePriv - AND gp.Host = '' - LIMIT 1; - - IF NOT vHasPrivilege THEN - SELECT TRUE INTO vHasPrivilege - FROM mysql.db db - JOIN tRole tr ON tr.name = db.`User` - WHERE db.Db = vDb - AND db.Execute_priv = 'Y'; - END IF; - - IF NOT vHasPrivilege THEN - SELECT TRUE INTO vHasPrivilege - FROM mysql.procs_priv pp - JOIN tRole tr ON tr.name = pp.`User` - WHERE pp.Db = vDb - AND pp.Routine_name = vObject - AND pp.Routine_type = vType - AND pp.Proc_priv = 'Execute' - LIMIT 1; - END IF; - - DROP TEMPORARY TABLE tRole; - RETURN vHasPrivilege; -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 */ ; @@ -2529,13 +2790,13 @@ DROP TABLE IF EXISTS `clientDied`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `clientDied` ( - `id` int(11) NOT NULL DEFAULT 0, - `clientName` varchar(50) NOT NULL, + `clientFk` int(11) NOT NULL DEFAULT 0, + `clientName__` varchar(50) NOT NULL COMMENT '@deprecated 2023-10-15', `lastInvoiced` date DEFAULT NULL, - `workerCode` varchar(3) NOT NULL, - `Boss` varchar(3) NOT NULL, - `Aviso` varchar(13) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, - PRIMARY KEY (`id`) + `workerCode__` varchar(3) NOT NULL COMMENT '@deprecated 2023-10-15', + `Boss__` varchar(3) NOT NULL COMMENT '@deprecated 2023-10-15', + `warning` enum('first','second','third') CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + PRIMARY KEY (`clientFk`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Clientes que no han comprado en los ultimos 3 meses, se actualiza con proceso nocturno el 3 de cada mes'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -2598,13 +2859,13 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; -- --- Table structure for table `compradores` +-- Table structure for table `compradores__` -- -DROP TABLE IF EXISTS `compradores`; +DROP TABLE IF EXISTS `compradores__`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE `compradores` ( +CREATE TABLE `compradores__` ( `Id_Trabajador` int(10) unsigned NOT NULL, `año` int(4) NOT NULL, `semana` int(2) NOT NULL, @@ -3058,17 +3319,17 @@ DROP TABLE IF EXISTS `salesByItemTypeDay`; CREATE TABLE `salesByItemTypeDay` ( `itemTypeFk` smallint(5) unsigned NOT NULL, `dated` date NOT NULL, - `netSale` int(11) NOT NULL DEFAULT 0, - `stems` int(11) NOT NULL DEFAULT 0, - `references` int(11) NOT NULL DEFAULT 0, - `trash` int(11) NOT NULL DEFAULT 0, - `faults` int(11) NOT NULL DEFAULT 0, - `claimed` decimal(10,2) NOT NULL DEFAULT 0.00, - `accepted` decimal(10,2) NOT NULL DEFAULT 0.00, - `sale` decimal(10,2) NOT NULL DEFAULT 0.00, - `buy` decimal(10,2) NOT NULL DEFAULT 0.00, - `costComponent` decimal(10,2) NOT NULL DEFAULT 0.00, - `marginComponent` decimal(10,2) NOT NULL DEFAULT 0.00, + `netSale__` int(11) NOT NULL DEFAULT 0 COMMENT '@deprecated 2023-08-31, Mismo valor que campo sale', + `stems` int(11) NOT NULL DEFAULT 0 COMMENT 'Número de tallos vendidos', + `references` int(11) NOT NULL DEFAULT 0 COMMENT 'Número de artículos distintos por tipo vendidos', + `trash` int(11) NOT NULL DEFAULT 0 COMMENT 'Tallos basura', + `faults` int(11) NOT NULL DEFAULT 0 COMMENT 'Tallos faltas', + `claimed` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'Valor total de reclamaciones', + `accepted` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'Valor total de reclamaciones aceptadas', + `sale` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'Ventas totales', + `buy` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'Valor de compras totales', + `costComponent` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'Suma de componentes que son valor de compra', + `marginComponent` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'Suma de componentes que son márgen', PRIMARY KEY (`itemTypeFk`,`dated`), KEY `itemTypeSalesByweek_period_idx` (`dated`), CONSTRAINT `itemTypeSalesByweek_itemTypeFk` FOREIGN KEY (`itemTypeFk`) REFERENCES `vn`.`itemType` (`id`) @@ -3734,18 +3995,15 @@ BEGIN SELECT c.id FROM vn.client c JOIN vn.country co ON co.id = c.countryFk WHERE co.code = vCountryCode - ) sub ON sub.id = cd.id; + ) sub ON sub.id = cd.clientFk; - INSERT INTO clientDied (id, clientName, lastInvoiced, workerCode, Boss, Aviso) + INSERT INTO clientDied (clientFk, lastInvoiced, warning) SELECT c.id, - c.name, sub.lastShipped, - w.code, - b.code, CASE - WHEN lastShipped < vThridPeriod OR lastShipped IS NULL THEN 'Tercer Aviso' - WHEN lastShipped < vSecondPeriod THEN 'Segundo Aviso' - WHEN lastShipped < vFirstPeriod THEN 'Primer Aviso' + WHEN lastShipped < vThridPeriod OR lastShipped IS NULL THEN 'third' + WHEN lastShipped < vSecondPeriod THEN 'second' + WHEN lastShipped < vFirstPeriod THEN 'first' END FROM vn.client c JOIN vn.country co ON co .id = c.countryFk @@ -4006,95 +4264,6 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `compradores_add` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `compradores_add`(IN vYear INT, IN vWeekFrom INT, IN vWeekTo INT) -BEGIN -/** - * Sustituye los registros de "bs.compradores". - * - * @param vYear: año ventas - * @param vWeekFrom: semana desde - * @param vWeekTo: semana hasta - */ - REPLACE bs.compradores - SELECT it.workerFk AS Id_Trabajador, vYear AS año, tm.week AS semana, SUM(importe) AS importe, 0 AS comision - FROM bs.ventas v - JOIN vn.time tm ON tm.dated = v.fecha - JOIN vn.itemType it ON it.id = v.tipo_id - WHERE tm.year = vYear - AND tm.week BETWEEN vWeekFrom AND vWeekTo - AND it.categoryFk != 6 - GROUP BY it.workerFk, tm.week; -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `compradores_add_launcher` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `compradores_add_launcher`() -BEGIN - - DECLARE vYear INT; - DECLARE vWeek INT; - DECLARE done BOOL DEFAULT FALSE; - - DECLARE rs CURSOR FOR - SELECT year, week - FROM vn.time - WHERE dated <= util.VN_CURDATE() - AND year = vYear - AND week >= vWeek; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; - - SELECT MAX(año) INTO vYear - FROM compradores; - - SELECT MAX(semana) INTO vWeek - FROM compradores - WHERE año = vYear; - - OPEN rs; - - FETCH rs INTO vYear, vWeek; - - WHILE NOT done DO - - CALL compradores_add(vYear, vWeek, vWeek); - - FETCH rs INTO vYear, vWeek; - - END WHILE; - - CLOSE rs; - - CALL compradores_evolution_add; - -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `compradores_evolution_add` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -4648,6 +4817,8 @@ BEGIN DECLARE vClaimManaId INT; DECLARE vManaBankId INT; DECLARE vManaGreugeTypeId INT; + DECLARE vManaFromDays INT; + DECLARE vManaToDays INT; SELECT id INTO vManaId FROM vn.component WHERE code = 'mana'; @@ -4664,23 +4835,32 @@ BEGIN SELECT id INTO vManaGreugeTypeId FROM vn.greugeType WHERE code = 'mana'; - SELECT IFNULL(MAX(dated), '2016-01-01') - INTO vFromDated + SELECT manaFromDays, manaToDays + INTO vManaFromDays, vManaToDays + FROM vn.salespersonConfig; + + SELECT MAX(dated) + INTO vFromDated FROM vn.clientManaCache; - DELETE - FROM vn.clientManaCache - WHERE dated = vFromDated; + DELETE + FROM vn.clientManaCache + WHERE dated = vFromDated; - SELECT IFNULL(MAX(dated), '2016-01-01') - INTO vFromDated + SELECT MAX(dated) + INTO vFromDated FROM vn.clientManaCache; - WHILE timestampadd(DAY,30,vFromDated) < util.VN_CURDATE() DO + IF ISNULL(vFromDated) THEN + SELECT manaDateFrom + INTO vFromDated + FROM vn.salespersonConfig; + END IF; + WHILE vFromDated + INTERVAL vManaToDays DAY < util.VN_CURDATE() DO SELECT - timestampadd(DAY,30,vFromDated), - timestampadd(DAY,-90,vFromDated) + vFromDated + INTERVAL vManaToDays DAY, + vFromDated - INTERVAL vManaFromDays DAY INTO vToDated, vForDeleteDated; @@ -4691,8 +4871,8 @@ BEGIN INSERT INTO vn.clientManaCache(clientFk, mana, dated) SELECT Id_Cliente, - cast(sum(mana) as decimal(10,2)) as mana, - vToDated as dated + SUM(mana), + vToDated FROM ( SELECT cs.Id_Cliente, Cantidad * Valor as mana @@ -4709,7 +4889,6 @@ BEGIN WHERE Id_Banco = vManaBankId AND Fechacobro > vFromDated AND Fechacobro <= vToDated - UNION ALL SELECT g.Id_Cliente, g.Importe FROM vn2008.Greuges g @@ -4725,9 +4904,7 @@ BEGIN HAVING Id_Cliente; SET vFromDated = vToDated; - END WHILE; - END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -4760,9 +4937,16 @@ BEGIN GROUP BY c.lastSalesPersonFk )avgPortfolioWeight ON avgPortfolioWeight.lastSalesPersonFk = wm.workerFk JOIN vn.salespersonConfig spc - SET wm.pricesModifierRate = GREATEST( - spc.manaMinRate, - LEAST(spc.manaMaxRate, ROUND( - wm.amount / avgPortfolioWeight.amount))); + SET wm.pricesModifierRate = + IFNULL( + GREATEST( + spc.manaMinRate, + LEAST( + spc.manaMaxRate, + ROUND( - wm.amount / avgPortfolioWeight.amount, 3) + ) + ) + ,0); END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -4787,13 +4971,12 @@ BEGIN DECLARE vDone BOOL; DECLARE vError VARCHAR(255); DECLARE vErrorCode VARCHAR(255); - DECLARE vNErrors INT DEFAULT 0; DECLARE vSchema VARCHAR(255); DECLARE vProcedure VARCHAR(255); DECLARE vLogMail VARCHAR(255); - DECLARE vId INT; + DECLARE vNightTaskFk INT; - DECLARE rs CURSOR FOR + DECLARE vQueue CURSOR FOR SELECT id, `schema`, `procedure` FROM nightTask WHERE finished <= util.VN_CURDATE() @@ -4804,14 +4987,17 @@ BEGIN SET vDone = TRUE; SET max_sp_recursion_depth = 3; - OPEN rs; - myLoop: LOOP + SELECT logMail INTO vLogMail + FROM nightTaskConfig LIMIT 1; + + OPEN vQueue; + l: LOOP SET vDone = FALSE; - FETCH rs INTO vId, vSchema, vProcedure; + FETCH vQueue INTO vNightTaskFk, vSchema, vProcedure; IF vDone THEN - LEAVE myLoop; + LEAVE l; END IF; UPDATE nightTask @@ -4819,7 +5005,7 @@ BEGIN `finished` = NULL, `error` = NULL, `errorCode` = NULL - WHERE id = vId; + WHERE id = vNightTaskFk; SET vError = NULL; CALL nightTask_launchTask( @@ -4830,36 +5016,30 @@ BEGIN ); IF vError IS NOT NULL THEN - SET vNErrors = vNErrors + 1; + IF vLogMail IS NOT NULL THEN + CALL vn.mail_insert( + vLogMail, + NULL, + CONCAT('Nightly task failed (', vSchema, '.', vProcedure, ')'), + CONCAT( + '[', vErrorCode, '] ', vError, CHAR(13, 10), -- Line break + 'See ', SCHEMA(), '.nightTask table for more info.' + ) + ); + END IF; UPDATE nightTask SET `error` = vError, `errorCode` = vErrorCode - WHERE id = vId; + WHERE id = vNightTaskFk; ELSE UPDATE nightTask SET finished = util.VN_NOW(), lastFinished = util.VN_NOW() - WHERE id = vId; + WHERE id = vNightTaskFk; END IF; END LOOP; - - CLOSE rs; - - SELECT logMail INTO vLogMail - FROM nightTaskConfig LIMIT 1; - - IF vNErrors > 0 AND vLogMail IS NOT NULL THEN - CALL vn.mail_insert( - vLogMail, - NULL, - 'Nightly task failed', - CONCAT( - vNErrors, ' procedures of nightly tasks have failed. ', - 'Please, see `', SCHEMA() ,'`.`nightTask` table for more info.' - ) - ); - END IF; + CLOSE vQueue; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -5108,11 +5288,10 @@ BEGIN DELETE FROM salesByItemTypeDay WHERE dated BETWEEN vDateStart AND vDateEnd; - INSERT INTO salesByItemTypeDay (itemTypeFk, dated, `references`, netSale, stems) + INSERT INTO salesByItemTypeDay (itemTypeFk, dated, `references`, stems) SELECT it.id itemTypeFk, bs.dated, COUNT(DISTINCT(i.id)) `references`, - SUM(bs.amount) netSale, SUM(i.stems * s.quantity) stems FROM sale bs JOIN vn.itemType it ON it.id = bs.typeFk @@ -8530,9 +8709,9 @@ DELIMITER ;; /*!50003 SET @saved_cs_client = @@character_set_client */ ;; /*!50003 SET @saved_cs_results = @@character_set_results */ ;; /*!50003 SET @saved_col_connection = @@collation_connection */ ;; -/*!50003 SET character_set_client = utf8mb3 */ ;; -/*!50003 SET character_set_results = utf8mb3 */ ;; -/*!50003 SET collation_connection = utf8mb3_general_ci */ ;; +/*!50003 SET character_set_client = utf8mb4 */ ;; +/*!50003 SET character_set_results = utf8mb4 */ ;; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ;; /*!50003 SET @saved_sql_mode = @@sql_mode */ ;; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;; /*!50003 SET @saved_time_zone = @@time_zone */ ;; @@ -8735,14 +8914,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `ekt_load` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `ekt_load`(IN `vSelf` INT) proc:BEGIN @@ -8889,7 +9068,7 @@ proc:BEGIN ,`grouping` ,quantity ,groupingMode - ,packageFk + ,packagingFk ,weight ) SELECT @@ -8902,7 +9081,7 @@ proc:BEGIN ,IFNULL(b.`grouping`, e.pac) ,@pac * e.qty ,vForceToPacking - ,IF(vHasToChangePackagingFk OR ISNULL(b.packageFk), vPackage, b.packageFk) + ,IF(vHasToChangePackagingFk OR ISNULL(b.packagingFk), vPackage, b.packagingFk) ,(IFNULL(i.weightByPiece,0) * @pac)/1000 FROM edi.ekt e LEFT JOIN vn.buy b ON b.id = vBuy @@ -11491,6 +11670,7 @@ CREATE TABLE `tpvTransaction` ( KEY `user_id` (`clientFk`), KEY `response` (`response`), KEY `error_code` (`errorCode`), + KEY `tpvTransaction_status_IDX` (`status`,`receiptFk`) USING BTREE, CONSTRAINT `receipt_id` FOREIGN KEY (`receiptFk`) REFERENCES `vn`.`receipt` (`Id`) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT `tpvTransaction_ibfk_1` FOREIGN KEY (`clientFk`) REFERENCES `vn`.`client` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `tpvTransaction_ibfk_2` FOREIGN KEY (`merchantFk`) REFERENCES `tpvMerchant` (`id`) ON DELETE CASCADE ON UPDATE CASCADE @@ -11905,14 +12085,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `item_getVisible` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `item_getVisible`( vWarehouse TINYINT, @@ -12002,14 +12182,14 @@ BEGIN ENGINE = MEMORY SELECT * FROM ( - SELECT b.itemFk, b.packageFk, b.packing + SELECT b.itemFk, b.packagingFk, b.packing FROM vn.buy b JOIN vn.entry e ON e.id = b.entryFk JOIN vn.travel t ON t.id = e.travelFk WHERE t.landed BETWEEN vDateInv AND vDate AND NOT b.isIgnored AND b.price2 >= 0 - AND b.packageFk IS NOT NULL + AND b.packagingFk IS NOT NULL ORDER BY t.warehouseInFk = vWarehouse DESC, t.landed DESC LIMIT 10000000000000000000 ) t GROUP BY itemFk; @@ -12026,10 +12206,10 @@ BEGIN JOIN `filter` f ON f.itemFk = i.id JOIN currentStock s ON s.itemFk = i.id LEFT JOIN tmp t ON t.itemFk = i.id - LEFT JOIN vn.packaging p ON p.id = t.packageFk + LEFT JOIN vn.packaging p ON p.id = t.packagingFk WHERE CEIL(s.quantity / t.packing) > 0 -- FIXME: Column Cubos.box not included in view vn.packaging - /* AND p.box */; + /* AND p.box */ ; DROP TEMPORARY TABLE `filter`, @@ -12921,6 +13101,7 @@ BEGIN DECLARE vRow INT; DECLARE vAdd INT; DECLARE vAvailable INT; + DECLARE vMinQuantity INT; DECLARE vDone BOOL; DECLARE vGrouping INT; DECLARE vRate INT; @@ -12951,15 +13132,23 @@ BEGIN FROM tmp.zoneGetShipped WHERE warehouseFk = vWarehouse; - SELECT available INTO vAvailable + SELECT IFNULL(available, 0) INTO vAvailable FROM tmp.ticketLot WHERE warehouseFk = vWarehouse AND itemFk = vItem; - IF vAmount > IFNULL(vAvailable, 0) THEN + IF vAmount > vAvailable THEN CALL util.throw ('ORDER_ROW_UNAVAILABLE'); END IF; + SELECT IFNULL(minQuantity, 0) INTO vMinQuantity + FROM vn.item + WHERE id = vItem; + + IF vAmount < LEAST(vMinQuantity, vAvailable) THEN + CALL util.throw ('quantityLessThanMin'); + END IF; + OPEN cur; l: LOOP @@ -13474,18 +13663,25 @@ BEGIN END IF; -- Busca un ticket existente que coincida con los parametros - + WITH tPrevia AS + (SELECT DISTINCT s.ticketFk + FROM vn.sale s + JOIN vn.saleGroupDetail sgd ON sgd.saleFk = s.id + JOIN vn.ticket t ON t.id = s.ticketFk + WHERE t.shipped BETWEEN vShipment AND util.dayend(vShipment) + ) SELECT t.id INTO vTicket FROM vn.ticket t + LEFT JOIN tPrevia tp ON tp.ticketFk = t.id LEFT JOIN vn.ticketState tls on tls.ticket = t.id - JOIN `order` o + JOIN hedera.`order` o ON o.address_id = t.addressFk AND vWarehouse = t.warehouseFk - -- AND o.agency_id = t.agencyModeFk AND o.date_send = t.landed - AND vShipment = DATE(t.shipped) + AND DATE(t.shipped) = vShipment WHERE o.id = vSelf AND t.refFk IS NULL + AND tp.ticketFk IS NULL AND IFNULL(tls.alertLevel,0) = 0 LIMIT 1; @@ -13556,7 +13752,8 @@ BEGIN IF vSale THEN UPDATE vn.sale - SET quantity = quantity + vAmount + SET quantity = quantity + vAmount, + originalQuantity = quantity WHERE id = vSale; SELECT s.quantity INTO vNewQuantity @@ -15288,6 +15485,7 @@ SET character_set_client = utf8; /*!50001 CREATE VIEW `sipConf` AS SELECT 1 AS `id`, 1 AS `name`, + 1 AS `regexten`, 1 AS `callbackextension`, 1 AS `md5secret`, 1 AS `callerid`, @@ -15298,10 +15496,12 @@ SET character_set_client = utf8; 1 AS `context`, 1 AS `incominglimit`, 1 AS `pickupgroup`, - 1 AS `careinvite`, + 1 AS `directmedia`, 1 AS `insecure`, 1 AS `transport`, 1 AS `nat`, + 1 AS `disallow`, + 1 AS `allow`, 1 AS `ipaddr`, 1 AS `regseconds`, 1 AS `port`, @@ -15328,11 +15528,9 @@ CREATE TABLE `sipConfig` ( `context` varchar(80) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `incomingLimit` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `pickupGroup` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - `careInvite` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + `directMedia` enum('yes','no') DEFAULT NULL, `insecure` varchar(45) NOT NULL, `transport` varchar(255) DEFAULT NULL, - `avpf` varchar(255) DEFAULT NULL, - `icesupport` varchar(255) DEFAULT NULL, `encryption` varchar(255) DEFAULT NULL, `dtlsenable` varchar(255) DEFAULT NULL, `dtlverify` varchar(255) DEFAULT NULL, @@ -15340,6 +15538,9 @@ CREATE TABLE `sipConfig` ( `dtlsprivatekey` varchar(255) DEFAULT NULL, `dtlssetup` varchar(255) DEFAULT NULL, `nat` varchar(255) DEFAULT NULL, + `disallow` varchar(100) DEFAULT 'all', + `allow` varchar(100) DEFAULT 'g729;ilbc;gsm;ulaw;alaw', + `qualify` enum('yes','no') DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Default values for SIP accounts'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -19499,6 +19700,20 @@ CREATE TABLE `version` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `versionConfig` +-- + +DROP TABLE IF EXISTS `versionConfig`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `versionConfig` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `realm` varchar(16) DEFAULT NULL COMMENT 'Data set on which the project runs', + PRIMARY KEY (`id`) +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `versionLog` -- @@ -21635,6 +21850,20 @@ CREATE TABLE `addressObservation` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Observaciones de los consignatarios'; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `addressShortage` +-- + +DROP TABLE IF EXISTS `addressShortage`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `addressShortage` ( + `addressFk` int(11) NOT NULL, + PRIMARY KEY (`addressFk`), + CONSTRAINT `addressShortage_FK` FOREIGN KEY (`addressFk`) REFERENCES `address` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `agency` -- @@ -22301,52 +22530,6 @@ CREATE TABLE `bookingPlanner` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; --- --- Table structure for table `botanicExport` --- - -DROP TABLE IF EXISTS `botanicExport`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `botanicExport` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `ediGenusFk` mediumint(8) unsigned NOT NULL, - `ediSpecieFk` mediumint(8) unsigned DEFAULT NULL, - `countryFk__` mediumint(8) unsigned DEFAULT NULL, - `restriction` enum('Sin restriccion','Importacion Prohibida','pasaporte fitosanitario','pasaporte individual','declaracion origen') CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - `description` varchar(45) DEFAULT NULL, - `isProtectedZone` tinyint(1) NOT NULL DEFAULT 0, - `code` enum('importProhibited','phytosanitaryPassport','individualPassport') DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `Id_Paises` (`countryFk__`), - KEY `botanicExport_ibfk_2_idx` (`ediGenusFk`), - KEY `botanicExport_ibfk_3_idx` (`ediSpecieFk`), - CONSTRAINT `botanicExport_ibfk_1` FOREIGN KEY (`countryFk__`) REFERENCES `country` (`id`) -) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Especifica los generos y especies prohibidos en paises'; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -DELIMITER ;; -/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`botanicExport_beforeInsert` - BEFORE INSERT ON `botanicExport` - FOR EACH ROW -BEGIN - IF (SELECT botanicExport_isUpdatable (NEW.ediGenusFk, NEW.ediSpecieFk, NEW.restriction) ) > 0 THEN - CALL util.throw ('Datos duplicados'); - END IF; -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; - -- -- Table structure for table `budget` -- @@ -22506,7 +22689,7 @@ CREATE TABLE `business` ( `workerBusinessProfessionalCategoryFk` int(11) DEFAULT NULL, `calendarTypeFk` int(11) DEFAULT 1, `isHourlyLabor` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Contrato por horas', - `workcenterFk` int(11) DEFAULT NULL, + `workcenterFk` int(11) NOT NULL DEFAULT 9, `rate` int(11) DEFAULT NULL, `workerBusinessCategoryFk` int(11) DEFAULT NULL, `workerBusinessTypeFk` int(11) DEFAULT NULL, @@ -22766,7 +22949,7 @@ CREATE TABLE `buy` ( `comissionValue` decimal(10,3) NOT NULL DEFAULT 0.000, `packageValue` decimal(10,3) NOT NULL DEFAULT 0.000, `location` varchar(5) DEFAULT NULL, - `packageFk` varchar(10) DEFAULT '--', + `packagingFk` varchar(10) DEFAULT '--', `price1` decimal(10,2) DEFAULT 0.00, `price2` decimal(10,2) DEFAULT 0.00, `price3` decimal(10,2) DEFAULT 0.00, @@ -22782,9 +22965,10 @@ CREATE TABLE `buy` ( `deliveryFk` int(11) DEFAULT NULL, `itemOriginalFk` int(11) DEFAULT NULL COMMENT 'Item original de la entrada', `editorFk` int(10) unsigned DEFAULT NULL, + `packageFk` varchar(10) GENERATED ALWAYS AS (`packagingFk`) VIRTUAL, PRIMARY KEY (`id`), KEY `CompresId_Trabajador` (`workerFk`), - KEY `Id_Cubo` (`packageFk`), + KEY `Id_Cubo` (`packagingFk`), KEY `Id_Entrada` (`entryFk`), KEY `container_id` (`containerFk`), KEY `buy_edi_id` (`ektFk`), @@ -22799,7 +22983,7 @@ CREATE TABLE `buy` ( CONSTRAINT `buy_fk_4` FOREIGN KEY (`deliveryFk`) REFERENCES `edi`.`deliveryInformation` (`ID`) ON DELETE SET NULL ON UPDATE SET NULL, CONSTRAINT `buy_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), CONSTRAINT `buy_ibfk_1` FOREIGN KEY (`itemFk`) REFERENCES `item` (`id`) ON UPDATE CASCADE, - CONSTRAINT `buy_ibfk_2` FOREIGN KEY (`packageFk`) REFERENCES `packaging` (`id`) ON UPDATE CASCADE, + CONSTRAINT `buy_ibfk_2` FOREIGN KEY (`packagingFk`) REFERENCES `packaging` (`id`) ON UPDATE CASCADE, CONSTRAINT `buy_id` FOREIGN KEY (`entryFk`) REFERENCES `entry` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, CONSTRAINT `buy_itemfk` FOREIGN KEY (`itemFk`) REFERENCES `item` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci ROW_FORMAT=DYNAMIC; @@ -22994,11 +23178,11 @@ DELIMITER ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`buy_afterUpdate` AFTER UPDATE ON `buy` @@ -23044,7 +23228,7 @@ trig: BEGIN !(NEW.quantity <=> OLD.quantity) OR !(NEW.packing <=> OLD.packing) OR !(NEW.grouping <=> OLD.grouping) OR - !(NEW.packageFk <=> OLD.packageFk) OR + !(NEW.packagingFk <=> OLD.packagingFk) OR !(NEW.weight <=> OLD.weight) THEN CALL vn.mail_insert( CONCAT(account.user_getNameFromId(vBuyerFk),'@verdnatura.es'), @@ -24029,7 +24213,9 @@ CREATE TABLE `claimResponsible` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `description` varchar(45) NOT NULL, `responsability` tinyint(4) NOT NULL DEFAULT 0 COMMENT 'if=1 >sensib >culpa', - PRIMARY KEY (`id`) + `code` varchar(3) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `claimResponsible_UN` (`code`) ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Responsables de las causas'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -24178,7 +24364,7 @@ CREATE TABLE `client` ( `hasToInvoice` tinyint(1) NOT NULL DEFAULT 1, `isFreezed` tinyint(1) NOT NULL DEFAULT 0, `salesPersonFk` int(10) unsigned DEFAULT NULL, - `credit` decimal(10,2) NOT NULL DEFAULT 0.00, + `credit` decimal(10,2) unsigned NOT NULL DEFAULT 0.00, `countryFk` mediumint(8) unsigned NOT NULL DEFAULT 1, `isActive` tinyint(1) NOT NULL DEFAULT 1, `gestdocFk` int(11) DEFAULT NULL, @@ -24234,6 +24420,7 @@ CREATE TABLE `client` ( KEY `client_FK_3` (`transferorFk`), KEY `codpos` (`postcode`), KEY `client_fk_editor` (`editorFk`), + KEY `client_isTaxDataChecked_IDX` (`isTaxDataChecked`) USING BTREE, CONSTRAINT `canal_nuevo_cliente` FOREIGN KEY (`contactChannelFk`) REFERENCES `contactChannel` (`id`) ON UPDATE CASCADE, CONSTRAINT `client_FK` FOREIGN KEY (`businessTypeFk`) REFERENCES `businessType` (`code`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `client_FK_1` FOREIGN KEY (`bankEntityFk`) REFERENCES `bankEntity` (`id`) ON UPDATE CASCADE, @@ -24287,6 +24474,31 @@ DELIMITER ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`client_AfterInsert` + AFTER INSERT ON `client` + FOR EACH ROW +BEGIN + IF NEW.credit IS NOT NULL AND NEW.credit THEN + INSERT INTO clientCredit + SET clientFk = NEW.id, + workerFk = NEW.editorFk, + amount = NEW.credit; + END IF; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; /*!50003 SET character_set_client = utf8mb4 */ ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; @@ -24298,17 +24510,23 @@ DELIMITER ;; FOR EACH ROW BEGIN DECLARE vText VARCHAR(255) DEFAULT NULL; - DECLARE vPayMethodFk INT; + DECLARE vPayMethodFk INT; SET NEW.editorFk = account.myUser_getId(); + IF NOT(NEW.credit <=> OLD.credit) THEN + INSERT INTO clientCredit + SET clientFk = NEW.id, + amount = NEW.credit, + workerFk = NEW.editorFk; + END IF; -- Comprueba que el formato de los teléfonos es válido IF !(NEW.phone <=> OLD.phone) AND (NEW.phone <> '') THEN CALL pbx.phone_isValid(NEW.phone); END IF; - IF !(NEW.mobile <=> OLD.mobile) AND (NEW.mobile <> '')THEN + IF !(NEW.mobile <=> OLD.mobile) AND (NEW.mobile <> '')THEN CALL pbx.phone_isValid(NEW.mobile); END IF; @@ -24318,7 +24536,7 @@ BEGIN IF NEW.payMethodFk = vPayMethodFk AND NEW.dueDay = 0 THEN SET NEW.dueDay = 5; - END IF; + END IF; -- Avisar al comercial si ha llegado la documentación sepa/core @@ -24331,12 +24549,12 @@ BEGIN END IF; IF vText IS NOT NULL - THEN + THEN INSERT INTO mail(receiver, replyTo, `subject`, body) SELECT CONCAT(IF(ac.id,u.name, 'jgallego'), '@verdnatura.es'), - 'administracion@verdnatura.es', - CONCAT('Cliente ', NEW.id), + 'administracion@verdnatura.es', + CONCAT('Cliente ', NEW.id), CONCAT('Recibida la documentación: ', vText) FROM worker w LEFT JOIN account.user u ON w.id = u.id AND u.active @@ -24344,10 +24562,10 @@ BEGIN WHERE w.id = NEW.salesPersonFk; END IF; - IF NEW.salespersonFk IS NULL AND OLD.salespersonFk IS NOT NULL THEN + IF NEW.salespersonFk IS NULL AND OLD.salespersonFk IS NOT NULL THEN IF (SELECT COUNT(clientFk) FROM clientProtected - WHERE clientFk = NEW.id + WHERE clientFk = NEW.id ) > 0 THEN CALL util.throw("HAS_CLIENT_PROTECTED"); END IF; @@ -24360,7 +24578,6 @@ BEGIN IF !(NEW.businessTypeFk <=> OLD.businessTypeFk) AND (NEW.businessTypeFk = 'individual' OR OLD.businessTypeFk = 'individual') THEN SET NEW.isTaxDataChecked = 0; END IF; - END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -24509,6 +24726,8 @@ CREATE TABLE `clientContact` ( `editorFk` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`), KEY `clientContact_fk_editor` (`editorFk`), + KEY `clientContact_FK` (`clientFk`), + CONSTRAINT `clientContact_FK` FOREIGN KEY (`clientFk`) REFERENCES `client` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `clientContact_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`) ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -24980,7 +25199,7 @@ DROP TABLE IF EXISTS `clientSample`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `clientSample` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `clientFk` int(10) unsigned NOT NULL, + `clientFk` int(11) NOT NULL, `typeFk` int(10) unsigned NOT NULL, `created` datetime NOT NULL DEFAULT current_timestamp(), `workerFk` int(10) unsigned NOT NULL, @@ -24991,7 +25210,9 @@ CREATE TABLE `clientSample` ( PRIMARY KEY (`id`), KEY `empresa_id` (`companyFk`), KEY `clientSample_fk_editor` (`editorFk`), + KEY `clientSample_FK` (`clientFk`), CONSTRAINT `clientSampleCompany_Fk` FOREIGN KEY (`companyFk`) REFERENCES `company` (`id`) ON UPDATE CASCADE, + CONSTRAINT `clientSample_FK` FOREIGN KEY (`clientFk`) REFERENCES `client` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `clientSample_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`) ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -25138,7 +25359,7 @@ DROP TABLE IF EXISTS `cmr`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `cmr` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `ticketFk` int(11) DEFAULT NULL COMMENT 'refs #6092 @toDeprecate 2023-08-02', + `ticketFk__` int(11) DEFAULT NULL COMMENT '@deprecated 2023-10-20 refs #6092', `truckPlate` varchar(30) DEFAULT NULL, `observations` varchar(255) DEFAULT NULL, `senderInstruccions` varchar(255) DEFAULT NULL, @@ -25155,14 +25376,14 @@ CREATE TABLE `cmr` ( `landed` datetime DEFAULT NULL COMMENT 'Hora de llegada a destino', `ead` datetime DEFAULT NULL COMMENT 'Estimated Arriving Date', PRIMARY KEY (`id`), - KEY `cmr_fk1_idx` (`ticketFk`), + KEY `cmr_fk1_idx` (`ticketFk__`), KEY `cmr_fk2_idx` (`companyFk`), KEY `cmr_fk3_idx` (`addressToFk`), KEY `cm_fk4_idx` (`supplierFk`), KEY `cmr_FK` (`addressFromFk`), CONSTRAINT `cmrCompany_Fk` FOREIGN KEY (`companyFk`) REFERENCES `company` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT `cmr_FK` FOREIGN KEY (`addressFromFk`) REFERENCES `address` (`id`) ON UPDATE CASCADE, - CONSTRAINT `cmr_fk1` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`), + CONSTRAINT `cmr_fk1` FOREIGN KEY (`ticketFk__`) REFERENCES `ticket` (`id`), CONSTRAINT `cmr_fk3` FOREIGN KEY (`addressToFk`) REFERENCES `address` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT `cmr_supplierFk` FOREIGN KEY (`supplierFk`) REFERENCES `supplier` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; @@ -25223,51 +25444,6 @@ CREATE TABLE `cmrPallet` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='relaciona los cmr con los pallets de expediciones'; /*!40101 SET character_set_client = @saved_cs_client */; --- --- Temporary table structure for view `cmr_list` --- - -DROP TABLE IF EXISTS `cmr_list`; -/*!50001 DROP VIEW IF EXISTS `cmr_list`*/; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; -/*!50001 CREATE VIEW `cmr_list` AS SELECT - 1 AS `cmrFk`, - 1 AS `ticketFk`, - 1 AS `truckPlate`, - 1 AS `observations`, - 1 AS `senderInstruccions`, - 1 AS `paymentInstruccions`, - 1 AS `specialAgreements`, - 1 AS `created`, - 1 AS `packagesList`, - 1 AS `clientName`, - 1 AS `clientPostalCode`, - 1 AS `clientStreet`, - 1 AS `clientCity`, - 1 AS `clientProvince`, - 1 AS `clientCountry`, - 1 AS `companyName`, - 1 AS `companyStreet`, - 1 AS `companyPostCode`, - 1 AS `companyCity`, - 1 AS `companyCountry`, - 1 AS `warehouseAddress`, - 1 AS `shipped`, - 1 AS `clientOficialName`, - 1 AS `supplierFk`, - 1 AS `carrierName`, - 1 AS `carrierStreet`, - 1 AS `carrierPostCode`, - 1 AS `carrierCity`, - 1 AS `carrierCountry`, - 1 AS `phone`, - 1 AS `mobile`, - 1 AS `addressFk`, - 1 AS `stamp`, - 1 AS `merchandiseDetail` */; -SET character_set_client = @saved_cs_client; - -- -- Table structure for table `collection` -- @@ -25448,6 +25624,140 @@ CREATE TABLE `collectionVolumetry` ( CONSTRAINT `collectionVolumetry_FK_1` FOREIGN KEY (`trainFk`) REFERENCES `train` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`collectionVolumetry_afterInsert` + AFTER INSERT ON `collectionVolumetry` + FOR EACH ROW +BEGIN + DECLARE vJSON JSON DEFAULT JSON_OBJECT(); + DECLARE vUserFk INT DEFAULT account.myUser_getId(); + + SET vJSON = JSON_MERGE(JSON_OBJECT('id', NEW.id), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('level', NEW.level), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('lines', NEW.lines), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('liters', NEW.liters), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('height', NEW.height), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('itemPackingTypeFk', NEW.itemPackingTypeFk), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('trainFk', NEW.trainFk), vJSON); + + SET vJSON = JSON_MERGE(JSON_OBJECT('userFk', vUserFk), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('action', 'insert'), vJSON); + + SET vJSON = util.notification_send( + 'modified-collection-volumetry', + JSON_OBJECT('data', JSON_EXTRACT(vJSON, '$')), + vUserFk + ); +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`collectionVolumetry_afterUpdate` + AFTER UPDATE ON `collectionVolumetry` + FOR EACH ROW +BEGIN + DECLARE vJSON JSON DEFAULT JSON_OBJECT(); + DECLARE vUserFk INT DEFAULT account.myUser_getId(); + + IF NOT (NEW.id <=> OLD.id) THEN + SET vJSON = JSON_MERGE(JSON_OBJECT('id', NEW.id), vJSON); + END IF; + + IF NOT (NEW.`level` <=> OLD.`level`) THEN + SET vJSON = JSON_MERGE(JSON_OBJECT('level', NEW.`level`), vJSON); + END IF; + + IF NOT (NEW.`lines` <=> OLD.`lines`) THEN + SET vJSON = JSON_MERGE(JSON_OBJECT('lines', NEW.`lines`), vJSON); + END IF; + + IF NOT (NEW.liters <=> OLD.liters) THEN + SET vJSON = JSON_MERGE(JSON_OBJECT('liters', NEW.liters), vJSON); + END IF; + + IF NOT (NEW.height <=> OLD.height) THEN + SET vJSON = JSON_MERGE(JSON_OBJECT('height', NEW.height), vJSON); + END IF; + + IF NOT (NEW.itemPackingTypeFk <=> OLD.itemPackingTypeFk) THEN + SET vJSON = JSON_MERGE(JSON_OBJECT('itemPackingTypeFk', NEW.itemPackingTypeFk), vJSON); + END IF; + + IF NOT (NEW.trainFk <=> OLD.trainFk) THEN + SET vJSON = JSON_MERGE(JSON_OBJECT('trainFk', NEW.trainFk), vJSON); + END IF; + + SET vJSON = JSON_MERGE(JSON_OBJECT('userFk', vUserFk), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('action', 'update'), vJSON); + + SET vJSON = util.notification_send( + 'modified-collection-volumetry', + JSON_OBJECT('data', JSON_EXTRACT(vJSON, '$')), + vUserFk + ); +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`collectionVolumetry_afterDelete` + AFTER DELETE ON `collectionVolumetry` + FOR EACH ROW +BEGIN + DECLARE vJSON JSON DEFAULT JSON_OBJECT(); + DECLARE vUserFk INT DEFAULT account.myUser_getId(); + + SET vJSON = JSON_MERGE(JSON_OBJECT('id', OLD.id), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('level', OLD.level), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('lines', OLD.lines), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('liters', OLD.liters), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('height', OLD.height), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('itemPackingTypeFk', OLD.itemPackingTypeFk), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('trainFk', OLD.trainFk), vJSON); + + SET vJSON = JSON_MERGE(JSON_OBJECT('userFk', vUserFk), vJSON); + SET vJSON = JSON_MERGE(JSON_OBJECT('action', 'delete'), vJSON); + + SET vJSON = util.notification_send( + 'modified-collection-volumetry', + JSON_OBJECT('data', JSON_EXTRACT(vJSON, '$')), + vUserFk + ); +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; -- -- Table structure for table `collectionWagon` @@ -25458,14 +25768,14 @@ DROP TABLE IF EXISTS `collectionWagon`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `collectionWagon` ( `collectionFk` int(11) NOT NULL, - `wagonFk` int(11) NOT NULL, + `wagonFk` varchar(6) NOT NULL, `position` int(11) unsigned NOT NULL, PRIMARY KEY (`collectionFk`,`position`), UNIQUE KEY `collectionWagon_unique` (`collectionFk`,`wagonFk`), - KEY `collectionWagon_wagon` (`wagonFk`), - CONSTRAINT `collectionWagon_collection` FOREIGN KEY (`collectionFk`) REFERENCES `collection` (`id`) ON UPDATE CASCADE, - CONSTRAINT `collectionWagon_wagon` FOREIGN KEY (`wagonFk`) REFERENCES `wagon` (`id`) ON UPDATE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; + KEY `collectionWagon_FK_1` (`wagonFk`), + CONSTRAINT `collectionWagon_FK_1` FOREIGN KEY (`wagonFk`) REFERENCES `wagon` (`id`) ON UPDATE CASCADE, + CONSTRAINT `collectionWagon_collection` FOREIGN KEY (`collectionFk`) REFERENCES `collection` (`id`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -25477,16 +25787,18 @@ DROP TABLE IF EXISTS `collectionWagonTicket`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `collectionWagonTicket` ( `ticketFk` int(11) NOT NULL, - `wagonFk` int(11) NOT NULL, + `wagonFk` varchar(6) NOT NULL, `trayFk` int(11) unsigned NOT NULL, - `side` set('L','R') DEFAULT NULL, - PRIMARY KEY (`ticketFk`), - KEY `collectionWagonTicket_wagon` (`wagonFk`), + `side` set('L','R') CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + `rgb` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 'Color de la balda', + `height` int(11) DEFAULT NULL COMMENT 'altura de la balda', + PRIMARY KEY (`ticketFk`,`trayFk`), KEY `collectionWagonTicket_tray` (`trayFk`), - CONSTRAINT `collectionWagonTicket_ticket` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`) ON UPDATE CASCADE, - CONSTRAINT `collectionWagonTicket_tray` FOREIGN KEY (`trayFk`) REFERENCES `wagonTypeTray` (`id`) ON UPDATE CASCADE, - CONSTRAINT `collectionWagonTicket_wagon` FOREIGN KEY (`wagonFk`) REFERENCES `wagon` (`id`) ON UPDATE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; + KEY `collectionWagonTicket_FK_1` (`wagonFk`), + CONSTRAINT `collectionWagonTicket_FK` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`) ON UPDATE CASCADE, + CONSTRAINT `collectionWagonTicket_FK_1` FOREIGN KEY (`wagonFk`) REFERENCES `wagon` (`id`) ON UPDATE CASCADE, + CONSTRAINT `collectionWagonTicket_tray` FOREIGN KEY (`trayFk`) REFERENCES `wagonTypeTray` (`id`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -25609,6 +25921,23 @@ SET character_set_client = utf8; 1 AS `footnotes` */; SET character_set_client = @saved_cs_client; +-- +-- Table structure for table `comparativeConfig` +-- + +DROP TABLE IF EXISTS `comparativeConfig`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `comparativeConfig` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `defaultDayRange` int(10) unsigned DEFAULT NULL COMMENT 'Rango de días predeterminado si no se especifica', + `weekRange` int(10) unsigned DEFAULT NULL COMMENT 'La cantidad de semanas que se restarán y sumarán', + `maxDayRange` int(10) unsigned DEFAULT NULL COMMENT 'El rango máximo de días antes de utilizar el rango de días predeterminado', + `minDayRange` int(10) unsigned DEFAULT NULL COMMENT 'El rango mínimo de días antes de utilizar el rango de días predeterminado', + PRIMARY KEY (`id`) +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `comparativeFilterType` -- @@ -26062,34 +26391,6 @@ CREATE TABLE `cplusCorrectingType` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; --- --- Table structure for table `cplusInvoiceType472` --- - -DROP TABLE IF EXISTS `cplusInvoiceType472`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `cplusInvoiceType472` ( - `id` int(10) unsigned NOT NULL, - `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='(*18) TIPO FACTURA (Asientos)SOPORTADO – DEDUCIBLE (472)'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `siiTypeInvoiceOut` --- - -DROP TABLE IF EXISTS `siiTypeInvoiceOut`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `siiTypeInvoiceOut` ( - `id` int(10) unsigned NOT NULL, - `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='(*18) TIPO FACTURA (Asientos)REPERCUTIDO - DEVENGADO (477)'; -/*!40101 SET character_set_client = @saved_cs_client */; - -- -- Table structure for table `cplusRectificationType` -- @@ -26146,34 +26447,6 @@ CREATE TABLE `cplusTerIdNif` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; --- --- Table structure for table `cplusTrascendency472` --- - -DROP TABLE IF EXISTS `cplusTrascendency472`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `cplusTrascendency472` ( - `id` int(10) unsigned NOT NULL, - `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='(*15) CLAVE DE RÉGIMEN ESPECIAL O TRASCENDENCIA(Asientos)SOPORTADO – DEDUCIBLE (472)'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `cplusTrascendency477` --- - -DROP TABLE IF EXISTS `cplusTrascendency477`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `cplusTrascendency477` ( - `id` int(10) unsigned NOT NULL, - `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='(*15) CLAVE DE RÉGIMEN ESPECIAL O TRASCENDENCIA(Asientos) REPERCUTIDO - DEVENGADO (477)'; -/*!40101 SET character_set_client = @saved_cs_client */; - -- -- Table structure for table `creditClassification` -- @@ -27340,18 +27613,15 @@ DROP TABLE IF EXISTS `duaTax`; CREATE TABLE `duaTax` ( `id` int(11) NOT NULL AUTO_INCREMENT, `duaFk` int(11) NOT NULL, - `supplierFk` int(10) unsigned NOT NULL, `taxClassFk` tinyint(3) unsigned NOT NULL, `base` decimal(10,2) NOT NULL, `rate` decimal(5,2) NOT NULL, `tax` decimal(10,2) NOT NULL, PRIMARY KEY (`id`), KEY `fk_dua_tax_awb_dua1_idx` (`duaFk`), - KEY `duaTax_fk2_idx` (`supplierFk`), KEY `duaTax_fk3_idx` (`taxClassFk`), CONSTRAINT `duaTax_fk1` FOREIGN KEY (`duaFk`) REFERENCES `dua` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `duaTax_fk3` FOREIGN KEY (`taxClassFk`) REFERENCES `taxClass` (`id`) ON UPDATE CASCADE, - CONSTRAINT `duaTax_supplierFk` FOREIGN KEY (`supplierFk`) REFERENCES `supplier` (`id`) ON UPDATE CASCADE + CONSTRAINT `duaTax_fk3` FOREIGN KEY (`taxClassFk`) REFERENCES `taxClass` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; @@ -28049,31 +28319,6 @@ CREATE TABLE `errorLogApp` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Guarda un registro de errores e la app de almacén'; /*!40101 SET character_set_client = @saved_cs_client */; --- --- Table structure for table `errorProduction` --- - -DROP TABLE IF EXISTS `errorProduction`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `errorProduction` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `userFk` int(11) DEFAULT NULL, - `firstname` varchar(100) DEFAULT NULL, - `lastname` varchar(100) DEFAULT NULL, - `rol` varchar(100) DEFAULT NULL, - `ticketNumber` int(11) DEFAULT NULL, - `lineNumber` int(11) DEFAULT NULL, - `error` int(11) DEFAULT NULL, - `volume` double DEFAULT NULL, - `hourStart` varchar(100) DEFAULT NULL, - `hourEnd` varchar(100) DEFAULT NULL, - `hourWorked` varchar(100) DEFAULT NULL, - `dated` date DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - -- -- Table structure for table `erte` -- @@ -28197,6 +28442,10 @@ CREATE TABLE `expedition` ( `hasNewRoute` tinyint(1) NOT NULL DEFAULT 0, `isBox` int(11) GENERATED ALWAYS AS (`freightItemFk`) VIRTUAL COMMENT 'Columna virtual provisional para Salix', `editorFk` int(10) unsigned DEFAULT NULL, + `packingSiteFk` int(11) DEFAULT NULL, + `monitorId` varchar(255) DEFAULT NULL, + `started` timestamp NOT NULL, + `ended` timestamp NOT NULL, PRIMARY KEY (`id`), KEY `index1` (`agencyModeFk`), KEY `index2` (`freightItemFk`), @@ -28207,7 +28456,9 @@ CREATE TABLE `expedition` ( KEY `workerFk` (`workerFk`), KEY `expedition_FK` (`stateTypeFk`), KEY `expedition_fk_editor` (`editorFk`), + KEY `expedition_FK_1` (`packingSiteFk`), CONSTRAINT `expedition_FK` FOREIGN KEY (`stateTypeFk`) REFERENCES `expeditionStateType` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `expedition_FK_1` FOREIGN KEY (`packingSiteFk`) REFERENCES `packingSite` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT `expedition_fk1` FOREIGN KEY (`agencyModeFk`) REFERENCES `agencyMode` (`id`) ON UPDATE CASCADE, CONSTRAINT `expedition_fk2` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `expedition_fk3` FOREIGN KEY (`packagingFk`) REFERENCES `packaging` (`id`) ON UPDATE CASCADE, @@ -28596,19 +28847,17 @@ CREATE TABLE `expeditionState` ( /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb3 */ ; -/*!50003 SET character_set_results = utf8mb3 */ ; -/*!50003 SET collation_connection = utf8mb3_general_ci */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER expeditionState_BeforeInsert -BEFORE INSERT -ON expeditionState FOR EACH ROW +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`expeditionState_BeforeInsert` + BEFORE INSERT ON `expeditionState` + FOR EACH ROW BEGIN - - SET NEW.userFk = account.myUser_getId(); - + SET NEW.userFk = IFNULL(NEW.userFk, account.myUser_getId()); END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -29165,7 +29414,7 @@ DROP TABLE IF EXISTS `greuge`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `greuge` ( `Id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `clientFk` int(10) unsigned NOT NULL, + `clientFk` int(11) NOT NULL, `description` varchar(45) NOT NULL, `amount` decimal(10,2) NOT NULL, `shipped` datetime NOT NULL DEFAULT current_timestamp(), @@ -29183,6 +29432,7 @@ CREATE TABLE `greuge` ( KEY `greuge_fk_editor` (`editorFk`), CONSTRAINT `Id_Ticket_Greuge_Ticket` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `greuge_FK` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `greuge_FK_1` FOREIGN KEY (`clientFk`) REFERENCES `client` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `greuge_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), CONSTRAINT `greuges_type_fk` FOREIGN KEY (`greugeTypeFk`) REFERENCES `greugeType` (`id`) ON DELETE SET NULL ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci ROW_FORMAT=COMPACT; @@ -29604,11 +29854,11 @@ CREATE TABLE `invoiceIn` ( `docFk` int(11) DEFAULT NULL, `booked` date DEFAULT NULL COMMENT 'Fecha de contabilizacion', `operated` date DEFAULT NULL COMMENT 'Fecha de entrega de la mercancia o el suministro', - `cplusInvoiceType472Fk` int(10) unsigned DEFAULT 1, + `siiTypeInvoiceInFk` int(10) unsigned DEFAULT 1, `cplusRectificationTypeFk` int(10) unsigned DEFAULT 1, `cplusSubjectOpFk` int(10) unsigned DEFAULT 1, `cplusTaxBreakFk` int(10) unsigned DEFAULT 1, - `cplusTrascendency472Fk` int(10) unsigned DEFAULT 1, + `siiTrascendencyInvoiceInFk` int(10) unsigned DEFAULT 1, `bookEntried` date DEFAULT NULL COMMENT 'Fecha Asiento', `isVatDeductible` tinyint(1) NOT NULL DEFAULT 1, `withholdingSageFk` smallint(6) DEFAULT NULL COMMENT 'Tipos de retención SAGE', @@ -29623,9 +29873,9 @@ CREATE TABLE `invoiceIn` ( KEY `fecha` (`issued`), KEY `recibida_ibfk_3_idx` (`cplusSubjectOpFk`), KEY `recibida_ibfk_4_idx` (`cplusTaxBreakFk`), - KEY `recibida_ibfk_5_idx` (`cplusInvoiceType472Fk`), + KEY `recibida_ibfk_5_idx` (`siiTypeInvoiceInFk`), KEY `recibida_ibfk_6` (`cplusRectificationTypeFk`), - KEY `recibida_ibfk_7` (`cplusTrascendency472Fk`), + KEY `recibida_ibfk_7` (`siiTrascendencyInvoiceInFk`), KEY `invoiceIn_withholdingFk_idx` (`withholdingSageFk`), KEY `invoiceIn_expenceFkDeductible_idx` (`expenceFkDeductible`), KEY `invoiceIn_fk_editor` (`editorFk`), @@ -29636,9 +29886,9 @@ CREATE TABLE `invoiceIn` ( CONSTRAINT `invoiceIn_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), CONSTRAINT `invoiceIn_ibfk_3` FOREIGN KEY (`cplusSubjectOpFk`) REFERENCES `cplusSubjectOp` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceIn_ibfk_4` FOREIGN KEY (`cplusTaxBreakFk`) REFERENCES `cplusTaxBreak` (`id`) ON UPDATE CASCADE, - CONSTRAINT `invoiceIn_ibfk_5` FOREIGN KEY (`cplusInvoiceType472Fk`) REFERENCES `cplusInvoiceType472` (`id`) ON UPDATE CASCADE, + CONSTRAINT `invoiceIn_ibfk_5` FOREIGN KEY (`siiTypeInvoiceInFk`) REFERENCES `siiTypeInvoiceIn` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceIn_ibfk_6` FOREIGN KEY (`cplusRectificationTypeFk`) REFERENCES `cplusRectificationType` (`id`) ON UPDATE CASCADE, - CONSTRAINT `invoiceIn_ibfk_7` FOREIGN KEY (`cplusTrascendency472Fk`) REFERENCES `cplusTrascendency472` (`id`) ON UPDATE CASCADE, + CONSTRAINT `invoiceIn_ibfk_7` FOREIGN KEY (`siiTrascendencyInvoiceInFk`) REFERENCES `siiTrascendencyInvoiceIn` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceIn_supplierFk` FOREIGN KEY (`supplierFk`) REFERENCES `supplier` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceIn_withholdingFk` FOREIGN KEY (`withholdingSageFk`) REFERENCES `sage`.`TiposRetencion` (`CodigoRetencion`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; @@ -29825,6 +30075,7 @@ CREATE TABLE `invoiceInConfig` ( `retentionName` varchar(25) NOT NULL, `sageWithholdingFk` smallint(6) NOT NULL, `daysAgo` int(10) unsigned DEFAULT 45 COMMENT 'Días en el pasado para mostrar facturas en invoiceIn series en salix', + `taxRowLimit` int(11) DEFAULT 4 COMMENT 'Número máximo de líneas de IVA que puede tener una factura', PRIMARY KEY (`id`), KEY `invoiceInConfig_sageWithholdingFk` (`sageWithholdingFk`), CONSTRAINT `invoiceInConfig_sageWithholdingFk` FOREIGN KEY (`sageWithholdingFk`) REFERENCES `sage`.`TiposRetencion` (`CodigoRetencion`) ON DELETE CASCADE ON UPDATE CASCADE @@ -30116,6 +30367,7 @@ DELIMITER ;; BEFORE INSERT ON `invoiceInTax` FOR EACH ROW BEGIN + CALL invoiceInTax_afterUpsert(NEW.invoiceInFk); SET NEW.editorFk = account.myUser_getId(); END */;; DELIMITER ; @@ -30136,6 +30388,10 @@ DELIMITER ;; BEFORE UPDATE ON `invoiceInTax` FOR EACH ROW BEGIN + IF NOT (NEW.invoiceInFk <=> OLD.invoiceInFk) THEN + CALL invoiceInTax_afterUpsert(NEW.invoiceInFk); + END IF; + SET NEW.editorFk = account.myUser_getId(); END */;; DELIMITER ; @@ -30217,7 +30473,7 @@ CREATE TABLE `invoiceOut` ( `siiTypeInvoiceOutFk` int(10) unsigned NOT NULL DEFAULT 1, `cplusTaxBreakFk` int(10) unsigned NOT NULL DEFAULT 1, `cplusSubjectOpFk` int(10) unsigned NOT NULL DEFAULT 1, - `cplusTrascendency477Fk` int(10) unsigned NOT NULL DEFAULT 1, + `siiTrascendencyInvoiceOutFk` int(10) unsigned NOT NULL DEFAULT 1, PRIMARY KEY (`id`,`ref`), UNIQUE KEY `Id_Factura` (`ref`), KEY `Id_Banco` (`bankFk`), @@ -30227,7 +30483,7 @@ CREATE TABLE `invoiceOut` ( KEY `Facturas_ibfk_2_idx` (`siiTypeInvoiceOutFk`), KEY `Facturas_ibfk_3_idx` (`cplusSubjectOpFk`), KEY `Facturas_ibfk_4_idx` (`cplusTaxBreakFk`), - KEY `Facturas_ibfk_5_idx` (`cplusTrascendency477Fk`), + KEY `Facturas_ibfk_5_idx` (`siiTrascendencyInvoiceOutFk`), KEY `Facturas_idx_Vencimiento` (`dued`), KEY `invoiceOut_serial` (`serial`), CONSTRAINT `invoiceOut_ibfk_2` FOREIGN KEY (`siiTypeInvoiceOutFk`) REFERENCES `siiTypeInvoiceOut` (`id`) ON UPDATE CASCADE, @@ -30392,7 +30648,7 @@ CREATE TABLE `invoiceOutSerial` ( `isTaxed` tinyint(1) NOT NULL DEFAULT 1, `taxAreaFk` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'NATIONAL', `isCEE` tinyint(1) NOT NULL DEFAULT 0, - `siiTypeInvoiceOutFk` int(10) unsigned DEFAULT 1, + `cplusInvoiceType477Fk` int(10) unsigned DEFAULT 1, `footNotes` longtext DEFAULT NULL, `isRefEditable` tinyint(4) NOT NULL DEFAULT 0, `type` enum('global','quick') DEFAULT NULL, @@ -30999,6 +31255,7 @@ CREATE TABLE `itemConfig` ( `validPriorities` varchar(50) NOT NULL DEFAULT '[1,2,3]', `defaultPriority` int(11) NOT NULL DEFAULT 2, `warehouseFk` smallint(6) unsigned DEFAULT NULL, + `downloadMaxAttempts` tinyint(3) DEFAULT NULL COMMENT 'Intentos máximos para que se borre', PRIMARY KEY (`id`), KEY `itemConfig_FK` (`defaultTag`), CONSTRAINT `itemConfig_FK` FOREIGN KEY (`defaultTag`) REFERENCES `tag` (`id`) @@ -31375,11 +31632,14 @@ CREATE TABLE `itemShelving` ( `packagingFk` varchar(10) DEFAULT NULL, `userFk` int(10) unsigned DEFAULT NULL, `isChecked` tinyint(1) DEFAULT NULL COMMENT 'Este valor cambia al escanear un carro. True: Existe. False: Nuevo. Null: No escaneado', + `buyFk` int(11) DEFAULT NULL, PRIMARY KEY (`id`), + UNIQUE KEY `itemShelving_UN` (`buyFk`,`shelvingFk`), KEY `itemShelving_fk1_idx` (`itemFk`), KEY `itemShelving_fk2_idx` (`shelvingFk`), KEY `itemShelving_fk3_idx` (`packagingFk`), KEY `itemShelving_fk3_idx1` (`userFk`), + CONSTRAINT `itemShelvingBuy_FK` FOREIGN KEY (`buyFk`) REFERENCES `buy` (`id`), CONSTRAINT `itemShelving_fk1` FOREIGN KEY (`itemFk`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `itemShelving_fk2` FOREIGN KEY (`shelvingFk`) REFERENCES `shelving` (`code`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `itemShelving_fk3` FOREIGN KEY (`packagingFk`) REFERENCES `packaging` (`id`) ON UPDATE CASCADE @@ -31476,23 +31736,16 @@ DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`itemShelving_AFTER_UPDATE` AFTER UPDATE ON `itemShelving` FOR EACH ROW -INSERT INTO vn.itemShelvingLog( itemShelvingFk, - workerFk, - accion, - itemFk, - shelvingFk, - visible, - `grouping`, - packing) - VALUES( NEW.id, - account.myUser_getId(), - 'CAMBIO', - NEW.itemFk, - NEW.shelvingFk, - NEW.visible, - NEW.`grouping`, - NEW.packing - ) */;; + + INSERT INTO itemShelvingLog + SET itemShelvingFk = NEW.id, + workerFk = account.myUser_getId(), + accion = 'CAMBIO', + itemFk = NEW.itemFk, + shelvingFk = NEW.shelvingFk, + visible = NEW.visible, + `grouping` = NEW.`grouping`, + packing = NEW.packing */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -31671,6 +31924,7 @@ CREATE TABLE `itemShelvingSale` ( `quantity` decimal(10,0) NOT NULL DEFAULT 0, `created` timestamp NOT NULL DEFAULT current_timestamp(), `userFk` int(11) unsigned NOT NULL, + `isPicked` tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `itemShelvingSale_fk1_idx` (`itemShelvingFk`), KEY `itemShelvingSale_fk2_idx` (`saleFk`), @@ -31683,11 +31937,11 @@ CREATE TABLE `itemShelvingSale` ( /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`itemShelvingSale_AFTER_INSERT` AFTER INSERT ON `itemShelvingSale` @@ -33385,7 +33639,13 @@ CREATE TABLE `packagingConfig` ( `palletPackaging` varchar(10) DEFAULT 'pallet USA', `carryPackaging` varchar(10) DEFAULT 'cc', `freightItemPackaging` int(11) DEFAULT 71, - PRIMARY KEY (`id`) + `defaultSmallPackageFk` varchar(10) NOT NULL DEFAULT '94p' COMMENT 'bulto pequeño', + `defaultBigPackageFk` varchar(10) NOT NULL DEFAULT '94m' COMMENT 'bulto grande', + PRIMARY KEY (`id`), + KEY `packagingConfig_FK` (`defaultSmallPackageFk`), + KEY `packagingConfig_FK_1` (`defaultBigPackageFk`), + CONSTRAINT `packagingConfig_FK` FOREIGN KEY (`defaultSmallPackageFk`) REFERENCES `packaging` (`id`) ON UPDATE CASCADE, + CONSTRAINT `packagingConfig_FK_1` FOREIGN KEY (`defaultBigPackageFk`) REFERENCES `packaging` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Altura mínima para preparar pedidos en preparacion previa'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -33458,19 +33718,96 @@ CREATE TABLE `packingSite` ( `id` int(11) NOT NULL AUTO_INCREMENT, `code` varchar(10) DEFAULT NULL, `hostFk` int(11) DEFAULT NULL, + `printerRfidFk` tinyint(3) unsigned DEFAULT NULL, `printerFk` tinyint(3) unsigned DEFAULT NULL, `collectionFk` int(11) DEFAULT NULL COMMENT 'Last collection packed on this site', `monitorId` varchar(255) DEFAULT NULL, + `parkingFk` int(11) DEFAULT NULL, + `scannerFk` int(11) DEFAULT NULL, + `screenFk` int(11) DEFAULT NULL, + `editorFk` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `packingSite_UN` (`code`), + UNIQUE KEY `printerRfidFk` (`printerRfidFk`), + UNIQUE KEY `scannerFk` (`scannerFk`), + UNIQUE KEY `screenFk` (`screenFk`), + UNIQUE KEY `packingSite_UNI` (`hostFk`), KEY `packingSite_FK_1` (`printerFk`), - KEY `packingSite_FK` (`hostFk`), KEY `packingSite_FK_2` (`collectionFk`), + KEY `packingSite_FK_3` (`parkingFk`), CONSTRAINT `packingSite_FK` FOREIGN KEY (`hostFk`) REFERENCES `host` (`id`), CONSTRAINT `packingSite_FK_1` FOREIGN KEY (`printerFk`) REFERENCES `printer` (`id`), - CONSTRAINT `packingSite_FK_2` FOREIGN KEY (`collectionFk`) REFERENCES `collection` (`id`) ON DELETE SET NULL ON UPDATE CASCADE + CONSTRAINT `packingSite_FK_2` FOREIGN KEY (`collectionFk`) REFERENCES `collection` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT `packingSite_FK_3` FOREIGN KEY (`parkingFk`) REFERENCES `parking` (`id`) ON DELETE CASCADE ON UPDATE SET NULL, + CONSTRAINT `packingSite_FK_4` FOREIGN KEY (`printerRfidFk`) REFERENCES `printer` (`id`) ON UPDATE CASCADE, + CONSTRAINT `packingSite_FK_5` FOREIGN KEY (`scannerFk`) REFERENCES `scanner` (`id`) ON UPDATE CASCADE, + CONSTRAINT `packingSite_FK_6` FOREIGN KEY (`screenFk`) REFERENCES `screen` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`packingSite_beforeInsert` + BEFORE INSERT ON `packingSite` + FOR EACH ROW +BEGIN + SET NEW.editorFk = account.myUser_getId(); +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`packingSite_beforeUpdate` + BEFORE UPDATE ON `packingSite` + FOR EACH ROW +BEGIN + SET NEW.editorFk = account.myUser_getId(); +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`packingSite_afterDelete` + AFTER DELETE ON `packingSite` + FOR EACH ROW +BEGIN + INSERT INTO packingSiteDeviceLog + SET `action` = 'delete', + `changedModel` = 'PackingSite', + `changedModelId` = OLD.id, + `userFk` = account.myUser_getId(); +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; -- -- Table structure for table `packingSiteAdvanced` @@ -33506,6 +33843,34 @@ CREATE TABLE `packingSiteConfig` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `packingSiteDeviceLog` +-- + +DROP TABLE IF EXISTS `packingSiteDeviceLog`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `packingSiteDeviceLog` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `originFk` int(11) DEFAULT NULL, + `userFk` int(10) unsigned DEFAULT NULL, + `action` set('insert','update','delete') NOT NULL, + `creationDate` timestamp NULL DEFAULT current_timestamp(), + `description` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + `changedModel` enum('PackingSite') NOT NULL DEFAULT 'PackingSite', + `oldInstance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`oldInstance`)), + `newInstance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`newInstance`)), + `changedModelId` int(11) NOT NULL, + `changedModelValue` varchar(45) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `userFk` (`userFk`), + KEY `packingSiteDeviceLog_changedModel` (`changedModel`,`changedModelId`,`creationDate`), + KEY `packingSiteDeviceLog_packingSiteDeviceLog` (`originFk`,`creationDate`), + CONSTRAINT `packingSiteDeviceLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `client` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `packingSiteDeviceLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci `PAGE_COMPRESSED`=1; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `packingSiteLog` -- @@ -34014,13 +34379,13 @@ CREATE TABLE `pgc` ( `cplusTaxBreakFk` int(10) unsigned DEFAULT 1, `mod340` tinyint(1) NOT NULL DEFAULT 0, `mod347` tinyint(1) NOT NULL DEFAULT 0, - `cplusTrascendency477Fk` int(10) unsigned DEFAULT 1, + `siiTrascendencyInvoiceOutFk` int(10) unsigned DEFAULT 1, `isEqualizated` tinyint(1) DEFAULT 0, PRIMARY KEY (`code`), KEY `pgc_fk1_idx` (`cplusTaxBreakFk`), - KEY `pgc_fk2_idx` (`cplusTrascendency477Fk`), + KEY `pgc_fk2_idx` (`siiTrascendencyInvoiceOutFk`), CONSTRAINT `pgc_fk1` FOREIGN KEY (`cplusTaxBreakFk`) REFERENCES `cplusTaxBreak` (`id`) ON UPDATE CASCADE, - CONSTRAINT `pgc_fk2` FOREIGN KEY (`cplusTrascendency477Fk`) REFERENCES `cplusTrascendency477` (`id`) ON UPDATE CASCADE + CONSTRAINT `pgc_fk2` FOREIGN KEY (`siiTrascendencyInvoiceOutFk`) REFERENCES `siiTrascendencyInvoiceOut` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Plan General Contable'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -34511,6 +34876,7 @@ CREATE TABLE `printer` ( `isLabeler` tinyint(1) DEFAULT 0 COMMENT 'Indica si es impresora de etiquetas', `sectorFk` int(11) DEFAULT NULL, `paperSizeFk` varchar(100) DEFAULT NULL, + `isRfid` tinyint(4) NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `printer_UN` (`reference`), UNIQUE KEY `printer_UN1` (`macWifi`), @@ -34596,10 +34962,40 @@ CREATE TABLE `productionConfig` ( `pendingCollectionsAge` tinyint(3) unsigned DEFAULT 6, `maxNotAssignedCollectionLifeTime` time NOT NULL DEFAULT '00:10:00' COMMENT 'Tiempo de vida de las colecciones sin asignar. Cuando se supera son eliminadas', `maxProductionScopeDays` int(11) NOT NULL DEFAULT 1 COMMENT 'maximo numero de dias en F11', - PRIMARY KEY (`id`) + `orderMode` enum('Location','Age') NOT NULL DEFAULT 'Location', + `stockScopeDays` int(11) DEFAULT 1 COMMENT 'Días a futuro al revisar el stock', + `shortageAddressFk` int(11) DEFAULT NULL COMMENT 'Consignatario por defecto para añadir un item de alta', + PRIMARY KEY (`id`), + KEY `productionConfig_FK` (`shortageAddressFk`), + CONSTRAINT `productionConfig_FK` FOREIGN KEY (`shortageAddressFk`) REFERENCES `address` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Recoge los parámetros que condicionan la producción'; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `productionError` +-- + +DROP TABLE IF EXISTS `productionError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `productionError` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `userFk` int(11) DEFAULT NULL, + `firstname` varchar(100) DEFAULT NULL, + `lastname` varchar(100) DEFAULT NULL, + `rol` varchar(100) DEFAULT NULL, + `ticketNumber` int(11) DEFAULT NULL, + `lineNumber` int(11) DEFAULT NULL, + `error` int(11) DEFAULT NULL, + `volume` double DEFAULT NULL, + `hourStart` varchar(100) DEFAULT NULL, + `hourEnd` varchar(100) DEFAULT NULL, + `hourWorked` varchar(100) DEFAULT NULL, + `dated` date DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Temporary table structure for view `productionVolume` -- @@ -34867,6 +35263,7 @@ CREATE TABLE `province` ( `geoFk` int(11) DEFAULT NULL, `autonomyFk` int(11) DEFAULT NULL, PRIMARY KEY (`id`), + UNIQUE KEY `countryName_UN` (`countryFk`,`name`), KEY `Paises_Id` (`countryFk`), KEY `warehouse_Id` (`warehouseFk`), KEY `provicne_zone_fk_idx` (`zoneFk`), @@ -35150,7 +35547,7 @@ CREATE TABLE `rateLog` ( KEY `rateLog_originFk` (`originFk`,`creationDate`), CONSTRAINT `rateOriginFk` FOREIGN KEY (`originFk`) REFERENCES `rate` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `rateUserFk` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -35842,8 +36239,6 @@ DROP TABLE IF EXISTS `routeConfig`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `routeConfig` ( `id` int(10) unsigned NOT NULL, - `kmRate` decimal(10,4) DEFAULT NULL, - `kmTruckRate` decimal(10,4) DEFAULT NULL, `m3Distribution` decimal(10,4) DEFAULT NULL, `m3Management` decimal(10,2) DEFAULT NULL, `m3Palletization` decimal(10,2) DEFAULT NULL, @@ -36050,24 +36445,6 @@ CREATE TABLE `routesMonitor` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; --- --- Temporary table structure for view `routesReduced` --- - -DROP TABLE IF EXISTS `routesReduced`; -/*!50001 DROP VIEW IF EXISTS `routesReduced`*/; -SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; -/*!50001 CREATE VIEW `routesReduced` AS SELECT - 1 AS `description`, - 1 AS `name`, - 1 AS `routeFk`, - 1 AS `eta`, - 1 AS `bufferFk`, - 1 AS `beachFk`, - 1 AS `itempackingTypeFk` */; -SET character_set_client = @saved_cs_client; - -- -- Table structure for table `sale` -- @@ -36081,7 +36458,7 @@ CREATE TABLE `sale` ( `ticketFk` int(11) NOT NULL, `concept` varchar(50) DEFAULT NULL, `quantity` decimal(10,2) NOT NULL DEFAULT 0.00, - `originalQuantity` double(9,1) DEFAULT NULL, + `originalQuantity` double(9,1) DEFAULT NULL COMMENT 'Se utiliza para notificar a través de rocket los cambios de quantity', `price` decimal(10,2) NOT NULL DEFAULT 0.00, `discount` tinyint(2) unsigned NOT NULL DEFAULT 0, `priceFixed` decimal(10,2) NOT NULL DEFAULT 0.00, @@ -36096,6 +36473,7 @@ CREATE TABLE `sale` ( KEY `Id_Ticket` (`ticketFk`), KEY `itemFk_ticketFk` (`itemFk`,`ticketFk`), KEY `sale_fk_editor` (`editorFk`), + KEY `sale_created_IDX` (`created`) USING BTREE, CONSTRAINT `movement_ticket_id` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `sale_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), CONSTRAINT `sale_ibfk_1` FOREIGN KEY (`itemFk`) REFERENCES `item` (`id`) ON UPDATE CASCADE @@ -36115,6 +36493,7 @@ DELIMITER ;; FOR EACH ROW BEGIN SET NEW.editorFk = account.myUser_getId(); + SET NEW.originalQuantity = NEW.quantity; END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -36578,8 +36957,8 @@ CREATE TABLE `saleGroupDetail` ( `saleFk` int(11) NOT NULL, `saleGroupFk` int(11) NOT NULL, PRIMARY KEY (`id`), + UNIQUE KEY `saleGroupDetail_UN` (`saleFk`), KEY `saleGroupDetail_FK_1` (`saleGroupFk`), - KEY `saleFk` (`saleFk`), CONSTRAINT `saleGroupDetail_ibfk_1` FOREIGN KEY (`saleFk`) REFERENCES `sale` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='relaciona sale y saleGroup'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -36916,6 +37295,9 @@ CREATE TABLE `salespersonConfig` ( `id` int(11) NOT NULL AUTO_INCREMENT, `manaMaxRate` decimal(3,2) DEFAULT 0.05 COMMENT 'Valor máximo a recficar en una línea por el maná de un comercial', `manaMinRate` decimal(3,2) DEFAULT -0.05 COMMENT 'Valor mínimo a recficar en una línea por el maná de un comercial', + `manaDateFrom` date NOT NULL DEFAULT '2023-01-01' COMMENT 'first date to count mana', + `manaFromDays` int(11) NOT NULL DEFAULT 90 COMMENT 'Range of days from mana calculation', + `manaToDays` int(11) NOT NULL DEFAULT 30 COMMENT 'Range of days to mana calculation', PRIMARY KEY (`id`) ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -36940,6 +37322,66 @@ CREATE TABLE `sample` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `scanner` +-- + +DROP TABLE IF EXISTS `scanner`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `scanner` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL, + `modelFk` varchar(50) NOT NULL, + PRIMARY KEY (`id`), + KEY `scanner_FK` (`modelFk`), + CONSTRAINT `scanner_FK` FOREIGN KEY (`modelFk`) REFERENCES `scannerModel` (`code`) ON UPDATE CASCADE +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `scannerModel` +-- + +DROP TABLE IF EXISTS `scannerModel`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `scannerModel` ( + `code` varchar(50) NOT NULL, + PRIMARY KEY (`code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `screen` +-- + +DROP TABLE IF EXISTS `screen`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `screen` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL, + `modelFk` varchar(50) NOT NULL, + PRIMARY KEY (`id`), + KEY `screen_FK` (`modelFk`), + CONSTRAINT `screen_FK` FOREIGN KEY (`modelFk`) REFERENCES `screenModel` (`code`) ON UPDATE CASCADE +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `screenModel` +-- + +DROP TABLE IF EXISTS `screenModel`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `screenModel` ( + `code` varchar(50) NOT NULL, + PRIMARY KEY (`code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `sector` -- @@ -36963,13 +37405,12 @@ CREATE TABLE `sector` ( `isHideForPickers` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'sector a ocultar a los sacadores', `isReserve` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Sectores de reserva, como Albenfruit o Fuentes', `mainPrinterFk` tinyint(3) unsigned DEFAULT NULL, - PRIMARY KEY (`id`,`warehouseFk`), + PRIMARY KEY (`id`), UNIQUE KEY `code_UNIQUE` (`code`), KEY `sector_fk1_idx` (`warehouseFk`), KEY `sector_report` (`reportFk`), KEY `sector_FK` (`sonFk`,`warehouseFk`), KEY `sector_FK_1` (`mainPrinterFk`), - CONSTRAINT `sector_FK` FOREIGN KEY (`sonFk`, `warehouseFk`) REFERENCES `sector` (`id`, `warehouseFk`) ON UPDATE CASCADE, CONSTRAINT `sector_FK_1` FOREIGN KEY (`mainPrinterFk`) REFERENCES `printer` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `sector_fk1` FOREIGN KEY (`warehouseFk`) REFERENCES `warehouse` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `sector_report` FOREIGN KEY (`reportFk`) REFERENCES `report` (`id`) @@ -37293,6 +37734,7 @@ CREATE TABLE `shelving` ( `isSpam` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'señala las matrículas con producto que se puede llevar a la reserva', `isRecyclable` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'las matrículas marcadas como reciclables se liberan cada noche desde vn.shelving_clean para poder volver a utilizarlas', `editorFk` int(10) unsigned DEFAULT NULL, + `isMoving` tinyint(1) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `shelving_UN` (`code`), KEY `shelving_fk1_idx` (`parkingFk`), @@ -37347,6 +37789,9 @@ BEGIN CALL util.throw('NOT_EMPTY_CODE_ALLOWED'); END IF; + IF NOT(OLD.parkingFk <=> NEW.parkingFK) THEN + SET NEW.isMoving = FALSE; + END IF; END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -37406,6 +37851,66 @@ CREATE TABLE `shelvingLog` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci `PAGE_COMPRESSED`=1; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `siiTrascendencyInvoiceIn` +-- + +DROP TABLE IF EXISTS `siiTrascendencyInvoiceIn`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `siiTrascendencyInvoiceIn` ( + `id` int(10) unsigned NOT NULL, + `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Clave de régimen especial o trascendencia en facturas recibidas en el suministro de inmediato'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `siiTrascendencyInvoiceOut` +-- + +DROP TABLE IF EXISTS `siiTrascendencyInvoiceOut`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `siiTrascendencyInvoiceOut` ( + `id` int(10) unsigned NOT NULL, + `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Clave de régimen especial o trascendencia en facturas expedidas del suministro de inmediato'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `siiTypeInvoiceIn` +-- + +DROP TABLE IF EXISTS `siiTypeInvoiceIn`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `siiTypeInvoiceIn` ( + `id` int(10) unsigned NOT NULL, + `code` varchar(2) NOT NULL, + `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `code_UNIQUE` (`code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Tipo de Factura Recibidas en el suministro de inmediato'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `siiTypeInvoiceOut` +-- + +DROP TABLE IF EXISTS `siiTypeInvoiceOut`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `siiTypeInvoiceOut` ( + `id` int(10) unsigned NOT NULL, + `code` varchar(2) NOT NULL, + `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `code_UNIQUE` (`code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Tipo de Factura Emitidas en el suministro de inmediato'; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `silexACL` -- @@ -37909,7 +38414,7 @@ DROP TABLE IF EXISTS `supplier`; CREATE TABLE `supplier` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL, - `account` varchar(10) DEFAULT NULL, + `account` varchar(10) NOT NULL DEFAULT '4100000000' COMMENT 'Default accounting code for suppliers.', `street` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL, `city` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL, `provinceFk` smallint(5) unsigned DEFAULT NULL, @@ -37964,7 +38469,8 @@ CREATE TABLE `supplier` ( CONSTRAINT `supplier_transactionFk` FOREIGN KEY (`transactionTypeSageFk`) REFERENCES `sage`.`TiposTransacciones` (`CodigoTransaccion`) ON UPDATE CASCADE, CONSTRAINT `supplier_withholdingFk` FOREIGN KEY (`withholdingSageFk`) REFERENCES `sage`.`TiposRetencion` (`CodigoRetencion`) ON UPDATE CASCADE, CONSTRAINT `supplier_workerFk` FOREIGN KEY (`workerFk`) REFERENCES `worker` (`id`) ON UPDATE CASCADE, - CONSTRAINT `suppplier_supplierActivityFk` FOREIGN KEY (`supplierActivityFk`) REFERENCES `supplierActivity` (`code`) ON UPDATE CASCADE + CONSTRAINT `suppplier_supplierActivityFk` FOREIGN KEY (`supplierActivityFk`) REFERENCES `supplierActivity` (`code`) ON UPDATE CASCADE, + CONSTRAINT `supplierAccountTooShort` CHECK (octet_length(`account`) = 10) ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; @@ -38185,7 +38691,7 @@ DROP TABLE IF EXISTS `supplierAddress`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `supplierAddress` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `supplierFk` int(11) DEFAULT NULL, + `supplierFk` int(10) unsigned DEFAULT NULL, `nickname` varchar(40) DEFAULT NULL, `street` varchar(255) DEFAULT NULL, `provinceFk` smallint(6) unsigned DEFAULT NULL, @@ -38197,6 +38703,8 @@ CREATE TABLE `supplierAddress` ( PRIMARY KEY (`id`), KEY `supplierAddress_province_fk` (`provinceFk`), KEY `supplierAddress_fk_editor` (`editorFk`), + KEY `supplierAddress_FK` (`supplierFk`), + CONSTRAINT `supplierAddress_FK` FOREIGN KEY (`supplierFk`) REFERENCES `supplier` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `supplierAddress_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), CONSTRAINT `supplierAddress_province_fk` FOREIGN KEY (`provinceFk`) REFERENCES `province` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; @@ -38883,7 +39391,7 @@ BEGIN SET NEW.editorFk = account.myUser_getId(); - IF !(NEW.routeFk <=> OLD.routeFk) THEN + IF NOT (NEW.routeFk <=> OLD.routeFk) THEN INSERT IGNORE INTO `vn`.`routeRecalc` (`routeFk`) SELECT r.id FROM vn.route r @@ -38893,7 +39401,7 @@ BEGIN GROUP BY r.id; END IF; - IF !(DATE(NEW.shipped) <=> DATE(OLD.shipped)) THEN + IF NOT (DATE(NEW.shipped) <=> DATE(OLD.shipped)) THEN IF YEAR(NEW.shipped) < 2000 THEN SIGNAL SQLSTATE '46000' SET MESSAGE_TEXT = 'Year cannot be lesser than 2000'; @@ -38905,7 +39413,7 @@ BEGIN END IF; - IF !(NEW.isDeleted <=> OLD.isDeleted) AND NEW.isDeleted THEN + IF NOT (NEW.isDeleted <=> OLD.isDeleted) AND NEW.isDeleted THEN INSERT IGNORE INTO `vn`.`routeRecalc` (`routeFk`) SELECT r.id FROM vn.ticket t @@ -38924,7 +39432,7 @@ BEGIN CALL util.throw ('This ticket is deleted'); END IF; - IF !(NEW.routeFk <=> OLD.routeFk) AND NEW.routeFk IS NOT NULL THEN + IF NOT (NEW.routeFk <=> OLD.routeFk) AND NEW.routeFk IS NOT NULL THEN SELECT MAX(TIME(shipped)) INTO vNewTime FROM vn.ticket WHERE routeFk = NEW.routeFk @@ -40178,7 +40686,7 @@ CREATE TABLE `ticketTracking` ( `notes` varchar(255) DEFAULT NULL, `created` timestamp NULL DEFAULT current_timestamp(), `ticketFk` int(11) DEFAULT NULL, - `workerFk` int(11) DEFAULT NULL, + `workerFk` int(10) unsigned DEFAULT NULL, `supervisorFk` int(10) unsigned DEFAULT NULL, `editorFk` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`), @@ -40191,6 +40699,7 @@ CREATE TABLE `ticketTracking` ( KEY `ticketTracking_created_IDX` (`created`) USING BTREE, CONSTRAINT `inter_state` FOREIGN KEY (`stateFk`) REFERENCES `state` (`id`) ON UPDATE CASCADE, CONSTRAINT `responsable` FOREIGN KEY (`supervisorFk`) REFERENCES `worker` (`id`) ON UPDATE CASCADE, + CONSTRAINT `ticketTracking_FK3` FOREIGN KEY (`workerFk`) REFERENCES `account`.`user` (`id`) ON UPDATE CASCADE, CONSTRAINT `ticketTracking_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), CONSTRAINT `ticketTracking_ibfk_1` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; @@ -40499,7 +41008,7 @@ CREATE TABLE `till` ( `isAccountable` tinyint(1) NOT NULL DEFAULT 0, `serie` varchar(2) DEFAULT NULL, `number` int(11) DEFAULT NULL, - `concept` varchar(50) NOT NULL, + `concept` varchar(50) DEFAULT NULL, `in` decimal(10,2) DEFAULT NULL, `out` decimal(10,2) DEFAULT NULL, `bankFk` int(11) DEFAULT 1, @@ -40526,28 +41035,6 @@ CREATE TABLE `till` ( CONSTRAINT `till_ibfk_3` FOREIGN KEY (`workerFk`) REFERENCES `worker` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -DELIMITER ;; -/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`till_beforeInsert` - BEFORE INSERT ON `till` - FOR EACH ROW -BEGIN - IF NEW.concept IS NULL OR NEW.concept REGEXP '^[[:space:]]*$' THEN - SET NEW.concept = 'SIN DETALLE'; - END IF; -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -- -- Table structure for table `tillConfig` @@ -40873,6 +41360,22 @@ CREATE TABLE `trainingCourseType` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Lista de las formaciones'; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `transitoryDuaUnified` +-- + +DROP TABLE IF EXISTS `transitoryDuaUnified`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `transitoryDuaUnified` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `supplierFk` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `transitoryDuaUnified_FK` (`supplierFk`), + CONSTRAINT `transitoryDuaUnified_FK` FOREIGN KEY (`supplierFk`) REFERENCES `supplier` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Transitarios que al contabilizar sus entradas sólo generan un único DUA para todos los proveedores'; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `travel` -- @@ -40965,6 +41468,14 @@ DELIMITER ;; BEGIN SET NEW.editorFk = account.myUser_getId(); + IF ((NOT NEW.shipped <=> OLD.shipped ) + OR (NOT NEW.landed <=> OLD.landed ) + OR (NOT NEW.warehouseInFk <=> OLD.warehouseInFk ) + OR (NOT NEW.warehouseOutFk <=> OLD.warehouseOutFk )) + AND (OLD.totalEntries AND OLD.landed < CURDATE()) THEN + CALL util.throw("Cannot past travels with entries"); + END IF; + IF NOT (NEW.landed <=> OLD.landed) OR NOT (NEW.shipped <=> OLD.shipped) THEN CALL travel_checkDates(NEW.shipped, NEW.landed); @@ -40983,7 +41494,9 @@ BEGIN CALL travel_checkPackaging(NEW.id); END IF; - CALL travel_checkWarehouseIsFeedStock(NEW.warehouseInFk); + IF NOT (NEW.warehouseInFk <=> OLD.warehouseInFk) THEN + CALL travel_checkWarehouseIsFeedStock(NEW.warehouseInFk); + END IF; END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -41606,7 +42119,7 @@ DROP TABLE IF EXISTS `wagon`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `wagon` ( - `id` int(11) NOT NULL AUTO_INCREMENT, + `id` varchar(6) NOT NULL COMMENT '26 letras de alfabeto inglés', `volume` int(11) NOT NULL DEFAULT 150 COMMENT 'Volumen en litros', `plate` varchar(10) NOT NULL COMMENT 'Matrícula', `typeFk` int(11) unsigned NOT NULL, @@ -41614,7 +42127,7 @@ CREATE TABLE `wagon` ( PRIMARY KEY (`id`), KEY `wagon_type` (`typeFk`), CONSTRAINT `wagon_type` FOREIGN KEY (`typeFk`) REFERENCES `wagonType` (`id`) ON UPDATE CASCADE -) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -41701,10 +42214,10 @@ CREATE TABLE `wagonVolumetry` ( `lines` int(10) unsigned NOT NULL DEFAULT 1, `liters` int(10) unsigned NOT NULL DEFAULT 0, `height` int(10) unsigned NOT NULL DEFAULT 20, - `wagonFk` int(11) NOT NULL, + `wagonFk` varchar(6) NOT NULL, PRIMARY KEY (`id`), - KEY `wagonVolumetry_FK` (`wagonFk`), - CONSTRAINT `wagonVolumetry_FK` FOREIGN KEY (`wagonFk`) REFERENCES `wagon` (`id`) ON DELETE CASCADE ON UPDATE CASCADE + KEY `wagonVolumetry_FK_1` (`wagonFk`), + CONSTRAINT `wagonVolumetry_FK_1` FOREIGN KEY (`wagonFk`) REFERENCES `wagon` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -41875,14 +42388,12 @@ CREATE TABLE `worker` ( `photo` blob DEFAULT NULL, `phone` varchar(9) DEFAULT NULL, `mobileExtension` int(4) DEFAULT NULL, - `userFk` int(10) unsigned DEFAULT NULL, - `bossFk` int(11) NOT NULL DEFAULT 103, + `bossFk` int(10) unsigned DEFAULT 103, `fiDueDate` datetime DEFAULT NULL, `hasMachineryAuthorized` tinyint(2) DEFAULT 0, `seniority` date DEFAULT NULL, `isTodayRelative` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Para el F11. Calcula los problemas de visiblidad en funcion del dia actual', `isF11Allowed` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Usuario autorizado para abrir el F11', - `sectorFk__` int(11) DEFAULT NULL COMMENT '@deprecated 2023-06-26', `maritalStatus` enum('S','M') NOT NULL, `labelerFk__` tinyint(3) unsigned DEFAULT NULL COMMENT '@deprecated 2023-06-26', `originCountryFk` mediumint(8) unsigned DEFAULT NULL COMMENT 'País de origen', @@ -41900,7 +42411,6 @@ CREATE TABLE `worker` ( `editorFk` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `CodigoTrabajador_UNIQUE` (`code`), - UNIQUE KEY `user_id_UNIQUE` (`userFk`), UNIQUE KEY `worker_business` (`businessFk`), UNIQUE KEY `locker` (`locker`), KEY `sub` (`sub`), @@ -41912,6 +42422,7 @@ CREATE TABLE `worker` ( CONSTRAINT `worker_FK` FOREIGN KEY (`labelerFk__`) REFERENCES `printer` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `worker_FK_1` FOREIGN KEY (`originCountryFk`) REFERENCES `country` (`id`) ON UPDATE CASCADE, CONSTRAINT `worker_FK_2` FOREIGN KEY (`educationLevelFk`) REFERENCES `educationLevel` (`id`) ON UPDATE CASCADE, + CONSTRAINT `worker_FK_3` FOREIGN KEY (`bossFk`) REFERENCES `worker` (`id`) ON UPDATE CASCADE, CONSTRAINT `worker_businessFk` FOREIGN KEY (`businessFk`) REFERENCES `business` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT `worker_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), CONSTRAINT `worker_ibfk_1` FOREIGN KEY (`id`) REFERENCES `account`.`user` (`id`) @@ -42762,10 +43273,29 @@ CREATE TABLE `workerTimeControlConfig` ( `longWeekDays` int(11) DEFAULT NULL COMMENT 'Días a tener en cuenta para calcular el descanso largo', `teleworkingStart` int(11) DEFAULT NULL COMMENT 'Hora comienzo jornada de los teletrabajdores expresada en segundos', `teleworkingStartBreakTime` int(11) DEFAULT NULL COMMENT 'Hora comienzo descanso de los teletrabjadores expresada en segundos', + `maxTimeToBreak` int(11) DEFAULT 3600, + `maxWorkShortCycle` int(10) unsigned DEFAULT 561600 COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descanso semanal corto', + `maxWorkLongCycle` int(10) unsigned DEFAULT 950400 COMMENT 'Máximo tiempo que un trabajador puede estar trabajando con el que adquirirá el derecho a un descanso semanal largo', PRIMARY KEY (`id`) ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin COMMENT='All values in seconds'; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `workerTimeControlError` +-- + +DROP TABLE IF EXISTS `workerTimeControlError`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `workerTimeControlError` ( + `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `code` char(35) NOT NULL, + `description` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `code` (`code`) +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `workerTimeControlLog` -- @@ -43439,17 +43969,19 @@ DROP TABLE IF EXISTS `zoneIncluded`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `zoneIncluded` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `zoneFk` int(11) NOT NULL, `geoFk` int(11) NOT NULL, `isIncluded` tinyint(1) DEFAULT NULL, `editorFk` int(10) unsigned DEFAULT NULL, - PRIMARY KEY (`zoneFk`,`geoFk`), - KEY `geoFk_idx` (`geoFk`), + PRIMARY KEY (`id`), + UNIQUE KEY `unique_zone_geo` (`zoneFk`,`geoFk`), KEY `zoneIncluded_fk_editor` (`editorFk`), - CONSTRAINT `zoneFk2` FOREIGN KEY (`zoneFk`) REFERENCES `zone` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `zoneGeoFk2` FOREIGN KEY (`geoFk`) REFERENCES `zoneGeo` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + KEY `zoneIncluded_FK_2` (`geoFk`), + CONSTRAINT `zoneIncluded_FK_1` FOREIGN KEY (`zoneFk`) REFERENCES `zone` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `zoneIncluded_FK_2` FOREIGN KEY (`geoFk`) REFERENCES `zoneGeo` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `zoneIncluded_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; +) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -43494,11 +44026,11 @@ DELIMITER ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`zoneIncluded_afterDelete` AFTER DELETE ON `zoneIncluded` @@ -43803,6 +44335,27 @@ DELIMITER ;; /*!50003 SET character_set_client = @saved_cs_client */ ;; /*!50003 SET character_set_results = @saved_cs_results */ ;; /*!50003 SET collation_connection = @saved_col_connection */ ;; +/*!50106 DROP EVENT IF EXISTS `itemImageQueue_check` */;; +DELIMITER ;; +/*!50003 SET @saved_cs_client = @@character_set_client */ ;; +/*!50003 SET @saved_cs_results = @@character_set_results */ ;; +/*!50003 SET @saved_col_connection = @@collation_connection */ ;; +/*!50003 SET character_set_client = utf8mb4 */ ;; +/*!50003 SET character_set_results = utf8mb4 */ ;; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ;; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ;; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;; +/*!50003 SET @saved_time_zone = @@time_zone */ ;; +/*!50003 SET time_zone = 'SYSTEM' */ ;; +/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `itemImageQueue_check` ON SCHEDULE EVERY 1 HOUR STARTS '2023-07-28 00:00:00' ON COMPLETION PRESERVE DISABLE ON SLAVE DO BEGIN + DELETE FROM itemImageQueue + WHERE attempts >= (SELECT downloadMaxAttempts FROM itemConfig); +END */ ;; +/*!50003 SET time_zone = @saved_time_zone */ ;; +/*!50003 SET sql_mode = @saved_sql_mode */ ;; +/*!50003 SET character_set_client = @saved_cs_client */ ;; +/*!50003 SET character_set_results = @saved_cs_results */ ;; +/*!50003 SET collation_connection = @saved_col_connection */ ;; /*!50106 DROP EVENT IF EXISTS `mysqlConnectionsSorter_kill` */;; DELIMITER ;; /*!50003 SET @saved_cs_client = @@character_set_client */ ;; @@ -44056,6 +44609,24 @@ DELIMITER ;; /*!50003 SET character_set_client = @saved_cs_client */ ;; /*!50003 SET character_set_results = @saved_cs_results */ ;; /*!50003 SET collation_connection = @saved_col_connection */ ;; +/*!50106 DROP EVENT IF EXISTS `zoneClosure_doRecalc` */;; +DELIMITER ;; +/*!50003 SET @saved_cs_client = @@character_set_client */ ;; +/*!50003 SET @saved_cs_results = @@character_set_results */ ;; +/*!50003 SET @saved_col_connection = @@collation_connection */ ;; +/*!50003 SET character_set_client = utf8mb3 */ ;; +/*!50003 SET character_set_results = utf8mb3 */ ;; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ;; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ;; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;; +/*!50003 SET @saved_time_zone = @@time_zone */ ;; +/*!50003 SET time_zone = 'SYSTEM' */ ;; +/*!50106 CREATE*/ /*!50117 DEFINER=`salix`@`10.0.%.%`*/ /*!50106 EVENT `zoneClosure_doRecalc` ON SCHEDULE AT '2023-11-13 07:15:54' ON COMPLETION NOT PRESERVE DISABLE ON SLAVE DO CALL zoneClosure_recalc */ ;; +/*!50003 SET time_zone = @saved_time_zone */ ;; +/*!50003 SET sql_mode = @saved_sql_mode */ ;; +/*!50003 SET character_set_client = @saved_cs_client */ ;; +/*!50003 SET character_set_results = @saved_cs_results */ ;; +/*!50003 SET collation_connection = @saved_col_connection */ ;; /*!50106 DROP EVENT IF EXISTS `zoneGeo_doCalc` */;; DELIMITER ;; /*!50003 SET @saved_cs_client = @@character_set_client */ ;; @@ -44221,42 +44792,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP FUNCTION IF EXISTS `botanicExport_isUpdatable` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` FUNCTION `botanicExport_isUpdatable`(vEdiGenusFk MEDIUMINT, - vEdiSpecieFk MEDIUMINT, - vRestriction MEDIUMINT) RETURNS int(11) - DETERMINISTIC -BEGIN - DECLARE vIsUpdatable INTEGER; - SELECT COUNT(*) INTO vIsUpdatable - FROM botanicExport - WHERE ediGenusFk = vEdiGenusFk - AND (vEdiSpecieFk = ediSpecieFk OR IFNULL(vEdiSpecieFk,ediSpecieFk) IS NULL) - AND vRestriction = restriction; -RETURN vIsUpdatable; -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP FUNCTION IF EXISTS `buy_getUnitVolume` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` FUNCTION `buy_getUnitVolume`(vSelf INT) RETURNS int(11) DETERMINISTIC @@ -44271,7 +44814,7 @@ BEGIN DECLARE vPackaging VARCHAR(10); DECLARE vPacking INT; - SELECT itemFk, packageFk, packing + SELECT itemFk, packagingFk, packing INTO vItem, vPackaging, vPacking FROM buy WHERE id = vSelf; @@ -44443,63 +44986,19 @@ BEGIN * @return Mana del cliente */ DECLARE vMana DECIMAL(10,2); - DECLARE vFromDated DATE; - DECLARE vHasMana BOOLEAN; - DECLARE vManaComponent INT; - DECLARE vAutoManaComponent INT; - DECLARE vManaBank INT; - DECLARE vManaGreugeType INT; - SELECT id INTO vManaGreugeType FROM greugeType WHERE code = 'mana'; - SELECT id INTO vManaBank FROM bank WHERE code = 'mana'; - SELECT id INTO vManaComponent FROM component WHERE code = 'mana'; - SELECT id INTO vAutoManaComponent FROM component WHERE code = 'autoMana'; + CREATE OR REPLACE TEMPORARY TABLE tmp.client + SELECT vClient id; - SELECT COUNT(*) INTO vHasMana - FROM `client` c - WHERE c.id = vClient AND c.typeFk = 'normal'; + CALL client_getMana(); - IF NOT vHasMana THEN - RETURN 0; - END IF; + SET vMana = (SELECT mana + FROM tmp.clientMana); - SELECT max(dated) INTO vFromDated - FROM clientManaCache; + DROP TEMPORARY TABLE + tmp.client, + tmp.clientMana; - SELECT sum(mana) INTO vMana - FROM - ( - SELECT mana - FROM clientManaCache - WHERE clientFk = vClient - AND dated = vFromDated - UNION ALL - SELECT s.quantity * value - FROM ticket t - JOIN address a ON a.id = t.addressFk - JOIN sale s on s.ticketFk = t.id - JOIN saleComponent sc on sc.saleFk = s.id - WHERE sc.componentFk IN (vManaComponent, vAutoManaComponent) - AND t.shipped > vFromDated - AND t.shipped < TIMESTAMPADD(DAY,1,util.VN_CURDATE()) - AND a.clientFk = vClient - UNION ALL - SELECT - amountPaid - FROM receipt r - JOIN `client` c ON c.id = r.clientFk - WHERE r.bankFk = vManaBank - AND r.payed > vFromDated - AND r.payed <= util.VN_CURDATE() - AND c.id = vClient - UNION ALL - SELECT g.amount - FROM greuge g - JOIN `client` c ON c.id = g.clientFk - WHERE g.greugeTypeFk = vManaGreugeType - AND g.shipped > vFromDated - AND g.shipped <= util.VN_CURDATE() - AND c.id = vClient - ) sub; RETURN IFNULL(vMana,0); END ;; DELIMITER ; @@ -44583,7 +45082,7 @@ BEGIN * * @param vClient client id * @param vDate date to check the risk - * @return client risk + * @return Client risk */ DECLARE vDebt DECIMAL(10,2); DECLARE vHasDebt BOOLEAN; @@ -44603,6 +45102,10 @@ BEGIN SELECT risk INTO vDebt FROM tmp.risk; + DROP TEMPORARY TABLE + tmp.clientGetDebt, + tmp.risk; + RETURN vDebt; END ;; DELIMITER ; @@ -45010,27 +45513,25 @@ DELIMITER ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; DELIMITER ;; -CREATE DEFINER=`root`@`localhost` FUNCTION `duaTax_getRate`(vDua INT, vTaxClass INT) RETURNS decimal(5,2) +CREATE DEFINER=`root`@`localhost` FUNCTION `duaTax_getRate`(vDuaFk INT, vTaxClassFk INT) RETURNS decimal(5,2) DETERMINISTIC BEGIN - DECLARE vCountryFk INTEGER; - - SELECT s.countryFk INTO vCountryFk - FROM dua d - JOIN supplier s ON s.id = d.companyFk - WHERE d.id = vDua; - - RETURN (SELECT rate - FROM - (SELECT taxClassFk, rate - FROM invoiceInTaxBookingAccount - WHERE effectived <= util.VN_CURDATE() - AND countryFk = vCountryFk - AND taxClassFk = vTaxClass - ORDER BY effectived DESC - LIMIT 10000000000000000000 - ) ba1 - GROUP BY taxClassFk); +/** + * Devuelve el rate para un Dua teniendo en cuenta la fecha de opreción del DUA + * + * @param vDuaFk Identificador de la tabla dua + * @param vTaxClassFk Identificador del IVA de la tabla invoiceInTaxBookingAccount + */ + RETURN ( + SELECT rate + FROM dua d + JOIN supplier s ON s.id = d.companyFk + JOIN invoiceInTaxBookingAccount iit ON iit.countryFk = s.countryFk + AND iit.taxClassFk = vTaxClassFk + AND iit.effectived <= IFNULL( d.operated, util.VN_CURDATE()) + WHERE d.id = vDuaFk + ORDER BY effectived DESC + LIMIT 1); END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -46893,61 +47394,6 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP FUNCTION IF EXISTS `phytoPassport` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` FUNCTION `phytoPassport`(vRef VARCHAR(15)) RETURNS text CHARSET utf8mb3 COLLATE utf8mb3_general_ci - DETERMINISTIC -BEGIN -DECLARE vPhyto TEXT CHARSET utf8 COLLATE utf8_unicode_ci; -SELECT - GROUP_CONCAT(i.id, - ':', - ppa.denomination, - ' ', - pp.number, - CHAR(13,10) - SEPARATOR '') fitosanitario - INTO vPhyto -FROM - sale s - JOIN - ticket t ON t.id = s.ticketFk - JOIN - item i ON i.id = s.itemFk - JOIN - plantpassport pp ON pp.producerFk = i.producerFk - JOIN - plantpassportAuthority ppa ON ppa.id = pp.plantpassportAuthorityFk - JOIN - itemBotanicalWithGenus ib ON ib.itemFk = i.id - JOIN - botanicExport be ON be.`code` = 'phytosanitaryPassport' - LEFT JOIN - ediGenus eg ON eg.id = be.ediGenusFk - LEFT JOIN - ediSpecie es ON es.id = be.ediSpecieFk -WHERE - t.refFk = vRef - AND ib.ediBotanic LIKE CONCAT(IFNULL(eg.latinGenusName, ''), - IF(latinSpeciesName > '', - CONCAT(' ', latinSpeciesName), - ''), - '%'); -RETURN vPhyto; -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP FUNCTION IF EXISTS `priceFixed_getRate2` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -49313,14 +49759,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `buy_afterUpsert` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `buy_afterUpsert`(vSelf INT) BEGIN @@ -49359,7 +49805,7 @@ BEGIN LEFT JOIN item i ON i.id = b.itemFk LEFT JOIN itemType it ON it.id = i.typeFk LEFT JOIN itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN packaging p ON p.id = b.packageFk AND NOT p.isBox + LEFT JOIN packaging p ON p.id = b.packagingFk AND NOT p.isBox JOIN volumeConfig vc ON TRUE WHERE b.id = vSelf; @@ -49573,14 +50019,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `buy_getVolume` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `buy_getVolume`() BEGIN @@ -49590,9 +50036,9 @@ BEGIN */ SELECT t.name Temp, CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * - item_getVolume(b.itemFk, b.packageFk)) / vc.trolleyM3 / 1000000 ,1) AS DECIMAL(10,2)) carros , + item_getVolume(b.itemFk, b.packagingFk)) / vc.trolleyM3 / 1000000 ,1) AS DECIMAL(10,2)) carros , CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * - item_getVolume(b.itemFk, b.packageFk)) / vc.palletM3 / 1000000,1) AS DECIMAL(10,2)) espais + item_getVolume(b.itemFk, b.packagingFk)) / vc.palletM3 / 1000000,1) AS DECIMAL(10,2)) espais FROM buy b JOIN tmp.buy tb ON tb.buyFk = b.id JOIN volumeConfig vc @@ -49671,14 +50117,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `buy_recalcPrices` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `buy_recalcPrices`() BEGIN @@ -49691,7 +50137,7 @@ BEGIN DECLARE vWarehouseFk INT; DECLARE vHasNotPrice BOOL; DECLARE vBuyingValue DECIMAL(10,3); - DECLARE vPackageFk VARCHAR(10); + DECLARE vPackagingFk VARCHAR(10); DECLARE vIsWarehouseFloramondo BOOL; SELECT t.landed, t.warehouseInFk, (w.`name` = 'Floramondo') @@ -49707,7 +50153,7 @@ BEGIN UPDATE buy b JOIN tmp.buyRecalc br ON br.id = b.id AND (@buyId := b.id) - LEFT JOIN packaging p ON p.id = b.packageFk + LEFT JOIN packaging p ON p.id = b.packagingFk JOIN item i ON i.id = b.itemFk JOIN entry e ON e.id = b.entryFk JOIN itemType it ON it.id = i.typeFk @@ -49715,7 +50161,7 @@ BEGIN JOIN agencyMode am ON am.id = tr.agencyModeFk JOIN tmp.rate r JOIN volumeConfig vc - SET b.freightValue = @PF:= IFNULL(((am.m3 * @m3:= item_getVolume(b.itemFk, b.packageFk) / 1000000) + SET b.freightValue = @PF:= IFNULL(((am.m3 * @m3:= item_getVolume(b.itemFk, b.packagingFk) / 1000000) / b.packing) * IF(am.hasWeightVolumetric, GREATEST(b.weight / @m3 / vc.aerealVolumetricDensity, 1), 1), 0), b.comissionValue = @CF:= ROUND(IFNULL(e.commission * b.buyingValue / 100, 0), 3), b.packageValue = @EF:= IF(vIsWarehouseFloramondo, 0, IFNULL(ROUND(IF(p.isPackageReturnable, p.returnCost / b.packing , p.`value` / b.packing), 3),0)), @@ -49723,8 +50169,8 @@ BEGIN b.price2 = @t2:= round(@t3 * (1 + ((r.rate2 - r.rate3)/100)),2), b.price2 = @t2:= IF(@t2 <= @t3,@t3 , @t2); - SELECT (b.buyingValue = b.price2), b.buyingValue, b.packageFk - INTO vHasNotPrice, vBuyingValue, vPackageFk + SELECT (b.buyingValue = b.price2), b.buyingValue, b.packagingFk + INTO vHasNotPrice, vBuyingValue, vPackagingFk FROM vn.buy b WHERE b.id = @buyId AND b.buyingValue <> 0.01; @@ -50332,7 +50778,7 @@ BEGIN SELECT tcb.warehouseFk, tcb.itemFk, c2.id, - ROUND(base * (0.01 + wm.pricesModifierRate), 3) manaAuto + ROUND(base * wm.pricesModifierRate, 3) manaAuto FROM tmp.ticketComponentBase tcb JOIN `client` c on c.id = vClientFk JOIN workerMana wm ON c.salesPersonFk = wm.workerFk @@ -50615,7 +51061,12 @@ BEGIN DELETE FROM sharingCart where ended < vDateShort; DELETE FROM sharingClient where ended < vDateShort; DELETE tw.* FROM ticketWeekly tw - LEFT JOIN sale s ON s.ticketFk = tw.ticketFk WHERE s.itemFk IS NULL; + LEFT JOIN sale s ON s.ticketFk = tw.ticketFk + LEFT JOIN ticketRequest tr ON tr.ticketFk = tw.ticketFk + LEFT JOIN ticketService ts ON ts.ticketFk = tw.ticketFk + WHERE s.id IS NULL + AND tr.id IS NULL + AND ts.id IS NULL; DELETE FROM claim WHERE ticketCreated < vFourYearsAgo; DELETE FROM message WHERE sendDate < vDateShort; -- Robert ubicacion anterior de trevelLog comentario para debug @@ -50941,6 +51392,7 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt; CREATE TEMPORARY TABLE tmp.clientGetDebt + (INDEX (clientFk)) SELECT clientFk FROM bs.defaulter WHERE created = util.VN_CURDATE() @@ -51368,14 +51820,14 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt; CREATE TEMPORARY TABLE tmp.clientGetDebt - SELECT cd.id as clientFk + SELECT cd.clientFk FROM bs.clientDied cd - LEFT JOIN clientProtected cp ON cp.clientFk = cd.id - JOIN client c ON c.id = cd.id + LEFT JOIN clientProtected cp ON cp.clientFk = cd.clientFk + JOIN client c ON c.id = cd.clientFk JOIN province p ON p.id = c.provinceFk LEFT JOIN autonomy a ON a.id = p.autonomyFk JOIN country co ON co.id = p.countryFk - WHERE cd.Aviso = 'TERCER AVISO' + WHERE cd.warning = 'third' AND cp.clientFk IS NULL AND co.code NOT IN ('PT') AND a.name <> 'Canarias' @@ -51621,18 +52073,19 @@ BEGIN * Calculates the risk for active clients * * @table tmp.clientGetDebt(clientFk) - * @param vDate maximum date of records + * @param vDate Maximum date of records * @return tmp.risk */ DECLARE vStarted DATETIME; DECLARE vEnded DATETIME; - SELECT TIMESTAMPADD(MONTH, -riskScope, util.VN_CURDATE()) INTO vStarted FROM clientConfig; - SET vEnded = TIMESTAMP(IFNULL(vDate, util.VN_CURDATE()), '23:59:59'); + SELECT util.VN_CURDATE() - INTERVAL riskScope MONTH INTO vStarted + FROM clientConfig; - DROP TEMPORARY TABLE IF EXISTS tClientRisk; - CREATE TEMPORARY TABLE tClientRisk + SET vEnded = util.dayEnd(IFNULL(vDate, util.VN_CURDATE())); + + CREATE OR REPLACE TEMPORARY TABLE tClientRisk ENGINE = MEMORY SELECT cr.clientFk, SUM(cr.amount) amount FROM clientRisk cr @@ -51655,12 +52108,14 @@ BEGIN GROUP BY t.clientFk; INSERT INTO tClientRisk - SELECT t.clientFk, totalWithVat + SELECT t.clientFk, SUM(totalWithVat) FROM ticket t JOIN tmp.clientGetDebt c ON c.clientFk = t.clientFk WHERE refFk IS NULL - AND shipped BETWEEN vStarted AND vEnded; + AND shipped BETWEEN vStarted AND vEnded + GROUP BY t.clientFk; + -- refs #6351 BUG: No cambiar a CREATE OR REPLACE DROP TEMPORARY TABLE IF EXISTS tmp.risk; CREATE TEMPORARY TABLE tmp.risk (PRIMARY KEY (clientFk)) @@ -51679,6 +52134,75 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `client_getMana` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `client_getMana`() +BEGIN +/** + * Devuelve el mana de los clientes de la tabla tmp.client(id) + * @return tmp.clientMana(id, mana) + * + */ + DECLARE vFromDated DATE; + + DELETE tc FROM tmp.client tc + JOIN client c ON c.id = tc.id + WHERE c.typeFk <> 'normal'; + + SELECT MAX(dated) INTO vFromDated + FROM clientManaCache; + + CREATE OR REPLACE TEMPORARY TABLE tmp.clientMana + SELECT id, SUM(mana) mana + FROM + ( + SELECT tc.id, cmc.mana + FROM clientManaCache cmc + JOIN tmp.client tc ON tc.id = cmc.clientFk + WHERE cmc.dated = vFromDated + UNION ALL + SELECT tc.id, s.quantity * value + FROM ticket t + JOIN address a ON a.id = t.addressFk + JOIN tmp.client tc ON tc.id = a.clientFk + JOIN sale s on s.ticketFk = t.id + JOIN saleComponent sc on sc.saleFk = s.id + JOIN component comp ON sc.componentFk = comp.id + JOIN componentType ct ON ct.id = comp.typeFk AND ct.code = 'mana' + WHERE t.shipped > vFromDated + AND t.shipped < util.tomorrow() + UNION ALL + SELECT tc.id, -amountPaid + FROM receipt r + JOIN `client` c ON c.id = r.clientFk + JOIN tmp.client tc ON tc.id = c.id + JOIN bank b ON r.bankFk = b.id AND b.code = 'mana' + WHERE r.payed > vFromDated + AND r.payed <= util.VN_CURDATE() + UNION ALL + SELECT tc.id, g.amount + FROM greuge g + JOIN `client` c ON c.id = g.clientFk + JOIN tmp.client tc ON tc.id = c.id + JOIN greugeType gt ON gt.id = g.greugeTypeFk AND gt.code = 'mana' + WHERE g.shipped > vFromDated + AND g.shipped <= util.VN_CURDATE() + ) sub + GROUP BY id; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `client_RandomList` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -51778,7 +52302,7 @@ BEGIN DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; CREATE OR REPLACE TEMPORARY TABLE tClientList - SELECT c.id clientFk + SELECT c.clientFk FROM bs.clientDied cd JOIN client c ON c.id = cd.id LEFT JOIN clientProtected cp ON cp.clientFk = c.id @@ -51786,7 +52310,7 @@ BEGIN JOIN province p ON p.id = c.provinceFk LEFT JOIN autonomy a ON a.id = p.autonomyFk JOIN country co ON co.id = p.countryFk - WHERE cd.Aviso = 'TERCER AVISO' + WHERE cd.warning = 'third' AND cp.clientFk IS NULL AND sp.salesPersonFk IS NULL AND a.name <> 'Canarias' @@ -51865,127 +52389,6 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `cmr_getByTicket` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `cmr_getByTicket`(vTicketFk INT) -BEGIN - - DECLARE vLanded DATE; - - SELECT DATE_ADD(util.VN_CURDATE(), INTERVAL landingDays DAY) INTO vLanded - FROM vn.cmrConfig; - - IF vTicketFk THEN - - IF (SELECT count(ticketFk) FROM vn.cmr WHERE ticketFk = vTicketFk) THEN - - SELECT id FROM vn.cmr WHERE ticketFk = vTicketFk; - - ELSE - - INSERT INTO vn.cmr(ticketFk, companyFk, addressFromFk, addressToFk, ead) - SELECT vTicketFk, t.companyFk, a.id, t.addressFk, vLanded - FROM vn.ticket t - JOIN vn.warehouse w ON w.id = t.warehouseFk - JOIN vn.address a ON a.id = w.addressFk - WHERE t.id = vTicketFk; - - SELECT LAST_INSERT_ID(); - - END IF; - - ELSE - - INSERT INTO vn.cmr(ead) VALUES(vLanded); - - SELECT LAST_INSERT_ID(); - - END IF; -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `cmr_sendOverview` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `cmr_sendOverview`() -BEGIN -/** - * Insert the monthly CMR summary in vn.mail on the 5th of each month. - */ - - SET SESSION group_concat_max_len = 1000000; --- IF (DAY(util.VN_CURDATE()) = 5) THEN - INSERT INTO - vn.mail (receiver, - replyTo, - subject, - body) - SELECT - c2.email, - 'cmr@verdnatura.es', - 'Resumen CMR', - CONCAT('
-

Resumen Mensual CMR

- - - - - - - - ' - , GROUP_CONCAT('' ORDER BY c.id SEPARATOR '' ), - '
- Estimado cliente,
- A continuación le enviamos el resumen menual de CMR ',UPPER(MONTHNAME(util.VN_CURDATE() - INTERVAL 1 MONTH)),' ', YEAR(util.VN_CURDATE() - INTERVAL 1 MONTH), '.

- Le rogamos que nos devuelva el resumen firmado a cmr@verdnatura.es
-

-
CMRTicket
', c.id, ' ', c.ticketFk, '
- -

- Saludos cordiales, Dpto administración. -

') - FROM vn.cmr c - JOIN vn.address a ON c.addressToFk = a.id - JOIN vn.client c2 ON a.clientFk = c2.id - WHERE c.state = 'Pending' - AND MONTH(c.created) = MONTH(util.VN_CURDATE() - INTERVAL 1 MONTH) - AND YEAR(c.created) = YEAR(util.VN_CURDATE() - INTERVAL 1 MONTH) - AND c2.email IS NOT NULL -- No cogemos los CMRs dirigidos a 'Verdnatura' - GROUP BY c2.id; - - -- Actualizamos el estado a 'Enviado' - UPDATE vn.cmr c - SET c.state = 'Sent' - WHERE c.state = 'Pending' - AND MONTH(c.created) = MONTH(util.VN_CURDATE() - INTERVAL 1 MONTH) - AND YEAR(c.created) = YEAR(util.VN_CURDATE() - INTERVAL 1 MONTH); --- END IF; -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `collectionPlacement_get` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -54275,46 +54678,51 @@ BEGIN * Borra los valores de duaTax y los vuelve a crear en base a la tabla duaEntry * * @param vDuaFk Id del dua a recalcular -**/ + */ DELETE FROM duaTax WHERE duaFk = vDuaFk; - INSERT INTO duaTax(duaFk, supplierFk, taxClassFk, base) - SELECT vDuaFk, supplierFk, taxClassFk, sum(sub.Base) as Base + INSERT INTO duaTax(duaFk, taxClassFk, base) + SELECT vDuaFk, taxClassFk, SUM(sub.totalBase) FROM intrastat ist JOIN - (SELECT - e.supplierFk, - i.intrastatFk, - CAST(sum(b.quantity * b.buyingValue * de.customsValue / de.value) * di.amount/ tei.Base AS DECIMAL(10,2)) as Base + (SELECT i.intrastatFk, + CAST(SUM(b.quantity * + b.buyingValue * + de.customsValue / + de.value) + * di.totalAmount / + bi.totalAmount AS DECIMAL(10,2) + ) totalBase FROM buy b JOIN item i ON i.id = b.itemFk JOIN entry e ON e.id = b.entryFk JOIN duaEntry de ON de.entryFk = e.id - JOIN - ( - SELECT i.intrastatFk, - CAST(sum(b.quantity * b.buyingValue * de.customsValue / de.value) AS DECIMAL(10,2)) as Base - FROM buy b - JOIN item i ON i.id = b.itemFk - JOIN entry e ON e.id = b.entryFk - JOIN duaEntry de ON de.entryFk = e.id - WHERE de.duaFk = vDuaFk - GROUP BY i.intrastatFk - - ) tei ON tei.intrastatFk = i.intrastatFk - JOIN - ( - SELECT intrastatFk, sum(amount) as amount - FROM duaIntrastat - WHERE duaFk = vDuaFk - GROUP BY intrastatFK - ) di ON di.intrastatFk = i.intrastatFk + JOIN( + SELECT i.intrastatFk, + CAST(SUM(b.quantity * + b.buyingValue * + de.customsValue / + de.value) AS DECIMAL(10,2) + ) totalAmount + FROM buy b + JOIN item i ON i.id = b.itemFk + JOIN entry e ON e.id = b.entryFk + JOIN duaEntry de ON de.entryFk = e.id + WHERE de.duaFk = vDuaFk + GROUP BY i.intrastatFk + ) bi ON bi.intrastatFk = i.intrastatFk + JOIN( + SELECT intrastatFk, SUM(amount) totalAmount + FROM duaIntrastat + WHERE duaFk = vDuaFk + GROUP BY intrastatFK + ) di ON di.intrastatFk = i.intrastatFk WHERE de.duaFk = vDuaFk - GROUP BY e.supplierFk, i.intrastatFk - HAVING Base - ) sub ON ist.id = sub.intrastatFk - GROUP BY ist.taxClassFk, sub.supplierFk; + GROUP BY i.intrastatFk + HAVING totalBase + )sub ON ist.id = sub.intrastatFk + GROUP BY ist.taxClassFk; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -54617,14 +55025,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `entry_checkPackaging` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `entry_checkPackaging`(vEntryFk INT) BEGIN @@ -54638,7 +55046,7 @@ BEGIN SELECT count(*) INTO vpackageOrPackingNull FROM buy b WHERE b.entryFk = vEntryFk - AND (b.packing IS NULL OR b.packageFk IS NULL); + AND (b.packing IS NULL OR b.packagingFk IS NULL); IF vpackageOrPackingNull THEN CALL util.throw("packageOrPackingNull"); @@ -54714,7 +55122,8 @@ BEGIN commission, currencyFk, companyFk, - clonedFrom + clonedFrom, + typeFk ) SELECT IFNULL(vTravelFk, travelFk), supplierFk, @@ -54724,7 +55133,8 @@ BEGIN commission, currencyFk, companyFk, - vSelf + vSelf, + typeFk FROM entry WHERE id = vSelf; @@ -54801,7 +55211,7 @@ BEGIN containerFk, comissionValue, packageValue, - packageFk, + packagingFk, price1, price2, price3, @@ -54824,7 +55234,7 @@ BEGIN containerFk, comissionValue, packageValue, - packageFk, + packagingFk, price1, price2, price3, @@ -55000,6 +55410,7 @@ BEGIN * * @param vSelf Identificador de entry * @param vDays Número de dias a futuro que se quiere la nueva entrada + * @param vChangeEntry Si se modifica la entrada original * * @return vNewEntryFk Identificador de la nueva entrada */ @@ -55007,8 +55418,12 @@ BEGIN DECLARE vTravelFk INT; DECLARE vInvoiceAmountOldEntryFk DECIMAL(10,2); DECLARE vInvoiceAmountNewEntry DECIMAL(10,2); + DECLARE vIsOrdered BOOL; + DECLARE vIsConfirmed BOOL; + DECLARE vInvoiceNumber VARCHAR(50); + DECLARE vTypeFk VARCHAR(100); - SELECT travelFk INTO vTravelFk + SELECT travelFk, isOrdered, isConfirmed, invoiceNumber, typeFk INTO vTravelFk, vIsOrdered, vIsConfirmed, vInvoiceNumber, vTypeFk FROM entry WHERE id = vSelf; @@ -55017,7 +55432,11 @@ BEGIN UPDATE entry e SET e.travelFk = vNewTravelFk, - e.evaNotes = CONCAT('No impresas de: ', vSelf, ' ', IFNULL(e.evaNotes,'')) + e.evaNotes = CONCAT('No impresas de: ', vSelf, ' ', IFNULL(e.evaNotes,'')), + e.isOrdered = vIsOrdered, + e.isConfirmed = vIsConfirmed, + e.invoiceNumber = vInvoiceNumber, + e.typeFk = vTypeFk WHERE e.id = vNewEntryFk; IF vChangeEntry THEN @@ -55523,246 +55942,6 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `errorProduction_add` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `errorProduction_add`( - vAction VARCHAR(25), - vDatedFrom DATETIME, - vDatedTo DATETIME) -BEGIN -/** - * Rellena la tabla vn.errorProduction - * - * @param vAction Accion que se quiere añadir - * @param vDatedFrom Fecha desde - * @param vDatedTo Fecha hasta - */ - DECLARE vDepartment VARCHAR(255); - - CASE - WHEN vAction = 'SACAR' THEN - SET vDepartment = 'Sacadores'; - WHEN vAction = 'ENCAJAR' THEN - SET vDepartment = 'Encajadores'; - WHEN vAction = 'CONTROLAR' THEN - SET vDepartment = 'Revisadores'; - END CASE; - - IF (vDepartment = 'Encajadores') THEN - CREATE OR REPLACE TEMPORARY TABLE total - ENGINE = MEMORY - SELECT e.workerFk, - COUNT(DISTINCT t.id) ticketCount, - COUNT(s.id) lineCount - FROM expedition e - JOIN ticket t ON e.ticketFk = t.id - JOIN sale s ON s.ticketFk = t.id - WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo - GROUP BY e.workerFk; - ELSE - CREATE OR REPLACE TEMPORARY TABLE total - ENGINE = MEMORY - SELECT st.workerFk, - COUNT(DISTINCT t.id) ticketCount, - COUNT(s.id) lineCount - FROM saleTracking st - JOIN `state` s2 ON s2.id = st.stateFk - JOIN sale s ON s.id = st.saleFk - JOIN ticket t ON s.ticketFk = t.id - WHERE (t.shipped BETWEEN vDatedFrom AND vDatedTo) - AND s2.code IN ('OK','PREVIOUS_PREPARATION','PREPARED','CHECKED') - GROUP BY st.workerFk; - END IF; - - CALL timeControl_calculateAll(vDatedFrom, vDatedTo); - - CREATE OR REPLACE TEMPORARY TABLE errorsByClaim - ENGINE = MEMORY - SELECT COUNT(c.ticketFk) errors, - cd.workerFk - FROM claimDevelopment cd - JOIN claim c ON cd.claimFk = c.id - JOIN ticket t ON c.ticketFk = t.id - JOIN claimResponsible cr ON cd.claimResponsibleFk = cr.id - WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo - AND cr.description = vDepartment - GROUP BY cd.workerFk; - - CREATE OR REPLACE TEMPORARY TABLE volume - ENGINE = MEMORY - SELECT SUM(w.volume) volume, - w.workerFk - FROM bs.workerProductivity w - WHERE w.dated BETWEEN vDatedFrom AND vDatedTo - GROUP BY w.workerFk; - - CREATE OR REPLACE TEMPORARY TABLE errorsByChecker - ENGINE = MEMORY - SELECT sub1.workerFk, COUNT(id) errors - FROM ( - SELECT st.workerFk, - t.id - FROM saleMistake sm - JOIN saleTracking st ON sm.saleFk = st.saleFk - JOIN `state` s2 ON s2.id = st.stateFk - JOIN sale s ON s.id = sm.saleFk - JOIN ticket t on t.id = s.ticketFk - WHERE (t.shipped BETWEEN vDatedFrom AND vDatedTo) - AND s2.code IN ('OK','PREVIOUS_PREPARATION','PREPARED','CHECKED') - ) sub1 - GROUP BY sub1.workerFk; - - CREATE OR REPLACE TEMPORARY TABLE expeditionErrors - ENGINE = MEMORY - SELECT COUNT(t.id) errors, - e.workerFk - FROM vn.expeditionMistake pm - JOIN vn.expedition e ON e.id = pm.expeditionFk - JOIN vn.ticket t ON t.id = e.ticketFk - WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo - GROUP BY e.workerFk; - - IF (vDepartment = 'Sacadores') THEN - - INSERT INTO errorProduction(userFk, - firstname, - lastname, - rol, - ticketNumber, - lineNumber, - error, - volume, - hourStart, - hourEnd, - hourWorked, - dated) - SELECT w.id, - w.firstName, - w.lastName, - vDepartment, - t.ticketCount totalTickets, - t.lineCount, - IFNULL(ec.errors,0) + IFNULL(ec2.errors,0) errors, - IF(vDepartment = 'Revisadores', NULL, v.volume) volume, - SUBSTRING(tc.timed, 1, 5) hourStart, - SUBSTRING(tc.timed, LENGTH(tc.timed)-4, 5) hourEnd, - IFNULL(CAST(tc.timeWorkDecimal AS DECIMAL (10,2)) , 0) hourWorked, - vDatedFrom dated - FROM total t - LEFT JOIN worker w ON w.id = t.workerFk - LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = t.workerFk - LEFT JOIN errorsByClaim ec ON ec.workerFk = t.workerFk - LEFT JOIN volume v ON v.workerFk = t.workerFk - LEFT JOIN errorsByChecker ec2 ON ec2.workerFk = t.workerFk - JOIN (SELECT DISTINCT w.id -- Verificamos que son sacadores - FROM vn.collection c - JOIN vn.state s ON s.id = c.stateFk - JOIN vn.train tn ON tn.id = c.trainFk - JOIN vn.worker w ON w.id = c.workerFk - WHERE c.created BETWEEN vDatedFrom AND vDatedTo) sub ON sub.id = w.id - GROUP BY w.id; - - CREATE OR REPLACE TEMPORARY TABLE itemPickerErrors -- Errores de los sacadores, derivadores de los revisadores - ENGINE = MEMORY - SELECT COUNT(c.ticketFk) errors, - tt.workerFk - FROM claimDevelopment cd - JOIN claim c ON cd.claimFk = c.id - JOIN ticket t ON c.ticketFk = t.id - JOIN claimResponsible cr ON cd.claimResponsibleFk = cr.id - JOIN ticketTracking tt ON tt.ticketFk = t.id - JOIN `state` s ON s.id = tt.stateFk - WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo - AND cr.description = 'Revisadores' - AND s.code = 'ON_PREPARATION' - GROUP BY workerFk; - - UPDATE errorProduction ep - JOIN itemPickerErrors ipe ON ipe.workerFk = ep.userFk - SET ep.error = ep.error + ipe.errors - WHERE vDatedFrom = ep.dated AND ep.rol = 'Sacadores'; - - DROP TEMPORARY TABLE itemPickerErrors; - ELSE - INSERT INTO errorProduction(userFk, - firstname, - lastname, - rol, - ticketNumber, - lineNumber, - error, - volume, - hourStart, - hourEnd, - hourWorked, - dated) - SELECT w.id, - w.firstName, - w.lastName, - vDepartment, - t.ticketCount totalTickets, - t.lineCount, - IFNULL(ec.errors,0) + IFNULL(ec2.errors,0) + IFNULL(pe.errors,0) errors, - IF(vDepartment = 'Revisadores', NULL, v.volume) volume, - SUBSTRING(tc.timed, 1, 5) hourStart, - SUBSTRING(tc.timed, LENGTH(tc.timed)-4, 5) hourEnd, - IFNULL(CAST(tc.timeWorkDecimal AS DECIMAL (10,2)) , 0) hourWorked, - vDatedFrom dated - FROM total t - LEFT JOIN worker w ON w.id = t.workerFk - LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = t.workerFk - LEFT JOIN errorsByClaim ec ON ec.workerFk = t.workerFk - LEFT JOIN volume v ON v.workerFk = t.workerFk - LEFT JOIN errorsByChecker ec2 ON ec2.workerFk = t.workerFk - LEFT JOIN expeditionErrors pe ON pe.workerFk = t.workerFk - GROUP BY w.id; - END IF; - - DROP TEMPORARY TABLE total, - errorsByClaim, - volume, - errorsByChecker, - expeditionErrors; -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `errorProduction_addLauncher` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `errorProduction_addLauncher`() -BEGIN - DECLARE vDatedFrom DATETIME; - DECLARE vDatedTo DATETIME; - - SELECT DATE_SUB(util.VN_CURDATE(),INTERVAL 1 DAY), CONCAT(DATE_SUB(util.VN_CURDATE(),INTERVAL 1 DAY),' 23:59:59') INTO vDatedFrom, vDatedTo; - - CALL vn.errorProduction_add('SACAR', vDatedFrom, vDatedTo); - CALL vn.errorProduction_add('ENCAJAR', vDatedFrom, vDatedTo); - CALL vn.errorProduction_add('CONTROLAR', vDatedFrom, vDatedTo); -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `expeditionGetFromRoute` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -56627,14 +56806,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `fustControl` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `fustControl`(vFromDated DATE, vToDated DATE) BEGIN @@ -56656,14 +56835,14 @@ BEGIN LEFT JOIN ( SELECT FustCode, sum(fustQuantity) stucks FROM ( - SELECT IFNULL(pe.equivalentFk ,b.packageFk) FustCode, s.quantity / b.packing AS fustQuantity + SELECT IFNULL(pe.equivalentFk ,b.packagingFk) FustCode, s.quantity / b.packing AS fustQuantity FROM vn.sale s JOIN vn.ticket t ON t.id = s.ticketFk JOIN vn.warehouse w ON w.id = t.warehouseFk JOIN vn.warehouseAlias wa ON wa.id = w.aliasFk JOIN cache.last_buy lb ON lb.item_id = s.itemFk AND lb.warehouse_id = t.warehouseFk JOIN vn.buy b ON b.id = lb.buy_id - JOIN vn.packaging p ON p.id = b.packageFk + JOIN vn.packaging p ON p.id = b.packagingFk LEFT JOIN vn.packageEquivalent pe ON pe.packagingFk = p.id JOIN vn.address a ON a.id = t.addressFk JOIN vn.province p2 ON p2.id = a.provinceFk @@ -57332,7 +57511,7 @@ proc: BEGIN inv.groupingMode = b.groupingMode, inv.comissionValue = b.comissionValue, inv.packageValue = b.packageValue, - inv.packageFk = b.packageFk, + inv.packageFk = b.packagingFk, inv.price1 = b.price1, inv.price2 = b.price2, inv.price3 = b.price3, @@ -57348,28 +57527,28 @@ proc: BEGIN groupingMode, comissionValue, packageValue, - packageFk, + packagingFk, price1, price2, price3, minPrice, entryFk) SELECT itemFk, - GREATEST(quantity, 0), - buyingValue, - freightValue, - packing, - `grouping`, - groupingMode, - comissionValue, - packageValue, - packageFk, - price1, - price2, - price3, - minPrice, - vEntryFk - FROM tmp.inventory; + GREATEST(quantity, 0), + buyingValue, + freightValue, + packing, + `grouping`, + groupingMode, + comissionValue, + packageValue, + packageFk, + price1, + price2, + price3, + minPrice, + vEntryFk + FROM tmp.inventory; SELECT vWh, COUNT(*), util.VN_NOW() FROM tmp.inventory; @@ -57437,14 +57616,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `inventory_repair` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `inventory_repair`() BEGIN @@ -57470,7 +57649,7 @@ BEGIN i.stems, b.quantity, b.buyingValue, - b.packageFk , + b.packagingFk , s.id AS supplierFk, s.name AS supplier FROM itemType it @@ -57484,7 +57663,7 @@ BEGIN LEFT JOIN origin o ON o.id = i.originFk ) ON it.id = i.typeFk LEFT JOIN edi.ekt ek ON b.ektFk = ek.id - WHERE (b.packageFk = "--" OR b.price2 = 0 OR b.packing = 0 OR b.buyingValue = 0) AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-1,util.VN_CURDATE())) AND s.name = 'INVENTARIO'; + WHERE (b.packagingFk = "--" OR b.price2 = 0 OR b.packing = 0 OR b.buyingValue = 0) AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-1,util.VN_CURDATE())) AND s.name = 'INVENTARIO'; DROP TEMPORARY TABLE IF EXISTS tmp.lastEntryOk; CREATE TEMPORARY TABLE tmp.lastEntryOk @@ -57507,7 +57686,7 @@ BEGIN i.stems, b.quantity, b.buyingValue, - b.packageFk , + b.packagingFk, s.id AS supplierFk, s.name AS supplier FROM itemType it @@ -57521,7 +57700,7 @@ BEGIN LEFT JOIN origin o ON o.id = i.originFk ) ON it.id = i.typeFk LEFT JOIN edi.ekt ek ON b.ektFk = ek.id - WHERE b.packageFk != "--" AND b.price2 != 0 AND b.packing != 0 AND b.buyingValue > 0 AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-2,util.VN_CURDATE())) + WHERE b.packagingFk != "--" AND b.price2 != 0 AND b.packing != 0 AND b.buyingValue > 0 AND tr.landed > util.firstDayOfMonth(TIMESTAMPADD(MONTH,-2,util.VN_CURDATE())) ORDER BY tr.landed DESC; DROP TEMPORARY TABLE IF EXISTS tmp.lastEntryOkGroup; @@ -57534,7 +57713,7 @@ BEGIN UPDATE buy b JOIN tmp.lastEntry lt ON lt.buyFk = b.id JOIN tmp.lastEntryOkGroup eo ON eo.itemFk = lt.itemFk AND eo.warehouseFk = lt.warehouseFk - SET b.packageFk = eo.packageFk WHERE b.packageFk = "--"; + SET b.packagingFk = eo.packagingFk WHERE b.packagingFk = "--"; UPDATE buy b JOIN tmp.lastEntry lt ON lt.buyFk = b.id @@ -57854,6 +58033,41 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `invoiceInTax_afterUpsert` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceInTax_afterUpsert`(vInvoiceInFk INT) +BEGIN +/** + * Triggered actions when a invoiceInTax is updated or inserted. + * + * @param vInvoiceInFk The invoiceIn id + */ + DECLARE vTaxRowLimit INT; + DECLARE vLines INT; + + SELECT taxRowLimit INTO vTaxRowLimit FROM invoiceInConfig; + + SELECT COUNT(*) INTO vLines + FROM invoiceInTax + WHERE invoiceInFk = vInvoiceInFk; + + IF vLines >= vTaxRowLimit THEN + CALL util.throw (CONCAT('The maximum number of lines is ', vTaxRowLimit)); + END IF; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `invoiceInTax_getFromDua` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -57981,10 +58195,10 @@ BEGIN ii.issued, ii.operated, ii.supplierRef, - ii.cplusTrascendency472Fk, + ii.siiTrascendencyInvoiceInFk, ii.cplusTaxBreakFk, ii.cplusSubjectOpFk, - ii.cplusInvoiceType472Fk, + ii.siiTypeInvoiceInFk, ii.cplusRectificationTypeFk, ii.booked, IFNULL(a.isUeeMember, c.isUeeMember) isUeeMember, @@ -58014,7 +58228,7 @@ BEGIN 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 + JOIN siiTypeInvoiceIn cit ON cit.id = ii.siiTypeInvoiceInFk 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 @@ -58137,10 +58351,10 @@ BEGIN tii.supplierRef FACTURAEX, TRUE L340, (tii.isSameCountry OR NOT tii.isUeeMember) LRECT349, - tii.cplusTrascendency472Fk TIPOCLAVE, + tii.siiTrascendencyInvoiceInFk TIPOCLAVE, tii.cplusTaxBreakFk TIPOEXENCI, tii.cplusSubjectOpFk TIPONOSUJE, - tii.cplusInvoiceType472Fk TIPOFACT, + tii.siiTypeInvoiceInFk TIPOFACT, tii.cplusRectificationTypeFk TIPORECTIF, tii.cplusTerIdNifFk TERIDNIF, tii.nif TERNIF, @@ -58209,7 +58423,7 @@ BEGIN 1 TIPOCLAVE, tii.cplusTaxBreakFk TIPOEXENCI, tii.cplusSubjectOpFk TIPONOSUJE, - tii.cplusInvoiceType472Fk TIPOFACT, + tii.siiTypeInvoiceInFk TIPOFACT, tii.cplusRectificationTypeFk TIPORECTIF, tii.cplusTerIdNifFk TERIDNIF, tii.nif TERNIF, @@ -58369,7 +58583,7 @@ BEGIN io.issued AS FECHA, 1 AS NFACTICK, IF(ic.correctingFk,'D','') AS TIPOOPE, - io.cplusTrascendency477Fk AS TIPOCLAVE, + io.siiTrascendencyInvoiceOutFk AS TIPOCLAVE, io.cplusTaxBreakFk AS TIPOEXENCI, io.cplusSubjectOpFk AS TIPONOSUJE, io.siiTypeInvoiceOutFk AS TIPOFACT, @@ -58505,7 +58719,7 @@ BEGIN rs.TERNIF, rs.TERNOM, pgc.mod340 AS L340, - pgc.cplusTrascendency477Fk AS TIPOCLAVE, + pgc.siiTrascendencyInvoiceOutFk AS TIPOCLAVE, pgc.cplusTaxBreakFk as TIPOEXENCI, rs.TIPONOSUJE, rs.TIPOFACT, @@ -58582,85 +58796,6 @@ BEGIN SELECT CONCAT(vContador, ' total') AS FACTURAS_ASENTADAS; -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `invoiceOutDelete` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceOutDelete`(vRef VARCHAR(15)) -BEGIN - DECLARE vAsien INTEGER; - DECLARE vSendMail BOOL; - DECLARE vBody TEXT; - - SELECT ASIEN INTO vAsien - FROM XDiario - WHERE SERIE = SUBSTRING(vRef, 1, 1) - AND FACTURA = SUBSTRING(vRef, 2, LENGTH(vRef)-1) - LIMIT 1; - - SELECT IF(enlazado OR enlazadoSage, TRUE, FALSE), - CONCAT( - ' - - - - - - - ', - GROUP_CONCAT( - CONCAT(' - - - - - - - ' - ) SEPARATOR ' ' - ), - '
FECHASUBCTACONTRACONCEPTOEURODEBEEUROHABER
', IFNULL(FECHA,''), '', IFNULL(SUBCTA,''), '', IFNULL(CONTRA,''), '', IFNULL(CONCEPTO,''), '', IFNULL(EURODEBE,''), '', IFNULL(EUROHABER,''), '
' - ) - INTO vSendMail, vBody - FROM XDiario - WHERE ASIEN = vAsien; - - DELETE FROM XDiario - WHERE ASIEN = vAsien; - - IF vSendMail THEN - CALL mail_insert( - 'administracion@verdnatura.es', - 'noreply@verdnatura.es', - CONCAT('Eliminada factura ' ,vRef), - CONCAT( - '
-

Se ha eliminado el asiento ', vAsien, ' que estaba enlazado en SAGE/CONTAPLUS, vinculado a la factura ', vRef ,'

- ', vBody, '
' - ) - ); - END IF; - - UPDATE ticket - SET refFk = NULL - WHERE refFk = vRef; - - DELETE - FROM invoiceOut - WHERE ref = vRef; - END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -59317,46 +59452,6 @@ ELSE INSERT INTO vn.itemBarcode(itemFk,code) VALUES (vItemFk,vCode); END IF; -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `itemFreight_Show` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `itemFreight_Show`(vItemFk INT, vWarehouseFk INT) -BEGIN - - SELECT cm3 Volumen_Entrada, - cm3delivery Volumen_Salida, - p.volume Volumen_del_embalaje, - p.width Ancho_del_embalaje, - p.`depth` Largo_del_embalaje, - b.packageFk , - IFNULL(p.height, i.`size`) + 10 Altura, - b.packing Packing_Entrada, - i.packingOut Packing_Salida, - i.id itemFk, - b.id buyFk, - b.entryFk, - w.name warehouseFk - FROM vn.itemCost ic - JOIN vn.item i ON i.id = ic.itemFk - LEFT JOIN cache.last_buy lb ON lb.item_id = ic.itemFk AND lb.warehouse_id = ic.warehouseFk - LEFT JOIN vn.buy b ON b.id = lb.buy_id - LEFT JOIN vn.packaging p ON p.id = b.packageFk - LEFT JOIN vn.warehouse w ON w.id = ic.warehouseFk - WHERE ic.itemFk = vItemFk - AND ic.warehouseFk = vWarehouseFk; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -59649,7 +59744,7 @@ BEGIN AND ish.visible > 0 AND ish.itemFk = vItemFk GROUP BY ish.id - ORDER BY (sc.id = vSectorFk) DESC, sh.priority DESC; + ORDER BY (sc.id = vSectorFk) DESC, sh.priority DESC, ish.created, p.pickingOrder; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -59677,78 +59772,78 @@ BEGIN * @param vShowType mostrar tipos */ - DECLARE vWarehouseFk INT; - DECLARE vShipped DATE; - DECLARE vCalcFk INT; - DECLARE vTypeFk INT; + DECLARE vWarehouseFk INT; + DECLARE vShipped DATE; + DECLARE vCalcFk INT; + DECLARE vTypeFk INT; + DECLARE vTag1 VARCHAR(25); + DECLARE vTag5 VARCHAR(25); + DECLARE vTag6 VARCHAR(25); + DECLARE vTag7 VARCHAR(25); + DECLARE vTag8 VARCHAR(25); - DECLARE vTag1 VARCHAR(25); - DECLARE vTag5 VARCHAR(25); - DECLARE vTag6 VARCHAR(25); - DECLARE vTag7 VARCHAR(25); - DECLARE vTag8 VARCHAR(25); + DECLARE vValue1 VARCHAR(50); + DECLARE vValue5 VARCHAR(50); + DECLARE vValue6 VARCHAR(50); + DECLARE vValue7 VARCHAR(50); + DECLARE vValue8 VARCHAR(50); - DECLARE vValue1 VARCHAR(50); - DECLARE vValue5 VARCHAR(50); - DECLARE vValue6 VARCHAR(50); - DECLARE vValue7 VARCHAR(50); - DECLARE vValue8 VARCHAR(50); + SELECT warehouseFk, shipped INTO vWarehouseFk, vShipped + FROM vn.ticket + WHERE id = vTicketFk; - SELECT warehouseFk, shipped INTO vWarehouseFk, vShipped - FROM vn.ticket - WHERE id = vTicketFk; + SELECT typeFk, tag5, value5, tag6, value6, tag7, value7, tag8, value8, t1.name, it1.value + INTO vTypeFk, vTag5, vValue5, vTag6, vValue6, vTag7, vValue7, vTag8, vValue8, vTag1, vValue1 + FROM vn.item i + LEFT JOIN vn.itemTag it1 ON it1.itemFk = i.id AND it1.priority = 1 + LEFT JOIN vn.tag t1 ON t1.id = it1.tagFk + WHERE i.id = vItemFk; - SELECT typeFk, tag5, value5, tag6, value6, tag7, value7, tag8, value8, t1.name, it1.value - INTO vTypeFk, vTag5, vValue5, vTag6, vValue6, vTag7, vValue7, vTag8, vValue8, vTag1, vValue1 - FROM vn.item i - LEFT JOIN vn.itemTag it1 ON it1.itemFk = i.id AND it1.priority = 1 - LEFT JOIN vn.tag t1 ON t1.id = it1.tagFk - WHERE i.id = vItemFk; + CALL cache.available_refresh(vCalcFk, FALSE, vWarehouseFk, vShipped); - CALL cache.available_refresh(vCalcFk, FALSE, vWarehouseFk, vShipped); - - SELECT i.id itemFk, - i.longName, - i.subName, - i.tag5, - i.value5, - (i.value5 <=> vValue5 COLLATE utf8_general_ci) match5, - i.tag6, - i.value6, - (i.value6 <=> vValue6 COLLATE utf8_general_ci) match6, - i.tag7, - i.value7, - (i.value7 <=> vValue7 COLLATE utf8_general_ci) match7, - i.tag8, - i.value8, - (i.value8 <=> vValue8 COLLATE utf8_general_ci) match8, - a.available, - IFNULL(ip.counter,0) counter, - IF(b.groupingMode = 1, b.grouping, b.packing) as minQuantity - FROM vn.item i - JOIN cache.available a ON a.item_id = i.id - LEFT JOIN vn.itemProposal ip ON ip.mateFk = i.id AND ip.itemFk = vItemFk - LEFT JOIN vn.itemTag it1 ON it1.itemFk = i.id AND it1.priority = 1 - LEFT JOIN vn.tag t1 ON t1.id = it1.tagFk + SELECT i.id itemFk, + i.longName, + i.subName, + i.tag5, + i.value5, + (i.value5 <=> vValue5 COLLATE utf8_general_ci) match5, + i.tag6, + i.value6, + (i.value6 <=> vValue6 COLLATE utf8_general_ci) match6, + i.tag7, + i.value7, + (i.value7 <=> vValue7 COLLATE utf8_general_ci) match7, + i.tag8, + i.value8, + (i.value8 <=> vValue8 COLLATE utf8_general_ci) match8, + a.available, + IFNULL(ip.counter,0) counter, + IF(b.groupingMode = 1, b.grouping, b.packing) as minQuantity, + iss.visible located + FROM item i + JOIN cache.available a ON a.item_id = i.id + LEFT JOIN itemProposal ip ON ip.mateFk = i.id AND ip.itemFk = vItemFk + LEFT JOIN itemTag it1 ON it1.itemFk = i.id AND it1.priority = 1 + LEFT JOIN tag t1 ON t1.id = it1.tagFk LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = vWarehouseFk - LEFT JOIN vn.buy b ON b.id = lb.buy_id - WHERE a.calc_id = vCalcFk - AND available > 0 - AND IF(vShowType,i.typeFk = vTypeFk,true) - AND i.id != vItemFk - ORDER BY counter DESC, - (t1.name = vTag1 COLLATE utf8_general_ci) DESC, - (it1.value = vValue1 COLLATE utf8_general_ci) DESC, - (i.tag6 = vTag6 COLLATE utf8_general_ci) DESC, - (i.value6 = vValue6 COLLATE utf8_general_ci) DESC, - (i.tag5 = vTag5 COLLATE utf8_general_ci) DESC, - (i.value5 = vValue5 COLLATE utf8_general_ci) DESC, - (i.tag7 = vTag7 COLLATE utf8_general_ci) DESC, - (i.value7 = vValue7 COLLATE utf8_general_ci) DESC, - (i.tag8 = vTag8 COLLATE utf8_general_ci) DESC, - (i.value8 = vValue8 COLLATE utf8_general_ci) DESC; - + LEFT JOIN buy b ON b.id = lb.buy_id + LEFT JOIN itemShelvingStock iss ON iss.itemFk = i.id AND iss.warehouseFk = vWarehouseFk + WHERE a.calc_id = vCalcFk + AND available > 0 + AND IF(vShowType,i.typeFk = vTypeFk,true) + AND i.id != vItemFk + ORDER BY counter DESC, + (t1.name = vTag1 COLLATE utf8_general_ci) DESC, + (it1.value = vValue1 COLLATE utf8_general_ci) DESC, + (i.tag5 = vTag5 COLLATE utf8_general_ci) DESC, + (i.value5 = vValue5 COLLATE utf8_general_ci) DESC, + (i.tag6 = vTag6 COLLATE utf8_general_ci) DESC, + (i.value6 = vValue6 COLLATE utf8_general_ci) DESC, + (i.tag7 = vTag7 COLLATE utf8_general_ci) DESC, + (i.value7 = vValue7 COLLATE utf8_general_ci) DESC, + (i.tag8 = vTag8 COLLATE utf8_general_ci) DESC, + (i.value8 = vValue8 COLLATE utf8_general_ci) DESC; END ;; DELIMITER ; @@ -60126,14 +60221,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `itemShelvingMakeFromDate` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `itemShelvingMakeFromDate`(IN `vShelvingFk` VARCHAR(8), IN `vBarcode` VARCHAR(22), IN `vQuantity` INT, IN `vPackagingFk` VARCHAR(10), IN `vGrouping` INT, IN `vPacking` INT, IN `vWarehouseFk` INT, `vCreated` VARCHAR(22)) BEGIN @@ -60183,7 +60278,7 @@ BEGIN vCreated, IF(vGrouping = 0, IFNULL(b.packing, vPacking), vGrouping) `grouping`, IF(vPacking = 0, b.packing, vPacking) packing, - IF(vPackagingFk = '', b.packageFk, vPackagingFk) packaging + IF(vPackagingFk = '', b.packagingFk, vPackagingFk) packaging FROM vn.item i LEFT JOIN cache.last_buy lb ON i.id = lb.item_id AND lb.warehouse_id = vWarehouseFk LEFT JOIN vn.buy b ON b.id = lb.buy_id @@ -60371,7 +60466,6 @@ proc:BEGIN WHERE s.warehouseFk = vWarehouseFk AND s.isMain; - SELECT COUNT(*) INTO hasFatherSector FROM vn.sector WHERE sonFk = vSectorFk; @@ -60386,52 +60480,49 @@ proc:BEGIN DROP TEMPORARY TABLE IF EXISTS tmp.itemShelvingRadar; IF hasFatherSector THEN - CREATE TEMPORARY TABLE tmp.itemShelvingRadar (PRIMARY KEY (itemFk)) ENGINE = MEMORY - SELECT * FROM ( - SELECT iss.itemFk, - i.longName, - i.size, - i.subName producer, - IFNULL(a.available,0) available, - SUM(IF(s.sonFk = vSectorFk, IFNULL(iss.visible,0), 0)) upstairs, - SUM(IF(iss.sectorFk = vSectorFk, IFNULL(iss.visible,0), 0)) downstairs, - IF(it.isPackaging, null, IFNULL(v.visible,0)) as visible, - vSectorFk as sectorFk + SELECT * + FROM ( + SELECT iss.itemFk, + i.longName, + i.size, + i.subName producer, + IFNULL(a.available,0) available, + SUM(IF(s.sonFk = vSectorFk, IFNULL(iss.visible,0), 0)) upstairs, + SUM(IF(iss.sectorFk = vSectorFk, IFNULL(iss.visible,0), 0)) downstairs, + IF(it.isPackaging, NULL, IFNULL(v.visible,0)) as visible, + vSectorFk sectorFk + FROM vn.itemShelvingStock iss + JOIN vn.sector s ON s.id = iss.sectorFk + JOIN vn.item i on i.id = iss.itemFk + JOIN vn.itemType it ON it.id = i.typeFk AND vBuyerFk IN (0,it.workerFk) + LEFT JOIN cache.available a ON a.item_id = iss.itemFk AND a.calc_id = vCalcAvailableFk + LEFT JOIN cache.visible v ON v.item_id = iss.itemFk AND v.calc_id = vCalcVisibleFk + WHERE vSectorFk IN (iss.sectorFk, s.sonFk) + GROUP BY iss.itemFk - FROM vn.itemShelvingStock iss - JOIN vn.sector s ON s.id = iss.sectorFk - JOIN vn.item i on i.id = iss.itemFk - JOIN vn.itemType it ON it.id = i.typeFk AND vBuyerFk IN (0,it.workerFk) - LEFT JOIN cache.available a ON a.item_id = iss.itemFk AND a.calc_id = vCalcAvailableFk - LEFT JOIN cache.visible v ON v.item_id = iss.itemFk AND v.calc_id = vCalcVisibleFk - WHERE vSectorFk IN (iss.sectorFk, s.sonFk) - AND it.workerFk != 3366 + UNION ALL - GROUP BY iss.itemFk - - UNION ALL - - SELECT v.item_id, - i.longName, - i.size, - i.subName producer, - IFNULL(a.available,0) as available, - 0 upstairs, - 0 downstairs, - IF(it.isPackaging, NULL, v.visible) visible, - vSectorFk as sectorFk - FROM cache.visible v - JOIN vn.item i on i.id = v.item_id - JOIN vn.itemType it ON it.id = i.typeFk AND vBuyerFk IN (0,it.workerFk) - LEFT JOIN vn.itemShelvingStock iss ON iss.itemFk = v.item_id AND iss.warehouseFk = vWarehouseFk - LEFT JOIN cache.available a ON a.item_id = v.item_id AND a.calc_id = vCalcAvailableFk - WHERE v.calc_id = vCalcVisibleFk - AND iss.itemFk IS NULL - AND it.isInventory - ) sub GROUP BY itemFk; + SELECT v.item_id, + i.longName, + i.size, + i.subName producer, + IFNULL(a.available,0) as available, + 0 upstairs, + 0 downstairs, + IF(it.isPackaging, NULL, v.visible) visible, + vSectorFk as sectorFk + FROM cache.visible v + JOIN vn.item i on i.id = v.item_id + JOIN vn.itemType it ON it.id = i.typeFk AND vBuyerFk IN (0,it.workerFk) + LEFT JOIN vn.itemShelvingStock iss ON iss.itemFk = v.item_id AND iss.warehouseFk = vWarehouseFk + LEFT JOIN cache.available a ON a.item_id = v.item_id AND a.calc_id = vCalcAvailableFk + WHERE v.calc_id = vCalcVisibleFk + AND iss.itemFk IS NULL + AND it.isInventory + ) sub GROUP BY itemFk; SELECT ishr.*, CAST(visible - upstairs - downstairs AS DECIMAL(10,0)) AS nicho, @@ -60446,12 +60537,8 @@ proc:BEGIN AND tst.alertLevel = 0 GROUP BY s.itemFk ) sub ON sub.itemFk = ishr.itemFk - ORDER BY i.typeFk, i.longName - ; - - + ORDER BY i.typeFk, i.longName; ELSE - CREATE TEMPORARY TABLE tmp.itemShelvingRadar (PRIMARY KEY (itemFk)) ENGINE = MEMORY @@ -60473,32 +60560,25 @@ proc:BEGIN IFNULL(v.visible,0) visible, b.isPickedOff, iss.sectorFk - FROM vn.itemShelvingStock iss - JOIN vn.item i on i.id = iss.itemFk - LEFT JOIN cache.last_buy lb ON lb.item_id = iss.itemFk AND lb.warehouse_id = vWarehouseFk - LEFT JOIN vn.buy b ON b.id = lb.buy_id - LEFT JOIN cache.available a ON a.item_id = iss.itemFk AND a.calc_id = vCalcAvailableFk - LEFT JOIN cache.visible v ON v.item_id = iss.itemFk AND v.calc_id = vCalcVisibleFk - LEFT JOIN (SELECT itemFk, sum(saldo) as onTheWay - FROM vn.itemPlacementSupplyList - WHERE saldo > 0 - GROUP BY itemFk - ) ips ON ips.itemFk = i.id - WHERE IFNULL(iss.sectorFk,0) IN (0, vSectorFk) - OR iss.sectorFk = vSectorFk; - /* - UPDATE tmp.itemShelvingRadar isr - JOIN vn.itemShelvingStock iss ON iss.itemFk = isr.itemFk - SET isr.dayEndVisible = isr.dayEndVisible + iss.visible, - isr.firstNegative = isr.firstNegative + iss.visible, - isr.itemPlacementVisible = isr.itemPlacementVisible + iss.visible - WHERE iss.sectorFk = vSonSectorFk; - */ + FROM vn.itemShelvingStock iss + JOIN vn.item i on i.id = iss.itemFk + LEFT JOIN cache.last_buy lb ON lb.item_id = iss.itemFk AND lb.warehouse_id = vWarehouseFk + LEFT JOIN vn.buy b ON b.id = lb.buy_id + LEFT JOIN cache.available a ON a.item_id = iss.itemFk AND a.calc_id = vCalcAvailableFk + LEFT JOIN cache.visible v ON v.item_id = iss.itemFk AND v.calc_id = vCalcVisibleFk + LEFT JOIN (SELECT itemFk, sum(saldo) as onTheWay + FROM vn.itemPlacementSupplyList + WHERE saldo > 0 + GROUP BY itemFk + ) ips ON ips.itemFk = i.id + WHERE IFNULL(iss.sectorFk,0) IN (0, vSectorFk) + OR iss.sectorFk = vSectorFk; + DROP TEMPORARY TABLE IF EXISTS tmp.itemOutTime; CREATE TEMPORARY TABLE tmp.itemOutTime SELECT *,SUM(amount) quantity FROM - (SELECT item_id itemFk, + (SELECT item_id itemFk, amount, IF(HOUR(t.shipped), HOUR(t.shipped), HOUR(z.`hour`)) as hours, IF(MINUTE(t.shipped), MINUTE(t.shipped), MINUTE(z.`hour`)) as minutes @@ -60528,15 +60608,19 @@ proc:BEGIN firstNegative = if (firstNegative < 0, firstNegative, firstNegative + quantity), `hour` = ifnull(if (firstNegative > 0 , `hour`, hours),0), `minute` = ifnull(if (firstNegative > 0, `minute`, minutes),0); -/* - UPDATE tmp.itemShelvingRadar - SET itemPlacementVisible = 0, - dayEndVisible = 0, - firstNegative = 0 - WHERE itemPlacementVisible = - itemShelvingStock; -*/ - SELECT * FROM tmp.itemShelvingRadar; + UPDATE tmp.itemShelvingRadar isr + JOIN (SELECT s.itemFk, sum(s.quantity) amount + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + JOIN ticketLastState tls ON tls.ticketFk = t.id + WHERE t.shipped BETWEEN util.VN_CURDATE() AND util.dayend(util.VN_CURDATE()) + AND tls.name = 'Prep Camara' + GROUP BY s.itemFk) sub ON sub.itemFk = isr.itemFk + SET isr.dayEndVisible = dayEndVisible + sub.amount, + firstNegative = firstNegative + sub.amount; + + SELECT * FROM tmp.itemShelvingRadar; END IF; DROP TEMPORARY TABLE tmp.itemShelvingRadar; @@ -60707,6 +60791,318 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `itemShelvingSale_reserve` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `itemShelvingSale_reserve`() +BEGIN +/** + * Reserva cantidades con ubicaciones para un conjunto de sales del mismo + * almacen. + * + * @table tmp.sale(saleFk, userFk) + */ + DECLARE vCalcFk INT; + DECLARE vWarehouseFk INT; + DECLARE vCurrentYear INT DEFAULT YEAR(util.VN_NOW()); + DECLARE vLastPickingOrder INT; + + SELECT t.warehouseFk, MAX(p.pickingOrder) + INTO vWarehouseFk, vLastPickingOrder + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN tmp.sale ts ON ts.saleFk = s.id + LEFT JOIN itemShelvingSale iss ON iss.saleFk = ts.saleFk + LEFT JOIN itemShelving ish ON ish.id = iss.itemShelvingFk + LEFT JOIN shelving sh ON sh.code = ish.shelvingFk + LEFT JOIN parking p ON p.id = sh.parkingFk + WHERE t.warehouseFk IS NOT NULL; + + IF vWarehouseFk IS NULL THEN + CALL util.throw('Warehouse not set'); + END IF; + + CALL cache.visible_refresh(vCalcFk, FALSE, vWarehouseFk); + + SET @outstanding = 0; + SET @oldsaleFk = 0; + + CREATE OR REPLACE TEMPORARY TABLE tSalePlacementQuantity + (INDEX(saleFk)) + ENGINE = MEMORY + SELECT saleFk, userFk, quantityToReserve, itemShelvingFk + FROM( SELECT saleFk, + sub.userFk, + itemShelvingFk , + IF(saleFk <> @oldsaleFk, @outstanding := quantity, @outstanding), + @qtr := LEAST(@outstanding, available) quantityToReserve, + @outStanding := @outStanding - @qtr, + @oldsaleFk := saleFk + FROM( + SELECT ts.saleFk, + ts.userFk, + s.quantity, + ish.id itemShelvingFk, + ish.visible - IFNULL(ishr.reservedQuantity, 0) available + FROM tmp.sale ts + JOIN sale s ON s.id = ts.saleFk + JOIN itemShelving ish ON ish.itemFk = s.itemFk + LEFT JOIN ( + SELECT itemShelvingFk, SUM(quantity) reservedQuantity + FROM itemShelvingSale + WHERE NOT isPicked + GROUP BY itemShelvingFk) ishr ON ishr.itemShelvingFk = ish.id + JOIN shelving sh ON sh.code = ish.shelvingFk + JOIN parking p ON p.id = sh.parkingFk + JOIN sector sc ON sc.id = p.sectorFk + JOIN warehouse w ON w.id = sc.warehouseFk + JOIN productionConfig pc + WHERE w.id = vWarehouseFk + AND NOT sc.isHideForPickers + ORDER BY + s.id, + p.pickingOrder >= vLastPickingOrder, + sh.priority DESC, + ish.visible >= s.quantity DESC, + s.quantity MOD ish.grouping = 0 DESC, + ish.grouping DESC, + IF(pc.orderMode = 'Location', p.pickingOrder, ish.created) + )sub + )sub2 + WHERE quantityToReserve > 0; + + INSERT INTO itemShelvingSale( + itemShelvingFk, + saleFk, + quantity, + userFk) + SELECT itemShelvingFk, + saleFk, + quantityToReserve, + IFNULL(userFk, getUser()) + FROM tSalePlacementQuantity spl; + + DROP TEMPORARY TABLE tmp.sale; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `itemShelvingSale_reserveByCollection` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `itemShelvingSale_reserveByCollection`( + vCollectionFk INT(11) +) +BEGIN +/** + * Reserva cantidades con ubicaciones para el contenido de una colección + * + * @param vCollectionFk Identificador de collection + */ + CREATE OR REPLACE TEMPORARY TABLE tmp.sale + (INDEX(saleFk)) + ENGINE = MEMORY + SELECT s.id saleFk, NULL userFk + FROM ticketCollection tc + JOIN sale s ON s.ticketFk = tc.ticketFk + LEFT JOIN ( + SELECT DISTINCT saleFk + FROM saleTracking st + JOIN state s ON s.id = st.stateFk + WHERE st.isChecked + AND s.semaphore = 1)st ON st.saleFk = s.id + WHERE tc.collectionFk = vCollectionFk + AND st.saleFk IS NULL + AND NOT s.isPicked; + + CALL itemShelvingSale_reserve(); +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `itemShelvingSale_reserveBySale` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `itemShelvingSale_reserveBySale`( + vSelf INT , + vQuantity INT, + vUserFk INT +) +BEGIN +/** + * Reserva cantida y ubicación para una saleFk + * + * @param vSelf Identificador de la venta + * @param vQuantity Cantidad a reservar + * @param vUserFk Id de usuario que realiza la reserva + */ + CREATE OR REPLACE TEMPORARY TABLE tmp.sale + ENGINE = MEMORY + SELECT vSelf saleFk, vUserFk userFk; + + CALL itemShelvingSale_reserve(); +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `itemShelvingSale_setQuantity` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `itemShelvingSale_setQuantity`( + vItemShelvingSaleFk INT(10), + vQuantity DECIMAL(10,0), + vIsItemShelvingSaleEmpty BOOLEAN +) +BEGIN +/** + * Gestiona la reserva de un itemShelvingFk, actualizando isPicked y quantity + * en vn.itemShelvingSale y vn.sale.isPicked en caso necesario. + * Si la reserva de la ubicación es fallida, se regulariza la situación + * + * @param vItemShelvingSaleFk Id itemShelvingSaleFK + * @param vQuantity Cantidad real que se ha cogido de la ubicación + * @param vIsItemShelvingSaleEmpty determina si ka ubicación itemShelvingSale se ha + * quedado vacio tras el movimiento + */ + DECLARE vSaleFk INT; + DECLARE vCursorSaleFk INT; + DECLARE vItemShelvingFk INT; + DECLARE vReservedQuantity INT; + DECLARE vRemainingQuantity INT; + DECLARE vItemFk INT; + DECLARE vUserFk INT; + DECLARE vDone BOOLEAN DEFAULT FALSE; + DECLARE vSales CURSOR FOR + SELECT iss.saleFk, iss.userFk + FROM itemShelvingSale iss + JOIN sale s ON s.id = iss.saleFk + WHERE iss.id = vItemShelvingSaleFk + AND s.itemFk = vItemFk + AND NOT iss.isPicked; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + + IF (SELECT isPicked FROM itemShelvingSale WHERE id = vItemShelvingSaleFk) THEN + CALL util.throw('Booking completed'); + END IF; + + SELECT s.itemFk, iss.saleFk, iss.itemShelvingFk + INTO vItemFk, vSaleFk, vItemShelvingFk + FROM itemShelvingSale iss + JOIN sale s ON s.id = iss.saleFk + WHERE iss.id = vItemShelvingSaleFk + AND NOT iss.isPicked; + + UPDATE itemShelvingSale + SET isPicked = TRUE, + quantity = vQuantity + WHERE id = vItemShelvingSaleFk; + + UPDATE itemShelving + SET visible = IF(vIsItemShelvingSaleEmpty, 0, GREATEST(0,visible - vQuantity)) + WHERE id = vItemShelvingFk; + + IF vIsItemShelvingSaleEmpty THEN + OPEN vSales; +l: LOOP + SET vDone = FALSE; + FETCH vSales INTO vCursorSaleFk, vUserFk; + IF vDone THEN + LEAVE l; + END IF; + + CREATE OR REPLACE TEMPORARY TABLE tmp.sale + (INDEX(saleFk, userFk)) + ENGINE = MEMORY + SELECT vCursorSaleFk, vUserFk; + + CALL itemShelvingSale_reserveWhitUser(); + DROP TEMPORARY TABLE tmp.sale; + + END LOOP; + CLOSE vSales; + + DELETE iss + FROM itemShelvingSale iss + JOIN sale s ON s.id = iss.saleFk + WHERE iss.id = vItemShelvingSaleFk + AND s.itemFk = vItemFk + AND NOT iss.isPicked; + END IF; + + SELECT SUM(quantity) INTO vRemainingQuantity + FROM itemShelvingSale + WHERE saleFk = vSaleFk + AND NOT isPicked; + + IF vRemainingQuantity THEN + CALL itemShelvingSale_reserveBySale (vSaleFk, vRemainingQuantity, NULL); + + SELECT SUM(quantity) INTO vRemainingQuantity + FROM itemShelvingSale + WHERE saleFk = vSaleFk + AND NOT isPicked; + + IF NOT vRemainingQuantity <=> 0 THEN + SELECT SUM(iss.quantity) + INTO vReservedQuantity + FROM itemShelvingSale iss + WHERE iss.saleFk = vSaleFk; + + CALL saleTracking_new( + vSaleFk, + TRUE, + vReservedQuantity, + `account`.`myUser_getId`(), + NULL, + 'PREPARED', + TRUE); + + UPDATE sale s + SET s.quantity = vReservedQuantity + WHERE s.id = vSaleFk ; + END IF; + END IF; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `itemShelvingTransfer` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -60764,14 +61160,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `itemShelving_add` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `itemShelving_add`(IN vShelvingFk VARCHAR(8), IN vBarcode VARCHAR(22), IN vQuantity INT, IN vPackagingFk VARCHAR(10), IN vGrouping INT, IN vPacking INT, IN vWarehouseFk INT) BEGIN @@ -60827,7 +61223,7 @@ BEGIN vQuantity, IFNULL(vGrouping, b.grouping), IFNULL(vPacking, b.packing), - IFNULL(vPackagingFk, b.packageFk) + IFNULL(vPackagingFk, b.packagingFk) FROM item i LEFT JOIN cache.last_buy lb ON i.id = lb.item_id AND lb.warehouse_id = vWarehouseFk LEFT JOIN buy b ON b.id = lb.buy_id @@ -60944,27 +61340,6 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `itemShelving_BuyerGet` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `itemShelving_BuyerGet`( ) -BEGIN - - SELECT * FROM vn.buyer; - -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `itemShelving_filterBuyer` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -61185,90 +61560,165 @@ DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `itemShelving_getSaleDate`(vShelvingFk VARCHAR(3)) BEGIN - /* Devuelve la minima fecha en que se necesita cada producto en esa matricula. + /* Devuelve la mínima fecha en que se necesita cada producto en esa matrícula. * * @param vShelvingFk Matrícula del carro o pallet */ DECLARE vWarehouseFk INT; + DECLARE vStockScopeDays INT; - SELECT warehouseFk INTO vWarehouseFk - FROM shelving s - JOIN parking p ON s.parkingFk = p.id - JOIN sector st ON st.id = p.sectorFk - WHERE s.code = vShelvingFk COLLATE utf8_unicode_ci; + SELECT s.warehouseFk, stockScopeDays + INTO vWarehouseFk, vStockScopeDays + FROM sector s + JOIN operator o ON s.id = o.sectorFk + JOIN productionConfig pc + WHERE o.workerFk = account.myUser_getId(); - DROP TEMPORARY TABLE IF EXISTS tmp.itemShelvingDistinct; - CREATE TEMPORARY TABLE tmp.itemShelvingDistinct + IF vWarehouseFk IS NULL + THEN CALL util.throw('WarehouseFk not setted'); + END IF; + + IF vStockScopeDays IS NULL + THEN CALL util.throw('StockScopeDays not setted'); + END IF; + + CREATE OR REPLACE TEMPORARY TABLE tmp.tItems (PRIMARY KEY (itemFk)) ENGINE = MEMORY - SELECT itemFk, SUM(visible) visible - FROM vn.itemShelving - WHERE shelvingFk = vShelvingFk COLLATE utf8_unicode_ci - GROUP BY itemFk; + SELECT itemFk, SUM(visible) visible + FROM itemShelving + WHERE shelvingFk = vShelvingFk COLLATE utf8_unicode_ci + GROUP BY itemFk; - DROP TEMPORARY TABLE IF EXISTS tmp.item; - CREATE TEMPORARY TABLE tmp.item - (PRIMARY KEY (itemFk)) - ENGINE = MEMORY - SELECT * FROM tmp.itemShelvingDistinct; + CREATE OR REPLACE TEMPORARY TABLE tmp.tStockByDay + (INDEX (itemFk, dated)) + ENGINE = MEMORY + SELECT dated, + SUM(t3.amount) OVER (PARTITION BY t3.itemFk ORDER BY dated) stock, + t3.itemFk + FROM ( + SELECT t.itemFk, dated, SUM(amount) amount + FROM ( + SELECT t2.itemFk, t2.amount, t2.dated + FROM ( + SELECT item_id itemFk, amount, util.VN_CURDATE() dated + FROM cache.stock s + JOIN tmp.tItems i ON i.itemFk = s.item_id + WHERE s.warehouse_id = vWarehouseFk + UNION ALL + SELECT ish.itemFk, - SUM(ish.visible), util.VN_CURDATE() + FROM itemShelving ish + JOIN tmp.tItems i ON i.itemFk = ish.itemFk + JOIN shelving sh ON sh.code = ish.shelvingFk + JOIN parking p ON sh.parkingFk = p.id + JOIN sector s ON s.id = p.sectorFk + WHERE s.isReserve + GROUP BY ish.itemFk + UNION ALL + SELECT iei.itemFk, SUM(quantity), landed + FROM itemEntryIn iei + JOIN tmp.tItems i ON i.itemFk = iei.itemFk + WHERE iei.landed BETWEEN util.VN_CURDATE() AND util.VN_CURDATE() + INTERVAL vStockScopeDays DAY + AND iei.warehouseInFk = vWarehouseFk + AND NOT isVirtualStock + GROUP BY iei.itemFk, iei.landed + UNION ALL + SELECT ieo.itemFk, SUM(quantity), shipped + FROM itemEntryOut ieo + JOIN tmp.tItems i ON i.itemFk = ieo.itemFk + WHERE ieo.shipped BETWEEN util.VN_CURDATE() AND util.VN_CURDATE() + INTERVAL vStockScopeDays DAY + AND ieo.warehouseOutFk = vWarehouseFk + GROUP BY ieo.itemFk, ieo.shipped + UNION ALL + SELECT i.itemFk, SUM(ito.quantity), DATE(ito.shipped) + FROM itemTicketOut ito + JOIN tmp.tItems i ON i.itemFk = ito.itemFk + WHERE ito.shipped BETWEEN util.VN_CURDATE() AND util.VN_CURDATE() + INTERVAL vStockScopeDays DAY + AND ito.warehouseFk = vWarehouseFk + GROUP BY ito.itemFk, ito.shipped + ) t2 + JOIN tmp.tItems i ON i.itemFk = t2.itemFk)t + GROUP BY t.itemFk, dated + ) t3; - DROP TEMPORARY TABLE IF EXISTS tmp.stockByDay; - CREATE TEMPORARY TABLE tmp.stockByDay - (index (itemFk, dated)) - ENGINE = MEMORY - SELECT t3.amount, dated, - @stock := IF(@itemFk = t3.itemFk, @stock + t3.amount, t3.amount) stock, - @itemFk := t3.itemFk itemFk - FROM ( - SELECT * FROM ( - SELECT t2.* FROM ( - SELECT item_id itemFk, amount, util.VN_CURDATE() dated - FROM cache.stock - WHERE warehouse_id = vWarehouseFk - UNION ALL - SELECT ish.itemFk, - sum(visible), util.VN_CURDATE() - FROM vn.itemShelving ish + -- Se restan las entradas de hoy + UPDATE tmp.tStockByDay sbd + JOIN (SELECT iei.itemFk, SUM(quantity) todayEntry + FROM itemEntryIn iei + JOIN tmp.tItems i ON i.itemFk = iei.itemFk + WHERE iei.landed = util.VN_CURDATE() + AND iei.warehouseInFk = vWarehouseFk + AND NOT iei.isVirtualStock) sub ON sub.itemFk = sbd.itemFk + SET sbd.stock = sbd.stock - sub.todayEntry + WHERE sbd.dated = util.VN_CURDATE(); + + -- Se añaden las lineas de venta servidas + UPDATE tmp.tStockByDay sbd + JOIN (SELECT s.itemFK, SUM(quantity) amount + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + WHERE t.warehouseFk = vWarehouseFk + AND t.shipped BETWEEN util.VN_CURDATE() AND util.midnight() + AND s.isPicked + GROUP BY s.itemFk) sub ON sub.itemFk = sbd.itemFk + SET sbd.stock = sbd.stock + sub.amount; + + -- Se añaden los items ubicados hoy + UPDATE tmp.tStockByDay sbd + JOIN (SELECT ish.itemFK, SUM(ish.visible) amount + FROM itemShelving ish JOIN shelving sh ON sh.code = ish.shelvingFk - JOIN parking p ON sh.parkingFk = p.id + JOIN parking p ON p.id = sh.parkingFk JOIN sector s ON s.id = p.sectorFk - WHERE s.isReserve - GROUP BY ish.itemFk - UNION ALL - SELECT item_id, sum(iei.amount), dat - FROM vn2008.item_entry_in iei - WHERE dat >= util.VN_CURDATE() - AND warehouse_id = vWarehouseFk - AND isVirtualStock = FALSE - GROUP BY item_id, dat - UNION ALL - SELECT item_id, sum(ieo.amount), dat - FROM vn2008.item_entry_out ieo - WHERE dat >= util.VN_CURDATE() - AND warehouse_id = vWarehouseFk - GROUP BY item_id, dat - UNION ALL - SELECT i.itemFk, sum(io.amount), dat - FROM vn2008.item_out io - JOIN tmp.item i ON i.itemFk = io.item_id - WHERE io.dat >= util.VN_CURDATE() - AND io.warehouse_id = vWarehouseFk - GROUP BY io.item_id, io.dat - ) t2 - JOIN tmp.itemShelvingDistinct ish ON ish.itemFk = t2.itemFk) t - order by t.itemFk, DATE(t.dated), t.amount DESC) t3; + WHERE s.warehouseFk = vWarehouseFk + AND NOT s.isReserve + AND ish.created BETWEEN util.VN_CURDATE() AND util.midnight() + GROUP BY ish.itemFk) sub ON sub.itemFk = sbd.itemFk + SET sbd.stock = sbd.stock + sub.amount; - SELECT sbd.itemFk, i.longName, DATE(dated) dated, ish.visible amount, sbd.stock - FROM tmp.stockByDay sbd - JOIN vn.item i ON i.id = sbd.itemFk - JOIN tmp.itemShelvingDistinct ish ON ish.itemFk = sbd.itemFk - WHERE ish.visible >= sbd.stock - GROUP BY itemFk - ORDER BY dated; + SELECT ts.itemFk, + i.longName, + IF(ts.stock<=0, ts.dated, NULL) dated, + ts.stock, + sub4.visible, + sub4.shelvingFk + FROM( + SELECT IFNULL(sub2.minDated, sub.minDated) dated, + IFNULL(sub2.itemFk, sub.itemFk) itemFk + FROM(SELECT sbd.itemFk, + MIN(dated) minDated, + sbd.stock + FROM tmp.tItems ti + LEFT JOIN tmp.tStockByDay sbd ON sbd.itemFk = ti.itemFk + GROUP BY itemFk)sub + LEFT JOIN ( + SELECT sbd.itemFk, + MIN(dated) minDated, + sbd.stock + FROM tmp.tItems ti + LEFT JOIN tmp.tStockByDay sbd ON sbd.itemFk = ti.itemFk + WHERE sbd.stock <= 0 + GROUP BY itemFk)sub2 ON sub2.itemFk =sub.itemFk + WHERE sub2.itemFk IS NOT NULL + OR (sub2.itemFk IS NULL AND sub.itemFk IS NOT NULL)) sub3 + LEFT JOIN tmp.tStockByDay ts ON ts.itemFk = sub3.itemFk AND ts.dated = sub3.dated + JOIN (SELECT ish.itemFk, + ish.visible, + p.sectorFk, + ish.shelvingFk + FROM itemShelving ish + JOIN vn.shelving sh ON sh.code = ish.shelvingFk + LEFT JOIN parking p ON p.id = parkingFk + LEFT JOIN vn.sector s ON s.id = p.sectorFk + WHERE ish.shelvingFk = vShelvingFk COLLATE utf8_unicode_ci + ) sub4 ON sub4.itemFk = ts.itemFk + LEFT JOIN sector s ON s.id = sub4.sectorFk + LEFT JOIN item i ON i.id = ts.itemFk + WHERE NOT s.isReserve; + + DROP TEMPORARY TABLE tmp.tStockByDay, tmp.tItems; - DROP TEMPORARY TABLE tmp.stockByDay, - tmp.itemShelvingDistinct, - tmp.item; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -62156,8 +62606,7 @@ BEGIN * @table tmp.itemCalc(itemFk, wareHouseFk, dated, quantity) * @return tmp.itemAtp(itemFk, warehouseFk, quantity) */ - DROP TEMPORARY TABLE IF EXISTS tItemOrdered; - CREATE TEMPORARY TABLE tItemOrdered + CREATE OR REPLACE TEMPORARY TABLE tItemOrdered (UNIQUE(itemFk, warehouseFk, dated)) ENGINE = MEMORY SELECT itemFk, warehouseFk, dated, SUM(quantity) quantity @@ -62175,8 +62624,8 @@ BEGIN SET @lastWareHouseFk := 0; SET @lastQuantity := 0; - DROP TEMPORARY TABLE IF EXISTS tmp.itemAtp; - CREATE TEMPORARY TABLE tmp.itemAtp + CREATE OR REPLACE TEMPORARY TABLE tmp.itemAtp + (INDEX (itemFk, wareHouseFk)) SELECT itemFk, wareHouseFk, MIN(quantityAccumulated) quantity FROM ( SELECT @@ -62542,6 +62991,7 @@ BEGIN CALL `cache`.stock_refresh(vForce); CALL item_getMinacum(NULL, util.VN_CURDATE(), vDays, NULL); CALL item_getMinETD(); + CALL item_zoneClosure(); SELECT i.id itemFk, i.longName, @@ -62552,7 +63002,8 @@ BEGIN w.name warehouse, SUM(IFNULL(sub.amount,0)) lack, i.inkFk, - IFNULL(im.timed, util.midnight()) timed + IFNULL(im.timed, util.midnight()) timed, + IFNULL(izc.timed, util.midnight()) minTimed FROM (SELECT item_id, warehouse_id, amount @@ -62570,14 +63021,16 @@ BEGIN JOIN itemType it ON it.id = i.typeFk JOIN itemCategory ic ON ic.id = it.categoryFk LEFT JOIN tmp.itemMinETD im ON im.itemFk = i.id + LEFT JOIN tmp.itemZoneClosure izc ON izc.itemFk = i.id WHERE w.isForTicket - AND ic.display <> 0 + AND ic.display AND it.code != 'GEN' GROUP BY i.id, w.id HAVING lack < 0; DROP TEMPORARY TABLE tmp.itemMinacum; DROP TEMPORARY TABLE tmp.itemMinETD; + DROP TEMPORARY TABLE tmp.itemZoneClosure; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -63000,7 +63453,7 @@ BEGIN ), i.subname = JSON_VALUE(vValues, '$.4'), i.size = JSON_VALUE(vOverwrites, '$.size'), - i.stems = JSON_VALUE(vOverwrites, '$.stems'), + i.stems = IFNULL(JSON_VALUE(vOverwrites, '$.stems'),i.stems), i.category = JSON_VALUE(vOverwrites, '$.category'), i.tag5 = JSON_VALUE(vTags, '$.5'), i.tag6 = JSON_VALUE(vTags, '$.6'), @@ -63170,6 +63623,97 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `item_setVisibleDiscard` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `item_setVisibleDiscard`( + vItemFk INT, + vWarehouseFk INT, + vQuantity INT, + vAddressFk INT) +BEGIN +/** + * Procedimiento para dar dar de baja/alta un item, si vAddressFk es NULL se entiende que se da de alta y se toma el addressFk de la configuración + * + * @param vItemFk Identificador del ítem + * @param vWarehouseFk id del warehouse + * @param vQuantity a dar de alta/baja + * @param vAddressFk id address + */ + DECLARE vTicketFk INT; + DECLARE vClientFk INT; + DECLARE vDefaultCompanyFk INT; + DECLARE vCalc INT; + DECLARE vAddressShortage INT; + + SELECT barcodeToItem(vItemFk) INTO vItemFk; + + SELECT DEFAULT(companyFk) INTO vDefaultCompanyFk + FROM vn.ticket LIMIT 1; + + IF vAddressFk IS NULL THEN + SELECT pc.shortageAddressFk INTO vAddressShortage + FROM productionConfig pc ; + ELSE + SET vAddressShortage = vAddressFk; + END IF; + + SELECT a.clientFk INTO vClientFk + FROM address a + WHERE a.id = vAddressFk; + + SELECT t.id INTO vTicketFk + FROM ticket t + JOIN address a ON a.id = t.addressFk + JOIN ticketState ts ON ts.ticketFk = t.id + WHERE t.warehouseFk = vWarehouseFk + AND a.id = vAddressShortage + AND DATE(t.shipped) = util.VN_CURDATE() + AND ts.code = 'DELIVERED' + LIMIT 1; + + CALL cache.visible_refresh(vCalc, TRUE, vWarehouseFk); + + IF vTicketFk IS NULL THEN + CALL ticket_add( + vClientFk, + util.VN_CURDATE(), + vWarehouseFk, + vDefaultCompanyFk, + vAddressFk, + NULL, + NULL, + util.VN_CURDATE(), + account.myUser_getId(), + FALSE, + vTicketFk); + END IF; + + INSERT INTO sale(ticketFk, itemFk, concept, quantity) + SELECT vTicketFk, + vItemFk, + CONCAT(longName,' ', worker_getCode(), ' ', LEFT(CAST(util.VN_NOW() AS TIME),5)), + vQuantity + FROM item + WHERE id = vItemFk; + + UPDATE cache.visible + SET visible = visible - vQuantity + WHERE calc_id = vCalc + AND item_id = vItemFk; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `item_updatePackingShelve` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; @@ -63242,6 +63786,10 @@ BEGIN DECLARE vHasNotInventory BOOLEAN DEFAULT FALSE; DECLARE vInventoried2 DATE; DECLARE vDateDayEnd DATETIME; + DECLARE vInventorySupplierFk INT; + + SELECT inventorySupplierFk INTO vInventorySupplierFk + FROM entryConfig; SET vDateDayEnd = util.dayEnd(vDated); @@ -63249,7 +63797,7 @@ BEGIN FROM travel tr JOIN entry E ON E.travelFk = tr.id WHERE landed <= vDateDayEnd - AND E.supplierFk = 4 + AND E.supplierFk = vInventorySupplierFk ORDER BY landed DESC LIMIT 1; @@ -63261,7 +63809,7 @@ BEGIN FROM travel tr JOIN entry E ON E.travelFk = tr.id WHERE landed >= vDated - AND E.supplierFk = 4 + AND E.supplierFk = vInventorySupplierFk ORDER BY landed ASC LIMIT 1; @@ -63293,7 +63841,7 @@ BEGIN JOIN itemType t ON t.id = i.typeFk JOIN warehouse w ON w.id = warehouseInFk WHERE landed = vDateDayEnd - AND e.supplierFk = 4 + AND e.supplierFk = vInventorySupplierFk AND w.valuatedInventory AND t.isInventory GROUP BY tr.warehouseInFk, b.itemFk; @@ -63301,19 +63849,24 @@ BEGIN END IF; INSERT INTO inv(warehouseFk, Id_Article, cantidad, Almacen) - SELECT tr.warehouseInFk, b.itemFk, b.quantity * IF(vHasNotInventory,-1,1), w.`name` - FROM buy b - JOIN item i ON i.id = b.itemFk - JOIN entry e ON e.id = b.entryFk - JOIN travel tr ON tr.id = e.travelFk - JOIN itemType t ON t.id = i.typeFk - JOIN warehouse w ON w.id = tr.warehouseInFk - WHERE tr.landed BETWEEN vInventoried AND vDateDayEnd - AND IF(tr.landed = util.VN_CURDATE(), tr.isReceived, trUE) - AND NOT e.isRaid - AND w.valuatedInventory - AND t.isInventory - ON DUPLICATE KEY UPDATE inv.cantidad = inv.cantidad + (b.quantity * IF(vHasNotInventory,-1,1)); + SELECT tr.warehouseInFk, + b.itemFk, + b.quantity * IF(vHasNotInventory,-1,1), + w.`name` + FROM buy b + JOIN item i ON i.id = b.itemFk + JOIN entry e ON e.id = b.entryFk + JOIN travel tr ON tr.id = e.travelFk + JOIN itemType t ON t.id = i.typeFk + JOIN warehouse w ON w.id = tr.warehouseInFk + WHERE tr.landed BETWEEN vInventoried AND vDateDayEnd + AND IF(tr.landed = util.VN_CURDATE(), tr.isReceived, trUE) + AND NOT e.isRaid + AND w.valuatedInventory + AND t.isInventory + AND e.supplierFk <> vInventorySupplierFk + ON DUPLICATE KEY UPDATE inv.cantidad = + inv.cantidad + (b.quantity * IF(vHasNotInventory,-1,1)); INSERT INTO inv(warehouseFk, Id_Article, cantidad, Almacen) SELECT tr.warehouseOutFk, b.itemFk, b.quantity * IF(vHasNotInventory,1,-1), w.`name` @@ -63432,6 +63985,44 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `item_zoneClosure` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `item_zoneClosure`() +BEGIN + +/* Devuelve una tabla temporal con la hora minima de un ticket sino tiene el de la zoneClosure y + * si tampoco hay el de la zona , para todos los artículos con salida hoy. + * + * @return tmp.itemZoneClosure(itemFk, timed) + */ + + CREATE OR REPLACE TEMPORARY TABLE tmp.itemZoneClosure + (INDEX (itemFk)) + ENGINE = MEMORY + SELECT s.itemFk, + MIN(DATE_FORMAT(IF(HOUR(t.shipped),t.shipped, + IFNULL(zc.hour, z.HOUR)), '%H:%i') + )timed + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + LEFT JOIN `zone` z ON z.id = t.zoneFk + LEFT JOIN vn.zoneClosure zc ON zc.zoneFk = t.zoneFk + WHERE t.shipped BETWEEN util.VN_CURDATE() AND CONCAT(util.VN_CURDATE(), ' 23:59:59') + GROUP BY s.itemFk; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `ledger_doCompensation` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -63932,74 +64523,244 @@ DELIMITER ; /*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `manaSpellersRequery`(vWorkerFk INTEGER) +`whole_proc`: BEGIN /** - * Recalcula el mana consumido por un trabajador + * Guarda en workerMana el mana consumido por un trabajador * * @param vWorkerFk Id Trabajador */ DECLARE vWorkerIsExcluded BOOLEAN; - DECLARE vFromDated DATE; - DECLARE vToDated DATE DEFAULT TIMESTAMPADD(DAY,1,util.VN_CURDATE()); - DECLARE vMana INT; - DECLARE vAutoMana INT; - DECLARE vClaimMana INT; - DECLARE vManaBank INT; - DECLARE vManaGreugeType INT; SELECT COUNT(*) INTO vWorkerIsExcluded FROM workerManaExcluded WHERE workerFk = vWorkerFk; - IF NOT vWorkerIsExcluded THEN - SELECT id INTO vMana - FROM `component` WHERE code = 'mana'; - - SELECT id INTO vAutoMana - FROM `component` WHERE code = 'autoMana'; - - SELECT id INTO vClaimMana - FROM `component` WHERE code = 'manaClaim'; - - SELECT id INTO vManaBank - FROM `bank` WHERE code = 'mana'; - - SELECT id INTO vManaGreugeType - FROM `greugeType` WHERE code = 'mana'; - - SELECT max(dated) INTO vFromDated - FROM clientManaCache; - - REPLACE workerMana (workerFk, amount) - SELECT vWorkerFk, sum(mana) FROM - ( - SELECT s.quantity * sc.value as mana - FROM ticket t - JOIN address a ON a.id = t.addressFk - JOIN client c ON c.id = a.clientFk - JOIN sale s ON s.ticketFk = t.id - JOIN saleComponent sc ON sc.saleFk = s.id - WHERE c.salesPersonFk = vWorkerFk AND sc.componentFk IN (vMana, vAutoMana, vClaimMana) - AND t.shipped > vFromDated AND t.shipped < vToDated - UNION ALL - SELECT - r.amountPaid - FROM receipt r - JOIN client c ON c.id = r.clientFk - WHERE c.salesPersonFk = vWorkerFk AND bankFk = vManaBank - AND payed > vFromDated - UNION ALL - SELECT g.amount - FROM greuge g - JOIN client c ON c.id = g.clientFk - WHERE c.salesPersonFk = vWorkerFk AND g.greugeTypeFk = vManaGreugeType - AND g.shipped > vFromDated and g.shipped < util.VN_CURDATE() - UNION ALL - SELECT cc.mana - FROM clientManaCache cc - JOIN client c ON c.id = cc.clientFk - WHERE c.salesPersonFk = vWorkerFk AND cc.dated = vFromDated - ) sub; + IF vWorkerIsExcluded THEN + LEAVE whole_proc; END IF; + + CREATE OR REPLACE TEMPORARY TABLE tmp.client + SELECT id + FROM client + WHERE salesPersonFk = vWorkerFk; + + CALL client_getMana(); + + INSERT INTO workerMana (workerFk, amount) + SELECT vWorkerFk, sum(mana) + FROM tmp.clientMana + ON DUPLICATE KEY UPDATE amount = VALUES(amount); + + DROP TEMPORARY TABLE + tmp.client, + tmp.clientMana; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `multipleInventory` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `multipleInventory`( + vDate DATE, + vWarehouseFk TINYINT, + vMaxDays TINYINT +) +proc: BEGIN + DECLARE vDateTomorrow DATE DEFAULT vDate + INTERVAL 1 DAY; + DECLARE vDateFrom DATE DEFAULT vDate; + DECLARE vDateTo DATETIME; + DECLARE vDateToTomorrow DATETIME; + DECLARE vDefaultDayRange INT; + + IF vDate < util.VN_CURDATE() THEN + LEAVE proc; + END IF; + + IF vDate = util.VN_CURDATE() THEN + SELECT inventoried INTO vDateFrom + FROM config; + END IF; + + SELECT defaultDayRange INTO vDefaultDayRange + FROM comparativeConfig; + + SET vDateTo = vDate + INTERVAL IFNULL(vMaxDays, vDefaultDayRange) DAY; + SET vDateToTomorrow = vDateTo + INTERVAL 1 DAY; + + ALTER TABLE vn2008.article_inventory + ADD `avalaible` INT NOT NULL, + ADD `sd` INT NOT NULL, + ADD `rest` INT NOT NULL, + ADD `expected` INT NOT NULL, + ADD `inventory` INT NOT NULL, + ADD `visible` INT NOT NULL, + ADD `life` TINYINT NOT NULL DEFAULT '0'; + + -- Calculo del inventario + UPDATE vn2008.article_inventory ai + JOIN ( + SELECT itemFk Id_Article, SUM(quantity) Subtotal + FROM ( + SELECT s.itemFk, - s.quantity quantity + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + JOIN warehouse w ON w.id = t.warehouseFk + WHERE t.shipped BETWEEN vDateFrom AND util.dayEnd(vDate) + AND IFNULL(vWarehouseFk, t.warehouseFk) = t.warehouseFk + AND w.isComparative + UNION ALL + SELECT b.itemFk, b.quantity + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel t ON t.id = e.travelFk + JOIN warehouse w ON w.id = t.warehouseInFk + WHERE t.landed BETWEEN vDateFrom AND util.dayEnd(vDate) + AND IFNULL(vWarehouseFk, t.warehouseInFk) = t.warehouseInFk + AND w.isComparative + AND NOT e.isExcludedFromAvailable + AND NOT e.isRaid + UNION ALL + SELECT b.itemFk, - b.quantity + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel t ON t.id = e.travelFk + JOIN warehouse w ON w.id = t.warehouseOutFk + WHERE t.shipped BETWEEN vDateFrom AND util.dayEnd(vDate) + AND IFNULL(vWarehouseFk, t.warehouseOutFk) = t.warehouseOutFk + AND w.isComparative + AND NOT e.isExcludedFromAvailable + AND NOT e.isRaid + ) sub2 + GROUP BY itemFk + ) sub ON ai.article_id = sub.Id_Article + SET ai.inventory = sub.Subtotal, + ai.visible = sub.Subtotal, + ai.avalaible = sub.Subtotal, + ai.sd = sub.Subtotal; + + -- Cálculo del visible + UPDATE vn2008.article_inventory ai + JOIN ( + SELECT itemFk Id_Article, SUM(quantity) Subtotal + FROM ( + SELECT s.itemFk, s.quantity + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + JOIN warehouse w ON w.id = t.warehouseFk + WHERE t.shipped >= vDate + AND t.shipped < vDateTomorrow + AND (NOT isPicked AND NOT t.isLabeled AND t.refFk IS NULL) + AND IFNULL(vWarehouseFk, t.warehouseFk) = t.warehouseFk + AND w.isComparative + UNION ALL + SELECT b.itemFk, - b.quantity + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel t ON t.id = e.travelFk + JOIN warehouse w ON w.id = t.warehouseInFk + WHERE t.landed = vDate + AND NOT t.isReceived + AND NOT e.isExcludedFromAvailable + AND NOT e.isRaid + AND IFNULL(vWarehouseFk, t.warehouseInFk) = t.warehouseInFk + AND w.isComparative + UNION ALL + SELECT b.itemFk, b.quantity + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel t ON t.id = e.travelFk + JOIN warehouse w ON w.id = t.warehouseOutFk + WHERE t.shipped = vDate + AND NOT t.isReceived + AND NOT e.isExcludedFromAvailable + AND NOT e.isRaid + AND IFNULL(vWarehouseFk, t.warehouseOutFk) = t.warehouseOutFk + AND w.isComparative + ) sub2 + GROUP BY itemFk + ) sub ON ai.article_id = sub.Id_Article + SET ai.visible = ai.visible + sub.Subtotal; + + -- Calculo del disponible + CREATE OR REPLACE TEMPORARY TABLE tmp.itemCalc + (INDEX (itemFk, warehouseFk)) + ENGINE = MEMORY + SELECT sub.itemFk, + vWarehouseFk warehouseFk, + sub.dated, + SUM(sub.quantity) quantity + FROM ( + SELECT s.itemFk, + DATE(t.shipped) dated, + - s.quantity quantity + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + JOIN warehouse w ON w.id = t.warehouseFk + WHERE t.shipped BETWEEN vDateTomorrow AND vDateTo + AND IFNULL(vWarehouseFk, t.warehouseFk) = t.warehouseFk + AND w.isComparative + UNION ALL + SELECT b.itemFk, t.landed, b.quantity + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel t ON t.id = e.travelFk + JOIN warehouse w ON w.id = t.warehouseInFk + WHERE t.landed BETWEEN vDateTomorrow AND vDateTo + AND IFNULL(vWarehouseFk, t.warehouseInFk) = t.warehouseInFk + AND w.isComparative + AND NOT e.isExcludedFromAvailable + AND NOT e.isRaid + UNION ALL + SELECT b.itemFk, t.shipped, - b.quantity + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel t ON t.id = e.travelFk + JOIN warehouse w ON w.id = t.warehouseOutFk + WHERE t.shipped BETWEEN vDateTomorrow AND vDateTo + AND IFNULL(vWarehouseFk, t.warehouseOutFk) = t.warehouseOutFk + AND w.isComparative + AND NOT e.isExcludedFromAvailable + AND NOT e.isRaid + ) sub + GROUP BY sub.itemFk, sub.dated; + + CALL item_getAtp(vDate); + CALL vn2008.item_travel(vWarehouseFk, vDate); + UPDATE vn2008.article_inventory ai + JOIN ( + SELECT it.itemFk, + SUM(it.quantity) quantity, + im.quantity minQuantity + FROM tmp.itemCalc it + JOIN tmp.itemAtp im ON im.itemFk = it.itemFk + JOIN item i ON i.id = it.itemFk + LEFT JOIN origin o ON o.id = i.originFk + LEFT JOIN vn2008.item_travel t ON t.wh = o.warehouseFk + WHERE it.dated < IF(vMaxDays < 0 AND t.landing IS NOT NULL, + t.landing, + vDateToTomorrow) + GROUP BY it.itemFk + ) sub ON sub.itemFk = ai.article_id + SET ai.avalaible = IF(sub.minQuantity > 0, + ai.avalaible, + ai.avalaible + sub.minQuantity), + ai.sd = ai.inventory + sub.quantity; + + DROP TEMPORARY TABLE + vn2008.item_travel, + tmp.itemCalc, + tmp.itemAtp; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -64969,15 +65730,15 @@ proc: BEGIN DECLARE vEndingDate DATETIME; DECLARE vIsTodayRelative BOOLEAN; - SELECT TIMESTAMPADD(DAY, LEAST(vScopeDays, pc.maxProductionScopeDays), util.dayEnd(util.VN_CURDATE())) + SELECT util.dayEnd(util.VN_CURDATE()) + INTERVAL LEAST(vScopeDays, maxProductionScopeDays) DAY INTO vEndingDate - FROM productionConfig pc; + FROM productionConfig; SELECT isTodayRelative INTO vIsTodayRelative FROM worker - WHERE id = getUser(); + WHERE id = getUser(); -- Cambiar por account.myUser_getId(), falta dar permisos - CALL prepareTicketList( util.VN_CURDATE() - INTERVAL 1 DAY, vEndingDate); + CALL prepareTicketList(util.yesterday(), vEndingDate); CREATE OR REPLACE TEMPORARY TABLE tmp.ticket SELECT * FROM tmp.productionTicket; @@ -65046,7 +65807,7 @@ proc: BEGIN JOIN agency ag ON ag.id = am.agencyFk LEFT JOIN ticketState tls ON tls.ticket = tt.ticketFk LEFT JOIN ticketLastUpdated tlu ON tlu.ticketFk = tt.ticketFk - LEFT JOIN worker w on w.id = tls.worker + LEFT JOIN worker w ON w.id = tls.worker LEFT JOIN routesMonitor rm ON rm.routeFk = t.routeFk LEFT JOIN `zone` z ON z.id = t.zoneFk LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk @@ -65106,31 +65867,33 @@ proc: BEGIN FROM tmp.productionTicket tt JOIN saleVolume sv ON sv.ticketFk = tt.ticketFk GROUP BY tt.ticketFk - ) m on m.ticketFk = pb.ticketFk + ) m ON m.ticketFk = pb.ticketFk SET pb.`lines` = m.`lines`, pb.m3 = m.m3, pb.preparationRate = m.rate; DELETE FROM tmp.productionBuffer - WHERE `lines`= 0; + WHERE NOT `lines`; -- Lineas por linea de encajado UPDATE tmp.productionBuffer pb - JOIN ( SELECT ticketFk, + JOIN ( + SELECT ticketFk, SUM(sub.H) H, SUM(sub.V) V, SUM(sub.N) N FROM ( - SELECT t.ticketFk, + SELECT t.ticketFk, SUM(i.itemPackingTypeFk = 'H') H, SUM(i.itemPackingTypeFk = 'V') V, SUM(i.itemPackingTypeFk IS NULL) N FROM tmp.productionTicket t JOIN sale s ON s.ticketFk = t.ticketFk JOIN item i ON i.id = s.itemFk - GROUP BY t.ticketFk, i.itemPackingTypeFk) sub + GROUP BY t.ticketFk, i.itemPackingTypeFk + ) sub GROUP BY ticketFk - ) sub2 ON sub2.ticketFk = pb.ticketFk + ) sub2 ON sub2.ticketFk = pb.ticketFk SET pb.H = sub2.H, pb.V = sub2.V, pb.N = sub2.N; @@ -65154,15 +65917,30 @@ proc: BEGIN -- Insertamos todos los tickets que tienen productos parkineados -- en sectores de previa, segun el sector + CREATE OR REPLACE TEMPORARY TABLE tItemShelvingStock + (PRIMARY KEY(itemFk, sectorFk)) + ENGINE = MEMORY + SELECT ish.itemFk, + p.sectorFk, + sc.isPreviousPrepared, + sc.itemPackingTypeFk + FROM itemShelving ish + JOIN shelving sh ON sh.code = ish.shelvingFk + JOIN parking p ON p.id = sh.parkingFk + JOIN sector sc ON sc.id = p.sectorFk + WHERE p.sectorFk + AND ish.visible + GROUP BY ish.itemFk, p.sectorFk; + INSERT INTO tmp.ticketWithPrevia(ticketFk, salesCount) SELECT pb.ticketFk, COUNT(DISTINCT s.id) FROM tmp.productionBuffer pb JOIN sale s ON s.ticketFk = pb.ticketFk - JOIN itemShelvingStock iss ON iss.itemFk = s.itemFk + JOIN tItemShelvingStock iss ON iss.itemFk = s.itemFk JOIN sector sc ON sc.id = iss.sectorFk JOIN item i ON i.id = iss.itemFk WHERE iss.isPreviousPrepared - AND (sc.itemPackingTypeFk IS NULL + AND (sc.itemPackingTypeFk IS NULL OR (i.itemPackingTypeFk IS NULL AND NOT pb.V) OR sc.itemPackingTypeFk = i.itemPackingTypeFk) AND s.quantity > 0 @@ -65170,14 +65948,16 @@ proc: BEGIN -- Se calcula la cantidad de productos que estan ya preparados porque su saleGroup está aparcado UPDATE tmp.ticketWithPrevia twp - JOIN ( SELECT pb.ticketFk, COUNT(DISTINCT s.id) salesInParkingCount - FROM tmp.productionBuffer pb - JOIN sale s ON s.ticketFk = pb.ticketFk - JOIN saleGroupDetail sgd ON sgd.saleFk = s.id - JOIN saleGroup sg ON sg.id = sgd.saleGroupFk - WHERE sg.parkingFk IS NOT NULL - AND s.quantity > 0 - GROUP BY pb.ticketFk) sub ON twp.ticketFk = sub.ticketFk + JOIN ( + SELECT pb.ticketFk, COUNT(DISTINCT s.id) salesInParkingCount + FROM tmp.productionBuffer pb + JOIN sale s ON s.ticketFk = pb.ticketFk + JOIN saleGroupDetail sgd ON sgd.saleFk = s.id + JOIN saleGroup sg ON sg.id = sgd.saleGroupFk + WHERE sg.parkingFk IS NOT NULL + AND s.quantity > 0 + GROUP BY pb.ticketFk + ) sub ON twp.ticketFk = sub.ticketFk SET twp.salesInParkingCount = sub.salesInParkingCount; -- Marcamos como pendientes aquellos que no coinciden las cantidades @@ -65186,11 +65966,244 @@ proc: BEGIN SET pb.previousWithoutParking = TRUE WHERE twp.salesCount > twp.salesInParkingCount; - DROP TEMPORARY TABLE tmp.productionTicket; - DROP TEMPORARY TABLE tmp.ticket; - DROP TEMPORARY TABLE tmp.risk; - DROP TEMPORARY TABLE tmp.ticket_problems; - DROP TEMPORARY TABLE tmp.ticketWithPrevia; + DROP TEMPORARY TABLE + tmp.productionTicket, + tmp.ticket, + tmp.risk, + tmp.ticket_problems, + tmp.ticketWithPrevia, + tItemShelvingStock; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `productionError_add` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `productionError_add`() +BEGIN + DECLARE vDatedFrom DATETIME; + DECLARE vDatedTo DATETIME; +/** + * Rellena la tabla vn.productionError con estadisticas de encajadores, revisores y sacadores. Se ejecuta en el nightTask + */ + SELECT util.VN_CURDATE() - INTERVAL 1 DAY, util.dayend(util.VN_CURDATE() - INTERVAL 1 DAY) INTO vDatedFrom, vDatedTo; + CALL timeControl_calculateAll(vDatedFrom, vDatedTo); + + -- Rellena la tabla tmp.errorsByClaim con encajadores, revisores y sacadores + CREATE OR REPLACE TEMPORARY TABLE tmp.errorsByClaim + ENGINE = MEMORY + SELECT COUNT(c.ticketFk) errors, + cd.workerFk + FROM claimDevelopment cd + JOIN claim c ON cd.claimFk = c.id + JOIN ticket t ON c.ticketFk = t.id + JOIN claimResponsible cr ON cd.claimResponsibleFk = cr.id + WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo + AND cr.code IN ('pic', 'chk', 'pck') + GROUP BY cd.workerFk; + + -- Genera la tabla tmp.volume con encajadores, sacadores y revisores + CREATE OR REPLACE TEMPORARY TABLE tmp.volume + ENGINE = MEMORY + SELECT SUM(w.volume) volume, + w.workerFk + FROM bs.workerProductivity w + WHERE w.dated BETWEEN vDatedFrom AND vDatedTo + GROUP BY w.workerFk; + + -- Rellena la tabla tmp.errorsByChecker con fallos de revisores + CREATE OR REPLACE TEMPORARY TABLE tmp.errorsByChecker + ENGINE = MEMORY + SELECT st.workerFk, + COUNT(t.id) errors + FROM saleMistake sm + JOIN saleTracking st ON sm.saleFk = st.saleFk + JOIN `state` s2 ON s2.id = st.stateFk + JOIN sale s ON s.id = sm.saleFk + JOIN ticket t on t.id = s.ticketFk + WHERE (t.shipped BETWEEN vDatedFrom AND vDatedTo) + AND s2.code IN ('OK','PREVIOUS_PREPARATION','PREPARED','CHECKED') + GROUP BY st.workerFk; + + -- Rellena la tabla tmp.expeditionErrors con fallos de expediciones + CREATE OR REPLACE TEMPORARY TABLE tmp.expeditionErrors + ENGINE = MEMORY + SELECT COUNT(t.id) errors, + e.workerFk + FROM vn.expeditionMistake pm + JOIN vn.expedition e ON e.id = pm.expeditionFk + JOIN vn.ticket t ON t.id = e.ticketFk + WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo + GROUP BY e.workerFk; + + -- Genera la tabla tmp.total para sacadores y revisores + CREATE OR REPLACE TEMPORARY TABLE tmp.total + ENGINE = MEMORY + SELECT st.workerFk, + COUNT(DISTINCT t.id) ticketCount, + COUNT(s.id) lineCount + FROM saleTracking st + JOIN `state` s2 ON s2.id = st.stateFk + JOIN sale s ON s.id = st.saleFk + JOIN ticket t ON s.ticketFk = t.id + WHERE (t.shipped BETWEEN vDatedFrom AND vDatedTo) + AND s2.code IN ('OK','PREVIOUS_PREPARATION','PREPARED','CHECKED') + GROUP BY st.workerFk; + + -- Rellena la tabla vn.productionError con sacadores + INSERT INTO productionError(userFk, + firstname, + lastname, + rol, + ticketNumber, + lineNumber, + error, + volume, + hourStart, + hourEnd, + hourWorked, + dated) + SELECT w.id, + w.firstName, + w.lastName, + "Sacadores", + t.ticketCount totalTickets, + t.lineCount, + IFNULL(ec.errors,0) + IFNULL(ec2.errors,0) errors, + v.volume volume, + SUBSTRING(tc.tableTimed, 1, 5) hourStart, + SUBSTRING(tc.tableTimed, LENGTH(tc.tableTimed)-4, 5) hourEnd, + IFNULL(CAST(tc.timeWorkDecimal AS DECIMAL (10,2)) , 0) hourWorked, + vDatedFrom dated + FROM tmp.total t + LEFT JOIN worker w ON w.id = t.workerFk + LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = t.workerFk + LEFT JOIN tmp.errorsByClaim ec ON ec.workerFk = t.workerFk + LEFT JOIN tmp.volume v ON v.workerFk = t.workerFk + LEFT JOIN tmp.errorsByChecker ec2 ON ec2.workerFk = t.workerFk + JOIN (SELECT DISTINCT w.id -- Verificamos que son sacadores + FROM vn.collection c + JOIN vn.state s ON s.id = c.stateFk + JOIN vn.train tn ON tn.id = c.trainFk + JOIN vn.worker w ON w.id = c.workerFk + WHERE c.created BETWEEN vDatedFrom AND vDatedTo) sub ON sub.id = w.id + GROUP BY w.id; + + CREATE OR REPLACE TEMPORARY TABLE itemPickerErrors -- Errores de los sacadores, derivadores de los revisadores + ENGINE = MEMORY + SELECT COUNT(c.ticketFk) errors, + tt.workerFk + FROM claimDevelopment cd + JOIN claim c ON cd.claimFk = c.id + JOIN ticket t ON c.ticketFk = t.id + JOIN claimResponsible cr ON cd.claimResponsibleFk = cr.id + JOIN ticketTracking tt ON tt.ticketFk = t.id + JOIN `state` s ON s.id = tt.stateFk + WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo + AND cr.code = 'chk' + AND s.code = 'ON_PREPARATION' + GROUP BY workerFk; + + UPDATE productionError ep + JOIN itemPickerErrors ipe ON ipe.workerFk = ep.userFk + SET ep.error = ep.error + ipe.errors + WHERE vDatedFrom = ep.dated AND ep.rol = 'Sacadores'; + + DROP TEMPORARY TABLE itemPickerErrors; + + -- Rellena la tabla vn.productionError con revisores + CALL productionError_addCheckerPackager(vDatedFrom, vDatedTo, "Revisadores"); + + -- Genera la tabla tmp.total para encajadores + CREATE OR REPLACE TEMPORARY TABLE tmp.total + ENGINE = MEMORY + SELECT e.workerFk, + COUNT(DISTINCT t.id) ticketCount, + COUNT(s.id) lineCount + FROM expedition e + JOIN ticket t ON e.ticketFk = t.id + JOIN sale s ON s.ticketFk = t.id + WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo + GROUP BY e.workerFk; + + -- Rellena la tabla vn.productionError con encajadores + CALL productionError_addCheckerPackager(vDatedFrom, vDatedTo, "Encajadores"); + + DROP TEMPORARY TABLE tmp.errorsByClaim, + tmp.volume, + tmp.errorsByChecker, + tmp.expeditionErrors, + tmp.total; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `productionError_addCheckerPackager` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `productionError_addCheckerPackager`( + vDatedFrom DATETIME, + vDatedTo DATETIME, + vRol VARCHAR(50)) +BEGIN +/** + * Rellena la tabla vn.productionError con rol + * + * @param vDatedFrom Fecha desde + * @param vDatedTo Fecha hasta + * @param vRol rol a insertar + */ + INSERT INTO productionError(userFk, + firstname, + lastname, + rol, + ticketNumber, + lineNumber, + error, + volume, + hourStart, + hourEnd, + hourWorked, + dated) + SELECT w.id, + w.firstName, + w.lastName, + vRol, + t.ticketCount totalTickets, + t.lineCount, + IFNULL(ec.errors,0) + IFNULL(ec2.errors,0) + IFNULL(pe.errors,0) errors, + NULL volume, + SUBSTRING(tc.tableTimed, 1, 5) hourStart, + SUBSTRING(tc.tableTimed, LENGTH(tc.tableTimed)-4, 5) hourEnd, + IFNULL(CAST(tc.timeWorkDecimal AS DECIMAL (10,2)) , 0) hourWorked, + vDatedFrom dated + FROM tmp.total t + LEFT JOIN worker w ON w.id = t.workerFk + LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = t.workerFk + LEFT JOIN tmp.errorsByClaim ec ON ec.workerFk = t.workerFk + LEFT JOIN tmp.volume v ON v.workerFk = t.workerFk + LEFT JOIN tmp.errorsByChecker ec2 ON ec2.workerFk = t.workerFk + LEFT JOIN tmp.expeditionErrors pe ON pe.workerFk = t.workerFk + GROUP BY w.id; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -66163,6 +67176,40 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `route_checkDeliveryMethod` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `route_checkDeliveryMethod`(vSelf INT) +BEGIN +/** +* Comprueba si el deliveryMethod del agencyMode de la ruta es reparto +* +* @param vSelf Id de ruta +*/ + DECLARE vDeliveryMethod VARCHAR(45); + + SELECT dm.code INTO vDeliveryMethod + FROM route r + JOIN agencyMode am ON am.id = r.agencyModeFk + JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk + WHERE r.id = vSelf; + + IF vDeliveryMethod <> 'DELIVERY' THEN + CALL util.throw('Route tickets via delivery only'); + END IF; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `route_doRecalc` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -66241,63 +67288,66 @@ BEGIN * @param vRouteFk * @select Información de los tickets */ -SELECT * - FROM ( - SELECT t.id Id, - t.clientFk Client, - a.id Address, - a.nickname ClientName, - t.packages Packages, - a.street AddressName, - a.postalCode PostalCode, - a.city City, - sub2.itemPackingTypeFk PackingType, - c.phone ClientPhone, - c.mobile ClientMobile, - a.phone AddressPhone, - a.mobile AddressMobile, - d.longitude Longitude, - d.latitude Latitude, - wm.mediaValue SalePersonPhone, - tob.description Note, - t.isSigned Signed, - t.priority, - t.cmrFk - FROM ticket t - JOIN client c ON t.clientFk = c.id - JOIN address a ON t.addressFk = a.id - LEFT JOIN delivery d ON d.ticketFk = t.id - LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk - LEFT JOIN( - SELECT tob.description, t.id - FROM ticketObservation tob - JOIN ticket t ON tob.ticketFk = t.id - JOIN observationType ot ON ot.id = tob.observationTypeFk - WHERE t.routeFk = vRouteFk - AND ot.code = 'delivery' - )tob ON tob.id = t.id - LEFT JOIN( - SELECT sub.ticketFk, - CONCAT('(', - GROUP_CONCAT(DISTINCT sub.itemPackingTypeFk - ORDER BY sub.items DESC SEPARATOR ','), - ') ') itemPackingTypeFk - FROM ( - SELECT s.ticketFk, i.itemPackingTypeFk, COUNT(*) items - FROM ticket t - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - WHERE t.routeFk = vRouteFk - GROUP BY t.id, i.itemPackingTypeFk - )sub - GROUP BY sub.ticketFk - )sub2 ON sub2.ticketFk = t.id - WHERE t.routeFk = vRouteFk - ORDER BY d.id DESC - LIMIT 10000000000000000000 - )sub3 - GROUP BY sub3.id - ORDER BY sub3.priority; +SELECT t.id Id, + t.clientFk Client, + a.id Address, + a.nickname ClientName, + t.packages Packages, + a.street AddressName, + a.postalCode PostalCode, + a.city City, + sub3.itemPackingTypeFk PackingType, + c.phone ClientPhone, + c.mobile ClientMobile, + a.phone AddressPhone, + a.mobile AddressMobile, + d.longitude Longitude, + d.latitude Latitude, + wm.mediaValue SalePersonPhone, + tob.description Note, + t.isSigned Signed, + t.priority, + t.cmrFk + FROM ticket t + JOIN client c ON t.clientFk = c.id + JOIN address a ON t.addressFk = a.id + LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk + LEFT JOIN ( + SELECT t.addressFk, MAX(d.ticketFk) lastTicketFk + FROM ticket t + JOIN delivery d ON t.id = d.ticketFk + JOIN ticket ti ON ti.routeFk = vRouteFk + AND ti.id = t.id + AND ti.clientFk = t.clientFk + GROUP BY addressFk + )sub ON sub.addressFk = a.id + LEFT JOIN delivery d ON d.ticketFk = sub.lastTicketFk + LEFT JOIN( + SELECT t.id ticketFk, tob.description + FROM ticketObservation tob + JOIN ticket t ON tob.ticketFk = t.id + JOIN observationType ot ON ot.id = tob.observationTypeFk + WHERE t.routeFk = vRouteFk + AND ot.code = 'delivery' + )tob ON tob.ticketFk = t.id + LEFT JOIN( + SELECT sub2.ticketFk, + CONCAT('(', + GROUP_CONCAT(DISTINCT sub2.itemPackingTypeFk + ORDER BY sub2.items DESC SEPARATOR ','), + ') ') itemPackingTypeFk + FROM ( + SELECT s.ticketFk, i.itemPackingTypeFk, COUNT(*) items + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + WHERE t.routeFk = vRouteFk + GROUP BY t.id, i.itemPackingTypeFk + )sub2 + GROUP BY sub2.ticketFk + )sub3 ON sub3.ticketFk = t.id + WHERE t.routeFk = vRouteFk + ORDER BY priority, Id; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -66510,6 +67560,62 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `saleSplit` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `saleSplit`(vSaleFk INT, vQuantity INT) +BEGIN + + + DECLARE vNewSaleFk INT; + + INSERT INTO vn.sale(itemFk, + concept, + price, + discount, + quantity, + ticketFk, + isPriceFixed) + SELECT s.itemFk, + i.longName, + s.price, + s.discount, + vQuantity, + s.ticketFk, + s.isPriceFixed + FROM vn.sale s + JOIN vn.item i ON i.id = s.itemFk + WHERE s.id = vSaleFk; + + UPDATE vn.sale s + JOIN vn.item i ON i.id = s.itemFk + SET s.quantity = s.quantity - vQuantity, s.concept = i.longName + WHERE s.id = vSaleFk; + + SELECT LAST_INSERT_ID() INTO vNewSaleFk; + + INSERT INTO vn.saleComponent( saleFk, + componentFk, + value) + SELECT vNewSaleFk, + componentFk, + value + FROM vn.saleComponent + WHERE saleFk = vSaleFk; + +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `sales_merge` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -67100,19 +68206,19 @@ BEGIN DECLARE vComponentCount INT; DECLARE vCursor CURSOR FOR - SELECT DISTINCT tt.warehouseFk, IF(vIsTodayRelative, util.VN_CURDATE(), date(tt.shipped)) + SELECT DISTINCT tt.warehouseFk, IF(vIsTodayRelative, util.VN_CURDATE(), DATE(tt.shipped)) FROM tmp.sale_getProblems tt WHERE DATE(tt.shipped) BETWEEN util.VN_CURDATE() - AND TIMESTAMPADD(DAY, IF(vIsTodayRelative, 9.9, 1.9), util.VN_CURDATE()); + AND util.VN_CURDATE() + INTERVAL IF(vIsTodayRelative, 9.9, 1.9) DAY; DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; DELETE tt.* FROM tmp.sale_getProblems tt - JOIN vn.ticketObservation tto ON tto.ticketFk = tt.ticketFk - JOIN vn.observationType ot ON ot.id = tto.observationTypeFk - WHERE ot.code = 'administrative' - AND tto.description = 'Miriam'; + JOIN ticketObservation tto ON tto.ticketFk = tt.ticketFk + JOIN observationType ot ON ot.id = tto.observationTypeFk + WHERE ot.code = 'administrative' + AND tto.description = 'Miriam'; CREATE OR REPLACE TEMPORARY TABLE tmp.sale_problems ( ticketFk INT(11), @@ -67134,38 +68240,41 @@ BEGIN CREATE OR REPLACE TEMPORARY TABLE tmp.ticket_list (PRIMARY KEY (ticketFk)) ENGINE = MEMORY - SELECT tp.ticketFk, tp.clientFk - FROM tmp.sale_getProblems tp; + SELECT ticketFk, clientFk + FROM tmp.sale_getProblems; SELECT COUNT(*) INTO vComponentCount - FROM vn.component c - WHERE c.isRequired; + FROM component + WHERE isRequired; -- Too Little INSERT INTO tmp.sale_problems(ticketFk, isTooLittle) SELECT tp.ticketFk, TRUE FROM tmp.sale_getProblems tp - JOIN vn.ticket t ON t.id = tp.ticketFk - JOIN (SELECT t.addressFk, SUM(sv.litros) litros, t.totalWithoutVat + JOIN ticket t ON t.id = tp.ticketFk + JOIN ( + SELECT t.addressFk, SUM(sv.litros) litros, t.totalWithoutVat FROM tmp.ticket_list tl - JOIN vn.saleVolume sv ON sv.ticketFk = tl.ticketFk - JOIN vn.ticket t ON t.id = tl.ticketFk - JOIN vn.zoneClosure zc ON zc.zoneFk = t.zoneFk AND zc.dated = util.VN_CURDATE() - JOIN vn.agencyMode am ON am.id = t.agencyModeFk - JOIN vn.deliveryMethod dm ON dm.id = am.deliveryMethodFk - WHERE util.VN_NOW() < TIMESTAMPADD(MINUTE,MINUTE(zc.`hour`) ,TIMESTAMPADD(HOUR,HOUR(zc.`hour`),util.VN_CURDATE())) - AND dm.code IN('AGENCY','DELIVERY','PICKUP') + JOIN saleVolume sv ON sv.ticketFk = tl.ticketFk + JOIN ticket t ON t.id = tl.ticketFk + JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk + AND zc.dated = util.VN_CURDATE() + JOIN agencyMode am ON am.id = t.agencyModeFk + JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk + WHERE util.VN_NOW() < (util.VN_CURDATE() + INTERVAL HOUR(zc.`hour`) HOUR) + INTERVAL MINUTE(zc.`hour`) MINUTE + AND dm.code IN ('AGENCY','DELIVERY','PICKUP') AND t.shipped BETWEEN util.VN_CURDATE() AND util.midnight() - GROUP BY t.addressFk) sub ON sub.addressFk = t.addressFk - JOIN vn.volumeConfig vc + GROUP BY t.addressFk + ) sub ON sub.addressFk = t.addressFk + JOIN volumeConfig vc WHERE sub.litros < vc.minTicketVolume - AND sub.totalWithoutVat < vc.minTicketValue; + AND sub.totalWithoutVat < vc.minTicketValue; -- Faltan componentes INSERT INTO tmp.sale_problems(ticketFk, hasComponentLack, saleFk) - SELECT sub.ticketFk, sub.hasComponentLack, sub.saleFk - FROM( - SELECT tl.ticketFk, (COUNT(DISTINCT s.id) * vComponentCount > COUNT(c.id)) hasComponentLack, s.id saleFk + SELECT ticketFk, (vComponentCount > nComp) hasComponentLack, saleFk + FROM ( + SELECT COUNT(s.id) nComp, tl.ticketFk, s.id saleFk FROM tmp.ticket_list tl JOIN vn.sale s ON s.ticketFk = tl.ticketFk LEFT JOIN vn.saleComponent sc ON sc.saleFk = s.id @@ -67173,17 +68282,17 @@ BEGIN JOIN vn.ticket t ON t.id = tl.ticketFk JOIN vn.agencyMode am ON am.id = t.agencyModeFk JOIN vn.deliveryMethod dm ON dm.id = am.deliveryMethodFk - WHERE dm.code IN('AGENCY','DELIVERY','PICKUP') + WHERE dm.code IN ('AGENCY','DELIVERY','PICKUP') AND s.quantity > 0 GROUP BY s.id - LIMIT 10000000000000000) sub - WHERE sub.hasComponentLack; + ) sub + HAVING hasComponentLack; -- Cliente congelado INSERT INTO tmp.sale_problems(ticketFk, isFreezed) SELECT DISTINCT tl.ticketFk, TRUE FROM tmp.ticket_list tl - JOIN vn.client c ON c.id = tl.clientFk + JOIN client c ON c.id = tl.clientFk WHERE c.isFreezed ON DUPLICATE KEY UPDATE isFreezed = c.isFreezed; @@ -67191,21 +68300,21 @@ BEGIN CREATE OR REPLACE TEMPORARY TABLE tmp.clientGetDebt (PRIMARY KEY (clientFk)) ENGINE = MEMORY - SELECT DISTINCT clientFk - FROM tmp.ticket_list; + SELECT DISTINCT clientFk + FROM tmp.ticket_list; CALL client_getDebt(util.VN_CURDATE()); INSERT INTO tmp.sale_problems(ticketFk, risk, hasHighRisk) SELECT DISTINCT tl.ticketFk, r.risk, ((r.risk - cc.riskTolerance) > c.credit + 10) FROM tmp.ticket_list tl - JOIN vn.ticket t ON t.id = tl.ticketFk - JOIN vn.agencyMode a ON t.agencyModeFk = a.id + JOIN ticket t ON t.id = tl.ticketFk + JOIN agencyMode a ON t.agencyModeFk = a.id JOIN tmp.risk r ON r.clientFk = t.clientFk - JOIN vn.client c ON c.id = t.clientFk - JOIN vn.clientConfig cc + JOIN client c ON c.id = t.clientFk + JOIN clientConfig cc WHERE r.risk > c.credit + 10 - AND a.isRiskFree = FALSE + AND NOT a.isRiskFree ON DUPLICATE KEY UPDATE risk = r.risk, hasHighRisk = ((r.risk - cc.riskTolerance) > c.credit + 10); @@ -67213,13 +68322,12 @@ BEGIN INSERT INTO tmp.sale_problems(ticketFk, hasTicketRequest) SELECT DISTINCT tl.ticketFk, TRUE FROM tmp.ticket_list tl - JOIN vn.ticketRequest tr ON tr.ticketFk = tl.ticketFk + JOIN ticketRequest tr ON tr.ticketFk = tl.ticketFk WHERE tr.isOK IS NULL ON DUPLICATE KEY UPDATE hasTicketRequest = TRUE; -- Disponible, Faltas, Inventario y Retrasos OPEN vCursor; - l: LOOP SET vDone = FALSE; FETCH vCursor INTO vWarehouseFk, vDate; @@ -67241,21 +68349,21 @@ BEGIN LEFT(CONCAT('F: ',GROUP_CONCAT(i.id, ' ', i.longName, ' ')),250) problem, s.id AS saleFk FROM tmp.ticket_list tl - JOIN vn.ticket t ON t.id = tl.ticketFk - JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - JOIN vn.itemCategory ic ON ic.id = it.categoryFk + JOIN ticket t ON t.id = tl.ticketFk + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it on it.id = i.typeFk + JOIN itemCategory ic ON ic.id = it.categoryFk LEFT JOIN cache.visible v ON v.item_id = i.id AND v.calc_id = vVisibleCache LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache - LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + LEFT JOIN itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk WHERE IFNULL(v.visible,0) < s.quantity AND IFNULL(av.available ,0) < s.quantity AND IFNULL(issw.visible, 0) < s.quantity - AND s.isPicked = FALSE - AND s.reserved = FALSE - AND ic.merchandise = TRUE - AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT s.isPicked + AND NOT s.reserved + AND ic.merchandise + AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) AND NOT i.generic AND util.VN_CURDATE() = vDate AND t.warehouseFk = vWarehouseFk @@ -67268,24 +68376,25 @@ BEGIN FROM ( SELECT tl.ticketFk, LEFT(GROUP_CONCAT('I: ',i.id, ' ', i.longName, ' '),250) problem, s.id AS saleFk FROM tmp.ticket_list tl - JOIN vn.ticket t ON t.id = tl.ticketFk - JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - JOIN vn.itemCategory ic ON ic.id = it.categoryFk + JOIN ticket t ON t.id = tl.ticketFk + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it on it.id = i.typeFk + JOIN itemCategory ic ON ic.id = it.categoryFk LEFT JOIN cache.visible v ON v.item_id = s.itemFk AND v.calc_id = vVisibleCache - LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + LEFT JOIN itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk WHERE IFNULL(v.visible,0) >= s.quantity AND IFNULL(issw.visible, 0) < s.quantity AND s.quantity > 0 - AND s.isPicked = FALSE - AND s.reserved = FALSE - AND ic.merchandise = TRUE - AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT s.isPicked + AND NOT s.reserved + AND ic.merchandise + AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) AND NOT i.generic AND util.VN_CURDATE() = vDate AND t.warehouseFk = vWarehouseFk - GROUP BY tl.ticketFk) sub + GROUP BY tl.ticketFk + ) sub ON DUPLICATE KEY UPDATE itemDelay = sub.problem, saleFk = sub.saleFk; -- Retraso: Disponible suficiente, pero no visible ni ubicado @@ -67294,26 +68403,27 @@ BEGIN FROM ( SELECT tl.ticketFk, LEFT(GROUP_CONCAT('R: ',i.id, ' ', i.longName, ' '),250) problem, s.id AS saleFk FROM tmp.ticket_list tl - JOIN vn.ticket t ON t.id = tl.ticketFk - JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - JOIN vn.itemCategory ic ON ic.id = it.categoryFk + JOIN ticket t ON t.id = tl.ticketFk + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it on it.id = i.typeFk + JOIN itemCategory ic ON ic.id = it.categoryFk LEFT JOIN cache.visible v ON v.item_id = s.itemFk AND v.calc_id = vVisibleCache LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache - LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible,0) < s.quantity - AND IFNULL(av.available ,0) >= s.quantity + LEFT JOIN itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + WHERE IFNULL(v.visible, 0) < s.quantity + AND IFNULL(av.available, 0) >= s.quantity AND IFNULL(issw.visible, 0) < s.quantity AND s.quantity > 0 - AND s.isPicked = FALSE - AND s.reserved = FALSE - AND ic.merchandise = TRUE - AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT s.isPicked + AND NOT s.reserved + AND ic.merchandise + AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) AND NOT i.generic AND util.VN_CURDATE() = vDate AND t.warehouseFk = vWarehouseFk - GROUP BY tl.ticketFk) sub + GROUP BY tl.ticketFk + ) sub ON DUPLICATE KEY UPDATE itemDelay = sub.problem, saleFk = sub.saleFk; -- Redondeo: Cantidad pedida incorrecta en al grouping de la última compra @@ -67321,11 +68431,10 @@ BEGIN INSERT INTO tmp.sale_problems(ticketFk, hasRounding, saleFk) SELECT ticketFk, problem, saleFk FROM ( - SELECT - tl.ticketFk, - s.id saleFk , - LEFT(GROUP_CONCAT('RE: ',i.id, ' ', IFNULL(i.longName,''), ' '), 250) problem, - MOD(s.quantity, b.`grouping`) hasRounding + SELECT tl.ticketFk, + s.id saleFk , + LEFT(GROUP_CONCAT('RE: ',i.id, ' ', IFNULL(i.longName,''), ' '), 250) problem, + MOD(s.quantity, b.`grouping`) hasRounding FROM tmp.ticket_list tl JOIN ticket t ON t.id = tl.ticketFk AND t.warehouseFk = vWarehouseFk @@ -67338,14 +68447,13 @@ BEGIN ) sub ON DUPLICATE KEY UPDATE hasRounding = sub.problem, saleFk = sub.saleFk; END LOOP; - CLOSE vCursor; INSERT INTO tmp.sale_problems(ticketFk, isTaxDataChecked) SELECT DISTINCT tl.ticketFk, FALSE FROM tmp.ticket_list tl - JOIN vn.client c ON c.id = tl.clientFk - WHERE c.isTaxDataChecked = FALSE + JOIN client c ON c.id = tl.clientFk + WHERE NOT c.isTaxDataChecked ON DUPLICATE KEY UPDATE isTaxDataChecked = FALSE; DROP TEMPORARY TABLE @@ -68066,30 +69174,36 @@ DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `shelving_clean`() BEGIN - DELETE FROM vn.shelving + DELETE FROM shelving WHERE length(code) > 3 AND parked < TIMESTAMPADD(WEEK,-1,util.VN_CURDATE()); - DELETE FROM vn.itemShelving + DELETE FROM itemShelving WHERE visible <= 0 AND created < TIMESTAMPADD(MONTH,-1,util.VN_CURDATE()); DELETE ish.* - FROM vn.itemShelving ish + FROM itemShelving ish JOIN vn.shelving sh ON sh.code = ish.shelvingFk WHERE sh.parkingFk IS NULL AND ish.created < TIMESTAMPADD(WEEK,-1,util.VN_CURDATE()); - UPDATE vn.shelving sh - LEFT JOIN vn.itemShelving its ON its.shelvingFk = sh.`code` +UPDATE shelving sh + LEFT JOIN itemShelving its ON its.shelvingFk = sh.`code` SET isPrinted = 0, - parkingFk = NULL - WHERE its.id IS NULL - AND sh.isRecyclable - AND ( sh.parked IS NULL - OR - sh.parked < TIMESTAMPADD(MONTH,-1,util.VN_CURDATE()) - ); + parkingFk = NULL + WHERE its.id IS NULL + AND sh.isRecyclable + AND ( + sh.parked IS NULL + OR + sh.parked < TIMESTAMPADD(MONTH,-1,util.VN_CURDATE()) + ) + AND IF(code REGEXP '^[A-Za-z]{2}[0-9]', LEFT (code, 2) NOT IN ( + SELECT DISTINCT LEFT(its.shelvingFk, 2) + FROM itemShelving its + WHERE its.shelvingFk REGEXP '^[A-Za-z]{2}[0-9]' + ), TRUE); END ;; DELIMITER ; @@ -68297,58 +69411,86 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `stockBuyedByWorker` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `stockBuyedByWorker`( - vDate DATE, - vWorker INT) + vDated DATE, + vWorker INT +) BEGIN /** - * Calculates the space reserved by buyers of the same container + * Inserta el volumen de compra de un comprador + * en stockBuyed de acuerdo con la fecha. * - * @param vdate date of container delivery - * @param vWorker buyer reserving space in the container + * @param vDated Fecha de compra + * @param vWorker Id de trabajador */ - DECLARE vVolume DECIMAL(10, 2); - DECLARE vWarehouseFk INT; - DECLARE vCompressionRatio DECIMAL(1, 1); + CREATE OR REPLACE TEMPORARY TABLE tStockBuyed + (INDEX (userFk)) + ENGINE = MEMORY + SELECT requested, reserved, userFk + FROM stockBuyed + WHERE dated = vDated + AND userFk = vWorker; - CALL stockTraslation(vDate); + DELETE FROM stockBuyed + WHERE dated = vDated + AND userFk = vWorker; - SELECT warehouseFk, conversionCoefficient INTO vWarehouseFk, vCompressionRatio - FROM auctionConfig; + CALL stockTraslation(vDated); - SELECT volume INTO vVolume - FROM vn.packaging WHERE id = 'cc'; + INSERT INTO stockBuyed(userFk, buyed, `dated`, reserved, requested, description) + SELECT it.workerFk, + SUM((ti.quantity / b.packing) * buy_getVolume(b.id)) / vc.palletM3 / 1000000, + vDated, + sb.reserved, + sb.requested, + u.name + FROM itemType it + JOIN item i ON i.typeFk = it.id + LEFT JOIN tmp.item ti ON ti.itemFk = i.id + JOIN itemCategory ic ON ic.id = it.categoryFk + JOIN warehouse wh ON wh.code = 'VNH' + JOIN tmp.buyUltimate bu ON bu.itemFk = i.id + AND bu.warehouseFk = wh.id + JOIN buy b ON b.id = bu.buyFk + JOIN volumeConfig vc + JOIN account.`user` u ON u.id = it.workerFk + LEFT JOIN tStockBuyed sb ON sb.userFk = it.workerFk + WHERE ic.display + AND it.workerFk = vWorker; SELECT b.entryFk Id_Entrada, i.id Id_Article, i.name Article, - ti.amount Cantidad, - (vCompressionRatio * (ti.amount / b.packing) * vn.buy_getVolume(b.id)) - / vVolume buyed, - b.packageFk id_cubo, + ti.quantity Cantidad, + (ac.conversionCoefficient * (ti.quantity / b.packing) * buy_getVolume(b.id)) + / (vc.trolleyM3 * 1000000) buyed, + b.packagingFk id_cubo, b.packing FROM tmp.item ti - JOIN item i ON i.id = ti.item_id + JOIN item i ON i.id = ti.itemFk JOIN itemType it ON i.typeFk = it.id JOIN itemCategory ic ON ic.id = it.categoryFk JOIN worker w ON w.id = it.workerFk + JOIN auctionConfig ac JOIN tmp.buyUltimate bu ON bu.itemFk = i.id - AND bu.warehouseFk = vWarehouseFk + AND bu.warehouseFk = ac.warehouseFk JOIN buy b ON b.id = bu.buyFk - WHERE ic.display AND w.id = vWorker; + JOIN volumeConfig vc + WHERE ic.display + AND w.id = vWorker; - DROP TEMPORARY TABLE - tmp.buyUltimate, - tmp.item; + DROP TEMPORARY TABLE tmp.buyUltimate, + tmp.item, + tStockBuyed; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -68365,51 +69507,59 @@ DELIMITER ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `stockBuyed_add`(vDated DATE) +CREATE DEFINER=`root`@`localhost` PROCEDURE `stockBuyed_add`( + vDated DATE +) BEGIN /** - * Inserta el volumen de compra por comprador en stockBuyed de acuerdo con la fecha + * Inserta el volumen de compra por comprador + * en stockBuyed de acuerdo con la fecha. * * @param vDated Fecha de compra */ - - CREATE OR REPLACE TEMPORARY TABLE tStockBuyed + CREATE OR REPLACE TEMPORARY TABLE tStockBuyed (INDEX (userFk)) ENGINE = MEMORY SELECT requested, reserved, userFk FROM stockBuyed WHERE dated = vDated; + DELETE FROM stockBuyed WHERE dated = vDated; + CALL stockTraslation(vDated); INSERT INTO stockBuyed(userFk, buyed, `dated`, description) - SELECT it.workerFk, - SUM(( ti.amount / b.packing ) * buy_getVolume(b.id)) / vc.palletM3 / 1000000 buyed, + SELECT it.workerFk, + SUM((ti.quantity / b.packing) * buy_getVolume(b.id)) / vc.palletM3 / 1000000, vDated, u.name - FROM tmp.item ti - JOIN item i ON i.id = ti.item_id - JOIN itemType it ON it.id = i.typeFk + FROM itemType it + JOIN item i ON i.typeFk = it.id + LEFT JOIN tmp.item ti ON ti.itemFk = i.id JOIN itemCategory ic ON ic.id = it.categoryFk JOIN warehouse wh ON wh.code = 'VNH' JOIN tmp.buyUltimate bu ON bu.itemFk = i.id AND bu.warehouseFk = wh.id JOIN buy b ON b.id = bu.buyFk JOIN volumeConfig vc JOIN account.`user` u ON u.id = it.workerFk - WHERE ic.display <> 0 + JOIN workerDepartment wd ON wd.workerFk = u.id + JOIN department d ON d.id = wd.departmentFk + WHERE ic.display + AND d.code IN ('shopping', 'logistic', 'franceTeam') GROUP BY it.workerFk; INSERT INTO stockBuyed(buyed, dated, description) - SELECT SUM(ic.cm3 * ito.quantity / vc.palletM3 / 1000000), + SELECT SUM(ic.cm3 * ito.quantity / vc.palletM3 / 1000000), vDated, - IF(c.country = 'España',p.name,c.country) destiny + IF(c.code = 'ES', p.name, c.country) destiny FROM itemTicketOut ito JOIN ticket t ON t.id = ito.ticketFk JOIN `address` a ON a.id = t.addressFk JOIN province p ON p.id = a.provinceFk JOIN country c ON c.id = p.countryFk JOIN warehouse wh ON wh.id = t.warehouseFk - JOIN itemCost ic ON ic.itemFk = ito.itemFk AND ic.warehouseFk = t.warehouseFk + JOIN itemCost ic ON ic.itemFk = ito.itemFk + AND ic.warehouseFk = t.warehouseFk JOIN volumeConfig vc WHERE ito.shipped BETWEEN vDated AND util.dayend(vDated) AND wh.code = 'VNH' @@ -68421,8 +69571,7 @@ BEGIN s.reserved = ts.reserved WHERE s.dated = vDated; - DROP TEMPORARY TABLE - tmp.buyUltimate, + DROP TEMPORARY TABLE tmp.buyUltimate, tmp.item, tStockBuyed; END ;; @@ -68441,44 +69590,44 @@ DELIMITER ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `stockTraslation`(vDate DATE) +CREATE DEFINER=`root`@`localhost` PROCEDURE `stockTraslation`( + vDated DATE +) BEGIN /** - * Calcula el stock del almacén de subasta desde FechaInventario hasta vDate - * sin tener en cuenta las salidas del mismo dia vDate + * Calcula el stock del almacén de subasta desde FechaInventario hasta vDated + * sin tener en cuenta las salidas del mismo dia vDated * para ver el transporte a reservar - * @param vDate Fecha hasta la cual calcula el stock + * + * @param vDated Fecha hasta la cual calcula el stock + * @return tmp.item */ DECLARE vAuctionWarehouseFk INT; - DELETE FROM stockBuyed WHERE dated = vDate; - SELECT warehouseFk INTO vAuctionWarehouseFk FROM auctionConfig; - DROP TEMPORARY TABLE IF EXISTS tmp.item; - CREATE TEMPORARY TABLE tmp.item - (UNIQUE INDEX i USING HASH (item_id)) + CREATE OR REPLACE TEMPORARY TABLE tmp.item + (UNIQUE INDEX i USING HASH (itemFk)) ENGINE = MEMORY - SELECT item_id, SUM(amount) amount - FROM vn2008.item_entry_in - WHERE dat = vDate - AND vDate >= util.VN_CURDATE() - AND warehouse_id = vAuctionWarehouseFk - AND isVirtualStock is FALSE - GROUP BY item_id - HAVING amount != 0; + SELECT itemFk, SUM(quantity) quantity + FROM itemEntryIn + WHERE landed = vDated + AND vDated >= util.VN_CURDATE() + AND warehouseInFk = vAuctionWarehouseFk + AND NOT isVirtualStock + GROUP BY itemFk + HAVING quantity; - CALL `cache`.stock_refresh (FALSE); + CALL `cache`.stock_refresh(FALSE); - INSERT INTO tmp.item (item_id,amount) - SELECT item_id,s.amount - FROM `cache`.stock s + INSERT INTO tmp.item (itemFk, quantity) + SELECT item_id, amount + FROM `cache`.stock WHERE warehouse_id = vAuctionWarehouseFk - ON DUPLICATE KEY UPDATE amount = tmp.item.amount + VALUES(amount); - - CALL buyUltimate(vAuctionWarehouseFk, vDate); + ON DUPLICATE KEY UPDATE quantity = tmp.item.quantity + VALUES(quantity); + CALL buyUltimate(vAuctionWarehouseFk, vDated); END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -68650,7 +69799,10 @@ DELIMITER ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `supplierPackaging_ReportSource`(vFromDated DATE, vSupplierFk INT) +CREATE DEFINER=`root`@`localhost` PROCEDURE `supplierPackaging_ReportSource`( + vFromDated DATE, + vSupplierFk INT +) BEGIN /** * Selecciona los embalajes de un proveedor a partir de una fecha @@ -68658,15 +69810,26 @@ BEGIN * @param vFromDated Fecha de la que partir * @param vSupplierFk Id del proveedor */ - DECLARE vCounter INT DEFAULT 0; - DECLARE vMaxRow INT DEFAULT 0; - DECLARE vItemFk INT DEFAULT 0; SET @vBalance = 0; + SET @vItemFk = NULL; - CREATE OR REPLACE TEMPORARY TABLE tSupplierPackagingList - SELECT ROW_NUMBER() OVER(ORDER BY landed) `row`, + CREATE OR REPLACE TEMPORARY TABLE tSupplierPackaging + SELECT supplierFk, itemFk, - entryFk + longName, + supplier, + entryFk, + landed, + `in`, + `out`, + warehouse, + buyingValue, + IF ( + NOT (@vItemFk <=> sub.itemFk), + @vBalance := (`in` - `out`), + @vBalance := (`in` - `out` + @vBalance) + ) balance, + @vItemFk := sub.itemFk previousItemFk FROM ( SELECT supplierFk, itemFk, @@ -68674,8 +69837,8 @@ BEGIN supplier, entryFk, landed, - `out`, `in`, + `out`, warehouse, buyingValue FROM supplierPackaging @@ -68688,103 +69851,33 @@ BEGIN supplier, 'previous', vFromDated, - SUM(`out`), SUM(`in`), + SUM(`out`), NULL, buyingValue FROM supplierPackaging WHERE supplierFk = vSupplierFk AND landed < vFromDated GROUP BY itemFk - ) sub - GROUP BY itemFk - HAVING entryFk <> 'previous' - ORDER BY landed; + ORDER BY itemFk, landed, entryFk + ) sub + WHERE `out` OR `in`; - SELECT MAX(`row`) INTO vMaxRow - FROM tSupplierPackagingList; - - CREATE OR REPLACE TEMPORARY TABLE tSupplierPackaging( - supplierFk INT, - itemFk INT, - longName VARCHAR(50), - supplier VARCHAR(50), - entryFk VARCHAR(50), - landed DATE, - `in` VARCHAR(50), - `out` VARCHAR(50), - warehouse INT, - buyingValue INT, - balance INT - ); - - l1: LOOP - SET @vBalance = 0; - IF vCounter = vMaxRow THEN - LEAVE l1; - ELSE - SET vCounter = vCounter + 1; - END IF; - - SELECT itemFk INTO vItemFk - FROM tSupplierPackagingList - WHERE `row` = vCounter; - - INSERT INTO tSupplierPackaging - SELECT supplierFk, - itemFk, - longName, - supplier, - entryFk, - landed, - `in`, - `out`, - warehouse, - buyingValue, - @vBalance:= (`in` - `out` + @vBalance) - FROM ( - SELECT supplierFk, - itemFk, - longName, - supplier, - entryFk, - landed, - `out`, - `in`, - warehouse, - buyingValue - FROM supplierPackaging - WHERE supplierFk = vSupplierFk - AND landed >= vFromDated - AND itemFk = vItemFk - UNION ALL - SELECT vSupplierFk, - itemFk, - longName, - supplier, - 'previous', - vFromDated, - SUM(`out`), - SUM(`in`), - NULL, - buyingValue - FROM supplierPackaging - WHERE supplierFk = vSupplierFk - AND landed < vFromDated - AND itemFk = vItemFk - GROUP BY itemFk - ORDER BY landed - ) sub - WHERE `out` OR `in`; - END LOOP l1; - - SELECT * + SELECT supplierFk, + itemFk, + longName, + supplier, + entryFk, + landed, + `in`, + `out`, + warehouse, + buyingValue, + balance FROM tSupplierPackaging - ORDER BY itemFk, landed; + WHERE NOT (NOT balance AND landed < CURDATE() - INTERVAL 1 YEAR); - DROP TEMPORARY TABLE IF EXISTS - tSupplierPackaging, - tSupplierPackagingList; + DROP TEMPORARY TABLE tSupplierPackaging; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -68929,9 +70022,11 @@ BEGIN UPDATE vn.supplier s JOIN ( SELECT p.supplierFk - FROM vn.payment p - LEFT JOIN vn.supplier s ON s.id = p.supplierFk - LEFT JOIN vn.payMethod pm ON pm.id = s.payMethodFk + FROM supplier s + JOIN payMethod pm ON pm.id = s.payMethodFk + JOIN (SELECT supplierFk,MAX(created) created + FROM payment + GROUP BY supplierFk) p ON p.supplierFk = s.id WHERE p.created < (util.VN_CURDATE() - INTERVAL pm.graceMonthsDisableChecked MONTH) AND pm.graceMonthsDisableChecked AND s.isPayMethodChecked @@ -68964,14 +70059,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `ticketBoxesView` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `ticketBoxesView`(IN vTicketFk INT) BEGIN @@ -68988,7 +70083,7 @@ BEGIN JOIN item i ON i.id = s.itemFk JOIN cache.last_buy lb on lb.warehouse_id = t.warehouseFk AND lb.item_id = s.itemFk JOIN buy b on b.id = lb.buy_id - JOIN packaging p on p.id = b.packageFk + JOIN packaging p on p.id = b.packagingFk WHERE s.quantity >= b.packing AND t.id = vTicketFk AND p.isBox @@ -70495,11 +71590,26 @@ CREATE DEFINER=`root`@`localhost` PROCEDURE `ticket_add`( ,vIsRequiredZone INT ,OUT vNewTicket INT) BEGIN +/** +* Crea un ticket, +* ¡¡NO se debe llamar directamente, llamar a salix que hace comprobaciones previas!! +* +* @param vClientId id del cliente +* @param vShipped dia preparacion +* @param vWarehouseFk id del warehouse +* @param vCompanyFk id la empresa +* @param vAddressFk id del consignatario +* @param vAgencyModeFk id de la agencia +* @param vRouteFk id de la ruta | NULL +* @param vlanded dia llegada +* @param vUserId que crea el ticket +* @param vIsRequiredZone Indica si tiene que tener zona valida para ser creado +* @return vNewTicket id del ticket creado +*/ DECLARE vZoneFk INT; DECLARE vPrice DECIMAL(10,2); DECLARE vBonus DECIMAL(10,2); DECLARE vIsActive BOOL; - DECLARE vNickname VARCHAR(100); IF vClientId IS NULL THEN CALL util.throw ('CLIENT_NOT_ESPECIFIED'); @@ -70565,10 +71675,6 @@ BEGIN JOIN agencyMode am ON am.id = a.agencyModeFk WHERE a.id = vAddressFk; - SELECT a.nickname INTO vNickname - FROM address a - WHERE a.id = vAddressFk; - SET vNewTicket = LAST_INSERT_ID(); INSERT INTO ticketObservation(ticketFk, observationTypeFk, description) @@ -70630,14 +71736,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `ticket_canAdvance` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `ticket_canAdvance`(vDateFuture DATE, vDateToAdvance DATE, vWarehouseFk INT) BEGIN @@ -70704,12 +71810,14 @@ BEGIN dest.liters, origin.futureLines - origin.hasStock AS notMovableLines, (origin.futureLines = origin.hasStock) AS isFullMovable, + origin.futureZoneFk, + origin.futureZoneName, origin.classColor futureClassColor, dest.classColor FROM ( SELECT s.ticketFk, - t.workerFk, + c.salesPersonFk workerFk, t.shipped, t.totalWithVat, st.name futureState, @@ -70719,14 +71827,18 @@ BEGIN GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) futureIpt, CAST(SUM(litros) AS DECIMAL(10,0)) futureLiters, SUM((s.quantity <= IFNULL(st.amount,0))) hasStock, + z.id futureZoneFk, + z.name futureZoneName, st.classColor FROM ticket t + JOIN client c ON c.id = t.clientFk JOIN sale s ON s.ticketFk = t.id JOIN saleVolume sv ON sv.saleFk = s.id JOIN item i ON i.id = s.itemFk JOIN ticketState ts ON ts.ticketFk = t.id JOIN state st ON st.id = ts.stateFk JOIN agencyMode am ON t.agencyModeFk = am.id + JOIN zone z ON t.zoneFk = z.id LEFT JOIN itemPackingType ipt ON ipt.code = i.itemPackingTypeFk LEFT JOIN tmp.stock st ON st.itemFk = i.id WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture) @@ -71009,22 +72121,22 @@ BEGIN DECLARE vStateFk INT; INSERT INTO ticket ( - clientFk, - shipped, - addressFk, - agencyModeFk, - nickname, - warehouseFk, - companyFk, - landed, - zoneFk, - zonePrice, - zoneBonus, - routeFk, - priority, - hasPriority, - clonedFrom - ) + clientFk, + shipped, + addressFk, + agencyModeFk, + nickname, + warehouseFk, + companyFk, + landed, + zoneFk, + zonePrice, + zoneBonus, + routeFk, + priority, + hasPriority, + clonedFrom + ) SELECT clientFk, shipped, @@ -71041,18 +72153,18 @@ BEGIN priority, hasPriority, vOriginalTicket - FROM ticket - WHERE id = vOriginalTicket; + FROM ticket + WHERE id = vOriginalTicket; SET vNewTicket = LAST_INSERT_ID(); INSERT INTO ticketObservation(ticketFk, observationTypeFk, description) - SELECT vNewTicket, o.observationTypeFk, o.description - FROM ticketObservation o - WHERE o.ticketFk = vOriginalTicket; + SELECT vNewTicket, observationTypeFk, description + FROM ticketObservation + WHERE ticketFk = vOriginalTicket; INSERT INTO ticketTracking(ticketFk, stateFk, workerFk, created) - SELECT vNewTicket, stateFk, workerFk , created + SELECT vNewTicket, stateFk, workerFk, created FROM ticketTracking WHERE ticketFk = vOriginalTicket ORDER BY created; @@ -72161,32 +73273,29 @@ BEGIN */ CALL sale_getProblems(vIsTodayRelative); - DROP TEMPORARY TABLE IF EXISTS tmp.ticket_problems; - CREATE TEMPORARY TABLE tmp.ticket_problems - (PRIMARY KEY (ticketFk)) - ENGINE = MEMORY - SELECT - ticketFk, - MAX(p.isFreezed) isFreezed, - MAX(p.risk) risk, - MAX(p.hasHighRisk) hasHighRisk, - MAX(p.hasTicketRequest) hasTicketRequest, - MAX(p.itemShortage) itemShortage, - MIN(p.isTaxDataChecked) isTaxDataChecked, - MAX(p.hasComponentLack) hasComponentLack, - MAX(p.isTooLittle) isTooLittle, - MAX(p.itemDelay) itemDelay, - MAX(p.hasRounding) hasRounding, - MAX(p.itemLost) itemLost, - 0 totalProblems - FROM tmp.sale_problems p - GROUP BY ticketFk; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticket_problems + (PRIMARY KEY (ticketFk)) + ENGINE = MEMORY + SELECT ticketFk, + MAX(isFreezed) isFreezed, + MAX(risk) risk, + MAX(hasHighRisk) hasHighRisk, + MAX(hasTicketRequest) hasTicketRequest, + MAX(itemShortage) itemShortage, + MIN(isTaxDataChecked) isTaxDataChecked, + MAX(hasComponentLack) hasComponentLack, + MAX(isTooLittle) isTooLittle, + MAX(itemDelay) itemDelay, + MAX(hasRounding) hasRounding, + MAX(itemLost) itemLost, + 0 totalProblems + FROM tmp.sale_problems + GROUP BY ticketFk; UPDATE tmp.ticket_problems tp - SET tp.totalProblems = - ( + SET tp.totalProblems = ( (tp.isFreezed) + - IF(tp.risk, TRUE, FALSE) + + IF(tp.risk,TRUE, FALSE) + (tp.hasTicketRequest) + (tp.isTaxDataChecked = 0) + (tp.hasComponentLack) + @@ -72197,8 +73306,7 @@ BEGIN (tp.itemShortage) ); - DROP TEMPORARY TABLE - tmp.sale_problems; + DROP TEMPORARY TABLE tmp.sale_problems; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -72231,124 +73339,124 @@ BEGIN CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouseFk); CALL `vn`.`zoneClosure_recalc`(); - DROP TEMPORARY TABLE IF EXISTS tmp.salesToSplit; - - CREATE TEMPORARY TABLE tmp.salesToSplit + CREATE OR REPLACE TEMPORARY TABLE tmp.salesToSplit (saleFk INT PRIMARY KEY, ticketFk INT, - problem VARCHAR(1)) ENGINE = MEMORY; + problem VARCHAR(1), + INDEX(ticketFk)) ENGINE = MEMORY; INSERT INTO tmp.salesToSplit(saleFk, ticketFk, problem) - SELECT s.id, s.ticketFk, 'F' - FROM vn.ticket t - JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - JOIN vn.itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN cache.visible v ON v.item_id = i.id AND v.calc_id = vVisibleCache - LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache - LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible,0) < s.quantity - AND IFNULL(av.available ,0) < s.quantity - AND IFNULL(issw.visible, 0) < s.quantity - AND s.isPicked = FALSE - AND s.reserved = FALSE - AND ic.merchandise = TRUE - AND t.shipped BETWEEN util.VN_CURDATE() AND util.dayend(util.VN_CURDATE()) - AND NOT i.generic - AND t.warehouseFk = vWarehouseFk; + SELECT s.id, s.ticketFk, 'F' + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it on it.id = i.typeFk + JOIN itemCategory ic ON ic.id = it.categoryFk + LEFT JOIN cache.visible v ON v.item_id = i.id AND v.calc_id = vVisibleCache + LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache + LEFT JOIN itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + WHERE IFNULL(v.visible,0) < s.quantity + AND IFNULL(av.available ,0) < s.quantity + AND IFNULL(issw.visible, 0) < s.quantity + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND ic.merchandise = TRUE + AND t.shipped BETWEEN util.VN_CURDATE() AND util.dayend(util.VN_CURDATE()) + AND NOT i.generic + AND t.warehouseFk = vWarehouseFk; INSERT IGNORE INTO tmp.salesToSplit(saleFk, ticketFk, problem) - SELECT s.id, s.ticketFk, 'I' - FROM vn.ticket t - JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - JOIN vn.itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN cache.visible v ON v.item_id = s.itemFk AND v.calc_id = vVisibleCache - LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible,0) >= s.quantity - AND IFNULL(issw.visible, 0) < s.quantity - AND s.quantity > 0 - AND s.isPicked = FALSE - AND s.reserved = FALSE - AND ic.merchandise = TRUE - AND t.shipped BETWEEN util.VN_CURDATE() AND util.dayend(util.VN_CURDATE()) - AND NOT i.generic - AND t.warehouseFk = vWarehouseFk; + SELECT s.id, s.ticketFk, 'I' + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it on it.id = i.typeFk + JOIN itemCategory ic ON ic.id = it.categoryFk + LEFT JOIN cache.visible v ON v.item_id = s.itemFk AND v.calc_id = vVisibleCache + LEFT JOIN itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + WHERE IFNULL(v.visible,0) >= s.quantity + AND IFNULL(issw.visible, 0) < s.quantity + AND s.quantity > 0 + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND ic.merchandise = TRUE + AND t.shipped BETWEEN util.VN_CURDATE() AND util.dayend(util.VN_CURDATE()) + AND NOT i.generic + AND t.warehouseFk = vWarehouseFk; INSERT IGNORE INTO tmp.salesToSplit(saleFk, ticketFk, problem) - SELECT s.id, s.ticketFk, 'R' - FROM vn.ticket t - JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - JOIN vn.itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN cache.visible v ON v.item_id = s.itemFk AND v.calc_id = vVisibleCache - LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache - LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible,0) < s.quantity - AND IFNULL(av.available ,0) >= s.quantity - AND IFNULL(issw.visible, 0) < s.quantity - AND s.quantity > 0 - AND s.isPicked = FALSE - AND s.reserved = FALSE - AND ic.merchandise = TRUE - AND t.shipped BETWEEN util.VN_CURDATE() AND util.dayend(util.VN_CURDATE()) - AND NOT i.generic - AND t.warehouseFk = vWarehouseFk; + SELECT s.id, s.ticketFk, 'R' + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it on it.id = i.typeFk + JOIN itemCategory ic ON ic.id = it.categoryFk + LEFT JOIN cache.visible v ON v.item_id = s.itemFk AND v.calc_id = vVisibleCache + LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache + LEFT JOIN itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + WHERE IFNULL(v.visible,0) < s.quantity + AND IFNULL(av.available ,0) >= s.quantity + AND IFNULL(issw.visible, 0) < s.quantity + AND s.quantity > 0 + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND ic.merchandise = TRUE + AND t.shipped BETWEEN util.VN_CURDATE() AND util.dayend(util.VN_CURDATE()) + AND NOT i.generic + AND t.warehouseFk = vWarehouseFk; - DROP TEMPORARY TABLE IF EXISTS tmp.ticketsToSplit; - - CREATE TEMPORARY TABLE tmp.ticketsToSplit - (ticketFk INT PRIMARY KEY, + CREATE OR REPLACE TEMPORARY TABLE tTicketsToSplit( + ticketFk INT PRIMARY KEY, problems VARCHAR(100), addressFk INT, ipt VARCHAR(10), - etd TIME) ENGINE = MEMORY; + etd TIME, + INDEX(addressFk) + ) ENGINE = MEMORY; - INSERT INTO tmp.ticketsToSplit - SELECT - ss.ticketFk, - GROUP_CONCAT(DISTINCT ss.problem ORDER BY ss.problem) problems, - t.addressFk, - GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt, - zc.`hour` etd - FROM tmp.salesToSplit ss - JOIN vn.ticket t ON t.id = ss.ticketFk - JOIN vn.sale s ON s.id = ss.saleFk - JOIN vn.item i ON i.id = s.itemFk - LEFT JOIN vn.zoneClosure zc ON zc.zoneFk = t.zoneFk - GROUP BY ss.ticketFk; + INSERT INTO tTicketsToSplit + SELECT ss.ticketFk, + GROUP_CONCAT(DISTINCT ss.problem ORDER BY ss.problem) problems, + t.addressFk, + GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt, + DATE_FORMAT(IF(HOUR(t.shipped), + t.shipped, + IFNULL(zc.hour, z.HOUR)),'%H:%i') etd + FROM tmp.salesToSplit ss + JOIN ticket t ON t.id = ss.ticketFk + JOIN sale s ON s.id = ss.saleFk + JOIN item i ON i.id = s.itemFk + LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk + LEFT JOIN zone z ON z.id = t.zoneFk + GROUP BY ss.ticketFk; - SELECT - ts.*, - t.id ticketFuture, - st.name state, - zc.`hour` tfEtd, - GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) tfIpt, - st2.name tfState - FROM tmp.ticketsToSplit ts - LEFT JOIN vn.ticketState ts2 ON ts2.ticketFk = ts.ticketFk - LEFT JOIN vn.state st ON st.id = ts2.stateFk - LEFT JOIN vn.ticket t - ON t.id != ts.ticketFk - AND t.addressFk = ts.addressFk - AND t.shipped BETWEEN vDated AND util.dayend(vDated) - LEFT JOIN vn.zoneClosure zc ON zc.zoneFk = t.zoneFk AND zc.dated = vDated - LEFT JOIN vn.sale s ON s.ticketFk = t.id - LEFT JOIN vn.item i ON i.id = s.itemFk - LEFT JOIN vn.ticketState tst ON tst.ticketFk = t.id - LEFT JOIN vn.state st2 ON st2.id = tst.stateFk + SELECT ts.*, + t.id ticketFuture, + st.name state, + zc.`hour` tfEtd, + GROUP_CONCAT( + DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk + ) tfIpt, + st2.name tfState + FROM tTicketsToSplit ts + LEFT JOIN ticketState ts2 ON ts2.ticketFk = ts.ticketFk + LEFT JOIN `state` st ON st.id = ts2.stateFk + LEFT JOIN ticket t ON t.id != ts.ticketFk + AND t.addressFk = ts.addressFk + AND t.shipped BETWEEN vDated AND util.dayend(vDated) + LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk AND zc.dated = vDated + LEFT JOIN sale s ON s.ticketFk = t.id + LEFT JOIN item i ON i.id = s.itemFk + LEFT JOIN ticketState tst ON tst.ticketFk = t.id + LEFT JOIN state st2 ON st2.id = tst.stateFk WHERE (t.id IS NULL - OR (vDated > util.VN_CURDATE()) - OR (vDated = util.VN_CURDATE() AND vHour >= zc.`hour`)) + OR (vDated > util.VN_CURDATE()) + OR (vDated = util.VN_CURDATE() AND vHour >= zc.`hour`)) AND ts.etd <= vHour GROUP BY ts.ticketFk, t.id ORDER BY ts.etd, ts.ticketFk; - DROP TEMPORARY TABLE - tmp.ticketsToSplit; + DROP TEMPORARY TABLE tTicketsToSplit; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -72983,16 +74091,19 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `ticket_setState` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `ticket_setState`(vSelf INT, vStateCode VARCHAR(255) COLLATE utf8_general_ci) +CREATE DEFINER=`root`@`localhost` PROCEDURE `ticket_setState`( + vSelf INT, + vStateCode VARCHAR(255) COLLATE utf8_general_ci +) BEGIN /** * Modifica el estado de un ticket si se cumplen las condiciones necesarias. @@ -73004,35 +74115,27 @@ BEGIN DECLARE vTicketStateCode VARCHAR(255); DECLARE vCanChangeState BOOL; DECLARE vPackedAlertLevel INT; - DECLARE vOnPreparationAlertLevel INT; - DECLARE vNextAlertLevel INT; DECLARE vZoneFk INT; - SELECT s.alertLevel, s.`code`, s2.alertLevel, t.zoneFk - INTO vticketAlertLevel, vTicketStateCode, vNextAlertLevel , vZoneFk + SELECT s.alertLevel, s.`code`, t.zoneFk + INTO vticketAlertLevel, vTicketStateCode, vZoneFk FROM state s JOIN ticketTracking tt ON tt.stateFk = s.id - JOIN state s2 ON s2.code = vStateCode JOIN ticket t ON t.id = tt.ticketFk WHERE tt.ticketFk = vSelf ORDER BY tt.created DESC LIMIT 1; SELECT id INTO vPackedAlertLevel FROM alertLevel WHERE code = 'PACKED'; - SELECT id INTO vOnPreparationAlertLevel FROM alertLevel WHERE code = 'ON_PREPARATION'; IF vStateCode = 'OK' AND vZoneFk IS NULL THEN CALL util.throw('ASSIGN_ZONE_FIRST'); END IF; - IF vNextAlertLevel > vticketAlertLevel && vticketAlertLevel < vOnPreparationAlertLevel THEN - UPDATE sale - SET originalQuantity = quantity - WHERE ticketFk = vSelf; - END IF; - - SET vCanChangeState = (vStateCode <> 'ON_CHECKING' OR vticketAlertLevel < vPackedAlertLevel) - AND NOT ( + SET vCanChangeState = ( + vStateCode <> 'ON_CHECKING' OR + vticketAlertLevel < vPackedAlertLevel + )AND NOT ( vTicketStateCode IN ('CHECKED', 'CHECKING') AND vStateCode IN ('PREPARED', 'ON_PREPARATION') ); @@ -73407,7 +74510,7 @@ BEGIN (INDEX (departmentFk)) SELECT dated, businessFk, - userFk, + sub.id userFk, departmentFk, hourStart, hourEnd, @@ -73435,8 +74538,7 @@ BEGIN at2.permissionRate, at2.discountRate, ct.hoursWeek hoursWeek, - at2.isAllowedToWork, - u.userFk + at2.isAllowedToWork FROM time t LEFT JOIN business b ON t.dated BETWEEN b.started AND IFNULL(b.ended, vDatedTo) LEFT JOIN worker w ON w.id = b.workerFk @@ -73622,212 +74724,205 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `timeControl_calculate` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `timeControl_calculate`( vDatedFrom DATETIME, vDatedTo DATETIME) BEGIN /* + * Agrupa por trabajador y día, el tiempo de trabajo y descanso retribuido(si tiene). + * Los registros horarios incorrectos (tmp.timeControlError) no se considerarán. + * Si un trabajador ha trabajado más de un cierto umbral de tiempo (vTimeToBreakTime) + * y no ha tenido descansos que superen un parámetro determinado(vMaxTimeToBreak), + * se le añadirá un tiempo de descanso (vBreakTime) a sus horas trabajadas. + * El tiempo de descanso solo se añade si el trabajador realmente disfrutó del descanso. + * Si disfrutó de menos tiempo de descanso, solo se añade el tiempo que disfrutó. + * * @param vDatedFrom * @param vDatedTo - * Cálculo de horas trabajadas por empleado y día, - * sin tener en cuenta los días con fichadas incorrectas (tabla tmp.timeControlError) - * En el caso de haber hecho descanso y trabajado un mínimo de tiempo (vTimeToBreakTime), - * se añade al tiempo de trabajo efectivo el descanso (vBreakTime) + * * @return tmp.timeControlCalculate * (workerFk, dated, timeWorkSeconds, timeWorkSexagesimal, timeWorkDecimal, timed) */ - DECLARE vHourToSeconds INTEGER; + DECLARE vHourSeconds INTEGER; DECLARE vDatedFromYesterday DATETIME; DECLARE vDatedToTomorrow DATETIME; DECLARE vTimeToBreakTime INT; DECLARE vBreakTime INT; + DECLARE vMaxTimeToBreak INT; SELECT DATE_SUB(vDatedFrom, INTERVAL 1 DAY), DATE_ADD(vDatedTo, INTERVAL 1 DAY) INTO vDatedFromYesterday, vDatedToTomorrow; - SELECT timeToBreakTime, breakTime INTO vTimeToBreakTime, vBreakTime + SELECT timeToBreakTime, breakTime, maxTimeToBreak, TIME_TO_SEC('01:00:00') + INTO vTimeToBreakTime, vBreakTime, vMaxTimeToBreak, vHourSeconds FROM workerTimeControlConfig LIMIT 1; - CALL timeControl_getError(vDatedFrom, vDatedTo); + CALL timeControl_getError(vDatedFromYesterday, vDatedToTomorrow); - DROP TEMPORARY TABLE IF EXISTS tmp.workerTimeControl; - CREATE TEMPORARY TABLE tmp.workerTimeControl - (INDEX (userFk), INDEX (timed)) - ENGINE = MEMORY - SELECT DISTINCT(wtc.id), - wtc.userFk, + CREATE OR REPLACE TEMPORARY TABLE tmp.workerTimeControl + (INDEX(userFk, timed), INDEX(timed), INDEX(direction)) + ENGINE = MEMORY + SELECT wtc.userFk, wtc.timed, + DATE(wtc.timed) dated, wtc.direction, TRUE isReal FROM workerTimeControl wtc - JOIN tmp.`user` w ON w.userFk = wtc.userFk + JOIN tmp.`user` u ON u.userFk = wtc.userFk + LEFT JOIN ( + SELECT wtc.userFk, MIN(wtc.timed) firstIn + FROM workerTimeControl wtc + JOIN tmp.`user` u ON u.userFk = wtc.userFk + LEFT JOIN tmp.timeControlError tce ON tce.id = wtc.id + WHERE wtc.timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + AND wtc.direction = 'in' + AND tce.id IS NULL + GROUP BY userFk + ) fi ON wtc.userFk = fi.userFk + LEFT JOIN ( + SELECT wtc.userFk, MAX(wtc.timed) lastOut + FROM workerTimeControl wtc + JOIN tmp.`user` u ON u.userFk = wtc.userFk + LEFT JOIN tmp.timeControlError tce ON tce.id = wtc.id + WHERE wtc.timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + AND wtc.direction = 'out' + AND tce.id IS NULL + GROUP BY userFk + ) lo ON wtc.userFk = lo.userFk LEFT JOIN tmp.timeControlError tce ON tce.id = wtc.id - WHERE wtc.timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + WHERE wtc.timed BETWEEN fi.firstIn AND lo.lastOut AND tce.id IS NULL - ORDER BY wtc.userFk, wtc.timed ASC; + ORDER BY wtc.userFk, wtc.timed; - SELECT MAX(id) INTO @vCont - FROM tmp.workerTimeControl; + CREATE OR REPLACE TEMPORARY TABLE tmp.wtcToinsert + (INDEX(timed)) + ENGINE = MEMORY + WITH wtc AS( + SELECT timed, + userFk, + dated, + direction, + LEAD(dated) OVER + (PARTITION BY userFk, dated ORDER BY timed) nextDay, + LEAD(userFk) OVER + (PARTITION BY userFk ORDER BY timed) nextUserFk, + ROW_NUMBER() OVER (ORDER BY userFk, timed) MOD 2 isOdd + FROM tmp.workerTimeControl + WHERE timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + ORDER BY userFk, timed + ), wtcToinsert AS( + SELECT userFk, + dated, + IF(userFk = nextUserFk + AND nextDay IS NULL + AND isOdd + AND direction <> 'out', TRUE, FALSE) outNextDay, + IF(userFk = nextUserFk + AND nextDay IS NULL + AND NOT isOdd + AND direction <> 'out', TRUE, FALSE) outNextDayWhitBreak + FROM wtc + HAVING outNextDay OR outNextDayWhitBreak + )SELECT userFk, util.dayEnd(dated) timed, 'out' direction + FROM wtcToinsert + WHERE outNextDay + UNION ALL + SELECT userFk, dated + INTERVAL 1 DAY, 'in' + FROM wtcToinsert + WHERE outNextDay + UNION ALL + SELECT userFk, util.dayEnd(dated) - INTERVAL 1 SECOND, 'middle' + FROM wtcToinsert + WHERE outNextDayWhitBreak + UNION ALL + SELECT userFk, util.dayEnd(dated), 'out' + FROM wtcToinsert + WHERE outNextDayWhitBreak + UNION ALL + SELECT userFk, dated + INTERVAL 1 DAY, 'in' + FROM wtcToinsert + WHERE outNextDayWhitBreak + UNION ALL + SELECT userFk, dated + INTERVAL 1 DAY + INTERVAL 1 SECOND, 'middle' + FROM wtcToinsert + WHERE outNextDayWhitBreak; - DROP TEMPORARY TABLE IF EXISTS tmp.workerTimeControlAux; - CREATE TEMPORARY TABLE tmp.workerTimeControlAux ( - `id` int(11) , - `userFk` int(10) unsigned , - `timed` datetime, - `direction` enum('in', 'out','middle') - ) ENGINE=MEMORY; + INSERT INTO tmp.workerTimeControl (userFk, timed, dated, direction, isReal) + SELECT userFk, timed, DATE(timed), direction, FALSE + FROM tmp.wtcToinsert; - SET @counter := 0; - SET @vIsOdd := FALSE; - - -- Cambio de dia en medio de un descanso - INSERT INTO tmp.workerTimeControlAux (id, userFk, timed, direction) - SELECT @vCont:= @vCont + 1 id, - userFk, - util.dayEnd(dated) timed, - 'middle' direction - FROM(SELECT wtc.userFk, - DATE(@lastTimed) dated, - (@vIsOdd := NOT @vIsOdd) isOdd, - IF(@vIsOdd AND wtc.direction = 'middle' - AND DATE(timed) <> DATE(@lastTimed), TRUE, FALSE) hasBreak, - @lastTimed := wtc.timed - FROM tmp.workerTimeControl wtc - ORDER BY wtc.userFk, wtc.timed - LIMIT 10000000000000000000 - )sub - WHERE hasBreak; - - SET @counter := 0; - SET @vIsOdd := FALSE; - - INSERT INTO tmp.workerTimeControlAux (id, userFk, timed, direction) - SELECT @vCont:= @vCont + 1, - userFk, - DATE_ADD(sub.dated, INTERVAL 1 DAY), - 'middle' - FROM(SELECT wtc.userFk, - DATE(@lastTimed) dated, - (@vIsOdd := NOT @vIsOdd) isOdd, - IF(@vIsOdd AND wtc.direction = 'middle' - AND DATE(timed) <> DATE(@lastTimed), TRUE, FALSE) hasBreak, - @lastTimed := wtc.timed - FROM tmp.workerTimeControl wtc - ORDER BY wtc.userFk, wtc.timed - LIMIT 10000000000000000000 - )sub - WHERE hasBreak; - - -- Cambio de dia - INSERT INTO tmp.workerTimeControlAux (id, userFk, timed, direction) - SELECT @vCont:= @vCont + 1 id, - sub.userFk, - util.dayEnd(sub.dated) timed, - 'out' direction - FROM (SELECT MAX(wtc.timed) timed, wtc.userFk, date(wtc.timed) dated - FROM workerTimeControl wtc - JOIN tmp.`user` w ON w.userFk = wtc.userFk - LEFT JOIN tmp.timeControlError tce ON tce.id = wtc.id - WHERE wtc.timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow - AND tce.id IS NULL - GROUP BY wtc.userFk, DATE(wtc.timed) - ) sub - JOIN tmp.workerTimeControl wtc ON wtc.timed = sub.timed - AND wtc.userFk = sub.userFk - WHERE wtc.direction <> 'out'; - - INSERT INTO tmp.workerTimeControlAux (id, userFk, timed, direction) - SELECT @vCont:= @vCont + 1, sub.userFk, DATE_ADD(sub.dated, INTERVAL 1 DAY), 'in' - FROM (SELECT MAX(wtc.timed) timed, wtc.userFk, date(wtc.timed) dated - FROM workerTimeControl wtc - JOIN tmp.`user` w ON w.userFk = wtc.userFk - LEFT JOIN tmp.timeControlError tce ON tce.id = wtc.id - WHERE wtc.timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow - AND tce.id IS NULL - GROUP BY wtc.userFk, DATE(wtc.timed) - ) sub - JOIN tmp.workerTimeControl wtc ON wtc.timed = sub.timed - AND wtc.userFk = sub.userFk - WHERE wtc.direction <> 'out'; - - INSERT INTO tmp.workerTimeControl (id, userFk, timed, direction, isReal) - SELECT id, userFk, timed, direction, FALSE FROM tmp.workerTimeControlAux; - - SET vHourToSeconds = 3600; - SET @vIsOdd := TRUE; - SET @vDated := 0; - SET @vLastTimed := 0; - SET @vPreviousTimed := 0; - - DROP TEMPORARY TABLE IF EXISTS tmp.workerBreakDays; - CREATE TEMPORARY TABLE tmp.workerBreakDays - (INDEX (userFk), INDEX (dated)) - ENGINE = MEMORY - SELECT sub.userFk, - sub.dated - FROM (SELECT (@vIsOdd := NOT @vIsOdd), - IF(wtc.direction = 'in', @vIsOdd := TRUE, NULL), - IF(@vIsOdd, @vLastTimed := UNIX_TIMESTAMP(wtc.timed), NULL), - IF(@vIsOdd, 0, UNIX_TIMESTAMP(wtc.timed) - @vLastTimed) timeWork, - IF(direction='in', @vDated := DATE(wtc.timed), @vDated) dated, - wtc.userFk - FROM tmp.workerTimeControl wtc - ORDER BY wtc.userFk, wtc.timed, wtc.id - LIMIT 10000000000000000000 - )sub - GROUP BY sub.userFk, sub.dated - HAVING SUM(sub.timeWork) >= vTimeToBreakTime; - - SET @vIsOdd := TRUE; - SET @vDated := 0; - SET @vLastTimed := 0; - - DROP TEMPORARY TABLE IF EXISTS tmp.workerTimeControlAux2; - CREATE TEMPORARY TABLE tmp.workerTimeControlAux2 - SELECT * - FROM tmp.workerTimeControl - WHERE timed BETWEEN vDatedFromYesterday AND vDatedTo - ORDER BY userFk, timed, id; - - DROP TEMPORARY TABLE IF EXISTS tmp.timeControlCalculate; + SET @accumulatedForBreakTime = 0; + SET @oldrealDay = NULL; CREATE OR REPLACE TEMPORARY TABLE tmp.timeControlCalculate - (INDEX (userFk, dated)) - ENGINE = MEMORY - SELECT sub.userFk, - sub.dated, - IF(wb.userFk, vBreakTime, 0) + SUM(sub.timeWork) timeWorkSeconds, - SEC_TO_TIME(IF(wb.userFk, vBreakTime, 0) + SUM(sub.timeWork)) timeWorkSexagesimal, - (IF(wb.userFk, vBreakTime, 0) + SUM(sub.timeWork)) / vHourToSeconds timeWorkDecimal, - CAST(GROUP_CONCAT(DATE_FORMAT(sub.realTimed, "%H:%i") - ORDER BY sub.timed ASC SEPARATOR ' - ') AS CHAR(256)) timed - FROM (SELECT (@vIsOdd := NOT @vIsOdd), - IF(direction='in', @vIsOdd := TRUE, 0), - IF(@vIsOdd, @vLastTimed := UNIX_TIMESTAMP(timed), 0), - IF(@vIsOdd, 0, UNIX_TIMESTAMP(timed) - @vLastTimed) timeWork, - timed, - userFk, - DATE(timed) dated, - IF(isReal, timed, NULL) realTimed - FROM tmp.workerTimeControlAux2 - )sub - LEFT JOIN tmp.workerBreakDays wb ON wb.userFk = sub.userFk AND wb.dated = sub.dated - WHERE sub.timed BETWEEN vDatedFrom AND vDatedTo - GROUP BY sub.userFk, sub.dated; + WITH workerTimed AS ( + SELECT + userFk, + dated, + timed, + (direction ='in' AND isReal) breakPoint, + SUM(CASE WHEN (direction ='in' AND isReal) THEN TRUE ELSE FALSE END) + OVER (ORDER BY userFk, timed) AS realDay, + TIMESTAMPDIFF(SECOND, LAG(timed) + OVER (PARTITION BY userFk, dated ORDER BY timed), timed) gapTime, + ROW_NUMBER() + OVER (PARTITION BY userFk, dated ORDER BY timed) MOD 2 isOdd + FROM tmp.workerTimeControl + WHERE timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + ), accumulated AS ( + SELECT SUM(IF(isOdd, 0, gapTime)) + OVER (PARTITION BY userFk,dated ORDER BY userFk,timed) accumulatedWorkTime, + SUM(IF(NOT isOdd OR breakPoint, 0, IFNULL(gapTime, 0))) + OVER (PARTITION BY realDay ORDER BY realDay,timed) accumulatedBreakTime, + IF(realDay <> @oldrealDay OR (isOdd AND gapTime >= vMaxTimeToBreak), + @accumulatedForBreakTime := 0, + @accumulatedForBreakTime := @accumulatedForBreakTime + + IF(isOdd, 0, gapTime )) accumulatedForBreakTime, + @oldrealDay := realDay, + userFk, + dated, + realDay + FROM workerTimed + ), totalWorked AS ( + SELECT userFk, + dated, + MAX(accumulatedWorkTime) + + IF(MAX(accumulatedForBreakTime) >= vTimeToBreakTime, + LEAST(vBreakTime, MAX(accumulatedBreakTime)), + 0) timeWorkSeconds + FROM accumulated + GROUP BY userFk, dated + )SELECT tw.userFk, + tw.dated, + timeWorkSeconds, + SEC_TO_TIME(timeWorkSeconds) timeWorkSexagesimal, + timeWorkSeconds / vHourSeconds timeWorkDecimal, + sub.tableTimed + FROM totalWorked tw + JOIN ( + SELECT userFk, + dated, + GROUP_CONCAT(DATE_FORMAT(timed, "%H:%i") ORDER BY timed ASC + SEPARATOR ' - ')tableTimed + FROM tmp.workerTimeControl + WHERE timed BETWEEN vDatedFromYesterday AND vDatedToTomorrow + AND isReal + GROUP BY userFk, dated + )sub ON sub.dated = tw.dated + AND sub.userFk = tw.userFk + WHERE tw.dated BETWEEN vDatedFrom AND vDatedTo; - DROP TEMPORARY TABLE tmp.workerBreakDays; DROP TEMPORARY TABLE tmp.timeControlError; - DROP TEMPORARY TABLE tmp.workerTimeControlAux; - DROP TEMPORARY TABLE tmp.workerTimeControlAux2; + DROP TEMPORARY TABLE tmp.wtcToinsert; DROP TEMPORARY TABLE tmp.workerTimeControl; END ;; DELIMITER ; @@ -73958,19 +75053,17 @@ BEGIN * @param vDatedFrom workerTimeControl * @param vDatedTo workerTimeControl */ + DROP TEMPORARY TABLE IF EXISTS tmp.`user`; - DROP TEMPORARY TABLE IF EXISTS tmp.`user`; - - CREATE TEMPORARY TABLE tmp.`user` + CREATE TEMPORARY TABLE tmp.`user` SELECT u.id userFk FROM account.user u - JOIN vn.worker w ON w.userFk = u.id - WHERE w.id = vWorkerFk; + JOIN vn.worker w ON w.id = u.id + WHERE w.id = vWorkerFk; - CALL vn.timeControl_calculate(vDatedFrom, vDatedTo); - - DROP TEMPORARY TABLE tmp.`user`; + CALL vn.timeControl_calculate(vDatedFrom, vDatedTo); + DROP TEMPORARY TABLE tmp.`user`; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -74121,14 +75214,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `travelVolume` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `travelVolume`(vTravelFk INT) BEGIN @@ -74142,9 +75235,9 @@ BEGIN e.id Id_Entrada, e.invoiceNumber Referencia, CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * - vn.item_getVolume(b.itemFk ,b.packageFk)) / vc.trolleyM3 / 1000000 ,1) AS DECIMAL(10,2)) AS CC, + vn.item_getVolume(b.itemFk ,b.packagingFk)) / vc.trolleyM3 / 1000000 ,1) AS DECIMAL(10,2)) AS CC, CAST(ROUND(SUM(GREATEST(b.stickers ,b.quantity /b.packing ) * - vn.item_getVolume(b.itemFk ,b.packageFk)) / vc.palletM3 / 1000000,1) AS DECIMAL(10,2)) AS espais + vn.item_getVolume(b.itemFk ,b.packagingFk)) / vc.palletM3 / 1000000,1) AS DECIMAL(10,2)) AS espais FROM vn.buy b JOIN vn.entry e ON e.id = b.entryFk JOIN vn.supplier s ON s.id = e.supplierFk @@ -74164,21 +75257,21 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `travelVolume_get` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `travelVolume_get`(vFromDated DATE, vToDated DATE, vWarehouseFk INT) BEGIN SELECT tr.landed Fecha, a.name Agencia, count(DISTINCT e.id) numEntradas, - FLOOR(sum(item_getVolume(b.itemFk, b.packageFk) * b.stickers / 1000000 )) AS m3 + FLOOR(sum(item_getVolume(b.itemFk, b.packagingFk) * b.stickers / 1000000 )) AS m3 FROM vn.travel tr JOIN vn.agencyMode a ON a.id = tr.agencyModeFk JOIN vn.entry e ON e.travelFk = tr.id @@ -74452,52 +75545,46 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `travel_doRecalc` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb3 */ ; -/*!50003 SET character_set_results = utf8mb3 */ ; -/*!50003 SET collation_connection = utf8mb3_general_ci */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `travel_doRecalc`() -BEGIN +proc: BEGIN /** - * Recounts the number of entries of changed travels. - */ - DECLARE vDone BOOL; +* Recounts the number of entries of changed travels. +*/ DECLARE vTravelFk INT; - DECLARE vTotalEntries INT; - DECLARE cCur CURSOR FOR + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + DO RELEASE_LOCK('vn.ticket_doRecalc'); + END; + + IF !GET_LOCK('vn.travel_doRecalc', 0) THEN + LEAVE proc; + END IF; + + CREATE OR REPLACE TEMPORARY TABLE tTravel + ENGINE = MEMORY SELECT travelFk FROM travelRecalc; - DECLARE CONTINUE HANDLER FOR NOT FOUND - SET vDone = TRUE; + UPDATE travel t + JOIN tTravel tt ON tt.travelFk = t.id + SET t.totalEntries = ( + SELECT COUNT(e.id) + FROM entry e + WHERE e.travelFk = t.id + ); - OPEN cCur; - - myLoop: LOOP - SET vDone = FALSE; - FETCH cCur INTO vTravelFk; - - IF vDone THEN - LEAVE myLoop; - END IF; - - SELECT COUNT(*) INTO vTotalEntries - FROM entry - WHERE travelFk = vTravelFk; - - UPDATE travel - SET totalEntries = vTotalEntries - WHERE id = vTravelFk; - - DELETE FROM travelRecalc WHERE travelFk = vTravelFk; - END LOOP; - - CLOSE cCur; + DELETE tr FROM travelRecalc tr JOIN tTravel t ON tr.travelFk = t.travelFk; + DROP TEMPORARY TABLE tTravel; + DO RELEASE_LOCK('vn.travel_doRecalc'); END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -74505,14 +75592,14 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `travel_getEntriesMissingPackage` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `travel_getEntriesMissingPackage`(vSelf INT) BEGIN @@ -74528,7 +75615,7 @@ BEGIN JOIN entry e ON e.travelFk = t.id JOIN buy b ON b.entryFk = e.id WHERE t.id = vTravelFk - AND (b.packing IS NULL OR b.packageFk IS NULL); + AND (b.packing IS NULL OR b.packagingFk IS NULL); END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -75277,38 +76364,6 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `workerCreate` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `workerCreate`( - vFirstname VARCHAR(50), - vLastName VARCHAR(50), - vCode CHAR(3), - vBossFk INT, - vUserFk INT, - vFi VARCHAR(15) , - vBirth DATE -) -BEGIN -/** - * Create new worker - * - */ - INSERT INTO worker(id, code, firstName, lastName, bossFk, fi, birth,userFk) - VALUES (vUserFk, vCode, vFirstname, vLastName, vBossFk, vFi, vBirth,vUserFk); -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 */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `workerCreateExternal` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -76422,41 +77477,44 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `workerTimeControl_clockIn` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `workerTimeControl_clockIn`( - vWorker INT, + vWorkerFk INT, vTimed DATETIME, - vDirection VARCHAR(10)) + vDirection VARCHAR(10) +) BEGIN /** * Verifica si el empleado puede fichar - * @param vWorker Identificador del trabajador + * @param vWorkerFk Identificador del trabajador * @param vTimed valor de la fichada, IF vTimed IS NULL vTimed = NOW * @param vDirection solo se pueden pasa los valores del campo * workerTimeControl.direction ENUM('in', 'out', 'middle') * @return Si todo es correcto, retorna el número de id la tabla workerTimeControl. - * Si hay algún problema, devuelve el mesaje a que se debe mostrar al usuario + * Si hay algún problema, devuelve el mesaje que se debe mostrar al usuario * Solo retorna el primer problema, en caso de no ocurrir ningún error se añadirá * fichada a la tabla vn.workerTimeControl */ + DECLARE vLastIn DATETIME; DECLARE vLastOut DATETIME; DECLARE vNextIn DATETIME; - DECLARE vLastDirection VARCHAR(6); - DECLARE vNextDirection VARCHAR(6); + DECLARE vNextOut DATETIME; + DECLARE vNextDirection ENUM('in', 'out'); + DECLARE vLastDirection ENUM('in', 'out'); + DECLARE vDayMaxTime INTEGER; DECLARE vDayBreak INT; DECLARE vShortWeekBreak INT; DECLARE vLongWeekBreak INT; DECLARE vWeekScope INT; - DECLARE vGap INT; DECLARE vMailTo VARCHAR(50) DEFAULT NULL; DECLARE vUserName VARCHAR(50) DEFAULT NULL; DECLARE vIsError BOOLEAN DEFAULT FALSE; @@ -76464,79 +77522,40 @@ BEGIN DECLARE vErrorCode VARCHAR(50); DECLARE vDated DATE; DECLARE vIsAllowedToWork VARCHAR(50); - DECLARE vDepartmentFk INT; - DECLARE vTimedLoop BIGINT; - DECLARE vTimedLoopPrevious BIGINT; - DECLARE vHasBreakWeek BOOLEAN DEFAULT FALSE; - DECLARE vManual BOOLEAN DEFAULT TRUE; - DECLARE vDone INT DEFAULT FALSE; - - DECLARE vCursor CURSOR FOR - SELECT UNIX_TIMESTAMP(vTimed) timed - UNION - SELECT UNIX_TIMESTAMP(timed) - FROM workerTimeControl - WHERE timed BETWEEN (vTimed - INTERVAL vGap SECOND) AND vTimed - AND userFk = vWorker - AND direction IN ('in', 'out') - ORDER BY timed ASC; - - DECLARE vCursor2 CURSOR FOR - SELECT UNIX_TIMESTAMP(vTimed) timed - UNION - SELECT UNIX_TIMESTAMP(timed) - FROM workerTimeControl - WHERE timed BETWEEN vTimed AND (vTimed + INTERVAL vGap SECOND) - AND userFk = vWorker - AND direction IN ('in', 'out') - ORDER BY timed ASC; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + DECLARE vIsManual BOOLEAN DEFAULT TRUE; + DECLARE vMaxWorkShortCycle INT; + DECLARE vMaxWorkLongCycle INT; DECLARE EXIT HANDLER FOR SQLSTATE '45000' BEGIN - SELECT CONCAT(u.name, '@verdnatura.es'), + SELECT CONCAT(u.name, '@verdnatura.es'), CONCAT(w.firstName, ' ', w.lastName) INTO vMailTo, vUserName FROM account.user u JOIN worker w ON w.bossFk = u.id - WHERE w.id = vWorker; + WHERE w.id = vWorkerFk; - CASE vErrorCode - WHEN 'IS_NOT_ALLOWED_FUTURE' THEN - SELECT 'No se permite fichar a futuro' INTO vErrorMessage; - WHEN 'INACTIVE_BUSINESS' THEN - SELECT 'No hay un contrato en vigor' INTO vErrorMessage; - WHEN 'IS_NOT_ALLOWED_WORK' THEN - SELECT 'No está permitido trabajar' INTO vErrorMessage; - WHEN 'ODD_WORKERTIMECONTROL' THEN - SELECT 'Fichadas impares' INTO vErrorMessage; - WHEN 'BREAK_DAY' THEN - SELECT CONCAT('Descanso diario ', FORMAT(vDayBreak/3600, 0), 'h.') - INTO vErrorMessage; - WHEN 'BREAK_WEEK' THEN - SELECT CONCAT('Descanso semanal ', - FORMAT(vShortWeekBreak / 3600,0) ,'h. / ', - FORMAT(vLongWeekBreak / 3600, 0) ,'h.') INTO vErrorMessage; - WHEN 'WRONG_DIRECTION' THEN - SELECT 'Dirección incorrecta' INTO vErrorMessage; - ELSE - SELECT 'Error sin definir'INTO vErrorMessage; - END CASE; + SELECT `description` INTO vErrorMessage + FROM workerTimeControlError + WHERE `code` = vErrorCode; + + IF vErrorMessage IS NULL THEN + SET vErrorMessage = 'Error sin definir'; + END IF; SELECT vErrorMessage `error`; SELECT CONCAT(vUserName, ' no ha podido fichar por el siguiente problema: ', vErrorMessage) INTO vErrorMessage; - CALL mail_insert( vMailTo, vMailTo, 'Error al fichar', vErrorMessage); + CALL mail_insert( vMailTo, vMailTo, 'Error al fichar', vErrorMessage); END; IF (vTimed IS NULL) THEN SET vTimed = util.VN_NOW(); - SET vManual = FALSE; + SET vIsManual = FALSE; END IF; SET vDated = DATE(vTimed); @@ -76546,70 +77565,38 @@ BEGIN wc.dayBreak), wc.shortWeekBreak, wc.longWeekBreak, - wc.weekScope + wc.weekScope, + wc.dayMaxTime, + wc.maxWorkShortCycle, + wc.maxWorkLongCycle INTO vDayBreak, vShortWeekBreak, vLongWeekBreak, - vWeekScope + vWeekScope, + vDayMaxTime, + vMaxWorkShortCycle, + vMaxWorkLongCycle FROM business b JOIN professionalCategory pc ON pc.id = b.workerBusinessProfessionalCategoryFk - JOIN workerTimeControlConfig wc ON TRUE - WHERE b.workerFk = vWorker + JOIN workerTimeControlConfig wc + WHERE b.workerFk = vWorkerFk AND vDated BETWEEN b.started AND IFNULL(b.ended, vDated); - SELECT timed INTO vLastIn - FROM workerTimeControl - WHERE userFk = vWorker - AND direction = 'in' - AND timed < vTimed - ORDER BY timed DESC - LIMIT 1; - - SELECT timed INTO vLastOut - FROM workerTimeControl - WHERE userFk = vWorker - AND direction = 'out' - AND timed < vTimed - ORDER BY timed DESC - LIMIT 1; - - SELECT timed INTO vNextIn - FROM workerTimeControl - WHERE userFk = vWorker - AND direction = 'in' - AND timed > vTimed - ORDER BY timed ASC - LIMIT 1; - - SELECT direction INTO vNextDirection - FROM workerTimeControl - WHERE userFk = vWorker - AND timed > vTimed - ORDER BY timed ASC - LIMIT 1; - - SELECT direction INTO vLastDirection - FROM workerTimeControl - WHERE userFk = vWorker - AND timed < vTimed - ORDER BY timed DESC - LIMIT 1; - - -- FICHADAS A FUTURO - IF vTimed > DATE_ADD(util.VN_NOW(), INTERVAL 60 SECOND) THEN - SET vErrorCode = 'IS_NOT_ALLOWED_FUTURE'; - CALL util.throw(vErrorCode); - END IF; - -- CONTRATO EN VIGOR IF vDayBreak IS NULL THEN SET vErrorCode = 'INACTIVE_BUSINESS'; CALL util.throw(vErrorCode); END IF; + -- FICHADAS A FUTURO + IF vTimed > util.VN_NOW() + INTERVAL 1 MINUTE THEN + SET vErrorCode = 'IS_NOT_ALLOWED_FUTURE'; + CALL util.throw(vErrorCode); + END IF; + -- VERIFICAR SI ESTÁ PERMITIDO TRABAJAR - CALL timeBusiness_calculateByWorker(vWorker, vDated, vDated); + CALL timeBusiness_calculateByWorker(vWorkerFk, vDated, vDated); SELECT isAllowedToWork INTO vIsAllowedToWork FROM tmp.timeBusinessCalculate; DROP TEMPORARY TABLE tmp.timeBusinessCalculate; @@ -76620,7 +77607,7 @@ BEGIN END IF; -- DIRECCION CORRECTA - CALL workerTimeControl_direction(vWorker, vTimed); + CALL workerTimeControl_direction(vWorkerFk, vTimed); IF (SELECT IF(IF(option1 IN ('inMiddle', 'outMiddle'), 'middle', @@ -76636,17 +77623,25 @@ BEGIN END IF; DROP TEMPORARY TABLE tmp.workerTimeControlDirection; - IF vIsError = TRUE THEN + IF vIsError THEN SET vErrorCode = 'WRONG_DIRECTION'; CALL util.throw(vErrorCode); END IF; -- FICHADAS IMPARES + SELECT timed INTO vLastIn + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction = 'in' + AND timed < vTimed + ORDER BY timed DESC + LIMIT 1; + IF (SELECT IF(vDirection = 'in', MOD(COUNT(*), 2) , IF (vDirection = 'out', NOT MOD(COUNT(*), 2), FALSE)) FROM workerTimeControl - WHERE userFk = vWorker + WHERE userFk = vWorkerFk AND timed BETWEEN vLastIn AND vTimed ) THEN SET vErrorCode = 'ODD_WORKERTIMECONTROL'; @@ -76654,6 +77649,22 @@ BEGIN END IF; -- DESCANSO DIARIO + SELECT timed INTO vLastOut + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction = 'out' + AND timed < vTimed + ORDER BY timed DESC + LIMIT 1; + + SELECT timed INTO vNextIn + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction = 'in' + AND timed > vTimed + ORDER BY timed ASC + LIMIT 1; + CASE vDirection WHEN 'in' THEN IF UNIX_TIMESTAMP(vTimed) - UNIX_TIMESTAMP(vLastOut) <= vDayBreak THEN @@ -76671,94 +77682,93 @@ BEGIN CALL util.throw(vErrorCode); END IF; - -- VERIFICAR DESCANSO SEMANAL + + IF (vDirection IN('in', 'out')) THEN - -- VERIFICA DESCANSO CORTO EN LA ÚLTIMA SEMANA - SET vGap = vWeekScope; - SET vTimedLoopPrevious = UNIX_TIMESTAMP((vTimed - INTERVAL vGap SECOND)); - SET vDone = FALSE; - OPEN vCursor; - l:LOOP - FETCH vCursor INTO vTimedLoop; - IF vDone THEN - LEAVE l; - END IF; - IF vShortWeekBreak - (vTimedLoop - vTimedLoopPrevious) <= 0 THEN - SET vHasBreakWeek = TRUE; - LEAVE l; - END IF; - SET vTimedLoopPrevious = vTimedLoop; - END LOOP l; - CLOSE vCursor; - -- VERIFICA DESCANSO LARGO EN LA ÚLTIMAS 2 SEMANAS - IF NOT vHasBreakWeek THEN - SET vGap = vWeekScope * 2; - SET vTimedLoopPrevious = UNIX_TIMESTAMP(vTimed - INTERVAL vGap SECOND); - SET vDone = FALSE; - OPEN vCursor; - l:LOOP - FETCH vCursor INTO vTimedLoop; - IF vDone THEN - LEAVE l; - END IF; - IF vLongWeekBreak - (vTimedLoop - vTimedLoopPrevious) <= 0 THEN - SET vHasBreakWeek = TRUE; - LEAVE l; - END IF; - SET vTimedLoopPrevious = vTimedLoop; - END LOOP l; - CLOSE vCursor; + -- VERIFICA MAXIMO TIEMPO DESDE ENTRADA HASTA LA SALIDA + + SELECT timed INTO vNextOut + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction = 'out' + AND timed > vTimed + ORDER BY timed ASC + LIMIT 1; + + SELECT direction INTO vNextDirection + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction IN('in','out') + AND timed > vTimed + ORDER BY timed ASC + LIMIT 1; + + SELECT direction INTO vLastDirection + FROM workerTimeControl + WHERE userFk = vWorkerFk + AND direction IN('in', 'out') + AND timed < vTimed + ORDER BY timed ASC + LIMIT 1; + + IF (vDirection ='in' + AND vNextDirection = 'out' + AND UNIX_TIMESTAMP(vNextOut) - UNIX_TIMESTAMP(vTimed) > vDayMaxTime) OR + (vDirection ='out' + AND vLastDirection = 'in' + AND UNIX_TIMESTAMP(vTimed) -UNIX_TIMESTAMP(vLastIn) > vDayMaxTime) THEN + SET vErrorCode = 'DAY_MAX_TIME'; + CALL util.throw(vErrorCode); END IF; - IF vManual THEN - -- VERIFICA DESCANSO CORTO EN LA PRÓXIMA SEMANA - SET vGap = vWeekScope; - SET vTimedLoopPrevious = vTimed; - SET vDone = FALSE; - OPEN vCursor2; - l:LOOP - FETCH vCursor2 INTO vTimedLoop; - IF vDone THEN - LEAVE l; - END IF; - IF vShortWeekBreak - (vTimedLoop - vTimedLoopPrevious) <= 0 THEN - SET vHasBreakWeek = TRUE; - LEAVE l; - END IF; - SET vTimedLoopPrevious = vTimedLoop; - END LOOP l; - CLOSE vCursor2; - -- VERIFICA DESCANSO LARGO EN LAS PRÓXIMAS 2 SEMANAS - IF NOT vHasBreakWeek THEN - SET vGap = vWeekScope * 2; - SET vTimedLoopPrevious = vTimed; - SET vDone = FALSE; - OPEN vCursor2; - l:LOOP - FETCH vCursor2 INTO vTimedLoop; - IF vDone THEN - LEAVE l; - END IF; - IF vShortWeekBreak - (vTimedLoop - vTimedLoopPrevious) <= 0 THEN - SET vHasBreakWeek = TRUE; - LEAVE l; - END IF; - SET vTimedLoopPrevious = vTimedLoop; - END LOOP l; - CLOSE vCursor2; - END IF; - END IF; - IF NOT vHasBreakWeek THEN + -- VERIFICA DESCANSO SEMANAL + + WITH wtc AS( + (SELECT timed + FROM vn.workerTimeControl + WHERE userFk = vWorkerFk + AND direction IN ('in', 'out') + AND timed BETWEEN vTimed - INTERVAL (vWeekScope * 2) SECOND + AND vTimed + INTERVAL (vWeekScope * 2) SECOND ) + UNION + (SELECT vTimed) + ), wtcGap AS( + SELECT timed, + TIMESTAMPDIFF(SECOND, LAG(timed) OVER (ORDER BY timed), timed) gap + FROM wtc + ORDER BY timed + ), wtcBreak AS( + SELECT timed, + IF(IFNULL(gap, 0) > vShortWeekBreak, TRUE, FALSE) hasShortBreak, + IF(IFNULL(gap, 0) > vLongWeekBreak, TRUE, FALSE) hasLongBreak + FROM wtcGap + ORDER BY timed + ), wtcBreakCounter AS( + SELECT timed, + SUM(hasShortBreak) OVER (ORDER BY timed) breakCounter , + LEAD(hasLongBreak) OVER (ORDER BY timed) nextHasLongBreak + FROM wtcBreak + )SELECT TIMESTAMPDIFF(SECOND, MIN(timed), MAX(timed)) > vMaxWorkLongCycle OR + (TIMESTAMPDIFF(SECOND, MIN(timed), MAX(timed))> vMaxWorkShortCycle + AND NOT SUM(IFNULL(nextHasLongBreak, 1))) + hasError INTO vIsError + FROM wtcBreakCounter + GROUP BY breakCounter + HAVING hasError + LIMIT 1; + + IF vIsError THEN SET vErrorCode = 'BREAK_WEEK'; CALL util.throw(vErrorCode); END IF; END IF; -- SE PERMITE FICHAR - INSERT INTO workerTimeControl(userFk, timed, direction, manual) - VALUES(vWorker, vTimed, vDirection, vManual); + INSERT INTO workerTimeControl(userFk, timed, direction, `manual`) + VALUES(vWorkerFk, vTimed, vDirection, vIsManual); SELECT LAST_INSERT_ID() id; + END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -77628,15 +78638,28 @@ DELIMITER ;; CREATE DEFINER=`root`@`localhost` PROCEDURE `worker_updateBusiness`(vSelf INT) BEGIN /** - * Actualiza en la tabla @worker el contrato actual del trabajador. + * Activates an account and configures its email settings. * - * @param vSelf Id del trabajador + * @param vSelf account id. */ - UPDATE worker w - LEFT JOIN business b ON b.workerFk = w.id - AND util.VN_CURDATE() BETWEEN b.started AND IFNULL(b.ended, util.VN_CURDATE()) - SET w.businessFk = b.id - WHERE w.id = vSelf; + DECLARE vOldBusinessFk INT; + DECLARE vNewBusinessFk INT; + + SELECT businessFk INTO vOldBusinessFk FROM worker WHERE id = vSelf; + + SELECT id INTO vNewBusinessFk + FROM business + WHERE workerFk = vSelf + AND util.VN_CURDATE() BETWEEN started AND IFNULL(ended, util.VN_CURDATE()) + LIMIT 1; + + UPDATE worker + SET businessFk = vNewBusinessFk + WHERE id = vSelf; + + IF vOldBusinessFk IS NULL THEN + CALL account.account_enable(vSelf); + END IF; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -78204,6 +79227,74 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `zone_getAddresses` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `zone_getAddresses`( + vSelf INT, + vLanded DATE +) +BEGIN +/** + * Devuelve un listado de todos los clientes activos + * con consignatarios a los que se les puede + * vender producto para esa zona y no tiene un ticket + * para ese día. + * + * @param vSelf Id de zona + * @param vDated Fecha de entrega + * @return Un select + */ + CALL zone_getPostalCode(vSelf); + + WITH notHasTicket AS ( + SELECT id + FROM vn.client + WHERE id NOT IN ( + SELECT clientFk + FROM vn.ticket + WHERE landed BETWEEN vLanded AND util.dayEnd(vLanded) + ) + ) + SELECT c.id clientFk, + c.name, + c.phone, + c.mobile, + c.salesPersonFk, + u.name username, + aai.invoiced, + cnb.lastShipped + FROM vn.client c + JOIN notHasTicket ON notHasTicket.id = c.id + LEFT JOIN account.`user` u ON u.id = c.salesPersonFk + JOIN vn.`address` a ON a.clientFk = c.id + JOIN vn.postCode pc ON pc.code = a.postalCode + JOIN vn.town t ON t.id = pc.townFk AND t.provinceFk = a.provinceFk + JOIN vn.zoneGeo zg ON zg.name = a.postalCode + JOIN tmp.zoneNodes zn ON zn.geoFk = pc.geoFk + LEFT JOIN bs.clientNewBorn cnb ON cnb.clientFk = c.id + LEFT JOIN vn.annualAverageInvoiced aai ON aai.clientFk = c.id + JOIN vn.clientType ct ON ct.code = c.typeFk + WHERE a.isActive + AND c.isActive + AND ct.code = 'normal' + AND c.businessTypeFk <> 'worker' + GROUP BY c.id; + + DROP TEMPORARY TABLE tmp.zoneNodes; +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 */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP PROCEDURE IF EXISTS `zone_getAgency` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -78986,8 +80077,7 @@ BEGIN */ DECLARE vGeoFk INT DEFAULT NULL; - DROP TEMPORARY TABLE IF EXISTS tmp.zoneNodes; - CREATE TEMPORARY TABLE tmp.zoneNodes ( + CREATE OR REPLACE TEMPORARY TABLE tmp.zoneNodes ( geoFk INT, name VARCHAR(100), parentFk INT, @@ -79000,14 +80090,14 @@ BEGIN CALL zone_getLeaves(vSelf, NULL , NULL, TRUE); - UPDATE tmp.zoneNodes zn + UPDATE tmp.zoneNodes SET isChecked = 0 WHERE parentFk IS NULL; myLoop: LOOP SET vGeoFk = NULL; SELECT geoFk INTO vGeoFk - FROM tmp.zoneNodes zn + FROM tmp.zoneNodes WHERE NOT isChecked LIMIT 1; @@ -79023,10 +80113,6 @@ BEGIN DELETE FROM tmp.zoneNodes WHERE sons > 0; - - SELECT zn.geoFk, zn.name - FROM tmp.zoneNodes zn - JOIN zone z ON z.id = zn.zoneFk; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -79997,7 +81083,7 @@ USE `pbx`; /*!50001 SET collation_connection = utf8mb4_unicode_ci */; /*!50001 CREATE ALGORITHM=UNDEFINED */ /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ -/*!50001 VIEW `sipConf` AS select `s`.`user_id` AS `id`,`s`.`extension` AS `name`,NULL AS `callbackextension`,`s`.`md5Secret` AS `md5secret`,`u`.`nickname` AS `callerid`,`c`.`host` AS `host`,`c`.`deny` AS `deny`,`c`.`permit` AS `permit`,`c`.`type` AS `type`,`c`.`context` AS `context`,`c`.`incomingLimit` AS `incominglimit`,`c`.`pickupGroup` AS `pickupgroup`,`c`.`careInvite` AS `careinvite`,`c`.`insecure` AS `insecure`,`c`.`transport` AS `transport`,`c`.`nat` AS `nat`,`r`.`ipAddr` AS `ipaddr`,`r`.`regSeconds` AS `regseconds`,`r`.`port` AS `port`,`r`.`defaultUser` AS `defaultuser`,`r`.`userAgent` AS `useragent`,`r`.`lastMs` AS `lastms`,`r`.`fullContact` AS `fullcontact`,`r`.`regServer` AS `regserver` from (((`pbx`.`sip` `s` join `account`.`user` `u` on(`u`.`id` = `s`.`user_id`)) left join `pbx`.`sipReg` `r` on(`s`.`user_id` = `r`.`userId`)) join `pbx`.`sipConfig` `c`) */; +/*!50001 VIEW `sipConf` AS select `s`.`user_id` AS `id`,`s`.`extension` AS `name`,`s`.`extension` AS `regexten`,NULL AS `callbackextension`,`s`.`md5Secret` AS `md5secret`,`u`.`nickname` AS `callerid`,`c`.`host` AS `host`,`c`.`deny` AS `deny`,`c`.`permit` AS `permit`,`c`.`type` AS `type`,`c`.`context` AS `context`,`c`.`incomingLimit` AS `incominglimit`,`c`.`pickupGroup` AS `pickupgroup`,`c`.`directMedia` AS `directmedia`,`c`.`insecure` AS `insecure`,`c`.`transport` AS `transport`,`c`.`nat` AS `nat`,`c`.`disallow` AS `disallow`,`c`.`allow` AS `allow`,`r`.`ipAddr` AS `ipaddr`,`r`.`regSeconds` AS `regseconds`,`r`.`port` AS `port`,`r`.`defaultUser` AS `defaultuser`,`r`.`userAgent` AS `useragent`,`r`.`lastMs` AS `lastms`,`r`.`fullContact` AS `fullcontact`,`r`.`regServer` AS `regserver` from (((`pbx`.`sip` `s` join `account`.`user` `u` on(`u`.`id` = `s`.`user_id`)) left join `pbx`.`sipReg` `r` on(`s`.`user_id` = `r`.`userId`)) join `pbx`.`sipConfig` `c`) */; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; @@ -80238,12 +81324,12 @@ USE `vn`; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; -/*!50001 SET character_set_client = utf8mb4 */; -/*!50001 SET character_set_results = utf8mb4 */; -/*!50001 SET collation_connection = utf8mb4_unicode_ci */; +/*!50001 SET character_set_client = utf8mb3 */; +/*!50001 SET character_set_results = utf8mb3 */; +/*!50001 SET collation_connection = utf8mb3_general_ci */; /*!50001 CREATE ALGORITHM=UNDEFINED */ /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ -/*!50001 VIEW `awbVolume` AS select `d`.`awbFk` AS `awbFk`,`b`.`stickers` * `i`.`density` * if(`p`.`volume` > 0,`p`.`volume`,`p`.`width` * `p`.`depth` * if(`p`.`height` = 0,`i`.`size` + 10,`p`.`height`)) / (`vc`.`aerealVolumetricDensity` * 1000) AS `volume`,`b`.`id` AS `buyFk` from ((((((((`buy` `b` join `item` `i` on(`b`.`itemFk` = `i`.`id`)) join `itemType` `it` on(`i`.`typeFk` = `it`.`id`)) join `packaging` `p` on(`p`.`id` = `b`.`packageFk`)) join `entry` `e` on(`b`.`entryFk` = `e`.`id`)) join `travel` `t` on(`t`.`id` = `e`.`travelFk`)) join `duaEntry` `de` on(`de`.`entryFk` = `e`.`id`)) join `dua` `d` on(`d`.`id` = `de`.`duaFk`)) join `volumeConfig` `vc`) where `t`.`shipped` > makedate(year(`util`.`VN_CURDATE`()) - 1,1) */; +/*!50001 VIEW `awbVolume` AS select `d`.`awbFk` AS `awbFk`,`b`.`stickers` * `i`.`density` * if(`p`.`volume` > 0,`p`.`volume`,`p`.`width` * `p`.`depth` * if(`p`.`height` = 0,`i`.`size` + 10,`p`.`height`)) / (`vc`.`aerealVolumetricDensity` * 1000) AS `volume`,`b`.`id` AS `buyFk` from ((((((((`buy` `b` join `item` `i` on(`b`.`itemFk` = `i`.`id`)) join `itemType` `it` on(`i`.`typeFk` = `it`.`id`)) join `packaging` `p` on(`p`.`id` = `b`.`packagingFk`)) join `entry` `e` on(`b`.`entryFk` = `e`.`id`)) join `travel` `t` on(`t`.`id` = `e`.`travelFk`)) join `duaEntry` `de` on(`de`.`entryFk` = `e`.`id`)) join `dua` `d` on(`d`.`id` = `de`.`duaFk`)) join `volumeConfig` `vc`) where `t`.`shipped` > makedate(year(`util`.`VN_CURDATE`()) - 1,1) */; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; @@ -80374,24 +81460,6 @@ USE `vn`; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; --- --- Final view structure for view `cmr_list` --- - -/*!50001 DROP VIEW IF EXISTS `cmr_list`*/; -/*!50001 SET @saved_cs_client = @@character_set_client */; -/*!50001 SET @saved_cs_results = @@character_set_results */; -/*!50001 SET @saved_col_connection = @@collation_connection */; -/*!50001 SET character_set_client = utf8mb4 */; -/*!50001 SET character_set_results = utf8mb4 */; -/*!50001 SET collation_connection = utf8mb4_unicode_ci */; -/*!50001 CREATE ALGORITHM=UNDEFINED */ -/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ -/*!50001 VIEW `cmr_list` AS select `cmr`.`id` AS `cmrFk`,`cmr`.`ticketFk` AS `ticketFk`,`cmr`.`truckPlate` AS `truckPlate`,`cmr`.`observations` AS `observations`,`cmr`.`senderInstruccions` AS `senderInstruccions`,`cmr`.`paymentInstruccions` AS `paymentInstruccions`,`cmr`.`specialAgreements` AS `specialAgreements`,`cmr`.`created` AS `created`,`cmr`.`packagesList` AS `packagesList`,`aTo`.`nickname` AS `clientName`,`aTo`.`postalCode` AS `clientPostalCode`,`aTo`.`street` AS `clientStreet`,`aTo`.`city` AS `clientCity`,`pTo`.`name` AS `clientProvince`,`cTo`.`country` AS `clientCountry`,`su`.`name` AS `companyName`,`su`.`street` AS `companyStreet`,`su`.`postCode` AS `companyPostCode`,`su`.`city` AS `companyCity`,`cSu`.`country` AS `companyCountry`,concat(`aFrom`.`street`,' ',`aFrom`.`postalCode`,' ',`aFrom`.`city`,' (',`cFrom`.`country`,')') AS `warehouseAddress`,`cmr`.`created` AS `shipped`,`aTo`.`nickname` AS `clientOficialName`,`cmr`.`supplierFk` AS `supplierFk`,`aSu`.`name` AS `carrierName`,`aSu`.`street` AS `carrierStreet`,`aSu`.`postCode` AS `carrierPostCode`,`aSu`.`city` AS `carrierCity`,`cAs`.`country` AS `carrierCountry`,ifnull(`aTo`.`phone`,`client`.`phone`) AS `phone`,ifnull(`aTo`.`mobile`,`client`.`mobile`) AS `mobile`,`aTo`.`id` AS `addressFk`,`c`.`stamp` AS `stamp`,`cmr`.`merchandiseDetail` AS `merchandiseDetail` from ((((((((((((`cmr` left join `address` `aTo` on(`aTo`.`id` = `cmr`.`addressToFk`)) left join `province` `pTo` on(`pTo`.`id` = `aTo`.`provinceFk`)) left join `country` `cTo` on(`cTo`.`id` = `pTo`.`countryFk`)) left join `client` on(`client`.`id` = `aTo`.`clientFk`)) left join `supplier` `su` on(`su`.`id` = `cmr`.`companyFk`)) left join `country` `cSu` on(`cSu`.`id` = `su`.`countryFk`)) left join `address` `aFrom` on(`aFrom`.`id` = `cmr`.`addressFromFk`)) left join `province` `pFrom` on(`pFrom`.`id` = `aFrom`.`provinceFk`)) left join `country` `cFrom` on(`cFrom`.`id` = `pFrom`.`countryFk`)) left join `supplier` `aSu` on(`aSu`.`id` = `cmr`.`supplierFk`)) left join `country` `cAs` on(`cAs`.`id` = `aSu`.`countryFk`)) join `company` `c` on(`c`.`id` = `cmr`.`companyFk`)) */; -/*!50001 SET character_set_client = @saved_cs_client */; -/*!50001 SET character_set_results = @saved_cs_results */; -/*!50001 SET collation_connection = @saved_col_connection */; - -- -- Final view structure for view `companyL10n` -- @@ -81490,24 +82558,6 @@ USE `vn`; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; --- --- Final view structure for view `routesReduced` --- - -/*!50001 DROP VIEW IF EXISTS `routesReduced`*/; -/*!50001 SET @saved_cs_client = @@character_set_client */; -/*!50001 SET @saved_cs_results = @@character_set_results */; -/*!50001 SET @saved_col_connection = @@collation_connection */; -/*!50001 SET character_set_client = utf8mb4 */; -/*!50001 SET character_set_results = utf8mb4 */; -/*!50001 SET collation_connection = utf8mb4_unicode_ci */; -/*!50001 CREATE ALGORITHM=UNDEFINED */ -/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ -/*!50001 VIEW `routesReduced` AS select `et`.`description` AS `description`,`rm`.`name` AS `name`,`t`.`routeFk` AS `routeFk`,`et`.`eta` AS `eta`,`rm`.`bufferFk` AS `bufferFk`,`rm`.`beachFk` AS `beachFk`,`i`.`itemPackingTypeFk` AS `itempackingTypeFk` from (((((((`expeditionTruck` `et` join `routesMonitor` `rm` on(`rm`.`expeditionTruckFk` = `et`.`id`)) join `ticket` `t` on(`t`.`routeFk` = `rm`.`routeFk`)) join `ticketState` `ts` on(`ts`.`ticketFk` = `t`.`id`)) join `state` `st` on(`st`.`id` = `ts`.`stateFk`)) join `sale` `s` on(`s`.`ticketFk` = `t`.`id`)) join `item` `i` on(`i`.`id` = `s`.`itemFk`)) join `config` `c`) where `et`.`eta` > `util`.`yesterday`() group by `t`.`routeFk` order by `et`.`eta`,`t`.`routeFk` */; -/*!50001 SET character_set_client = @saved_cs_client */; -/*!50001 SET character_set_results = @saved_cs_results */; -/*!50001 SET collation_connection = @saved_col_connection */; - -- -- Final view structure for view `saleCost` -- @@ -82165,4 +83215,4 @@ USE `vn`; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2023-08-30 15:59:19 +-- Dump completed on 2023-11-20 10:10:52 diff --git a/db/export-data.sh b/db/export-data.sh index a516992d34..97092da4f6 100755 --- a/db/export-data.sh +++ b/db/export-data.sh @@ -45,12 +45,12 @@ TABLES=( alertLevel bookingPlanner businessType - cplusInvoiceType472 + siiTypeInvoiceIn siiTypeInvoiceOut cplusRectificationType cplusSubjectOp cplusTaxBreak - cplusTrascendency472 + siiTrascendencyInvoiceIn claimResponsible claimReason claimRedelivery @@ -68,6 +68,8 @@ TABLES=( volumeConfig workCenter companyI18n + workerTimeControlError + silexACL ) dump_tables ${TABLES[@]} diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 9491364591..ed6aa474f1 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -197,5 +197,7 @@ "Booking completed": "Booking complete", "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation", "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets", - "Try again": "Try again" -} + "Try again": "Try again", + "keepPrice": "keepPrice", + "Cannot past travels with entries": "Cannot past travels with entries" +} \ No newline at end of file diff --git a/modules/client/back/methods/client/filter.js b/modules/client/back/methods/client/filter.js index eaf4ecf308..47d5f6d2f5 100644 --- a/modules/client/back/methods/client/filter.js +++ b/modules/client/back/methods/client/filter.js @@ -82,12 +82,15 @@ module.exports = Self => { if (args.zoneFk) { let stmts = []; stmts.push(new ParameterizedSQL('CALL vn.zone_getPostalCode(?)', [args.zoneFk])); - stmts.push(`SELECT name FROM tmp.zoneNodes`); + stmts.push(` + SELECT zn.geoFk, zn.name + FROM tmp.zoneNodes zn + JOIN zone z ON z.id = zn.zoneFk`); stmts.push(`DROP TEMPORARY TABLE tmp.zoneNodes`); const sql = ParameterizedSQL.join(stmts, ';'); - const [results] = await conn.executeStmt(sql); + const results = await conn.executeStmt(sql); - for (let result of results) + for (let result of results[1]) postalCode.push(result.name); } diff --git a/modules/ticket/back/methods/ticket/specs/getSalespersonMana.spec.js b/modules/ticket/back/methods/ticket/specs/getSalespersonMana.spec.js index 6029ca4a78..12c115ff94 100644 --- a/modules/ticket/back/methods/ticket/specs/getSalespersonMana.spec.js +++ b/modules/ticket/back/methods/ticket/specs/getSalespersonMana.spec.js @@ -9,7 +9,7 @@ describe('ticket getSalesPersonMana()', () => { const mana = await models.Ticket.getSalesPersonMana(1, options); - expect(mana).toEqual(124); + expect(mana).toEqual(73); await tx.rollback(); } catch (e) { From 0a2fd9cf5de1915d897d4a5871f74f74ff988019 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 20 Nov 2023 18:39:37 +0100 Subject: [PATCH 264/449] fix: refs #6432, #5848 account sync fixes --- .../test.js | 4 +- ...ount-synchronizer.js => account-linker.js} | 12 +- modules/account/back/models/account-config.js | 158 ++++++++---------- modules/account/back/models/ldap-config.js | 3 +- modules/account/back/models/ldap-config.json | 2 +- modules/account/back/models/role-config.js | 4 +- modules/account/back/models/role-config.json | 2 +- modules/account/back/models/samba-config.js | 3 +- modules/account/back/models/samba-config.json | 2 +- modules/account/back/models/sip-config.js | 2 +- modules/account/back/models/sip-config.json | 3 +- modules/account/front/descriptor/index.html | 3 +- 12 files changed, 96 insertions(+), 102 deletions(-) rename modules/account/back/methods/{account-synchronizer => account-linker}/test.js (59%) rename modules/account/back/mixins/{account-synchronizer.js => account-linker.js} (85%) diff --git a/modules/account/back/methods/account-synchronizer/test.js b/modules/account/back/methods/account-linker/test.js similarity index 59% rename from modules/account/back/methods/account-synchronizer/test.js rename to modules/account/back/methods/account-linker/test.js index a779401686..990af2df8d 100644 --- a/modules/account/back/methods/account-synchronizer/test.js +++ b/modules/account/back/methods/account-linker/test.js @@ -1,3 +1,4 @@ +const NotFoundError = require('vn-loopback/util/not-found-error'); module.exports = Self => { Self.remoteMethod('test', { @@ -9,7 +10,8 @@ module.exports = Self => { }); Self.test = async function() { - let connector = await Self.getSynchronizer(); + const connector = await Self.getLinker(); + if (!connector) throw new NotFoundError('Linker not configured'); await connector.test(); }; }; diff --git a/modules/account/back/mixins/account-synchronizer.js b/modules/account/back/mixins/account-linker.js similarity index 85% rename from modules/account/back/mixins/account-synchronizer.js rename to modules/account/back/mixins/account-linker.js index 8ba8bfe9d8..c882d0893e 100644 --- a/modules/account/back/mixins/account-synchronizer.js +++ b/modules/account/back/mixins/account-linker.js @@ -3,14 +3,14 @@ const app = require('vn-loopback/server/server'); const UserError = require('vn-loopback/util/user-error'); module.exports = function(Self, options) { - require('../methods/account-synchronizer/test')(Self); + require('../methods/account-linker/test')(Self); Self.once('attached', function() { - app.models.AccountConfig.addSynchronizer(Self); + app.models.AccountConfig.addLinker(Self); }); /** - * Mixin for user synchronizers. + * Mixin for account linkers. * * @property {Array} $ * @property {Object} accountConfig @@ -18,12 +18,12 @@ module.exports = function(Self, options) { */ let Mixin = { /** - * Initalizes the synchronizer. + * Initalizes the linker. */ async init() {}, /** - * Deinitalizes the synchronizer. + * Deinitalizes the linker. */ async deinit() {}, @@ -57,7 +57,7 @@ module.exports = function(Self, options) { async syncRoles() {}, /** - * Tests synchronizer configuration. + * Tests linker configuration. */ async test() { try { diff --git a/modules/account/back/models/account-config.js b/modules/account/back/models/account-config.js index 0db699b99f..2cc6b240dc 100644 --- a/modules/account/back/models/account-config.js +++ b/modules/account/back/models/account-config.js @@ -3,94 +3,85 @@ const models = require('vn-loopback/server/server').models; module.exports = Self => { Object.assign(Self, { - synchronizers: [], + linkers: [], - addSynchronizer(synchronizer) { - this.synchronizers.push(synchronizer); + addLinker(linker) { + this.linkers.push(linker); }, - async getInstance() { - let instance = await Self.findOne({ + async initEngine() { + const accountConfig = await Self.findOne({ fields: ['homedir', 'shell', 'idBase'] }); - await instance.synchronizerInit(); - return instance; + const mailConfig = await models.MailConfig.findOne({ + fields: ['domain'] + }); + + const linkers = []; + + for (const Linker of Self.linkers) { + const linker = await Linker.getLinker(); + if (!linker) continue; + Object.assign(linker, {accountConfig}); + await linker.init(); + linkers.push(linker); + } + + Object.assign(accountConfig, { + linkers, + domain: mailConfig.domain + }); + + return { + accountConfig, + linkers + }; + }, + + async deinitEngine(engine) { + for (const linker of engine.linkers) + await linker.deinit(); + }, + + async syncUser(userName, password) { + const engine = await Self.initEngine(); + try { + await Self.syncUserBase(engine, userName, password, true); + } finally { + await Self.deinitEngine(engine); + } }, async syncUsers() { - let instance = await Self.getInstance(); + const engine = await Self.initEngine(); + + let usersToSync = new Set(); + for (const linker of engine.linkers) + await linker.getUsers(usersToSync); - let usersToSync = await instance.synchronizerGetUsers(); usersToSync = Array.from(usersToSync.values()) .sort((a, b) => a.localeCompare(b)); for (let userName of usersToSync) { try { + // eslint-disable-next-line no-console console.log(`Synchronizing user '${userName}'`); - await instance.synchronizerSyncUser(userName); + + await Self.syncUserBase(engine, userName); + + // eslint-disable-next-line no-console console.log(` -> User '${userName}' sinchronized`); } catch (err) { + // eslint-disable-next-line no-console console.error(` -> User '${userName}' synchronization error:`, err.message); } } - await instance.synchronizerDeinit(); + await Self.deinitEngine(engine); await Self.syncRoles(); }, - async syncUser(userName, password) { - let instance = await Self.getInstance(); - try { - await instance.synchronizerSyncUser(userName, password, true); - } finally { - await instance.synchronizerDeinit(); - } - }, - - async syncRoles() { - let instance = await Self.getInstance(); - try { - await instance.synchronizerSyncRoles(); - } finally { - await instance.synchronizerDeinit(); - } - }, - - async getSynchronizer() { - return await Self.findOne(); - } - }); - - Object.assign(Self.prototype, { - async synchronizerInit() { - let mailConfig = await models.MailConfig.findOne({ - fields: ['domain'] - }); - - let synchronizers = []; - - for (let Synchronizer of Self.synchronizers) { - let synchronizer = await Synchronizer.getSynchronizer(); - if (!synchronizer) continue; - Object.assign(synchronizer, { - accountConfig: this - }); - await synchronizer.init(); - synchronizers.push(synchronizer); - } - - Object.assign(this, { - synchronizers, - domain: mailConfig.domain - }); - }, - - async synchronizerDeinit() { - for (let synchronizer of this.synchronizers) - await synchronizer.deinit(); - }, - - async synchronizerSyncUser(userName, password, syncGroups) { + async syncUserBase(engine, userName, password, syncGroups) { if (!userName) return; userName = userName.toLowerCase(); @@ -98,7 +89,7 @@ module.exports = Self => { if (['administrator', 'root'].indexOf(userName) >= 0) return; - let user = await models.VnUser.findOne({ + const user = await models.VnUser.findOne({ where: {name: userName}, fields: [ 'id', @@ -130,27 +121,28 @@ module.exports = Self => { ] }); - let info = { + const info = { user, hasAccount: false }; if (user) { - let exists = await models.Account.exists(user.id); + const exists = await models.Account.exists(user.id); + const {accountConfig} = engine; Object.assign(info, { hasAccount: user.active && exists, - corporateMail: `${userName}@${this.domain}`, - uidNumber: this.idBase + user.id + corporateMail: `${userName}@${accountConfig.domain}`, + uidNumber: accountConfig.idBase + user.id }); } - let errs = []; + const errs = []; - for (let synchronizer of this.synchronizers) { + for (const linker of engine.linkers) { try { - await synchronizer.syncUser(userName, info, password); + await linker.syncUser(userName, info, password); if (syncGroups) - await synchronizer.syncUserGroups(userName, info); + await linker.syncUserGroups(userName, info); } catch (err) { errs.push(err); } @@ -159,18 +151,16 @@ module.exports = Self => { if (errs.length) throw errs[0]; }, - async synchronizerGetUsers() { - let usersToSync = new Set(); + async syncRoles() { + const engine = await Self.initEngine(); + try { + await Self.rawSql(`CALL account.role_sync`); - for (let synchronizer of this.synchronizers) - await synchronizer.getUsers(usersToSync); - - return usersToSync; - }, - - async synchronizerSyncRoles() { - for (let synchronizer of this.synchronizers) - await synchronizer.syncRoles(); + for (const linker of engine.linkers) + await linker.syncRoles(); + } finally { + await Self.deinitEngine(engine); + } } }); }; diff --git a/modules/account/back/models/ldap-config.js b/modules/account/back/models/ldap-config.js index 9dcc4136d3..b557d243c8 100644 --- a/modules/account/back/models/ldap-config.js +++ b/modules/account/back/models/ldap-config.js @@ -7,7 +7,7 @@ const nthash = require('smbhash').nthash; module.exports = Self => { const shouldSync = process.env.NODE_ENV !== 'test'; - Self.getSynchronizer = async function() { + Self.getLinker = async function() { return await Self.findOne({ fields: [ 'server', @@ -24,6 +24,7 @@ module.exports = Self => { this.client = ldap.createClient({ url: this.server }); + this.client.on('error', () => {}); await this.client.bind(this.rdn, this.password); }, diff --git a/modules/account/back/models/ldap-config.json b/modules/account/back/models/ldap-config.json index 2fd5aa9014..d4d3a094d2 100644 --- a/modules/account/back/models/ldap-config.json +++ b/modules/account/back/models/ldap-config.json @@ -7,7 +7,7 @@ } }, "mixins": { - "AccountSynchronizer": {} + "AccountLinker": {} }, "properties": { "id": { diff --git a/modules/account/back/models/role-config.js b/modules/account/back/models/role-config.js index b90ef75fb6..d6c57b70b5 100644 --- a/modules/account/back/models/role-config.js +++ b/modules/account/back/models/role-config.js @@ -1,6 +1,6 @@ module.exports = Self => { - Self.getSynchronizer = async function() { + Self.getLinker = async function() { let NODE_ENV = process.env.NODE_ENV; if (!NODE_ENV || NODE_ENV == 'development') return null; @@ -45,6 +45,7 @@ module.exports = Self => { } if (!isUpdatable) { + // eslint-disable-next-line no-console console.warn(`RoleConfig.syncUser(): User '${userName}' cannot be updated, not managed by me`); return; } @@ -82,6 +83,7 @@ module.exports = Self => { [mysqlUser, this.userHost]); } catch (err) { if (err.code == 'ER_REVOKE_GRANTS') + // eslint-disable-next-line no-console console.warn(`${err.code}: ${err.sqlMessage}: ${err.sql}`); else throw err; diff --git a/modules/account/back/models/role-config.json b/modules/account/back/models/role-config.json index f4138bea8b..3b843eaea4 100644 --- a/modules/account/back/models/role-config.json +++ b/modules/account/back/models/role-config.json @@ -7,7 +7,7 @@ } }, "mixins": { - "AccountSynchronizer": {} + "AccountLinker": {} }, "properties": { "id": { diff --git a/modules/account/back/models/samba-config.js b/modules/account/back/models/samba-config.js index 7714fb01cc..f5672ca215 100644 --- a/modules/account/back/models/samba-config.js +++ b/modules/account/back/models/samba-config.js @@ -13,7 +13,7 @@ const UserAccountControlFlags = { module.exports = Self => { const shouldSync = process.env.NODE_ENV !== 'test'; - Self.getSynchronizer = async function() { + Self.getLinker = async function() { return await Self.findOne({ fields: [ 'host', @@ -39,6 +39,7 @@ module.exports = Self => { url: `ldaps://${this.adController}:636`, tlsOptions: {rejectUnauthorized: this.verifyCert} }); + adClient.on('error', () => {}); await adClient.bind(bindDn, this.adPassword); Object.assign(this, { adClient, diff --git a/modules/account/back/models/samba-config.json b/modules/account/back/models/samba-config.json index 28cbb26890..4c9e0a794b 100644 --- a/modules/account/back/models/samba-config.json +++ b/modules/account/back/models/samba-config.json @@ -7,7 +7,7 @@ } }, "mixins": { - "AccountSynchronizer": {} + "AccountLinker": {} }, "properties": { "id": { diff --git a/modules/account/back/models/sip-config.js b/modules/account/back/models/sip-config.js index 3b5cb2dbb3..7037833378 100644 --- a/modules/account/back/models/sip-config.js +++ b/modules/account/back/models/sip-config.js @@ -2,7 +2,7 @@ const app = require('vn-loopback/server/server'); module.exports = Self => { - Self.getSynchronizer = async function() { + Self.getLinker = async function() { return await Self.findOne({fields: ['id']}); }; diff --git a/modules/account/back/models/sip-config.json b/modules/account/back/models/sip-config.json index 6c5ba3db38..a25d09c67e 100644 --- a/modules/account/back/models/sip-config.json +++ b/modules/account/back/models/sip-config.json @@ -7,7 +7,7 @@ } }, "mixins": { - "AccountSynchronizer": {} + "AccountLinker": {} }, "properties": { "id": { @@ -16,4 +16,3 @@ } } } - \ No newline at end of file diff --git a/modules/account/front/descriptor/index.html b/modules/account/front/descriptor/index.html index b0a70edd11..86e78dfcef 100644 --- a/modules/account/front/descriptor/index.html +++ b/modules/account/front/descriptor/index.html @@ -68,7 +68,6 @@ Deactivate user - + Do you want to synchronize user? From fc653746f0d5e6e0769b1ffa335ca447549f96a8 Mon Sep 17 00:00:00 2001 From: pablone Date: Tue, 21 Nov 2023 07:54:25 +0100 Subject: [PATCH 265/449] remove(barcode): refs #5228 remove barcode from report --- .../expedition-pallet-label/assets/css/style.css | 3 --- .../expedition-pallet-label.html | 1 - .../expedition-pallet-label.js | 14 -------------- 3 files changed, 18 deletions(-) diff --git a/print/templates/reports/expedition-pallet-label/assets/css/style.css b/print/templates/reports/expedition-pallet-label/assets/css/style.css index bd73664869..178ce79d2d 100644 --- a/print/templates/reports/expedition-pallet-label/assets/css/style.css +++ b/print/templates/reports/expedition-pallet-label/assets/css/style.css @@ -56,9 +56,6 @@ html { margin-left: 35px; float:left; } -#barcode{ - text-align: center; -} #right { float: right; margin-top: 20px; diff --git a/print/templates/reports/expedition-pallet-label/expedition-pallet-label.html b/print/templates/reports/expedition-pallet-label/expedition-pallet-label.html index 0cb25613e6..a34755f911 100644 --- a/print/templates/reports/expedition-pallet-label/expedition-pallet-label.html +++ b/print/templates/reports/expedition-pallet-label/expedition-pallet-label.html @@ -9,7 +9,6 @@ -
diff --git a/print/templates/reports/expedition-pallet-label/expedition-pallet-label.js b/print/templates/reports/expedition-pallet-label/expedition-pallet-label.js index bcd90418f3..00f1f8ba11 100644 --- a/print/templates/reports/expedition-pallet-label/expedition-pallet-label.js +++ b/print/templates/reports/expedition-pallet-label/expedition-pallet-label.js @@ -39,19 +39,5 @@ module.exports = { const data = String(id); return qrcode.toDataURL(data, {margin: 0}); }, - getBarcode(id) { - const xmlSerializer = new XMLSerializer(); - const document = new DOMImplementation().createDocument('http://www.w3.org/1999/xhtml', 'html', null); - const svgNode = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - - jsBarcode(svgNode, id, { - xmlDocument: document, - format: 'code128', - displayValue: false, - width: 6, - height: 90, - }); - return xmlSerializer.serializeToString(svgNode); - }, }, }; From dd11cf53273e6f52e0d27c37afe2ed61a23adcb5 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 21 Nov 2023 09:03:25 +0100 Subject: [PATCH 266/449] ref #5835 fix test --- .../back/methods/invoice-in-due-day/specs/new.spec.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js b/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js index f2f04b993e..c188a511da 100644 --- a/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js +++ b/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js @@ -5,11 +5,6 @@ describe('invoiceInDueDay new()', () => { beforeAll(async() => { const activeCtx = { accessToken: {userId: 9}, - http: { - req: { - headers: {origin: 'http://localhost'} - } - } }; spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ active: activeCtx @@ -24,7 +19,6 @@ describe('invoiceInDueDay new()', () => { req: { accessToken: {userId: userId}, - headers: {origin: 'http://localhost:5000'}, } }; From bf7c67dbdeb595594beff1977a6374f0d8a5009d Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Tue, 21 Nov 2023 09:26:02 +0100 Subject: [PATCH 267/449] fix: refs #6197 add definer to events --- modules/account/back/models/role-inherit.js | 2 +- modules/zone/back/models/zone-closure.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/account/back/models/role-inherit.js b/modules/account/back/models/role-inherit.js index 7d31e62b1c..e994f844ef 100644 --- a/modules/account/back/models/role-inherit.js +++ b/modules/account/back/models/role-inherit.js @@ -9,7 +9,7 @@ module.exports = Self => { Self.observe(hook, async() => { try { await Self.rawSql(` - CREATE EVENT account.role_sync + CREATE DEFINER = CURRENT_ROLE EVENT account.role_sync ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 5 SECOND DO CALL role_sync; `); diff --git a/modules/zone/back/models/zone-closure.js b/modules/zone/back/models/zone-closure.js index d25d6f7074..61350ef56d 100644 --- a/modules/zone/back/models/zone-closure.js +++ b/modules/zone/back/models/zone-closure.js @@ -14,7 +14,7 @@ module.exports = Self => { async function doCalc(ctx) { try { await Self.rawSql(` - CREATE EVENT zoneClosure_doRecalc + CREATE DEFINER = CURRENT_ROLE EVENT zoneClosure_doRecalc ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 15 SECOND DO CALL zoneClosure_recalc; `); From 02e8b909262ba5c94f04a99c150807d8033d90a2 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 21 Nov 2023 10:12:07 +0100 Subject: [PATCH 268/449] refs #6454 test: fix e2e by dump --- e2e/helpers/selectors.js | 1 + .../10-travel/02_basic_data_and_log.spec.js | 21 +++++++- e2e/paths/14-account/06_accounts.spec.js | 12 ----- e2e/paths/14-account/08_samba.spec.js | 5 +- loopback/locale/es.json | 3 +- .../back/methods/ticket/specs/addSale.spec.js | 54 ++++++++----------- modules/travel/front/search-panel/index.js | 13 +---- 7 files changed, 50 insertions(+), 59 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index b5dbd42ac1..acd13800b5 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -145,6 +145,7 @@ export default { adController: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adController"]', adUser: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adUser"]', adPassword: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adPassword"]', + userDn: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.userDn"]', verifyCert: 'vn-account-samba vn-check[ng-model="$ctrl.config.verifyCert"]', save: 'vn-account-samba vn-submit' }, diff --git a/e2e/paths/10-travel/02_basic_data_and_log.spec.js b/e2e/paths/10-travel/02_basic_data_and_log.spec.js index 5abf8a65e5..0079e80235 100644 --- a/e2e/paths/10-travel/02_basic_data_and_log.spec.js +++ b/e2e/paths/10-travel/02_basic_data_and_log.spec.js @@ -22,7 +22,7 @@ describe('Travel basic data path', () => { await page.waitForState('travel.card.basicData'); }); - it('should set a wrong delivery date then receive an error on submit', async() => { + it('should throw error if try move a travel with entries', async() => { const lastMonth = Date.vnNew(); lastMonth.setMonth(lastMonth.getMonth() - 1); @@ -30,6 +30,23 @@ describe('Travel basic data path', () => { await page.waitToClick(selectors.travelBasicData.save); const message = await page.waitForSnackbar(); + expect(message.text).toContain('Cannot past travels with entries'); + }); + + it('should set a wrong delivery date then receive an error on submit', async() => { + await page.loginAndModule('buyer', 'travel'); + await page.write(selectors.travelIndex.generalSearchFilter, '4'); + await page.keyboard.press('Enter'); + await page.accessToSection('travel.card.basicData'); + await page.waitForState('travel.card.basicData'); + + const lastMonth = Date.vnNew(); + lastMonth.setMonth(lastMonth.getMonth() - 2); + + await page.pickDate(selectors.travelBasicData.deliveryDate, lastMonth); + await page.waitToClick(selectors.travelBasicData.save); + const message = await page.waitForSnackbar(); + expect(message.text).toContain('Landing cannot be lesser than shipment'); }); @@ -39,7 +56,7 @@ describe('Travel basic data path', () => { await page.waitToClick(selectors.travelBasicData.undoChanges); const result = await page.waitToGetProperty(selectors.travelBasicData.reference, 'value'); - expect(result).toEqual('third travel'); + expect(result).toEqual('fourth travel'); }); it('should now edit the whole form then save', async() => { diff --git a/e2e/paths/14-account/06_accounts.spec.js b/e2e/paths/14-account/06_accounts.spec.js index 83893e0cfe..8bd6ea7d5f 100644 --- a/e2e/paths/14-account/06_accounts.spec.js +++ b/e2e/paths/14-account/06_accounts.spec.js @@ -23,18 +23,6 @@ describe('Account Accounts path', () => { expect(message.text).toContain('Roles synchronized!'); }); - it('should sync user', async() => { - await page.waitToClick(selectors.accountAccounts.syncUser); - await page.write(selectors.accountAccounts.syncUserName, 'sysadmin'); - await page.write(selectors.accountAccounts.syncUserPassword, 'nightmare'); - - await page.waitToClick(selectors.accountAccounts.buttonAccept); - - const message = await page.waitForSnackbar(); - - expect(message.text).toContain('User synchronized!'); - }); - it('should relogin', async() => { await page.loginAndModule('sysadmin', 'account'); await page.accessToSection('account.accounts'); diff --git a/e2e/paths/14-account/08_samba.spec.js b/e2e/paths/14-account/08_samba.spec.js index 6e7ef9bbfb..a92344acb8 100644 --- a/e2e/paths/14-account/08_samba.spec.js +++ b/e2e/paths/14-account/08_samba.spec.js @@ -20,8 +20,9 @@ describe('Account Samba path', () => { await page.waitToClick(selectors.accountSamba.checkEnable); await page.write(selectors.accountSamba.adDomain, '1234'); await page.write(selectors.accountSamba.adController, '1234'); - await page.write(selectors.accountSamba.adUser, 'nightmare'); - await page.write(selectors.accountSamba.adPassword, 'sysadmin'); + await page.write(selectors.accountSamba.adUser, 'sysadmin'); + await page.write(selectors.accountSamba.adPassword, 'nightmare'); + await page.write(selectors.accountSamba.userDn, 'testDn'); await page.waitToClick(selectors.accountSamba.verifyCert); await page.waitToClick(selectors.accountSamba.save); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index a4de6f9972..41acc36c3b 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -327,5 +327,6 @@ "The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada", "User disabled": "Usuario desactivado", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", - "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima" + "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", + "Cannot past travels with entries": "No se pueden pasar envíos con entradas" } diff --git a/modules/ticket/back/methods/ticket/specs/addSale.spec.js b/modules/ticket/back/methods/ticket/specs/addSale.spec.js index b1ecb133b0..8c0e39becf 100644 --- a/modules/ticket/back/methods/ticket/specs/addSale.spec.js +++ b/modules/ticket/back/methods/ticket/specs/addSale.spec.js @@ -3,33 +3,30 @@ const LoopBackContext = require('loopback-context'); describe('ticket addSale()', () => { const ticketId = 13; - beforeAll(async() => { - const activeCtx = { - accessToken: {userId: 9}, + function getActiveCtx(userId) { + return { + accessToken: {userId}, http: { req: { - headers: {origin: 'http://localhost'} + accessToken: {userId}, + headers: {origin: 'http://localhost'}, + __: () => {} } } }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ - active: activeCtx - }); - }); + } it('should create a new sale for the ticket with id 13', async() => { const tx = await models.Ticket.beginTransaction({}); + const activeCtx = getActiveCtx(9); + const ctx = activeCtx.http; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); try { const options = {transaction: tx}; - const ctx = { - req: { - accessToken: {userId: 9}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; const itemId = 4; const quantity = 10; const newSale = await models.Ticket.addSale(ctx, ticketId, itemId, quantity, options); @@ -45,19 +42,16 @@ describe('ticket addSale()', () => { it('should not be able to add a sale if the item quantity is not available', async() => { const tx = await models.Ticket.beginTransaction({}); + const activeCtx = getActiveCtx(18); + const ctx = activeCtx.http; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); let error; - try { const options = {transaction: tx}; - const ctx = { - req: { - accessToken: {userId: 9}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; const itemId = 11; const quantity = 10; @@ -74,18 +68,16 @@ describe('ticket addSale()', () => { it('should not be able to add a sale if the ticket is not editable', async() => { const tx = await models.Ticket.beginTransaction({}); + const activeCtx = getActiveCtx(9); + const ctx = activeCtx.http; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); let error; - try { const options = {transaction: tx}; - const ctx = { - req: { - accessToken: {userId: 9}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; + const notEditableTicketId = 1; const itemId = 4; const quantity = 10; diff --git a/modules/travel/front/search-panel/index.js b/modules/travel/front/search-panel/index.js index f53c15ca8a..5969a8c3f9 100644 --- a/modules/travel/front/search-panel/index.js +++ b/modules/travel/front/search-panel/index.js @@ -37,17 +37,8 @@ class Controller extends SearchPanel { } applyFilters(param) { - if (typeof this.filter.scopeDays === 'number') { - const today = Date.vnNew(); - const shippedFrom = new Date(today.getTime()); - shippedFrom.setDate(today.getDate() - 30); - shippedFrom.setHours(0, 0, 0, 0); - - const shippedTo = new Date(today.getTime()); - shippedTo.setDate(shippedTo.getDate() + this.filter.scopeDays); - shippedTo.setHours(23, 59, 59, 999); - Object.assign(this.filter, {shippedFrom, shippedTo}); - } + if (this.filter?.search) + delete this.filter.scopeDays; this.model.applyFilter({}, this.filter) .then(() => { From 707173d6184c9f7dbe663d69e3dd2e2fb4042c79 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Wed, 22 Nov 2023 07:04:33 +0100 Subject: [PATCH 269/449] refs #5890 fix: getTickets --- back/methods/collection/getTickets.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js index f04822697c..cfd404bebb 100644 --- a/back/methods/collection/getTickets.js +++ b/back/methods/collection/getTickets.js @@ -74,8 +74,8 @@ module.exports = Self => { LEFT JOIN parking p ON p.id = sh.parkingFk LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk LEFT JOIN origin o ON o.id = i.originFk - WHERE tc.collectionFk = ? - GROUP BY ish.id, p.code, p2.code + WHERE tc.collectionFk = ? AND iss.quantity IS NOT NULL + GROUP BY s.id, ish.id, p.code, p2.code ORDER BY pickingOrder;`, [id], myOptions); if (print) From a27bb53089eb6913b2ffbd14dc6c296be1ac6dee Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 22 Nov 2023 08:57:45 +0100 Subject: [PATCH 270/449] refs #5835 getTotals fixed --- .../back/methods/invoice-in/getTotals.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/invoiceIn/back/methods/invoice-in/getTotals.js b/modules/invoiceIn/back/methods/invoice-in/getTotals.js index f35c106176..4c45284d52 100644 --- a/modules/invoiceIn/back/methods/invoice-in/getTotals.js +++ b/modules/invoiceIn/back/methods/invoice-in/getTotals.js @@ -29,15 +29,18 @@ module.exports = Self => { SELECT iit.*, SUM(iidd.amount) totalDueDay FROM vn.invoiceIn ii - LEFT JOIN (SELECT SUM(iit.taxableBase) totalTaxableBase, - CAST(SUM(iit.taxableBase * (1 + (ti.PorcentajeIva / 100))) AS DECIMAL(10,2)) totalVat + LEFT JOIN ( + SELECT SUM(iit.taxableBase) totalTaxableBase, + CAST( + SUM(COALESCE(iit.taxableBase * (1 + (ti.PorcentajeIva / 100)), iit.taxableBase)) + AS DECIMAL(10, 2) + ) totalVat FROM vn.invoiceInTax iit LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk - WHERE iit.invoiceInFk = ?) iit ON TRUE + WHERE iit.invoiceInFk = ? + ) iit ON TRUE LEFT JOIN vn.invoiceInDueDay iidd ON iidd.invoiceInFk = ii.id - WHERE - ii.id = ?`, [id, id]); - + WHERE ii.id = ?`, [id, id]); return result; }; }; From a0a9e299d93e7adb778b2c021a8ef91477278510 Mon Sep 17 00:00:00 2001 From: jgallego Date: Wed, 22 Nov 2023 12:39:21 +0100 Subject: [PATCH 271/449] feat: refs #6275 getTickets with phone --- .../methods/route/getExpeditionSummary.js | 40 +++++++++---------- .../route/back/methods/route/getTickets.js | 11 +++-- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/modules/route/back/methods/route/getExpeditionSummary.js b/modules/route/back/methods/route/getExpeditionSummary.js index d35ab86115..ee89401a86 100644 --- a/modules/route/back/methods/route/getExpeditionSummary.js +++ b/modules/route/back/methods/route/getExpeditionSummary.js @@ -34,30 +34,30 @@ module.exports = Self => { SUM(delivered) delivered, GROUP_CONCAT(totalPacking ORDER BY total DESC SEPARATOR ' ') itemPackingType FROM ( - SELECT r.id AS routeFk, - t.addressFk, - CONCAT (IFNULL(e.itemPackingTypeFk,'-'), '', COUNT(*)) totalPacking, - COUNT(*) total, - SUM(est.code = 'ON DELIVERY') delivery, - SUM(est.code = 'LOST') lost, - SUM(est.code = 'DELIVERED') delivered, - t.priority - FROM vn.ticket t - JOIN vn.route r ON r.id = t.routeFk - JOIN vn.expedition e ON e.ticketFk = t.id - LEFT JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk - JOIN vn.agencyMode am ON am.id = r.agencyModeFk - JOIN vn.agency ag ON ag.id = am.agencyFk - LEFT JOIN vn.userConfig uc ON uc.userFk = account.myUser_getId() - WHERE (r.created = util.VN_CURDATE() OR r.created = TIMESTAMPADD(day,-1, util.VN_CURDATE())) - AND t.routeFk = ? - GROUP BY t.addressFk, e.itemPackingTypeFk - ) sub + SELECT r.id AS routeFk, + t.addressFk, + CONCAT (IFNULL(e.itemPackingTypeFk,'-'), '', COUNT(*)) totalPacking, + COUNT(*) total, + SUM(est.code = 'ON DELIVERY') delivery, + SUM(est.code = 'LOST') lost, + SUM(est.code = 'DELIVERED') delivered, + t.priority + FROM vn.ticket t + JOIN vn.route r ON r.id = t.routeFk + JOIN vn.expedition e ON e.ticketFk = t.id + LEFT JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk + JOIN vn.agencyMode am ON am.id = r.agencyModeFk + JOIN vn.agency ag ON ag.id = am.agencyFk + LEFT JOIN vn.userConfig uc ON uc.userFk = account.myUser_getId() + WHERE (r.created = util.VN_CURDATE() OR r.created = util.yesterday()) + AND t.routeFk = ? + GROUP BY t.addressFk, e.itemPackingTypeFk + ) sub GROUP BY addressFk ORDER BY priority DESC `; - const results = await Self.rawSql(query, [routeFk], options); + const results = await Self.rawSql(query, [routeFk], myOptions); return results; }; }; diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js index 1eb9e27f51..8e1356a423 100644 --- a/modules/route/back/methods/route/getTickets.js +++ b/modules/route/back/methods/route/getTickets.js @@ -51,11 +51,16 @@ module.exports = Self => { u.nickname AS userNickname, vn.ticketTotalVolume(t.id) AS volume, tob.description, - GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt + GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt, + c.phone ClientPhone, + c.mobile ClientMobile, + a.phone AddressPhone, + a.mobile AddressMobile FROM vn.route r JOIN ticket t ON t.routeFk = r.id - JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk + JOIN client c ON t.clientFk = c.id + LEFT JOIN vn.sale s ON s.ticketFk = t.id + LEFT JOIN vn.item i ON i.id = s.itemFk LEFT JOIN ticketState ts ON ts.ticketFk = t.id LEFT JOIN state st ON st.id = ts.stateFk LEFT JOIN warehouse wh ON wh.id = t.warehouseFk From e856de0cfd8681f05b1639d003074545f38f9f39 Mon Sep 17 00:00:00 2001 From: jgallego Date: Wed, 22 Nov 2023 15:54:38 +0100 Subject: [PATCH 272/449] feat: refs #6028 test --- .../00-getRoutesByWorker.sql | 4 -- .../client/specs/getRoutesByWorker.spec.js | 19 ------ modules/route/back/methods/route/filter.js | 6 +- .../route/back/methods/route/getByWorker.js | 66 +++++++++++++++++++ .../back/methods/route/getRoutesByWorker.js | 48 -------------- .../methods/route/specs/getByWorker.spec.js | 39 +++++++++++ modules/route/back/models/route.js | 2 +- 7 files changed, 110 insertions(+), 74 deletions(-) rename db/changes/{233001 => 234801}/00-getRoutesByWorker.sql (71%) delete mode 100644 modules/client/back/methods/client/specs/getRoutesByWorker.spec.js create mode 100644 modules/route/back/methods/route/getByWorker.js delete mode 100644 modules/route/back/methods/route/getRoutesByWorker.js create mode 100644 modules/route/back/methods/route/specs/getByWorker.spec.js diff --git a/db/changes/233001/00-getRoutesByWorker.sql b/db/changes/234801/00-getRoutesByWorker.sql similarity index 71% rename from db/changes/233001/00-getRoutesByWorker.sql rename to db/changes/234801/00-getRoutesByWorker.sql index aa612d48e0..bdc4a246ed 100644 --- a/db/changes/233001/00-getRoutesByWorker.sql +++ b/db/changes/234801/00-getRoutesByWorker.sql @@ -18,7 +18,3 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Route', 'insertTicket', 'WRITE', 'ALLOW', 'ROLE', 'employee'), ('Route', 'getDeliveryPoint', 'READ', 'ALLOW', 'ROLE', 'deliveryBoss'), ('Route', 'summary', 'READ', 'ALLOW', 'ROLE', 'employee'); - - -INSERT INTO salix.AccessToken (id, ttl, scopes, created, userId, outdated) VALUES('1z0GILWTs8huKrJGp7Fj0PvHaGA8Gg9DTNhm6nn6AfhkNJygeVUHMZKOGfMPp0xO', 1209600, NULL, '2023-07-17 13:34:10', 56, '2023-07-31 13:34:10'); -INSERT INTO salix.AccessToken (id, ttl, scopes, created, userId, outdated) VALUES('1z0GILWTs8huKrJGp7Fj0PvHaGA8Gg9DTNhm6nn6AfhkNJygeVUHMZKOGfMPp0xP', 1209600, NULL, '2023-07-17 13:34:10', 57, '2023-07-31 13:34:10'); diff --git a/modules/client/back/methods/client/specs/getRoutesByWorker.spec.js b/modules/client/back/methods/client/specs/getRoutesByWorker.spec.js deleted file mode 100644 index b43fe49d2b..0000000000 --- a/modules/client/back/methods/client/specs/getRoutesByWorker.spec.js +++ /dev/null @@ -1,19 +0,0 @@ -const {models} = require('vn-loopback/server/server'); - -describe('getRoutesByWorker', () => { - fit('should return the routes of the worker can view all routes', async() => { - const deliveryBossId = 57; - const ctx = {req: {accessToken: {userId: deliveryBossId}}}; - const result = await models.Route.getRoutesByWorker(ctx); - - expect(result.length).toEqual(7); - }); - - fit('should return the routes of the worker can not view all routes', async() => { - const deliveryId = 56; - const ctx = {req: {accessToken: {userId: deliveryId}}}; - const result = await models.Route.getRoutesByWorker(ctx); - - expect(result.length).toEqual(5); - }); -}); diff --git a/modules/route/back/methods/route/filter.js b/modules/route/back/methods/route/filter.js index fc35e979fe..afefa77d17 100644 --- a/modules/route/back/methods/route/filter.js +++ b/modules/route/back/methods/route/filter.js @@ -105,7 +105,7 @@ module.exports = Self => { } }); - filter = mergeFilters(ctx.args.filter, {where}); + filter = mergeFilters(filter, {where}); let stmts = []; let stmt; @@ -129,9 +129,11 @@ module.exports = Self => { r.description, am.name agencyName, u.name AS workerUserName, - v.numberPlate AS vehiclePlateNumber + v.numberPlate AS vehiclePlateNumber, + Date_format(r.time, '%H:%i') hour FROM route r LEFT JOIN agencyMode am ON am.id = r.agencyModeFk + LEFT JOIN agency a ON a.id = am.agencyFk LEFT JOIN vehicle v ON v.id = r.vehicleFk LEFT JOIN worker w ON w.id = r.workerFk LEFT JOIN account.user u ON u.id = w.id` diff --git a/modules/route/back/methods/route/getByWorker.js b/modules/route/back/methods/route/getByWorker.js new file mode 100644 index 0000000000..2f8a286e68 --- /dev/null +++ b/modules/route/back/methods/route/getByWorker.js @@ -0,0 +1,66 @@ +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; + +module.exports = Self => { + Self.remoteMethodCtx('getByWorker', { + description: 'Return the routes by worker', + accessType: 'READ', + returns: { + type: ['object'], + root: true + }, + http: { + path: `/getByWorker`, + verb: 'GET' + } + }); + + Self.getByWorker = async ctx => { + const models = Self.app.models; + const userId = ctx.req.accessToken.userId; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const canViewAll = await models.ACL.checkAccessAcl(ctx, 'Route', 'canViewAllRoute', 'READ'); + let filterGrant = {}; + console.log(userId); + console.log(canViewAll); + if (canViewAll) { + const userConfig = await models.UserConfig.getUserConfig(ctx, myOptions); + filterGrant = { + where: {'a.warehouseFk': userConfig.warehouseFk} + }; + } else { + filterGrant = { + where: {'r.workerFk': userId} + }; + } + + const currentDate = Date.vnNew(); + currentDate.setHours(0, 0, 0, 0); + const nextDay = Date.vnNew(); + nextDay.setDate(currentDate.getDate() + 1); + + const filter = { + where: { + and: [ + { + or: [ + {'r.created': currentDate}, + {'r.created': nextDay} + ] + } + ] + }, + order: [ + 'r.created ASC', + 'r.time ASC', + 'am.name ASC' + ] + }; + + const result = await Self.filter(ctx, mergeFilters(filter, filterGrant)); + return result; + }; +}; diff --git a/modules/route/back/methods/route/getRoutesByWorker.js b/modules/route/back/methods/route/getRoutesByWorker.js deleted file mode 100644 index 0a6f598166..0000000000 --- a/modules/route/back/methods/route/getRoutesByWorker.js +++ /dev/null @@ -1,48 +0,0 @@ -module.exports = Self => { - Self.remoteMethodCtx('getRoutesByWorker', { - description: 'Return the routes by worker', - accessType: 'READ', - returns: { - type: 'object', - root: true - }, - http: { - path: `/get-routes-by-worker`, - verb: 'GET' - } - }); - - Self.getRoutesByWorker = async(ctx, options) => { - const userId = ctx.req.accessToken.userId; - const myOptions = {}; - - if (typeof options == 'object') - Object.assign(myOptions, options); - - const canViewAll = await Self.app.models.ACL.checkAccessAcl(ctx, 'Route', 'canViewAllRoute', 'READ'); - const condition = canViewAll ? `ay.warehouseFK = uc.warehouseFk` : `r.workerFk = ${userId}`; - - return Self.rawSql(` - SELECT concat(w.firstName , ' ', w.lastName) driver, - r.id, - Date_format(r.time, '%H:%i') hour, - r.created, - r.m3, - v.numberPlate, - a.name, - r.kmStart, - r.kmEnd, - r.started, - r.finished - FROM vn.route r - JOIN vn.vehicle v ON r.vehicleFk = v.id - JOIN vn.agencyMode a ON r.agencyModeFk = a.id - JOIN vn.agency ay ON a.agencyFk = ay.id - JOIN vn.worker w ON r.workerFk = w.id - LEFT JOIN vn.userConfig uc ON uc.userFk = ? - WHERE (r.created = util.VN_CURDATE() OR r.created = TIMESTAMPADD(day, 1, util.VN_CURDATE())) - AND ${condition} - ORDER BY r.created ASC, r.time ASC, a.name ASC - `, [userId], myOptions); - }; -}; diff --git a/modules/route/back/methods/route/specs/getByWorker.spec.js b/modules/route/back/methods/route/specs/getByWorker.spec.js new file mode 100644 index 0000000000..52b8d6d87f --- /dev/null +++ b/modules/route/back/methods/route/specs/getByWorker.spec.js @@ -0,0 +1,39 @@ +const app = require('vn-loopback/server/server'); +const LoopBackContext = require('loopback-context'); + +fdescribe('route getByWorker()', () => { + const userId = 56; + const activeCtx = { + accessToken: {userId: userId}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + const ctx = {req: activeCtx}; + + beforeAll(() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + + it('should return routes assigned to the worker', async() => { + const result = await app.models.Route.getByWorker(ctx); + + // Aquí se verifica que el resultado contiene rutas asignadas al usuario + console.log(result); + + expect(result.every(route => route.workerFk === userId)).toBe(true); + }); + + it('should return all routes if user has canViewAllRoute permission', async() => { + // Simular que el usuario tiene permiso para ver todas las rutas + spyOn(app.models.ACL, 'checkAccessAcl').and.returnValue(Promise.resolve(true)); + + const result = await app.models.Route.getByWorker(ctx); + + expect(result.some(route => route.workerFk != userId)).toBe(true); + }); +}); diff --git a/modules/route/back/models/route.js b/modules/route/back/models/route.js index 073c601fe9..cbdd75679c 100644 --- a/modules/route/back/models/route.js +++ b/modules/route/back/models/route.js @@ -14,10 +14,10 @@ module.exports = Self => { require('../methods/route/driverRouteEmail')(Self); require('../methods/route/sendSms')(Self); require('../methods/route/downloadZip')(Self); - require('../methods/route/getRoutesByWorker')(Self); require('../methods/route/cmr')(Self); require('../methods/route/getExternalCmrs')(Self); require('../methods/route/downloadCmrsZip')(Self); + require('../methods/route/getByWorker')(Self); Self.validate('kmStart', validateDistance, { message: 'Distance must be lesser than 1000' From 6b07ee4eb1913294468af4e4202c9d768c1ff716 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 22 Nov 2023 18:35:14 +0100 Subject: [PATCH 273/449] hotfix workerhours --- modules/worker/front/time-control/index.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index a60c715899..f8a94be527 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -111,10 +111,8 @@ class Controller extends Section { dayIndex.setDate(dayIndex.getDate() + 1); } - if (this.worker) { - this.fetchHours(); - this.getWeekData(); - } + this.fetchHours(); + this.getWeekData(); } set weekTotalHours(totalHours) { @@ -404,7 +402,7 @@ class Controller extends Section { }); } - changeState(state, reason) { + state(state, reason) { this.state = state; this.reason = reason; this.repaint(); From f4fabb9fff0f95506c289834adbef3e6af58e713 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 23 Nov 2023 08:26:14 +0100 Subject: [PATCH 274/449] refs #6491 refactor(order_filter): optimized --- CHANGELOG.md | 1 + modules/order/back/methods/order/filter.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08a62f0449..1f16511b68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - (Ticket -> Adelantar) Permite mover lineas sin generar negativos - (Ticket -> Adelantar) Permite modificar la fecha de los tickets +- (Trabajadores -> Notificaciones) Nueva sección (lilium) ### Changed ### Fixed diff --git a/modules/order/back/methods/order/filter.js b/modules/order/back/methods/order/filter.js index 97fca5c10f..592ed11e60 100644 --- a/modules/order/back/methods/order/filter.js +++ b/modules/order/back/methods/order/filter.js @@ -139,6 +139,8 @@ module.exports = Self => { filter = mergeFilters(filter, {where}); const stmts = []; let stmt; + stmts.push(`SET @_optimizer_search_depth = @@optimizer_search_depth`); + stmts.push(`SET SESSION optimizer_search_depth = 0`); stmt = new ParameterizedSQL(` CREATE OR REPLACE TEMPORARY TABLE tmp.filter @@ -195,6 +197,7 @@ module.exports = Self => { stmt.merge(`GROUP BY id`); stmt.merge(conn.makePagination(filter)); stmts.push(stmt); + stmts.push(`SET SESSION optimizer_search_depth = @_optimizer_search_depth`); stmt = new ParameterizedSQL(`SELECT * FROM tmp.filter`); stmt.merge(conn.makeOrderBy(filter.order)); From 217aa1ac770ffb1e3e13cc76188cf800671af8bc Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 23 Nov 2023 08:35:08 +0100 Subject: [PATCH 275/449] refs #6491 deploy(2350) init version --- CHANGELOG.md | 7 +++++++ db/{changes => .archive}/233001/.gitkeep | 0 db/{changes => .archive}/233001/00-aclSaleTracking.sql | 0 db/{changes => .archive}/233001/00-clientSms.sql | 0 db/{changes => .archive}/233001/00-company.sql | 0 db/{changes => .archive}/233001/00-fixACLVehicle.sql | 0 db/{changes => .archive}/233001/00-itemRecycle.sql | 0 .../233001/00-itemShelving_inventory.sql | 0 db/{changes => .archive}/233001/00-noUniqueSocialName.sql | 0 db/{changes => .archive}/233001/00-roadmap.sql | 0 db/{changes => .archive}/233001/00-roadmapACL.sql | 0 db/{changes => .archive}/233001/00-ticketWeight.sql | 0 db/{changes => .archive}/233201/.gitkeep | 0 .../233201/00-acl_viaexpressConfig.sql | 0 db/{changes => .archive}/233201/00-transferClient.sql | 0 db/{changes => .archive}/233201/00-updatePrice.sql | 0 db/{changes => .archive}/233201/00-viaexpress.sql | 0 db/{changes => .archive}/233201/00-workerDocuware.sql | 0 db/{changes => .archive}/233202/00-client_create_upper.sql | 0 db/{changes => .archive}/233202/00-ticketSmsACL.sql | 0 db/{changes => .archive}/233401/00-setDeleted_acl.sql | 0 db/{changes => .archive}/233601/.gitkeep | 0 db/{changes => .archive}/233601/00-aclWorker.sql | 0 db/{changes => .archive}/233601/00-addExpeditionState.sql | 0 db/{changes => .archive}/233601/00-department.sql | 0 db/{changes => .archive}/233601/00-saleGroupDetail.sql | 0 db/{changes => .archive}/233801/.gitkeep | 0 db/{changes => .archive}/233801/00-firstScript.sql | 0 db/{changes => .archive}/233801/01-deviceLog_acl.sql | 0 db/{changes => .archive}/233802/.gitkeep | 0 .../233802/00-collectionGetTicketsACL.sql | 0 db/changes/235001/.gitkeep | 0 package-lock.json | 4 ++-- package.json | 2 +- 34 files changed, 10 insertions(+), 3 deletions(-) rename db/{changes => .archive}/233001/.gitkeep (100%) rename db/{changes => .archive}/233001/00-aclSaleTracking.sql (100%) rename db/{changes => .archive}/233001/00-clientSms.sql (100%) rename db/{changes => .archive}/233001/00-company.sql (100%) rename db/{changes => .archive}/233001/00-fixACLVehicle.sql (100%) rename db/{changes => .archive}/233001/00-itemRecycle.sql (100%) rename db/{changes => .archive}/233001/00-itemShelving_inventory.sql (100%) rename db/{changes => .archive}/233001/00-noUniqueSocialName.sql (100%) rename db/{changes => .archive}/233001/00-roadmap.sql (100%) rename db/{changes => .archive}/233001/00-roadmapACL.sql (100%) rename db/{changes => .archive}/233001/00-ticketWeight.sql (100%) rename db/{changes => .archive}/233201/.gitkeep (100%) rename db/{changes => .archive}/233201/00-acl_viaexpressConfig.sql (100%) rename db/{changes => .archive}/233201/00-transferClient.sql (100%) rename db/{changes => .archive}/233201/00-updatePrice.sql (100%) rename db/{changes => .archive}/233201/00-viaexpress.sql (100%) rename db/{changes => .archive}/233201/00-workerDocuware.sql (100%) rename db/{changes => .archive}/233202/00-client_create_upper.sql (100%) rename db/{changes => .archive}/233202/00-ticketSmsACL.sql (100%) rename db/{changes => .archive}/233401/00-setDeleted_acl.sql (100%) rename db/{changes => .archive}/233601/.gitkeep (100%) rename db/{changes => .archive}/233601/00-aclWorker.sql (100%) rename db/{changes => .archive}/233601/00-addExpeditionState.sql (100%) rename db/{changes => .archive}/233601/00-department.sql (100%) rename db/{changes => .archive}/233601/00-saleGroupDetail.sql (100%) rename db/{changes => .archive}/233801/.gitkeep (100%) rename db/{changes => .archive}/233801/00-firstScript.sql (100%) rename db/{changes => .archive}/233801/01-deviceLog_acl.sql (100%) rename db/{changes => .archive}/233802/.gitkeep (100%) rename db/{changes => .archive}/233802/00-collectionGetTicketsACL.sql (100%) create mode 100644 db/changes/235001/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f16511b68..d8d040fd67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ 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). +## [2350.01] - 2023-12-14 + +### Added +### Changed +### Fixed + + ## [2348.01] - 2023-11-30 ### Added diff --git a/db/changes/233001/.gitkeep b/db/.archive/233001/.gitkeep similarity index 100% rename from db/changes/233001/.gitkeep rename to db/.archive/233001/.gitkeep diff --git a/db/changes/233001/00-aclSaleTracking.sql b/db/.archive/233001/00-aclSaleTracking.sql similarity index 100% rename from db/changes/233001/00-aclSaleTracking.sql rename to db/.archive/233001/00-aclSaleTracking.sql diff --git a/db/changes/233001/00-clientSms.sql b/db/.archive/233001/00-clientSms.sql similarity index 100% rename from db/changes/233001/00-clientSms.sql rename to db/.archive/233001/00-clientSms.sql diff --git a/db/changes/233001/00-company.sql b/db/.archive/233001/00-company.sql similarity index 100% rename from db/changes/233001/00-company.sql rename to db/.archive/233001/00-company.sql diff --git a/db/changes/233001/00-fixACLVehicle.sql b/db/.archive/233001/00-fixACLVehicle.sql similarity index 100% rename from db/changes/233001/00-fixACLVehicle.sql rename to db/.archive/233001/00-fixACLVehicle.sql diff --git a/db/changes/233001/00-itemRecycle.sql b/db/.archive/233001/00-itemRecycle.sql similarity index 100% rename from db/changes/233001/00-itemRecycle.sql rename to db/.archive/233001/00-itemRecycle.sql diff --git a/db/changes/233001/00-itemShelving_inventory.sql b/db/.archive/233001/00-itemShelving_inventory.sql similarity index 100% rename from db/changes/233001/00-itemShelving_inventory.sql rename to db/.archive/233001/00-itemShelving_inventory.sql diff --git a/db/changes/233001/00-noUniqueSocialName.sql b/db/.archive/233001/00-noUniqueSocialName.sql similarity index 100% rename from db/changes/233001/00-noUniqueSocialName.sql rename to db/.archive/233001/00-noUniqueSocialName.sql diff --git a/db/changes/233001/00-roadmap.sql b/db/.archive/233001/00-roadmap.sql similarity index 100% rename from db/changes/233001/00-roadmap.sql rename to db/.archive/233001/00-roadmap.sql diff --git a/db/changes/233001/00-roadmapACL.sql b/db/.archive/233001/00-roadmapACL.sql similarity index 100% rename from db/changes/233001/00-roadmapACL.sql rename to db/.archive/233001/00-roadmapACL.sql diff --git a/db/changes/233001/00-ticketWeight.sql b/db/.archive/233001/00-ticketWeight.sql similarity index 100% rename from db/changes/233001/00-ticketWeight.sql rename to db/.archive/233001/00-ticketWeight.sql diff --git a/db/changes/233201/.gitkeep b/db/.archive/233201/.gitkeep similarity index 100% rename from db/changes/233201/.gitkeep rename to db/.archive/233201/.gitkeep diff --git a/db/changes/233201/00-acl_viaexpressConfig.sql b/db/.archive/233201/00-acl_viaexpressConfig.sql similarity index 100% rename from db/changes/233201/00-acl_viaexpressConfig.sql rename to db/.archive/233201/00-acl_viaexpressConfig.sql diff --git a/db/changes/233201/00-transferClient.sql b/db/.archive/233201/00-transferClient.sql similarity index 100% rename from db/changes/233201/00-transferClient.sql rename to db/.archive/233201/00-transferClient.sql diff --git a/db/changes/233201/00-updatePrice.sql b/db/.archive/233201/00-updatePrice.sql similarity index 100% rename from db/changes/233201/00-updatePrice.sql rename to db/.archive/233201/00-updatePrice.sql diff --git a/db/changes/233201/00-viaexpress.sql b/db/.archive/233201/00-viaexpress.sql similarity index 100% rename from db/changes/233201/00-viaexpress.sql rename to db/.archive/233201/00-viaexpress.sql diff --git a/db/changes/233201/00-workerDocuware.sql b/db/.archive/233201/00-workerDocuware.sql similarity index 100% rename from db/changes/233201/00-workerDocuware.sql rename to db/.archive/233201/00-workerDocuware.sql diff --git a/db/changes/233202/00-client_create_upper.sql b/db/.archive/233202/00-client_create_upper.sql similarity index 100% rename from db/changes/233202/00-client_create_upper.sql rename to db/.archive/233202/00-client_create_upper.sql diff --git a/db/changes/233202/00-ticketSmsACL.sql b/db/.archive/233202/00-ticketSmsACL.sql similarity index 100% rename from db/changes/233202/00-ticketSmsACL.sql rename to db/.archive/233202/00-ticketSmsACL.sql diff --git a/db/changes/233401/00-setDeleted_acl.sql b/db/.archive/233401/00-setDeleted_acl.sql similarity index 100% rename from db/changes/233401/00-setDeleted_acl.sql rename to db/.archive/233401/00-setDeleted_acl.sql diff --git a/db/changes/233601/.gitkeep b/db/.archive/233601/.gitkeep similarity index 100% rename from db/changes/233601/.gitkeep rename to db/.archive/233601/.gitkeep diff --git a/db/changes/233601/00-aclWorker.sql b/db/.archive/233601/00-aclWorker.sql similarity index 100% rename from db/changes/233601/00-aclWorker.sql rename to db/.archive/233601/00-aclWorker.sql diff --git a/db/changes/233601/00-addExpeditionState.sql b/db/.archive/233601/00-addExpeditionState.sql similarity index 100% rename from db/changes/233601/00-addExpeditionState.sql rename to db/.archive/233601/00-addExpeditionState.sql diff --git a/db/changes/233601/00-department.sql b/db/.archive/233601/00-department.sql similarity index 100% rename from db/changes/233601/00-department.sql rename to db/.archive/233601/00-department.sql diff --git a/db/changes/233601/00-saleGroupDetail.sql b/db/.archive/233601/00-saleGroupDetail.sql similarity index 100% rename from db/changes/233601/00-saleGroupDetail.sql rename to db/.archive/233601/00-saleGroupDetail.sql diff --git a/db/changes/233801/.gitkeep b/db/.archive/233801/.gitkeep similarity index 100% rename from db/changes/233801/.gitkeep rename to db/.archive/233801/.gitkeep diff --git a/db/changes/233801/00-firstScript.sql b/db/.archive/233801/00-firstScript.sql similarity index 100% rename from db/changes/233801/00-firstScript.sql rename to db/.archive/233801/00-firstScript.sql diff --git a/db/changes/233801/01-deviceLog_acl.sql b/db/.archive/233801/01-deviceLog_acl.sql similarity index 100% rename from db/changes/233801/01-deviceLog_acl.sql rename to db/.archive/233801/01-deviceLog_acl.sql diff --git a/db/changes/233802/.gitkeep b/db/.archive/233802/.gitkeep similarity index 100% rename from db/changes/233802/.gitkeep rename to db/.archive/233802/.gitkeep diff --git a/db/changes/233802/00-collectionGetTicketsACL.sql b/db/.archive/233802/00-collectionGetTicketsACL.sql similarity index 100% rename from db/changes/233802/00-collectionGetTicketsACL.sql rename to db/.archive/233802/00-collectionGetTicketsACL.sql diff --git a/db/changes/235001/.gitkeep b/db/changes/235001/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package-lock.json b/package-lock.json index b66279ae36..78ef939870 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "salix-back", - "version": "23.48.01", + "version": "23.50.01", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "salix-back", - "version": "23.48.01", + "version": "23.50.01", "license": "GPL-3.0", "dependencies": { "axios": "^1.2.2", diff --git a/package.json b/package.json index 04fcb008bc..586c963dd6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.48.01", + "version": "23.50.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From f44424dbcfe92bc3bb5b5f3e42467ef8acfb6d2c Mon Sep 17 00:00:00 2001 From: jgallego Date: Thu, 23 Nov 2023 09:44:47 +0100 Subject: [PATCH 276/449] test: refs #6028 test --- back/methods/collection/newCollection.js | 133 ------------------ .../collection/spec/newCollection.spec.js | 12 -- back/models/collection.js | 1 - .../00-getRoutesByWorker.sql | 6 + .../route/back/methods/route/getByWorker.js | 3 +- .../methods/route/specs/getByWorker.spec.js | 5 +- 6 files changed, 8 insertions(+), 152 deletions(-) delete mode 100644 back/methods/collection/newCollection.js delete mode 100644 back/methods/collection/spec/newCollection.spec.js rename db/changes/{234801 => 235001}/00-getRoutesByWorker.sql (71%) diff --git a/back/methods/collection/newCollection.js b/back/methods/collection/newCollection.js deleted file mode 100644 index 2be9f8b0ef..0000000000 --- a/back/methods/collection/newCollection.js +++ /dev/null @@ -1,133 +0,0 @@ -module.exports = Self => { - Self.remoteMethodCtx('newCollection', { - description: 'Make a new collection of tickets', - accessType: 'WRITE', - accepts: [{ - arg: 'collectionFk', - type: 'Number', - required: false, - description: 'The collection id' - }, { - arg: 'sectorFk', - type: 'Number', - required: true, - description: 'The sector of worker' - }, { - arg: 'vWagons', - type: 'Number', - required: true, - description: 'The number of wagons' - }], - returns: { - type: 'Object', - root: true - }, - http: { - path: `/newCollection`, - verb: 'POST' - } - }); - - Self.newCollection = async(ctx, collectionFk, sectorFk, vWagons) => { - let query = ''; - const userId = ctx.req.accessToken.userId; - - if (!collectionFk) { - query = `CALL vn.collectionTrain_newBeta(?,?,?)`; - const [result] = await Self.rawSql(query, [sectorFk, vWagons, userId], {userId}); - if (result.length == 0) - throw new Error(`No collections for today`); - - collectionFk = result[0].vCollectionFk; - } - - query = `CALL vn.collectionTicket_get(?)`; - const [tickets] = await Self.rawSql(query, [collectionFk], {userId}); - - query = `CALL vn.collectionSale_get(?)`; - const [sales] = await Self.rawSql(query, [collectionFk], {userId}); - - query = `CALL vn.collectionPlacement_get(?)`; - const [placements] = await Self.rawSql(query, [collectionFk], {userId}); - - query = `CALL vn.collectionSticker_print(?,?)`; - await Self.rawSql(query, [collectionFk, sectorFk], {userId}); - - return makeCollection(tickets, sales, placements, collectionFk); - }; - - /** - * Returns a collection json - * @param {*} tickets - Request tickets - * @param {*} sales - Request sales - * @param {*} placements - Request placements - * @param {*} collectionFk - Request placements - * @return {Object} Collection JSON - */ - async function makeCollection(tickets, sales, placements, collectionFk) { - let collection = []; - - for (let i = 0; i < tickets.length; i++) { - let ticket = {}; - ticket['ticketFk'] = tickets[i]['ticketFk']; - ticket['level'] = tickets[i]['level']; - ticket['agencyName'] = tickets[i]['agencyName']; - ticket['warehouseFk'] = tickets[i]['warehouseFk']; - ticket['salesPersonFk'] = tickets[i]['salesPersonFk']; - - let ticketSales = []; - - for (let x = 0; x < sales.length; x++) { - if (sales[x]['ticketFk'] == ticket['ticketFk']) { - let sale = {}; - sale['collectionFk'] = collectionFk; - sale['ticketFk'] = sales[x]['ticketFk']; - sale['saleFk'] = sales[x]['saleFk']; - sale['itemFk'] = sales[x]['itemFk']; - sale['quantity'] = sales[x]['quantity']; - if (sales[x]['quantityPicked'] != null) - sale['quantityPicked'] = sales[x]['quantityPicked']; - else - sale['quantityPicked'] = 0; - sale['longName'] = sales[x]['longName']; - sale['size'] = sales[x]['size']; - sale['color'] = sales[x]['color']; - sale['discount'] = sales[x]['discount']; - sale['price'] = sales[x]['price']; - sale['stems'] = sales[x]['stems']; - sale['category'] = sales[x]['category']; - sale['origin'] = sales[x]['origin']; - sale['clientFk'] = sales[x]['clientFk']; - sale['productor'] = sales[x]['productor']; - sale['reserved'] = sales[x]['reserved']; - sale['isPreviousPrepared'] = sales[x]['isPreviousPrepared']; - sale['isPrepared'] = sales[x]['isPrepared']; - sale['isControlled'] = sales[x]['isControlled']; - - let salePlacements = []; - - for (let z = 0; z < placements.length; z++) { - if (placements[z]['saleFk'] == sale['saleFk']) { - let placement = {}; - placement['saleFk'] = placements[z]['saleFk']; - placement['itemFk'] = placements[z]['itemFk']; - placement['placement'] = placements[z]['placement']; - placement['shelving'] = placements[z]['shelving']; - placement['created'] = placements[z]['created']; - placement['visible'] = placements[z]['visible']; - placement['order'] = placements[z]['order']; - placement['grouping'] = placements[z]['grouping']; - salePlacements.push(placement); - } - } - sale['placements'] = salePlacements; - ticketSales.push(sale); - } - } - ticket['sales'] = ticketSales; - collection.push(ticket); - } - - return collection; - } -}; diff --git a/back/methods/collection/spec/newCollection.spec.js b/back/methods/collection/spec/newCollection.spec.js deleted file mode 100644 index e729594d17..0000000000 --- a/back/methods/collection/spec/newCollection.spec.js +++ /dev/null @@ -1,12 +0,0 @@ -const {models} = require('vn-loopback/server/server'); - -describe('newCollection()', () => { - it('should return a new collection', async() => { - pending('#3400 analizar que hacer con rutas de back collection'); - let ctx = {req: {accessToken: {userId: 1106}}}; - let response = await models.Collection.newCollection(ctx, 1, 1, 1); - - expect(response.length).toBeGreaterThan(0); - expect(response[0].ticketFk).toEqual(2); - }); -}); diff --git a/back/models/collection.js b/back/models/collection.js index bfa906af60..1c10d49fa9 100644 --- a/back/models/collection.js +++ b/back/models/collection.js @@ -1,6 +1,5 @@ module.exports = Self => { require('../methods/collection/getCollection')(Self); - require('../methods/collection/newCollection')(Self); require('../methods/collection/getSectors')(Self); require('../methods/collection/setSaleQuantity')(Self); require('../methods/collection/previousLabel')(Self); diff --git a/db/changes/234801/00-getRoutesByWorker.sql b/db/changes/235001/00-getRoutesByWorker.sql similarity index 71% rename from db/changes/234801/00-getRoutesByWorker.sql rename to db/changes/235001/00-getRoutesByWorker.sql index bdc4a246ed..00d6e658a5 100644 --- a/db/changes/234801/00-getRoutesByWorker.sql +++ b/db/changes/235001/00-getRoutesByWorker.sql @@ -11,7 +11,13 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Route', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Route', 'getRoutesByWorker', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Route', 'canViewAllRoute', 'READ', 'ALLOW', 'ROLE', 'deliveryBoss'), + ('Route', 'cmr', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'downloadCmrsZip', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'downloadZip', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Route', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'getByWorker', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'getDeliveryPoint', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Route', 'getExternalCmrs', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Route', 'getSuggestedTickets', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Route', 'getTickets', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Route', 'guessPriority', 'WRITE', 'ALLOW', 'ROLE', 'employee'), diff --git a/modules/route/back/methods/route/getByWorker.js b/modules/route/back/methods/route/getByWorker.js index 2f8a286e68..7e70cb1f14 100644 --- a/modules/route/back/methods/route/getByWorker.js +++ b/modules/route/back/methods/route/getByWorker.js @@ -24,8 +24,7 @@ module.exports = Self => { const canViewAll = await models.ACL.checkAccessAcl(ctx, 'Route', 'canViewAllRoute', 'READ'); let filterGrant = {}; - console.log(userId); - console.log(canViewAll); + if (canViewAll) { const userConfig = await models.UserConfig.getUserConfig(ctx, myOptions); filterGrant = { diff --git a/modules/route/back/methods/route/specs/getByWorker.spec.js b/modules/route/back/methods/route/specs/getByWorker.spec.js index 52b8d6d87f..f3103509a3 100644 --- a/modules/route/back/methods/route/specs/getByWorker.spec.js +++ b/modules/route/back/methods/route/specs/getByWorker.spec.js @@ -1,7 +1,7 @@ const app = require('vn-loopback/server/server'); const LoopBackContext = require('loopback-context'); -fdescribe('route getByWorker()', () => { +describe('route getByWorker()', () => { const userId = 56; const activeCtx = { accessToken: {userId: userId}, @@ -22,9 +22,6 @@ fdescribe('route getByWorker()', () => { it('should return routes assigned to the worker', async() => { const result = await app.models.Route.getByWorker(ctx); - // Aquí se verifica que el resultado contiene rutas asignadas al usuario - console.log(result); - expect(result.every(route => route.workerFk === userId)).toBe(true); }); From 900dffbbba344b62662e7fa8ce388d0d9006a20e Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 23 Nov 2023 10:26:28 +0100 Subject: [PATCH 277/449] refs #5811 delete viaexpress expeditions included --- back/models/viaexpress-config.js | 2 + loopback/locale/en.json | 3 +- loopback/locale/es.json | 5 +- .../methods/expedition/deleteExpeditions.js | 66 +++++++++++-------- modules/ticket/back/models/expedition.json | 2 +- 5 files changed, 45 insertions(+), 33 deletions(-) diff --git a/back/models/viaexpress-config.js b/back/models/viaexpress-config.js index d0335b28b6..429c0a0d84 100644 --- a/back/models/viaexpress-config.js +++ b/back/models/viaexpress-config.js @@ -1,4 +1,6 @@ module.exports = Self => { require('../methods/viaexpress-config/internationalExpedition')(Self); require('../methods/viaexpress-config/renderer')(Self); + require('../methods/viaexpress-config/deleteShipment')(Self); + require('../methods/viaexpress-config/deleteShipmentRenderer')(Self); }; diff --git a/loopback/locale/en.json b/loopback/locale/en.json index ed6aa474f1..7d5b5ed47f 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -199,5 +199,6 @@ "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets", "Try again": "Try again", "keepPrice": "keepPrice", - "Cannot past travels with entries": "Cannot past travels with entries" + "Cannot past travels with entries": "Cannot past travels with entries", + "It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}" } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 41acc36c3b..01384efb42 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -328,5 +328,6 @@ "User disabled": "Usuario desactivado", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", - "Cannot past travels with entries": "No se pueden pasar envíos con entradas" -} + "Cannot past travels with entries": "No se pueden pasar envíos con entradas", + "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}" +} \ No newline at end of file diff --git a/modules/ticket/back/methods/expedition/deleteExpeditions.js b/modules/ticket/back/methods/expedition/deleteExpeditions.js index 2419d3a5e8..72c48fd3ad 100644 --- a/modules/ticket/back/methods/expedition/deleteExpeditions.js +++ b/modules/ticket/back/methods/expedition/deleteExpeditions.js @@ -1,6 +1,7 @@ +const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethod('deleteExpeditions', { + Self.remoteMethodCtx('deleteExpeditions', { description: 'Delete the selected expeditions', accessType: 'WRITE', accepts: [{ @@ -9,44 +10,51 @@ module.exports = Self => { required: true, description: 'The expeditions ids to delete' }], - returns: { - type: ['object'], - root: true - }, http: { path: `/deleteExpeditions`, verb: 'POST' } }); - Self.deleteExpeditions = async(expeditionIds, options) => { + Self.deleteExpeditions = async(ctx, expeditionIds) => { const models = Self.app.models; - const myOptions = {}; - let tx; + const $t = ctx.req.__; + const notDeletedExpeditions = []; - if (typeof options == 'object') - Object.assign(myOptions, options); + for (let expeditionId of expeditionIds) { + const filter = { + fields: [], + where: { + id: expeditionId + }, + include: [ + { + relation: 'agencyMode', + scope: { + fields: ['code'], + } + } + ] + }; - if (!myOptions.transaction) { - tx = await Self.beginTransaction({}); - myOptions.transaction = tx; + const expedition = await models.Expedition.findOne(filter); + const {code} = expedition.agencyMode(); + + if (code && code.toLowerCase().substring(0, 10) == 'viaexpress') { + const isDeleted = await models.ViaexpressConfig.deleteShipment(expeditionId); + + if (isDeleted === 'true') + await models.Expedition.destroyById(expeditionId); + + else if (!isDeleted) + notDeletedExpeditions.push(expeditionId); + } else + await models.Expedition.destroyById(expeditionId); } - - try { - const promises = []; - for (let expeditionId of expeditionIds) { - const deletedExpedition = models.Expedition.destroyById(expeditionId, myOptions); - promises.push(deletedExpedition); - } - - const deletedExpeditions = await Promise.all(promises); - - if (tx) await tx.commit(); - - return deletedExpeditions; - } catch (e) { - if (tx) await tx.rollback(); - throw e; + if (notDeletedExpeditions.length) { + throw new UserError( + $t(`It was not able to remove the next expeditions:`, {expeditions: notDeletedExpeditions.join()}) + ); } }; }; diff --git a/modules/ticket/back/models/expedition.json b/modules/ticket/back/models/expedition.json index 1ad083ce38..069c6e2813 100644 --- a/modules/ticket/back/models/expedition.json +++ b/modules/ticket/back/models/expedition.json @@ -33,7 +33,7 @@ }, "agencyMode": { "type": "belongsTo", - "model": "agency-mode", + "model": "AgencyMode", "foreignKey": "agencyModeFk" }, "worker": { From 2e67ef4f5d40e86cfc6bfa251b2da278509e2a5f Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 23 Nov 2023 10:32:07 +0100 Subject: [PATCH 278/449] refs #5811 refactor deleteExpeditions --- modules/ticket/back/methods/expedition/deleteExpeditions.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/ticket/back/methods/expedition/deleteExpeditions.js b/modules/ticket/back/methods/expedition/deleteExpeditions.js index 72c48fd3ad..a53c5d82cd 100644 --- a/modules/ticket/back/methods/expedition/deleteExpeditions.js +++ b/modules/ticket/back/methods/expedition/deleteExpeditions.js @@ -43,11 +43,9 @@ module.exports = Self => { if (code && code.toLowerCase().substring(0, 10) == 'viaexpress') { const isDeleted = await models.ViaexpressConfig.deleteShipment(expeditionId); - if (isDeleted === 'true') - await models.Expedition.destroyById(expeditionId); + if (isDeleted === 'true') await models.Expedition.destroyById(expeditionId); - else if (!isDeleted) - notDeletedExpeditions.push(expeditionId); + else notDeletedExpeditions.push(expeditionId); } else await models.Expedition.destroyById(expeditionId); } From db15285858f366732b256725756b57306e7437a5 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 23 Nov 2023 11:21:56 +0100 Subject: [PATCH 279/449] refs #5811 test updated --- .../methods/expedition/deleteExpeditions.js | 20 ++++++++++++++----- .../specs/deleteExpeditions.spec.js | 13 ++++++------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/modules/ticket/back/methods/expedition/deleteExpeditions.js b/modules/ticket/back/methods/expedition/deleteExpeditions.js index a53c5d82cd..3c98c80174 100644 --- a/modules/ticket/back/methods/expedition/deleteExpeditions.js +++ b/modules/ticket/back/methods/expedition/deleteExpeditions.js @@ -13,6 +13,10 @@ module.exports = Self => { http: { path: `/deleteExpeditions`, verb: 'POST' + }, + returns: { + type: ['object'], + root: true } }); @@ -20,6 +24,7 @@ module.exports = Self => { const models = Self.app.models; const $t = ctx.req.__; const notDeletedExpeditions = []; + const deletedExpeditions = []; for (let expeditionId of expeditionIds) { const filter = { @@ -43,16 +48,21 @@ module.exports = Self => { if (code && code.toLowerCase().substring(0, 10) == 'viaexpress') { const isDeleted = await models.ViaexpressConfig.deleteShipment(expeditionId); - if (isDeleted === 'true') await models.Expedition.destroyById(expeditionId); - - else notDeletedExpeditions.push(expeditionId); - } else - await models.Expedition.destroyById(expeditionId); + if (isDeleted === 'true') { + const deletedExpedition = await models.Expedition.destroyById(expeditionId); + deletedExpeditions.push(deletedExpedition); + } else notDeletedExpeditions.push(expeditionId); + } else { + const deletedExpedition = await models.Expedition.destroyById(expeditionId); + deletedExpeditions.push(deletedExpedition); + } } + if (notDeletedExpeditions.length) { throw new UserError( $t(`It was not able to remove the next expeditions:`, {expeditions: notDeletedExpeditions.join()}) ); } + return deletedExpeditions; }; }; diff --git a/modules/ticket/back/methods/expedition/specs/deleteExpeditions.spec.js b/modules/ticket/back/methods/expedition/specs/deleteExpeditions.spec.js index 61937989e2..bf8bafe34b 100644 --- a/modules/ticket/back/methods/expedition/specs/deleteExpeditions.spec.js +++ b/modules/ticket/back/methods/expedition/specs/deleteExpeditions.spec.js @@ -2,17 +2,16 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('ticket deleteExpeditions()', () => { + let ctx; beforeAll(async() => { - const activeCtx = { + ctx = { accessToken: {userId: 9}, - http: { - req: { - headers: {origin: 'http://localhost'} - } + req: { + headers: {origin: 'http://localhost'} } }; spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ - active: activeCtx + active: ctx }); }); @@ -23,7 +22,7 @@ describe('ticket deleteExpeditions()', () => { const options = {transaction: tx}; const expeditionIds = [12, 13]; - const result = await models.Expedition.deleteExpeditions(expeditionIds, options); + const result = await models.Expedition.deleteExpeditions(ctx, expeditionIds, options); expect(result.length).toEqual(2); From 5b145a57e6991bf07c54c4f1126834028c592cc9 Mon Sep 17 00:00:00 2001 From: jgallego Date: Thu, 23 Nov 2023 11:29:53 +0100 Subject: [PATCH 280/449] error: refs 6028 test front quitado --- modules/route/front/tickets/index.spec.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/modules/route/front/tickets/index.spec.js b/modules/route/front/tickets/index.spec.js index 2c73048bd7..fef4b83313 100644 --- a/modules/route/front/tickets/index.spec.js +++ b/modules/route/front/tickets/index.spec.js @@ -209,22 +209,6 @@ describe('Route', () => { }); }); - describe('guessPriority()', () => { - it('should perform a GET query then call both refresh and showSuccess methods', () => { - jest.spyOn(controller.$.model, 'refresh'); - jest.spyOn(controller.vnApp, 'showSuccess'); - controller.$params = {id: 99}; - - const url = `Routes/${controller.$params.id}/guessPriority/`; - $httpBackend.expectGET(url).respond('ok'); - controller.guessPriority(); - $httpBackend.flush(); - - expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Order changed'); - expect(controller.$.model.refresh).toHaveBeenCalledWith(); - }); - }); - describe('onDrop()', () => { it('should call the insert method when dragging a ticket number', () => { jest.spyOn(controller, 'insert'); From 6b2c1e09de32381e265b4838e01e25c09442f77a Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 23 Nov 2023 11:31:00 +0100 Subject: [PATCH 281/449] refs #5835 refactor --- modules/invoiceIn/back/methods/invoice-in/getTotals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/invoiceIn/back/methods/invoice-in/getTotals.js b/modules/invoiceIn/back/methods/invoice-in/getTotals.js index 4c45284d52..7bef9f7e99 100644 --- a/modules/invoiceIn/back/methods/invoice-in/getTotals.js +++ b/modules/invoiceIn/back/methods/invoice-in/getTotals.js @@ -32,7 +32,7 @@ module.exports = Self => { LEFT JOIN ( SELECT SUM(iit.taxableBase) totalTaxableBase, CAST( - SUM(COALESCE(iit.taxableBase * (1 + (ti.PorcentajeIva / 100)), iit.taxableBase)) + SUM(IFNULL(iit.taxableBase * (1 + (ti.PorcentajeIva / 100)), iit.taxableBase)) AS DECIMAL(10, 2) ) totalVat FROM vn.invoiceInTax iit From 4735307f5d439d25ac3d4a476a01a77399613c80 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 23 Nov 2023 11:49:00 +0100 Subject: [PATCH 282/449] refs #5890: fix(Collection/getTickets): accepts iss.quantity nulls --- back/methods/collection/getTickets.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js index cfd404bebb..50117b954a 100644 --- a/back/methods/collection/getTickets.js +++ b/back/methods/collection/getTickets.js @@ -49,7 +49,7 @@ module.exports = Self => { ish.packing, ish.grouping, s.isAdded, - s.originalQuantity, + s.originalQuantity, s.quantity saleQuantity, iss.quantity reservedQuantity, SUM(iss.quantity) OVER (PARTITION BY s.id ORDER BY ish.id) accumulatedQuantity, @@ -74,7 +74,7 @@ module.exports = Self => { LEFT JOIN parking p ON p.id = sh.parkingFk LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk LEFT JOIN origin o ON o.id = i.originFk - WHERE tc.collectionFk = ? AND iss.quantity IS NOT NULL + WHERE tc.collectionFk = ? GROUP BY s.id, ish.id, p.code, p2.code ORDER BY pickingOrder;`, [id], myOptions); @@ -105,7 +105,7 @@ module.exports = Self => { LEFT JOIN vn.buy c ON c.itemFk = s.itemFk LEFT JOIN vn.entry e ON e.id = c.entryFk LEFT JOIN vn.travel tr ON tr.id = e.travelFk - WHERE s.ticketFk = ? + WHERE s.ticketFk = ? AND tr.landed >= util.VN_CURDATE() - INTERVAL 1 YEAR`, [ticketId], myOptions); ticket.sales = []; From e314a67fe72f6112337330f7aefa1e46b7d7e84f Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 23 Nov 2023 13:25:31 +0100 Subject: [PATCH 283/449] refs #6274 time control methods migrated --- .../methods/worker-time-control/clockIn.js | 34 ++++++++++++++++ .../methods/worker-time-control/getClockIn.js | 30 ++++++++++++++ .../back/methods/worker-time-control/login.js | 39 +++++++++++++++++++ .../worker/back/models/worker-time-control.js | 3 ++ 4 files changed, 106 insertions(+) create mode 100644 modules/worker/back/methods/worker-time-control/clockIn.js create mode 100644 modules/worker/back/methods/worker-time-control/getClockIn.js create mode 100644 modules/worker/back/methods/worker-time-control/login.js diff --git a/modules/worker/back/methods/worker-time-control/clockIn.js b/modules/worker/back/methods/worker-time-control/clockIn.js new file mode 100644 index 0000000000..45de85f1db --- /dev/null +++ b/modules/worker/back/methods/worker-time-control/clockIn.js @@ -0,0 +1,34 @@ +module.exports = Self => { + Self.remoteMethodCtx('clockIn', { + description: 'Check if the employee can clock in', + accessType: 'READ', + accepts: [ + { + arg: 'workerFk', + type: 'integer', + required: true, + }, + { + arg: 'direction', + type: 'integer' + }, + { + arg: 'key', + type: 'string', + } + ], + http: { + path: `/clockIn`, + verb: 'POST' + } + }); + + Self.clockIn = async(ctx, pin, direction, key, options) => { + const myOptions = {}; + if (typeof options == 'object') + Object.assign(myOptions, options); + + const query = 'CALL vn.workerTimeControl_clockIn(?, NULL, ?)'; + return await Self.rawSql(query, [workerFk, direction], options); + }; +}; diff --git a/modules/worker/back/methods/worker-time-control/getClockIn.js b/modules/worker/back/methods/worker-time-control/getClockIn.js new file mode 100644 index 0000000000..603914655d --- /dev/null +++ b/modules/worker/back/methods/worker-time-control/getClockIn.js @@ -0,0 +1,30 @@ +module.exports = Self => { + Self.remoteMethodCtx('getClockIn', { + description: 'Shows the clockings for each day, in columns per day', + accessType: 'READ', + accepts: [ + { + arg: 'workerFk', + type: 'int', + required: true, + }, + { + arg: 'key', + type: 'string', + } + ], + http: { + path: `/getClockIn`, + verb: 'POST' + } + }); + + Self.getClockIn = async(ctx, workerFk, key, options) => { + const myOptions = {}; + if (typeof options == 'object') + Object.assign(myOptions, options); + + const query = `CALL vn.workerTimeControl_getClockIn(?, CURDATE())`; + return await Self.rawSql(query, [workerFk], myOptions); + }; +}; diff --git a/modules/worker/back/methods/worker-time-control/login.js b/modules/worker/back/methods/worker-time-control/login.js new file mode 100644 index 0000000000..75813411af --- /dev/null +++ b/modules/worker/back/methods/worker-time-control/login.js @@ -0,0 +1,39 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('login', { + description: 'Consult the user\'s information and the buttons that must be activated after logging in', + accessType: 'READ', + accepts: [ + { + arg: 'pin', + type: 'string', + required: true, + }, + { + arg: 'key', + type: 'string', + } + ], + returns: { + type: 'Object', + root: true + }, + http: { + path: `/login`, + verb: 'POST' + } + }); + + Self.login = async(ctx, pin, key, options) => { + const myOptions = {}; + if (typeof options == 'object') + Object.assign(myOptions, options); + + const query = `CALL vn.workerTimeControl_login(?)`; + const user = await Self.rawSql(query, [pin], myOptions); + + if (!user) throw new UserError('Indique el pin.'); + return user; + }; +}; diff --git a/modules/worker/back/models/worker-time-control.js b/modules/worker/back/models/worker-time-control.js index d5da680cf8..1457c7a462 100644 --- a/modules/worker/back/models/worker-time-control.js +++ b/modules/worker/back/models/worker-time-control.js @@ -10,6 +10,9 @@ module.exports = Self => { require('../methods/worker-time-control/weeklyHourRecordEmail')(Self); require('../methods/worker-time-control/getMailStates')(Self); require('../methods/worker-time-control/resendWeeklyHourEmail')(Self); + require('../methods/worker-time-control/login')(Self); + require('../methods/worker-time-control/getClockIn')(Self); + require('../methods/worker-time-control/clockIn')(Self); Self.rewriteDbError(function(err) { if (err.code === 'ER_DUP_ENTRY') From eeef279483a5adc30d3ad3e31197d1f0e0141c5f Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 23 Nov 2023 13:34:29 +0100 Subject: [PATCH 284/449] refs #5811 replace decription --- back/methods/viaexpress-config/deleteShipment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/methods/viaexpress-config/deleteShipment.js b/back/methods/viaexpress-config/deleteShipment.js index 40509899bc..babd3eeee5 100644 --- a/back/methods/viaexpress-config/deleteShipment.js +++ b/back/methods/viaexpress-config/deleteShipment.js @@ -3,7 +3,7 @@ const {DOMParser} = require('xmldom'); module.exports = Self => { Self.remoteMethod('deleteShipment', { - description: 'Create an expedition and return a label', + description: 'Delete a shipment by providing the expedition ID, interacting with Viaexpress API', accessType: 'WRITE', accepts: [{ arg: 'expeditionFk', From ebe467f721c659ab7cfaa12230fc6771e3d2b73c Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 24 Nov 2023 07:04:55 +0100 Subject: [PATCH 285/449] refs #6506 hotfix --- modules/worker/front/calendar/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/worker/front/calendar/index.html b/modules/worker/front/calendar/index.html index d64c22408e..75e892575c 100644 --- a/modules/worker/front/calendar/index.html +++ b/modules/worker/front/calendar/index.html @@ -70,6 +70,7 @@ fields="['started', 'ended']" ng-model="$ctrl.businessId" search-function="{businessFk: $search}" + show-field="businessFk" value-field="businessFk" order="businessFk DESC" limit="5"> From 8a568f180a3d9de0f745aa33ff894616fb3eec8a Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 24 Nov 2023 07:47:57 +0100 Subject: [PATCH 286/449] refs #6506 fix e2e, refactor business --- modules/worker/front/calendar/index.html | 2 +- modules/worker/front/time-control/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/worker/front/calendar/index.html b/modules/worker/front/calendar/index.html index 75e892575c..0e5433dc59 100644 --- a/modules/worker/front/calendar/index.html +++ b/modules/worker/front/calendar/index.html @@ -71,7 +71,7 @@ ng-model="$ctrl.businessId" search-function="{businessFk: $search}" show-field="businessFk" - value-field="businessFk" + value-field="businessId" order="businessFk DESC" limit="5"> diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index f8a94be527..4d5f55d278 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -402,7 +402,7 @@ class Controller extends Section { }); } - state(state, reason) { + changeState(state, reason) { this.state = state; this.reason = reason; this.repaint(); From 4071c06b5f7a2817b717d673d94e80bf4553df6e Mon Sep 17 00:00:00 2001 From: jgallego Date: Fri, 24 Nov 2023 08:15:39 +0100 Subject: [PATCH 287/449] feat: refs #6275 getTickets con los campos de silex --- modules/route/back/methods/route/getTickets.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js index 8e1356a423..89c68131af 100644 --- a/modules/route/back/methods/route/getTickets.js +++ b/modules/route/back/methods/route/getTickets.js @@ -3,7 +3,7 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; module.exports = Self => { Self.remoteMethod('getTickets', { - description: 'Return the tickets information displayed on the route module', + description: 'Find all instances of the model matched by filter from the data source.', accessType: 'READ', accepts: [ { @@ -55,7 +55,12 @@ module.exports = Self => { c.phone ClientPhone, c.mobile ClientMobile, a.phone AddressPhone, - a.mobile AddressMobile + a.mobile AddressMobile, + a.longitude, + a.latitude, + wm.mediaValue SalePersonPhone, + t.cmrFk, + t.isSigned Signed FROM vn.route r JOIN ticket t ON t.routeFk = r.id JOIN client c ON t.clientFk = c.id @@ -70,7 +75,8 @@ module.exports = Self => { LEFT JOIN address a ON a.id = t.addressFk LEFT JOIN agencyMode am ON am.id = t.agencyModeFk LEFT JOIN account.user u ON u.id = r.workerFk - LEFT JOIN vehicle v ON v.id = r.vehicleFk` + LEFT JOIN vehicle v ON v.id = r.vehicleFk + LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk` ); if (!filter.where) filter.where = {}; From 5d18c211a0c9159a39e4f4d02c18d899f4d1b689 Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 24 Nov 2023 08:40:06 +0100 Subject: [PATCH 288/449] refs #6507 state --- modules/worker/front/time-control/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index 4d5f55d278..f8a94be527 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -402,7 +402,7 @@ class Controller extends Section { }); } - changeState(state, reason) { + state(state, reason) { this.state = state; this.reason = reason; this.repaint(); From 8ac3887d8025840b3b90c4cbaae3af4e3d2171c4 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 24 Nov 2023 10:53:38 +0100 Subject: [PATCH 289/449] refs #5811 rename methods --- .../{deleteShipment.ejs => deleteExpedition.ejs} | 0 .../{deleteShipment.js => deleteExpedition.js} | 8 ++++---- ...eteShipmentRenderer.js => deleteExpeditionRenderer.js} | 8 ++++---- back/models/viaexpress-config.js | 4 ++-- .../ticket/back/methods/expedition/deleteExpeditions.js | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) rename back/methods/viaexpress-config/{deleteShipment.ejs => deleteExpedition.ejs} (100%) rename back/methods/viaexpress-config/{deleteShipment.js => deleteExpedition.js} (88%) rename back/methods/viaexpress-config/{deleteShipmentRenderer.js => deleteExpeditionRenderer.js} (79%) diff --git a/back/methods/viaexpress-config/deleteShipment.ejs b/back/methods/viaexpress-config/deleteExpedition.ejs similarity index 100% rename from back/methods/viaexpress-config/deleteShipment.ejs rename to back/methods/viaexpress-config/deleteExpedition.ejs diff --git a/back/methods/viaexpress-config/deleteShipment.js b/back/methods/viaexpress-config/deleteExpedition.js similarity index 88% rename from back/methods/viaexpress-config/deleteShipment.js rename to back/methods/viaexpress-config/deleteExpedition.js index babd3eeee5..189745554a 100644 --- a/back/methods/viaexpress-config/deleteShipment.js +++ b/back/methods/viaexpress-config/deleteExpedition.js @@ -2,7 +2,7 @@ const axios = require('axios'); const {DOMParser} = require('xmldom'); module.exports = Self => { - Self.remoteMethod('deleteShipment', { + Self.remoteMethod('deleteExpedition', { description: 'Delete a shipment by providing the expedition ID, interacting with Viaexpress API', accessType: 'WRITE', accepts: [{ @@ -15,19 +15,19 @@ module.exports = Self => { root: true }, http: { - path: `/deleteShipment`, + path: `/deleteExpedition`, verb: 'POST' } }); - Self.deleteShipment = async expeditionFk => { + Self.deleteExpedition = async expeditionFk => { const models = Self.app.models; const viaexpressConfig = await models.ViaexpressConfig.findOne({ fields: ['url'] }); - const renderedXml = await models.ViaexpressConfig.deleteShipmentRenderer(expeditionFk); + const renderedXml = await models.ViaexpressConfig.deleteExpeditionRenderer(expeditionFk); const response = await axios.post(`${viaexpressConfig.url}ServicioVxClientes.asmx`, renderedXml, { headers: { 'Content-Type': 'application/soap+xml; charset=utf-8' diff --git a/back/methods/viaexpress-config/deleteShipmentRenderer.js b/back/methods/viaexpress-config/deleteExpeditionRenderer.js similarity index 79% rename from back/methods/viaexpress-config/deleteShipmentRenderer.js rename to back/methods/viaexpress-config/deleteExpeditionRenderer.js index d9106a9ec8..645eaddd12 100644 --- a/back/methods/viaexpress-config/deleteShipmentRenderer.js +++ b/back/methods/viaexpress-config/deleteExpeditionRenderer.js @@ -2,7 +2,7 @@ const fs = require('fs'); const ejs = require('ejs'); module.exports = Self => { - Self.remoteMethod('deleteShipmentRenderer', { + Self.remoteMethod('deleteExpeditionRenderer', { description: 'Renders the data from an XML', accessType: 'READ', accepts: [{ @@ -15,12 +15,12 @@ module.exports = Self => { root: true }, http: { - path: `/deleteShipmentRenderer`, + path: `/deleteExpeditionRenderer`, verb: 'GET' } }); - Self.deleteShipmentRenderer = async expeditionFk => { + Self.deleteExpeditionRenderer = async expeditionFk => { const models = Self.app.models; const viaexpressConfig = await models.ViaexpressConfig.findOne({ @@ -37,7 +37,7 @@ module.exports = Self => { externalId: expedition.externalId }; - const template = fs.readFileSync(__dirname + '/deleteShipment.ejs', 'utf-8'); + const template = fs.readFileSync(__dirname + '/deleteExpedition.ejs', 'utf-8'); const renderedXml = ejs.render(template, data); return renderedXml; }; diff --git a/back/models/viaexpress-config.js b/back/models/viaexpress-config.js index 429c0a0d84..d00c99e823 100644 --- a/back/models/viaexpress-config.js +++ b/back/models/viaexpress-config.js @@ -1,6 +1,6 @@ module.exports = Self => { require('../methods/viaexpress-config/internationalExpedition')(Self); require('../methods/viaexpress-config/renderer')(Self); - require('../methods/viaexpress-config/deleteShipment')(Self); - require('../methods/viaexpress-config/deleteShipmentRenderer')(Self); + require('../methods/viaexpress-config/deleteExpedition')(Self); + require('../methods/viaexpress-config/deleteExpeditionRenderer')(Self); }; diff --git a/modules/ticket/back/methods/expedition/deleteExpeditions.js b/modules/ticket/back/methods/expedition/deleteExpeditions.js index 3c98c80174..55ca474d7d 100644 --- a/modules/ticket/back/methods/expedition/deleteExpeditions.js +++ b/modules/ticket/back/methods/expedition/deleteExpeditions.js @@ -46,7 +46,7 @@ module.exports = Self => { const {code} = expedition.agencyMode(); if (code && code.toLowerCase().substring(0, 10) == 'viaexpress') { - const isDeleted = await models.ViaexpressConfig.deleteShipment(expeditionId); + const isDeleted = await models.ViaexpressConfig.deleteExpedition(expeditionId); if (isDeleted === 'true') { const deletedExpedition = await models.Expedition.destroyById(expeditionId); From 2be1639e9fb841da26c819379dcee66828d55e99 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 24 Nov 2023 12:42:25 +0100 Subject: [PATCH 290/449] refactor: refs #3222 Expence to expense --- db/.archive/225201/00-invoiceOut_new.sql | 14 +- db/.archive/231001/02-invoiceOut_new.sql | 14 +- db/.archive/232001/00-invoiceOut_new.sql | 14 +- db/dump/fixtures.sql | 10 +- db/dump/structure.sql | 158 +++++++++--------- .../invoiceIn/back/locale/invoiceIn/en.yml | 2 +- .../invoiceIn/back/locale/invoiceIn/es.yml | 2 +- .../invoiceIn/back/locale/invoiceInTax/en.yml | 2 +- .../invoiceIn/back/locale/invoiceInTax/es.yml | 2 +- .../back/methods/invoice-in/filter.js | 2 +- .../invoiceIn/back/models/invoice-in-tax.json | 2 +- modules/invoiceIn/back/models/invoice-in.json | 2 +- modules/item/back/models/expense.json | 2 +- modules/item/back/models/item.json | 2 +- modules/item/front/basic-data/index.html | 2 +- .../methods/agency-term/createInvoiceIn.js | 4 +- .../route/back/models/agency-term-config.json | 2 +- .../back/models/ticket-service-type.json | 2 +- 18 files changed, 119 insertions(+), 119 deletions(-) diff --git a/db/.archive/225201/00-invoiceOut_new.sql b/db/.archive/225201/00-invoiceOut_new.sql index 8e23fb43b7..c0f6bc6974 100644 --- a/db/.archive/225201/00-invoiceOut_new.sql +++ b/db/.archive/225201/00-invoiceOut_new.sql @@ -118,13 +118,13 @@ BEGIN SELECT 'UPDATE', account.myUser_getId(), ti.id, CONCAT('Crea factura ', vNewRef) FROM tmp.ticketToInvoice ti; - CALL invoiceExpenceMake(vNewInvoiceId); + CALL invoiceExpenseMake(vNewInvoiceId); CALL invoiceTaxMake(vNewInvoiceId,vTaxArea); UPDATE invoiceOut io JOIN ( SELECT SUM(amount) AS total - FROM invoiceOutExpence + FROM invoiceOutExpense WHERE invoiceOutFk = vNewInvoiceId ) base JOIN ( @@ -166,18 +166,18 @@ BEGIN SET @vTaxableBaseServices := 0.00; SET @vTaxCodeGeneral := NULL; - INSERT INTO vn.invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) - SELECT vNewInvoiceInId, @vTaxableBaseServices, sub.expenceFk, sub.taxTypeSageFk , sub.transactionTypeSageFk + INSERT INTO vn.invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk) + SELECT vNewInvoiceInId, @vTaxableBaseServices, sub.expenseFk, sub.taxTypeSageFk , sub.transactionTypeSageFk FROM ( - SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase, i.expenceFk, i.taxTypeSageFk , i.transactionTypeSageFk, @vTaxCodeGeneral := i.taxClassCodeFk + SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase, i.expenseFk, i.taxTypeSageFk , i.transactionTypeSageFk, @vTaxCodeGeneral := i.taxClassCodeFk FROM tmp.ticketServiceTax tst JOIN vn.invoiceOutTaxConfig i ON i.taxClassCodeFk = tst.code WHERE i.isService HAVING taxableBase ) sub; - INSERT INTO vn.invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) - SELECT vNewInvoiceInId, SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral, @vTaxableBaseServices, 0) taxableBase, i.expenceFk, i.taxTypeSageFk , i.transactionTypeSageFk + INSERT INTO vn.invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk) + SELECT vNewInvoiceInId, SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral, @vTaxableBaseServices, 0) taxableBase, i.expenseFk, i.taxTypeSageFk , i.transactionTypeSageFk FROM tmp.ticketTax tt JOIN vn.invoiceOutTaxConfig i ON i.taxClassCodeFk = tt.code WHERE !i.isService diff --git a/db/.archive/231001/02-invoiceOut_new.sql b/db/.archive/231001/02-invoiceOut_new.sql index d570dfb726..e87c44cd03 100644 --- a/db/.archive/231001/02-invoiceOut_new.sql +++ b/db/.archive/231001/02-invoiceOut_new.sql @@ -139,13 +139,13 @@ BEGIN SELECT 'UPDATE', account.myUser_getId(), ti.id, CONCAT('Crea factura ', vNewRef) FROM tmp.ticketToInvoice ti; - CALL invoiceExpenceMake(vNewInvoiceId); + CALL invoiceExpenseMake(vNewInvoiceId); CALL invoiceTaxMake(vNewInvoiceId,vTaxArea); UPDATE invoiceOut io JOIN ( SELECT SUM(amount) total - FROM invoiceOutExpence + FROM invoiceOutExpense WHERE invoiceOutFk = vNewInvoiceId ) base JOIN ( @@ -182,15 +182,15 @@ BEGIN SET @vTaxableBaseServices := 0.00; SET @vTaxCodeGeneral := NULL; - INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk) SELECT vNewInvoiceInFk, @vTaxableBaseServices, - sub.expenceFk, + sub.expenseFk, sub.taxTypeSageFk, sub.transactionTypeSageFk FROM ( SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase, - i.expenceFk, + i.expenseFk, i.taxTypeSageFk, i.transactionTypeSageFk, @vTaxCodeGeneral := i.taxClassCodeFk @@ -200,11 +200,11 @@ BEGIN HAVING taxableBase ) sub; - INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk) SELECT vNewInvoiceInFk, SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral, @vTaxableBaseServices, 0) taxableBase, - i.expenceFk, + i.expenseFk, i.taxTypeSageFk , i.transactionTypeSageFk FROM tmp.ticketTax tt diff --git a/db/.archive/232001/00-invoiceOut_new.sql b/db/.archive/232001/00-invoiceOut_new.sql index b497dffda6..175c31b749 100644 --- a/db/.archive/232001/00-invoiceOut_new.sql +++ b/db/.archive/232001/00-invoiceOut_new.sql @@ -135,13 +135,13 @@ BEGIN INSERT INTO ticketTracking(stateFk,ticketFk,workerFk) SELECT * FROM tmp.updateInter; - CALL invoiceExpenceMake(vNewInvoiceId); + CALL invoiceExpenseMake(vNewInvoiceId); CALL invoiceTaxMake(vNewInvoiceId,vTaxArea); UPDATE invoiceOut io JOIN ( SELECT SUM(amount) total - FROM invoiceOutExpence + FROM invoiceOutExpense WHERE invoiceOutFk = vNewInvoiceId ) base JOIN ( @@ -178,15 +178,15 @@ BEGIN SET @vTaxableBaseServices := 0.00; SET @vTaxCodeGeneral := NULL; - INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk) SELECT vNewInvoiceInFk, @vTaxableBaseServices, - sub.expenceFk, + sub.expenseFk, sub.taxTypeSageFk, sub.transactionTypeSageFk FROM ( SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase, - i.expenceFk, + i.expenseFk, i.taxTypeSageFk, i.transactionTypeSageFk, @vTaxCodeGeneral := i.taxClassCodeFk @@ -196,11 +196,11 @@ BEGIN HAVING taxableBase ) sub; - INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk) SELECT vNewInvoiceInFk, SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral, @vTaxableBaseServices, 0) taxableBase, - i.expenceFk, + i.expenseFk, i.taxTypeSageFk , i.transactionTypeSageFk FROM tmp.ticketTax tt diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 788487ed07..93b7b796f1 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -630,7 +630,7 @@ INSERT INTO `vn`.`invoiceOutTax` (`invoiceOutFk`, `taxableBase`, `vat`, `pgcFk`) (4, 8.07, 0.81, 4770000010), (5, 8.07, 0.81, 4770000010); -INSERT INTO `vn`.`expence`(`id`, `name`, `isWithheld`) +INSERT INTO `vn`.`expense`(`id`, `name`, `isWithheld`) VALUES (2000000000, 'Inmovilizado pendiente', 0), (2000000001, 'Compra de bienes de inmovilizado', 0), @@ -642,7 +642,7 @@ INSERT INTO `vn`.`expence`(`id`, `name`, `isWithheld`) (7050000000, 'Prestacion de servicios', 1); -INSERT INTO `vn`.`invoiceOutExpence`(`id`, `invoiceOutFk`, `amount`, `expenceFk`, `created`) +INSERT INTO `vn`.`invoiceOutExpense`(`id`, `invoiceOutFk`, `amount`, `expenseFk`, `created`) VALUES (1, 1, 813.06, 2000000000, util.VN_CURDATE()), (2, 1, 33.80, 4751000000, util.VN_CURDATE()), @@ -922,7 +922,7 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`) ('SER', 'Services'), ('VT', 'Sales'); -INSERT INTO `vn`.`item`(`id`, `typeFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`, +INSERT INTO `vn`.`item`(`id`, `typeFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenseFk`, `comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`, `genericFk`, `itemPackingTypeFk`, `hasMinPrice`, `packingShelve`, `weightByPiece`) VALUES (1, 2, 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'EMB', 0, NULL, 'V', 0, 15,3), @@ -1939,7 +1939,7 @@ INSERT INTO `vn`.`ticketRequest`(`id`, `description`, `requesterFk`, `attenderFk (4, 'Melee weapon combat first 15cm', 18, 35, 15, NULL, 1.30, NULL, NULL, 11, util.VN_CURDATE()), (5, 'Melee weapon combat first 15cm', 18, 35, 15, 4, 1.30, 0, NULL, 18, util.VN_CURDATE()); -INSERT INTO `vn`.`ticketServiceType`(`id`, `name`, `expenceFk`) +INSERT INTO `vn`.`ticketServiceType`(`id`, `name`, `expenseFk`) VALUES (1, 'Porte Agencia', 7001000000), (2, 'Portes Retorno', 7001000000), @@ -2561,7 +2561,7 @@ INSERT INTO `vn`.`duaInvoiceIn`(`id`, `duaFk`, `invoiceInFk`) (9, 9, 9), (10, 10, 10); -INSERT INTO `vn`.`invoiceInTax` (`invoiceInFk`, `taxableBase`, `expenceFk`, `foreignValue`, `taxTypeSageFk`, `transactionTypeSageFk`) +INSERT INTO `vn`.`invoiceInTax` (`invoiceInFk`, `taxableBase`, `expenseFk`, `foreignValue`, `taxTypeSageFk`, `transactionTypeSageFk`) VALUES (1, 99.99, '2000000000', NULL, NULL, NULL), (2, 999.99, '2000000000', NULL, NULL, NULL), diff --git a/db/dump/structure.sql b/db/dump/structure.sql index d8a717aa3c..1db4252f48 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -9692,7 +9692,7 @@ proc: BEGIN `name`, longName, subName, - expenceFk, + expenseFk, typeFk, intrastatFk, originFk, @@ -10080,7 +10080,7 @@ BEGIN `name`, longName, subName, - expenceFk, + expenseFk, typeFk, intrastatFk, originFk, @@ -17338,7 +17338,7 @@ BEGIN JOIN vn.XDiario x ON x.id = mci.id JOIN vn.supplier s ON s.id = supplierFk JOIN vn.invoiceInTax iit ON iit.invoiceInFk = ii.id - JOIN vn.expence e ON e.id = iit.expenceFk + JOIN vn.expense e ON e.id = iit.expenseFk JOIN TiposRetencion t ON t.CodigoRetencion = ii.withholdingSageFk LEFT JOIN tmp.invoiceDua id ON id.id = mci.id JOIN (SELECT SUM(x2.BASEEURO) taxableBase, SUM(x2.EURODEBE) taxBase @@ -17441,7 +17441,7 @@ BEGIN i.serial COLLATE utf8mb3_unicode_ci serial, i.supplierFk, i.issued, - IF(expenceFkDeductible, FALSE, i.isVatDeductible) isVatDeductible, + IF(expenseFkDeductible, FALSE, i.isVatDeductible) isVatDeductible, IF(c.code = 'EUR', '',c.`code`) currencyFk FROM vn.invoiceIn i JOIN vn.currency c ON c.id = i.currencyFk @@ -17949,7 +17949,7 @@ BEGIN e.id accountFk, UCASE(e.name), '' - FROM vn.expence e + FROM vn.expense e UNION SELECT company_getCode(vCompanyFk), b.account, @@ -22010,7 +22010,7 @@ DROP TABLE IF EXISTS `agencyTermConfig`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `agencyTermConfig` ( - `expenceFk` varchar(10) DEFAULT NULL, + `expenseFk` varchar(10) DEFAULT NULL, `vatAccountSupported` varchar(15) DEFAULT NULL, `vatPercentage` decimal(28,10) DEFAULT NULL, `transaction` varchar(50) DEFAULT NULL @@ -29097,19 +29097,19 @@ SET character_set_client = utf8; SET character_set_client = @saved_cs_client; -- --- Table structure for table `expence` +-- Table structure for table `expense` -- -DROP TABLE IF EXISTS `expence`; +DROP TABLE IF EXISTS `expense`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE `expence` ( +CREATE TABLE `expense` ( `id` varchar(10) NOT NULL, `name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL, `isWithheld` tinyint(4) NOT NULL DEFAULT 0, `code` varchar(25) DEFAULT NULL, PRIMARY KEY (`id`), - UNIQUE KEY `expence_UN` (`code`) + UNIQUE KEY `expense_UN` (`code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -29862,7 +29862,7 @@ CREATE TABLE `invoiceIn` ( `bookEntried` date DEFAULT NULL COMMENT 'Fecha Asiento', `isVatDeductible` tinyint(1) NOT NULL DEFAULT 1, `withholdingSageFk` smallint(6) DEFAULT NULL COMMENT 'Tipos de retención SAGE', - `expenceFkDeductible` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + `expenseFkDeductible` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `editorFk` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`), KEY `proveedor_id` (`supplierFk`), @@ -29877,12 +29877,12 @@ CREATE TABLE `invoiceIn` ( KEY `recibida_ibfk_6` (`cplusRectificationTypeFk`), KEY `recibida_ibfk_7` (`siiTrascendencyInvoiceInFk`), KEY `invoiceIn_withholdingFk_idx` (`withholdingSageFk`), - KEY `invoiceIn_expenceFkDeductible_idx` (`expenceFkDeductible`), + KEY `invoiceIn_expenseFkDeductible_idx` (`expenseFkDeductible`), KEY `invoiceIn_fk_editor` (`editorFk`), KEY `invoiceIn_FK` (`currencyFk`), CONSTRAINT `invoiceInCompany_Fk` FOREIGN KEY (`companyFk`) REFERENCES `company` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceIn_FK` FOREIGN KEY (`currencyFk`) REFERENCES `currency` (`id`) ON UPDATE CASCADE, - CONSTRAINT `invoiceIn_expenceFkDeductible` FOREIGN KEY (`expenceFkDeductible`) REFERENCES `expence` (`id`) ON UPDATE CASCADE, + CONSTRAINT `invoiceIn_expenseFkDeductible` FOREIGN KEY (`expenseFkDeductible`) REFERENCES `expense` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceIn_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), CONSTRAINT `invoiceIn_ibfk_3` FOREIGN KEY (`cplusSubjectOpFk`) REFERENCES `cplusSubjectOp` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceIn_ibfk_4` FOREIGN KEY (`cplusTaxBreakFk`) REFERENCES `cplusTaxBreak` (`id`) ON UPDATE CASCADE, @@ -30283,7 +30283,7 @@ CREATE TABLE `invoiceInSage` ( `taxTypeSageFk` smallint(6) NOT NULL, `transactionTypeSageFk` tinyint(4) NOT NULL, `isService` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Para diferenciar producto de servicio', - `expenceFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + `expenseFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `withholdingSageFk` smallint(6) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `invoiceInSafe_unique` (`taxClassFk`,`invoiceInSerialFk`,`isService`,`withholdingSageFk`), @@ -30292,8 +30292,8 @@ CREATE TABLE `invoiceInSage` ( KEY `invoiceInSage_invoiceInSerialFk` (`invoiceInSerialFk`), KEY `invoiceInSage_taxTypeSageFk` (`taxTypeSageFk`), KEY `invoiceInSage_transactionTypeSageFk` (`transactionTypeSageFk`), - KEY `invoiceInSage_idx` (`expenceFk`), - CONSTRAINT `invoiceInSage_expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `expence` (`id`) ON UPDATE CASCADE, + KEY `invoiceInSage_idx` (`expenseFk`), + CONSTRAINT `invoiceInSage_expenseFk` FOREIGN KEY (`expenseFk`) REFERENCES `expense` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceInSage_invoiceInSerialFk` FOREIGN KEY (`invoiceInSerialFk`) REFERENCES `invoiceInSerial` (`code`) ON UPDATE CASCADE, CONSTRAINT `invoiceInSage_taxClassFk` FOREIGN KEY (`taxClassFk`) REFERENCES `taxClass` (`code`) ON UPDATE CASCADE, CONSTRAINT `invoiceInSage_taxTypeSageFk` FOREIGN KEY (`taxTypeSageFk`) REFERENCES `sage`.`TiposIva` (`CodigoIva`) ON UPDATE CASCADE, @@ -30334,7 +30334,7 @@ CREATE TABLE `invoiceInTax` ( `invoiceInFk` mediumint(8) unsigned NOT NULL, `taxCodeFk` int(10) DEFAULT NULL, `taxableBase` decimal(10,2) NOT NULL, - `expenceFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + `expenseFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `foreignValue` decimal(10,2) DEFAULT NULL, `taxTypeSageFk` smallint(6) DEFAULT NULL COMMENT 'Tipo de IVA SAGE', `transactionTypeSageFk` tinyint(4) DEFAULT NULL COMMENT 'Tipo de transacción SAGE', @@ -30345,9 +30345,9 @@ CREATE TABLE `invoiceInTax` ( KEY `recibida_iva_ibfk_2` (`taxCodeFk`), KEY `recibida_iva_taxTypeSageFk` (`taxTypeSageFk`), KEY `invoiceInTax_transactionTypeSageFk_idx` (`transactionTypeSageFk`), - KEY `invoiceInTax_idx` (`expenceFk`), + KEY `invoiceInTax_idx` (`expenseFk`), KEY `invoiceInTax_fk_editor` (`editorFk`), - CONSTRAINT `invoiceInTax_expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `expence` (`id`) ON UPDATE CASCADE, + CONSTRAINT `invoiceInTax_expenseFk` FOREIGN KEY (`expenseFk`) REFERENCES `expense` (`id`) ON UPDATE CASCADE, CONSTRAINT `invoiceInTax_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), CONSTRAINT `invoiceInTax_ibfk_5` FOREIGN KEY (`invoiceInFk`) REFERENCES `invoiceIn` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `invoiceInTax_transactionTypeSageFk` FOREIGN KEY (`transactionTypeSageFk`) REFERENCES `sage`.`TiposTransacciones` (`CodigoTransaccion`) ON UPDATE CASCADE, @@ -30615,23 +30615,23 @@ CREATE TABLE `invoiceOutConfig` ( /*!40101 SET character_set_client = @saved_cs_client */; -- --- Table structure for table `invoiceOutExpence` +-- Table structure for table `invoiceOutExpense` -- -DROP TABLE IF EXISTS `invoiceOutExpence`; +DROP TABLE IF EXISTS `invoiceOutExpense`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE `invoiceOutExpence` ( +CREATE TABLE `invoiceOutExpense` ( `id` int(11) NOT NULL AUTO_INCREMENT, `invoiceOutFk` int(10) unsigned NOT NULL, `amount` decimal(10,2) NOT NULL DEFAULT 0.00, - `expenceFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + `expenseFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `created` timestamp NULL DEFAULT current_timestamp(), PRIMARY KEY (`id`), - KEY `invoiceOutExpence_FK_1_idx` (`invoiceOutFk`), - KEY `invoiceOutExpence_expenceFk_idx` (`expenceFk`), - CONSTRAINT `invoiceOutExpence_FK_1` FOREIGN KEY (`invoiceOutFk`) REFERENCES `invoiceOut` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `invoiceOutExpence_expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `expence` (`id`) ON UPDATE CASCADE + KEY `invoiceOutExpense_FK_1_idx` (`invoiceOutFk`), + KEY `invoiceOutExpense_expenseFk_idx` (`expenseFk`), + CONSTRAINT `invoiceOutExpense_FK_1` FOREIGN KEY (`invoiceOutFk`) REFERENCES `invoiceOut` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `invoiceOutExpense_expenseFk` FOREIGN KEY (`expenseFk`) REFERENCES `expense` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Desglosa la base imponible de una factura en funcion del tipo de gasto/venta'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -30694,7 +30694,7 @@ CREATE TABLE `invoiceOutTaxConfig` ( `taxTypeSageFk` smallint(6) DEFAULT NULL, `transactionTypeSageFk` tinyint(4) DEFAULT NULL, `isService` tinyint(1) DEFAULT 0, - `expenceFk` varchar(10) DEFAULT NULL, + `expenseFk` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`), KEY `invoiceOutTaxConfig_FK` (`taxClassCodeFk`), KEY `invoiceOutTaxConfig_FK_1` (`taxTypeSageFk`), @@ -30737,7 +30737,7 @@ CREATE TABLE `item` ( `description` varchar(1000) DEFAULT NULL, `density` int(11) NOT NULL DEFAULT 167 COMMENT 'Almacena la densidad en kg/m3 para el calculo de los portes, si no se especifica se pone por defecto la del tipo en un trigger', `relevancy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'La web ordena de forma descendiente por este campo para mostrar los artículos', - `expenceFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '7001000000', + `expenseFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '7001000000', `isActive` tinyint(1) NOT NULL DEFAULT 1, `longName` varchar(50) DEFAULT NULL, `subName` varchar(50) DEFAULT NULL, @@ -30792,11 +30792,11 @@ CREATE TABLE `item` ( KEY `item_size_IDX` (`size`) USING BTREE, KEY `item_size_IDX2` (`longName`) USING BTREE, KEY `item_lastUsed_IDX` (`lastUsed`) USING BTREE, - KEY `item_expenceFk_idx` (`expenceFk`), + KEY `item_expenseFk_idx` (`expenseFk`), KEY `item_fk_editor` (`editorFk`), CONSTRAINT `item_FK` FOREIGN KEY (`genericFk`) REFERENCES `item` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT `item_FK_1` FOREIGN KEY (`typeFk`) REFERENCES `itemType` (`id`), - CONSTRAINT `item_expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `expence` (`id`) ON UPDATE CASCADE, + CONSTRAINT `item_expenseFk` FOREIGN KEY (`expenseFk`) REFERENCES `expense` (`id`) ON UPDATE CASCADE, CONSTRAINT `item_family` FOREIGN KEY (`family`) REFERENCES `itemFamily` (`code`) ON UPDATE CASCADE, CONSTRAINT `item_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`), CONSTRAINT `item_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `origin` (`id`) ON UPDATE CASCADE, @@ -40606,10 +40606,10 @@ DROP TABLE IF EXISTS `ticketServiceType`; CREATE TABLE `ticketServiceType` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL, - `expenceFk` varchar(10) NOT NULL DEFAULT '7050000000', + `expenseFk` varchar(10) NOT NULL DEFAULT '7050000000', PRIMARY KEY (`id`), - KEY `ticketServiceType_expenceFk_idx` (`expenceFk`), - CONSTRAINT `ticketServiceType_expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `expence` (`id`) ON UPDATE CASCADE + KEY `ticketServiceType_expenseFk_idx` (`expenseFk`), + CONSTRAINT `ticketServiceType_expenseFk` FOREIGN KEY (`expenseFk`) REFERENCES `expense` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci COMMENT='Lista de los posibles servicios a elegir'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -46533,7 +46533,7 @@ BEGIN WHERE io.ref = vInvoiceRef UNION ALL SELECT ioe.amount - FROM invoiceOutExpence ioe + FROM invoiceOutExpense ioe JOIN invoiceOut io ON io.id = ioe.invoiceOutFk WHERE io.ref = vInvoiceRef ) t1; @@ -57741,7 +57741,7 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `invoiceExpenceMake` */; +/*!50003 DROP PROCEDURE IF EXISTS `invoiceExpenseMake` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -57749,28 +57749,28 @@ DELIMITER ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceExpenceMake`(IN vInvoice INT) +CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceExpenseMake`(IN vInvoice INT) BEGIN /* Inserta las partidas de gasto correspondientes a la factura * REQUIERE tabla tmp.ticketToInvoice * @param vInvoice Numero de factura */ - DELETE FROM invoiceOutExpence + DELETE FROM invoiceOutExpense WHERE invoiceOutFk = vInvoice; - INSERT INTO invoiceOutExpence(invoiceOutFk, expenceFk, amount) + INSERT INTO invoiceOutExpense(invoiceOutFk, expenseFk, amount) SELECT vInvoice, - expenceFk, + expenseFk, SUM(ROUND(quantity * price * (100 - discount)/100,2)) amount FROM tmp.ticketToInvoice t JOIN sale s ON s.ticketFk = t.id JOIN item i ON i.id = s.itemFk - GROUP BY i.expenceFk + GROUP BY i.expenseFk HAVING amount != 0; - INSERT INTO invoiceOutExpence(invoiceOutFk, expenceFk, amount) + INSERT INTO invoiceOutExpense(invoiceOutFk, expenseFk, amount) SELECT vInvoice, - tst.expenceFk, + tst.expenseFk, SUM(ROUND(ts.quantity * ts.price ,2)) amount FROM tmp.ticketToInvoice t JOIN ticketService ts ON ts.ticketFk = t.id @@ -58125,7 +58125,7 @@ CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceInTax_getFromEntries`(IN vId BEGIN DECLARE vRate DOUBLE DEFAULT 1; DECLARE vDated DATE; - DECLARE vExpenceFk VARCHAR(10); + DECLARE vExpenseFk VARCHAR(10); SELECT MAX(rr.dated) INTO vDated FROM referenceRate rr @@ -58139,8 +58139,8 @@ BEGIN WHERE dated = vDated; END IF; - SELECT id INTO vExpenceFk - FROM vn.expence + SELECT id INTO vExpenseFk + FROM vn.expense WHERE `name` = 'Adquisición mercancia Extracomunitaria' GROUP BY id LIMIT 1; @@ -58148,10 +58148,10 @@ BEGIN DELETE FROM invoiceInTax WHERE invoiceInFk = vId; - INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, foreignValue, taxTypeSageFk, transactionTypeSageFk) + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, foreignValue, taxTypeSageFk, transactionTypeSageFk) SELECT ii.id, SUM(b.buyingValue * b.quantity) / IFNULL(vRate,1) taxableBase, - vExpenceFk, + vExpenseFk, IF(ii.currencyFk = 1,NULL,SUM(b.buyingValue * b.quantity )) divisa, taxTypeSageFk, transactionTypeSageFk @@ -58188,7 +58188,7 @@ BEGIN SELECT ii.bookEntried, iit.foreignValue, ii.companyFk, - ii.expenceFkDeductible, + ii.expenseFkDeductible, iit.taxableBase, iit.transactionTypeSageFk, ii.serial, @@ -58218,8 +58218,8 @@ BEGIN cit.id invoicesCount, e.code, e.isWithheld, - e.id expenceFk, - e.name expenceName + e.id expenseFk, + e.name expenseName FROM invoiceIn ii JOIN supplier s ON s.id = ii.supplierFk LEFT JOIN province p ON p.id = s.provinceFk @@ -58231,7 +58231,7 @@ BEGIN JOIN siiTypeInvoiceIn cit ON cit.id = ii.siiTypeInvoiceInFk 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 expense e ON e.id = iit.expenseFk LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk LEFT JOIN sage.taxType tt ON tt.id = ti.CodigoIva WHERE ii.id = vSelf; @@ -58286,7 +58286,7 @@ BEGIN empresa_id) SELECT vBookNumber ASIEN, tii.bookEntried FECHA, - IF(tii.isWithheld, LPAD(RIGHT(tii.supplierAccount, 5), 10, tii.expenceFk),tii.expenceFk) SUBCTA, + IF(tii.isWithheld, LPAD(RIGHT(tii.supplierAccount, 5), 10, tii.expenseFk),tii.expenseFk) 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, @@ -58301,7 +58301,7 @@ BEGIN tii.companyFk empresa_id FROM tInvoiceIn tii WHERE tii.code IS NULL OR tii.code <> 'suplido' - GROUP BY tii.expenceFk; + GROUP BY tii.expenseFk; -- Líneas de IVA INSERT INTO XDiario( @@ -58335,11 +58335,11 @@ BEGIN empresa_id) SELECT vBookNumber ASIEN, tii.bookEntried FECHA, - IF(tii.expenceFkDeductible>0, tii.expenceFkDeductible, tii.CuentaIvaSoportado) SUBCTA, + IF(tii.expenseFkDeductible>0, tii.expenseFkDeductible, 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, + GROUP_CONCAT(DISTINCT tii.expenseName SEPARATOR ', ') CONCEPTO, vSelf FACTURA, tii.PorcentajeIva IVA, IF(tii.isUeeMember AND eWithheld.id IS NULL, '', '*') AUXILIAR, @@ -58365,13 +58365,13 @@ BEGIN LEFT JOIN ( SELECT e.id FROM tInvoiceIn tii - JOIN expence e ON e.id = tii.expenceFk + JOIN expense e ON e.id = tii.expenseFk WHERE e.isWithheld LIMIT 1 ) eWithheld ON TRUE WHERE tii.taxTypeSageFk IS NOT NULL AND (tii.taxCode IS NULL OR tii.taxCode NOT IN ('import10', 'import21')) - GROUP BY tii.PorcentajeIva, tii.expenceFk; + GROUP BY tii.PorcentajeIva, tii.expenseFk; -- Línea iva inversor sujeto pasivo INSERT INTO XDiario( @@ -58408,7 +58408,7 @@ BEGIN 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, + GROUP_CONCAT(DISTINCT tii.expenseName SEPARATOR ', ') CONCEPTO, vSelf FACTURA, tii.PorcentajeIva IVA, '*' AUXILIAR, @@ -58436,7 +58436,7 @@ BEGIN AND NOT(tii.isVies AND c.nontaxableTransactionTypeFk = tii.transactionTypeSageFk AND tii.taxCode = 'nonTaxable') - GROUP BY tii.PorcentajeIva, tii.expenceFk; + GROUP BY tii.PorcentajeIva, tii.expenseFk; -- Actualización del registro original UPDATE invoiceIn ii @@ -58509,14 +58509,14 @@ BEGIN FROM ticket WHERE refFk = vInvoiceRef; - CALL invoiceExpenceMake(vInvoiceFk); + CALL invoiceExpenseMake(vInvoiceFk); CALL invoiceTaxMake(vInvoiceFk,vTaxArea); UPDATE invoiceOut io JOIN ( SELECT SUM(amount) AS total - FROM invoiceOutExpence + FROM invoiceOutExpense WHERE invoiceOutFk = vInvoiceFk ) base JOIN ( @@ -58552,7 +58552,7 @@ BEGIN * param vInvoice factura_id */ DECLARE vBookNumber INT; - DECLARE vExpenceConcept VARCHAR(50); + DECLARE vExpenseConcept VARCHAR(50); DECLARE vSpainCountryFk INT; DECLARE vOldBookNumber INT; @@ -58644,7 +58644,7 @@ BEGIN SELECT vBookNumber AS ASIEN, rs.FECHA, - ioe.expenceFk AS SUBCTA, + ioe.expenseFk AS SUBCTA, rs.clientBookingAccount AS CONTRA, ioe.amount AS EUROHABER, rs.Concept AS CONCEPTO, @@ -58652,13 +58652,13 @@ BEGIN rs.FECHA_OP, rs.companyFk AS empresa_id FROM rs - JOIN invoiceOutExpence ioe + JOIN invoiceOutExpense ioe WHERE ioe.invoiceOutFk = vInvoice; SELECT GROUP_CONCAT(`name` SEPARATOR ',') - INTO vExpenceConcept - FROM expence e - JOIN invoiceOutExpence ioe ON ioe.expenceFk = e.id + INTO vExpenseConcept + FROM expense e + JOIN invoiceOutExpense ioe ON ioe.expenseFk = e.id WHERE ioe.invoiceOutFk = vInvoice; -- Lineas de IVA @@ -58701,7 +58701,7 @@ BEGIN rs.clientBookingAccount AS CONTRA, iot.vat AS EUROHABER, iot.taxableBase AS BASEEURO, - CONCAT(vExpenceConcept,' : ',rs.Concept) AS CONCEPTO, + CONCAT(vExpenseConcept,' : ',rs.Concept) AS CONCEPTO, rs.invoiceNum AS FACTURA, IF(pe2.equFk,0,pgc.rate) AS IVA, IF(pe2.equFk,0,pgce.rate) AS RECEQUIV, @@ -58844,7 +58844,7 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; -/*!50003 DROP PROCEDURE IF EXISTS `invoiceOutTaxAndExpence` */; +/*!50003 DROP PROCEDURE IF EXISTS `invoiceOutTaxAndExpense` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -58852,7 +58852,7 @@ DELIMITER ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; DELIMITER ;; -CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceOutTaxAndExpence`() +CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceOutTaxAndExpense`() BEGIN /* Para tickets ya facturados, vuelve a repetir el proceso de facturación. @@ -58906,7 +58906,7 @@ BEGIN FROM ticket WHERE refFk = vInvoiceRef; - CALL invoiceExpenceMake(vInvoice); + CALL invoiceExpenseMake(vInvoice); CALL invoiceTaxMake(vInvoice,vCountry,vTaxArea); FETCH rs INTO vInvoice ,vInvoiceRef; @@ -59140,13 +59140,13 @@ BEGIN INSERT INTO ticketTracking(stateFk,ticketFk,workerFk) SELECT * FROM tmp.updateInter; - CALL invoiceExpenceMake(vNewInvoiceId); + CALL invoiceExpenseMake(vNewInvoiceId); CALL invoiceTaxMake(vNewInvoiceId,vTaxArea); UPDATE invoiceOut io JOIN ( SELECT SUM(amount) total - FROM invoiceOutExpence + FROM invoiceOutExpense WHERE invoiceOutFk = vNewInvoiceId ) base JOIN ( @@ -59183,15 +59183,15 @@ BEGIN SET @vTaxableBaseServices := 0.00; SET @vTaxCodeGeneral := NULL; - INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk) SELECT vNewInvoiceInFk, @vTaxableBaseServices, - sub.expenceFk, + sub.expenseFk, sub.taxTypeSageFk, sub.transactionTypeSageFk FROM ( SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase, - i.expenceFk, + i.expenseFk, i.taxTypeSageFk, i.transactionTypeSageFk, @vTaxCodeGeneral := i.taxClassCodeFk @@ -59201,11 +59201,11 @@ BEGIN HAVING taxableBase ) sub; - INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk) SELECT vNewInvoiceInFk, SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral, @vTaxableBaseServices, 0) taxableBase, - i.expenceFk, + i.expenseFk, i.taxTypeSageFk , i.transactionTypeSageFk FROM tmp.ticketTax tt diff --git a/modules/invoiceIn/back/locale/invoiceIn/en.yml b/modules/invoiceIn/back/locale/invoiceIn/en.yml index ec9a824b61..9e94eba0d4 100644 --- a/modules/invoiceIn/back/locale/invoiceIn/en.yml +++ b/modules/invoiceIn/back/locale/invoiceIn/en.yml @@ -16,5 +16,5 @@ columns: bookEntried: book entried isVatDeductible: is VAT deductible withholdingSageFk: withholding - expenceFkDeductible: expence deductible + expenseFkDeductible: expense deductible editorFk: editor \ No newline at end of file diff --git a/modules/invoiceIn/back/locale/invoiceIn/es.yml b/modules/invoiceIn/back/locale/invoiceIn/es.yml index 64e96b3792..bd64c4327a 100644 --- a/modules/invoiceIn/back/locale/invoiceIn/es.yml +++ b/modules/invoiceIn/back/locale/invoiceIn/es.yml @@ -16,5 +16,5 @@ columns: bookEntried: fecha asiento isVatDeductible: impuesto deducible withholdingSageFk: código de retención - expenceFkDeductible: gasto deducible + expenseFkDeductible: gasto deducible editorFk: editor \ No newline at end of file diff --git a/modules/invoiceIn/back/locale/invoiceInTax/en.yml b/modules/invoiceIn/back/locale/invoiceInTax/en.yml index c0d12c37df..6af547d3f2 100644 --- a/modules/invoiceIn/back/locale/invoiceInTax/en.yml +++ b/modules/invoiceIn/back/locale/invoiceInTax/en.yml @@ -4,7 +4,7 @@ columns: invoiceInFk: invoice in taxCodeFk: tax taxableBase: taxable base - expenceFk: expence + expenseFk: expense foreignValue: foreign amount taxTypeSageFk: tax type transactionTypeSageFk: transaction type diff --git a/modules/invoiceIn/back/locale/invoiceInTax/es.yml b/modules/invoiceIn/back/locale/invoiceInTax/es.yml index 7cb847ed86..92f3855e44 100644 --- a/modules/invoiceIn/back/locale/invoiceInTax/es.yml +++ b/modules/invoiceIn/back/locale/invoiceInTax/es.yml @@ -4,7 +4,7 @@ columns: invoiceInFk: factura recibida taxCodeFk: código IVA taxableBase: base imponible - expenceFk: código gasto + expenseFk: código gasto foreignValue: importe divisa taxTypeSageFk: código impuesto transactionTypeSageFk: código transacción diff --git a/modules/invoiceIn/back/methods/invoice-in/filter.js b/modules/invoiceIn/back/methods/invoice-in/filter.js index f5eab90999..dd193af85b 100644 --- a/modules/invoiceIn/back/methods/invoice-in/filter.js +++ b/modules/invoiceIn/back/methods/invoice-in/filter.js @@ -146,7 +146,7 @@ module.exports = Self => { ii.docFk AS dmsFk, dm.file, ii.supplierFk, - ii.expenceFkDeductible deductibleExpenseFk, + ii.expenseFkDeductible deductibleExpenseFk, s.name AS supplierName, s.account, SUM(iid.amount) AS amount, diff --git a/modules/invoiceIn/back/models/invoice-in-tax.json b/modules/invoiceIn/back/models/invoice-in-tax.json index 1f68476c3a..bc57a4376b 100644 --- a/modules/invoiceIn/back/models/invoice-in-tax.json +++ b/modules/invoiceIn/back/models/invoice-in-tax.json @@ -21,7 +21,7 @@ "expenseFk": { "type": "number", "mysql": { - "columnName": "expenceFk" + "columnName": "expenseFk" } }, "created": { diff --git a/modules/invoiceIn/back/models/invoice-in.json b/modules/invoiceIn/back/models/invoice-in.json index 7548998668..5be55c8510 100644 --- a/modules/invoiceIn/back/models/invoice-in.json +++ b/modules/invoiceIn/back/models/invoice-in.json @@ -51,7 +51,7 @@ "deductibleExpenseFk": { "type": "number", "mysql": { - "columnName": "expenceFkDeductible" + "columnName": "expenseFkDeductible" } } }, diff --git a/modules/item/back/models/expense.json b/modules/item/back/models/expense.json index 03147c08b2..468063602f 100644 --- a/modules/item/back/models/expense.json +++ b/modules/item/back/models/expense.json @@ -3,7 +3,7 @@ "base": "VnModel", "options": { "mysql": { - "table": "expence" + "table": "expense" } }, "properties": { diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json index 6db1f5efc0..3f3547fd1a 100644 --- a/modules/item/back/models/item.json +++ b/modules/item/back/models/item.json @@ -119,7 +119,7 @@ "expenseFk": { "type": "number", "mysql": { - "columnName": "expenceFk" + "columnName": "expenseFk" } }, "minPrice": { diff --git a/modules/item/front/basic-data/index.html b/modules/item/front/basic-data/index.html index 426c178006..3e47faa5fd 100644 --- a/modules/item/front/basic-data/index.html +++ b/modules/item/front/basic-data/index.html @@ -105,7 +105,7 @@ url="Expenses" label="Expense" ng-model="$ctrl.item.expenseFk" - vn-name="expence" + vn-name="expense" initial-data="$ctrl.item.expense"> diff --git a/modules/route/back/methods/agency-term/createInvoiceIn.js b/modules/route/back/methods/agency-term/createInvoiceIn.js index 5a8430e49f..f00ab95c6c 100644 --- a/modules/route/back/methods/agency-term/createInvoiceIn.js +++ b/modules/route/back/methods/agency-term/createInvoiceIn.js @@ -54,7 +54,7 @@ module.exports = Self => { dmsFk: firstDms.id, }, myOptions); - const expence = await models.AgencyTermConfig.findOne(null, myOptions); + const expense = await models.AgencyTermConfig.findOne(null, myOptions); const [taxTypeSage] = await Self.rawSql(` SELECT IFNULL(s.taxTypeSageFk, CodigoIva) value @@ -78,7 +78,7 @@ module.exports = Self => { await models.InvoiceInTax.create({ invoiceInFk: newInvoiceIn.id, taxableBase: firstRow.totalPrice, - expenseFk: expence.expenceFk, + expenseFk: expense.expenseFk, taxTypeSageFk: taxTypeSage.value, transactionTypeSageFk: transactionTypeSage.value }, myOptions); diff --git a/modules/route/back/models/agency-term-config.json b/modules/route/back/models/agency-term-config.json index c94fc266b2..81a608acfc 100644 --- a/modules/route/back/models/agency-term-config.json +++ b/modules/route/back/models/agency-term-config.json @@ -7,7 +7,7 @@ } }, "properties": { - "expenceFk": { + "expenseFk": { "type": "string", "id": true }, diff --git a/modules/ticket/back/models/ticket-service-type.json b/modules/ticket/back/models/ticket-service-type.json index ec2c9232a5..9340d60230 100644 --- a/modules/ticket/back/models/ticket-service-type.json +++ b/modules/ticket/back/models/ticket-service-type.json @@ -18,7 +18,7 @@ "expenseFk": { "type": "number", "mysql": { - "columnName": "expenceFk" + "columnName": "expenseFk" } } }, From f9d5cad4123a1c032c05e56e36da9927d7f52b10 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 27 Nov 2023 07:57:18 +0100 Subject: [PATCH 291/449] refs #6506 contract --- modules/worker/front/calendar/index.html | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/modules/worker/front/calendar/index.html b/modules/worker/front/calendar/index.html index d64c22408e..0b6732024c 100644 --- a/modules/worker/front/calendar/index.html +++ b/modules/worker/front/calendar/index.html @@ -70,17 +70,18 @@ fields="['started', 'ended']" ng-model="$ctrl.businessId" search-function="{businessFk: $search}" + show-field="businessFk" value-field="businessFk" order="businessFk DESC" limit="5"> - -
#{{businessFk}}
-
- {{started | date: 'dd/MM/yyyy'}} - {{ended ? (ended | date: 'dd/MM/yyyy') : 'Indef.'}} -
-
- - + +
#{{businessFk}}
+
+ {{started | date: 'dd/MM/yyyy'}} - {{ended ? (ended | date: 'dd/MM/yyyy') : 'Indef.'}} +
+
+ +
From 72a0932e35539bd53857a0e3cb9c02916c8e5965 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 27 Nov 2023 09:46:27 +0100 Subject: [PATCH 292/449] refs #6264 other: rename camel-case variable --- back/methods/vn-user/specs/sign-in.spec.js | 12 ++++++------ .../methods/account/specs/change-password.spec.js | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/back/methods/vn-user/specs/sign-in.spec.js b/back/methods/vn-user/specs/sign-in.spec.js index f4cad88b9c..e02c72ad32 100644 --- a/back/methods/vn-user/specs/sign-in.spec.js +++ b/back/methods/vn-user/specs/sign-in.spec.js @@ -2,7 +2,7 @@ const {models} = require('vn-loopback/server/server'); describe('VnUser Sign-in()', () => { const employeeId = 1; - const unauthCtx = { + const unAuthCtx = { req: { headers: {}, connection: { @@ -15,7 +15,7 @@ describe('VnUser Sign-in()', () => { const {VnUser, AccessToken} = models; describe('when credentials are correct', () => { it('should return the token', async() => { - let login = await VnUser.signIn(unauthCtx, 'salesAssistant', 'nightmare'); + let login = await VnUser.signIn(unAuthCtx, 'salesAssistant', 'nightmare'); let accessToken = await AccessToken.findById(login.token); let ctx = {req: {accessToken: accessToken}}; @@ -25,7 +25,7 @@ describe('VnUser Sign-in()', () => { }); it('should return the token if the user doesnt exist but the client does', async() => { - let login = await VnUser.signIn(unauthCtx, 'PetterParker', 'nightmare'); + let login = await VnUser.signIn(unAuthCtx, 'PetterParker', 'nightmare'); let accessToken = await AccessToken.findById(login.token); let ctx = {req: {accessToken: accessToken}}; @@ -40,7 +40,7 @@ describe('VnUser Sign-in()', () => { let error; try { - await VnUser.signIn(unauthCtx, 'IDontExist', 'TotallyWrongPassword'); + await VnUser.signIn(unAuthCtx, 'IDontExist', 'TotallyWrongPassword'); } catch (e) { error = e; } @@ -61,7 +61,7 @@ describe('VnUser Sign-in()', () => { const options = {transaction: tx}; await employee.updateAttribute('twoFactor', 'email', options); - await VnUser.signIn(unauthCtx, 'employee', 'nightmare', options); + await VnUser.signIn(unAuthCtx, 'employee', 'nightmare', options); await tx.rollback(); } catch (e) { await tx.rollback(); @@ -86,7 +86,7 @@ describe('VnUser Sign-in()', () => { const options = {transaction: tx}; await employee.updateAttribute('passExpired', yesterday, options); - await VnUser.signIn(unauthCtx, 'employee', 'nightmare', options); + await VnUser.signIn(unAuthCtx, 'employee', 'nightmare', options); await tx.rollback(); } catch (e) { await tx.rollback(); diff --git a/modules/account/back/methods/account/specs/change-password.spec.js b/modules/account/back/methods/account/specs/change-password.spec.js index 2fa3010afb..c799602128 100644 --- a/modules/account/back/methods/account/specs/change-password.spec.js +++ b/modules/account/back/methods/account/specs/change-password.spec.js @@ -2,7 +2,7 @@ const {models} = require('vn-loopback/server/server'); describe('account changePassword()', () => { const userId = 70; - const unauthCtx = { + const unAuthCtx = { req: { headers: {}, connection: { @@ -79,7 +79,7 @@ describe('account changePassword()', () => { passExpired: yesterday } , options); - await models.VnUser.signIn(unauthCtx, 'trainee', 'nightmare', options); + await models.VnUser.signIn(unAuthCtx, 'trainee', 'nightmare', options); } catch (e) { if (e.message != 'Pass expired') throw e; From 81be3b18f77be9062aed7d29811a8977d7a1b54d Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 27 Nov 2023 09:48:15 +0100 Subject: [PATCH 293/449] refs #6264 test: validate-token and renew-token --- back/methods/vn-user/is-token-valid.js | 5 ++- .../methods/vn-user/specs/renew-token.spec.js | 45 +++++++++++++++---- .../vn-user/specs/validate-token.spec.js | 38 +++++++++++++++- loopback/server/boot/date.js | 3 +- 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/back/methods/vn-user/is-token-valid.js b/back/methods/vn-user/is-token-valid.js index f4c2a9ea80..c5c05a1788 100644 --- a/back/methods/vn-user/is-token-valid.js +++ b/back/methods/vn-user/is-token-valid.js @@ -2,8 +2,9 @@ const tokenConfig = require('./token-config'); module.exports = async token => { const accessTokenConfig = await tokenConfig(); - - const now = Date.vnNew(); + let now = Date.now(); + if (Date?.vnNow !== undefined) + now = Date.vnNow(); const differenceMilliseconds = now - token.created; const differenceSeconds = Math.floor(differenceMilliseconds / 1000); return differenceSeconds > accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime; diff --git a/back/methods/vn-user/specs/renew-token.spec.js b/back/methods/vn-user/specs/renew-token.spec.js index cae91f3107..21d3de1a99 100644 --- a/back/methods/vn-user/specs/renew-token.spec.js +++ b/back/methods/vn-user/specs/renew-token.spec.js @@ -1,22 +1,49 @@ +const {models} = require('vn-loopback/server/server'); describe('Renew Token', () => { - it('Token is valid', async() => { - let login = await VnUser.signIn(unauthCtx, 'salesAssistant', 'nightmare'); - let accessToken = await AccessToken.findById(login.token); - let ctx = {req: {accessToken: accessToken}}; - - expect(login.token).toBeDefined(); + const startingTime = Date.now(); + let ctx = null; + beforeAll(async() => { + const unAuthCtx = { + req: { + headers: {}, + connection: { + remoteAddress: '127.0.0.1' + }, + getLocale: () => 'en' + }, + args: {} + }; + let login = await models.VnUser.signIn(unAuthCtx, 'salesAssistant', 'nightmare'); + let accessToken = await models.AccessToken.findById(login.token); + ctx = {req: {accessToken: accessToken}}; }); - it('Token is is invalid', async() => { + beforeEach(() => { + jasmine.clock().install(); + jasmine.clock().mockDate(new Date(startingTime)); + }); + + afterEach(() => { + jasmine.clock().uninstall(); + }); + + it('should renew process', async() => { + jasmine.clock().mockDate(new Date(startingTime + 21600000)); + const {id} = await models.VnUser.renewToken(ctx); + + expect(id).not.toEqual(ctx.req.accessToken.id); + }); + + it('NOT should renew', async() => { let error; try { - await models.VnUser.validateCode('developer', '123456'); + await models.VnUser.renewToken(ctx); } catch (e) { error = e; } expect(error).toBeDefined(); expect(error.statusCode).toBe(400); - expect(error.message).toEqual('Invalid or expired verification code'); + expect(error.message).toEqual('The renew period has not been exceeded'); }); }); diff --git a/back/methods/vn-user/specs/validate-token.spec.js b/back/methods/vn-user/specs/validate-token.spec.js index 0d0af689f4..25207336d7 100644 --- a/back/methods/vn-user/specs/validate-token.spec.js +++ b/back/methods/vn-user/specs/validate-token.spec.js @@ -1,9 +1,43 @@ -describe('Validate Token', () => { - it('Token is not expired', async() => { +const {models} = require('vn-loopback/server/server'); +describe('Validate Token', () => { + const startingTime = Date.now(); + let ctx = null; + beforeAll(async() => { + const unAuthCtx = { + req: { + headers: {}, + connection: { + remoteAddress: '127.0.0.1' + }, + getLocale: () => 'en' + }, + args: {} + }; + let login = await models.VnUser.signIn(unAuthCtx, 'salesAssistant', 'nightmare'); + let accessToken = await models.AccessToken.findById(login.token); + ctx = {req: {accessToken: accessToken}}; + }); + + beforeEach(() => { + jasmine.clock().install(); + jasmine.clock().mockDate(new Date(startingTime)); + }); + + afterEach(() => { + jasmine.clock().uninstall(); + }); + + it('Token is not expired', async() => { + jasmine.clock().mockDate(new Date(startingTime + 21600000)); + const isValid = await models.VnUser.validateToken(ctx.req.accessToken); + + expect(isValid).toBeTrue(); }); it('Token is expired', async() => { + const isValid = await models.VnUser.validateToken(ctx.req.accessToken); + expect(isValid).toBeFalse(); }); }); diff --git a/loopback/server/boot/date.js b/loopback/server/boot/date.js index 8107455625..d592dc416b 100644 --- a/loopback/server/boot/date.js +++ b/loopback/server/boot/date.js @@ -1,6 +1,5 @@ module.exports = () => { - Date.vnUTC = () => { - const env = process.env.NODE_ENV; + Date.vnUTC = (env = process.env.NODE_ENV) => { if (!env || env === 'development') return new Date(Date.UTC(2001, 0, 1, 11)); From aefff68c2903d94f1470b11d76781635fcad1b8c Mon Sep 17 00:00:00 2001 From: guillermo Date: Mon, 27 Nov 2023 09:51:56 +0100 Subject: [PATCH 294/449] refactor: refs #3222 Requested changes --- modules/invoiceIn/back/models/invoice-in-tax.json | 5 +---- modules/item/back/models/item.json | 8 +------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/modules/invoiceIn/back/models/invoice-in-tax.json b/modules/invoiceIn/back/models/invoice-in-tax.json index bc57a4376b..5bfbbe2a8d 100644 --- a/modules/invoiceIn/back/models/invoice-in-tax.json +++ b/modules/invoiceIn/back/models/invoice-in-tax.json @@ -19,10 +19,7 @@ "type": "number" }, "expenseFk": { - "type": "number", - "mysql": { - "columnName": "expenseFk" - } + "type": "number" }, "created": { "type": "date" diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json index 3f3547fd1a..097fe77088 100644 --- a/modules/item/back/models/item.json +++ b/modules/item/back/models/item.json @@ -117,10 +117,7 @@ "description": "The item family" }, "expenseFk": { - "type": "number", - "mysql": { - "columnName": "expenseFk" - } + "type": "number" }, "minPrice": { "type": "number" @@ -131,9 +128,6 @@ "nonRecycledPlastic": { "type": "number" }, - "minQuantity": { - "type": "number" - }, "packingOut": { "type": "number" }, From 9da5fb9a14e739458f823290b1f1996ad7c1762a Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 27 Nov 2023 10:24:25 +0100 Subject: [PATCH 295/449] refs #6264 other: rename camel-case variable --- back/methods/vn-user/specs/sign-in.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/methods/vn-user/specs/sign-in.spec.js b/back/methods/vn-user/specs/sign-in.spec.js index 99d7b90f90..f800454aa5 100644 --- a/back/methods/vn-user/specs/sign-in.spec.js +++ b/back/methods/vn-user/specs/sign-in.spec.js @@ -15,7 +15,7 @@ describe('VnUser Sign-in()', () => { const {VnUser, AccessToken, SignInLog} = models; describe('when credentials are correct', () => { it('should return the token if user uses email', async() => { - let login = await VnUser.signIn(unauthCtx, 'salesAssistant@mydomain.com', 'nightmare'); + let login = await VnUser.signIn(unAuthCtx, 'salesAssistant@mydomain.com', 'nightmare'); let accessToken = await AccessToken.findById(login.token); let ctx = {req: {accessToken: accessToken}}; let signInLog = await SignInLog.find({where: {token: accessToken.id}}); From 62fab4e74412ed9df395079ee92371deb48b8e1e Mon Sep 17 00:00:00 2001 From: robert Date: Mon, 27 Nov 2023 11:52:37 +0100 Subject: [PATCH 296/449] refs #5854 itemShelving traducciones --- modules/item/back/locale/item-shelving/en.yml | 13 +++++++++++++ modules/item/back/locale/item-shelving/es.yml | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 modules/item/back/locale/item-shelving/en.yml create mode 100644 modules/item/back/locale/item-shelving/es.yml diff --git a/modules/item/back/locale/item-shelving/en.yml b/modules/item/back/locale/item-shelving/en.yml new file mode 100644 index 0000000000..062d4db3f8 --- /dev/null +++ b/modules/item/back/locale/item-shelving/en.yml @@ -0,0 +1,13 @@ +name: itemShelving +columns: + id: id + itemFk: itemFk + shelvingFk: shelvingFk + visible: visible + created: created + grouping: grouping + packing: packing + packagingFk: packagingFk + userFk: userFk + isChecked: isChecked + buyFk: buyFk diff --git a/modules/item/back/locale/item-shelving/es.yml b/modules/item/back/locale/item-shelving/es.yml new file mode 100644 index 0000000000..a64b23bfaa --- /dev/null +++ b/modules/item/back/locale/item-shelving/es.yml @@ -0,0 +1,13 @@ +name: artículo del carro +columns: + id: id + itemFk: artículo + shelvingFk: matrícula carro + visible: visible + created: creado + grouping: agrupación + packing: embalaje + packagingFk: paquete + userFk: usuario + isChecked: está revisado + buyFk: compra \ No newline at end of file From 37555cbb63290c523e2d237d5d058890d59cb751 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 27 Nov 2023 15:10:00 +0100 Subject: [PATCH 297/449] refs #6335 warmFix(ticketAdvance): correct properties --- modules/ticket/front/advance/index.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index fb539311f7..1f47d8242a 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -202,9 +202,9 @@ export default class Controller extends Section { if (!ticket.landed) { const newLanded = await this.getLanded({ shipped: this.$.model.userParams.dateToAdvance, - addressFk: ticket.addressFk, - agencyModeFk: ticket.agencyModeFk, - warehouseFk: ticket.warehouseFk + addressFk: ticket.futureAddressFk, + agencyModeFk: ticket.agencyModeFk ?? ticket.futureAgencyModeFk, + warehouseFk: ticket.futureWarehouseFk }); if (!newLanded) throw new Error(this.$t(`No delivery zone available for this landing date`)); @@ -213,13 +213,13 @@ export default class Controller extends Section { ticket.zoneFk = newLanded.zoneFk; } const params = { - clientFk: ticket.clientFk, + clientFk: ticket.futureClientFk, nickname: ticket.nickname, agencyModeFk: ticket.agencyModeFk ?? ticket.futureAgencyModeFk, - addressFk: ticket.addressFk, + addressFk: ticket.futureAddressFk, zoneFk: ticket.zoneFk ?? ticket.futureZoneFk, - warehouseFk: ticket.warehouseFk, - companyFk: ticket.companyFk, + warehouseFk: ticket.futureWarehouseFk, + companyFk: ticket.futureCompanyFk, shipped: this.$.model.userParams.dateToAdvance, landed: ticket.landed, isDeleted: false, From 50a97693b99d91df8d5c6b776de7d784a6195c4f Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 28 Nov 2023 07:48:42 +0100 Subject: [PATCH 298/449] refs 5666 feat: remove loggable.js file --- loopback/common/models/loggable.js | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 loopback/common/models/loggable.js diff --git a/loopback/common/models/loggable.js b/loopback/common/models/loggable.js deleted file mode 100644 index 360c845661..0000000000 --- a/loopback/common/models/loggable.js +++ /dev/null @@ -1,15 +0,0 @@ -const LoopBackContext = require('loopback-context'); - -module.exports = function(Self) { - Self.setup = function() { - Self.super_.setup.call(this); - }; - - Self.observe('before save', async function(ctx) { - ctx.options.httpCtx = LoopBackContext.getCurrentContext(); - }); - - Self.observe('before delete', async function(ctx) { - ctx.options.httpCtx = LoopBackContext.getCurrentContext(); - }); -}; From f5f2896cbf3be60d1c70d4eb1f850143d1eb0153 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 28 Nov 2023 08:12:16 +0100 Subject: [PATCH 299/449] refs 5666 feat: replace Role model by VnRole model --- back/models/dms-type.json | 4 ++-- back/models/image-collection.json | 5 ++--- back/models/notificationAcl.json | 4 ++-- back/models/vn-user.json | 2 +- modules/account/back/models/role-inherit.json | 4 ++-- modules/account/back/models/role-role.json | 4 ++-- modules/claim/back/models/claim-state.json | 2 +- modules/client/back/models/client-credit-limit.json | 4 ++-- 8 files changed, 14 insertions(+), 15 deletions(-) diff --git a/back/models/dms-type.json b/back/models/dms-type.json index de3d564b43..8d7195132b 100644 --- a/back/models/dms-type.json +++ b/back/models/dms-type.json @@ -29,12 +29,12 @@ "relations": { "readRole": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "readRoleFk" }, "writeRole": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "writeRoleFk" } }, diff --git a/back/models/image-collection.json b/back/models/image-collection.json index 186ab02084..ae0e0adcdd 100644 --- a/back/models/image-collection.json +++ b/back/models/image-collection.json @@ -46,12 +46,12 @@ }, "readRole": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "readRoleFk" }, "writeRole": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "writeRoleFk" } }, @@ -64,4 +64,3 @@ } ] } - \ No newline at end of file diff --git a/back/models/notificationAcl.json b/back/models/notificationAcl.json index a201879610..9ab85530f7 100644 --- a/back/models/notificationAcl.json +++ b/back/models/notificationAcl.json @@ -24,8 +24,8 @@ }, "role": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "roleFk" } } -} \ No newline at end of file +} diff --git a/back/models/vn-user.json b/back/models/vn-user.json index bda0a6ec3d..cf5796123e 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -66,7 +66,7 @@ "relations": { "role": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "roleFk" }, "roles": { diff --git a/modules/account/back/models/role-inherit.json b/modules/account/back/models/role-inherit.json index 4b69ffdc26..a89f47b77a 100644 --- a/modules/account/back/models/role-inherit.json +++ b/modules/account/back/models/role-inherit.json @@ -15,12 +15,12 @@ "relations": { "owner": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "role" }, "inherits": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "inheritsFrom" } } diff --git a/modules/account/back/models/role-role.json b/modules/account/back/models/role-role.json index 77df7a9204..e59351c598 100644 --- a/modules/account/back/models/role-role.json +++ b/modules/account/back/models/role-role.json @@ -14,12 +14,12 @@ "relations": { "owner": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "role" }, "inherits": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "inheritsFrom" } } diff --git a/modules/claim/back/models/claim-state.json b/modules/claim/back/models/claim-state.json index f5bde4168c..3ee932f168 100644 --- a/modules/claim/back/models/claim-state.json +++ b/modules/claim/back/models/claim-state.json @@ -32,7 +32,7 @@ "relations": { "writeRole": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "roleFk" } }, diff --git a/modules/client/back/models/client-credit-limit.json b/modules/client/back/models/client-credit-limit.json index 740f0cf534..922d4d14ba 100644 --- a/modules/client/back/models/client-credit-limit.json +++ b/modules/client/back/models/client-credit-limit.json @@ -19,8 +19,8 @@ "relations": { "role": { "type": "belongsTo", - "model": "Role", + "model": "VnRole", "foreignKey": "roleFk" } } -} \ No newline at end of file +} From 2fa56cce4b0a554b63e12bea0112e047700acbc8 Mon Sep 17 00:00:00 2001 From: jgallego Date: Tue, 28 Nov 2023 09:22:00 +0100 Subject: [PATCH 300/449] fix: refs #5652 arreglo fixtures --- db/dump/fixtures.sql | 6 +++--- .../back/methods/sales-monitor/specs/salesFilter.spec.js | 2 +- modules/ticket/back/methods/ticket/specs/filter.spec.js | 2 +- .../back/methods/ticket/specs/getSalespersonMana.spec.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 93b7b796f1..2d5a4093c1 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -362,7 +362,7 @@ INSERT INTO `vn`.`contactChannel`(`id`, `name`) INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city`,`postcode`,`phone`,`mobile`,`isRelevant`,`email`,`iban`,`dueDay`,`accountingAccount`,`isEqualizated`,`provinceFk`,`hasToInvoice`,`credit`,`countryFk`,`isActive`,`gestdocFk`,`quality`,`payMethodFk`,`created`,`isToBeMailed`,`contactChannelFk`,`hasSepaVnl`,`hasCoreVnl`,`hasCoreVnh`,`riskCalculated`,`clientTypeFk`, `hasToInvoiceByAddress`,`isTaxDataChecked`,`isFreezed`,`creditInsurance`,`isCreatedAsServed`,`hasInvoiceSimplified`,`salesPersonFk`,`isVies`,`eypbc`, `businessTypeFk`,`typeFk`) VALUES - (1101, 'Bruce Wayne', '84612325V', 'BATMAN', 'Alfred', '1007 MOUNTAIN DRIVE, GOTHAM', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist','loses'), + (1101, 'Bruce Wayne', '84612325V', 'BATMAN', 'Alfred', '1007 MOUNTAIN DRIVE, GOTHAM', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist','normal'), (1102, 'Petter Parker', '87945234L', 'SPIDER MAN', 'Aunt May', '20 INGRAM STREET, QUEENS, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist','normal'), (1103, 'Clark Kent', '06815934E', 'SUPER MAN', 'lois lane', '344 CLINTON STREET, APARTAMENT 3-D', 'Gotham', 46460, 1111111111, 222222222, 1, 'ClarkKent@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 0, 19, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist','normal'), (1104, 'Tony Stark', '06089160W', 'IRON MAN', 'Pepper Potts', '10880 MALIBU POINT, 90265', 'Gotham', 46460, 1111111111, 222222222, 1, 'TonyStark@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist','normal'), @@ -372,8 +372,8 @@ INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city (1108, 'Charles Xavier', '22641921P', 'PROFESSOR X', 'Beast', '3800 VICTORY PKWY, CINCINNATI, OH 45207, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 5, 1, 300, 13, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1, 'florist','normal'), (1109, 'Bruce Banner', '16104829E', 'HULK', 'Black widow', 'SOMEWHERE IN NEW YORK', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, 9, 0, 1, 'florist','normal'), (1110, 'Jessica Jones', '58282869H', 'JESSICA JONES', 'Luke Cage', 'NYCC 2015 POSTER', 'Gotham', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, NULL, 0, 1, 'florist','normal'), - (1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','normal'), - (1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','normal'); + (1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','loses'), + (1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','loses'); INSERT INTO `vn`.`client`(`id`, `name`, `fi`, `socialName`, `contact`, `street`, `city`, `postcode`, `isRelevant`, `email`, `iban`,`dueDay`,`accountingAccount`, `isEqualizated`, `provinceFk`, `hasToInvoice`, `credit`, `countryFk`, `isActive`, `gestdocFk`, `quality`, `payMethodFk`,`created`, `isTaxDataChecked`) SELECT id, name, CONCAT(RPAD(CONCAT(id,9),8,id),'A'), CONCAT(name, 'Social'), CONCAT(name, 'Contact'), CONCAT(name, 'Street'), 'GOTHAM', 46460, 1, CONCAT(name,'@mydomain.com'), NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5, util.VN_CURDATE(), 1 diff --git a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js index c3da7f08bc..bdafd14e23 100644 --- a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js +++ b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js @@ -151,7 +151,7 @@ describe('SalesMonitor salesFilter()', () => { const result = await models.SalesMonitor.salesFilter(ctx, filter, options); const firstRow = result[0]; - expect(result.length).toEqual(15); + expect(result.length).toEqual(12); expect(firstRow.alertLevel).not.toEqual(0); await tx.rollback(); diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js index 2e5730980b..43f3c3680f 100644 --- a/modules/ticket/back/methods/ticket/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js @@ -68,7 +68,7 @@ describe('ticket filter()', () => { const filter = {}; const result = await models.Ticket.filter(ctx, filter, options); - expect(result.length).toEqual(9); + expect(result.length).toEqual(6); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket/specs/getSalespersonMana.spec.js b/modules/ticket/back/methods/ticket/specs/getSalespersonMana.spec.js index 12c115ff94..6029ca4a78 100644 --- a/modules/ticket/back/methods/ticket/specs/getSalespersonMana.spec.js +++ b/modules/ticket/back/methods/ticket/specs/getSalespersonMana.spec.js @@ -9,7 +9,7 @@ describe('ticket getSalesPersonMana()', () => { const mana = await models.Ticket.getSalesPersonMana(1, options); - expect(mana).toEqual(73); + expect(mana).toEqual(124); await tx.rollback(); } catch (e) { From f2673c38183ef06dd7c8ed7e04bddd842b53ab52 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 28 Nov 2023 12:12:42 +0100 Subject: [PATCH 301/449] refs #5835 rate added --- modules/invoiceIn/back/methods/invoice-in/summary.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/invoiceIn/back/methods/invoice-in/summary.js b/modules/invoiceIn/back/methods/invoice-in/summary.js index 0e55eeaace..fe198b2b40 100644 --- a/modules/invoiceIn/back/methods/invoice-in/summary.js +++ b/modules/invoiceIn/back/methods/invoice-in/summary.js @@ -112,7 +112,7 @@ module.exports = Self => { { relation: 'taxTypeSage', scope: { - fields: ['vat'] + fields: ['vat', 'rate'] } }] } From 63533459b0991abf3c3d67492c1739780f7bbd98 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 28 Nov 2023 13:22:17 +0100 Subject: [PATCH 302/449] refs #6434 feat: improve signIn method --- back/methods/vn-user/sign-in.js | 8 +--- back/methods/vn-user/specs/sign-in.spec.js | 15 +++--- back/models/vn-user.js | 47 ++++++++++++++----- db/changes/234901/00-createSignInLogTable.sql | 15 ++++++ modules/account/back/models/sign_in-log.json | 7 ++- 5 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 db/changes/234901/00-createSignInLogTable.sql diff --git a/back/methods/vn-user/sign-in.js b/back/methods/vn-user/sign-in.js index 9c2d568f4f..782046641e 100644 --- a/back/methods/vn-user/sign-in.js +++ b/back/methods/vn-user/sign-in.js @@ -49,13 +49,7 @@ module.exports = Self => { if (vnUser.twoFactor) throw new ForbiddenError(null, 'REQUIRES_2FA'); } - const validateLogin = await Self.validateLogin(user, password); - await Self.app.models.SignInLog.create({ - token: validateLogin.token, - userFk: vnUser.id, - ip: ctx.req.ip - }); - return validateLogin; + return Self.validateLogin(user, password, ctx); }; Self.passExpired = async vnUser => { diff --git a/back/methods/vn-user/specs/sign-in.spec.js b/back/methods/vn-user/specs/sign-in.spec.js index ac2dfe2b23..1c4b4af51b 100644 --- a/back/methods/vn-user/specs/sign-in.spec.js +++ b/back/methods/vn-user/specs/sign-in.spec.js @@ -2,7 +2,7 @@ const {models} = require('vn-loopback/server/server'); describe('VnUser Sign-in()', () => { const employeeId = 1; - const unauthCtx = { + const unAuthCtx = { req: { headers: {}, connection: { @@ -15,20 +15,21 @@ describe('VnUser Sign-in()', () => { const {VnUser, AccessToken, SignInLog} = models; describe('when credentials are correct', () => { it('should return the token if user uses email', async() => { - let login = await VnUser.signIn(unauthCtx, 'salesAssistant@mydomain.com', 'nightmare'); + let login = await VnUser.signIn(unAuthCtx, 'salesAssistant@mydomain.com', 'nightmare'); let accessToken = await AccessToken.findById(login.token); let ctx = {req: {accessToken: accessToken}}; let signInLog = await SignInLog.find({where: {token: accessToken.id}}); expect(signInLog.length).toEqual(1); expect(signInLog[0].userFk).toEqual(accessToken.userId); + expect(signInLog[0].owner).toEqual(true); expect(login.token).toBeDefined(); await VnUser.logout(ctx.req.accessToken.id); }); it('should return the token', async() => { - let login = await VnUser.signIn(unauthCtx, 'salesAssistant', 'nightmare'); + let login = await VnUser.signIn(unAuthCtx, 'salesAssistant', 'nightmare'); let accessToken = await AccessToken.findById(login.token); let ctx = {req: {accessToken: accessToken}}; @@ -38,7 +39,7 @@ describe('VnUser Sign-in()', () => { }); it('should return the token if the user doesnt exist but the client does', async() => { - let login = await VnUser.signIn(unauthCtx, 'PetterParker', 'nightmare'); + let login = await VnUser.signIn(unAuthCtx, 'PetterParker', 'nightmare'); let accessToken = await AccessToken.findById(login.token); let ctx = {req: {accessToken: accessToken}}; @@ -53,7 +54,7 @@ describe('VnUser Sign-in()', () => { let error; try { - await VnUser.signIn(unauthCtx, 'IDontExist', 'TotallyWrongPassword'); + await VnUser.signIn(unAuthCtx, 'IDontExist', 'TotallyWrongPassword'); } catch (e) { error = e; } @@ -74,7 +75,7 @@ describe('VnUser Sign-in()', () => { const options = {transaction: tx}; await employee.updateAttribute('twoFactor', 'email', options); - await VnUser.signIn(unauthCtx, 'employee', 'nightmare', options); + await VnUser.signIn(unAuthCtx, 'employee', 'nightmare', options); await tx.rollback(); } catch (e) { await tx.rollback(); @@ -99,7 +100,7 @@ describe('VnUser Sign-in()', () => { const options = {transaction: tx}; await employee.updateAttribute('passExpired', yesterday, options); - await VnUser.signIn(unauthCtx, 'employee', 'nightmare', options); + await VnUser.signIn(unAuthCtx, 'employee', 'nightmare', options); await tx.rollback(); } catch (e) { await tx.rollback(); diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 719e96cbf7..6b9b9bab58 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -124,20 +124,43 @@ module.exports = function(Self) { return email.send(); }); - Self.signInValidate = (user, userToken) => { + + /** + * Sign-in validate. * + * @param {Integer} user The user + * @param {Object} userToken Options + * @param {Object} token accessToken + * @param {Object} ctx context + */ + Self.signInValidate = async(user, userToken, token, ctx) => { const [[key, value]] = Object.entries(Self.userUses(user)); - if (userToken[key].toLowerCase().trim() !== value.toLowerCase().trim()) { - console.error('ERROR!!! - Signin with other user', userToken, user); + const isOwner = Self.rawSql(`SELECT ? = ? `, [userToken[key], value]); + await Self.app.models.SignInLog.create({ + token: token.id, + userFk: userToken.id, + ip: ctx.req.ip, + owner: isOwner + }); + if (!isOwner) { + console.error('ERROR!!! - SignIn with other user', userToken, user); throw new UserError('Try again'); } }; - Self.validateLogin = async function(user, password) { + /** + * Validate login params* + * @param {String} user The user + * @param {String} password + * @param {Object} ctx context + */ + Self.validateLogin = async function(user, password, ctx) { const loginInfo = Object.assign({password}, Self.userUses(user)); const token = await Self.login(loginInfo, 'user'); const userToken = await token.user.get(); - Self.signInValidate(user, userToken); + + if (ctx) + await Self.signInValidate(user, userToken, token, ctx); try { await Self.app.models.Account.sync(userToken.name, password); @@ -187,8 +210,8 @@ module.exports = function(Self) { }; Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls = - Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls - .filter(acl => acl.property != 'changePassword'); + Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls + .filter(acl => acl.property != 'changePassword'); Self.userSecurity = async(ctx, userId, options) => { const models = Self.app.models; @@ -226,10 +249,12 @@ module.exports = function(Self) { const env = process.env.NODE_ENV; const liliumUrl = await Self.app.models.Url.findOne({ - where: {and: [ - {appName: 'lilium'}, - {environment: env} - ]} + where: { + and: [ + {appName: 'lilium'}, + {environment: env} + ] + } }); class Mailer { diff --git a/db/changes/234901/00-createSignInLogTable.sql b/db/changes/234901/00-createSignInLogTable.sql new file mode 100644 index 0000000000..f772683757 --- /dev/null +++ b/db/changes/234901/00-createSignInLogTable.sql @@ -0,0 +1,15 @@ + +DROP TABLE IF EXISTS `account`.`signInLog`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `account`.`signInLog` ( + id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `token` varchar(255) NOT NULL , + `userFk` int(10) unsigned DEFAULT NULL, + `creationDate` timestamp NULL DEFAULT current_timestamp(), + `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, + `owner` tinyint(1) DEFAULT 1, + KEY `userFk` (`userFk`), + CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +); + diff --git a/modules/account/back/models/sign_in-log.json b/modules/account/back/models/sign_in-log.json index c5c014e60a..0da3dc3ddb 100644 --- a/modules/account/back/models/sign_in-log.json +++ b/modules/account/back/models/sign_in-log.json @@ -25,7 +25,12 @@ "type": "number" }, "ip": { - "type": "string" + "type": "string" + }, + "owner": { + "type": "boolean", + "required": true, + "default": true } }, "relations": { From 29fb36010cd303390b1f56b686d57d644f67ce88 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 28 Nov 2023 14:48:03 +0100 Subject: [PATCH 303/449] refs #6274 back methods created --- db/changes/235001/00-timecontrol.sql | 13 ++++++++++++ .../methods/worker-time-control/clockIn.js | 19 +++++++++--------- .../methods/worker-time-control/getClockIn.js | 20 ++++++++++--------- .../back/methods/worker-time-control/login.js | 10 +++------- 4 files changed, 37 insertions(+), 25 deletions(-) create mode 100644 db/changes/235001/00-timecontrol.sql diff --git a/db/changes/235001/00-timecontrol.sql b/db/changes/235001/00-timecontrol.sql new file mode 100644 index 0000000000..ac7dc85d6d --- /dev/null +++ b/db/changes/235001/00-timecontrol.sql @@ -0,0 +1,13 @@ +INSERT INTO `account`.`role` (name, description) + VALUES ('timeControl','Tablet para fichar'); + +INSERT INTO `account`.`roleInherit` (role, inheritsFrom) + VALUES (127, 11); + +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('workerTimeControl', 'login', 'READ', 'ALLOW', 'ROLE', '*'), + ('workerTimeControl', 'getClockIn', 'READ', 'ALLOW', 'ROLE', '*'), + ('workerTimeControl', 'clockIn', 'WRITE', 'ALLOW', 'ROLE', '*'); + +CALL `account`.`role_sync`(); diff --git a/modules/worker/back/methods/worker-time-control/clockIn.js b/modules/worker/back/methods/worker-time-control/clockIn.js index 45de85f1db..3cc57d3418 100644 --- a/modules/worker/back/methods/worker-time-control/clockIn.js +++ b/modules/worker/back/methods/worker-time-control/clockIn.js @@ -1,7 +1,7 @@ module.exports = Self => { - Self.remoteMethodCtx('clockIn', { + Self.remoteMethod('clockIn', { description: 'Check if the employee can clock in', - accessType: 'READ', + accessType: 'WRITE', accepts: [ { arg: 'workerFk', @@ -10,25 +10,26 @@ module.exports = Self => { }, { arg: 'direction', - type: 'integer' + type: 'string' }, - { - arg: 'key', - type: 'string', - } + ], http: { path: `/clockIn`, verb: 'POST' + }, + returns: { + type: 'Object', + root: true } }); - Self.clockIn = async(ctx, pin, direction, key, options) => { + Self.clockIn = async(workerFk, direction, options) => { const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); const query = 'CALL vn.workerTimeControl_clockIn(?, NULL, ?)'; - return await Self.rawSql(query, [workerFk, direction], options); + return await Self.rawSql(query, [workerFk, direction], myOptions); }; }; diff --git a/modules/worker/back/methods/worker-time-control/getClockIn.js b/modules/worker/back/methods/worker-time-control/getClockIn.js index 603914655d..bc0675db85 100644 --- a/modules/worker/back/methods/worker-time-control/getClockIn.js +++ b/modules/worker/back/methods/worker-time-control/getClockIn.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethodCtx('getClockIn', { + Self.remoteMethod('getClockIn', { description: 'Shows the clockings for each day, in columns per day', accessType: 'READ', accepts: [ @@ -8,23 +8,25 @@ module.exports = Self => { type: 'int', required: true, }, - { - arg: 'key', - type: 'string', - } + ], http: { path: `/getClockIn`, - verb: 'POST' - } + verb: 'GET' + }, + returns: { + type: ['Object'], + root: true + }, }); - Self.getClockIn = async(ctx, workerFk, key, options) => { + Self.getClockIn = async(workerFk, options) => { const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); const query = `CALL vn.workerTimeControl_getClockIn(?, CURDATE())`; - return await Self.rawSql(query, [workerFk], myOptions); + const [result] = await Self.rawSql(query, [workerFk], myOptions); + return result; }; }; diff --git a/modules/worker/back/methods/worker-time-control/login.js b/modules/worker/back/methods/worker-time-control/login.js index 75813411af..894b5ba178 100644 --- a/modules/worker/back/methods/worker-time-control/login.js +++ b/modules/worker/back/methods/worker-time-control/login.js @@ -1,7 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethodCtx('login', { + Self.remoteMethod('login', { description: 'Consult the user\'s information and the buttons that must be activated after logging in', accessType: 'READ', accepts: [ @@ -10,10 +10,6 @@ module.exports = Self => { type: 'string', required: true, }, - { - arg: 'key', - type: 'string', - } ], returns: { type: 'Object', @@ -25,7 +21,7 @@ module.exports = Self => { } }); - Self.login = async(ctx, pin, key, options) => { + Self.login = async(pin, options) => { const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); @@ -34,6 +30,6 @@ module.exports = Self => { const user = await Self.rawSql(query, [pin], myOptions); if (!user) throw new UserError('Indique el pin.'); - return user; + return user[0][0]; }; }; From 0186c2c80678f518de105192d1e306f2361f056a Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 29 Nov 2023 07:33:49 +0100 Subject: [PATCH 304/449] refs #6085 aclMail back --- db/changes/235001/00-aclsMails.sql | 7 ++++ .../account/front/alias/acl/create/index.js | 33 +++++++++++++++++++ modules/account/front/alias/acl/index.js | 4 +++ .../account/front/alias/acl/index/index.js | 15 +++++++++ modules/account/front/alias/acl/main/index.js | 18 ++++++++++ 5 files changed, 77 insertions(+) create mode 100644 db/changes/235001/00-aclsMails.sql create mode 100644 modules/account/front/alias/acl/create/index.js create mode 100644 modules/account/front/alias/acl/index.js create mode 100644 modules/account/front/alias/acl/index/index.js create mode 100644 modules/account/front/alias/acl/main/index.js diff --git a/db/changes/235001/00-aclsMails.sql b/db/changes/235001/00-aclsMails.sql new file mode 100644 index 0000000000..92603aec48 --- /dev/null +++ b/db/changes/235001/00-aclsMails.sql @@ -0,0 +1,7 @@ +-- Definición de la tabla mailAliasACL +CREATE TABLE `account`.`mailAliasACL` ( + `mailAliasFk` int(10) unsigned NOT NULL, + `roleFk` int(10) unsigned NOT NULL, + FOREIGN KEY (`mailAliasFk`) REFERENCES `account`.`mailAlias` (`id`), + FOREIGN KEY (`roleFk`) REFERENCES `account`.`role` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; diff --git a/modules/account/front/alias/acl/create/index.js b/modules/account/front/alias/acl/create/index.js new file mode 100644 index 0000000000..1f9d732723 --- /dev/null +++ b/modules/account/front/alias/acl/create/index.js @@ -0,0 +1,33 @@ +import ngModule from '../../module'; +import Section from 'salix/components/section'; + +export default class Controller extends Section { + constructor(...args) { + super(...args); + this.accessTypes = [ + {name: '*'}, + {name: 'READ'}, + {name: 'WRITE'} + ]; + this.permissions = [ + {name: 'ALLOW'}, + {name: 'DENY'} + ]; + + this.models = []; + for (let model in window.validations) + this.models.push({name: model}); + + this.acl = { + property: '*', + principalType: 'ROLE', + accessType: 'READ', + permission: 'ALLOW' + }; + } +} + +ngModule.component('vnAclMailCreate', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/account/front/alias/acl/index.js b/modules/account/front/alias/acl/index.js new file mode 100644 index 0000000000..8393859a5a --- /dev/null +++ b/modules/account/front/alias/acl/index.js @@ -0,0 +1,4 @@ +import './main'; +import './index/'; +import './create'; +import './search-panel'; diff --git a/modules/account/front/alias/acl/index/index.js b/modules/account/front/alias/acl/index/index.js new file mode 100644 index 0000000000..b78dfa7f51 --- /dev/null +++ b/modules/account/front/alias/acl/index/index.js @@ -0,0 +1,15 @@ +import ngModule from '../../module'; +import Section from 'salix/components/section'; + +export default class Controller extends Section { + onDelete(row) { + return this.$http.delete(`ACLs/${row.id}`) + .then(() => this.$.model.refresh()) + .then(() => this.vnApp.showSuccess(this.$t('ACL removed'))); + } +} + +ngModule.component('vnAclMailIndex', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/account/front/alias/acl/main/index.js b/modules/account/front/alias/acl/main/index.js new file mode 100644 index 0000000000..431ef48c50 --- /dev/null +++ b/modules/account/front/alias/acl/main/index.js @@ -0,0 +1,18 @@ +import ngModule from '../../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class ACL extends ModuleMain { + exprBuilder(param, value) { + switch (param) { + case 'search': + return {model: {like: `%${value}%`}}; + default: + return {[param]: value}; + } + } +} + +ngModule.vnComponent('vnAclMailComponent', { + controller: ACL, + template: require('./index.html') +}); From e548ef4dae1d056cfc2f34396a3e3e164ee2b9a8 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 29 Nov 2023 07:51:58 +0100 Subject: [PATCH 305/449] refs #6085 searchpanel and change path --- .../account/front/alias/acl/create/index.js | 4 +-- .../account/front/alias/acl/index/index.js | 4 +-- modules/account/front/alias/acl/main/index.js | 6 ++--- .../front/alias/acl/search-panel/index.js | 26 +++++++++++++++++++ modules/account/front/alias/index.js | 1 + 5 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 modules/account/front/alias/acl/search-panel/index.js diff --git a/modules/account/front/alias/acl/create/index.js b/modules/account/front/alias/acl/create/index.js index 1f9d732723..58e70e4aa7 100644 --- a/modules/account/front/alias/acl/create/index.js +++ b/modules/account/front/alias/acl/create/index.js @@ -1,4 +1,4 @@ -import ngModule from '../../module'; +import ngModule from '../../../module'; import Section from 'salix/components/section'; export default class Controller extends Section { @@ -28,6 +28,6 @@ export default class Controller extends Section { } ngModule.component('vnAclMailCreate', { - template: require('./index.html'), + // template: require('./index.html'), controller: Controller }); diff --git a/modules/account/front/alias/acl/index/index.js b/modules/account/front/alias/acl/index/index.js index b78dfa7f51..5d8d495747 100644 --- a/modules/account/front/alias/acl/index/index.js +++ b/modules/account/front/alias/acl/index/index.js @@ -1,4 +1,4 @@ -import ngModule from '../../module'; +import ngModule from '../../../module'; import Section from 'salix/components/section'; export default class Controller extends Section { @@ -10,6 +10,6 @@ export default class Controller extends Section { } ngModule.component('vnAclMailIndex', { - template: require('./index.html'), + // template: require('./index.html'), controller: Controller }); diff --git a/modules/account/front/alias/acl/main/index.js b/modules/account/front/alias/acl/main/index.js index 431ef48c50..97f04ee503 100644 --- a/modules/account/front/alias/acl/main/index.js +++ b/modules/account/front/alias/acl/main/index.js @@ -1,4 +1,4 @@ -import ngModule from '../../module'; +import ngModule from '../../../module'; import ModuleMain from 'salix/components/module-main'; export default class ACL extends ModuleMain { @@ -13,6 +13,6 @@ export default class ACL extends ModuleMain { } ngModule.vnComponent('vnAclMailComponent', { - controller: ACL, - template: require('./index.html') + controller: ACL + // template: require('./index.html') }); diff --git a/modules/account/front/alias/acl/search-panel/index.js b/modules/account/front/alias/acl/search-panel/index.js new file mode 100644 index 0000000000..67db333834 --- /dev/null +++ b/modules/account/front/alias/acl/search-panel/index.js @@ -0,0 +1,26 @@ +import ngModule from '../../../module'; +import SearchPanel from 'core/components/searchbar/search-panel'; + +export default class Controller extends SearchPanel { + constructor(...args) { + super(...args); + this.accessTypes = [ + {name: '*'}, + {name: 'READ'}, + {name: 'WRITE'} + ]; + this.permissions = [ + {name: 'ALLOW'}, + {name: 'DENY'} + ]; + + this.models = []; + for (let model in window.validations) + this.models.push({name: model}); + } +} + +ngModule.component('vnAclSearchPanel', { + // template: require('./index.html'), + controller: Controller +}); diff --git a/modules/account/front/alias/index.js b/modules/account/front/alias/index.js index 8eed3a3d3d..5984217494 100644 --- a/modules/account/front/alias/index.js +++ b/modules/account/front/alias/index.js @@ -7,3 +7,4 @@ import './descriptor'; import './create'; import './basic-data'; import './users'; +import './acl'; From 48dd068190e20819d9906b8212c5f1c74b58e00d Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 29 Nov 2023 08:37:56 +0100 Subject: [PATCH 306/449] refs #6274 upperCase Model --- db/changes/235001/00-timecontrol.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db/changes/235001/00-timecontrol.sql b/db/changes/235001/00-timecontrol.sql index ac7dc85d6d..4e350b002a 100644 --- a/db/changes/235001/00-timecontrol.sql +++ b/db/changes/235001/00-timecontrol.sql @@ -6,8 +6,8 @@ INSERT INTO `account`.`roleInherit` (role, inheritsFrom) INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) VALUES - ('workerTimeControl', 'login', 'READ', 'ALLOW', 'ROLE', '*'), - ('workerTimeControl', 'getClockIn', 'READ', 'ALLOW', 'ROLE', '*'), - ('workerTimeControl', 'clockIn', 'WRITE', 'ALLOW', 'ROLE', '*'); + ('WorkerTimeControl', 'login', 'READ', 'ALLOW', 'ROLE', 'timeControl'), + ('WorkerTimeControl', 'getClockIn', 'READ', 'ALLOW', 'ROLE', 'timeControl'), + ('WorkerTimeControl', 'clockIn', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'); CALL `account`.`role_sync`(); From 2e22984e77de749f76d93f36821350160c3ad138 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 29 Nov 2023 09:13:54 +0100 Subject: [PATCH 307/449] refs #6197 fix: add salix role in fixtures --- db/dump/fixtures.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 93b7b796f1..441026f43d 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1,3 +1,7 @@ +CREATE ROLE 'salix'; +GRANT 'salix' TO 'root'@'%'; +SET DEFAULT ROLE 'salix' FOR 'root'@'%'; + CREATE SCHEMA IF NOT EXISTS `vn2008`; CREATE SCHEMA IF NOT EXISTS `tmp`; From 9a3efdd6fe9e29cf0dd6ca97c8c384e26bd99a53 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 29 Nov 2023 13:55:44 +0100 Subject: [PATCH 308/449] refs #6085 model y back --- modules/account/back/models/mail-alias-acl.js | 70 +++++++++++++++++++ .../account/back/models/mail-alias-acl.json | 29 ++++++++ 2 files changed, 99 insertions(+) create mode 100644 modules/account/back/models/mail-alias-acl.js create mode 100644 modules/account/back/models/mail-alias-acl.json diff --git a/modules/account/back/models/mail-alias-acl.js b/modules/account/back/models/mail-alias-acl.js new file mode 100644 index 0000000000..4a74472fed --- /dev/null +++ b/modules/account/back/models/mail-alias-acl.js @@ -0,0 +1,70 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + require('../methods/notification/getList')(Self); + + Self.observe('before save', async function(ctx) { + await checkModifyPermission(ctx); + }); + + Self.observe('before delete', async function(ctx) { + await checkModifyPermission(ctx); + }); + + async function checkModifyPermission(ctx) { + const models = Self.app.models; + const instance = ctx.instance; + const userId = ctx.options.accessToken.userId; + + let mailAliasFk; + let roleFk; + + if (instance) { + mailAliasFk = instance.mailAliasFk; + roleFk = instance.roleFk; + } else { + const mailAliasAcl = await models.MailAlias.findById(ctx.where.id); + mailAliasFk = mailAliasAcl.id; + roleFk = mailAliasAcl.roleFk; + } + + const role = await models.VnUser.findById(roleFk, {fields: ['id', 'role']}); + const available = await Self.getAvailable(roleFk); + const hasAcl = available.has(mailAliasFk); + + if (!hasAcl || (userId.role != role)) + throw new UserError('The alias cant be modified'); + } + + Self.getAvailable = async function(userId, options) { + const availableMailAliasMap = new Map(); + const models = Self.app.models; + + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const roles = await models.RoleMapping.find({ + fields: ['roleId'], + where: {principalId: userId} + }, myOptions); + + const availableMailAlias = await models.MailAliasAcl.find({ + fields: ['mailAliasFk', 'roleFk'], + include: {relation: 'roleFk'}, + where: { + roleFk: { + inq: roles.map(role => role.roleId), + }, + } + }, myOptions); + + for (available of availableMailAlias) { + availableMailAliasMap.set(available.mailAliasFk, { + mailAliasFk: available.mailAliasFk, + }); + } + return availableMailAliasMap; + }; +}; diff --git a/modules/account/back/models/mail-alias-acl.json b/modules/account/back/models/mail-alias-acl.json new file mode 100644 index 0000000000..2e44f38ebb --- /dev/null +++ b/modules/account/back/models/mail-alias-acl.json @@ -0,0 +1,29 @@ +{ + "name": "mailAliasACL", + "base": "VnModel", + "options": { + "mysql": { + "table": "account.mailAliasACL" + } + }, + "properties": { + "mailAliasFk": { + "type": "number" + }, + "roleFk": { + "type": "number" + } + }, + "relations": { + "mailAlias": { + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "mailAliasFk" + }, + "role": { + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "roleFk" + } + } +} From 48b82b02cad3501d599c4ef688942de5f0ecf807 Mon Sep 17 00:00:00 2001 From: JAVIER SEGARRA MARTINEZ Date: Wed, 29 Nov 2023 19:32:10 +0000 Subject: [PATCH 309/449] refs #6434 change param type for signInValidate --- back/models/vn-user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 6b9b9bab58..e32d83a367 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -127,7 +127,7 @@ module.exports = function(Self) { /** * Sign-in validate. * - * @param {Integer} user The user + * @param {String} user The user * @param {Object} userToken Options * @param {Object} token accessToken * @param {Object} ctx context From ed6c0924d794e1a99a1f08e9c69ba55303120c24 Mon Sep 17 00:00:00 2001 From: JAVIER SEGARRA MARTINEZ Date: Wed, 29 Nov 2023 19:33:04 +0000 Subject: [PATCH 310/449] refs #6434 perf: remove console.error --- back/models/vn-user.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index e32d83a367..288bd4d1f4 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -141,10 +141,8 @@ module.exports = function(Self) { ip: ctx.req.ip, owner: isOwner }); - if (!isOwner) { - console.error('ERROR!!! - SignIn with other user', userToken, user); + if (!isOwner) throw new UserError('Try again'); - } }; /** From 9176cdb4cbed343727f470d01bc0cfff9a65ad8b Mon Sep 17 00:00:00 2001 From: JAVIER SEGARRA MARTINEZ Date: Wed, 29 Nov 2023 19:34:00 +0000 Subject: [PATCH 311/449] refs #6434 perf: new field in SignInLog table --- back/models/vn-user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 288bd4d1f4..ad0f88d8c4 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -136,6 +136,7 @@ module.exports = function(Self) { const [[key, value]] = Object.entries(Self.userUses(user)); const isOwner = Self.rawSql(`SELECT ? = ? `, [userToken[key], value]); await Self.app.models.SignInLog.create({ + userName: user, token: token.id, userFk: userToken.id, ip: ctx.req.ip, From 46774b2e73b42fefa147803770e54adfd992a06c Mon Sep 17 00:00:00 2001 From: JAVIER SEGARRA MARTINEZ Date: Wed, 29 Nov 2023 19:35:37 +0000 Subject: [PATCH 312/449] refs #6434 perf: new field in SignInLog table --- db/changes/234901/00-createSignInLogTable.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/db/changes/234901/00-createSignInLogTable.sql b/db/changes/234901/00-createSignInLogTable.sql index f772683757..49187c9cb6 100644 --- a/db/changes/234901/00-createSignInLogTable.sql +++ b/db/changes/234901/00-createSignInLogTable.sql @@ -7,6 +7,7 @@ CREATE TABLE `account`.`signInLog` ( `token` varchar(255) NOT NULL , `userFk` int(10) unsigned DEFAULT NULL, `creationDate` timestamp NULL DEFAULT current_timestamp(), + `userName` varchar(30) NOT NULL, `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `owner` tinyint(1) DEFAULT 1, KEY `userFk` (`userFk`), From 1576ab992d2cc6a4b5f1e89efa5c2c6136c52634 Mon Sep 17 00:00:00 2001 From: JAVIER SEGARRA MARTINEZ Date: Wed, 29 Nov 2023 19:36:30 +0000 Subject: [PATCH 313/449] refs #6434 perf: new field in SignInLog table --- modules/account/back/models/sign_in-log.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/account/back/models/sign_in-log.json b/modules/account/back/models/sign_in-log.json index 0da3dc3ddb..8656e92dc2 100644 --- a/modules/account/back/models/sign_in-log.json +++ b/modules/account/back/models/sign_in-log.json @@ -27,6 +27,9 @@ "ip": { "type": "string" }, + "userName": { + "type": "string" + }, "owner": { "type": "boolean", "required": true, From d4cd23853ffbd474ee7c55401437c47763a204ef Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 30 Nov 2023 07:32:16 +0100 Subject: [PATCH 314/449] refs #6264 perf: try to remove jasmine.clock() --- back/methods/vn-user/is-token-valid.js | 6 ++---- back/methods/vn-user/renew-token.js | 2 +- back/methods/vn-user/specs/validate-token.spec.js | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/back/methods/vn-user/is-token-valid.js b/back/methods/vn-user/is-token-valid.js index c5c05a1788..23b68797ea 100644 --- a/back/methods/vn-user/is-token-valid.js +++ b/back/methods/vn-user/is-token-valid.js @@ -2,10 +2,8 @@ const tokenConfig = require('./token-config'); module.exports = async token => { const accessTokenConfig = await tokenConfig(); - let now = Date.now(); - if (Date?.vnNow !== undefined) - now = Date.vnNow(); + const now = Date.now(); const differenceMilliseconds = now - token.created; const differenceSeconds = Math.floor(differenceMilliseconds / 1000); - return differenceSeconds > accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime; + return differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime; }; diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index 4226886fc2..cb88e665dc 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -29,7 +29,7 @@ module.exports = Self => { // Check if current token is valid const isValid = await Self.validateToken(token); - if (!isValid) throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded'); + if (isValid) throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded'); const {courtesyTime} = await tokenConfig(); diff --git a/back/methods/vn-user/specs/validate-token.spec.js b/back/methods/vn-user/specs/validate-token.spec.js index 25207336d7..ec254d0e5a 100644 --- a/back/methods/vn-user/specs/validate-token.spec.js +++ b/back/methods/vn-user/specs/validate-token.spec.js @@ -29,13 +29,13 @@ describe('Validate Token', () => { }); it('Token is not expired', async() => { - jasmine.clock().mockDate(new Date(startingTime + 21600000)); const isValid = await models.VnUser.validateToken(ctx.req.accessToken); expect(isValid).toBeTrue(); }); it('Token is expired', async() => { + jasmine.clock().mockDate(new Date(startingTime + 21600000)); const isValid = await models.VnUser.validateToken(ctx.req.accessToken); expect(isValid).toBeFalse(); From 138d11b7b0cb72c3b0d91fa553eaf32cfba5b8de Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 30 Nov 2023 08:10:32 +0100 Subject: [PATCH 315/449] refs #6434 perf new version folder for sql file --- db/changes/{234604 => 264802}/00-createSignInLogTable.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{234604 => 264802}/00-createSignInLogTable.sql (100%) diff --git a/db/changes/234604/00-createSignInLogTable.sql b/db/changes/264802/00-createSignInLogTable.sql similarity index 100% rename from db/changes/234604/00-createSignInLogTable.sql rename to db/changes/264802/00-createSignInLogTable.sql From 6b354a20adc64aed73826740de80839051aca1c0 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 30 Nov 2023 08:13:28 +0100 Subject: [PATCH 316/449] refs #6434 perf: add sql table description --- db/changes/234901/00-createSignInLogTable.sql | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/db/changes/234901/00-createSignInLogTable.sql b/db/changes/234901/00-createSignInLogTable.sql index 49187c9cb6..942f651c97 100644 --- a/db/changes/234901/00-createSignInLogTable.sql +++ b/db/changes/234901/00-createSignInLogTable.sql @@ -1,4 +1,9 @@ +-- +-- Table structure for table `signInLog` +-- Description: log to debug cross-login error +-- + DROP TABLE IF EXISTS `account`.`signInLog`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; From 58855a7cddb75720369e9eb596f96f0e16f8f692 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 30 Nov 2023 08:14:56 +0100 Subject: [PATCH 317/449] refs #6434 perf: remove bad characters method description --- back/models/vn-user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index ad0f88d8c4..e14cd30eac 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -126,7 +126,7 @@ module.exports = function(Self) { }); /** - * Sign-in validate. * + * Sign-in validate * @param {String} user The user * @param {Object} userToken Options * @param {Object} token accessToken @@ -147,7 +147,7 @@ module.exports = function(Self) { }; /** - * Validate login params* + * Validate login params * @param {String} user The user * @param {String} password * @param {Object} ctx context From 80f8037f58f72f0e3ecdf34755d81422951eebe8 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 30 Nov 2023 08:23:14 +0100 Subject: [PATCH 318/449] refs #6434 perf remove version folder for sql file --- db/changes/264802/00-createSignInLogTable.sql | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 db/changes/264802/00-createSignInLogTable.sql diff --git a/db/changes/264802/00-createSignInLogTable.sql b/db/changes/264802/00-createSignInLogTable.sql deleted file mode 100644 index 5253481357..0000000000 --- a/db/changes/264802/00-createSignInLogTable.sql +++ /dev/null @@ -1,20 +0,0 @@ - - --- --- Table structure for table `signInLog` --- Description: log to debug cross-login error --- - -DROP TABLE IF EXISTS `account`.`signInLog`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `account`.`signInLog` ( - id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, - `token` varchar(255) NOT NULL , - `userFk` int(10) unsigned DEFAULT NULL, - `creationDate` timestamp NULL DEFAULT current_timestamp(), - `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - KEY `userFk` (`userFk`), - CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -); - From 7611acb8f2d156358b8d4699594cfbc2ac3157f6 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 30 Nov 2023 08:34:10 +0100 Subject: [PATCH 319/449] refs #6434 perf rename version folder for sql file --- db/changes/{234901 => 234802}/00-createSignInLogTable.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{234901 => 234802}/00-createSignInLogTable.sql (100%) diff --git a/db/changes/234901/00-createSignInLogTable.sql b/db/changes/234802/00-createSignInLogTable.sql similarity index 100% rename from db/changes/234901/00-createSignInLogTable.sql rename to db/changes/234802/00-createSignInLogTable.sql From 9cdb7c3ccab620912c1a4bb9c7c7ac955895c00e Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 30 Nov 2023 09:18:00 +0100 Subject: [PATCH 320/449] refs #6065 remove workcenter --- modules/worker/front/time-control/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index f8a94be527..f6a6ed535c 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -111,8 +111,10 @@ class Controller extends Section { dayIndex.setDate(dayIndex.getDate() + 1); } - this.fetchHours(); - this.getWeekData(); + if (this.worker) { + this.fetchHours(); + this.getWeekData(); + } } set weekTotalHours(totalHours) { @@ -171,8 +173,6 @@ class Controller extends Section { ]} }; this.$.model.applyFilter(filter, params).then(() => { - if (!this.card.hasWorkCenter) return; - this.getWorkedHours(this.started, this.ended); this.getAbsences(); }); From 3f22f48df728e16624d86985df9e180ad448e510 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 30 Nov 2023 12:13:12 +0100 Subject: [PATCH 321/449] fix(getFiltered): refs #3271 fix to event filter --- db/dump/fixtures.sql | 6 +- .../back/methods/route/getExternalCmrs.js | 190 +++++++++--------- .../back/methods/zone/getEventsFiltered.js | 57 +++--- .../zone/specs/getEventsFiltered.spec.js | 10 +- 4 files changed, 133 insertions(+), 130 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 788487ed07..a0b97b34e1 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2343,9 +2343,11 @@ INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `weekDays`) (8, 'indefinitely', 'mon,tue,wed,thu,fri,sat,sun'), (10, 'indefinitely', 'mon,tue,wed,thu,fri,sat,sun'); -INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `started`, `ended`) +INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `started`, `ended`, `weekDays`) VALUES - (9, 'range', DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR), DATE_ADD(util.VN_CURDATE(), INTERVAL +1 YEAR)); + (9, 'range', DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR), DATE_ADD(util.VN_CURDATE(), INTERVAL +1 YEAR), 'mon'), + (9, 'range', util.VN_CURDATE(), NULL, 'tue'), + (9, 'range', NULL, util.VN_CURDATE(), 'wed'); INSERT INTO `vn`.`workerTimeControl`(`userFk`, `timed`, `manual`, `direction`, `isSendMail`) VALUES diff --git a/modules/route/back/methods/route/getExternalCmrs.js b/modules/route/back/methods/route/getExternalCmrs.js index 4750e53a1e..3fc9798b05 100644 --- a/modules/route/back/methods/route/getExternalCmrs.js +++ b/modules/route/back/methods/route/getExternalCmrs.js @@ -3,99 +3,101 @@ const buildFilter = require('vn-loopback/util/filter').buildFilter; const mergeFilters = require('vn-loopback/util/filter').mergeFilters; module.exports = Self => { - Self.remoteMethod('getExternalCmrs', { - description: 'Returns an array of external cmrs', - accessType: 'READ', - accepts: [ - { - arg: 'filter', - type: 'object', - description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', - }, - { - arg: 'cmrFk', - type: 'integer', - description: 'Searchs the route by id', - }, - { - arg: 'ticketFk', - type: 'integer', - description: 'The worker id', - }, - { - arg: 'routeFk', - type: 'integer', - description: 'The route id', - }, - { - arg: 'country', - type: 'string', - description: 'The agencyMode id', - }, - { - arg: 'clientFk', - type: 'integer', - description: 'The vehicle id', - }, - { - arg: 'hasCmrDms', - type: 'boolean', - description: 'The vehicle id', - }, - { - arg: 'shipped', - type: 'date', - description: 'The to date filter', - }, - ], - returns: { - type: ['object'], - root: true - }, - http: { - path: `/getExternalCmrs`, - verb: 'GET' - } - }); + Self.remoteMethod('getExternalCmrs', { + description: 'Returns an array of external cmrs', + accessType: 'READ', + accepts: [ + { + arg: 'filter', + type: 'object', + description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', + }, + { + arg: 'cmrFk', + type: 'integer', + description: 'Searchs the route by id', + }, + { + arg: 'ticketFk', + type: 'integer', + description: 'The worker id', + }, + { + arg: 'routeFk', + type: 'integer', + description: 'The route id', + }, + { + arg: 'country', + type: 'string', + description: 'The agencyMode id', + }, + { + arg: 'clientFk', + type: 'integer', + description: 'The vehicle id', + }, + { + arg: 'hasCmrDms', + type: 'boolean', + description: 'The vehicle id', + }, + { + arg: 'shipped', + type: 'date', + description: 'The to date filter', + }, + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/getExternalCmrs`, + verb: 'GET' + } + }); - Self.getExternalCmrs = async( - filter, - cmrFk, - ticketFk, - routeFk, - country, - clientFk, - hasCmrDms, - shipped, - options - ) => { - const params = { - cmrFk, - ticketFk, - routeFk, - country, - clientFk, - hasCmrDms, - shipped, - }; - const conn = Self.dataSource.connector; + Self.getExternalCmrs = async( + filter, + cmrFk, + ticketFk, + routeFk, + country, + clientFk, + hasCmrDms, + shipped, + options + ) => { + const params = { + cmrFk, + ticketFk, + routeFk, + country, + clientFk, + hasCmrDms, + shipped, + }; + const conn = Self.dataSource.connector; - let where = buildFilter(params, (param, value) => {return {[param]: value}}); - filter = mergeFilters(filter, {where}); + let where = buildFilter(params, (param, value) => { + return {[param]: value}; + }); + filter = mergeFilters(filter, {where}); - if (!filter.where) { - const yesterday = new Date(); - yesterday.setDate(yesterday.getDate() - 1); - filter.where = {'shipped': yesterday.toISOString().split('T')[0]} - } + if (!filter.where) { + const yesterday = new Date(); + yesterday.setDate(yesterday.getDate() - 1); + filter.where = {'shipped': yesterday.toISOString().split('T')[0]}; + } - const myOptions = {}; + const myOptions = {}; - if (typeof options == 'object') - Object.assign(myOptions, options); + if (typeof options == 'object') + Object.assign(myOptions, options); - let stmts = []; - const stmt = new ParameterizedSQL(` + let stmts = []; + const stmt = new ParameterizedSQL(` SELECT * FROM ( SELECT t.cmrFk, @@ -129,13 +131,13 @@ module.exports = Self => { AND dm.code = 'DELIVERY' AND t.cmrFk ) sub - `); + `); - stmt.merge(conn.makeSuffix(filter)); - const itemsIndex = stmts.push(stmt) - 1; + stmt.merge(conn.makeSuffix(filter)); + const itemsIndex = stmts.push(stmt) - 1; - const sql = ParameterizedSQL.join(stmts, ';'); - const result = await conn.executeStmt(sql); - return itemsIndex === 0 ? result : result[itemsIndex]; - }; + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql); + return itemsIndex === 0 ? result : result[itemsIndex]; + }; }; diff --git a/modules/zone/back/methods/zone/getEventsFiltered.js b/modules/zone/back/methods/zone/getEventsFiltered.js index b7875785df..85db76a583 100644 --- a/modules/zone/back/methods/zone/getEventsFiltered.js +++ b/modules/zone/back/methods/zone/getEventsFiltered.js @@ -35,44 +35,39 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - query = ` - SELECT * - FROM vn.zoneEvent - WHERE zoneFk = ? - AND ((type = 'indefinitely') - OR (type = 'day' AND dated BETWEEN ? AND ?) - OR (type = 'range' - AND ( - (started BETWEEN ? AND ?) - OR - (ended BETWEEN ? AND ?) - OR - (started <= ? AND ended >= ?) - ) - ) - ) - ORDER BY type='indefinitely' DESC, type='range' DESC, type='day' DESC;`; - const events = await Self.rawSql(query, - [zoneFk, started, ended, started, ended, started, ended, started, ended], myOptions); + ended = simpleDate(ended); + started = simpleDate(started); query = ` - SELECT e.* - FROM vn.zoneExclusion e - LEFT JOIN vn.zoneExclusionGeo eg ON eg.zoneExclusionFk = e.id - WHERE e.zoneFk = ? - AND e.dated BETWEEN ? AND ? - AND eg.zoneExclusionFk IS NULL;`; + SELECT * + FROM vn.zoneEvent + WHERE zoneFk = ? + AND (IFNULL(started, ?) <= ? AND IFNULL(ended,?) >= ?) + ORDER BY type='indefinitely' DESC, type='range' DESC, type='day' DESC;`; + const events = await Self.rawSql(query, + [zoneFk, started, ended, ended, started], myOptions); + + query = ` + SELECT e.* + FROM vn.zoneExclusion e + LEFT JOIN vn.zoneExclusionGeo eg ON eg.zoneExclusionFk = e.id + WHERE e.zoneFk = ? + AND e.dated BETWEEN ? AND ? + AND eg.zoneExclusionFk IS NULL;`; const exclusions = await Self.rawSql(query, [zoneFk, started, ended], myOptions); query = ` - SELECT eg.*, e.zoneFk, e.dated, e.created, e.userFk - FROM vn.zoneExclusion e - LEFT JOIN vn.zoneExclusionGeo eg ON eg.zoneExclusionFk = e.id - WHERE e.zoneFk = ? - AND e.dated BETWEEN ? AND ? - AND eg.zoneExclusionFk IS NOT NULL;`; + SELECT eg.*, e.zoneFk, e.dated, e.created, e.userFk + FROM vn.zoneExclusion e + LEFT JOIN vn.zoneExclusionGeo eg ON eg.zoneExclusionFk = e.id + WHERE e.zoneFk = ? + AND e.dated BETWEEN ? AND ? + AND eg.zoneExclusionFk IS NOT NULL;`; const geoExclusions = await Self.rawSql(query, [zoneFk, started, ended], myOptions); return {events, exclusions, geoExclusions}; }; + function simpleDate(date) { + return date.toISOString().split('T')[0]; + } }; diff --git a/modules/zone/back/methods/zone/specs/getEventsFiltered.spec.js b/modules/zone/back/methods/zone/specs/getEventsFiltered.spec.js index 6fd6bb9944..d1c7f1fc49 100644 --- a/modules/zone/back/methods/zone/specs/getEventsFiltered.spec.js +++ b/modules/zone/back/methods/zone/specs/getEventsFiltered.spec.js @@ -30,7 +30,7 @@ describe('zone getEventsFiltered()', () => { const result = await models.Zone.getEventsFiltered(9, today, today, options); - expect(result.events.length).toEqual(1); + expect(result.events.length).toEqual(3); expect(result.exclusions.length).toEqual(0); await tx.rollback(); @@ -47,11 +47,15 @@ describe('zone getEventsFiltered()', () => { const options = {transaction: tx}; const date = Date.vnNew(); date.setFullYear(date.getFullYear() - 2); - const dateTomorrow = new Date(date.setDate(date.getDate() + 1)); + const dateTomorrow = new Date(date); + dateTomorrow.setDate(dateTomorrow.getDate() + 1); const result = await models.Zone.getEventsFiltered(9, date, dateTomorrow, options); + console.log('dateTomorrow: ', dateTomorrow); + console.log('date: ', date); + console.log('result: ', result); - expect(result.events.length).toEqual(0); + expect(result.events.length).toEqual(1); expect(result.exclusions.length).toEqual(0); await tx.rollback(); From 16001099b61adc0d297f88c204e0748e5c3ee57f Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 30 Nov 2023 12:15:48 +0100 Subject: [PATCH 322/449] refs #5666 feat: update ACLs for role and vnRole --- db/changes/235001/00-updateACL_Role_VnRole.sql | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 db/changes/235001/00-updateACL_Role_VnRole.sql diff --git a/db/changes/235001/00-updateACL_Role_VnRole.sql b/db/changes/235001/00-updateACL_Role_VnRole.sql new file mode 100644 index 0000000000..0b10839910 --- /dev/null +++ b/db/changes/235001/00-updateACL_Role_VnRole.sql @@ -0,0 +1,8 @@ +-- Auto-generated SQL script #202311301038 +INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) + VALUES ('VnRole','*','*','ALLOW','ROLE','$everyone'); +INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) + VALUES ('VnRole','*','*','ALLOW','ROLE','employee'); + +-- Auto-generated SQL script #202311301203 +UPDATE `salix`.`ACL` SET permission='DENY' WHERE model='Role'; From 01e713522415ac0710145f802eb0e8b9384cadbb Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 30 Nov 2023 12:20:05 +0100 Subject: [PATCH 323/449] refs #5666 feat: replace Role by VnRole in front --- modules/account/front/acl/create/index.html | 4 ++-- modules/account/front/acl/search-panel/index.html | 6 +++--- modules/account/front/create/index.html | 2 +- modules/account/front/privileges/index.html | 2 +- modules/account/front/role/basic-data/index.html | 8 ++++---- modules/account/front/role/card/index.js | 2 +- modules/account/front/role/create/index.html | 6 +++--- modules/account/front/role/descriptor/index.js | 2 +- modules/account/front/role/main/index.html | 4 ++-- modules/account/front/role/subroles/index.html | 6 +++--- modules/account/front/role/summary/index.js | 2 +- modules/account/front/search-panel/index.html | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/modules/account/front/acl/create/index.html b/modules/account/front/acl/create/index.html index 7f4fa9e462..14332f737a 100644 --- a/modules/account/front/acl/create/index.html +++ b/modules/account/front/acl/create/index.html @@ -15,7 +15,7 @@ @@ -32,7 +32,7 @@ diff --git a/modules/account/front/acl/search-panel/index.html b/modules/account/front/acl/search-panel/index.html index b83b9c255c..a3efab440d 100644 --- a/modules/account/front/acl/search-panel/index.html +++ b/modules/account/front/acl/search-panel/index.html @@ -4,7 +4,7 @@ -
\ No newline at end of file + diff --git a/modules/account/front/create/index.html b/modules/account/front/create/index.html index acc07d3468..70a5188857 100644 --- a/modules/account/front/create/index.html +++ b/modules/account/front/create/index.html @@ -30,7 +30,7 @@ + url="VnRoles"> diff --git a/modules/account/front/role/basic-data/index.html b/modules/account/front/role/basic-data/index.html index 7499271864..a6d39f3e32 100644 --- a/modules/account/front/role/basic-data/index.html +++ b/modules/account/front/role/basic-data/index.html @@ -1,6 +1,6 @@ @@ -11,13 +11,13 @@ @@ -35,4 +35,4 @@ ng-click="watcher.loadOriginalData()"> - \ No newline at end of file + diff --git a/modules/account/front/role/card/index.js b/modules/account/front/role/card/index.js index 6f888211de..3c7c758efc 100644 --- a/modules/account/front/role/card/index.js +++ b/modules/account/front/role/card/index.js @@ -3,7 +3,7 @@ import ModuleCard from 'salix/components/module-card'; class Controller extends ModuleCard { reload() { - this.$http.get(`Roles/${this.$params.id}`) + this.$http.get(`VnRoles/${this.$params.id}`) .then(res => this.role = res.data); } } diff --git a/modules/account/front/role/create/index.html b/modules/account/front/role/create/index.html index 02900d5808..b747f7d00e 100644 --- a/modules/account/front/role/create/index.html +++ b/modules/account/front/role/create/index.html @@ -1,6 +1,6 @@ @@ -12,13 +12,13 @@ diff --git a/modules/account/front/role/descriptor/index.js b/modules/account/front/role/descriptor/index.js index a1b5781336..17b585cb79 100644 --- a/modules/account/front/role/descriptor/index.js +++ b/modules/account/front/role/descriptor/index.js @@ -11,7 +11,7 @@ class Controller extends Descriptor { } onDelete() { - return this.$http.delete(`Roles/${this.id}`) + return this.$http.delete(`VnRoles/${this.id}`) .then(() => this.$state.go('account.role')) .then(() => this.vnApp.showSuccess(this.$t('Role removed'))); } diff --git a/modules/account/front/role/main/index.html b/modules/account/front/role/main/index.html index 9d7e6e053a..cfef28e57a 100644 --- a/modules/account/front/role/main/index.html +++ b/modules/account/front/role/main/index.html @@ -1,6 +1,6 @@ @@ -15,4 +15,4 @@ - \ No newline at end of file + diff --git a/modules/account/front/role/subroles/index.html b/modules/account/front/role/subroles/index.html index bc554b9f93..eba1002b0e 100644 --- a/modules/account/front/role/subroles/index.html +++ b/modules/account/front/role/subroles/index.html @@ -33,14 +33,14 @@ ng-click="$ctrl.onAddClick()" fixed-bottom-right> - @@ -49,7 +49,7 @@ - this.$.summary = res.data); } diff --git a/modules/account/front/search-panel/index.html b/modules/account/front/search-panel/index.html index f80b537aa4..a539d96576 100644 --- a/modules/account/front/search-panel/index.html +++ b/modules/account/front/search-panel/index.html @@ -19,7 +19,7 @@ vn-one label="Role" ng-model="filter.roleFk" - url="Roles" + url="VnRoles" value-field="id" show-field="name"> @@ -28,4 +28,4 @@ - \ No newline at end of file + From ab69dcd4fe5c182f71713de516ff12c40a29a792 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 30 Nov 2023 12:32:41 +0100 Subject: [PATCH 324/449] refs #6524 fix: fixtures and feat: new changelog format --- CHANGELOG.md | 13 ++++++------- db/dump/fixtures.sql | 4 ++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f16511b68..70174ede3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,14 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [2348.01] - 2023-11-30 -### Added -- (Ticket -> Adelantar) Permite mover lineas sin generar negativos -- (Ticket -> Adelantar) Permite modificar la fecha de los tickets -- (Trabajadores -> Notificaciones) Nueva sección (lilium) +### Características Añadidas 🆕 +- **Tickets → Adelantar:** Permite mover lineas sin generar negativos +- **Tickets → Adelantar:** Permite modificar la fecha de los tickets +- **Trabajadores → Notificaciones:** Nueva sección (lilium) -### Changed -### Fixed -- (Ticket -> RocketChat) Arreglada detección de cambios +### Correcciones 🛠️ +- **Tickets → RocketChat:** Arreglada detección de cambios ## [2346.01] - 2023-11-16 diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 788487ed07..d9eed401e4 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1,6 +1,10 @@ CREATE SCHEMA IF NOT EXISTS `vn2008`; CREATE SCHEMA IF NOT EXISTS `tmp`; +CREATE ROLE 'salix'; +GRANT 'salix' TO 'root'@'%'; +SET DEFAULT ROLE 'salix' FOR 'root'@'%'; + UPDATE `util`.`config` SET `environment`= 'development'; From 8ab981907d2f1db8b702883e5790a8c01cf247c5 Mon Sep 17 00:00:00 2001 From: davidd Date: Thu, 30 Nov 2023 14:25:00 +0100 Subject: [PATCH 325/449] refactor(ticketTracking.userFk): refs #6398 workerFk to userFk --- db/changes/235001/00-alterTable.sql | 1 + db/changes/235001/01-procedures.sql | 1129 +++++++++++++++++ db/changes/235001/02-views.sql | 34 + db/dump/fixtures.sql | 3 +- .../importToNewRefundTicket.js | 2 +- .../back/methods/ticket/specs/state.spec.js | 20 +- modules/ticket/back/methods/ticket/state.js | 4 +- modules/ticket/back/models/ticket-state.json | 10 +- modules/ticket/back/models/ticket-tracking.js | 2 +- .../ticket/back/models/ticket-tracking.json | 26 +- modules/ticket/front/tracking/index/index.js | 10 +- modules/zone/back/methods/zone/deleteZone.js | 2 +- 12 files changed, 1201 insertions(+), 42 deletions(-) create mode 100644 db/changes/235001/00-alterTable.sql create mode 100644 db/changes/235001/01-procedures.sql create mode 100644 db/changes/235001/02-views.sql diff --git a/db/changes/235001/00-alterTable.sql b/db/changes/235001/00-alterTable.sql new file mode 100644 index 0000000000..b6974b715a --- /dev/null +++ b/db/changes/235001/00-alterTable.sql @@ -0,0 +1 @@ +ALTER TABLE `vn`.`ticketTracking` CHANGE `workerFk` `userFk` int(10) unsigned DEFAULT NULL NULL; \ No newline at end of file diff --git a/db/changes/235001/01-procedures.sql b/db/changes/235001/01-procedures.sql new file mode 100644 index 0000000000..121348fbf9 --- /dev/null +++ b/db/changes/235001/01-procedures.sql @@ -0,0 +1,1129 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `hedera`.`order_confirmWithUser`(vSelf INT, vUserId INT) +BEGIN +/** + * Confirms an order, creating each of its tickets on the corresponding + * date, store and user. + * + * @param vSelf The order identifier + * @param vUser The user identifier + */ + DECLARE vOk BOOL; + DECLARE vDone BOOL DEFAULT FALSE; + DECLARE vWarehouse INT; + DECLARE vShipment DATE; + DECLARE vTicket INT; + DECLARE vNotes VARCHAR(255); + DECLARE vItem INT; + DECLARE vConcept VARCHAR(30); + DECLARE vAmount INT; + DECLARE vPrice DECIMAL(10,2); + DECLARE vSale INT; + DECLARE vRate INT; + DECLARE vRowId INT; + DECLARE vPriceFixed DECIMAL(10,2); + DECLARE vDelivery DATE; + DECLARE vAddress INT; + DECLARE vIsConfirmed BOOL; + DECLARE vClientId INT; + DECLARE vCompanyId INT; + DECLARE vAgencyModeId INT; + DECLARE TICKET_FREE INT DEFAULT 2; + DECLARE vCalc INT; + DECLARE vIsLogifloraItem BOOL; + DECLARE vOldQuantity INT; + DECLARE vNewQuantity INT; + DECLARE vIsTaxDataChecked BOOL; + + DECLARE cDates CURSOR FOR + SELECT zgs.shipped, r.warehouse_id + FROM `order` o + JOIN order_row r ON r.order_id = o.id + LEFT JOIN tmp.zoneGetShipped zgs ON zgs.warehouseFk = r.warehouse_id + WHERE o.id = vSelf AND r.amount != 0 + GROUP BY r.warehouse_id; + + DECLARE cRows CURSOR FOR + SELECT r.id, r.item_id, i.name, r.amount, r.price, r.rate, i.isFloramondo + FROM order_row r + JOIN vn.item i ON i.id = r.item_id + WHERE r.amount != 0 + AND r.warehouse_id = vWarehouse + AND r.order_id = vSelf + ORDER BY r.rate DESC; + + DECLARE CONTINUE HANDLER FOR NOT FOUND + SET vDone = TRUE; + + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + ROLLBACK; + RESIGNAL; + END; + + -- Carga los datos del pedido + SELECT o.date_send, o.address_id, o.note, a.clientFk, + o.company_id, o.agency_id, c.isTaxDataChecked + INTO vDelivery, vAddress, vNotes, vClientId, + vCompanyId, vAgencyModeId, vIsTaxDataChecked + FROM hedera.`order` o + JOIN vn.address a ON a.id = o.address_id + JOIN vn.client c ON c.id = a.clientFk + WHERE o.id = vSelf; + + -- Verifica si el cliente tiene los datos comprobados + IF NOT vIsTaxDataChecked THEN + CALL util.throw ('clientNotVerified'); + END IF; + + -- Carga las fechas de salida de cada almacen + CALL vn.zone_getShipped (vDelivery, vAddress, vAgencyModeId, FALSE); + + -- Trabajador que realiza la accion + IF vUserId IS NULL THEN + SELECT employeeFk INTO vUserId FROM orderConfig; + END IF; + + START TRANSACTION; + + CALL order_checkEditable(vSelf); + + -- Check order is not empty + + SELECT COUNT(*) > 0 INTO vOk + FROM order_row WHERE order_id = vSelf AND amount > 0; + + IF NOT vOk THEN + CALL util.throw ('ORDER_EMPTY'); + END IF; + + -- Crea los tickets del pedido + + OPEN cDates; + + lDates: + LOOP + SET vTicket = NULL; + SET vDone = FALSE; + FETCH cDates INTO vShipment, vWarehouse; + + IF vDone THEN + LEAVE lDates; + END IF; + + -- Busca un ticket existente que coincida con los parametros + WITH tPrevia AS + (SELECT DISTINCT s.ticketFk + FROM vn.sale s + JOIN vn.saleGroupDetail sgd ON sgd.saleFk = s.id + JOIN vn.ticket t ON t.id = s.ticketFk + WHERE t.shipped BETWEEN vShipment AND util.dayend(vShipment) + ) + SELECT t.id INTO vTicket + FROM vn.ticket t + LEFT JOIN tPrevia tp ON tp.ticketFk = t.id + LEFT JOIN vn.ticketState tls on tls.ticket = t.id + JOIN hedera.`order` o + ON o.address_id = t.addressFk + AND vWarehouse = t.warehouseFk + AND o.date_send = t.landed + AND DATE(t.shipped) = vShipment + WHERE o.id = vSelf + AND t.refFk IS NULL + AND tp.ticketFk IS NULL + AND IFNULL(tls.alertLevel,0) = 0 + LIMIT 1; + + -- Crea el ticket en el caso de no existir uno adecuado + IF vTicket IS NULL + THEN + + SET vShipment = IFNULL(vShipment, util.VN_CURDATE()); + + CALL vn.ticket_add( + vClientId, + vShipment, + vWarehouse, + vCompanyId, + vAddress, + vAgencyModeId, + NULL, + vDelivery, + vUserId, + TRUE, + vTicket + ); + ELSE + INSERT INTO vn.ticketTracking + SET ticketFk = vTicket, + userFk = vUserId, + stateFk = TICKET_FREE; + END IF; + + INSERT IGNORE INTO vn.orderTicket + SET orderFk = vSelf, + ticketFk = vTicket; + + -- Añade las notas + + IF vNotes IS NOT NULL AND vNotes != '' + THEN + INSERT INTO vn.ticketObservation SET + ticketFk = vTicket, + observationTypeFk = 4 /* salesperson */, + `description` = vNotes + ON DUPLICATE KEY UPDATE + `description` = CONCAT(VALUES(`description`),'. ', `description`); + END IF; + + -- Añade los movimientos y sus componentes + + OPEN cRows; + + lRows: LOOP + SET vDone = FALSE; + FETCH cRows INTO vRowId, vItem, vConcept, vAmount, vPrice, vRate, vIsLogifloraItem; + + IF vDone THEN + LEAVE lRows; + END IF; + + SET vSale = NULL; + + SELECT s.id, s.quantity INTO vSale, vOldQuantity + FROM vn.sale s + WHERE ticketFk = vTicket + AND price = vPrice + AND itemFk = vItem + AND discount = 0 + LIMIT 1; + + IF vSale THEN + UPDATE vn.sale + SET quantity = quantity + vAmount, + originalQuantity = quantity + WHERE id = vSale; + + SELECT s.quantity INTO vNewQuantity + FROM vn.sale s + WHERE id = vSale; + ELSE + -- Obtiene el coste + SELECT SUM(rc.`price`) valueSum INTO vPriceFixed + FROM orderRowComponent rc + JOIN vn.component c ON c.id = rc.componentFk + JOIN vn.componentType ct ON ct.id = c.typeFk AND ct.isBase + WHERE rc.rowFk = vRowId; + + INSERT INTO vn.sale + SET itemFk = vItem, + ticketFk = vTicket, + concept = vConcept, + quantity = vAmount, + price = vPrice, + priceFixed = vPriceFixed, + isPriceFixed = TRUE; + + SET vSale = LAST_INSERT_ID(); + + INSERT INTO vn.saleComponent + (saleFk, componentFk, `value`) + SELECT vSale, rc.componentFk, rc.price + FROM orderRowComponent rc + JOIN vn.component c ON c.id = rc.componentFk + WHERE rc.rowFk = vRowId + GROUP BY vSale, rc.componentFk; + END IF; + + UPDATE order_row SET Id_Movimiento = vSale + WHERE id = vRowId; + + -- Inserta en putOrder si la compra es de Floramondo + IF vIsLogifloraItem THEN + CALL cache.availableNoRaids_refresh(vCalc,FALSE,vWarehouse,vShipment); + + SET @available := 0; + + SELECT GREATEST(0,available) INTO @available + FROM cache.availableNoRaids + WHERE calc_id = vCalc + AND item_id = vItem; + + UPDATE cache.availableNoRaids + SET available = GREATEST(0,available - vAmount) + WHERE item_id = vItem + AND calc_id = vCalc; + + INSERT INTO edi.putOrder ( + deliveryInformationID, + supplyResponseId, + quantity , + EndUserPartyId, + EndUserPartyGLN, + FHAdminNumber, + saleFk + ) + SELECT di.ID, + i.supplyResponseFk, + CEIL((vAmount - @available)/ sr.NumberOfItemsPerCask), + o.address_id , + vClientId, + IFNULL(ca.fhAdminNumber, fhc.defaultAdminNumber), + vSale + FROM edi.deliveryInformation di + JOIN vn.item i ON i.supplyResponseFk = di.supplyResponseID + JOIN edi.supplyResponse sr ON sr.ID = i.supplyResponseFk + LEFT JOIN edi.clientFHAdminNumber ca ON ca.clientFk = vClientId + JOIN edi.floraHollandConfig fhc + JOIN hedera.`order` o ON o.id = vSelf + WHERE i.id = vItem + AND di.LatestOrderDateTime > util.VN_NOW() + AND vAmount > @available + LIMIT 1; + END IF; + END LOOP; + + CLOSE cRows; + END LOOP; + + CLOSE cDates; + + UPDATE `order` SET confirmed = TRUE, confirm_date = util.VN_NOW() + WHERE id = vSelf; + + COMMIT; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceOut_new`( + vSerial VARCHAR(255), + vInvoiceDate DATE, + vTaxArea VARCHAR(25), + OUT vNewInvoiceId INT) +BEGIN +/** + * Creación de facturas emitidas. + * requiere previamente tabla tmp.ticketToInvoice(id). + * + * @param vSerial serie a la cual se hace la factura + * @param vInvoiceDate fecha de la factura + * @param vTaxArea tipo de iva en relacion a la empresa y al cliente + * @param vNewInvoiceId id de la factura que se acaba de generar + * @return vNewInvoiceId + */ + DECLARE vIsAnySaleToInvoice BOOL; + DECLARE vIsAnyServiceToInvoice BOOL; + DECLARE vNewRef VARCHAR(255); + DECLARE vWorker INT DEFAULT account.myUser_getId(); + DECLARE vCompanyFk INT; + DECLARE vInterCompanyFk INT; + DECLARE vClientFk INT; + DECLARE vCplusStandardInvoiceTypeFk INT DEFAULT 1; + DECLARE vCplusCorrectingInvoiceTypeFk INT DEFAULT 6; + DECLARE vCplusSimplifiedInvoiceTypeFk INT DEFAULT 2; + DECLARE vCorrectingSerial VARCHAR(1) DEFAULT 'R'; + DECLARE vSimplifiedSerial VARCHAR(1) DEFAULT 'S'; + DECLARE vNewInvoiceInFk INT; + DECLARE vIsInterCompany BOOL DEFAULT FALSE; + DECLARE vIsCEESerial BOOL DEFAULT FALSE; + DECLARE vIsCorrectInvoiceDate BOOL; + DECLARE vMaxShipped DATE; + DECLARE vDone BOOL; + DECLARE vTicketFk INT; + DECLARE vCursor CURSOR FOR + SELECT id + FROM tmp.ticketToInvoice; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + + SET vInvoiceDate = IFNULL(vInvoiceDate, util.VN_CURDATE()); + + SELECT t.clientFk, + t.companyFk, + MAX(DATE(t.shipped)), + DATE(vInvoiceDate) >= invoiceOut_getMaxIssued( + vSerial, + t.companyFk, + YEAR(vInvoiceDate)) + INTO vClientFk, + vCompanyFk, + vMaxShipped, + vIsCorrectInvoiceDate + FROM tmp.ticketToInvoice tt + JOIN ticket t ON t.id = tt.id; + + IF(vMaxShipped > vInvoiceDate) THEN + CALL util.throw("Invoice date can't be less than max date"); + END IF; + + IF NOT vIsCorrectInvoiceDate THEN + CALL util.throw('Exists an invoice with a previous date'); + END IF; + + -- Eliminem de tmp.ticketToInvoice els tickets que no han de ser facturats + DELETE ti.* + FROM tmp.ticketToInvoice ti + JOIN ticket t ON t.id = ti.id + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN supplier su ON su.id = t.companyFk + JOIN client c ON c.id = t.clientFk + LEFT JOIN itemTaxCountry itc ON itc.itemFk = i.id AND itc.countryFk = su.countryFk + WHERE (YEAR(t.shipped) < 2001 AND t.isDeleted) + OR c.isTaxDataChecked = FALSE + OR t.isDeleted + OR c.hasToInvoice = FALSE + OR itc.id IS NULL; + + SELECT SUM(s.quantity * s.price * (100 - s.discount)/100) <> 0 + INTO vIsAnySaleToInvoice + FROM tmp.ticketToInvoice t + JOIN sale s ON s.ticketFk = t.id; + + SELECT COUNT(*) > 0 INTO vIsAnyServiceToInvoice + FROM tmp.ticketToInvoice t + JOIN ticketService ts ON ts.ticketFk = t.id; + + IF (vIsAnySaleToInvoice OR vIsAnyServiceToInvoice) + AND (vCorrectingSerial = vSerial OR NOT hasAnyNegativeBase()) + THEN + + -- el trigger añade el siguiente Id_Factura correspondiente a la vSerial + INSERT INTO invoiceOut( + ref, + serial, + issued, + clientFk, + dued, + companyFk, + siiTypeInvoiceOutFk + ) + SELECT + 1, + vSerial, + vInvoiceDate, + vClientFk, + getDueDate(vInvoiceDate, dueDay), + vCompanyFk, + IF(vSerial = vCorrectingSerial, + vCplusCorrectingInvoiceTypeFk, + IF(vSerial = vSimplifiedSerial, + vCplusSimplifiedInvoiceTypeFk, + vCplusStandardInvoiceTypeFk)) + FROM client + WHERE id = vClientFk; + + SET vNewInvoiceId = LAST_INSERT_ID(); + + SELECT `ref` + INTO vNewRef + FROM invoiceOut + WHERE id = vNewInvoiceId; + + OPEN vCursor; + l: LOOP + SET vDone = FALSE; + FETCH vCursor INTO vTicketFk; + + IF vDone THEN + LEAVE l; + END IF; + + CALL ticket_recalc(vTicketFk, vTaxArea); + + END LOOP; + CLOSE vCursor; + + UPDATE ticket t + JOIN tmp.ticketToInvoice ti ON ti.id = t.id + SET t.refFk = vNewRef; + + DROP TEMPORARY TABLE IF EXISTS tmp.updateInter; + CREATE TEMPORARY TABLE tmp.updateInter ENGINE = MEMORY + SELECT s.id, ti.id ticket_id, vWorker Id_Trabajador + FROM tmp.ticketToInvoice ti + LEFT JOIN ticketState ts ON ti.id = ts.ticket + JOIN state s + WHERE IFNULL(ts.alertLevel, 0) < 3 and s.`code` = getAlert3State(ti.id); + + INSERT INTO ticketTracking(stateFk, ticketFk, userFk) + SELECT * FROM tmp.updateInter; + + CALL invoiceExpenceMake(vNewInvoiceId); + CALL invoiceTaxMake(vNewInvoiceId, vTaxArea); + + UPDATE invoiceOut io + JOIN ( + SELECT SUM(amount) total + FROM invoiceOutExpence + WHERE invoiceOutFk = vNewInvoiceId + ) base + JOIN ( + SELECT SUM(vat) total + FROM invoiceOutTax + WHERE invoiceOutFk = vNewInvoiceId + ) vat + SET io.amount = base.total + vat.total + WHERE io.id = vNewInvoiceId; + + DROP TEMPORARY TABLE tmp.updateInter; + + SELECT COUNT(*), id + INTO vIsInterCompany, vInterCompanyFk + FROM company + WHERE clientFk = vClientFk; + + IF (vIsInterCompany) THEN + + INSERT INTO invoiceIn(supplierFk, supplierRef, issued, companyFk) + SELECT vCompanyFk, vNewRef, vInvoiceDate, vInterCompanyFk; + + SET vNewInvoiceInFk = LAST_INSERT_ID(); + + DROP TEMPORARY TABLE IF EXISTS tmp.ticket; + CREATE TEMPORARY TABLE tmp.ticket + (KEY (ticketFk)) + ENGINE = MEMORY + SELECT id ticketFk + FROM tmp.ticketToInvoice; + + CALL `ticket_getTax`('NATIONAL'); + + SET @vTaxableBaseServices := 0.00; + SET @vTaxCodeGeneral := NULL; + + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) + SELECT vNewInvoiceInFk, + @vTaxableBaseServices, + sub.expenceFk, + sub.taxTypeSageFk, + sub.transactionTypeSageFk + FROM ( + SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase, + i.expenceFk, + i.taxTypeSageFk, + i.transactionTypeSageFk, + @vTaxCodeGeneral := i.taxClassCodeFk + FROM tmp.ticketServiceTax tst + JOIN invoiceOutTaxConfig i ON i.taxClassCodeFk = tst.code + WHERE i.isService + HAVING taxableBase + ) sub; + + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) + SELECT vNewInvoiceInFk, + SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral, + @vTaxableBaseServices, 0) taxableBase, + i.expenceFk, + i.taxTypeSageFk , + i.transactionTypeSageFk + FROM tmp.ticketTax tt + JOIN invoiceOutTaxConfig i ON i.taxClassCodeFk = tt.code + WHERE !i.isService + GROUP BY tt.pgcFk + HAVING taxableBase + ORDER BY tt.priority; + + CALL invoiceInDueDay_calculate(vNewInvoiceInFk); + + SELECT COUNT(*) INTO vIsCEESerial + FROM invoiceOutSerial + WHERE code = vSerial; + + IF vIsCEESerial THEN + + INSERT INTO invoiceInIntrastat ( + invoiceInFk, + intrastatFk, + amount, + stems, + countryFk, + net) + SELECT + vNewInvoiceInFk, + i.intrastatFk, + SUM(CAST((s.quantity * s.price * (100 - s.discount) / 100 ) AS DECIMAL(10, 2))), + SUM(CAST(IFNULL(i.stems, 1) * s.quantity AS DECIMAL(10, 2))), + su.countryFk, + CAST(SUM(IFNULL(i.stems, 1) + * s.quantity + * IF(ic.grams, ic.grams, IFNULL(i.weightByPiece, 0)) / 1000) AS DECIMAL(10, 2)) + FROM sale s + JOIN ticket t ON s.ticketFk = t.id + JOIN supplier su ON su.id = t.companyFk + JOIN item i ON i.id = s.itemFk + LEFT JOIN itemCost ic ON ic.itemFk = i.id AND ic.warehouseFk = t.warehouseFk + WHERE t.refFk = vNewRef + GROUP BY i.intrastatFk; + + END IF; + DROP TEMPORARY TABLE tmp.ticket; + DROP TEMPORARY TABLE tmp.ticketAmount; + DROP TEMPORARY TABLE tmp.ticketTax; + DROP TEMPORARY TABLE tmp.ticketServiceTax; + END IF; + END IF; + DROP TEMPORARY TABLE `tmp`.`ticketToInvoice`; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`productionError_add`() +BEGIN + DECLARE vDatedFrom DATETIME; + DECLARE vDatedTo DATETIME; +/** + * Rellena la tabla vn.productionError con estadisticas de encajadores, revisores y sacadores. Se ejecuta en el nightTask + */ + SELECT util.VN_CURDATE() - INTERVAL 1 DAY, util.dayend(util.VN_CURDATE() - INTERVAL 1 DAY) INTO vDatedFrom, vDatedTo; + CALL timeControl_calculateAll(vDatedFrom, vDatedTo); + + -- Rellena la tabla tmp.errorsByClaim con encajadores, revisores y sacadores + CREATE OR REPLACE TEMPORARY TABLE tmp.errorsByClaim + ENGINE = MEMORY + SELECT COUNT(c.ticketFk) errors, + cd.workerFk + FROM claimDevelopment cd + JOIN claim c ON cd.claimFk = c.id + JOIN ticket t ON c.ticketFk = t.id + JOIN claimResponsible cr ON cd.claimResponsibleFk = cr.id + WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo + AND cr.code IN ('pic', 'chk', 'pck') + GROUP BY cd.workerFk; + + -- Genera la tabla tmp.volume con encajadores, sacadores y revisores + CREATE OR REPLACE TEMPORARY TABLE tmp.volume + ENGINE = MEMORY + SELECT SUM(w.volume) volume, + w.workerFk + FROM bs.workerProductivity w + WHERE w.dated BETWEEN vDatedFrom AND vDatedTo + GROUP BY w.workerFk; + + -- Rellena la tabla tmp.errorsByChecker con fallos de revisores + CREATE OR REPLACE TEMPORARY TABLE tmp.errorsByChecker + ENGINE = MEMORY + SELECT st.workerFk, + COUNT(t.id) errors + FROM saleMistake sm + JOIN saleTracking st ON sm.saleFk = st.saleFk + JOIN `state` s2 ON s2.id = st.stateFk + JOIN sale s ON s.id = sm.saleFk + JOIN ticket t on t.id = s.ticketFk + WHERE (t.shipped BETWEEN vDatedFrom AND vDatedTo) + AND s2.code IN ('OK','PREVIOUS_PREPARATION','PREPARED','CHECKED') + GROUP BY st.workerFk; + + -- Rellena la tabla tmp.expeditionErrors con fallos de expediciones + CREATE OR REPLACE TEMPORARY TABLE tmp.expeditionErrors + ENGINE = MEMORY + SELECT COUNT(t.id) errors, + e.workerFk + FROM vn.expeditionMistake pm + JOIN vn.expedition e ON e.id = pm.expeditionFk + JOIN vn.ticket t ON t.id = e.ticketFk + WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo + GROUP BY e.workerFk; + + -- Genera la tabla tmp.total para sacadores y revisores + CREATE OR REPLACE TEMPORARY TABLE tmp.total + ENGINE = MEMORY + SELECT st.workerFk, + COUNT(DISTINCT t.id) ticketCount, + COUNT(s.id) lineCount + FROM saleTracking st + JOIN `state` s2 ON s2.id = st.stateFk + JOIN sale s ON s.id = st.saleFk + JOIN ticket t ON s.ticketFk = t.id + WHERE (t.shipped BETWEEN vDatedFrom AND vDatedTo) + AND s2.code IN ('OK','PREVIOUS_PREPARATION','PREPARED','CHECKED') + GROUP BY st.workerFk; + + -- Rellena la tabla vn.productionError con sacadores + INSERT INTO productionError(userFk, + firstname, + lastname, + rol, + ticketNumber, + lineNumber, + error, + volume, + hourStart, + hourEnd, + hourWorked, + dated) + SELECT w.id, + w.firstName, + w.lastName, + "Sacadores", + t.ticketCount totalTickets, + t.lineCount, + IFNULL(ec.errors,0) + IFNULL(ec2.errors,0) errors, + v.volume volume, + SUBSTRING(tc.tableTimed, 1, 5) hourStart, + SUBSTRING(tc.tableTimed, LENGTH(tc.tableTimed)-4, 5) hourEnd, + IFNULL(CAST(tc.timeWorkDecimal AS DECIMAL (10,2)) , 0) hourWorked, + vDatedFrom dated + FROM tmp.total t + LEFT JOIN worker w ON w.id = t.workerFk + LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = t.workerFk + LEFT JOIN tmp.errorsByClaim ec ON ec.workerFk = t.workerFk + LEFT JOIN tmp.volume v ON v.workerFk = t.workerFk + LEFT JOIN tmp.errorsByChecker ec2 ON ec2.workerFk = t.workerFk + JOIN (SELECT DISTINCT w.id -- Verificamos que son sacadores + FROM vn.collection c + JOIN vn.state s ON s.id = c.stateFk + JOIN vn.train tn ON tn.id = c.trainFk + JOIN vn.worker w ON w.id = c.workerFk + WHERE c.created BETWEEN vDatedFrom AND vDatedTo) sub ON sub.id = w.id + GROUP BY w.id; + + CREATE OR REPLACE TEMPORARY TABLE itemPickerErrors -- Errores de los sacadores, derivadores de los revisadores + ENGINE = MEMORY + SELECT COUNT(c.ticketFk) errors, + tt.userFk + FROM claimDevelopment cd + JOIN claim c ON cd.claimFk = c.id + JOIN ticket t ON c.ticketFk = t.id + JOIN claimResponsible cr ON cd.claimResponsibleFk = cr.id + JOIN ticketTracking tt ON tt.ticketFk = t.id + JOIN `state` s ON s.id = tt.stateFk + WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo + AND cr.code = 'chk' + AND s.code = 'ON_PREPARATION' + GROUP BY tt.userFk; + + UPDATE productionError ep + JOIN itemPickerErrors ipe ON ipe.workerFk = ep.userFk + SET ep.error = ep.error + ipe.errors + WHERE vDatedFrom = ep.dated AND ep.rol = 'Sacadores'; + + DROP TEMPORARY TABLE itemPickerErrors; + + -- Rellena la tabla vn.productionError con revisores + CALL productionError_addCheckerPackager(vDatedFrom, vDatedTo, "Revisadores"); + + -- Genera la tabla tmp.total para encajadores + CREATE OR REPLACE TEMPORARY TABLE tmp.total + ENGINE = MEMORY + SELECT e.workerFk, + COUNT(DISTINCT t.id) ticketCount, + COUNT(s.id) lineCount + FROM expedition e + JOIN ticket t ON e.ticketFk = t.id + JOIN sale s ON s.ticketFk = t.id + WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo + GROUP BY e.workerFk; + + -- Rellena la tabla vn.productionError con encajadores + CALL productionError_addCheckerPackager(vDatedFrom, vDatedTo, "Encajadores"); + + DROP TEMPORARY TABLE tmp.errorsByClaim, + tmp.volume, + tmp.errorsByChecker, + tmp.expeditionErrors, + tmp.total; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`sectorProductivity_add`() +BEGIN + DECLARE vDatedFrom DATETIME; + DECLARE vDatedTo DATETIME; + + SELECT DATE_SUB(util.VN_CURDATE(),INTERVAL 1 DAY), CONCAT(DATE_SUB(util.VN_CURDATE(),INTERVAL 1 DAY),' 23:59:59') INTO vDatedFrom, vDatedTo; + + DROP TEMPORARY TABLE IF EXISTS tmp.timeControlCalculate; + DROP TEMPORARY TABLE IF EXISTS tmp.errorsByChecker; + DROP TEMPORARY TABLE IF EXISTS tmp.previousErrors; + + CALL timeControl_calculateAll(vDatedFrom, vDatedTo); + + CREATE TEMPORARY TABLE tmp.errorsByChecker + ENGINE = MEMORY + SELECT sc.userFk workerFk, COUNT(DISTINCT s.ticketFk) errorsByChecker + FROM saleMistake sm + JOIN vn.saleGroupDetail sgd on sgd.saleFk = sm.saleFk + JOIN vn.sectorCollectionSaleGroup scsg on scsg.saleGroupFk = sgd.saleGroupFk + JOIN vn.sectorCollection sc on sc.id = scsg.sectorCollectionFk + JOIN sale s ON s.id = sm.saleFk + JOIN ticket t on t.id = s.ticketFk + WHERE (t.shipped BETWEEN vDatedFrom AND vDatedTo) + GROUP BY sc.userFk ; + + CREATE TEMPORARY TABLE tmp.previousErrors -- Errores de previa, derivadores de los revisadores (por reclamación) + ENGINE = MEMORY + SELECT tt.userFk, COUNT(c.ticketFk) errorsByClaim + FROM claimDevelopment cd + JOIN claim c ON cd.claimFk = c.id + JOIN ticket t ON c.ticketFk = t.id + JOIN claimResponsible cr ON cd.claimResponsibleFk = cr.id + JOIN ticketTracking tt ON tt.ticketFk = t.id + JOIN `state` s ON s.id = tt.stateFk + WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo AND cr.description = 'Revisadores' AND s.code = 'OK PREVIOUS' + GROUP BY cd.workerFk; + + DELETE FROM sectorProductivity + WHERE dated = vDatedFrom + AND sector IN ('Algemesi Artificial','Algemesi Complementos'); + + INSERT INTO sectorProductivity(workerFk, firstName, lastName, sector, ticketCount, saleCount, error, volume, hourWorked, dated) + SELECT w.id workerFk, + w.firstName, + w.lastName, + se.description sector, + COUNT(DISTINCT s.ticketFk) ticketCount, + COUNT(sgd.id) saleCount, + IFNULL(ec2.errorsByChecker,0) + IFNULL(pe.errorsByClaim, 0) errors, + wp.volume, + IFNULL(CAST(tc.timeWorkDecimal AS DECIMAL (10,2)) , 0) AS hourWorked, + DATE(vDatedFrom) dated + FROM vn.saleGroupDetail sgd + JOIN vn.saleGroup sg on sg.id = sgd.saleGroupFk + JOIN vn.sectorCollectionSaleGroup scsg on scsg.saleGroupFk = sgd.saleGroupFk + JOIN vn.sectorCollection sc on sc.id = scsg.sectorCollectionFk + join vn.sector se on se.id = sc.sectorFk + JOIN vn.worker w ON w.id = sc.userFk + LEFT JOIN vn.sale s ON s.id = sgd.saleFk + LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = w.id + LEFT JOIN bs.workerProductivity wp ON wp.workerFk = w.id + LEFT JOIN `state` s2 ON s2.id = wp.stateFk AND s2.code = 'OK PREVIOUS' + LEFT JOIN tmp.errorsByChecker ec2 ON ec2.workerFk = w.id + LEFT JOIN tmp.previousErrors pe ON pe.workerFk = w.id + WHERE DATE(sc.created) = vDatedFrom + AND wp.dated = vDatedFrom + GROUP BY w.id; + + DROP TEMPORARY TABLE tmp.timeControlCalculate; + DROP TEMPORARY TABLE tmp.errorsByChecker; + DROP TEMPORARY TABLE tmp.previousErrors; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticketStateUpdate`(vTicketFk INT, vStateCode VARCHAR(45)) +BEGIN + + /* + * @deprecated:utilizar ticket_setState + */ + + DECLARE vAlertLevel INT; + + SELECT s.alertLevel INTO vAlertLevel + FROM vn.state s + JOIN vn.ticketState ts ON ts.stateFk = s.id + WHERE ts.ticketFk = vTicketFk; + + IF !(vStateCode = 'ON_CHECKING' AND vAlertLevel > 1) THEN + + INSERT INTO ticketTracking(stateFk, ticketFk, userFk) + SELECT id, vTicketFk, account.myUser_getId() + FROM vn.state + WHERE `code` = vStateCode collate utf8_unicode_ci; + + END IF; + +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_Clone`(vOriginalTicket INT, OUT vNewTicket INT) +BEGIN +/** + * Clona el contenido de un ticket en otro + * + * @param vOriginalTicket ticket Original + * @param vNewTicket ticket creado + */ + DECLARE vStateFk INT; + + INSERT INTO ticket ( + clientFk, + shipped, + addressFk, + agencyModeFk, + nickname, + warehouseFk, + companyFk, + landed, + zoneFk, + zonePrice, + zoneBonus, + routeFk, + priority, + hasPriority, + clonedFrom + ) + SELECT + clientFk, + shipped, + addressFk, + agencyModeFk, + nickname, + warehouseFk, + companyFk, + landed, + zoneFk, + zonePrice, + zoneBonus, + routeFk, + priority, + hasPriority, + vOriginalTicket + FROM ticket + WHERE id = vOriginalTicket; + + SET vNewTicket = LAST_INSERT_ID(); + + INSERT INTO ticketObservation(ticketFk, observationTypeFk, description) + SELECT vNewTicket, observationTypeFk, description + FROM ticketObservation + WHERE ticketFk = vOriginalTicket; + + INSERT INTO ticketTracking(ticketFk, stateFk, userFk, created) + SELECT vNewTicket, stateFk, userFk, created + FROM ticketTracking + WHERE ticketFk = vOriginalTicket + ORDER BY created; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_add`( + vClientId INT + ,vShipped DATE + ,vWarehouseFk INT + ,vCompanyFk INT + ,vAddressFk INT + ,vAgencyModeFk INT + ,vRouteFk INT + ,vlanded DATE + ,vUserId INT + ,vIsRequiredZone INT + ,OUT vNewTicket INT) +BEGIN +/** +* Crea un ticket, +* ¡¡NO se debe llamar directamente, llamar a salix que hace comprobaciones previas!! +* +* @param vClientId id del cliente +* @param vShipped dia preparacion +* @param vWarehouseFk id del warehouse +* @param vCompanyFk id la empresa +* @param vAddressFk id del consignatario +* @param vAgencyModeFk id de la agencia +* @param vRouteFk id de la ruta | NULL +* @param vlanded dia llegada +* @param vUserId que crea el ticket +* @param vIsRequiredZone Indica si tiene que tener zona valida para ser creado +* @return vNewTicket id del ticket creado +*/ + DECLARE vZoneFk INT; + DECLARE vPrice DECIMAL(10,2); + DECLARE vBonus DECIMAL(10,2); + DECLARE vIsActive BOOL; + + IF vClientId IS NULL THEN + CALL util.throw ('CLIENT_NOT_ESPECIFIED'); + END IF; + + SELECT isActive INTO vIsActive + FROM vn.client + WHERE id = vClientId; + + IF NOT vIsActive THEN + CALL util.throw ('CLIENT_NOT_ACTIVE'); + END IF; + + IF NOT vAddressFk OR vAddressFk IS NULL THEN + SELECT id INTO vAddressFk + FROM address + WHERE clientFk = vClientId + AND isDefaultAddress; + END IF; + + IF vAgencyModeFk IS NOT NULL THEN + CALL vn.zone_getShipped (vlanded, vAddressFk, vAgencyModeFk, TRUE); + + SELECT zoneFk, price, bonus + INTO vZoneFk, vPrice, vBonus + FROM tmp.zoneGetShipped + WHERE shipped = vShipped + AND warehouseFk = vWarehouseFk + LIMIT 1; + + IF (vZoneFk IS NULL OR vZoneFk = 0) AND vIsRequiredZone THEN + CALL util.throw ('NOT_ZONE_WITH_THIS_PARAMETERS'); + END IF; + END IF; + + INSERT INTO ticket ( + clientFk, + shipped, + addressFk, + agencyModeFk, + nickname, + warehouseFk, + routeFk, + companyFk, + landed, + zoneFk, + zonePrice, + zoneBonus + ) + SELECT vClientId, + vShipped, + a.id, + vAgencyModeFk, + a.nickname, + vWarehouseFk, + IF(vRouteFk,vRouteFk,NULL), + vCompanyFk, + vlanded, + vZoneFk, + vPrice, + vBonus + FROM address a + JOIN agencyMode am ON am.id = a.agencyModeFk + WHERE a.id = vAddressFk; + + SET vNewTicket = LAST_INSERT_ID(); + + INSERT INTO ticketObservation(ticketFk, observationTypeFk, description) + SELECT vNewTicket, ao.observationTypeFk, ao.description + FROM addressObservation ao + JOIN address a ON a.id = ao.addressFk + WHERE a.id = vAddressFk; + + IF (SELECT COUNT(*) + FROM bs.clientNewBorn cnb + WHERE cnb.clientFk = vClientId + AND NOT cnb.isRookie) = 0 THEN + + CALL vn.ticketObservation_addNewBorn(vNewTicket); + END IF; + + IF (SELECT ct.isCreatedAsServed FROM vn.clientType ct JOIN vn.client c ON c.typeFk = ct.code WHERE c.id = vClientId ) <> FALSE THEN + INSERT INTO ticketTracking(stateFk, ticketFk, userFk) + SELECT id, vNewTicket, account.myUser_getId() + FROM state + WHERE `code` = 'DELIVERED'; + END IF; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setNextState`(vSelf INT) +BEGIN +/** + * Cambia el estado del ticket al siguiente estado según la tabla state + * + * @param vSelf id dle ticket + */ + DECLARE vStateFk INT; + DECLARE vNewStateFk INT; + + SELECT stateFk INTO vStateFk + FROM ticketState + WHERE ticketFk = vSelf; + + SELECT nextStateFk INTO vNewStateFk + FROM state + WHERE id = vStateFk; + + INSERT INTO ticketTracking(stateFk, ticketFk, userFk) + VALUES (vNewStateFk, vSelf, account.myUser_getId()); +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setPreviousState`(vTicketFk INT) +BEGIN + DECLARE vControlFk INT; + + SELECT MAX(id) INTO vControlFk + FROM ticketTracking + WHERE ticketFk = vTicketFk; + + IF (SELECT s.code + FROM vn.state s + JOIN ticketTracking tt ON tt.stateFk = s.id + WHERE tt.id = vControlFk) + = 'PREVIOUS_PREPARATION' THEN + SELECT id + INTO vControlFk + FROM ticketTracking tt + JOIN vn.state s ON tt.stateFk = s.id + WHERE ticketFk = vTicketFk + AND id < vControlFk + AND s.code != 'PREVIOUS_PREPARATION' + ORDER BY id DESC + LIMIT 1; + + INSERT INTO ticketTracking(stateFk, ticketFk, userFk) + SELECT s.nextStateFk, tt.ticketFk, account.myUser_getId() + FROM ticketTracking tt + JOIN vn.state s ON tt.stateFk = s.id + WHERE id = vControlFk; + END IF; +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setState`( + vSelf INT, + vStateCode VARCHAR(255) COLLATE utf8_general_ci +) +BEGIN +/** + * Modifica el estado de un ticket si se cumplen las condiciones necesarias. + * + * @param vSelf el id del ticket + * @param vStateCode estado a modificar del ticket + */ + DECLARE vticketAlertLevel INT; + DECLARE vTicketStateCode VARCHAR(255); + DECLARE vCanChangeState BOOL; + DECLARE vPackedAlertLevel INT; + DECLARE vZoneFk INT; + + SELECT s.alertLevel, s.`code`, t.zoneFk + INTO vticketAlertLevel, vTicketStateCode, vZoneFk + FROM state s + JOIN ticketTracking tt ON tt.stateFk = s.id + JOIN ticket t ON t.id = tt.ticketFk + WHERE tt.ticketFk = vSelf + ORDER BY tt.created DESC + LIMIT 1; + + SELECT id INTO vPackedAlertLevel FROM alertLevel WHERE code = 'PACKED'; + + IF vStateCode = 'OK' AND vZoneFk IS NULL THEN + CALL util.throw('ASSIGN_ZONE_FIRST'); + END IF; + + SET vCanChangeState = ( + vStateCode <> 'ON_CHECKING' OR + vticketAlertLevel < vPackedAlertLevel + )AND NOT ( + vTicketStateCode IN ('CHECKED', 'CHECKING') + AND vStateCode IN ('PREPARED', 'ON_PREPARATION') + ); + + IF vCanChangeState THEN + INSERT INTO ticketTracking (stateFk, ticketFk, userFk) + SELECT id, vSelf, account.myUser_getId() + FROM state + WHERE `code` = vStateCode COLLATE utf8_unicode_ci; + + IF vStateCode = 'PACKED' THEN + CALL ticket_doCmr(vSelf); + END IF; + ELSE + CALL util.throw('INCORRECT_TICKET_STATE'); + END IF; +END$$ +DELIMITER ; diff --git a/db/changes/235001/02-views.sql b/db/changes/235001/02-views.sql new file mode 100644 index 0000000000..d399bb3b45 --- /dev/null +++ b/db/changes/235001/02-views.sql @@ -0,0 +1,34 @@ +CREATE OR REPLACE DEFINER=`root`@`localhost` + SQL SECURITY DEFINER + VIEW `vn`.`ticketState` +AS SELECT `tt`.`created` AS `updated`, + `tt`.`stateFk` AS `stateFk`, + `tt`.`userFk` AS `userFk`, + `tls`.`ticketFk` AS `ticketFk`, + `s`.`id` AS `state`, + `s`.`order` AS `productionOrder`, + `s`.`alertLevel` AS `alertLevel`, + `s`.`code` AS `code`, + `tls`.`ticketFk` AS `ticket`, + `tt`.`userFk` AS `worker`, + `s`.`isPreviousPreparable` AS `isPreviousPreparable`, + `s`.`isPicked` AS `isPicked` +FROM ( + ( + `vn`.`ticketLastState` `tls` + JOIN `vn`.`ticketTracking` `tt` ON(`tt`.`id` = `tls`.`ticketTrackingFk`) + ) + JOIN `vn`.`state` `s` ON(`s`.`id` = `tt`.`stateFk`) + ); + +CREATE OR REPLACE DEFINER=`root`@`localhost` + SQL SECURITY DEFINER + VIEW `vn2008`.`v_inter` +AS SELECT `tt`.`id` AS `inter_id`, + `tt`.`stateFk` AS `state_id`, + `tt`.`notes` AS `nota`, + `tt`.`created` AS `odbc_date`, + `tt`.`ticketFk` AS `Id_Ticket`, + `tt`.`userFk` AS `Id_Trabajador`, + `tt`.`supervisorFk` AS `Id_supervisor` +FROM `vn`.`ticketTracking` `tt`; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 788487ed07..dc37b76f98 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -767,7 +767,7 @@ INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `des -- FIX for state hours on local, inter_afterInsert -- UPDATE vncontrol.inter SET odbc_date = DATE_ADD(util.VN_CURDATE(), INTERVAL -10 SECOND); -INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `workerFk`, `created`) +INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `userFk`, `created`) VALUES (1, 16, 5 , DATE_ADD(util.VN_NOW(), INTERVAL -1 MONTH)), (2, 16, 5 , DATE_ADD(util.VN_NOW(), INTERVAL -1 MONTH)), @@ -811,6 +811,7 @@ INSERT INTO `vn`.`config`(`id`, `mdbServer`, `fakeEmail`, `defaultersMaxAmount`, VALUES (1, 'beta-server', 'nightmare@mydomain.com', '200', DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH)); + INSERT INTO `vn`.`greugeType`(`id`, `name`, `code`) VALUES (1, 'Diff', 'diff'), diff --git a/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js b/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js index be3baccd73..a01590f58e 100644 --- a/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js +++ b/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js @@ -123,7 +123,7 @@ module.exports = Self => { await models.TicketTracking.create({ ticketFk: newRefundTicket.id, stateFk: state.id, - workerFk: worker.id + userFk: worker.id }, myOptions); const salesToRefund = await models.ClaimBeginning.find(salesFilter, myOptions); diff --git a/modules/ticket/back/methods/ticket/specs/state.spec.js b/modules/ticket/back/methods/ticket/specs/state.spec.js index 9b5e801653..f369932de0 100644 --- a/modules/ticket/back/methods/ticket/specs/state.spec.js +++ b/modules/ticket/back/methods/ticket/specs/state.spec.js @@ -94,10 +94,10 @@ describe('ticket state()', () => { const ticketTracking = await models.Ticket.state(ctx, params, options); - expect(ticketTracking.__data.ticketFk).toBe(params.ticketFk); - expect(ticketTracking.__data.stateFk).toBe(params.stateFk); - expect(ticketTracking.__data.workerFk).toBe(49); - expect(ticketTracking.__data.id).toBeDefined(); + expect(ticketTracking.ticketFk).toBe(params.ticketFk); + expect(ticketTracking.stateFk).toBe(params.stateFk); + expect(ticketTracking.userFk).toBe(49); + expect(ticketTracking.id).toBeDefined(); await tx.rollback(); } catch (e) { @@ -116,14 +116,14 @@ describe('ticket state()', () => { const ticket = await models.Ticket.create(sampleTicket, options); const ctx = {req: {accessToken: {userId: 18}}}; const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options); - const params = {ticketFk: ticket.id, stateFk: assignedState.id, workerFk: 1}; + const params = {ticketFk: ticket.id, stateFk: assignedState.id, userFk: 1}; const res = await models.Ticket.state(ctx, params, options); - expect(res.__data.ticketFk).toBe(params.ticketFk); - expect(res.__data.stateFk).toBe(params.stateFk); - expect(res.__data.workerFk).toBe(params.workerFk); - expect(res.__data.workerFk).toBe(1); - expect(res.__data.id).toBeDefined(); + expect(res.ticketFk).toBe(params.ticketFk); + expect(res.stateFk).toBe(params.stateFk); + expect(res.userFk).toBe(params.userFk); + expect(res.userFk).toBe(1); + expect(res.id).toBeDefined(); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket/state.js b/modules/ticket/back/methods/ticket/state.js index 01bfbba20c..adac2e42f2 100644 --- a/modules/ticket/back/methods/ticket/state.js +++ b/modules/ticket/back/methods/ticket/state.js @@ -51,12 +51,12 @@ module.exports = Self => { params.stateFk = state.id; } - if (!params.workerFk) { + if (!params.userFk) { const worker = await models.Worker.findOne({ where: {id: userId} }, myOptions); - params.workerFk = worker.id; + params.userFk = worker.id; } const ticketState = await models.TicketState.findById(params.ticketFk, { diff --git a/modules/ticket/back/models/ticket-state.json b/modules/ticket/back/models/ticket-state.json index a10938ef01..3ee50fac06 100644 --- a/modules/ticket/back/models/ticket-state.json +++ b/modules/ticket/back/models/ticket-state.json @@ -33,10 +33,10 @@ "model": "State", "foreignKey": "stateFk" }, - "worker": { - "type": "belongsTo", - "model": "Worker", - "foreignKey": "workerFk" - } + "user": { + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "userFk" + } } } diff --git a/modules/ticket/back/models/ticket-tracking.js b/modules/ticket/back/models/ticket-tracking.js index 92e046d3e1..72e1880b97 100644 --- a/modules/ticket/back/models/ticket-tracking.js +++ b/modules/ticket/back/models/ticket-tracking.js @@ -2,5 +2,5 @@ module.exports = function(Self) { require('../methods/ticket-tracking/setDelivered')(Self); Self.validatesPresenceOf('stateFk', {message: 'State cannot be blank'}); - Self.validatesPresenceOf('workerFk', {message: 'Worker cannot be blank'}); + Self.validatesPresenceOf('userFk', {message: 'Worker cannot be blank'}); }; diff --git a/modules/ticket/back/models/ticket-tracking.json b/modules/ticket/back/models/ticket-tracking.json index 8b5ce0b643..8b0617145c 100644 --- a/modules/ticket/back/models/ticket-tracking.json +++ b/modules/ticket/back/models/ticket-tracking.json @@ -8,21 +8,21 @@ }, "properties": { "id": { - "id": true, - "type": "number", - "forceId": false + "id": true, + "type": "number", + "forceId": false }, "created": { - "type": "date" + "type": "date" }, "ticketFk": { - "type": "number" + "type": "number" }, "stateFk": { - "type": "number" + "type": "number" }, - "workerFk": { - "type": "number" + "userFk": { + "type": "number" } }, "relations": { @@ -36,10 +36,10 @@ "model": "State", "foreignKey": "stateFk" }, - "worker": { - "type": "belongsTo", - "model": "Worker", - "foreignKey": "workerFk" - } + "user": { + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "userFk" + } } } diff --git a/modules/ticket/front/tracking/index/index.js b/modules/ticket/front/tracking/index/index.js index 95665b071e..ff3dc881b1 100644 --- a/modules/ticket/front/tracking/index/index.js +++ b/modules/ticket/front/tracking/index/index.js @@ -7,15 +7,9 @@ class Controller extends Section { this.filter = { include: [ { - relation: 'worker', + relation: 'user', scope: { - fields: ['id'], - include: { - relation: 'user', - scope: { - fields: ['name'] - } - } + fields: ['name'] } }, { relation: 'state', diff --git a/modules/zone/back/methods/zone/deleteZone.js b/modules/zone/back/methods/zone/deleteZone.js index 13d45428ca..38e724cd3c 100644 --- a/modules/zone/back/methods/zone/deleteZone.js +++ b/modules/zone/back/methods/zone/deleteZone.js @@ -64,7 +64,7 @@ module.exports = Self => { promises.push(models.TicketTracking.create({ ticketFk: ticket.id, stateFk: fixingState.id, - workerFk: worker.id + userFk: worker.id }, myOptions)); } } From 72283005b80ee3fab6dbb25daa1e1258846a28a5 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 30 Nov 2023 14:43:14 +0100 Subject: [PATCH 326/449] remove(console.log): refs #3271 remove console.log --- modules/zone/back/methods/zone/specs/getEventsFiltered.spec.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/zone/back/methods/zone/specs/getEventsFiltered.spec.js b/modules/zone/back/methods/zone/specs/getEventsFiltered.spec.js index d1c7f1fc49..7167b83de0 100644 --- a/modules/zone/back/methods/zone/specs/getEventsFiltered.spec.js +++ b/modules/zone/back/methods/zone/specs/getEventsFiltered.spec.js @@ -51,9 +51,6 @@ describe('zone getEventsFiltered()', () => { dateTomorrow.setDate(dateTomorrow.getDate() + 1); const result = await models.Zone.getEventsFiltered(9, date, dateTomorrow, options); - console.log('dateTomorrow: ', dateTomorrow); - console.log('date: ', date); - console.log('result: ', result); expect(result.events.length).toEqual(1); expect(result.exclusions.length).toEqual(0); From e634a5e2139d8f948d9478f668e12b7c97a5b884 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 30 Nov 2023 15:15:40 +0100 Subject: [PATCH 327/449] refs #5914 feat: create getTaxBases and use in negatives and positives procedures --- db/changes/235001/00-getTaxBases.sql | 33 +++++++++++++++++++ .../235001/01-newHasAnyPositiveBase.sql | 28 ++++++++++++++++ .../235001/01-refactorHasAnyNegativeBase.sql | 28 ++++++++++++++++ db/dump/fixtures.sql | 13 ++++---- 4 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 db/changes/235001/00-getTaxBases.sql create mode 100644 db/changes/235001/01-newHasAnyPositiveBase.sql create mode 100644 db/changes/235001/01-refactorHasAnyNegativeBase.sql diff --git a/db/changes/235001/00-getTaxBases.sql b/db/changes/235001/00-getTaxBases.sql new file mode 100644 index 0000000000..fa43c32f78 --- /dev/null +++ b/db/changes/235001/00-getTaxBases.sql @@ -0,0 +1,33 @@ +DELIMITER $$ +$$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`getTaxBases`() +BEGIN + +/* Calcula y devuelve en número de bases imponibles postivas y negativas +* Requiere la tabla temporal tmp.ticketToInvoice(id) +* +* returns tmp.taxBases +*/ + + CREATE OR REPLACE TEMPORARY TABLE tmp.ticket + (KEY (ticketFk)) + ENGINE = MEMORY + SELECT id ticketFk + FROM tmp.ticketToInvoice; + + CALL ticket_getTax(NULL); + + DROP TEMPORARY TABLE IF EXISTS tmp.taxBases; + CREATE TEMPORARY TABLE tmp.taxBases + ENGINE = MEMORY + SELECT + SUM(CASE WHEN taxableBase > 0 THEN 1 ELSE 0 END) as positive, + SUM(CASE WHEN taxableBase < 0 THEN 1 ELSE 0 END) as negative + FROM( + SELECT SUM(taxableBase) as taxableBase + FROM tmp.ticketTax + GROUP BY pgcFk + ) t; + +END$$ +DELIMITER ; diff --git a/db/changes/235001/01-newHasAnyPositiveBase.sql b/db/changes/235001/01-newHasAnyPositiveBase.sql new file mode 100644 index 0000000000..c9e7e8e059 --- /dev/null +++ b/db/changes/235001/01-newHasAnyPositiveBase.sql @@ -0,0 +1,28 @@ +DELIMITER $$ +$$ +CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`hasAnyPositiveBase`() RETURNS tinyint(1) + DETERMINISTIC +BEGIN + +/* Calcula si existe alguna base imponible positiva +* Requiere la tabla temporal tmp.ticketToInvoice(id) para getTaxBases() +* +* returns BOOLEAN +*/ + + DECLARE hasAnyPositiveBase BOOLEAN; + + CALL getTaxBases(); + + SELECT positive > 0 INTO hasAnyPositiveBase + FROM tmp.taxBases; + + DROP TEMPORARY TABLE + tmp.ticketTax, + tmp.ticket, + tmp.taxBases; + + RETURN hasAnyPositiveBase; + +END$$ +DELIMITER ; diff --git a/db/changes/235001/01-refactorHasAnyNegativeBase.sql b/db/changes/235001/01-refactorHasAnyNegativeBase.sql new file mode 100644 index 0000000000..b6780e280f --- /dev/null +++ b/db/changes/235001/01-refactorHasAnyNegativeBase.sql @@ -0,0 +1,28 @@ +DELIMITER $$ +$$ +CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`hasAnyNegativeBase`() RETURNS tinyint(1) + DETERMINISTIC +BEGIN + +/* Calcula si existe alguna base imponible negativa +* Requiere la tabla temporal tmp.ticketToInvoice(id) para getTaxBases() +* +* returns BOOLEAN +*/ + + DECLARE hasAnyNegativeBase BOOLEAN; + + CALL getTaxBases(); + + SELECT negative > 0 INTO hasAnyNegativeBase + FROM tmp.taxBases; + + DROP TEMPORARY TABLE + tmp.ticketTax, + tmp.ticket, + tmp.taxBases; + + RETURN hasAnyNegativeBase; + +END$$ +DELIMITER ; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 788487ed07..ed0a30d145 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -598,18 +598,19 @@ INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion` INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaFk`, `isCEE`, `type`) VALUES - ('A', 'Global nacional', 1, 'NATIONAL', 0, 'global'), - ('T', 'Española rapida', 1, 'NATIONAL', 0, 'quick'), - ('V', 'Intracomunitaria global', 0, 'CEE', 1, 'global'), - ('M', 'Múltiple nacional', 1, 'NATIONAL', 0, 'quick'), - ('E', 'Exportación rápida', 0, 'WORLD', 0, 'quick'); + ('A', 'Global nacional', 1, 'NATIONAL', 0, 'global'), + ('T', 'Española rapida', 1, 'NATIONAL', 0, 'quick'), + ('V', 'Intracomunitaria global', 0, 'CEE', 1, 'global'), + ('M', 'Múltiple nacional', 1, 'NATIONAL', 0, 'quick'), + ('R', 'Rectificativa', 1, 'NATIONAL', 0, NULL), + ('E', 'Exportación rápida', 0, 'WORLD', 0, 'quick'); INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`) VALUES (1, 'T', 1026.24, util.VN_CURDATE(), 1101, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0), (2, 'T', 121.36, util.VN_CURDATE(), 1102, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0), (3, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0), - (4, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0), + (4, 'T', 8.88, util.VN_CURDATE(), 1104, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0), (5, 'A', 8.88, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 0); UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1; From b2e7ea3089b24acfbc1dfbde612cbe7ee36940b5 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 30 Nov 2023 15:16:41 +0100 Subject: [PATCH 328/449] refs #5914 feat: make invoice support rectificative --- loopback/locale/es.json | 3 ++- .../back/methods/client/canBeInvoiced.js | 2 +- .../back/methods/invoiceOut/invoiceClient.js | 1 + .../invoiceOut/specs/transferinvoice.spec.js | 23 +++++++++++----- .../methods/invoiceOut/transferInvoice.js | 8 +++--- .../invoiceOut/front/descriptor-menu/index.js | 2 +- .../back/methods/sale/specs/refund.spec.js | 8 +++--- .../back/methods/ticket/canBeInvoiced.js | 16 ++++++++---- .../back/methods/ticket/invoiceTickets.js | 1 - .../ticket/back/methods/ticket/makeInvoice.js | 26 +++++++++++-------- .../ticket/specs/canBeInvoiced.spec.js | 8 +++--- .../ticket/specs/invoiceTickets.spec.js | 10 +++---- .../methods/ticket/specs/makeInvoice.spec.js | 4 +-- modules/ticket/front/descriptor-menu/index.js | 2 +- .../front/descriptor-menu/index.spec.js | 5 ++-- modules/ticket/front/sale/index.js | 2 +- modules/ticket/front/sale/index.spec.js | 2 +- 17 files changed, 72 insertions(+), 51 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 41acc36c3b..71e0dc6af6 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -328,5 +328,6 @@ "User disabled": "Usuario desactivado", "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", - "Cannot past travels with entries": "No se pueden pasar envíos con entradas" + "Cannot past travels with entries": "No se pueden pasar envíos con entradas", + "No tickets to invoice": "No hay tickets para facturar" } diff --git a/modules/client/back/methods/client/canBeInvoiced.js b/modules/client/back/methods/client/canBeInvoiced.js index 843e9549fc..cdb8655005 100644 --- a/modules/client/back/methods/client/canBeInvoiced.js +++ b/modules/client/back/methods/client/canBeInvoiced.js @@ -1,7 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = function(Self) { - Self.remoteMethodCtx('canBeInvoiced', { + Self.remoteMethod('canBeInvoiced', { description: 'Change property isEqualizated in all client addresses', accessType: 'READ', accepts: [ diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js index fa22dab1e0..530b02353c 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js +++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js @@ -80,6 +80,7 @@ module.exports = Self => { invoiceType, args.companyFk, args.invoiceDate, + null, options ); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js index dea4b6d007..b3bd178265 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js @@ -23,20 +23,29 @@ describe('InvoiceOut tranferInvoice()', () => { const tx = await models.InvoiceOut.beginTransaction({}); const options = {transaction: tx}; const args = { - id: '1', + id: '4', refFk: 'T4444444', newClientFk: 1, - cplusRectificationId: 1, - siiTypeInvoiceOutId: 1, - invoiceCorrectionTypeId: 1 + cplusRectificationTypeFk: 1, + siiTypeInvoiceOutFk: 1, + invoiceCorrectionTypeFk: 1 }; ctx.args = args; try { + const {clientFk: oldClient} = await models.InvoiceOut.findById(args.id, {fields: ['clientFk']}); + const invoicesBefore = await models.InvoiceOut.find({}, options); const result = await models.InvoiceOut.transferInvoice( ctx, options); + const invoicesAfter = await models.InvoiceOut.find({}, options); + const rectificativeInvoice = invoicesAfter[invoicesAfter.length - 2]; + const newInvoice = invoicesAfter[invoicesAfter.length - 1]; expect(result).toBeDefined(); + expect(invoicesAfter.length - invoicesBefore.length).toEqual(2); + expect(rectificativeInvoice.clientFk).toEqual(oldClient); + expect(newInvoice.clientFk).toEqual(args.newClientFk); + await tx.rollback(); } catch (e) { await tx.rollback(); @@ -51,9 +60,9 @@ describe('InvoiceOut tranferInvoice()', () => { id: '1', refFk: 'T1111111', newClientFk: 1101, - cplusRectificationId: 1, - siiTypeInvoiceOutId: 1, - invoiceCorrectionTypeId: 1 + cplusRectificationTypeFk: 1, + siiTypeInvoiceOutFk: 1, + invoiceCorrectionTypeFk: 1 }; ctx.args = args; try { diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js index dcdd9b9b15..5f24285399 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js @@ -22,7 +22,7 @@ module.exports = Self => { required: true }, { - arg: 'cplusRectificationFk', + arg: 'cplusRectificationTypeFk', type: 'number', required: true }, @@ -50,7 +50,7 @@ module.exports = Self => { Self.transferInvoice = async(ctx, options) => { const models = Self.app.models; const myOptions = {userId: ctx.req.accessToken.userId}; - const {id, refFk, newClientFk, cplusRectificationFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk} = ctx.args; + const {id, refFk, newClientFk, cplusRectificationTypeFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk} = ctx.args; let tx; if (typeof options == 'object') Object.assign(myOptions, options); @@ -87,11 +87,11 @@ module.exports = Self => { } const invoiceCorrection = - {correctedFk: id, cplusRectificationFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk}; + {correctedFk: id, cplusRectificationTypeFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk}; const refundTicketIds = refundTickets.map(ticket => ticket.id); await models.Ticket.invoiceTickets(ctx, refundTicketIds, invoiceCorrection, myOptions); - const [[invoiceId]] = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions); + const [invoiceId] = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, null, myOptions); if (tx) { await tx.commit(); diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index f9d436092c..aee323e399 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -131,7 +131,7 @@ class Controller extends Section { id: this.invoiceOut.id, refFk: this.invoiceOut.ref, newClientFk: this.clientId, - cplusRectificationFk: this.cplusRectificationType, + cplusRectificationTypeFk: this.cplusRectificationType, siiTypeInvoiceOutFk: this.siiTypeInvoiceOut, invoiceCorrectionTypeFk: this.invoiceCorrectionType }; diff --git a/modules/ticket/back/methods/sale/specs/refund.spec.js b/modules/ticket/back/methods/sale/specs/refund.spec.js index 08eb1fabd2..60f77e90c5 100644 --- a/modules/ticket/back/methods/sale/specs/refund.spec.js +++ b/modules/ticket/back/methods/sale/specs/refund.spec.js @@ -23,9 +23,9 @@ describe('Sale refund()', () => { try { const options = {transaction: tx}; - const refundedTicket = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options); + const refundedTickets = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options); - expect(refundedTicket).toBeDefined(); + expect(refundedTickets).toBeDefined(); await tx.rollback(); } catch (e) { @@ -42,11 +42,11 @@ describe('Sale refund()', () => { const options = {transaction: tx}; const ticketsBefore = await models.Ticket.find({}, options); - const ticket = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options); + const tickets = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options); const refundedTicket = await models.Ticket.findOne({ where: { - id: ticket.id + id: tickets[0].id }, include: [ { diff --git a/modules/ticket/back/methods/ticket/canBeInvoiced.js b/modules/ticket/back/methods/ticket/canBeInvoiced.js index 348f02348b..fe7223c178 100644 --- a/modules/ticket/back/methods/ticket/canBeInvoiced.js +++ b/modules/ticket/back/methods/ticket/canBeInvoiced.js @@ -10,6 +10,11 @@ module.exports = function(Self) { description: 'The tickets id', type: ['number'], required: true + }, + { + arg: 'isRectificative', + description: 'If it is rectificative', + type: 'boolean' } ], returns: { @@ -23,7 +28,7 @@ module.exports = function(Self) { } }); - Self.canBeInvoiced = async(ctx, ticketsIds, options) => { + Self.canBeInvoiced = async(ctx, ticketsIds, isRectificative, options) => { const myOptions = {}; const $t = ctx.req.__; // $translate @@ -48,10 +53,11 @@ module.exports = function(Self) { const [supplierCompany] = await Self.rawSql(query, [companyFk], options); const isSpanishCompany = supplierCompany?.isSpanishCompany; - - const [result] = await Self.rawSql('SELECT hasAnyNegativeBase() AS base', null, options); - const hasAnyNegativeBase = result?.base && isSpanishCompany; - if (hasAnyNegativeBase) + const taxBaseFunction = isRectificative ? 'hasAnyPositiveBase' : 'hasAnyNegativeBase'; + const [result] = + await Self.rawSql(`SELECT ?() AS hasBasesProblem`, [taxBaseFunction], options); + const hasAnyIncorrectBase = result?.hasBasesProblem && isSpanishCompany; + if (hasAnyIncorrectBase) throw new UserError($t('Negative basis of tickets', {ticketsIds: ticketsIds})); const today = Date.vnNew(); diff --git a/modules/ticket/back/methods/ticket/invoiceTickets.js b/modules/ticket/back/methods/ticket/invoiceTickets.js index 29fb1769b7..212f6556a2 100644 --- a/modules/ticket/back/methods/ticket/invoiceTickets.js +++ b/modules/ticket/back/methods/ticket/invoiceTickets.js @@ -93,7 +93,6 @@ module.exports = function(Self) { async function createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, invoiceCorrection, myOptions) { const models = Self.app.models; - console.log(ticketsIds, address); await models.Ticket.rawSql(` CREATE OR REPLACE TEMPORARY TABLE tmp.ticketToInvoice (PRIMARY KEY (id)) diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js index 6f1586c2b1..fe7e527c8e 100644 --- a/modules/ticket/back/methods/ticket/makeInvoice.js +++ b/modules/ticket/back/methods/ticket/makeInvoice.js @@ -67,20 +67,24 @@ module.exports = function(Self) { fields: ['id', 'clientFk', 'addressFk'] }, myOptions); - await models.Ticket.canBeInvoiced(ctx, ticketsIds, myOptions); + await models.Ticket.canBeInvoiced(ctx, ticketsIds, !!invoiceCorrection, myOptions); const [firstTicket] = tickets; const clientId = firstTicket.clientFk; - const clientCanBeInvoiced = await models.Client.canBeInvoiced(clientId, companyFk, invoiceCorrection, myOptions); - if (!clientCanBeInvoiced && !invoiceCorrection) + const clientCanBeInvoiced = + await models.Client.canBeInvoiced(clientId, companyFk, myOptions); + + if (!clientCanBeInvoiced) throw new UserError(`This client can't be invoiced`); - const query = `SELECT vn.invoiceSerial(?, ?, ?) AS serial`; - const [{serial}] = await Self.rawSql(query, [ - clientId, - companyFk, - invoiceType, - ], myOptions); + const [{serial}] = invoiceCorrection ? [{serial: 'R'}] : await Self.rawSql( + `SELECT vn.invoiceSerial(?, ?, ?) AS serial`, + [ + clientId, + companyFk, + invoiceType + ], + myOptions); const invoiceOutSerial = await models.InvoiceOutSerial.findById(serial); if (invoiceOutSerial?.taxAreaFk == 'WORLD') { @@ -92,7 +96,7 @@ module.exports = function(Self) { await Self.rawSql('CALL invoiceOut_new(?, ?, null, @invoiceId)', [serial, invoiceDate], myOptions); const [resultInvoice] = await Self.rawSql('SELECT @invoiceId id', [], myOptions); - if (!resultInvoice) + if (!resultInvoice?.id) throw new UserError('No tickets to invoice', 'notInvoiced'); if (invoiceCorrection) { @@ -102,7 +106,7 @@ module.exports = function(Self) { ); } - if (serial != 'R' && resultInvoice.id) + if (resultInvoice.id) // serial != 'R' && await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions); if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js b/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js index 538dbc49f6..e443ed6d39 100644 --- a/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js +++ b/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js @@ -27,7 +27,7 @@ describe('ticket canBeInvoiced()', () => { WHERE id IN (?) `, [ticketId], options); - const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], options); + const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); expect(canBeInvoiced).toEqual(false); @@ -59,7 +59,7 @@ describe('ticket canBeInvoiced()', () => { WHERE id IN (?) `, [ticketId], options); - const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], options); + const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); expect(canBeInvoiced).toEqual(false); @@ -95,7 +95,7 @@ describe('ticket canBeInvoiced()', () => { WHERE id IN (?) `, [ticketId], options); - const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], options); + const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); expect(canBeInvoiced).toEqual(false); @@ -123,7 +123,7 @@ describe('ticket canBeInvoiced()', () => { WHERE id IN (?) `, [ticketId], options); - const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], options); + const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); expect(canBeInvoiced).toEqual(true); diff --git a/modules/ticket/back/methods/ticket/specs/invoiceTickets.spec.js b/modules/ticket/back/methods/ticket/specs/invoiceTickets.spec.js index 8971fb24a7..162dc066a6 100644 --- a/modules/ticket/back/methods/ticket/specs/invoiceTickets.spec.js +++ b/modules/ticket/back/methods/ticket/specs/invoiceTickets.spec.js @@ -31,7 +31,7 @@ describe('ticket invoiceTickets()', () => { const options = {transaction: tx}; const ticketsIds = [11, 16]; - await models.Ticket.invoiceTickets(ctx, ticketsIds, options); + await models.Ticket.invoiceTickets(ctx, ticketsIds, null, options); await tx.rollback(); } catch (e) { @@ -57,7 +57,7 @@ describe('ticket invoiceTickets()', () => { await client.updateAttribute('isTaxDataChecked', false, options); const ticketsIds = [11]; - await models.Ticket.invoiceTickets(ctx, ticketsIds, options); + await models.Ticket.invoiceTickets(ctx, ticketsIds, null, options); await tx.rollback(); } catch (e) { @@ -80,8 +80,8 @@ describe('ticket invoiceTickets()', () => { const options = {transaction: tx}; const ticketsIds = [11]; - await models.Ticket.invoiceTickets(ctx, ticketsIds, options); - await models.Ticket.invoiceTickets(ctx, ticketsIds, options); + await models.Ticket.invoiceTickets(ctx, ticketsIds, null, options); + await models.Ticket.invoiceTickets(ctx, ticketsIds, null, options); await tx.rollback(); } catch (e) { @@ -102,7 +102,7 @@ describe('ticket invoiceTickets()', () => { const options = {transaction: tx}; const ticketsIds = [11]; - const invoicesIds = await models.Ticket.invoiceTickets(ctx, ticketsIds, options); + const invoicesIds = await models.Ticket.invoiceTickets(ctx, ticketsIds, null, options); expect(invoicesIds.length).toBeGreaterThan(0); diff --git a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js index 9b1fd8f6f3..4563036026 100644 --- a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js +++ b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js @@ -42,7 +42,7 @@ describe('ticket makeInvoice()', () => { WHERE id IN (?) `, [ticketsIds], options); - const invoiceId = await models.Ticket.makeInvoice(ctx, invoiceType, companyFk, invoiceDate, options); + const invoiceId = await models.Ticket.makeInvoice(ctx, invoiceType, companyFk, invoiceDate, null, options); expect(invoiceId).toBeDefined(); @@ -70,7 +70,7 @@ describe('ticket makeInvoice()', () => { WHERE id IN (?) `, [ticketsId], options); - await models.Ticket.makeInvoice(ctx, invoiceType, companyFk, invoiceDate, options); + await models.Ticket.makeInvoice(ctx, invoiceType, companyFk, invoiceDate, null, options); await tx.rollback(); } catch (e) { error = e; diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index 18db8c1474..cd819e6235 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -292,7 +292,7 @@ class Controller extends Section { const query = 'Tickets/refund'; return this.$http.post(query, params) .then(res => { - const refundTicket = res.data; + const [refundTicket] = res.data; this.vnApp.showSuccess(this.$t('The following refund ticket have been created', { ticketId: refundTicket.id })); diff --git a/modules/ticket/front/descriptor-menu/index.spec.js b/modules/ticket/front/descriptor-menu/index.spec.js index 1bb2701654..c755b14c3d 100644 --- a/modules/ticket/front/descriptor-menu/index.spec.js +++ b/modules/ticket/front/descriptor-menu/index.spec.js @@ -262,11 +262,12 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { const params = { ticketsIds: [16] }; - $httpBackend.expectPOST('Tickets/refund', params).respond({id: 99}); + const response = {id: 99}; + $httpBackend.expectPOST('Tickets/refund', params).respond([response]); controller.refund(); $httpBackend.flush(); - expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.sale', {id: 99}); + expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.sale', response); }); }); diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index 4f6a9e7573..ed6d9b10a3 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -526,7 +526,7 @@ class Controller extends Section { const params = {salesIds: salesIds, withWarehouse: withWarehouse}; const query = 'Sales/refund'; this.$http.post(query, params).then(res => { - const refundTicket = res.data; + const [refundTicket] = res.data; this.vnApp.showSuccess(this.$t('The following refund ticket have been created', { ticketId: refundTicket.id })); diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 70781eb581..36be32f52d 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -729,7 +729,7 @@ describe('Ticket', () => { salesIds: [1, 4], }; const refundTicket = {id: 99}; - $httpBackend.expect('POST', 'Sales/refund', params).respond(200, refundTicket); + $httpBackend.expect('POST', 'Sales/refund', params).respond(200, [refundTicket]); controller.createRefund(); $httpBackend.flush(); From 303b6f524051e05439eb8bd0342e9a97771727cd Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 1 Dec 2023 13:48:56 +0100 Subject: [PATCH 329/449] fix(expencefk): refs #6398 expenceFk to expenseFk --- db/changes/235001/01-procedures.sql | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/db/changes/235001/01-procedures.sql b/db/changes/235001/01-procedures.sql index 121348fbf9..3777708d57 100644 --- a/db/changes/235001/01-procedures.sql +++ b/db/changes/235001/01-procedures.sql @@ -450,13 +450,13 @@ BEGIN INSERT INTO ticketTracking(stateFk, ticketFk, userFk) SELECT * FROM tmp.updateInter; - CALL invoiceExpenceMake(vNewInvoiceId); + CALL invoiceExpenseMake(vNewInvoiceId); CALL invoiceTaxMake(vNewInvoiceId, vTaxArea); UPDATE invoiceOut io JOIN ( SELECT SUM(amount) total - FROM invoiceOutExpence + FROM invoiceOutExpense WHERE invoiceOutFk = vNewInvoiceId ) base JOIN ( @@ -493,15 +493,15 @@ BEGIN SET @vTaxableBaseServices := 0.00; SET @vTaxCodeGeneral := NULL; - INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk) SELECT vNewInvoiceInFk, @vTaxableBaseServices, - sub.expenceFk, + sub.expenseFk, sub.taxTypeSageFk, sub.transactionTypeSageFk FROM ( SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase, - i.expenceFk, + i.expenseFk, i.taxTypeSageFk, i.transactionTypeSageFk, @vTaxCodeGeneral := i.taxClassCodeFk @@ -511,11 +511,11 @@ BEGIN HAVING taxableBase ) sub; - INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk) + INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk) SELECT vNewInvoiceInFk, SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral, @vTaxableBaseServices, 0) taxableBase, - i.expenceFk, + i.expenseFk, i.taxTypeSageFk , i.transactionTypeSageFk FROM tmp.ticketTax tt From 6d486fbec99ae2b471882a2b24530b5b34453f06 Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 1 Dec 2023 13:58:45 +0100 Subject: [PATCH 330/449] refs #6085 trad, remove front, back test --- back/models/specs/mailAliasAccount.spec.js | 73 +++++++++++++++++++ db/changes/235001/00-aclsMails.sql | 3 +- db/dump/fixtures.sql | 7 ++ front/core/locale/es.yml | 1 + loopback/locale/es.json | 4 +- modules/account/back/model-config.json | 3 + .../account/back/models/mail-alias-account.js | 68 ++++++++--------- modules/account/back/models/mail-alias-acl.js | 59 ++++++--------- .../account/back/models/mail-alias-acl.json | 10 ++- .../account/front/alias/acl/create/index.js | 33 --------- modules/account/front/alias/acl/index.js | 4 - .../account/front/alias/acl/index/index.js | 15 ---- modules/account/front/alias/acl/main/index.js | 18 ----- .../front/alias/acl/search-panel/index.js | 26 ------- modules/account/front/alias/index.js | 1 - 15 files changed, 151 insertions(+), 174 deletions(-) create mode 100644 back/models/specs/mailAliasAccount.spec.js delete mode 100644 modules/account/front/alias/acl/create/index.js delete mode 100644 modules/account/front/alias/acl/index.js delete mode 100644 modules/account/front/alias/acl/index/index.js delete mode 100644 modules/account/front/alias/acl/main/index.js delete mode 100644 modules/account/front/alias/acl/search-panel/index.js diff --git a/back/models/specs/mailAliasAccount.spec.js b/back/models/specs/mailAliasAccount.spec.js new file mode 100644 index 0000000000..46d447f901 --- /dev/null +++ b/back/models/specs/mailAliasAccount.spec.js @@ -0,0 +1,73 @@ +const models = require('vn-loopback/server/server').models; + +fdescribe('loopback model MailAliasAccount', () => { + it('should fail to add a mail Alias if the worker doesnt have ACLs', async() => { + const tx = await models.MailAliasAccount.beginTransaction({}); + let error; + + try { + const options = {transaction: tx, accessToken: {userId: 1}}; + await models.MailAliasAccount.create({mailAliasFk: 2, roleFk: 5}, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toEqual('The alias cant be modified'); + }); + + it('should add a mail Alias', async() => { + const tx = await models.MailAliasAccount.beginTransaction({}); + let error; + + try { + const options = {transaction: tx, accessToken: {userId: 9}}; + await models.MailAliasAccount.create({mailAliasFk: 2, roleFk: 5}, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toBeUndefined(); + }); + + it('should add a mail Alias of an inherit role', async() => { + const tx = await models.MailAliasAccount.beginTransaction({}); + let error; + + try { + const options = {transaction: tx, accessToken: {userId: 9}}; + await models.MailAliasAccount.create({mailAliasFk: 3, roleFk: 5}, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toBeUndefined(); + }); + + it('should delete a mail Alias', async() => { + const tx = await models.MailAliasAccount.beginTransaction({}); + let error; + + try { + const options = {transaction: tx, accessToken: {userId: 1}}; + const mailAclId = 2; + await models.MailAliasAccount.destroyAll({id: mailAclId}, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toBeUndefined(); + }); +}); + diff --git a/db/changes/235001/00-aclsMails.sql b/db/changes/235001/00-aclsMails.sql index 92603aec48..5cfea40301 100644 --- a/db/changes/235001/00-aclsMails.sql +++ b/db/changes/235001/00-aclsMails.sql @@ -1,5 +1,6 @@ -- Definición de la tabla mailAliasACL -CREATE TABLE `account`.`mailAliasACL` ( + +CREATE OR REPLACE TABLE `account`.`mailAliasAcl` ( `mailAliasFk` int(10) unsigned NOT NULL, `roleFk` int(10) unsigned NOT NULL, FOREIGN KEY (`mailAliasFk`) REFERENCES `account`.`mailAlias` (`id`), diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 93b7b796f1..62f96b459f 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -3002,3 +3002,10 @@ INSERT INTO `vn`.`invoiceCorrectionType` (`id`, `description`) (1, 'Error in VAT calculation'), (2, 'Error in sales details'), (3, 'Error in customer data'); + +INSERT INTO `account`.`mailAliasAcl` (`mailAliasFk`, `roleFk`) + VALUES + (1, 1), + (2, 9), + (3, 15); + diff --git a/front/core/locale/es.yml b/front/core/locale/es.yml index 96c34d98ca..1b9bbb40b3 100644 --- a/front/core/locale/es.yml +++ b/front/core/locale/es.yml @@ -68,3 +68,4 @@ Load more results: Cargar más resultados Send cau: Enviar cau By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc ExplainReason: Explique el motivo por el que no deberia aparecer este fallo +You already have the mailAlias: Ya tienes este mail diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 01384efb42..2e516bf120 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -329,5 +329,7 @@ "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", "Cannot past travels with entries": "No se pueden pasar envíos con entradas", - "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}" + "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", + "You already have the mailAlias": "You already have the mailAlias", + "The alias cant be modified": "The alias cant be modified" } \ No newline at end of file diff --git a/modules/account/back/model-config.json b/modules/account/back/model-config.json index b4bd6dbafd..0cd43d0cec 100644 --- a/modules/account/back/model-config.json +++ b/modules/account/back/model-config.json @@ -14,6 +14,9 @@ "MailAliasAccount": { "dataSource": "vn" }, + "MailAliasAcl": { + "dataSource": "vn" + }, "MailConfig": { "dataSource": "vn" }, diff --git a/modules/account/back/models/mail-alias-account.js b/modules/account/back/models/mail-alias-account.js index 6f5213f24b..a951896893 100644 --- a/modules/account/back/models/mail-alias-account.js +++ b/modules/account/back/models/mail-alias-account.js @@ -2,54 +2,54 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { + Self.rewriteDbError(function(err) { + if (err.code === 'ER_DUP_ENTRY') + return new UserError(`You already have the mailAlias`); + return err; + }); + Self.observe('before save', async ctx => { const changes = ctx.currentInstance || ctx.instance; - await Self.hasGrant(ctx, changes.mailAlias); + await checkModifyPermission(ctx, changes.mailAlias); }); Self.observe('before delete', async ctx => { const mailAliasAccount = await Self.findById(ctx.where.id); - await Self.hasGrant(ctx, mailAliasAccount.mailAlias); + await checkModifyPermission(ctx, mailAliasAccount.mailAlias); }); - /** - * Checks if current user has - * grant to add/remove alias - * - * @param {Object} ctx - Request context - * @param {Interger} mailAlias - mailAlias id - * @return {Boolean} True for user with grant - */ - Self.hasGrant = async function(ctx, mailAlias) { + async function checkModifyPermission(ctx, mailAliasFk) { + const userId = ctx.options.accessToken.userId; + const available = await Self.getAvailable(userId); + if (!available.has(mailAliasFk)) + throw new UserError('The alias cant be modified'); + } + + Self.getAvailable = async function(userId, options) { const models = Self.app.models; - const accessToken = {req: {accessToken: ctx.options.accessToken}}; - const userId = accessToken.req.accessToken.userId; - const canEditAlias = await models.ACL.checkAccessAcl(accessToken, 'MailAliasAccount', 'canEditAlias', 'WRITE'); - if (canEditAlias) return true; + const myOptions = {}; - const user = await models.VnUser.findById(userId, {fields: ['hasGrant']}); - if (!user.hasGrant) - throw new UserError(`You don't have grant privilege`); + if (typeof options == 'object') + Object.assign(myOptions, options); - const account = await models.Account.findById(userId, { - fields: ['id'], - include: { - relation: 'aliases', - scope: { - fields: ['mailAlias'] - } + const roles = await models.RoleMapping.find({ + fields: ['roleId'], + where: {principalId: userId} + }, myOptions); + + const availableMailAlias = await models.MailAliasAcl.find({ + fields: ['mailAliasFk'], + include: {relation: 'mailAlias'}, + where: { + roleFk: { + inq: roles.map(role => role.roleId), + }, } - }); - - const aliases = account.aliases().map(alias => alias.mailAlias); - - const hasAlias = aliases.includes(mailAlias); - if (!hasAlias) - throw new UserError(`You cannot assign/remove an alias that you are not assigned to`); - - return true; + }, myOptions); + const mailAliasArray = Array.from(availableMailAlias, alias => alias.mailAliasFk); + return new Set(mailAliasArray); }; }; diff --git a/modules/account/back/models/mail-alias-acl.js b/modules/account/back/models/mail-alias-acl.js index 4a74472fed..a951896893 100644 --- a/modules/account/back/models/mail-alias-acl.js +++ b/modules/account/back/models/mail-alias-acl.js @@ -1,43 +1,33 @@ + const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - require('../methods/notification/getList')(Self); - - Self.observe('before save', async function(ctx) { - await checkModifyPermission(ctx); + Self.rewriteDbError(function(err) { + if (err.code === 'ER_DUP_ENTRY') + return new UserError(`You already have the mailAlias`); + return err; }); - Self.observe('before delete', async function(ctx) { - await checkModifyPermission(ctx); + Self.observe('before save', async ctx => { + const changes = ctx.currentInstance || ctx.instance; + + await checkModifyPermission(ctx, changes.mailAlias); }); - async function checkModifyPermission(ctx) { - const models = Self.app.models; - const instance = ctx.instance; + Self.observe('before delete', async ctx => { + const mailAliasAccount = await Self.findById(ctx.where.id); + + await checkModifyPermission(ctx, mailAliasAccount.mailAlias); + }); + + async function checkModifyPermission(ctx, mailAliasFk) { const userId = ctx.options.accessToken.userId; - - let mailAliasFk; - let roleFk; - - if (instance) { - mailAliasFk = instance.mailAliasFk; - roleFk = instance.roleFk; - } else { - const mailAliasAcl = await models.MailAlias.findById(ctx.where.id); - mailAliasFk = mailAliasAcl.id; - roleFk = mailAliasAcl.roleFk; - } - - const role = await models.VnUser.findById(roleFk, {fields: ['id', 'role']}); - const available = await Self.getAvailable(roleFk); - const hasAcl = available.has(mailAliasFk); - - if (!hasAcl || (userId.role != role)) + const available = await Self.getAvailable(userId); + if (!available.has(mailAliasFk)) throw new UserError('The alias cant be modified'); } Self.getAvailable = async function(userId, options) { - const availableMailAliasMap = new Map(); const models = Self.app.models; const myOptions = {}; @@ -51,20 +41,15 @@ module.exports = Self => { }, myOptions); const availableMailAlias = await models.MailAliasAcl.find({ - fields: ['mailAliasFk', 'roleFk'], - include: {relation: 'roleFk'}, + fields: ['mailAliasFk'], + include: {relation: 'mailAlias'}, where: { roleFk: { inq: roles.map(role => role.roleId), }, } }, myOptions); - - for (available of availableMailAlias) { - availableMailAliasMap.set(available.mailAliasFk, { - mailAliasFk: available.mailAliasFk, - }); - } - return availableMailAliasMap; + const mailAliasArray = Array.from(availableMailAlias, alias => alias.mailAliasFk); + return new Set(mailAliasArray); }; }; diff --git a/modules/account/back/models/mail-alias-acl.json b/modules/account/back/models/mail-alias-acl.json index 2e44f38ebb..014b95d144 100644 --- a/modules/account/back/models/mail-alias-acl.json +++ b/modules/account/back/models/mail-alias-acl.json @@ -1,28 +1,30 @@ { - "name": "mailAliasACL", + "name": "MailAliasAcl", "base": "VnModel", "options": { "mysql": { - "table": "account.mailAliasACL" + "table": "account.mailAliasAcl" } }, "properties": { "mailAliasFk": { + "id": true, "type": "number" }, "roleFk": { + "id": true, "type": "number" } }, "relations": { "mailAlias": { "type": "belongsTo", - "model": "VnUser", + "model": "MailAlias", "foreignKey": "mailAliasFk" }, "role": { "type": "belongsTo", - "model": "VnUser", + "model": "Role", "foreignKey": "roleFk" } } diff --git a/modules/account/front/alias/acl/create/index.js b/modules/account/front/alias/acl/create/index.js deleted file mode 100644 index 58e70e4aa7..0000000000 --- a/modules/account/front/alias/acl/create/index.js +++ /dev/null @@ -1,33 +0,0 @@ -import ngModule from '../../../module'; -import Section from 'salix/components/section'; - -export default class Controller extends Section { - constructor(...args) { - super(...args); - this.accessTypes = [ - {name: '*'}, - {name: 'READ'}, - {name: 'WRITE'} - ]; - this.permissions = [ - {name: 'ALLOW'}, - {name: 'DENY'} - ]; - - this.models = []; - for (let model in window.validations) - this.models.push({name: model}); - - this.acl = { - property: '*', - principalType: 'ROLE', - accessType: 'READ', - permission: 'ALLOW' - }; - } -} - -ngModule.component('vnAclMailCreate', { - // template: require('./index.html'), - controller: Controller -}); diff --git a/modules/account/front/alias/acl/index.js b/modules/account/front/alias/acl/index.js deleted file mode 100644 index 8393859a5a..0000000000 --- a/modules/account/front/alias/acl/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import './main'; -import './index/'; -import './create'; -import './search-panel'; diff --git a/modules/account/front/alias/acl/index/index.js b/modules/account/front/alias/acl/index/index.js deleted file mode 100644 index 5d8d495747..0000000000 --- a/modules/account/front/alias/acl/index/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import ngModule from '../../../module'; -import Section from 'salix/components/section'; - -export default class Controller extends Section { - onDelete(row) { - return this.$http.delete(`ACLs/${row.id}`) - .then(() => this.$.model.refresh()) - .then(() => this.vnApp.showSuccess(this.$t('ACL removed'))); - } -} - -ngModule.component('vnAclMailIndex', { - // template: require('./index.html'), - controller: Controller -}); diff --git a/modules/account/front/alias/acl/main/index.js b/modules/account/front/alias/acl/main/index.js deleted file mode 100644 index 97f04ee503..0000000000 --- a/modules/account/front/alias/acl/main/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import ngModule from '../../../module'; -import ModuleMain from 'salix/components/module-main'; - -export default class ACL extends ModuleMain { - exprBuilder(param, value) { - switch (param) { - case 'search': - return {model: {like: `%${value}%`}}; - default: - return {[param]: value}; - } - } -} - -ngModule.vnComponent('vnAclMailComponent', { - controller: ACL - // template: require('./index.html') -}); diff --git a/modules/account/front/alias/acl/search-panel/index.js b/modules/account/front/alias/acl/search-panel/index.js deleted file mode 100644 index 67db333834..0000000000 --- a/modules/account/front/alias/acl/search-panel/index.js +++ /dev/null @@ -1,26 +0,0 @@ -import ngModule from '../../../module'; -import SearchPanel from 'core/components/searchbar/search-panel'; - -export default class Controller extends SearchPanel { - constructor(...args) { - super(...args); - this.accessTypes = [ - {name: '*'}, - {name: 'READ'}, - {name: 'WRITE'} - ]; - this.permissions = [ - {name: 'ALLOW'}, - {name: 'DENY'} - ]; - - this.models = []; - for (let model in window.validations) - this.models.push({name: model}); - } -} - -ngModule.component('vnAclSearchPanel', { - // template: require('./index.html'), - controller: Controller -}); diff --git a/modules/account/front/alias/index.js b/modules/account/front/alias/index.js index 5984217494..8eed3a3d3d 100644 --- a/modules/account/front/alias/index.js +++ b/modules/account/front/alias/index.js @@ -7,4 +7,3 @@ import './descriptor'; import './create'; import './basic-data'; import './users'; -import './acl'; From c0ce7e542febf97895ad6ff14e9869f182407e05 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 4 Dec 2023 09:40:57 +0100 Subject: [PATCH 331/449] refs #6085 solve testback --- back/models/specs/mailAliasAccount.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/back/models/specs/mailAliasAccount.spec.js b/back/models/specs/mailAliasAccount.spec.js index 46d447f901..c07e16d60a 100644 --- a/back/models/specs/mailAliasAccount.spec.js +++ b/back/models/specs/mailAliasAccount.spec.js @@ -24,7 +24,7 @@ fdescribe('loopback model MailAliasAccount', () => { try { const options = {transaction: tx, accessToken: {userId: 9}}; - await models.MailAliasAccount.create({mailAliasFk: 2, roleFk: 5}, options); + await models.MailAliasAccount.create({mailAlias: 2, account: 5}, options); await tx.rollback(); } catch (e) { @@ -41,7 +41,7 @@ fdescribe('loopback model MailAliasAccount', () => { try { const options = {transaction: tx, accessToken: {userId: 9}}; - await models.MailAliasAccount.create({mailAliasFk: 3, roleFk: 5}, options); + await models.MailAliasAccount.create({mailAlias: 3, account: 5}, options); await tx.rollback(); } catch (e) { From 051c93a42cdee0ab6403924c95cc1dd4771e6859 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 4 Dec 2023 09:41:24 +0100 Subject: [PATCH 332/449] remove fdescribe --- back/models/specs/mailAliasAccount.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/models/specs/mailAliasAccount.spec.js b/back/models/specs/mailAliasAccount.spec.js index c07e16d60a..d26ed2313a 100644 --- a/back/models/specs/mailAliasAccount.spec.js +++ b/back/models/specs/mailAliasAccount.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; -fdescribe('loopback model MailAliasAccount', () => { +describe('loopback model MailAliasAccount', () => { it('should fail to add a mail Alias if the worker doesnt have ACLs', async() => { const tx = await models.MailAliasAccount.beginTransaction({}); let error; From b9671c0b67b6b4222b61598ac6a5ee2460a684f2 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 4 Dec 2023 14:44:50 +0100 Subject: [PATCH 333/449] refs #6264 perf: remove files related to token --- back/methods/vn-user/is-token-valid.js | 9 --------- back/methods/vn-user/token-config.js | 9 --------- 2 files changed, 18 deletions(-) delete mode 100644 back/methods/vn-user/is-token-valid.js delete mode 100644 back/methods/vn-user/token-config.js diff --git a/back/methods/vn-user/is-token-valid.js b/back/methods/vn-user/is-token-valid.js deleted file mode 100644 index 23b68797ea..0000000000 --- a/back/methods/vn-user/is-token-valid.js +++ /dev/null @@ -1,9 +0,0 @@ -const tokenConfig = require('./token-config'); - -module.exports = async token => { - const accessTokenConfig = await tokenConfig(); - const now = Date.now(); - const differenceMilliseconds = now - token.created; - const differenceSeconds = Math.floor(differenceMilliseconds / 1000); - return differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime; -}; diff --git a/back/methods/vn-user/token-config.js b/back/methods/vn-user/token-config.js deleted file mode 100644 index 0936e0b896..0000000000 --- a/back/methods/vn-user/token-config.js +++ /dev/null @@ -1,9 +0,0 @@ -const DEFAULT_FIELDS = ['renewPeriod', 'courtesyTime']; -const {models} = require('vn-loopback/server/server'); -let currentAccessTokenConfig = null; -module.exports = async(fields = DEFAULT_FIELDS) => { - if (currentAccessTokenConfig) return currentAccessTokenConfig; - const accessTokenConfig = await models.AccessTokenConfig.findOne({fields}); - if (!accessTokenConfig) currentAccessTokenConfig = accessTokenConfig; - return accessTokenConfig; -}; From 5656ed7a2b29860b571125b46796abdd2d7609bd Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 4 Dec 2023 14:46:05 +0100 Subject: [PATCH 334/449] refs #6264 perf: use functions extracted previously --- back/methods/vn-user/renew-token.js | 5 +++-- back/methods/vn-user/validate-token.js | 10 +++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index cb88e665dc..d5d22fd0de 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -1,5 +1,6 @@ const UserError = require('vn-loopback/util/user-error'); -const tokenConfig = require('./token-config'); +const {models} = require('vn-loopback/server/server'); + const DEFAULT_COURTESY_TIME = 60; const handlePromiseLogout = (Self, {id}, courtesyTime = DEFAULT_COURTESY_TIME) => { new Promise(res => { @@ -31,7 +32,7 @@ module.exports = Self => { const isValid = await Self.validateToken(token); if (isValid) throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded'); - const {courtesyTime} = await tokenConfig(); + const {courtesyTime} = await models.AccessTokenConfig.findOne({fields: ['renewPeriod', 'courtesyTime']}); // Schedule to remove current token handlePromiseLogout(Self, token, courtesyTime); diff --git a/back/methods/vn-user/validate-token.js b/back/methods/vn-user/validate-token.js index fadaed43b9..ef3c5b2126 100644 --- a/back/methods/vn-user/validate-token.js +++ b/back/methods/vn-user/validate-token.js @@ -1,5 +1,4 @@ -const isTokenValid = require('./is-token-valid'); - +const {models} = require('vn-loopback/server/server'); module.exports = Self => { Self.remoteMethod('validateToken', { description: 'Validates the current logged user token', @@ -14,7 +13,12 @@ module.exports = Self => { }); Self.validateToken = async function(token) { - const isValid = await isTokenValid(token); + const accessTokenConfig = await models.AccessTokenConfig.findOne({fields: ['renewPeriod', 'courtesyTime']}); + const now = Date.now(); + const differenceMilliseconds = now - token.created; + const differenceSeconds = Math.floor(differenceMilliseconds / 1000); + const isValid = differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime; + return isValid; }; }; From 2fe631f078bf2ca596e083ede0c015e3c1aec2d5 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 5 Dec 2023 07:15:22 +0100 Subject: [PATCH 335/449] refs #5666 feat: change models permissions --- back/model-config.json | 12 ++++++------ db/changes/235001/00-updateACL_Role_VnRole.sql | 14 +++++++++----- loopback/server/model-config.json | 8 -------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/back/model-config.json b/back/model-config.json index 84dd9eebd2..27a94498cf 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -139,12 +139,6 @@ "Warehouse": { "dataSource": "vn" }, - "VnUser": { - "dataSource": "vn" - }, - "VnRole": { - "dataSource": "vn" - }, "OsTicket": { "dataSource": "osticket" }, @@ -159,6 +153,12 @@ }, "ViaexpressConfig": { "dataSource": "vn" + }, + "VnUser": { + "dataSource": "vn" + }, + "VnRole": { + "dataSource": "vn" } } diff --git a/db/changes/235001/00-updateACL_Role_VnRole.sql b/db/changes/235001/00-updateACL_Role_VnRole.sql index 0b10839910..6fbec02a60 100644 --- a/db/changes/235001/00-updateACL_Role_VnRole.sql +++ b/db/changes/235001/00-updateACL_Role_VnRole.sql @@ -1,8 +1,12 @@ -- Auto-generated SQL script #202311301038 -INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) - VALUES ('VnRole','*','*','ALLOW','ROLE','$everyone'); -INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) - VALUES ('VnRole','*','*','ALLOW','ROLE','employee'); +-- INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) +-- VALUES ('VnRole','*','*','ALLOW','ROLE','$everyone'); +-- INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) +-- VALUES ('VnRole','*','*','ALLOW','ROLE','employee'); +INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId) VALUES + ('VnRole','*','READ','ALLOW','ROLE','employee'), + ('VnRole','*','WRITE','ALLOW','ROLE','it'); -- Auto-generated SQL script #202311301203 -UPDATE `salix`.`ACL` SET permission='DENY' WHERE model='Role'; +DELETE FROM`salix`.`ACL` WHERE model='Role'; + diff --git a/loopback/server/model-config.json b/loopback/server/model-config.json index 33ef3797d6..51874988db 100644 --- a/loopback/server/model-config.json +++ b/loopback/server/model-config.json @@ -25,14 +25,6 @@ "FieldAcl": { "dataSource": "vn" }, - "Role": { - "dataSource": "vn", - "options": { - "mysql": { - "table": "salix.Role" - } - } - }, "RoleMapping": { "dataSource": "vn", "options": { From 57add7abf016602c15786d719efd3f46142a549a Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 5 Dec 2023 07:16:12 +0100 Subject: [PATCH 336/449] refs #5666 perf: replace Role by VnRole --- back/methods/vn-user/privileges.js | 2 +- back/methods/vn-user/specs/privileges.spec.js | 2 +- modules/account/back/models/ldap-config.js | 2 +- modules/ticket/back/methods/sale/specs/canEdit.spec.js | 4 ++-- .../back/methods/worker/specs/activeWithInheritedRole.spec.js | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/back/methods/vn-user/privileges.js b/back/methods/vn-user/privileges.js index 08cfaaae88..9f936c29ba 100644 --- a/back/methods/vn-user/privileges.js +++ b/back/methods/vn-user/privileges.js @@ -68,7 +68,7 @@ module.exports = Self => { userToUpdate.hasGrant = hasGrant; if (roleFk) { - const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions); + const role = await models.VnRole.findById(roleFk, {fields: ['name']}, myOptions); const hasRole = await Self.hasRole(userId, role.name, myOptions); if (!hasRole) diff --git a/back/methods/vn-user/specs/privileges.spec.js b/back/methods/vn-user/specs/privileges.spec.js index 3d25eecf97..04d9c09ff3 100644 --- a/back/methods/vn-user/specs/privileges.spec.js +++ b/back/methods/vn-user/specs/privileges.spec.js @@ -70,7 +70,7 @@ describe('VnUser privileges()', () => { const tx = await models.VnUser.beginTransaction({}); const options = {transaction: tx}; - const agency = await models.Role.findOne({ + const agency = await models.VnRole.findOne({ where: { name: 'agency' } diff --git a/modules/account/back/models/ldap-config.js b/modules/account/back/models/ldap-config.js index b557d243c8..89f0add486 100644 --- a/modules/account/back/models/ldap-config.js +++ b/modules/account/back/models/ldap-config.js @@ -239,7 +239,7 @@ module.exports = Self => { // Prepare data - let roles = await $.Role.find({ + let roles = await $.VnRole.find({ fields: ['id', 'name', 'description'] }); let roleRoles = await $.RoleRole.find({ diff --git a/modules/ticket/back/methods/sale/specs/canEdit.spec.js b/modules/ticket/back/methods/sale/specs/canEdit.spec.js index eef9136a84..200ea24cc5 100644 --- a/modules/ticket/back/methods/sale/specs/canEdit.spec.js +++ b/modules/ticket/back/methods/sale/specs/canEdit.spec.js @@ -102,7 +102,7 @@ describe('sale canEdit()', () => { try { const options = {transaction: tx}; - const role = await models.Role.findOne({ + const role = await models.VnRole.findOne({ where: { name: roleEnabled.principalId } @@ -159,7 +159,7 @@ describe('sale canEdit()', () => { try { const options = {transaction: tx}; - const role = await models.Role.findOne({ + const role = await models.VnRole.findOne({ where: { name: roleEnabled.principalId } diff --git a/modules/worker/back/methods/worker/specs/activeWithInheritedRole.spec.js b/modules/worker/back/methods/worker/specs/activeWithInheritedRole.spec.js index da54f6adbe..580e073513 100644 --- a/modules/worker/back/methods/worker/specs/activeWithInheritedRole.spec.js +++ b/modules/worker/back/methods/worker/specs/activeWithInheritedRole.spec.js @@ -3,7 +3,7 @@ const app = require('vn-loopback/server/server'); describe('Worker activeWithInheritedRole', () => { let allRolesCount; beforeAll(async() => { - allRolesCount = await app.models.Role.count(); + allRolesCount = await app.models.VnRole.count(); }); it('should return the workers with an inherited role of salesPerson', async() => { From b4f4714c0a9f6fae89c38b165e813582b37fc99f Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 5 Dec 2023 07:47:38 +0100 Subject: [PATCH 337/449] refs #5666 feat: remove loggable.json --- loopback/common/models/loggable.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 loopback/common/models/loggable.json diff --git a/loopback/common/models/loggable.json b/loopback/common/models/loggable.json deleted file mode 100644 index 62822d0af3..0000000000 --- a/loopback/common/models/loggable.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "Loggable", - "base": "VnModel", - "validateUpsert": true, - "mixins": { - "Loggable": true - } -} From 1d92bbf4a21f24e30e4e51328e636b19ecc6a560 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 5 Dec 2023 07:48:56 +0100 Subject: [PATCH 338/449] refs #5666 feat: replace base value and add mixins --- modules/claim/back/models/claim-beginning.json | 5 ++++- modules/claim/back/models/claim-development.json | 5 ++++- modules/claim/back/models/claim-dms.json | 5 ++++- modules/claim/back/models/claim-end.json | 5 ++++- modules/claim/back/models/claim-observation.json | 5 ++++- modules/claim/back/models/claim-state.json | 5 ++++- modules/claim/back/models/claim.json | 5 ++++- modules/client/back/models/address.json | 5 ++++- modules/client/back/models/client-contact.json | 5 ++++- modules/client/back/models/client-dms.json | 5 ++++- modules/client/back/models/client-informa.json | 5 ++++- modules/client/back/models/client-observation.json | 5 ++++- modules/client/back/models/client-sample.json | 5 ++++- modules/client/back/models/client.json | 5 ++++- modules/client/back/models/greuge.json | 5 ++++- modules/client/back/models/recovery.json | 5 ++++- modules/entry/back/models/buy.json | 5 ++++- modules/entry/back/models/entry-observation.json | 5 ++++- modules/entry/back/models/entry.json | 5 ++++- modules/invoiceIn/back/models/invoice-in-tax.json | 5 ++++- modules/invoiceIn/back/models/invoice-in.json | 5 ++++- modules/item/back/models/item-barcode.json | 5 ++++- modules/item/back/models/item-botanical.json | 5 ++++- modules/item/back/models/item-shelving.json | 5 ++++- modules/item/back/models/item-tag.json | 5 ++++- modules/item/back/models/item-tax-country.json | 5 ++++- modules/item/back/models/item.json | 5 ++++- modules/route/back/models/route.json | 5 ++++- modules/shelving/back/models/shelving.json | 5 ++++- modules/supplier/back/models/supplier-account.json | 5 ++++- modules/supplier/back/models/supplier-address.json | 5 ++++- modules/supplier/back/models/supplier-contact.json | 5 ++++- modules/supplier/back/models/supplier.json | 5 ++++- modules/ticket/back/models/expedition.json | 5 ++++- modules/ticket/back/models/sale.json | 5 ++++- modules/ticket/back/models/ticket-dms.json | 5 ++++- modules/ticket/back/models/ticket-observation.json | 5 ++++- modules/ticket/back/models/ticket-packaging.json | 5 ++++- modules/ticket/back/models/ticket-refund.json | 5 ++++- modules/ticket/back/models/ticket-request.json | 5 ++++- modules/ticket/back/models/ticket-service.json | 5 ++++- modules/ticket/back/models/ticket-tracking.json | 5 ++++- modules/ticket/back/models/ticket-weekly.json | 5 ++++- modules/ticket/back/models/ticket.json | 5 ++++- modules/travel/back/models/travel-thermograph.json | 5 ++++- modules/travel/back/models/travel.json | 5 ++++- modules/worker/back/models/device-production-user.json | 5 ++++- modules/worker/back/models/device-production.json | 5 ++++- modules/worker/back/models/worker-dms.json | 5 ++++- modules/worker/back/models/worker.json | 5 ++++- modules/zone/back/models/zone-event.json | 5 ++++- modules/zone/back/models/zone-exclusion.json | 5 ++++- modules/zone/back/models/zone-included.json | 5 ++++- modules/zone/back/models/zone-warehouse.json | 5 ++++- modules/zone/back/models/zone.json | 5 ++++- 55 files changed, 220 insertions(+), 55 deletions(-) diff --git a/modules/claim/back/models/claim-beginning.json b/modules/claim/back/models/claim-beginning.json index d355881e85..d224586da4 100644 --- a/modules/claim/back/models/claim-beginning.json +++ b/modules/claim/back/models/claim-beginning.json @@ -1,6 +1,9 @@ { "name": "ClaimBeginning", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "claimBeginning" diff --git a/modules/claim/back/models/claim-development.json b/modules/claim/back/models/claim-development.json index b0f352f50e..732955660c 100644 --- a/modules/claim/back/models/claim-development.json +++ b/modules/claim/back/models/claim-development.json @@ -1,6 +1,9 @@ { "name": "ClaimDevelopment", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "claimDevelopment" diff --git a/modules/claim/back/models/claim-dms.json b/modules/claim/back/models/claim-dms.json index 26c90fd690..ed12c925b0 100644 --- a/modules/claim/back/models/claim-dms.json +++ b/modules/claim/back/models/claim-dms.json @@ -1,6 +1,9 @@ { "name": "ClaimDms", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "claimDms" diff --git a/modules/claim/back/models/claim-end.json b/modules/claim/back/models/claim-end.json index 9f12ff93a0..ef5477f50e 100644 --- a/modules/claim/back/models/claim-end.json +++ b/modules/claim/back/models/claim-end.json @@ -1,6 +1,9 @@ { "name": "ClaimEnd", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "claimEnd" diff --git a/modules/claim/back/models/claim-observation.json b/modules/claim/back/models/claim-observation.json index 2d418b76e9..1e4cb6a0f6 100644 --- a/modules/claim/back/models/claim-observation.json +++ b/modules/claim/back/models/claim-observation.json @@ -1,6 +1,9 @@ { "name": "ClaimObservation", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "claimObservation" diff --git a/modules/claim/back/models/claim-state.json b/modules/claim/back/models/claim-state.json index 3ee932f168..c50fdebdfc 100644 --- a/modules/claim/back/models/claim-state.json +++ b/modules/claim/back/models/claim-state.json @@ -1,6 +1,9 @@ { "name": "ClaimState", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "claimState" diff --git a/modules/claim/back/models/claim.json b/modules/claim/back/models/claim.json index a7db1f3e1f..b85b9e073c 100644 --- a/modules/claim/back/models/claim.json +++ b/modules/claim/back/models/claim.json @@ -1,6 +1,9 @@ { "name": "Claim", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "claim" diff --git a/modules/client/back/models/address.json b/modules/client/back/models/address.json index 5f962677d8..e8bf8d8a06 100644 --- a/modules/client/back/models/address.json +++ b/modules/client/back/models/address.json @@ -1,7 +1,10 @@ { "name": "Address", "description": "Client addresses", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "address" diff --git a/modules/client/back/models/client-contact.json b/modules/client/back/models/client-contact.json index 3f71ab79e6..55cc9d4369 100644 --- a/modules/client/back/models/client-contact.json +++ b/modules/client/back/models/client-contact.json @@ -1,7 +1,10 @@ { "name": "ClientContact", "description": "Client phone contacts", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "clientContact" diff --git a/modules/client/back/models/client-dms.json b/modules/client/back/models/client-dms.json index 14b19498e3..6dbcd0140c 100644 --- a/modules/client/back/models/client-dms.json +++ b/modules/client/back/models/client-dms.json @@ -1,6 +1,9 @@ { "name": "ClientDms", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "clientDms" diff --git a/modules/client/back/models/client-informa.json b/modules/client/back/models/client-informa.json index 0c652484e9..5e536faffb 100644 --- a/modules/client/back/models/client-informa.json +++ b/modules/client/back/models/client-informa.json @@ -1,6 +1,9 @@ { "name": "ClientInforma", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "log": { "model":"ClientLog", "relation": "client", diff --git a/modules/client/back/models/client-observation.json b/modules/client/back/models/client-observation.json index 95d00d374f..b204ebeb4a 100644 --- a/modules/client/back/models/client-observation.json +++ b/modules/client/back/models/client-observation.json @@ -1,7 +1,10 @@ { "name": "ClientObservation", "description": "Client notes", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "clientObservation" diff --git a/modules/client/back/models/client-sample.json b/modules/client/back/models/client-sample.json index a32f308ab1..4cd55d9dfd 100644 --- a/modules/client/back/models/client-sample.json +++ b/modules/client/back/models/client-sample.json @@ -1,6 +1,9 @@ { "name": "ClientSample", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "clientSample" diff --git a/modules/client/back/models/client.json b/modules/client/back/models/client.json index f32915bb5c..bfde05162a 100644 --- a/modules/client/back/models/client.json +++ b/modules/client/back/models/client.json @@ -1,6 +1,9 @@ { "name": "Client", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "client" diff --git a/modules/client/back/models/greuge.json b/modules/client/back/models/greuge.json index 884cbd34ed..f57744f8a0 100644 --- a/modules/client/back/models/greuge.json +++ b/modules/client/back/models/greuge.json @@ -1,6 +1,9 @@ { "name": "Greuge", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "greuge" diff --git a/modules/client/back/models/recovery.json b/modules/client/back/models/recovery.json index 5ea89197da..89ec544945 100644 --- a/modules/client/back/models/recovery.json +++ b/modules/client/back/models/recovery.json @@ -1,6 +1,9 @@ { "name": "Recovery", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "recovery" diff --git a/modules/entry/back/models/buy.json b/modules/entry/back/models/buy.json index 30379eaf68..fa804f4d80 100644 --- a/modules/entry/back/models/buy.json +++ b/modules/entry/back/models/buy.json @@ -1,6 +1,9 @@ { "name": "Buy", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "buy" diff --git a/modules/entry/back/models/entry-observation.json b/modules/entry/back/models/entry-observation.json index cdf0c5e6ed..6a1592037a 100644 --- a/modules/entry/back/models/entry-observation.json +++ b/modules/entry/back/models/entry-observation.json @@ -1,6 +1,9 @@ { "name": "EntryObservation", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "entryObservation" diff --git a/modules/entry/back/models/entry.json b/modules/entry/back/models/entry.json index a7508b4e8a..0f3e389b6f 100644 --- a/modules/entry/back/models/entry.json +++ b/modules/entry/back/models/entry.json @@ -1,6 +1,9 @@ { "name": "Entry", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "entry" diff --git a/modules/invoiceIn/back/models/invoice-in-tax.json b/modules/invoiceIn/back/models/invoice-in-tax.json index 5bfbbe2a8d..53b5548b63 100644 --- a/modules/invoiceIn/back/models/invoice-in-tax.json +++ b/modules/invoiceIn/back/models/invoice-in-tax.json @@ -1,6 +1,9 @@ { "name": "InvoiceInTax", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "invoiceInTax" diff --git a/modules/invoiceIn/back/models/invoice-in.json b/modules/invoiceIn/back/models/invoice-in.json index 5be55c8510..59c179e768 100644 --- a/modules/invoiceIn/back/models/invoice-in.json +++ b/modules/invoiceIn/back/models/invoice-in.json @@ -1,6 +1,9 @@ { "name": "InvoiceIn", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "invoiceIn" diff --git a/modules/item/back/models/item-barcode.json b/modules/item/back/models/item-barcode.json index 12068a65fe..6726900eaf 100644 --- a/modules/item/back/models/item-barcode.json +++ b/modules/item/back/models/item-barcode.json @@ -1,6 +1,9 @@ { "name": "ItemBarcode", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "itemBarcode" diff --git a/modules/item/back/models/item-botanical.json b/modules/item/back/models/item-botanical.json index 8a8bba8703..ff1410615c 100644 --- a/modules/item/back/models/item-botanical.json +++ b/modules/item/back/models/item-botanical.json @@ -1,6 +1,9 @@ { "name": "ItemBotanical", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "itemBotanical" diff --git a/modules/item/back/models/item-shelving.json b/modules/item/back/models/item-shelving.json index bb1a141c42..f3be98fc4e 100644 --- a/modules/item/back/models/item-shelving.json +++ b/modules/item/back/models/item-shelving.json @@ -1,6 +1,9 @@ { "name": "ItemShelving", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "itemShelving" diff --git a/modules/item/back/models/item-tag.json b/modules/item/back/models/item-tag.json index 0742f8d3ff..5702cf6cff 100644 --- a/modules/item/back/models/item-tag.json +++ b/modules/item/back/models/item-tag.json @@ -1,6 +1,9 @@ { "name": "ItemTag", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "itemTag" diff --git a/modules/item/back/models/item-tax-country.json b/modules/item/back/models/item-tax-country.json index 002be97d81..795a1b9507 100644 --- a/modules/item/back/models/item-tax-country.json +++ b/modules/item/back/models/item-tax-country.json @@ -1,6 +1,9 @@ { "name": "ItemTaxCountry", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "itemTaxCountry" diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json index 097fe77088..595fb537d1 100644 --- a/modules/item/back/models/item.json +++ b/modules/item/back/models/item.json @@ -1,6 +1,9 @@ { "name": "Item", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "item" diff --git a/modules/route/back/models/route.json b/modules/route/back/models/route.json index cdb64dd715..f8be9023c2 100644 --- a/modules/route/back/models/route.json +++ b/modules/route/back/models/route.json @@ -1,6 +1,9 @@ { "name": "Route", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "route" diff --git a/modules/shelving/back/models/shelving.json b/modules/shelving/back/models/shelving.json index 3103b5a4a5..46fce31e85 100644 --- a/modules/shelving/back/models/shelving.json +++ b/modules/shelving/back/models/shelving.json @@ -1,6 +1,9 @@ { "name": "Shelving", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "shelving" diff --git a/modules/supplier/back/models/supplier-account.json b/modules/supplier/back/models/supplier-account.json index bc9cf0e24b..460c435e20 100644 --- a/modules/supplier/back/models/supplier-account.json +++ b/modules/supplier/back/models/supplier-account.json @@ -1,6 +1,9 @@ { "name": "SupplierAccount", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "supplierAccount" diff --git a/modules/supplier/back/models/supplier-address.json b/modules/supplier/back/models/supplier-address.json index 001b3a31ff..fcd5992870 100644 --- a/modules/supplier/back/models/supplier-address.json +++ b/modules/supplier/back/models/supplier-address.json @@ -1,7 +1,10 @@ { "name": "SupplierAddress", "description": "Supplier addresses", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "supplierAddress" diff --git a/modules/supplier/back/models/supplier-contact.json b/modules/supplier/back/models/supplier-contact.json index f928cd2043..4ea1b8c2a4 100644 --- a/modules/supplier/back/models/supplier-contact.json +++ b/modules/supplier/back/models/supplier-contact.json @@ -1,6 +1,9 @@ { "name": "SupplierContact", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "supplierContact" diff --git a/modules/supplier/back/models/supplier.json b/modules/supplier/back/models/supplier.json index b6245ef324..59d23f1061 100644 --- a/modules/supplier/back/models/supplier.json +++ b/modules/supplier/back/models/supplier.json @@ -1,6 +1,9 @@ { "name": "Supplier", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "supplier" diff --git a/modules/ticket/back/models/expedition.json b/modules/ticket/back/models/expedition.json index 069c6e2813..2dcca1e87a 100644 --- a/modules/ticket/back/models/expedition.json +++ b/modules/ticket/back/models/expedition.json @@ -1,6 +1,9 @@ { "name": "Expedition", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "expedition" diff --git a/modules/ticket/back/models/sale.json b/modules/ticket/back/models/sale.json index 72ca1f5e06..96a36bbc94 100644 --- a/modules/ticket/back/models/sale.json +++ b/modules/ticket/back/models/sale.json @@ -1,6 +1,9 @@ { "name": "Sale", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "sale" diff --git a/modules/ticket/back/models/ticket-dms.json b/modules/ticket/back/models/ticket-dms.json index 071999be7f..a3e6975060 100644 --- a/modules/ticket/back/models/ticket-dms.json +++ b/modules/ticket/back/models/ticket-dms.json @@ -1,6 +1,9 @@ { "name": "TicketDms", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "ticketDms" diff --git a/modules/ticket/back/models/ticket-observation.json b/modules/ticket/back/models/ticket-observation.json index 64e49b2170..26d6f75863 100644 --- a/modules/ticket/back/models/ticket-observation.json +++ b/modules/ticket/back/models/ticket-observation.json @@ -1,6 +1,9 @@ { "name": "TicketObservation", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "ticketObservation" diff --git a/modules/ticket/back/models/ticket-packaging.json b/modules/ticket/back/models/ticket-packaging.json index 6c94c810e6..0cf4948096 100644 --- a/modules/ticket/back/models/ticket-packaging.json +++ b/modules/ticket/back/models/ticket-packaging.json @@ -1,6 +1,9 @@ { "name": "TicketPackaging", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "ticketPackaging" diff --git a/modules/ticket/back/models/ticket-refund.json b/modules/ticket/back/models/ticket-refund.json index d344a3f1c8..249270c8bb 100644 --- a/modules/ticket/back/models/ticket-refund.json +++ b/modules/ticket/back/models/ticket-refund.json @@ -1,6 +1,9 @@ { "name": "TicketRefund", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "ticketRefund" diff --git a/modules/ticket/back/models/ticket-request.json b/modules/ticket/back/models/ticket-request.json index f8407792ef..2cfcd30a16 100644 --- a/modules/ticket/back/models/ticket-request.json +++ b/modules/ticket/back/models/ticket-request.json @@ -1,6 +1,9 @@ { "name": "TicketRequest", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "ticketRequest" diff --git a/modules/ticket/back/models/ticket-service.json b/modules/ticket/back/models/ticket-service.json index f1dbede133..4dfbd2fbd2 100644 --- a/modules/ticket/back/models/ticket-service.json +++ b/modules/ticket/back/models/ticket-service.json @@ -1,6 +1,9 @@ { "name": "TicketService", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "ticketService" diff --git a/modules/ticket/back/models/ticket-tracking.json b/modules/ticket/back/models/ticket-tracking.json index 8b5ce0b643..472bdb966c 100644 --- a/modules/ticket/back/models/ticket-tracking.json +++ b/modules/ticket/back/models/ticket-tracking.json @@ -1,6 +1,9 @@ { "name": "TicketTracking", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "ticketTracking" diff --git a/modules/ticket/back/models/ticket-weekly.json b/modules/ticket/back/models/ticket-weekly.json index c5e485aa23..7494cac792 100644 --- a/modules/ticket/back/models/ticket-weekly.json +++ b/modules/ticket/back/models/ticket-weekly.json @@ -1,6 +1,9 @@ { "name": "TicketWeekly", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "ticketWeekly" diff --git a/modules/ticket/back/models/ticket.json b/modules/ticket/back/models/ticket.json index ec4193bed7..c55cd82bbc 100644 --- a/modules/ticket/back/models/ticket.json +++ b/modules/ticket/back/models/ticket.json @@ -1,6 +1,9 @@ { "name": "Ticket", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "ticket" diff --git a/modules/travel/back/models/travel-thermograph.json b/modules/travel/back/models/travel-thermograph.json index 08eec2847c..cc8e60aaf7 100644 --- a/modules/travel/back/models/travel-thermograph.json +++ b/modules/travel/back/models/travel-thermograph.json @@ -1,6 +1,9 @@ { "name": "TravelThermograph", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "travelThermograph" diff --git a/modules/travel/back/models/travel.json b/modules/travel/back/models/travel.json index 95d4581214..701894a766 100644 --- a/modules/travel/back/models/travel.json +++ b/modules/travel/back/models/travel.json @@ -1,6 +1,9 @@ { "name": "Travel", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "travel" diff --git a/modules/worker/back/models/device-production-user.json b/modules/worker/back/models/device-production-user.json index 3eeaae137f..35a90fb50d 100644 --- a/modules/worker/back/models/device-production-user.json +++ b/modules/worker/back/models/device-production-user.json @@ -1,6 +1,9 @@ { "name": "DeviceProductionUser", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "log": { "model": "DeviceProductionLog", "relation": "deviceProduction" diff --git a/modules/worker/back/models/device-production.json b/modules/worker/back/models/device-production.json index 35787cccc2..f6e5105adc 100644 --- a/modules/worker/back/models/device-production.json +++ b/modules/worker/back/models/device-production.json @@ -1,6 +1,9 @@ { "name": "DeviceProduction", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "log": { "model": "DeviceProductionLog" }, diff --git a/modules/worker/back/models/worker-dms.json b/modules/worker/back/models/worker-dms.json index e9a9f17730..a5c0f30b2d 100644 --- a/modules/worker/back/models/worker-dms.json +++ b/modules/worker/back/models/worker-dms.json @@ -1,6 +1,9 @@ { "name": "WorkerDms", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "workerDocument" diff --git a/modules/worker/back/models/worker.json b/modules/worker/back/models/worker.json index 1a777fffeb..ed430f133f 100644 --- a/modules/worker/back/models/worker.json +++ b/modules/worker/back/models/worker.json @@ -1,7 +1,10 @@ { "name": "Worker", "description": "Company employees", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "worker" diff --git a/modules/zone/back/models/zone-event.json b/modules/zone/back/models/zone-event.json index e477dad6aa..366bdec9d9 100644 --- a/modules/zone/back/models/zone-event.json +++ b/modules/zone/back/models/zone-event.json @@ -1,6 +1,9 @@ { "name": "ZoneEvent", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "zoneEvent" diff --git a/modules/zone/back/models/zone-exclusion.json b/modules/zone/back/models/zone-exclusion.json index 00c9145cda..6e91a0a013 100644 --- a/modules/zone/back/models/zone-exclusion.json +++ b/modules/zone/back/models/zone-exclusion.json @@ -1,6 +1,9 @@ { "name": "ZoneExclusion", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "zoneExclusion" diff --git a/modules/zone/back/models/zone-included.json b/modules/zone/back/models/zone-included.json index deba73f34e..a34e51091d 100644 --- a/modules/zone/back/models/zone-included.json +++ b/modules/zone/back/models/zone-included.json @@ -1,6 +1,9 @@ { "name": "ZoneIncluded", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "zoneIncluded" diff --git a/modules/zone/back/models/zone-warehouse.json b/modules/zone/back/models/zone-warehouse.json index b222e95e72..c2cc989f0a 100644 --- a/modules/zone/back/models/zone-warehouse.json +++ b/modules/zone/back/models/zone-warehouse.json @@ -1,6 +1,9 @@ { "name": "ZoneWarehouse", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "zoneWarehouse" diff --git a/modules/zone/back/models/zone.json b/modules/zone/back/models/zone.json index c86da3d3e9..cf73710530 100644 --- a/modules/zone/back/models/zone.json +++ b/modules/zone/back/models/zone.json @@ -1,6 +1,9 @@ { "name": "Zone", - "base": "Loggable", + "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "zone" From 6f32a588bbc9faacdb5182cf01477f779af19219 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 5 Dec 2023 07:49:10 +0100 Subject: [PATCH 339/449] refs #5666 feat: add role relation to RoleMapping --- loopback/server/model-config.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/loopback/server/model-config.json b/loopback/server/model-config.json index 51874988db..56b5360e84 100644 --- a/loopback/server/model-config.json +++ b/loopback/server/model-config.json @@ -31,6 +31,13 @@ "mysql": { "table": "salix.RoleMapping" } + }, + "relations": { + "role": { + "type": "belongsTo", + "model": "VnRole", + "foreignKey": "roleId" + } } }, "Schema": { From 7a63e527a5298b05028c7721eddbefcfe597f695 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 5 Dec 2023 07:50:52 +0100 Subject: [PATCH 340/449] refs #5666 perf: remove comments --- db/changes/235001/00-updateACL_Role_VnRole.sql | 6 ------ 1 file changed, 6 deletions(-) diff --git a/db/changes/235001/00-updateACL_Role_VnRole.sql b/db/changes/235001/00-updateACL_Role_VnRole.sql index 6fbec02a60..b08a44138e 100644 --- a/db/changes/235001/00-updateACL_Role_VnRole.sql +++ b/db/changes/235001/00-updateACL_Role_VnRole.sql @@ -1,12 +1,6 @@ --- Auto-generated SQL script #202311301038 --- INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) --- VALUES ('VnRole','*','*','ALLOW','ROLE','$everyone'); --- INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId) --- VALUES ('VnRole','*','*','ALLOW','ROLE','employee'); INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId) VALUES ('VnRole','*','READ','ALLOW','ROLE','employee'), ('VnRole','*','WRITE','ALLOW','ROLE','it'); --- Auto-generated SQL script #202311301203 DELETE FROM`salix`.`ACL` WHERE model='Role'; From 318f7e3c0d3d05d498863a7238bddfd380f9cdc7 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Tue, 5 Dec 2023 08:20:55 +0100 Subject: [PATCH 341/449] REFS #6275 feat:Silex_to_Salix --- db/changes/235001/00-silexToSalix.sql | 46 +++++++++++++++++++ .../route/back/methods/route/getTickets.js | 26 +++++------ 2 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 db/changes/235001/00-silexToSalix.sql diff --git a/db/changes/235001/00-silexToSalix.sql b/db/changes/235001/00-silexToSalix.sql new file mode 100644 index 0000000000..362b967ccf --- /dev/null +++ b/db/changes/235001/00-silexToSalix.sql @@ -0,0 +1,46 @@ + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`delivery_beforeInsert` + BEFORE INSERT ON `delivery` + FOR EACH ROW +BEGIN + + IF (NEW.ticketFk IS NOT NULL) + THEN + UPDATE address + SET longitude = NEW.longitude, + latitude = NEW.latitude + WHERE id IN ( + SELECT addressFK + FROM ticket + WHERE id = NEW.ticketFk + ); + END IF; + +END$$ +DELIMITER ; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`delivery_beforeUpdate` + BEFORE UPDATE ON `delivery` + FOR EACH ROW +BEGIN + +IF (NEW.longitude <> OLD.longitude OR NEW.latitude <> OLD.latitude OR NEW.ticketFk <> OLD.ticketFk) + THEN + UPDATE address + SET longitude = NEW.longitude, + latitude = NEW.latitude + WHERE id IN ( + SELECT addressFK + FROM ticket + WHERE id = NEW.ticketFk + ); + END IF; + +END$$ +DELIMITER ; + + +ALTER TABLE `vn`.`address` MODIFY COLUMN longitude decimal(11,7) DEFAULT NULL NULL COMMENT 'Indica la última longitud proporcionada por tabla delivery'; +ALTER TABLE `vn`.`address` MODIFY COLUMN latitude decimal(11,7) DEFAULT NULL NULL COMMENT 'Indica la última latitud proporcionada por tabla delivery'; diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js index 89c68131af..d1ebf9ee74 100644 --- a/modules/route/back/methods/route/getTickets.js +++ b/modules/route/back/methods/route/getTickets.js @@ -40,27 +40,27 @@ module.exports = Self => { t.clientFk, t.priority, t.addressFk, - st.code AS ticketStateCode, - st.name AS ticketStateName, - wh.name AS warehouseName, - tob.description AS ticketObservation, + st.code ticketStateCode, + st.name ticketStateName, + wh.name warehouseName, + tob.description ticketObservation, a.street, a.postalCode, a.city, - am.name AS agencyModeName, - u.nickname AS userNickname, - vn.ticketTotalVolume(t.id) AS volume, + am.name agencyModeName, + u.nickname userNickname, + vn.ticketTotalVolume(t.id) volume, tob.description, GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt, - c.phone ClientPhone, - c.mobile ClientMobile, - a.phone AddressPhone, - a.mobile AddressMobile, + c.phone clientPhone, + c.mobile clientMobile, + a.phone addressPhone, + a.mobile addressMobile, a.longitude, a.latitude, - wm.mediaValue SalePersonPhone, + wm.mediaValue salePersonPhone, t.cmrFk, - t.isSigned Signed + t.isSigned signed FROM vn.route r JOIN ticket t ON t.routeFk = r.id JOIN client c ON t.clientFk = c.id From af07a531ed5c92f313b5b3f4313b3f03bb9dacb9 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 5 Dec 2023 08:49:55 +0100 Subject: [PATCH 342/449] refs #6318 quantity --- modules/ticket/back/methods/ticket-request/confirm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket-request/confirm.js b/modules/ticket/back/methods/ticket-request/confirm.js index 00310f33c3..e782bd66e7 100644 --- a/modules/ticket/back/methods/ticket-request/confirm.js +++ b/modules/ticket/back/methods/ticket-request/confirm.js @@ -63,7 +63,7 @@ module.exports = Self => { const isAvailable = itemStock.available > 0; - if (!isAvailable) + if (!isAvailable || !ctx.args.quantity) throw new UserError(`This item is not available`); if (request.saleFk) From 419ab418160579a6fa8f420a4fe098199d1f0a8e Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 5 Dec 2023 09:55:22 +0100 Subject: [PATCH 343/449] refs #6276 Acl addTimeEntry --- db/changes/235001/00-timecontrol.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/changes/235001/00-timecontrol.sql b/db/changes/235001/00-timecontrol.sql index 4e350b002a..8b59c1cac6 100644 --- a/db/changes/235001/00-timecontrol.sql +++ b/db/changes/235001/00-timecontrol.sql @@ -8,6 +8,6 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp VALUES ('WorkerTimeControl', 'login', 'READ', 'ALLOW', 'ROLE', 'timeControl'), ('WorkerTimeControl', 'getClockIn', 'READ', 'ALLOW', 'ROLE', 'timeControl'), - ('WorkerTimeControl', 'clockIn', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'); + ('WorkerTimeControl', 'addTimeEntry', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'); CALL `account`.`role_sync`(); From f55e85a189ddb7244d45eeb205e9dea3f4183894 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 5 Dec 2023 10:35:48 +0100 Subject: [PATCH 344/449] refs #6010 remove pending --- modules/ticket/back/methods/ticket/specs/filter.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js index 43f3c3680f..c1d3f1a9c5 100644 --- a/modules/ticket/back/methods/ticket/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js @@ -141,7 +141,6 @@ describe('ticket filter()', () => { }); it('should return the tickets that are not pending', async() => { - pending('#6010 test intermitente'); const tx = await models.Ticket.beginTransaction({}); try { From 25006a938be9214bcd62690d5c3c1709053a0e26 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 5 Dec 2023 11:53:27 +0100 Subject: [PATCH 345/449] refs #6274 refactor clockIn --- db/changes/235001/00-timecontrol.sql | 2 +- .../methods/worker-time-control/addTimeEntry.js | 5 +---- .../back/methods/worker-time-control/clockIn.js | 16 +++++++++++++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/db/changes/235001/00-timecontrol.sql b/db/changes/235001/00-timecontrol.sql index 8b59c1cac6..4e350b002a 100644 --- a/db/changes/235001/00-timecontrol.sql +++ b/db/changes/235001/00-timecontrol.sql @@ -8,6 +8,6 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp VALUES ('WorkerTimeControl', 'login', 'READ', 'ALLOW', 'ROLE', 'timeControl'), ('WorkerTimeControl', 'getClockIn', 'READ', 'ALLOW', 'ROLE', 'timeControl'), - ('WorkerTimeControl', 'addTimeEntry', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'); + ('WorkerTimeControl', 'clockIn', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'); CALL `account`.`role_sync`(); diff --git a/modules/worker/back/methods/worker-time-control/addTimeEntry.js b/modules/worker/back/methods/worker-time-control/addTimeEntry.js index cc652fb90b..f3b0127c4f 100644 --- a/modules/worker/back/methods/worker-time-control/addTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/addTimeEntry.js @@ -46,10 +46,7 @@ module.exports = Self => { if (!isSubordinate || (isSubordinate && isHimself && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); - query = `CALL vn.workerTimeControl_clockIn(?,?,?)`; - const [response] = await Self.rawSql(query, [workerId, args.timed, args.direction], myOptions); - if (response[0] && response[0].error) - throw new UserError(response[0].error); + const response = await Self.clockIn(workerId, args.timed, args.direction, myOptions); await models.WorkerTimeControl.resendWeeklyHourEmail(ctx, workerId, args.timed, myOptions); diff --git a/modules/worker/back/methods/worker-time-control/clockIn.js b/modules/worker/back/methods/worker-time-control/clockIn.js index 3cc57d3418..6ed7427785 100644 --- a/modules/worker/back/methods/worker-time-control/clockIn.js +++ b/modules/worker/back/methods/worker-time-control/clockIn.js @@ -1,3 +1,5 @@ +const UserError = require('vn-loopback/util/user-error'); + module.exports = Self => { Self.remoteMethod('clockIn', { description: 'Check if the employee can clock in', @@ -8,6 +10,10 @@ module.exports = Self => { type: 'integer', required: true, }, + { + arg: 'timed', + type: 'date' + }, { arg: 'direction', type: 'string' @@ -24,12 +30,16 @@ module.exports = Self => { } }); - Self.clockIn = async(workerFk, direction, options) => { + Self.clockIn = async(workerFk, timed, direction, options) => { const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const query = 'CALL vn.workerTimeControl_clockIn(?, NULL, ?)'; - return await Self.rawSql(query, [workerFk, direction], myOptions); + const query = 'CALL vn.workerTimeControl_clockIn(?, ?, ?)'; + const [response] = await Self.rawSql(query, [workerFk, timed, direction], myOptions); + if (response[0] && response[0].error) + throw new UserError(response[0].error); + + return response; }; }; From 035b31d878cb989e64f3dc06cd75ff539aad6f74 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 5 Dec 2023 12:00:31 +0100 Subject: [PATCH 346/449] refs #5666 test: fix e2e tests --- front/core/directives/rule.js | 6 +++++- modules/account/front/role/basic-data/index.html | 10 +++++++--- modules/account/front/role/create/index.html | 4 ++-- modules/account/front/role/descriptor/index.html | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/front/core/directives/rule.js b/front/core/directives/rule.js index f65efe176c..d944e13ed9 100644 --- a/front/core/directives/rule.js +++ b/front/core/directives/rule.js @@ -23,7 +23,7 @@ export function directive($translate, $window) { let rule = $attrs.rule.split('.'); let modelName = rule.shift(); let fieldName = rule.shift(); - + let modelAlias = $attrs.ruleAlias; let split = $attrs.ngModel.split('.'); if (!fieldName) fieldName = split.pop() || null; if (!modelName) modelName = firstUpper(split.pop() || ''); @@ -31,8 +31,12 @@ export function directive($translate, $window) { if (!modelName || !fieldName) throw new Error(`rule: Cannot retrieve model or field attribute`); + let modelValidations = vnValidations[modelName]; + if (!modelValidations) + modelValidations = vnValidations[modelAlias]; + if (!modelValidations) throw new Error(`rule: Model '${modelName}' doesn't exist`); diff --git a/modules/account/front/role/basic-data/index.html b/modules/account/front/role/basic-data/index.html index a6d39f3e32..46cb080b78 100644 --- a/modules/account/front/role/basic-data/index.html +++ b/modules/account/front/role/basic-data/index.html @@ -7,6 +7,7 @@
@@ -14,12 +15,15 @@ label="Name" ng-model="$ctrl.role.name" rule + rule-alias="VnRole" vn-focus>
+ label="Description" + ng-model="$ctrl.role.description" + rule + rule-alias="VnRole" + > diff --git a/modules/account/front/role/create/index.html b/modules/account/front/role/create/index.html index b747f7d00e..ee43484d74 100644 --- a/modules/account/front/role/create/index.html +++ b/modules/account/front/role/create/index.html @@ -13,13 +13,13 @@ diff --git a/modules/account/front/role/descriptor/index.html b/modules/account/front/role/descriptor/index.html index 4cd4ac8229..d8bf4857a0 100644 --- a/modules/account/front/role/descriptor/index.html +++ b/modules/account/front/role/descriptor/index.html @@ -24,4 +24,4 @@ on-accept="$ctrl.onDelete()" question="Are you sure you want to continue?" message="Role will be removed"> - \ No newline at end of file + From a5fb07bf127a81e2e9e80935e89ae8840b28babe Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 5 Dec 2023 13:05:26 +0100 Subject: [PATCH 347/449] refs #6264 perf remove unnecessary code --- loopback/server/middleware/current-user.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/loopback/server/middleware/current-user.js b/loopback/server/middleware/current-user.js index 8ff4bb618b..b450f6bb13 100644 --- a/loopback/server/middleware/current-user.js +++ b/loopback/server/middleware/current-user.js @@ -1,16 +1,7 @@ -const {models} = require('vn-loopback/server/server'); - module.exports = function(options) { return async function(req, res, next) { - if (!req.accessToken) { - const token = req.headers.authorization; - if (!token) return next(); - - const accessToken = await models.AccessToken.findById(token); - if (!accessToken) return next(); - + if (!req.accessToken) return next(); - } let LoopBackContext = require('loopback-context'); let loopbackContext = LoopBackContext.getCurrentContext(); From b50a6add0d5e7cc2678a35ff9707f20457dec769 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 5 Dec 2023 15:57:42 +0100 Subject: [PATCH 348/449] refs #6274 merge renewToken --- db/changes/235001/00-timecontrol.sql | 3 ++- db/changes/{234601 => 235001}/00-updateCourtesyTime.sql | 0 2 files changed, 2 insertions(+), 1 deletion(-) rename db/changes/{234601 => 235001}/00-updateCourtesyTime.sql (100%) diff --git a/db/changes/235001/00-timecontrol.sql b/db/changes/235001/00-timecontrol.sql index 4e350b002a..0d3bd59b2e 100644 --- a/db/changes/235001/00-timecontrol.sql +++ b/db/changes/235001/00-timecontrol.sql @@ -8,6 +8,7 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp VALUES ('WorkerTimeControl', 'login', 'READ', 'ALLOW', 'ROLE', 'timeControl'), ('WorkerTimeControl', 'getClockIn', 'READ', 'ALLOW', 'ROLE', 'timeControl'), - ('WorkerTimeControl', 'clockIn', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'); + ('WorkerTimeControl', 'clockIn', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'), + ('VnUser', 'renewToken', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'); CALL `account`.`role_sync`(); diff --git a/db/changes/234601/00-updateCourtesyTime.sql b/db/changes/235001/00-updateCourtesyTime.sql similarity index 100% rename from db/changes/234601/00-updateCourtesyTime.sql rename to db/changes/235001/00-updateCourtesyTime.sql From c9bcd672c90af292ed5ef81b5619fe9493daec80 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Thu, 7 Dec 2023 07:59:21 +0100 Subject: [PATCH 349/449] refs #6028 add:email in ByWorker --- modules/route/back/methods/route/filter.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/route/back/methods/route/filter.js b/modules/route/back/methods/route/filter.js index afefa77d17..ea2f0533e6 100644 --- a/modules/route/back/methods/route/filter.js +++ b/modules/route/back/methods/route/filter.js @@ -130,13 +130,15 @@ module.exports = Self => { am.name agencyName, u.name AS workerUserName, v.numberPlate AS vehiclePlateNumber, - Date_format(r.time, '%H:%i') hour + Date_format(r.time, '%H:%i') hour, + eu.email FROM route r LEFT JOIN agencyMode am ON am.id = r.agencyModeFk LEFT JOIN agency a ON a.id = am.agencyFk LEFT JOIN vehicle v ON v.id = r.vehicleFk LEFT JOIN worker w ON w.id = r.workerFk - LEFT JOIN account.user u ON u.id = w.id` + LEFT JOIN account.user u ON u.id = w.id + LEFT JOIN account.emailUser eu ON eu.userFk = r.workerFk` ); stmt.merge(conn.makeSuffix(filter)); From 0263d880caec8672234a3e90b4a3fb71981b6f7c Mon Sep 17 00:00:00 2001 From: sergiodt Date: Thu, 7 Dec 2023 08:00:17 +0100 Subject: [PATCH 350/449] refs #6028 add:email in ByWorker --- modules/route/back/methods/route/filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/route/back/methods/route/filter.js b/modules/route/back/methods/route/filter.js index ea2f0533e6..7c2225dc9b 100644 --- a/modules/route/back/methods/route/filter.js +++ b/modules/route/back/methods/route/filter.js @@ -138,7 +138,7 @@ module.exports = Self => { LEFT JOIN vehicle v ON v.id = r.vehicleFk LEFT JOIN worker w ON w.id = r.workerFk LEFT JOIN account.user u ON u.id = w.id - LEFT JOIN account.emailUser eu ON eu.userFk = r.workerFk` + LEFT JOIN account.emailUser eu ON eu.userFk = r.workerFk` ); stmt.merge(conn.makeSuffix(filter)); From 58ba1c10d0029c0b62c72e14748ccd88685f8195 Mon Sep 17 00:00:00 2001 From: jgallego Date: Thu, 7 Dec 2023 08:01:16 +0100 Subject: [PATCH 351/449] ci: dev-test --- CHANGELOG.md | 6 ++++++ db/changes/235201/.gitkeep | 0 package.json | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/changes/235201/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bc8ae0211..dfdc563fb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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). +## [2352.01] - 2023-12-28 + +### Added +### Changed +### Fixed + ## [2350.01] - 2023-12-14 ### Added diff --git a/db/changes/235201/.gitkeep b/db/changes/235201/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package.json b/package.json index 586c963dd6..66a5cd2fa6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.50.01", + "version": "23.52.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From 61ed53bd1d75f3bbc0e0478231a2c60b8033aba6 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Thu, 7 Dec 2023 10:37:06 +0100 Subject: [PATCH 352/449] REFS #6275 feat:Silex_to_Salix --- db/changes/235001/00-silexToSalix.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/changes/235001/00-silexToSalix.sql b/db/changes/235001/00-silexToSalix.sql index 362b967ccf..bad430ac24 100644 --- a/db/changes/235001/00-silexToSalix.sql +++ b/db/changes/235001/00-silexToSalix.sql @@ -5,7 +5,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`delivery_beforeInsert FOR EACH ROW BEGIN - IF (NEW.ticketFk IS NOT NULL) + IF (NEW.longitude IS NOT NULL AND NEW.latitude IS NOT NULL AND NEW.ticketFK IS NOT NULL) THEN UPDATE address SET longitude = NEW.longitude, @@ -26,7 +26,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`delivery_beforeUpdate FOR EACH ROW BEGIN -IF (NEW.longitude <> OLD.longitude OR NEW.latitude <> OLD.latitude OR NEW.ticketFk <> OLD.ticketFk) +IF (NEW.longitude IS NOT NULL AND NEW.latitude IS NOT NULL AND NEW.ticketFK IS NOT NULL) THEN UPDATE address SET longitude = NEW.longitude, From fa65cc84a9e98b9d3c7e059b67ae0b797c261e86 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Thu, 7 Dec 2023 11:39:22 +0100 Subject: [PATCH 353/449] REFS #6275 feat:Silex_to_Salix --- .../methods/route/specs/getExpeditionSummary.spec.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 modules/route/back/methods/route/specs/getExpeditionSummary.spec.js diff --git a/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js b/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js new file mode 100644 index 0000000000..b2147aa0b8 --- /dev/null +++ b/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js @@ -0,0 +1,10 @@ +const app = require('vn-loopback/server/server'); + +describe('route getExpeditionSummary()', () => { + const routeId = 1; + fit('should return a summary of expeditions for a route', async() => { + const result = await app.models.Route.getExpeditionSummary(routeId); + + expect(result.length).toEqual(3); + }); +}); From 9937fbed5e77c1986ee4a5076c1df53aa05b3d56 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Thu, 7 Dec 2023 11:59:01 +0100 Subject: [PATCH 354/449] REFS #6275 feat:Silex_to_Salix --- .../route/back/methods/route/specs/getExpeditionSummary.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js b/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js index b2147aa0b8..bdc1242276 100644 --- a/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js +++ b/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js @@ -2,7 +2,7 @@ const app = require('vn-loopback/server/server'); describe('route getExpeditionSummary()', () => { const routeId = 1; - fit('should return a summary of expeditions for a route', async() => { + it('should return a summary of expeditions for a route', async() => { const result = await app.models.Route.getExpeditionSummary(routeId); expect(result.length).toEqual(3); From 7e9134ecc385967ab71eb1b81a9a3ccdb9e13d59 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 7 Dec 2023 13:47:07 +0100 Subject: [PATCH 355/449] refs #5971 change sql address --- print/templates/reports/invoice/invoice.html | 4 ++++ print/templates/reports/invoice/sql/tickets.sql | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/print/templates/reports/invoice/invoice.html b/print/templates/reports/invoice/invoice.html index 45b6c39342..af1aaa423f 100644 --- a/print/templates/reports/invoice/invoice.html +++ b/print/templates/reports/invoice/invoice.html @@ -16,6 +16,7 @@
+ @@ -80,6 +81,9 @@ {{formatDate(ticket.shipped, '%d-%m-%Y')}} + +

{{ticket.street}}

+

{{ticket.nickname}}

diff --git a/print/templates/reports/invoice/sql/tickets.sql b/print/templates/reports/invoice/sql/tickets.sql index a8385599c1..35828c5de0 100644 --- a/print/templates/reports/invoice/sql/tickets.sql +++ b/print/templates/reports/invoice/sql/tickets.sql @@ -2,9 +2,12 @@ SELECT t.id, t.shipped, t.nickname, - tto.description + tto.description, + t.addressFk, + a.street FROM invoiceOut io JOIN ticket t ON t.refFk = io.REF + JOIN `address` a ON a.id = t.addressFk LEFT JOIN observationType ot ON ot.code = 'invoiceOut' LEFT JOIN ticketObservation tto ON tto.ticketFk = t.id AND tto.observationTypeFk = ot.id From 968dc6523132aab070131880afe6bdad55c0931f Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 7 Dec 2023 14:47:22 +0100 Subject: [PATCH 356/449] refs #6274 tests created --- .../worker-time-control/addTimeEntry.js | 8 ++---- .../methods/worker-time-control/clockIn.js | 2 +- .../methods/worker-time-control/getClockIn.js | 4 +-- .../resendWeeklyHourEmail.js | 2 +- .../worker-time-control/specs/clockIn.spec.js | 28 +++++++++++++++++++ .../specs/getClockIn.spec.js | 16 +++++++++++ .../worker-time-control/specs/login.spec.js | 20 +++++++++++++ 7 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js create mode 100644 modules/worker/back/methods/worker-time-control/specs/getClockIn.spec.js create mode 100644 modules/worker/back/methods/worker-time-control/specs/login.spec.js diff --git a/modules/worker/back/methods/worker-time-control/addTimeEntry.js b/modules/worker/back/methods/worker-time-control/addTimeEntry.js index f3b0127c4f..96e3a47d91 100644 --- a/modules/worker/back/methods/worker-time-control/addTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/addTimeEntry.js @@ -43,13 +43,9 @@ module.exports = Self => { const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); const isHimself = userId == workerId; - if (!isSubordinate || (isSubordinate && isHimself && !isTeamBoss)) + if (!isSubordinate || (isHimself && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); - const response = await Self.clockIn(workerId, args.timed, args.direction, myOptions); - - await models.WorkerTimeControl.resendWeeklyHourEmail(ctx, workerId, args.timed, myOptions); - - return response; + return await Self.clockIn(workerId, args.timed, args.direction, myOptions); }; }; diff --git a/modules/worker/back/methods/worker-time-control/clockIn.js b/modules/worker/back/methods/worker-time-control/clockIn.js index 6ed7427785..2e2441cc2a 100644 --- a/modules/worker/back/methods/worker-time-control/clockIn.js +++ b/modules/worker/back/methods/worker-time-control/clockIn.js @@ -7,7 +7,7 @@ module.exports = Self => { accepts: [ { arg: 'workerFk', - type: 'integer', + type: 'number', required: true, }, { diff --git a/modules/worker/back/methods/worker-time-control/getClockIn.js b/modules/worker/back/methods/worker-time-control/getClockIn.js index bc0675db85..4707006439 100644 --- a/modules/worker/back/methods/worker-time-control/getClockIn.js +++ b/modules/worker/back/methods/worker-time-control/getClockIn.js @@ -25,8 +25,8 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - const query = `CALL vn.workerTimeControl_getClockIn(?, CURDATE())`; - const [result] = await Self.rawSql(query, [workerFk], myOptions); + const query = `CALL vn.workerTimeControl_getClockIn(?, ?)`; + const [result] = await Self.rawSql(query, [workerFk, Date.vnNew()], myOptions); return result; }; }; diff --git a/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js b/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js index 2452a29f9c..8964584551 100644 --- a/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js +++ b/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js @@ -1,6 +1,6 @@ module.exports = Self => { Self.remoteMethodCtx('resendWeeklyHourEmail', { - description: 'Adds a new hour registry', + description: 'Send the records for the week of the date provided', accessType: 'WRITE', accepts: [{ arg: 'id', diff --git a/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js b/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js new file mode 100644 index 0000000000..970fd2fe20 --- /dev/null +++ b/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js @@ -0,0 +1,28 @@ +const models = require('vn-loopback/server/server').models; + +describe('workerTimeControl clockIn()', () => { + const workerId = 9; + const inTime = '2001-01-01T00:00:00.000Z'; + + it('should correctly clock in', async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + + try { + const options = {transaction: tx}; + await models.WorkerTimeControl.clockIn(workerId, inTime, 'in', options); + const isClockIn = await models.WorkerTimeControl.findOne({ + where: { + userFk: workerId + } + }, options); + + expect(isClockIn).toBeDefined(); + expect(isClockIn.direction).toBe('in'); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); + diff --git a/modules/worker/back/methods/worker-time-control/specs/getClockIn.spec.js b/modules/worker/back/methods/worker-time-control/specs/getClockIn.spec.js new file mode 100644 index 0000000000..d75ffac704 --- /dev/null +++ b/modules/worker/back/methods/worker-time-control/specs/getClockIn.spec.js @@ -0,0 +1,16 @@ +const models = require('vn-loopback/server/server').models; + +describe('workerTimeControl getClockIn()', () => { + it('should correctly get the timetable of a worker', async() => { + const response = await models.WorkerTimeControl.getClockIn(1106, {}); + + expect(response.length).toEqual(4); + const [inHrs, middleOutHrs, middleInHrs, outHrs] = response; + + expect(inHrs['0daysAgo']).toEqual('07:00'); + expect(middleOutHrs['0daysAgo']).toEqual('10:00'); + expect(middleInHrs['0daysAgo']).toEqual('10:20'); + expect(outHrs['0daysAgo']).toEqual('14:50'); + }); +}); + diff --git a/modules/worker/back/methods/worker-time-control/specs/login.spec.js b/modules/worker/back/methods/worker-time-control/specs/login.spec.js new file mode 100644 index 0000000000..88596f2975 --- /dev/null +++ b/modules/worker/back/methods/worker-time-control/specs/login.spec.js @@ -0,0 +1,20 @@ +const UserError = require('vn-loopback/util/user-error'); +const models = require('vn-loopback/server/server').models; + +describe('workerTimeControl login()', () => { + it('should correctly login', async() => { + const response = await models.WorkerTimeControl.login(9, {}); + + expect(response.name).toBe('developer'); + }); + + it('should throw UserError if pin is not provided', async() => { + try { + await models.WorkerTimeControl.login(); + } catch (error) { + expect(error).toBeInstanceOf(UserError); + expect(error.message).toBe('Indique el pin.'); + } + }); +}); + From b86c73777fe4970326e249843913f6226d824087 Mon Sep 17 00:00:00 2001 From: JAVIER SEGARRA MARTINEZ Date: Thu, 7 Dec 2023 19:05:54 +0000 Subject: [PATCH 357/449] Update back/tests.js --- back/tests.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/back/tests.js b/back/tests.js index 97e548d334..efade4d7dd 100644 --- a/back/tests.js +++ b/back/tests.js @@ -7,6 +7,10 @@ process.on('warning', warning => { console.log(warning.stack); }); +process.on('SIGUSR2', async() => { + if (container) await container.rm(); +}); + process.on('exit', async function() { if (container) await container.rm(); }); From 5a99408ba7295439a3a8061380b009dcf153731e Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 11 Dec 2023 07:31:57 +0100 Subject: [PATCH 358/449] feat: refs #6548 add buyer department to salesPerson list in client BasicData --- modules/client/front/basic-data/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/client/front/basic-data/index.html b/modules/client/front/basic-data/index.html index e48b39fdc0..acab99d915 100644 --- a/modules/client/front/basic-data/index.html +++ b/modules/client/front/basic-data/index.html @@ -62,7 +62,7 @@ From ec66386b442a292329819041dca82b2c2677b2b6 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 11 Dec 2023 07:49:44 +0100 Subject: [PATCH 359/449] refs #5914 fix: correct sql folder --- db/changes/{235001 => 235201}/00-getTaxBases.sql | 0 db/changes/{235001 => 235201}/01-newHasAnyPositiveBase.sql | 0 db/changes/{235001 => 235201}/01-refactorHasAnyNegativeBase.sql | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename db/changes/{235001 => 235201}/00-getTaxBases.sql (100%) rename db/changes/{235001 => 235201}/01-newHasAnyPositiveBase.sql (100%) rename db/changes/{235001 => 235201}/01-refactorHasAnyNegativeBase.sql (100%) diff --git a/db/changes/235001/00-getTaxBases.sql b/db/changes/235201/00-getTaxBases.sql similarity index 100% rename from db/changes/235001/00-getTaxBases.sql rename to db/changes/235201/00-getTaxBases.sql diff --git a/db/changes/235001/01-newHasAnyPositiveBase.sql b/db/changes/235201/01-newHasAnyPositiveBase.sql similarity index 100% rename from db/changes/235001/01-newHasAnyPositiveBase.sql rename to db/changes/235201/01-newHasAnyPositiveBase.sql diff --git a/db/changes/235001/01-refactorHasAnyNegativeBase.sql b/db/changes/235201/01-refactorHasAnyNegativeBase.sql similarity index 100% rename from db/changes/235001/01-refactorHasAnyNegativeBase.sql rename to db/changes/235201/01-refactorHasAnyNegativeBase.sql From 584f3264edc86712c840998d5794c9b34c7fd632 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 11 Dec 2023 08:54:58 +0100 Subject: [PATCH 360/449] refs #6085 refactor sql trad --- .../{235001 => 235201}/00-aclsMails.sql | 0 front/core/locale/es.yml | 2 +- loopback/locale/es.json | 6 +- .../account/back/models/mail-alias-account.js | 14 ++--- modules/account/back/models/mail-alias-acl.js | 55 ------------------- 5 files changed, 9 insertions(+), 68 deletions(-) rename db/changes/{235001 => 235201}/00-aclsMails.sql (100%) delete mode 100644 modules/account/back/models/mail-alias-acl.js diff --git a/db/changes/235001/00-aclsMails.sql b/db/changes/235201/00-aclsMails.sql similarity index 100% rename from db/changes/235001/00-aclsMails.sql rename to db/changes/235201/00-aclsMails.sql diff --git a/front/core/locale/es.yml b/front/core/locale/es.yml index 1b9bbb40b3..17e955ff52 100644 --- a/front/core/locale/es.yml +++ b/front/core/locale/es.yml @@ -68,4 +68,4 @@ Load more results: Cargar más resultados Send cau: Enviar cau By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc ExplainReason: Explique el motivo por el que no deberia aparecer este fallo -You already have the mailAlias: Ya tienes este mail +You already have the mailAlias: Ya tienes este alias de correo diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 2e516bf120..c26bf3ebc7 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -330,6 +330,6 @@ "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", "Cannot past travels with entries": "No se pueden pasar envíos con entradas", "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", - "You already have the mailAlias": "You already have the mailAlias", - "The alias cant be modified": "The alias cant be modified" -} \ No newline at end of file + "You already have the mailAlias": "Ya tienes este alias de correo", + "The alias cant be modified": "Este alias de correo no puede ser modificado" +} diff --git a/modules/account/back/models/mail-alias-account.js b/modules/account/back/models/mail-alias-account.js index a951896893..91fc43008f 100644 --- a/modules/account/back/models/mail-alias-account.js +++ b/modules/account/back/models/mail-alias-account.js @@ -22,12 +22,6 @@ module.exports = Self => { async function checkModifyPermission(ctx, mailAliasFk) { const userId = ctx.options.accessToken.userId; - const available = await Self.getAvailable(userId); - if (!available.has(mailAliasFk)) - throw new UserError('The alias cant be modified'); - } - - Self.getAvailable = async function(userId, options) { const models = Self.app.models; const myOptions = {}; @@ -47,9 +41,11 @@ module.exports = Self => { roleFk: { inq: roles.map(role => role.roleId), }, + mailAliasFk } }, myOptions); - const mailAliasArray = Array.from(availableMailAlias, alias => alias.mailAliasFk); - return new Set(mailAliasArray); - }; + + console.log(availableMailAlias); + if (!availableMailAlias.length) throw new UserError('The alias cant be modified'); + } }; diff --git a/modules/account/back/models/mail-alias-acl.js b/modules/account/back/models/mail-alias-acl.js deleted file mode 100644 index a951896893..0000000000 --- a/modules/account/back/models/mail-alias-acl.js +++ /dev/null @@ -1,55 +0,0 @@ - -const UserError = require('vn-loopback/util/user-error'); - -module.exports = Self => { - Self.rewriteDbError(function(err) { - if (err.code === 'ER_DUP_ENTRY') - return new UserError(`You already have the mailAlias`); - return err; - }); - - Self.observe('before save', async ctx => { - const changes = ctx.currentInstance || ctx.instance; - - await checkModifyPermission(ctx, changes.mailAlias); - }); - - Self.observe('before delete', async ctx => { - const mailAliasAccount = await Self.findById(ctx.where.id); - - await checkModifyPermission(ctx, mailAliasAccount.mailAlias); - }); - - async function checkModifyPermission(ctx, mailAliasFk) { - const userId = ctx.options.accessToken.userId; - const available = await Self.getAvailable(userId); - if (!available.has(mailAliasFk)) - throw new UserError('The alias cant be modified'); - } - - Self.getAvailable = async function(userId, options) { - const models = Self.app.models; - - const myOptions = {}; - - if (typeof options == 'object') - Object.assign(myOptions, options); - - const roles = await models.RoleMapping.find({ - fields: ['roleId'], - where: {principalId: userId} - }, myOptions); - - const availableMailAlias = await models.MailAliasAcl.find({ - fields: ['mailAliasFk'], - include: {relation: 'mailAlias'}, - where: { - roleFk: { - inq: roles.map(role => role.roleId), - }, - } - }, myOptions); - const mailAliasArray = Array.from(availableMailAlias, alias => alias.mailAliasFk); - return new Set(mailAliasArray); - }; -}; From 57ed36cdfc3a0015da94a0eacc74bb0bbcef1505 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 11 Dec 2023 09:43:38 +0100 Subject: [PATCH 361/449] ref #6085 remove console options --- modules/account/back/models/mail-alias-account.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/account/back/models/mail-alias-account.js b/modules/account/back/models/mail-alias-account.js index 91fc43008f..cf9c73f3b1 100644 --- a/modules/account/back/models/mail-alias-account.js +++ b/modules/account/back/models/mail-alias-account.js @@ -26,8 +26,7 @@ module.exports = Self => { const myOptions = {}; - if (typeof options == 'object') - Object.assign(myOptions, options); + Object.assign(myOptions); const roles = await models.RoleMapping.find({ fields: ['roleId'], @@ -45,7 +44,6 @@ module.exports = Self => { } }, myOptions); - console.log(availableMailAlias); if (!availableMailAlias.length) throw new UserError('The alias cant be modified'); } }; From 6ac5d28c4003cd7a192955d5538e5074e45d8b11 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 11 Dec 2023 09:59:09 +0100 Subject: [PATCH 362/449] refs #6085 fix back --- back/models/specs/mailAliasAccount.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/back/models/specs/mailAliasAccount.spec.js b/back/models/specs/mailAliasAccount.spec.js index d26ed2313a..c13cc7ae84 100644 --- a/back/models/specs/mailAliasAccount.spec.js +++ b/back/models/specs/mailAliasAccount.spec.js @@ -6,8 +6,8 @@ describe('loopback model MailAliasAccount', () => { let error; try { - const options = {transaction: tx, accessToken: {userId: 1}}; - await models.MailAliasAccount.create({mailAliasFk: 2, roleFk: 5}, options); + const options = {transaction: tx, accessToken: {userId: 57}}; + await models.MailAliasAccount.create({mailAlias: 2, account: 5}, options); await tx.rollback(); } catch (e) { From 53ff8784ffd8c388b3f3607a1d09977980fa4cf3 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 11 Dec 2023 10:16:46 +0100 Subject: [PATCH 363/449] refs #6085 remove myOptions --- modules/account/back/models/mail-alias-account.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/account/back/models/mail-alias-account.js b/modules/account/back/models/mail-alias-account.js index cf9c73f3b1..8f8e45ae83 100644 --- a/modules/account/back/models/mail-alias-account.js +++ b/modules/account/back/models/mail-alias-account.js @@ -24,14 +24,10 @@ module.exports = Self => { const userId = ctx.options.accessToken.userId; const models = Self.app.models; - const myOptions = {}; - - Object.assign(myOptions); - const roles = await models.RoleMapping.find({ fields: ['roleId'], where: {principalId: userId} - }, myOptions); + }); const availableMailAlias = await models.MailAliasAcl.find({ fields: ['mailAliasFk'], @@ -42,7 +38,7 @@ module.exports = Self => { }, mailAliasFk } - }, myOptions); + }); if (!availableMailAlias.length) throw new UserError('The alias cant be modified'); } From 09ad31a92def0a95fc8066c12dd717dbeb8021f4 Mon Sep 17 00:00:00 2001 From: guillermo Date: Mon, 11 Dec 2023 10:58:48 +0100 Subject: [PATCH 364/449] feat: refs #6172 Requested changes --- front/salix/module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/salix/module.js b/front/salix/module.js index bb7e189a9a..62d6cac98c 100644 --- a/front/salix/module.js +++ b/front/salix/module.js @@ -120,7 +120,7 @@ function $exceptionHandler(vnApp, $window, $state, $injector) { messageT = 'Invalid login'; break; case 403: - messageT = exception.data.error.message || 'Access denied'; + messageT = exception.data?.error?.message || 'Access denied'; break; case 502: messageT = 'It seems that the server has fall down'; From d1f0557923efb2fa1e774ad1b6a3a590fb94f27d Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 11 Dec 2023 12:40:16 +0100 Subject: [PATCH 365/449] refs #5666 perf: remove ruleAlias property --- front/core/directives/rule.js | 5 ----- modules/account/front/role/basic-data/index.html | 6 ++---- modules/account/front/role/card/index.spec.js | 4 ++-- modules/account/front/role/descriptor/index.spec.js | 4 ++-- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/front/core/directives/rule.js b/front/core/directives/rule.js index d944e13ed9..34781c2aac 100644 --- a/front/core/directives/rule.js +++ b/front/core/directives/rule.js @@ -23,7 +23,6 @@ export function directive($translate, $window) { let rule = $attrs.rule.split('.'); let modelName = rule.shift(); let fieldName = rule.shift(); - let modelAlias = $attrs.ruleAlias; let split = $attrs.ngModel.split('.'); if (!fieldName) fieldName = split.pop() || null; if (!modelName) modelName = firstUpper(split.pop() || ''); @@ -31,12 +30,8 @@ export function directive($translate, $window) { if (!modelName || !fieldName) throw new Error(`rule: Cannot retrieve model or field attribute`); - let modelValidations = vnValidations[modelName]; - if (!modelValidations) - modelValidations = vnValidations[modelAlias]; - if (!modelValidations) throw new Error(`rule: Model '${modelName}' doesn't exist`); diff --git a/modules/account/front/role/basic-data/index.html b/modules/account/front/role/basic-data/index.html index 46cb080b78..846f8b455e 100644 --- a/modules/account/front/role/basic-data/index.html +++ b/modules/account/front/role/basic-data/index.html @@ -14,15 +14,13 @@ diff --git a/modules/account/front/role/card/index.spec.js b/modules/account/front/role/card/index.spec.js index f39840e5fa..f02c08f285 100644 --- a/modules/account/front/role/card/index.spec.js +++ b/modules/account/front/role/card/index.spec.js @@ -1,6 +1,6 @@ import './index'; -describe('component vnRoleCard', () => { +fdescribe('component vnRoleCard', () => { let controller; let $httpBackend; @@ -15,7 +15,7 @@ describe('component vnRoleCard', () => { it('should reload the controller data', () => { controller.$params.id = 1; - $httpBackend.expectGET('Roles/1').respond('foo'); + $httpBackend.expectGET('VnRoles/1').respond('foo'); controller.reload(); $httpBackend.flush(); diff --git a/modules/account/front/role/descriptor/index.spec.js b/modules/account/front/role/descriptor/index.spec.js index e2761c6396..eafb96727e 100644 --- a/modules/account/front/role/descriptor/index.spec.js +++ b/modules/account/front/role/descriptor/index.spec.js @@ -1,6 +1,6 @@ import './index'; -describe('component vnRoleDescriptor', () => { +fdescribe('component vnRoleDescriptor', () => { let controller; let $httpBackend; @@ -18,7 +18,7 @@ describe('component vnRoleDescriptor', () => { controller.$state.go = jest.fn(); jest.spyOn(controller.vnApp, 'showSuccess'); - $httpBackend.expectDELETE('Roles/1').respond(); + $httpBackend.expectDELETE('VnRoles/1').respond(); controller.onDelete(); $httpBackend.flush(); From 2beb1f65f09847b78ec5e486af4f359a36887cb0 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 11 Dec 2023 12:45:55 +0100 Subject: [PATCH 366/449] refs #6085 findOne --- modules/account/back/models/mail-alias-account.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/account/back/models/mail-alias-account.js b/modules/account/back/models/mail-alias-account.js index 8f8e45ae83..5eb5614081 100644 --- a/modules/account/back/models/mail-alias-account.js +++ b/modules/account/back/models/mail-alias-account.js @@ -29,7 +29,7 @@ module.exports = Self => { where: {principalId: userId} }); - const availableMailAlias = await models.MailAliasAcl.find({ + const availableMailAlias = await models.MailAliasAcl.findOne({ fields: ['mailAliasFk'], include: {relation: 'mailAlias'}, where: { @@ -40,6 +40,6 @@ module.exports = Self => { } }); - if (!availableMailAlias.length) throw new UserError('The alias cant be modified'); + if (!availableMailAlias) throw new UserError('The alias cant be modified'); } }; From f817551a57f1e9b04682d642dfb4d5b7a926d84e Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 11 Dec 2023 12:59:02 +0100 Subject: [PATCH 367/449] refs #5666 perf: remove ruleAlias property --- modules/account/front/role/create/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/account/front/role/create/index.html b/modules/account/front/role/create/index.html index ee43484d74..77d6fc2c1f 100644 --- a/modules/account/front/role/create/index.html +++ b/modules/account/front/role/create/index.html @@ -13,14 +13,14 @@ + ng-model="$ctrl.role.description" + rule="VnRole.description"> From 84270587cb8beeeab9db0aa56a5af1c1e26250d2 Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 11 Dec 2023 13:42:19 +0100 Subject: [PATCH 368/449] refs #6274 refactor --- modules/worker/back/methods/worker-time-control/addTimeEntry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/methods/worker-time-control/addTimeEntry.js b/modules/worker/back/methods/worker-time-control/addTimeEntry.js index 96e3a47d91..5dbac51ca2 100644 --- a/modules/worker/back/methods/worker-time-control/addTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/addTimeEntry.js @@ -46,6 +46,6 @@ module.exports = Self => { if (!isSubordinate || (isHimself && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); - return await Self.clockIn(workerId, args.timed, args.direction, myOptions); + return Self.clockIn(workerId, args.timed, args.direction, myOptions); }; }; From c81ca94d2e5c8d7e1a5cb94e2d2da1c0f23dcdce Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 11 Dec 2023 14:44:33 +0100 Subject: [PATCH 369/449] refs #6220 add filter address --- modules/client/back/methods/client/filter.js | 56 +++++++++++++------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/modules/client/back/methods/client/filter.js b/modules/client/back/methods/client/filter.js index 47d5f6d2f5..782d355ca6 100644 --- a/modules/client/back/methods/client/filter.js +++ b/modules/client/back/methods/client/filter.js @@ -129,25 +129,43 @@ module.exports = Self => { const stmts = []; const stmt = new ParameterizedSQL( `SELECT - DISTINCT c.id, - c.name, - c.fi, - c.socialName, - c.phone, - c.mobile, - c.city, - c.postcode, - c.email, - c.isActive, - c.isFreezed, - p.id AS provinceFk, - p.name AS province, - u.id AS salesPersonFk, - u.name AS salesPerson - FROM client c - LEFT JOIN account.user u ON u.id = c.salesPersonFk - LEFT JOIN province p ON p.id = c.provinceFk - JOIN vn.address a ON a.clientFk = c.id + DISTINCT c.id, + c.name, + c.fi, + c.socialName, + c.phone, + c.mobile, + c.city, + c.postcode, + c.email, + c.isActive, + c.isFreezed, + p.id AS provinceFk, + p.name AS province, + u.id AS salesPersonFk, + u.name AS salesPerson, + a.street, + a.city AS addressCity, + a.provinceFk AS addressProvinceFk, + a.postalCode AS addressPostalCode, + a.phone AS addressPhone, + a.mobile AS addressMobile, + a.nickname, + a.isDefaultAddress, + a.agencyModeFk AS addressAgencyModeFk, + a.isActive AS addressIsActive, + a.longitude AS addressLongitude, + a.latitude AS addressLatitude, + a.isEqualizated, + a.customsAgentFk AS addressCustomsAgentFk, + a.incotermsFk AS addressIncotermsFk, + a.isLogifloraAllowed, + a.editorFk AS addressEditorFk + FROM client c + LEFT JOIN account.user u ON u.id = c.salesPersonFk + LEFT JOIN province p ON p.id = c.provinceFk + JOIN vn.address a ON a.clientFk = c.id; + ` ); From 7e6f311a431502c72abd7116a76518638bcc0160 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 11 Dec 2023 14:51:11 +0100 Subject: [PATCH 370/449] refs #6220 address filter --- modules/client/back/methods/client/filter.js | 32 ++++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/client/back/methods/client/filter.js b/modules/client/back/methods/client/filter.js index 782d355ca6..d88f15c3fa 100644 --- a/modules/client/back/methods/client/filter.js +++ b/modules/client/back/methods/client/filter.js @@ -140,27 +140,27 @@ module.exports = Self => { c.email, c.isActive, c.isFreezed, - p.id AS provinceFk, - p.name AS province, - u.id AS salesPersonFk, - u.name AS salesPerson, + p.id, + p.name, + u.id, + u.name, a.street, - a.city AS addressCity, - a.provinceFk AS addressProvinceFk, - a.postalCode AS addressPostalCode, - a.phone AS addressPhone, - a.mobile AS addressMobile, + a.city, + a.provinceFk, + a.postalCode, + a.phone, + a.mobile, a.nickname, a.isDefaultAddress, - a.agencyModeFk AS addressAgencyModeFk, - a.isActive AS addressIsActive, - a.longitude AS addressLongitude, - a.latitude AS addressLatitude, + a.agencyModeFk, + a.isActive, + a.longitude, + a.latitude, a.isEqualizated, - a.customsAgentFk AS addressCustomsAgentFk, - a.incotermsFk AS addressIncotermsFk, + a.customsAgentFk, + a.incotermsFk, a.isLogifloraAllowed, - a.editorFk AS addressEditorFk + a.editorFk FROM client c LEFT JOIN account.user u ON u.id = c.salesPersonFk LEFT JOIN province p ON p.id = c.provinceFk From ae767762451137bb58fcaee927f8b401cfe18284 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 12 Dec 2023 12:09:06 +0100 Subject: [PATCH 371/449] refs #2051 feat: removeFile approach --- back/methods/dms/removeFile.js | 15 +++++++---- back/methods/dms/specs/removeFile.spec.js | 2 +- .../back/methods/claim-dms/removeFile.js | 16 ++++++------ .../claim-dms/specs/removeFile.spec.js | 3 ++- .../client-dms/specs/removeFile.spec.js | 3 ++- .../back/methods/ticket-dms/removeFile.js | 14 +++++------ .../ticket-dms/specs/removeFile.spec.js | 2 +- .../back/methods/worker-dms/removeFile.js | 25 ++++++++++++++++--- .../worker-dms/specs/removeFile.spec.js | 3 ++- 9 files changed, 54 insertions(+), 29 deletions(-) diff --git a/back/methods/dms/removeFile.js b/back/methods/dms/removeFile.js index a9ff368834..cb81ff3220 100644 --- a/back/methods/dms/removeFile.js +++ b/back/methods/dms/removeFile.js @@ -34,20 +34,25 @@ module.exports = Self => { } try { - const dms = await models.Dms.findById(id, null, myOptions); + let modelDms = null; + if (myOptions.model) { + modelDms = await models[myOptions.model].findById(id, null, myOptions); + id = modelDms.dmsFk; + } + const targetDms = await models.Dms.findById(id, null, myOptions); const trashDmsType = await models.DmsType.findOne({ where: {code: 'trash'} }, myOptions); - const hasWriteRole = await models.DmsType.hasWriteRole(ctx, dms.dmsTypeFk, myOptions); + const hasWriteRole = await models.DmsType.hasWriteRole(ctx, targetDms.dmsTypeFk, myOptions); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); - await dms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); + await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); if (tx) await tx.commit(); - - return dms; + if (modelDms) modelDms.destroy(myOptions); + return targetDms; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/back/methods/dms/specs/removeFile.spec.js b/back/methods/dms/specs/removeFile.spec.js index 59a2acecb0..e0d1dc1e79 100644 --- a/back/methods/dms/specs/removeFile.spec.js +++ b/back/methods/dms/specs/removeFile.spec.js @@ -1,6 +1,6 @@ const {models} = require('vn-loopback/server/server'); -describe('dms removeFile()', () => { +fdescribe('dms removeFile()', () => { let dmsId = 1; it(`should return an error for a user without enough privileges`, async() => { diff --git a/modules/claim/back/methods/claim-dms/removeFile.js b/modules/claim/back/methods/claim-dms/removeFile.js index edc714235f..257b09cf2d 100644 --- a/modules/claim/back/methods/claim-dms/removeFile.js +++ b/modules/claim/back/methods/claim-dms/removeFile.js @@ -31,15 +31,15 @@ module.exports = Self => { } try { - const models = Self.app.models; - const targetClaimDms = await models.ClaimDms.findById(id, null, myOptions); - const targetDms = await models.Dms.findById(targetClaimDms.dmsFk, null, myOptions); - const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}}, myOptions); + // const {models: ClaimDms, Dms} = Self.app.models; + // const targetClaimDms = await ClaimDms.findById(id, null, myOptions); + // await Dms.findById(targetClaimDms.dmsFk, null, myOptions); + // const trashDmsType = await DmsType.findOne({where: {code: 'trash'}}, myOptions); + myOptions.model = 'ClaimDms'; + const targetDms = await Self.app.models.Dms.removeFile(ctx, id, myOptions); + // await targetClaimDms.destroy(myOptions); - await models.Dms.removeFile(ctx, targetClaimDms.dmsFk, myOptions); - await targetClaimDms.destroy(myOptions); - - await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); + // await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); if (tx) await tx.commit(); diff --git a/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js b/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js index 1cd3b16cb6..210d805e73 100644 --- a/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js +++ b/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js @@ -1,6 +1,7 @@ const app = require('vn-loopback/server/server'); -describe('TicketDms removeFile()', () => { +// f +fdescribe('TicketDms removeFile()', () => { const ticketDmsId = 1; it(`should return an error for a user without enough privileges`, async() => { let clientId = 1101; diff --git a/modules/client/back/methods/client-dms/specs/removeFile.spec.js b/modules/client/back/methods/client-dms/specs/removeFile.spec.js index 6dac712932..61a00a610f 100644 --- a/modules/client/back/methods/client-dms/specs/removeFile.spec.js +++ b/modules/client/back/methods/client-dms/specs/removeFile.spec.js @@ -1,6 +1,7 @@ const models = require('vn-loopback/server/server').models; -describe('ClientDms removeFile()', () => { +// f +fdescribe('ClientDms removeFile()', () => { it(`should return an error for a user without enough privileges`, async() => { const tx = await models.Client.beginTransaction({}); diff --git a/modules/ticket/back/methods/ticket-dms/removeFile.js b/modules/ticket/back/methods/ticket-dms/removeFile.js index f48dc7fef1..2e3ccd149d 100644 --- a/modules/ticket/back/methods/ticket-dms/removeFile.js +++ b/modules/ticket/back/methods/ticket-dms/removeFile.js @@ -19,7 +19,6 @@ module.exports = Self => { }); Self.removeFile = async(ctx, id, options) => { - const models = Self.app.models; const myOptions = {}; let tx; @@ -32,14 +31,15 @@ module.exports = Self => { } try { - const targetTicketDms = await models.TicketDms.findById(id, null, myOptions); - const targetDms = await models.Dms.findById(targetTicketDms.dmsFk, null, myOptions); - const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}}, myOptions); + // const targetTicketDms = await models.TicketDms.findById(id, null, myOptions); + myOptions.model = 'TicketDms'; + // await models.Dms.findById(targetTicketDms.dmsFk, null, myOptions); + // const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}}, myOptions); - await models.Dms.removeFile(ctx, targetTicketDms.dmsFk, myOptions); - await targetTicketDms.destroy(myOptions); + const targetDms = await Self.app.models.Dms.removeFile(ctx, id, myOptions); + // await targetTicketDms.destroy(myOptions); - await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); + // await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js b/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js index 9296984c39..ca4cb5bc35 100644 --- a/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js +++ b/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; -describe('TicketDms removeFile()', () => { +fdescribe('TicketDms removeFile()', () => { const ticketDmsId = 1; it(`should return an error for a user without enough privileges`, async() => { const tx = await models.TicketDms.beginTransaction({}); diff --git a/modules/worker/back/methods/worker-dms/removeFile.js b/modules/worker/back/methods/worker-dms/removeFile.js index b441c56ce1..397255bb2f 100644 --- a/modules/worker/back/methods/worker-dms/removeFile.js +++ b/modules/worker/back/methods/worker-dms/removeFile.js @@ -18,13 +18,30 @@ module.exports = Self => { } }); - Self.removeFile = async(ctx, id) => { + Self.removeFile = async(ctx, id, options) => { const models = Self.app.models; - const workerDms = await Self.findById(id); + let tx; + try { + const myOptions = {}; - await models.Dms.removeFile(ctx, workerDms.dmsFk); + if (typeof options == 'object') + Object.assign(myOptions, options); - return workerDms.destroy(); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + // const workerDms = await Self.findById(id); + myOptions.model = 'WorkerDms'; + await models.Dms.removeFile(ctx, id, myOptions); + // await workerDms.destroy(); + if (tx) await tx.commit(); + + return workerDms; + } catch (e) { + await tx.rollback(); + throw e; + } }; }; diff --git a/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js b/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js index 3efd09464a..e66628656a 100644 --- a/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js +++ b/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js @@ -1,6 +1,7 @@ const app = require('vn-loopback/server/server'); -describe('WorkerDms removeFile()', () => { +// f +fdescribe('WorkerDms removeFile()', () => { const workerDmsFk = 1; it(`should return an error for a user without enough privileges`, async() => { let clientId = 1101; From ea39f8b3be10e0f92c143d398a21bdfb82463739 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 12 Dec 2023 12:25:51 +0100 Subject: [PATCH 372/449] remove duplicate --- db/dump/fixtures.sql | 4 ---- 1 file changed, 4 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index f422dcb451..3354e95c2d 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -5,10 +5,6 @@ SET DEFAULT ROLE 'salix' FOR 'root'@'%'; CREATE SCHEMA IF NOT EXISTS `vn2008`; CREATE SCHEMA IF NOT EXISTS `tmp`; -CREATE ROLE 'salix'; -GRANT 'salix' TO 'root'@'%'; -SET DEFAULT ROLE 'salix' FOR 'root'@'%'; - UPDATE `util`.`config` SET `environment`= 'development'; From 6cefc982e46261dd680e7e1d5797a2d2ffd1daa9 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 12 Dec 2023 13:14:41 +0100 Subject: [PATCH 373/449] refs #6220 add filter address --- modules/client/back/methods/client/filter.js | 81 ++++++++++---------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/modules/client/back/methods/client/filter.js b/modules/client/back/methods/client/filter.js index d88f15c3fa..43310c86b5 100644 --- a/modules/client/back/methods/client/filter.js +++ b/modules/client/back/methods/client/filter.js @@ -107,17 +107,29 @@ module.exports = Self => { return {or: [ {'c.phone': {like: `%${value}%`}}, {'c.mobile': {like: `%${value}%`}}, + {'a.phone': {like: `%${value}%`}}, ]}; case 'zoneFk': - param = 'a.postalCode'; - return {[param]: {inq: postalCode}}; + return {'a.postalCode': {inq: postalCode}}; + case 'city': + return {or: [ + {'c.city': {like: `%${value}`}}, + {'a.city': {like: `%${value}`}} + ]}; + case 'postcode': + return {or: [ + {'c.postcode': {like: `%${value}`}}, + {'a.postalCode': {like: `%${value}`}} + ]}; + case 'provinceFk': + return {or: [ + {'p.name': {like: `%${value}`}}, + {'a.provinceFk': {like: `%${value}`}} + ]}; case 'name': case 'salesPersonFk': case 'fi': case 'socialName': - case 'city': - case 'postcode': - case 'provinceFk': case 'email': param = `c.${param}`; return {[param]: {like: `%${value}%`}}; @@ -129,47 +141,32 @@ module.exports = Self => { const stmts = []; const stmt = new ParameterizedSQL( `SELECT - DISTINCT c.id, - c.name, - c.fi, - c.socialName, - c.phone, - c.mobile, - c.city, - c.postcode, - c.email, - c.isActive, - c.isFreezed, - p.id, - p.name, - u.id, - u.name, - a.street, - a.city, - a.provinceFk, - a.postalCode, - a.phone, - a.mobile, - a.nickname, - a.isDefaultAddress, - a.agencyModeFk, - a.isActive, - a.longitude, - a.latitude, - a.isEqualizated, - a.customsAgentFk, - a.incotermsFk, - a.isLogifloraAllowed, - a.editorFk - FROM client c - LEFT JOIN account.user u ON u.id = c.salesPersonFk - LEFT JOIN province p ON p.id = c.provinceFk - JOIN vn.address a ON a.clientFk = c.id; - + DISTINCT c.id, + c.name, + c.fi, + c.socialName, + CONCAT(c.phone, ',',GROUP_CONCAT(DISTINCT a.phone)) phone, + c.mobile, + CONCAT(c.city, ',',GROUP_CONCAT(DISTINCT a.city)) city, + c.postcode, + a.postalCode, + c.email, + c.isActive, + c.isFreezed, + p.id AS provinceFk2, + a.provinceFk, + p.name AS province, + u.id AS salesPersonFk, + u.name AS salesPerson + FROM client c + LEFT JOIN account.user u ON u.id = c.salesPersonFk + LEFT JOIN province p ON p.id = c.provinceFk + JOIN address a ON a.clientFk = c.id ` ); stmt.merge(conn.makeWhere(filter.where)); + stmt.merge('GROUP BY c.id'); stmt.merge(conn.makePagination(filter)); const clientsIndex = stmts.push(stmt) - 1; From 78aa25d74fe7b34c58d9dc0224db3b47312a73d0 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 12 Dec 2023 13:21:08 +0100 Subject: [PATCH 374/449] refs #6220 fix testback --- modules/client/back/methods/client/specs/filter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/client/back/methods/client/specs/filter.spec.js b/modules/client/back/methods/client/specs/filter.spec.js index 6795850508..4a61f8aafb 100644 --- a/modules/client/back/methods/client/specs/filter.spec.js +++ b/modules/client/back/methods/client/specs/filter.spec.js @@ -146,7 +146,7 @@ describe('client filter()', () => { const randomResultClient = result[randomIndex]; expect(result.length).toBeGreaterThanOrEqual(20); - expect(randomResultClient.city.toLowerCase()).toEqual('gotham'); + expect(randomResultClient.city.toLowerCase()).toEqual('gotham,gotham'); await tx.rollback(); } catch (e) { From 6b70f8b3eb0c5d5111adf0df1f2af77dc1083382 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 12 Dec 2023 13:49:14 +0100 Subject: [PATCH 375/449] refs #2051 feat: uploadFile approach --- .../claim/back/methods/claim/uploadFile.js | 116 +++++++----------- .../client/back/methods/client/uploadFile.js | 24 ++-- .../methods/ticket/specs/uploadFile.spec.js | 27 +++- .../ticket/back/methods/ticket/uploadFile.js | 10 +- .../methods/worker/specs/uploadFile.spec.js | 4 +- .../worker/back/methods/worker/uploadFile.js | 32 +++-- 6 files changed, 113 insertions(+), 100 deletions(-) diff --git a/modules/claim/back/methods/claim/uploadFile.js b/modules/claim/back/methods/claim/uploadFile.js index 3d0737cf81..7e4798fefb 100644 --- a/modules/claim/back/methods/claim/uploadFile.js +++ b/modules/claim/back/methods/claim/uploadFile.js @@ -1,6 +1,3 @@ -const UserError = require('vn-loopback/util/user-error'); -const fs = require('fs-extra'); -const path = require('path'); module.exports = Self => { Self.remoteMethodCtx('uploadFile', { @@ -57,96 +54,75 @@ module.exports = Self => { }); Self.uploadFile = async(ctx, id, options) => { - const tx = await Self.beginTransaction({}); + const models = Self.app.models; const myOptions = {}; + let tx; if (typeof options == 'object') Object.assign(myOptions, options); - if (!myOptions.transaction) + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); myOptions.transaction = tx; + } - const models = Self.app.models; - const promises = []; - const TempContainer = models.TempContainer; - const ClaimContainer = models.ClaimContainer; - const fileOptions = {}; - const args = ctx.args; + // const promises = []; + // const TempContainer = models.TempContainer; + // const ClaimContainer = models.ClaimContainer; + // const fileOptions = {}; + // const args = ctx.args; - let srcFile; + // let srcFile; try { - const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId, myOptions); - if (!hasWriteRole) - throw new UserError(`You don't have enough privileges`); + myOptions.model = 'ClaimDms'; + myOptions.create = {claimFk: id}; + const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions); - // Upload file to temporary path - const tempContainer = await TempContainer.container('dms'); - const uploaded = await TempContainer.upload(tempContainer.name, ctx.req, ctx.result, fileOptions); - const files = Object.values(uploaded.files).map(file => { - return file[0]; - }); + // const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId, myOptions); + // if (!hasWriteRole) + // throw new UserError(`You don't have enough privileges`); - const addedDms = []; - for (const uploadedFile of files) { - const newDms = await createDms(ctx, uploadedFile, myOptions); - const pathHash = ClaimContainer.getHash(newDms.id); + // // Upload file to temporary path + // const tempContainer = await TempContainer.container('dms'); + // const uploaded = await TempContainer.upload(tempContainer.name, ctx.req, ctx.result, fileOptions); + // const files = Object.values(uploaded.files).map(file => { + // return file[0]; + // }); - const file = await TempContainer.getFile(tempContainer.name, uploadedFile.name); - srcFile = path.join(file.client.root, file.container, file.name); + // const addedDms = []; + // for (const uploadedFile of files) { + // const newDms = await createDms(ctx, uploadedFile, myOptions); + // const pathHash = ClaimContainer.getHash(newDms.id); - const claimContainer = await ClaimContainer.container(pathHash); - const dstFile = path.join(claimContainer.client.root, pathHash, newDms.file); + // const file = await TempContainer.getFile(tempContainer.name, uploadedFile.name); + // srcFile = path.join(file.client.root, file.container, file.name); - await fs.move(srcFile, dstFile, { - overwrite: true - }); + // const claimContainer = await ClaimContainer.container(pathHash); + // const dstFile = path.join(claimContainer.client.root, pathHash, newDms.file); - addedDms.push(newDms); - } + // await fs.move(srcFile, dstFile, { + // overwrite: true + // }); - addedDms.forEach(dms => { - const newClaimDms = models.ClaimDms.create({ - claimFk: id, - dmsFk: dms.id - }, myOptions); + // addedDms.push(newDms); + // } - promises.push(newClaimDms); - }); - const resolvedPromises = await Promise.all(promises); + // addedDms.forEach(dms => { + // const newClaimDms = models.ClaimDms.create({ + // claimFk: id, + // dmsFk: dms.id + // }, myOptions); + + // promises.push(newClaimDms); + // }); + // const resolvedPromises = await Promise.all(promises); if (tx) await tx.commit(); - return resolvedPromises; + return uploadedFiles; } catch (e) { if (tx) await tx.rollback(); - - if (fs.existsSync(srcFile)) - await fs.unlink(srcFile); - throw e; } }; - - async function createDms(ctx, file, myOptions) { - const models = Self.app.models; - const myUserId = ctx.req.accessToken.userId; - const args = ctx.args; - - const newDms = await models.Dms.create({ - workerFk: myUserId, - dmsTypeFk: args.dmsTypeId, - companyFk: args.companyId, - warehouseFk: args.warehouseId, - reference: args.reference, - description: args.description, - contentType: file.type, - hasFile: args.hasFile - }, myOptions); - - let fileName = file.name; - const extension = models.DmsContainer.getFileExtension(fileName); - fileName = `${newDms.id}.${extension}`; - - return newDms.updateAttribute('file', fileName, myOptions); - } }; diff --git a/modules/client/back/methods/client/uploadFile.js b/modules/client/back/methods/client/uploadFile.js index 99ede27c67..8f471f1b6d 100644 --- a/modules/client/back/methods/client/uploadFile.js +++ b/modules/client/back/methods/client/uploadFile.js @@ -56,8 +56,8 @@ module.exports = Self => { Self.uploadFile = async(ctx, id, options) => { const models = Self.app.models; - let tx; const myOptions = {}; + let tx; if (typeof options == 'object') Object.assign(myOptions, options); @@ -67,23 +67,25 @@ module.exports = Self => { myOptions.transaction = tx; } - const promises = []; + // const promises = []; try { + myOptions.model = 'ClientDms'; + myOptions.create = {clientFk: id}; const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions); - uploadedFiles.forEach(dms => { - const newClientDms = models.ClientDms.create({ - clientFk: id, - dmsFk: dms.id - }, myOptions); + // uploadedFiles.forEach(dms => { + // const newClientDms = models.ClientDms.create({ + // clientFk: id, + // dmsFk: dms.id + // }, myOptions); - promises.push(newClientDms); - }); - const resolvedPromises = await Promise.all(promises); + // promises.push(newClientDms); + // }); + // const resolvedPromises = await Promise.all(promises); if (tx) await tx.commit(); - return resolvedPromises; + return uploadedFiles; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js b/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js index 133c13265b..8c01133e69 100644 --- a/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js +++ b/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; - -describe('Ticket uploadFile()', () => { +// f +fdescribe('Ticket uploadFile()', () => { it(`should return an error for a user without enough privileges`, async() => { const tx = await models.Ticket.beginTransaction({}); @@ -23,4 +23,27 @@ describe('Ticket uploadFile()', () => { expect(error.message).toEqual(`You don't have enough privileges`); }); + + // fit(`should uploadFile`, async() => { + // const tx = await models.Ticket.beginTransaction({}); + + // let error; + // try { + // const options = {transaction: tx}; + + // const ticketId = 15; + // const currentUserId = 9; + // const ticketTypeId = 14; + // const ctx = {req: {accessToken: {userId: currentUserId}}, args: {dmsTypeId: ticketTypeId}, result: new ArrayBuffer(20000)}; + + // await models.Ticket.uploadFile(ctx, ticketId, options); + + // await tx.rollback(); + // } catch (e) { + // await tx.rollback(); + // error = e; + // } + + // expect(error.message).toEqual(`You don't have enough privileges`); + // }); }); diff --git a/modules/ticket/back/methods/ticket/uploadFile.js b/modules/ticket/back/methods/ticket/uploadFile.js index 4de9904e14..63bbe845a9 100644 --- a/modules/ticket/back/methods/ticket/uploadFile.js +++ b/modules/ticket/back/methods/ticket/uploadFile.js @@ -59,10 +59,12 @@ module.exports = Self => { myOptions.transaction = tx; } - const promises = []; + // const promises = []; try { + myOptions.model = 'TicketDms'; + myOptions.create = {ticketFk: id}; const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions); - uploadedFiles.forEach(dms => { + /* uploadedFiles.forEach(dms => { const newTicketDms = models.TicketDms.create({ ticketFk: id, dmsFk: dms.id @@ -71,10 +73,10 @@ module.exports = Self => { promises.push(newTicketDms); }); const resolvedPromises = await Promise.all(promises); - +*/ if (tx) await tx.commit(); - return resolvedPromises; + return uploadedFiles; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/worker/back/methods/worker/specs/uploadFile.spec.js b/modules/worker/back/methods/worker/specs/uploadFile.spec.js index 7a929cd2ba..34426c6a01 100644 --- a/modules/worker/back/methods/worker/specs/uploadFile.spec.js +++ b/modules/worker/back/methods/worker/specs/uploadFile.spec.js @@ -1,6 +1,6 @@ const app = require('vn-loopback/server/server'); - -describe('Worker uploadFile()', () => { +// f +fdescribe('Worker uploadFile()', () => { it(`should return an error for a user without enough privileges`, async() => { let workerId = 1106; let currentUserId = 1102; diff --git a/modules/worker/back/methods/worker/uploadFile.js b/modules/worker/back/methods/worker/uploadFile.js index 588cfe4bde..e624dc9042 100644 --- a/modules/worker/back/methods/worker/uploadFile.js +++ b/modules/worker/back/methods/worker/uploadFile.js @@ -48,14 +48,24 @@ module.exports = Self => { Self.uploadFile = async(ctx, id) => { const models = Self.app.models; - const promises = []; - const tx = await Self.beginTransaction({}); + const myOptions = {}; + let tx; + // const promises = []; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } try { - const options = {transaction: tx}; + myOptions.model = 'WorkerDms'; + myOptions.create = {workerFk: id}; - const uploadedFiles = await models.Dms.uploadFile(ctx, options); - uploadedFiles.forEach(dms => { + const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions); + /* uploadedFiles.forEach(dms => { const newWorkerDms = models.WorkerDms.create({ workerFk: id, dmsFk: dms.id @@ -64,13 +74,13 @@ module.exports = Self => { promises.push(newWorkerDms); }); const resolvedPromises = await Promise.all(promises); +*/ + if (tx) await tx.commit(); - await tx.commit(); - - return resolvedPromises; - } catch (err) { - await tx.rollback(); - throw err; + return uploadedFiles; + } catch (e) { + if (tx) await tx.rollback(); + throw e; } }; }; From 6334431d2b01ba0bbfc559ac69c30719e8d48c10 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 12 Dec 2023 14:00:35 +0100 Subject: [PATCH 376/449] refs #2051 feat: uploadFile approach --- back/methods/dms/uploadFile.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/back/methods/dms/uploadFile.js b/back/methods/dms/uploadFile.js index a4212b8047..abed95a3a6 100644 --- a/back/methods/dms/uploadFile.js +++ b/back/methods/dms/uploadFile.js @@ -96,8 +96,21 @@ module.exports = Self => { } if (tx) await tx.commit(); + const promises = []; + const {model, create} = myOptions; + addedDms.forEach(dms => { + const newDms = models[model].create({ + ...create, + dmsFk: dms.id + }, myOptions); - return addedDms; + promises.push(newDms); + }); + const resolvedPromises = await Promise.all(promises); + + // if (tx) await tx.commit(); + + return resolvedPromises; } catch (e) { if (tx) await tx.rollback(); From 412cac7e94114a891fc66111133de27eb29e8e40 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 12 Dec 2023 14:42:36 +0100 Subject: [PATCH 377/449] refs #5925 models table docuware --- back/methods/docuware/upload.js | 5 +++++ back/models/docuwareTablet.json | 20 ++++++++++++++++++++ back/models/user-config.json | 10 +++++++++- db/changes/235201/00-tabletDocuware.sql | 24 ++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 back/models/docuwareTablet.json create mode 100644 db/changes/235201/00-tabletDocuware.sql diff --git a/back/methods/docuware/upload.js b/back/methods/docuware/upload.js index 7055bf8d5c..a587079a2e 100644 --- a/back/methods/docuware/upload.js +++ b/back/methods/docuware/upload.js @@ -103,6 +103,11 @@ module.exports = Self => { 'FieldName': 'FILTRO_TABLET', 'ItemElementName': 'string', 'Item': 'Tablet1', + }, + { + 'FieldName': 'ID_TABLET', + 'ItemElementName': 'integer', + 'Item': userConfig.tabletFk, } ] }; diff --git a/back/models/docuwareTablet.json b/back/models/docuwareTablet.json new file mode 100644 index 0000000000..dde336bcac --- /dev/null +++ b/back/models/docuwareTablet.json @@ -0,0 +1,20 @@ +{ + "name": "docuwareTablet", + "base": "VnModel", + "options": { + "mysql": { + "table": "vn.docuwareTablet" + } + }, + "properties": { + "id": { + "type": "number" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + } +} diff --git a/back/models/user-config.json b/back/models/user-config.json index 52125dc012..35f6aa1e6a 100644 --- a/back/models/user-config.json +++ b/back/models/user-config.json @@ -26,6 +26,9 @@ }, "darkMode": { "type": "boolean" + }, + "tabletFk": { + "type": "number" } }, "relations": { @@ -43,6 +46,11 @@ "type": "belongsTo", "model": "VnUser", "foreignKey": "userFk" - } + }, + "Tablet": { + "type": "belongsTo", + "model": "docuwareTablet", + "foreignKey": "tabletFk" + } } } diff --git a/db/changes/235201/00-tabletDocuware.sql b/db/changes/235201/00-tabletDocuware.sql new file mode 100644 index 0000000000..c480c1001a --- /dev/null +++ b/db/changes/235201/00-tabletDocuware.sql @@ -0,0 +1,24 @@ +-- vn.docuwareTablet definition + +CREATE TABLE `vn`.`docuwareTablet` ( + `id` int(3) NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL, + `description` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +-- Auto-generated SQL script. Actual values for binary/complex data types may differ - what you see is the default string representation of values. +INSERT INTO `vn`.`docuwareTablet` (`id`,`name`,`description`) + VALUES (1,'tabletRRHH','tablet de recursos humanos'); +INSERT INTO `vn`.`docuwareTablet` (`id`,`name`,`description`) + VALUES (2,'tabletIT','tablet de IT'); +INSERT INTO `vn`.`docuwareTablet` (`id`,`name`,`description`) + VALUES (3,'tabletCompradores','tablet de compradores'); +INSERT INTO `vn`.`docuwareTablet` (`id`,`name`,`description`) + VALUES (4,'tabletComerciales','tablet de comerciales'); +INSERT INTO `vn`.`docuwareTablet` (`id`,`name`,`description`) + VALUES (5,'tabletAdministracion','tablet de administracion'); + +ALTER TABLE `vn`.`userConfig` +ADD COLUMN tabletFk int(3), +ADD FOREIGN KEY (tabletFk) REFERENCES `vn`.`docuwareTablet`(id); From d206c93305e490024b12751d90fcd335668dafdb Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 12 Dec 2023 15:03:00 +0100 Subject: [PATCH 378/449] refs #2051 feat: getAllowedContentTypes approach --- front/salix/components/index.js | 1 + front/salix/components/section-dms/index.js | 24 +++++++++ front/salix/components/section-dms/style.scss | 0 modules/client/front/dms/create/index.js | 54 ++++++++----------- modules/client/front/dms/edit/index.js | 41 ++++++-------- modules/invoiceIn/front/basic-data/index.js | 15 ++---- .../agency-term/createInvoiceIn/index.js | 45 ++++++---------- modules/ticket/front/dms/create/index.js | 53 ++++++++---------- modules/ticket/front/dms/edit/index.js | 41 ++++++-------- .../travel/front/thermograph/create/index.js | 8 +-- .../travel/front/thermograph/edit/index.js | 13 ++--- modules/worker/front/dms/create/index.js | 11 ++-- modules/worker/front/dms/edit/index.js | 42 ++++++--------- 13 files changed, 142 insertions(+), 206 deletions(-) create mode 100644 front/salix/components/section-dms/index.js create mode 100644 front/salix/components/section-dms/style.scss diff --git a/front/salix/components/index.js b/front/salix/components/index.js index 38b0d0e1fb..e843f2f5ee 100644 --- a/front/salix/components/index.js +++ b/front/salix/components/index.js @@ -15,6 +15,7 @@ import './module-card'; import './module-main'; import './side-menu/side-menu'; import './section'; +import './section-dms'; import './summary'; import './topbar/topbar'; import './user-popover'; diff --git a/front/salix/components/section-dms/index.js b/front/salix/components/section-dms/index.js new file mode 100644 index 0000000000..ae7d496cd2 --- /dev/null +++ b/front/salix/components/section-dms/index.js @@ -0,0 +1,24 @@ +import ngModule from '../../module'; +import Component from 'core/lib/component'; +import './style.scss'; + +export default class SectionDms extends Component { + getAllowedContentTypes() { + return this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + return contentTypes; + }); + } + + getDms(dmsId) { + return this.$http.get(`Dms/${dmsId}`).then(res => res); + } + getDmsTypes(params) { + return this.$http.get('DmsTypes/findOne', params).then(res => res); + } +} + +ngModule.vnComponent('vnSectionDms', { + controller: SectionDms +}); diff --git a/front/salix/components/section-dms/style.scss b/front/salix/components/section-dms/style.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/modules/client/front/dms/create/index.js b/modules/client/front/dms/create/index.js index 461d0aa368..ec88379812 100644 --- a/modules/client/front/dms/create/index.js +++ b/modules/client/front/dms/create/index.js @@ -1,8 +1,8 @@ import ngModule from '../../module'; -import Section from 'salix/components/section'; +import SectionDms from 'salix/components/section-dms'; import './style.scss'; -class Controller extends Section { +class Controller extends SectionDms { constructor($element, $) { super($element, $); this.dms = { @@ -20,46 +20,36 @@ class Controller extends Section { this._client = value; if (value) { - this.setDefaultParams(); - this.getAllowedContentTypes(); + const params = {filter: { + where: {code: 'paymentsLaw'} + }}; + this.getDmsTypes(params).then(res => this.handleDefaultParams(res)); + this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); } } - getAllowedContentTypes() { - this.$http.get('DmsContainers/allowedContentTypes').then(res => { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - }); - } - get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - setDefaultParams() { - const params = {filter: { - where: {code: 'paymentsLaw'} - }}; - this.$http.get('DmsTypes/findOne', {params}).then(res => { - const dmsType = res.data && res.data; - const companyId = this.vnConfig.companyFk; - const warehouseId = this.vnConfig.warehouseFk; - const defaultParams = { - reference: this.client.id, - warehouseId: warehouseId, - companyId: companyId, - dmsTypeId: dmsType.id, - description: this.$t('ClientFileDescription', { - dmsTypeName: dmsType.name, - clientId: this.client.id, - clientName: this.client.name - }).toUpperCase() - }; + handleDefaultParams({data: dmsType}) { + const companyId = this.vnConfig.companyFk; + const warehouseId = this.vnConfig.warehouseFk; + const defaultParams = { + reference: this.client.id, + warehouseId: warehouseId, + companyId: companyId, + dmsTypeId: dmsType.id, + description: this.$t('ClientFileDescription', { + dmsTypeName: dmsType.name, + clientId: this.client.id, + clientName: this.client.name + }).toUpperCase() + }; - this.dms = Object.assign(this.dms, defaultParams); - }); + this.dms = Object.assign(this.dms, defaultParams); } onSubmit() { diff --git a/modules/client/front/dms/edit/index.js b/modules/client/front/dms/edit/index.js index 8765eeff2c..36c1a96726 100644 --- a/modules/client/front/dms/edit/index.js +++ b/modules/client/front/dms/edit/index.js @@ -1,8 +1,8 @@ import ngModule from '../../module'; -import Section from 'salix/components/section'; +import SectionDms from 'salix/components/section-dms'; import './style.scss'; -class Controller extends Section { +class Controller extends SectionDms { get client() { return this._client; } @@ -11,39 +11,28 @@ class Controller extends Section { this._client = value; if (value) { - this.setDefaultParams(); - this.getAllowedContentTypes(); + this.getDms(this.$params.dmsId).then(handleDefaultParams); + this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); } } - getAllowedContentTypes() { - this.$http.get('DmsContainers/allowedContentTypes').then(res => { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - }); - } - get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - setDefaultParams() { - const path = `Dms/${this.$params.dmsId}`; - this.$http.get(path).then(res => { - const dms = res.data && res.data; - this.dms = { - reference: dms.reference, - warehouseId: dms.warehouseFk, - companyId: dms.companyFk, - dmsTypeId: dms.dmsTypeFk, - description: dms.description, - hasFile: dms.hasFile, - hasFileAttached: false, - files: [] - }; - }); + handleDefaultParams({data: dms}) { + this.dms = { + reference: dms.reference, + warehouseId: dms.warehouseFk, + companyId: dms.companyFk, + dmsTypeId: dms.dmsTypeFk, + description: dms.description, + hasFile: dms.hasFile, + hasFileAttached: false, + files: [] + }; } onSubmit() { diff --git a/modules/invoiceIn/front/basic-data/index.js b/modules/invoiceIn/front/basic-data/index.js index 246f1b16fd..797fda59dc 100644 --- a/modules/invoiceIn/front/basic-data/index.js +++ b/modules/invoiceIn/front/basic-data/index.js @@ -1,8 +1,8 @@ import ngModule from '../module'; -import Section from 'salix/components/section'; +import SectionDms from 'salix/components/section-dms'; import UserError from 'core/lib/user-error'; -class Controller extends Section { +class Controller extends SectionDms { constructor($element, $, vnFile) { super($element, $, vnFile); this.dms = { @@ -11,7 +11,7 @@ class Controller extends Section { hasFileAttached: false }; this.vnFile = vnFile; - this.getAllowedContentTypes(); + this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); this._editDownloadDisabled = false; } @@ -53,15 +53,6 @@ class Controller extends Section { }); } - getAllowedContentTypes() { - this.$http.get('DmsContainers/allowedContentTypes').then(res => { - if (res.data.length > 0) { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - } - }); - } - openEditDialog(dmsId) { this.getFile(dmsId).then(() => this.$.dmsEditDialog.show()); } diff --git a/modules/route/front/agency-term/createInvoiceIn/index.js b/modules/route/front/agency-term/createInvoiceIn/index.js index 0198ab80fd..5e54f79294 100644 --- a/modules/route/front/agency-term/createInvoiceIn/index.js +++ b/modules/route/front/agency-term/createInvoiceIn/index.js @@ -1,9 +1,9 @@ import ngModule from '../../module'; -import Section from 'salix/components/section'; +import SectionDms from 'salix/components/section-dms'; import './style.scss'; import UserError from 'core/lib/user-error'; -class Controller extends Section { +class Controller extends SectionDms { constructor($element, $) { super($element, $); this.dms = { @@ -19,9 +19,11 @@ class Controller extends Section { set route(value) { this._route = value; - - this.setDefaultParams(); - this.getAllowedContentTypes(); + const params = {filter: { + where: {code: 'invoiceIn'} + }}; + this.getDmsTypes(params).then(res => this.handleDefaultParams(res)); + this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); } $onChanges() { @@ -29,36 +31,23 @@ class Controller extends Section { this.params = JSON.parse(this.$params.q); } - getAllowedContentTypes() { - this.$http.get('DmsContainers/allowedContentTypes').then(res => { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - }); - } - get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - setDefaultParams() { - const params = {filter: { - where: {code: 'invoiceIn'} - }}; - this.$http.get('DmsTypes/findOne', {params}).then(res => { - const dmsType = res.data && res.data; - const companyId = this.vnConfig.companyFk; - const warehouseId = this.vnConfig.warehouseFk; - const defaultParams = { - warehouseId: warehouseId, - companyId: companyId, - dmsTypeId: dmsType.id, - description: this.params.supplierName - }; + handleDefaultParams({data: dmsType}) { + const companyId = this.vnConfig.companyFk; + const warehouseId = this.vnConfig.warehouseFk; + const defaultParams = { + warehouseId: warehouseId, + companyId: companyId, + dmsTypeId: dmsType.id, + description: this.params.supplierName + }; - this.dms = Object.assign(this.dms, defaultParams); - }); + this.dms = Object.assign(this.dms, defaultParams); } onSubmit() { diff --git a/modules/ticket/front/dms/create/index.js b/modules/ticket/front/dms/create/index.js index b25abf17c2..7b25e4665e 100644 --- a/modules/ticket/front/dms/create/index.js +++ b/modules/ticket/front/dms/create/index.js @@ -1,7 +1,7 @@ import ngModule from '../../module'; -import Section from 'salix/components/section'; +import SectionDms from 'salix/components/section-dms'; -class Controller extends Section { +class Controller extends SectionDms { constructor($element, $) { super($element, $); this.dms = { @@ -19,45 +19,36 @@ class Controller extends Section { this._ticket = value; if (value) { - this.setDefaultParams(); - this.getAllowedContentTypes(); + const params = {filter: { + where: {code: 'ticket'} + }}; + this.getDmsTypes(params).then(res => this.handleDefaultParams(res)); + this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); } } - getAllowedContentTypes() { - this.$http.get('DmsContainers/allowedContentTypes').then(res => { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - }); - } - get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - setDefaultParams() { - const params = {filter: { - where: {code: 'ticket'} - }}; - this.$http.get('DmsTypes/findOne', {params}).then(res => { - const dmsTypeId = res.data && res.data.id; - const warehouseId = this.vnConfig.warehouseFk; - const defaultParams = { - reference: this.ticket.id, - warehouseId: warehouseId, - companyId: this.ticket.companyFk, - dmsTypeId: dmsTypeId, - description: this.$t('FileDescription', { - ticketId: this.ticket.id, - clientId: this.ticket.client.id, - clientName: this.ticket.client.name - }).toUpperCase() - }; + handleDefaultParams(data) { + const dmsTypeId = res?.data?.id; + const warehouseId = this.vnConfig.warehouseFk; + const defaultParams = { + reference: this.ticket.id, + warehouseId: warehouseId, + companyId: this.ticket.companyFk, + dmsTypeId: dmsTypeId, + description: this.$t('FileDescription', { + ticketId: this.ticket.id, + clientId: this.ticket.client.id, + clientName: this.ticket.client.name + }).toUpperCase() + }; - this.dms = Object.assign(this.dms, defaultParams); - }); + this.dms = Object.assign(this.dms, defaultParams); } onSubmit() { diff --git a/modules/ticket/front/dms/edit/index.js b/modules/ticket/front/dms/edit/index.js index 808ca6a6a5..9b64f5906d 100644 --- a/modules/ticket/front/dms/edit/index.js +++ b/modules/ticket/front/dms/edit/index.js @@ -1,7 +1,7 @@ import ngModule from '../../module'; -import Section from 'salix/components/section'; +import SectionDms from 'salix/components/section-dms'; -class Controller extends Section { +class Controller extends SectionDms { get ticket() { return this._ticket; } @@ -10,39 +10,28 @@ class Controller extends Section { this._ticket = value; if (value) { - this.setDefaultParams(); - this.getAllowedContentTypes(); + this.getDms(this.$params.dmsId).then(handleDefaultParams); + this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); } } - getAllowedContentTypes() { - this.$http.get('DmsContainers/allowedContentTypes').then(res => { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - }); - } - get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - setDefaultParams() { - const path = `Dms/${this.$params.dmsId}`; - this.$http.get(path).then(res => { - const dms = res.data && res.data; - this.dms = { - reference: dms.reference, - warehouseId: dms.warehouseFk, - companyId: dms.companyFk, - dmsTypeId: dms.dmsTypeFk, - description: dms.description, - hasFile: dms.hasFile, - hasFileAttached: false, - files: [] - }; - }); + handleDefaultParams({data: dms}) { + this.dms = { + reference: dms.reference, + warehouseId: dms.warehouseFk, + companyId: dms.companyFk, + dmsTypeId: dms.dmsTypeFk, + description: dms.description, + hasFile: dms.hasFile, + hasFileAttached: false, + files: [] + }; } onSubmit() { diff --git a/modules/travel/front/thermograph/create/index.js b/modules/travel/front/thermograph/create/index.js index fa2c1261ad..e51d23124e 100644 --- a/modules/travel/front/thermograph/create/index.js +++ b/modules/travel/front/thermograph/create/index.js @@ -17,16 +17,10 @@ class Controller extends Section { if (value) { this.setDefaultParams(); - this.getAllowedContentTypes(); + this.allowedContentTypes = this.getAllowedContentTypes(); } } - getAllowedContentTypes() { - this.$http.get('DmsContainers/allowedContentTypes').then(res => { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - }); - } get contentTypesInfo() { return this.$t('ContentTypesInfo', { diff --git a/modules/travel/front/thermograph/edit/index.js b/modules/travel/front/thermograph/edit/index.js index a8df3142d3..1678643b2e 100644 --- a/modules/travel/front/thermograph/edit/index.js +++ b/modules/travel/front/thermograph/edit/index.js @@ -1,8 +1,8 @@ import ngModule from '../../module'; -import Section from 'salix/components/section'; +import SectionDms from 'salix/components/section-dms'; import './style.scss'; -class Controller extends Section { +class Controller extends SectionDms { get travel() { return this._travel; } @@ -12,17 +12,10 @@ class Controller extends Section { if (value) { this.setDefaultParams(); - this.getAllowedContentTypes(); + this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); } } - getAllowedContentTypes() { - this.$http.get('DmsContainers/allowedContentTypes').then(res => { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - }); - } - get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes diff --git a/modules/worker/front/dms/create/index.js b/modules/worker/front/dms/create/index.js index ff6112211a..2f06128b59 100644 --- a/modules/worker/front/dms/create/index.js +++ b/modules/worker/front/dms/create/index.js @@ -21,17 +21,12 @@ class Controller extends Section { if (value) { this.setDefaultParams(); - this.getAllowedContentTypes(); + this.getAllowedContentTypes().then(data => { + this.allowedContentTypes = data; + }); } } - getAllowedContentTypes() { - this.$http.get('DmsContainers/allowedContentTypes').then(res => { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - }); - } - get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes diff --git a/modules/worker/front/dms/edit/index.js b/modules/worker/front/dms/edit/index.js index 31d4c2853b..8a17905639 100644 --- a/modules/worker/front/dms/edit/index.js +++ b/modules/worker/front/dms/edit/index.js @@ -1,8 +1,8 @@ import ngModule from '../../module'; -import Section from 'salix/components/section'; +import SectionDms from 'salix/components/section-dms'; import './style.scss'; -class Controller extends Section { +class Controller extends SectionDms { get worker() { return this._worker; } @@ -11,16 +11,10 @@ class Controller extends Section { this._worker = value; if (value) { - this.setDefaultParams(); - this.getAllowedContentTypes(); - } - } + this.getDms(this.$params.dmsId).then(handleDefaultParams); - getAllowedContentTypes() { - this.$http.get('DmsContainers/allowedContentTypes').then(res => { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - }); + this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); + } } get contentTypesInfo() { @@ -29,21 +23,17 @@ class Controller extends Section { }); } - setDefaultParams() { - const path = `Dms/${this.$params.dmsId}`; - this.$http.get(path).then(res => { - const dms = res.data && res.data; - this.dms = { - reference: dms.reference, - warehouseId: dms.warehouseFk, - companyId: dms.companyFk, - dmsTypeId: dms.dmsTypeFk, - description: dms.description, - hasFile: dms.hasFile, - hasFileAttached: false, - files: [] - }; - }); + handleDefaultParams({data: dms}) { + this.dms = { + reference: dms.reference, + warehouseId: dms.warehouseFk, + companyId: dms.companyFk, + dmsTypeId: dms.dmsTypeFk, + description: dms.description, + hasFile: dms.hasFile, + hasFileAttached: false, + files: [] + }; } onSubmit() { From 5f4adab017696ece18a9a94094567a58dfc1f631 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 12 Dec 2023 18:03:09 +0100 Subject: [PATCH 379/449] refs #5854 --- modules/item/back/locale/item-shelving/es.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/item/back/locale/item-shelving/es.yml b/modules/item/back/locale/item-shelving/es.yml index a64b23bfaa..3aedcd0bf6 100644 --- a/modules/item/back/locale/item-shelving/es.yml +++ b/modules/item/back/locale/item-shelving/es.yml @@ -5,8 +5,8 @@ columns: shelvingFk: matrícula carro visible: visible created: creado - grouping: agrupación - packing: embalaje + grouping: grouping + packing: packing packagingFk: paquete userFk: usuario isChecked: está revisado From 0ae75d973fe9ad55cd709f409d698fe1e68446fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Segarra=20Mart=C3=ADnez?= Date: Tue, 12 Dec 2023 19:42:46 +0100 Subject: [PATCH 380/449] refs #6264 perf: remove async keyword --- loopback/server/middleware/current-user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loopback/server/middleware/current-user.js b/loopback/server/middleware/current-user.js index b450f6bb13..a6624351e7 100644 --- a/loopback/server/middleware/current-user.js +++ b/loopback/server/middleware/current-user.js @@ -1,5 +1,5 @@ module.exports = function(options) { - return async function(req, res, next) { + return function(req, res, next) { if (!req.accessToken) return next(); From 8441877f36491c956517b3c00b22cac5a6492f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Segarra=20Mart=C3=ADnez?= Date: Tue, 12 Dec 2023 19:43:32 +0100 Subject: [PATCH 381/449] refs #6264 perf: remove field's query --- back/methods/vn-user/renew-token.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index d5d22fd0de..4254d075a2 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -32,7 +32,7 @@ module.exports = Self => { const isValid = await Self.validateToken(token); if (isValid) throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded'); - const {courtesyTime} = await models.AccessTokenConfig.findOne({fields: ['renewPeriod', 'courtesyTime']}); + const {courtesyTime} = await models.AccessTokenConfig.findOne({fields: ['courtesyTime']}); // Schedule to remove current token handlePromiseLogout(Self, token, courtesyTime); From 435819cf3cb32ff3e28007baf6491537db97fe6c Mon Sep 17 00:00:00 2001 From: sergiodt Date: Wed, 13 Dec 2023 07:24:13 +0100 Subject: [PATCH 382/449] refs #6275 feat:Silex_to_Salix test getExpeditionSummary --- .../route/back/methods/route/specs/getExpeditionSummary.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js b/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js index bdc1242276..9d70c339aa 100644 --- a/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js +++ b/modules/route/back/methods/route/specs/getExpeditionSummary.spec.js @@ -5,6 +5,6 @@ describe('route getExpeditionSummary()', () => { it('should return a summary of expeditions for a route', async() => { const result = await app.models.Route.getExpeditionSummary(routeId); - expect(result.length).toEqual(3); + expect(result.every(route => route.id = routeId)).toBeTruthy(); }); }); From 2393625a48ddbaf72f33be6420212fa3b8e3d232 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 13 Dec 2023 08:22:58 +0100 Subject: [PATCH 383/449] refs #5925 Tablet --- back/methods/docuware/upload.js | 17 +++++++++++------ back/models/docuwareTablet.json | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/back/methods/docuware/upload.js b/back/methods/docuware/upload.js index a587079a2e..0af20b8ac8 100644 --- a/back/methods/docuware/upload.js +++ b/back/methods/docuware/upload.js @@ -56,6 +56,16 @@ module.exports = Self => { }] }); + // get tablet + const tablet = await models.userConfig.findById(id, { + include: [{ + relation: 'Tablet', + scope: { + fields: ['id'] + } + }] + }); + // upload file const templateJson = { 'Fields': [ @@ -102,12 +112,7 @@ module.exports = Self => { { 'FieldName': 'FILTRO_TABLET', 'ItemElementName': 'string', - 'Item': 'Tablet1', - }, - { - 'FieldName': 'ID_TABLET', - 'ItemElementName': 'integer', - 'Item': userConfig.tabletFk, + 'Item': tablet.id, } ] }; diff --git a/back/models/docuwareTablet.json b/back/models/docuwareTablet.json index dde336bcac..e9e3b6bad9 100644 --- a/back/models/docuwareTablet.json +++ b/back/models/docuwareTablet.json @@ -3,7 +3,7 @@ "base": "VnModel", "options": { "mysql": { - "table": "vn.docuwareTablet" + "table": "docuwareTablet" } }, "properties": { From 69dd34665fa79a717477b638339437f72958044c Mon Sep 17 00:00:00 2001 From: pablone Date: Wed, 13 Dec 2023 08:50:17 +0100 Subject: [PATCH 384/449] refactor(renameTable): refs #6125 clientCreditLimit to roleCreditLimit --- db/changes/235201/00-clientCreditLimitToRoleCreditLimit.sql | 4 ++++ db/dump/fixtures.sql | 2 +- modules/client/back/model-config.json | 2 +- modules/client/back/models/client.js | 2 +- .../{client-credit-limit.json => role-credit-limit.json} | 4 ++-- 5 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 db/changes/235201/00-clientCreditLimitToRoleCreditLimit.sql rename modules/client/back/models/{client-credit-limit.json => role-credit-limit.json} (85%) diff --git a/db/changes/235201/00-clientCreditLimitToRoleCreditLimit.sql b/db/changes/235201/00-clientCreditLimitToRoleCreditLimit.sql new file mode 100644 index 0000000000..bf4cc60029 --- /dev/null +++ b/db/changes/235201/00-clientCreditLimitToRoleCreditLimit.sql @@ -0,0 +1,4 @@ +RENAME TABLE `vn`.`clientCreditLimit` TO `vn`.`roleCreditLimit`; +ALTER TABLE `vn`.`clientCreditLimit` DROP FOREIGN KEY `clientCreditLimit_FK`; +ALTER TABLE `vn`.`roleCreditLimit` ADD CONSTRAINT `roleCreditLimit_FK` FOREIGN KEY (`roleFk`) REFERENCES `account`.`role`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 3354e95c2d..78793a31ac 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -493,7 +493,7 @@ INSERT INTO `vn`.`clientCredit`(`clientFk`, `workerFk`, `amount`, `created`) (1104, 9, 90 , util.VN_CURDATE()), (1105, 9, 90 , util.VN_CURDATE()); -INSERT INTO `vn`.`clientCreditLimit`(`id`, `maxAmount`, `roleFk`) +INSERT INTO `vn`.`roleCreditLimit`(`id`, `maxAmount`, `roleFk`) VALUES (1, 9999999, 20), (2, 10000, 21), diff --git a/modules/client/back/model-config.json b/modules/client/back/model-config.json index 0cc5df9a2f..a214077324 100644 --- a/modules/client/back/model-config.json +++ b/modules/client/back/model-config.json @@ -29,7 +29,7 @@ "ClientCredit": { "dataSource": "vn" }, - "ClientCreditLimit": { + "RoleCreditLimit": { "dataSource": "vn" }, "ClientConsumptionQueue": { diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 72b7027798..a9e14effa6 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -463,7 +463,7 @@ module.exports = Self => { throw new UserError(`You can't change the credit set to zero from a financialBoss`); } - const creditLimits = await models.ClientCreditLimit.find({ + const creditLimits = await models.RoleCreditLimit.find({ fields: ['roleFk'], where: { maxAmount: {gte: changes.credit} diff --git a/modules/client/back/models/client-credit-limit.json b/modules/client/back/models/role-credit-limit.json similarity index 85% rename from modules/client/back/models/client-credit-limit.json rename to modules/client/back/models/role-credit-limit.json index 740f0cf534..4ea28b1a47 100644 --- a/modules/client/back/models/client-credit-limit.json +++ b/modules/client/back/models/role-credit-limit.json @@ -1,9 +1,9 @@ { - "name": "ClientCreditLimit", + "name": "RoleCreditLimit", "base": "VnModel", "options": { "mysql": { - "table": "clientCreditLimit" + "table": "roleCreditLimit" } }, "properties": { From 2f61b648f732c8125c67ffff095504d985a136c8 Mon Sep 17 00:00:00 2001 From: davidd Date: Wed, 13 Dec 2023 09:49:03 +0100 Subject: [PATCH 385/449] refs #6398 --- db/changes/{235001 => 235201}/00-alterTable.sql | 0 db/changes/{235001 => 235201}/01-procedures.sql | 0 db/changes/{235001 => 235201}/02-views.sql | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename db/changes/{235001 => 235201}/00-alterTable.sql (100%) rename db/changes/{235001 => 235201}/01-procedures.sql (100%) rename db/changes/{235001 => 235201}/02-views.sql (100%) diff --git a/db/changes/235001/00-alterTable.sql b/db/changes/235201/00-alterTable.sql similarity index 100% rename from db/changes/235001/00-alterTable.sql rename to db/changes/235201/00-alterTable.sql diff --git a/db/changes/235001/01-procedures.sql b/db/changes/235201/01-procedures.sql similarity index 100% rename from db/changes/235001/01-procedures.sql rename to db/changes/235201/01-procedures.sql diff --git a/db/changes/235001/02-views.sql b/db/changes/235201/02-views.sql similarity index 100% rename from db/changes/235001/02-views.sql rename to db/changes/235201/02-views.sql From 5b3645a6419e765cf186b4280d22594f83acfb7d Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 13 Dec 2023 11:59:00 +0100 Subject: [PATCH 386/449] refs #6434 fix: bad merge --- back/models/vn-user.js | 27 +++++++++++++++++++ db/changes/234801/00-createSignInLogTable.sql | 19 ------------- 2 files changed, 27 insertions(+), 19 deletions(-) delete mode 100644 db/changes/234801/00-createSignInLogTable.sql diff --git a/back/models/vn-user.js b/back/models/vn-user.js index d840e34e8f..7b1471e5c2 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -125,6 +125,33 @@ module.exports = function(Self) { return email.send(); }); + /** + * Sign-in validate + * @param {String} user The user + * @param {Object} userToken Options + * @param {Object} token accessToken + * @param {Object} ctx context + */ + Self.signInValidate = async(user, userToken, token, ctx) => { + const [[key, value]] = Object.entries(Self.userUses(user)); + const isOwner = Self.rawSql(`SELECT ? = ? `, [userToken[key], value]); + await Self.app.models.SignInLog.create({ + userName: user, + token: token.id, + userFk: userToken.id, + ip: ctx.req.ip, + owner: isOwner + }); + if (!isOwner) + throw new UserError('Try again'); + }; + + /** + * Validate login params + * @param {String} user The user + * @param {String} password + * @param {Object} ctx context + */ Self.validateLogin = async function(user, password) { let loginInfo = Object.assign({password}, Self.userUses(user)); token = await Self.login(loginInfo, 'user'); diff --git a/db/changes/234801/00-createSignInLogTable.sql b/db/changes/234801/00-createSignInLogTable.sql deleted file mode 100644 index 977de46463..0000000000 --- a/db/changes/234801/00-createSignInLogTable.sql +++ /dev/null @@ -1,19 +0,0 @@ - - --- --- Table structure for table `signInLog` --- - -DROP TABLE IF EXISTS `account`.`signInLog`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `account`.`signInLog` ( - `id` varchar(10) NOT NULL , - `userFk` int(10) unsigned DEFAULT NULL, - `creationDate` timestamp NULL DEFAULT current_timestamp(), - `ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - PRIMARY KEY (`id`), - KEY `userFk` (`userFk`), - CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -); - From 5f93b8c44032a4b982d23383b8c5158f721e9817 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 13 Dec 2023 12:01:18 +0100 Subject: [PATCH 387/449] refs #6434 fix: bad merge --- back/models/vn-user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 7b1471e5c2..e14cd30eac 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -152,9 +152,9 @@ module.exports = function(Self) { * @param {String} password * @param {Object} ctx context */ - Self.validateLogin = async function(user, password) { - let loginInfo = Object.assign({password}, Self.userUses(user)); - token = await Self.login(loginInfo, 'user'); + Self.validateLogin = async function(user, password, ctx) { + const loginInfo = Object.assign({password}, Self.userUses(user)); + const token = await Self.login(loginInfo, 'user'); const userToken = await token.user.get(); From 4e8bec5684935258b23f2d30c568f0ad745c36d8 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 13 Dec 2023 12:03:04 +0100 Subject: [PATCH 388/449] refs #5925 user error --- back/methods/docuware/upload.js | 2 ++ loopback/locale/es.json | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/back/methods/docuware/upload.js b/back/methods/docuware/upload.js index 0af20b8ac8..5f44e9382b 100644 --- a/back/methods/docuware/upload.js +++ b/back/methods/docuware/upload.js @@ -120,6 +120,8 @@ module.exports = Self => { if (process.env.NODE_ENV != 'production') throw new UserError('Action not allowed on the test environment'); + if (!tablet.id) + throw new UserError('This user does not have an assigned tablet.'); // delete old const docuwareFile = await models.Docuware.checkFile(id, fileCabinet, false); if (docuwareFile) { diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 01384efb42..4a2e9a7946 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -329,5 +329,6 @@ "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", "Cannot past travels with entries": "No se pueden pasar envíos con entradas", - "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}" -} \ No newline at end of file + "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", + "This user does not have an assigned tablet.": "Este usuario no tiene tablet asignada" +} From d4fa1e9acaed06ef4dd30b1f44853c2c0420a822 Mon Sep 17 00:00:00 2001 From: davidd Date: Wed, 13 Dec 2023 12:04:07 +0100 Subject: [PATCH 389/449] refs #6398 --- db/changes/235201/02-views.sql | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/db/changes/235201/02-views.sql b/db/changes/235201/02-views.sql index d399bb3b45..a0f41594da 100644 --- a/db/changes/235201/02-views.sql +++ b/db/changes/235201/02-views.sql @@ -32,3 +32,21 @@ AS SELECT `tt`.`id` AS `inter_id`, `tt`.`userFk` AS `Id_Trabajador`, `tt`.`supervisorFk` AS `Id_supervisor` FROM `vn`.`ticketTracking` `tt`; + +CREATE OR REPLACE +ALGORITHM = UNDEFINED VIEW `ticketStateToday` AS +SELECT + `ts`.`ticket` AS `ticket`, + `ts`.`state` AS `state`, + `ts`.`productionOrder` AS `productionOrder`, + `ts`.`alertLevel` AS `alertLevel`, + `ts`.`userFk` AS `userFk`, + `ts`.`code` AS `code`, + `ts`.`updated` AS `updated`, + `ts`.`isPicked` AS `isPicked` +FROM + (`ticketState` `ts` +JOIN `ticket` `t` ON + (`t`.`id` = `ts`.`ticket`)) +WHERE + `t`.`shipped` BETWEEN `util`.`VN_CURDATE`() AND `MIDNIGHT`(`util`.`VN_CURDATE`()); From 6af99b7669f0ff0ac8a5b4110993686968d11dd5 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 13 Dec 2023 12:07:41 +0100 Subject: [PATCH 390/449] refs #6434 feat: delete records whe !owner --- db/changes/235201/00-truncate-where-signInLog.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 db/changes/235201/00-truncate-where-signInLog.sql diff --git a/db/changes/235201/00-truncate-where-signInLog.sql b/db/changes/235201/00-truncate-where-signInLog.sql new file mode 100644 index 0000000000..93d80d7161 --- /dev/null +++ b/db/changes/235201/00-truncate-where-signInLog.sql @@ -0,0 +1 @@ +DELETE FROM `account`.`signInLog` where owner <> FALSE From 5a36fabf058153792cda778c7e0e01c3b52588d1 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 13 Dec 2023 12:07:57 +0100 Subject: [PATCH 391/449] refs #6434 feat: insert record just when fail --- back/models/vn-user.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index e14cd30eac..1134df3632 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -135,15 +135,16 @@ module.exports = function(Self) { Self.signInValidate = async(user, userToken, token, ctx) => { const [[key, value]] = Object.entries(Self.userUses(user)); const isOwner = Self.rawSql(`SELECT ? = ? `, [userToken[key], value]); - await Self.app.models.SignInLog.create({ - userName: user, - token: token.id, - userFk: userToken.id, - ip: ctx.req.ip, - owner: isOwner - }); - if (!isOwner) - throw new UserError('Try again'); + if (!isOwner) { + await Self.app.models.SignInLog.create({ + userName: user, + token: token.id, + userFk: userToken.id, + ip: ctx.req.ip, + owner: isOwner + }); + } + throw new UserError('Try again'); }; /** From 11b54d66af6f77158441e0627186c128d3c5234c Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 13 Dec 2023 13:31:32 +0100 Subject: [PATCH 392/449] refs #6434 fix: bad merge --- back/methods/vn-user/sign-in.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/back/methods/vn-user/sign-in.js b/back/methods/vn-user/sign-in.js index 9626e2e79d..782046641e 100644 --- a/back/methods/vn-user/sign-in.js +++ b/back/methods/vn-user/sign-in.js @@ -40,14 +40,11 @@ module.exports = Self => { const validCredentials = vnUser && await vnUser.hasPassword(password); - if (!validCredentials) - throw new UserError('Invalid credentials'); - - if (!vnUser.active) - throw new UserError('User disabled'); - - await Self.sendTwoFactor(ctx, vnUser, myOptions); - await Self.passExpired(vnUser, myOptions); + if (validCredentials) { + if (!vnUser.active) + throw new UserError('User disabled'); + await Self.sendTwoFactor(ctx, vnUser, myOptions); + await Self.passExpired(vnUser, myOptions); if (vnUser.twoFactor) throw new ForbiddenError(null, 'REQUIRES_2FA'); From d364a50ec4ecabc20e6e273b155341f169c601a4 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 13 Dec 2023 13:39:43 +0100 Subject: [PATCH 393/449] refs #6264 feat: remove validateToken endpoint --- back/methods/vn-user/renew-token.js | 12 +++++- .../vn-user/specs/validate-token.spec.js | 43 ------------------- back/methods/vn-user/validate-token.js | 24 ----------- back/models/vn-user.js | 1 - back/models/vn-user.json | 7 --- 5 files changed, 11 insertions(+), 76 deletions(-) delete mode 100644 back/methods/vn-user/specs/validate-token.spec.js delete mode 100644 back/methods/vn-user/validate-token.js diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index 4254d075a2..e7e826cd13 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -29,7 +29,7 @@ module.exports = Self => { const {accessToken: token} = ctx.req; // Check if current token is valid - const isValid = await Self.validateToken(token); + const isValid = await validateToken(token); if (isValid) throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded'); const {courtesyTime} = await models.AccessTokenConfig.findOne({fields: ['courtesyTime']}); @@ -43,4 +43,14 @@ module.exports = Self => { return {id: accessToken.id, ttl: accessToken.ttl}; }; + + async function validateToken(token) { + const accessTokenConfig = await models.AccessTokenConfig.findOne({fields: ['renewPeriod', 'courtesyTime']}); + const now = Date.now(); + const differenceMilliseconds = now - token.created; + const differenceSeconds = Math.floor(differenceMilliseconds / 1000); + const isValid = differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime; + + return isValid; + } }; diff --git a/back/methods/vn-user/specs/validate-token.spec.js b/back/methods/vn-user/specs/validate-token.spec.js deleted file mode 100644 index ec254d0e5a..0000000000 --- a/back/methods/vn-user/specs/validate-token.spec.js +++ /dev/null @@ -1,43 +0,0 @@ -const {models} = require('vn-loopback/server/server'); - -describe('Validate Token', () => { - const startingTime = Date.now(); - let ctx = null; - beforeAll(async() => { - const unAuthCtx = { - req: { - headers: {}, - connection: { - remoteAddress: '127.0.0.1' - }, - getLocale: () => 'en' - }, - args: {} - }; - let login = await models.VnUser.signIn(unAuthCtx, 'salesAssistant', 'nightmare'); - let accessToken = await models.AccessToken.findById(login.token); - ctx = {req: {accessToken: accessToken}}; - }); - - beforeEach(() => { - jasmine.clock().install(); - jasmine.clock().mockDate(new Date(startingTime)); - }); - - afterEach(() => { - jasmine.clock().uninstall(); - }); - - it('Token is not expired', async() => { - const isValid = await models.VnUser.validateToken(ctx.req.accessToken); - - expect(isValid).toBeTrue(); - }); - - it('Token is expired', async() => { - jasmine.clock().mockDate(new Date(startingTime + 21600000)); - const isValid = await models.VnUser.validateToken(ctx.req.accessToken); - - expect(isValid).toBeFalse(); - }); -}); diff --git a/back/methods/vn-user/validate-token.js b/back/methods/vn-user/validate-token.js deleted file mode 100644 index ef3c5b2126..0000000000 --- a/back/methods/vn-user/validate-token.js +++ /dev/null @@ -1,24 +0,0 @@ -const {models} = require('vn-loopback/server/server'); -module.exports = Self => { - Self.remoteMethod('validateToken', { - description: 'Validates the current logged user token', - returns: { - type: 'Boolean', - root: true - }, - http: { - path: `/validateToken`, - verb: 'GET' - } - }); - - Self.validateToken = async function(token) { - const accessTokenConfig = await models.AccessTokenConfig.findOne({fields: ['renewPeriod', 'courtesyTime']}); - const now = Date.now(); - const differenceMilliseconds = now - token.created; - const differenceSeconds = Math.floor(differenceMilliseconds / 1000); - const isValid = differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime; - - return isValid; - }; -}; diff --git a/back/models/vn-user.js b/back/models/vn-user.js index e14cd30eac..80287de5b0 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -10,7 +10,6 @@ module.exports = function(Self) { require('../methods/vn-user/sign-in')(Self); require('../methods/vn-user/acl')(Self); require('../methods/vn-user/recover-password')(Self); - require('../methods/vn-user/validate-token')(Self); require('../methods/vn-user/privileges')(Self); require('../methods/vn-user/validate-auth')(Self); require('../methods/vn-user/renew-token')(Self); diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 0f6daff5ac..86ffac2bbc 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -104,13 +104,6 @@ "permission": "ALLOW" }, { - "property": "validateToken", - "accessType": "EXECUTE", - "principalType": "ROLE", - "principalId": "$authenticated", - "permission": "ALLOW" - }, - { "property": "validateAuth", "accessType": "EXECUTE", "principalType": "ROLE", From a5ecec960351372d518a3d8f4fd5e8d7d3c6d2ce Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 13 Dec 2023 13:47:30 +0100 Subject: [PATCH 394/449] refs #2051 feat: remove front methods refactor --- front/salix/components/index.js | 1 - front/salix/components/section-dms/index.js | 24 --------- front/salix/components/section-dms/style.scss | 0 modules/client/front/dms/create/index.js | 54 +++++++++++-------- modules/client/front/dms/edit/index.js | 41 ++++++++------ modules/invoiceIn/front/basic-data/index.js | 15 ++++-- .../agency-term/createInvoiceIn/index.js | 45 ++++++++++------ modules/ticket/front/dms/create/index.js | 53 ++++++++++-------- modules/ticket/front/dms/edit/index.js | 41 ++++++++------ modules/ticket/front/tracking/index/index.js | 10 +--- .../travel/front/thermograph/create/index.js | 8 ++- .../travel/front/thermograph/edit/index.js | 13 +++-- modules/worker/front/dms/create/index.js | 11 ++-- 13 files changed, 182 insertions(+), 134 deletions(-) delete mode 100644 front/salix/components/section-dms/index.js delete mode 100644 front/salix/components/section-dms/style.scss diff --git a/front/salix/components/index.js b/front/salix/components/index.js index e843f2f5ee..38b0d0e1fb 100644 --- a/front/salix/components/index.js +++ b/front/salix/components/index.js @@ -15,7 +15,6 @@ import './module-card'; import './module-main'; import './side-menu/side-menu'; import './section'; -import './section-dms'; import './summary'; import './topbar/topbar'; import './user-popover'; diff --git a/front/salix/components/section-dms/index.js b/front/salix/components/section-dms/index.js deleted file mode 100644 index ae7d496cd2..0000000000 --- a/front/salix/components/section-dms/index.js +++ /dev/null @@ -1,24 +0,0 @@ -import ngModule from '../../module'; -import Component from 'core/lib/component'; -import './style.scss'; - -export default class SectionDms extends Component { - getAllowedContentTypes() { - return this.$http.get('DmsContainers/allowedContentTypes').then(res => { - const contentTypes = res.data.join(', '); - this.allowedContentTypes = contentTypes; - return contentTypes; - }); - } - - getDms(dmsId) { - return this.$http.get(`Dms/${dmsId}`).then(res => res); - } - getDmsTypes(params) { - return this.$http.get('DmsTypes/findOne', params).then(res => res); - } -} - -ngModule.vnComponent('vnSectionDms', { - controller: SectionDms -}); diff --git a/front/salix/components/section-dms/style.scss b/front/salix/components/section-dms/style.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/modules/client/front/dms/create/index.js b/modules/client/front/dms/create/index.js index ec88379812..461d0aa368 100644 --- a/modules/client/front/dms/create/index.js +++ b/modules/client/front/dms/create/index.js @@ -1,8 +1,8 @@ import ngModule from '../../module'; -import SectionDms from 'salix/components/section-dms'; +import Section from 'salix/components/section'; import './style.scss'; -class Controller extends SectionDms { +class Controller extends Section { constructor($element, $) { super($element, $); this.dms = { @@ -20,36 +20,46 @@ class Controller extends SectionDms { this._client = value; if (value) { - const params = {filter: { - where: {code: 'paymentsLaw'} - }}; - this.getDmsTypes(params).then(res => this.handleDefaultParams(res)); - this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); + this.setDefaultParams(); + this.getAllowedContentTypes(); } } + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + }); + } + get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - handleDefaultParams({data: dmsType}) { - const companyId = this.vnConfig.companyFk; - const warehouseId = this.vnConfig.warehouseFk; - const defaultParams = { - reference: this.client.id, - warehouseId: warehouseId, - companyId: companyId, - dmsTypeId: dmsType.id, - description: this.$t('ClientFileDescription', { - dmsTypeName: dmsType.name, - clientId: this.client.id, - clientName: this.client.name - }).toUpperCase() - }; + setDefaultParams() { + const params = {filter: { + where: {code: 'paymentsLaw'} + }}; + this.$http.get('DmsTypes/findOne', {params}).then(res => { + const dmsType = res.data && res.data; + const companyId = this.vnConfig.companyFk; + const warehouseId = this.vnConfig.warehouseFk; + const defaultParams = { + reference: this.client.id, + warehouseId: warehouseId, + companyId: companyId, + dmsTypeId: dmsType.id, + description: this.$t('ClientFileDescription', { + dmsTypeName: dmsType.name, + clientId: this.client.id, + clientName: this.client.name + }).toUpperCase() + }; - this.dms = Object.assign(this.dms, defaultParams); + this.dms = Object.assign(this.dms, defaultParams); + }); } onSubmit() { diff --git a/modules/client/front/dms/edit/index.js b/modules/client/front/dms/edit/index.js index 36c1a96726..8765eeff2c 100644 --- a/modules/client/front/dms/edit/index.js +++ b/modules/client/front/dms/edit/index.js @@ -1,8 +1,8 @@ import ngModule from '../../module'; -import SectionDms from 'salix/components/section-dms'; +import Section from 'salix/components/section'; import './style.scss'; -class Controller extends SectionDms { +class Controller extends Section { get client() { return this._client; } @@ -11,28 +11,39 @@ class Controller extends SectionDms { this._client = value; if (value) { - this.getDms(this.$params.dmsId).then(handleDefaultParams); - this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); + this.setDefaultParams(); + this.getAllowedContentTypes(); } } + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + }); + } + get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - handleDefaultParams({data: dms}) { - this.dms = { - reference: dms.reference, - warehouseId: dms.warehouseFk, - companyId: dms.companyFk, - dmsTypeId: dms.dmsTypeFk, - description: dms.description, - hasFile: dms.hasFile, - hasFileAttached: false, - files: [] - }; + setDefaultParams() { + const path = `Dms/${this.$params.dmsId}`; + this.$http.get(path).then(res => { + const dms = res.data && res.data; + this.dms = { + reference: dms.reference, + warehouseId: dms.warehouseFk, + companyId: dms.companyFk, + dmsTypeId: dms.dmsTypeFk, + description: dms.description, + hasFile: dms.hasFile, + hasFileAttached: false, + files: [] + }; + }); } onSubmit() { diff --git a/modules/invoiceIn/front/basic-data/index.js b/modules/invoiceIn/front/basic-data/index.js index 797fda59dc..246f1b16fd 100644 --- a/modules/invoiceIn/front/basic-data/index.js +++ b/modules/invoiceIn/front/basic-data/index.js @@ -1,8 +1,8 @@ import ngModule from '../module'; -import SectionDms from 'salix/components/section-dms'; +import Section from 'salix/components/section'; import UserError from 'core/lib/user-error'; -class Controller extends SectionDms { +class Controller extends Section { constructor($element, $, vnFile) { super($element, $, vnFile); this.dms = { @@ -11,7 +11,7 @@ class Controller extends SectionDms { hasFileAttached: false }; this.vnFile = vnFile; - this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); + this.getAllowedContentTypes(); this._editDownloadDisabled = false; } @@ -53,6 +53,15 @@ class Controller extends SectionDms { }); } + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + if (res.data.length > 0) { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + } + }); + } + openEditDialog(dmsId) { this.getFile(dmsId).then(() => this.$.dmsEditDialog.show()); } diff --git a/modules/route/front/agency-term/createInvoiceIn/index.js b/modules/route/front/agency-term/createInvoiceIn/index.js index 5e54f79294..0198ab80fd 100644 --- a/modules/route/front/agency-term/createInvoiceIn/index.js +++ b/modules/route/front/agency-term/createInvoiceIn/index.js @@ -1,9 +1,9 @@ import ngModule from '../../module'; -import SectionDms from 'salix/components/section-dms'; +import Section from 'salix/components/section'; import './style.scss'; import UserError from 'core/lib/user-error'; -class Controller extends SectionDms { +class Controller extends Section { constructor($element, $) { super($element, $); this.dms = { @@ -19,11 +19,9 @@ class Controller extends SectionDms { set route(value) { this._route = value; - const params = {filter: { - where: {code: 'invoiceIn'} - }}; - this.getDmsTypes(params).then(res => this.handleDefaultParams(res)); - this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); + + this.setDefaultParams(); + this.getAllowedContentTypes(); } $onChanges() { @@ -31,23 +29,36 @@ class Controller extends SectionDms { this.params = JSON.parse(this.$params.q); } + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + }); + } + get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - handleDefaultParams({data: dmsType}) { - const companyId = this.vnConfig.companyFk; - const warehouseId = this.vnConfig.warehouseFk; - const defaultParams = { - warehouseId: warehouseId, - companyId: companyId, - dmsTypeId: dmsType.id, - description: this.params.supplierName - }; + setDefaultParams() { + const params = {filter: { + where: {code: 'invoiceIn'} + }}; + this.$http.get('DmsTypes/findOne', {params}).then(res => { + const dmsType = res.data && res.data; + const companyId = this.vnConfig.companyFk; + const warehouseId = this.vnConfig.warehouseFk; + const defaultParams = { + warehouseId: warehouseId, + companyId: companyId, + dmsTypeId: dmsType.id, + description: this.params.supplierName + }; - this.dms = Object.assign(this.dms, defaultParams); + this.dms = Object.assign(this.dms, defaultParams); + }); } onSubmit() { diff --git a/modules/ticket/front/dms/create/index.js b/modules/ticket/front/dms/create/index.js index 7b25e4665e..b25abf17c2 100644 --- a/modules/ticket/front/dms/create/index.js +++ b/modules/ticket/front/dms/create/index.js @@ -1,7 +1,7 @@ import ngModule from '../../module'; -import SectionDms from 'salix/components/section-dms'; +import Section from 'salix/components/section'; -class Controller extends SectionDms { +class Controller extends Section { constructor($element, $) { super($element, $); this.dms = { @@ -19,36 +19,45 @@ class Controller extends SectionDms { this._ticket = value; if (value) { - const params = {filter: { - where: {code: 'ticket'} - }}; - this.getDmsTypes(params).then(res => this.handleDefaultParams(res)); - this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); + this.setDefaultParams(); + this.getAllowedContentTypes(); } } + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + }); + } + get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - handleDefaultParams(data) { - const dmsTypeId = res?.data?.id; - const warehouseId = this.vnConfig.warehouseFk; - const defaultParams = { - reference: this.ticket.id, - warehouseId: warehouseId, - companyId: this.ticket.companyFk, - dmsTypeId: dmsTypeId, - description: this.$t('FileDescription', { - ticketId: this.ticket.id, - clientId: this.ticket.client.id, - clientName: this.ticket.client.name - }).toUpperCase() - }; + setDefaultParams() { + const params = {filter: { + where: {code: 'ticket'} + }}; + this.$http.get('DmsTypes/findOne', {params}).then(res => { + const dmsTypeId = res.data && res.data.id; + const warehouseId = this.vnConfig.warehouseFk; + const defaultParams = { + reference: this.ticket.id, + warehouseId: warehouseId, + companyId: this.ticket.companyFk, + dmsTypeId: dmsTypeId, + description: this.$t('FileDescription', { + ticketId: this.ticket.id, + clientId: this.ticket.client.id, + clientName: this.ticket.client.name + }).toUpperCase() + }; - this.dms = Object.assign(this.dms, defaultParams); + this.dms = Object.assign(this.dms, defaultParams); + }); } onSubmit() { diff --git a/modules/ticket/front/dms/edit/index.js b/modules/ticket/front/dms/edit/index.js index 9b64f5906d..808ca6a6a5 100644 --- a/modules/ticket/front/dms/edit/index.js +++ b/modules/ticket/front/dms/edit/index.js @@ -1,7 +1,7 @@ import ngModule from '../../module'; -import SectionDms from 'salix/components/section-dms'; +import Section from 'salix/components/section'; -class Controller extends SectionDms { +class Controller extends Section { get ticket() { return this._ticket; } @@ -10,28 +10,39 @@ class Controller extends SectionDms { this._ticket = value; if (value) { - this.getDms(this.$params.dmsId).then(handleDefaultParams); - this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); + this.setDefaultParams(); + this.getAllowedContentTypes(); } } + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + }); + } + get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - handleDefaultParams({data: dms}) { - this.dms = { - reference: dms.reference, - warehouseId: dms.warehouseFk, - companyId: dms.companyFk, - dmsTypeId: dms.dmsTypeFk, - description: dms.description, - hasFile: dms.hasFile, - hasFileAttached: false, - files: [] - }; + setDefaultParams() { + const path = `Dms/${this.$params.dmsId}`; + this.$http.get(path).then(res => { + const dms = res.data && res.data; + this.dms = { + reference: dms.reference, + warehouseId: dms.warehouseFk, + companyId: dms.companyFk, + dmsTypeId: dms.dmsTypeFk, + description: dms.description, + hasFile: dms.hasFile, + hasFileAttached: false, + files: [] + }; + }); } onSubmit() { diff --git a/modules/ticket/front/tracking/index/index.js b/modules/ticket/front/tracking/index/index.js index 95665b071e..ff3dc881b1 100644 --- a/modules/ticket/front/tracking/index/index.js +++ b/modules/ticket/front/tracking/index/index.js @@ -7,15 +7,9 @@ class Controller extends Section { this.filter = { include: [ { - relation: 'worker', + relation: 'user', scope: { - fields: ['id'], - include: { - relation: 'user', - scope: { - fields: ['name'] - } - } + fields: ['name'] } }, { relation: 'state', diff --git a/modules/travel/front/thermograph/create/index.js b/modules/travel/front/thermograph/create/index.js index e51d23124e..fa2c1261ad 100644 --- a/modules/travel/front/thermograph/create/index.js +++ b/modules/travel/front/thermograph/create/index.js @@ -17,10 +17,16 @@ class Controller extends Section { if (value) { this.setDefaultParams(); - this.allowedContentTypes = this.getAllowedContentTypes(); + this.getAllowedContentTypes(); } } + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + }); + } get contentTypesInfo() { return this.$t('ContentTypesInfo', { diff --git a/modules/travel/front/thermograph/edit/index.js b/modules/travel/front/thermograph/edit/index.js index 1678643b2e..a8df3142d3 100644 --- a/modules/travel/front/thermograph/edit/index.js +++ b/modules/travel/front/thermograph/edit/index.js @@ -1,8 +1,8 @@ import ngModule from '../../module'; -import SectionDms from 'salix/components/section-dms'; +import Section from 'salix/components/section'; import './style.scss'; -class Controller extends SectionDms { +class Controller extends Section { get travel() { return this._travel; } @@ -12,10 +12,17 @@ class Controller extends SectionDms { if (value) { this.setDefaultParams(); - this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); + this.getAllowedContentTypes(); } } + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + }); + } + get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes diff --git a/modules/worker/front/dms/create/index.js b/modules/worker/front/dms/create/index.js index 2f06128b59..ff6112211a 100644 --- a/modules/worker/front/dms/create/index.js +++ b/modules/worker/front/dms/create/index.js @@ -21,12 +21,17 @@ class Controller extends Section { if (value) { this.setDefaultParams(); - this.getAllowedContentTypes().then(data => { - this.allowedContentTypes = data; - }); + this.getAllowedContentTypes(); } } + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + }); + } + get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes From bdf5dd6e3c4e334b44a65a254220cdf239eab0f6 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 13 Dec 2023 13:48:22 +0100 Subject: [PATCH 395/449] refs #2051 feat: restore dms methods --- back/methods/dms/removeFile.js | 15 +++++---------- back/methods/dms/uploadFile.js | 15 +-------------- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/back/methods/dms/removeFile.js b/back/methods/dms/removeFile.js index cb81ff3220..a9ff368834 100644 --- a/back/methods/dms/removeFile.js +++ b/back/methods/dms/removeFile.js @@ -34,25 +34,20 @@ module.exports = Self => { } try { - let modelDms = null; - if (myOptions.model) { - modelDms = await models[myOptions.model].findById(id, null, myOptions); - id = modelDms.dmsFk; - } - const targetDms = await models.Dms.findById(id, null, myOptions); + const dms = await models.Dms.findById(id, null, myOptions); const trashDmsType = await models.DmsType.findOne({ where: {code: 'trash'} }, myOptions); - const hasWriteRole = await models.DmsType.hasWriteRole(ctx, targetDms.dmsTypeFk, myOptions); + const hasWriteRole = await models.DmsType.hasWriteRole(ctx, dms.dmsTypeFk, myOptions); if (!hasWriteRole) throw new UserError(`You don't have enough privileges`); - await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); + await dms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); if (tx) await tx.commit(); - if (modelDms) modelDms.destroy(myOptions); - return targetDms; + + return dms; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/back/methods/dms/uploadFile.js b/back/methods/dms/uploadFile.js index abed95a3a6..a4212b8047 100644 --- a/back/methods/dms/uploadFile.js +++ b/back/methods/dms/uploadFile.js @@ -96,21 +96,8 @@ module.exports = Self => { } if (tx) await tx.commit(); - const promises = []; - const {model, create} = myOptions; - addedDms.forEach(dms => { - const newDms = models[model].create({ - ...create, - dmsFk: dms.id - }, myOptions); - promises.push(newDms); - }); - const resolvedPromises = await Promise.all(promises); - - // if (tx) await tx.commit(); - - return resolvedPromises; + return addedDms; } catch (e) { if (tx) await tx.rollback(); From 7b9e3b0985f55a35e326a54680930ff4da410cba Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 13 Dec 2023 14:24:05 +0100 Subject: [PATCH 396/449] refs #2051 perf: removeFile after review --- back/methods/dms/removeFile.js | 2 +- .../back/methods/claim-dms/removeFile.js | 21 +++++++------- .../back/methods/client-dms/removeFile.js | 12 ++++---- .../back/methods/ticket-dms/removeFile.js | 15 +++++----- .../back/methods/worker-dms/removeFile.js | 29 ++++++++++--------- 5 files changed, 42 insertions(+), 37 deletions(-) diff --git a/back/methods/dms/removeFile.js b/back/methods/dms/removeFile.js index a9ff368834..dc55b4d385 100644 --- a/back/methods/dms/removeFile.js +++ b/back/methods/dms/removeFile.js @@ -22,8 +22,8 @@ module.exports = Self => { Self.removeFile = async(ctx, id, options) => { const models = Self.app.models; - let tx; const myOptions = {}; + let tx; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/claim/back/methods/claim-dms/removeFile.js b/modules/claim/back/methods/claim-dms/removeFile.js index 257b09cf2d..0f1da626cf 100644 --- a/modules/claim/back/methods/claim-dms/removeFile.js +++ b/modules/claim/back/methods/claim-dms/removeFile.js @@ -1,3 +1,5 @@ +const UserError = require('vn-loopback/util/user-error'); + module.exports = Self => { Self.remoteMethodCtx('removeFile', { description: 'Removes a claim document', @@ -19,8 +21,8 @@ module.exports = Self => { }); Self.removeFile = async(ctx, id, options) => { - let tx; const myOptions = {}; + let tx; if (typeof options == 'object') Object.assign(myOptions, options); @@ -31,19 +33,18 @@ module.exports = Self => { } try { - // const {models: ClaimDms, Dms} = Self.app.models; - // const targetClaimDms = await ClaimDms.findById(id, null, myOptions); - // await Dms.findById(targetClaimDms.dmsFk, null, myOptions); - // const trashDmsType = await DmsType.findOne({where: {code: 'trash'}}, myOptions); - myOptions.model = 'ClaimDms'; - const targetDms = await Self.app.models.Dms.removeFile(ctx, id, myOptions); - // await targetClaimDms.destroy(myOptions); + const claimDms = await Self.findById(id, null, myOptions); - // await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); + const targetDms = await Self.app.models.Dms.removeFile(ctx, claimDms.dmsFk, myOptions); + + if (!targetDms || ! claimDms) + throw new UserError('Try again'); + + const claimDestroyed = await claimDms.destroy(myOptions); if (tx) await tx.commit(); - return targetDms; + return claimDestroyed; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/client/back/methods/client-dms/removeFile.js b/modules/client/back/methods/client-dms/removeFile.js index 786a329289..5bd34adcf6 100644 --- a/modules/client/back/methods/client-dms/removeFile.js +++ b/modules/client/back/methods/client-dms/removeFile.js @@ -19,9 +19,8 @@ module.exports = Self => { }); Self.removeFile = async(ctx, id, options) => { - const models = Self.app.models; - let tx; const myOptions = {}; + let tx; if (typeof options == 'object') Object.assign(myOptions, options); @@ -34,13 +33,16 @@ module.exports = Self => { try { const clientDms = await Self.findById(id, null, myOptions); - await models.Dms.removeFile(ctx, clientDms.dmsFk, myOptions); + const targetDms = await Self.app.models.Dms.removeFile(ctx, clientDms.dmsFk, myOptions); - const destroyedClient = await clientDms.destroy(myOptions); + if (!targetDms || !clientDms) + throw new UserError('Try again'); + + const clientDestroyed = await clientDms.destroy(myOptions); if (tx) await tx.commit(); - return destroyedClient; + return clientDestroyed; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/ticket/back/methods/ticket-dms/removeFile.js b/modules/ticket/back/methods/ticket-dms/removeFile.js index 2e3ccd149d..2f6426fbbc 100644 --- a/modules/ticket/back/methods/ticket-dms/removeFile.js +++ b/modules/ticket/back/methods/ticket-dms/removeFile.js @@ -31,19 +31,18 @@ module.exports = Self => { } try { - // const targetTicketDms = await models.TicketDms.findById(id, null, myOptions); - myOptions.model = 'TicketDms'; - // await models.Dms.findById(targetTicketDms.dmsFk, null, myOptions); - // const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}}, myOptions); + const ticketDms = await Self.findById(id, null, myOptions); - const targetDms = await Self.app.models.Dms.removeFile(ctx, id, myOptions); - // await targetTicketDms.destroy(myOptions); + const targetDms = await Self.app.models.Dms.removeFile(ctx, ticketDms.dmsFk, myOptions); - // await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); + if (!targetDms || !ticketDms) + throw new UserError('Try again'); + + const ticketDestroyed = await ticketDms.destroy(myOptions); if (tx) await tx.commit(); - return targetDms; + return ticketDestroyed; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/worker/back/methods/worker-dms/removeFile.js b/modules/worker/back/methods/worker-dms/removeFile.js index 397255bb2f..6c7b6b8508 100644 --- a/modules/worker/back/methods/worker-dms/removeFile.js +++ b/modules/worker/back/methods/worker-dms/removeFile.js @@ -19,25 +19,28 @@ module.exports = Self => { }); Self.removeFile = async(ctx, id, options) => { - const models = Self.app.models; + const myOptions = {}; let tx; + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + try { - const myOptions = {}; + const WorkerDms = await Self.findById(id, null, myOptions); - if (typeof options == 'object') - Object.assign(myOptions, options); + const targetDms = await Self.app.models.Dms.removeFile(ctx, WorkerDms.dmsFk, myOptions); - if (!myOptions.transaction) { - tx = await Self.beginTransaction({}); - myOptions.transaction = tx; - } - // const workerDms = await Self.findById(id); - myOptions.model = 'WorkerDms'; - await models.Dms.removeFile(ctx, id, myOptions); - // await workerDms.destroy(); + if (!targetDms || !WorkerDms) + throw new UserError('Try again'); + + const workerDestroyed = await WorkerDms.destroy(myOptions); if (tx) await tx.commit(); - return workerDms; + return workerDestroyed; } catch (e) { await tx.rollback(); throw e; From b9efbc7d4413c363bca6431f6ba7423ff55cc993 Mon Sep 17 00:00:00 2001 From: robert Date: Wed, 13 Dec 2023 14:30:29 +0100 Subject: [PATCH 397/449] refs #5854 --- modules/item/back/locale/item-shelving/en.yml | 10 +++++----- modules/item/back/locale/item-shelving/es.yml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/item/back/locale/item-shelving/en.yml b/modules/item/back/locale/item-shelving/en.yml index 062d4db3f8..997815b2cf 100644 --- a/modules/item/back/locale/item-shelving/en.yml +++ b/modules/item/back/locale/item-shelving/en.yml @@ -1,13 +1,13 @@ name: itemShelving columns: id: id - itemFk: itemFk - shelvingFk: shelvingFk + itemFk: item + shelvingFk: shelving visible: visible created: created grouping: grouping packing: packing - packagingFk: packagingFk - userFk: userFk + packagingFk: package + userFk: user isChecked: isChecked - buyFk: buyFk + buyFk: buy diff --git a/modules/item/back/locale/item-shelving/es.yml b/modules/item/back/locale/item-shelving/es.yml index 3aedcd0bf6..f00dfd6c5e 100644 --- a/modules/item/back/locale/item-shelving/es.yml +++ b/modules/item/back/locale/item-shelving/es.yml @@ -7,7 +7,7 @@ columns: created: creado grouping: grouping packing: packing - packagingFk: paquete + packagingFk: embalaje userFk: usuario isChecked: está revisado buyFk: compra \ No newline at end of file From 40499e44cf8d38dbaadb8501c8829d23ec5f7008 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 13 Dec 2023 15:05:41 +0100 Subject: [PATCH 398/449] refs #6220 remove concat --- modules/client/back/methods/client/filter.js | 10 ++++++---- .../client/back/methods/client/specs/filter.spec.js | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/client/back/methods/client/filter.js b/modules/client/back/methods/client/filter.js index 43310c86b5..e703ce53d7 100644 --- a/modules/client/back/methods/client/filter.js +++ b/modules/client/back/methods/client/filter.js @@ -145,16 +145,18 @@ module.exports = Self => { c.name, c.fi, c.socialName, - CONCAT(c.phone, ',',GROUP_CONCAT(DISTINCT a.phone)) phone, + c.phone, + a.phone, c.mobile, - CONCAT(c.city, ',',GROUP_CONCAT(DISTINCT a.city)) city, + c.city, + a.city, c.postcode, a.postalCode, c.email, c.isActive, c.isFreezed, - p.id AS provinceFk2, - a.provinceFk, + p.id AS provinceClientFk, + a.provinceFk AS provinceAddressFk, p.name AS province, u.id AS salesPersonFk, u.name AS salesPerson diff --git a/modules/client/back/methods/client/specs/filter.spec.js b/modules/client/back/methods/client/specs/filter.spec.js index 4a61f8aafb..6795850508 100644 --- a/modules/client/back/methods/client/specs/filter.spec.js +++ b/modules/client/back/methods/client/specs/filter.spec.js @@ -146,7 +146,7 @@ describe('client filter()', () => { const randomResultClient = result[randomIndex]; expect(result.length).toBeGreaterThanOrEqual(20); - expect(randomResultClient.city.toLowerCase()).toEqual('gotham,gotham'); + expect(randomResultClient.city.toLowerCase()).toEqual('gotham'); await tx.rollback(); } catch (e) { From 06bae4482495653d63c30762bc7dcc1a3b84b6cc Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 13 Dec 2023 15:38:46 +0100 Subject: [PATCH 399/449] refs #2051 perf: uploadFile after review --- .../claim/back/methods/claim/uploadFile.js | 56 +++---------------- .../client/back/methods/client/uploadFile.js | 23 +++----- .../ticket/back/methods/ticket/uploadFile.js | 22 +++----- .../back/methods/worker-dms/removeFile.js | 10 +++- .../worker/back/methods/worker/uploadFile.js | 19 ++----- modules/worker/front/dms/edit/index.js | 42 ++++++++------ 6 files changed, 64 insertions(+), 108 deletions(-) diff --git a/modules/claim/back/methods/claim/uploadFile.js b/modules/claim/back/methods/claim/uploadFile.js index 7e4798fefb..4fd041456a 100644 --- a/modules/claim/back/methods/claim/uploadFile.js +++ b/modules/claim/back/methods/claim/uploadFile.js @@ -54,7 +54,7 @@ module.exports = Self => { }); Self.uploadFile = async(ctx, id, options) => { - const models = Self.app.models; + const {Dms, ClaimDms} = Self.app.models; const myOptions = {}; let tx; @@ -66,56 +66,14 @@ module.exports = Self => { myOptions.transaction = tx; } - // const promises = []; - // const TempContainer = models.TempContainer; - // const ClaimContainer = models.ClaimContainer; - // const fileOptions = {}; - // const args = ctx.args; - - // let srcFile; try { - myOptions.model = 'ClaimDms'; - myOptions.create = {claimFk: id}; - const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions); + const uploadedFiles = await Dms.uploadFile(ctx, myOptions); - // const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId, myOptions); - // if (!hasWriteRole) - // throw new UserError(`You don't have enough privileges`); - - // // Upload file to temporary path - // const tempContainer = await TempContainer.container('dms'); - // const uploaded = await TempContainer.upload(tempContainer.name, ctx.req, ctx.result, fileOptions); - // const files = Object.values(uploaded.files).map(file => { - // return file[0]; - // }); - - // const addedDms = []; - // for (const uploadedFile of files) { - // const newDms = await createDms(ctx, uploadedFile, myOptions); - // const pathHash = ClaimContainer.getHash(newDms.id); - - // const file = await TempContainer.getFile(tempContainer.name, uploadedFile.name); - // srcFile = path.join(file.client.root, file.container, file.name); - - // const claimContainer = await ClaimContainer.container(pathHash); - // const dstFile = path.join(claimContainer.client.root, pathHash, newDms.file); - - // await fs.move(srcFile, dstFile, { - // overwrite: true - // }); - - // addedDms.push(newDms); - // } - - // addedDms.forEach(dms => { - // const newClaimDms = models.ClaimDms.create({ - // claimFk: id, - // dmsFk: dms.id - // }, myOptions); - - // promises.push(newClaimDms); - // }); - // const resolvedPromises = await Promise.all(promises); + const promises = uploadedFiles.map(dms => ClaimDms.create({ + claimFk: id, + dmsFk: dms.id + }, myOptions)); + await Promise.all(promises); if (tx) await tx.commit(); diff --git a/modules/client/back/methods/client/uploadFile.js b/modules/client/back/methods/client/uploadFile.js index 8f471f1b6d..1a59659557 100644 --- a/modules/client/back/methods/client/uploadFile.js +++ b/modules/client/back/methods/client/uploadFile.js @@ -55,7 +55,7 @@ module.exports = Self => { }); Self.uploadFile = async(ctx, id, options) => { - const models = Self.app.models; + const {Dms, ClientDms} = Self.app.models; const myOptions = {}; let tx; @@ -67,21 +67,16 @@ module.exports = Self => { myOptions.transaction = tx; } - // const promises = []; - try { - myOptions.model = 'ClientDms'; - myOptions.create = {clientFk: id}; - const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions); - // uploadedFiles.forEach(dms => { - // const newClientDms = models.ClientDms.create({ - // clientFk: id, - // dmsFk: dms.id - // }, myOptions); + const uploadedFiles = await Dms.uploadFile(ctx, myOptions); + const promises = uploadedFiles.map(dms => + ClientDms.create({ + clientFk: id, + dmsFk: dms.id + }, myOptions) - // promises.push(newClientDms); - // }); - // const resolvedPromises = await Promise.all(promises); + ); + await Promise.all(promises); if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/uploadFile.js b/modules/ticket/back/methods/ticket/uploadFile.js index 63bbe845a9..eb563783cc 100644 --- a/modules/ticket/back/methods/ticket/uploadFile.js +++ b/modules/ticket/back/methods/ticket/uploadFile.js @@ -47,7 +47,7 @@ module.exports = Self => { }); Self.uploadFile = async(ctx, id, options) => { - const models = Self.app.models; + const {Dms, TicketDms} = Self.app.models; const myOptions = {}; let tx; @@ -59,21 +59,15 @@ module.exports = Self => { myOptions.transaction = tx; } - // const promises = []; try { - myOptions.model = 'TicketDms'; - myOptions.create = {ticketFk: id}; - const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions); - /* uploadedFiles.forEach(dms => { - const newTicketDms = models.TicketDms.create({ - ticketFk: id, - dmsFk: dms.id - }, myOptions); + const uploadedFiles = await Dms.uploadFile(ctx, myOptions); + const promises = uploadedFiles.map(dms => TicketDms.create({ + ticketFk: id, + dmsFk: dms.id + }, myOptions)); + + await Promise.all(promises); - promises.push(newTicketDms); - }); - const resolvedPromises = await Promise.all(promises); -*/ if (tx) await tx.commit(); return uploadedFiles; diff --git a/modules/worker/back/methods/worker-dms/removeFile.js b/modules/worker/back/methods/worker-dms/removeFile.js index 6c7b6b8508..9fddc8b4bf 100644 --- a/modules/worker/back/methods/worker-dms/removeFile.js +++ b/modules/worker/back/methods/worker-dms/removeFile.js @@ -30,9 +30,15 @@ module.exports = Self => { } try { - const WorkerDms = await Self.findById(id, null, myOptions); + // const dms = await Self.app.models.Dms.findById(id, null, myOptions); + const WorkerDms = await Self.findOne({ + where: {document: id} + }, myOptions); - const targetDms = await Self.app.models.Dms.removeFile(ctx, WorkerDms.dmsFk, myOptions); + // const targetDms = await Self.app.models.Dms.removeFile(ctx, id, myOptions); + // const WorkerDms = await Self.findById(+targetDms.reference, null, myOptions); + + const targetDms = await Self.app.models.Dms.removeFile(ctx, id, myOptions); if (!targetDms || !WorkerDms) throw new UserError('Try again'); diff --git a/modules/worker/back/methods/worker/uploadFile.js b/modules/worker/back/methods/worker/uploadFile.js index e624dc9042..c3526cbb18 100644 --- a/modules/worker/back/methods/worker/uploadFile.js +++ b/modules/worker/back/methods/worker/uploadFile.js @@ -47,10 +47,9 @@ module.exports = Self => { }); Self.uploadFile = async(ctx, id) => { - const models = Self.app.models; + const {Dms, WorkerDms} = Self.app.models; const myOptions = {}; let tx; - // const promises = []; if (typeof options == 'object') Object.assign(myOptions, options); @@ -61,20 +60,14 @@ module.exports = Self => { } try { - myOptions.model = 'WorkerDms'; - myOptions.create = {workerFk: id}; - - const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions); - /* uploadedFiles.forEach(dms => { - const newWorkerDms = models.WorkerDms.create({ + const uploadedFiles = await Dms.uploadFile(ctx, myOptions); + const promises = uploadedFiles.map(dms => + WorkerDms.create({ workerFk: id, dmsFk: dms.id - }, options); + }, myOptions)); + await Promise.all(promises); - promises.push(newWorkerDms); - }); - const resolvedPromises = await Promise.all(promises); -*/ if (tx) await tx.commit(); return uploadedFiles; diff --git a/modules/worker/front/dms/edit/index.js b/modules/worker/front/dms/edit/index.js index 8a17905639..31d4c2853b 100644 --- a/modules/worker/front/dms/edit/index.js +++ b/modules/worker/front/dms/edit/index.js @@ -1,8 +1,8 @@ import ngModule from '../../module'; -import SectionDms from 'salix/components/section-dms'; +import Section from 'salix/components/section'; import './style.scss'; -class Controller extends SectionDms { +class Controller extends Section { get worker() { return this._worker; } @@ -11,29 +11,39 @@ class Controller extends SectionDms { this._worker = value; if (value) { - this.getDms(this.$params.dmsId).then(handleDefaultParams); - - this.getAllowedContentTypes().then(data => this.allowedContentTypes = data); + this.setDefaultParams(); + this.getAllowedContentTypes(); } } + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + }); + } + get contentTypesInfo() { return this.$t('ContentTypesInfo', { allowedContentTypes: this.allowedContentTypes }); } - handleDefaultParams({data: dms}) { - this.dms = { - reference: dms.reference, - warehouseId: dms.warehouseFk, - companyId: dms.companyFk, - dmsTypeId: dms.dmsTypeFk, - description: dms.description, - hasFile: dms.hasFile, - hasFileAttached: false, - files: [] - }; + setDefaultParams() { + const path = `Dms/${this.$params.dmsId}`; + this.$http.get(path).then(res => { + const dms = res.data && res.data; + this.dms = { + reference: dms.reference, + warehouseId: dms.warehouseFk, + companyId: dms.companyFk, + dmsTypeId: dms.dmsTypeFk, + description: dms.description, + hasFile: dms.hasFile, + hasFileAttached: false, + files: [] + }; + }); } onSubmit() { From d7454cdb198fab8e5cb0292935a15e90e7378fa7 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 14 Dec 2023 11:41:59 +0100 Subject: [PATCH 400/449] refs #6576 fix: correct version --- CHANGELOG.md | 11 ++--------- db/changes/235201/.gitkeep | 0 db/dump/fixtures.sql | 4 ---- package.json | 2 +- 4 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 db/changes/235201/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index dfdc563fb4..45912aff3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,17 +5,10 @@ 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). -## [2352.01] - 2023-12-28 - -### Added -### Changed -### Fixed - ## [2350.01] - 2023-12-14 -### Added -### Changed -### Fixed +### Características Añadidas 🆕 +- **Tickets → Expediciones:** Añadido soporte para Viaexpress ## [2348.01] - 2023-11-30 diff --git a/db/changes/235201/.gitkeep b/db/changes/235201/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index f422dcb451..3354e95c2d 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -5,10 +5,6 @@ SET DEFAULT ROLE 'salix' FOR 'root'@'%'; CREATE SCHEMA IF NOT EXISTS `vn2008`; CREATE SCHEMA IF NOT EXISTS `tmp`; -CREATE ROLE 'salix'; -GRANT 'salix' TO 'root'@'%'; -SET DEFAULT ROLE 'salix' FOR 'root'@'%'; - UPDATE `util`.`config` SET `environment`= 'development'; diff --git a/package.json b/package.json index 66a5cd2fa6..586c963dd6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.52.01", + "version": "23.50.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From 61a323078bd1e30f6ba402570e39700a503aed2f Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 14 Dec 2023 12:04:05 +0100 Subject: [PATCH 401/449] refs #6264 fix: remove DEFAULT_COURTESY_TIME --- back/methods/vn-user/renew-token.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index e7e826cd13..d2f322d40d 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -1,8 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); const {models} = require('vn-loopback/server/server'); -const DEFAULT_COURTESY_TIME = 60; -const handlePromiseLogout = (Self, {id}, courtesyTime = DEFAULT_COURTESY_TIME) => { +const handlePromiseLogout = (Self, {id}, courtesyTime) => { new Promise(res => { setTimeout(() => { res(Self.logout(id)); From 8d2985091793832c403e1553e60ddef9f5d222c4 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 14 Dec 2023 12:21:07 +0100 Subject: [PATCH 402/449] refs #6264 perf: remove UserError exception --- back/methods/vn-user/renew-token.js | 3 ++- back/methods/vn-user/specs/renew-token.spec.js | 10 +++++----- front/core/services/token.js | 4 ---- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index d2f322d40d..194747949b 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -29,7 +29,8 @@ module.exports = Self => { // Check if current token is valid const isValid = await validateToken(token); - if (isValid) throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded'); + if (isValid) + return token; const {courtesyTime} = await models.AccessTokenConfig.findOne({fields: ['courtesyTime']}); diff --git a/back/methods/vn-user/specs/renew-token.spec.js b/back/methods/vn-user/specs/renew-token.spec.js index 21d3de1a99..b6c15e3c2e 100644 --- a/back/methods/vn-user/specs/renew-token.spec.js +++ b/back/methods/vn-user/specs/renew-token.spec.js @@ -37,13 +37,13 @@ describe('Renew Token', () => { it('NOT should renew', async() => { let error; try { - await models.VnUser.renewToken(ctx); + const response = await models.VnUser.renewToken(ctx); + + expect(error).toBeUnDefined(); + expect(error.statusCode).toBe(200); + expect(response.token.id).toEqual(ctx.req.accessToken.id); } catch (e) { error = e; } - - expect(error).toBeDefined(); - expect(error.statusCode).toBe(400); - expect(error.message).toEqual('The renew period has not been exceeded'); }); }); diff --git a/front/core/services/token.js b/front/core/services/token.js index f1408f7e3e..c8cb4f6bb6 100644 --- a/front/core/services/token.js +++ b/front/core/services/token.js @@ -103,10 +103,6 @@ export default class Token { const token = res.data; this.set(token.id, now, token.ttl, this.remember); }) - .catch(res => { - if (res.data?.error?.code !== 'periodNotExceeded') - throw res; - }) .finally(() => { this.checking = false; }); From d2461d67c954a7d249425733af1771aae5a0b7c2 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 14 Dec 2023 12:25:40 +0100 Subject: [PATCH 403/449] refs #6264 test: perf renew-token.spec.js --- back/methods/vn-user/specs/renew-token.spec.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/back/methods/vn-user/specs/renew-token.spec.js b/back/methods/vn-user/specs/renew-token.spec.js index b6c15e3c2e..674ce36f40 100644 --- a/back/methods/vn-user/specs/renew-token.spec.js +++ b/back/methods/vn-user/specs/renew-token.spec.js @@ -36,14 +36,14 @@ describe('Renew Token', () => { it('NOT should renew', async() => { let error; + let response; try { - const response = await models.VnUser.renewToken(ctx); - - expect(error).toBeUnDefined(); - expect(error.statusCode).toBe(200); - expect(response.token.id).toEqual(ctx.req.accessToken.id); + response = await models.VnUser.renewToken(ctx); } catch (e) { error = e; } + + expect(error).toBeUndefined(); + expect(response.id).toEqual(ctx.req.accessToken.id); }); }); From d0af29c0c57d9c19270ddbd502170201219ef1d8 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 14 Dec 2023 12:28:41 +0100 Subject: [PATCH 404/449] refs #6264 test: remove force describe for dms test --- back/methods/dms/specs/removeFile.spec.js | 2 +- modules/claim/back/methods/claim-dms/specs/removeFile.spec.js | 2 +- modules/client/back/methods/client-dms/specs/removeFile.spec.js | 2 +- modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js | 2 +- modules/ticket/back/methods/ticket/specs/uploadFile.spec.js | 2 +- modules/worker/back/methods/worker-dms/specs/removeFile.spec.js | 2 +- modules/worker/back/methods/worker/specs/uploadFile.spec.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/back/methods/dms/specs/removeFile.spec.js b/back/methods/dms/specs/removeFile.spec.js index e0d1dc1e79..59a2acecb0 100644 --- a/back/methods/dms/specs/removeFile.spec.js +++ b/back/methods/dms/specs/removeFile.spec.js @@ -1,6 +1,6 @@ const {models} = require('vn-loopback/server/server'); -fdescribe('dms removeFile()', () => { +describe('dms removeFile()', () => { let dmsId = 1; it(`should return an error for a user without enough privileges`, async() => { diff --git a/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js b/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js index 210d805e73..108427b4cb 100644 --- a/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js +++ b/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js @@ -1,7 +1,7 @@ const app = require('vn-loopback/server/server'); // f -fdescribe('TicketDms removeFile()', () => { +describe('TicketDms removeFile()', () => { const ticketDmsId = 1; it(`should return an error for a user without enough privileges`, async() => { let clientId = 1101; diff --git a/modules/client/back/methods/client-dms/specs/removeFile.spec.js b/modules/client/back/methods/client-dms/specs/removeFile.spec.js index 61a00a610f..95c7d2ac4a 100644 --- a/modules/client/back/methods/client-dms/specs/removeFile.spec.js +++ b/modules/client/back/methods/client-dms/specs/removeFile.spec.js @@ -1,7 +1,7 @@ const models = require('vn-loopback/server/server').models; // f -fdescribe('ClientDms removeFile()', () => { +describe('ClientDms removeFile()', () => { it(`should return an error for a user without enough privileges`, async() => { const tx = await models.Client.beginTransaction({}); diff --git a/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js b/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js index ca4cb5bc35..9296984c39 100644 --- a/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js +++ b/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; -fdescribe('TicketDms removeFile()', () => { +describe('TicketDms removeFile()', () => { const ticketDmsId = 1; it(`should return an error for a user without enough privileges`, async() => { const tx = await models.TicketDms.beginTransaction({}); diff --git a/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js b/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js index 8c01133e69..70d5320767 100644 --- a/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js +++ b/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; // f -fdescribe('Ticket uploadFile()', () => { +describe('Ticket uploadFile()', () => { it(`should return an error for a user without enough privileges`, async() => { const tx = await models.Ticket.beginTransaction({}); diff --git a/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js b/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js index e66628656a..82c6c3edde 100644 --- a/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js +++ b/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js @@ -1,7 +1,7 @@ const app = require('vn-loopback/server/server'); // f -fdescribe('WorkerDms removeFile()', () => { +describe('WorkerDms removeFile()', () => { const workerDmsFk = 1; it(`should return an error for a user without enough privileges`, async() => { let clientId = 1101; diff --git a/modules/worker/back/methods/worker/specs/uploadFile.spec.js b/modules/worker/back/methods/worker/specs/uploadFile.spec.js index 34426c6a01..71145ef5f1 100644 --- a/modules/worker/back/methods/worker/specs/uploadFile.spec.js +++ b/modules/worker/back/methods/worker/specs/uploadFile.spec.js @@ -1,6 +1,6 @@ const app = require('vn-loopback/server/server'); // f -fdescribe('Worker uploadFile()', () => { +describe('Worker uploadFile()', () => { it(`should return an error for a user without enough privileges`, async() => { let workerId = 1106; let currentUserId = 1102; From 1939c65fabcdf68ffb351ba5b51bbb3763d8b7e2 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 14 Dec 2023 12:35:54 +0100 Subject: [PATCH 405/449] refs #6264 test: remove force describe for dms test --- .../claim-dms/specs/removeFile.spec.js | 1 - .../client-dms/specs/removeFile.spec.js | 1 - .../methods/ticket/specs/uploadFile.spec.js | 25 +------------------ .../ticket/back/methods/ticket/uploadFile.js | 1 + .../back/methods/worker-dms/removeFile.js | 4 --- .../worker-dms/specs/removeFile.spec.js | 1 - .../methods/worker/specs/uploadFile.spec.js | 2 +- 7 files changed, 3 insertions(+), 32 deletions(-) diff --git a/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js b/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js index 108427b4cb..1cd3b16cb6 100644 --- a/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js +++ b/modules/claim/back/methods/claim-dms/specs/removeFile.spec.js @@ -1,6 +1,5 @@ const app = require('vn-loopback/server/server'); -// f describe('TicketDms removeFile()', () => { const ticketDmsId = 1; it(`should return an error for a user without enough privileges`, async() => { diff --git a/modules/client/back/methods/client-dms/specs/removeFile.spec.js b/modules/client/back/methods/client-dms/specs/removeFile.spec.js index 95c7d2ac4a..6dac712932 100644 --- a/modules/client/back/methods/client-dms/specs/removeFile.spec.js +++ b/modules/client/back/methods/client-dms/specs/removeFile.spec.js @@ -1,6 +1,5 @@ const models = require('vn-loopback/server/server').models; -// f describe('ClientDms removeFile()', () => { it(`should return an error for a user without enough privileges`, async() => { const tx = await models.Client.beginTransaction({}); diff --git a/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js b/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js index 70d5320767..133c13265b 100644 --- a/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js +++ b/modules/ticket/back/methods/ticket/specs/uploadFile.spec.js @@ -1,5 +1,5 @@ const models = require('vn-loopback/server/server').models; -// f + describe('Ticket uploadFile()', () => { it(`should return an error for a user without enough privileges`, async() => { const tx = await models.Ticket.beginTransaction({}); @@ -23,27 +23,4 @@ describe('Ticket uploadFile()', () => { expect(error.message).toEqual(`You don't have enough privileges`); }); - - // fit(`should uploadFile`, async() => { - // const tx = await models.Ticket.beginTransaction({}); - - // let error; - // try { - // const options = {transaction: tx}; - - // const ticketId = 15; - // const currentUserId = 9; - // const ticketTypeId = 14; - // const ctx = {req: {accessToken: {userId: currentUserId}}, args: {dmsTypeId: ticketTypeId}, result: new ArrayBuffer(20000)}; - - // await models.Ticket.uploadFile(ctx, ticketId, options); - - // await tx.rollback(); - // } catch (e) { - // await tx.rollback(); - // error = e; - // } - - // expect(error.message).toEqual(`You don't have enough privileges`); - // }); }); diff --git a/modules/ticket/back/methods/ticket/uploadFile.js b/modules/ticket/back/methods/ticket/uploadFile.js index eb563783cc..5b79aa9737 100644 --- a/modules/ticket/back/methods/ticket/uploadFile.js +++ b/modules/ticket/back/methods/ticket/uploadFile.js @@ -61,6 +61,7 @@ module.exports = Self => { try { const uploadedFiles = await Dms.uploadFile(ctx, myOptions); + const promises = uploadedFiles.map(dms => TicketDms.create({ ticketFk: id, dmsFk: dms.id diff --git a/modules/worker/back/methods/worker-dms/removeFile.js b/modules/worker/back/methods/worker-dms/removeFile.js index 9fddc8b4bf..343d6d50b4 100644 --- a/modules/worker/back/methods/worker-dms/removeFile.js +++ b/modules/worker/back/methods/worker-dms/removeFile.js @@ -30,14 +30,10 @@ module.exports = Self => { } try { - // const dms = await Self.app.models.Dms.findById(id, null, myOptions); const WorkerDms = await Self.findOne({ where: {document: id} }, myOptions); - // const targetDms = await Self.app.models.Dms.removeFile(ctx, id, myOptions); - // const WorkerDms = await Self.findById(+targetDms.reference, null, myOptions); - const targetDms = await Self.app.models.Dms.removeFile(ctx, id, myOptions); if (!targetDms || !WorkerDms) diff --git a/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js b/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js index 82c6c3edde..3efd09464a 100644 --- a/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js +++ b/modules/worker/back/methods/worker-dms/specs/removeFile.spec.js @@ -1,6 +1,5 @@ const app = require('vn-loopback/server/server'); -// f describe('WorkerDms removeFile()', () => { const workerDmsFk = 1; it(`should return an error for a user without enough privileges`, async() => { diff --git a/modules/worker/back/methods/worker/specs/uploadFile.spec.js b/modules/worker/back/methods/worker/specs/uploadFile.spec.js index 71145ef5f1..7a929cd2ba 100644 --- a/modules/worker/back/methods/worker/specs/uploadFile.spec.js +++ b/modules/worker/back/methods/worker/specs/uploadFile.spec.js @@ -1,5 +1,5 @@ const app = require('vn-loopback/server/server'); -// f + describe('Worker uploadFile()', () => { it(`should return an error for a user without enough privileges`, async() => { let workerId = 1106; From 9316c31180da1f26ae30b0642980a8249936a0cc Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Thu, 14 Dec 2023 12:36:36 +0100 Subject: [PATCH 406/449] refs #6264 perf: rename variable when destroy ids --- modules/claim/back/methods/claim-dms/removeFile.js | 4 ++-- modules/client/back/methods/client-dms/removeFile.js | 4 ++-- modules/ticket/back/methods/ticket-dms/removeFile.js | 4 ++-- modules/worker/back/methods/worker-dms/removeFile.js | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/claim/back/methods/claim-dms/removeFile.js b/modules/claim/back/methods/claim-dms/removeFile.js index 0f1da626cf..28e78c9d70 100644 --- a/modules/claim/back/methods/claim-dms/removeFile.js +++ b/modules/claim/back/methods/claim-dms/removeFile.js @@ -40,11 +40,11 @@ module.exports = Self => { if (!targetDms || ! claimDms) throw new UserError('Try again'); - const claimDestroyed = await claimDms.destroy(myOptions); + const claimDmsDestroyed = await claimDms.destroy(myOptions); if (tx) await tx.commit(); - return claimDestroyed; + return claimDmsDestroyed; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/client/back/methods/client-dms/removeFile.js b/modules/client/back/methods/client-dms/removeFile.js index 5bd34adcf6..bc9a0f7194 100644 --- a/modules/client/back/methods/client-dms/removeFile.js +++ b/modules/client/back/methods/client-dms/removeFile.js @@ -38,11 +38,11 @@ module.exports = Self => { if (!targetDms || !clientDms) throw new UserError('Try again'); - const clientDestroyed = await clientDms.destroy(myOptions); + const clientDmsDestroyed = await clientDms.destroy(myOptions); if (tx) await tx.commit(); - return clientDestroyed; + return clientDmsDestroyed; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/ticket/back/methods/ticket-dms/removeFile.js b/modules/ticket/back/methods/ticket-dms/removeFile.js index 2f6426fbbc..6fba4c5527 100644 --- a/modules/ticket/back/methods/ticket-dms/removeFile.js +++ b/modules/ticket/back/methods/ticket-dms/removeFile.js @@ -38,11 +38,11 @@ module.exports = Self => { if (!targetDms || !ticketDms) throw new UserError('Try again'); - const ticketDestroyed = await ticketDms.destroy(myOptions); + const ticketDmsDestroyed = await ticketDms.destroy(myOptions); if (tx) await tx.commit(); - return ticketDestroyed; + return ticketDmsDestroyed; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/worker/back/methods/worker-dms/removeFile.js b/modules/worker/back/methods/worker-dms/removeFile.js index 343d6d50b4..a5a3b6bb82 100644 --- a/modules/worker/back/methods/worker-dms/removeFile.js +++ b/modules/worker/back/methods/worker-dms/removeFile.js @@ -39,10 +39,10 @@ module.exports = Self => { if (!targetDms || !WorkerDms) throw new UserError('Try again'); - const workerDestroyed = await WorkerDms.destroy(myOptions); + const workerDmsDestroyed = await WorkerDms.destroy(myOptions); if (tx) await tx.commit(); - return workerDestroyed; + return workerDmsDestroyed; } catch (e) { await tx.rollback(); throw e; From bbb9f58a9edaa16b442cedbf7bb3226a18651b1d Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 14 Dec 2023 14:37:14 +0100 Subject: [PATCH 407/449] refs #6220 fix(client_filter): fix where --- modules/client/back/methods/client/filter.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/client/back/methods/client/filter.js b/modules/client/back/methods/client/filter.js index e703ce53d7..f805c4be95 100644 --- a/modules/client/back/methods/client/filter.js +++ b/modules/client/back/methods/client/filter.js @@ -113,18 +113,18 @@ module.exports = Self => { return {'a.postalCode': {inq: postalCode}}; case 'city': return {or: [ - {'c.city': {like: `%${value}`}}, - {'a.city': {like: `%${value}`}} + {'c.city': {like: `%${value}%`}}, + {'a.city': {like: `%${value}%`}} ]}; case 'postcode': return {or: [ - {'c.postcode': {like: `%${value}`}}, - {'a.postalCode': {like: `%${value}`}} + {'c.postcode': value}, + {'a.postalCode': value} ]}; case 'provinceFk': return {or: [ - {'p.name': {like: `%${value}`}}, - {'a.provinceFk': {like: `%${value}`}} + {'p.id': value}, + {'a.provinceFk': value} ]}; case 'name': case 'salesPersonFk': From e89ec55839e065aaabb34d4df3a4472cb20c452d Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 14 Dec 2023 15:09:07 +0100 Subject: [PATCH 408/449] fix: refs #6172 --- e2e/paths/08-route/03_create_and_clone.spec.js | 2 +- front/core/services/locale/en.yml | 2 +- front/core/services/locale/es.yml | 2 +- front/salix/module.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/paths/08-route/03_create_and_clone.spec.js b/e2e/paths/08-route/03_create_and_clone.spec.js index 0b8da98b46..31c0cfc18b 100644 --- a/e2e/paths/08-route/03_create_and_clone.spec.js +++ b/e2e/paths/08-route/03_create_and_clone.spec.js @@ -26,7 +26,7 @@ describe('Route create path', () => { await page.waitToClick(selectors.createRouteView.submitButton); const message = await page.waitForSnackbar(); - expect(message.text).toContain('Access denied'); + expect(message.text).toContain('Access Denied'); }); }); diff --git a/front/core/services/locale/en.yml b/front/core/services/locale/en.yml index 2be73e696c..8eb8a6f0dd 100644 --- a/front/core/services/locale/en.yml +++ b/front/core/services/locale/en.yml @@ -3,4 +3,4 @@ Could not contact the server: Could not contact the server, make sure you have a Please enter your username: Please enter your username It seems that the server has fall down: It seems that the server has fall down, wait a few minutes and try again Session has expired: Your session has expired, please login again -Access denied: Access denied \ No newline at end of file +Access Denied: Access Denied \ No newline at end of file diff --git a/front/core/services/locale/es.yml b/front/core/services/locale/es.yml index e9811e38f0..2c43ca3b2a 100644 --- a/front/core/services/locale/es.yml +++ b/front/core/services/locale/es.yml @@ -3,5 +3,5 @@ Could not contact the server: No se ha podido contactar con el servidor, asegura Please enter your username: Por favor introduce tu nombre de usuario It seems that the server has fall down: Parece que el servidor se ha caído, espera unos minutos e inténtalo de nuevo Session has expired: Tu sesión ha expirado, por favor vuelve a iniciar sesión -Access denied: Acción no permitida +Access Denied: Acción no permitida Direction not found: Dirección no encontrada diff --git a/front/salix/module.js b/front/salix/module.js index 62d6cac98c..0ce855308f 100644 --- a/front/salix/module.js +++ b/front/salix/module.js @@ -120,7 +120,7 @@ function $exceptionHandler(vnApp, $window, $state, $injector) { messageT = 'Invalid login'; break; case 403: - messageT = exception.data?.error?.message || 'Access denied'; + messageT = exception.data?.error?.message || 'Access Denied'; break; case 502: messageT = 'It seems that the server has fall down'; From 21a1dbeae7fe4a9d9fe75ef910efbdb0fd023dde Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 14 Dec 2023 15:56:49 +0100 Subject: [PATCH 409/449] refs #5914 fix: ticket canBeInvoiced and optimized invoiceTickets --- .../235201/01-refactorHasAnyNegativeBase.sql | 1 + db/dump/fixtures.sql | 2 +- e2e/paths/05-ticket/18_index_payout.spec.js | 2 +- e2e/paths/09-invoice-out/01_summary.spec.js | 4 +-- loopback/locale/en.json | 6 ++-- loopback/locale/es.json | 9 +++-- .../methods/client/specs/consumption.spec.js | 4 +-- .../invoiceOut/specs/transferinvoice.spec.js | 26 ++++++++++++++- .../front/descriptor-menu/index.html | 2 +- .../invoiceOut/front/index/manual/index.html | 1 + .../back/methods/ticket/canBeInvoiced.js | 23 +++---------- .../back/methods/ticket/invoiceTickets.js | 33 ++++++++----------- .../ticket/back/methods/ticket/makeInvoice.js | 2 +- 13 files changed, 64 insertions(+), 51 deletions(-) diff --git a/db/changes/235201/01-refactorHasAnyNegativeBase.sql b/db/changes/235201/01-refactorHasAnyNegativeBase.sql index b6780e280f..65822fc95a 100644 --- a/db/changes/235201/01-refactorHasAnyNegativeBase.sql +++ b/db/changes/235201/01-refactorHasAnyNegativeBase.sql @@ -26,3 +26,4 @@ BEGIN END$$ DELIMITER ; + diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 874e42787e..127bf5ef00 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -720,7 +720,7 @@ INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agen INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `zonePrice`, `zoneBonus`, `created`, `weight`) VALUES (1 , 3, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 121, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1), - (2 , 1, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2), + (2 , 1, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 1, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2), (3 , 1, 7, 1, 6, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 3, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), NULL), (4 , 3, 2, 1, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 9, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), NULL), (5 , 3, 3, 3, 3, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 10, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), NULL), diff --git a/e2e/paths/05-ticket/18_index_payout.spec.js b/e2e/paths/05-ticket/18_index_payout.spec.js index 7e5201d11a..9c55184243 100644 --- a/e2e/paths/05-ticket/18_index_payout.spec.js +++ b/e2e/paths/05-ticket/18_index_payout.spec.js @@ -35,7 +35,7 @@ describe('Ticket index payout path', () => { await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton); await page.write(selectors.ticketsIndex.advancedSearchClient, '1101'); await page.keyboard.press('Enter'); - await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 9); + await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 10); await page.waitToClick(selectors.ticketsIndex.firstTicketCheckbox); await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox); diff --git a/e2e/paths/09-invoice-out/01_summary.spec.js b/e2e/paths/09-invoice-out/01_summary.spec.js index 728f0130a9..09ac66ffce 100644 --- a/e2e/paths/09-invoice-out/01_summary.spec.js +++ b/e2e/paths/09-invoice-out/01_summary.spec.js @@ -28,7 +28,6 @@ describe('InvoiceOut summary path', () => { it('should contain the tax breakdown', async() => { const firstTax = await page.waitToGetProperty(selectors.invoiceOutSummary.taxOne, 'innerText'); - const secondTax = await page.waitToGetProperty(selectors.invoiceOutSummary.taxTwo, 'innerText'); expect(firstTax).toContain('10%'); @@ -37,10 +36,9 @@ describe('InvoiceOut summary path', () => { it('should contain the tickets info', async() => { const firstTicket = await page.waitToGetProperty(selectors.invoiceOutSummary.ticketOne, 'innerText'); - const secondTicket = await page.waitToGetProperty(selectors.invoiceOutSummary.ticketTwo, 'innerText'); expect(firstTicket).toContain('Bat cave'); - expect(secondTicket).toContain('Stark tower'); + expect(secondTicket).toContain('Bat cave'); }); }); diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 7d5b5ed47f..962e1ea130 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -45,6 +45,7 @@ "Extension format is invalid": "Extension format is invalid", "NO_ZONE_FOR_THIS_PARAMETERS": "NO_ZONE_FOR_THIS_PARAMETERS", "This client can't be invoiced": "This client can't be invoiced", + "You must provide the correction information to generate a corrective invoice": "You must provide the correction information to generate a corrective invoice", "The introduced hour already exists": "The introduced hour already exists", "Invalid parameters to create a new ticket": "Invalid parameters to create a new ticket", "Concept cannot be blank": "Concept cannot be blank", @@ -178,7 +179,8 @@ "The renew period has not been exceeded": "The renew period has not been exceeded", "You can not use the same password": "You can not use the same password", "Valid priorities": "Valid priorities: %d", - "Negative basis of tickets": "Negative basis of tickets: {{ticketsIds}}", + "hasAnyNegativeBase": "Negative basis of tickets: {{ticketsIds}}", + "hasAnyPositiveBase": "Positive basis of tickets: {{ticketsIds}}", "This ticket cannot be left empty.": "This ticket cannot be left empty. %s", "Social name should be uppercase": "Social name should be uppercase", "Street should be uppercase": "Street should be uppercase", @@ -201,4 +203,4 @@ "keepPrice": "keepPrice", "Cannot past travels with entries": "Cannot past travels with entries", "It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}" -} \ No newline at end of file +} diff --git a/loopback/locale/es.json b/loopback/locale/es.json index e544be0e69..0c2ad3238f 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -72,6 +72,7 @@ "The secret can't be blank": "La contraseña no puede estar en blanco", "We weren't able to send this SMS": "No hemos podido enviar el SMS", "This client can't be invoiced": "Este cliente no puede ser facturado", + "You must provide the correction information to generate a corrective invoice": "Debes informar la información de corrección para generar una factura rectificativa", "This ticket can't be invoiced": "Este ticket no puede ser facturado", "You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado", "This ticket can not be modified": "Este ticket no puede ser modificado", @@ -305,7 +306,8 @@ "Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico", "The renew period has not been exceeded": "El periodo de renovación no ha sido superado", "Valid priorities": "Prioridades válidas: %d", - "Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}", + "hasAnyNegativeBase": "Base negativa para los tickets: {{ticketsIds}}", + "hasAnyPositiveBase": "Base positivas para los tickets: {{ticketsIds}}", "You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado", "This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s", "The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias", @@ -330,5 +332,8 @@ "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", "Cannot past travels with entries": "No se pueden pasar envíos con entradas", "No tickets to invoice": "No hay tickets para facturar", - "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}" + "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", + "Base negativa para los tickets: 39": "Base negativa para los tickets: 39", + "Base negativa para los tickets: 41": "Base negativa para los tickets: 41", + "keepPrice": "keepPrice" } diff --git a/modules/client/back/methods/client/specs/consumption.spec.js b/modules/client/back/methods/client/specs/consumption.spec.js index 47a495d799..85dbb74229 100644 --- a/modules/client/back/methods/client/specs/consumption.spec.js +++ b/modules/client/back/methods/client/specs/consumption.spec.js @@ -16,7 +16,7 @@ describe('client consumption() filter', () => { }; const result = await models.Client.consumption(ctx, filter, options); - expect(result.length).toEqual(10); + expect(result.length).toEqual(11); await tx.rollback(); } catch (e) { @@ -49,7 +49,7 @@ describe('client consumption() filter', () => { const thirdRow = result[2]; expect(result.length).toEqual(3); - expect(firstRow.quantity).toEqual(10); + expect(firstRow.quantity).toEqual(11); expect(secondRow.quantity).toEqual(15); expect(thirdRow.quantity).toEqual(20); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js index b3bd178265..11575999ac 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js @@ -2,7 +2,7 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); -describe('InvoiceOut tranferInvoice()', () => { +describe('InvoiceOut transferInvoice()', () => { const activeCtx = { accessToken: {userId: 5}, http: { @@ -69,9 +69,33 @@ describe('InvoiceOut tranferInvoice()', () => { await models.InvoiceOut.transferInvoice( ctx, options); + await tx.rollback(); } catch (e) { expect(e.message).toBe(`Select a different client`); await tx.rollback(); } }); + + it('should throw an UserError when it is refund', async() => { + const tx = await models.InvoiceOut.beginTransaction({}); + const options = {transaction: tx}; + const args = { + id: '1', + refFk: 'T1111111', + newClientFk: 1102, + cplusRectificationTypeFk: 1, + siiTypeInvoiceOutFk: 1, + invoiceCorrectionTypeFk: 1 + }; + ctx.args = args; + try { + await models.InvoiceOut.transferInvoice( + ctx, + options); + await tx.rollback(); + } catch (e) { + expect(e.message).toContain(`This ticket is already a refund`); + await tx.rollback(); + } + }); }); diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index 267aa0b153..435db36124 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -227,7 +227,7 @@ vn-one vn-id="siiTypeInvoiceOut" data="siiTypeInvoiceOuts" - show-field="code" + show-field="description" value-field="id" fields="['id','code','description']" required="true" diff --git a/modules/invoiceOut/front/index/manual/index.html b/modules/invoiceOut/front/index/manual/index.html index c3362a319d..5872911e46 100644 --- a/modules/invoiceOut/front/index/manual/index.html +++ b/modules/invoiceOut/front/index/manual/index.html @@ -6,6 +6,7 @@ auto-load="true" url="InvoiceOutSerials" data="invoiceOutSerials" + where="{code: {neq: 'R'}}" order="code"> { diff --git a/modules/ticket/back/methods/ticket/invoiceTickets.js b/modules/ticket/back/methods/ticket/invoiceTickets.js index 212f6556a2..f1793773b2 100644 --- a/modules/ticket/back/methods/ticket/invoiceTickets.js +++ b/modules/ticket/back/methods/ticket/invoiceTickets.js @@ -47,10 +47,10 @@ module.exports = function(Self) { let invoicesIds = []; try { const tickets = await models.Ticket.find({ + fields: ['id', 'clientFk', 'companyFk', 'addressFk'], where: { id: {inq: ticketsIds} - }, - fields: ['id', 'clientFk', 'companyFk'] + } }, myOptions); const [firstTicket] = tickets; @@ -65,18 +65,17 @@ module.exports = function(Self) { fields: ['id', 'hasToInvoiceByAddress'] }, myOptions); + let ticketsByAddress = {[firstTicket.addressFk]: ticketsIds}; if (client.hasToInvoiceByAddress) { - const query = ` - SELECT DISTINCT addressFk - FROM ticket t - WHERE id IN (?)`; - const result = await Self.rawSql(query, [ticketsIds], myOptions); - - const addressIds = result.map(address => address.addressFk); - for (const address of addressIds) - await createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, invoiceCorrection, myOptions); - } else - await createInvoice(ctx, companyId, ticketsIds, null, invoicesIds, invoiceCorrection, myOptions); + ticketsByAddress = tickets.reduce((group, ticket) => { + const {addressFk} = ticket; + group[addressFk] = group[addressFk] ?? []; + group[addressFk].push(ticket.id); + return group; + }, {}); + } + for (const ticketIds of Object.values(ticketsByAddress)) + invoicesIds.push(await createInvoice(ctx, companyId, ticketIds, invoiceCorrection, myOptions)); if (tx) await tx.commit(); } catch (e) { @@ -91,7 +90,7 @@ module.exports = function(Self) { return invoicesIds; }; - async function createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, invoiceCorrection, myOptions) { + async function createInvoice(ctx, companyId, ticketsIds, invoiceCorrection, myOptions) { const models = Self.app.models; await models.Ticket.rawSql(` CREATE OR REPLACE TEMPORARY TABLE tmp.ticketToInvoice @@ -100,12 +99,8 @@ module.exports = function(Self) { SELECT id FROM vn.ticket WHERE id IN (?) - ${address ? `AND addressFk = ${address}` : ''} `, [ticketsIds], myOptions); - - const invoiceId = - await models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), invoiceCorrection, myOptions); - invoicesIds.push(invoiceId); + return models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), invoiceCorrection, myOptions); } }; diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js index fe7e527c8e..32aa03f9d1 100644 --- a/modules/ticket/back/methods/ticket/makeInvoice.js +++ b/modules/ticket/back/methods/ticket/makeInvoice.js @@ -106,7 +106,7 @@ module.exports = function(Self) { ); } - if (resultInvoice.id) // serial != 'R' && + if (resultInvoice.id) await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions); if (tx) await tx.commit(); From c755b1e6fa7f948b78d9de47e6fad5c43f14a198 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 15 Dec 2023 08:50:22 +0100 Subject: [PATCH 410/449] refs #5914 fix: correct sql version --- db/changes/{235201 => 235001}/00-getTaxBases.sql | 0 db/changes/{235201 => 235001}/01-newHasAnyPositiveBase.sql | 0 db/changes/{235201 => 235001}/01-refactorHasAnyNegativeBase.sql | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename db/changes/{235201 => 235001}/00-getTaxBases.sql (100%) rename db/changes/{235201 => 235001}/01-newHasAnyPositiveBase.sql (100%) rename db/changes/{235201 => 235001}/01-refactorHasAnyNegativeBase.sql (100%) diff --git a/db/changes/235201/00-getTaxBases.sql b/db/changes/235001/00-getTaxBases.sql similarity index 100% rename from db/changes/235201/00-getTaxBases.sql rename to db/changes/235001/00-getTaxBases.sql diff --git a/db/changes/235201/01-newHasAnyPositiveBase.sql b/db/changes/235001/01-newHasAnyPositiveBase.sql similarity index 100% rename from db/changes/235201/01-newHasAnyPositiveBase.sql rename to db/changes/235001/01-newHasAnyPositiveBase.sql diff --git a/db/changes/235201/01-refactorHasAnyNegativeBase.sql b/db/changes/235001/01-refactorHasAnyNegativeBase.sql similarity index 100% rename from db/changes/235201/01-refactorHasAnyNegativeBase.sql rename to db/changes/235001/01-refactorHasAnyNegativeBase.sql From 59f2e3d0e62c16c1822210bb7a71730bd3625025 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 15 Dec 2023 08:54:41 +0100 Subject: [PATCH 411/449] refs #5914 fix: remove unnecessary --- db/dump/structure.sql | 30 ------------------------------ loopback/locale/es.json | 3 +-- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 4e1695185d..1db4252f48 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -26391,36 +26391,6 @@ CREATE TABLE `cplusCorrectingType` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; --- --- Table structure for table `cplusInvoiceType472` --- - -DROP TABLE IF EXISTS `cplusInvoiceType472`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `cplusInvoiceType472` ( - `id` int(10) unsigned NOT NULL, - `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='(*18) TIPO FACTURA (Asientos)SOPORTADO – DEDUCIBLE (472)'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `siiTypeInvoiceOut` --- - -DROP TABLE IF EXISTS `siiTypeInvoiceOut`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `siiTypeInvoiceOut` ( - `id` int(10) unsigned NOT NULL, - `code` varchar(2) NOT NULL, - `description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `code_UNIQUE` (`code`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Tipo de Factura Emitidas en el suministro de inmediato'; -/*!40101 SET character_set_client = @saved_cs_client */; - -- -- Table structure for table `cplusRectificationType` -- diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 0c2ad3238f..3a1cdfe990 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -334,6 +334,5 @@ "No tickets to invoice": "No hay tickets para facturar", "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", "Base negativa para los tickets: 39": "Base negativa para los tickets: 39", - "Base negativa para los tickets: 41": "Base negativa para los tickets: 41", - "keepPrice": "keepPrice" + "Base negativa para los tickets: 41": "Base negativa para los tickets: 41" } From 356fe6869635c241b897e8531b202aebe46b563c Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 15 Dec 2023 08:57:09 +0100 Subject: [PATCH 412/449] refs #5914 fix: remove unnecessary translation --- loopback/locale/es.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 3a1cdfe990..e137beb2dd 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -332,7 +332,5 @@ "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", "Cannot past travels with entries": "No se pueden pasar envíos con entradas", "No tickets to invoice": "No hay tickets para facturar", - "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", - "Base negativa para los tickets: 39": "Base negativa para los tickets: 39", - "Base negativa para los tickets: 41": "Base negativa para los tickets: 41" + "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}" } From c9af8cba816a04088347151447c833616371c306 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Fri, 15 Dec 2023 12:50:05 +0100 Subject: [PATCH 413/449] refs #5878 feat: remove . for this message --- front/salix/locale/es.yml | 2 +- loopback/locale/en.json | 4 ++-- loopback/locale/es.json | 4 ++-- modules/ticket/back/methods/ticket/isEditableOrThrow.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/front/salix/locale/es.yml b/front/salix/locale/es.yml index 8ed58a4e4a..044d0d043b 100644 --- a/front/salix/locale/es.yml +++ b/front/salix/locale/es.yml @@ -18,7 +18,7 @@ Show summary: Mostrar vista previa What is new: Novedades de la versión Settings: Ajustes There is a new version, click here to reload: Hay una nueva versión, pulse aquí para recargar -This ticket is locked.: Este ticket está bloqueado +This ticket is locked: Este ticket está bloqueado # Actions diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 7d5b5ed47f..c5e8d4fcf4 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -183,7 +183,7 @@ "Social name should be uppercase": "Social name should be uppercase", "Street should be uppercase": "Street should be uppercase", "You don't have enough privileges.": "You don't have enough privileges.", - "This ticket is locked.": "This ticket is locked.", + "This ticket is locked": "This ticket is locked", "This ticket is not editable.": "This ticket is not editable.", "The ticket doesn't exist.": "The ticket doesn't exist.", "The sales do not exists": "The sales do not exists", @@ -201,4 +201,4 @@ "keepPrice": "keepPrice", "Cannot past travels with entries": "Cannot past travels with entries", "It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}" -} \ No newline at end of file +} diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 01384efb42..a8134909e8 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -312,7 +312,7 @@ "You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado", "This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado", "You don't have enough privileges.": "No tienes suficientes permisos.", - "This ticket is locked.": "Este ticket está bloqueado.", + "This ticket is locked": "Este ticket está bloqueado.", "This ticket is not editable.": "Este ticket no es editable.", "The ticket doesn't exist.": "No existe el ticket.", "Social name should be uppercase": "La razón social debe ir en mayúscula", @@ -330,4 +330,4 @@ "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", "Cannot past travels with entries": "No se pueden pasar envíos con entradas", "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}" -} \ No newline at end of file +} diff --git a/modules/ticket/back/methods/ticket/isEditableOrThrow.js b/modules/ticket/back/methods/ticket/isEditableOrThrow.js index f8285cecd8..41438be3a9 100644 --- a/modules/ticket/back/methods/ticket/isEditableOrThrow.js +++ b/modules/ticket/back/methods/ticket/isEditableOrThrow.js @@ -41,7 +41,7 @@ module.exports = Self => { throw new ForbiddenError(`This ticket is not editable.`); if (isLocked && !isWeekly) - throw new ForbiddenError(`This ticket is locked.`); + throw new ForbiddenError(`This ticket is locked`); if (isWeekly && !canEditWeeklyTicket) throw new ForbiddenError(`You don't have enough privileges.`); From dc98436b85cc52dfd09bb5b2138c442ae60b411d Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Fri, 15 Dec 2023 13:01:44 +0100 Subject: [PATCH 414/449] refs #2051 perf: rename variable --- modules/worker/back/methods/worker-dms/removeFile.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/worker/back/methods/worker-dms/removeFile.js b/modules/worker/back/methods/worker-dms/removeFile.js index a5a3b6bb82..8eb6c05fde 100644 --- a/modules/worker/back/methods/worker-dms/removeFile.js +++ b/modules/worker/back/methods/worker-dms/removeFile.js @@ -18,7 +18,7 @@ module.exports = Self => { } }); - Self.removeFile = async(ctx, id, options) => { + Self.removeFile = async(ctx, dmsFk, options) => { const myOptions = {}; let tx; if (typeof options == 'object') @@ -31,10 +31,10 @@ module.exports = Self => { try { const WorkerDms = await Self.findOne({ - where: {document: id} + where: {document: dmsFk} }, myOptions); - const targetDms = await Self.app.models.Dms.removeFile(ctx, id, myOptions); + const targetDms = await Self.app.models.Dms.removeFile(ctx, dmsFk, myOptions); if (!targetDms || !WorkerDms) throw new UserError('Try again'); From 8d650cf6c080782f6fd639ed6594725b8913c49b Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 18 Dec 2023 08:09:44 +0100 Subject: [PATCH 415/449] refs #6172 test: remove message code --- modules/ticket/back/methods/ticket/specs/addSale.spec.js | 2 +- .../back/methods/ticket/specs/isEditableOrThrow.spec.js | 4 ++-- .../back/methods/ticket/specs/recalculateComponents.spec.js | 2 +- .../ticket/back/methods/ticket/specs/transferClient.spec.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/ticket/back/methods/ticket/specs/addSale.spec.js b/modules/ticket/back/methods/ticket/specs/addSale.spec.js index 8c0e39becf..72c9541d90 100644 --- a/modules/ticket/back/methods/ticket/specs/addSale.spec.js +++ b/modules/ticket/back/methods/ticket/specs/addSale.spec.js @@ -89,6 +89,6 @@ describe('ticket addSale()', () => { error = e; } - expect(error.message).toEqual(`This ticket is locked.`); + expect(error.message).toEqual(`This ticket is locked`); }); }); diff --git a/modules/ticket/back/methods/ticket/specs/isEditableOrThrow.spec.js b/modules/ticket/back/methods/ticket/specs/isEditableOrThrow.spec.js index 6c89bac268..bdf5473251 100644 --- a/modules/ticket/back/methods/ticket/specs/isEditableOrThrow.spec.js +++ b/modules/ticket/back/methods/ticket/specs/isEditableOrThrow.spec.js @@ -40,7 +40,7 @@ describe('ticket isEditableOrThrow()', () => { expect(error.message).toEqual(`This ticket is not editable.`); }); - it('should throw an error as this ticket is locked.', async() => { + it('should throw an error as This ticket is locked', async() => { const tx = await models.Ticket.beginTransaction({}); let error; try { @@ -57,7 +57,7 @@ describe('ticket isEditableOrThrow()', () => { await tx.rollback(); } - expect(error.message).toEqual(`This ticket is locked.`); + expect(error.message).toEqual(`This ticket is locked`); }); it('should throw an error as you do not have enough privileges.', async() => { diff --git a/modules/ticket/back/methods/ticket/specs/recalculateComponents.spec.js b/modules/ticket/back/methods/ticket/specs/recalculateComponents.spec.js index 383c2c6d51..d358a79f5b 100644 --- a/modules/ticket/back/methods/ticket/specs/recalculateComponents.spec.js +++ b/modules/ticket/back/methods/ticket/specs/recalculateComponents.spec.js @@ -39,6 +39,6 @@ describe('ticket recalculateComponents()', () => { error = e; } - expect(error).toEqual(new ForbiddenError(`This ticket is locked.`)); + expect(error).toEqual(new ForbiddenError(`This ticket is locked`)); }); }); diff --git a/modules/ticket/back/methods/ticket/specs/transferClient.spec.js b/modules/ticket/back/methods/ticket/specs/transferClient.spec.js index c09c20083d..5a9edd17e4 100644 --- a/modules/ticket/back/methods/ticket/specs/transferClient.spec.js +++ b/modules/ticket/back/methods/ticket/specs/transferClient.spec.js @@ -23,7 +23,7 @@ describe('Ticket transferClient()', () => { error = e; } - expect(error.message).toEqual(`This ticket is locked.`); + expect(error.message).toEqual(`This ticket is locked`); }); it('should be assigned a different clientFk', async() => { From d60f2a7f88f44906f300e9c5c060ed4b5ec82f1e Mon Sep 17 00:00:00 2001 From: davidd Date: Tue, 19 Dec 2023 09:43:09 +0100 Subject: [PATCH 416/449] fix: refs #6398 Changed alias of views --- db/changes/235201/02-views.sql | 4 ++-- modules/ticket/back/methods/ticket/state.js | 4 ++-- modules/ticket/back/models/ticket-state.json | 8 ++++---- modules/ticket/back/models/ticket-tracking.json | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/db/changes/235201/02-views.sql b/db/changes/235201/02-views.sql index a0f41594da..af190f5967 100644 --- a/db/changes/235201/02-views.sql +++ b/db/changes/235201/02-views.sql @@ -3,7 +3,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` VIEW `vn`.`ticketState` AS SELECT `tt`.`created` AS `updated`, `tt`.`stateFk` AS `stateFk`, - `tt`.`userFk` AS `userFk`, + `tt`.`userFk` AS `workerFk`, `tls`.`ticketFk` AS `ticketFk`, `s`.`id` AS `state`, `s`.`order` AS `productionOrder`, @@ -40,7 +40,7 @@ SELECT `ts`.`state` AS `state`, `ts`.`productionOrder` AS `productionOrder`, `ts`.`alertLevel` AS `alertLevel`, - `ts`.`userFk` AS `userFk`, + `ts`.`userFk` AS `worker`, `ts`.`code` AS `code`, `ts`.`updated` AS `updated`, `ts`.`isPicked` AS `isPicked` diff --git a/modules/ticket/back/methods/ticket/state.js b/modules/ticket/back/methods/ticket/state.js index adac2e42f2..01bfbba20c 100644 --- a/modules/ticket/back/methods/ticket/state.js +++ b/modules/ticket/back/methods/ticket/state.js @@ -51,12 +51,12 @@ module.exports = Self => { params.stateFk = state.id; } - if (!params.userFk) { + if (!params.workerFk) { const worker = await models.Worker.findOne({ where: {id: userId} }, myOptions); - params.userFk = worker.id; + params.workerFk = worker.id; } const ticketState = await models.TicketState.findById(params.ticketFk, { diff --git a/modules/ticket/back/models/ticket-state.json b/modules/ticket/back/models/ticket-state.json index 3ee50fac06..3dd3229397 100644 --- a/modules/ticket/back/models/ticket-state.json +++ b/modules/ticket/back/models/ticket-state.json @@ -34,9 +34,9 @@ "foreignKey": "stateFk" }, "user": { - "type": "belongsTo", - "model": "VnUser", - "foreignKey": "userFk" - } + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "workerFk" + } } } diff --git a/modules/ticket/back/models/ticket-tracking.json b/modules/ticket/back/models/ticket-tracking.json index 8b0617145c..4b5a4d4732 100644 --- a/modules/ticket/back/models/ticket-tracking.json +++ b/modules/ticket/back/models/ticket-tracking.json @@ -37,9 +37,9 @@ "foreignKey": "stateFk" }, "user": { - "type": "belongsTo", - "model": "VnUser", - "foreignKey": "userFk" - } + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "userFk" + } } } From 17e177b7888adf882683876d75f20d6d79b64799 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 19 Dec 2023 10:12:03 +0100 Subject: [PATCH 417/449] fix: refs #6398 Fix tests back --- modules/ticket/back/methods/ticket/state.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/methods/ticket/state.js b/modules/ticket/back/methods/ticket/state.js index 01bfbba20c..adac2e42f2 100644 --- a/modules/ticket/back/methods/ticket/state.js +++ b/modules/ticket/back/methods/ticket/state.js @@ -51,12 +51,12 @@ module.exports = Self => { params.stateFk = state.id; } - if (!params.workerFk) { + if (!params.userFk) { const worker = await models.Worker.findOne({ where: {id: userId} }, myOptions); - params.workerFk = worker.id; + params.userFk = worker.id; } const ticketState = await models.TicketState.findById(params.ticketFk, { From 5936a129dad5caa678e5d276b1cec7ac22beccfa Mon Sep 17 00:00:00 2001 From: davidd Date: Tue, 19 Dec 2023 12:58:20 +0100 Subject: [PATCH 418/449] refs #6398 --- db/changes/235201/02-views.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/changes/235201/02-views.sql b/db/changes/235201/02-views.sql index af190f5967..1d031c38d2 100644 --- a/db/changes/235201/02-views.sql +++ b/db/changes/235201/02-views.sql @@ -40,7 +40,7 @@ SELECT `ts`.`state` AS `state`, `ts`.`productionOrder` AS `productionOrder`, `ts`.`alertLevel` AS `alertLevel`, - `ts`.`userFk` AS `worker`, + `ts`.`worker` AS `worker`, `ts`.`code` AS `code`, `ts`.`updated` AS `updated`, `ts`.`isPicked` AS `isPicked` From 7777696cf75d7ce20c18bdc48f40ad251a0a5b6f Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 19 Dec 2023 13:58:08 +0100 Subject: [PATCH 419/449] refs #6589 fix(worker_absences): fix started hours --- modules/worker/back/methods/calendar/absences.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/worker/back/methods/calendar/absences.js b/modules/worker/back/methods/calendar/absences.js index 8420ed7705..8a5d189871 100644 --- a/modules/worker/back/methods/calendar/absences.js +++ b/modules/worker/back/methods/calendar/absences.js @@ -39,6 +39,7 @@ module.exports = Self => { started.setFullYear(year); started.setMonth(0); started.setDate(1); + started.setHours(0, 0, 0, 0); const ended = Date.vnNew(); ended.setFullYear(year); From 516a3760a183fc42d5ea42fa3a6b7a90f8154a41 Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 20 Dec 2023 07:27:13 +0100 Subject: [PATCH 420/449] feat: refs #6582 Added traductions --- modules/route/back/locale/route/en.yml | 15 +++++++++++++++ modules/route/back/locale/route/es.yml | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/modules/route/back/locale/route/en.yml b/modules/route/back/locale/route/en.yml index 96aaddb72e..12b16c38c5 100644 --- a/modules/route/back/locale/route/en.yml +++ b/modules/route/back/locale/route/en.yml @@ -17,3 +17,18 @@ columns: agencyModeFk: agency routeFk: route zoneFk: zone + name: name + beachFk: beach + ticketPacked: tickets packed + ticketFree: tickets free + ticketProduction: tickets production + packages: packages + note: note + dated: dated + dockFk: dock + priority: priority + etd: etd + expeditionTruckFk: truck + m3boxes: m3 boxes + bufferFk: buffer + isPickingAllowed: is picking allowed diff --git a/modules/route/back/locale/route/es.yml b/modules/route/back/locale/route/es.yml index c0a4347917..cf6afc2119 100644 --- a/modules/route/back/locale/route/es.yml +++ b/modules/route/back/locale/route/es.yml @@ -17,3 +17,19 @@ columns: agencyModeFk: agencia routeFk: ruta zoneFk: zona + name: nombre + beachFk: playa + ticketPacked: tickets encajados + ticketFree: tickets libres + ticketProduction: tickets producción + packages: paquetes + note: nota + dated: fecha + dockFk: muelle + priority: prioridad + etd: etd + expeditionTruckFk: camión + m3boxes: m3 cajas + bufferFk: buffer + isPickingAllowed: está permitido recoger + From 753c6e9ec5e772f893e41d98f9f09175bbd28c36 Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 20 Dec 2023 07:28:54 +0100 Subject: [PATCH 421/449] feat: refs #6582 Added traductions --- modules/route/back/locale/route/en.yml | 2 +- modules/route/back/locale/route/es.yml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/route/back/locale/route/en.yml b/modules/route/back/locale/route/en.yml index 12b16c38c5..d86cbe3422 100644 --- a/modules/route/back/locale/route/en.yml +++ b/modules/route/back/locale/route/en.yml @@ -31,4 +31,4 @@ columns: expeditionTruckFk: truck m3boxes: m3 boxes bufferFk: buffer - isPickingAllowed: is picking allowed + isPickingAllowed: is picking allowed \ No newline at end of file diff --git a/modules/route/back/locale/route/es.yml b/modules/route/back/locale/route/es.yml index cf6afc2119..baefb6433e 100644 --- a/modules/route/back/locale/route/es.yml +++ b/modules/route/back/locale/route/es.yml @@ -31,5 +31,4 @@ columns: expeditionTruckFk: camión m3boxes: m3 cajas bufferFk: buffer - isPickingAllowed: está permitido recoger - + isPickingAllowed: está permitido recoger \ No newline at end of file From 57b3d96628ff5a1d7618d3741373ab84d061e4a4 Mon Sep 17 00:00:00 2001 From: JAVIER SEGARRA MARTINEZ Date: Wed, 20 Dec 2023 09:27:25 +0000 Subject: [PATCH 422/449] refs #6434 fix: bad throw error --- back/models/vn-user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 7b8a308c2a..b1d09f0c0b 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -142,8 +142,8 @@ module.exports = function(Self) { ip: ctx.req.ip, owner: isOwner }); - } throw new UserError('Try again'); + } }; /** From cb35c3632802ea9b94d41f8bb9fa321ed4b5c10f Mon Sep 17 00:00:00 2001 From: JAVIER SEGARRA MARTINEZ Date: Wed, 20 Dec 2023 10:59:36 +0000 Subject: [PATCH 423/449] refs #6434 test: update tests --- back/methods/vn-user/specs/sign-in.spec.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/back/methods/vn-user/specs/sign-in.spec.js b/back/methods/vn-user/specs/sign-in.spec.js index 1c4b4af51b..a14dd301ef 100644 --- a/back/methods/vn-user/specs/sign-in.spec.js +++ b/back/methods/vn-user/specs/sign-in.spec.js @@ -20,10 +20,7 @@ describe('VnUser Sign-in()', () => { let ctx = {req: {accessToken: accessToken}}; let signInLog = await SignInLog.find({where: {token: accessToken.id}}); - expect(signInLog.length).toEqual(1); - expect(signInLog[0].userFk).toEqual(accessToken.userId); - expect(signInLog[0].owner).toEqual(true); - expect(login.token).toBeDefined(); + expect(signInLog.length).toEqual(0); await VnUser.logout(ctx.req.accessToken.id); }); From 542b09073e627bd4cc442c2a98979e370cdedf54 Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 20 Dec 2023 14:02:05 +0100 Subject: [PATCH 424/449] changes moved: refs #6274 --- db/changes/{235001 => 235201}/00-timecontrol.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{235001 => 235201}/00-timecontrol.sql (100%) diff --git a/db/changes/235001/00-timecontrol.sql b/db/changes/235201/00-timecontrol.sql similarity index 100% rename from db/changes/235001/00-timecontrol.sql rename to db/changes/235201/00-timecontrol.sql From 7b0c5fe0a00b5b8ce3410c8e69736e7615afe2d5 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 21 Dec 2023 08:33:50 +0100 Subject: [PATCH 425/449] refs #5739 fix: sql --- CHANGELOG.md | 6 ++++++ .../{235201 => 240001}/00-alterTable.sql | 0 .../00-clientCreditLimitToRoleCreditLimit.sql | 2 +- .../{235201 => 240001}/01-procedures.sql | 0 db/changes/{235201 => 240001}/02-views.sql | 18 +++++++++++------- db/dump/structure.sql | 1 + package-lock.json | 4 ++-- package.json | 2 +- 8 files changed, 22 insertions(+), 11 deletions(-) rename db/changes/{235201 => 240001}/00-alterTable.sql (100%) rename db/changes/{235201 => 240001}/00-clientCreditLimitToRoleCreditLimit.sql (74%) rename db/changes/{235201 => 240001}/01-procedures.sql (100%) rename db/changes/{235201 => 240001}/02-views.sql (79%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45912aff3a..b69b8a29b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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). +## [2400.01] - 2024-01-04 + +### Added +### Changed +### Fixed + ## [2350.01] - 2023-12-14 ### Características Añadidas 🆕 diff --git a/db/changes/235201/00-alterTable.sql b/db/changes/240001/00-alterTable.sql similarity index 100% rename from db/changes/235201/00-alterTable.sql rename to db/changes/240001/00-alterTable.sql diff --git a/db/changes/235201/00-clientCreditLimitToRoleCreditLimit.sql b/db/changes/240001/00-clientCreditLimitToRoleCreditLimit.sql similarity index 74% rename from db/changes/235201/00-clientCreditLimitToRoleCreditLimit.sql rename to db/changes/240001/00-clientCreditLimitToRoleCreditLimit.sql index bf4cc60029..2bc0f830dd 100644 --- a/db/changes/235201/00-clientCreditLimitToRoleCreditLimit.sql +++ b/db/changes/240001/00-clientCreditLimitToRoleCreditLimit.sql @@ -1,4 +1,4 @@ RENAME TABLE `vn`.`clientCreditLimit` TO `vn`.`roleCreditLimit`; -ALTER TABLE `vn`.`clientCreditLimit` DROP FOREIGN KEY `clientCreditLimit_FK`; +ALTER TABLE `vn`.`roleCreditLimit` DROP FOREIGN KEY `clientCreditLimit_FK`; ALTER TABLE `vn`.`roleCreditLimit` ADD CONSTRAINT `roleCreditLimit_FK` FOREIGN KEY (`roleFk`) REFERENCES `account`.`role`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/db/changes/235201/01-procedures.sql b/db/changes/240001/01-procedures.sql similarity index 100% rename from db/changes/235201/01-procedures.sql rename to db/changes/240001/01-procedures.sql diff --git a/db/changes/235201/02-views.sql b/db/changes/240001/02-views.sql similarity index 79% rename from db/changes/235201/02-views.sql rename to db/changes/240001/02-views.sql index 1d031c38d2..86a1049a79 100644 --- a/db/changes/235201/02-views.sql +++ b/db/changes/240001/02-views.sql @@ -1,6 +1,9 @@ +CREATE SCHEMA IF NOT EXISTS `vn2008`; +USE `vn`; + CREATE OR REPLACE DEFINER=`root`@`localhost` SQL SECURITY DEFINER - VIEW `vn`.`ticketState` + VIEW `ticketState` AS SELECT `tt`.`created` AS `updated`, `tt`.`stateFk` AS `stateFk`, `tt`.`userFk` AS `workerFk`, @@ -15,10 +18,10 @@ AS SELECT `tt`.`created` AS `updated`, `s`.`isPicked` AS `isPicked` FROM ( ( - `vn`.`ticketLastState` `tls` - JOIN `vn`.`ticketTracking` `tt` ON(`tt`.`id` = `tls`.`ticketTrackingFk`) + `ticketLastState` `tls` + JOIN `ticketTracking` `tt` ON(`tt`.`id` = `tls`.`ticketTrackingFk`) ) - JOIN `vn`.`state` `s` ON(`s`.`id` = `tt`.`stateFk`) + JOIN `state` `s` ON(`s`.`id` = `tt`.`stateFk`) ); CREATE OR REPLACE DEFINER=`root`@`localhost` @@ -33,9 +36,10 @@ AS SELECT `tt`.`id` AS `inter_id`, `tt`.`supervisorFk` AS `Id_supervisor` FROM `vn`.`ticketTracking` `tt`; -CREATE OR REPLACE -ALGORITHM = UNDEFINED VIEW `ticketStateToday` AS -SELECT +CREATE OR REPLACE DEFINER=`root`@`localhost` + SQL SECURITY DEFINER + VIEW `ticketStateToday` +AS SELECT `ts`.`ticket` AS `ticket`, `ts`.`state` AS `state`, `ts`.`productionOrder` AS `productionOrder`, diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 1db4252f48..694f745efa 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -26391,6 +26391,7 @@ CREATE TABLE `cplusCorrectingType` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `cplusRectificationType` -- diff --git a/package-lock.json b/package-lock.json index 78ef939870..27216b2343 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "salix-back", - "version": "23.50.01", + "version": "24.00.01", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "salix-back", - "version": "23.50.01", + "version": "24.00.01", "license": "GPL-3.0", "dependencies": { "axios": "^1.2.2", diff --git a/package.json b/package.json index 586c963dd6..e8ceaf5f14 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.50.01", + "version": "24.00.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From 38279b07868591761fcdcfb4d4b1b69992ffa307 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 21 Dec 2023 08:37:30 +0100 Subject: [PATCH 426/449] refs #6594 deploy: init version 24.02 --- CHANGELOG.md | 6 ++++++ db/changes/240201/.gitkeep | 0 package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 db/changes/240201/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index b69b8a29b2..1907f46bd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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). +## [2402.01] - 2024-01-11 + +### Added +### Changed +### Fixed + ## [2400.01] - 2024-01-04 ### Added diff --git a/db/changes/240201/.gitkeep b/db/changes/240201/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package-lock.json b/package-lock.json index 27216b2343..012fb50e75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "salix-back", - "version": "24.00.01", + "version": "24.02.01", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "salix-back", - "version": "24.00.01", + "version": "24.02.01", "license": "GPL-3.0", "dependencies": { "axios": "^1.2.2", diff --git a/package.json b/package.json index e8ceaf5f14..ab3d99e19f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "24.00.01", + "version": "24.02.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From f384616d693ae5c3121effb1baa815e4388c9865 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 21 Dec 2023 08:57:46 +0100 Subject: [PATCH 427/449] move changes: refs #6274 --- db/changes/{235001 => 240201}/00-updateCourtesyTime.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{235001 => 240201}/00-updateCourtesyTime.sql (100%) diff --git a/db/changes/235001/00-updateCourtesyTime.sql b/db/changes/240201/00-updateCourtesyTime.sql similarity index 100% rename from db/changes/235001/00-updateCourtesyTime.sql rename to db/changes/240201/00-updateCourtesyTime.sql From 0f20f95dc581f9454f84f8f944812735083a411b Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 21 Dec 2023 10:08:17 +0100 Subject: [PATCH 428/449] refactor: refs #6433 Deleted isPreviousPrepared* columns in model --- modules/shelving/back/models/sector.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/modules/shelving/back/models/sector.json b/modules/shelving/back/models/sector.json index 47d66bd8d0..5ff67491bb 100644 --- a/modules/shelving/back/models/sector.json +++ b/modules/shelving/back/models/sector.json @@ -20,18 +20,10 @@ "type": "number", "required": true }, - "isPreviousPreparedByPacking": { - "type": "boolean", - "required": true - }, "code": { "type": "string", "required": false }, - "isPreviousPrepared": { - "type": "boolean", - "required": true - }, "isPackagingArea": { "type": "boolean", "required": true From dc661f298bfe6c8f4f858bbee0097472435c7379 Mon Sep 17 00:00:00 2001 From: JAVIER SEGARRA MARTINEZ Date: Thu, 21 Dec 2023 09:10:18 +0000 Subject: [PATCH 429/449] refs #6434 test: update tests --- back/methods/vn-user/specs/renew-token.spec.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/back/methods/vn-user/specs/renew-token.spec.js b/back/methods/vn-user/specs/renew-token.spec.js index 674ce36f40..146f6eb0cb 100644 --- a/back/methods/vn-user/specs/renew-token.spec.js +++ b/back/methods/vn-user/specs/renew-token.spec.js @@ -27,8 +27,10 @@ describe('Renew Token', () => { jasmine.clock().uninstall(); }); - it('should renew process', async() => { - jasmine.clock().mockDate(new Date(startingTime + 21600000)); + it('should renew token', async() => { + const mockDate = new Date(startingTime + 26600000); + jasmine.clock().mockDate(mockDate); + console.log(startingTime, mockDate) const {id} = await models.VnUser.renewToken(ctx); expect(id).not.toEqual(ctx.req.accessToken.id); From 9951e911ae302e09c08813cbb98ceb038bfbd3c2 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 21 Dec 2023 10:39:46 +0100 Subject: [PATCH 430/449] refs #5925 feat(docuware_upload): use userConfig.tabletFk --- .vscode/settings.json | 2 +- back/methods/docuware/specs/upload.spec.js | 31 +++++++++++++-- back/methods/docuware/upload.js | 46 +++++++++++----------- back/models/docuwareTablet.json | 5 +-- back/models/user-config.json | 2 +- db/changes/235201/00-tabletDocuware.sql | 24 ----------- db/changes/240201/00-tabletDocuware.sql | 10 +++++ db/dump/fixtures.sql | 5 +++ loopback/locale/es.json | 2 +- 9 files changed, 70 insertions(+), 57 deletions(-) delete mode 100644 db/changes/235201/00-tabletDocuware.sql create mode 100644 db/changes/240201/00-tabletDocuware.sql diff --git a/.vscode/settings.json b/.vscode/settings.json index 40ec5c0d37..36b7e21d84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,7 @@ // Carácter predeterminado de final de línea. "files.eol": "\n", "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, "search.useIgnoreFiles": false, "editor.defaultFormatter": "dbaeumer.vscode-eslint", diff --git a/back/methods/docuware/specs/upload.spec.js b/back/methods/docuware/specs/upload.spec.js index 3b8c55a504..2577fa42db 100644 --- a/back/methods/docuware/specs/upload.spec.js +++ b/back/methods/docuware/specs/upload.spec.js @@ -24,15 +24,40 @@ describe('docuware upload()', () => { }); it('should try upload file', async() => { + const tx = await models.Docuware.beginTransaction({}); spyOn(ticketModel, 'deliveryNotePdf').and.returnValue(new Promise(resolve => resolve({}))); let error; try { - await models.Docuware.upload(ctx, ticketIds, fileCabinetName); + const options = {transaction: tx}; + const user = await models.UserConfig.findById(userId, null, options); + await user.updateAttribute('tabletFk', 'Tablet1'); + await models.Docuware.upload(ctx, ticketIds, fileCabinetName, options); + + await tx.rollback(); } catch (e) { - error = e.message; + error = e; + await tx.rollback(); } - expect(error).toEqual('Action not allowed on the test environment'); + expect(error.message).toEqual('Action not allowed on the test environment'); + }); + + it('should throw error when not have tablet assigned', async() => { + const tx = await models.Docuware.beginTransaction({}); + spyOn(ticketModel, 'deliveryNotePdf').and.returnValue(new Promise(resolve => resolve({}))); + + let error; + try { + const options = {transaction: tx}; + await models.Docuware.upload(ctx, ticketIds, fileCabinetName, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toEqual('This user does not have an assigned tablet'); }); }); diff --git a/back/methods/docuware/upload.js b/back/methods/docuware/upload.js index 5f44e9382b..27be72295e 100644 --- a/back/methods/docuware/upload.js +++ b/back/methods/docuware/upload.js @@ -29,12 +29,24 @@ module.exports = Self => { } }); - Self.upload = async function(ctx, ticketIds, fileCabinet) { + Self.upload = async function(ctx, ticketIds, fileCabinet, options) { delete ctx.args.ticketIds; const models = Self.app.models; const action = 'store'; - const options = await Self.getOptions(); + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const userConfig = await models.UserConfig.findById(ctx.req.accessToken.userId, { + fields: ['tabletFk'] + }, myOptions); + + if (!userConfig?.tabletFk) + throw new UserError('This user does not have an assigned tablet'); + + const docuwareOptions = await Self.getOptions(); const fileCabinetId = await Self.getFileCabinet(fileCabinet); const dialogId = await Self.getDialog(fileCabinet, action, fileCabinetId); @@ -45,7 +57,7 @@ module.exports = Self => { const deliveryNote = await models.Ticket.deliveryNotePdf(ctx, { id, type: 'deliveryNote' - }); + }, myOptions); // get ticket data const ticket = await models.Ticket.findById(id, { include: [{ @@ -54,17 +66,7 @@ module.exports = Self => { fields: ['id', 'name', 'fi'] } }] - }); - - // get tablet - const tablet = await models.userConfig.findById(id, { - include: [{ - relation: 'Tablet', - scope: { - fields: ['id'] - } - }] - }); + }, myOptions); // upload file const templateJson = { @@ -112,7 +114,7 @@ module.exports = Self => { { 'FieldName': 'FILTRO_TABLET', 'ItemElementName': 'string', - 'Item': tablet.id, + 'Item': userConfig.tabletFk, } ] }; @@ -120,19 +122,17 @@ module.exports = Self => { if (process.env.NODE_ENV != 'production') throw new UserError('Action not allowed on the test environment'); - if (!tablet.id) - throw new UserError('This user does not have an assigned tablet.'); // delete old const docuwareFile = await models.Docuware.checkFile(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 deleteUri = `${docuwareOptions.url}/FileCabinets/${fileCabinetId}/Documents/${docuwareFile.id}/Fields`; + await axios.put(deleteUri, deleteJson, docuwareOptions.headers); } - const uploadUri = `${options.url}/FileCabinets/${fileCabinetId}/Documents?StoreDialogId=${dialogId}`; + const uploadUri = `${docuwareOptions.url}/FileCabinets/${fileCabinetId}/Documents?StoreDialogId=${dialogId}`; const FormData = require('form-data'); const data = new FormData(); @@ -142,7 +142,7 @@ module.exports = Self => { headers: { 'Content-Type': 'multipart/form-data', 'X-File-ModifiedDate': Date.vnNew(), - 'Cookie': options.headers.headers.Cookie, + 'Cookie': docuwareOptions.headers.headers.Cookie, ...data.getHeaders() }, }; @@ -153,11 +153,11 @@ module.exports = Self => { const $t = ctx.req.__; const message = $t('Failed to upload delivery note', {id}); if (uploaded.length) - await models.TicketTracking.setDelivered(ctx, uploaded); + await models.TicketTracking.setDelivered(ctx, uploaded, myOptions); throw new UserError(message); } uploaded.push(id); } - return models.TicketTracking.setDelivered(ctx, ticketIds); + return models.TicketTracking.setDelivered(ctx, ticketIds, myOptions); }; }; diff --git a/back/models/docuwareTablet.json b/back/models/docuwareTablet.json index e9e3b6bad9..dbbf62f56e 100644 --- a/back/models/docuwareTablet.json +++ b/back/models/docuwareTablet.json @@ -7,10 +7,7 @@ } }, "properties": { - "id": { - "type": "number" - }, - "name": { + "tablet": { "type": "string" }, "description": { diff --git a/back/models/user-config.json b/back/models/user-config.json index 35f6aa1e6a..5c5df1b9ef 100644 --- a/back/models/user-config.json +++ b/back/models/user-config.json @@ -28,7 +28,7 @@ "type": "boolean" }, "tabletFk": { - "type": "number" + "type": "string" } }, "relations": { diff --git a/db/changes/235201/00-tabletDocuware.sql b/db/changes/235201/00-tabletDocuware.sql deleted file mode 100644 index c480c1001a..0000000000 --- a/db/changes/235201/00-tabletDocuware.sql +++ /dev/null @@ -1,24 +0,0 @@ --- vn.docuwareTablet definition - -CREATE TABLE `vn`.`docuwareTablet` ( - `id` int(3) NOT NULL AUTO_INCREMENT, - `name` varchar(100) NOT NULL, - `description` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; - --- Auto-generated SQL script. Actual values for binary/complex data types may differ - what you see is the default string representation of values. -INSERT INTO `vn`.`docuwareTablet` (`id`,`name`,`description`) - VALUES (1,'tabletRRHH','tablet de recursos humanos'); -INSERT INTO `vn`.`docuwareTablet` (`id`,`name`,`description`) - VALUES (2,'tabletIT','tablet de IT'); -INSERT INTO `vn`.`docuwareTablet` (`id`,`name`,`description`) - VALUES (3,'tabletCompradores','tablet de compradores'); -INSERT INTO `vn`.`docuwareTablet` (`id`,`name`,`description`) - VALUES (4,'tabletComerciales','tablet de comerciales'); -INSERT INTO `vn`.`docuwareTablet` (`id`,`name`,`description`) - VALUES (5,'tabletAdministracion','tablet de administracion'); - -ALTER TABLE `vn`.`userConfig` -ADD COLUMN tabletFk int(3), -ADD FOREIGN KEY (tabletFk) REFERENCES `vn`.`docuwareTablet`(id); diff --git a/db/changes/240201/00-tabletDocuware.sql b/db/changes/240201/00-tabletDocuware.sql new file mode 100644 index 0000000000..ffa0226b33 --- /dev/null +++ b/db/changes/240201/00-tabletDocuware.sql @@ -0,0 +1,10 @@ +-- vn.docuwareTablet definition + +CREATE TABLE `vn`.`docuwareTablet` ( + `tablet` varchar(100) NOT NULL PRIMARY KEY, + `description` varchar(255) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +ALTER TABLE `vn`.`userConfig` +ADD COLUMN tabletFk varchar(100) DEFAULT NULL, +ADD FOREIGN KEY (tabletFk) REFERENCES `vn`.`docuwareTablet`(tablet); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 8997e40b1e..479704dd96 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -3009,3 +3009,8 @@ INSERT INTO `vn`.`invoiceCorrectionType` (`id`, `description`) (1, 'Error in VAT calculation'), (2, 'Error in sales details'), (3, 'Error in customer data'); + +INSERT INTO `vn`.`docuwareTablet` (`tablet`,`description`) + VALUES + ('Tablet1','Jarvis tablet'), + ('Tablet2','Avengers tablet'); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 94bc29a867..a197197ba1 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -330,5 +330,5 @@ "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", "Cannot past travels with entries": "No se pueden pasar envíos con entradas", "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", - "This user does not have an assigned tablet.": "Este usuario no tiene tablet asignada" + "This user does not have an assigned tablet": "Este usuario no tiene tablet asignada" } From 0998b5bf2cfb59d4864cc24f8d6b1aceab9f2495 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 21 Dec 2023 13:58:33 +0100 Subject: [PATCH 431/449] add locale and refactor: refs #6274 --- loopback/locale/es.json | 5 +++-- .../worker/back/methods/worker-time-control/clockIn.js | 6 +++--- modules/worker/back/methods/worker-time-control/login.js | 9 ++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index a8134909e8..185212d516 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -329,5 +329,6 @@ "The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima", "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", "Cannot past travels with entries": "No se pueden pasar envíos con entradas", - "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}" -} + "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", + "Incorrect pin.": "Pin incorrecto." +} \ No newline at end of file diff --git a/modules/worker/back/methods/worker-time-control/clockIn.js b/modules/worker/back/methods/worker-time-control/clockIn.js index 2e2441cc2a..44e0c547ae 100644 --- a/modules/worker/back/methods/worker-time-control/clockIn.js +++ b/modules/worker/back/methods/worker-time-control/clockIn.js @@ -36,9 +36,9 @@ module.exports = Self => { Object.assign(myOptions, options); const query = 'CALL vn.workerTimeControl_clockIn(?, ?, ?)'; - const [response] = await Self.rawSql(query, [workerFk, timed, direction], myOptions); - if (response[0] && response[0].error) - throw new UserError(response[0].error); + const [[response]] = await Self.rawSql(query, [workerFk, timed, direction], myOptions); + if (response && response.error) + throw new UserError(response.error); return response; }; diff --git a/modules/worker/back/methods/worker-time-control/login.js b/modules/worker/back/methods/worker-time-control/login.js index 894b5ba178..b2a17b4e4b 100644 --- a/modules/worker/back/methods/worker-time-control/login.js +++ b/modules/worker/back/methods/worker-time-control/login.js @@ -8,7 +8,7 @@ module.exports = Self => { { arg: 'pin', type: 'string', - required: true, + required: true }, ], returns: { @@ -27,9 +27,8 @@ module.exports = Self => { Object.assign(myOptions, options); const query = `CALL vn.workerTimeControl_login(?)`; - const user = await Self.rawSql(query, [pin], myOptions); - - if (!user) throw new UserError('Indique el pin.'); - return user[0][0]; + const [[user]] = await Self.rawSql(query, [pin], myOptions); + if (!user) throw new UserError('Incorrect pin.'); + return user; }; }; From 27a369bef4aa176fc4d43c5efb2a7f20239995ec Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 21 Dec 2023 18:34:22 +0100 Subject: [PATCH 432/449] refactor(ticketSms): refs #6259 merge ticksms to clientsms --- db/changes/235201/00-ticketSmsToClientSms.sql | 25 +++++++++++++++++ db/dump/fixtures.sql | 14 ++++++++++ modules/client/back/model-config.json | 3 -- modules/client/back/models/client-sms.json | 5 ++++ modules/client/back/models/ticket-sms.json | 28 ------------------- modules/ticket/back/methods/ticket/sendSms.js | 4 ++- .../back/methods/ticket/specs/sendSms.spec.js | 4 +-- 7 files changed, 49 insertions(+), 34 deletions(-) create mode 100644 db/changes/235201/00-ticketSmsToClientSms.sql delete mode 100644 modules/client/back/models/ticket-sms.json diff --git a/db/changes/235201/00-ticketSmsToClientSms.sql b/db/changes/235201/00-ticketSmsToClientSms.sql new file mode 100644 index 0000000000..f2aa73863d --- /dev/null +++ b/db/changes/235201/00-ticketSmsToClientSms.sql @@ -0,0 +1,25 @@ +ALTER TABLE `vn`.`clientSms` ADD `ticketFk` int(11) NULL; +ALTER TABLE `vn`.`clientSms` ADD CONSTRAINT `clientSms_FK_2` FOREIGN KEY (`ticketFk`) REFERENCES `vn`.`ticket`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +INSERT INTO`vn`.`clientSms` (`clientFk`, `smsFk`, `ticketFk`) + SELECT `t`.`clientFk`, `s`.`smsFk`, `s`.`ticketFk` + FROM `vn`.`clientSms` `s` + JOIN `vn`.`ticket` `t` ON `t`.`id` = `s`.`ticketFk`; + +RENAME TABLE `vn`.`ticketSms` TO `vn`.`ticketSms__`; + +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`clientSms_beforeInsert` + BEFORE INSERT ON `clientSms` + FOR EACH ROW +BEGIN + DECLARE vTicketOwner INT; + + SELECT clientFk INTO vTicketOwner + FROM ticket + WHERE id = NEW.ticketFk; + + IF NOT NEW.clientFk = vTicketOwner THEN + CALL util.throw('Unable to send an SMS ticket to a client who is not the owner'); + END IF; +END$$ \ No newline at end of file diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 8997e40b1e..7ea766d616 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -3009,3 +3009,17 @@ INSERT INTO `vn`.`invoiceCorrectionType` (`id`, `description`) (1, 'Error in VAT calculation'), (2, 'Error in sales details'), (3, 'Error in customer data'); + +INSERT INTO `vn`.`sms` (`id`, `senderFk`, `sender`, `destination`, `message`, `statusCode`, `status`, `created`) + VALUES (1, 66, '111111111', '0001111111111', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'OK', util.VN_CURDATE()), + (2, 66, '222222222', '0002222222222', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'PENDING', util.VN_CURDATE()), + (3, 66, '333333333', '0003333333333', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'ERROR', util.VN_CURDATE()), + (4, 66, '444444444', '0004444444444', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'OK', util.VN_CURDATE()); + +INSERT INTO `vn`.`clientSms` (`id`, `clientFk`, `smsFk`, `ticketFk`) + VALUES(1, 1103, 1, NULL), + (2, 1103, 2, NULL), + (3, 1103, 3, 32), + (4, 1103, 4, 32), + (13, 1101, 1, NULL), + (14, 1101, 4, 27); \ No newline at end of file diff --git a/modules/client/back/model-config.json b/modules/client/back/model-config.json index a214077324..fc1254dd80 100644 --- a/modules/client/back/model-config.json +++ b/modules/client/back/model-config.json @@ -113,9 +113,6 @@ "SageTransactionType": { "dataSource": "vn" }, - "TicketSms": { - "dataSource": "vn" - }, "TpvError": { "dataSource": "vn" }, diff --git a/modules/client/back/models/client-sms.json b/modules/client/back/models/client-sms.json index b2244ebbb0..df1b587378 100644 --- a/modules/client/back/models/client-sms.json +++ b/modules/client/back/models/client-sms.json @@ -21,6 +21,11 @@ "type": "belongsTo", "model": "Sms", "foreignKey": "smsFk" + }, + "ticket": { + "type": "belongsTo", + "model": "Ticket", + "foreignKey": "ticketFk" } } } diff --git a/modules/client/back/models/ticket-sms.json b/modules/client/back/models/ticket-sms.json deleted file mode 100644 index 03f592f51e..0000000000 --- a/modules/client/back/models/ticket-sms.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "TicketSms", - "base": "VnModel", - "options": { - "mysql": { - "table": "ticketSms" - } - }, - "properties": { - "smsFk": { - "type": "number", - "id": true, - "description": "Identifier" - } - }, - "relations": { - "ticket": { - "type": "belongsTo", - "model": "Ticket", - "foreignKey": "ticketFk" - }, - "sms": { - "type": "belongsTo", - "model": "Sms", - "foreignKey": "smsFk" - } - } -} diff --git a/modules/ticket/back/methods/ticket/sendSms.js b/modules/ticket/back/methods/ticket/sendSms.js index ffc95c6b43..36e52fe3dd 100644 --- a/modules/ticket/back/methods/ticket/sendSms.js +++ b/modules/ticket/back/methods/ticket/sendSms.js @@ -33,7 +33,9 @@ module.exports = Self => { Self.sendSms = async(ctx, id, destination, message) => { const models = Self.app.models; const sms = await models.Sms.send(ctx, destination, message); - await models.TicketSms.create({ + const {clientFk} = await models.Ticket.findById(id); + await models.ClientSms.create({ + clientFk, ticketFk: id, smsFk: sms.id }); diff --git a/modules/ticket/back/methods/ticket/specs/sendSms.spec.js b/modules/ticket/back/methods/ticket/specs/sendSms.spec.js index 3f93198d14..43507ec567 100644 --- a/modules/ticket/back/methods/ticket/specs/sendSms.spec.js +++ b/modules/ticket/back/methods/ticket/specs/sendSms.spec.js @@ -17,9 +17,9 @@ describe('ticket sendSms()', () => { const filter = { ticketFk: id }; - const ticketSms = await models.TicketSms.findOne(filter, options); + const clientSms = await models.ClientSms.findOne(filter, options); - expect(ticketSms.ticketFk).toEqual(id); + expect(clientSms.ticketFk).toEqual(id); await tx.rollback(); } catch (e) { From 86db5a931d8b047fb55ca0c2139599737deb74b5 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 22 Dec 2023 10:44:21 +0100 Subject: [PATCH 433/449] arrange test suites: refs #6274 --- .../worker-time-control/specs/clockIn.spec.js | 553 +++++++++++++++++ .../worker-time-control/specs/login.spec.js | 2 +- .../specs/timeEntry.spec.js | 578 +----------------- 3 files changed, 555 insertions(+), 578 deletions(-) diff --git a/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js b/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js index 970fd2fe20..9cd3ed1c06 100644 --- a/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js +++ b/modules/worker/back/methods/worker-time-control/specs/clockIn.spec.js @@ -1,8 +1,29 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('workerTimeControl clockIn()', () => { const workerId = 9; + const salesBossId = 19; + const hankPymId = 1107; + const jessicaJonesId = 1110; + const HHRRId = 37; + const teamBossId = 13; + const monday = 1; + const tuesday = 2; + const thursday = 4; + const friday = 5; + const sunday = 7; const inTime = '2001-01-01T00:00:00.000Z'; + const activeCtx = { + accessToken: {userId: 50}, + }; + const ctx = {req: activeCtx}; + + beforeAll(() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); it('should correctly clock in', async() => { const tx = await models.WorkerTimeControl.beginTransaction({}); @@ -24,5 +45,537 @@ describe('workerTimeControl clockIn()', () => { throw e; } }); + + describe('as Role errors', () => { + it('should add if the current user is team boss and the target user is himself', async() => { + activeCtx.accessToken.userId = teamBossId; + const workerId = teamBossId; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + try { + const options = {transaction: tx}; + + const todayAtOne = Date.vnNew(); + todayAtOne.setHours(1, 0, 0, 0); + + ctx.args = {timed: todayAtOne, direction: 'in'}; + const createdTimeEntry = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + expect(createdTimeEntry.id).toBeDefined(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should delete the created time entry for the team boss as himself', async() => { + activeCtx.accessToken.userId = teamBossId; + const workerId = teamBossId; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + try { + const options = {transaction: tx}; + + const todayAtOne = Date.vnNew(); + todayAtOne.setHours(1, 0, 0, 0); + + ctx.args = {timed: todayAtOne, direction: 'in'}; + const createdTimeEntry = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + expect(createdTimeEntry.id).toBeDefined(); + + await models.WorkerTimeControl.deleteTimeEntry(ctx, createdTimeEntry.id, options); + + const deletedTimeEntry = await models.WorkerTimeControl.findById(createdTimeEntry.id, null, options); + + expect(deletedTimeEntry).toBeNull(); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should edit the created time entry for the team boss as HHRR', async() => { + activeCtx.accessToken.userId = HHRRId; + const workerId = teamBossId; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + try { + const options = {transaction: tx}; + + const todayAtOne = Date.vnNew(); + todayAtOne.setHours(1, 0, 0, 0); + + ctx.args = {timed: todayAtOne, direction: 'in'}; + const createdTimeEntry = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + expect(createdTimeEntry.id).toBeDefined(); + + ctx.args = {direction: 'out'}; + const updatedTimeEntry = await models.WorkerTimeControl.updateTimeEntry( + ctx, createdTimeEntry.id, options + ); + + expect(updatedTimeEntry.direction).toEqual('out'); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + }); + + describe('as saleBoss editor', () => { + let workerId; + beforeEach(() => { + activeCtx.accessToken.userId = salesBossId; + workerId = hankPymId; + }); + + it('should fail to add a time entry if the target user has an absence that day', async() => { + const date = Date.vnNew(); + date.setHours(8, 0, 0); + date.setDate(date.getDate() - 16); + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + try { + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`No está permitido trabajar`); + }); + + it('should fail to add a time entry for a worker without an existing contract', async() => { + const date = Date.vnNew(); + date.setFullYear(date.getFullYear() - 2); + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + try { + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`No hay un contrato en vigor`); + }); + + it('should fail to add a time entry for a worker without an existing contract and exceeding time', async() => { + let date = Date.vnNew(); + date.setDate(date.getDate() - 2); + let error; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + date.setHours(0, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date.setHours(20, 0, 1); + ctx.args = {timed: date, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Superado el tiempo máximo entre entrada y salida`); + }); + + describe('direction errors', () => { + let date = Date.vnNew(); + date.setDate(date.getDate() - 1); + let error; + it('should throw an error when trying "in" direction twice', async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + date.setHours(8, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date.setHours(10, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Dirección incorrecta`); + }); + + it('should throw an error when trying "in" direction after insert "in" and "middle"', async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + date.setHours(8, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + date.setHours(9, 0, 0); + ctx.args = {timed: date, direction: 'middle'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date.setHours(10, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Dirección incorrecta`); + }); + + it('Should throw an error when trying "out" before closing a "middle" couple', async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + date.setHours(8, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + date.setHours(9, 0, 0); + ctx.args = {timed: date, direction: 'middle'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date.setHours(10, 0, 0); + ctx.args = {timed: date, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Dirección incorrecta`); + }); + + it('should throw an error when trying "middle" after "out"', async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + date.setHours(8, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + date.setHours(9, 0, 0); + ctx.args = {timed: date, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date.setHours(10, 0, 0); + ctx.args = {timed: date, direction: 'middle'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Dirección incorrecta`); + }); + + it('should throw an error when trying "out" direction twice', async() => { + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + date.setHours(8, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + date.setHours(9, 0, 0); + ctx.args = {timed: date, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date.setHours(10, 0, 0); + ctx.args = {timed: date, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Dirección incorrecta`); + }); + }); + + describe('12h rest', () => { + activeCtx.accessToken.userId = salesBossId; + const workerId = hankPymId; + it('should throw an error when the 12h rest is not fulfilled yet', async() => { + let date = Date.vnNew(); + date.setDate(date.getDate() - 2); + date = weekDay(date, monday); + let error; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + date.setHours(8, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + date.setHours(16, 0, 0); + ctx.args = {timed: date, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date = weekDay(date, tuesday); + date.setHours(4, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Descanso diario`); + }); + + it('should not fail as the 12h rest is fulfilled', async() => { + let date = Date.vnNew(); + date.setDate(date.getDate() - 2); + date = weekDay(date, monday); + let error; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + date.setHours(8, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + date.setHours(16, 0, 0); + ctx.args = {timed: date, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date = weekDay(date, tuesday); + date.setHours(4, 1, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).not.toBeDefined; + }); + }); + + describe('for 3500kg drivers with enforced 9h rest', () => { + activeCtx.accessToken.userId = salesBossId; + const workerId = jessicaJonesId; + it('should throw an error when the 9h enforced rest is not fulfilled', async() => { + let date = Date.vnNew(); + date.setDate(date.getDate() - 2); + date = weekDay(date, monday); + let error; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + date.setHours(8, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + date.setHours(16, 0, 0); + ctx.args = {timed: date, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date = weekDay(date, tuesday); + date.setHours(1, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Descanso diario`); + }); + + it('should not fail when the 9h enforced rest is fulfilled', async() => { + let date = Date.vnNew(); + date.setDate(date.getDate() - 2); + date = weekDay(date, monday); + let error; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + date.setHours(8, 0, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + date.setHours(16, 0, 0); + ctx.args = {timed: date, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + try { + date = weekDay(date, tuesday); + date.setHours(1, 1, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).not.toBeDefined; + }); + }); + + describe('for 72h weekly rest', () => { + + it('should throw an error when work 11 consecutive days', async() => { + let date = Date.vnNew(); + date.setMonth(date.getMonth() - 1); + date.setDate(1); + let error; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + await populateWeek(date, monday, sunday, ctx, workerId, options); + date = nextWeek(date); + await populateWeek(date, monday, thursday, ctx, workerId, options); + try { + date = weekDay(date, friday); + date.setHours(10, 0, 1); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Descanso semanal`); + }); + + it('should throw an error when the 72h weekly rest is not fulfilled', async() => { + + let date = Date.vnNew(); + date.setMonth(date.getMonth() - 1); + date.setDate(1); + let error; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + await populateWeek(date, monday, sunday, ctx, workerId, options); + date = nextWeek(date); + await populateWeek(date, monday, thursday, ctx, workerId, options); + + try { + date = weekDay(date, sunday); + date.setHours(17, 59, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toBe(`Descanso semanal`); + }); + + it('should throw an error when the 72h weekly rest is fulfilled', async() => { + + let date = Date.vnNew(); + date.setMonth(date.getMonth() - 1); + date.setDate(1); + let error; + + const tx = await models.WorkerTimeControl.beginTransaction({}); + const options = {transaction: tx}; + + await populateWeek(date, monday, sunday, ctx, workerId, options); + date = nextWeek(date); + await populateWeek(date, monday, thursday, ctx, workerId, options); + + try { + date = weekDay(date, sunday); + date.setHours(18, 00, 0); + ctx.args = {timed: date, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).not.toBeDefined; + }); + }); + }); }); +function weekDay(date, dayToSet) { + const currentDay = date.getDay(); + const distance = dayToSet - currentDay; + + date.setDate(date.getDate() + distance); + return date; +} + +function nextWeek(date) { + const sunday = 7; + const currentDay = date.getDay(); + let newDate = date; + if (currentDay != 0) + newDate = weekDay(date, sunday); + + newDate.setDate(newDate.getDate() + 1); + return newDate; +} + +async function populateWeek(date, dayStart, dayEnd, ctx, workerId, options) { + const dateStart = new Date(weekDay(date, dayStart)); + const dateEnd = new Date(dateStart); + dateEnd.setDate(dateStart.getDate() + dayEnd); + + for (let i = dayStart; i <= dayEnd; i++) { + dateStart.setHours(10, 0, 0); + ctx.args = {timed: dateStart, direction: 'in'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + dateStart.setHours(18, 0, 0); + ctx.args = {timed: dateStart, direction: 'out'}; + await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + dateStart.setDate(dateStart.getDate() + 1); + } +} diff --git a/modules/worker/back/methods/worker-time-control/specs/login.spec.js b/modules/worker/back/methods/worker-time-control/specs/login.spec.js index 88596f2975..392d9a66b4 100644 --- a/modules/worker/back/methods/worker-time-control/specs/login.spec.js +++ b/modules/worker/back/methods/worker-time-control/specs/login.spec.js @@ -13,7 +13,7 @@ describe('workerTimeControl login()', () => { await models.WorkerTimeControl.login(); } catch (error) { expect(error).toBeInstanceOf(UserError); - expect(error.message).toBe('Indique el pin.'); + expect(error.message).toBe('Incorrect pin.'); } }); }); diff --git a/modules/worker/back/methods/worker-time-control/specs/timeEntry.spec.js b/modules/worker/back/methods/worker-time-control/specs/timeEntry.spec.js index 42ec6290a2..92c01792f5 100644 --- a/modules/worker/back/methods/worker-time-control/specs/timeEntry.spec.js +++ b/modules/worker/back/methods/worker-time-control/specs/timeEntry.spec.js @@ -3,18 +3,10 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('workerTimeControl add/delete timeEntry()', () => { - const HHRRId = 37; - const teamBossId = 13; const employeeId = 1; - const salesPersonId = 1106; const salesBossId = 19; const hankPymId = 1107; - const jessicaJonesId = 1110; const monday = 1; - const tuesday = 2; - const thursday = 4; - const friday = 5; - const sunday = 7; const activeCtx = { accessToken: {userId: 50}, }; @@ -61,560 +53,11 @@ describe('workerTimeControl add/delete timeEntry()', () => { expect(error.statusCode).toBe(400); expect(error.message).toBe(`You don't have enough privileges`); }); - - it('should add if the current user is team boss and the target user is himself', async() => { - activeCtx.accessToken.userId = teamBossId; - const workerId = teamBossId; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - try { - const options = {transaction: tx}; - - const todayAtOne = Date.vnNew(); - todayAtOne.setHours(1, 0, 0, 0); - - ctx.args = {timed: todayAtOne, direction: 'in'}; - const [createdTimeEntry] = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - expect(createdTimeEntry.id).toBeDefined(); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should try but fail to delete his own time entry', async() => { - activeCtx.accessToken.userId = salesBossId; - const workerId = salesBossId; - - let error; - const tx = await models.WorkerTimeControl.beginTransaction({}); - try { - const options = {transaction: tx}; - - const todayAtOne = Date.vnNew(); - todayAtOne.setHours(1, 0, 0, 0); - - ctx.args = {timed: todayAtOne, direction: 'in'}; - const [createdTimeEntry] = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - activeCtx.accessToken.userId = salesPersonId; - await models.WorkerTimeControl.deleteTimeEntry(ctx, createdTimeEntry.id, options); - - await tx.rollback(); - } catch (e) { - error = e; - await tx.rollback(); - } - - expect(error).toBeDefined(); - expect(error.statusCode).toBe(400); - expect(error.message).toBe(`You don't have enough privileges`); - }); - - it('should delete the created time entry for the team boss as himself', async() => { - activeCtx.accessToken.userId = teamBossId; - const workerId = teamBossId; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - try { - const options = {transaction: tx}; - - const todayAtOne = Date.vnNew(); - todayAtOne.setHours(1, 0, 0, 0); - - ctx.args = {timed: todayAtOne, direction: 'in'}; - const [createdTimeEntry] = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - expect(createdTimeEntry.id).toBeDefined(); - - await models.WorkerTimeControl.deleteTimeEntry(ctx, createdTimeEntry.id, options); - - const deletedTimeEntry = await models.WorkerTimeControl.findById(createdTimeEntry.id, null, options); - - expect(deletedTimeEntry).toBeNull(); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should delete the created time entry for the team boss as HHRR', async() => { - activeCtx.accessToken.userId = HHRRId; - const workerId = teamBossId; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - try { - const options = {transaction: tx}; - - const todayAtOne = Date.vnNew(); - todayAtOne.setHours(1, 0, 0, 0); - - ctx.args = {timed: todayAtOne, direction: 'in'}; - const [createdTimeEntry] = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - expect(createdTimeEntry.id).toBeDefined(); - - await models.WorkerTimeControl.deleteTimeEntry(ctx, createdTimeEntry.id, options); - - const deletedTimeEntry = await models.WorkerTimeControl.findById(createdTimeEntry.id, null, options); - - expect(deletedTimeEntry).toBeNull(); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should edit the created time entry for the team boss as HHRR', async() => { - activeCtx.accessToken.userId = HHRRId; - const workerId = teamBossId; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - try { - const options = {transaction: tx}; - - const todayAtOne = Date.vnNew(); - todayAtOne.setHours(1, 0, 0, 0); - - ctx.args = {timed: todayAtOne, direction: 'in'}; - const [createdTimeEntry] = await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - expect(createdTimeEntry.id).toBeDefined(); - - ctx.args = {direction: 'out'}; - const updatedTimeEntry = await models.WorkerTimeControl.updateTimeEntry(ctx, createdTimeEntry.id, options); - - expect(updatedTimeEntry.direction).toEqual('out'); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); }); describe('WorkerTimeControl_clockIn calls', () => { - let workerId; - beforeEach(() => { - activeCtx.accessToken.userId = salesBossId; - workerId = hankPymId; - }); - it('should fail to add a time entry if the target user has an absence that day', async() => { - const date = Date.vnNew(); - date.setHours(8, 0, 0); - date.setDate(date.getDate() - 16); - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - try { - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); + beforeEach(() => activeCtx.accessToken.userId = salesBossId); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`No está permitido trabajar`); - }); - - it('should fail to add a time entry for a worker without an existing contract', async() => { - const date = Date.vnNew(); - date.setFullYear(date.getFullYear() - 2); - - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - try { - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`No hay un contrato en vigor`); - }); - - it('should fail to add a time entry for a worker without an existing contract', async() => { - let date = Date.vnNew(); - date.setDate(date.getDate() - 2); - let error; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - date.setHours(0, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - try { - date.setHours(20,0, 1); - ctx.args = {timed: date, direction: 'out'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Superado el tiempo máximo entre entrada y salida`); - }); - - describe('direction errors', () => { - let date = Date.vnNew(); - date.setDate(date.getDate() - 1); - let error; - it('should throw an error when trying "in" direction twice', async() => { - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - date.setHours(8, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - try { - date.setHours(10, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Dirección incorrecta`); - }); - - it('should throw an error when trying "in" direction after insert "in" and "middle"', async() => { - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - date.setHours(8, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - date.setHours(9, 0, 0); - ctx.args = {timed: date, direction: 'middle'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - try { - date.setHours(10, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Dirección incorrecta`); - }); - - it('Should throw an error when trying "out" before closing a "middle" couple', async() => { - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - date.setHours(8, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - date.setHours(9, 0, 0); - ctx.args = {timed: date, direction: 'middle'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - try { - date.setHours(10, 0, 0); - ctx.args = {timed: date, direction: 'out'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Dirección incorrecta`); - }); - - it('should throw an error when trying "middle" after "out"', async() => { - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - date.setHours(8, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - date.setHours(9, 0, 0); - ctx.args = {timed: date, direction: 'out'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - try { - date.setHours(10, 0, 0); - ctx.args = {timed: date, direction: 'middle'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Dirección incorrecta`); - }); - - it('should throw an error when trying "out" direction twice', async() => { - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - date.setHours(8, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - date.setHours(9, 0, 0); - ctx.args = {timed: date, direction: 'out'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - try { - date.setHours(10, 0, 0); - ctx.args = {timed: date, direction: 'out'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Dirección incorrecta`); - }); - }); - - describe('12h rest', () => { - activeCtx.accessToken.userId = salesBossId; - const workerId = hankPymId; - it('should throw an error when the 12h rest is not fulfilled yet', async() => { - - let date = Date.vnNew(); - date.setDate(date.getDate() - 2); - date = weekDay(date, monday); - let error; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - date.setHours(8, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - date.setHours(16, 0, 0); - ctx.args = {timed: date, direction: 'out'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - try { - date = weekDay(date, tuesday); - date.setHours(4, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Descanso diario`); - }); - - it('should not fail as the 12h rest is fulfilled', async() => { - let date = Date.vnNew(); - date.setDate(date.getDate() - 2); - date = weekDay(date, monday); - let error; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - date.setHours(8, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - date.setHours(16, 0, 0); - ctx.args = {timed: date, direction: 'out'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - try { - date = weekDay(date, tuesday); - date.setHours(4, 1, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).not.toBeDefined; - }); - }); - - describe('for 3500kg drivers with enforced 9h rest', () => { - activeCtx.accessToken.userId = salesBossId; - const workerId = jessicaJonesId; - it('should throw an error when the 9h enforced rest is not fulfilled', async() => { - - let date = Date.vnNew(); - date.setDate(date.getDate() - 2); - date = weekDay(date, monday); - let error; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - date.setHours(8, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - date.setHours(16, 0, 0); - ctx.args = {timed: date, direction: 'out'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - try { - date = weekDay(date, tuesday); - date.setHours(1, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Descanso diario`); - }); - - it('should not fail when the 9h enforced rest is fulfilled', async() => { - - let date = Date.vnNew(); - date.setDate(date.getDate() - 2); - date = weekDay(date, monday); - let error; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - date.setHours(8, 0, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - date.setHours(16, 0, 0); - ctx.args = {timed: date, direction: 'out'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - try { - date = weekDay(date, tuesday); - date.setHours(1, 1, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).not.toBeDefined; - }); - }); - - describe('for 72h weekly rest', () => { - - it('should throw an error when work 11 consecutive days', async() => { - let date = Date.vnNew(); - date.setMonth(date.getMonth() - 1); - date.setDate(1); - let error; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - await populateWeek(date, monday, sunday, ctx, workerId, options); - date = nextWeek(date); - await populateWeek(date, monday, thursday, ctx, workerId, options); - try { - date = weekDay(date, friday); - date.setHours(10, 0, 1); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Descanso semanal`); - }); - - it('should throw an error when the 72h weekly rest is not fulfilled', async() => { - - let date = Date.vnNew(); - date.setMonth(date.getMonth() - 1); - date.setDate(1); - let error; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - await populateWeek(date, monday, sunday, ctx, workerId, options); - date = nextWeek(date); - await populateWeek(date, monday, thursday, ctx, workerId, options); - - try { - date = weekDay(date, sunday); - date.setHours(17, 59, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error.message).toBe(`Descanso semanal`); - }); - - it('should throw an error when the 72h weekly rest is fulfilled', async() => { - - let date = Date.vnNew(); - date.setMonth(date.getMonth() - 1); - date.setDate(1); - let error; - - const tx = await models.WorkerTimeControl.beginTransaction({}); - const options = {transaction: tx}; - - await populateWeek(date, monday, sunday, ctx, workerId, options); - date = nextWeek(date); - await populateWeek(date, monday, thursday, ctx, workerId, options); - - try { - date = weekDay(date, sunday); - date.setHours(18, 00, 0); - ctx.args = {timed: date, direction: 'in'}; - await models.WorkerTimeControl.addTimeEntry(ctx, workerId, options); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).not.toBeDefined; - }); - }); - describe('WorkerTimeControl_calculate calls', () => { let dated = Date.vnNew(); dated.setDate(dated.getDate() - 7); @@ -836,25 +279,6 @@ function weekDay(date, dayToSet) { return date; } -function nextWeek(date) { - const sunday = 7; - const currentDay = date.getDay(); - let newDate = date; - if (currentDay != 0) - newDate = weekDay(date, sunday); - - newDate.setDate(newDate.getDate() + 1); - return newDate; -} - -function lastWeek(date) { - const monday = 1; - newDate = weekDay(date, monday); - - newDate.setDate(newDate.getDate() - 1); - return newDate; -} - async function populateWeek(date, dayStart, dayEnd, ctx, workerId, options) { const dateStart = new Date(weekDay(date, dayStart)); const dateEnd = new Date(dateStart); From 2e1715a968fdfac0977952d3939cfe1b3f34190a Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 22 Dec 2023 15:19:45 +0100 Subject: [PATCH 434/449] refactor renewToken & replace ACL: refs #6274 --- back/methods/vn-user/renew-token.js | 41 ++++++++----------- .../methods/vn-user/specs/renew-token.spec.js | 1 - back/models/vn-user.json | 27 ++++++------ db/changes/240201/00-timecontrol.sql | 7 +++- 4 files changed, 37 insertions(+), 39 deletions(-) diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index 194747949b..d00085d8a9 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -1,14 +1,5 @@ -const UserError = require('vn-loopback/util/user-error'); const {models} = require('vn-loopback/server/server'); -const handlePromiseLogout = (Self, {id}, courtesyTime) => { - new Promise(res => { - setTimeout(() => { - res(Self.logout(id)); - } - , courtesyTime * 1000); - }); -}; module.exports = Self => { Self.remoteMethodCtx('renewToken', { description: 'Checks if the token has more than renewPeriod seconds to live and if so, renews it', @@ -28,14 +19,26 @@ module.exports = Self => { const {accessToken: token} = ctx.req; // Check if current token is valid - const isValid = await validateToken(token); - if (isValid) + + const {renewPeriod, courtesyTime} = await models.AccessTokenConfig.findOne({ + fields: ['renewPeriod', 'courtesyTime'] + }); + const now = Date.now(); + const differenceMilliseconds = now - token.created; + const differenceSeconds = Math.floor(differenceMilliseconds / 1000); + const isNotExceeded = differenceSeconds < renewPeriod - courtesyTime; + if (isNotExceeded) return token; - const {courtesyTime} = await models.AccessTokenConfig.findOne({fields: ['courtesyTime']}); - // Schedule to remove current token - handlePromiseLogout(Self, token, courtesyTime); + setTimeout(async() => { + try { + await Self.logout(token.id); + } catch (err) { + // eslint-disable-next-line no-console + console.error(err); + } + }, courtesyTime * 1000); // Create new accessToken const user = await Self.findById(token.userId); @@ -43,14 +46,4 @@ module.exports = Self => { return {id: accessToken.id, ttl: accessToken.ttl}; }; - - async function validateToken(token) { - const accessTokenConfig = await models.AccessTokenConfig.findOne({fields: ['renewPeriod', 'courtesyTime']}); - const now = Date.now(); - const differenceMilliseconds = now - token.created; - const differenceSeconds = Math.floor(differenceMilliseconds / 1000); - const isValid = differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime; - - return isValid; - } }; diff --git a/back/methods/vn-user/specs/renew-token.spec.js b/back/methods/vn-user/specs/renew-token.spec.js index 146f6eb0cb..8d9bbf11ce 100644 --- a/back/methods/vn-user/specs/renew-token.spec.js +++ b/back/methods/vn-user/specs/renew-token.spec.js @@ -30,7 +30,6 @@ describe('Renew Token', () => { it('should renew token', async() => { const mockDate = new Date(startingTime + 26600000); jasmine.clock().mockDate(mockDate); - console.log(startingTime, mockDate) const {id} = await models.VnUser.renewToken(ctx); expect(id).not.toEqual(ctx.req.accessToken.id); diff --git a/back/models/vn-user.json b/back/models/vn-user.json index 86ffac2bbc..d0687098d5 100644 --- a/back/models/vn-user.json +++ b/back/models/vn-user.json @@ -95,27 +95,30 @@ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" - }, - { - "property": "recoverPassword", - "accessType": "EXECUTE", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - }, - { - "property": "validateAuth", + }, { + "property": "recoverPassword", "accessType": "EXECUTE", "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" - }, - { + }, { + "property": "validateAuth", + "accessType": "EXECUTE", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }, { "property": "privileges", "accessType": "*", "principalType": "ROLE", "principalId": "$authenticated", "permission": "ALLOW" + }, { + "property": "renewToken", + "accessType": "WRITE", + "principalType": "ROLE", + "principalId": "$authenticated", + "permission": "ALLOW" } ], "scopes": { diff --git a/db/changes/240201/00-timecontrol.sql b/db/changes/240201/00-timecontrol.sql index 0d3bd59b2e..c3ddf5d96c 100644 --- a/db/changes/240201/00-timecontrol.sql +++ b/db/changes/240201/00-timecontrol.sql @@ -1,3 +1,7 @@ +DELETE FROM `salix`.`ACL` + WHERE model = 'VnUser' + AND property = 'renewToken'; + INSERT INTO `account`.`role` (name, description) VALUES ('timeControl','Tablet para fichar'); @@ -8,7 +12,6 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp VALUES ('WorkerTimeControl', 'login', 'READ', 'ALLOW', 'ROLE', 'timeControl'), ('WorkerTimeControl', 'getClockIn', 'READ', 'ALLOW', 'ROLE', 'timeControl'), - ('WorkerTimeControl', 'clockIn', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'), - ('VnUser', 'renewToken', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'); + ('WorkerTimeControl', 'clockIn', 'WRITE', 'ALLOW', 'ROLE', 'timeControl'); CALL `account`.`role_sync`(); From 5a1c4ddea02f52c6e836246b70c1a5d0d459e082 Mon Sep 17 00:00:00 2001 From: pablone Date: Tue, 26 Dec 2023 08:20:13 +0100 Subject: [PATCH 435/449] refactor(ticketSms): refs #6259 ticketSmsToClientSms --- .../00-ticketSmsToClientSms.sql | 16 ---------------- .../back/methods/ticket/specs/sendSms.spec.js | 8 ++++---- 2 files changed, 4 insertions(+), 20 deletions(-) rename db/changes/{240001 => 240201}/00-ticketSmsToClientSms.sql (52%) diff --git a/db/changes/240001/00-ticketSmsToClientSms.sql b/db/changes/240201/00-ticketSmsToClientSms.sql similarity index 52% rename from db/changes/240001/00-ticketSmsToClientSms.sql rename to db/changes/240201/00-ticketSmsToClientSms.sql index f2aa73863d..cd3cf7dd3a 100644 --- a/db/changes/240001/00-ticketSmsToClientSms.sql +++ b/db/changes/240201/00-ticketSmsToClientSms.sql @@ -7,19 +7,3 @@ INSERT INTO`vn`.`clientSms` (`clientFk`, `smsFk`, `ticketFk`) JOIN `vn`.`ticket` `t` ON `t`.`id` = `s`.`ticketFk`; RENAME TABLE `vn`.`ticketSms` TO `vn`.`ticketSms__`; - -DELIMITER $$ -CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`clientSms_beforeInsert` - BEFORE INSERT ON `clientSms` - FOR EACH ROW -BEGIN - DECLARE vTicketOwner INT; - - SELECT clientFk INTO vTicketOwner - FROM ticket - WHERE id = NEW.ticketFk; - - IF NOT NEW.clientFk = vTicketOwner THEN - CALL util.throw('Unable to send an SMS ticket to a client who is not the owner'); - END IF; -END$$ \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/specs/sendSms.spec.js b/modules/ticket/back/methods/ticket/specs/sendSms.spec.js index 43507ec567..afc1ada54c 100644 --- a/modules/ticket/back/methods/ticket/specs/sendSms.spec.js +++ b/modules/ticket/back/methods/ticket/specs/sendSms.spec.js @@ -14,10 +14,10 @@ describe('ticket sendSms()', () => { await models.Ticket.sendSms(ctx, id, destination, message, options); - const filter = { - ticketFk: id - }; - const clientSms = await models.ClientSms.findOne(filter, options); + const clientSms = await models.ClientSms.findOne( + {where: {ticketFk: id}}, + options + ); expect(clientSms.ticketFk).toEqual(id); From 1b8461034e12fce15f4918e517f9cbe7ff40a896 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 29 Dec 2023 12:40:48 +0100 Subject: [PATCH 436/449] using hasAnyNegative: refs #6515 --- .../back/methods/invoiceOut/createManualInvoice.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js index 18e6903d68..043dfbead2 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js @@ -85,7 +85,7 @@ module.exports = Self => { throw new UserError(`A ticket with an amount of zero can't be invoiced`); // Validates ticket nagative base - const hasNegativeBase = await getNegativeBase(ticketId, myOptions); + const hasNegativeBase = await getNegativeBase(maxShipped, clientId, companyId, myOptions); if (hasNegativeBase && company.code == 'VNL') throw new UserError(`A ticket with a negative base can't be invoiced`); } else { @@ -162,10 +162,13 @@ module.exports = Self => { return result.invoiceable; } - async function getNegativeBase(ticketId, options) { + async function getNegativeBase(maxShipped, clientId, companyId, options) { const models = Self.app.models; - const query = 'SELECT vn.hasSomeNegativeBase(?) AS base'; - const [result] = await models.InvoiceOut.rawSql(query, [ticketId], options); + await models.InvoiceOut.rawSql('CALL invoiceOut_exportationFromClient(?,?,?)', + [maxShipped, clientId, companyId], options + ); + const query = 'SELECT vn.hasAnyNegativeBase() AS base'; + const [result] = await models.InvoiceOut.rawSql(query, [], options); return result.base; } From 15ec91ec790fbe18191262127a20b402ce824d70 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 29 Dec 2023 14:05:01 +0100 Subject: [PATCH 437/449] fix query: refs #6369 --- modules/invoiceOut/back/methods/invoiceOut/negativeBases.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js b/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js index ae9c404afd..96c7893160 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js +++ b/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js @@ -90,7 +90,7 @@ module.exports = Self => { AND t.refFk IS NULL AND c.typeFk IN ('normal','trust') GROUP BY t.clientFk, negativeBase.taxableBase - HAVING amount <> 0`, [args.from, args.to])); + HAVING amount < 0`, [args.from, args.to])); stmt = new ParameterizedSQL(` SELECT f.* From 318761185bbf1172657002f2adfde77b895c7118 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 2 Jan 2024 08:07:16 +0100 Subject: [PATCH 438/449] refs #6434 fix: remove console.log --- back/methods/vn-user/specs/renew-token.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/back/methods/vn-user/specs/renew-token.spec.js b/back/methods/vn-user/specs/renew-token.spec.js index 146f6eb0cb..8d9bbf11ce 100644 --- a/back/methods/vn-user/specs/renew-token.spec.js +++ b/back/methods/vn-user/specs/renew-token.spec.js @@ -30,7 +30,6 @@ describe('Renew Token', () => { it('should renew token', async() => { const mockDate = new Date(startingTime + 26600000); jasmine.clock().mockDate(mockDate); - console.log(startingTime, mockDate) const {id} = await models.VnUser.renewToken(ctx); expect(id).not.toEqual(ctx.req.accessToken.id); From 0101dcda3ac950c1add6c3c426c4f745389805c1 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 2 Jan 2024 08:12:45 +0100 Subject: [PATCH 439/449] refs #5925 fix: add options --- back/methods/docuware/specs/upload.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/methods/docuware/specs/upload.spec.js b/back/methods/docuware/specs/upload.spec.js index 2577fa42db..866499b665 100644 --- a/back/methods/docuware/specs/upload.spec.js +++ b/back/methods/docuware/specs/upload.spec.js @@ -31,7 +31,7 @@ describe('docuware upload()', () => { try { const options = {transaction: tx}; const user = await models.UserConfig.findById(userId, null, options); - await user.updateAttribute('tabletFk', 'Tablet1'); + await user.updateAttribute('tabletFk', 'Tablet1', options); await models.Docuware.upload(ctx, ticketIds, fileCabinetName, options); await tx.rollback(); From 801037da64bf3c02d8017ba29e2dc7cf698448b6 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 2 Jan 2024 08:47:12 +0100 Subject: [PATCH 440/449] fix changes: refs #6274 --- db/changes/{240201 => 234601}/00-updateCourtesyTime.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{240201 => 234601}/00-updateCourtesyTime.sql (100%) diff --git a/db/changes/240201/00-updateCourtesyTime.sql b/db/changes/234601/00-updateCourtesyTime.sql similarity index 100% rename from db/changes/240201/00-updateCourtesyTime.sql rename to db/changes/234601/00-updateCourtesyTime.sql From 763af7da2d17c14ec49d34f4455b6a2de95f111a Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 2 Jan 2024 08:58:41 +0100 Subject: [PATCH 441/449] fix test: refs #6274 --- .../worker/back/methods/worker-time-control/specs/login.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/methods/worker-time-control/specs/login.spec.js b/modules/worker/back/methods/worker-time-control/specs/login.spec.js index 392d9a66b4..8e992de96d 100644 --- a/modules/worker/back/methods/worker-time-control/specs/login.spec.js +++ b/modules/worker/back/methods/worker-time-control/specs/login.spec.js @@ -3,7 +3,7 @@ const models = require('vn-loopback/server/server').models; describe('workerTimeControl login()', () => { it('should correctly login', async() => { - const response = await models.WorkerTimeControl.login(9, {}); + const response = await models.WorkerTimeControl.login(9); expect(response.name).toBe('developer'); }); From 6b8a4a512bc58067c2efd00b141e8a45a0d99e8c Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 2 Jan 2024 10:42:50 +0100 Subject: [PATCH 442/449] adding filter: refs #6606 --- .../back/methods/invoiceOut/negativeBasesCsv.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/negativeBasesCsv.js b/modules/invoiceOut/back/methods/invoiceOut/negativeBasesCsv.js index d70a8fce52..87e9a67eae 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/negativeBasesCsv.js +++ b/modules/invoiceOut/back/methods/invoiceOut/negativeBasesCsv.js @@ -10,13 +10,17 @@ module.exports = Self => { type: 'date', description: 'From date', required: true - }, - { + }, { arg: 'to', type: 'date', description: 'To date', required: true - }], + }, { + arg: 'filter', + type: 'object', + description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string' + }, + ], returns: [ { arg: 'body', From 1e3a7e5f9113aac0beb95b052c2b8be745934995 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 2 Jan 2024 13:17:10 +0100 Subject: [PATCH 443/449] refs #5914 refactor: invoiceTickets --- ...00-fixInvoiceCorrectionConstraintsName.sql | 7 +++++ .../{235001 => 240001}/00-getTaxBases.sql | 0 .../01-newHasAnyPositiveBase.sql | 2 +- .../01-refactorHasAnyNegativeBase.sql | 2 +- .../back/models/invoice-correction.json | 27 +++++++++++++++++++ .../back/methods/ticket/canBeInvoiced.js | 7 ----- .../back/methods/ticket/invoiceTickets.js | 19 +++++++------ .../ticket/back/methods/ticket/makeInvoice.js | 3 +-- .../ticket/specs/canBeInvoiced.spec.js | 20 +++----------- 9 files changed, 50 insertions(+), 37 deletions(-) create mode 100644 db/changes/240001/00-fixInvoiceCorrectionConstraintsName.sql rename db/changes/{235001 => 240001}/00-getTaxBases.sql (100%) rename db/changes/{235001 => 240001}/01-newHasAnyPositiveBase.sql (91%) rename db/changes/{235001 => 240001}/01-refactorHasAnyNegativeBase.sql (91%) diff --git a/db/changes/240001/00-fixInvoiceCorrectionConstraintsName.sql b/db/changes/240001/00-fixInvoiceCorrectionConstraintsName.sql new file mode 100644 index 0000000000..426afea900 --- /dev/null +++ b/db/changes/240001/00-fixInvoiceCorrectionConstraintsName.sql @@ -0,0 +1,7 @@ +ALTER TABLE `vn`.`invoiceCorrection` DROP FOREIGN KEY `cplusInvoiceTyoeFk`; +ALTER TABLE `vn`.`invoiceCorrection` DROP FOREIGN KEY `invoiceCorrectionType_Fk33`; +ALTER TABLE `vn`.`invoiceCorrection` DROP FOREIGN KEY `invoiceCorrection_ibfk_1`; + +ALTER TABLE `vn`.`invoiceCorrection` ADD CONSTRAINT `siiTypeInvoiceOut_FK` FOREIGN KEY (`siiTypeInvoiceOutFk`) REFERENCES `vn`.`siiTypeInvoiceOut`(id) ON UPDATE CASCADE; +ALTER TABLE `vn`.`invoiceCorrection` ADD CONSTRAINT `invoiceCorrectionType_FK` FOREIGN KEY (`invoiceCorrectionTypeFk`) REFERENCES `vn`.`invoiceCorrectionType`(id) ON UPDATE CASCADE; +ALTER TABLE `vn`.`invoiceCorrection` ADD CONSTRAINT `cplusRectificationType_FK` FOREIGN KEY (`cplusRectificationTypeFk`) REFERENCES `vn`.`cplusRectificationType`(id) ON UPDATE CASCADE; diff --git a/db/changes/235001/00-getTaxBases.sql b/db/changes/240001/00-getTaxBases.sql similarity index 100% rename from db/changes/235001/00-getTaxBases.sql rename to db/changes/240001/00-getTaxBases.sql diff --git a/db/changes/235001/01-newHasAnyPositiveBase.sql b/db/changes/240001/01-newHasAnyPositiveBase.sql similarity index 91% rename from db/changes/235001/01-newHasAnyPositiveBase.sql rename to db/changes/240001/01-newHasAnyPositiveBase.sql index c9e7e8e059..70fd51bccd 100644 --- a/db/changes/235001/01-newHasAnyPositiveBase.sql +++ b/db/changes/240001/01-newHasAnyPositiveBase.sql @@ -14,7 +14,7 @@ BEGIN CALL getTaxBases(); - SELECT positive > 0 INTO hasAnyPositiveBase + SELECT positive INTO hasAnyPositiveBase FROM tmp.taxBases; DROP TEMPORARY TABLE diff --git a/db/changes/235001/01-refactorHasAnyNegativeBase.sql b/db/changes/240001/01-refactorHasAnyNegativeBase.sql similarity index 91% rename from db/changes/235001/01-refactorHasAnyNegativeBase.sql rename to db/changes/240001/01-refactorHasAnyNegativeBase.sql index 65822fc95a..f851ee6b94 100644 --- a/db/changes/235001/01-refactorHasAnyNegativeBase.sql +++ b/db/changes/240001/01-refactorHasAnyNegativeBase.sql @@ -14,7 +14,7 @@ BEGIN CALL getTaxBases(); - SELECT negative > 0 INTO hasAnyNegativeBase + SELECT negative INTO hasAnyNegativeBase FROM tmp.taxBases; DROP TEMPORARY TABLE diff --git a/modules/invoiceOut/back/models/invoice-correction.json b/modules/invoiceOut/back/models/invoice-correction.json index 5924c9232f..58f6f63b72 100644 --- a/modules/invoiceOut/back/models/invoice-correction.json +++ b/modules/invoiceOut/back/models/invoice-correction.json @@ -26,6 +26,33 @@ "invoiceCorrectionTypeFk": { "type": "number", "required": true + }, + "relations": { + "correcting": { + "type": "belongsTo", + "model": "InvoiceOut", + "foreignKey": "correctingFk" + }, + "corrected": { + "type": "belongsTo", + "model": "InvoiceOut", + "foreignKey": "correctedFk" + }, + "cplusRectificationType": { + "type": "belongsTo", + "model": "cplusRectificationType", + "foreignKey": "cplusRectificationTypeFk" + }, + "siiTypeInvoiceOut": { + "type": "belongsTo", + "model": "siiTypeInvoiceOut", + "foreignKey": "siiTypeInvoiceOutFk" + }, + "invoiceCorrectionType": { + "type": "belongsTo", + "model": "invoiceCorrectionType", + "foreignKey": "invoiceCorrectionTypeFk" + } } } } diff --git a/modules/ticket/back/methods/ticket/canBeInvoiced.js b/modules/ticket/back/methods/ticket/canBeInvoiced.js index 75d13a5086..855a864c26 100644 --- a/modules/ticket/back/methods/ticket/canBeInvoiced.js +++ b/modules/ticket/back/methods/ticket/canBeInvoiced.js @@ -17,11 +17,6 @@ module.exports = function(Self) { type: 'boolean' } ], - returns: { - arg: 'data', - type: 'boolean', - root: true - }, http: { path: `/canBeInvoiced`, verb: 'get' @@ -63,7 +58,5 @@ module.exports = function(Self) { if (ticketsIds.length == 1 && priceZero) throw new UserError(`A ticket with an amount of zero can't be invoiced`); }); - - return true; }; }; diff --git a/modules/ticket/back/methods/ticket/invoiceTickets.js b/modules/ticket/back/methods/ticket/invoiceTickets.js index f1793773b2..57f6232892 100644 --- a/modules/ticket/back/methods/ticket/invoiceTickets.js +++ b/modules/ticket/back/methods/ticket/invoiceTickets.js @@ -61,20 +61,19 @@ module.exports = function(Self) { if (!isSameClient) throw new UserError(`You can't invoice tickets from multiple clients`); - const client = await models.Client.findById(clientId, { - fields: ['id', 'hasToInvoiceByAddress'] + const {hasToInvoiceByAddress} = await models.Client.findById(clientId, { + fields: ['hasToInvoiceByAddress'] }, myOptions); - let ticketsByAddress = {[firstTicket.addressFk]: ticketsIds}; - if (client.hasToInvoiceByAddress) { - ticketsByAddress = tickets.reduce((group, ticket) => { - const {addressFk} = ticket; + let ticketsByAddress = hasToInvoiceByAddress + ? Object.values(tickets.reduce((group, {id, addressFk}) => { group[addressFk] = group[addressFk] ?? []; - group[addressFk].push(ticket.id); + group[addressFk].push(id); return group; - }, {}); - } - for (const ticketIds of Object.values(ticketsByAddress)) + }, {})) + : [[ticketsIds]]; + + for (const ticketIds of ticketsByAddress) invoicesIds.push(await createInvoice(ctx, companyId, ticketIds, invoiceCorrection, myOptions)); if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js index 32aa03f9d1..83222a4ee0 100644 --- a/modules/ticket/back/methods/ticket/makeInvoice.js +++ b/modules/ticket/back/methods/ticket/makeInvoice.js @@ -106,8 +106,7 @@ module.exports = function(Self) { ); } - if (resultInvoice.id) - await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions); + await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions); if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js b/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js index e443ed6d39..1509b87df9 100644 --- a/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js +++ b/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js @@ -27,10 +27,7 @@ describe('ticket canBeInvoiced()', () => { WHERE id IN (?) `, [ticketId], options); - const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); - - expect(canBeInvoiced).toEqual(false); - + await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); await tx.rollback(); } catch (e) { error = e; @@ -59,10 +56,7 @@ describe('ticket canBeInvoiced()', () => { WHERE id IN (?) `, [ticketId], options); - const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); - - expect(canBeInvoiced).toEqual(false); - + await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); await tx.rollback(); } catch (e) { error = e; @@ -95,10 +89,7 @@ describe('ticket canBeInvoiced()', () => { WHERE id IN (?) `, [ticketId], options); - const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); - - expect(canBeInvoiced).toEqual(false); - + await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); await tx.rollback(); } catch (e) { error = e; @@ -123,10 +114,7 @@ describe('ticket canBeInvoiced()', () => { WHERE id IN (?) `, [ticketId], options); - const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); - - expect(canBeInvoiced).toEqual(true); - + await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options); await tx.rollback(); } catch (e) { await tx.rollback(); From c116bc56c3e23d52cff1ba6cda4eb396cd0aeaad Mon Sep 17 00:00:00 2001 From: pablone Date: Tue, 2 Jan 2024 19:37:51 +0100 Subject: [PATCH 444/449] refactor(clientSms): refs #6259 redirect to lilium --- modules/client/front/sms/index.html | 42 ++--------------------------- modules/client/front/sms/index.js | 28 ++++--------------- 2 files changed, 7 insertions(+), 63 deletions(-) diff --git a/modules/client/front/sms/index.html b/modules/client/front/sms/index.html index e2bc0785e3..7fb3b870e0 100644 --- a/modules/client/front/sms/index.html +++ b/modules/client/front/sms/index.html @@ -1,40 +1,2 @@ - - - - - - - - Sender - Destination - Message - Status - Created - - - - - - - {{::clientSms.sms.sender.name}} - - - {{::clientSms.sms.destination}} - {{::clientSms.sms.message}} - {{::clientSms.sms.status}} - {{::clientSms.sms.created | date:'dd/MM/yyyy HH:mm'}} - - - - - - - + + diff --git a/modules/client/front/sms/index.js b/modules/client/front/sms/index.js index 6ad64282e7..8fa130248c 100644 --- a/modules/client/front/sms/index.js +++ b/modules/client/front/sms/index.js @@ -1,32 +1,14 @@ import ngModule from '../module'; import Section from 'salix/components/section'; -export default class Controller extends Section { +class Controller extends Section { constructor($element, $) { super($element, $); + } - this.filter = { - fields: ['id', 'smsFk'], - include: { - relation: 'sms', - scope: { - fields: [ - 'senderFk', - 'sender', - 'destination', - 'message', - 'statusCode', - 'status', - 'created'], - include: { - relation: 'sender', - scope: { - fields: ['name'] - } - } - } - } - }; + async $onInit() { + this.$state.go('client.card.summary', {id: this.$params.id}); + window.location.href = await this.vnApp.getUrl(`Customer/${this.$params.id}/sms`); } } From 5dc49d226ad4450b130ff47231702593a69ddc00 Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 3 Jan 2024 10:13:56 +0100 Subject: [PATCH 445/449] refs #6274 fix locale --- loopback/locale/en.json | 3 ++- loopback/locale/es.json | 7 +++--- .../back/methods/worker-time-control/login.js | 7 +++--- .../worker-time-control/specs/login.spec.js | 24 +++++++++++++++---- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index c5e8d4fcf4..508c173444 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -200,5 +200,6 @@ "Try again": "Try again", "keepPrice": "keepPrice", "Cannot past travels with entries": "Cannot past travels with entries", - "It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}" + "It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}", + "Incorrect pin": "Incorrect pin." } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index fc209a9cdd..e2b90983b0 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -330,9 +330,8 @@ "quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima", "Cannot past travels with entries": "No se pueden pasar envíos con entradas", "It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}", - "This user does not have an assigned tablet": "Este usuario no tiene tablet asignada", - "Incorrect pin.": "Pin incorrecto.", + "This user does not have an assigned tablet": "Este usuario no tiene tablet asignada", + "Incorrect pin": "Pin incorrecto.", "You already have the mailAlias": "Ya tienes este alias de correo", "The alias cant be modified": "Este alias de correo no puede ser modificado" -} - +} \ No newline at end of file diff --git a/modules/worker/back/methods/worker-time-control/login.js b/modules/worker/back/methods/worker-time-control/login.js index b2a17b4e4b..9aa4bd1452 100644 --- a/modules/worker/back/methods/worker-time-control/login.js +++ b/modules/worker/back/methods/worker-time-control/login.js @@ -1,7 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethod('login', { + Self.remoteMethodCtx('login', { description: 'Consult the user\'s information and the buttons that must be activated after logging in', accessType: 'READ', accepts: [ @@ -21,14 +21,15 @@ module.exports = Self => { } }); - Self.login = async(pin, options) => { + Self.login = async(ctx, pin, options) => { const myOptions = {}; + const $t = ctx.req.__; if (typeof options == 'object') Object.assign(myOptions, options); const query = `CALL vn.workerTimeControl_login(?)`; const [[user]] = await Self.rawSql(query, [pin], myOptions); - if (!user) throw new UserError('Incorrect pin.'); + if (!user) throw new UserError($t('Incorrect pin')); return user; }; }; diff --git a/modules/worker/back/methods/worker-time-control/specs/login.spec.js b/modules/worker/back/methods/worker-time-control/specs/login.spec.js index 8e992de96d..d9f2dbb393 100644 --- a/modules/worker/back/methods/worker-time-control/specs/login.spec.js +++ b/modules/worker/back/methods/worker-time-control/specs/login.spec.js @@ -1,20 +1,34 @@ -const UserError = require('vn-loopback/util/user-error'); const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); +const UserError = require('vn-loopback/util/user-error'); describe('workerTimeControl login()', () => { + let ctx; + beforeAll(async() => { + ctx = { + accessToken: {userId: 9}, + req: { + headers: {origin: 'http://localhost'}, + __: key => key + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: ctx + }); + }); + it('should correctly login', async() => { - const response = await models.WorkerTimeControl.login(9); + const response = await models.WorkerTimeControl.login(ctx, 9); expect(response.name).toBe('developer'); }); it('should throw UserError if pin is not provided', async() => { try { - await models.WorkerTimeControl.login(); + await models.WorkerTimeControl.login(ctx); } catch (error) { expect(error).toBeInstanceOf(UserError); - expect(error.message).toBe('Incorrect pin.'); + expect(error.message).toBe('Incorrect pin'); } }); }); - From f73a447391b7541f41e3be2ccc05327c1254578e Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 3 Jan 2024 11:57:49 +0100 Subject: [PATCH 446/449] refs #6398 Hotfix 1/2 --- modules/ticket/back/models/ticket-tracking.json | 3 --- modules/ticket/front/tracking/index/index.html | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/modules/ticket/back/models/ticket-tracking.json b/modules/ticket/back/models/ticket-tracking.json index 4b5a4d4732..ac0eb9a699 100644 --- a/modules/ticket/back/models/ticket-tracking.json +++ b/modules/ticket/back/models/ticket-tracking.json @@ -20,9 +20,6 @@ }, "stateFk": { "type": "number" - }, - "userFk": { - "type": "number" } }, "relations": { diff --git a/modules/ticket/front/tracking/index/index.html b/modules/ticket/front/tracking/index/index.html index 12c4778c99..10ee6d8488 100644 --- a/modules/ticket/front/tracking/index/index.html +++ b/modules/ticket/front/tracking/index/index.html @@ -23,9 +23,9 @@ {{::tracking.state.name}} - {{::tracking.worker.user.name || 'System' | translate}} + ng-class="{'link': tracking.user.id}" + ng-click="workerDescriptor.show($event, tracking.user.id)"> + {{::tracking.user.name || 'System' | translate}} {{::tracking.created | date:'dd/MM/yyyy HH:mm'}} From ba26237998a1bf2143c0b095963cd48aa1bffb28 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 3 Jan 2024 12:19:28 +0100 Subject: [PATCH 447/449] refs #5914 refactor: getTaxBases --- db/changes/240001/00-getTaxBases.sql | 10 ++++---- .../240001/01-newHasAnyPositiveBase.sql | 6 +++-- .../240001/01-refactorHasAnyNegativeBase.sql | 7 ++++-- .../front/descriptor-menu/locale/es.yml | 1 + .../back/methods/ticket/invoiceTickets.js | 2 +- .../ticket/specs/canBeInvoiced.spec.js | 25 +++++++++++++++++++ 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/db/changes/240001/00-getTaxBases.sql b/db/changes/240001/00-getTaxBases.sql index fa43c32f78..8bd1b745ac 100644 --- a/db/changes/240001/00-getTaxBases.sql +++ b/db/changes/240001/00-getTaxBases.sql @@ -2,8 +2,8 @@ DELIMITER $$ $$ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`getTaxBases`() BEGIN - -/* Calcula y devuelve en número de bases imponibles postivas y negativas +/** +* Calcula y devuelve en número de bases imponibles postivas y negativas * Requiere la tabla temporal tmp.ticketToInvoice(id) * * returns tmp.taxBases @@ -21,10 +21,10 @@ BEGIN CREATE TEMPORARY TABLE tmp.taxBases ENGINE = MEMORY SELECT - SUM(CASE WHEN taxableBase > 0 THEN 1 ELSE 0 END) as positive, - SUM(CASE WHEN taxableBase < 0 THEN 1 ELSE 0 END) as negative + SUM(taxableBase > 0) as positive, + SUM(taxableBase < 0) as negative FROM( - SELECT SUM(taxableBase) as taxableBase + SELECT SUM(taxableBase) taxableBase FROM tmp.ticketTax GROUP BY pgcFk ) t; diff --git a/db/changes/240001/01-newHasAnyPositiveBase.sql b/db/changes/240001/01-newHasAnyPositiveBase.sql index 70fd51bccd..c4edfaed0e 100644 --- a/db/changes/240001/01-newHasAnyPositiveBase.sql +++ b/db/changes/240001/01-newHasAnyPositiveBase.sql @@ -4,7 +4,8 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`hasAnyPositiveBase`( DETERMINISTIC BEGIN -/* Calcula si existe alguna base imponible positiva +/** +* Calcula si existe alguna base imponible positiva * Requiere la tabla temporal tmp.ticketToInvoice(id) para getTaxBases() * * returns BOOLEAN @@ -15,7 +16,8 @@ BEGIN CALL getTaxBases(); SELECT positive INTO hasAnyPositiveBase - FROM tmp.taxBases; + FROM tmp.taxBases + LIMIT 1; DROP TEMPORARY TABLE tmp.ticketTax, diff --git a/db/changes/240001/01-refactorHasAnyNegativeBase.sql b/db/changes/240001/01-refactorHasAnyNegativeBase.sql index f851ee6b94..a3eb2d9c7e 100644 --- a/db/changes/240001/01-refactorHasAnyNegativeBase.sql +++ b/db/changes/240001/01-refactorHasAnyNegativeBase.sql @@ -4,7 +4,8 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`hasAnyNegativeBase`( DETERMINISTIC BEGIN -/* Calcula si existe alguna base imponible negativa +/** +* Calcula si existe alguna base imponible negativa * Requiere la tabla temporal tmp.ticketToInvoice(id) para getTaxBases() * * returns BOOLEAN @@ -15,7 +16,8 @@ BEGIN CALL getTaxBases(); SELECT negative INTO hasAnyNegativeBase - FROM tmp.taxBases; + FROM tmp.taxBases + LIMIT 1; DROP TEMPORARY TABLE tmp.ticketTax, @@ -27,3 +29,4 @@ BEGIN END$$ DELIMITER ; + diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml index 9456646afc..bf89b2ba09 100644 --- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml +++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml @@ -23,3 +23,4 @@ The following refund tickets have been created: "Se han creado los siguientes ti Refund...: Abono... Transfer invoice to...: Transferir factura a... Rectificative type: Tipo rectificativa +Invoice trasfered!: ¡Factura transferida! diff --git a/modules/ticket/back/methods/ticket/invoiceTickets.js b/modules/ticket/back/methods/ticket/invoiceTickets.js index 57f6232892..06429836e0 100644 --- a/modules/ticket/back/methods/ticket/invoiceTickets.js +++ b/modules/ticket/back/methods/ticket/invoiceTickets.js @@ -71,7 +71,7 @@ module.exports = function(Self) { group[addressFk].push(id); return group; }, {})) - : [[ticketsIds]]; + : [ticketsIds]; for (const ticketIds of ticketsByAddress) invoicesIds.push(await createInvoice(ctx, companyId, ticketIds, invoiceCorrection, myOptions)); diff --git a/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js b/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js index 1509b87df9..78973e040e 100644 --- a/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js +++ b/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js @@ -121,4 +121,29 @@ describe('ticket canBeInvoiced()', () => { throw e; } }); + + it('should return falsy for a ticket has positiveBase', async() => { + const tx = await models.Ticket.beginTransaction({}); + + try { + const options = {transaction: tx}; + + await models.Ticket.rawSql(` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketToInvoice + (PRIMARY KEY (id)) + ENGINE = MEMORY + SELECT id + FROM vn.ticket + WHERE id IN (?) + `, [ticketId], options); + + await models.Ticket.canBeInvoiced(ctx, [ticketId], true, options); + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toEqual(`hasAnyPositiveBase`); + }); }); From 227afbe39dfa3255f177a6d6736e1a4267bbe249 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 3 Jan 2024 14:54:01 +0100 Subject: [PATCH 448/449] refs #5914 fix(invoiceOut_descriptorMenu): transalation --- modules/invoiceOut/front/descriptor-menu/index.js | 2 +- modules/invoiceOut/front/descriptor-menu/locale/es.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index aee323e399..2c28599e7c 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -137,7 +137,7 @@ class Controller extends Section { }; this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => { const invoiceId = res.data; - this.vnApp.showSuccess(this.$t('Invoice trasfered!')); + this.vnApp.showSuccess(this.$t('Transferred invoice')); this.$state.go('invoiceOut.card.summary', {id: invoiceId}); }); } diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml index bf89b2ba09..aaeefd9cc4 100644 --- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml +++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml @@ -23,4 +23,4 @@ The following refund tickets have been created: "Se han creado los siguientes ti Refund...: Abono... Transfer invoice to...: Transferir factura a... Rectificative type: Tipo rectificativa -Invoice trasfered!: ¡Factura transferida! +Transferred invoice: Factura transferida From 2a65ad6b31d3055e6d13e345c5e86811ddf32ab9 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 4 Jan 2024 08:22:01 +0100 Subject: [PATCH 449/449] refs #6635 build: new version --- CHANGELOG.md | 7 +++++++ db/changes/240401/.gitkeep | 0 package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 db/changes/240401/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index 1907f46bd2..69e93a309b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ 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). +## [2404.01] - 2024-01-25 + +### Added +### Changed +### Fixed + + ## [2402.01] - 2024-01-11 ### Added diff --git a/db/changes/240401/.gitkeep b/db/changes/240401/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package-lock.json b/package-lock.json index 012fb50e75..36e11dc8fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "salix-back", - "version": "24.02.01", + "version": "24.04.01", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "salix-back", - "version": "24.02.01", + "version": "24.04.01", "license": "GPL-3.0", "dependencies": { "axios": "^1.2.2", diff --git a/package.json b/package.json index ab3d99e19f..f13c441628 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "24.02.01", + "version": "24.04.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0",
{{$t('clientId')}} {{client.id}}
{{$t('invoice')}}