refs #6254 feat(collection): add getTickets
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Alex Moreno 2023-09-27 15:08:36 +02:00
parent cf36b10763
commit 1307d4727c
6 changed files with 201 additions and 4 deletions

View File

@ -0,0 +1,179 @@
module.exports = Self => {
Self.remoteMethodCtx('getTickets', {
description: 'Make a new collection of tickets',
accessType: 'WRITE',
accepts: [{
arg: 'paramId',
type: 'number',
description: 'The collection or ticket id',
required: true
}, {
arg: 'print',
type: 'boolean',
description: 'True if you want to print'
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/getTickets`,
verb: 'POST'
}
});
Self.getTickets = async(ctx, paramId, print, options) => {
const userId = ctx.req.accessToken.userId;
const origin = ctx.req.headers.origin;
const $t = ctx.req.__; // $translate
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
myOptions.userId = userId;
const promises = [];
try {
const [tickets] = await Self.rawSql(`CALL vn.collection_getTickets(?)`, [paramId], myOptions);
const sales = await Self.rawSql(`
SELECT
s.ticketFk,
sgd.saleGroupFk,
s.id saleFk,
s.itemFk,
i.longName,
i.size,
IFNULL(sub2.semaphore,st.semaphore) semaphore,
ic.color,
ip.productor,
o.code origin,
s.concept,
b.packing,
b.grouping,
s.isAdded,
c.workerFk,
i.packingShelve,
sm.id hasMistake,
s.originalQuantity,
s.quantity saleQuantity,
IF(p2.code IS NOT NULL, s.quantity, iss.quantity) reservedQuantity,
sh.code,
IFNULL(p2.code, p.code) parkingCode,
IFNULL(p2.pickingOrder, p.pickingOrder) pickingOrder,
iss.id itemShelvingSaleFk
FROM ticketCollection tc
LEFT JOIN collection c ON c.id = tc.collectionFk
JOIN ticket t ON t.id = tc.ticketFk
JOIN sale s ON s.ticketFk = t.id
LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id
LEFT JOIN saleGroup sg ON sg.id = sgd.saleGroupFk
LEFT JOIN parking p2 ON p2.id = sg.parkingFk
LEFT JOIN cache.last_buy lb ON lb.item_id = s.itemFk AND lb.warehouse_id = t.warehouseFk
LEFT JOIN buy b ON b.id = lb.buy_id
JOIN item i ON i.id = s.itemFk
LEFT JOIN itemShelvingSale iss ON iss.saleFk = s.id
LEFT JOIN itemShelving ish ON ish.id = iss.itemShelvingFk
LEFT JOIN shelving sh ON sh.code = ish.shelvingFk
LEFT JOIN parking p ON p.id = sh.parkingFk
LEFT JOIN (
SELECT sub.saleFk, sub.isChecked, sub.stateFk, sub.originalQuantity, sub.semaphore
FROM (
SELECT DISTINCT st.id,
st.saleFk, st.isChecked, st.stateFk, st.originalQuantity ,sta.semaphore
FROM ticketCollection tc
JOIN sale s ON s.ticketFk = tc.ticketFk
JOIN saleTracking st ON st.saleFk = s.id
JOIN state sta ON sta.id = st.stateFk
WHERE tc.collectionFk = ?
ORDER BY st.id DESC
LIMIT 10000000000000000000) sub
GROUP BY sub.saleFk, sub.stateFK
) sub2 ON sub2.saleFk = s.id AND sub2.isChecked = 1
LEFT JOIN state st ON st.id = sub2.stateFk
LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk
LEFT JOIN itemProductor ip ON ip.itemFk = s.itemFk
LEFT JOIN origin o ON o.id = i.originFk
LEFT JOIN saleMistake sm ON sm.saleFk = s.id
WHERE tc.collectionFk = ?
GROUP BY s.id, p.code, p2.code
ORDER BY pickingOrder`, [paramId, paramId], myOptions);
if (print)
await Self.rawSql(`CALL vn.collection_printSticker(?, ?)`, [paramId, null], myOptions);
const collection = {collectionFk: paramId, tickets: []};
if (tickets && tickets.length) {
for (let ticket of tickets) {
const ticketId = ticket.ticketFk;
// SEND ROCKET
if (ticket.observaciones != '') {
for (observation of ticket.observaciones.split(' ')) {
if (['#', '@'].includes(observation.charAt(0))) {
promises.push(Self.app.models.Chat.send(ctx, observation,
$t('The ticket is in preparation', {
ticketId: ticketId,
ticketUrl: `${origin}/#!/ticket/${ticketId}/summary`,
salesPersonId: ticket.salesPersonFk
})));
}
}
}
// SET COLLECTION
if (sales && sales.length) {
// GET BARCODES
const barcodes = await Self.rawSql(`
SELECT s.id saleFk, b.code, c.id
FROM vn.sale s
LEFT JOIN vn.itemBarcode b ON b.itemFk = s.itemFk
LEFT JOIN vn.buy c ON c.itemFk = s.itemFk
LEFT JOIN vn.entry e ON e.id = c.entryFk
LEFT JOIN vn.travel tr ON tr.id = e.travelFk
WHERE s.ticketFk = ? AND tr.landed >= DATE_SUB(util.VN_CURDATE(), INTERVAL 1 YEAR)`,
[ticketId], myOptions);
// BINDINGS
ticket.sales = sales.reduce((acc, sale) => {
if (sale.ticketFk == ticketId) {
sale.Barcodes = [];
if (barcodes && barcodes.length) {
sale.Barcodes = barcodes.reduce((bacc, barcode) => {
if (barcode.saleFk == sale.saleFk) {
for (let prop in barcode) {
if (['id', 'code'].includes(prop) && barcode[prop]) {
bacc.push(barcode[prop].toString());
bacc.push('0' + barcode[prop]);
}
}
}
return bacc;
}, []);
}
acc.push(sale);
}
return acc;
}, []);
}
collection.tickets.push(ticket);
}
}
if (tx) await tx.commit();
await Promise.all(promises);
return collection;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -0,0 +1,11 @@
const models = require('vn-loopback/server/server').models;
describe('collection getTickets()', () => {
it('should return a list of tickets from a collection', async() => {
let ctx = {req: {accessToken: {userId: 1107}}};
let response = await models.Collection.getCollection(ctx);
expect(response.length).toBeGreaterThan(0);
expect(response[0].collectionFk).toEqual(3);
});
});

View File

@ -4,4 +4,5 @@ module.exports = Self => {
require('../methods/collection/getSectors')(Self);
require('../methods/collection/setSaleQuantity')(Self);
require('../methods/collection/previousLabel')(Self);
require('../methods/collection/getTickets')(Self);
};

View File

@ -0,0 +1,3 @@
INSERT INTO `salix`.`ACL`(model, property, accessType, permission, principalType, principalId)
VALUES
('Collection', 'getTickets', 'WRITE', 'ALLOW', 'ROLE', 'employee');

View File

@ -187,5 +187,6 @@
"This ticket is not editable.": "This ticket is not editable.",
"The ticket doesn't exist.": "The ticket doesn't exist.",
"The sales do not exists": "The sales do not exists",
"Ticket without Route": "Ticket without route"
"Ticket without Route": "Ticket without route",
"The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation"
}

View File

@ -314,8 +314,10 @@
"This ticket is locked.": "Este ticket está bloqueado.",
"This ticket is not editable.": "Este ticket no es editable.",
"The ticket doesn't exist.": "No existe el ticket.",
"Social name should be uppercase": "La razón social debe ir en mayúscula",
"Social name should be uppercase": "La razón social debe ir en mayúscula",
"Street should be uppercase": "La dirección fiscal debe ir en mayúscula",
"The response is not a PDF": "La respuesta no es un PDF",
"Ticket without Route": "Ticket sin ruta"
}
"Ticket without Route": "Ticket sin ruta",
"The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} està en preparación",
"Invalid collection or ticket": "Invalid collection or ticket"
}