refs #6669 fix:ticket_isOutClosureZone #1984
|
@ -1,20 +0,0 @@
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethod('getSectors', {
|
|
||||||
description: 'Get all sectors',
|
|
||||||
accessType: 'READ',
|
|
||||||
returns: {
|
|
||||||
type: 'Object',
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/getSectors`,
|
|
||||||
verb: 'GET'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.getSectors = async() => {
|
|
||||||
const query = `CALL vn.sector_get()`;
|
|
||||||
const [result] = await Self.rawSql(query);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,11 +0,0 @@
|
||||||
const {models} = require('vn-loopback/server/server');
|
|
||||||
|
|
||||||
describe('getSectors()', () => {
|
|
||||||
it('return list of sectors', async() => {
|
|
||||||
let response = await models.Collection.getSectors();
|
|
||||||
|
|
||||||
expect(response.length).toBeGreaterThan(0);
|
|
||||||
expect(response[0].id).toEqual(1);
|
|
||||||
expect(response[0].description).toEqual('First sector');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,6 +1,5 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/collection/getCollection')(Self);
|
require('../methods/collection/getCollection')(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);
|
||||||
require('../methods/collection/getTickets')(Self);
|
require('../methods/collection/getTickets')(Self);
|
||||||
|
|
|
@ -17,7 +17,6 @@ BEGIN
|
||||||
|
|
||||||
CALL productionControl(vWarehouseFk, 0);
|
CALL productionControl(vWarehouseFk, 0);
|
||||||
|
|
||||||
-- Products with vn.item.isBoxPickingMode = TRUE, pay atention to vn.itemShelving.packing
|
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tmp.sale
|
CREATE OR REPLACE TEMPORARY TABLE tmp.sale
|
||||||
(saleFk INT PRIMARY KEY)
|
(saleFk INT PRIMARY KEY)
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -52,8 +51,8 @@ BEGIN
|
||||||
LEFT JOIN ticketState ts ON ts.ticketFk = s.ticketFk
|
LEFT JOIN ticketState ts ON ts.ticketFk = s.ticketFk
|
||||||
LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = vWarehouseFk
|
LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = vWarehouseFk
|
||||||
LEFT JOIN buy b ON b.id = lb.buy_id
|
LEFT JOIN buy b ON b.id = lb.buy_id
|
||||||
WHERE s.quantity BETWEEN ish.packing AND (ish.visible - IFNULL(tISS.reserve,0))
|
WHERE IF(i.isBoxPickingMode, ish.packing, i.packingOut)
|
||||||
AND i.isBoxPickingMode
|
<= LEAST(s.quantity, ish.visible - IFNULL(tISS.reserve,0))
|
||||||
AND NOT pb.problem
|
AND NOT pb.problem
|
||||||
AND sgd.saleFk IS NULL
|
AND sgd.saleFk IS NULL
|
||||||
AND p.sectorFk = vSectorFk
|
AND p.sectorFk = vSectorFk
|
||||||
|
@ -64,47 +63,13 @@ BEGIN
|
||||||
GROUP BY s.id
|
GROUP BY s.id
|
||||||
ORDER BY etd;
|
ORDER BY etd;
|
||||||
|
|
||||||
-- Remaining products, vn.item.packingOut
|
SELECT *
|
||||||
INSERT IGNORE INTO tmp.sale
|
FROM tmp.sale
|
||||||
SELECT
|
WHERE stickers;
|
||||||
s.ticketFk,
|
|
||||||
s.id saleFk,
|
|
||||||
s.itemFk,
|
|
||||||
s.concept,
|
|
||||||
s.quantity,
|
|
||||||
MAKETIME(pb.HH,pb.mm,0) etd,
|
|
||||||
pb.routeFk,
|
|
||||||
s.quantity / i.packingOut stickers,
|
|
||||||
i.packingOut,
|
|
||||||
pc.defaultBigPackageFk
|
|
||||||
FROM sale s
|
|
||||||
JOIN item i ON i.id = s.itemFk
|
|
||||||
JOIN itemShelving ish ON ish.itemFk = s.itemFk
|
|
||||||
JOIN shelving sh ON sh.code = ish.shelvingFk
|
|
||||||
JOIN parking p ON p.id = sh.parkingFk
|
|
||||||
JOIN tmp.productionBuffer pb ON pb.ticketFk = s.ticketFk
|
|
||||||
JOIN agencyMode am ON am.id = pb.agencyModeFk
|
|
||||||
JOIN packagingConfig pc
|
|
||||||
LEFT JOIN routesMonitor rm ON rm.routeFk = pb.routeFk
|
|
||||||
LEFT JOIN itemShelvingStock iss ON iss.itemFk = s.itemFk AND iss.sectorFk = p.sectorFk
|
|
||||||
LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id
|
|
||||||
LEFT JOIN ticketState ts ON ts.ticketFk = s.ticketFk
|
|
||||||
WHERE s.quantity >= i.packingOut
|
|
||||||
AND NOT pb.problem
|
|
||||||
AND s.quantity > 0
|
|
||||||
AND sgd.saleFk IS NULL
|
|
||||||
AND p.sectorFk = vSectorFk
|
|
||||||
AND ts.isPreviousPreparable
|
|
||||||
AND iss.visible >= s.quantity
|
|
||||||
AND ((rm.bufferFk AND rm.isPickingAllowed)
|
|
||||||
OR am.code = 'REC_ALG')
|
|
||||||
AND pb.shipped = vDated
|
|
||||||
GROUP BY s.id
|
|
||||||
ORDER BY etd;
|
|
||||||
|
|
||||||
SELECT * FROM tmp.sale;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tmp.productionBuffer;
|
DROP TEMPORARY TABLE tmp.productionBuffer;
|
||||||
DROP TEMPORARY TABLE tmp.sale;
|
DROP TEMPORARY TABLE tmp.sale;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL `vn`.`sale_getBoxPickingList`(1, curdate());
|
|
@ -1,13 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`sector_get`()
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtiene los sectores
|
|
||||||
*/
|
|
||||||
|
|
||||||
SELECT s.id,s.description,s.warehouseFk
|
|
||||||
FROM vn.sector s;
|
|
||||||
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -4,7 +4,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`ticket_beforeUpdate`
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE vNewTime TIME;
|
DECLARE vNewTime TIME;
|
||||||
DECLARE vHasTicketRefund BOOL;
|
|
||||||
|
|
||||||
SET NEW.editorFk = account.myUser_getId();
|
SET NEW.editorFk = account.myUser_getId();
|
||||||
|
|
||||||
|
@ -64,14 +63,5 @@ BEGIN
|
||||||
|
|
||||||
CALL vn.routeUpdateM3(NEW.routeFk);
|
CALL vn.routeUpdateM3(NEW.routeFk);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
SELECT COUNT(*) INTO vHasTicketRefund
|
|
||||||
FROM ticketRefund
|
|
||||||
WHERE originalTicketFk = NEW.id
|
|
||||||
OR refundTicketFk = NEW.id;
|
|
||||||
|
|
||||||
IF vHasTicketRefund AND NEW.clientFk <> OLD.clientFk THEN
|
|
||||||
CALL util.throw('The ticket has a refund associated');
|
|
||||||
END IF;
|
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
REVOKE UPDATE ON vn.ticket FROM employee;
|
||||||
|
|
||||||
|
GRANT UPDATE (id,
|
||||||
|
warehouseFk,
|
||||||
|
shipped,
|
||||||
|
nickname,
|
||||||
|
refFk,
|
||||||
|
addressFk,
|
||||||
|
workerFk,
|
||||||
|
observations,
|
||||||
|
isSigned,
|
||||||
|
isLabeled,
|
||||||
|
isPrinted,
|
||||||
|
packages,
|
||||||
|
location,
|
||||||
|
hour,
|
||||||
|
created,
|
||||||
|
isBlocked,
|
||||||
|
solution,
|
||||||
|
routeFk,
|
||||||
|
priority,
|
||||||
|
hasPriority,
|
||||||
|
companyFk,
|
||||||
|
agencyModeFk,
|
||||||
|
landed,
|
||||||
|
isBoxed,
|
||||||
|
isDeleted,
|
||||||
|
zoneFk,
|
||||||
|
zonePrice,
|
||||||
|
zoneBonus,
|
||||||
|
totalWithVat,
|
||||||
|
totalWithoutVat,
|
||||||
|
weight,
|
||||||
|
clonedFrom,
|
||||||
|
cmrFk,
|
||||||
|
editorFk)
|
||||||
|
ON vn.ticket TO employee;
|
|
@ -1,49 +1,60 @@
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('Ticket transferClient()', () => {
|
describe('Ticket transferClient()', () => {
|
||||||
const userId = 9;
|
const originalTicketId = 8;
|
||||||
const activeCtx = {
|
const refundTicketId = 24;
|
||||||
accessToken: {userId: userId},
|
const clientId = 1;
|
||||||
};
|
let ctx;
|
||||||
const ctx = {req: activeCtx};
|
let options;
|
||||||
|
let tx;
|
||||||
|
beforeEach(async() => {
|
||||||
|
ctx = {
|
||||||
|
req: {
|
||||||
|
accessToken: {userId: 9},
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
},
|
||||||
|
args: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
options = {transaction: tx};
|
||||||
|
tx = await models.Ticket.beginTransaction({});
|
||||||
|
options.transaction = tx;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async() => {
|
||||||
|
await tx.rollback();
|
||||||
|
});
|
||||||
|
|
||||||
it('should throw an error as the ticket is not editable', async() => {
|
it('should throw an error as the ticket is not editable', async() => {
|
||||||
const tx = await models.Ticket.beginTransaction({});
|
|
||||||
let error;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
|
||||||
const ticketId = 4;
|
const ticketId = 4;
|
||||||
const clientId = 1;
|
const clientId = 1;
|
||||||
await models.Ticket.transferClient(ctx, ticketId, clientId, options);
|
await models.Ticket.transferClient(ctx, ticketId, clientId, options);
|
||||||
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
expect(e.message).toEqual(`This ticket is locked`);
|
||||||
error = e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(error.message).toEqual(`This ticket is locked`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be assigned a different clientFk', async() => {
|
it('should be assigned a different clientFk in the original ticket', async() => {
|
||||||
const tx = await models.Ticket.beginTransaction({});
|
await models.Ticket.transferClient(ctx, 2, clientId, options);
|
||||||
let updatedTicket;
|
const afterTransfer = await models.Ticket.findById(2, null, options);
|
||||||
const ticketId = 10;
|
|
||||||
const clientId = 1;
|
|
||||||
|
|
||||||
try {
|
expect(afterTransfer.clientFk).toEqual(clientId);
|
||||||
const options = {transaction: tx};
|
});
|
||||||
|
|
||||||
await models.Ticket.transferClient(ctx, ticketId, clientId, options);
|
it('should be assigned a different clientFk in the original and refund ticket and claim', async() => {
|
||||||
updatedTicket = await models.Ticket.findById(ticketId, {fields: ['clientFk']}, options);
|
await models.Ticket.transferClient(ctx, originalTicketId, clientId, options);
|
||||||
|
|
||||||
await tx.rollback();
|
const [originalTicket, refundTicket] = await models.Ticket.find({
|
||||||
} catch (e) {
|
where: {id: {inq: [originalTicketId, refundTicketId]}}
|
||||||
await tx.rollback();
|
}, options);
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(updatedTicket.clientFk).toEqual(clientId);
|
const claim = await models.Claim.findOne({
|
||||||
|
where: {ticketFk: originalTicketId}
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
expect(originalTicket.clientFk).toEqual(clientId);
|
||||||
|
expect(refundTicket.clientFk).toEqual(clientId);
|
||||||
|
expect(claim.clientFk).toEqual(clientId);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,20 +2,17 @@ module.exports = Self => {
|
||||||
Self.remoteMethodCtx('transferClient', {
|
Self.remoteMethodCtx('transferClient', {
|
||||||
description: 'Transfering ticket to another client',
|
description: 'Transfering ticket to another client',
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [
|
accepts: [{
|
||||||
{
|
arg: 'id',
|
||||||
arg: 'id',
|
type: 'number',
|
||||||
type: 'number',
|
required: true,
|
||||||
required: true,
|
description: 'the ticket id',
|
||||||
description: 'the ticket id',
|
http: {source: 'path'}
|
||||||
http: {source: 'path'}
|
}, {
|
||||||
},
|
arg: 'clientFk',
|
||||||
{
|
type: 'number',
|
||||||
arg: 'clientFk',
|
required: true,
|
||||||
type: 'number',
|
}],
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
http: {
|
http: {
|
||||||
path: `/:id/transferClient`,
|
path: `/:id/transferClient`,
|
||||||
verb: 'PATCH'
|
verb: 'PATCH'
|
||||||
|
@ -25,21 +22,51 @@ module.exports = Self => {
|
||||||
Self.transferClient = async(ctx, id, clientFk, options) => {
|
Self.transferClient = async(ctx, id, clientFk, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
await Self.isEditableOrThrow(ctx, id, myOptions);
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
const ticket = await models.Ticket.findById(
|
try {
|
||||||
id,
|
await Self.isEditableOrThrow(ctx, id, myOptions);
|
||||||
{fields: ['id', 'shipped', 'clientFk', 'addressFk']},
|
|
||||||
myOptions
|
|
||||||
);
|
|
||||||
const client = await models.Client.findById(clientFk, {fields: ['id', 'defaultAddressFk']}, myOptions);
|
|
||||||
|
|
||||||
await ticket.updateAttributes({
|
const ticketRefund = await models.TicketRefund.findOne({
|
||||||
clientFk,
|
where: {or: [{originalTicketFk: id}, {refundTicketFk: id}]},
|
||||||
addressFk: client.defaultAddressFk,
|
include: [{relation: 'refundTicket'}, {relation: 'originalTicket'}]
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
|
const {defaultAddressFk: addressFk} = await models.Client.findById(clientFk,
|
||||||
|
{fields: ['id', 'defaultAddressFk']}, myOptions);
|
||||||
|
|
||||||
|
const attributes = {clientFk, addressFk};
|
||||||
|
|
||||||
|
const tickets = [];
|
||||||
|
const ticketIds = [];
|
||||||
|
|
||||||
|
if (ticketRefund) {
|
||||||
|
const {refundTicket, originalTicket} = ticketRefund;
|
||||||
|
tickets.push(refundTicket(), originalTicket());
|
||||||
|
|
||||||
|
for (const ticket of tickets) {
|
||||||
|
await ticket.updateAttributes(attributes, myOptions);
|
||||||
|
ticketIds.push(ticket.id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await Self.updateAll({id}, attributes, myOptions);
|
||||||
|
ticketIds.push(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
await models.Claim.updateAll({ticketFk: {inq: ticketIds}}, {clientFk}, myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue