From 273068e59597eb0887de64237b60ad7a42096a6d Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 8 Oct 2024 12:18:15 +0200 Subject: [PATCH 1/5] fix: refs #7917 fix methods, tests, acls --- .../00-firstScript.sql | 6 +++++ modules/entry/back/methods/entry/filter.js | 4 +--- .../route/back/methods/agency-term/filter.js | 6 +++++ .../methods/agency-term/specs/filter.spec.js | 5 +++++ .../route/back/methods/route/getTickets.js | 12 +++++++--- .../methods/route/specs/getTickets.spec.js | 2 +- .../back/methods/route/specs/summary.spec.js | 10 ++++----- modules/route/back/methods/route/summary.js | 6 ++--- modules/supplier/back/models/supplier.js | 7 ++++++ modules/zone/back/models/agency.json | 22 +++++++++---------- 10 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 db/versions/11292-tealChrysanthemum/00-firstScript.sql diff --git a/db/versions/11292-tealChrysanthemum/00-firstScript.sql b/db/versions/11292-tealChrysanthemum/00-firstScript.sql new file mode 100644 index 000000000..2db448e06 --- /dev/null +++ b/db/versions/11292-tealChrysanthemum/00-firstScript.sql @@ -0,0 +1,6 @@ +INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) + VALUES + ('Route', 'getTickets', 'READ', 'ALLOW', 'ROLE', 'supplier'), + ('AgencyTerm', 'filter', 'READ', 'ALLOW', 'ROLE', 'supplier'), + ('Route', 'summary', 'READ', 'ALLOW', 'ROLE', 'supplier'); + diff --git a/modules/entry/back/methods/entry/filter.js b/modules/entry/back/methods/entry/filter.js index f4703245c..bf8ad0557 100644 --- a/modules/entry/back/methods/entry/filter.js +++ b/modules/entry/back/methods/entry/filter.js @@ -173,9 +173,7 @@ module.exports = Self => { } }); filter = mergeFilters(ctx.args.filter, {where}); - const userId = ctx.req.accessToken.userId; - const client = await Self.app.models.Client.findById(userId, myOptions); - const supplier = await Self.app.models.Supplier.findOne({where: {nif: client.fi}}, myOptions); + const supplier = await Self.app.models.Supplier.isSupplier(ctx); if (supplier) { if (!filter.where) filter.where = {}; filter.where[`e.supplierFk`] = supplier.id; diff --git a/modules/route/back/methods/agency-term/filter.js b/modules/route/back/methods/agency-term/filter.js index 9d1268958..2d48e4baa 100644 --- a/modules/route/back/methods/agency-term/filter.js +++ b/modules/route/back/methods/agency-term/filter.js @@ -74,6 +74,12 @@ module.exports = Self => { filter = mergeFilters(filter, {where}); + const supplier = await Self.app.models.Supplier.isSupplier(ctx, myOptions); + if (supplier) { + if (!filter.where) filter.where = {}; + filter.where[`a.supplierFk`] = supplier.id; + } + const date = Date.vnNew(); date.setHours(0, 0, 0, 0); const stmts = []; diff --git a/modules/route/back/methods/agency-term/specs/filter.spec.js b/modules/route/back/methods/agency-term/specs/filter.spec.js index 41e696157..10ec70d45 100644 --- a/modules/route/back/methods/agency-term/specs/filter.spec.js +++ b/modules/route/back/methods/agency-term/specs/filter.spec.js @@ -30,6 +30,7 @@ describe('AgencyTerm filter()', () => { it('should return results matching "search" searching by integer', async() => { let ctx = { args: { + ctx: {req: {accessToken: {userId: authUserId}}}, search: 1, } }; @@ -43,6 +44,7 @@ describe('AgencyTerm filter()', () => { it('should return results matching "search" searching by string', async() => { let ctx = { args: { + ctx: {req: {accessToken: {userId: authUserId}}}, search: 'Plants SL', } }; @@ -65,6 +67,7 @@ describe('AgencyTerm filter()', () => { const ctx = { args: { + ctx: {req: {accessToken: {userId: authUserId}}}, from: from, to: to } @@ -84,6 +87,7 @@ describe('AgencyTerm filter()', () => { it('should return results matching "agencyModeFk"', async() => { let ctx = { args: { + ctx: {req: {accessToken: {userId: authUserId}}}, agencyModeFk: 1, } }; @@ -97,6 +101,7 @@ describe('AgencyTerm filter()', () => { it('should return results matching "agencyFk"', async() => { let ctx = { args: { + ctx: {req: {accessToken: {userId: authUserId}}}, agencyFk: 2, } }; diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js index c0b952b70..d174fe013 100644 --- a/modules/route/back/methods/route/getTickets.js +++ b/modules/route/back/methods/route/getTickets.js @@ -2,7 +2,7 @@ const {ParameterizedSQL} = require('loopback-connector'); module.exports = Self => { - Self.remoteMethod('getTickets', { + Self.remoteMethodCtx('getTickets', { description: 'Find all instances of the model matched by filter from the data source.', accessType: 'READ', accepts: [ @@ -23,7 +23,7 @@ module.exports = Self => { } }); - Self.getTickets = async(filter, options) => { + Self.getTickets = async(ctx, filter, options) => { const conn = Self.dataSource.connector; const myOptions = {}; @@ -77,7 +77,9 @@ module.exports = Self => { LEFT JOIN ticketObservation tob2 ON tob2.ticketFk = t.id AND tob2.observationTypeFk = ot2.id LEFT JOIN address a ON a.id = t.addressFk - LEFT JOIN agencyMode am ON am.id = t.agencyModeFk + LEFT JOIN agencyMode am ON am.id = t.agencyModeFk + LEFT JOIN agency ag ON am.agencyFk = ag.id + LEFT JOIN supplierAgencyTerm sat ON sat.agencyFk = ag.id LEFT JOIN account.user u ON u.id = r.workerFk LEFT JOIN vehicle v ON v.id = r.vehicleFk LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk` @@ -85,6 +87,10 @@ module.exports = Self => { if (!filter.where) filter.where = {}; + const supplier = await Self.app.models.Supplier.isSupplier(ctx, myOptions); + if (supplier) + filter.where['sat.supplierFk'] = supplier.id; + const where = filter.where; where['r.id'] = filter.id; diff --git a/modules/route/back/methods/route/specs/getTickets.spec.js b/modules/route/back/methods/route/specs/getTickets.spec.js index 687547e45..1704f2ffc 100644 --- a/modules/route/back/methods/route/specs/getTickets.spec.js +++ b/modules/route/back/methods/route/specs/getTickets.spec.js @@ -3,7 +3,7 @@ const app = require('vn-loopback/server/server'); describe('route getTickets()', () => { it('should return the tickets for a given route', async() => { const filter = {id: 2}; - let result = await app.models.Route.getTickets(filter); + let result = await app.models.Route.getTickets(ctx, filter); expect(result.length).toEqual(1); }); diff --git a/modules/route/back/methods/route/specs/summary.spec.js b/modules/route/back/methods/route/specs/summary.spec.js index a9516f7c5..6eaeba3d4 100644 --- a/modules/route/back/methods/route/specs/summary.spec.js +++ b/modules/route/back/methods/route/specs/summary.spec.js @@ -2,34 +2,34 @@ const app = require('vn-loopback/server/server'); describe('route summary()', () => { it('should return a summary object containing data from one route', async() => { - const result = await app.models.Route.summary(1); + const result = await app.models.Route.summary(ctx, 1); expect(result.route.id).toEqual(1); }); it(`should return a summary object containing it's agency`, async() => { - const result = await app.models.Route.summary(1); + const result = await app.models.Route.summary(ctx, 1); const agency = result.route.agencyMode(); expect(agency.name).toEqual('inhouse pickup'); }); it(`should return a summary object containing it's vehicle`, async() => { - const result = await app.models.Route.summary(1); + const result = await app.models.Route.summary(ctx, 1); const vehicle = result.route.vehicle(); expect(vehicle.numberPlate).toEqual('3333-BAT'); }); it(`should return a summary object containing it's worker`, async() => { - const result = await app.models.Route.summary(1); + const result = await app.models.Route.summary(ctx, 1); const worker = result.route.worker().user(); expect(worker.name).toEqual('delivery'); }); it(`should return a summary object containing data from the tickets`, async() => { - const result = await app.models.Route.summary(2); + const result = await app.models.Route.summary(ctx, 2); expect(result.tickets.length).toEqual(1); }); diff --git a/modules/route/back/methods/route/summary.js b/modules/route/back/methods/route/summary.js index acd17759d..9beeb050d 100644 --- a/modules/route/back/methods/route/summary.js +++ b/modules/route/back/methods/route/summary.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethod('summary', { + Self.remoteMethodCtx('summary', { description: 'Returns the information of a route showed in the route summary', accessType: 'READ', accepts: [{ @@ -19,7 +19,7 @@ module.exports = Self => { } }); - Self.summary = async id => { + Self.summary = async(ctx, id) => { let summary = {}; let filter = { @@ -53,7 +53,7 @@ module.exports = Self => { }; summary.route = await Self.app.models.Route.findOne(filter); - summary.tickets = await Self.app.models.Route.getTickets({id: id, order: 'priority ASC'}); + summary.tickets = await Self.app.models.Route.getTickets(ctx, {id, order: 'priority ASC'}); return summary; }; diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index 2d3ffef3e..7773faa78 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -162,4 +162,11 @@ module.exports = Self => { if ((nameChanged) && !isAlpha(name)) throw new UserError('The social name has an invalid format'); }); + + Self.isSupplier = async(ctx, options = {}) => { + const userId = ctx.req.accessToken.userId; + const client = await Self.app.models.Client.findById(userId, options); + const supplier = await Self.app.models.Supplier.findOne({where: {nif: client.fi}}, options); + return supplier; + }; }; diff --git a/modules/zone/back/models/agency.json b/modules/zone/back/models/agency.json index 18b315d9a..20e42d227 100644 --- a/modules/zone/back/models/agency.json +++ b/modules/zone/back/models/agency.json @@ -35,19 +35,19 @@ }, "relations": { "supplierAgencyTerm": { - "type": "hasOne", - "model": "SupplierAgencyTerm", - "foreignKey": "agencyFk" + "type": "hasOne", + "model": "SupplierAgencyTerm", + "foreignKey": "agencyFk" }, "warehouse": { - "type": "belongsTo", - "model": "Warehouse", - "foreignKey": "warehouseFk" - }, + "type": "belongsTo", + "model": "Warehouse", + "foreignKey": "warehouseFk" + }, "workCenter": { - "type": "belongsTo", - "model": "WorkCenter", - "foreignKey": "workCenterFk" - } + "type": "belongsTo", + "model": "WorkCenter", + "foreignKey": "workCenterFk" + } } } -- 2.40.1 From 5e7dea94b1b6a45d14b4063eeda3e61297b67328 Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 18 Nov 2024 08:32:44 +0100 Subject: [PATCH 2/5] fix: refs #7917 tests --- .../methods/agency-term/specs/filter.spec.js | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/modules/route/back/methods/agency-term/specs/filter.spec.js b/modules/route/back/methods/agency-term/specs/filter.spec.js index 10ec70d45..b1f3eb1f4 100644 --- a/modules/route/back/methods/agency-term/specs/filter.spec.js +++ b/modules/route/back/methods/agency-term/specs/filter.spec.js @@ -3,8 +3,16 @@ const models = require('vn-loopback/server/server').models; describe('AgencyTerm filter()', () => { const authUserId = 9; + let ctx; const today = Date.vnNew(); today.setHours(2, 0, 0, 0); + beforeAll(async() => { + ctx = { + args: { + ctx: {req: {accessToken: {userId: authUserId}}}, + } + }; + }); it('should return all results matching the filter', async() => { const tx = await models.AgencyTerm.beginTransaction({}); @@ -12,7 +20,6 @@ describe('AgencyTerm filter()', () => { try { const options = {transaction: tx}; const filter = {}; - const ctx = {req: {accessToken: {userId: authUserId}}}; const agencyTerms = await models.AgencyTerm.filter(ctx, filter, options); const firstAgencyTerm = agencyTerms[0]; @@ -28,9 +35,8 @@ describe('AgencyTerm filter()', () => { }); it('should return results matching "search" searching by integer', async() => { - let ctx = { + ctx = { args: { - ctx: {req: {accessToken: {userId: authUserId}}}, search: 1, } }; @@ -42,9 +48,8 @@ describe('AgencyTerm filter()', () => { }); it('should return results matching "search" searching by string', async() => { - let ctx = { + ctx = { args: { - ctx: {req: {accessToken: {userId: authUserId}}}, search: 'Plants SL', } }; @@ -65,14 +70,6 @@ describe('AgencyTerm filter()', () => { const to = Date.vnNew(); to.setHours(23, 59, 59, 999); - const ctx = { - args: { - ctx: {req: {accessToken: {userId: authUserId}}}, - from: from, - to: to - } - }; - const results = await models.AgencyTerm.filter(ctx, options); expect(results.length).toBe(5); @@ -85,9 +82,8 @@ describe('AgencyTerm filter()', () => { }); it('should return results matching "agencyModeFk"', async() => { - let ctx = { + ctx = { args: { - ctx: {req: {accessToken: {userId: authUserId}}}, agencyModeFk: 1, } }; @@ -99,9 +95,8 @@ describe('AgencyTerm filter()', () => { }); it('should return results matching "agencyFk"', async() => { - let ctx = { + ctx = { args: { - ctx: {req: {accessToken: {userId: authUserId}}}, agencyFk: 2, } }; -- 2.40.1 From bbe62ece6e94b8610186c71fc94bbee022f0ecca Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 18 Nov 2024 08:46:48 +0100 Subject: [PATCH 3/5] fix: refs #7917 model --- modules/supplier/back/models/supplier.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index 0acb36341..86f124d88 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -164,8 +164,7 @@ module.exports = Self => { throw new UserError('The social name has an invalid format'); }); - Self.isSupplier = async(ctx, options = {}) => { - const userId = ctx.req.accessToken.userId; + Self.isSupplier = async(userId, options = {}) => { const client = await Self.app.models.Client.findById(userId, options); const supplier = await Self.app.models.Supplier.findOne({where: {nif: client.fi}}, options); return supplier; -- 2.40.1 From 0c4985604b170362b126f3083c15c8ed376ff66d Mon Sep 17 00:00:00 2001 From: carlossa Date: Mon, 18 Nov 2024 10:53:52 +0100 Subject: [PATCH 4/5] fix: refs #7917 test back --- .../methods/agency-term/specs/filter.spec.js | 66 ++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/modules/route/back/methods/agency-term/specs/filter.spec.js b/modules/route/back/methods/agency-term/specs/filter.spec.js index b1f3eb1f4..c47b14c95 100644 --- a/modules/route/back/methods/agency-term/specs/filter.spec.js +++ b/modules/route/back/methods/agency-term/specs/filter.spec.js @@ -2,17 +2,9 @@ const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models; describe('AgencyTerm filter()', () => { - const authUserId = 9; - let ctx; const today = Date.vnNew(); today.setHours(2, 0, 0, 0); - beforeAll(async() => { - ctx = { - args: { - ctx: {req: {accessToken: {userId: authUserId}}}, - } - }; - }); + let ctx = beforeAll.getCtx(); it('should return all results matching the filter', async() => { const tx = await models.AgencyTerm.beginTransaction({}); @@ -35,26 +27,33 @@ describe('AgencyTerm filter()', () => { }); it('should return results matching "search" searching by integer', async() => { - ctx = { - args: { - search: 1, - } + // ctx = { + // args: { + // search: 1, + // } + // }; + const filter = { + order: 'isActive ASC, name', + search: 1 }; - let result = await app.models.AgencyTerm.filter(ctx); + let result = await app.models.AgencyTerm.filter(ctx, filter); expect(result.length).toEqual(1); expect(result[0].routeFk).toEqual(1); }); it('should return results matching "search" searching by string', async() => { - ctx = { - args: { - search: 'Plants SL', - } + // ctx = { + // args: { + // search: 'Plants SL', + // } + // }; + const filter = { + search: 'Plants SL' }; - let result = await app.models.AgencyTerm.filter(ctx); + let result = await app.models.AgencyTerm.filter(ctx, filter); expect(result.length).toEqual(2); }); @@ -82,26 +81,31 @@ describe('AgencyTerm filter()', () => { }); it('should return results matching "agencyModeFk"', async() => { - ctx = { - args: { - agencyModeFk: 1, - } + // ctx = { + // args: { + // agencyModeFk: 1, + // } + // }; + const filter = { + agencyModeFk: 1, }; - - let result = await app.models.AgencyTerm.filter(ctx); + let result = await app.models.AgencyTerm.filter(ctx, filter); expect(result.length).toEqual(1); expect(result[0].routeFk).toEqual(1); }); it('should return results matching "agencyFk"', async() => { - ctx = { - args: { - agencyFk: 2, - } - }; + // ctx = { + // args: { + // agencyFk: 2, + // } + // }; - let result = await app.models.AgencyTerm.filter(ctx); + const filter = { + agencyFk: 2 + }; + let result = await app.models.AgencyTerm.filter(ctx, filter); expect(result.length).toEqual(1); expect(result[0].routeFk).toEqual(2); -- 2.40.1 From 839475a669b60e28e4992201de5f6a2f46591ace Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 19 Nov 2024 12:34:04 +0100 Subject: [PATCH 5/5] fix: refs #7917 fix tback --- .../methods/agency-term/specs/filter.spec.js | 8 ++++++ .../back/methods/route/specs/summary.spec.js | 26 +++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/modules/route/back/methods/agency-term/specs/filter.spec.js b/modules/route/back/methods/agency-term/specs/filter.spec.js index c47b14c95..b6729db2b 100644 --- a/modules/route/back/methods/agency-term/specs/filter.spec.js +++ b/modules/route/back/methods/agency-term/specs/filter.spec.js @@ -5,6 +5,14 @@ describe('AgencyTerm filter()', () => { const today = Date.vnNew(); today.setHours(2, 0, 0, 0); let ctx = beforeAll.getCtx(); + beforeAll(async() => { + ctx = { + req: { + accessToken: {}, + headers: {origin: 'http://localhost'}, + } + }; + }); it('should return all results matching the filter', async() => { const tx = await models.AgencyTerm.beginTransaction({}); diff --git a/modules/route/back/methods/route/specs/summary.spec.js b/modules/route/back/methods/route/specs/summary.spec.js index 6eaeba3d4..522a19bd4 100644 --- a/modules/route/back/methods/route/specs/summary.spec.js +++ b/modules/route/back/methods/route/specs/summary.spec.js @@ -1,35 +1,51 @@ const app = require('vn-loopback/server/server'); describe('route summary()', () => { + let ctx = beforeAll.getCtx(); + beforeAll(async() => { + ctx = { + req: { + accessToken: {}, + headers: {origin: 'http://localhost'}, + } + }; + }); + it('should return a summary object containing data from one route', async() => { - const result = await app.models.Route.summary(ctx, 1); + const filter = { + id: 1 + }; + const result = await app.models.Route.summary(ctx, filter); expect(result.route.id).toEqual(1); }); it(`should return a summary object containing it's agency`, async() => { - const result = await app.models.Route.summary(ctx, 1); + const filter = { + id: 1 + }; + const result = await app.models.Route.summary(ctx, filter); const agency = result.route.agencyMode(); expect(agency.name).toEqual('inhouse pickup'); }); it(`should return a summary object containing it's vehicle`, async() => { - const result = await app.models.Route.summary(ctx, 1); + const result = await app.models.Route.summary(ctx, filter); const vehicle = result.route.vehicle(); expect(vehicle.numberPlate).toEqual('3333-BAT'); }); it(`should return a summary object containing it's worker`, async() => { - const result = await app.models.Route.summary(ctx, 1); + const result = await app.models.Route.summary(ctx, filter); const worker = result.route.worker().user(); expect(worker.name).toEqual('delivery'); }); it(`should return a summary object containing data from the tickets`, async() => { - const result = await app.models.Route.summary(ctx, 2); + const result = await app.models.Route.summary(ctx, filter); expect(result.tickets.length).toEqual(1); }); -- 2.40.1