Merge pull request '#2934 - HOTFIX: Route suggested tickets' (#635) from 2934-suggested_tickets into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-on: #635
Reviewed-by: Carlos Jimenez Ruiz <carlosjr@verdnatura.es>
This commit is contained in:
Carlos Jimenez Ruiz 2021-06-02 09:28:12 +00:00
commit 611907f4dd
5 changed files with 93 additions and 48 deletions

View File

@ -19,14 +19,17 @@ module.exports = Self => {
} }
}); });
Self.getSuggestedTickets = async id => { Self.getSuggestedTickets = async(id, options) => {
const route = await Self.app.models.Route.findById(id); let myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const route = await Self.app.models.Route.findById(id, null, myOptions);
const zoneAgencyModes = await Self.app.models.ZoneAgencyMode.find({ const zoneAgencyModes = await Self.app.models.ZoneAgencyMode.find({
where: { where: {
agencyModeFk: route.agencyModeFk agencyModeFk: route.agencyModeFk
} }
}); }, myOptions);
const zoneIds = []; const zoneIds = [];
for (let zoneAgencyMode of zoneAgencyModes) for (let zoneAgencyMode of zoneAgencyModes)
@ -38,10 +41,9 @@ module.exports = Self => {
maxDate.setHours(23, 59, 59, 59); maxDate.setHours(23, 59, 59, 59);
let tickets = await Self.app.models.Ticket.find({ let tickets = await Self.app.models.Ticket.find({
where: { where: {
agencyModeFk: route.agencyModeFk,
zoneFk: {inq: zoneIds}, zoneFk: {inq: zoneIds},
routeFk: null, routeFk: null,
shipped: {between: [minDate, maxDate]} landed: {between: [minDate, maxDate]}
}, },
include: [ include: [
{ {
@ -57,7 +59,7 @@ module.exports = Self => {
} }
}, },
] ]
}); }, myOptions);
return tickets; return tickets;
}; };

View File

@ -26,26 +26,46 @@ module.exports = Self => {
} }
}); });
Self.insertTicket = async(routeId, ticketId) => { Self.insertTicket = async(routeId, ticketId, options) => {
const models = Self.app.models; const models = Self.app.models;
const route = await models.Route.findById(routeId); let tx;
const minDate = new Date(route.finished); let myOptions = {};
minDate.setHours(0, 0, 0, 0);
const maxDate = new Date(route.finished); if (typeof options == 'object')
maxDate.setHours(23, 59, 59, 59); Object.assign(myOptions, options);
const ticket = await models.Ticket.findOne({
where: {
id: ticketId,
routeFk: null,
landed: {between: [minDate, maxDate]},
}
});
if (!ticket) if (!myOptions.transaction) {
throw new UserError('The selected ticket is not suitable for this route'); tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
return ticket.updateAttribute('routeFk', route.id); try {
const route = await models.Route.findById(routeId, null, myOptions);
const minDate = new Date(route.created);
minDate.setHours(0, 0, 0, 0);
const maxDate = new Date(route.created);
maxDate.setHours(23, 59, 59, 59);
const ticket = await models.Ticket.findOne({
where: {
id: ticketId,
routeFk: null,
landed: {between: [minDate, maxDate]},
}
}, myOptions);
if (!ticket)
throw new UserError('The selected ticket is not suitable for this route');
const result = await ticket.updateAttribute('routeFk', route.id, myOptions);
if (tx) await tx.commit();
return result;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
}; };
}; };

View File

@ -2,6 +2,8 @@ const app = require('vn-loopback/server/server');
const LoopBackContext = require('loopback-context'); const LoopBackContext = require('loopback-context');
describe('route getSuggestedTickets()', () => { describe('route getSuggestedTickets()', () => {
const routeID = 1;
const ticketId = 12;
it('should return an array of suggested tickets', async() => { it('should return an array of suggested tickets', async() => {
const activeCtx = { const activeCtx = {
accessToken: {userId: 19}, accessToken: {userId: 19},
@ -11,20 +13,30 @@ describe('route getSuggestedTickets()', () => {
active: activeCtx active: activeCtx
}); });
const routeID = 1; const tx = await app.models.Ticket.beginTransaction({});
const ticketInRoute = await app.models.Ticket.findById(12);
await ticketInRoute.updateAttribute('routeFk', null); try {
const options = {transaction: tx};
const ticketInRoute = await app.models.Ticket.findById(ticketId, null, options);
const result = await app.models.Route.getSuggestedTickets(routeID); await ticketInRoute.updateAttributes({
routeFk: null,
landed: new Date()
}, options);
const length = result.length; const result = await app.models.Route.getSuggestedTickets(routeID, options);
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(result.length).toEqual(1); const length = result.length;
expect(anyResult.zoneFk).toEqual(1); const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(anyResult.agencyModeFk).toEqual(1);
await ticketInRoute.updateAttribute('routeFk', routeID); expect(result.length).toEqual(1);
expect(anyResult.zoneFk).toEqual(1);
expect(anyResult.agencyModeFk).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -3,7 +3,6 @@ const LoopBackContext = require('loopback-context');
describe('route insertTicket()', () => { describe('route insertTicket()', () => {
const deliveryId = 56; const deliveryId = 56;
let originalTicket;
const routeId = 1; const routeId = 1;
const activeCtx = { const activeCtx = {
accessToken: {userId: deliveryId}, accessToken: {userId: deliveryId},
@ -19,12 +18,24 @@ describe('route insertTicket()', () => {
it('should add the ticket to a route', async() => { it('should add the ticket to a route', async() => {
const ticketId = 12; const ticketId = 12;
originalTicket = await app.models.Ticket.findById(ticketId); const tx = await app.models.Ticket.beginTransaction({});
await originalTicket.updateAttribute('routeFk', null);
const result = await app.models.Route.insertTicket(routeId, ticketId); try {
const options = {transaction: tx};
const ticketInRoute = await app.models.Ticket.findById(ticketId, null, options);
await ticketInRoute.updateAttributes({
routeFk: null,
landed: new Date()
}, options);
expect(result.routeFk).toEqual(routeId); const result = await app.models.Route.insertTicket(routeId, ticketId, options);
expect(result.routeFk).toEqual(routeId);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should throw and error if the ticket is not suitable for the route', async() => { it('should throw and error if the ticket is not suitable for the route', async() => {

View File

@ -63,14 +63,14 @@
display-controls=true> display-controls=true>
</vn-input-number> </vn-input-number>
</vn-td> </vn-td>
<vn-td expand title="{{ticket.street}}">{{::ticket.street}}</vn-td> <vn-td expand title="{{::ticket.street}}">{{::ticket.street}}</vn-td>
<vn-td expand>{{::ticket.city}}</vn-td> <vn-td expand>{{::ticket.city}}</vn-td>
<vn-td shrink>{{::ticket.postalCode}}</vn-td> <vn-td shrink>{{::ticket.postalCode}}</vn-td>
<vn-td expand> <vn-td expand>
<span <span
ng-click="clientDescriptor.show($event, ticket.clientFk)" ng-click="clientDescriptor.show($event, ticket.clientFk)"
class="link"> class="link">
{{ticket.nickname}} {{::ticket.nickname}}
</span> </span>
</vn-td> </vn-td>
<vn-td shrink>{{::ticket.packages}}</vn-td> <vn-td shrink>{{::ticket.packages}}</vn-td>
@ -84,8 +84,8 @@
</vn-td> </vn-td>
<vn-td shrink> <vn-td shrink>
<vn-icon <vn-icon
ng-if="ticket.notes.length" ng-if="::ticket.notes.length"
title="{{ticket.notes[0].description}}" title="{{::ticket.notes[0].description}}"
icon="insert_drive_file" icon="insert_drive_file"
class="bright"> class="bright">
</vn-icon> </vn-icon>
@ -149,18 +149,18 @@
ng-model="ticket.checked"> ng-model="ticket.checked">
</vn-check> </vn-check>
</vn-td> </vn-td>
<vn-td number>{{ticket.id}}</vn-td> <vn-td number>{{::ticket.id}}</vn-td>
<vn-td number> <vn-td number>
<span <span
ng-click="$ctrl.showClientDescriptor($event, ticket.clientFk)" ng-click="::$ctrl.showClientDescriptor($event, ticket.clientFk)"
class="link"> class="link">
{{ticket.nickname}} {{::ticket.nickname}}
</span> </span>
</vn-td> </vn-td>
<vn-td number shrink>{{ticket.packages}}</vn-td> <vn-td number shrink>{{::ticket.packages}}</vn-td>
<vn-td expand>{{ticket.warehouse.name}}</vn-td> <vn-td expand>{{::ticket.warehouse.name}}</vn-td>
<vn-td number shrink>{{ticket.address.postalCode}}</vn-td> <vn-td number shrink>{{::ticket.address.postalCode}}</vn-td>
<vn-td expand title="{{ticket.address.street}}">{{ticket.address.street}}</vn-td> <vn-td expand title="{{::ticket.address.street}}">{{::ticket.address.street}}</vn-td>
</vn-tr> </vn-tr>
</vn-tbody> </vn-tbody>
</vn-table> </vn-table>