From 3a2fc984dd6f6ab905b4344196461ba5191ceb45 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 26 Oct 2022 15:18:14 +0200 Subject: [PATCH 01/88] refs #4564 --- print/core/report.js | 54 ++++++++++--------- .../claim-pickup-order/claim-pickup-order.js | 2 + 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/print/core/report.js b/print/core/report.js index c5182d1a8..d37b79c6d 100644 --- a/print/core/report.js +++ b/print/core/report.js @@ -23,39 +23,43 @@ class Report extends Component { } async toPdfStream() { - const template = await this.render(); - const defaultOptions = Object.assign({}, config.pdf); + try { + const template = await this.render(); + const defaultOptions = Object.assign({}, config.pdf); - const optionsPath = `${this.path}/options.json`; - const fullPath = path.resolve(__dirname, optionsPath); - let options = defaultOptions; - if (fs.existsSync(fullPath)) - options = require(optionsPath); + const optionsPath = `${this.path}/options.json`; + const fullPath = path.resolve(__dirname, optionsPath); + let options = defaultOptions; + if (fs.existsSync(fullPath)) + options = require(optionsPath); - return new Promise(resolve => { - Cluster.pool.queue({}, async({page}) => { - await page.emulateMediaType('screen'); - await page.setContent(template); + return new Promise(resolve => { + Cluster.pool.queue({}, async({page}) => { + await page.emulateMediaType('screen'); + await page.setContent(template); - const element = await page.$('#pageFooter'); + const element = await page.$('#pageFooter'); - let footer = '\n'; - if (element) { - footer = await page.evaluate(el => { - const html = el.innerHTML; - el.remove(); - return html; - }, element); - } + let footer = '\n'; + if (element) { + footer = await page.evaluate(el => { + const html = el.innerHTML; + el.remove(); + return html; + }, element); + } - options.headerTemplate = '\n'; - options.footerTemplate = footer; + options.headerTemplate = '\n'; + options.footerTemplate = footer; - const stream = await page.pdf(options); + const stream = await page.pdf(options); - resolve(stream); + resolve(stream); + }); }); - }); + } catch (e) { + console.log('ERROR CATCHED:', e); + } } /** diff --git a/print/templates/reports/claim-pickup-order/claim-pickup-order.js b/print/templates/reports/claim-pickup-order/claim-pickup-order.js index f7d21a2d3..2982379db 100755 --- a/print/templates/reports/claim-pickup-order/claim-pickup-order.js +++ b/print/templates/reports/claim-pickup-order/claim-pickup-order.js @@ -5,6 +5,8 @@ const reportFooter = new Component('report-footer'); module.exports = { name: 'claim-pickup-order', async serverPrefetch() { + // FORCE FAIL FOR TEST + throw new Error('Something went wrong'); this.client = await this.fetchClient(this.id); this.sales = await this.fetchSales(this.id); this.claimConfig = await this.fetchClaimConfig(); From 84a5f3986b5aaa838a6882cfbdd24dff1e0d8561 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 2 Nov 2022 13:24:35 +0100 Subject: [PATCH 02/88] feat(worker): createWorker refs #4658 --- modules/worker/back/methods/worker/new.js | 197 ++++++++++++++++++++++ modules/worker/back/models/worker.js | 1 + 2 files changed, 198 insertions(+) create mode 100644 modules/worker/back/methods/worker/new.js diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js new file mode 100644 index 000000000..481011563 --- /dev/null +++ b/modules/worker/back/methods/worker/new.js @@ -0,0 +1,197 @@ +const md5 = require('md5'); +const {Email} = require('vn-print'); + +module.exports = Self => { + Self.remoteMethodCtx('new', { + description: 'Creates a new ticket and returns the id', + accessType: 'WRITE', + accepts: [ + { + arg: 'fi', + type: 'number', + description: `The fi of worker`, + required: true + }, + { + arg: 'name', + type: 'string', + description: `REPLACE!`, + required: true + }, + { + arg: 'firstName', + type: 'string', + description: `REPLACE!`, + required: true + }, + { + arg: 'lastNames', + type: 'string', + description: `REPLACE!`, + required: true + }, + { + arg: 'password', + type: 'string', + description: `REPLACE!`, + required: true + }, + { + arg: 'email', + type: 'string', + description: `REPLACE!`, + required: true + }, + { + arg: 'role', + type: 'number', + description: `REPLACE!` + }, + { + arg: 'street', + type: 'string', + description: `REPLACE!` + }, + { + arg: 'string', + type: 'number', + description: `REPLACE!` + }, + { + arg: 'provinceFk', + type: 'number', + description: `REPLACE!` + }, + { + arg: 'postalCode', + type: 'number', + description: `REPLACE!` + }, + { + arg: 'phone', + type: 'number', + description: `REPLACE!` + }, + { + arg: 'workerCode', + type: 'string', + description: `REPLACE!` + }, + { + arg: 'bossFk', + type: 'number', + description: `REPLACE!` + }, + { + arg: 'birth', + type: 'date', + description: `REPLACE!` + } + ], + returns: { + type: 'number', + root: true + }, + http: { + path: `/new`, + verb: 'POST' + } + }); + + Self.new = async(ctx, options) => { + const models = Self.app.models; + const myOptions = {}; + const args = ctx.args; + + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + let client; + try { + client = await models.Client.findOne({ + where: {fi: fi}, + }, myOptions); + + if (!client) { + const nickname = args.firstName.concat(' ', args.lastNames); + const user = await models.Account.create({ + name: args.name, + nickname, + password: md5(args.password), + email: args.email, + role: args.role + }, myOptions); + + await models.UserAccount.create({ + id: user.id + }, myOptions); + + await models.Worker.rawSql('CALL vn.clientCreate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + [ + args.firstName, + args.lastNames, + args.fi, + args.address, + args.postalCode, + args.town, + args.province, + args.company, + args.phone, + args.email, + user.id + ] + , myOptions); + + const address = await models.Address.create({ + clientFk: user.id, + address: args.street, + town: args.town, + provinceFk: args.provinceFk, + postalCode: args.postalCode, + mobile: args.phone, + nickname: 'TR ' + nickname, + isDefaultAddress: true + }, myOptions); + + client = await models.Sale.findById(user.id, null, myOptions); + await client.updateAttribute('defaultAddressFk ', address.id); + } + + await models.Worker.rawSql('CALL vn.workerCreate(?, ?, ?, ?, ?, ?, ?)', + [ + args.firstName, + args.lastNames, + args.workerCode, + args.bossFk, + user.id, + args.fi, + args.birth + ] + , myOptions); + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + + // TODO: create this email, use client-welcome as template. And view CALL mail_insert in redmine for the body + // TODO: or use same funcionality back/methods/account/recover-password.js + const email = new Email('worker-welcome', { + recipient: args.email, + lang: ctx.req.getLocale() + }); + + await email.send(); + + // return id, and in front use for redirection + return client.id; + }; +}; diff --git a/modules/worker/back/models/worker.js b/modules/worker/back/models/worker.js index ec6c4af28..e66259cd0 100644 --- a/modules/worker/back/models/worker.js +++ b/modules/worker/back/models/worker.js @@ -13,4 +13,5 @@ module.exports = Self => { require('../methods/worker/contracts')(Self); require('../methods/worker/holidays')(Self); require('../methods/worker/activeContract')(Self); + require('../methods/worker/new')(Self); }; From db3a6df23d3bb04fb398d6d02748323fe1454d14 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 14 Nov 2022 15:19:16 +0100 Subject: [PATCH 03/88] feat(worker): new worker --- .../10503-november/00-aclProfileType.sql | 18 ++ db/dump/fixtures.sql | 8 + modules/worker/back/methods/worker/new.js | 102 ++++++--- modules/worker/back/model-config.json | 18 +- .../worker/back/models/new-worker-config.json | 39 ++++ modules/worker/back/models/profile-type.json | 19 ++ modules/worker/back/models/worker.json | 5 +- modules/worker/front/create/index.html | 208 ++++++++++++++++++ modules/worker/front/create/index.js | 98 +++++++++ modules/worker/front/create/index.spec.js | 122 ++++++++++ modules/worker/front/create/locale/es.yml | 12 + modules/worker/front/index.js | 1 + modules/worker/front/index/index.html | 6 + modules/worker/front/routes.json | 11 +- .../email/worker-welcome/assets/css/import.js | 11 + .../email/worker-welcome/client-welcome.html | 10 + .../email/worker-welcome/client-welcome.js | 23 ++ .../email/worker-welcome/locale/es.yml | 7 + .../email/worker-welcome/sql/client.sql | 11 + 19 files changed, 684 insertions(+), 45 deletions(-) create mode 100644 db/changes/10503-november/00-aclProfileType.sql create mode 100644 modules/worker/back/models/new-worker-config.json create mode 100644 modules/worker/back/models/profile-type.json create mode 100644 modules/worker/front/create/index.html create mode 100644 modules/worker/front/create/index.js create mode 100644 modules/worker/front/create/index.spec.js create mode 100644 modules/worker/front/create/locale/es.yml create mode 100644 print/templates/email/worker-welcome/assets/css/import.js create mode 100644 print/templates/email/worker-welcome/client-welcome.html create mode 100755 print/templates/email/worker-welcome/client-welcome.js create mode 100644 print/templates/email/worker-welcome/locale/es.yml create mode 100644 print/templates/email/worker-welcome/sql/client.sql diff --git a/db/changes/10503-november/00-aclProfileType.sql b/db/changes/10503-november/00-aclProfileType.sql new file mode 100644 index 000000000..638b3d580 --- /dev/null +++ b/db/changes/10503-november/00-aclProfileType.sql @@ -0,0 +1,18 @@ + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('ProfileType', '*', '*', 'ALLOW', 'ROLE', 'employee'); + +CREATE TABLE `vn`.`newWorkerConfig` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `street` VARCHAR(25) NULL, + `provinceFk` smallint(6) unsigned NULL, + `companyFk` smallint(5) unsigned NULL, + `profileTypeFk` INT(11) NULL, + `roleFk` int(10) unsigned NULL, + PRIMARY KEY (`id`), + CONSTRAINT `newWorkerConfig_province_fk` FOREIGN KEY (`provinceFk`) REFERENCES `vn`.`province` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `newWorkerConfig_company_fk` FOREIGN KEY (`companyFk`) REFERENCES `vn`.`company` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `newWorkerConfig_profileType_fk` FOREIGN KEY (`profileTypeFk`) REFERENCES `vn`.`profileType` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `newWorkerConfig_role_fk` FOREIGN KEY (`roleFk`) REFERENCES `account`.`role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 6624e99f4..a6fb9cbbb 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2719,3 +2719,11 @@ UPDATE `account`.`user` INSERT INTO `vn`.`osTicketConfig` (`id`, `host`, `user`, `password`, `oldStatus`, `newStatusId`, `day`, `comment`, `hostDb`, `userDb`, `passwordDb`, `portDb`, `responseType`, `fromEmailId`, `replyTo`) VALUES (0, 'http://localhost:56596/scp', 'ostadmin', 'Admin1', 'open', 3, 60, 'Este CAU se ha cerrado automáticamente. Si el problema persiste responda a este mensaje.', 'localhost', 'osticket', 'osticket', 40003, 'reply', 1, 'all'); + +INSERT INTO `vn`.`profileType` (`id`, `name`) + VALUES + (1, 'working'); + +INSERT INTO `vn`.`newWorkerConfig` (`id`, `street`, `provinceFk`, `companyFk`, `profileTypeFk`, `roleFk`) + VALUES + (1, 'S/ ', 1, 442, 1, 1); diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 481011563..bdab1335a 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -8,7 +8,7 @@ module.exports = Self => { accepts: [ { arg: 'fi', - type: 'number', + type: 'string', description: `The fi of worker`, required: true }, @@ -30,12 +30,6 @@ module.exports = Self => { description: `REPLACE!`, required: true }, - { - arg: 'password', - type: 'string', - description: `REPLACE!`, - required: true - }, { arg: 'email', type: 'string', @@ -43,49 +37,76 @@ module.exports = Self => { required: true }, { - arg: 'role', + arg: 'roleFk', type: 'number', - description: `REPLACE!` + description: `REPLACE!`, + required: true }, { arg: 'street', type: 'string', - description: `REPLACE!` + description: `REPLACE!`, + required: true }, { - arg: 'string', - type: 'number', - description: `REPLACE!` + arg: 'city', + type: 'string', + description: `REPLACE!`, + required: true }, { arg: 'provinceFk', type: 'number', - description: `REPLACE!` + description: `REPLACE!`, + required: true }, { - arg: 'postalCode', + arg: 'iban', + type: 'string', + description: `REPLACE!`, + required: true + }, + { + arg: 'bankEntityFk', type: 'number', - description: `REPLACE!` + description: `REPLACE!`, + required: true + }, + { + arg: 'companyFk', + type: 'number', + description: `REPLACE!`, + required: true + }, + { + arg: 'postcode', + type: 'string', + description: `REPLACE!`, + required: true }, { arg: 'phone', - type: 'number', - description: `REPLACE!` + type: 'string', + description: `REPLACE!`, + required: true }, { - arg: 'workerCode', + arg: 'code', type: 'string', - description: `REPLACE!` + description: `REPLACE!`, + required: true }, { arg: 'bossFk', type: 'number', - description: `REPLACE!` + description: `REPLACE!`, + required: true }, { arg: 'birth', type: 'date', - description: `REPLACE!` + description: `REPLACE!`, + required: true } ], returns: { @@ -104,7 +125,7 @@ module.exports = Self => { const args = ctx.args; let tx; - + console.log(args); if (typeof options == 'object') Object.assign(myOptions, options); @@ -116,15 +137,16 @@ module.exports = Self => { let client; try { client = await models.Client.findOne({ - where: {fi: fi}, + where: {fi: args.fi}, }, myOptions); if (!client) { const nickname = args.firstName.concat(' ', args.lastNames); + const randomPassword = await models.Worker.rawSql('SELECT account.passwordGenerate();'); const user = await models.Account.create({ name: args.name, nickname, - password: md5(args.password), + password: md5(randomPassword), email: args.email, role: args.role }, myOptions); @@ -138,11 +160,11 @@ module.exports = Self => { args.firstName, args.lastNames, args.fi, - args.address, + args.street, args.postalCode, - args.town, - args.province, - args.company, + args.city, + args.provinceFk, + args.companyFk, args.phone, args.email, user.id @@ -151,8 +173,8 @@ module.exports = Self => { const address = await models.Address.create({ clientFk: user.id, - address: args.street, - town: args.town, + street: args.street, + city: args.city, provinceFk: args.provinceFk, postalCode: args.postalCode, mobile: args.phone, @@ -160,17 +182,22 @@ module.exports = Self => { isDefaultAddress: true }, myOptions); - client = await models.Sale.findById(user.id, null, myOptions); - await client.updateAttribute('defaultAddressFk ', address.id); - } + client = await models.Client.findById(user.id, null, myOptions); + console.log(address.id); + await client.updateAttributes({ + iban: args.iban, + bankEntityFk: args.bankEntityFk, + defaultAddressFk: address.id + }, myOptions); + } await models.Worker.rawSql('CALL vn.workerCreate(?, ?, ?, ?, ?, ?, ?)', [ args.firstName, args.lastNames, - args.workerCode, + args.code, args.bossFk, - user.id, + client.id, args.fi, args.birth ] @@ -184,6 +211,9 @@ module.exports = Self => { // TODO: create this email, use client-welcome as template. And view CALL mail_insert in redmine for the body // TODO: or use same funcionality back/methods/account/recover-password.js + + // TODO: call worerWelcomeEmail, and this is who create the url for change password + const email = new Email('worker-welcome', { recipient: args.email, lang: ctx.req.getLocale() diff --git a/modules/worker/back/model-config.json b/modules/worker/back/model-config.json index 3f3416504..de8aadd41 100644 --- a/modules/worker/back/model-config.json +++ b/modules/worker/back/model-config.json @@ -1,7 +1,7 @@ { "AbsenceType": { "dataSource": "vn" - }, + }, "Calendar": { "dataSource": "vn" }, @@ -16,13 +16,22 @@ }, "Department": { "dataSource": "vn" - }, + }, + "Device": { + "dataSource": "vn" + }, "EducationLevel": { "dataSource": "vn" }, "Journey": { "dataSource": "vn" }, + "NewWorkerConfig":{ + "dataSource": "vn" + }, + "ProfileType":{ + "dataSource": "vn" + }, "Time": { "dataSource": "vn" }, @@ -55,11 +64,8 @@ }, "WorkerDepartment": { "dataSource": "vn" - }, - "WorkerTimeControl": { - "dataSource": "vn" }, - "Device": { + "WorkerTimeControl": { "dataSource": "vn" }, "WorkerLog": { diff --git a/modules/worker/back/models/new-worker-config.json b/modules/worker/back/models/new-worker-config.json new file mode 100644 index 000000000..2102d236c --- /dev/null +++ b/modules/worker/back/models/new-worker-config.json @@ -0,0 +1,39 @@ +{ + "name": "NewWorkerConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "newWorkerConfig" + } + }, + "properties": { + "id": { + "type": "number", + "id": true, + "description": "Identifier" + }, + "street": { + "type": "string" + }, + "provinceFk": { + "type": "number" + }, + "companyFk": { + "type": "number" + }, + "profileTypeFk": { + "type": "number" + }, + "roleFk": { + "type": "number" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] +} diff --git a/modules/worker/back/models/profile-type.json b/modules/worker/back/models/profile-type.json new file mode 100644 index 000000000..d1d750de8 --- /dev/null +++ b/modules/worker/back/models/profile-type.json @@ -0,0 +1,19 @@ +{ + "name": "ProfileType", + "base": "VnModel", + "options": { + "mysql": { + "table": "profileType" + } + }, + "properties": { + "id": { + "type": "number", + "id": true, + "description": "Identifier" + }, + "name": { + "type": "string" + } + } +} diff --git a/modules/worker/back/models/worker.json b/modules/worker/back/models/worker.json index 3d41707ce..e3a941dd3 100644 --- a/modules/worker/back/models/worker.json +++ b/modules/worker/back/models/worker.json @@ -52,6 +52,9 @@ }, "mobileExtension": { "type" : "number" + }, + "code": { + "type" : "string" } }, "relations": { @@ -91,4 +94,4 @@ "foreignKey": "sectorFk" } } -} \ No newline at end of file +} diff --git a/modules/worker/front/create/index.html b/modules/worker/front/create/index.html new file mode 100644 index 000000000..58b4da060 --- /dev/null +++ b/modules/worker/front/create/index.html @@ -0,0 +1,208 @@ + + +
+ + + + + + + + + + + + + + + + + + + + {{name}} ({{country.country}}) + + + + {{name}}, {{province.name}} + ({{province.country.country}}) + + + + + + + {{code}} - {{town.name}} ({{town.province.name}}, + {{town.province.country.country}}) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{bic}} {{name}} + + + + + + + + + + + + + +
+ + + diff --git a/modules/worker/front/create/index.js b/modules/worker/front/create/index.js new file mode 100644 index 000000000..a068b2006 --- /dev/null +++ b/modules/worker/front/create/index.js @@ -0,0 +1,98 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +export default class Controller extends Section { + constructor($element, $) { + super($element, $); + this.$http.get('NewWorkerConfigs/findOne').then(res => { + return this.worker = Object.assign({}, res.data); + }); + } + + onSubmit() { + return this.$.watcher.submit().then(json => { + this.$state.go('client.card.basicData', {id: json.data.id}); + this.$http.get(`Clients/${this.client.id}/checkDuplicatedData`); + }); + } + + autofillBic() { + if (!this.worker || !this.worker.iban) return; + + let bankEntityId = parseInt(this.worker.iban.substr(4, 4)); + let filter = {where: {id: bankEntityId}}; + + if (this.ibanCountry != 'ES') return; + + this.$http.get(`BankEntities`, {filter}).then(response => { + const hasData = response.data && response.data[0]; + + if (hasData) + this.worker.bankEntityFk = response.data[0].id; + else if (!hasData) + this.worker.bankEntityFk = null; + }); + } + + get province() { + return this._province; + } + + // Province auto complete + set province(selection) { + this._province = selection; + } + + get town() { + return this._town; + } + + // Town auto complete + set town(selection) { + this._town = selection; + + if (!selection) return; + + const province = selection.province; + const postcodes = selection.postcodes; + + if (!this.client.provinceFk) + this.client.provinceFk = province.id; + + if (postcodes.length === 1) + this.client.postcode = postcodes[0].code; + } + + get postcode() { + return this._postcode; + } + + // Postcode auto complete + set postcode(selection) { + this._postcode = selection; + + if (!selection) return; + + const town = selection.town; + const province = town.province; + + if (!this.client.city) + this.client.city = town.name; + + if (!this.client.provinceFk) + this.client.provinceFk = province.id; + } + + onResponse(response) { + this.client.postcode = response.code; + this.client.city = response.city; + this.client.provinceFk = response.provinceFk; + } +} + +Controller.$inject = ['$element', '$scope']; + +ngModule.vnComponent('vnWorkerCreate', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/worker/front/create/index.spec.js b/modules/worker/front/create/index.spec.js new file mode 100644 index 000000000..24fc80d21 --- /dev/null +++ b/modules/worker/front/create/index.spec.js @@ -0,0 +1,122 @@ +import './index'; + +describe('Client', () => { + describe('Component vnClientCreate', () => { + let $scope; + let $state; + let controller; + + beforeEach(ngModule('client')); + + beforeEach(inject(($componentController, $rootScope, _$state_) => { + $scope = $rootScope.$new(); + $state = _$state_; + $scope.watcher = { + submit: () => { + return { + then: callback => { + callback({data: {id: '1234'}}); + } + }; + } + }; + const $element = angular.element(''); + controller = $componentController('vnClientCreate', {$element, $scope}); + })); + + it('should define and set scope, state and client properties', () => { + expect(controller.$).toBe($scope); + expect(controller.$state).toBe($state); + expect(controller.client.active).toBe(true); + }); + + describe('onSubmit()', () => { + it(`should call submit() on the watcher then expect a callback`, () => { + jest.spyOn($state, 'go'); + controller.onSubmit(); + + expect(controller.$state.go).toHaveBeenCalledWith('client.card.basicData', {id: '1234'}); + }); + }); + + describe('province() setter', () => { + it(`should set countryFk property`, () => { + controller.client.countryFk = null; + controller.province = { + id: 1, + name: 'New york', + country: { + id: 2, + name: 'USA' + } + }; + + expect(controller.client.countryFk).toEqual(2); + }); + }); + + describe('town() setter', () => { + it(`should set provinceFk property`, () => { + controller.town = { + provinceFk: 1, + code: 46001, + province: { + id: 1, + name: 'New york', + country: { + id: 2, + name: 'USA' + } + }, + postcodes: [] + }; + + expect(controller.client.provinceFk).toEqual(1); + }); + + it(`should set provinceFk property and fill the postalCode if there's just one`, () => { + controller.town = { + provinceFk: 1, + code: 46001, + province: { + id: 1, + name: 'New york', + country: { + id: 2, + name: 'USA' + } + }, + postcodes: [{code: '46001'}] + }; + + expect(controller.client.provinceFk).toEqual(1); + expect(controller.client.postcode).toEqual('46001'); + }); + }); + + describe('postcode() setter', () => { + it(`should set the town, provinceFk and contryFk properties`, () => { + controller.postcode = { + townFk: 1, + code: 46001, + town: { + id: 1, + name: 'New York', + province: { + id: 1, + name: 'New york', + country: { + id: 2, + name: 'USA' + } + } + } + }; + + expect(controller.client.city).toEqual('New York'); + expect(controller.client.provinceFk).toEqual(1); + expect(controller.client.countryFk).toEqual(2); + }); + }); + }); +}); diff --git a/modules/worker/front/create/locale/es.yml b/modules/worker/front/create/locale/es.yml new file mode 100644 index 000000000..afe3feaa6 --- /dev/null +++ b/modules/worker/front/create/locale/es.yml @@ -0,0 +1,12 @@ +Name: Nombre +Tax number: NIF/CIF +Business name: Razón social +Web user: Usuario Web +Email: E-mail +Create and edit: Crear y editar +You can save multiple emails: >- + Puede guardar varios correos electrónicos encadenándolos mediante comas + sin espacios, ejemplo: user@dominio.com, user2@dominio.com siendo el primer + correo electrónico el principal +The type of business must be filled in basic data: El tipo de negocio debe estar rellenado en datos básicos +Access permission: Permiso de acceso diff --git a/modules/worker/front/index.js b/modules/worker/front/index.js index f703e7c21..97126407c 100644 --- a/modules/worker/front/index.js +++ b/modules/worker/front/index.js @@ -4,6 +4,7 @@ import './main'; import './index/'; import './summary'; import './card'; +import './create'; import './descriptor'; import './descriptor-popover'; import './search-panel'; diff --git a/modules/worker/front/index/index.html b/modules/worker/front/index/index.html index 98df416b4..b48a84854 100644 --- a/modules/worker/front/index/index.html +++ b/modules/worker/front/index/index.html @@ -42,6 +42,12 @@ + + + diff --git a/modules/worker/front/routes.json b/modules/worker/front/routes.json index ca33eaa76..dad55512b 100644 --- a/modules/worker/front/routes.json +++ b/modules/worker/front/routes.json @@ -16,7 +16,7 @@ {"state": "worker.card.timeControl", "icon": "access_time"}, {"state": "worker.card.dms.index", "icon": "cloud_upload"}, { - "icon": "icon-wiki", + "icon": "icon-wiki", "external":true, "url": "http://wiki.verdnatura.es", "description": "Wikipedia" @@ -134,6 +134,13 @@ "worker": "$ctrl.worker" }, "acl": ["hr"] + }, + { + "url": "/create", + "state": "worker.create", + "component": "vn-worker-create", + "description": "New worker", + "acl": ["hr"] } ] -} \ No newline at end of file +} diff --git a/print/templates/email/worker-welcome/assets/css/import.js b/print/templates/email/worker-welcome/assets/css/import.js new file mode 100644 index 000000000..4b4bb7086 --- /dev/null +++ b/print/templates/email/worker-welcome/assets/css/import.js @@ -0,0 +1,11 @@ +const Stylesheet = require(`vn-print/core/stylesheet`); + +const path = require('path'); +const vnPrintPath = path.resolve('print'); + +module.exports = new Stylesheet([ + `${vnPrintPath}/common/css/spacing.css`, + `${vnPrintPath}/common/css/misc.css`, + `${vnPrintPath}/common/css/layout.css`, + `${vnPrintPath}/common/css/email.css`]) + .mergeStyles(); diff --git a/print/templates/email/worker-welcome/client-welcome.html b/print/templates/email/worker-welcome/client-welcome.html new file mode 100644 index 000000000..6aaee6120 --- /dev/null +++ b/print/templates/email/worker-welcome/client-welcome.html @@ -0,0 +1,10 @@ + +
+
+

{{ $t('title', [id]) }}

+

{{ $t('description.dearWorker') }},

+

+

{{ $t('workerData', this.user.name, this.url) }}

+
+
+
diff --git a/print/templates/email/worker-welcome/client-welcome.js b/print/templates/email/worker-welcome/client-welcome.js new file mode 100755 index 000000000..9fbcf86a6 --- /dev/null +++ b/print/templates/email/worker-welcome/client-welcome.js @@ -0,0 +1,23 @@ +const Component = require(`vn-print/core/component`); +const emailBody = new Component('email-body'); + +module.exports = { + name: 'client-welcome', + async serverPrefetch() { + this.client = await this.fetchClient(this.id); + }, + methods: { + fetchClient(id) { + return this.findOneFromDef('client', [id]); + }, + }, + components: { + 'email-body': emailBody.build(), + }, + props: { + id: { + type: Number, + required: true + } + } +}; diff --git a/print/templates/email/worker-welcome/locale/es.yml b/print/templates/email/worker-welcome/locale/es.yml new file mode 100644 index 000000000..769df453e --- /dev/null +++ b/print/templates/email/worker-welcome/locale/es.yml @@ -0,0 +1,7 @@ +subject: Bienvenido a Verdnatura +title: "¡Te damos la bienvenida!" +dearWorker: Estimado trabajador +workerData: 'Bienvenido a Verdnatura SL, este es tu usuario: {0}. Pero primero debes + cambiar tu contraseña. + ' diff --git a/print/templates/email/worker-welcome/sql/client.sql b/print/templates/email/worker-welcome/sql/client.sql new file mode 100644 index 000000000..49e1d4bf6 --- /dev/null +++ b/print/templates/email/worker-welcome/sql/client.sql @@ -0,0 +1,11 @@ +SELECT + c.id, + u.name AS userName, + CONCAT(w.lastName, ' ', w.firstName) salesPersonName, + w.phone AS salesPersonPhone, + CONCAT(wu.name, '@verdnatura.es') AS salesPersonEmail +FROM client c + JOIN account.user u ON u.id = c.id + LEFT JOIN worker w ON w.id = c.salesPersonFk + LEFT JOIN account.user wu ON wu.id = w.userFk +WHERE c.id = ? \ No newline at end of file From 6113ea398d3465424f066d0633741f7576bf1b39 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 14 Nov 2022 15:19:38 +0100 Subject: [PATCH 04/88] feat: worker-welcome --- .../worker-welcome/{client-welcome.html => worker-welcome.html} | 0 .../email/worker-welcome/{client-welcome.js => worker-welcome.js} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename print/templates/email/worker-welcome/{client-welcome.html => worker-welcome.html} (100%) rename print/templates/email/worker-welcome/{client-welcome.js => worker-welcome.js} (100%) diff --git a/print/templates/email/worker-welcome/client-welcome.html b/print/templates/email/worker-welcome/worker-welcome.html similarity index 100% rename from print/templates/email/worker-welcome/client-welcome.html rename to print/templates/email/worker-welcome/worker-welcome.html diff --git a/print/templates/email/worker-welcome/client-welcome.js b/print/templates/email/worker-welcome/worker-welcome.js similarity index 100% rename from print/templates/email/worker-welcome/client-welcome.js rename to print/templates/email/worker-welcome/worker-welcome.js From 7a7da9508f7dbdfc0fbee318d29fe2c3a8c65afb Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 15 Nov 2022 12:56:30 +0100 Subject: [PATCH 05/88] feat: workerWelcomeEmail --- modules/worker/back/methods/worker/new.js | 156 +++++++++--------- .../back/methods/worker/workerWelcomeEmail.js | 78 +++++++++ .../email/worker-welcome/worker-welcome.html | 1 - 3 files changed, 159 insertions(+), 76 deletions(-) create mode 100644 modules/worker/back/methods/worker/workerWelcomeEmail.js diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index bdab1335a..a57ca8c21 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -1,5 +1,4 @@ const md5 = require('md5'); -const {Email} = require('vn-print'); module.exports = Self => { Self.remoteMethodCtx('new', { @@ -10,113 +9,113 @@ module.exports = Self => { arg: 'fi', type: 'string', description: `The fi of worker`, - required: true + required: true, }, { arg: 'name', type: 'string', description: `REPLACE!`, - required: true + required: true, }, { arg: 'firstName', type: 'string', description: `REPLACE!`, - required: true + required: true, }, { arg: 'lastNames', type: 'string', description: `REPLACE!`, - required: true + required: true, }, { arg: 'email', type: 'string', description: `REPLACE!`, - required: true + required: true, }, { arg: 'roleFk', type: 'number', description: `REPLACE!`, - required: true + required: true, }, { arg: 'street', type: 'string', description: `REPLACE!`, - required: true + required: true, }, { arg: 'city', type: 'string', description: `REPLACE!`, - required: true + required: true, }, { arg: 'provinceFk', type: 'number', description: `REPLACE!`, - required: true + required: true, }, { arg: 'iban', type: 'string', description: `REPLACE!`, - required: true + required: true, }, { arg: 'bankEntityFk', type: 'number', description: `REPLACE!`, - required: true + required: true, }, { arg: 'companyFk', type: 'number', description: `REPLACE!`, - required: true + required: true, }, { arg: 'postcode', type: 'string', description: `REPLACE!`, - required: true + required: true, }, { arg: 'phone', type: 'string', description: `REPLACE!`, - required: true + required: true, }, { arg: 'code', type: 'string', description: `REPLACE!`, - required: true + required: true, }, { arg: 'bossFk', type: 'number', description: `REPLACE!`, - required: true + required: true, }, { arg: 'birth', type: 'date', description: `REPLACE!`, - required: true - } + required: true, + }, ], returns: { type: 'number', - root: true + root: true, }, http: { path: `/new`, - verb: 'POST' - } + verb: 'POST', + }, }); Self.new = async(ctx, options) => { @@ -126,8 +125,7 @@ module.exports = Self => { let tx; console.log(args); - if (typeof options == 'object') - Object.assign(myOptions, options); + if (typeof options == 'object') Object.assign(myOptions, options); if (!myOptions.transaction) { tx = await Self.beginTransaction({}); @@ -136,26 +134,38 @@ module.exports = Self => { let client; try { - client = await models.Client.findOne({ - where: {fi: args.fi}, - }, myOptions); + client = await models.Client.findOne( + { + where: {fi: args.fi}, + }, + myOptions + ); if (!client) { const nickname = args.firstName.concat(' ', args.lastNames); - const randomPassword = await models.Worker.rawSql('SELECT account.passwordGenerate();'); - const user = await models.Account.create({ - name: args.name, - nickname, - password: md5(randomPassword), - email: args.email, - role: args.role - }, myOptions); + const randomPassword = await models.Worker.rawSql( + 'SELECT account.passwordGenerate();' + ); + const user = await models.Account.create( + { + name: args.name, + nickname, + password: md5(randomPassword), + email: args.email, + role: args.role, + }, + myOptions + ); - await models.UserAccount.create({ - id: user.id - }, myOptions); + await models.UserAccount.create( + { + id: user.id, + }, + myOptions + ); - await models.Worker.rawSql('CALL vn.clientCreate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + await models.Worker.rawSql( + 'CALL vn.clientCreate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [ args.firstName, args.lastNames, @@ -167,31 +177,38 @@ module.exports = Self => { args.companyFk, args.phone, args.email, - user.id - ] - , myOptions); + user.id, + ], + myOptions + ); - const address = await models.Address.create({ - clientFk: user.id, - street: args.street, - city: args.city, - provinceFk: args.provinceFk, - postalCode: args.postalCode, - mobile: args.phone, - nickname: 'TR ' + nickname, - isDefaultAddress: true - }, myOptions); + const address = await models.Address.create( + { + clientFk: user.id, + street: args.street, + city: args.city, + provinceFk: args.provinceFk, + postalCode: args.postalCode, + mobile: args.phone, + nickname: 'TR ' + nickname, + isDefaultAddress: true, + }, + myOptions + ); client = await models.Client.findById(user.id, null, myOptions); - console.log(address.id); - await client.updateAttributes({ - iban: args.iban, - bankEntityFk: args.bankEntityFk, - defaultAddressFk: address.id - }, myOptions); + await client.updateAttributes( + { + iban: args.iban, + bankEntityFk: args.bankEntityFk, + defaultAddressFk: address.id, + }, + myOptions + ); } - await models.Worker.rawSql('CALL vn.workerCreate(?, ?, ?, ?, ?, ?, ?)', + await models.Worker.rawSql( + 'CALL vn.workerCreate(?, ?, ?, ?, ?, ?, ?)', [ args.firstName, args.lastNames, @@ -199,9 +216,10 @@ module.exports = Self => { args.bossFk, client.id, args.fi, - args.birth - ] - , myOptions); + args.birth, + ], + myOptions + ); if (tx) await tx.commit(); } catch (e) { @@ -209,19 +227,7 @@ module.exports = Self => { throw e; } - // TODO: create this email, use client-welcome as template. And view CALL mail_insert in redmine for the body - // TODO: or use same funcionality back/methods/account/recover-password.js - - // TODO: call worerWelcomeEmail, and this is who create the url for change password - - const email = new Email('worker-welcome', { - recipient: args.email, - lang: ctx.req.getLocale() - }); - - await email.send(); - - // return id, and in front use for redirection + await models.Worker.workerWelcomeEmail(client.id); return client.id; }; }; diff --git a/modules/worker/back/methods/worker/workerWelcomeEmail.js b/modules/worker/back/methods/worker/workerWelcomeEmail.js new file mode 100644 index 000000000..7462df34d --- /dev/null +++ b/modules/worker/back/methods/worker/workerWelcomeEmail.js @@ -0,0 +1,78 @@ +const {Email} = require('vn-print'); + +module.exports = Self => { + Self.remoteMethodCtx('workerWelcomeEmail', { + description: + 'Sends the welcome email to the new worker', + accessType: 'WRITE', + accepts: [ + { + arg: 'id', + type: 'number', + required: true, + description: 'The worker id', + http: {source: 'path'}, + } + ], + returns: { + type: ['object'], + root: true, + }, + http: { + path: '/:id/worker-welcome-email', + verb: 'POST', + }, + }); + + Self.workerWelcomeEmail = 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 args = Object.assign({}, ctx.args); + const params = { + recipient: args.recipient, + lang: ctx.req.getLocale(), + }; + + delete args.ctx; + for (const param in args) params[param] = args[param]; + + const claim = await models.Claim.findById(args.id, { + fields: ['id', 'clientFk'], + include: { + relation: 'client', + scope: { + fields: ['name', 'salesPersonFk'], + }, + }, + }); + + const message = $t('Claim pickup order sent', { + claimId: args.id, + clientName: claim.client().name, + claimUrl: `${origin}/#!/claim/${args.id}/summary`, + }); + + const salesPersonId = claim.client().salesPersonFk; + if (salesPersonId) + await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); + + await models.ClaimLog.create({ + originFk: args.id, + userFk: userId, + action: 'insert', + description: 'Claim-pickup-order sent', + changedModel: 'Mail', + }); + + const email = new Email('worker-welcome', { + recipient: args.email, + lang: ctx.req.getLocale(), + }); + + await email.send(); + // TODO: or use same funcionality back/methods/account/recover-password.js + }; +}; diff --git a/print/templates/email/worker-welcome/worker-welcome.html b/print/templates/email/worker-welcome/worker-welcome.html index 6aaee6120..f91c9941d 100644 --- a/print/templates/email/worker-welcome/worker-welcome.html +++ b/print/templates/email/worker-welcome/worker-welcome.html @@ -3,7 +3,6 @@

{{ $t('title', [id]) }}

{{ $t('description.dearWorker') }},

-

{{ $t('workerData', this.user.name, this.url) }}

From 7c75eaadce02044fe970a7565fbc7ced641abdbd Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 21 Nov 2022 15:15:25 +0100 Subject: [PATCH 06/88] feat: worker-welcome --- print/templates/email/worker-welcome/sql/client.sql | 11 ----------- print/templates/email/worker-welcome/sql/worker.sql | 7 +++++++ .../email/worker-welcome/worker-welcome.html | 2 +- .../templates/email/worker-welcome/worker-welcome.js | 8 ++++---- 4 files changed, 12 insertions(+), 16 deletions(-) delete mode 100644 print/templates/email/worker-welcome/sql/client.sql create mode 100644 print/templates/email/worker-welcome/sql/worker.sql diff --git a/print/templates/email/worker-welcome/sql/client.sql b/print/templates/email/worker-welcome/sql/client.sql deleted file mode 100644 index 49e1d4bf6..000000000 --- a/print/templates/email/worker-welcome/sql/client.sql +++ /dev/null @@ -1,11 +0,0 @@ -SELECT - c.id, - u.name AS userName, - CONCAT(w.lastName, ' ', w.firstName) salesPersonName, - w.phone AS salesPersonPhone, - CONCAT(wu.name, '@verdnatura.es') AS salesPersonEmail -FROM client c - JOIN account.user u ON u.id = c.id - LEFT JOIN worker w ON w.id = c.salesPersonFk - LEFT JOIN account.user wu ON wu.id = w.userFk -WHERE c.id = ? \ No newline at end of file diff --git a/print/templates/email/worker-welcome/sql/worker.sql b/print/templates/email/worker-welcome/sql/worker.sql new file mode 100644 index 000000000..99377fec9 --- /dev/null +++ b/print/templates/email/worker-welcome/sql/worker.sql @@ -0,0 +1,7 @@ +SELECT + u.id, + u.name AS userName, + e.email +FROM account.user u + LEFT JOIN account.emailUser e ON e.userFk = u.id +WHERE u.id = ?; diff --git a/print/templates/email/worker-welcome/worker-welcome.html b/print/templates/email/worker-welcome/worker-welcome.html index f91c9941d..28e5689f1 100644 --- a/print/templates/email/worker-welcome/worker-welcome.html +++ b/print/templates/email/worker-welcome/worker-welcome.html @@ -3,7 +3,7 @@

{{ $t('title', [id]) }}

{{ $t('description.dearWorker') }},

-

{{ $t('workerData', this.user.name, this.url) }}

+

{{ $t('workerData', this.worker.name, this.url) }}

diff --git a/print/templates/email/worker-welcome/worker-welcome.js b/print/templates/email/worker-welcome/worker-welcome.js index 9fbcf86a6..b9bf2ca28 100755 --- a/print/templates/email/worker-welcome/worker-welcome.js +++ b/print/templates/email/worker-welcome/worker-welcome.js @@ -2,13 +2,13 @@ const Component = require(`vn-print/core/component`); const emailBody = new Component('email-body'); module.exports = { - name: 'client-welcome', + name: 'worker-welcome', async serverPrefetch() { - this.client = await this.fetchClient(this.id); + this.worker = await this.fetchWorker(this.id); }, methods: { - fetchClient(id) { - return this.findOneFromDef('client', [id]); + fetchWorker(id) { + return this.findOneFromDef('worker', [id]); }, }, components: { From f70a9cb78588a139ff37ce115d6b3c7bbdc9857d Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 23 Nov 2022 14:46:25 +0100 Subject: [PATCH 07/88] feat(worker_new): use resetPassword funcionality --- modules/worker/back/methods/worker/new.js | 7 +- .../back/methods/worker/workerWelcomeEmail.js | 78 ------------------- 2 files changed, 6 insertions(+), 79 deletions(-) delete mode 100644 modules/worker/back/methods/worker/workerWelcomeEmail.js diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index a57ca8c21..7a61434f0 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -227,7 +227,12 @@ module.exports = Self => { throw e; } - await models.Worker.workerWelcomeEmail(client.id); + await models.user.resetPassword({ + email: args.email, + emailTemplate: 'worker-welcome', + id: client.id + }); + return client.id; }; }; diff --git a/modules/worker/back/methods/worker/workerWelcomeEmail.js b/modules/worker/back/methods/worker/workerWelcomeEmail.js deleted file mode 100644 index 7462df34d..000000000 --- a/modules/worker/back/methods/worker/workerWelcomeEmail.js +++ /dev/null @@ -1,78 +0,0 @@ -const {Email} = require('vn-print'); - -module.exports = Self => { - Self.remoteMethodCtx('workerWelcomeEmail', { - description: - 'Sends the welcome email to the new worker', - accessType: 'WRITE', - accepts: [ - { - arg: 'id', - type: 'number', - required: true, - description: 'The worker id', - http: {source: 'path'}, - } - ], - returns: { - type: ['object'], - root: true, - }, - http: { - path: '/:id/worker-welcome-email', - verb: 'POST', - }, - }); - - Self.workerWelcomeEmail = 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 args = Object.assign({}, ctx.args); - const params = { - recipient: args.recipient, - lang: ctx.req.getLocale(), - }; - - delete args.ctx; - for (const param in args) params[param] = args[param]; - - const claim = await models.Claim.findById(args.id, { - fields: ['id', 'clientFk'], - include: { - relation: 'client', - scope: { - fields: ['name', 'salesPersonFk'], - }, - }, - }); - - const message = $t('Claim pickup order sent', { - claimId: args.id, - clientName: claim.client().name, - claimUrl: `${origin}/#!/claim/${args.id}/summary`, - }); - - const salesPersonId = claim.client().salesPersonFk; - if (salesPersonId) - await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); - - await models.ClaimLog.create({ - originFk: args.id, - userFk: userId, - action: 'insert', - description: 'Claim-pickup-order sent', - changedModel: 'Mail', - }); - - const email = new Email('worker-welcome', { - recipient: args.email, - lang: ctx.req.getLocale(), - }); - - await email.send(); - // TODO: or use same funcionality back/methods/account/recover-password.js - }; -}; From 42adba35387ea784fb115c984198d908ec25181f Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 23 Nov 2022 15:11:46 +0100 Subject: [PATCH 08/88] mail content --- print/templates/email/worker-welcome/locale/es.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/print/templates/email/worker-welcome/locale/es.yml b/print/templates/email/worker-welcome/locale/es.yml index 769df453e..d95f37bd6 100644 --- a/print/templates/email/worker-welcome/locale/es.yml +++ b/print/templates/email/worker-welcome/locale/es.yml @@ -1,7 +1,8 @@ subject: Bienvenido a Verdnatura title: "¡Te damos la bienvenida!" dearWorker: Estimado trabajador -workerData: 'Bienvenido a Verdnatura SL, este es tu usuario: {0}. Pero primero debes - cambiar tu contraseña. - ' +workerData: 'Estos son los datos de tu usuario de Verdnatura. + Usuario: {0}. Haz click aquí para + establecer tu contraseña. + .' From 7822a6cac81b25cd2559cf4e95f01d9f3c8d144e Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 12 Dec 2022 13:48:20 +0100 Subject: [PATCH 09/88] change folder --- db/changes/225001/.gitkeep | 1 - db/changes/{224903 => 225001}/00-aclProfileType.sql | 0 2 files changed, 1 deletion(-) delete mode 100644 db/changes/225001/.gitkeep rename db/changes/{224903 => 225001}/00-aclProfileType.sql (100%) diff --git a/db/changes/225001/.gitkeep b/db/changes/225001/.gitkeep deleted file mode 100644 index 7a4187c02..000000000 --- a/db/changes/225001/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -Delete this file diff --git a/db/changes/224903/00-aclProfileType.sql b/db/changes/225001/00-aclProfileType.sql similarity index 100% rename from db/changes/224903/00-aclProfileType.sql rename to db/changes/225001/00-aclProfileType.sql From bb944f9fee9b0a4928a03068b20e3006a6fd6556 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 12 Dec 2022 15:05:49 +0100 Subject: [PATCH 10/88] feat(newWorker): use worker-welcome --- front/salix/components/app/app.js | 2 +- modules/worker/back/methods/worker/new.js | 5 +++-- modules/worker/front/create/index.js | 3 +-- modules/worker/front/index/locale/es.yml | 1 + print/templates/email/email-verify/email-verify.js | 2 +- print/templates/email/recover-password/recover-password.js | 2 +- print/templates/email/worker-welcome/locale/es.yml | 4 ++-- print/templates/email/worker-welcome/sql/worker.sql | 2 +- print/templates/email/worker-welcome/worker-welcome.html | 4 ++-- print/templates/email/worker-welcome/worker-welcome.js | 5 +++++ 10 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 modules/worker/front/index/locale/es.yml diff --git a/front/salix/components/app/app.js b/front/salix/components/app/app.js index 20f0ad969..91a8d2215 100644 --- a/front/salix/components/app/app.js +++ b/front/salix/components/app/app.js @@ -21,7 +21,7 @@ export default class App extends Component { get showLayout() { const state = this.$state.current.name || this.$location.$$path.substring(1).replace('/', '.'); - const outLayout = ['login', 'recoverPassword', 'resetPassword']; + const outLayout = ['login', 'recoverPassword', 'resetPassword', 'reset-password']; return state && !outLayout.some(ol => ol == state); } diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 7a61434f0..97fdc1033 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -124,7 +124,7 @@ module.exports = Self => { const args = ctx.args; let tx; - console.log(args); + if (typeof options == 'object') Object.assign(myOptions, options); if (!myOptions.transaction) { @@ -224,6 +224,7 @@ module.exports = Self => { if (tx) await tx.commit(); } catch (e) { if (tx) await tx.rollback(); + console.log(e); throw e; } @@ -233,6 +234,6 @@ module.exports = Self => { id: client.id }); - return client.id; + return {id: client.id}; }; }; diff --git a/modules/worker/front/create/index.js b/modules/worker/front/create/index.js index a068b2006..fdc02361d 100644 --- a/modules/worker/front/create/index.js +++ b/modules/worker/front/create/index.js @@ -11,8 +11,7 @@ export default class Controller extends Section { onSubmit() { return this.$.watcher.submit().then(json => { - this.$state.go('client.card.basicData', {id: json.data.id}); - this.$http.get(`Clients/${this.client.id}/checkDuplicatedData`); + this.$state.go('worker.card.basicData', {id: json.data.id}); }); } diff --git a/modules/worker/front/index/locale/es.yml b/modules/worker/front/index/locale/es.yml new file mode 100644 index 000000000..df6383273 --- /dev/null +++ b/modules/worker/front/index/locale/es.yml @@ -0,0 +1 @@ +New worker: Nuevo trabajador diff --git a/print/templates/email/email-verify/email-verify.js b/print/templates/email/email-verify/email-verify.js index 7f0b80a13..4f2b29266 100755 --- a/print/templates/email/email-verify/email-verify.js +++ b/print/templates/email/email-verify/email-verify.js @@ -10,7 +10,7 @@ module.exports = { }, props: { url: { - type: [String], + type: String, required: true } } diff --git a/print/templates/email/recover-password/recover-password.js b/print/templates/email/recover-password/recover-password.js index b589411a9..d8448f370 100755 --- a/print/templates/email/recover-password/recover-password.js +++ b/print/templates/email/recover-password/recover-password.js @@ -10,7 +10,7 @@ module.exports = { }, props: { url: { - type: [String], + type: String, required: true } } diff --git a/print/templates/email/worker-welcome/locale/es.yml b/print/templates/email/worker-welcome/locale/es.yml index d95f37bd6..d53a4e1f0 100644 --- a/print/templates/email/worker-welcome/locale/es.yml +++ b/print/templates/email/worker-welcome/locale/es.yml @@ -3,6 +3,6 @@ title: "¡Te damos la bienvenida!" dearWorker: Estimado trabajador workerData: 'Estos son los datos de tu usuario de Verdnatura. Usuario: {0}. Haz click aquí para - establecer tu contraseña. + establecer tu contraseña .' diff --git a/print/templates/email/worker-welcome/sql/worker.sql b/print/templates/email/worker-welcome/sql/worker.sql index 99377fec9..f75d135d9 100644 --- a/print/templates/email/worker-welcome/sql/worker.sql +++ b/print/templates/email/worker-welcome/sql/worker.sql @@ -1,6 +1,6 @@ SELECT u.id, - u.name AS userName, + u.name, e.email FROM account.user u LEFT JOIN account.emailUser e ON e.userFk = u.id diff --git a/print/templates/email/worker-welcome/worker-welcome.html b/print/templates/email/worker-welcome/worker-welcome.html index 28e5689f1..fbb05d149 100644 --- a/print/templates/email/worker-welcome/worker-welcome.html +++ b/print/templates/email/worker-welcome/worker-welcome.html @@ -2,8 +2,8 @@

{{ $t('title', [id]) }}

-

{{ $t('description.dearWorker') }},

-

{{ $t('workerData', this.worker.name, this.url) }}

+

{{ $t('dearWorker') }},

+

diff --git a/print/templates/email/worker-welcome/worker-welcome.js b/print/templates/email/worker-welcome/worker-welcome.js index b9bf2ca28..3fc9b4706 100755 --- a/print/templates/email/worker-welcome/worker-welcome.js +++ b/print/templates/email/worker-welcome/worker-welcome.js @@ -5,6 +5,7 @@ module.exports = { name: 'worker-welcome', async serverPrefetch() { this.worker = await this.fetchWorker(this.id); + console.log(this.url); }, methods: { fetchWorker(id) { @@ -18,6 +19,10 @@ module.exports = { id: { type: Number, required: true + }, + url: { + type: String, + required: true } } }; From 156f2b9129c02b8ed928f72007b05d977625573a Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 14 Dec 2022 15:03:55 +0100 Subject: [PATCH 11/88] feat: handle errors and autogenerate user and code --- loopback/locale/es.json | 9 ++-- modules/worker/back/methods/worker/new.js | 54 ++++++++++++++--------- modules/worker/front/create/index.html | 9 ++-- modules/worker/front/create/index.js | 14 ++++++ modules/worker/front/create/locale/es.yml | 20 ++++----- 5 files changed, 69 insertions(+), 37 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 932dfe98f..41dfff73a 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -247,7 +247,10 @@ "Empty data source": "Origen de datos vacio", "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" + "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", + "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" } diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 97fdc1033..07a091693 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -1,4 +1,5 @@ const md5 = require('md5'); +const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('new', { @@ -8,103 +9,103 @@ module.exports = Self => { { arg: 'fi', type: 'string', - description: `The fi of worker`, + description: `The worker fi`, required: true, }, { arg: 'name', type: 'string', - description: `REPLACE!`, + description: `The user name`, required: true, }, { arg: 'firstName', type: 'string', - description: `REPLACE!`, + description: `The worker firstname`, required: true, }, { arg: 'lastNames', type: 'string', - description: `REPLACE!`, + description: `The worker lastnames`, required: true, }, { arg: 'email', type: 'string', - description: `REPLACE!`, + description: `The worker email`, required: true, }, { arg: 'roleFk', type: 'number', - description: `REPLACE!`, + description: `The worker role`, required: true, }, { arg: 'street', type: 'string', - description: `REPLACE!`, + description: `The worker address`, required: true, }, { arg: 'city', type: 'string', - description: `REPLACE!`, + description: `The worker city`, required: true, }, { arg: 'provinceFk', type: 'number', - description: `REPLACE!`, + description: `The worker province`, required: true, }, { arg: 'iban', type: 'string', - description: `REPLACE!`, + description: `The worker iban`, required: true, }, { arg: 'bankEntityFk', type: 'number', - description: `REPLACE!`, + description: `The worker bank entity`, required: true, }, { arg: 'companyFk', type: 'number', - description: `REPLACE!`, + description: `The worker company`, required: true, }, { arg: 'postcode', type: 'string', - description: `REPLACE!`, + description: `The worker postcode`, required: true, }, { arg: 'phone', type: 'string', - description: `REPLACE!`, + description: `The worker phone`, required: true, }, { arg: 'code', type: 'string', - description: `REPLACE!`, + description: `The worker code`, required: true, }, { arg: 'bossFk', type: 'number', - description: `REPLACE!`, + description: `The worker boss`, required: true, }, { arg: 'birth', type: 'date', - description: `REPLACE!`, + description: `The worker birth`, required: true, }, ], @@ -152,7 +153,7 @@ module.exports = Self => { nickname, password: md5(randomPassword), email: args.email, - role: args.role, + role: args.roleFk, }, myOptions ); @@ -222,10 +223,21 @@ module.exports = Self => { ); if (tx) await tx.commit(); - } catch (e) { + } catch (err) { if (tx) await tx.rollback(); - console.log(e); - throw e; + const code = err.code; + const message = err.sqlMessage; + + if (code === 'ER_DUP_ENTRY' && message.includes(`for key 'mail'`)) + throw new UserError(`This personal mail already exists`); + + if (code === 'ER_DUP_ENTRY' && message.includes(`CodigoTrabajador_UNIQUE`)) + throw new UserError(`This worker code already exists`); + + if (code === 'ER_DUP_ENTRY' && message.includes(`PRIMARY`)) + throw new UserError(`This worker already exists`); + + throw err; } await models.user.resetPassword({ diff --git a/modules/worker/front/create/index.html b/modules/worker/front/create/index.html index 58b4da060..a86a4e899 100644 --- a/modules/worker/front/create/index.html +++ b/modules/worker/front/create/index.html @@ -13,11 +13,13 @@ label="Firstname" ng-model="$ctrl.worker.firstName" rule + on-change="$ctrl.generateCodeUser()" vn-focus> @@ -38,6 +40,8 @@ vn-one label="Code" ng-model="$ctrl.worker.code" + maxLength="3" + on-change="$ctrl.worker.code = $ctrl.worker.code.toUpperCase()" rule> + rule> - - Puede guardar varios correos electrónicos encadenándolos mediante comas - sin espacios, ejemplo: user@dominio.com, user2@dominio.com siendo el primer - correo electrónico el principal -The type of business must be filled in basic data: El tipo de negocio debe estar rellenado en datos básicos Access permission: Permiso de acceso From 5eda1388efdbe94854308d31a6798982df6a4fc7 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 27 Dec 2022 10:26:56 +0100 Subject: [PATCH 12/88] refs #4927 unique key added --- CHANGELOG.md | 4 ++-- db/changes/230201/.gitkeep | 0 db/changes/230201/00-SupplierUniqueKey.sql | 1 + modules/supplier/back/models/supplier.js | 4 ---- 4 files changed, 3 insertions(+), 6 deletions(-) delete mode 100644 db/changes/230201/.gitkeep create mode 100644 db/changes/230201/00-SupplierUniqueKey.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index 95b3028de..906dd002c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- +- ### Changed -- \ No newline at end of file +- Se permite añadir Proveedores con la misma razón social pero con países distintos diff --git a/db/changes/230201/.gitkeep b/db/changes/230201/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/db/changes/230201/00-SupplierUniqueKey.sql b/db/changes/230201/00-SupplierUniqueKey.sql new file mode 100644 index 000000000..9c0d4a192 --- /dev/null +++ b/db/changes/230201/00-SupplierUniqueKey.sql @@ -0,0 +1 @@ +ALTER TABLE `vn`.`supplier` ADD UNIQUE (name, countryFk); diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index 44549c65c..64c585b6a 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -16,10 +16,6 @@ module.exports = Self => { message: 'The social name cannot be empty' }); - Self.validatesUniquenessOf('name', { - message: 'The supplier name must be unique' - }); - if (this.city) { Self.validatesPresenceOf('city', { message: 'City cannot be empty' From 3792a80ad53259be8c9035eeab044511d0bfd605 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 29 Dec 2022 14:24:32 +0100 Subject: [PATCH 13/88] =?UTF-8?q?refs=20#4925=20feat:=20a=C3=B1adido=20bac?= =?UTF-8?q?k=20para=20editar=20tags?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/changes/230201/00-ACL_tag_update.sql | 3 + .../core/components/crud-model/crud-model.js | 47 +++++----- modules/item/back/methods/tag/onSubmit.js | 94 +++++++++++++++++++ modules/item/back/models/item-tag.js | 4 +- modules/item/back/models/tag.js | 1 + modules/item/front/tags/index.html | 9 +- modules/item/front/tags/index.js | 11 ++- 7 files changed, 137 insertions(+), 32 deletions(-) create mode 100644 db/changes/230201/00-ACL_tag_update.sql create mode 100644 modules/item/back/methods/tag/onSubmit.js diff --git a/db/changes/230201/00-ACL_tag_update.sql b/db/changes/230201/00-ACL_tag_update.sql new file mode 100644 index 000000000..3c103e990 --- /dev/null +++ b/db/changes/230201/00-ACL_tag_update.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Tag', 'onSubmit', 'WRITE', 'ALLOW', 'ROLE', 'employee'); diff --git a/front/core/components/crud-model/crud-model.js b/front/core/components/crud-model/crud-model.js index 16b837d6a..10414daa3 100644 --- a/front/core/components/crud-model/crud-model.js +++ b/front/core/components/crud-model/crud-model.js @@ -147,28 +147,17 @@ export default class CrudModel extends ModelProxy { this.moreRows = null; } - /** - * Saves current changes on the server. - * - * @return {Promise} The save request promise - */ - save() { - if (!this.isChanged) - return this.$q.resolve(); + getChanges() { + if (!this.isChanged) return null; - let deletes = []; - let updates = []; - let creates = []; - let orgDeletes = []; - let orgUpdates = []; - let orgCreates = []; + const deletes = []; + const updates = []; + const creates = []; - let pk = this.primaryKey; + const pk = this.primaryKey; - for (let row of this.removed) { + for (let row of this.removed) deletes.push(row.$orgRow[pk]); - orgDeletes.push(row); - } for (let row of this.data) { if (row.$isNew) { @@ -178,7 +167,6 @@ export default class CrudModel extends ModelProxy { data[prop] = row[prop]; } creates.push(row); - orgCreates.push(row); } else if (row.$oldData) { let data = {}; for (let prop in row.$oldData) @@ -187,7 +175,6 @@ export default class CrudModel extends ModelProxy { data, where: {[pk]: row.$orgRow[pk]} }); - orgUpdates.push(row); } } @@ -198,8 +185,20 @@ export default class CrudModel extends ModelProxy { changes[prop] = undefined; } - if (!changes) - return this.$q.resolve(); + return changes; + } + + /** + * Saves current changes on the server. + * + * @return {Promise} The save request promise + */ + save() { + const pk = this.primaryKey; + const changes = this.getChanges(); + if (!changes) return this.$q.resolve(); + + const creates = changes.creates; let url = this.saveUrl ? this.saveUrl : `${this._url}/crud`; return this.$http.post(url, changes) @@ -207,8 +206,8 @@ export default class CrudModel extends ModelProxy { const created = res.data; // Apply new data to created instances - for (let i = 0; i < orgCreates.length; i++) { - const row = orgCreates[i]; + for (let i = 0; i < creates.length; i++) { + const row = creates[i]; row[pk] = created[i][pk]; for (let prop in row) { diff --git a/modules/item/back/methods/tag/onSubmit.js b/modules/item/back/methods/tag/onSubmit.js new file mode 100644 index 000000000..1bd33d3d4 --- /dev/null +++ b/modules/item/back/methods/tag/onSubmit.js @@ -0,0 +1,94 @@ + +module.exports = function(Self) { + Self.remoteMethodCtx('onSubmit', { + description: 'Creates client address updating default address', + accessType: 'WRITE', + accepts: [ + { + arg: 'creates', + type: ['object'], + description: 'The itemTags records to create' + }, { + arg: 'deletes', + type: ['number'], + description: 'The itemTags ids to delete' + }, { + arg: 'updates', + type: ['object'], + description: 'The itemTags records to update' + }, { + arg: 'maxPriority', + type: 'number', + description: 'The maxPriority value' + } + ], + returns: { + root: true, + type: 'object' + }, + http: { + verb: 'PATCH', + path: '/onSubmit' + } + }); + + Self.onSubmit = async(ctx, options) => { + const models = Self.app.models; + const args = ctx.args; + let tx; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const promises = []; + + if (args.deletes) { + for (const itemTagId of args.deletes) { + const itemTagDeleted = await models.ItemTag.destroyById(itemTagId, myOptions); + promises.push(itemTagDeleted); + } + } + + if (args.updates) { + console.log('args.updates', args.updates); + for (const row of args.updates) { + if (row.data.priority) { + const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); + const itemTagUpdatedPriority = await itemTag.updateAttributes({ + priority: row.data.priority + args.maxPriority + }, myOptions); + promises.push(itemTagUpdatedPriority); + } + } + for (const row of args.updates) { + const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); + const itemTagUpdated = await itemTag.updateAttributes(row.data, myOptions); + promises.push(itemTagUpdated); + } + } + + if (args.creates) { + for (const itemTag of args.creates) { + const newItemTag = await models.ItemTag.create(itemTag, myOptions); + promises.push(newItemTag); + } + } + + const resolvedPromises = await Promise.all(promises); + + if (tx) await tx.commit(); + + return resolvedPromises; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/item/back/models/item-tag.js b/modules/item/back/models/item-tag.js index 5b7163913..4fd44270a 100644 --- a/modules/item/back/models/item-tag.js +++ b/modules/item/back/models/item-tag.js @@ -4,8 +4,8 @@ module.exports = Self => { require('../methods/item-tag/filterItemTags')(Self); Self.rewriteDbError(function(err) { - if (err.code === 'ER_DUP_ENTRY') - return new UserError(`The tag or priority can't be repeated for an item`); + // if (err.code === 'ER_DUP_ENTRY') + // return new UserError(`The tag or priority can't be repeated for an item`); if (err.code === 'ER_BAD_NULL_ERROR') return new UserError(`Tag value cannot be blank`); return err; diff --git a/modules/item/back/models/tag.js b/modules/item/back/models/tag.js index 43fbc0db3..92760e34f 100644 --- a/modules/item/back/models/tag.js +++ b/modules/item/back/models/tag.js @@ -1,3 +1,4 @@ module.exports = Self => { require('../methods/tag/filterValue')(Self); + require('../methods/tag/onSubmit')(Self); }; diff --git a/modules/item/front/tags/index.html b/modules/item/front/tags/index.html index c040b9984..471a53634 100644 --- a/modules/item/front/tags/index.html +++ b/modules/item/front/tags/index.html @@ -19,7 +19,7 @@ data="tags" auto-load="true"> -
+ - - + -
\ No newline at end of file + diff --git a/modules/item/front/tags/index.js b/modules/item/front/tags/index.js index 3b3cd58ef..b5c1fa7f9 100644 --- a/modules/item/front/tags/index.js +++ b/modules/item/front/tags/index.js @@ -29,8 +29,15 @@ class Controller extends Section { } onSubmit() { - this.$.watcher.check(); - this.$.model.save().then(() => { + const changes = this.$.model.getChanges(); + console.log(changes); + const data = { + creates: changes.creates, + deletes: changes.deletes, + updates: changes.updates, + maxPriority: this.getHighestPriority() + }; + this.$http.patch(`Tags/onSubmit`, data).then(() => { this.$.watcher.notifySaved(); this.$.watcher.updateOriginalData(); this.card.reload(); From aa5cfde1ae85e01be945fa6e5d92e44d42c6773f Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 2 Jan 2023 14:52:03 +0100 Subject: [PATCH 14/88] test(worker_new): add back tests --- CHANGELOG.md | 1 + db/dump/fixtures.sql | 14 +- .../components/reset-password/locale/es.yml | 2 +- modules/worker/back/methods/worker/new.js | 27 +++- .../back/methods/worker/specs/new.spec.js | 140 ++++++++++++++++++ modules/worker/front/create/index.js | 20 +++ .../email/worker-welcome/worker-welcome.js | 1 - 7 files changed, 188 insertions(+), 17 deletions(-) create mode 100644 modules/worker/back/methods/worker/specs/new.spec.js diff --git a/CHANGELOG.md b/CHANGELOG.md index bafedc760..897774716 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - [General](Inicio) Permite recuperar la contraseña +- [Trabajadores](Nuevo trabajador) Nueva sección ### Changed diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 03a0f8b50..933651f06 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -934,10 +934,10 @@ INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `freightItemFk`, (7, 2, 4, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), 1, 18, NULL, 94, NULL,NULL), (8, 3, 5, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), 1, 18, NULL, 94, 1, NULL), (9, 3, 6, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 2, NULL), - (10, 7, 7, 71, NOW(), 1, 18, NULL, 94, 3, NULL), - (11, 7, 8, 71, NOW(), 1, 18, NULL, 94, 3, NULL), - (12, 7, 9, 71, NOW(), 1, 18, NULL, 94, 3, NULL), - (13, 1, 10,71, NOW(), 1, 18, NULL, 94, 3, NULL); + (10, 7, 7, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL), + (11, 7, 8, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL), + (12, 7, 9, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL), + (13, 1, 10,71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL); INSERT INTO `vn`.`expeditionState`(`id`, `created`, `expeditionFk`, `typeFk`, `userFk`) @@ -1910,7 +1910,7 @@ DROP TEMPORARY TABLE IF EXISTS tmp.worker; CREATE TEMPORARY TABLE tmp.worker (PRIMARY KEY (id)) ENGINE = MEMORY - SELECT w.id, w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL +1 YEAR)), '-12-25'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk` + SELECT w.id, w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL +1 YEAR)), '-12-25'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk` FROM `vn`.`worker` `w`; INSERT INTO `vn`.`business`(`id`, `workerFk`, `companyCodeFk`, `started`, `ended`, `workerBusiness`, `reasonEndFk`, `notes`, `departmentFk`, `workerBusinessProfessionalCategoryFk`, `calendarTypeFk`, `isHourlyLabor`, `workerBusinessAgreementFk`, `workcenterFk`) @@ -1920,7 +1920,7 @@ DROP TEMPORARY TABLE IF EXISTS tmp.worker; CREATE TEMPORARY TABLE tmp.worker (PRIMARY KEY (id)) ENGINE = MEMORY - SELECT '1111' as 'id', w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -2 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)), '-12-24'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk` + SELECT '1111' as 'id', w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -2 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR)), '-12-24'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk` FROM `vn`.`worker` `w` WHERE `w`.`id` = 1109; @@ -2633,7 +2633,7 @@ INSERT INTO `vn`.`machineWorker` (`workerFk`, `machineFk`, `inTimed`, `outTimed` INSERT INTO `vn`.`zoneExclusion` (`id`, `zoneFk`, `dated`, `created`, `userFk`) VALUES - (1, 1, DATE_ADD(CURDATE(), INTERVAL (IF(DAYOFWEEK(CURDATE())<=7, 7, 14) - DAYOFWEEK(util.VN_CURDATE())) DAY), util.VN_CURDATE(), 100), + (1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL (IF(DAYOFWEEK(util.VN_CURDATE())<=7, 7, 14) - DAYOFWEEK(util.VN_CURDATE())) DAY), util.VN_CURDATE(), 100), (2, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL (IF(DAYOFWEEK(util.VN_CURDATE())<=8, 8, 15) - DAYOFWEEK(util.VN_CURDATE())) DAY), util.VN_CURDATE(), 100); INSERT INTO `vn`.`zoneExclusionGeo` (`zoneExclusionFk`, `geoFk`) diff --git a/front/salix/components/reset-password/locale/es.yml b/front/salix/components/reset-password/locale/es.yml index 0771d5dc3..30893a152 100644 --- a/front/salix/components/reset-password/locale/es.yml +++ b/front/salix/components/reset-password/locale/es.yml @@ -1,6 +1,6 @@ Reset password: Restrablecer contraseña New password: Nueva contraseña -Repeat password: Repetir contraseñaç +Repeat password: Repetir contraseña Password changed!: ¡Contraseña cambiada! Password requirements: > La contraseña debe tener al menos {{ length }} caracteres de longitud, diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index 07a091693..b6da3301a 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -1,4 +1,3 @@ -const md5 = require('md5'); const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { @@ -108,6 +107,12 @@ module.exports = Self => { description: `The worker birth`, required: true, }, + { + arg: 'profileTypeFk', + type: 'number', + description: `The worker profile type ¿DELETE?`, + required: true, + } ], returns: { type: 'number', @@ -134,6 +139,7 @@ module.exports = Self => { } let client; + try { client = await models.Client.findOne( { @@ -144,14 +150,15 @@ module.exports = Self => { if (!client) { const nickname = args.firstName.concat(' ', args.lastNames); - const randomPassword = await models.Worker.rawSql( - 'SELECT account.passwordGenerate();' + const [randomPassword] = await models.Worker.rawSql( + 'SELECT account.passwordGenerate() as password;' ); + const user = await models.Account.create( { name: args.name, nickname, - password: md5(randomPassword), + password: randomPassword.password, email: args.email, role: args.roleFk, }, @@ -208,6 +215,10 @@ module.exports = Self => { myOptions ); } + + const user = await models.Account.findById(client.id, null, myOptions); + await user.updateAttribute('email', args.email, myOptions); + await models.Worker.rawSql( 'CALL vn.workerCreate(?, ?, ?, ?, ?, ?, ?)', [ @@ -223,10 +234,10 @@ module.exports = Self => { ); if (tx) await tx.commit(); - } catch (err) { + } catch (error) { if (tx) await tx.rollback(); - const code = err.code; - const message = err.sqlMessage; + const code = error.code; + const message = error.sqlMessage; if (code === 'ER_DUP_ENTRY' && message.includes(`for key 'mail'`)) throw new UserError(`This personal mail already exists`); @@ -237,7 +248,7 @@ module.exports = Self => { if (code === 'ER_DUP_ENTRY' && message.includes(`PRIMARY`)) throw new UserError(`This worker already exists`); - throw err; + throw error; } await models.user.resetPassword({ diff --git a/modules/worker/back/methods/worker/specs/new.spec.js b/modules/worker/back/methods/worker/specs/new.spec.js new file mode 100644 index 000000000..2cb8bebef --- /dev/null +++ b/modules/worker/back/methods/worker/specs/new.spec.js @@ -0,0 +1,140 @@ +const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); + +describe('Worker new', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + + const employeeId = 1; + const defaultWorker = { + fi: '78457139E', + name: 'defaultWorker', + firstName: 'default', + lastNames: 'worker', + email: 'defaultWorker@mydomain.com', + roleFk: 1, + street: 'S/ defaultWorkerStreet', + city: 'defaultWorkerCity', + provinceFk: 1, + iban: 'ES8304879798578129532677', + bankEntityFk: 128, + companyFk: 442, + postcode: '46680', + phone: '633342693', + code: 'DWW', + bossFk: 9, + birth: '2022-12-11T23:00:00.000Z' + }; + + it('should return error if personal mail already exists', async() => { + const user = await models.Account.findById(employeeId, {fields: ['email']}); + + const tx = await models.Worker.beginTransaction({}); + + let error; + try { + const options = {transaction: tx}; + const ctx = { + args: Object.assign({}, defaultWorker, {email: user.email}) + }; + + await models.Worker.new(ctx, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toEqual('This personal mail already exists'); + }); + + it('should return error if worker code already exists', async() => { + const worker = await models.Worker.findById(employeeId, {fields: ['code']}); + + const tx = await models.Worker.beginTransaction({}); + + let error; + try { + const options = {transaction: tx}; + const ctx = { + args: Object.assign({}, defaultWorker, {code: worker.code}) + }; + + await models.Worker.new(ctx, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toEqual('This worker code already exists'); + }); + + it('should return error if worker already exists', async() => { + const worker = await models.Client.findById(employeeId, {fields: ['fi']}); + + const tx = await models.Worker.beginTransaction({}); + + let error; + try { + const options = {transaction: tx}; + const ctx = { + args: Object.assign({}, defaultWorker, {fi: worker.fi}) + }; + await models.Worker.new(ctx, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toEqual('This worker already exists'); + }); + + it('should create a new worker', async() => { + const newWorker = await models.Worker.new({args: defaultWorker}); + + await models.Worker.destroyById(newWorker.id); + await models.Address.destroyAll({clientFk: newWorker.id}); + await models.Mandate.destroyAll({clientFk: newWorker.id}); + await models.Client.destroyById(newWorker.id); + await models.Account.destroyById(newWorker.id); + + expect(newWorker.id).toBeDefined(); + }); + + it('should create a new worker in client', async() => { + const bruceWayneId = 1101; + const client = await models.Client.findById(bruceWayneId, {fields: ['fi', 'email']}); + + const newWorkerData = { + args: Object.assign( + {}, + defaultWorker, + { + fi: client.fi, + email: client.email + }) + }; + const newWorker = await models.Worker.new(newWorkerData); + + await models.Worker.destroyById(newWorker.id); + + expect(newWorker.id).toEqual(bruceWayneId); + }); +}); diff --git a/modules/worker/front/create/index.js b/modules/worker/front/create/index.js index 3314a4b10..b09fde94f 100644 --- a/modules/worker/front/create/index.js +++ b/modules/worker/front/create/index.js @@ -7,6 +7,26 @@ export default class Controller extends Section { this.$http.get('NewWorkerConfigs/findOne').then(res => { return this.worker = Object.assign({}, res.data); }); + // DELETE + this.worker = { + fi: '73226971P', + name: 'ASDASD', + firstName: 'Test', + lastNames: 'Test', + email: 'developer4@mydomain.com', + roleFk: 1, + street: 'S/ ', + city: 'asd', + provinceFk: 1, + iban: 'ES2420386579855387888566', + bankEntityFk: 128, + companyFk: 442, + postcode: 'asd', + phone: '633342693', + code: 'ASD', + bossFk: 34, + birth: '2022-12-11T23:00:00.000Z' + }; } onSubmit() { diff --git a/print/templates/email/worker-welcome/worker-welcome.js b/print/templates/email/worker-welcome/worker-welcome.js index 3fc9b4706..043a172a1 100755 --- a/print/templates/email/worker-welcome/worker-welcome.js +++ b/print/templates/email/worker-welcome/worker-welcome.js @@ -5,7 +5,6 @@ module.exports = { name: 'worker-welcome', async serverPrefetch() { this.worker = await this.fetchWorker(this.id); - console.log(this.url); }, methods: { fetchWorker(id) { From 46c3d87dabce836faf4a21003d6a9ac9d6551493 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 3 Jan 2023 08:09:46 +0100 Subject: [PATCH 15/88] feat(worker_create): add vn-acl --- modules/worker/front/index/index.html | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/modules/worker/front/index/index.html b/modules/worker/front/index/index.html index b48a84854..7044ca551 100644 --- a/modules/worker/front/index/index.html +++ b/modules/worker/front/index/index.html @@ -6,23 +6,23 @@ class="vn-w-sm"> - @@ -52,4 +54,4 @@ -
\ No newline at end of file + From 22d0da273e3e027b0d59c5195de013d698af19a9 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 3 Jan 2023 13:21:51 +0100 Subject: [PATCH 16/88] =?UTF-8?q?refs=20#4925=20fix:=20coge=20=C3=BAnicame?= =?UTF-8?q?nte=20los=20=C3=BAltimos=20cambios=20aplicados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/item/front/tags/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/item/front/tags/index.js b/modules/item/front/tags/index.js index b5c1fa7f9..bfa1f3f46 100644 --- a/modules/item/front/tags/index.js +++ b/modules/item/front/tags/index.js @@ -30,7 +30,6 @@ class Controller extends Section { onSubmit() { const changes = this.$.model.getChanges(); - console.log(changes); const data = { creates: changes.creates, deletes: changes.deletes, @@ -38,9 +37,9 @@ class Controller extends Section { maxPriority: this.getHighestPriority() }; this.$http.patch(`Tags/onSubmit`, data).then(() => { + this.$.model.refresh(); this.$.watcher.notifySaved(); this.$.watcher.updateOriginalData(); - this.card.reload(); }); } } From fec965a8ddb79ba35c0d1800e9be2a32531a2a75 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 3 Jan 2023 13:29:27 +0100 Subject: [PATCH 17/88] =?UTF-8?q?refs=204925=20refactor:=20borrados=20cons?= =?UTF-8?q?ole.log=20y=20actualizada=20descripci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/item/back/methods/tag/onSubmit.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/item/back/methods/tag/onSubmit.js b/modules/item/back/methods/tag/onSubmit.js index 1bd33d3d4..b80b80d90 100644 --- a/modules/item/back/methods/tag/onSubmit.js +++ b/modules/item/back/methods/tag/onSubmit.js @@ -1,7 +1,7 @@ module.exports = function(Self) { Self.remoteMethodCtx('onSubmit', { - description: 'Creates client address updating default address', + description: 'Save model changes', accessType: 'WRITE', accepts: [ { @@ -57,7 +57,6 @@ module.exports = function(Self) { } if (args.updates) { - console.log('args.updates', args.updates); for (const row of args.updates) { if (row.data.priority) { const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); From 21a62a0fab016623b0993be5b7ade9e3cddc8940 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 3 Jan 2023 13:29:44 +0100 Subject: [PATCH 18/88] refactor --- modules/item/back/models/item-tag.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/item/back/models/item-tag.js b/modules/item/back/models/item-tag.js index 4fd44270a..5b7163913 100644 --- a/modules/item/back/models/item-tag.js +++ b/modules/item/back/models/item-tag.js @@ -4,8 +4,8 @@ module.exports = Self => { require('../methods/item-tag/filterItemTags')(Self); Self.rewriteDbError(function(err) { - // if (err.code === 'ER_DUP_ENTRY') - // return new UserError(`The tag or priority can't be repeated for an item`); + if (err.code === 'ER_DUP_ENTRY') + return new UserError(`The tag or priority can't be repeated for an item`); if (err.code === 'ER_BAD_NULL_ERROR') return new UserError(`Tag value cannot be blank`); return err; From ef437f2feec1209691e1f365c3a394ac6008ea00 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 3 Jan 2023 14:50:29 +0100 Subject: [PATCH 19/88] test: e2e and backTest --- .../{225001 => 230201}/00-aclProfileType.sql | 25 +++++++ db/dump/fixtures.sql | 26 +++---- e2e/helpers/selectors.js | 20 ++++++ e2e/helpers/tests.js | 26 +++---- e2e/paths/03-worker/06_create.spec.js | 72 +++++++++++++++++++ modules/worker/front/create/index.html | 30 ++++---- modules/worker/front/create/index.js | 41 +++++++---- 7 files changed, 186 insertions(+), 54 deletions(-) rename db/changes/{225001 => 230201}/00-aclProfileType.sql (54%) create mode 100644 e2e/paths/03-worker/06_create.spec.js diff --git a/db/changes/225001/00-aclProfileType.sql b/db/changes/230201/00-aclProfileType.sql similarity index 54% rename from db/changes/225001/00-aclProfileType.sql rename to db/changes/230201/00-aclProfileType.sql index 638b3d580..cae7166c9 100644 --- a/db/changes/225001/00-aclProfileType.sql +++ b/db/changes/230201/00-aclProfileType.sql @@ -16,3 +16,28 @@ CREATE TABLE `vn`.`newWorkerConfig` ( CONSTRAINT `newWorkerConfig_profileType_fk` FOREIGN KEY (`profileTypeFk`) REFERENCES `vn`.`profileType` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `newWorkerConfig_role_fk` FOREIGN KEY (`roleFk`) REFERENCES `account`.`role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ); + +UPDATE `salix`.`ACL` +SET accessType='READ' +WHERE model='Worker' + AND property='*' + AND accessType='*' + AND permission='ALLOW' + AND principalType='ROLE' + AND principalId='employee'; + + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Worker', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'hr'), + ('Worker', 'createAbsence', '*', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'updateAbsence', '*', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'deleteAbsence', '*', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'new', 'WRITE', 'ALLOW', 'ROLE', 'hr'), + ('Role', '*', 'READ', 'ALLOW', 'ROLE', 'hr'); + +/* +INSERT INTO `vn`.`newWorkerConfig` (`id`, `street`, `provinceFk`, `companyFk`, `profileTypeFk`, `roleFk`) + VALUES + (1, 'C/ ', 57, 442, 1, 1); +*/ diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 90cc19d01..8f1648048 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -934,10 +934,10 @@ INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `freightItemFk`, (7, 2, 4, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), 1, 18, NULL, 94, NULL,NULL), (8, 3, 5, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), 1, 18, NULL, 94, 1, NULL), (9, 3, 6, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 2, NULL), - (10, 7, 7, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL), - (11, 7, 8, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL), - (12, 7, 9, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL), - (13, 1, 10,71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL); + (10, 7, 7, 71, NOW(), 1, 18, NULL, 94, 3, NULL), + (11, 7, 8, 71, NOW(), 1, 18, NULL, 94, 3, NULL), + (12, 7, 9, 71, NOW(), 1, 18, NULL, 94, 3, NULL), + (13, 1, 10,71, NOW(), 1, 18, NULL, 94, 3, NULL); INSERT INTO `vn`.`expeditionState`(`id`, `created`, `expeditionFk`, `typeFk`, `userFk`) @@ -1910,7 +1910,7 @@ DROP TEMPORARY TABLE IF EXISTS tmp.worker; CREATE TEMPORARY TABLE tmp.worker (PRIMARY KEY (id)) ENGINE = MEMORY - SELECT w.id, w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL +1 YEAR)), '-12-25'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk` + SELECT w.id, w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL +1 YEAR)), '-12-25'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk` FROM `vn`.`worker` `w`; INSERT INTO `vn`.`business`(`id`, `workerFk`, `companyCodeFk`, `started`, `ended`, `workerBusiness`, `reasonEndFk`, `notes`, `departmentFk`, `workerBusinessProfessionalCategoryFk`, `calendarTypeFk`, `isHourlyLabor`, `workerBusinessAgreementFk`, `workcenterFk`) @@ -1920,7 +1920,7 @@ DROP TEMPORARY TABLE IF EXISTS tmp.worker; CREATE TEMPORARY TABLE tmp.worker (PRIMARY KEY (id)) ENGINE = MEMORY - SELECT '1111' as 'id', w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -2 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR)), '-12-24'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk` + SELECT '1111' as 'id', w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -2 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)), '-12-24'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk` FROM `vn`.`worker` `w` WHERE `w`.`id` = 1109; @@ -2741,13 +2741,6 @@ INSERT INTO `vn`.`ticketLog` (`originFk`, userFk, `action`, changedModel, oldIns (7, 18, 'update', 'Sale', '{"price":3}', '{"price":5}', 1, NULL), (7, 18, 'update', NULL, NULL, NULL, NULL, "Cambio cantidad Melee weapon heavy shield 1x0.5m de '5' a '10'"); -INSERT INTO `vn`.`profileType` (`id`, `name`) - VALUES - (1, 'working'); - -INSERT INTO `vn`.`newWorkerConfig` (`id`, `street`, `provinceFk`, `companyFk`, `profileTypeFk`, `roleFk`) - VALUES - (1, 'S/ ', 1, 442, 1, 1); INSERT INTO `vn`.`osTicketConfig` (`id`, `host`, `user`, `password`, `oldStatus`, `newStatusId`, `day`, `comment`, `hostDb`, `userDb`, `passwordDb`, `portDb`, `responseType`, `fromEmailId`, `replyTo`) VALUES @@ -2758,6 +2751,13 @@ INSERT INTO `vn`.`mdbApp` (`app`, `baselineBranchFk`, `userFk`, `locked`) ('foo', 'master', NULL, NULL), ('bar', 'test', 9, util.VN_NOW()); +INSERT INTO `vn`.`profileType` (`id`, `name`) + VALUES + (1, 'working'); + +INSERT INTO `vn`.`newWorkerConfig` (`id`, `street`, `provinceFk`, `companyFk`, `profileTypeFk`, `roleFk`) + VALUES + (1, 'S/ ', 1, 442, 1, 1); INSERT INTO `salix`.`url` (`appName`, `environment`, `url`) VALUES diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index e1792ea7b..134e41796 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -964,6 +964,7 @@ export default { confirmButton: '.vn-confirm.shown button[response="accept"]' }, workerSummary: { + summaryIcon: 'vn-worker-descriptor a[title="Go to module summary"]', header: 'vn-worker-summary h5', id: 'vn-worker-summary vn-one:nth-child(1) > vn-label-value:nth-child(3) > section > span', email: 'vn-worker-summary vn-one:nth-child(1) > vn-label-value:nth-child(4) > section > span', @@ -1016,6 +1017,25 @@ export default { furlough: 'vn-worker-calendar > vn-side-menu [name="absenceTypes"] > vn-chip:nth-child(4)', halfFurlough: 'vn-worker-calendar > vn-side-menu [name="absenceTypes"] > vn-chip:nth-child(5)', }, + workerCreate: { + newWorkerButton: 'vn-worker-index a[ui-sref="worker.create"]', + firstname: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.firstName"]', + lastname: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.lastNames"]', + birth: 'vn-worker-create vn-date-picker[ng-model="$ctrl.worker.birth"]', + fi: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.fi"]', + code: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.code"]', + phone: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.phone"]', + city: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.city"]', + postcode: 'vn-worker-create vn-datalist[ng-model="$ctrl.worker.postcode"]', + street: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.street"]', + user: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.name"]', + email: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.email"]', + boss: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.bossFk"]', + role: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.roleFk"]', + iban: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.iban"]', + switft: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.bankEntityFk"]', + createButton: 'vn-worker-create vn-submit[label="Create"]', + }, invoiceOutIndex: { topbarSearch: 'vn-searchbar', searchResult: 'vn-invoice-out-index vn-card > vn-table > div > vn-tbody > a.vn-tr', diff --git a/e2e/helpers/tests.js b/e2e/helpers/tests.js index aac9963dd..9ac616011 100644 --- a/e2e/helpers/tests.js +++ b/e2e/helpers/tests.js @@ -25,20 +25,20 @@ async function test() { const jasmine = new Jasmine(); const specFiles = [ - `./e2e/paths/01*/*[sS]pec.js`, - `./e2e/paths/02*/*[sS]pec.js`, + // `./e2e/paths/01*/*[sS]pec.js`, + // `./e2e/paths/02*/*[sS]pec.js`, `./e2e/paths/03*/*[sS]pec.js`, - `./e2e/paths/04*/*[sS]pec.js`, - `./e2e/paths/05*/*[sS]pec.js`, - `./e2e/paths/06*/*[sS]pec.js`, - `./e2e/paths/07*/*[sS]pec.js`, - `./e2e/paths/08*/*[sS]pec.js`, - `./e2e/paths/09*/*[sS]pec.js`, - `./e2e/paths/10*/*[sS]pec.js`, - `./e2e/paths/11*/*[sS]pec.js`, - `./e2e/paths/12*/*[sS]pec.js`, - `./e2e/paths/13*/*[sS]pec.js`, - `./e2e/paths/**/*[sS]pec.js` + // `./e2e/paths/04*/*[sS]pec.js`, + // `./e2e/paths/05*/*[sS]pec.js`, + // `./e2e/paths/06*/*[sS]pec.js`, + // `./e2e/paths/07*/*[sS]pec.js`, + // `./e2e/paths/08*/*[sS]pec.js`, + // `./e2e/paths/09*/*[sS]pec.js`, + // `./e2e/paths/10*/*[sS]pec.js`, + // `./e2e/paths/11*/*[sS]pec.js`, + // `./e2e/paths/12*/*[sS]pec.js`, + // `./e2e/paths/13*/*[sS]pec.js`, + // `./e2e/paths/**/*[sS]pec.js` ]; jasmine.loadConfig({ diff --git a/e2e/paths/03-worker/06_create.spec.js b/e2e/paths/03-worker/06_create.spec.js new file mode 100644 index 000000000..b93dace88 --- /dev/null +++ b/e2e/paths/03-worker/06_create.spec.js @@ -0,0 +1,72 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +xdescribe('Worker calendar path', () => { + let browser; + let page; + let newWorker; + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('hr', 'worker'); + await page.waitToClick(selectors.workerCreate.newWorkerButton); + await page.waitForState('worker.create'); + }); + + afterAll(async() => { + await browser.close(); + }); + + it('should insert default data', async() => { + await page.write(selectors.workerCreate.firstname, 'Victor'); + await page.write(selectors.workerCreate.lastname, 'Von Doom'); + await page.write(selectors.workerCreate.fi, '78457139E'); + await page.write(selectors.workerCreate.phone, '12356789'); + await page.write(selectors.workerCreate.postcode, '46680'); + await page.write(selectors.workerCreate.street, 'Doomstadt'); + await page.write(selectors.workerCreate.email, 'doctorDoom@marvel.com'); + await page.write(selectors.workerCreate.iban, 'ES9121000418450200051332'); + await page.autocompleteSearch(selectors.workerCreate.switft, 'BBKKESMMMMM'); + }); + + it('should check for autocompleted worker code and worker user name', async() => { + const workerCode = await page + .waitToGetProperty(selectors.workerCreate.code, 'value'); + + newWorker = await page + .waitToGetProperty(selectors.workerCreate.user, 'value'); + + expect(workerCode).toEqual('VVD'); + expect(newWorker).toContain('victorvd'); + }); + + it('should fail if necessary data is void', async() => { + await page.waitToClick(selectors.workerCreate.createButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('is a required argument'); + }); + + it('should create a new worker and go to worker basic data', async() => { + await page.pickDate(selectors.workerCreate.birth, new Date(1962, 8, 5)); + await page.autocompleteSearch(selectors.workerCreate.role, 'Jefe de personal de reparto'); + await page.autocompleteSearch(selectors.workerCreate.boss, 'deliveryBoss'); + await page.waitToClick(selectors.workerCreate.createButton); + const message = await page.waitForSnackbar(); + await page.waitForState('worker.card.basicData'); + + expect(message.text).toContain('Data saved!'); + }); + + xit('rollback', async() => { + await page.loginAndModule('sysadmin', 'account'); + await page.accessToSearchResult(newWorker); + await page.accessToSection('account.card.summary'); + await page.waitToClick(selectors.accountDescriptor.menuButton); + await page.waitToClick(selectors.accountDescriptor.deleteAccount); + await page.waitToClick(selectors.accountDescriptor.acceptButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('User removed'); + }); +}); diff --git a/modules/worker/front/create/index.html b/modules/worker/front/create/index.html index a86a4e899..c09930b80 100644 --- a/modules/worker/front/create/index.html +++ b/modules/worker/front/create/index.html @@ -62,21 +62,6 @@ rule> {{name}} ({{country.country}}) - - - {{name}}, {{province.name}} - ({{province.country.country}}) - - - - + + + + + {{name}}, {{province.name}} + ({{province.country.country}}) + + { - return this.worker = Object.assign({}, res.data); - }); + // this.$http.get('NewWorkerConfigs/findOne').then(res => { + // return this.worker = Object.assign({}, res.data); + // }); // DELETE this.worker = { fi: '73226971P', @@ -74,6 +74,13 @@ export default class Controller extends Section { // Province auto complete set province(selection) { this._province = selection; + + if (!selection) return; + + const country = selection.country; + + if (!this.worker.countryFk) + this.worker.countryFk = country.id; } get town() { @@ -87,13 +94,17 @@ export default class Controller extends Section { if (!selection) return; const province = selection.province; + const country = province.country; const postcodes = selection.postcodes; - if (!this.client.provinceFk) - this.client.provinceFk = province.id; + if (!this.worker.provinceFk) + this.worker.provinceFk = province.id; + + if (!this.worker.countryFk) + this.worker.countryFk = country.id; if (postcodes.length === 1) - this.client.postcode = postcodes[0].code; + this.worker.postcode = postcodes[0].code; } get postcode() { @@ -108,18 +119,22 @@ export default class Controller extends Section { const town = selection.town; const province = town.province; + const country = province.country; - if (!this.client.city) - this.client.city = town.name; + if (!this.worker.city) + this.worker.city = town.name; - if (!this.client.provinceFk) - this.client.provinceFk = province.id; + if (!this.worker.provinceFk) + this.worker.provinceFk = province.id; + + if (!this.worker.countryFk) + this.worker.countryFk = country.id; } onResponse(response) { - this.client.postcode = response.code; - this.client.city = response.city; - this.client.provinceFk = response.provinceFk; + this.worker.postcode = response.code; + this.worker.city = response.city; + this.worker.provinceFk = response.provinceFk; } } From 9b9824939835b2fa6de8ca618c2e40e3590c07aa Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 4 Jan 2023 09:23:18 +0100 Subject: [PATCH 20/88] test: front test and e2e --- ...aclProfileType.sql => 00-createWorker.sql} | 2 +- e2e/helpers/selectors.js | 1 + e2e/helpers/tests.js | 26 +++++----- e2e/paths/03-worker/06_create.spec.js | 23 ++++++--- modules/worker/front/create/index.js | 26 ++-------- modules/worker/front/create/index.spec.js | 49 +++++++++++-------- 6 files changed, 62 insertions(+), 65 deletions(-) rename db/changes/230201/{00-aclProfileType.sql => 00-createWorker.sql} (96%) diff --git a/db/changes/230201/00-aclProfileType.sql b/db/changes/230201/00-createWorker.sql similarity index 96% rename from db/changes/230201/00-aclProfileType.sql rename to db/changes/230201/00-createWorker.sql index cae7166c9..d4118b4fa 100644 --- a/db/changes/230201/00-aclProfileType.sql +++ b/db/changes/230201/00-createWorker.sql @@ -31,7 +31,7 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri VALUES ('Worker', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'hr'), ('Worker', 'createAbsence', '*', 'ALLOW', 'ROLE', 'employee'), - ('Worker', 'updateAbsence', '*', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'updateAbsence', 'WRITE', 'ALLOW', 'ROLE', 'employee'), ('Worker', 'deleteAbsence', '*', 'ALLOW', 'ROLE', 'employee'), ('Worker', 'new', 'WRITE', 'ALLOW', 'ROLE', 'hr'), ('Role', '*', 'READ', 'ALLOW', 'ROLE', 'hr'); diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 134e41796..6bfb38e5d 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -58,6 +58,7 @@ export default { deleteAccount: '.vn-menu [name="deleteUser"]', setPassword: '.vn-menu [name="setPassword"]', activateAccount: '.vn-menu [name="enableAccount"]', + disableAccount: '.vn-menu [name="disableAccount"]', activateUser: '.vn-menu [name="activateUser"]', deactivateUser: '.vn-menu [name="deactivateUser"]', newPassword: 'vn-textfield[ng-model="$ctrl.newPassword"]', diff --git a/e2e/helpers/tests.js b/e2e/helpers/tests.js index 9ac616011..aac9963dd 100644 --- a/e2e/helpers/tests.js +++ b/e2e/helpers/tests.js @@ -25,20 +25,20 @@ async function test() { const jasmine = new Jasmine(); const specFiles = [ - // `./e2e/paths/01*/*[sS]pec.js`, - // `./e2e/paths/02*/*[sS]pec.js`, + `./e2e/paths/01*/*[sS]pec.js`, + `./e2e/paths/02*/*[sS]pec.js`, `./e2e/paths/03*/*[sS]pec.js`, - // `./e2e/paths/04*/*[sS]pec.js`, - // `./e2e/paths/05*/*[sS]pec.js`, - // `./e2e/paths/06*/*[sS]pec.js`, - // `./e2e/paths/07*/*[sS]pec.js`, - // `./e2e/paths/08*/*[sS]pec.js`, - // `./e2e/paths/09*/*[sS]pec.js`, - // `./e2e/paths/10*/*[sS]pec.js`, - // `./e2e/paths/11*/*[sS]pec.js`, - // `./e2e/paths/12*/*[sS]pec.js`, - // `./e2e/paths/13*/*[sS]pec.js`, - // `./e2e/paths/**/*[sS]pec.js` + `./e2e/paths/04*/*[sS]pec.js`, + `./e2e/paths/05*/*[sS]pec.js`, + `./e2e/paths/06*/*[sS]pec.js`, + `./e2e/paths/07*/*[sS]pec.js`, + `./e2e/paths/08*/*[sS]pec.js`, + `./e2e/paths/09*/*[sS]pec.js`, + `./e2e/paths/10*/*[sS]pec.js`, + `./e2e/paths/11*/*[sS]pec.js`, + `./e2e/paths/12*/*[sS]pec.js`, + `./e2e/paths/13*/*[sS]pec.js`, + `./e2e/paths/**/*[sS]pec.js` ]; jasmine.loadConfig({ diff --git a/e2e/paths/03-worker/06_create.spec.js b/e2e/paths/03-worker/06_create.spec.js index b93dace88..c1a555cbb 100644 --- a/e2e/paths/03-worker/06_create.spec.js +++ b/e2e/paths/03-worker/06_create.spec.js @@ -1,7 +1,7 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; -xdescribe('Worker calendar path', () => { +describe('Worker calendar path', () => { let browser; let page; let newWorker; @@ -58,15 +58,22 @@ xdescribe('Worker calendar path', () => { expect(message.text).toContain('Data saved!'); }); - xit('rollback', async() => { + it('rollback', async() => { await page.loginAndModule('sysadmin', 'account'); await page.accessToSearchResult(newWorker); - await page.accessToSection('account.card.summary'); - await page.waitToClick(selectors.accountDescriptor.menuButton); - await page.waitToClick(selectors.accountDescriptor.deleteAccount); - await page.waitToClick(selectors.accountDescriptor.acceptButton); - const message = await page.waitForSnackbar(); - expect(message.text).toContain('User removed'); + await page.waitToClick(selectors.accountDescriptor.menuButton); + await page.waitToClick(selectors.accountDescriptor.deactivateUser); + await page.waitToClick(selectors.accountDescriptor.acceptButton); + let message = await page.waitForSnackbar(); + + expect(message.text).toContain('User deactivated!'); + + await page.waitToClick(selectors.accountDescriptor.menuButton); + await page.waitToClick(selectors.accountDescriptor.disableAccount); + await page.waitToClick(selectors.accountDescriptor.acceptButton); + message = await page.waitForSnackbar(); + + expect(message.text).toContain('Account disabled!'); }); }); diff --git a/modules/worker/front/create/index.js b/modules/worker/front/create/index.js index 7965ab7e7..b80b3ae94 100644 --- a/modules/worker/front/create/index.js +++ b/modules/worker/front/create/index.js @@ -4,29 +4,9 @@ import Section from 'salix/components/section'; export default class Controller extends Section { constructor($element, $) { super($element, $); - // this.$http.get('NewWorkerConfigs/findOne').then(res => { - // return this.worker = Object.assign({}, res.data); - // }); - // DELETE - this.worker = { - fi: '73226971P', - name: 'ASDASD', - firstName: 'Test', - lastNames: 'Test', - email: 'developer4@mydomain.com', - roleFk: 1, - street: 'S/ ', - city: 'asd', - provinceFk: 1, - iban: 'ES2420386579855387888566', - bankEntityFk: 128, - companyFk: 442, - postcode: 'asd', - phone: '633342693', - code: 'ASD', - bossFk: 34, - birth: '2022-12-11T23:00:00.000Z' - }; + this.$http.get('NewWorkerConfigs/findOne').then(res => { + return this.worker = Object.assign({}, res.data); + }); } onSubmit() { diff --git a/modules/worker/front/create/index.spec.js b/modules/worker/front/create/index.spec.js index 24fc80d21..eac6c8bf0 100644 --- a/modules/worker/front/create/index.spec.js +++ b/modules/worker/front/create/index.spec.js @@ -1,12 +1,12 @@ import './index'; -describe('Client', () => { - describe('Component vnClientCreate', () => { +describe('Worker', () => { + describe('Component vnWorkerCreate', () => { let $scope; let $state; let controller; - beforeEach(ngModule('client')); + beforeEach(ngModule('worker')); beforeEach(inject(($componentController, $rootScope, _$state_) => { $scope = $rootScope.$new(); @@ -20,28 +20,23 @@ describe('Client', () => { }; } }; - const $element = angular.element(''); - controller = $componentController('vnClientCreate', {$element, $scope}); + const $element = angular.element(''); + controller = $componentController('vnWorkerCreate', {$element, $scope}); + controller.worker = {}; })); - it('should define and set scope, state and client properties', () => { - expect(controller.$).toBe($scope); - expect(controller.$state).toBe($state); - expect(controller.client.active).toBe(true); - }); - describe('onSubmit()', () => { it(`should call submit() on the watcher then expect a callback`, () => { jest.spyOn($state, 'go'); controller.onSubmit(); - expect(controller.$state.go).toHaveBeenCalledWith('client.card.basicData', {id: '1234'}); + expect(controller.$state.go).toHaveBeenCalledWith('worker.card.basicData', {id: '1234'}); }); }); describe('province() setter', () => { it(`should set countryFk property`, () => { - controller.client.countryFk = null; + controller.worker.countryFk = null; controller.province = { id: 1, name: 'New york', @@ -51,7 +46,7 @@ describe('Client', () => { } }; - expect(controller.client.countryFk).toEqual(2); + expect(controller.worker.countryFk).toEqual(2); }); }); @@ -71,7 +66,7 @@ describe('Client', () => { postcodes: [] }; - expect(controller.client.provinceFk).toEqual(1); + expect(controller.worker.provinceFk).toEqual(1); }); it(`should set provinceFk property and fill the postalCode if there's just one`, () => { @@ -89,8 +84,8 @@ describe('Client', () => { postcodes: [{code: '46001'}] }; - expect(controller.client.provinceFk).toEqual(1); - expect(controller.client.postcode).toEqual('46001'); + expect(controller.worker.provinceFk).toEqual(1); + expect(controller.worker.postcode).toEqual('46001'); }); }); @@ -113,9 +108,23 @@ describe('Client', () => { } }; - expect(controller.client.city).toEqual('New York'); - expect(controller.client.provinceFk).toEqual(1); - expect(controller.client.countryFk).toEqual(2); + expect(controller.worker.city).toEqual('New York'); + expect(controller.worker.provinceFk).toEqual(1); + expect(controller.worker.countryFk).toEqual(2); + }); + }); + + describe('generateCodeUser()', () => { + it(`should generate worker code and name `, () => { + controller.worker = { + firstName: 'default', + lastNames: 'generate worker' + }; + + controller.generateCodeUser(); + + expect(controller.worker.code).toEqual('DGW'); + expect(controller.worker.name).toEqual('defaultgw'); }); }); }); From 9c044dc95b71cc1d2da391a4a28209485d74d7f3 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 4 Jan 2023 09:38:43 +0100 Subject: [PATCH 21/88] fix: phone --- modules/worker/back/methods/worker/specs/new.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/methods/worker/specs/new.spec.js b/modules/worker/back/methods/worker/specs/new.spec.js index 2cb8bebef..d6b226ad2 100644 --- a/modules/worker/back/methods/worker/specs/new.spec.js +++ b/modules/worker/back/methods/worker/specs/new.spec.js @@ -32,7 +32,7 @@ describe('Worker new', () => { bankEntityFk: 128, companyFk: 442, postcode: '46680', - phone: '633342693', + phone: '123456789', code: 'DWW', bossFk: 9, birth: '2022-12-11T23:00:00.000Z' From 3edc0403ba3a744b11ea2c618227709de72c322b Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 5 Jan 2023 10:35:42 +0100 Subject: [PATCH 22/88] fix --- front/core/components/crud-model/crud-model.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/front/core/components/crud-model/crud-model.js b/front/core/components/crud-model/crud-model.js index 10414daa3..421a79f9b 100644 --- a/front/core/components/crud-model/crud-model.js +++ b/front/core/components/crud-model/crud-model.js @@ -178,7 +178,7 @@ export default class CrudModel extends ModelProxy { } } - let changes = {deletes, updates, creates}; + const changes = {deletes, updates, creates}; for (let prop in changes) { if (changes[prop].length === 0) @@ -198,8 +198,7 @@ export default class CrudModel extends ModelProxy { const changes = this.getChanges(); if (!changes) return this.$q.resolve(); - const creates = changes.creates; - + const creates = changes.creates || []; let url = this.saveUrl ? this.saveUrl : `${this._url}/crud`; return this.$http.post(url, changes) .then(res => { From fd9ca3a4c13d7283dc6be959c9fb1999ee06a700 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 5 Jan 2023 10:35:49 +0100 Subject: [PATCH 23/88] add test --- .../back/methods/tag/specs/onSubmit.spec.js | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 modules/item/back/methods/tag/specs/onSubmit.spec.js diff --git a/modules/item/back/methods/tag/specs/onSubmit.spec.js b/modules/item/back/methods/tag/specs/onSubmit.spec.js new file mode 100644 index 000000000..a8077db67 --- /dev/null +++ b/modules/item/back/methods/tag/specs/onSubmit.spec.js @@ -0,0 +1,100 @@ +const models = require('vn-loopback/server/server').models; + +describe('tag onSubmit()', () => { + it('should delete a tag', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const deletes = [40]; + const ctx = { + args: { + deletes: deletes + } + }; + const result = await models.Tag.onSubmit(ctx, options); + + expect(result.length).toEqual(1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should update a tag', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const updates = [{data: {value: 'Container Test'}, where: {id: 36}}]; + const ctx = { + args: { + updates: updates + } + }; + const result = await models.Tag.onSubmit(ctx, options); + + expect(result.length).toEqual(1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should create a tag', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const creates = [{ + 'itemFk': '6', + 'priority': 8, + '$orgIndex': null, + '$oldData': null, + '$isNew': true, + 'tagFk': 3, + 'value': 'madera' + }]; + const ctx = { + args: { + creates: creates + } + }; + const result = await models.Tag.onSubmit(ctx, options); + + expect(result.length).toEqual(1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should swap priority for two tags', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const updates = [ + {data: {priority: 2}, where: {id: 36}}, + {data: {priority: 1}, where: {id: 37}} + ]; + const ctx = { + args: { + updates: updates, + maxPriority: 7, + + } + }; + const result = await models.Tag.onSubmit(ctx, options); + + expect(result.length).toEqual(4); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); From 3abbfc4fa7c9fa3c595caffed38aa5633f1fc096 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 5 Jan 2023 10:35:55 +0100 Subject: [PATCH 24/88] refacotr --- CHANGELOG.md | 1 + modules/item/front/tags/index.html | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7073dc53..4e45bb760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - [General] Al utilizar el traductor de Google se descuadraban los iconos +- [Artículos](Etiquetas) Permite intercambiar la relevancia entre dos etiquetas. ### Removed - [Tickets](Control clientes) Eliminada sección diff --git a/modules/item/front/tags/index.html b/modules/item/front/tags/index.html index 471a53634..f9b5370fa 100644 --- a/modules/item/front/tags/index.html +++ b/modules/item/front/tags/index.html @@ -73,10 +73,10 @@ - - + From e4603a06f2d9e92f95e0198c9918ee6e752167e1 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 12 Jan 2023 08:59:24 +0100 Subject: [PATCH 25/88] refacotor: borrados los await para que devuelva la promesa --- modules/item/back/methods/tag/onSubmit.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/item/back/methods/tag/onSubmit.js b/modules/item/back/methods/tag/onSubmit.js index b80b80d90..aec67e92a 100644 --- a/modules/item/back/methods/tag/onSubmit.js +++ b/modules/item/back/methods/tag/onSubmit.js @@ -51,7 +51,7 @@ module.exports = function(Self) { if (args.deletes) { for (const itemTagId of args.deletes) { - const itemTagDeleted = await models.ItemTag.destroyById(itemTagId, myOptions); + const itemTagDeleted = models.ItemTag.destroyById(itemTagId, myOptions); promises.push(itemTagDeleted); } } @@ -60,7 +60,7 @@ module.exports = function(Self) { for (const row of args.updates) { if (row.data.priority) { const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); - const itemTagUpdatedPriority = await itemTag.updateAttributes({ + const itemTagUpdatedPriority = itemTag.updateAttributes({ priority: row.data.priority + args.maxPriority }, myOptions); promises.push(itemTagUpdatedPriority); @@ -68,14 +68,14 @@ module.exports = function(Self) { } for (const row of args.updates) { const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); - const itemTagUpdated = await itemTag.updateAttributes(row.data, myOptions); + const itemTagUpdated = itemTag.updateAttributes(row.data, myOptions); promises.push(itemTagUpdated); } } if (args.creates) { for (const itemTag of args.creates) { - const newItemTag = await models.ItemTag.create(itemTag, myOptions); + const newItemTag = models.ItemTag.create(itemTag, myOptions); promises.push(newItemTag); } } From 41671e8a3a358ea8c3170b8c388c3e4d4640a398 Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 13 Jan 2023 08:38:29 +0100 Subject: [PATCH 26/88] refs #4927 modified hook to check name & country --- loopback/locale/es.json | 5 +++-- modules/supplier/back/models/supplier.js | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index ea83b36c4..f2acea939 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -252,5 +252,6 @@ "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", - "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9" -} \ No newline at end of file + "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9", + "A supplier with the same name already exists. Change the country.": "Un proveedor con el mismo nombre ya existe. Cambie el país." +} diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index 64c585b6a..cba220af8 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -116,13 +116,21 @@ module.exports = Self => { Self.observe('before save', async function(ctx) { const changes = ctx.data || ctx.instance; const orgData = ctx.currentInstance; - - const socialName = changes.name || orgData.name; const hasChanges = orgData && changes; - const socialNameChanged = hasChanges - && orgData.socialName != socialName; - if ((socialNameChanged) && !isAlpha(socialName)) - throw new UserError('The social name has an invalid format'); + if (hasChanges) { + const name = changes.name || orgData.name; + const nameChanged = hasChanges && orgData.name != name; + const countryFk = changes.countryFk || orgData.countryFk; + const countryChanged = hasChanges && orgData.countryFk != countryFk; + + if (nameChanged || countryChanged) { + if (!isAlpha(name)) throw new UserError('The social name has an invalid format'); + + const supplier = await Self.app.models.Supplier.findOne({where: {name, countryFk}, fields: ['id']}); + if (supplier) + throw new UserError('A supplier with the same name already exists. Change the country.'); + } + } }); }; From ecfad940571fef9ecfb2c855dc8a63369d4acbe7 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 16 Jan 2023 12:19:03 +0100 Subject: [PATCH 27/88] refactor(worker_new): remove roleFk and profileType --- db/changes/230201/00-createWorker.sql | 29 +++----------- db/dump/fixtures.sql | 4 ++ e2e/paths/03-worker/06_create.spec.js | 23 +++++------ modules/worker/back/methods/worker/new.js | 26 +++++-------- .../back/methods/worker/specs/new.spec.js | 1 - modules/worker/back/model-config.json | 34 ++++++++-------- ...-worker-config.json => worker-config.json} | 16 +------- modules/worker/front/create/index.html | 39 ++++++------------- modules/worker/front/create/index.js | 7 ++-- modules/worker/front/create/index.spec.js | 4 +- 10 files changed, 65 insertions(+), 118 deletions(-) rename modules/worker/back/models/{new-worker-config.json => worker-config.json} (58%) diff --git a/db/changes/230201/00-createWorker.sql b/db/changes/230201/00-createWorker.sql index d4118b4fa..7ca2c41ee 100644 --- a/db/changes/230201/00-createWorker.sql +++ b/db/changes/230201/00-createWorker.sql @@ -1,22 +1,3 @@ - -INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) - VALUES - ('ProfileType', '*', '*', 'ALLOW', 'ROLE', 'employee'); - -CREATE TABLE `vn`.`newWorkerConfig` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `street` VARCHAR(25) NULL, - `provinceFk` smallint(6) unsigned NULL, - `companyFk` smallint(5) unsigned NULL, - `profileTypeFk` INT(11) NULL, - `roleFk` int(10) unsigned NULL, - PRIMARY KEY (`id`), - CONSTRAINT `newWorkerConfig_province_fk` FOREIGN KEY (`provinceFk`) REFERENCES `vn`.`province` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `newWorkerConfig_company_fk` FOREIGN KEY (`companyFk`) REFERENCES `vn`.`company` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `newWorkerConfig_profileType_fk` FOREIGN KEY (`profileTypeFk`) REFERENCES `vn`.`profileType` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `newWorkerConfig_role_fk` FOREIGN KEY (`roleFk`) REFERENCES `account`.`role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -); - UPDATE `salix`.`ACL` SET accessType='READ' WHERE model='Worker' @@ -36,8 +17,8 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri ('Worker', 'new', 'WRITE', 'ALLOW', 'ROLE', 'hr'), ('Role', '*', 'READ', 'ALLOW', 'ROLE', 'hr'); -/* -INSERT INTO `vn`.`newWorkerConfig` (`id`, `street`, `provinceFk`, `companyFk`, `profileTypeFk`, `roleFk`) - VALUES - (1, 'C/ ', 57, 442, 1, 1); -*/ +ALTER TABLE `vn`.`workerConfig` ADD roleFk int(10) unsigned NOT NULL COMMENT 'Rol por defecto al dar de alta un trabajador nuevo'; +UPDATE `vn`.`workerConfig` + SET roleFk = 1 + WHERE id = 1; + diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index eae831aea..3fc40f75f 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2769,3 +2769,7 @@ INSERT INTO `vn`.`payDemDetail` (`id`, `detail`) VALUES (1, 1); +INSERT INTO `vn`.`workerConfig` (`id`, `businessUpdated`, `roleFk`) + VALUES + (1, NULL, 1); + diff --git a/e2e/paths/03-worker/06_create.spec.js b/e2e/paths/03-worker/06_create.spec.js index c1a555cbb..5f6f5cf9f 100644 --- a/e2e/paths/03-worker/06_create.spec.js +++ b/e2e/paths/03-worker/06_create.spec.js @@ -1,7 +1,7 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; -describe('Worker calendar path', () => { +describe('Worker create path', () => { let browser; let page; let newWorker; @@ -23,13 +23,12 @@ describe('Worker calendar path', () => { await page.write(selectors.workerCreate.fi, '78457139E'); await page.write(selectors.workerCreate.phone, '12356789'); await page.write(selectors.workerCreate.postcode, '46680'); - await page.write(selectors.workerCreate.street, 'Doomstadt'); + await page.write(selectors.workerCreate.street, 'S/ Doomstadt'); await page.write(selectors.workerCreate.email, 'doctorDoom@marvel.com'); await page.write(selectors.workerCreate.iban, 'ES9121000418450200051332'); await page.autocompleteSearch(selectors.workerCreate.switft, 'BBKKESMMMMM'); - }); - it('should check for autocompleted worker code and worker user name', async() => { + // should check for autocompleted worker code and worker user name const workerCode = await page .waitToGetProperty(selectors.workerCreate.code, 'value'); @@ -38,34 +37,30 @@ describe('Worker calendar path', () => { expect(workerCode).toEqual('VVD'); expect(newWorker).toContain('victorvd'); - }); - it('should fail if necessary data is void', async() => { + // should fail if necessary data is void await page.waitToClick(selectors.workerCreate.createButton); - const message = await page.waitForSnackbar(); + let message = await page.waitForSnackbar(); expect(message.text).toContain('is a required argument'); - }); - it('should create a new worker and go to worker basic data', async() => { + // should create a new worker and go to worker basic data' await page.pickDate(selectors.workerCreate.birth, new Date(1962, 8, 5)); - await page.autocompleteSearch(selectors.workerCreate.role, 'Jefe de personal de reparto'); await page.autocompleteSearch(selectors.workerCreate.boss, 'deliveryBoss'); await page.waitToClick(selectors.workerCreate.createButton); - const message = await page.waitForSnackbar(); + message = await page.waitForSnackbar(); await page.waitForState('worker.card.basicData'); expect(message.text).toContain('Data saved!'); - }); - it('rollback', async() => { + // 'rollback' await page.loginAndModule('sysadmin', 'account'); await page.accessToSearchResult(newWorker); await page.waitToClick(selectors.accountDescriptor.menuButton); await page.waitToClick(selectors.accountDescriptor.deactivateUser); await page.waitToClick(selectors.accountDescriptor.acceptButton); - let message = await page.waitForSnackbar(); + message = await page.waitForSnackbar(); expect(message.text).toContain('User deactivated!'); diff --git a/modules/worker/back/methods/worker/new.js b/modules/worker/back/methods/worker/new.js index b6da3301a..a7bb883cd 100644 --- a/modules/worker/back/methods/worker/new.js +++ b/modules/worker/back/methods/worker/new.js @@ -1,8 +1,9 @@ +/* eslint max-len: ["error", { "code": 130 }]*/ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('new', { - description: 'Creates a new ticket and returns the id', + description: 'Creates a new worker and returns the id', accessType: 'WRITE', accepts: [ { @@ -35,12 +36,6 @@ module.exports = Self => { description: `The worker email`, required: true, }, - { - arg: 'roleFk', - type: 'number', - description: `The worker role`, - required: true, - }, { arg: 'street', type: 'string', @@ -106,12 +101,6 @@ module.exports = Self => { type: 'date', description: `The worker birth`, required: true, - }, - { - arg: 'profileTypeFk', - type: 'number', - description: `The worker profile type ¿DELETE?`, - required: true, } ], returns: { @@ -150,6 +139,7 @@ module.exports = Self => { if (!client) { const nickname = args.firstName.concat(' ', args.lastNames); + const workerConfig = await models.WorkerConfig.findOne({fields: ['roleFk']}); const [randomPassword] = await models.Worker.rawSql( 'SELECT account.passwordGenerate() as password;' ); @@ -160,7 +150,7 @@ module.exports = Self => { nickname, password: randomPassword.password, email: args.email, - role: args.roleFk, + roleFk: workerConfig.roleFk, }, myOptions ); @@ -198,13 +188,17 @@ module.exports = Self => { provinceFk: args.provinceFk, postalCode: args.postalCode, mobile: args.phone, - nickname: 'TR ' + nickname, + nickname: nickname, isDefaultAddress: true, }, myOptions ); - client = await models.Client.findById(user.id, null, myOptions); + client = await models.Client.findById( + user.id, + {fields: ['id', 'name', 'socialName', 'street', 'city', 'iban', 'bankEntityFk', 'defaultAddressFk']}, + myOptions + ); await client.updateAttributes( { diff --git a/modules/worker/back/methods/worker/specs/new.spec.js b/modules/worker/back/methods/worker/specs/new.spec.js index d6b226ad2..f695ab80e 100644 --- a/modules/worker/back/methods/worker/specs/new.spec.js +++ b/modules/worker/back/methods/worker/specs/new.spec.js @@ -24,7 +24,6 @@ describe('Worker new', () => { firstName: 'default', lastNames: 'worker', email: 'defaultWorker@mydomain.com', - roleFk: 1, street: 'S/ defaultWorkerStreet', city: 'defaultWorkerCity', provinceFk: 1, diff --git a/modules/worker/back/model-config.json b/modules/worker/back/model-config.json index de8aadd41..7e03c8a23 100644 --- a/modules/worker/back/model-config.json +++ b/modules/worker/back/model-config.json @@ -26,9 +26,6 @@ "Journey": { "dataSource": "vn" }, - "NewWorkerConfig":{ - "dataSource": "vn" - }, "ProfileType":{ "dataSource": "vn" }, @@ -41,36 +38,42 @@ "WorkCenterHoliday": { "dataSource": "vn" }, - "WorkerDms": { + "Worker": { "dataSource": "vn" }, - "Worker": { + "WorkerConfig": { + "dataSource": "vn" + }, + "WorkerDepartment": { + "dataSource": "vn" + }, + "WorkerDisableExcluded": { + "dataSource": "vn" + }, + "WorkerDms": { "dataSource": "vn" }, "WorkerLabour": { "dataSource": "vn" }, + "WorkerLog": { + "dataSource": "vn" + }, "WorkerMana": { "dataSource": "vn" }, + "WorkerMedia": { + "dataSource": "vn" + }, "WorkerTeam": { "dataSource": "vn" }, "WorkerTeamCollegues": { "dataSource": "vn" }, - "WorkerMedia": { - "dataSource": "vn" - }, - "WorkerDepartment": { - "dataSource": "vn" - }, "WorkerTimeControl": { "dataSource": "vn" }, - "WorkerLog": { - "dataSource": "vn" - }, "WorkerTimeControlConfig": { "dataSource": "vn" }, @@ -79,9 +82,6 @@ }, "WorkerTimeControlMail": { "dataSource": "vn" - }, - "WorkerDisableExcluded": { - "dataSource": "vn" } } diff --git a/modules/worker/back/models/new-worker-config.json b/modules/worker/back/models/worker-config.json similarity index 58% rename from modules/worker/back/models/new-worker-config.json rename to modules/worker/back/models/worker-config.json index 2102d236c..05cdfef42 100644 --- a/modules/worker/back/models/new-worker-config.json +++ b/modules/worker/back/models/worker-config.json @@ -1,9 +1,9 @@ { - "name": "NewWorkerConfig", + "name": "WorkerConfig", "base": "VnModel", "options": { "mysql": { - "table": "newWorkerConfig" + "table": "workerConfig" } }, "properties": { @@ -12,18 +12,6 @@ "id": true, "description": "Identifier" }, - "street": { - "type": "string" - }, - "provinceFk": { - "type": "number" - }, - "companyFk": { - "type": "number" - }, - "profileTypeFk": { - "type": "number" - }, "roleFk": { "type": "number" } diff --git a/modules/worker/front/create/index.html b/modules/worker/front/create/index.html index c09930b80..5f5ab9d07 100644 --- a/modules/worker/front/create/index.html +++ b/modules/worker/front/create/index.html @@ -52,19 +52,9 @@ - - {{name}} ({{country.country}}) - + + {{name}} ({{country.country}}) + - - - - { - return this.worker = Object.assign({}, res.data); - }); + this.worker = {companyFk: this.vnConfig.user.companyFk}; } onSubmit() { @@ -45,6 +43,9 @@ export default class Controller extends Section { this.worker.code = newCode.toUpperCase().slice(0, 3); this.worker.name = totalNameArray[0] + newCode.slice(1); + + if (!this.worker.companyFk) + this.worker.companyFk = this.vnConfig.user.companyFk; } get province() { diff --git a/modules/worker/front/create/index.spec.js b/modules/worker/front/create/index.spec.js index eac6c8bf0..c2e9acce0 100644 --- a/modules/worker/front/create/index.spec.js +++ b/modules/worker/front/create/index.spec.js @@ -23,6 +23,7 @@ describe('Worker', () => { const $element = angular.element(''); controller = $componentController('vnWorkerCreate', {$element, $scope}); controller.worker = {}; + controller.vnConfig = {user: {companyFk: 1}}; })); describe('onSubmit()', () => { @@ -115,7 +116,7 @@ describe('Worker', () => { }); describe('generateCodeUser()', () => { - it(`should generate worker code and name `, () => { + it(`should generate worker code, name and company `, () => { controller.worker = { firstName: 'default', lastNames: 'generate worker' @@ -125,6 +126,7 @@ describe('Worker', () => { expect(controller.worker.code).toEqual('DGW'); expect(controller.worker.name).toEqual('defaultgw'); + expect(controller.worker.companyFk).toEqual(controller.vnConfig.user.companyFk); }); }); }); From 4e1c43eb4df7aa003f3353c194263de2dca1932c Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 17 Jan 2023 10:01:49 +0100 Subject: [PATCH 28/88] refs #4945 nombre temporal removed --- e2e/helpers/selectors.js | 3 ++- e2e/paths/04-item/07_create.spec.js | 11 ++++++++++- e2e/paths/04-item/10_item_log.spec.js | 10 +++++----- modules/item/back/methods/item/new.js | 17 ++++++++++++----- .../item/back/methods/item/specs/new.spec.js | 7 ++++--- modules/item/front/create/index.html | 16 ++++++++++++++-- modules/item/front/create/index.js | 4 +++- 7 files changed, 50 insertions(+), 18 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index b8f0813ed..04f2d4569 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -428,6 +428,7 @@ export default { }, itemCreateView: { temporalName: 'vn-item-create vn-textfield[ng-model="$ctrl.item.provisionalName"]', + priority: 'vn-input-number[ng-model="$ctrl.item.priority"]', type: 'vn-autocomplete[ng-model="$ctrl.item.typeFk"]', intrastat: 'vn-autocomplete[ng-model="$ctrl.item.intrastatFk"]', origin: 'vn-autocomplete[ng-model="$ctrl.item.originFk"]', @@ -521,7 +522,7 @@ export default { }, itemLog: { anyLineCreated: 'vn-item-log > vn-log vn-tbody > vn-tr', - fifthLineCreatedProperty: 'vn-item-log > vn-log vn-tbody > vn-tr:nth-child(5) table tr:nth-child(3) td.after', + fourthLineCreatedProperty: 'vn-item-log > vn-log vn-tbody > vn-tr:nth-child(4) table tr:nth-child(3) td.after', }, ticketSummary: { header: 'vn-ticket-summary > vn-card > h5', diff --git a/e2e/paths/04-item/07_create.spec.js b/e2e/paths/04-item/07_create.spec.js index 0820f2db7..8319a8dff 100644 --- a/e2e/paths/04-item/07_create.spec.js +++ b/e2e/paths/04-item/07_create.spec.js @@ -36,11 +36,20 @@ describe('Item Create', () => { await page.waitForState('item.create'); }); - it('should create the Infinity Gauntlet item', async() => { + it('should throw an error when insert an invalid priority', async() => { await page.write(selectors.itemCreateView.temporalName, 'Infinity Gauntlet'); await page.autocompleteSearch(selectors.itemCreateView.type, 'Crisantemo'); await page.autocompleteSearch(selectors.itemCreateView.intrastat, 'Coral y materiales similares'); await page.autocompleteSearch(selectors.itemCreateView.origin, 'Holand'); + await page.overwrite(selectors.itemCreateView.priority, '100'); + await page.waitToClick(selectors.itemCreateView.createButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('Valid priorities'); + }); + + it('should create the Infinity Gauntlet item', async() => { + await page.overwrite(selectors.itemCreateView.priority, '2'); await page.waitToClick(selectors.itemCreateView.createButton); const message = await page.waitForSnackbar(); diff --git a/e2e/paths/04-item/10_item_log.spec.js b/e2e/paths/04-item/10_item_log.spec.js index 2a885fe6f..f3ff6001c 100644 --- a/e2e/paths/04-item/10_item_log.spec.js +++ b/e2e/paths/04-item/10_item_log.spec.js @@ -48,17 +48,17 @@ describe('Item log path', () => { await page.accessToSection('item.card.log'); }); - it(`should confirm the log is showing 5 entries`, async() => { + it(`should confirm the log is showing 4 entries`, async() => { await page.waitForSelector(selectors.itemLog.anyLineCreated); const anyLineCreatedCount = await page.countElement(selectors.itemLog.anyLineCreated); - expect(anyLineCreatedCount).toEqual(5); + expect(anyLineCreatedCount).toEqual(4); }); it(`should confirm the log is showing the intrastat for the created item`, async() => { - const fifthLineCreatedProperty = await page - .waitToGetProperty(selectors.itemLog.fifthLineCreatedProperty, 'innerText'); + const fourthLineCreatedProperty = await page + .waitToGetProperty(selectors.itemLog.fourthLineCreatedProperty, 'innerText'); - expect(fifthLineCreatedProperty).toEqual('Coral y materiales similares'); + expect(fourthLineCreatedProperty).toEqual('Coral y materiales similares'); }); }); diff --git a/modules/item/back/methods/item/new.js b/modules/item/back/methods/item/new.js index fae37836f..b84072a8a 100644 --- a/modules/item/back/methods/item/new.js +++ b/modules/item/back/methods/item/new.js @@ -37,7 +37,9 @@ module.exports = Self => { 'typeFk', 'intrastatFk', 'originFk', - 'relevancy' + 'relevancy', + 'priority', + 'tag' ]; for (const key in params) { @@ -46,10 +48,14 @@ module.exports = Self => { } try { + const validPriorities = new Set([1, 2, 3]); + if (!validPriorities.has(params.priority)) + throw new UserError(`Valid priorities: ${[...validPriorities]}`); + const provisionalName = params.provisionalName; delete params.provisionalName; - const itemType = await models.ItemType.findById(params.typeFk, myOptions); + const itemType = await models.ItemType.findById(params.typeFk, {fields: ['isLaid']}, myOptions); params.isLaid = itemType.isLaid; @@ -63,13 +69,14 @@ module.exports = Self => { await Self.rawSql(query, null, myOptions); - let nameTag = await models.Tag.findOne({where: {name: 'Nombre temporal'}}); + const nameTag = await models.Tag.findById(params.tag, {fields: ['id']}, myOptions); let newTags = []; - newTags.push({itemFk: item.id, tagFk: nameTag.id, value: provisionalName, priority: '2'}); + newTags.push({itemFk: item.id, tagFk: nameTag.id, value: provisionalName, priority: item.priority}); typeTags.forEach(typeTag => { - newTags.push({itemFk: item.id, tagFk: typeTag.tagFk, value: '', priority: typeTag.priority}); + if (nameTag.id != typeTag.tagFk) + newTags.push({itemFk: item.id, tagFk: typeTag.tagFk, value: '', priority: typeTag.priority}); }); await models.ItemTag.create(newTags, myOptions); diff --git a/modules/item/back/methods/item/specs/new.spec.js b/modules/item/back/methods/item/specs/new.spec.js index 7364faa7d..e34ab2cf5 100644 --- a/modules/item/back/methods/item/specs/new.spec.js +++ b/modules/item/back/methods/item/specs/new.spec.js @@ -11,7 +11,8 @@ describe('item new()', () => { originFk: 1, provisionalName: 'planta', typeFk: 2, - relevancy: 0 + priority: 2, + tag: 1 }; let item = await models.Item.new(itemParams, options); @@ -20,7 +21,7 @@ describe('item new()', () => { item.isLaid = itemType.isLaid; - const temporalNameTag = await models.Tag.findOne({where: {name: 'Nombre temporal'}}, options); + const temporalNameTag = await models.Tag.findById(itemParams.tag, {fields: ['id']}, options); const temporalName = await models.ItemTag.findOne({ where: { @@ -31,7 +32,7 @@ describe('item new()', () => { item = await models.Item.findById(item.id, null, options); - itemType = await models.ItemType.findById(item.typeFk, options); + itemType = await models.ItemType.findById(item.typeFk, {fields: ['isLaid']}, options); item.isLaid = itemType.isLaid; diff --git a/modules/item/front/create/index.html b/modules/item/front/create/index.html index 6deaab1cd..806d0cb62 100644 --- a/modules/item/front/create/index.html +++ b/modules/item/front/create/index.html @@ -16,10 +16,22 @@ + + + + Date: Tue, 17 Jan 2023 14:06:18 +0100 Subject: [PATCH 29/88] feat: el pdf de las rutas se descarga en un zip --- .../route/back/methods/route/downloadZip.js | 62 +++++++++++++++++++ modules/route/back/models/route.js | 1 + modules/route/front/index/index.js | 14 +++-- 3 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 modules/route/back/methods/route/downloadZip.js diff --git a/modules/route/back/methods/route/downloadZip.js b/modules/route/back/methods/route/downloadZip.js new file mode 100644 index 000000000..597f1d1f6 --- /dev/null +++ b/modules/route/back/methods/route/downloadZip.js @@ -0,0 +1,62 @@ +const JSZip = require('jszip'); + +module.exports = Self => { + Self.remoteMethodCtx('downloadZip', { + description: 'Download a zip file with multiple routes pdfs', + accessType: 'READ', + accepts: [ + { + arg: 'id', + type: 'string', + description: 'The routes ids', + } + ], + returns: [ + { + arg: 'body', + type: 'file', + root: true + }, { + arg: 'Content-Type', + type: 'string', + http: {target: 'header'} + }, { + arg: 'Content-Disposition', + type: 'string', + http: {target: 'header'} + } + ], + http: { + path: '/downloadZip', + verb: 'GET' + } + }); + + Self.downloadZip = async function(ctx, id, options) { + const models = Self.app.models; + const myOptions = {}; + const zip = new JSZip(); + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const ids = id.split(','); + for (let id of ids) { + ctx.args.id = id; + const routePdf = await models.Route.driverRoutePdf(ctx, id); + const fileName = extractFileName(routePdf[2]); + const body = routePdf[0]; + + zip.file(fileName, body); + } + + const stream = zip.generateNodeStream({streamFiles: true}); + + return [stream, 'application/zip', `filename="download.zip"`]; + }; + + function extractFileName(str) { + const matches = str.match(/"(.*?)"/); + return matches ? matches[1] : str; + } +}; diff --git a/modules/route/back/models/route.js b/modules/route/back/models/route.js index 08cabd30e..883f4597e 100644 --- a/modules/route/back/models/route.js +++ b/modules/route/back/models/route.js @@ -13,6 +13,7 @@ module.exports = Self => { require('../methods/route/driverRoutePdf')(Self); require('../methods/route/driverRouteEmail')(Self); require('../methods/route/sendSms')(Self); + require('../methods/route/downloadZip')(Self); Self.validate('kmStart', validateDistance, { message: 'Distance must be lesser than 1000' diff --git a/modules/route/front/index/index.js b/modules/route/front/index/index.js index 9258c8fac..273657cec 100644 --- a/modules/route/front/index/index.js +++ b/modules/route/front/index/index.js @@ -34,12 +34,16 @@ export default class Controller extends Section { } showRouteReport() { - const routes = []; + const routesIds = []; for (let route of this.checked) - routes.push(route.id); - const routesId = routes.join(','); - - this.vnReport.show(`Routes/${routesId}/driver-route-pdf`); + routesIds.push(route.id); + const stringRoutesIds = routesIds.join(','); + const serializedParams = this.$httpParamSerializer({ + access_token: this.vnToken.token, + id: stringRoutesIds + }); + const url = `api/Routes/downloadZip?${serializedParams}`; + window.open(url, '_blank'); } openClonationDialog() { From 849f4e1a6d4368db50a7e55910219c5af1064c85 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 17 Jan 2023 14:24:04 +0100 Subject: [PATCH 30/88] fix: frontTest --- modules/route/front/index/index.spec.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/route/front/index/index.spec.js b/modules/route/front/index/index.spec.js index 05dd56433..c1f414d5e 100644 --- a/modules/route/front/index/index.spec.js +++ b/modules/route/front/index/index.spec.js @@ -44,17 +44,15 @@ describe('Component vnRouteIndex', () => { describe('showRouteReport()', () => { it('should call to the vnReport show method', () => { - controller.vnReport.show = jest.fn(); + jest.spyOn(window, 'open').mockReturnThis(); const data = controller.$.model.data; data[0].checked = true; data[2].checked = true; - const routeIds = '1,3'; - controller.showRouteReport(); - expect(controller.vnReport.show).toHaveBeenCalledWith(`Routes/${routeIds}/driver-route-pdf`); + expect(window.open).toHaveBeenCalled(); }); }); From be5f987b0a16699b4475973a5664a455d50313f6 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 18 Jan 2023 13:14:49 +0100 Subject: [PATCH 31/88] refs #4945 added defaultTag, validPriorities, defaultPriority in itemConfig --- .../230201/00-validPriorities_ItemConfig.sql | 8 ++++++++ db/dump/fixtures.sql | 4 ++++ e2e/helpers/selectors.js | 2 +- e2e/paths/04-item/10_item_log.spec.js | 10 +++++----- modules/item/back/methods/item/new.js | 7 +++---- modules/item/back/models/item-config.json | 18 +++++++++++++++++- modules/item/front/create/index.js | 19 ++++++++++++++----- 7 files changed, 52 insertions(+), 16 deletions(-) create mode 100644 db/changes/230201/00-validPriorities_ItemConfig.sql diff --git a/db/changes/230201/00-validPriorities_ItemConfig.sql b/db/changes/230201/00-validPriorities_ItemConfig.sql new file mode 100644 index 000000000..2e22352fe --- /dev/null +++ b/db/changes/230201/00-validPriorities_ItemConfig.sql @@ -0,0 +1,8 @@ +ALTER TABLE `vn`.`itemConfig` ADD defaultTag INT DEFAULT 56 NOT NULL; +ALTER TABLE `vn`.`itemConfig` ADD CONSTRAINT itemConfig_FK FOREIGN KEY (defaultTag) REFERENCES vn.tag(id); +ALTER TABLE `vn`.`itemConfig` ADD validPriorities varchar(50) DEFAULT '[1,2,3]' NOT NULL; +ALTER TABLE `vn`.`itemConfig` ADD defaultPriority INT DEFAULT 2 NOT NULL; + +INSERT INTO `salix`.`ACL` +(model, property, accessType, permission, principalType, principalId) +VALUES('ItemConfig', '*', 'READ', 'ALLOW', 'ROLE', 'buyer'); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index fba094ef4..5d6849cef 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2719,6 +2719,10 @@ INSERT INTO `vn`.`collection` (`id`, `created`, `workerFk`, `stateFk`, `itemPack VALUES (3, util.VN_NOW(), 1107, 5, NULL, 0, 0, 1, NULL, NULL); +INSERT INTO `vn`.`itemConfig` (`id`, `isItemTagTriggerDisabled`, `monthToDeactivate`, `wasteRecipients`, `validPriorities`, `defaultPriority`, `defaultTag`) + VALUES + (0, 0, 24, '', '[1,2,3]', 2, 56); + INSERT INTO `vn`.`ticketCollection` (`ticketFk`, `collectionFk`, `created`, `level`, `wagon`, `smartTagFk`, `usedShelves`, `itemCount`, `liters`) VALUES (9, 3, util.VN_NOW(), NULL, 0, NULL, NULL, NULL, NULL); diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 04f2d4569..c2ad63484 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -522,7 +522,7 @@ export default { }, itemLog: { anyLineCreated: 'vn-item-log > vn-log vn-tbody > vn-tr', - fourthLineCreatedProperty: 'vn-item-log > vn-log vn-tbody > vn-tr:nth-child(4) table tr:nth-child(3) td.after', + fifthLineCreatedProperty: 'vn-item-log > vn-log vn-tbody > vn-tr:nth-child(5) table tr:nth-child(2) td.after', }, ticketSummary: { header: 'vn-ticket-summary > vn-card > h5', diff --git a/e2e/paths/04-item/10_item_log.spec.js b/e2e/paths/04-item/10_item_log.spec.js index f3ff6001c..2a885fe6f 100644 --- a/e2e/paths/04-item/10_item_log.spec.js +++ b/e2e/paths/04-item/10_item_log.spec.js @@ -48,17 +48,17 @@ describe('Item log path', () => { await page.accessToSection('item.card.log'); }); - it(`should confirm the log is showing 4 entries`, async() => { + it(`should confirm the log is showing 5 entries`, async() => { await page.waitForSelector(selectors.itemLog.anyLineCreated); const anyLineCreatedCount = await page.countElement(selectors.itemLog.anyLineCreated); - expect(anyLineCreatedCount).toEqual(4); + expect(anyLineCreatedCount).toEqual(5); }); it(`should confirm the log is showing the intrastat for the created item`, async() => { - const fourthLineCreatedProperty = await page - .waitToGetProperty(selectors.itemLog.fourthLineCreatedProperty, 'innerText'); + const fifthLineCreatedProperty = await page + .waitToGetProperty(selectors.itemLog.fifthLineCreatedProperty, 'innerText'); - expect(fourthLineCreatedProperty).toEqual('Coral y materiales similares'); + expect(fifthLineCreatedProperty).toEqual('Coral y materiales similares'); }); }); diff --git a/modules/item/back/methods/item/new.js b/modules/item/back/methods/item/new.js index b84072a8a..0057cb50f 100644 --- a/modules/item/back/methods/item/new.js +++ b/modules/item/back/methods/item/new.js @@ -37,7 +37,6 @@ module.exports = Self => { 'typeFk', 'intrastatFk', 'originFk', - 'relevancy', 'priority', 'tag' ]; @@ -48,9 +47,9 @@ module.exports = Self => { } try { - const validPriorities = new Set([1, 2, 3]); - if (!validPriorities.has(params.priority)) - throw new UserError(`Valid priorities: ${[...validPriorities]}`); + const itemConfig = await models.ItemConfig.findOne({fields: ['validPriorities']}, myOptions); + if (!itemConfig.validPriorities.includes(params.priority)) + throw new UserError(`Valid priorities: ${[...itemConfig.validPriorities]}`); const provisionalName = params.provisionalName; delete params.provisionalName; diff --git a/modules/item/back/models/item-config.json b/modules/item/back/models/item-config.json index 364879986..36d25e0bb 100644 --- a/modules/item/back/models/item-config.json +++ b/modules/item/back/models/item-config.json @@ -16,6 +16,22 @@ "wasteRecipients": { "type": "string", "description": "Buyers waste report recipients" + }, + "validPriorities": { + "type": "array" + }, + "defaultPriority": { + "type": "int" + }, + "defaultTag": { + "type": "int" + } + }, + "relations": { + "tag": { + "type": "belongsTo", + "model": "Tag", + "foreignKey": "defaultTag" } } -} \ No newline at end of file +} diff --git a/modules/item/front/create/index.js b/modules/item/front/create/index.js index c3082ffd7..c9a121cd4 100644 --- a/modules/item/front/create/index.js +++ b/modules/item/front/create/index.js @@ -4,11 +4,20 @@ import Section from 'salix/components/section'; class Controller extends Section { constructor($element, $) { super($element, $); - this.item = { - relevancy: 0, - priority: 2, - tag: 1 - }; + this.fetchDefaultPriorityTag(); + } + + fetchDefaultPriorityTag() { + const filter = {fields: ['defaultPriority', 'defaultTag'], limit: 1}; + this.$http.get(`ItemConfigs`, {filter}) + .then(res => { + if (res.data) { + this.item = { + priority: res.data[0].defaultPriority, + tag: res.data[0].defaultTag + }; + } + }); } onSubmit() { From 89a7aa58877fb420a6ee0453b3e18a0320b40282 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 18 Jan 2023 14:51:03 +0100 Subject: [PATCH 32/88] refs #4945 refresh structure --- db/dump/structure.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 4626279e4..772d6055d 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -80203,3 +80203,4 @@ USE `vncontrol`; -- Dump completed on 2022-11-21 7:57:28 + From a5decd31665101d916da4b762950b088eed4c9e9 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 20 Jan 2023 07:42:15 +0100 Subject: [PATCH 33/88] Updated version --- CHANGELOG.md | 29 ++++++++++++++++++++--------- db/changes/230401/.gitkeep | 0 2 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 db/changes/230401/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index 98815430e..f8a04cfe8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,20 +5,31 @@ 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). -## [2302.01] - 2023-01-12 +## [2304.01] - 2023-02-09 ### Added -- [General](Inicio) Permite recuperar la contraseña -- [Ticket](Opciones) Subir albarán a Docuware -- [Ticket](Opciones) Enviar correo con PDF de Docuware -- [Artículo](Datos Básicos) Añadido campo Unidades/Caja +- ### Changed -- [Reclamaciones](Descriptor) Cambiado el campo Agencia por Zona -- [Tickets](Líneas preparadas) Actualizada sección para que sea más visual +- ### Fixed -- [General] Al utilizar el traductor de Google se descuadraban los iconos +- + +## [2302.01] - 2023-01-26 + +### Added +- (General -> Inicio) Permite recuperar la contraseña +- (Tickets -> Opciones) Subir albarán a Docuware +- (Tickets -> Opciones) Enviar correo con PDF de Docuware +- (Artículos -> Datos Básicos) Añadido campo Unidades/Caja + +### Changed +- (Reclamaciones -> Descriptor) Cambiado el campo Agencia por Zona +- (Tickets -> Líneas preparadas) Actualizada sección para que sea más visual + +### Fixed +- (General) Al utilizar el traductor de Google se descuadraban los iconos ### Removed -- [Tickets](Control clientes) Eliminada sección +- (Tickets -> Control clientes) Eliminada sección diff --git a/db/changes/230401/.gitkeep b/db/changes/230401/.gitkeep new file mode 100644 index 000000000..e69de29bb From 208f6f50d003cf33fc3db54410ab9a100a60a867 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 20 Jan 2023 07:43:27 +0100 Subject: [PATCH 34/88] Updated package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9633751a0..2e0fb9ae8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "9.0.0", + "version": "230401", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From a3b580e27d43511c2a29e6aaccf07c7c0c97402e Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 20 Jan 2023 08:01:19 +0100 Subject: [PATCH 35/88] refs #4945 item.relevancy comment --- db/changes/230201/00-validPriorities_ItemConfig.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/db/changes/230201/00-validPriorities_ItemConfig.sql b/db/changes/230201/00-validPriorities_ItemConfig.sql index 2e22352fe..a793997d0 100644 --- a/db/changes/230201/00-validPriorities_ItemConfig.sql +++ b/db/changes/230201/00-validPriorities_ItemConfig.sql @@ -2,6 +2,7 @@ ALTER TABLE `vn`.`itemConfig` ADD defaultTag INT DEFAULT 56 NOT NULL; ALTER TABLE `vn`.`itemConfig` ADD CONSTRAINT itemConfig_FK FOREIGN KEY (defaultTag) REFERENCES vn.tag(id); ALTER TABLE `vn`.`itemConfig` ADD validPriorities varchar(50) DEFAULT '[1,2,3]' NOT NULL; ALTER TABLE `vn`.`itemConfig` ADD defaultPriority INT DEFAULT 2 NOT NULL; +ALTER TABLE `vn`.`item` MODIFY COLUMN relevancy tinyint(1) DEFAULT 0 NOT NULL COMMENT 'La web ordena de forma descendiente por este campo para mostrar los artículos'; INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) From c77f1b17a60b72f0ec7d0dfde4803742ca9f17b1 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 20 Jan 2023 08:32:18 +0100 Subject: [PATCH 36/88] movida sql a nueva carpeta changes --- db/changes/{230201 => 230401}/00-ACL_tag_update.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{230201 => 230401}/00-ACL_tag_update.sql (100%) diff --git a/db/changes/230201/00-ACL_tag_update.sql b/db/changes/230401/00-ACL_tag_update.sql similarity index 100% rename from db/changes/230201/00-ACL_tag_update.sql rename to db/changes/230401/00-ACL_tag_update.sql From ace7a5939ece2caeb159351e86f3bd966fa4e0c6 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 20 Jan 2023 08:33:59 +0100 Subject: [PATCH 37/88] move to changes 230401 --- db/changes/230401/.gitkeep | 0 db/changes/{230201 => 230401}/00-createWorker.sql | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 db/changes/230401/.gitkeep rename db/changes/{230201 => 230401}/00-createWorker.sql (100%) diff --git a/db/changes/230401/.gitkeep b/db/changes/230401/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/db/changes/230201/00-createWorker.sql b/db/changes/230401/00-createWorker.sql similarity index 100% rename from db/changes/230201/00-createWorker.sql rename to db/changes/230401/00-createWorker.sql From 7148da7b72c1f26f563baa5e12a763eed0dd5817 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 20 Jan 2023 08:53:30 +0100 Subject: [PATCH 38/88] feat: cuando se descarga una sola factura, no descarga el zip --- CHANGELOG.md | 19 ++++++++++--------- modules/route/front/index/index.js | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8a04cfe8..bd3a13a7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,25 +8,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [2304.01] - 2023-02-09 ### Added -- +- ### Changed -- +- ### Fixed -- +- ## [2302.01] - 2023-01-26 ### Added -- (General -> Inicio) Permite recuperar la contraseña -- (Tickets -> Opciones) Subir albarán a Docuware -- (Tickets -> Opciones) Enviar correo con PDF de Docuware -- (Artículos -> Datos Básicos) Añadido campo Unidades/Caja +- (General -> Inicio) Permite recuperar la contraseña +- (Tickets -> Opciones) Subir albarán a Docuware +- (Tickets -> Opciones) Enviar correo con PDF de Docuware +- (Artículos -> Datos Básicos) Añadido campo Unidades/Caja +- (Rutas) Al descargar varias facturas se comprime en un zip ### Changed -- (Reclamaciones -> Descriptor) Cambiado el campo Agencia por Zona -- (Tickets -> Líneas preparadas) Actualizada sección para que sea más visual +- (Reclamaciones -> Descriptor) Cambiado el campo Agencia por Zona +- (Tickets -> Líneas preparadas) Actualizada sección para que sea más visual ### Fixed - (General) Al utilizar el traductor de Google se descuadraban los iconos diff --git a/modules/route/front/index/index.js b/modules/route/front/index/index.js index 273657cec..94f6db09c 100644 --- a/modules/route/front/index/index.js +++ b/modules/route/front/index/index.js @@ -38,12 +38,18 @@ export default class Controller extends Section { for (let route of this.checked) routesIds.push(route.id); const stringRoutesIds = routesIds.join(','); - const serializedParams = this.$httpParamSerializer({ - access_token: this.vnToken.token, - id: stringRoutesIds - }); - const url = `api/Routes/downloadZip?${serializedParams}`; - window.open(url, '_blank'); + + if (this.checked.length <= 1) { + const url = `api/Routes/${stringRoutesIds}/driver-route-pdf?access_token=${this.vnToken.token}`; + window.open(url, '_blank'); + } else { + const serializedParams = this.$httpParamSerializer({ + access_token: this.vnToken.token, + id: stringRoutesIds + }); + const url = `api/Routes/downloadZip?${serializedParams}`; + window.open(url, '_blank'); + } } openClonationDialog() { From f30b1ecff1f3e2e2811ffa5a318c919f7db48dd3 Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 20 Jan 2023 10:03:00 +0100 Subject: [PATCH 39/88] refs #4927 changed hook for validateAsync --- modules/supplier/back/models/supplier.js | 41 ++++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index cba220af8..4e509aafc 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -113,24 +113,37 @@ module.exports = Self => { throw new UserError('You can not modify is pay method checked'); }); + Self.validateAsync('name', 'countryFk', hasSupplierSameName, { + message: 'A supplier with the same name already exists. Change the country.' + }); + + async function hasSupplierSameName(err, done) { + if (!this.name || !this.countryFk) done(); + const supplier = await Self.app.models.Supplier.findOne( + { + where: { + name: this.name, + countryFk: this.countryFk + }, + fields: ['id'] + }); + + if (supplier && supplier.id != this.id) + err(); + + done(); + } + Self.observe('before save', async function(ctx) { const changes = ctx.data || ctx.instance; const orgData = ctx.currentInstance; + + const socialName = changes.name || orgData.name; const hasChanges = orgData && changes; + const socialNameChanged = hasChanges + && orgData.socialName != socialName; - if (hasChanges) { - const name = changes.name || orgData.name; - const nameChanged = hasChanges && orgData.name != name; - const countryFk = changes.countryFk || orgData.countryFk; - const countryChanged = hasChanges && orgData.countryFk != countryFk; - - if (nameChanged || countryChanged) { - if (!isAlpha(name)) throw new UserError('The social name has an invalid format'); - - const supplier = await Self.app.models.Supplier.findOne({where: {name, countryFk}, fields: ['id']}); - if (supplier) - throw new UserError('A supplier with the same name already exists. Change the country.'); - } - } + if ((socialNameChanged) && !isAlpha(socialName)) + throw new UserError('The social name has an invalid format'); }); }; From b281a51d90e7ef3b813bf418e74b0b4ce04b13c0 Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 20 Jan 2023 10:33:23 +0100 Subject: [PATCH 40/88] refs #4927 refresh structure --- db/dump/structure.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 772d6055d..4626279e4 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -80203,4 +80203,3 @@ USE `vncontrol`; -- Dump completed on 2022-11-21 7:57:28 - From a473d3a6f9809848449abb43295ebe682b0da303 Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 20 Jan 2023 12:01:13 +0100 Subject: [PATCH 41/88] refs #4945 changed input-number for autocomplete --- e2e/helpers/selectors.js | 2 +- e2e/paths/04-item/07_create.spec.js | 4 ++-- modules/item/front/create/index.html | 12 +++++++----- modules/item/front/create/index.js | 11 ++++++++--- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index a8131a458..e9d9d0580 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -428,7 +428,7 @@ export default { }, itemCreateView: { temporalName: 'vn-item-create vn-textfield[ng-model="$ctrl.item.provisionalName"]', - priority: 'vn-input-number[ng-model="$ctrl.item.priority"]', + priority: 'vn-autocomplete[ng-model="$ctrl.item.priority"]', type: 'vn-autocomplete[ng-model="$ctrl.item.typeFk"]', intrastat: 'vn-autocomplete[ng-model="$ctrl.item.intrastatFk"]', origin: 'vn-autocomplete[ng-model="$ctrl.item.originFk"]', diff --git a/e2e/paths/04-item/07_create.spec.js b/e2e/paths/04-item/07_create.spec.js index 8319a8dff..33324cdba 100644 --- a/e2e/paths/04-item/07_create.spec.js +++ b/e2e/paths/04-item/07_create.spec.js @@ -41,7 +41,7 @@ describe('Item Create', () => { await page.autocompleteSearch(selectors.itemCreateView.type, 'Crisantemo'); await page.autocompleteSearch(selectors.itemCreateView.intrastat, 'Coral y materiales similares'); await page.autocompleteSearch(selectors.itemCreateView.origin, 'Holand'); - await page.overwrite(selectors.itemCreateView.priority, '100'); + await page.clearInput(selectors.itemCreateView.priority); await page.waitToClick(selectors.itemCreateView.createButton); const message = await page.waitForSnackbar(); @@ -49,7 +49,7 @@ describe('Item Create', () => { }); it('should create the Infinity Gauntlet item', async() => { - await page.overwrite(selectors.itemCreateView.priority, '2'); + await page.autocompleteSearch(selectors.itemCreateView.priority, '2'); await page.waitToClick(selectors.itemCreateView.createButton); const message = await page.waitForSnackbar(); diff --git a/modules/item/front/create/index.html b/modules/item/front/create/index.html index 806d0cb62..15e212250 100644 --- a/modules/item/front/create/index.html +++ b/modules/item/front/create/index.html @@ -16,22 +16,24 @@ - - + ng-model="$ctrl.item.priority" + show-field="priority" + value-field="priority"> + { if (res.data) { + const dataRow = res.data[0]; + dataRow.validPriorities.forEach(priority => { + this.validPriorities.push({priority}); + }); this.item = { - priority: res.data[0].defaultPriority, - tag: res.data[0].defaultTag + priority: dataRow.defaultPriority, + tag: dataRow.defaultTag }; } }); From 30885a499ee19016ec87dc55609fc2a83b35d608 Mon Sep 17 00:00:00 2001 From: jgallego Date: Sat, 21 Jan 2023 07:29:27 +0100 Subject: [PATCH 42/88] link --- print/templates/email/printer-setup/locale/es.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/print/templates/email/printer-setup/locale/es.yml b/print/templates/email/printer-setup/locale/es.yml index 77a3a7299..7361e5ed3 100644 --- a/print/templates/email/printer-setup/locale/es.yml +++ b/print/templates/email/printer-setup/locale/es.yml @@ -8,8 +8,8 @@ description: https://www.youtube.com/watch?v=qhb0kgQF3o8. También necesitarás el QLabel, el programa para imprimir las cintas. - downloadFrom: Puedes descargarlo desde este enlace https://godex.s3-accelerate.amazonaws.com/gGnOPoojkP6vC1lgmrbEqQ.file?v01 + downloadFrom: Puedes descargarlo desde este enlace https://cdn.verdnatura.es/public/QLabel_IV_V1.37_Install_en.exe downloadDriver: En este enlace puedes descargar el driver de la impresora https://es.seagullscientific.com/support/downloads/drivers/godex/download/ sections: From 96becec9d3450c847184c091b8a10ea84eaaa9ea Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 23 Jan 2023 10:12:34 +0100 Subject: [PATCH 43/88] refs #4564 mixin vn-report created --- loopback/util/not-found-error.js | 9 ++++++ print/core/mixins/vn-report.js | 22 +++++++++++++ print/core/report.js | 54 +++++++++++++++----------------- 3 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 loopback/util/not-found-error.js create mode 100644 print/core/mixins/vn-report.js diff --git a/loopback/util/not-found-error.js b/loopback/util/not-found-error.js new file mode 100644 index 000000000..7a05254f9 --- /dev/null +++ b/loopback/util/not-found-error.js @@ -0,0 +1,9 @@ +module.exports = class NotFoundError extends Error { + constructor(message = 'Not found', code = 'NOT_FOUND', ...translateArgs) { + super(message); + this.name = 'NotFoundError'; + this.statusCode = 404; + this.code = code; + this.translateArgs = translateArgs; + } +}; diff --git a/print/core/mixins/vn-report.js b/print/core/mixins/vn-report.js new file mode 100644 index 000000000..66b9704e7 --- /dev/null +++ b/print/core/mixins/vn-report.js @@ -0,0 +1,22 @@ +const Component = require(`vn-print/core/component`); +const reportHeader = new Component('report-header'); +const reportFooter = new Component('report-footer'); +const reportBody = new Component('report-body'); +const NotFoundError = require('vn-loopback/util/not-found-error'); + +module.exports = { + components: { + 'report-body': reportBody.build(), + 'report-header': reportHeader.build(), + 'report-footer': reportFooter.build() + }, + methods: { + checkMainEntity: function(entity) { + if (entity == null) + throw new NotFoundError(); + }, + dated: function(filters, date, format) { + return filters.date(date, format); + } + }, +}; diff --git a/print/core/report.js b/print/core/report.js index d37b79c6d..c5182d1a8 100644 --- a/print/core/report.js +++ b/print/core/report.js @@ -23,43 +23,39 @@ class Report extends Component { } async toPdfStream() { - try { - const template = await this.render(); - const defaultOptions = Object.assign({}, config.pdf); + const template = await this.render(); + const defaultOptions = Object.assign({}, config.pdf); - const optionsPath = `${this.path}/options.json`; - const fullPath = path.resolve(__dirname, optionsPath); - let options = defaultOptions; - if (fs.existsSync(fullPath)) - options = require(optionsPath); + const optionsPath = `${this.path}/options.json`; + const fullPath = path.resolve(__dirname, optionsPath); + let options = defaultOptions; + if (fs.existsSync(fullPath)) + options = require(optionsPath); - return new Promise(resolve => { - Cluster.pool.queue({}, async({page}) => { - await page.emulateMediaType('screen'); - await page.setContent(template); + return new Promise(resolve => { + Cluster.pool.queue({}, async({page}) => { + await page.emulateMediaType('screen'); + await page.setContent(template); - const element = await page.$('#pageFooter'); + const element = await page.$('#pageFooter'); - let footer = '\n'; - if (element) { - footer = await page.evaluate(el => { - const html = el.innerHTML; - el.remove(); - return html; - }, element); - } + let footer = '\n'; + if (element) { + footer = await page.evaluate(el => { + const html = el.innerHTML; + el.remove(); + return html; + }, element); + } - options.headerTemplate = '\n'; - options.footerTemplate = footer; + options.headerTemplate = '\n'; + options.footerTemplate = footer; - const stream = await page.pdf(options); + const stream = await page.pdf(options); - resolve(stream); - }); + resolve(stream); }); - } catch (e) { - console.log('ERROR CATCHED:', e); - } + }); } /** From 765e4ed3328047a433fbbac188659694c10c5755 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 23 Jan 2023 13:15:30 +0100 Subject: [PATCH 44/88] refs #4564 all reports refactored --- print/core/mixins/vn-report.js | 3 +- .../balance-compensation.html | 4 +- .../balance-compensation.js | 26 ++------- .../campaign-metrics/campaign-metrics.html | 4 +- .../campaign-metrics/campaign-metrics.js | 25 ++------- .../claim-pickup-order.html | 2 +- .../claim-pickup-order/claim-pickup-order.js | 36 ++---------- .../client-debt-statement.html | 4 +- .../client-debt-statement.js | 42 ++------------ .../collection-label/collection-label.js | 11 +--- .../credit-request/credit-request.html | 2 +- .../reports/credit-request/credit-request.js | 19 +------ .../reports/delivery-note/delivery-note.html | 4 +- .../reports/delivery-note/delivery-note.js | 56 ++++--------------- .../reports/driver-route/driver-route.html | 4 +- .../reports/driver-route/driver-route.js | 24 ++------ .../reports/entry-order/entry-order.html | 2 +- .../reports/entry-order/entry-order.js | 30 ++-------- .../expedition-pallet-label.js | 11 +--- .../reports/exportation/exportation.html | 4 +- .../reports/exportation/exportation.js | 28 ++-------- .../extra-community/extra-community.html | 4 +- .../extra-community/extra-community.js | 41 ++++---------- .../incoterms-authorization.js | 17 +----- .../invoice-incoterms/invoice-incoterms.html | 2 +- .../invoice-incoterms/invoice-incoterms.js | 33 ++--------- print/templates/reports/invoice/invoice.html | 6 +- print/templates/reports/invoice/invoice.js | 53 ++++-------------- .../reports/invoiceIn/invoiceIn.html | 4 +- .../templates/reports/invoiceIn/invoiceIn.js | 37 +++--------- .../reports/item-label/item-label.html | 2 +- .../reports/item-label/item-label.js | 21 ++----- .../reports/letter-debtor/letter-debtor.html | 4 +- .../reports/letter-debtor/letter-debtor.js | 33 ++--------- .../reports/previa-label/previa-label.js | 22 ++------ print/templates/reports/receipt/receipt.js | 25 ++------- .../reports/sepa-core/sepa-core.html | 2 +- .../templates/reports/sepa-core/sepa-core.js | 46 ++------------- .../supplier-campaign-metrics.html | 6 +- .../supplier-campaign-metrics.js | 29 ++-------- .../vehicle-event-expired.html | 2 +- .../vehicle-event-expired.js | 19 ++----- print/templates/reports/zone/zone.html | 2 +- print/templates/reports/zone/zone.js | 18 ++---- 44 files changed, 169 insertions(+), 600 deletions(-) diff --git a/print/core/mixins/vn-report.js b/print/core/mixins/vn-report.js index 66b9704e7..4831d8cd9 100644 --- a/print/core/mixins/vn-report.js +++ b/print/core/mixins/vn-report.js @@ -15,7 +15,8 @@ module.exports = { if (entity == null) throw new NotFoundError(); }, - dated: function(filters, date, format) { + formatDate: function(date, format) { + const filters = this.$options.filters; return filters.date(date, format); } }, diff --git a/print/templates/reports/balance-compensation/balance-compensation.html b/print/templates/reports/balance-compensation/balance-compensation.html index 59af1bd11..1e9aa5661 100644 --- a/print/templates/reports/balance-compensation/balance-compensation.html +++ b/print/templates/reports/balance-compensation/balance-compensation.html @@ -3,7 +3,7 @@
-

{{$t('Place')}} {{currentDate()}}

+

{{$t('Place')}} {{formatDate(new Date(), '%d-%m-%Y')}}

{{$t('Compensation') | uppercase}}

{{$t('In one hand')}}:

@@ -17,7 +17,7 @@

{{$t('Agree') | uppercase}}

- {{$t('Date')}} {{client.payed | date('%d-%m-%Y')}} {{$t('Compensate')}} {{client.amountPaid}} € + {{$t('Date')}} {{formatDate(client.payed, '%d-%m-%Y')}} {{$t('Compensate')}} {{client.amountPaid}} € {{$t('From client')}} {{client.name}} {{$t('Toclient')}} {{company.name}}.

diff --git a/print/templates/reports/balance-compensation/balance-compensation.js b/print/templates/reports/balance-compensation/balance-compensation.js index 98a9cf577..bae7c5c3c 100644 --- a/print/templates/reports/balance-compensation/balance-compensation.js +++ b/print/templates/reports/balance-compensation/balance-compensation.js @@ -1,28 +1,12 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'balance-compensation', + mixins: [vnReport], async serverPrefetch() { - this.client = await this.fetchClient(this.id); - this.company = await this.fetchCompany(this.id); - }, - methods: { - fetchClient(id) { - return this.findOneFromDef('client', [id]); - }, - fetchCompany(id) { - return this.findOneFromDef('company', [id]); - }, - - currentDate() { - const current = new Date(); - const date = `${current.getDate()}/${current.getMonth() + 1}/${current.getFullYear()}`; - return date; - } - }, - components: { - 'report-body': reportBody.build() + this.client = await this.findOneFromDef('client', [this.id]); + this.checkMainEntity(this.client); + this.company = await this.findOneFromDef('company', [this.id]); }, props: { id: { diff --git a/print/templates/reports/campaign-metrics/campaign-metrics.html b/print/templates/reports/campaign-metrics/campaign-metrics.html index e86d4cd3b..57d616a29 100644 --- a/print/templates/reports/campaign-metrics/campaign-metrics.html +++ b/print/templates/reports/campaign-metrics/campaign-metrics.html @@ -13,11 +13,11 @@ {{$t('From')}} - {{from | date('%d-%m-%Y')}} + {{formatDate(from, '%d-%m-%Y')}} {{$t('To')}} - {{to | date('%d-%m-%Y')}} + {{formatDate(to, '%d-%m-%Y')}} diff --git a/print/templates/reports/campaign-metrics/campaign-metrics.js b/print/templates/reports/campaign-metrics/campaign-metrics.js index 14a4b6a9b..45bca88dc 100755 --- a/print/templates/reports/campaign-metrics/campaign-metrics.js +++ b/print/templates/reports/campaign-metrics/campaign-metrics.js @@ -1,27 +1,12 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'campaign-metrics', + mixins: [vnReport], async serverPrefetch() { - this.client = await this.fetchClient(this.id); - this.sales = await this.fetchSales(this.id, this.from, this.to); - - if (!this.client) - throw new Error('Something went wrong'); - }, - methods: { - fetchClient(id) { - return this.findOneFromDef('client', [id]); - }, - fetchSales(id, from, to) { - return this.rawSqlFromDef('sales', [id, from, to]); - }, - }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() + this.client = await this.findOneFromDef('client', [this.id]); + this.checkMainEntity(this.client); + this.sales = await this.rawSqlFromDef('sales', [this.id, this.from, this.to]); }, props: { id: { diff --git a/print/templates/reports/claim-pickup-order/claim-pickup-order.html b/print/templates/reports/claim-pickup-order/claim-pickup-order.html index b14f5410c..000568ef2 100644 --- a/print/templates/reports/claim-pickup-order/claim-pickup-order.html +++ b/print/templates/reports/claim-pickup-order/claim-pickup-order.html @@ -20,7 +20,7 @@ {{$t('date')}} - {{dated}} + {{formatDate(new Date(), '%d-%m-%Y')}} diff --git a/print/templates/reports/claim-pickup-order/claim-pickup-order.js b/print/templates/reports/claim-pickup-order/claim-pickup-order.js index fc82ee518..cc5cec1ea 100755 --- a/print/templates/reports/claim-pickup-order/claim-pickup-order.js +++ b/print/templates/reports/claim-pickup-order/claim-pickup-order.js @@ -1,36 +1,12 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'claim-pickup-order', + mixins: [vnReport], async serverPrefetch() { - // FORCE FAIL FOR TEST - throw new Error('Something went wrong'); - this.client = await this.fetchClient(this.id); - this.sales = await this.fetchSales(this.id); - - if (!this.client) - throw new Error('Something went wrong'); - }, - computed: { - dated: function() { - const filters = this.$options.filters; - - return filters.date(new Date(), '%d-%m-%Y'); - } - }, - methods: { - fetchClient(id) { - return this.findOneFromDef('client', [id]); - }, - fetchSales(id) { - return this.rawSqlFromDef('sales', [id]); - } - }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() + this.client = await this.findOneFromDef('client', [this.id]); + this.checkMainEntity(this.client); + this.sales = await this.rawSqlFromDef('sales', [this.id]); }, props: { id: { @@ -38,5 +14,5 @@ module.exports = { required: true, description: 'The claim id' } - } + }, }; diff --git a/print/templates/reports/client-debt-statement/client-debt-statement.html b/print/templates/reports/client-debt-statement/client-debt-statement.html index 962af021d..fb7bfd625 100644 --- a/print/templates/reports/client-debt-statement/client-debt-statement.html +++ b/print/templates/reports/client-debt-statement/client-debt-statement.html @@ -13,7 +13,7 @@ {{$t('date')}} - {{dated}} + {{formatDate(new Date(), '%d-%m-%Y');}} @@ -44,7 +44,7 @@ - {{sale.issued | date('%d-%m-%Y')}} + {{formatDate(sale.issued, '%d-%m-%Y');}} {{sale.ref}} {{sale.debtOut}} {{sale.debtIn}} diff --git a/print/templates/reports/client-debt-statement/client-debt-statement.js b/print/templates/reports/client-debt-statement/client-debt-statement.js index 45b97518f..a74595200 100755 --- a/print/templates/reports/client-debt-statement/client-debt-statement.js +++ b/print/templates/reports/client-debt-statement/client-debt-statement.js @@ -1,44 +1,18 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'client-debt-statement', + mixins: [vnReport], async serverPrefetch() { - this.client = await this.fetchClient(this.id); - this.sales = await this.fetchSales(this.id, this.from); - - if (!this.client) - throw new Error('Something went wrong'); - }, - computed: { - dated: function() { - const filters = this.$options.filters; - - return filters.date(new Date(), '%d-%m-%Y'); - } + this.client = await this.findOneFromDef('client', [this.id]); + this.checkMainEntity(this.client); + this.sales = await this.rawSqlFromDef('sales', + [this.from, this.id, this.from, this.id, this.from, this.id, this.from, this.id, this.from, this.id]); }, data() { return {totalBalance: 0.00}; }, methods: { - fetchClient(id) { - return this.findOneFromDef('client', [id]); - }, - fetchSales(id, from) { - return this.rawSqlFromDef('sales', [ - from, - id, - from, - id, - from, - id, - from, - id, - from, - id - ]); - }, getBalance(sale) { if (sale.debtOut) this.totalBalance += parseFloat(sale.debtOut); @@ -63,10 +37,6 @@ module.exports = { return debtIn.toFixed(2); }, }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() - }, props: { id: { type: Number, diff --git a/print/templates/reports/collection-label/collection-label.js b/print/templates/reports/collection-label/collection-label.js index e73afaeea..74024bb56 100644 --- a/print/templates/reports/collection-label/collection-label.js +++ b/print/templates/reports/collection-label/collection-label.js @@ -1,11 +1,10 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); const jsBarcode = require('jsbarcode'); const {DOMImplementation, XMLSerializer} = require('xmldom'); -const UserError = require('vn-loopback/util/user-error'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'collection-label', + mixins: [vnReport], props: { id: { type: Number, @@ -30,8 +29,7 @@ module.exports = { ticketIds = [this.id]; this.labelsData = await this.rawSqlFromDef('labelsData', [ticketIds]); - if (!this.labelsData.length) - throw new UserError('Empty data source'); + this.checkMainEntity(this.labelsData); }, methods: { getBarcode(id) { @@ -62,7 +60,4 @@ module.exports = { return value; }, }, - components: { - 'report-body': reportBody.build() - }, }; diff --git a/print/templates/reports/credit-request/credit-request.html b/print/templates/reports/credit-request/credit-request.html index d5e336809..c8e3f8c34 100644 --- a/print/templates/reports/credit-request/credit-request.html +++ b/print/templates/reports/credit-request/credit-request.html @@ -159,6 +159,6 @@

diff --git a/print/templates/reports/credit-request/credit-request.js b/print/templates/reports/credit-request/credit-request.js index c1aa74e1b..75e0b2263 100755 --- a/print/templates/reports/credit-request/credit-request.js +++ b/print/templates/reports/credit-request/credit-request.js @@ -1,20 +1,7 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body') -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); -const rptCreditRequest = { +module.exports = { name: 'credit-request', - computed: { - dated: function() { - const filters = this.$options.filters; - - return filters.date(new Date(), '%d-%m-%Y'); - } - }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() - } + mixins: [vnReport], }; -module.exports = rptCreditRequest; diff --git a/print/templates/reports/delivery-note/delivery-note.html b/print/templates/reports/delivery-note/delivery-note.html index 06653c949..9f217ba22 100644 --- a/print/templates/reports/delivery-note/delivery-note.html +++ b/print/templates/reports/delivery-note/delivery-note.html @@ -20,7 +20,7 @@ {{$t('date')}} - {{ticket.shipped | date('%d-%m-%Y')}} + {{formatDate(ticket.shipped, '%d-%m-%Y')}} {{$t('packages')}} @@ -231,7 +231,7 @@
{{$t('digitalSignature')}}
-
{{signature.created | date('%d-%m-%Y')}}
+
{{formatDate(signature.created, '%d-%m-%Y')}}
diff --git a/print/templates/reports/delivery-note/delivery-note.js b/print/templates/reports/delivery-note/delivery-note.js index 1a1a57c59..d9544a58c 100755 --- a/print/templates/reports/delivery-note/delivery-note.js +++ b/print/templates/reports/delivery-note/delivery-note.js @@ -1,25 +1,21 @@ const config = require(`vn-print/core/config`); -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportHeader = new Component('report-header'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); const md5 = require('md5'); const fs = require('fs-extra'); module.exports = { name: 'delivery-note', + mixins: [vnReport], async serverPrefetch() { - this.client = await this.fetchClient(this.id); - this.ticket = await this.fetchTicket(this.id); - this.sales = await this.fetchSales(this.id); - this.address = await this.fetchAddress(this.id); - this.services = await this.fetchServices(this.id); - this.taxes = await this.fetchTaxes(this.id); - this.packagings = await this.fetchPackagings(this.id); - this.signature = await this.fetchSignature(this.id); - - if (!this.ticket) - throw new Error('Something went wrong'); + this.ticket = await this.findOneFromDef('ticket', [this.id]); + this.checkMainEntity(this.ticket); + this.client = await this.findOneFromDef('client', [this.id]); + this.sales = await this.rawSqlFromDef('sales', [this.id]); + this.address = await this.findOneFromDef(`address`, [this.id]); + this.services = await this.rawSqlFromDef('services', [this.id]); + this.taxes = await this.rawSqlFromDef('taxes', [this.id]); + this.packagings = await this.rawSqlFromDef('packagings', [this.id]); + this.signature = await this.findOneFromDef('signature', [this.id]); }, data() { return {totalBalance: 0.00}; @@ -61,31 +57,6 @@ module.exports = { } }, methods: { - fetchClient(id) { - return this.findOneFromDef('client', [id]); - }, - fetchTicket(id) { - return this.findOneFromDef('ticket', [id]); - }, - fetchAddress(id) { - return this.findOneFromDef(`address`, [id]); - }, - fetchSignature(id) { - return this.findOneFromDef('signature', [id]); - }, - fetchTaxes(id) { - return this.findOneFromDef(`taxes`, [id]); - }, - fetchSales(id) { - return this.rawSqlFromDef('sales', [id]); - }, - fetchPackagings(id) { - return this.rawSqlFromDef('packagings', [id]); - }, - fetchServices(id) { - return this.rawSqlFromDef('services', [id]); - }, - getSubTotal() { let subTotal = 0.00; this.sales.forEach(sale => { @@ -125,11 +96,6 @@ module.exports = { ).join(', '); } }, - components: { - 'report-body': reportBody.build(), - 'report-header': reportHeader.build(), - 'report-footer': reportFooter.build() - }, props: { id: { type: Number, diff --git a/print/templates/reports/driver-route/driver-route.html b/print/templates/reports/driver-route/driver-route.html index 48489de6f..1475b8e77 100644 --- a/print/templates/reports/driver-route/driver-route.html +++ b/print/templates/reports/driver-route/driver-route.html @@ -16,13 +16,13 @@ {{$t('date')}} - {{route.created | date('%d-%m-%Y')}} + {{formatDate(route.created, '%d-%m-%Y')}} {{$t('vehicle')}} {{route.vehicleTradeMark}} {{route.vehicleModel}} {{$t('time')}} - {{route.time | date('%H:%M')}} + {{formatDate(route.time, '%H:%M')}} {{route.plateNumber}} diff --git a/print/templates/reports/driver-route/driver-route.js b/print/templates/reports/driver-route/driver-route.js index 1b2e8871a..c166e3809 100755 --- a/print/templates/reports/driver-route/driver-route.js +++ b/print/templates/reports/driver-route/driver-route.js @@ -1,9 +1,8 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'driver-route', + mixins: [vnReport], async serverPrefetch() { let ids = this.id; @@ -11,8 +10,8 @@ module.exports = { if (hasMultipleRoutes) ids = this.id.split(','); - const routes = await this.fetchRoutes(ids); - const tickets = await this.fetchTickets(ids); + const routes = await this.rawSqlFromDef('routes', [ids]); + const tickets = await this.rawSqlFromDef('tickets', [ids, ids]); const map = new Map(); @@ -27,20 +26,7 @@ module.exports = { this.routes = routes; - if (!this.routes) - throw new Error('Something went wrong'); - }, - methods: { - fetchRoutes(ids) { - return this.rawSqlFromDef('routes', [ids]); - }, - fetchTickets(ids) { - return this.rawSqlFromDef('tickets', [ids, ids]); - } - }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() + this.checkMainEntity(this.routes); }, props: { id: { diff --git a/print/templates/reports/entry-order/entry-order.html b/print/templates/reports/entry-order/entry-order.html index 26294787b..5d362dea9 100644 --- a/print/templates/reports/entry-order/entry-order.html +++ b/print/templates/reports/entry-order/entry-order.html @@ -16,7 +16,7 @@ {{$t('date')}} - {{entry.landed | date('%d-%m-%Y')}} + {{formatDate(entry.landed,'%d-%m-%Y')}} {{$t('ref')}} diff --git a/print/templates/reports/entry-order/entry-order.js b/print/templates/reports/entry-order/entry-order.js index 22c5b55fe..d31ad1a36 100755 --- a/print/templates/reports/entry-order/entry-order.js +++ b/print/templates/reports/entry-order/entry-order.js @@ -1,31 +1,18 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportHeader = new Component('report-header'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'entry-order', + mixins: [vnReport], async serverPrefetch() { - this.supplier = await this.fetchSupplier(this.id); - this.entry = await this.fetchEntry(this.id); - this.buys = await this.fetchBuys(this.id); - - if (!this.entry) - throw new Error('Something went wrong'); + this.entry = await this.findOneFromDef('entry', [this.id]); + this.checkMainEntity(this.entry); + this.supplier = await this.findOneFromDef('supplier', [this.id]); + this.buys = await this.rawSqlFromDef('buys', [this.id]); }, data() { return {totalBalance: 0.00}; }, methods: { - fetchSupplier(id) { - return this.findOneFromDef('supplier', [id]); - }, - fetchEntry(id) { - return this.findOneFromDef('entry', [id]); - }, - fetchBuys(id) { - return this.rawSqlFromDef('buys', [id]); - }, getTotal() { let total = 0.00; this.buys.forEach(buy => { @@ -35,11 +22,6 @@ module.exports = { return total; } }, - components: { - 'report-body': reportBody.build(), - 'report-header': reportHeader.build(), - 'report-footer': reportFooter.build() - }, props: { id: { type: Number, 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 0e8c297e8..321862671 100644 --- a/print/templates/reports/expedition-pallet-label/expedition-pallet-label.js +++ b/print/templates/reports/expedition-pallet-label/expedition-pallet-label.js @@ -1,12 +1,11 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); +const vnReport = require('../../../core/mixins/vn-report.js'); const jsBarcode = require('jsbarcode'); const {DOMImplementation, XMLSerializer} = require('xmldom'); -const UserError = require('vn-loopback/util/user-error'); const qrcode = require('qrcode'); module.exports = { name: 'expedition-pallet-label', + mixins: [vnReport], props: { id: { type: Number, @@ -33,8 +32,7 @@ module.exports = { }); this.QR = await this.getQR(QRdata); - if (!this.labelsData.length) - throw new UserError('Empty data source'); + this.checkMainEntity(this.labelsData); }, methods: { getQR(id) { @@ -56,7 +54,4 @@ module.exports = { return xmlSerializer.serializeToString(svgNode); }, }, - components: { - 'report-body': reportBody.build() - }, }; diff --git a/print/templates/reports/exportation/exportation.html b/print/templates/reports/exportation/exportation.html index 920e32a48..0800c024d 100644 --- a/print/templates/reports/exportation/exportation.html +++ b/print/templates/reports/exportation/exportation.html @@ -3,7 +3,7 @@

{{$t('title')}}

{{$t('toAttention')}}

-

+

  • @@ -32,4 +32,4 @@ - \ No newline at end of file + diff --git a/print/templates/reports/exportation/exportation.js b/print/templates/reports/exportation/exportation.js index 9f39aa1a1..123b350ee 100755 --- a/print/templates/reports/exportation/exportation.js +++ b/print/templates/reports/exportation/exportation.js @@ -1,33 +1,13 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'exportation', + mixins: [vnReport], async serverPrefetch() { - this.invoice = await this.fetchInvoice(this.reference); - - if (!this.invoice) - throw new Error('Something went wrong'); - + this.invoice = await this.findOneFromDef('invoice', [this.reference]); + this.checkMainEntity(this.invoice); this.company = await this.findOneFromDef('company', [this.invoice.companyFk]); }, - methods: { - fetchInvoice(reference) { - return this.findOneFromDef('invoice', [reference]); - } - }, - computed: { - issued: function() { - const filters = this.$options.filters; - - return filters.date(this.invoice.issued, '%d-%m-%Y'); - } - }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() - }, props: { reference: { type: Number, diff --git a/print/templates/reports/extra-community/extra-community.html b/print/templates/reports/extra-community/extra-community.html index 6a46cc689..cd61a4f4d 100644 --- a/print/templates/reports/extra-community/extra-community.html +++ b/print/templates/reports/extra-community/extra-community.html @@ -26,7 +26,7 @@ {{$t('shipped')}} - {{travel.shipped | date('%d-%m-%Y')}} + {{formatDate(travel.shipped, '%d-%m-%Y')}} {{$t('physicalKg')}} {{travel.loadedKg | number($i18n.locale)}} @@ -62,6 +62,6 @@
diff --git a/print/templates/reports/extra-community/extra-community.js b/print/templates/reports/extra-community/extra-community.js index 4dfe6e278..9941faa35 100755 --- a/print/templates/reports/extra-community/extra-community.js +++ b/print/templates/reports/extra-community/extra-community.js @@ -1,12 +1,10 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); const db = require(`vn-print/core/database`); module.exports = { name: 'extra-community', + mixins: [vnReport], async serverPrefetch() { - this.filters = this.$options.filters; const args = { landedTo: this.landedEnd, shippedFrom: this.shippedStart, @@ -21,8 +19,9 @@ module.exports = { }; const travels = await this.fetchTravels(args); + this.checkMainEntity(travels); const travelIds = travels.map(travel => travel.id); - const entries = await this.fetchEntries(travelIds); + const entries = await this.rawSqlFromDef('entries', [travelIds]); const map = new Map(); for (let travel of travels) @@ -35,23 +34,15 @@ module.exports = { } this.travels = travels; - - if (!this.travels) - throw new Error('Something went wrong'); }, computed: { - dated: function() { - return this.filters.date(new Date(), '%d-%m-%Y'); - }, landedEnd: function() { if (!this.landedTo) return; - - return this.filters.date(this.landedTo, '%Y-%m-%d'); + return formatDate(this.landedTo, '%Y-%m-%d'); }, shippedStart: function() { if (!this.shippedFrom) return; - - return this.filters.date(this.shippedFrom, '%Y-%m-%d'); + return formatDate(this.shippedFrom, '%Y-%m-%d'); } }, methods: { @@ -83,25 +74,17 @@ module.exports = { query = db.merge(query, where); query = db.merge(query, 'GROUP BY t.id'); query = db.merge(query, ` - ORDER BY - shipped ASC, - landed ASC, - travelFk, - loadPriority, - agencyModeFk, + ORDER BY + shipped ASC, + landed ASC, + travelFk, + loadPriority, + agencyModeFk, evaNotes `); return this.rawSql(query); }, - - fetchEntries(travelIds) { - return this.rawSqlFromDef('entries', [travelIds]); - } - }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() }, props: [ 'landedTo', diff --git a/print/templates/reports/incoterms-authorization/incoterms-authorization.js b/print/templates/reports/incoterms-authorization/incoterms-authorization.js index bfe675985..53425487e 100755 --- a/print/templates/reports/incoterms-authorization/incoterms-authorization.js +++ b/print/templates/reports/incoterms-authorization/incoterms-authorization.js @@ -1,23 +1,12 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'incoterms-authorization', + mixins: [vnReport], async serverPrefetch() { this.client = await this.findOneFromDef('client', [this.id]); + this.checkMainEntity(this.client); this.company = await this.findOneFromDef('company', [this.companyId]); - if (!this.client) - throw new Error('Something went wrong'); - }, - computed: { - issued: function() { - return new Date(); - } - }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() }, props: { id: { diff --git a/print/templates/reports/invoice-incoterms/invoice-incoterms.html b/print/templates/reports/invoice-incoterms/invoice-incoterms.html index 20c9ad440..1915828ba 100644 --- a/print/templates/reports/invoice-incoterms/invoice-incoterms.html +++ b/print/templates/reports/invoice-incoterms/invoice-incoterms.html @@ -20,7 +20,7 @@ {{$t('date')}} - {{invoice.issued | date('%d-%m-%Y')}} + {{formatDate(invoice.issued, '%d-%m-%Y')}} diff --git a/print/templates/reports/invoice-incoterms/invoice-incoterms.js b/print/templates/reports/invoice-incoterms/invoice-incoterms.js index 3afc50376..fcaffe5de 100755 --- a/print/templates/reports/invoice-incoterms/invoice-incoterms.js +++ b/print/templates/reports/invoice-incoterms/invoice-incoterms.js @@ -1,34 +1,13 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportHeader = new Component('report-header'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'invoice-incoterms', + mixins: [vnReport], async serverPrefetch() { - this.invoice = await this.fetchInvoice(this.reference); - this.client = await this.fetchClient(this.reference); - this.incoterms = await this.fetchIncoterms(this.reference); - - if (!this.invoice) - throw new Error('Something went wrong'); - }, - computed: { - - }, - methods: { - fetchInvoice(reference) { - return this.findOneFromDef('invoice', [reference]); - }, - fetchClient(reference) { - return this.findOneFromDef('client', [reference]); - }, - fetchIncoterms(reference) { - return this.findOneFromDef('incoterms', [reference, reference, reference]); - } - }, - components: { - 'report-body': reportBody.build(), - 'report-header': reportHeader.build() + this.invoice = await this.findOneFromDef('invoice', [this.reference]); + this.checkMainEntity(this.invoice); + this.client = await this.findOneFromDef('client', [this.reference]); + this.incoterms = await this.findOneFromDef('incoterms', [this.reference, this.reference, this.reference]); }, props: { reference: { diff --git a/print/templates/reports/invoice/invoice.html b/print/templates/reports/invoice/invoice.html index d23bba1e9..60d06d528 100644 --- a/print/templates/reports/invoice/invoice.html +++ b/print/templates/reports/invoice/invoice.html @@ -21,7 +21,7 @@ {{$t('date')}} - {{invoice.issued | date('%d-%m-%Y')}} + {{formatDate(invoice.issued, '%d-%m-%Y')}} @@ -53,7 +53,7 @@ {{row.ref}} - {{row.issued | date}} + {{formatDate(row.issued, '%d-%m-%Y')}} {{row.amount | currency('EUR', $i18n.locale)}} {{row.description}} @@ -75,7 +75,7 @@
- {{ticket.shipped | date}} + {{formatDate(ticket.shipped, '%d-%m-%Y')}}
diff --git a/print/templates/reports/invoice/invoice.js b/print/templates/reports/invoice/invoice.js index f7011ad81..7b572d970 100755 --- a/print/templates/reports/invoice/invoice.js +++ b/print/templates/reports/invoice/invoice.js @@ -1,22 +1,21 @@ -const Component = require(`vn-print/core/component`); const Report = require(`vn-print/core/report`); -const reportBody = new Component('report-body'); -const reportHeader = new Component('report-header'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); const invoiceIncoterms = new Report('invoice-incoterms'); module.exports = { name: 'invoice', + mixins: [vnReport], async serverPrefetch() { - this.invoice = await this.fetchInvoice(this.reference); - this.client = await this.fetchClient(this.reference); - this.taxes = await this.fetchTaxes(this.reference); - this.intrastat = await this.fetchIntrastat(this.reference); - this.rectified = await this.fetchRectified(this.reference); - this.hasIncoterms = await this.fetchHasIncoterms(this.reference); + this.invoice = await this.findOneFromDef('invoice', [this.reference]); + this.checkMainEntity(this.invoice); + this.client = await this.findOneFromDef('client', [this.reference]); + this.taxes = await this.rawSqlFromDef(`taxes`, [this.reference]); + this.intrastat = await this.rawSqlFromDef(`intrastat`, [this.reference, this.reference, this.reference]); + this.rectified = await this.rawSqlFromDef(`rectified`, [this.reference]); + this.hasIncoterms = await this.findValueFromDef(`hasIncoterms`, [this.reference]); - const tickets = await this.fetchTickets(this.reference); - const sales = await this.fetchSales(this.reference); + const tickets = await this.rawSqlFromDef('tickets', [this.reference]); + const sales = await this.rawSqlFromDef('sales', [this.reference, this.reference]); const map = new Map(); @@ -33,9 +32,6 @@ module.exports = { } this.tickets = tickets; - - if (!this.invoice) - throw new Error('Something went wrong'); }, data() { return {totalBalance: 0.00}; @@ -66,30 +62,6 @@ module.exports = { } }, methods: { - fetchInvoice(reference) { - return this.findOneFromDef('invoice', [reference]); - }, - fetchClient(reference) { - return this.findOneFromDef('client', [reference]); - }, - fetchTickets(reference) { - return this.rawSqlFromDef('tickets', [reference]); - }, - fetchSales(reference) { - return this.rawSqlFromDef('sales', [reference, reference]); - }, - fetchTaxes(reference) { - return this.rawSqlFromDef(`taxes`, [reference]); - }, - fetchIntrastat(reference) { - return this.rawSqlFromDef(`intrastat`, [reference, reference, reference]); - }, - fetchRectified(reference) { - return this.rawSqlFromDef(`rectified`, [reference]); - }, - fetchHasIncoterms(reference) { - return this.findValueFromDef(`hasIncoterms`, [reference]); - }, saleImport(sale) { const price = sale.quantity * sale.price; @@ -111,9 +83,6 @@ module.exports = { } }, components: { - 'report-body': reportBody.build(), - 'report-header': reportHeader.build(), - 'report-footer': reportFooter.build(), 'invoice-incoterms': invoiceIncoterms.build() }, props: { diff --git a/print/templates/reports/invoiceIn/invoiceIn.html b/print/templates/reports/invoiceIn/invoiceIn.html index f101f7408..22988b654 100644 --- a/print/templates/reports/invoiceIn/invoiceIn.html +++ b/print/templates/reports/invoiceIn/invoiceIn.html @@ -19,7 +19,7 @@ {{$t('date')}} - {{invoice.created | date('%d-%m-%Y')}} + {{formatDate(invoice.created, '%d-%m-%Y')}} @@ -54,7 +54,7 @@
- {{entry.landed | date}} + {{formatDate(entry.landed, '%d-%m-%Y')}}
diff --git a/print/templates/reports/invoiceIn/invoiceIn.js b/print/templates/reports/invoiceIn/invoiceIn.js index 03549c276..c59f4da7d 100755 --- a/print/templates/reports/invoiceIn/invoiceIn.js +++ b/print/templates/reports/invoiceIn/invoiceIn.js @@ -1,15 +1,14 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportHeader = new Component('report-header'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'invoiceIn', + mixins: [vnReport], async serverPrefetch() { - this.invoice = await this.fetchInvoice(this.id); + this.invoice = await this.findOneFromDef('invoice', [this.id]); + this.checkMainEntity(this.invoice); this.taxes = await this.fetchTaxes(this.id); - let defaultTax = await this.fetchDefaultTax(); + let defaultTax = await this.findOneFromDef('defaultTax'); if (defaultTax) { defaultTax = Object.assign(defaultTax, { @@ -19,11 +18,8 @@ module.exports = { this.taxes.push(defaultTax); } - if (!this.invoice) - throw new Error('Something went wrong'); - - const entries = await this.fetchEntry(this.id); - const buys = await this.fetchBuy(this.id); + const entries = await this.rawSqlFromDef('entry', [this.id]); + const buys = await this.rawSqlFromDef('buy', [this.id]); const map = new Map(); @@ -41,21 +37,7 @@ module.exports = { this.entries = entries; }, - computed: { - }, methods: { - fetchInvoice(id) { - return this.findOneFromDef('invoice', [id]); - }, - fetchEntry(id) { - return this.rawSqlFromDef('entry', [id]); - }, - fetchBuy(id) { - return this.rawSqlFromDef('buy', [id]); - }, - fetchDefaultTax() { - return this.findOneFromDef('defaultTax'); - }, async fetchTaxes(id) { const taxes = await this.rawSqlFromDef(`taxes`, [id]); return this.taxVat(taxes); @@ -95,11 +77,6 @@ module.exports = { return base + vat; } }, - components: { - 'report-body': reportBody.build(), - 'report-header': reportHeader.build(), - 'report-footer': reportFooter.build(), - }, props: { id: { type: Number, diff --git a/print/templates/reports/item-label/item-label.html b/print/templates/reports/item-label/item-label.html index 49593f7dd..66509ab38 100644 --- a/print/templates/reports/item-label/item-label.html +++ b/print/templates/reports/item-label/item-label.html @@ -16,7 +16,7 @@
{{packing()}}
-
{{dated}}
+
{{formatDate(new Date(), '%W/%d')}}
{{labelPage}}
{{item.size}}
diff --git a/print/templates/reports/item-label/item-label.js b/print/templates/reports/item-label/item-label.js index 6341bd11a..c5b9cdfd7 100755 --- a/print/templates/reports/item-label/item-label.js +++ b/print/templates/reports/item-label/item-label.js @@ -1,24 +1,17 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); +const vnReport = require('../../../core/mixins/vn-report.js'); const qrcode = require('qrcode'); module.exports = { name: 'item-label', + mixins: [vnReport], async serverPrefetch() { - this.item = await this.fetchItem(this.id, this.warehouseId); + this.item = await this.findOneFromDef('item', [this.id, this.warehouseId]); + this.checkMainEntity(this.item); this.tags = await this.fetchItemTags(this.id); this.barcode = await this.getBarcodeBase64(this.id); - - if (!this.item) - throw new Error('Something went wrong'); }, computed: { - dated() { - const filters = this.$options.filters; - - return filters.date(new Date(), '%W/%d'); - }, labelPage() { const labelNumber = this.labelNumber ? this.labelNumber : 1; const totalLabels = this.totalLabels ? this.totalLabels : 1; @@ -27,9 +20,6 @@ module.exports = { } }, methods: { - fetchItem(id, warehouseId) { - return this.findOneFromDef('item', [id, warehouseId]); - }, fetchItemTags(id) { return this.rawSqlFromDef('itemTags', [id]).then(rows => { const tags = {}; @@ -48,9 +38,6 @@ module.exports = { return `${this.item.packing}x${stems}`; } }, - components: { - 'report-body': reportBody.build() - }, props: { id: { type: Number, diff --git a/print/templates/reports/letter-debtor/letter-debtor.html b/print/templates/reports/letter-debtor/letter-debtor.html index 962af021d..30fbbe003 100644 --- a/print/templates/reports/letter-debtor/letter-debtor.html +++ b/print/templates/reports/letter-debtor/letter-debtor.html @@ -13,7 +13,7 @@ {{$t('date')}} - {{dated}} + {{formatDate(new Date(), '%d-%m-%Y')}} @@ -44,7 +44,7 @@ - {{sale.issued | date('%d-%m-%Y')}} + {{formatDate(sale.issued, '%d-%m-%Y')}} {{sale.ref}} {{sale.debtOut}} {{sale.debtIn}} diff --git a/print/templates/reports/letter-debtor/letter-debtor.js b/print/templates/reports/letter-debtor/letter-debtor.js index 749fde4ed..4446b13ae 100755 --- a/print/templates/reports/letter-debtor/letter-debtor.js +++ b/print/templates/reports/letter-debtor/letter-debtor.js @@ -1,36 +1,17 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'letter-debtor', + mixins: [vnReport], async serverPrefetch() { - this.client = await this.fetchClient(this.id); - this.sales = await this.fetchSales(this.id, this.companyId); - - if (!this.client) - throw new Error('Something went wrong'); - }, - computed: { - dated: function() { - const filters = this.$options.filters; - - return filters.date(new Date(), '%d-%m-%Y'); - } + this.client = await this.findOneFromDef('client', [this.id]); + this.checkMainEntity(this.client); + this.sales = await this.findOneFromDef('sales', [this.id, this.companyId]); }, data() { return {totalBalance: 0.00}; }, methods: { - fetchClient(id) { - return this.findOneFromDef('client', [id]); - }, - fetchSales(id, companyId) { - return this.findOneFromDef('sales', [ - id, - companyId - ]); - }, getBalance(sale) { if (sale.debtOut) this.totalBalance += parseFloat(sale.debtOut); @@ -57,10 +38,6 @@ module.exports = { return debtIn.toFixed(2); }, }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() - }, props: { id: { type: Number, diff --git a/print/templates/reports/previa-label/previa-label.js b/print/templates/reports/previa-label/previa-label.js index 7ad5ea961..833a15499 100755 --- a/print/templates/reports/previa-label/previa-label.js +++ b/print/templates/reports/previa-label/previa-label.js @@ -1,36 +1,24 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); +const vnReport = require('../../../core/mixins/vn-report.js'); const qrcode = require('qrcode'); -const UserError = require('vn-loopback/util/user-error'); module.exports = { name: 'previa-label', + mixins: [vnReport], async serverPrefetch() { - this.previa = await this.fetchPrevia(this.id); - this.sector = await this.fetchSector(this.id); + this.sector = await this.findOneFromDef('sector', [this.id]); + this.checkMainEntity(this.sector); + this.previa = await this.findOneFromDef('previa', [this.id]); this.barcode = await this.getBarcodeBase64(this.id); if (this.previa) this.previa = this.previa[0]; - - if (!this.sector) - throw new UserError('Something went wrong - no sector found'); }, methods: { - fetchPrevia(id) { - return this.findOneFromDef('previa', [id]); - }, getBarcodeBase64(id) { const data = String(id); return qrcode.toDataURL(data, {margin: 0}); }, - fetchSector(id) { - return this.findOneFromDef('sector', [id]); - } - }, - components: { - 'report-body': reportBody.build() }, props: { id: { diff --git a/print/templates/reports/receipt/receipt.js b/print/templates/reports/receipt/receipt.js index 9a9ccd452..89a431adf 100755 --- a/print/templates/reports/receipt/receipt.js +++ b/print/templates/reports/receipt/receipt.js @@ -1,27 +1,12 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'receipt', + mixins: [vnReport], async serverPrefetch() { - this.client = await this.fetchClient(this.id); - this.receipt = await this.fetchReceipt(this.id); - - if (!this.receipt) - throw new Error('Something went wrong'); - }, - methods: { - fetchClient(id) { - return this.findOneFromDef('client', [id]); - }, - fetchReceipt(id) { - return this.findOneFromDef('receipt', [id]); - } - }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() + this.receipt = await this.findOneFromDef('receipt', [this.id]); + this.checkMainEntity(this.receipt); + this.client = await this.findOneFromDef('client', [this.id]); }, props: { id: { diff --git a/print/templates/reports/sepa-core/sepa-core.html b/print/templates/reports/sepa-core/sepa-core.html index f2326e43c..a8c270ad5 100644 --- a/print/templates/reports/sepa-core/sepa-core.html +++ b/print/templates/reports/sepa-core/sepa-core.html @@ -147,7 +147,7 @@ {{$t('client.signLocation')}} - {{dated}}, {{client.province}} + {{formatDate(new Date(), '%d-%m-%Y')}}, {{client.province}} {{$t('client.sign')}} diff --git a/print/templates/reports/sepa-core/sepa-core.js b/print/templates/reports/sepa-core/sepa-core.js index ee8a64842..0e19d2a6a 100755 --- a/print/templates/reports/sepa-core/sepa-core.js +++ b/print/templates/reports/sepa-core/sepa-core.js @@ -1,44 +1,12 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportHeader = new Component('report-header'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); -const rptSepaCore = { +module.exports = { name: 'sepa-core', + mixins: [vnReport], async serverPrefetch() { - this.client = await this.fetchClient(this.id, this.companyId); - this.supplier = await this.fetchSupplier(this.id, this.companyId); - - if (!this.client) - throw new Error('Something went wrong'); - }, - computed: { - dated: function() { - const filters = this.$options.filters; - - return filters.date(new Date(), '%d-%m-%Y'); - } - }, - methods: { - fetchClient(id, companyId) { - return this.findOneFromDef('client', [ - companyId, - companyId, - id - ]); - }, - fetchSupplier(id, companyId) { - return this.findOneFromDef('supplier', [ - companyId, - companyId, - id - ]); - } - }, - components: { - 'report-body': reportBody.build(), - 'report-header': reportHeader.build(), - 'report-footer': reportFooter.build() + this.client = await this.findOneFromDef('client', [this.companyId, this.companyId, this.id]); + this.checkMainEntity(this.client); + this.supplier = await this.findOneFromDef('supplier', [this.companyId, this.companyId, this.id]); }, props: { id: { @@ -52,5 +20,3 @@ const rptSepaCore = { } } }; - -module.exports = rptSepaCore; diff --git a/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.html b/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.html index baff51bfe..08b27d0bd 100644 --- a/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.html +++ b/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.html @@ -13,11 +13,11 @@ {{$t('From')}} - {{from | date('%d-%m-%Y')}} + {{formatDate(from, '%d-%m-%Y')}} {{$t('To')}} - {{to | date('%d-%m-%Y')}} + {{formatDate(to, '%d-%m-%Y')}} @@ -38,7 +38,7 @@

{{$t('entry')}} {{entry.id}} - {{$t('dated')}} {{entry.shipped | date('%d-%m-%Y')}} + {{$t('dated')}} {{formatDate(entry.shipped, '%d-%m-%Y')}} {{$t('reference')}} {{entry.reference}}

diff --git a/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js b/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js index f6fb4bd4e..32a7e9b0a 100755 --- a/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js +++ b/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js @@ -1,19 +1,19 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); -const reportFooter = new Component('report-footer'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'supplier-campaign-metrics', + mixins: [vnReport], async serverPrefetch() { - this.supplier = await this.fetchSupplier(this.id); - let entries = await this.fetchEntries(this.id, this.from, this.to); + this.supplier = await this.findOneFromDef('supplier', [this.id]); + this.checkMainEntity(this.supplier); + let entries = await this.rawSqlFromDef('entries', [this.id, this.from, this.to]); const entriesId = []; for (let entry of entries) entriesId.push(entry.id); - const buys = await this.fetchBuys(entriesId); + const buys = await this.rawSqlFromDef('buys', [entriesId]); const entriesMap = new Map(); for (let entry of entries) @@ -29,23 +29,6 @@ module.exports = { } this.entries = entries; - if (!this.supplier) - throw new Error('Something went wrong'); - }, - methods: { - fetchSupplier(supplierId) { - return this.findOneFromDef('supplier', [supplierId]); - }, - fetchEntries(supplierId, from, to) { - return this.rawSqlFromDef('entries', [supplierId, from, to]); - }, - fetchBuys(entriesId) { - return this.rawSqlFromDef('buys', [entriesId]); - } - }, - components: { - 'report-body': reportBody.build(), - 'report-footer': reportFooter.build() }, props: { id: { diff --git a/print/templates/reports/vehicle-event-expired/vehicle-event-expired.html b/print/templates/reports/vehicle-event-expired/vehicle-event-expired.html index 65776851d..7435f272d 100644 --- a/print/templates/reports/vehicle-event-expired/vehicle-event-expired.html +++ b/print/templates/reports/vehicle-event-expired/vehicle-event-expired.html @@ -16,7 +16,7 @@ - +
{{vehicleEvent.numberPlate}} {{vehicleEvent.description}}{{vehicleEvent.finished | date('%d-%m-%Y')}}{{formatDate(vehicleEvent.finished, '%d-%m-%Y')}}
diff --git a/print/templates/reports/vehicle-event-expired/vehicle-event-expired.js b/print/templates/reports/vehicle-event-expired/vehicle-event-expired.js index ab6cffc00..b49e770a5 100755 --- a/print/templates/reports/vehicle-event-expired/vehicle-event-expired.js +++ b/print/templates/reports/vehicle-event-expired/vehicle-event-expired.js @@ -1,21 +1,10 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); - +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'vehicle-event-expired', + mixins: [vnReport], async serverPrefetch() { - this.vehicleEvents = await this.fetchVehicleEvent(this.eventIds); - - if (!this.vehicleEvents) - throw new Error('Something went wrong'); - }, - methods: { - fetchVehicleEvent(vehicleEventIds) { - return this.rawSqlFromDef('vehicleEvents', [vehicleEventIds]); - }, - }, - components: { - 'report-body': reportBody.build() + this.vehicleEvents = await this.rawSqlFromDef('vehicleEvents', [this.eventIds]); + this.checkMainEntity(this.vehicleEvents); }, props: { eventIds: { diff --git a/print/templates/reports/zone/zone.html b/print/templates/reports/zone/zone.html index 54c55e168..fe42fb2ad 100644 --- a/print/templates/reports/zone/zone.html +++ b/print/templates/reports/zone/zone.html @@ -1,5 +1,5 @@
{{zone.agencyName}}
{{zone.id}}
-
{{zone.plateNumber}} {{zone.time | date('%H:%M')}}
+
{{zone.plateNumber}} {{formatDate(zone.time, '%H:%M')}}
diff --git a/print/templates/reports/zone/zone.js b/print/templates/reports/zone/zone.js index 720542cd6..5baa41b8e 100755 --- a/print/templates/reports/zone/zone.js +++ b/print/templates/reports/zone/zone.js @@ -1,21 +1,11 @@ -const Component = require(`vn-print/core/component`); -const reportBody = new Component('report-body'); +const vnReport = require('../../../core/mixins/vn-report.js'); module.exports = { name: 'zone', + mixins: [vnReport], async serverPrefetch() { - this.zone = await this.fetchZone(this.id); - - if (!this.zone) - throw new Error('Something went wrong'); - }, - methods: { - fetchZone(id) { - return this.findOneFromDef('zone', [id]); - } - }, - components: { - 'report-body': reportBody.build() + this.zone = await this.findOneFromDef('zone', [this.id]); + this.checkMainEntity(this.zone); }, props: { id: { From 092501f0ef95cd5861f15ec555734ae8ecc45acc Mon Sep 17 00:00:00 2001 From: vicent Date: Mon, 23 Jan 2023 21:29:48 +0100 Subject: [PATCH 45/88] actualizado changelof --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd3a13a7d..01620fee4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [2304.01] - 2023-02-09 ### Added +- (Rutas) Al descargar varias facturas se comprime en un zip - ### Changed @@ -23,7 +24,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - (Tickets -> Opciones) Subir albarán a Docuware - (Tickets -> Opciones) Enviar correo con PDF de Docuware - (Artículos -> Datos Básicos) Añadido campo Unidades/Caja -- (Rutas) Al descargar varias facturas se comprime en un zip ### Changed - (Reclamaciones -> Descriptor) Cambiado el campo Agencia por Zona From ec5e2a21f7706ad5b69ec0c9d865889274a9db42 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 24 Jan 2023 08:09:35 +0100 Subject: [PATCH 46/88] =?UTF-8?q?feat:=20a=C3=B1adido=20icono=20carro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/shelving/front/routes.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/shelving/front/routes.json b/modules/shelving/front/routes.json index 09a8e389b..4059e5095 100644 --- a/modules/shelving/front/routes.json +++ b/modules/shelving/front/routes.json @@ -1,12 +1,12 @@ { "module": "shelving", "name": "Shelvings", - "icon" : "contact_support", + "icon" : "icon-inventory", "dependencies": ["worker"], "validations" : true, "menus": { "main": [ - {"state": "shelving.index", "icon": "contact_support"} + {"state": "shelving.index", "icon": "icon-inventory"} ], "card": [ {"state": "shelving.card.basicData", "icon": "settings"}, @@ -20,7 +20,7 @@ "abstract": true, "component": "vn-shelving", "description": "Shelvings" - }, + }, { "url": "/index?q", "state": "shelving.index", @@ -32,13 +32,13 @@ "state": "shelving.create", "component": "vn-shelving-create", "description": "New shelving" - }, + }, { "url": "/:id", "state": "shelving.card", "abstract": true, "component": "vn-shelving-card" - }, + }, { "url": "/summary", "state": "shelving.card.summary", @@ -47,7 +47,7 @@ "params": { "shelving": "$ctrl.shelving" } - }, + }, { "url": "/basic-data", "state": "shelving.card.basicData", @@ -56,7 +56,7 @@ "params": { "shelving": "$ctrl.shelving" } - }, + }, { "url" : "/log", "state": "shelving.card.log", @@ -64,4 +64,4 @@ "description": "Log" } ] -} \ No newline at end of file +} From 3ed04211fd82d788e018994abeccf12238d4c407 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 26 Jan 2023 13:05:12 +0100 Subject: [PATCH 47/88] Updated package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2031da475..46b7d4ffc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.02.03", + "version": "23.04.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From 25f0c0d9e3b0cd6f0695f1b50037a52be6af2cb9 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 26 Jan 2023 14:16:30 +0100 Subject: [PATCH 48/88] refs #5141 province added --- modules/claim/front/card/index.js | 24 +++++++++++++++++++---- modules/claim/front/descriptor/index.html | 6 +++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/modules/claim/front/card/index.js b/modules/claim/front/card/index.js index 8fb35db75..4a8677c90 100644 --- a/modules/claim/front/card/index.js +++ b/modules/claim/front/card/index.js @@ -19,10 +19,26 @@ class Controller extends ModuleCard { }, { relation: 'ticket', scope: { - fields: ['zoneFk'], - include: { - relation: 'zone' - } + fields: ['zoneFk', 'addressFk'], + include: [ + { + relation: 'zone', + scope: { + fields: ['name'] + } + }, + { + relation: 'address', + scope: { + fields: ['provinceFk'], + include: { + relation: 'province', + scope: { + fields: ['name'] + } + } + } + }] } }, { relation: 'claimState', diff --git a/modules/claim/front/descriptor/index.html b/modules/claim/front/descriptor/index.html index 90246824b..f346ecf17 100644 --- a/modules/claim/front/descriptor/index.html +++ b/modules/claim/front/descriptor/index.html @@ -55,9 +55,13 @@ - {{$ctrl.claim.ticket.zoneFk}} + {{$ctrl.claim.ticket.zone.name}} + + Date: Fri, 27 Jan 2023 10:05:03 +0100 Subject: [PATCH 49/88] refs #5077 hours set 00:00:00 only when date change --- modules/ticket/front/basic-data/step-one/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/ticket/front/basic-data/step-one/index.js b/modules/ticket/front/basic-data/step-one/index.js index f532265e2..99782de44 100644 --- a/modules/ticket/front/basic-data/step-one/index.js +++ b/modules/ticket/front/basic-data/step-one/index.js @@ -75,8 +75,10 @@ class Controller extends Component { } set shipped(value) { + if (new Date(this.ticket.shipped).toDateString() != value.toDateString()) + value.setHours(0, 0, 0, 0); + this.ticket.shipped = value; - this.ticket.shipped.setHours(0, 0, 0, 0); this.getLanded({ shipped: value, addressFk: this.ticket.addressFk, From 29c6ca35ff112093d47d1b193f12bd3f1fd2e597 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 27 Jan 2023 13:39:19 +0100 Subject: [PATCH 50/88] fix: test e2e --- modules/item/back/methods/tag/onSubmit.js | 24 ++++++----------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/modules/item/back/methods/tag/onSubmit.js b/modules/item/back/methods/tag/onSubmit.js index aec67e92a..7abbe60d4 100644 --- a/modules/item/back/methods/tag/onSubmit.js +++ b/modules/item/back/methods/tag/onSubmit.js @@ -47,44 +47,32 @@ module.exports = function(Self) { } try { - const promises = []; - if (args.deletes) { - for (const itemTagId of args.deletes) { - const itemTagDeleted = models.ItemTag.destroyById(itemTagId, myOptions); - promises.push(itemTagDeleted); - } + for (const itemTagId of args.deletes) + await models.ItemTag.destroyById(itemTagId, myOptions); } if (args.updates) { for (const row of args.updates) { if (row.data.priority) { const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); - const itemTagUpdatedPriority = itemTag.updateAttributes({ + await itemTag.updateAttributes({ priority: row.data.priority + args.maxPriority }, myOptions); - promises.push(itemTagUpdatedPriority); } } for (const row of args.updates) { const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); - const itemTagUpdated = itemTag.updateAttributes(row.data, myOptions); - promises.push(itemTagUpdated); + await itemTag.updateAttributes(row.data, myOptions); } } if (args.creates) { - for (const itemTag of args.creates) { - const newItemTag = models.ItemTag.create(itemTag, myOptions); - promises.push(newItemTag); - } + for (const itemTag of args.creates) + await models.ItemTag.create(itemTag, myOptions); } - const resolvedPromises = await Promise.all(promises); - if (tx) await tx.commit(); - - return resolvedPromises; } catch (e) { if (tx) await tx.rollback(); throw e; From 79bf1739baff7947c697ac5473a1f76294b18726 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 27 Jan 2023 13:52:14 +0100 Subject: [PATCH 51/88] fix: backTest --- modules/item/back/methods/tag/specs/onSubmit.spec.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/modules/item/back/methods/tag/specs/onSubmit.spec.js b/modules/item/back/methods/tag/specs/onSubmit.spec.js index a8077db67..f24aad7e4 100644 --- a/modules/item/back/methods/tag/specs/onSubmit.spec.js +++ b/modules/item/back/methods/tag/specs/onSubmit.spec.js @@ -12,9 +12,8 @@ describe('tag onSubmit()', () => { deletes: deletes } }; - const result = await models.Tag.onSubmit(ctx, options); + await models.Tag.onSubmit(ctx, options); - expect(result.length).toEqual(1); await tx.rollback(); } catch (e) { await tx.rollback(); @@ -33,9 +32,8 @@ describe('tag onSubmit()', () => { updates: updates } }; - const result = await models.Tag.onSubmit(ctx, options); + await models.Tag.onSubmit(ctx, options); - expect(result.length).toEqual(1); await tx.rollback(); } catch (e) { await tx.rollback(); @@ -62,9 +60,8 @@ describe('tag onSubmit()', () => { creates: creates } }; - const result = await models.Tag.onSubmit(ctx, options); + await models.Tag.onSubmit(ctx, options); - expect(result.length).toEqual(1); await tx.rollback(); } catch (e) { await tx.rollback(); @@ -88,9 +85,8 @@ describe('tag onSubmit()', () => { } }; - const result = await models.Tag.onSubmit(ctx, options); + await models.Tag.onSubmit(ctx, options); - expect(result.length).toEqual(4); await tx.rollback(); } catch (e) { await tx.rollback(); From 7e5f50e637a8e8f67e2527a1de46a556d1d4db26 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 08:30:39 +0100 Subject: [PATCH 52/88] refs #5072 email validation added --- db/changes/230401/00-updateIsToBeMailed.sql | 6 ++++++ loopback/locale/es.json | 3 ++- modules/client/back/models/client.js | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 db/changes/230401/00-updateIsToBeMailed.sql diff --git a/db/changes/230401/00-updateIsToBeMailed.sql b/db/changes/230401/00-updateIsToBeMailed.sql new file mode 100644 index 000000000..c04090663 --- /dev/null +++ b/db/changes/230401/00-updateIsToBeMailed.sql @@ -0,0 +1,6 @@ +UPDATE vn.client + SET isToBeMailed = FALSE + WHERE + mailAddress is NULL + AND email is NULL + AND isToBeMailed = TRUE; diff --git a/loopback/locale/es.json b/loopback/locale/es.json index d65054f37..1bf6c18f0 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -259,5 +259,6 @@ "Try again": "Vuelve a intentarlo", "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9", "Failed to upload file": "Error al subir archivo", - "The DOCUWARE PDF document does not exists": "The DOCUWARE PDF document does not exists" + "The DOCUWARE PDF document does not exists": "The DOCUWARE PDF document does not exists", + "There is no assigned email for this client": "No hay correo asignado para este cliente" } diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index e07993f79..2d8e7bd27 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -141,6 +141,16 @@ module.exports = Self => { done(); } + Self.validateAsync('isToBeMailed', isToBeMailed, { + message: 'There is no assigned email for this client' + }); + + function isToBeMailed(err, done) { + if (this.isToBeMailed == true && !this.email) + err(); + done(); + } + Self.validateAsync('defaultAddressFk', isActive, {message: 'Unable to default a disabled consignee'} ); From fbf252b634772ff61c9f6bba70aa8c00bcfd5014 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 08:31:56 +0100 Subject: [PATCH 53/88] refs #5072 template strings --- db/changes/230401/00-updateIsToBeMailed.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/changes/230401/00-updateIsToBeMailed.sql b/db/changes/230401/00-updateIsToBeMailed.sql index c04090663..1bb177f57 100644 --- a/db/changes/230401/00-updateIsToBeMailed.sql +++ b/db/changes/230401/00-updateIsToBeMailed.sql @@ -1,4 +1,4 @@ -UPDATE vn.client +UPDATE `vn`.`client` SET isToBeMailed = FALSE WHERE mailAddress is NULL From cf64de39f9653c0d88bb60e0dff0339a276a9507 Mon Sep 17 00:00:00 2001 From: Pau Navarro Date: Mon, 30 Jan 2023 09:01:20 +0100 Subject: [PATCH 54/88] refs #5146 @1h add step to vn-inputs --- modules/supplier/front/agency-term/index/index.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/supplier/front/agency-term/index/index.html b/modules/supplier/front/agency-term/index/index.html index 9d53226c5..44c6deba9 100644 --- a/modules/supplier/front/agency-term/index/index.html +++ b/modules/supplier/front/agency-term/index/index.html @@ -24,36 +24,42 @@ From 46ee12de6d29c65cf2925a630c18c683399c60fe Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 09:45:10 +0100 Subject: [PATCH 55/88] refs #5088 text deleted --- print/templates/reports/receipt/receipt.html | 6 +++--- print/templates/reports/receipt/sql/receipt.sql | 11 +++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/print/templates/reports/receipt/receipt.html b/print/templates/reports/receipt/receipt.html index e0bab5ecf..5dd4299be 100644 --- a/print/templates/reports/receipt/receipt.html +++ b/print/templates/reports/receipt/receipt.html @@ -4,9 +4,9 @@

{{$t('title')}}

- Recibo de {{client.socialName}}, la cantidad de - {{receipt.amountPaid}} € en concepto de 'entrega a cuenta', quedando pendiente en - la cuenta del cliente un saldo de {{receipt.amountUnpaid}} €. + Recibo de {{client.socialName}}, + la cantidad de {{receipt.amountPaid}} € + en concepto de 'entrega a cuenta'.

diff --git a/print/templates/reports/receipt/sql/receipt.sql b/print/templates/reports/receipt/sql/receipt.sql index b8f5a4112..4094d25b3 100644 --- a/print/templates/reports/receipt/sql/receipt.sql +++ b/print/templates/reports/receipt/sql/receipt.sql @@ -1,11 +1,10 @@ -SELECT - r.id, - r.amountPaid, - cr.amount AS amountUnpaid, - r.payed, +SELECT + r.id, + r.amountPaid, + r.payed, r.companyFk FROM receipt r JOIN client c ON c.id = r.clientFk JOIN vn.clientRisk cr ON cr.clientFk = c.id AND cr.companyFk = r.companyFk -WHERE r.id = ? \ No newline at end of file +WHERE r.id = ? From 77742d94d77a34576980f13f8f79250318fcd586 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 12:19:11 +0100 Subject: [PATCH 56/88] refs #5138 summary changed like route/tickets --- .../route/back/methods/route/getTickets.js | 11 ++- modules/route/front/summary/index.html | 82 ++++++++++--------- modules/route/front/tickets/index.html | 26 +++--- 3 files changed, 66 insertions(+), 53 deletions(-) diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js index 708644c1a..1eb9e27f5 100644 --- a/modules/route/back/methods/route/getTickets.js +++ b/modules/route/back/methods/route/getTickets.js @@ -50,14 +50,17 @@ module.exports = Self => { am.name AS agencyModeName, u.nickname AS userNickname, vn.ticketTotalVolume(t.id) AS volume, - tob.description + tob.description, + GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt 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 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 LEFT JOIN observationType ot ON ot.code = 'delivery' - LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id + LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id AND tob.observationTypeFk = ot.id LEFT JOIN address a ON a.id = t.addressFk LEFT JOIN agencyMode am ON am.id = t.agencyModeFk @@ -70,7 +73,9 @@ module.exports = Self => { const where = filter.where; where['r.id'] = filter.id; - stmt.merge(conn.makeSuffix(filter)); + stmt.merge(conn.makeWhere(filter.where)); + stmt.merge(conn.makeGroupBy('t.id')); + stmt.merge(conn.makeOrderBy(filter.order)); const tickets = await conn.executeStmt(stmt, myOptions); diff --git a/modules/route/front/summary/index.html b/modules/route/front/summary/index.html index 86f558634..a64ad4ff7 100644 --- a/modules/route/front/summary/index.html +++ b/modules/route/front/summary/index.html @@ -10,26 +10,26 @@ - - - - - {{$ctrl.summary.route.worker.user.name}} - @@ -40,35 +40,35 @@ - - - -

- Ticket

-

Ticket @@ -77,45 +77,49 @@ Order - Ticket id - Alias + Street + City + PC + Client + Warehouse Packages - Warehouse - PC - Street + Packaging + Ticket {{ticket.priority | dashIfEmpty}} + {{ticket.street}} + {{ticket.city}} + {{ticket.postalCode}} + + + {{ticket.nickname}} + + + {{ticket.warehouseName}} + {{ticket.packages}} + {{ticket.volume}} + {{ticket.ipt}} - {{ticket.id}} - - {{ticket.nickname}} - - - {{ticket.packages}} - {{ticket.volume}} - {{ticket.warehouseName}} - {{ticket.postalCode}} - {{ticket.street}} - - - + + @@ -123,12 +127,12 @@ - - diff --git a/modules/route/front/tickets/index.html b/modules/route/front/tickets/index.html index dae894ac7..18d6fb160 100644 --- a/modules/route/front/tickets/index.html +++ b/modules/route/front/tickets/index.html @@ -6,9 +6,9 @@ data="$ctrl.tickets" auto-load="true"> - -
@@ -25,18 +25,18 @@ vn-tooltip="Open buscaman" icon="icon-buscaman"> - - - City PC Client + Warehouse Packages + Packaging Ticket @@ -100,8 +102,10 @@ {{::ticket.nickname}} + {{ticket.warehouseName}} {{::ticket.packages}} {{::ticket.volume | number:2}} + {{::ticket.ipt}}
- - @@ -160,7 +164,7 @@ - - - \ No newline at end of file + From 03d75c5b72ce142e0683d6373ce79d23d868ba1b Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 12:25:57 +0100 Subject: [PATCH 57/88] refs #4927 changelog modified --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57be4697b..7f7a28f0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - (Trabajadores -> Nuevo trabajador) Nueva sección ### Changed -- +- (Proveedores -> Crear/Editar) Permite añadir Proveedores con la misma razón social pero con países distintos ### Fixed - (Artículos -> Etiquetas) Permite intercambiar la relevancia entre dos etiquetas. @@ -29,7 +29,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - (Reclamaciones -> Descriptor) Cambiado el campo Agencia por Zona - (Tickets -> Líneas preparadas) Actualizada sección para que sea más visual -- (Proveedores -> Crear/Editar) Permite añadir Proveedores con la misma razón social pero con países distintos ### Fixed - (General) Al utilizar el traductor de Google se descuadraban los iconos From a43f2cd35fcf1005435eb56fdf9d78f9eb143ea8 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 12:31:17 +0100 Subject: [PATCH 58/88] refs #5138 changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d00cafc2b..7aa44e258 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - (Trabajadores -> Nuevo trabajador) Nueva sección ### Changed -- +- (Rutas -> Sumario/Tickets) Actualizados campos de los tickets ### Fixed - (Artículos -> Etiquetas) Permite intercambiar la relevancia entre dos etiquetas. From f7a65cfa6ea63d6f5811fc6d09a3df6efcac2282 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 12:35:09 +0100 Subject: [PATCH 59/88] refs #5072 changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d00cafc2b..bda004470 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - (Artículos -> Etiquetas) Permite intercambiar la relevancia entre dos etiquetas. +- (Cliente -> Datos Fiscales) No se permite seleccionar 'Notificar vía e-mail' a los clientes sin e-mail ## [2302.01] - 2023-01-26 From c08836a1d1a6ce44670ef55e85d78bb144d20113 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 12:38:29 +0100 Subject: [PATCH 61/88] refs #5077 changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d00cafc2b..f2b966850 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - (Artículos -> Etiquetas) Permite intercambiar la relevancia entre dos etiquetas. +- (Tickets -> Datos básicos) Permite guardar la hora de envío ## [2302.01] - 2023-01-26 From 8580851b5b74883f54046e1fafca104587bbfe43 Mon Sep 17 00:00:00 2001 From: Pau Navarro Date: Mon, 30 Jan 2023 13:32:09 +0100 Subject: [PATCH 62/88] refs #5148 @0:30h change style to pre-line --- front/salix/components/log/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/front/salix/components/log/style.scss b/front/salix/components/log/style.scss index bc943996d..68cd5a047 100644 --- a/front/salix/components/log/style.scss +++ b/front/salix/components/log/style.scss @@ -42,6 +42,7 @@ vn-log { & > td.after, & > th.after { width: 40%; + white-space: pre-line; } } } From 9cb363e4e5236083ca6b1841d8c3edadab64fdab Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 13:34:08 +0100 Subject: [PATCH 63/88] refs #5074 deleted null in reference --- CHANGELOG.md | 2 +- modules/client/front/balance/create/index.js | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d00cafc2b..22efa1b28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - (Artículos -> Etiquetas) Permite intercambiar la relevancia entre dos etiquetas. - +- (Tickets -> Añadir pago) Eliminado "null" en las referencias ## [2302.01] - 2023-01-26 diff --git a/modules/client/front/balance/create/index.js b/modules/client/front/balance/create/index.js index 35b2e0b38..b64129e2e 100644 --- a/modules/client/front/balance/create/index.js +++ b/modules/client/front/balance/create/index.js @@ -59,13 +59,11 @@ class Controller extends Dialog { if (value) { const accountingType = value.accountingType; - if (this.originalDescription) { - this.receipt.description = - `${accountingType && accountingType.receiptDescription}, ${this.originalDescription}`; - } else { - this.receipt.description = - `${accountingType && accountingType.receiptDescription}`; - } + if (accountingType.receiptDescription != null) { + this.receipt.description = accountingType.receiptDescription; + if (this.originalDescription) this.receipt.description += `, ${this.originalDescription}`; + } else if (this.originalDescription) + this.receipt.description = this.originalDescription; this.maxAmount = accountingType && accountingType.maxAmount; this.receipt.payed = new Date(); From 896988279302a23febc45dd8dc3504e7aa66eda7 Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 30 Jan 2023 14:13:38 +0100 Subject: [PATCH 64/88] Removed where property dependency --- modules/ticket/back/methods/state/editableStates.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/state/editableStates.js b/modules/ticket/back/methods/state/editableStates.js index 2c90ac43b..115876f26 100644 --- a/modules/ticket/back/methods/state/editableStates.js +++ b/modules/ticket/back/methods/state/editableStates.js @@ -24,7 +24,7 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - let statesList = await models.State.find({where: filter.where}, myOptions); + let statesList = await models.State.find(filter, myOptions); const isProduction = await models.Account.hasRole(userId, 'production', myOptions); const isSalesPerson = await models.Account.hasRole(userId, 'salesPerson', myOptions); const isAdministrative = await models.Account.hasRole(userId, 'administrative', myOptions); From 444d2ae4c4b518b2d306d49b74190553de903b69 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 15:28:47 +0100 Subject: [PATCH 66/88] refs #5104 grouping/packing unified --- modules/entry/front/latest-buys/locale/es.yml | 4 +- modules/entry/front/summary/index.html | 14 +++-- modules/item/front/last-entries/index.html | 52 +++++++++---------- 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/modules/entry/front/latest-buys/locale/es.yml b/modules/entry/front/latest-buys/locale/es.yml index 8d70844fa..795e3f5f4 100644 --- a/modules/entry/front/latest-buys/locale/es.yml +++ b/modules/entry/front/latest-buys/locale/es.yml @@ -1,5 +1,5 @@ Edit buy(s): Editar compra(s) -Buying value: Precio +Buying value: Coste Freight value: Porte Commission value: Comisión Package value: Embalaje @@ -16,4 +16,4 @@ Field to edit: Campo a editar PackageName: Cubo Edit: Editar buy(s): compra(s) -Package out: Embalaje envíos \ No newline at end of file +Package out: Embalaje envíos diff --git a/modules/entry/front/summary/index.html b/modules/entry/front/summary/index.html index 04844ab99..8f1cd924d 100644 --- a/modules/entry/front/summary/index.html +++ b/modules/entry/front/summary/index.html @@ -38,7 +38,7 @@ - {{$ctrl.entryData.travel.ref}} @@ -114,8 +114,7 @@ Grouping Buying value Import - Grouping price - Packing price + PVP @@ -125,19 +124,18 @@ {{::line.packageFk | dashIfEmpty}} {{::line.weight}} - + {{::line.packing | dashIfEmpty}} - + {{::line.grouping | dashIfEmpty}} {{::line.buyingValue | currency: 'EUR':2}} {{::line.quantity * line.buyingValue | currency: 'EUR':2}} - {{::line.price2 | currency: 'EUR':2}} - {{::line.price3 | currency: 'EUR':2}} + {{::line.price2 | currency: 'EUR':2 | dashIfEmpty}} / {{::line.price3 | currency: 'EUR':2 | dashIfEmpty}} @@ -195,7 +193,7 @@ vn-id="item-descriptor" warehouse-fk="$ctrl.vnConfig.warehouseFk"> - diff --git a/modules/item/front/last-entries/index.html b/modules/item/front/last-entries/index.html index 0348d4f66..1c2db10a5 100644 --- a/modules/item/front/last-entries/index.html +++ b/modules/item/front/last-entries/index.html @@ -9,15 +9,15 @@ - + @@ -35,8 +35,7 @@ Warehouse Landed Entry - P.P.U - P.P.P + PVP Label Packing Grouping @@ -51,7 +50,7 @@ - @@ -65,30 +64,31 @@ {{::entry.entryFk | dashIfEmpty}} - {{::entry.price2 | dashIfEmpty}} - {{::entry.price3 | dashIfEmpty}} + + {{::entry.price2 | currency: 'EUR':2 | dashIfEmpty}} / {{::entry.price3 | currency: 'EUR':2 | dashIfEmpty}} + {{entry.stickers | dashIfEmpty}} - + {{::entry.packing | dashIfEmpty}} - + {{::entry.grouping | dashIfEmpty}} {{::entry.stems | dashIfEmpty}} {{::entry.quantity}} - - {{::entry.cost | dashIfEmpty}} + {{::$ctrl.$t('Cost')}}: {{::entry.buyingValue | currency: 'EUR':2 | dashIfEmpty}}
+ {{::$ctrl.$t('Package')}}: {{::entry.packageValue | currency: 'EUR':2 | dashIfEmpty}}
+ {{::$ctrl.$t('Freight')}}: {{::entry.freightValue | currency: 'EUR':2 | dashIfEmpty}}
+ {{::$ctrl.$t('Comission')}}: {{::entry.comissionValue | currency: 'EUR':2 | dashIfEmpty}}"> + {{::entry.cost | currency: 'EUR':2 | dashIfEmpty}}
{{::entry.weight | dashIfEmpty}} @@ -113,24 +113,24 @@ ng-click="contextmenu.filterBySelection()"> Filter by selection - Exclude selection - Remove filter - Remove all filters - Copy value - \ No newline at end of file + From 2bbd7cb2170eb9fd5b9a0bb943e36ea60c015853 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 15:40:08 +0100 Subject: [PATCH 67/88] refs #5104 changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d00cafc2b..3f2faeb13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - (Trabajadores -> Nuevo trabajador) Nueva sección ### Changed -- +- (Entradas -> Compras) Cambiados los campos "Precio Grouping/Packing" por "PVP" y "Precio" por "Coste" +- (Artículos -> Últimas compras) Cambiados los campos "P.P.U." y "P.P.P." por "PVP" ### Fixed - (Artículos -> Etiquetas) Permite intercambiar la relevancia entre dos etiquetas. From 53349fcea74961767c63de4e38c7b6c359f0c891 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 30 Jan 2023 15:41:04 +0100 Subject: [PATCH 68/88] refs #5104 changelog modified --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f2faeb13..e65983d33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - (Entradas -> Compras) Cambiados los campos "Precio Grouping/Packing" por "PVP" y "Precio" por "Coste" -- (Artículos -> Últimas compras) Cambiados los campos "P.P.U." y "P.P.P." por "PVP" +- (Artículos -> Últimas entradas) Cambiados los campos "P.P.U." y "P.P.P." por "PVP" ### Fixed - (Artículos -> Etiquetas) Permite intercambiar la relevancia entre dos etiquetas. From 7d617c0ac420afa0e7d63362569e5bf24abd2183 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 09:04:45 +0100 Subject: [PATCH 70/88] refs #5129 translations and userErrors added --- loopback/locale/en.json | 19 +++++----- loopback/locale/es.json | 6 ++-- modules/ticket/back/methods/sale/canEdit.js | 9 ++++- .../ticket/back/methods/sale/deleteSales.js | 4 +-- .../back/methods/sale/recalculatePrice.js | 4 +-- modules/ticket/back/methods/sale/reserve.js | 4 +-- .../back/methods/sale/specs/canEdit.spec.js | 36 +++++++++---------- .../ticket/back/methods/sale/updateConcept.js | 5 +-- .../ticket/back/methods/sale/updatePrice.js | 4 +-- .../back/methods/sale/updateQuantity.js | 4 +-- 10 files changed, 47 insertions(+), 48 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index a406b55a5..c810e5a69 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -67,7 +67,7 @@ "Changed client paymethod": "I have changed the pay method for client [{{clientName}} ({{clientId}})]({{{url}}})", "Sent units from ticket": "I sent *{{quantity}}* units of [{{concept}} ({{itemId}})]({{{itemUrl}}}) to *\"{{nickname}}\"* coming from ticket id [{{ticketId}}]({{{ticketUrl}}})", "Change quantity": "{{concept}} change of {{oldQuantity}} to {{newQuantity}}", - "Claim will be picked": "The product from the claim [({{claimId}})]({{{claimUrl}}}) from the client *{{clientName}}* will be picked", + "Claim will be picked": "The product from the claim [({{claimId}})]({{{claimUrl}}}) from the client *{{clientName}}* will be picked", "Claim state has changed to incomplete": "The state of the claim [({{claimId}})]({{{claimUrl}}}) from client *{{clientName}}* has changed to *incomplete*", "Claim state has changed to canceled": "The state of the claim [({{claimId}})]({{{claimUrl}}}) from client *{{clientName}}* has changed to *canceled*", "Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member", @@ -137,15 +137,18 @@ "Password does not meet requirements": "Password does not meet requirements", "You don't have privileges to change the zone": "You don't have privileges to change the zone or for these parameters there are more than one shipping options, talk to agencies", "Not enough privileges to edit a client": "Not enough privileges to edit a client", - "Claim pickup order sent": "Claim pickup order sent [{{claimId}}]({{{claimUrl}}}) to client *{{clientName}}*", + "Claim pickup order sent": "Claim pickup order sent [{{claimId}}]({{{claimUrl}}}) to client *{{clientName}}*", "You don't have grant privilege": "You don't have grant privilege", "You don't own the role and you can't assign it to another user": "You don't own the role and you can't assign it to another user", - "Email verify": "Email verify", + "Email verify": "Email verify", "Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) merged with [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})", - "Sale(s) blocked, please contact production": "Sale(s) blocked, please contact production", "App locked": "App locked by user {{userId}}", - "The sales of the receiver ticket can't be modified": "The sales of the receiver ticket can't be modified", - "Receipt's bank was not found": "Receipt's bank was not found", - "This receipt was not compensated": "This receipt was not compensated", - "Client's email was not found": "Client's email was not found" + "The sales of the receiver ticket can't be modified": "The sales of the receiver ticket can't be modified", + "Receipt's bank was not found": "Receipt's bank was not found", + "This receipt was not compensated": "This receipt was not compensated", + "Client's email was not found": "Client's email was not found", + "It is not possible to modify tracked sales": "It is not possible to modify tracked sales", + "It is not possible to modify sales that their articles are from Floramondo": "It is not possible to modify sales that their articles are from Floramondo", + "It is not possible to modify cloned sales": "It is not possible to modify cloned sales", + "Valid priorities: 1,2,3": "Valid priorities: 1,2,3" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index d65054f37..06c3efa2b 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -84,7 +84,6 @@ "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", - "Sale(s) blocked, contact production": "Linea(s) bloqueada(s), contacte con produccion", "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", @@ -259,5 +258,8 @@ "Try again": "Vuelve a intentarlo", "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9", "Failed to upload file": "Error al subir archivo", - "The DOCUWARE PDF document does not exists": "The DOCUWARE PDF document does not exists" + "The DOCUWARE PDF document does not exists": "The DOCUWARE PDF document does not exists", + "It is not possible to modify tracked sales": "No es posible modificar líneas de pedido que estén en marcha", + "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" } diff --git a/modules/ticket/back/methods/sale/canEdit.js b/modules/ticket/back/methods/sale/canEdit.js index f44bd6743..3091ebca7 100644 --- a/modules/ticket/back/methods/sale/canEdit.js +++ b/modules/ticket/back/methods/sale/canEdit.js @@ -56,6 +56,13 @@ module.exports = Self => { const shouldEditCloned = canEditCloned || !hasSaleCloned; const shouldEditFloramondo = canEditFloramondo || !hasSaleFloramondo; - return shouldEditTracked && shouldEditCloned && shouldEditFloramondo; + if (!shouldEditTracked) + throw new UserError('It is not possible to modify tracked sales'); + if (!shouldEditCloned) + throw new UserError('It is not possible to modify cloned sales'); + if (!shouldEditFloramondo) + throw new UserError('It is not possible to modify sales that their articles are from Floramondo'); + + return true; }; }; diff --git a/modules/ticket/back/methods/sale/deleteSales.js b/modules/ticket/back/methods/sale/deleteSales.js index c045b9197..5d1463a66 100644 --- a/modules/ticket/back/methods/sale/deleteSales.js +++ b/modules/ticket/back/methods/sale/deleteSales.js @@ -43,9 +43,7 @@ module.exports = Self => { try { const saleIds = sales.map(sale => sale.id); - const canEditSales = await models.Sale.canEdit(ctx, saleIds, myOptions); - if (!canEditSales) - throw new UserError(`Sale(s) blocked, please contact production`); + await models.Sale.canEdit(ctx, saleIds, myOptions); const ticket = await models.Ticket.findById(ticketId, { include: { diff --git a/modules/ticket/back/methods/sale/recalculatePrice.js b/modules/ticket/back/methods/sale/recalculatePrice.js index 38c68d7f6..2c8e6768b 100644 --- a/modules/ticket/back/methods/sale/recalculatePrice.js +++ b/modules/ticket/back/methods/sale/recalculatePrice.js @@ -37,9 +37,7 @@ module.exports = Self => { try { const salesIds = sales.map(sale => sale.id); - const canEditSale = await models.Sale.canEdit(ctx, salesIds, myOptions); - if (!canEditSale) - throw new UserError(`Sale(s) blocked, please contact production`); + await models.Sale.canEdit(ctx, salesIds, myOptions); const query = ` DROP TEMPORARY TABLE IF EXISTS tmp.recalculateSales; diff --git a/modules/ticket/back/methods/sale/reserve.js b/modules/ticket/back/methods/sale/reserve.js index 648e6de23..2dc368af6 100644 --- a/modules/ticket/back/methods/sale/reserve.js +++ b/modules/ticket/back/methods/sale/reserve.js @@ -51,9 +51,7 @@ module.exports = Self => { try { const salesIds = sales.map(sale => sale.id); - const canEditSale = await models.Sale.canEdit(ctx, salesIds, myOptions); - if (!canEditSale) - throw new UserError(`Sale(s) blocked, please contact production`); + await models.Sale.canEdit(ctx, salesIds, myOptions); let changesMade = ''; const promises = []; diff --git a/modules/ticket/back/methods/sale/specs/canEdit.spec.js b/modules/ticket/back/methods/sale/specs/canEdit.spec.js index 2aa873df5..58d8f0635 100644 --- a/modules/ticket/back/methods/sale/specs/canEdit.spec.js +++ b/modules/ticket/back/methods/sale/specs/canEdit.spec.js @@ -50,7 +50,7 @@ describe('sale canEdit()', () => { it('should return false if any of the sales has a saleTracking record', async() => { const tx = await models.Sale.beginTransaction({}); - + let error; try { const options = {transaction: tx}; @@ -59,15 +59,15 @@ describe('sale canEdit()', () => { const sales = [31]; - const result = await models.Sale.canEdit(ctx, sales, options); - - expect(result).toEqual(false); - + await models.Sale.canEdit(ctx, sales, options); await tx.rollback(); } catch (e) { await tx.rollback(); - throw e; + error = e; } + + expect(error).toEqual( + new Error('It is not possible to modify tracked sales')); }); }); @@ -75,22 +75,22 @@ describe('sale canEdit()', () => { const saleCloned = [29]; it('should return false if any of the sales is cloned', async() => { const tx = await models.Sale.beginTransaction({}); - + let error; try { const options = {transaction: tx}; const buyerId = 35; const ctx = {req: {accessToken: {userId: buyerId}}}; - const result = await models.Sale.canEdit(ctx, saleCloned, options); - - expect(result).toEqual(false); - + await models.Sale.canEdit(ctx, saleCloned, options); await tx.rollback(); } catch (e) { await tx.rollback(); - throw e; + error = e; } + + expect(error).toEqual( + new Error('It is not possible to modify cloned sales')); }); it('should return true if any of the sales is cloned and has the correct role', async() => { @@ -130,7 +130,7 @@ describe('sale canEdit()', () => { it('should return false if any of the sales isFloramondo', async() => { const tx = await models.Sale.beginTransaction({}); const sales = [26]; - + let error; try { const options = {transaction: tx}; @@ -140,15 +140,15 @@ describe('sale canEdit()', () => { const saleToEdit = await models.Sale.findById(sales[0], null, options); await saleToEdit.updateAttribute('itemFk', 9, options); - const result = await models.Sale.canEdit(ctx, sales, options); - - expect(result).toEqual(false); - + await models.Sale.canEdit(ctx, sales, options); await tx.rollback(); } catch (e) { await tx.rollback(); - throw e; + error = e; } + + expect(error).toEqual( + new Error('It is not possible to modify sales that their articles are from Floramondo')); }); it('should return true if any of the sales is of isFloramondo and has the correct role', async() => { diff --git a/modules/ticket/back/methods/sale/updateConcept.js b/modules/ticket/back/methods/sale/updateConcept.js index 0730f85e2..dcd25dcbb 100644 --- a/modules/ticket/back/methods/sale/updateConcept.js +++ b/modules/ticket/back/methods/sale/updateConcept.js @@ -40,10 +40,7 @@ module.exports = Self => { try { const currentLine = await models.Sale.findById(id, null, myOptions); - const canEditSale = await models.Sale.canEdit(ctx, [id], myOptions); - - if (!canEditSale) - throw new UserError(`Sale(s) blocked, please contact production`); + await models.Sale.canEdit(ctx, [id], myOptions); const line = await currentLine.updateAttributes({concept: newConcept}, myOptions); diff --git a/modules/ticket/back/methods/sale/updatePrice.js b/modules/ticket/back/methods/sale/updatePrice.js index 8f27e1af5..505de5180 100644 --- a/modules/ticket/back/methods/sale/updatePrice.js +++ b/modules/ticket/back/methods/sale/updatePrice.js @@ -66,9 +66,7 @@ module.exports = Self => { const sale = await models.Sale.findById(id, filter, myOptions); - const canEditSale = await models.Sale.canEdit(ctx, [id], myOptions); - if (!canEditSale) - throw new UserError(`Sale(s) blocked, please contact production`); + await models.Sale.canEdit(ctx, [id], myOptions); const oldPrice = sale.price; const userId = ctx.req.accessToken.userId; diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index 8cf0720ce..d2927c65c 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -41,9 +41,7 @@ module.exports = Self => { } try { - const canEditSale = await models.Sale.canEdit(ctx, [id], myOptions); - if (!canEditSale) - throw new UserError(`Sale(s) blocked, please contact production`); + await models.Sale.canEdit(ctx, [id], myOptions); const filter = { include: { From 4740cdbbb9696b8d2c8c2565a21a8bdb2c7034d0 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 31 Jan 2023 10:37:18 +0100 Subject: [PATCH 71/88] fix: e2e --- e2e/paths/03-worker/04_time_control.spec.js | 3 + front/core/components/button-menu/index.js | 1 + modules/ticket/front/sale/index.html | 1 + modules/ticket/front/summary/index.html | 61 +++++++++++---------- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/e2e/paths/03-worker/04_time_control.spec.js b/e2e/paths/03-worker/04_time_control.spec.js index bba7ced89..b5da799fc 100644 --- a/e2e/paths/03-worker/04_time_control.spec.js +++ b/e2e/paths/03-worker/04_time_control.spec.js @@ -23,6 +23,7 @@ describe('Worker time control path', () => { it('should go to the next month, go to current month and go 1 month in the past', async() => { let date = new Date(); + date.setDate(1); date.setMonth(date.getMonth() + 1); let month = date.toLocaleString('default', {month: 'long'}); @@ -32,6 +33,7 @@ describe('Worker time control path', () => { expect(result).toContain(month); date = new Date(); + date.setDate(1); month = date.toLocaleString('default', {month: 'long'}); await page.click(selectors.workerTimeControl.previousMonthButton); @@ -40,6 +42,7 @@ describe('Worker time control path', () => { expect(result).toContain(month); date = new Date(); + date.setDate(1); date.setMonth(date.getMonth() - 1); const timestamp = Math.round(date.getTime() / 1000); month = date.toLocaleString('default', {month: 'long'}); diff --git a/front/core/components/button-menu/index.js b/front/core/components/button-menu/index.js index c19962b08..e9e4e5ab7 100644 --- a/front/core/components/button-menu/index.js +++ b/front/core/components/button-menu/index.js @@ -87,6 +87,7 @@ ngModule.vnComponent('vnButtonMenu', { selectFields: ' diff --git a/modules/ticket/front/summary/index.html b/modules/ticket/front/summary/index.html index fe49a301f..af44ed67c 100644 --- a/modules/ticket/front/summary/index.html +++ b/modules/ticket/front/summary/index.html @@ -1,6 +1,6 @@
- - Ticket #{{$ctrl.summary.id}} - {{$ctrl.summary.client.name}} + Ticket #{{$ctrl.summary.id}} - {{$ctrl.summary.client.name}} ({{$ctrl.summary.client.id}}) - {{$ctrl.summary.nickname}} - -
- - {{$ctrl.summary.client.salesPersonUser.name}} - @@ -47,11 +48,11 @@ {{$ctrl.summary.zone.name}} - - {{$ctrl.summary.routeFk}} @@ -66,17 +67,17 @@ - - -

- Sale @@ -146,13 +147,13 @@ vn-tooltip="{{::$ctrl.$t('Claim')}}: {{::sale.claimBeginning.claimFk}}"> - - @@ -170,22 +171,22 @@ - {{sale.itemFk | zeroFill:6}} - {{::sale.visible}} - {{::sale.available}} @@ -216,7 +217,7 @@

- Packages @@ -241,7 +242,7 @@

- Service @@ -276,7 +277,7 @@

- Purchase request @@ -304,7 +305,7 @@ {{::request.quantity}} {{::request.price}} - @@ -336,9 +337,9 @@ - - - \ No newline at end of file + From ffdc539851a5eefa4b3e25690b395b4ca41628b5 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 11:29:07 +0100 Subject: [PATCH 72/88] refs #5138 fix e2e --- e2e/helpers/selectors.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index a1412f431..986c6547b 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -944,9 +944,9 @@ export default { routeSummary: { header: 'vn-route-summary > vn-card > h5', cost: 'vn-route-summary vn-label-value[label="Cost"]', - firstTicketID: 'vn-route-summary vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(2) > span', + firstTicketID: 'vn-route-summary vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(10) > span', firstTicketDescriptor: '.vn-popover.shown vn-ticket-descriptor', - firstAlias: 'vn-route-summary vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(3) > span', + firstAlias: 'vn-route-summary vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(5) > span', firstClientDescriptor: '.vn-popover.shown vn-client-descriptor', goToRouteSummaryButton: 'vn-route-summary > vn-card > h5 > a', From a358e58171ca37eef21e513a662f4040a5b1e483 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 12:12:25 +0100 Subject: [PATCH 73/88] docuware translation --- loopback/locale/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 06c3efa2b..df17b82a3 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -258,7 +258,7 @@ "Try again": "Vuelve a intentarlo", "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9", "Failed to upload file": "Error al subir archivo", - "The DOCUWARE PDF document does not exists": "The DOCUWARE PDF document does not exists", + "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 estén en marcha", "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" From 331b278726e59558894857a31dd43c9a44b6c02a Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 13:00:25 +0100 Subject: [PATCH 74/88] refs #5131 checkbox pending origin destination --- db/changes/230401/00-ticket_canAdvance.sql | 100 ++++++++++++++++++ .../back/methods/ticket/getTicketsAdvance.js | 16 +-- .../front/advance-search-panel/index.html | 32 +++--- .../front/advance-search-panel/index.js | 15 --- .../front/advance-search-panel/locale/es.yml | 2 + 5 files changed, 122 insertions(+), 43 deletions(-) create mode 100644 db/changes/230401/00-ticket_canAdvance.sql diff --git a/db/changes/230401/00-ticket_canAdvance.sql b/db/changes/230401/00-ticket_canAdvance.sql new file mode 100644 index 000000000..497defebe --- /dev/null +++ b/db/changes/230401/00-ticket_canAdvance.sql @@ -0,0 +1,100 @@ +DROP PROCEDURE IF EXISTS vn.ticket_canAdvance; + +DELIMITER $$ +$$ +CREATE 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 vn.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 vn.itemTicketOut + WHERE shipped >= vDateInventory + AND shipped < vDateFuture + AND warehouseFk = vWarehouseFk + UNION ALL + SELECT itemFk, quantity + FROM vn.itemEntryIn + WHERE landed >= vDateInventory + AND landed < vDateFuture + AND isVirtualStock = FALSE + AND warehouseInFk = vWarehouseFk + UNION ALL + SELECT itemFk, quantity + FROM vn.itemEntryOut + WHERE shipped >= vDateInventory + AND shipped < vDateFuture + AND warehouseOutFk = vWarehouseFk + ) t + GROUP BY itemFk HAVING amount != 0; + + DROP TEMPORARY TABLE IF EXISTS tmp.filter; + CREATE TEMPORARY TABLE tmp.filter + (INDEX (id)) + SELECT s.ticketFk futureId, + t2.ticketFk id, + sum((s.quantity <= IFNULL(st.amount,0))) hasStock, + count(DISTINCT s.id) saleCount, + t2.state, + t2.isNotValidated, + st.name futureState, + st.isNotValidated futureIsNotValidated, + GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) futureIpt, + t2.ipt, + t.workerFk, + CAST(sum(litros) AS DECIMAL(10,0)) liters, + CAST(count(*) AS DECIMAL(10,0)) `lines`, + t2.shipped, + t.shipped futureShipped, + t2.totalWithVat, + t.totalWithVat futureTotalWithVat + FROM vn.ticket t + JOIN vn.ticketState ts ON ts.ticketFk = t.id + JOIN vn.state st ON st.id = ts.stateFk + JOIN vn.saleVolume sv ON t.id = sv.ticketFk + JOIN (SELECT + t2.id ticketFk, + t2.addressFk, + st.isNotValidated, + st.name state, + GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt, + t2.shipped, + t2.totalWithVat + FROM vn.ticket t2 + JOIN vn.sale s ON s.ticketFk = t2.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.ticketState ts ON ts.ticketFk = t2.id + JOIN vn.state st ON st.id = ts.stateFk + LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk + WHERE t2.shipped BETWEEN vDateToAdvance AND util.dayend(vDateToAdvance) + AND t2.warehouseFk = vWarehouseFk + GROUP BY t2.id) t2 ON t2.addressFk = t.addressFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk + LEFT JOIN tmp.stock st ON st.itemFk = s.itemFk + WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture) + AND t.warehouseFk = vWarehouseFk + GROUP BY t.id; + + 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 19571bb51..a7dea56e2 100644 --- a/modules/ticket/back/methods/ticket/getTicketsAdvance.js +++ b/modules/ticket/back/methods/ticket/getTicketsAdvance.js @@ -50,14 +50,14 @@ module.exports = Self => { required: false }, { - arg: 'state', - type: 'string', + arg: 'isNotValidated', + type: 'boolean', description: 'Origin state', required: false }, { - arg: 'futureState', - type: 'string', + arg: 'futureIsNotValidated', + type: 'boolean', description: 'Destination state', required: false }, @@ -95,10 +95,10 @@ module.exports = Self => { return {'f.ipt': value}; case 'futureIpt': return {'f.futureIpt': value}; - case 'state': - return {'f.stateCode': {like: `%${value}%`}}; - case 'futureState': - return {'f.futureStateCode': {like: `%${value}%`}}; + case 'isNotValidated': + return {'f.isNotValidated': value}; + case 'futureIsNotValidated': + return {'f.futureIsNotValidated': value}; } }); diff --git a/modules/ticket/front/advance-search-panel/index.html b/modules/ticket/front/advance-search-panel/index.html index e8d5dc60d..dfe1f6b08 100644 --- a/modules/ticket/front/advance-search-panel/index.html +++ b/modules/ticket/front/advance-search-panel/index.html @@ -39,26 +39,18 @@ - - - {{name}} - - - - - {{name}} - - + + + + { - for (let state of res.data) { - groupedStates.push({ - id: state.id, - code: state.code, - name: this.$t(state.code) - }); - } - this.groupedStates = groupedStates; - }); - } - getItemPackingTypes() { let itemPackingTypes = []; const filter = { diff --git a/modules/ticket/front/advance-search-panel/locale/es.yml b/modules/ticket/front/advance-search-panel/locale/es.yml index 3dce7dae5..4ea2fc737 100644 --- a/modules/ticket/front/advance-search-panel/locale/es.yml +++ b/modules/ticket/front/advance-search-panel/locale/es.yml @@ -1 +1,3 @@ Advance tickets: Adelantar tickets +Pending Origin: Pendiente origen +Pending Destination: Pendiente destino From e5b7ebd8b4de413b4a73131fb6ebc1f8299df479 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 13:06:58 +0100 Subject: [PATCH 75/88] refs #5131 IPT null or value --- .../back/methods/ticket/getTicketsAdvance.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/methods/ticket/getTicketsAdvance.js b/modules/ticket/back/methods/ticket/getTicketsAdvance.js index a7dea56e2..1e1646cba 100644 --- a/modules/ticket/back/methods/ticket/getTicketsAdvance.js +++ b/modules/ticket/back/methods/ticket/getTicketsAdvance.js @@ -92,9 +92,19 @@ module.exports = Self => { case 'futureId': return {'f.futureId': value}; case 'ipt': - return {'f.ipt': value}; + return {or: + [ + {'f.ipt': {like: `%${value}%`}}, + {'f.ipt': null} + ] + }; case 'futureIpt': - return {'f.futureIpt': value}; + return {or: + [ + {'f.futureIpt': {like: `%${value}%`}}, + {'f.futureIpt': null} + ] + }; case 'isNotValidated': return {'f.isNotValidated': value}; case 'futureIsNotValidated': From 87bef62e350544e8c5d83db990540cf85f49f79b Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 13:21:51 +0100 Subject: [PATCH 76/88] refs #5131 hasStock refers to origin --- db/changes/230401/00-ticket_canAdvance.sql | 21 +++++++++++---------- modules/ticket/front/advance/index.html | 8 ++++---- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/db/changes/230401/00-ticket_canAdvance.sql b/db/changes/230401/00-ticket_canAdvance.sql index 497defebe..05200aa57 100644 --- a/db/changes/230401/00-ticket_canAdvance.sql +++ b/db/changes/230401/00-ticket_canAdvance.sql @@ -51,7 +51,6 @@ BEGIN (INDEX (id)) SELECT s.ticketFk futureId, t2.ticketFk id, - sum((s.quantity <= IFNULL(st.amount,0))) hasStock, count(DISTINCT s.id) saleCount, t2.state, t2.isNotValidated, @@ -65,32 +64,34 @@ BEGIN t2.shipped, t.shipped futureShipped, t2.totalWithVat, - t.totalWithVat futureTotalWithVat + t.totalWithVat futureTotalWithVat, + t2.hasStock FROM vn.ticket t JOIN vn.ticketState ts ON ts.ticketFk = t.id JOIN vn.state st ON st.id = ts.stateFk JOIN vn.saleVolume sv ON t.id = sv.ticketFk JOIN (SELECT - t2.id ticketFk, - t2.addressFk, - st.isNotValidated, - st.name state, - GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt, - t2.shipped, - t2.totalWithVat + t2.id ticketFk, + t2.addressFk, + st.isNotValidated, + st.name state, + GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt, + t2.shipped, + t2.totalWithVat, + sum((s.quantity <= IFNULL(st.amount,0))) hasStock FROM vn.ticket t2 JOIN vn.sale s ON s.ticketFk = t2.id JOIN vn.item i ON i.id = s.itemFk JOIN vn.ticketState ts ON ts.ticketFk = t2.id JOIN vn.state st ON st.id = ts.stateFk LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk + LEFT JOIN tmp.stock st ON st.itemFk = s.itemFk WHERE t2.shipped BETWEEN vDateToAdvance AND util.dayend(vDateToAdvance) AND t2.warehouseFk = vWarehouseFk GROUP BY t2.id) t2 ON t2.addressFk = t.addressFk JOIN vn.sale s ON s.ticketFk = t.id JOIN vn.item i ON i.id = s.itemFk LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk - LEFT JOIN tmp.stock st ON st.itemFk = s.itemFk WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture) AND t.warehouseFk = vWarehouseFk GROUP BY t.id; diff --git a/modules/ticket/front/advance/index.html b/modules/ticket/front/advance/index.html index f63c0fbf7..bd274b7fb 100644 --- a/modules/ticket/front/advance/index.html +++ b/modules/ticket/front/advance/index.html @@ -55,6 +55,9 @@ State + + Stock + Import @@ -73,9 +76,6 @@ Liters - - Stock - Lines @@ -111,6 +111,7 @@ {{::ticket.futureState | dashIfEmpty}} + {{::ticket.hasStock | dashIfEmpty}} {{::(ticket.futureTotalWithVat ? ticket.futureTotalWithVat : 0) | currency: 'EUR': 2}} @@ -136,7 +137,6 @@ {{::ticket.liters | dashIfEmpty}} - {{::ticket.hasStock | dashIfEmpty}} {{::ticket.lines | dashIfEmpty}} From b70557ee868fd7b1cafe21db29d4ede57572f899 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 14:20:08 +0100 Subject: [PATCH 77/88] refs #5131 agencies icon --- db/changes/230401/00-ticket_canAdvance.sql | 7 ++++++- modules/ticket/front/advance/index.html | 15 ++++++++++++--- modules/ticket/front/advance/index.js | 6 ++++++ modules/ticket/front/advance/locale/es.yml | 3 +++ modules/ticket/front/advance/style.scss | 7 +++++++ 5 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 modules/ticket/front/advance/style.scss diff --git a/db/changes/230401/00-ticket_canAdvance.sql b/db/changes/230401/00-ticket_canAdvance.sql index 05200aa57..2072259b1 100644 --- a/db/changes/230401/00-ticket_canAdvance.sql +++ b/db/changes/230401/00-ticket_canAdvance.sql @@ -65,7 +65,9 @@ BEGIN t.shipped futureShipped, t2.totalWithVat, t.totalWithVat futureTotalWithVat, - t2.hasStock + t2.hasStock, + t2.agency, + am.name futureAgency FROM vn.ticket t JOIN vn.ticketState ts ON ts.ticketFk = t.id JOIN vn.state st ON st.id = ts.stateFk @@ -78,12 +80,14 @@ BEGIN GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt, t2.shipped, t2.totalWithVat, + am.name agency, sum((s.quantity <= IFNULL(st.amount,0))) hasStock FROM vn.ticket t2 JOIN vn.sale s ON s.ticketFk = t2.id JOIN vn.item i ON i.id = s.itemFk JOIN vn.ticketState ts ON ts.ticketFk = t2.id JOIN vn.state st ON st.id = ts.stateFk + JOIN vn.agencyMode am ON t2.agencyModeFk = am.id LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk LEFT JOIN tmp.stock st ON st.itemFk = s.itemFk WHERE t2.shipped BETWEEN vDateToAdvance AND util.dayend(vDateToAdvance) @@ -91,6 +95,7 @@ BEGIN GROUP BY t2.id) t2 ON t2.addressFk = t.addressFk JOIN vn.sale s ON s.ticketFk = t.id JOIN vn.item i ON i.id = s.itemFk + JOIN vn.agencyMode am ON t.agencyModeFk = am.id LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture) AND t.warehouseFk = vWarehouseFk diff --git a/modules/ticket/front/advance/index.html b/modules/ticket/front/advance/index.html index bd274b7fb..d82d8cc50 100644 --- a/modules/ticket/front/advance/index.html +++ b/modules/ticket/front/advance/index.html @@ -32,7 +32,7 @@ - Origin + Origin Destination @@ -43,13 +43,15 @@ check-field="checked"> + + ID Date - + IPT @@ -67,7 +69,7 @@ Date - + IPT @@ -92,6 +94,13 @@ vn-click-stop> + + + + ' + this.$t(`Destination agency`, {agency: agency}); + } + moveTicketsAdvance() { let ticketsToMove = []; this.checked.forEach(ticket => { diff --git a/modules/ticket/front/advance/locale/es.yml b/modules/ticket/front/advance/locale/es.yml index b444fbdd3..da22cd433 100644 --- a/modules/ticket/front/advance/locale/es.yml +++ b/modules/ticket/front/advance/locale/es.yml @@ -4,3 +4,6 @@ Advance confirmation: ¿Desea adelantar {{checked}} tickets? Success: Tickets movidos correctamente Lines: Líneas Liters: Litros +Item Packing Type: Encajado +Origin agency: "Agencia origen: {{agency}}" +Destination agency: "Agencia destino: {{agency}}" diff --git a/modules/ticket/front/advance/style.scss b/modules/ticket/front/advance/style.scss new file mode 100644 index 000000000..8fa9de438 --- /dev/null +++ b/modules/ticket/front/advance/style.scss @@ -0,0 +1,7 @@ +@import "variables"; + +vn-ticket-advance{ + vn-icon { + color: #f7931e + } +} From 19d7e7e6102a97b849501d5c199e49e93309ea6a Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 14:23:40 +0100 Subject: [PATCH 78/88] refs #5131 totalWithVat order --- modules/ticket/front/advance/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ticket/front/advance/index.html b/modules/ticket/front/advance/index.html index d82d8cc50..9f271b498 100644 --- a/modules/ticket/front/advance/index.html +++ b/modules/ticket/front/advance/index.html @@ -60,7 +60,7 @@ Stock - + Import @@ -81,7 +81,7 @@ Lines - + Import From 3622eda589eaadd9fc6a5216c4fa00bbd4c48436 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 15:09:16 +0100 Subject: [PATCH 79/88] refs #5131 added lines liters to origin ticket --- db/changes/230401/00-ticket_canAdvance.sql | 18 +++++++++++------- modules/ticket/front/advance/index.html | 12 ++++++++++-- modules/ticket/front/advance/index.js | 4 ++++ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/db/changes/230401/00-ticket_canAdvance.sql b/db/changes/230401/00-ticket_canAdvance.sql index 2072259b1..fd9d451bf 100644 --- a/db/changes/230401/00-ticket_canAdvance.sql +++ b/db/changes/230401/00-ticket_canAdvance.sql @@ -59,15 +59,17 @@ BEGIN GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) futureIpt, t2.ipt, t.workerFk, - CAST(sum(litros) AS DECIMAL(10,0)) liters, - CAST(count(*) AS DECIMAL(10,0)) `lines`, + CAST(SUM(litros) AS DECIMAL(10,0)) futureLiters, + CAST(COUNT(*) AS DECIMAL(10,0)) `futureLines`, t2.shipped, t.shipped futureShipped, t2.totalWithVat, t.totalWithVat futureTotalWithVat, - t2.hasStock, t2.agency, - am.name futureAgency + am.name futureAgency, + t2.lines, + t2.liters, + SUM((s.quantity <= IFNULL(st.amount,0))) hasStock FROM vn.ticket t JOIN vn.ticketState ts ON ts.ticketFk = t.id JOIN vn.state st ON st.id = ts.stateFk @@ -77,19 +79,20 @@ BEGIN t2.addressFk, st.isNotValidated, st.name state, - GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt, + GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt, t2.shipped, t2.totalWithVat, am.name agency, - sum((s.quantity <= IFNULL(st.amount,0))) hasStock + CAST(SUM(litros) AS DECIMAL(10,0)) liters, + CAST(COUNT(*) AS DECIMAL(10,0)) `lines` FROM vn.ticket t2 + JOIN vn.saleVolume sv ON t2.id = sv.ticketFk JOIN vn.sale s ON s.ticketFk = t2.id JOIN vn.item i ON i.id = s.itemFk JOIN vn.ticketState ts ON ts.ticketFk = t2.id JOIN vn.state st ON st.id = ts.stateFk JOIN vn.agencyMode am ON t2.agencyModeFk = am.id LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk - LEFT JOIN tmp.stock st ON st.itemFk = s.itemFk WHERE t2.shipped BETWEEN vDateToAdvance AND util.dayend(vDateToAdvance) AND t2.warehouseFk = vWarehouseFk GROUP BY t2.id) t2 ON t2.addressFk = t.addressFk @@ -97,6 +100,7 @@ BEGIN JOIN vn.item i ON i.id = s.itemFk JOIN vn.agencyMode am ON t.agencyModeFk = am.id LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk + LEFT JOIN tmp.stock st ON st.itemFk = s.itemFk WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture) AND t.warehouseFk = vWarehouseFk GROUP BY t.id; diff --git a/modules/ticket/front/advance/index.html b/modules/ticket/front/advance/index.html index 9f271b498..3dd52b909 100644 --- a/modules/ticket/front/advance/index.html +++ b/modules/ticket/front/advance/index.html @@ -32,8 +32,8 @@ - Origin - Destination + Origin + Destination @@ -57,9 +57,15 @@ State + + Liters + Stock + + Lines + Import @@ -120,7 +126,9 @@ {{::ticket.futureState | dashIfEmpty}} + {{::ticket.futureLiters | dashIfEmpty}} {{::ticket.hasStock | dashIfEmpty}} + {{::ticket.futureLines | dashIfEmpty}} {{::(ticket.futureTotalWithVat ? ticket.futureTotalWithVat : 0) | currency: 'EUR': 2}} diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index ae299b00c..a29d2db97 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -163,6 +163,10 @@ export default class Controller extends Section { return {'liters': value}; case 'lines': return {'lines': value}; + case 'futureLiters': + return {'futureLiters': value}; + case 'futureLines': + return {'futureLines': value}; case 'ipt': return {'ipt': value}; case 'futureIpt': From 349829e5ed51a9a8eff91b5754fdda2bfa24f89f Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 15:29:00 +0100 Subject: [PATCH 80/88] refs #5131 fixed tests --- e2e/helpers/selectors.js | 4 +- e2e/paths/05-ticket/22_advance.spec.js | 61 ++++++------------- .../ticket/specs/getTicketsAdvance.spec.js | 14 ++--- 3 files changed, 27 insertions(+), 52 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index a1412f431..347396c94 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -778,8 +778,8 @@ export default { ipt: 'vn-autocomplete[label="Destination IPT"]', tableIpt: 'vn-autocomplete[name="ipt"]', tableFutureIpt: 'vn-autocomplete[name="futureIpt"]', - futureState: 'vn-autocomplete[label="Origin Grouped State"]', - state: 'vn-autocomplete[label="Destination Grouped State"]', + futureState: 'vn-check[label="Pending Origin"]', + state: 'vn-check[label="Pending Destination"]', warehouseFk: 'vn-autocomplete[label="Warehouse"]', tableButtonSearch: 'vn-button[vn-tooltip="Search"]', moveButton: 'vn-button[vn-tooltip="Advance tickets"]', diff --git a/e2e/paths/05-ticket/22_advance.spec.js b/e2e/paths/05-ticket/22_advance.spec.js index 6aaa81591..3a6234fe9 100644 --- a/e2e/paths/05-ticket/22_advance.spec.js +++ b/e2e/paths/05-ticket/22_advance.spec.js @@ -50,7 +50,7 @@ describe('Ticket Advance path', () => { await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); await page.autocompleteSearch(selectors.ticketAdvance.ipt, 'Horizontal'); await page.waitToClick(selectors.ticketAdvance.submit); - await page.waitForNumberOfElements(selectors.ticketAdvance.table, 0); + await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); await page.clearInput(selectors.ticketAdvance.ipt); @@ -62,7 +62,7 @@ describe('Ticket Advance path', () => { await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); await page.autocompleteSearch(selectors.ticketAdvance.futureIpt, 'Horizontal'); await page.waitToClick(selectors.ticketAdvance.submit); - await page.waitForNumberOfElements(selectors.ticketAdvance.table, 0); + await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); await page.clearInput(selectors.ticketAdvance.futureIpt); @@ -70,26 +70,36 @@ describe('Ticket Advance path', () => { await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); }); - it('should search with the origin grouped state', async() => { + it('should search with the origin pending state', async() => { await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); - await page.autocompleteSearch(selectors.ticketAdvance.futureState, 'Free'); + await page.waitToClick(selectors.ticketAdvance.futureState); await page.waitToClick(selectors.ticketAdvance.submit); await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); - await page.clearInput(selectors.ticketAdvance.futureState); + await page.waitToClick(selectors.ticketAdvance.futureState); + await page.waitToClick(selectors.ticketAdvance.submit); + await page.waitForNumberOfElements(selectors.ticketAdvance.table, 0); + + await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); + await page.waitToClick(selectors.ticketAdvance.futureState); await page.waitToClick(selectors.ticketAdvance.submit); await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); }); it('should search with the destination grouped state', async() => { await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); - await page.autocompleteSearch(selectors.ticketAdvance.state, 'Free'); + await page.waitToClick(selectors.ticketAdvance.state); await page.waitToClick(selectors.ticketAdvance.submit); await page.waitForNumberOfElements(selectors.ticketAdvance.table, 0); await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); - await page.clearInput(selectors.ticketAdvance.state); + await page.waitToClick(selectors.ticketAdvance.state); + await page.waitToClick(selectors.ticketAdvance.submit); + await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); + + await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); + await page.waitToClick(selectors.ticketAdvance.state); await page.waitToClick(selectors.ticketAdvance.submit); await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); }); @@ -116,42 +126,7 @@ describe('Ticket Advance path', () => { await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); }); - it('should search in smart-table with stock', async() => { - await page.waitToClick(selectors.ticketAdvance.tableButtonSearch); - await page.write(selectors.ticketAdvance.tableStock, '5'); - await page.waitForNumberOfElements(selectors.ticketAdvance.table, 2); - - await page.waitToClick(selectors.ticketAdvance.tableButtonSearch); - await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); - await page.waitToClick(selectors.ticketAdvance.submit); - await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); - }); - - it('should search in smart-table with especified Lines', async() => { - await page.waitToClick(selectors.ticketAdvance.tableButtonSearch); - await page.write(selectors.ticketAdvance.tableLines, '0'); - await page.keyboard.press('Enter'); - await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); - - await page.waitToClick(selectors.ticketAdvance.tableButtonSearch); - await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); - await page.waitToClick(selectors.ticketAdvance.submit); - await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); - }); - - it('should search in smart-table with especified Liters', async() => { - await page.waitToClick(selectors.ticketAdvance.tableButtonSearch); - await page.write(selectors.ticketAdvance.tableLiters, '0'); - await page.keyboard.press('Enter'); - await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); - - await page.waitToClick(selectors.ticketAdvance.tableButtonSearch); - await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton); - await page.waitToClick(selectors.ticketAdvance.submit); - await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1); - }); - - it('should check the three last tickets and move to the future', async() => { + it('should check the one ticket and move to the present', async() => { await page.waitToClick(selectors.ticketAdvance.multiCheck); await page.waitToClick(selectors.ticketAdvance.moveButton); await page.waitToClick(selectors.ticketAdvance.acceptButton); diff --git a/modules/ticket/back/methods/ticket/specs/getTicketsAdvance.spec.js b/modules/ticket/back/methods/ticket/specs/getTicketsAdvance.spec.js index aab053127..7d3bc174d 100644 --- a/modules/ticket/back/methods/ticket/specs/getTicketsAdvance.spec.js +++ b/modules/ticket/back/methods/ticket/specs/getTicketsAdvance.spec.js @@ -29,7 +29,7 @@ describe('TicketFuture getTicketsAdvance()', () => { } }); - it('should return the tickets matching the origin grouped state', async() => { + it('should return the tickets matching the origin pending state', async() => { const tx = await models.Ticket.beginTransaction({}); try { @@ -39,7 +39,7 @@ describe('TicketFuture getTicketsAdvance()', () => { dateFuture: tomorrow, dateToAdvance: today, warehouseFk: 1, - state: 'OK' + futureIsNotValidated: true }; const ctx = {req: {accessToken: {userId: 9}}, args}; @@ -54,7 +54,7 @@ describe('TicketFuture getTicketsAdvance()', () => { } }); - it('should return the tickets matching the destination grouped state', async() => { + it('should return the tickets matching the destination pending state', async() => { const tx = await models.Ticket.beginTransaction({}); try { @@ -64,13 +64,13 @@ describe('TicketFuture getTicketsAdvance()', () => { dateFuture: tomorrow, dateToAdvance: today, warehouseFk: 1, - futureState: 'FREE' + isNotValidated: true }; const ctx = {req: {accessToken: {userId: 9}}, args}; const result = await models.Ticket.getTicketsAdvance(ctx, options); - expect(result.length).toBeGreaterThan(0); + expect(result.length).toEqual(0); await tx.rollback(); } catch (e) { @@ -89,7 +89,7 @@ describe('TicketFuture getTicketsAdvance()', () => { dateFuture: tomorrow, dateToAdvance: today, warehouseFk: 1, - ipt: 'Vertical' + ipt: 'V' }; const ctx = {req: {accessToken: {userId: 9}}, args}; @@ -114,7 +114,7 @@ describe('TicketFuture getTicketsAdvance()', () => { dateFuture: tomorrow, dateToAdvance: today, warehouseFk: 1, - tfIpt: 'Vertical' + tfIpt: 'V' }; const ctx = {req: {accessToken: {userId: 9}}, args}; From a3da71996ac56793e24fed3762d596f434dcb531 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 15:36:51 +0100 Subject: [PATCH 81/88] refs #5131 changelog --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22efa1b28..d103f3194 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,14 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - (Rutas) Al descargar varias facturas se comprime en un zip -- (Trabajadores -> Nuevo trabajador) Nueva sección +- (Trabajadores -> Nuevo trabajador) Nueva sección +- (Tickets -> Adelantar tickets) Añadidos campos "líneas" y "litros" al ticket origen +- (Tickets -> Adelantar tickets) Nuevo icono muestra cuando las agencias de los tickets origen/destino son distintas ### Changed -- +- (Tickets -> Adelantar tickets) Cambiados selectores de estado por checks "Pendiente origen/destino" +- (Tickets -> Adelantar tickets) Cambiado stock de destino a origen. ### Fixed - (Artículos -> Etiquetas) Permite intercambiar la relevancia entre dos etiquetas. - (Tickets -> Añadir pago) Eliminado "null" en las referencias +- (Tickets -> Adelantar tickets) Permite ordenar por importe +- (Tickets -> Adelantar tickets) El filtrado por encajado muestra también los tickets sin tipo de encajado ## [2302.01] - 2023-01-26 From fd440a4db38d8f328bca88f7a684db2a5cc1e1e4 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 31 Jan 2023 15:42:36 +0100 Subject: [PATCH 82/88] refs #5129 better translation tracked sales --- loopback/locale/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index df17b82a3..f86d211f7 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -259,7 +259,7 @@ "Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9", "Failed to upload file": "Error al subir archivo", "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 estén en marcha", + "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" } From 17bb4b60727794f948e95a362d4dd40cdda6bf31 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 1 Feb 2023 07:17:16 +0100 Subject: [PATCH 83/88] refs #5088 added receiptId --- print/templates/reports/receipt/receipt.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/print/templates/reports/receipt/receipt.html b/print/templates/reports/receipt/receipt.html index 5dd4299be..be0bfc375 100644 --- a/print/templates/reports/receipt/receipt.html +++ b/print/templates/reports/receipt/receipt.html @@ -4,7 +4,7 @@

{{$t('title')}}

- Recibo de {{client.socialName}}, + Recibo #{{receipt.id}} de {{client.socialName}}, la cantidad de {{receipt.amountPaid}} € en concepto de 'entrega a cuenta'.

From 21281e09dbfbf915a7634e1cd6d81b76edace5f0 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 2 Feb 2023 15:13:53 +0100 Subject: [PATCH 84/88] hotfix removed supplier --- print/templates/reports/balance-compensation/sql/client.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/print/templates/reports/balance-compensation/sql/client.sql b/print/templates/reports/balance-compensation/sql/client.sql index 92e6f6cab..b4463be23 100644 --- a/print/templates/reports/balance-compensation/sql/client.sql +++ b/print/templates/reports/balance-compensation/sql/client.sql @@ -8,5 +8,4 @@ SELECT r.payed FROM client c JOIN receipt r ON r.clientFk = c.id - JOIN supplier s ON c.fi = s.nif - WHERE r.id = ? \ No newline at end of file + WHERE r.id = ? From 2717c6420c468163fc876e710cb161b65c7e243e Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 3 Feb 2023 14:58:58 +0100 Subject: [PATCH 85/88] fix(invoiceIn_descriptor): supplier.email --- modules/invoiceIn/back/models/invoice-in.json | 5 ----- modules/invoiceIn/front/card/index.js | 14 ++++++++------ modules/invoiceIn/front/descriptor/index.html | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/modules/invoiceIn/back/models/invoice-in.json b/modules/invoiceIn/back/models/invoice-in.json index fa8a1d8f8..c6a736b06 100644 --- a/modules/invoiceIn/back/models/invoice-in.json +++ b/modules/invoiceIn/back/models/invoice-in.json @@ -94,11 +94,6 @@ "model": "Supplier", "foreignKey": "supplierFk" }, - "supplierContact": { - "type": "hasMany", - "model": "SupplierContact", - "foreignKey": "supplierFk" - }, "currency": { "type": "belongsTo", "model": "Currency", diff --git a/modules/invoiceIn/front/card/index.js b/modules/invoiceIn/front/card/index.js index c7ac08cc7..48217faa5 100644 --- a/modules/invoiceIn/front/card/index.js +++ b/modules/invoiceIn/front/card/index.js @@ -6,13 +6,15 @@ class Controller extends ModuleCard { const filter = { include: [ { - relation: 'supplier' - }, - { - relation: 'supplierContact', + relation: 'supplier', scope: { - where: { - email: {neq: null} + include: { + relation: 'contacts', + scope: { + where: { + email: {neq: null}, + } + } } } }, diff --git a/modules/invoiceIn/front/descriptor/index.html b/modules/invoiceIn/front/descriptor/index.html index 223914c9c..c4330fbf0 100644 --- a/modules/invoiceIn/front/descriptor/index.html +++ b/modules/invoiceIn/front/descriptor/index.html @@ -40,7 +40,7 @@ Send agricultural receipt as PDF From 0a9d37ca08b1ff3676aaa3bdcbe38a3a0a7c4b71 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 6 Feb 2023 09:01:13 +0100 Subject: [PATCH 86/88] hotfix itemConfig --- db/changes/230202/00-itemConfig.sql | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 db/changes/230202/00-itemConfig.sql diff --git a/db/changes/230202/00-itemConfig.sql b/db/changes/230202/00-itemConfig.sql new file mode 100644 index 000000000..a793997d0 --- /dev/null +++ b/db/changes/230202/00-itemConfig.sql @@ -0,0 +1,9 @@ +ALTER TABLE `vn`.`itemConfig` ADD defaultTag INT DEFAULT 56 NOT NULL; +ALTER TABLE `vn`.`itemConfig` ADD CONSTRAINT itemConfig_FK FOREIGN KEY (defaultTag) REFERENCES vn.tag(id); +ALTER TABLE `vn`.`itemConfig` ADD validPriorities varchar(50) DEFAULT '[1,2,3]' NOT NULL; +ALTER TABLE `vn`.`itemConfig` ADD defaultPriority INT DEFAULT 2 NOT NULL; +ALTER TABLE `vn`.`item` MODIFY COLUMN relevancy tinyint(1) DEFAULT 0 NOT NULL COMMENT 'La web ordena de forma descendiente por este campo para mostrar los artículos'; + +INSERT INTO `salix`.`ACL` +(model, property, accessType, permission, principalType, principalId) +VALUES('ItemConfig', '*', 'READ', 'ALLOW', 'ROLE', 'buyer'); From ef5b29d6f38d2a391823337baab1eebd50ea5584 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 8 Feb 2023 13:47:35 +0100 Subject: [PATCH 87/88] hotfix ticketFutureAdvance warehouse --- modules/ticket/front/advance/index.js | 15 +++++++++------ modules/ticket/front/future/index.js | 15 +++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index b770440f1..488710ce7 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -65,12 +65,15 @@ export default class Controller extends Section { let today = new Date(); const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); - this.filterParams = { - dateFuture: tomorrow, - dateToAdvance: today, - warehouseFk: this.vnConfig.warehouseFk - }; - this.$.model.applyFilter(null, this.filterParams); + this.$http.get(`UserConfigs/getUserConfig`) + .then(res => { + this.filterParams = { + dateFuture: tomorrow, + dateToAdvance: today, + warehouseFk: res.data.warehouseFk + }; + this.$.model.addFilter({}, this.filterParams); + }); } compareDate(date) { diff --git a/modules/ticket/front/future/index.js b/modules/ticket/front/future/index.js index 5fb2c8f82..1887653e2 100644 --- a/modules/ticket/front/future/index.js +++ b/modules/ticket/front/future/index.js @@ -59,12 +59,15 @@ export default class Controller extends Section { setDefaultFilter() { const today = new Date(); - this.filterParams = { - originDated: today, - futureDated: today, - warehouseFk: this.vnConfig.warehouseFk - }; - this.$.model.applyFilter(null, this.filterParams); + this.$http.get(`UserConfigs/getUserConfig`) + .then(res => { + this.filterParams = { + originDated: today, + futureDated: today, + warehouseFk: res.data.warehouseFk + }; + this.$.model.applyFilter(null, this.filterParams); + }); } compareDate(date) { From 0529d56d4ec3947aa64b45a005501498b5862d96 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 9 Feb 2023 13:30:52 +0100 Subject: [PATCH 88/88] fix(delivery-note_report): fix taxes --- print/templates/reports/delivery-note/delivery-note.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/print/templates/reports/delivery-note/delivery-note.js b/print/templates/reports/delivery-note/delivery-note.js index d9544a58c..50d5720ad 100755 --- a/print/templates/reports/delivery-note/delivery-note.js +++ b/print/templates/reports/delivery-note/delivery-note.js @@ -13,7 +13,7 @@ module.exports = { this.sales = await this.rawSqlFromDef('sales', [this.id]); this.address = await this.findOneFromDef(`address`, [this.id]); this.services = await this.rawSqlFromDef('services', [this.id]); - this.taxes = await this.rawSqlFromDef('taxes', [this.id]); + this.taxes = await this.findOneFromDef('taxes', [this.id]); this.packagings = await this.rawSqlFromDef('packagings', [this.id]); this.signature = await this.findOneFromDef('signature', [this.id]); },