From 65e15ada69e85583b22a0f0cd1bed6ba2c8a7585 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 21 Sep 2022 14:53:02 +0200 Subject: [PATCH 01/29] refator: delete line break --- modules/ticket/back/methods/ticket/componentUpdate.js | 4 ++-- modules/ticket/back/methods/ticket/priceDifference.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 6b385992c4..2b2862d2a5 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -126,8 +126,8 @@ module.exports = Self => { myOptions); if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk) { - const error = `You don't have privileges to change the zone or - for these parameters there are more than one shipping options, talk to agencies`; + const error = `You don't have privileges to change the zone or ` + + `for these parameters there are more than one shipping options, talk to agencies`; throw new UserError(error); } diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 0e8cc2e068..14d4c08e7c 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -88,8 +88,8 @@ module.exports = Self => { myOptions); if (!zoneShipped || zoneShipped.zoneFk != args.zoneId) { - const error = `You don't have privileges to change the zone or - for these parameters there are more than one shipping options, talk to agencies`; + const error = `You don't have privileges to change the zone or ` + + `for these parameters there are more than one shipping options, talk to agencies`; throw new UserError(error); } From fae1516b33304721939d0da749e98e47a6c818d2 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 21 Sep 2022 14:55:43 +0200 Subject: [PATCH 02/29] refactor: correct bleeding --- modules/ticket/back/methods/ticket/componentUpdate.js | 2 +- modules/ticket/back/methods/ticket/priceDifference.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 2b2862d2a5..147be06f9c 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -127,7 +127,7 @@ module.exports = Self => { if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk) { const error = `You don't have privileges to change the zone or ` + - `for these parameters there are more than one shipping options, talk to agencies`; + `for these parameters there are more than one shipping options, talk to agencies`; throw new UserError(error); } diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 14d4c08e7c..16197f21b5 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -89,7 +89,7 @@ module.exports = Self => { if (!zoneShipped || zoneShipped.zoneFk != args.zoneId) { const error = `You don't have privileges to change the zone or ` + - `for these parameters there are more than one shipping options, talk to agencies`; + `for these parameters there are more than one shipping options, talk to agencies`; throw new UserError(error); } From 0fb748719107f0da016cdf3d637e985a8ac9aac5 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 22 Sep 2022 08:32:18 +0200 Subject: [PATCH 03/29] feat: add getItemTypeWorker endpoint --- .../ticket-request/getItemTypeWorker.js | 45 +++++++++++++++++++ .../specs/getItemTypeWorkers.spec.js | 9 ++++ modules/ticket/back/models/ticket-request.js | 1 + .../ticket/front/request/create/index.html | 3 +- 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 modules/ticket/back/methods/ticket-request/getItemTypeWorker.js create mode 100644 modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js diff --git a/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js b/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js new file mode 100644 index 0000000000..ca559f8534 --- /dev/null +++ b/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js @@ -0,0 +1,45 @@ +module.exports = Self => { + Self.remoteMethodCtx('getItemTypeWorker', { + description: 'Returns the workers that appear in itemType', + accessType: 'READ', + accepts: [], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/getItemTypeWorker`, + verb: 'GET' + } + }); + + Self.getItemTypeWorker = async(ctx, options) => { + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const query = + `SELECT DISTINCT w.id, w.firstName, w.lastName, u.name, u.nickname + FROM itemType it + JOIN worker w ON w.id = it.workerFk + JOIN account.user u ON u.id = w.id`; + + const result = await Self.rawSql(query); + + if (tx) await tx.commit(); + + return result; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js b/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js new file mode 100644 index 0000000000..d8791b0adc --- /dev/null +++ b/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js @@ -0,0 +1,9 @@ +const models = require('vn-loopback/server/server').models; + +describe('ticket-request getItemTypeWorker()', () => { + it('should return the workers at itemType as result', async() => { + const result = await models.TicketRequest.getItemTypeWorker(); + + expect(result.length).toEqual(2); + }); +}); diff --git a/modules/ticket/back/models/ticket-request.js b/modules/ticket/back/models/ticket-request.js index 234978f333..4125126dcd 100644 --- a/modules/ticket/back/models/ticket-request.js +++ b/modules/ticket/back/models/ticket-request.js @@ -5,6 +5,7 @@ module.exports = function(Self) { require('../methods/ticket-request/filter')(Self); require('../methods/ticket-request/deny')(Self); require('../methods/ticket-request/confirm')(Self); + require('../methods/ticket-request/getItemTypeWorker')(Self); Self.observe('before save', async function(ctx) { if (ctx.isNewInstance) { diff --git a/modules/ticket/front/request/create/index.html b/modules/ticket/front/request/create/index.html index 8d25358b52..71a2de2608 100644 --- a/modules/ticket/front/request/create/index.html +++ b/modules/ticket/front/request/create/index.html @@ -18,9 +18,8 @@ From 95e5b1a970048a7c5be408ba323e567d9abf90d7 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 22 Sep 2022 13:54:58 +0200 Subject: [PATCH 04/29] fix: code for search-function --- .../ticket-request/getItemTypeWorker.js | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js b/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js index ca559f8534..e635f61a9f 100644 --- a/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js +++ b/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js @@ -1,8 +1,15 @@ +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; + module.exports = Self => { Self.remoteMethodCtx('getItemTypeWorker', { description: 'Returns the workers that appear in itemType', accessType: 'READ', - accepts: [], + accepts: [{ + arg: 'filter', + type: 'Object', + description: 'Filter defining where and paginated data', + required: true + }], returns: { type: ['object'], root: true @@ -13,8 +20,9 @@ module.exports = Self => { } }); - Self.getItemTypeWorker = async(ctx, options) => { + Self.getItemTypeWorker = async(ctx, filter, options) => { const myOptions = {}; + const conn = Self.dataSource.connector; let tx; if (typeof options == 'object') @@ -32,11 +40,25 @@ module.exports = Self => { JOIN worker w ON w.id = it.workerFk JOIN account.user u ON u.id = w.id`; - const result = await Self.rawSql(query); + let stmt = new ParameterizedSQL(query); + + if (filter.where) { + const value = filter.where.firstName; + const myFilter = { + where: {or: [ + {'w.firstName': {like: `%${value}%`}}, + {'w.lastName': {like: `%${value}%`}}, + {'u.name': {like: `%${value}%`}}, + {'u.nickname': {like: `%${value}%`}} + ]} + }; + + stmt.merge(conn.makeSuffix(myFilter)); + } if (tx) await tx.commit(); - return result; + return conn.executeStmt(stmt); } catch (e) { if (tx) await tx.rollback(); throw e; From a486b1593b732cf3984317df7167b1b3d669bc60 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 22 Sep 2022 13:55:09 +0200 Subject: [PATCH 05/29] fix: backTest --- .../specs/getItemTypeWorkers.spec.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js b/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js index d8791b0adc..9cb58e006e 100644 --- a/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js @@ -1,8 +1,20 @@ const models = require('vn-loopback/server/server').models; describe('ticket-request getItemTypeWorker()', () => { + const ctx = {req: {accessToken: {userId: 18}}}; + + it('should return the buyer as result', async() => { + const filter = {where: {firstName: 'buyer'}}; + + const result = await models.TicketRequest.getItemTypeWorker(ctx, filter); + + expect(result.length).toEqual(1); + }); + it('should return the workers at itemType as result', async() => { - const result = await models.TicketRequest.getItemTypeWorker(); + const filter = {}; + + const result = await models.TicketRequest.getItemTypeWorker(ctx, filter); expect(result.length).toEqual(2); }); From 7a690dd8803051484bc169cca262434386b142c6 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 3 Oct 2022 15:11:29 +0200 Subject: [PATCH 06/29] feat(user): add section privileges and remove changeRole in descriptor test(user):back and e2e --- back/methods/account/privileges.js | 58 +++++++++++ back/methods/account/specs/privileges.spec.js | 99 +++++++++++++++++++ back/models/account.js | 3 +- back/models/account.json | 3 + db/changes/10490-august/00-user_hasGrant.sql | 1 + db/dump/fixtures.sql | 4 + e2e/helpers/selectors.js | 7 +- .../01_create_and_basic_data.spec.js | 21 ---- e2e/paths/14-account/09_privileges.spec.js | 86 ++++++++++++++++ modules/account/front/descriptor/index.html | 28 +----- modules/account/front/descriptor/index.js | 14 --- .../account/front/descriptor/index.spec.js | 11 --- modules/account/front/index.js | 1 + modules/account/front/privileges/index.html | 42 ++++++++ modules/account/front/privileges/index.js | 9 ++ .../account/front/privileges/locale/es.yml | 2 + modules/account/front/routes.json | 12 ++- 17 files changed, 324 insertions(+), 77 deletions(-) create mode 100644 back/methods/account/privileges.js create mode 100644 back/methods/account/specs/privileges.spec.js create mode 100644 db/changes/10490-august/00-user_hasGrant.sql create mode 100644 e2e/paths/14-account/09_privileges.spec.js create mode 100644 modules/account/front/privileges/index.html create mode 100644 modules/account/front/privileges/index.js create mode 100644 modules/account/front/privileges/locale/es.yml diff --git a/back/methods/account/privileges.js b/back/methods/account/privileges.js new file mode 100644 index 0000000000..df421125ed --- /dev/null +++ b/back/methods/account/privileges.js @@ -0,0 +1,58 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('privileges', { + description: 'Change role and hasGrant if user has privileges', + accepts: [ + { + arg: 'id', + type: 'number', + required: true, + description: 'The user id', + http: {source: 'path'} + }, + { + arg: 'roleFk', + type: 'number', + description: 'The new role for user', + }, + { + arg: 'hasGrant', + type: 'boolean', + description: 'Whether to has grant' + } + ], + http: { + path: `/:id/privileges`, + verb: 'POST' + } + }); + + Self.privileges = async function(ctx, id, roleFk, hasGrant, options) { + const models = Self.app.models; + const userId = ctx.req.accessToken.userId; + + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const user = await models.Account.findById(userId, null, myOptions); + + if (!user.hasGrant) + throw new UserError(`You don't have enough privileges`); + + const userToUpdate = await models.Account.findById(id); + if (hasGrant != null) + return await userToUpdate.updateAttribute('hasGrant', hasGrant, myOptions); + if (!roleFk) return; + + const role = await models.Role.findById(roleFk, null, myOptions); + const hasRole = await models.Account.hasRole(userId, role.name, myOptions); + + if (!hasRole) + throw new UserError(`You don't have enough privileges`); + + await userToUpdate.updateAttribute('roleFk', roleFk, myOptions); + }; +}; diff --git a/back/methods/account/specs/privileges.spec.js b/back/methods/account/specs/privileges.spec.js new file mode 100644 index 0000000000..137c086711 --- /dev/null +++ b/back/methods/account/specs/privileges.spec.js @@ -0,0 +1,99 @@ +const models = require('vn-loopback/server/server').models; + +describe('account privileges()', () => { + const employeeId = 1; + const developerId = 9; + const sysadminId = 66; + const bruceWayneId = 1101; + + it('should throw an error when user not has privileges', async() => { + const ctx = {req: {accessToken: {userId: developerId}}}; + const tx = await models.Account.beginTransaction({}); + + let error; + try { + const options = {transaction: tx}; + + await models.Account.privileges(ctx, employeeId, null, true, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toContain(`You don't have enough privileges`); + }); + + it('should throw an error when user has privileges but not has the role', async() => { + const ctx = {req: {accessToken: {userId: sysadminId}}}; + const tx = await models.Account.beginTransaction({}); + + let error; + try { + const options = {transaction: tx}; + + const root = await models.Role.findOne({ + where: { + name: 'root' + } + }, options); + await models.Account.privileges(ctx, employeeId, root.id, null, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toContain(`You don't have enough privileges`); + }); + + it('should change role', async() => { + const ctx = {req: {accessToken: {userId: sysadminId}}}; + const tx = await models.Account.beginTransaction({}); + + const options = {transaction: tx}; + const agency = await models.Role.findOne({ + where: { + name: 'agency' + } + }, options); + + let error; + let result; + try { + await models.Account.privileges(ctx, bruceWayneId, agency.id, null, options); + result = await models.Account.findById(bruceWayneId, null, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error).not.toBeDefined(); + expect(result.roleFk).toEqual(agency.id); + }); + + it('should change hasGrant', async() => { + const ctx = {req: {accessToken: {userId: sysadminId}}}; + const tx = await models.Account.beginTransaction({}); + + let error; + let result; + try { + const options = {transaction: tx}; + await models.Account.privileges(ctx, bruceWayneId, null, true, options); + result = await models.Account.findById(bruceWayneId, null, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error).not.toBeDefined(); + expect(result.hasGrant).toBeTruthy(); + }); +}); diff --git a/back/models/account.js b/back/models/account.js index ba703c68d7..f74052b5c9 100644 --- a/back/models/account.js +++ b/back/models/account.js @@ -7,6 +7,7 @@ module.exports = Self => { require('../methods/account/change-password')(Self); require('../methods/account/set-password')(Self); require('../methods/account/validate-token')(Self); + require('../methods/account/privileges')(Self); // Validations @@ -77,7 +78,7 @@ module.exports = Self => { `SELECT r.name FROM account.user u JOIN account.roleRole rr ON rr.role = u.role - JOIN account.role r ON r.id = rr.inheritsFrom + JOIN account.role r ON r.id = rr.inheritsFrom WHERE u.id = ?`, [userId], options); let roles = []; diff --git a/back/models/account.json b/back/models/account.json index 5f0b05f9bd..c25cd532d0 100644 --- a/back/models/account.json +++ b/back/models/account.json @@ -48,6 +48,9 @@ }, "image": { "type": "string" + }, + "hasGrant": { + "type": "boolean" } }, "relations": { diff --git a/db/changes/10490-august/00-user_hasGrant.sql b/db/changes/10490-august/00-user_hasGrant.sql new file mode 100644 index 0000000000..60d1273d83 --- /dev/null +++ b/db/changes/10490-august/00-user_hasGrant.sql @@ -0,0 +1 @@ +ALTER TABLE `account`.`user` ADD hasGrant TINYINT(1) NOT NULL; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 1f66a53cfc..a1c8b708ba 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2651,3 +2651,7 @@ INSERT INTO `vn`.`collection` (`id`, `created`, `workerFk`, `stateFk`, `itemPack 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); + +UPDATE `account`.`user` + SET `hasGrant` = 1 + WHERE `id` = 66; diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 0ad9ad7f40..e499b778b9 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -51,14 +51,12 @@ export default { accountDescriptor: { menuButton: 'vn-user-descriptor vn-icon-button[icon="more_vert"]', deleteAccount: '.vn-menu [name="deleteUser"]', - changeRole: '.vn-menu [name="changeRole"]', setPassword: '.vn-menu [name="setPassword"]', activateAccount: '.vn-menu [name="enableAccount"]', activateUser: '.vn-menu [name="activateUser"]', deactivateUser: '.vn-menu [name="deactivateUser"]', newPassword: 'vn-textfield[ng-model="$ctrl.newPassword"]', repeatPassword: 'vn-textfield[ng-model="$ctrl.repeatPassword"]', - newRole: 'vn-autocomplete[ng-model="$ctrl.newRole"]', activeAccountIcon: 'vn-icon[icon="contact_mail"]', activeUserIcon: 'vn-icon[icon="icon-disabled"]', acceptButton: 'button[response="accept"]', @@ -143,6 +141,11 @@ export default { verifyCert: 'vn-account-samba vn-check[ng-model="$ctrl.config.verifyCert"]', save: 'vn-account-samba vn-submit' }, + accountPrivileges: { + checkHasGrant: 'vn-user-privileges vn-check[ng-model="$ctrl.user.hasGrant"]', + role: 'vn-user-privileges vn-autocomplete[ng-model="$ctrl.user.roleFk"]', + save: 'vn-user-privileges vn-submit' + }, clientsIndex: { createClientButton: `vn-float-button` }, diff --git a/e2e/paths/14-account/01_create_and_basic_data.spec.js b/e2e/paths/14-account/01_create_and_basic_data.spec.js index 0400fb99e2..54e4d1f125 100644 --- a/e2e/paths/14-account/01_create_and_basic_data.spec.js +++ b/e2e/paths/14-account/01_create_and_basic_data.spec.js @@ -62,27 +62,6 @@ describe('Account create and basic data path', () => { }); describe('Descriptor option', () => { - describe('Edit role', () => { - it('should edit the role using the descriptor menu', async() => { - await page.waitToClick(selectors.accountDescriptor.menuButton); - await page.waitToClick(selectors.accountDescriptor.changeRole); - await page.autocompleteSearch(selectors.accountDescriptor.newRole, 'adminBoss'); - await page.waitToClick(selectors.accountDescriptor.acceptButton); - const message = await page.waitForSnackbar(); - - expect(message.text).toContain('Role changed succesfully!'); - }); - - it('should reload the roles section to see now there are more roles', async() => { - // when role updates db takes time to return changes, without this timeout the result would have been 3 - await page.waitForTimeout(1000); - await page.reloadSection('account.card.roles'); - const rolesCount = await page.countElement(selectors.accountRoles.anyResult); - - expect(rolesCount).toEqual(61); - }); - }); - describe('activate account', () => { it(`should check the active account icon isn't present in the descriptor`, async() => { await page.waitForNumberOfElements(selectors.accountDescriptor.activeAccountIcon, 0); diff --git a/e2e/paths/14-account/09_privileges.spec.js b/e2e/paths/14-account/09_privileges.spec.js new file mode 100644 index 0000000000..71e9345a8c --- /dev/null +++ b/e2e/paths/14-account/09_privileges.spec.js @@ -0,0 +1,86 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('Account privileges path', () => { + let browser; + let page; + + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('developer', 'account'); + await page.accessToSearchResult('1101'); + await page.accessToSection('account.card.privileges'); + }); + + afterAll(async() => { + await browser.close(); + }); + + describe('as developer', () => { + it('should throw error when give privileges', async() => { + await page.waitToClick(selectors.accountPrivileges.checkHasGrant); + await page.waitToClick(selectors.accountPrivileges.save); + + const message = await page.waitForSnackbar(); + + expect(message.text).toContain(`You don't have enough privileges`); + }); + + it('should throw error when change role', async() => { + await page.autocompleteSearch(selectors.accountPrivileges.role, 'employee'); + await page.waitToClick(selectors.accountPrivileges.save); + + const message = await page.waitForSnackbar(); + + expect(message.text).toContain(`You don't have enough privileges`); + }); + }); + + describe('as sysadmin', () => { + beforeAll(async() => { + await page.loginAndModule('sysadmin', 'account'); + await page.accessToSearchResult('9'); + await page.accessToSection('account.card.privileges'); + }); + + it('should give privileges', async() => { + await page.waitToClick(selectors.accountPrivileges.checkHasGrant); + await page.waitToClick(selectors.accountPrivileges.save); + const message = await page.waitForSnackbar(); + + await page.reloadSection('account.card.privileges'); + const result = await page.checkboxState(selectors.accountPrivileges.checkHasGrant); + + expect(message.text).toContain(`Data saved!`); + expect(result).toBe('checked'); + }); + + it('should change role', async() => { + await page.autocompleteSearch(selectors.accountPrivileges.role, 'employee'); + await page.waitToClick(selectors.accountPrivileges.save); + const message = await page.waitForSnackbar(); + + await page.reloadSection('account.card.privileges'); + const result = await page.waitToGetProperty(selectors.accountPrivileges.role, 'value'); + + expect(message.text).toContain(`Data saved!`); + expect(result).toContain('employee'); + }); + }); + + describe('as developer again', () => { + it('should remove privileges', async() => { + await page.accessToSearchResult('9'); + await page.accessToSection('account.card.privileges'); + + await page.waitToClick(selectors.accountPrivileges.checkHasGrant); + await page.waitToClick(selectors.accountPrivileges.save); + + await page.reloadSection('account.card.privileges'); + const result = await page.checkboxState(selectors.accountPrivileges.checkHasGrant); + + expect(result).toBe('unchecked'); + }); + }); +}); diff --git a/modules/account/front/descriptor/index.html b/modules/account/front/descriptor/index.html index c709c1ec02..7a7ba43f3e 100644 --- a/modules/account/front/descriptor/index.html +++ b/modules/account/front/descriptor/index.html @@ -11,14 +11,6 @@ translate> Delete - - Change role - - @@ -128,22 +120,6 @@ question="Are you sure you want to continue?" message="User will be deactivated"> - - - - - - - - - - - \ No newline at end of file + diff --git a/modules/account/front/descriptor/index.js b/modules/account/front/descriptor/index.js index 3f27b1f760..b802b2349c 100644 --- a/modules/account/front/descriptor/index.js +++ b/modules/account/front/descriptor/index.js @@ -30,20 +30,6 @@ class Controller extends Descriptor { .then(() => this.vnApp.showSuccess(this.$t('User removed'))); } - onChangeRole() { - this.newRole = this.user.role.id; - this.$.changeRole.show(); - } - - onChangeRoleAccept() { - const params = {roleFk: this.newRole}; - return this.$http.patch(`Accounts/${this.id}`, params) - .then(() => { - this.emit('change'); - this.vnApp.showSuccess(this.$t('Role changed succesfully!')); - }); - } - onChangePassClick(askOldPass) { this.$http.get('UserPasswords/findOne') .then(res => { diff --git a/modules/account/front/descriptor/index.spec.js b/modules/account/front/descriptor/index.spec.js index 8ee67a3046..f5e7aa7d43 100644 --- a/modules/account/front/descriptor/index.spec.js +++ b/modules/account/front/descriptor/index.spec.js @@ -30,17 +30,6 @@ describe('component vnUserDescriptor', () => { }); }); - describe('onChangeRoleAccept()', () => { - it('should call backend method to change role', () => { - $httpBackend.expectPATCH('Accounts/1').respond(); - controller.onChangeRoleAccept(); - $httpBackend.flush(); - - expect(controller.vnApp.showSuccess).toHaveBeenCalled(); - expect(controller.emit).toHaveBeenCalledWith('change'); - }); - }); - describe('onPassChange()', () => { it('should throw an error when password is empty', () => { expect(() => { diff --git a/modules/account/front/index.js b/modules/account/front/index.js index 50e04c9fa4..0cd0c49555 100644 --- a/modules/account/front/index.js +++ b/modules/account/front/index.js @@ -18,3 +18,4 @@ import './roles'; import './ldap'; import './samba'; import './accounts'; +import './privileges'; diff --git a/modules/account/front/privileges/index.html b/modules/account/front/privileges/index.html new file mode 100644 index 0000000000..e3e44898aa --- /dev/null +++ b/modules/account/front/privileges/index.html @@ -0,0 +1,42 @@ + + + +
+ + + + + + + + + + + + + + + + +
diff --git a/modules/account/front/privileges/index.js b/modules/account/front/privileges/index.js new file mode 100644 index 0000000000..00ba772df0 --- /dev/null +++ b/modules/account/front/privileges/index.js @@ -0,0 +1,9 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +export default class Controller extends Section {} + +ngModule.component('vnUserPrivileges', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/account/front/privileges/locale/es.yml b/modules/account/front/privileges/locale/es.yml new file mode 100644 index 0000000000..f7330e1be0 --- /dev/null +++ b/modules/account/front/privileges/locale/es.yml @@ -0,0 +1,2 @@ +Privileges: Privilegios +Has grant: Tiene privilegios diff --git a/modules/account/front/routes.json b/modules/account/front/routes.json index 66b26f4276..b96c931c95 100644 --- a/modules/account/front/routes.json +++ b/modules/account/front/routes.json @@ -19,7 +19,8 @@ {"state": "account.card.basicData", "icon": "settings"}, {"state": "account.card.roles", "icon": "group"}, {"state": "account.card.mailForwarding", "icon": "forward"}, - {"state": "account.card.aliases", "icon": "email"} + {"state": "account.card.aliases", "icon": "email"}, + {"state": "account.card.privileges", "icon": "badge"} ], "role": [ {"state": "account.role.card.basicData", "icon": "settings"}, @@ -99,6 +100,13 @@ "description": "Mail aliases", "acl": ["marketing", "hr"] }, + { + "url": "/privileges", + "state": "account.card.privileges", + "component": "vn-user-privileges", + "description": "Privileges", + "acl": ["hr"] + }, { "url": "/role?q", "state": "account.role", @@ -249,4 +257,4 @@ "acl": ["developer"] } ] -} \ No newline at end of file +} From 197bbf392b29e9e675c875b72779925c1ca89df6 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 4 Oct 2022 07:50:37 +0200 Subject: [PATCH 07/29] refator: updates translations --- loopback/locale/en.json | 4 +++- loopback/locale/es.json | 2 +- modules/ticket/back/methods/ticket/componentUpdate.js | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index fdea4ad4fd..73e186802a 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -131,5 +131,7 @@ "Fichadas impares": "Odd signs", "Descanso diario 9h.": "Daily rest 9h.", "Descanso semanal 36h. / 72h.": "Weekly rest 36h. / 72h.", - "Password does not meet requirements": "Password does not meet requirements" + "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" + } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 327568685b..95e996c48b 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -96,7 +96,7 @@ "This postcode already exists": "Este código postal ya existe", "Concept cannot be blank": "El concepto no puede quedar en blanco", "File doesn't exists": "El archivo no existe", - "You don't have privileges to change the zone or for these parameters there are more than one shipping options, talk to agencies": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias", + "You don't have privileges to change the zone": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias", "This ticket is already on weekly tickets": "Este ticket ya está en tickets programados", "Ticket id cannot be blank": "El id de ticket no puede quedar en blanco", "Weekday cannot be blank": "El día de la semana no puede quedar en blanco", diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 147be06f9c..baa6a0b41b 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -126,8 +126,7 @@ module.exports = Self => { myOptions); if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk) { - const error = `You don't have privileges to change the zone or ` + - `for these parameters there are more than one shipping options, talk to agencies`; + const error = `You don't have privileges to change the zone`; throw new UserError(error); } From f510e2614144ffa3f831e728b7b1aeae072a10a3 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 4 Oct 2022 07:55:30 +0200 Subject: [PATCH 08/29] refactor: translation --- modules/ticket/back/methods/ticket/priceDifference.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 16197f21b5..989e0e5cec 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -88,8 +88,7 @@ module.exports = Self => { myOptions); if (!zoneShipped || zoneShipped.zoneFk != args.zoneId) { - const error = `You don't have privileges to change the zone or ` + - `for these parameters there are more than one shipping options, talk to agencies`; + const error = `You don't have privileges to change the zone`; throw new UserError(error); } From 5c76437498a2ecc074991e62be99a69ac7d7193a Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 4 Oct 2022 08:19:09 +0200 Subject: [PATCH 09/29] refator: delete unnecessary transaction --- .../ticket-request/getItemTypeWorker.js | 46 ++++++++----------- .../specs/getItemTypeWorkers.spec.js | 2 +- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js b/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js index e635f61a9f..fd6af2f828 100644 --- a/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js +++ b/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js @@ -28,40 +28,30 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - if (!myOptions.transaction) { - tx = await Self.beginTransaction({}); - myOptions.transaction = tx; - } - - try { - const query = - `SELECT DISTINCT w.id, w.firstName, w.lastName, u.name, u.nickname + const query = + `SELECT DISTINCT u.nickname FROM itemType it JOIN worker w ON w.id = it.workerFk JOIN account.user u ON u.id = w.id`; - let stmt = new ParameterizedSQL(query); + let stmt = new ParameterizedSQL(query); - if (filter.where) { - const value = filter.where.firstName; - const myFilter = { - where: {or: [ - {'w.firstName': {like: `%${value}%`}}, - {'w.lastName': {like: `%${value}%`}}, - {'u.name': {like: `%${value}%`}}, - {'u.nickname': {like: `%${value}%`}} - ]} - }; + if (filter.where) { + const value = filter.where.firstName; + const myFilter = { + where: {or: [ + {'w.firstName': {like: `%${value}%`}}, + {'w.lastName': {like: `%${value}%`}}, + {'u.name': {like: `%${value}%`}}, + {'u.nickname': {like: `%${value}%`}} + ]} + }; - stmt.merge(conn.makeSuffix(myFilter)); - } - - if (tx) await tx.commit(); - - return conn.executeStmt(stmt); - } catch (e) { - if (tx) await tx.rollback(); - throw e; + stmt.merge(conn.makeSuffix(myFilter)); } + + if (tx) await tx.commit(); + + return conn.executeStmt(stmt); }; }; diff --git a/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js b/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js index 9cb58e006e..ae5c508b6d 100644 --- a/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/getItemTypeWorkers.spec.js @@ -16,6 +16,6 @@ describe('ticket-request getItemTypeWorker()', () => { const result = await models.TicketRequest.getItemTypeWorker(ctx, filter); - expect(result.length).toEqual(2); + expect(result.length).toBeGreaterThan(1); }); }); From 4fadc7e2a493d3bd310bf753ab62d7336996a735 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 6 Oct 2022 13:56:10 +0200 Subject: [PATCH 10/29] Added subversion --- db/changes/10491-august/delete.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 db/changes/10491-august/delete.keep diff --git a/db/changes/10491-august/delete.keep b/db/changes/10491-august/delete.keep new file mode 100644 index 0000000000..e69de29bb2 From 94a51db3d59cffd35c060a6261b1fb530e99c0c1 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 7 Oct 2022 10:56:12 +0200 Subject: [PATCH 11/29] hotFix(ticket_request): autocomplete buyer --- modules/ticket/back/methods/ticket-request/getItemTypeWorker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js b/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js index fd6af2f828..0655c7bba4 100644 --- a/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js +++ b/modules/ticket/back/methods/ticket-request/getItemTypeWorker.js @@ -29,7 +29,7 @@ module.exports = Self => { Object.assign(myOptions, options); const query = - `SELECT DISTINCT u.nickname + `SELECT DISTINCT u.id, u.nickname FROM itemType it JOIN worker w ON w.id = it.workerFk JOIN account.user u ON u.id = w.id`; From 6c5acc75eb9c243e3127b28454b708f24d884539 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 7 Oct 2022 12:00:06 +0200 Subject: [PATCH 12/29] Consumption fix --- .../methods/client/consumptionSendQueued.js | 80 +++++++++---------- modules/client/front/notification/index.js | 3 +- 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/modules/client/back/methods/client/consumptionSendQueued.js b/modules/client/back/methods/client/consumptionSendQueued.js index 3f551d3d29..74ccf164d6 100644 --- a/modules/client/back/methods/client/consumptionSendQueued.js +++ b/modules/client/back/methods/client/consumptionSendQueued.js @@ -18,50 +18,50 @@ module.exports = Self => { Self.consumptionSendQueued = async() => { const queues = await Self.rawSql(` SELECT - ccq.id, - c.id AS clientFk, - c.email AS clientEmail, - eu.email salesPersonEmail, - REPLACE(json_extract(params, '$.from'), '"', '') AS fromDate, - REPLACE(json_extract(params, '$.to'), '"', '') AS toDate - FROM clientConsumptionQueue ccq - JOIN client c ON ( - JSON_SEARCH( - JSON_ARRAY( - json_extract(params, '$.clients') - ) - , 'all', c.id) IS NOT NULL) - JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk - JOIN ticket t ON t.clientFk = c.id - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - JOIN itemType it ON it.id = i.typeFk - WHERE status = '' - AND it.isPackaging = FALSE - AND DATE(t.shipped) BETWEEN - REPLACE(json_extract(params, '$.from'), '"', '') AND - REPLACE(json_extract(params, '$.to'), '"', '') - GROUP BY c.id`); + id, + params + FROM clientConsumptionQueue + WHERE status = ''`); for (const queue of queues) { try { - const args = { - id: queue.clientFk, - recipient: queue.clientEmail, - replyTo: queue.salesPersonEmail, - from: queue.fromDate, - to: queue.toDate - }; + const params = JSON.parse(queue.params); - const email = new Email('campaign-metrics', args); - await email.send(); + const clients = await Self.rawSql(` + SELECT + c.id AS clientFk, + c.email AS clientEmail, + eu.email salesPersonEmail + FROM client c + JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk + JOIN ticket t ON t.clientFk = c.id + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it ON it.id = i.typeFk + WHERE c.id IN(?) + AND it.isPackaging = FALSE + AND DATE(t.shipped) BETWEEN ? AND ? + GROUP BY c.id`, [params.clients, params.from, params.to]); - await Self.rawSql(` - UPDATE clientConsumptionQueue - SET status = 'printed', - printed = ? - WHERE id = ?`, - [new Date(), queue.id]); + for (const client of clients) { + const args = { + id: client.clientFk, + recipient: client.clientEmail, + replyTo: client.salesPersonEmail, + from: params.from, + to: params.to + }; + + const email = new Email('campaign-metrics', args); + await email.send(); + + await Self.rawSql(` + UPDATE clientConsumptionQueue + SET status = 'printed', + printed = ? + WHERE id = ?`, + [new Date(), queue.id]); + } } catch (error) { await Self.rawSql(` UPDATE clientConsumptionQueue @@ -69,7 +69,7 @@ module.exports = Self => { WHERE id = ?`, [error.message, queue.id]); - throw e; + throw error; } } diff --git a/modules/client/front/notification/index.js b/modules/client/front/notification/index.js index e70af12b2f..4be96bc17e 100644 --- a/modules/client/front/notification/index.js +++ b/modules/client/front/notification/index.js @@ -77,12 +77,13 @@ export default class Controller extends Section { onSendClientConsumption() { const clientIds = this.checked.map(client => client.id); - const params = { + const data = { clients: clientIds, from: this.campaign.from, to: this.campaign.to }; + const params = JSON.stringify(data); this.$http.post('ClientConsumptionQueues', {params}) .then(() => this.$.filters.hide()) .then(() => this.vnApp.showSuccess(this.$t('Notifications sent!'))); From 587da840c0653d0b75f38fc971b6454da0fa6211 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 7 Oct 2022 12:16:30 +0200 Subject: [PATCH 13/29] Fix --- .../back/methods/client/consumptionSendQueued.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/client/back/methods/client/consumptionSendQueued.js b/modules/client/back/methods/client/consumptionSendQueued.js index 74ccf164d6..77e0e34f2a 100644 --- a/modules/client/back/methods/client/consumptionSendQueued.js +++ b/modules/client/back/methods/client/consumptionSendQueued.js @@ -54,14 +54,14 @@ module.exports = Self => { const email = new Email('campaign-metrics', args); await email.send(); - - await Self.rawSql(` - UPDATE clientConsumptionQueue - SET status = 'printed', - printed = ? - WHERE id = ?`, - [new Date(), queue.id]); } + + await Self.rawSql(` + UPDATE clientConsumptionQueue + SET status = 'printed', + printed = ? + WHERE id = ?`, + [new Date(), queue.id]); } catch (error) { await Self.rawSql(` UPDATE clientConsumptionQueue From 00d5876f8814a8af5269480c4768c0134d4c4cfa Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 7 Oct 2022 14:35:16 +0200 Subject: [PATCH 14/29] hotFix(travel_extraCommunity): fix css --- .../travel/front/extra-community/index.html | 15 ++++++------ .../travel/front/extra-community/style.scss | 23 +++++++++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/modules/travel/front/extra-community/index.html b/modules/travel/front/extra-community/index.html index f19ab592e7..fbf982b680 100644 --- a/modules/travel/front/extra-community/index.html +++ b/modules/travel/front/extra-community/index.html @@ -42,10 +42,10 @@ Id - + Supplier - + Agency @@ -100,7 +100,7 @@ {{::travel.id}} - + @@ -110,22 +110,23 @@ {{::travel.agencyModeName}} - {{::travel.stickers}} - {{::entry.ref}} + {{::entry.ref}} {{::entry.stickers}} {{::entry.loadedkg}} diff --git a/modules/travel/front/extra-community/style.scss b/modules/travel/front/extra-community/style.scss index 532a3056ab..4b0dd6b226 100644 --- a/modules/travel/front/extra-community/style.scss +++ b/modules/travel/front/extra-community/style.scss @@ -3,7 +3,7 @@ vn-travel-extra-community { .header { margin-bottom: 16px; - font-size: 1.25rem; + font-size: 1.1rem; line-height: 1; padding: 7px; padding-bottom: 7px; @@ -29,10 +29,10 @@ vn-travel-extra-community { outline: 0; height: 65px; pointer-events: fill; - user-select:all; + user-select: all; } - tr[draggable] *::selection{ + tr[draggable] *::selection { background-color: transparent; } @@ -43,16 +43,19 @@ vn-travel-extra-community { tr[draggable].dragging { background-color: $color-primary-light; color: $color-font-light; - font-weight:bold; + font-weight: bold; } - .td-editable{ - input{ - font-size: 1.25rem!important; - } + .td-editable { + max-width: 200px; } - .number *{ - text-align: right; + vn-input-number.number { + min-width: 100px; + padding-right: 10px; + } + + .number * { + text-align: center; } } From 3dee50a796a0e8c5ad792623ea63eb3d04070242 Mon Sep 17 00:00:00 2001 From: joan Date: Sun, 9 Oct 2022 20:14:14 +0200 Subject: [PATCH 15/29] Updated method accessType --- modules/claim/back/methods/claim/claimPickupEmail.js | 5 +++-- modules/route/back/methods/route/driverRouteEmail.js | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/claim/back/methods/claim/claimPickupEmail.js b/modules/claim/back/methods/claim/claimPickupEmail.js index b946353d65..4d64cc66ea 100644 --- a/modules/claim/back/methods/claim/claimPickupEmail.js +++ b/modules/claim/back/methods/claim/claimPickupEmail.js @@ -1,8 +1,9 @@ -const {Report, Email, smtp} = require('vn-print'); +const {Email} = require('vn-print'); module.exports = Self => { Self.remoteMethodCtx('claimPickupEmail', { description: 'Sends the the claim pickup order email with an attached PDF', + accessType: 'WRITE', accepts: [ { arg: 'id', @@ -40,7 +41,7 @@ module.exports = Self => { } }); - Self.claimPickupEmail = async(ctx, id) => { + Self.claimPickupEmail = async ctx => { const args = Object.assign({}, ctx.args); const params = { recipient: args.recipient, diff --git a/modules/route/back/methods/route/driverRouteEmail.js b/modules/route/back/methods/route/driverRouteEmail.js index 81d7703607..4d5279d2d4 100644 --- a/modules/route/back/methods/route/driverRouteEmail.js +++ b/modules/route/back/methods/route/driverRouteEmail.js @@ -3,6 +3,7 @@ const {Email} = require('vn-print'); module.exports = Self => { Self.remoteMethodCtx('driverRouteEmail', { description: 'Sends the driver route email with an attached PDF', + accessType: 'WRITE', accepts: [ { arg: 'id', From 934c0d0169456bdbaaeaa33bba2c407f1298ae65 Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 10 Oct 2022 07:28:10 +0200 Subject: [PATCH 16/29] Updated unit test --- modules/client/front/notification/index.js | 2 +- modules/client/front/notification/index.spec.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/client/front/notification/index.js b/modules/client/front/notification/index.js index 4be96bc17e..faa062b253 100644 --- a/modules/client/front/notification/index.js +++ b/modules/client/front/notification/index.js @@ -86,7 +86,7 @@ export default class Controller extends Section { const params = JSON.stringify(data); this.$http.post('ClientConsumptionQueues', {params}) .then(() => this.$.filters.hide()) - .then(() => this.vnApp.showSuccess(this.$t('Notifications sent!'))); + .then(() => this.vnApp.showSuccess(this.$t('Notification sent!'))); } exprBuilder(param, value) { diff --git a/modules/client/front/notification/index.spec.js b/modules/client/front/notification/index.spec.js index ea082c4038..4e754f6ad8 100644 --- a/modules/client/front/notification/index.spec.js +++ b/modules/client/front/notification/index.spec.js @@ -69,15 +69,16 @@ describe('Client notification', () => { data[0].$checked = true; data[1].$checked = true; - const params = Object.assign({ + const args = Object.assign({ clients: [1101, 1102] }, controller.campaign); + const params = JSON.stringify(args); $httpBackend.expect('POST', `ClientConsumptionQueues`, {params}).respond(200, params); controller.onSendClientConsumption(); $httpBackend.flush(); - expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Notifications sent!'); + expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Notification sent!'); }); }); From 4ecbb59ac01a88db5679afe84a68a93d56d7d99f Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 10 Oct 2022 07:49:08 +0200 Subject: [PATCH 17/29] Closure hours --- modules/ticket/back/methods/ticket/closeAll.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/ticket/back/methods/ticket/closeAll.js b/modules/ticket/back/methods/ticket/closeAll.js index 4f3813eb83..5e81e38274 100644 --- a/modules/ticket/back/methods/ticket/closeAll.js +++ b/modules/ticket/back/methods/ticket/closeAll.js @@ -18,6 +18,7 @@ module.exports = Self => { Self.closeAll = async() => { const toDate = new Date(); + toDate.setHours(0, 0, 0, 0); toDate.setDate(toDate.getDate() - 1); const todayMinDate = new Date(); From 18cd34bccb93c561c732601c19f1c2433a973d9b Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 10 Oct 2022 08:57:41 +0200 Subject: [PATCH 18/29] fix(travel_extraCommunity): css --- modules/travel/front/extra-community/index.html | 6 +++--- modules/travel/front/extra-community/style.scss | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/modules/travel/front/extra-community/index.html b/modules/travel/front/extra-community/index.html index fbf982b680..8d9b360ead 100644 --- a/modules/travel/front/extra-community/index.html +++ b/modules/travel/front/extra-community/index.html @@ -54,7 +54,7 @@ Packages - + Bl. KG @@ -100,7 +100,7 @@ {{::travel.id}} - + @@ -151,7 +151,7 @@ {{::entry.id}} - + diff --git a/modules/travel/front/extra-community/style.scss b/modules/travel/front/extra-community/style.scss index 4b0dd6b226..b3cc73a6a4 100644 --- a/modules/travel/front/extra-community/style.scss +++ b/modules/travel/front/extra-community/style.scss @@ -52,10 +52,15 @@ vn-travel-extra-community { vn-input-number.number { min-width: 100px; - padding-right: 10px; } .number * { text-align: center; } + + .multi-line{ + max-width: 200px; + word-wrap: normal; + white-space: normal; + } } From e497ddd66445f83c9aaa8c37d86f048a59f1df57 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 10 Oct 2022 09:21:14 +0200 Subject: [PATCH 19/29] fix: add td-editable --- .../travel/front/extra-community/index.html | 47 +++++++++---------- .../travel/front/extra-community/style.scss | 25 +++++----- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/modules/travel/front/extra-community/index.html b/modules/travel/front/extra-community/index.html index 8d9b360ead..5174f8da25 100644 --- a/modules/travel/front/extra-community/index.html +++ b/modules/travel/front/extra-community/index.html @@ -54,7 +54,7 @@ Packages - + Bl. KG @@ -107,31 +107,30 @@ {{::travel.cargoSupplierNickname}} - {{::travel.agencyModeName}} - - - + {{::travel.agencyModeName}} + + + {{travel.ref}} + + + + + {{::travel.stickers}} - - - + + + {{travel.kg}} + + + + + {{::travel.loadedKg}} {{::travel.volumeKg}} diff --git a/modules/travel/front/extra-community/style.scss b/modules/travel/front/extra-community/style.scss index b3cc73a6a4..fb64822f97 100644 --- a/modules/travel/front/extra-community/style.scss +++ b/modules/travel/front/extra-community/style.scss @@ -3,7 +3,6 @@ vn-travel-extra-community { .header { margin-bottom: 16px; - font-size: 1.1rem; line-height: 1; padding: 7px; padding-bottom: 7px; @@ -16,6 +15,10 @@ vn-travel-extra-community { overflow: hidden; text-overflow: ellipsis; cursor: pointer; + .multi-line{ + padding-top: 15px; + padding-bottom: 15px; + } } table[vn-droppable] { @@ -46,21 +49,19 @@ vn-travel-extra-community { font-weight: bold; } - .td-editable { - max-width: 200px; - } - - vn-input-number.number { - min-width: 100px; - } - - .number * { - text-align: center; - } .multi-line{ max-width: 200px; word-wrap: normal; white-space: normal; } + + vn-td-editable text { + background-color: transparent; + padding: 0; + border: 0; + border-bottom: 1px dashed $color-active; + border-radius: 0; + color: $color-active + } } From 31d1b84bb9efa9d69f81f84b2295eaf3dc03cedd Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 10 Oct 2022 10:25:59 +0200 Subject: [PATCH 20/29] Unfold when there's less than 100 nodes to show --- modules/zone/back/methods/zone/getLeaves.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/zone/back/methods/zone/getLeaves.js b/modules/zone/back/methods/zone/getLeaves.js index db17beb1bb..1b5b116e75 100644 --- a/modules/zone/back/methods/zone/getLeaves.js +++ b/modules/zone/back/methods/zone/getLeaves.js @@ -59,7 +59,10 @@ module.exports = Self => { } const leaves = map.get(parentId); - setLeaves(leaves); + + const maxNodes = 100; + if (res.length <= maxNodes) + setLeaves(leaves); return leaves || []; }; From 990a1b3c6793d4f1cbc4b77f9c278195069e3933 Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 10 Oct 2022 10:33:08 +0200 Subject: [PATCH 21/29] 250 nodes --- modules/zone/back/methods/zone/getLeaves.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/zone/back/methods/zone/getLeaves.js b/modules/zone/back/methods/zone/getLeaves.js index 1b5b116e75..ed421e3397 100644 --- a/modules/zone/back/methods/zone/getLeaves.js +++ b/modules/zone/back/methods/zone/getLeaves.js @@ -60,7 +60,7 @@ module.exports = Self => { const leaves = map.get(parentId); - const maxNodes = 100; + const maxNodes = 250; if (res.length <= maxNodes) setLeaves(leaves); From 7f023d7456ff5383ab5ec0d20034d2bb64d52734 Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 10 Oct 2022 12:23:40 +0200 Subject: [PATCH 22/29] Set user default warehouse --- modules/item/front/diary/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/item/front/diary/index.js b/modules/item/front/diary/index.js index 6d912ebe8a..c997ea4918 100644 --- a/modules/item/front/diary/index.js +++ b/modules/item/front/diary/index.js @@ -27,7 +27,7 @@ class Controller extends Section { if (this.$params.warehouseFk) this.warehouseFk = this.$params.warehouseFk; else if (value) - this.warehouseFk = value.itemType.warehouseFk; + this.warehouseFk = this.vnConfig.warehouseFk; if (this.$params.lineFk) this.lineFk = this.$params.lineFk; From e85d6bec8cd6c8f379d235aa2f28be3d85a1fed2 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 10 Oct 2022 14:03:29 +0200 Subject: [PATCH 23/29] fix e2e --- e2e/helpers/selectors.js | 4 ++-- e2e/paths/10-travel/04_extra_community.spec.js | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index fedcaf5f95..cd6d39795b 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -1022,8 +1022,8 @@ export default { }, travelExtraCommunity: { anySearchResult: 'vn-travel-extra-community > vn-card div > tbody > tr[ng-attr-id="{{::travel.id}}"]', - firstTravelReference: 'vn-travel-extra-community tbody:nth-child(2) vn-textfield[ng-model="travel.ref"]', - firstTravelLockedKg: 'vn-travel-extra-community tbody:nth-child(2) vn-input-number[ng-model="travel.kg"]', + firstTravelReference: 'vn-travel-extra-community tbody:nth-child(2) vn-td-editable[name="reference"]', + firstTravelLockedKg: 'vn-travel-extra-community tbody:nth-child(2) vn-td-editable[name="lockedKg"]', removeContinentFilter: 'vn-searchbar > form > vn-textfield > div.container > div.prepend > prepend > div > span:nth-child(3) > vn-icon > i' }, travelBasicData: { diff --git a/e2e/paths/10-travel/04_extra_community.spec.js b/e2e/paths/10-travel/04_extra_community.spec.js index a1cad6a7d1..c5975c9583 100644 --- a/e2e/paths/10-travel/04_extra_community.spec.js +++ b/e2e/paths/10-travel/04_extra_community.spec.js @@ -19,10 +19,10 @@ describe('Travel extra community path', () => { it('should edit the travel reference and the locked kilograms', async() => { await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter); await page.waitForSpinnerLoad(); - await page.clearInput(selectors.travelExtraCommunity.firstTravelReference); - await page.write(selectors.travelExtraCommunity.firstTravelReference, 'edited reference'); - await page.clearInput(selectors.travelExtraCommunity.firstTravelLockedKg); - await page.write(selectors.travelExtraCommunity.firstTravelLockedKg, '1500'); + await page.writeOnEditableTD(selectors.travelExtraCommunity.firstTravelReference, 'edited reference'); + await page.waitForSpinnerLoad(); + await page.writeOnEditableTD(selectors.travelExtraCommunity.firstTravelLockedKg, '1500'); + const message = await page.waitForSnackbar(); expect(message.text).toContain('Data saved!'); @@ -32,9 +32,9 @@ describe('Travel extra community path', () => { await page.accessToSection('travel.index'); await page.accessToSection('travel.extraCommunity'); await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter); - - const reference = await page.waitToGetProperty(selectors.travelExtraCommunity.firstTravelReference, 'value'); - const lockedKg = await page.waitToGetProperty(selectors.travelExtraCommunity.firstTravelLockedKg, 'value'); + await page.waitForTextInElement(selectors.travelExtraCommunity.firstTravelReference, 'edited reference'); + const reference = await page.getProperty(selectors.travelExtraCommunity.firstTravelReference, 'innerText'); + const lockedKg = await page.getProperty(selectors.travelExtraCommunity.firstTravelLockedKg, 'innerText'); expect(reference).toContain('edited reference'); expect(lockedKg).toContain(1500); From e3606c72731875f032d5ae77e3530b966c6ffaa3 Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 10 Oct 2022 14:46:06 +0200 Subject: [PATCH 24/29] Updated unit test --- modules/item/front/diary/index.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/item/front/diary/index.spec.js b/modules/item/front/diary/index.spec.js index 78dae08832..878ce66240 100644 --- a/modules/item/front/diary/index.spec.js +++ b/modules/item/front/diary/index.spec.js @@ -19,7 +19,8 @@ describe('Item', () => { describe('set item()', () => { it('should set warehouseFk property based on itemType warehouseFk', () => { jest.spyOn(controller.$, '$applyAsync'); - controller.item = {id: 1, itemType: {warehouseFk: 1}}; + controller.item = {id: 1}; + controller.vnConfig = {warehouseFk: 1}; expect(controller.$.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function)); $scope.$apply(); From d06492d367a0b4b6e586585e96ead1e714cd7f4d Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 11 Oct 2022 14:28:14 +0200 Subject: [PATCH 25/29] Transaction error --- back/methods/dms/deleteTrashFiles.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/back/methods/dms/deleteTrashFiles.js b/back/methods/dms/deleteTrashFiles.js index e8b342ccc2..5e31143339 100644 --- a/back/methods/dms/deleteTrashFiles.js +++ b/back/methods/dms/deleteTrashFiles.js @@ -17,7 +17,6 @@ module.exports = Self => { }); Self.deleteTrashFiles = async options => { - const tx = await Self.beginTransaction({}); const myOptions = {}; if (typeof options == 'object') @@ -27,6 +26,7 @@ module.exports = Self => { myOptions.transaction = tx; try { + const tx = await Self.beginTransaction({}); if (process.env.NODE_ENV == 'test') throw new UserError(`Action not allowed on the test environment`); @@ -61,10 +61,9 @@ module.exports = Self => { const dstFolder = path.join(dmsContainer.client.root, pathHash); try { await fs.rmdir(dstFolder); - await dms.destroy(myOptions); - } catch (err) { - await dms.destroy(myOptions); - } + } catch (err) {} + + await dms.destroy(myOptions); } if (tx) await tx.commit(); } catch (e) { From b2e98c9d73067a9be99d35c550f5c54a03030a7e Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 11 Oct 2022 14:39:57 +0200 Subject: [PATCH 26/29] Transaction --- back/methods/dms/deleteTrashFiles.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/back/methods/dms/deleteTrashFiles.js b/back/methods/dms/deleteTrashFiles.js index 5e31143339..6f9a2a211d 100644 --- a/back/methods/dms/deleteTrashFiles.js +++ b/back/methods/dms/deleteTrashFiles.js @@ -17,16 +17,18 @@ module.exports = Self => { }); Self.deleteTrashFiles = async options => { + let tx; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - if (!myOptions.transaction) + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); myOptions.transaction = tx; + } try { - const tx = await Self.beginTransaction({}); if (process.env.NODE_ENV == 'test') throw new UserError(`Action not allowed on the test environment`); From 74383b61e738405ada1fd7f6348f9d230ab213fb Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 13 Oct 2022 09:22:53 +0200 Subject: [PATCH 27/29] hotFix(monitor): use left join in ticketState --- modules/item/front/diary/index.spec.js | 3 ++- modules/monitor/back/methods/sales-monitor/salesFilter.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/item/front/diary/index.spec.js b/modules/item/front/diary/index.spec.js index 78dae08832..a80fbfc690 100644 --- a/modules/item/front/diary/index.spec.js +++ b/modules/item/front/diary/index.spec.js @@ -19,7 +19,8 @@ describe('Item', () => { describe('set item()', () => { it('should set warehouseFk property based on itemType warehouseFk', () => { jest.spyOn(controller.$, '$applyAsync'); - controller.item = {id: 1, itemType: {warehouseFk: 1}}; + controller.vnConfig = {warehouseFk: 1}; + controller.item = {id: 1}; expect(controller.$.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function)); $scope.$apply(); diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index ff642b0883..7be130dda8 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -211,7 +211,7 @@ module.exports = Self => { LEFT JOIN province p ON p.id = a.provinceFk LEFT JOIN warehouse w ON w.id = t.warehouseFk LEFT JOIN agencyMode am ON am.id = t.agencyModeFk - STRAIGHT_JOIN ticketState ts ON ts.ticketFk = t.id + LEFT JOIN ticketState ts ON ts.ticketFk = t.id LEFT JOIN state st ON st.id = ts.stateFk LEFT JOIN client c ON c.id = t.clientFk LEFT JOIN worker wk ON wk.id = c.salesPersonFk From 67097970edc46fc592194a74d39c5d566535ed3a Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 13 Oct 2022 10:44:20 +0200 Subject: [PATCH 28/29] Incoterms required param --- modules/ticket/back/methods/ticket/closure.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/ticket/back/methods/ticket/closure.js b/modules/ticket/back/methods/ticket/closure.js index 3cbc85f96f..23d7130ee8 100644 --- a/modules/ticket/back/methods/ticket/closure.js +++ b/modules/ticket/back/methods/ticket/closure.js @@ -101,6 +101,7 @@ module.exports = async function(Self, tickets, reqArgs = {}) { if (firstOrder == 1) { const args = { id: ticket.clientFk, + companyId: ticket.companyFk, recipientId: ticket.clientFk, recipient: ticket.recipient, replyTo: ticket.salesPersonEmail From 390ee60e59c308adda030523df42b2ff2a1b57b8 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 14 Oct 2022 07:26:34 +0200 Subject: [PATCH 29/29] Get first element in array --- modules/ticket/back/methods/ticket/closure.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket/closure.js b/modules/ticket/back/methods/ticket/closure.js index 23d7130ee8..d5fa58e7bd 100644 --- a/modules/ticket/back/methods/ticket/closure.js +++ b/modules/ticket/back/methods/ticket/closure.js @@ -110,7 +110,7 @@ module.exports = async function(Self, tickets, reqArgs = {}) { const email = new Email('incoterms-authorization', args); await email.send(); - const sample = await Self.rawSql( + const [sample] = await Self.rawSql( `SELECT id FROM sample WHERE code = 'incoterms-authorization'