Merge pull request '6028_route_getRouteByWorker' (!1857) from 6028_route_getRouteByWorker into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #1857 Reviewed-by: Alex Moreno <alexm@verdnatura.es>
This commit is contained in:
commit
4a62588464
|
@ -1,133 +0,0 @@
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethodCtx('newCollection', {
|
|
||||||
description: 'Make a new collection of tickets',
|
|
||||||
accessType: 'WRITE',
|
|
||||||
accepts: [{
|
|
||||||
arg: 'collectionFk',
|
|
||||||
type: 'Number',
|
|
||||||
required: false,
|
|
||||||
description: 'The collection id'
|
|
||||||
}, {
|
|
||||||
arg: 'sectorFk',
|
|
||||||
type: 'Number',
|
|
||||||
required: true,
|
|
||||||
description: 'The sector of worker'
|
|
||||||
}, {
|
|
||||||
arg: 'vWagons',
|
|
||||||
type: 'Number',
|
|
||||||
required: true,
|
|
||||||
description: 'The number of wagons'
|
|
||||||
}],
|
|
||||||
returns: {
|
|
||||||
type: 'Object',
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/newCollection`,
|
|
||||||
verb: 'POST'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.newCollection = async(ctx, collectionFk, sectorFk, vWagons) => {
|
|
||||||
let query = '';
|
|
||||||
const userId = ctx.req.accessToken.userId;
|
|
||||||
|
|
||||||
if (!collectionFk) {
|
|
||||||
query = `CALL vn.collectionTrain_newBeta(?,?,?)`;
|
|
||||||
const [result] = await Self.rawSql(query, [sectorFk, vWagons, userId], {userId});
|
|
||||||
if (result.length == 0)
|
|
||||||
throw new Error(`No collections for today`);
|
|
||||||
|
|
||||||
collectionFk = result[0].vCollectionFk;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = `CALL vn.collectionTicket_get(?)`;
|
|
||||||
const [tickets] = await Self.rawSql(query, [collectionFk], {userId});
|
|
||||||
|
|
||||||
query = `CALL vn.collectionSale_get(?)`;
|
|
||||||
const [sales] = await Self.rawSql(query, [collectionFk], {userId});
|
|
||||||
|
|
||||||
query = `CALL vn.collectionPlacement_get(?)`;
|
|
||||||
const [placements] = await Self.rawSql(query, [collectionFk], {userId});
|
|
||||||
|
|
||||||
query = `CALL vn.collectionSticker_print(?,?)`;
|
|
||||||
await Self.rawSql(query, [collectionFk, sectorFk], {userId});
|
|
||||||
|
|
||||||
return makeCollection(tickets, sales, placements, collectionFk);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a collection json
|
|
||||||
* @param {*} tickets - Request tickets
|
|
||||||
* @param {*} sales - Request sales
|
|
||||||
* @param {*} placements - Request placements
|
|
||||||
* @param {*} collectionFk - Request placements
|
|
||||||
* @return {Object} Collection JSON
|
|
||||||
*/
|
|
||||||
async function makeCollection(tickets, sales, placements, collectionFk) {
|
|
||||||
let collection = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < tickets.length; i++) {
|
|
||||||
let ticket = {};
|
|
||||||
ticket['ticketFk'] = tickets[i]['ticketFk'];
|
|
||||||
ticket['level'] = tickets[i]['level'];
|
|
||||||
ticket['agencyName'] = tickets[i]['agencyName'];
|
|
||||||
ticket['warehouseFk'] = tickets[i]['warehouseFk'];
|
|
||||||
ticket['salesPersonFk'] = tickets[i]['salesPersonFk'];
|
|
||||||
|
|
||||||
let ticketSales = [];
|
|
||||||
|
|
||||||
for (let x = 0; x < sales.length; x++) {
|
|
||||||
if (sales[x]['ticketFk'] == ticket['ticketFk']) {
|
|
||||||
let sale = {};
|
|
||||||
sale['collectionFk'] = collectionFk;
|
|
||||||
sale['ticketFk'] = sales[x]['ticketFk'];
|
|
||||||
sale['saleFk'] = sales[x]['saleFk'];
|
|
||||||
sale['itemFk'] = sales[x]['itemFk'];
|
|
||||||
sale['quantity'] = sales[x]['quantity'];
|
|
||||||
if (sales[x]['quantityPicked'] != null)
|
|
||||||
sale['quantityPicked'] = sales[x]['quantityPicked'];
|
|
||||||
else
|
|
||||||
sale['quantityPicked'] = 0;
|
|
||||||
sale['longName'] = sales[x]['longName'];
|
|
||||||
sale['size'] = sales[x]['size'];
|
|
||||||
sale['color'] = sales[x]['color'];
|
|
||||||
sale['discount'] = sales[x]['discount'];
|
|
||||||
sale['price'] = sales[x]['price'];
|
|
||||||
sale['stems'] = sales[x]['stems'];
|
|
||||||
sale['category'] = sales[x]['category'];
|
|
||||||
sale['origin'] = sales[x]['origin'];
|
|
||||||
sale['clientFk'] = sales[x]['clientFk'];
|
|
||||||
sale['productor'] = sales[x]['productor'];
|
|
||||||
sale['reserved'] = sales[x]['reserved'];
|
|
||||||
sale['isPreviousPrepared'] = sales[x]['isPreviousPrepared'];
|
|
||||||
sale['isPrepared'] = sales[x]['isPrepared'];
|
|
||||||
sale['isControlled'] = sales[x]['isControlled'];
|
|
||||||
|
|
||||||
let salePlacements = [];
|
|
||||||
|
|
||||||
for (let z = 0; z < placements.length; z++) {
|
|
||||||
if (placements[z]['saleFk'] == sale['saleFk']) {
|
|
||||||
let placement = {};
|
|
||||||
placement['saleFk'] = placements[z]['saleFk'];
|
|
||||||
placement['itemFk'] = placements[z]['itemFk'];
|
|
||||||
placement['placement'] = placements[z]['placement'];
|
|
||||||
placement['shelving'] = placements[z]['shelving'];
|
|
||||||
placement['created'] = placements[z]['created'];
|
|
||||||
placement['visible'] = placements[z]['visible'];
|
|
||||||
placement['order'] = placements[z]['order'];
|
|
||||||
placement['grouping'] = placements[z]['grouping'];
|
|
||||||
salePlacements.push(placement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sale['placements'] = salePlacements;
|
|
||||||
ticketSales.push(sale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ticket['sales'] = ticketSales;
|
|
||||||
collection.push(ticket);
|
|
||||||
}
|
|
||||||
|
|
||||||
return collection;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,12 +0,0 @@
|
||||||
const {models} = require('vn-loopback/server/server');
|
|
||||||
|
|
||||||
describe('newCollection()', () => {
|
|
||||||
it('should return a new collection', async() => {
|
|
||||||
pending('#3400 analizar que hacer con rutas de back collection');
|
|
||||||
let ctx = {req: {accessToken: {userId: 1106}}};
|
|
||||||
let response = await models.Collection.newCollection(ctx, 1, 1, 1);
|
|
||||||
|
|
||||||
expect(response.length).toBeGreaterThan(0);
|
|
||||||
expect(response[0].ticketFk).toEqual(2);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,6 +1,5 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/collection/getCollection')(Self);
|
require('../methods/collection/getCollection')(Self);
|
||||||
require('../methods/collection/newCollection')(Self);
|
|
||||||
require('../methods/collection/getSectors')(Self);
|
require('../methods/collection/getSectors')(Self);
|
||||||
require('../methods/collection/setSaleQuantity')(Self);
|
require('../methods/collection/setSaleQuantity')(Self);
|
||||||
require('../methods/collection/previousLabel')(Self);
|
require('../methods/collection/previousLabel')(Self);
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
DELETE FROM `salix`.`ACL`
|
||||||
|
WHERE
|
||||||
|
model = 'Route'
|
||||||
|
AND property = '*'
|
||||||
|
AND accessType = 'READ';
|
||||||
|
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||||
|
VALUES
|
||||||
|
('Route', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'getRoutesByWorker', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'canViewAllRoute', 'READ', 'ALLOW', 'ROLE', 'deliveryBoss'),
|
||||||
|
('Route', 'cmr', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'downloadCmrsZip', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'downloadZip', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'getByWorker', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'getDeliveryPoint', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'getExternalCmrs', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'getSuggestedTickets', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'getTickets', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'guessPriority', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'insertTicket', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Route', 'getDeliveryPoint', 'READ', 'ALLOW', 'ROLE', 'deliveryBoss'),
|
||||||
|
('Route', 'summary', 'READ', 'ALLOW', 'ROLE', 'employee');
|
|
@ -105,7 +105,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
filter = mergeFilters(ctx.args.filter, {where});
|
filter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
let stmts = [];
|
let stmts = [];
|
||||||
let stmt;
|
let stmt;
|
||||||
|
@ -129,9 +129,11 @@ module.exports = Self => {
|
||||||
r.description,
|
r.description,
|
||||||
am.name agencyName,
|
am.name agencyName,
|
||||||
u.name AS workerUserName,
|
u.name AS workerUserName,
|
||||||
v.numberPlate AS vehiclePlateNumber
|
v.numberPlate AS vehiclePlateNumber,
|
||||||
|
Date_format(r.time, '%H:%i') hour
|
||||||
FROM route r
|
FROM route r
|
||||||
LEFT JOIN agencyMode am ON am.id = r.agencyModeFk
|
LEFT JOIN agencyMode am ON am.id = r.agencyModeFk
|
||||||
|
LEFT JOIN agency a ON a.id = am.agencyFk
|
||||||
LEFT JOIN vehicle v ON v.id = r.vehicleFk
|
LEFT JOIN vehicle v ON v.id = r.vehicleFk
|
||||||
LEFT JOIN worker w ON w.id = r.workerFk
|
LEFT JOIN worker w ON w.id = r.workerFk
|
||||||
LEFT JOIN account.user u ON u.id = w.id`
|
LEFT JOIN account.user u ON u.id = w.id`
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('getByWorker', {
|
||||||
|
description: 'Return the routes by worker',
|
||||||
|
accessType: 'READ',
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/getByWorker`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getByWorker = async ctx => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const userId = ctx.req.accessToken.userId;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const canViewAll = await models.ACL.checkAccessAcl(ctx, 'Route', 'canViewAllRoute', 'READ');
|
||||||
|
let filterGrant = {};
|
||||||
|
|
||||||
|
if (canViewAll) {
|
||||||
|
const userConfig = await models.UserConfig.getUserConfig(ctx, myOptions);
|
||||||
|
filterGrant = {
|
||||||
|
where: {'a.warehouseFk': userConfig.warehouseFk}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
filterGrant = {
|
||||||
|
where: {'r.workerFk': userId}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentDate = Date.vnNew();
|
||||||
|
currentDate.setHours(0, 0, 0, 0);
|
||||||
|
const nextDay = Date.vnNew();
|
||||||
|
nextDay.setDate(currentDate.getDate() + 1);
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
where: {
|
||||||
|
and: [
|
||||||
|
{
|
||||||
|
or: [
|
||||||
|
{'r.created': currentDate},
|
||||||
|
{'r.created': nextDay}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
order: [
|
||||||
|
'r.created ASC',
|
||||||
|
'r.time ASC',
|
||||||
|
'am.name ASC'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await Self.filter(ctx, mergeFilters(filter, filterGrant));
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('getDeliveryPoint', {
|
Self.remoteMethod('getDeliveryPoint', {
|
||||||
description: 'get the deliveryPoint address',
|
description: 'get the deliveryPoint address',
|
||||||
accessType: 'WRITE',
|
accessType: 'READ',
|
||||||
accepts: {
|
accepts: {
|
||||||
arg: 'vehicleId',
|
arg: 'vehicleId',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('guessPriority', {
|
Self.remoteMethodCtx('guessPriority', {
|
||||||
description: 'Changes automatically the priority of the tickets in a route',
|
description: 'Changes automatically the priority of the tickets in a route',
|
||||||
accessType: 'READ',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'id',
|
arg: 'id',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
@ -15,7 +15,7 @@ module.exports = Self => {
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
path: `/:id/guessPriority`,
|
path: `/:id/guessPriority`,
|
||||||
verb: 'GET'
|
verb: 'PATCH'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ const UserError = require('vn-loopback/util/user-error');
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('insertTicket', {
|
Self.remoteMethod('insertTicket', {
|
||||||
description: 'Check if the ticket can be insert into the route and insert it',
|
description: 'Check if the ticket can be insert into the route and insert it',
|
||||||
accessType: 'READ',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'routeId',
|
arg: 'routeId',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
|
describe('route getByWorker()', () => {
|
||||||
|
const userId = 56;
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: userId},
|
||||||
|
http: {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const ctx = {req: activeCtx};
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return routes assigned to the worker', async() => {
|
||||||
|
const result = await app.models.Route.getByWorker(ctx);
|
||||||
|
|
||||||
|
expect(result.every(route => route.workerFk === userId)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return all routes if user has canViewAllRoute permission', async() => {
|
||||||
|
// Simular que el usuario tiene permiso para ver todas las rutas
|
||||||
|
spyOn(app.models.ACL, 'checkAccessAcl').and.returnValue(Promise.resolve(true));
|
||||||
|
|
||||||
|
const result = await app.models.Route.getByWorker(ctx);
|
||||||
|
|
||||||
|
expect(result.some(route => route.workerFk != userId)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
|
@ -17,6 +17,7 @@ module.exports = Self => {
|
||||||
require('../methods/route/cmr')(Self);
|
require('../methods/route/cmr')(Self);
|
||||||
require('../methods/route/getExternalCmrs')(Self);
|
require('../methods/route/getExternalCmrs')(Self);
|
||||||
require('../methods/route/downloadCmrsZip')(Self);
|
require('../methods/route/downloadCmrsZip')(Self);
|
||||||
|
require('../methods/route/getByWorker')(Self);
|
||||||
|
|
||||||
Self.validate('kmStart', validateDistance, {
|
Self.validate('kmStart', validateDistance, {
|
||||||
message: 'Distance must be lesser than 1000'
|
message: 'Distance must be lesser than 1000'
|
||||||
|
@ -31,5 +32,5 @@ module.exports = Self => {
|
||||||
const routeMaxKm = 1000;
|
const routeMaxKm = 1000;
|
||||||
if (routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd)
|
if (routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd)
|
||||||
err();
|
err();
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -120,7 +120,7 @@ class Controller extends Section {
|
||||||
|
|
||||||
guessPriority() {
|
guessPriority() {
|
||||||
let query = `Routes/${this.$params.id}/guessPriority/`;
|
let query = `Routes/${this.$params.id}/guessPriority/`;
|
||||||
this.$http.get(query).then(() => {
|
this.$http.patch(query).then(() => {
|
||||||
this.vnApp.showSuccess(this.$t('Order changed'));
|
this.vnApp.showSuccess(this.$t('Order changed'));
|
||||||
this.$.model.refresh();
|
this.$.model.refresh();
|
||||||
});
|
});
|
||||||
|
|
|
@ -209,22 +209,6 @@ describe('Route', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('guessPriority()', () => {
|
|
||||||
it('should perform a GET query then call both refresh and showSuccess methods', () => {
|
|
||||||
jest.spyOn(controller.$.model, 'refresh');
|
|
||||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
controller.$params = {id: 99};
|
|
||||||
|
|
||||||
const url = `Routes/${controller.$params.id}/guessPriority/`;
|
|
||||||
$httpBackend.expectGET(url).respond('ok');
|
|
||||||
controller.guessPriority();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Order changed');
|
|
||||||
expect(controller.$.model.refresh).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onDrop()', () => {
|
describe('onDrop()', () => {
|
||||||
it('should call the insert method when dragging a ticket number', () => {
|
it('should call the insert method when dragging a ticket number', () => {
|
||||||
jest.spyOn(controller, 'insert');
|
jest.spyOn(controller, 'insert');
|
||||||
|
|
Loading…
Reference in New Issue