diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js index d00085d8a..2fd1f43c0 100644 --- a/back/methods/vn-user/renew-token.js +++ b/back/methods/vn-user/renew-token.js @@ -33,16 +33,23 @@ module.exports = Self => { // Schedule to remove current token setTimeout(async() => { try { - await Self.logout(token.id); + const exists = await models.AccessToken.findById(token.id); + exists && await Self.logout(token.id); } catch (err) { // eslint-disable-next-line no-console console.error(err); } }, courtesyTime * 1000); + // Get scopes + + let createTokenOptions = {}; + const {scopes} = token; + if (scopes) + createTokenOptions = {scopes: [scopes[0]]}; // Create new accessToken const user = await Self.findById(token.userId); - const accessToken = await user.createAccessToken(); + const accessToken = await user.accessTokens.create(createTokenOptions); return {id: accessToken.id, ttl: accessToken.ttl}; }; diff --git a/back/methods/vn-user/specs/renew-token.spec.js b/back/methods/vn-user/specs/renew-token.spec.js index 8d9bbf11c..741388bf9 100644 --- a/back/methods/vn-user/specs/renew-token.spec.js +++ b/back/methods/vn-user/specs/renew-token.spec.js @@ -33,6 +33,17 @@ describe('Renew Token', () => { const {id} = await models.VnUser.renewToken(ctx); expect(id).not.toEqual(ctx.req.accessToken.id); + + await models.VnUser.logout(ctx.req.accessToken.id); + jasmine.clock().tick(70 * 1000); + let tokenNotExists; + try { + tokenNotExists = await models.AccessToken.findById(ctx.req.accessToken.id); + } catch (e) { + error = e; + } + + expect(tokenNotExists).toBeNull(); }); it('NOT should renew', async() => { diff --git a/back/methods/vn-user/specs/share-token.spec.js b/back/methods/vn-user/specs/share-token.spec.js index aaa83817c..e072a4fa8 100644 --- a/back/methods/vn-user/specs/share-token.spec.js +++ b/back/methods/vn-user/specs/share-token.spec.js @@ -1,6 +1,9 @@ const {models} = require('vn-loopback/server/server'); +const TOKEN_MULTIMEDIA = 'read:multimedia'; describe('Share Token', () => { let ctx = null; + const startingTime = Date.now(); + let multimediaToken = null; beforeAll(async() => { const unAuthCtx = { req: { @@ -17,11 +20,45 @@ describe('Share Token', () => { ctx = {req: {accessToken: accessToken}}; }); - it('should renew token', async() => { - const multimediaToken = await models.VnUser.shareToken(ctx); + beforeEach(async() => { + multimediaToken = await models.VnUser.shareToken(ctx); + jasmine.clock().install(); + jasmine.clock().mockDate(new Date(startingTime)); + }); + afterEach(() => { + jasmine.clock().uninstall(); + }); + + it('should generate token', async() => { expect(Object.keys(multimediaToken).length).toEqual(1); expect(multimediaToken.multimediaToken.userId).toEqual(ctx.req.accessToken.userId); - expect(multimediaToken.multimediaToken.scopes[0]).toEqual('read:multimedia'); + expect(multimediaToken.multimediaToken.scopes[0]).toEqual(TOKEN_MULTIMEDIA); + }); + + it('NOT should renew', async() => { + let error; + let response; + try { + response = await models.VnUser.renewToken(ctx); + } catch (e) { + error = e; + } + + expect(error).toBeUndefined(); + expect(response.id).toEqual(ctx.req.accessToken.id); + }); + + it('should renew token', async() => { + const mockDate = new Date(startingTime + 26600000); + jasmine.clock().mockDate(mockDate); + + const newShareToken = await models.VnUser.renewToken({req: {accessToken: multimediaToken.multimediaToken}}); + const {id} = newShareToken; + + expect(id).not.toEqual(ctx.req.accessToken.id); + const newMultimediaToken = await models.AccessToken.findById(id); + + expect(newMultimediaToken.scopes[0]).toEqual(TOKEN_MULTIMEDIA); }); }); diff --git a/db/routines/edi/procedures/ekt_load.sql b/db/routines/edi/procedures/ekt_load.sql index ccdcd1999..34814453b 100644 --- a/db/routines/edi/procedures/ekt_load.sql +++ b/db/routines/edi/procedures/ekt_load.sql @@ -147,7 +147,7 @@ proc:BEGIN (@t := IF(i.stems, i.stems, 1)) * e.pri / IFNULL(i.stemMultiplier, 1) buyingValue, IFNULL(vItem, vDefaultEntry) itemFk, e.qty stickers, - @pac := IFNULL(i.stemMultiplier, 1) * e.pac / @t packing, + @pac := GREATEST(1, IFNULL(i.stemMultiplier * e.pac / @t, 0)) packing, IFNULL(b.`grouping`, e.pac), @pac * e.qty, vForceToPacking, diff --git a/db/routines/hedera/events/order_doRecalc.sql b/db/routines/hedera/events/order_doRecalc.sql index d355e1a55..bbc61924f 100644 --- a/db/routines/hedera/events/order_doRecalc.sql +++ b/db/routines/hedera/events/order_doRecalc.sql @@ -3,6 +3,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` EVENT `hedera`.`order_doRecalc` ON SCHEDULE EVERY 10 SECOND STARTS '2019-08-29 14:18:04.000' ON COMPLETION PRESERVE - ENABLE + DISABLE DO CALL order_doRecalc$$ DELIMITER ; diff --git a/db/routines/hedera/procedures/order_requestRecalc.sql b/db/routines/hedera/procedures/order_requestRecalc.sql index 4bcb1010e..990894bb6 100644 --- a/db/routines/hedera/procedures/order_requestRecalc.sql +++ b/db/routines/hedera/procedures/order_requestRecalc.sql @@ -10,6 +10,7 @@ proc: BEGIN LEAVE proc; END IF; - INSERT INTO orderRecalc SET orderFk = vSelf; + -- #4409 Disable order recalc + -- INSERT INTO orderRecalc SET orderFk = vSelf; END$$ DELIMITER ; diff --git a/db/routines/util/procedures/slowLog_prune.sql b/db/routines/util/procedures/slowLog_prune.sql index 7294be2f6..d676ae3d9 100644 --- a/db/routines/util/procedures/slowLog_prune.sql +++ b/db/routines/util/procedures/slowLog_prune.sql @@ -6,16 +6,24 @@ BEGIN */ DECLARE vSlowQueryLog INT DEFAULT @@slow_query_log; DECLARE vSqlLogBin INT DEFAULT @@SESSION.sql_log_bin; + DECLARE vLogExists BOOL; SET sql_log_bin = OFF; SET GLOBAL slow_query_log = OFF; - RENAME TABLE `mysql`.`slow_log` TO `mysql`.`slow_log_temp`; + SELECT COUNT(*) > 0 INTO vLogExists + FROM information_schema.TABLES + WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'slow_log'; - DELETE FROM `mysql`.`slow_log_temp` + IF vLogExists THEN + DROP TEMPORARY TABLE IF EXISTS mysql.slow_log_temp; + RENAME TABLE mysql.slow_log TO mysql.slow_log_temp; + END IF; + + DELETE FROM mysql.slow_log_temp WHERE start_time < TIMESTAMPADD(WEEK, -1, util.VN_NOW()); - RENAME TABLE `mysql`.`slow_log_temp` TO `mysql`.`slow_log`; + RENAME TABLE mysql.slow_log_temp TO mysql.slow_log; SET GLOBAL slow_query_log = vSlowQueryLog; SET sql_log_bin = vSqlLogBin; diff --git a/db/routines/vn/procedures/item_setVisibleDiscard.sql b/db/routines/vn/procedures/item_setVisibleDiscard.sql index 1cc2a8871..0a6c54971 100644 --- a/db/routines/vn/procedures/item_setVisibleDiscard.sql +++ b/db/routines/vn/procedures/item_setVisibleDiscard.sql @@ -13,6 +13,7 @@ BEGIN * @param vQuantity a dar de alta/baja * @param vAddressFk id address */ + DECLARE vTicketFk INT; DECLARE vClientFk INT; DECLARE vDefaultCompanyFk INT; @@ -23,17 +24,17 @@ BEGIN SELECT DEFAULT(companyFk) INTO vDefaultCompanyFk FROM vn.ticket LIMIT 1; - - IF vAddressFk IS NULL THEN + + IF vAddressFk IS NULL THEN SELECT pc.shortageAddressFk INTO vAddressShortage FROM productionConfig pc ; - ELSE + ELSE SET vAddressShortage = vAddressFk; END IF; SELECT a.clientFk INTO vClientFk FROM address a - WHERE a.id = vAddressFk; + WHERE a.id = vAddressShortage; SELECT t.id INTO vTicketFk FROM ticket t @@ -65,7 +66,7 @@ BEGIN INSERT INTO sale(ticketFk, itemFk, concept, quantity) SELECT vTicketFk, vItemFk, - CONCAT(longName,' ', worker_getCode(), ' ', LEFT(CAST(util.VN_NOW() AS TIME),5)), + name, vQuantity FROM item WHERE id = vItemFk; diff --git a/db/versions/10994-wheatLaurel/00-modifyAcls.sql b/db/versions/10994-wheatLaurel/00-modifyAcls.sql new file mode 100644 index 000000000..905f67aba --- /dev/null +++ b/db/versions/10994-wheatLaurel/00-modifyAcls.sql @@ -0,0 +1,4 @@ +UPDATE salix.ACL SET principalId = "hr" WHERE property IN ('find','findById','findOne') AND model = "Worker"; + +INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) + VALUES ('Worker', '__get__summary', 'READ', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/e2e/paths/03-worker/01_summary.spec.js b/e2e/paths/03-worker/01_summary.spec.js index 51992b41d..3c6149726 100644 --- a/e2e/paths/03-worker/01_summary.spec.js +++ b/e2e/paths/03-worker/01_summary.spec.js @@ -2,7 +2,6 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; describe('Worker summary path', () => { - const workerId = 3; let browser; let page; beforeAll(async() => { @@ -10,7 +9,7 @@ describe('Worker summary path', () => { page = browser.page; await page.loginAndModule('employee', 'worker'); const httpDataResponse = page.waitForResponse(response => { - return response.status() === 200 && response.url().includes(`Workers/${workerId}`); + return response.status() === 200 && response.url().includes(`Workers/summary`); }); await page.accessToSearchResult('agencyNick'); await httpDataResponse; diff --git a/modules/claim/back/models/claim-beginning.js b/modules/claim/back/models/claim-beginning.js index 4b870e5ea..d269b2285 100644 --- a/modules/claim/back/models/claim-beginning.js +++ b/modules/claim/back/models/claim-beginning.js @@ -19,7 +19,7 @@ module.exports = Self => { if (ticket.ticketFk != claim.ticketFk) throw new UserError(`Cannot create a new claimBeginning from a different ticket`); } - // await claimIsEditable(ctx); + await claimIsEditable(ctx); }); Self.observe('before delete', async ctx => { @@ -36,7 +36,7 @@ module.exports = Self => { if (ctx.options && ctx.options.transaction) myOptions.transaction = ctx.options.transaction; - const claimBeginning = await Self.findById(ctx.where.id); + const claimBeginning = ctx.instance ?? await Self.findById(ctx.where.id); const filter = { where: {id: claimBeginning.claimFk}, diff --git a/modules/worker/back/models/worker.json b/modules/worker/back/models/worker.json index ed430f133..57dc80ec9 100644 --- a/modules/worker/back/models/worker.json +++ b/modules/worker/back/models/worker.json @@ -92,5 +92,87 @@ "model": "WorkerTeamCollegues", "foreignKey": "workerFk" } + }, + "scopes":{ + "summary": { + "include": [ + { + "relation": "user", + "scope": { + "fields": ["email", "name", "nickname", "roleFk"], + "include": [ + { + "relation": "role", + "scope": { + "fields": ["name"] + } + }, + { + "relation": "emailUser", + "scope": { + "fields": ["email"] + } + } + ] + } + }, { + "relation": "department", + "scope": { + "include": { + "relation": "department" + } + } + }, { + "relation": "boss" + }, { + "relation": "client", + "scope": { + "fields": [ + "id", + "name", + "fi", + "socialName", + "contact", + "street", + "city", + "postcode", + "email", + "mobile", + "isActive", + "credit", + "creditInsurance", + "iban", + "dueDay", + "isEqualizated", + "isFreezed", + "hasToInvoiceByAddress", + "hasToInvoice", + "isToBeMailed", + "hasSepaVnl", + "hasLcr", + "hasCoreVnl", + "hasCoreVnh", + "hasIncoterms", + "isTaxDataChecked", + "eypbc", + "quality", + "isVies", + "isRelevant", + "accountingAccount", + "created", + "sageTaxTypeFk", + "sageTransactionTypeFk", + "businessTypeFk", + "salesPersonFk", + "hasElectronicInvoice", + "rating", + "recommendedCredit" + ] + } + }, { + "relation": "sip" + } + ] + } } } diff --git a/modules/worker/front/card/index.js b/modules/worker/front/card/index.js index 9a40e31c2..1aa548db9 100644 --- a/modules/worker/front/card/index.js +++ b/modules/worker/front/card/index.js @@ -4,37 +4,13 @@ import ModuleCard from 'salix/components/module-card'; class Controller extends ModuleCard { reload() { const filter = { - include: [ - { - relation: 'user', - scope: { - fields: ['name', 'emailVerified'], - include: { - relation: 'emailUser', - scope: { - fields: ['email'] - } - } - } - }, { - relation: 'sip', - scope: { - fields: ['extension', 'secret'] - } - }, { - relation: 'department', - scope: { - include: { - relation: 'department' - } - } - } - ] + where: { + id: this.$params.id} }; return Promise.all([ - this.$http.get(`Workers/${this.$params.id}`, {filter}) - .then(res => this.worker = res.data), + this.$http.get(`Workers/summary`, {filter}) + .then(res => this.worker = res.data[0]), this.$http.get(`Workers/${this.$params.id}/activeContract`) .then(res => this.hasWorkCenter = res.data?.workCenterFk) ]); diff --git a/modules/worker/front/descriptor/index.js b/modules/worker/front/descriptor/index.js index d7962369c..ebf3d65ed 100644 --- a/modules/worker/front/descriptor/index.js +++ b/modules/worker/front/descriptor/index.js @@ -37,41 +37,11 @@ class Controller extends Descriptor { loadData() { const filter = { - include: [ - { - relation: 'user', - scope: { - fields: ['name', 'emailVerified'], - include: { - relation: 'emailUser', - scope: { - fields: ['email'] - } - } - } - }, { - relation: 'client', - scope: { - fields: ['fi'] - } - }, { - relation: 'sip', - scope: { - fields: ['extension'] - } - }, { - relation: 'department', - scope: { - include: { - relation: 'department' - } - } - } - ] + where: {id: this.id}, }; - return this.getData(`Workers/${this.id}`, {filter}) - .then(res => this.entity = res.data); + return this.getData(`Workers/summary`, {filter}) + .then(res => this.entity = res.data[0]); } getPassRequirements() { diff --git a/modules/worker/front/descriptor/index.spec.js b/modules/worker/front/descriptor/index.spec.js index 4f7fa6a05..cee8b0def 100644 --- a/modules/worker/front/descriptor/index.spec.js +++ b/modules/worker/front/descriptor/index.spec.js @@ -14,14 +14,14 @@ describe('vnWorkerDescriptor', () => { describe('loadData()', () => { it(`should perform a get query to store the worker data into the controller`, () => { const id = 1; - const response = 'foo'; + const response = ['foo']; $httpBackend.whenGET('UserConfigs/getUserConfig').respond({}); - $httpBackend.expectRoute('GET', `Workers/${id}`).respond(response); + $httpBackend.expectRoute('GET', `Workers/summary`).respond(response); controller.id = id; $httpBackend.flush(); - expect(controller.worker).toEqual(response); + expect([controller.worker]).toEqual(response); }); }); diff --git a/modules/worker/front/summary/index.js b/modules/worker/front/summary/index.js index 212609f58..d1a27a6d4 100644 --- a/modules/worker/front/summary/index.js +++ b/modules/worker/front/summary/index.js @@ -10,53 +10,14 @@ class Controller extends Summary { this.$.worker = null; if (!value) return; - const query = `Workers/${value.id}`; const filter = { - include: [ - { - relation: 'user', - scope: { - fields: ['name', 'roleFk'], - include: [{ - relation: 'role', - scope: { - fields: ['name'] - } - }, - { - relation: 'emailUser', - scope: { - fields: ['email'] - } - }] - } - }, - { - relation: 'client', - scope: {fields: ['fi', 'phone']} - }, - { - relation: 'boss', - scope: {fields: ['id', 'name']} - }, - { - relation: 'sip', - scope: {fields: ['extension']} - }, - { - relation: 'department', - scope: { - include: { - relation: 'department', - scope: {fields: ['id', 'code', 'name']} - } - } - } - ] + where: { + id: value.id + } }; - this.$http.get(query, {params: {filter}}).then(res => { - this.$.worker = res.data; + this.$http.get(`Workers/summary`, {filter}).then(res => { + this.$.worker = res.data[0]; }); }