refactor: refs #8613 add fk to claimEnd.claimDestinationFk #3479

Merged
ivanm merged 7 commits from 8613-addFkClaimDestinationFk into dev 2025-02-24 15:09:26 +00:00
24 changed files with 980 additions and 742 deletions
Showing only changes of commit 218bb4db6f - Show all commits

View File

@ -195,7 +195,7 @@ INSERT INTO `vn`.`sectorType` (`id`, `code`)
INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `code`, `typeFk`) INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `code`, `typeFk`)
VALUES VALUES
(1, 'First sector', 1, 'FIRST', 1), (1, 'First sector', 1, 'FIRST', 1),
(2, 'Second sector', 2, 'SECOND',1); (2, 'Second sector', 6, 'SECOND',1);
INSERT INTO `vn`.`printer` (`id`, `name`, `path`, `isLabeler`, `sectorFk`, `ipAddress`) INSERT INTO `vn`.`printer` (`id`, `name`, `path`, `isLabeler`, `sectorFk`, `ipAddress`)
VALUES VALUES
@ -730,7 +730,8 @@ INSERT INTO `vn`.`zoneWarehouse` (`id`, `zoneFk`, `warehouseFk`)
(10, 10, 3), (10, 10, 3),
(11, 11, 5), (11, 11, 5),
(12, 12, 4), (12, 12, 4),
(13, 13, 5); (13, 13, 5),
(14, 7, 4);
INSERT INTO `vn`.`zoneClosure` (`zoneFk`, `dated`, `hour`) INSERT INTO `vn`.`zoneClosure` (`zoneFk`, `dated`, `hour`)
VALUES VALUES
@ -1302,9 +1303,10 @@ INSERT INTO `vn`.`train`(`id`, `name`)
INSERT INTO `vn`.`operator` (`workerFk`, `numberOfWagons`, `trainFk`, `itemPackingTypeFk`, `warehouseFk`, `sectorFk`, `labelerFk`) INSERT INTO `vn`.`operator` (`workerFk`, `numberOfWagons`, `trainFk`, `itemPackingTypeFk`, `warehouseFk`, `sectorFk`, `labelerFk`)
VALUES VALUES
('1106', '1', '1', 'H', '1', '1', '1'), (1106, '1', '1', 'H', '1', '1', '1'),
('9', '2', '1', 'H', '1', '1', '1'), (9, '2', '1', 'H', '1', '1', '1'),
('1107', '1', '1', 'V', '1', '1', '1'); (1107, '1', '1', 'V', '1', '1', '1'),
(72, '1', '1', 'V', '1', '1', '1');
INSERT INTO `vn`.`collection`(`id`, `workerFk`, `stateFk`, `created`, `trainFk`) INSERT INTO `vn`.`collection`(`id`, `workerFk`, `stateFk`, `created`, `trainFk`)
VALUES VALUES
@ -1615,6 +1617,7 @@ INSERT INTO `bs`.`waste`(`buyerFk`, `year`, `week`, `itemFk`, `itemTypeFk`, `sal
(19, 100, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'grouping', NULL, 0.00, 99.6, 99.4, 0, 1, 0, NULL, 1, util.VN_CURDATE()), (19, 100, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'grouping', NULL, 0.00, 99.6, 99.4, 0, 1, 0, NULL, 1, util.VN_CURDATE()),
(20, 100, 2, 5, 450, 3, 2, 1.000, 1.000, 0.000, 10, 10, NULL, NULL, 0.00, 7.30, 7.00, 0, 1, 0, NULL, 2.5, util.VN_CURDATE()), (20, 100, 2, 5, 450, 3, 2, 1.000, 1.000, 0.000, 10, 10, NULL, NULL, 0.00, 7.30, 7.00, 0, 1, 0, NULL, 2.5, util.VN_CURDATE()),
(21, 100,72, 55, 500, 5, 3, 1.000, 1.000, 0.000, 1, 1, 'packing', NULL, 0.00, 78.3, 75.6, 0, 1, 0, 1, 3, util.VN_CURDATE()), (21, 100,72, 55, 500, 5, 3, 1.000, 1.000, 0.000, 1, 1, 'packing', NULL, 0.00, 78.3, 75.6, 0, 1, 0, 1, 3, util.VN_CURDATE()),
(22, 100, 4, 55, 0, 5, 0, 0, 0, 0.000, 1, 1, 'packing', NULL, 0.00, 78.3, 75.6, 0, 1, 0, 1, 3, util.VN_CURDATE()),
(10000002, 12,88, 50.0000, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'grouping', NULL, 0.00, 99.60, 99.40, 0, 1, 0, 1.00, 1,util.VN_CURDATE() - INTERVAL 2 MONTH); (10000002, 12,88, 50.0000, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'grouping', NULL, 0.00, 99.60, 99.40, 0, 1, 0, 1.00, 1,util.VN_CURDATE() - INTERVAL 2 MONTH);
INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`) INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`)
@ -1957,11 +1960,11 @@ INSERT INTO `vn`.`claimBeginning`(`id`, `claimFk`, `saleFk`, `quantity`)
INSERT INTO `vn`.`claimDestination`(`id`, `description`, `addressFk`) INSERT INTO `vn`.`claimDestination`(`id`, `description`, `addressFk`)
VALUES VALUES
(1, 'Bueno', NULL), (1, 'Bueno', 11),
(2, 'Basura/Perd.', 12), (2, 'Basura/Perd.', NULL),
(3, 'Confeccion', NULL), (3, 'Confeccion', NULL),
(4, 'Reclam.PRAG', 12), (4, 'Reclam.PRAG', NULL),
(5, 'Corregido', 11); (5, 'Corregido', NULL);
INSERT INTO `vn`.`claimDevelopment`(`id`, `claimFk`, `claimResponsibleFk`, `workerFk`, `claimReasonFk`, `claimResultFk`, `claimRedeliveryFk`, `claimDestinationFk`) INSERT INTO `vn`.`claimDevelopment`(`id`, `claimFk`, `claimResponsibleFk`, `workerFk`, `claimReasonFk`, `claimResultFk`, `claimRedeliveryFk`, `claimDestinationFk`)
VALUES VALUES
@ -1976,9 +1979,9 @@ INSERT INTO `vn`.`claimEnd`(`id`, `saleFk`, `claimFk`, `workerFk`, `claimDestina
(1, 31, 4, 21, 2), (1, 31, 4, 21, 2),
(2, 32, 3, 21, 3); (2, 32, 3, 21, 3);
INSERT INTO `vn`.`claimConfig`(`id`, `maxResponsibility`, `monthsToRefund`, `minShipped`,`daysToClaim`) INSERT INTO `vn`.`claimConfig`(`id`, `maxResponsibility`, `monthsToRefund`, `minShipped`,`daysToClaim`, `pickupDeliveryFk`, `warehouseFk`)
VALUES VALUES
(1, 5, 4, '2016-10-01', 7); (1, 5, 4, '2016-10-01', 7, 8, 4);
INSERT INTO `vn`.`claimRatio`(`clientFk`, `yearSale`, `claimAmount`, `claimingRate`, `priceIncreasing`, `packingRate`) INSERT INTO `vn`.`claimRatio`(`clientFk`, `yearSale`, `claimAmount`, `claimingRate`, `priceIncreasing`, `packingRate`)
VALUES VALUES
@ -3063,9 +3066,10 @@ INSERT INTO `salix`.`url` (`appName`, `environment`, `url`)
('salix', 'development', 'http://localhost:5000/#!/'), ('salix', 'development', 'http://localhost:5000/#!/'),
('docuware', 'development', 'http://docuware'); ('docuware', 'development', 'http://docuware');
INSERT INTO `vn`.`report` (`id`, `name`, `paperSizeFk`, `method`) INSERT INTO `vn`.`report` (`name`, `method`)
VALUES VALUES
(3, 'invoice', NULL, 'InvoiceOuts/{refFk}/invoice-out-pdf'); ('invoice', 'InvoiceOuts/{refFk}/invoice-out-pdf'),
('LabelBuy', 'Entries/{id}/{labelType}/buy-label');
INSERT INTO `vn`.`payDemDetail` (`id`, `detail`) INSERT INTO `vn`.`payDemDetail` (`id`, `detail`)
VALUES VALUES
@ -4142,3 +4146,6 @@ INSERT IGNORE INTO vn.vehicleType (id, name)
(2, 'furgoneta'), (2, 'furgoneta'),
(3, 'cabeza tractora'), (3, 'cabeza tractora'),
(4, 'remolque'); (4, 'remolque');
INSERT INTO vn.addressWaste (addressFk, type)
VALUES (11, 'fault');

View File

@ -25,20 +25,23 @@ BEGIN
DECLARE vPrintQueueFk INT; DECLARE vPrintQueueFk INT;
DECLARE vReportSize VARCHAR(255); DECLARE vReportSize VARCHAR(255);
DECLARE vIsThePrinterReal INT; DECLARE vIsThePrinterReal INT;
DECLARE vPrinteSize VARCHAR(255); DECLARE vPrinterSize VARCHAR(255);
DECLARE vPriorityFk INT; DECLARE vPriorityFk INT;
DECLARE vReportFk INT; DECLARE vReportFk INT;
DECLARE vTx BOOLEAN DEFAULT NOT @@in_transaction;
DECLARE EXIT HANDLER FOR SQLEXCEPTION DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN BEGIN
ROLLBACK; CALL util.tx_rollback(vTx);
RESIGNAL; RESIGNAL;
END; END;
SELECT id, paperSizeFk INTO vReportFk, vReportSize SELECT id, paperSizeFk INTO vReportFk, vReportSize
FROM report FROM report
WHERE name = vReportName; WHERE name = vReportName;
SELECT id, paperSizeFk INTO vIsThePrinterReal, vPrinteSize SELECT id, paperSizeFk INTO vIsThePrinterReal, vPrinterSize
FROM printer FROM printer
WHERE id = vPrinterFk; WHERE id = vPrinterFk;
@ -54,11 +57,10 @@ BEGIN
CALL util.throw('reportNotExists'); CALL util.throw('reportNotExists');
END IF; END IF;
IF vReportSize <> vPrinteSize THEN IF vReportSize <> vPrinterSize THEN
CALL util.throw('incorrectSize'); CALL util.throw('incorrectSize');
END IF; END IF;
CALL util.tx_start(vTx);
START TRANSACTION;
INSERT INTO printQueue INSERT INTO printQueue
SET printerFk = vPrinterFk, SET printerFk = vPrinterFk,
priorityFk = vPriorityFk, priorityFk = vPriorityFk,
@ -78,6 +80,7 @@ BEGIN
SET vI = vI + 1; SET vI = vI + 1;
END WHILE; END WHILE;
COMMIT;
CALL util.tx_commit(vTx);
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -0,0 +1,14 @@
ALTER TABLE `vn`.`claimConfig`
ADD COLUMN `pickupDeliveryFk` INT(11)
COMMENT 'Agencia utilizada para las recogidas mediante reparto',
ADD COLUMN `warehouseFk` smallint(6) unsigned
COMMENT 'Almacén usado para los tickets de reclamaciones',
ADD CONSTRAINT `fk_claimConfig_pickupdeliveryFk`
FOREIGN KEY (`pickupdeliveryFk`)
REFERENCES `agencyMode` (`id`),
ADD CONSTRAINT `fk_claimConfig_warehouseFk`
FOREIGN KEY (`warehouseFk`)
REFERENCES `warehouse` (`id`);

View File

@ -0,0 +1,2 @@
INSERT IGNORE INTO vn.state (name,`order`,alertLevel,code,isPreviousPreparable,isPicked)
VALUES ('Recogido',3,4,'PICKED_UP',0,1)

View File

@ -0,0 +1,5 @@
ALTER TABLE `vn`.`claimEnd`
ADD COLUMN `shelvingFk` INT(11) DEFAULT NULL AFTER `editorFk`,
ADD INDEX `claimEnd_fk_shelving` (`shelvingFk`),
ADD CONSTRAINT `claimEnd_fk_shelving` FOREIGN KEY (`shelvingFk`)
REFERENCES `shelving` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;

View File

@ -0,0 +1,8 @@
UPDATE vn.claimDestination cd
SET cd.addressFk = NULL
WHERE code IN ('garbage/loss','manufacturing','supplierClaim','corrected');
UPDATE vn.claimDestination cd
JOIN vn.addressWaste aw ON aw.`type` = 'fault'
SET cd.addressFk = aw.addressFk
WHERE code IN ('good');

View File

@ -258,5 +258,6 @@
"clonedFromTicketWeekly": ", that is a cloned sale from ticket {{ ticketWeekly }}", "clonedFromTicketWeekly": ", that is a cloned sale from ticket {{ ticketWeekly }}",
"negativeReplaced": "Replaced item [#{{oldItemId}}]({{{oldItemUrl}}}) {{oldItem}} with [#{{newItemId}}]({{{newItemUrl}}}) {{newItem}} from ticket [{{ticketId}}]({{{ticketUrl}}})", "negativeReplaced": "Replaced item [#{{oldItemId}}]({{{oldItemUrl}}}) {{oldItem}} with [#{{newItemId}}]({{{newItemUrl}}}) {{newItem}} from ticket [{{ticketId}}]({{{ticketUrl}}})",
"The tag and priority can't be repeated": "The tag and priority can't be repeated", "The tag and priority can't be repeated": "The tag and priority can't be repeated",
"duplicateWarehouse": "The introduced warehouse already exists" "The introduced warehouse already exists": "The introduced warehouse already exists",
"The code already exists": "The code already exists"
} }

View File

@ -399,5 +399,6 @@
"Price cannot be blank": "El precio no puede estar en blanco", "Price cannot be blank": "El precio no puede estar en blanco",
"clonedFromTicketWeekly": ", que es una linea clonada del ticket {{ticketWeekly}}", "clonedFromTicketWeekly": ", que es una linea clonada del ticket {{ticketWeekly}}",
"negativeReplaced": "Sustituido el articulo [#{{oldItemId}}]({{{oldItemUrl}}}) {{oldItem}} por [#{{newItemId}}]({{{newItemUrl}}}) {{newItem}} del ticket [{{ticketId}}]({{{ticketUrl}}})", "negativeReplaced": "Sustituido el articulo [#{{oldItemId}}]({{{oldItemUrl}}}) {{oldItem}} por [#{{newItemId}}]({{{newItemUrl}}}) {{newItem}} del ticket [{{ticketId}}]({{{ticketUrl}}})",
"duplicateWarehouse": "El almacén seleccionado ya existe en la zona" "The introduced warehouse already exists": "El almacén seleccionado ya existe en la zona",
"The code already exists": "El código ya existe"
} }

View File

@ -74,66 +74,77 @@ module.exports = Self => {
} }
try { try {
const worker = await models.Worker.findOne({ const claim = await models.Claim.findOne(filter, myOptions);
where: {id: userId} const today = Date.vnNew();
let agencyModeFk;
let nickname;
let state;
let discountValue = null;
let packages = 0;
const claimConfig = await models.ClaimConfig.findOne();
const warehouseFk = claimConfig.warehouseFk;
if (claim.pickup === null || claim.pickup == 'agency') {
state = await models.State.findOne({
where: {code: 'DELIVERED'}
}, myOptions); }, myOptions);
const obsevationType = await models.ObservationType.findOne({
where: {code: 'salesPerson'}
}, myOptions);
const agencyMode = await models.AgencyMode.findOne({ const agencyMode = await models.AgencyMode.findOne({
where: {code: 'refund'} where: {code: 'refund'}
}, myOptions); }, myOptions);
const state = await models.State.findOne({ agencyModeFk = agencyMode.id;
where: {code: 'DELIVERED'} nickname = `Abono del: ${claim.ticketFk}`;
} else {
discountValue = 100;
packages = 1;
state = await models.State.findOne({
where: {code: 'WAITING_FOR_PICKUP'}
}, myOptions); }, myOptions);
const zone = await models.Zone.findOne({ nickname = `Recogida pendiente del: ${claim.ticketFk}`;
where: {agencyModeFk: agencyMode.id}
}, myOptions);
const claim = await models.Claim.findOne(filter, myOptions);
const today = Date.vnNew();
agencyModeFk = claimConfig.pickupDeliveryFk;
}
const nextShipped = await models.Agency.getShipped(
ctx, today, claim.ticket().addressFk, agencyModeFk, warehouseFk, myOptions
);
const newRefundTicket = await models.Ticket.create({ const newRefundTicket = await models.Ticket.create({
clientFk: claim.ticket().clientFk, clientFk: claim.ticket().clientFk,
shipped: today, shipped: nextShipped,
landed: today, landed: null,
nickname: `Abono del: ${claim.ticketFk}`, nickname,
warehouseFk: claim.ticket().warehouseFk, warehouseFk,
companyFk: claim.ticket().companyFk, companyFk: claim.ticket().companyFk,
addressFk: claim.ticket().addressFk, addressFk: claim.ticket().addressFk,
agencyModeFk: agencyMode.id, agencyModeFk,
zoneFk: zone.id zoneFk: claim.ticket().zoneFk,
packages
}, myOptions); }, myOptions);
if (claim.pickup == 'pickup') {
const observationDelivery =
await models.ObservationType.findOne({where: {code: 'delivery'}}, myOptions);
await saveObservation({
description: `recoger reclamación: ${claim.id}`,
ticketFk: newRefundTicket.id,
observationTypeFk: observationDelivery.id
}, myOptions);
}
await models.TicketRefund.create({ await models.TicketRefund.create({
refundTicketFk: newRefundTicket.id, refundTicketFk: newRefundTicket.id,
originalTicketFk: claim.ticket().id originalTicketFk: claim.ticket().id
}, myOptions); }, myOptions);
await saveObservation({ const salesToRefund = await models.ClaimBeginning.find(salesFilter, myOptions);
description: `Reclama ticket: ${claim.ticketFk}`, const createdSales = await addSalesToTicket(salesToRefund, newRefundTicket.id, discountValue, myOptions);
ticketFk: newRefundTicket.id, await insertIntoClaimEnd(createdSales, id, userId, myOptions);
observationTypeFk: obsevationType.id
}, myOptions);
await models.Ticket.state(ctx, { await models.Ticket.state(ctx, {
ticketFk: newRefundTicket.id, ticketFk: newRefundTicket.id,
stateFk: state.id, stateFk: state.id,
userFk: worker.id userFk: userId
}, myOptions); }, myOptions);
const salesToRefund = await models.ClaimBeginning.find(salesFilter, myOptions);
const createdSales = await addSalesToTicket(salesToRefund, newRefundTicket.id, myOptions);
await insertIntoClaimEnd(createdSales, id, worker.id, myOptions);
await Self.rawSql('CALL vn.ticketCalculateClon(?, ?)', [
newRefundTicket.id, claim.ticketFk
], myOptions);
if (tx) await tx.commit(); if (tx) await tx.commit();
return newRefundTicket; return newRefundTicket;
@ -143,23 +154,36 @@ module.exports = Self => {
} }
}; };
async function addSalesToTicket(salesToRefund, ticketId, options) { async function addSalesToTicket(salesToRefund, newTicketId, discountValue, options) {
let formatedSales = []; const createdSales = [];
salesToRefund.forEach(sale => { const models = Self.app.models;
let formatedSale = { for (const saleToRefund of salesToRefund) {
itemFk: sale.sale().itemFk, const oldSale = saleToRefund.sale();
ticketFk: ticketId, const newSaleData = {
concept: sale.sale().concept, itemFk: oldSale.itemFk,
quantity: -Math.abs(sale.quantity), ticketFk: newTicketId,
price: sale.sale().price, concept: oldSale.concept,
discount: sale.sale().discount, quantity: -Math.abs(saleToRefund.quantity),
reserved: sale.sale().reserved, price: oldSale.price,
isPicked: sale.sale().isPicked, discount: discountValue ?? oldSale.discount,
created: sale.sale().created reserved: oldSale.reserved,
isPicked: oldSale.isPicked,
created: oldSale.created
}; };
formatedSales.push(formatedSale); const newSale = await models.Sale.create(newSaleData, options);
const oldSaleComponents = await models.SaleComponent.find({
where: {saleFk: oldSale.id}
}, options);
const newComponents = oldSaleComponents.map(component => {
const data = component.toJSON ? component.toJSON() : {...component};
delete data.id;
data.saleFk = newSale.id;
return data;
}); });
return await Self.app.models.Sale.create(formatedSales, options); await models.SaleComponent.create(newComponents, options);
createdSales.push(newSale);
}
return createdSales;
} }
async function insertIntoClaimEnd(createdSales, claimId, workerId, options) { async function insertIntoClaimEnd(createdSales, claimId, workerId, options) {

View File

@ -1,44 +0,0 @@
const app = require('vn-loopback/server/server');
const LoopBackContext = require('loopback-context');
const models = app.models;
describe('claimBeginning', () => {
const claimManagerId = 72;
const activeCtx = {
accessToken: {userId: claimManagerId},
__: value => value
};
const ctx = {req: activeCtx};
describe('importToNewRefundTicket()', () => {
it('should create a new ticket with negative sales and insert the negative sales into claimEnd', async() => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
let claimId = 1;
const tx = await models.Entry.beginTransaction({});
try {
const options = {transaction: tx};
const ticket = await models.ClaimBeginning.importToNewRefundTicket(ctx, claimId, options);
const refundTicketSales = await models.Sale.find({
where: {ticketFk: ticket.id}
}, options);
const salesInsertedInClaimEnd = await models.ClaimEnd.find({
where: {claimFk: claimId}
}, options);
expect(refundTicketSales.length).toEqual(1);
expect(refundTicketSales[0].quantity).toEqual(-5);
expect(salesInsertedInClaimEnd[0].saleFk).toEqual(refundTicketSales[0].id);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});
});

View File

@ -0,0 +1,99 @@
const app = require('vn-loopback/server/server');
const LoopBackContext = require('loopback-context');
const models = app.models;
describe('importToNewRefundTicket()', () => {
let tx;
const claimManagerId = 72;
const activeCtx = {
accessToken: {userId: claimManagerId},
};
let ctx = {req: activeCtx};
let options;
const claimId = 1;
const expectedDate = Date.vnNew();
beforeEach(async() => {
LoopBackContext.getCurrentContext = () => ({
active: activeCtx,
});
tx = await models.Entry.beginTransaction({});
options = {transaction: tx};
spyOn(models.Agency, 'getShipped').and.returnValue(Promise.resolve(expectedDate));
});
afterEach(async() => {
await tx.rollback();
});
it('should create a new ticket with negative sales and insert the negative sales into claimEnd', async() => {
const ticket = await models.ClaimBeginning.importToNewRefundTicket(ctx, claimId, options);
const refundTicketSales = await models.Sale.find({
where: {ticketFk: ticket.id}
}, options);
const salesInsertedInClaimEnd = await models.ClaimEnd.find({
where: {claimFk: claimId}
}, options);
expect(refundTicketSales.length).toEqual(1);
expect(refundTicketSales[0].quantity).toEqual(-5);
expect(salesInsertedInClaimEnd[0].saleFk).toEqual(refundTicketSales[0].id);
});
it('should set DELIVERED state and refund agency mode', async() => {
const state = await models.State.findOne({
where: {code: 'DELIVERED'}
}, options);
const ticket = await models.ClaimBeginning.importToNewRefundTicket(ctx, claimId, options);
const ticketTracking = await models.TicketTracking.findOne({
where: {ticketFk: ticket.id},
order: 'id DESC'
}, options);
const newSales = await models.Sale.find({
where: {ticketFk: ticket.id}
}, options);
newSales.forEach(sale => {
expect(sale.discount).toEqual(0);
});
expect(ticketTracking.stateFk).toEqual(state.id);
});
it('should set WAITING_FOR_PICKUP state for delivery pickups', async() => {
const state = await models.State.findOne({
where: {code: 'WAITING_FOR_PICKUP'}
}, options);
await models.Claim.updateAll({id: claimId}, {pickup: 'delivery'}, options);
const ticket = await models.ClaimBeginning.importToNewRefundTicket(ctx, claimId, options);
const ticketTracking = await models.TicketTracking.findOne({
where: {ticketFk: ticket.id},
order: 'id DESC'
}, options);
const newSales = await models.Sale.find({
where: {ticketFk: ticket.id}
}, options);
newSales.forEach(sale => {
expect(sale.discount).toEqual(100);
});
expect(ticketTracking.stateFk).toEqual(state.id);
});
it('should set DELIVERED state for agency pickups', async() => {
const state = await models.State.findOne({
where: {code: 'DELIVERED'}
}, options);
await models.Claim.updateAll({id: claimId}, {pickup: 'agency'}, options);
const ticket = await models.ClaimBeginning.importToNewRefundTicket(ctx, claimId, options);
const ticketTracking = await models.TicketTracking.findOne({
where: {ticketFk: ticket.id},
order: 'id DESC'
}, options);
expect(ticketTracking.stateFk).toEqual(state.id);
});
});

View File

@ -51,10 +51,13 @@ module.exports = Self => {
s.concept, s.concept,
s.price, s.price,
s.discount, s.discount,
s.quantity * s.price * ((100 - s.discount) / 100) total s.quantity * s.price * ((100 - s.discount) / 100) total,
ce.shelvingFk,
sh.code shelvingCode
FROM vn.claimEnd ce FROM vn.claimEnd ce
LEFT JOIN vn.sale s ON s.id = ce.saleFk LEFT JOIN vn.sale s ON s.id = ce.saleFk
LEFT JOIN vn.ticket t ON t.id = s.ticketFk LEFT JOIN vn.ticket t ON t.id = s.ticketFk
LEFT JOIN vn.shelving sh ON sh.id = ce.shelvingFk
) ce` ) ce`
); );

View File

@ -3,12 +3,14 @@ module.exports = Self => {
description: `Imports lines from claimBeginning to a new ticket description: `Imports lines from claimBeginning to a new ticket
with specific shipped, landed dates, agency and company`, with specific shipped, landed dates, agency and company`,
accessType: 'WRITE', accessType: 'WRITE',
accepts: [{ accepts: [
{
arg: 'id', arg: 'id',
type: 'number', type: 'number',
description: 'The claim id', description: 'The claim id',
http: {source: 'path'} http: {source: 'path'}
}], }
],
returns: { returns: {
type: ['Object'], type: ['Object'],
root: true root: true
@ -22,8 +24,6 @@ module.exports = Self => {
Self.regularizeClaim = async(ctx, claimFk, options) => { Self.regularizeClaim = async(ctx, claimFk, options) => {
const models = Self.app.models; const models = Self.app.models;
const $t = ctx.req.__; // $translate const $t = ctx.req.__; // $translate
const resolvedState = 3;
let tx; let tx;
const myOptions = {}; const myOptions = {};
@ -37,25 +37,39 @@ module.exports = Self => {
try { try {
const claimEnds = await models.ClaimEnd.find({ const claimEnds = await models.ClaimEnd.find({
include: { where: {claimFk: claimFk},
include: [
{
relation: 'claimDestination', relation: 'claimDestination',
fields: ['addressFk'] scope: {fields: ['addressFk']}
}, },
where: {claimFk: claimFk} {
relation: 'shelving',
scope: {
fields: ['code', 'parkingFk'],
include: {
relation: 'parking',
scope: {
fields: ['sectorFk'],
include: {
relation: 'sector',
scope: {fields: ['warehouseFk']}
}
}
}
}
}
]
}, myOptions); }, myOptions);
for (let claimEnd of claimEnds) { for (let claimEnd of claimEnds) {
const destination = claimEnd.claimDestination(); const destination = claimEnd.claimDestination();
const sale = await getSale(claimEnd.saleFk, myOptions); const sale = await getSale(claimEnd.saleFk, myOptions);
const addressId = destination && destination.addressFk; const addressId = destination?.addressFk;
let address;
if (addressId)
address = await models.Address.findById(addressId, null, myOptions);
const salesPerson = sale.ticket().client().salesPersonUser(); const salesPerson = sale.ticket().client().salesPersonUser();
if (salesPerson) { if (salesPerson) {
const nickname = address && address.nickname || destination.description; const nickname = destination.description;
const url = await Self.app.models.Url.getUrl(); const url = await Self.app.models.Url.getUrl();
const message = $t('Sent units from ticket', { const message = $t('Sent units from ticket', {
quantity: sale.quantity, quantity: sale.quantity,
@ -69,18 +83,21 @@ module.exports = Self => {
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
} }
if (!address) continue; if (!addressId) continue;
const warehouseFk = claimEnd.shelving().parking().sector().warehouseFk;
const address = await models.Address.findById(addressId, null, myOptions);
let ticketFk = await getTicketId({ let ticketFk = await getTicketId({
addressFk: addressId, addressFk: addressId,
companyFk: sale.ticket().companyFk, companyFk: sale.ticket().companyFk,
warehouseFk: sale.ticket().warehouseFk warehouseFk: warehouseFk
}, myOptions); }, myOptions);
if (!ticketFk) { if (!ticketFk) {
ctx.args = { ctx.args = {
clientId: address.clientFk, clientId: address.clientFk,
warehouseId: sale.ticket().warehouseFk, warehouseId: warehouseFk,
companyId: sale.ticket().companyFk, companyId: sale.ticket().companyFk,
addressId: addressId addressId: addressId
}; };
@ -90,15 +107,43 @@ module.exports = Self => {
ticketFk: ticketFk, ticketFk: ticketFk,
itemFk: sale.itemFk, itemFk: sale.itemFk,
concept: sale.concept, concept: sale.concept,
quantity: -sale.quantity, quantity: sale.quantity,
price: sale.price, price: sale.price,
discount: 100 discount: 100
}, myOptions); }, myOptions);
const [buyFk] = await Self.rawSql('SELECT vn.buy_getLastWithoutInventory(?, ?) buyFk',
[sale.itemFk, warehouseFk], myOptions
);
await Self.rawSql('CALL vn.itemShelving_add(?, ?, ?, NULL, NULL, NULL, ?)',
[claimEnd.shelving().code, buyFk.buyFk, -sale.quantity, warehouseFk],
myOptions
);
const operator = await models.Operator.findById(
ctx.req.accessToken.userId, {fields: ['labelerFk']}, myOptions);
const params = JSON.stringify({
copies: 1,
id: buyFk.buyFk,
labelType: 'qr'
});
await Self.rawSql(`CALL vn.report_print( ?, ?, ?, ?, ?)`,
['LabelBuy',
operator?.labelerFk,
ctx.req.accessToken.userId,
params,
'normal'
],
myOptions);
} }
const resolvedState = await models.ClaimState.findOne({
where: {code: 'resolved'}
}, myOptions);
let claim = await Self.findById(claimFk, null, myOptions); let claim = await Self.findById(claimFk, null, myOptions);
claim = await claim.updateAttributes({ claim = await claim.updateAttributes({
claimStateFk: resolvedState claimStateFk: resolvedState.id
}, myOptions); }, myOptions);
if (tx) await tx.commit(); if (tx) await tx.commit();
@ -151,7 +196,7 @@ module.exports = Self => {
} }
}, options); }, options);
return ticket && ticket.id; return ticket?.id;
} }
async function createTicket(ctx, options) { async function createTicket(ctx, options) {

View File

@ -1,11 +1,8 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('claim regularizeClaim()', () => { describe('claim regularizeClaim()', () => {
const userId = 18; const userId = 72;
const ctx = beforeAll.mockLoopBackContext(userId);
ctx.req.__ = (value, params) => {
return params.nickname;
};
const chatModel = models.Chat; const chatModel = models.Chat;
const claimId = 1; const claimId = 1;
const ticketId = 1; const ticketId = 1;
@ -13,9 +10,27 @@ describe('claim regularizeClaim()', () => {
const resolvedState = 3; const resolvedState = 3;
const trashDestination = 2; const trashDestination = 2;
const okDestination = 1; const okDestination = 1;
const trashAddress = 12;
let claimEnds = []; let claimEnds = [];
let trashTicket; const activeCtx = {accessToken: {userId}};
let ctx = {req: activeCtx};
let tx;
let options;
beforeEach(async() => {
LoopBackContext.getCurrentContext = () => ({
active: activeCtx,
});
ctx.req.__ = (_value, params) => {
return params.nickname;
};
tx = await models.Claim.beginTransaction({});
options = {transaction: tx};
});
afterEach(async() => {
await tx.rollback();
});
async function importTicket(ticketId, claimId, userId, options) { async function importTicket(ticketId, claimId, userId, options) {
const ticketSales = await models.Sale.find({ const ticketSales = await models.Sale.find({
@ -34,11 +49,6 @@ describe('claim regularizeClaim()', () => {
} }
it('should send a chat message with value "Trash" and then change claim state to resolved', async() => { it('should send a chat message with value "Trash" and then change claim state to resolved', async() => {
const tx = await models.Claim.beginTransaction({});
try {
const options = {transaction: tx};
spyOn(chatModel, 'sendCheckingPresence').and.callThrough(); spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
claimEnds = await importTicket(ticketId, claimId, userId, options); claimEnds = await importTicket(ticketId, claimId, userId, options);
@ -50,68 +60,62 @@ describe('claim regularizeClaim()', () => {
await models.Claim.regularizeClaim(ctx, claimId, options); await models.Claim.regularizeClaim(ctx, claimId, options);
let claimAfter = await models.Claim.findById(claimId, null, options); let claimAfter = await models.Claim.findById(claimId, null, options);
trashTicket = await models.Ticket.findOne({where: {addressFk: 12}}, options);
expect(trashTicket.addressFk).toEqual(trashAddress);
expect(claimBefore.claimStateFk).toEqual(pendentState); expect(claimBefore.claimStateFk).toEqual(pendentState);
expect(claimAfter.claimStateFk).toEqual(resolvedState); expect(claimAfter.claimStateFk).toEqual(resolvedState);
expect(chatModel.sendCheckingPresence).toHaveBeenCalledWith(ctx, 18, 'Trash');
expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should send a chat message with value "Bueno" and then change claim state to resolved', async() => { it('should change claim state to resolved', async() => {
const tx = await models.Claim.beginTransaction({}); const addressMissingFk = 11;
const shelvingFk = 1;
const warehouseFk = 6;
const minDate = Date.vnNew();
minDate.setHours(0, 0, 0, 0);
try { const maxDate = Date.vnNew();
const options = {transaction: tx}; maxDate.setHours(23, 59, 59, 59);
spyOn(chatModel, 'sendCheckingPresence').and.callThrough(); spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
claimEnds = await importTicket(ticketId, claimId, userId, options); claimEnds = await importTicket(ticketId, claimId, userId, options);
for (claimEnd of claimEnds) for (let claimEnd of claimEnds)
await claimEnd.updateAttributes({claimDestinationFk: okDestination}, options); await claimEnd.updateAttributes({claimDestinationFk: okDestination, shelvingFk}, options);
const sale = await models.Sale.findOne({
include: [
{
relation: 'ticket',
scope: {
fields: ['clientFk', 'companyFk']
}
}],
where: {id: claimEnds[0].saleFk}
}, options);
await models.Claim.regularizeClaim(ctx, claimId, options); await models.Claim.regularizeClaim(ctx, claimId, options);
expect(chatModel.sendCheckingPresence).toHaveBeenCalledWith(ctx, 18, 'Bueno'); const ticket = await models.Ticket.findOne({
expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(4); where: {
addressFk: addressMissingFk,
await tx.rollback(); companyFk: sale.ticket().companyFk,
} catch (e) { warehouseFk: warehouseFk,
await tx.rollback(); shipped: {between: [minDate, maxDate]},
throw e; landed: {between: [minDate, maxDate]}
} }
}); }, options);
it('should send a chat message to the salesPerson when claim isPickUp is enabled', async() => { const missingSale = await models.Sale.findOne({
const tx = await models.Claim.beginTransaction({}); where: {
ticketFk: ticket.id
try {
const options = {transaction: tx};
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
claimEnds = await importTicket(ticketId, claimId, userId, options);
for (claimEnd of claimEnds)
await claimEnd.updateAttributes({claimDestinationFk: okDestination}, options);
await models.Claim.regularizeClaim(ctx, claimId, options);
expect(chatModel.sendCheckingPresence).toHaveBeenCalledWith(ctx, 18, 'Bueno');
expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
} }
}, options);
const claimBeginning = await models.ClaimBeginning.findOne({
where: {
claimFk: claimId
}
}, options);
expect(missingSale.quantity).toBe(claimBeginning.quantity);
}); });
}); });

View File

@ -2,6 +2,9 @@
"Claim": { "Claim": {
"dataSource": "vn" "dataSource": "vn"
}, },
"ClaimConfig": {
"dataSource": "vn"
},
"ClaimContainer": { "ClaimContainer": {
"dataSource": "claimStorage" "dataSource": "claimStorage"
}, },

View File

@ -0,0 +1,42 @@
{
"name": "ClaimConfig",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "claimConfig"
}
},
"properties": {
"id": {
"type": "number",
"id": true,
"description": "Identifier"
},
"maxResponsibility": {
"type": "number"
},
"monthsToRefund": {
"type": "number"
},
"minShipped": {
"type": "date"
},
"pickupdeliveryFk": {
"type": "number"
},
"warehouseFk": {
"type": "number"
}
},
"relations": {
"pickupDelivery": {
"type": "belongsTo",
"model": "AgencyMode",
"foreignKey": "pickupdeliveryFk"
}
}
}

View File

@ -41,6 +41,11 @@
"type": "belongsTo", "type": "belongsTo",
"model": "ClaimDestination", "model": "ClaimDestination",
"foreignKey": "claimDestinationFk" "foreignKey": "claimDestinationFk"
},
"shelving": {
"type": "belongsTo",
"model": "Shelving",
"foreignKey": "shelvingFk"
} }
} }
} }

View File

@ -43,6 +43,17 @@ module.exports = function(Self) {
password: String(Math.random() * 100000000000000) password: String(Math.random() * 100000000000000)
}; };
const supplier = await models.Supplier.findOne({
where: {nif: data.fi}
});
const role = supplier ? await models.VnRole.findOne({
where: {name: 'supplier'}
}) : null;
if (role)
user.roleFk = role.id;
try { try {
const province = await models.Province.findOne({ const province = await models.Province.findOne({
where: {id: data.provinceFk}, where: {id: data.provinceFk},

View File

@ -48,11 +48,11 @@ describe('Client Create', () => {
expect(error.message).toEqual('An email is necessary'); expect(error.message).toEqual('An email is necessary');
}); });
it('should create a new account with dailyInvoice', async() => { it('should create a new account with dailyInvoice and role supplier', async() => {
const newAccount = { const newAccount = {
userName: 'deadpool', userName: 'deadpool',
email: 'deadpool@marvel.com', email: 'deadpool@marvel.com',
fi: '16195279J', fi: '07972486L',
name: 'Wade', name: 'Wade',
socialName: 'DEADPOOL MARVEL', socialName: 'DEADPOOL MARVEL',
street: 'WALL STREET', street: 'WALL STREET',
@ -61,7 +61,6 @@ describe('Client Create', () => {
provinceFk: 1 provinceFk: 1
}; };
try {
const province = await models.Province.findById(newAccount.provinceFk, { const province = await models.Province.findById(newAccount.provinceFk, {
fields: ['id', 'name', 'autonomyFk'], fields: ['id', 'name', 'autonomyFk'],
include: { include: {
@ -71,7 +70,9 @@ describe('Client Create', () => {
const client = await models.Client.createWithUser(newAccount, options); const client = await models.Client.createWithUser(newAccount, options);
const account = await models.VnUser.findOne({where: {name: newAccount.userName}}, options); const account = await models.VnUser.findOne({where: {name: newAccount.userName}}, options);
const supplierRole = await models.VnRole.findOne({where: {name: 'supplier'}}, options);
expect(account.roleFk).toEqual(supplierRole.id);
expect(province.autonomy().hasDailyInvoice).toBeTruthy(); expect(province.autonomy().hasDailyInvoice).toBeTruthy();
expect(account.name).toEqual(newAccount.userName); expect(account.name).toEqual(newAccount.userName);
expect(client.id).toEqual(account.id); expect(client.id).toEqual(account.id);
@ -81,13 +82,9 @@ describe('Client Create', () => {
expect(client.socialName).toEqual(newAccount.socialName); expect(client.socialName).toEqual(newAccount.socialName);
expect(client.businessTypeFk).toEqual(newAccount.businessTypeFk); expect(client.businessTypeFk).toEqual(newAccount.businessTypeFk);
expect(client.hasDailyInvoice).toBeTruthy(); expect(client.hasDailyInvoice).toBeTruthy();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should create a new account without dailyInvoice', async() => { it('should create a new account without dailyInvoice and role customer', async() => {
const newAccount = { const newAccount = {
userName: 'deadpool', userName: 'deadpool',
email: 'deadpool@marvel.com', email: 'deadpool@marvel.com',
@ -100,7 +97,6 @@ describe('Client Create', () => {
provinceFk: 3 provinceFk: 3
}; };
try {
const province = await models.Province.findById(newAccount.provinceFk, { const province = await models.Province.findById(newAccount.provinceFk, {
fields: ['id', 'name', 'autonomyFk'], fields: ['id', 'name', 'autonomyFk'],
include: { include: {
@ -109,13 +105,12 @@ describe('Client Create', () => {
}, options); }, options);
const client = await models.Client.createWithUser(newAccount, options); const client = await models.Client.createWithUser(newAccount, options);
const vnUser = await models.VnUser.findOne({where: {name: newAccount.userName}}, options);
const customerRole = await models.VnRole.findOne({where: {name: 'customer'}}, options);
expect(vnUser.roleFk).toEqual(customerRole.id);
expect(province.autonomy.hasDailyInvoice).toBeFalsy(); expect(province.autonomy.hasDailyInvoice).toBeFalsy();
expect(client.hasDailyInvoice).toBeFalsy(); expect(client.hasDailyInvoice).toBeFalsy();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should not be able to create a user if exists', async() => { it('should not be able to create a user if exists', async() => {

View File

@ -46,29 +46,24 @@ module.exports = Self => {
} }
try { try {
const itemDestination = await models.ClaimDestination.findOne({ const addressWaste = await models.AddressWaste.findOne({
include: { where: {type: 'fault'},
relation: 'address', include: 'address'
scope: {
fields: ['clientFk']
}
},
where: {description: 'Corregido'}
}, myOptions); }, myOptions);
const item = await models.Item.findById(itemFk, null, myOptions); const item = await models.Item.findById(itemFk, null, myOptions);
let ticketId = await getTicketId({ let ticketId = await getTicketId({
clientFk: itemDestination.address.clientFk, clientFk: addressWaste.address().clientFk,
addressFk: itemDestination.addressFk, addressFk: addressWaste.addressFk,
warehouseFk: warehouseFk warehouseFk: warehouseFk
}, myOptions); }, myOptions);
if (!ticketId) { if (!ticketId) {
ctx.args = { ctx.args = {
clientId: itemDestination.address().clientFk, clientId: addressWaste.address().clientFk,
warehouseId: warehouseFk, warehouseId: warehouseFk,
addressId: itemDestination.addressFk addressId: addressWaste.addressFk
}; };
ticketId = await createTicket(ctx, myOptions); ticketId = await createTicket(ctx, myOptions);
} }
@ -121,7 +116,7 @@ module.exports = Self => {
} }
}, options); }, options);
return ticket && ticket.id; return ticket?.id;
} }
}; };
}; };

View File

@ -0,0 +1,5 @@
module.exports = Self => {
Self.validatesUniquenessOf('code', {
message: `The code already exists`
});
};

View File

@ -1,4 +1,8 @@
module.exports = Self => { module.exports = Self => {
require('../methods/shelving/getSummary')(Self); require('../methods/shelving/getSummary')(Self);
require('../methods/shelving/addLog')(Self); require('../methods/shelving/addLog')(Self);
Self.validatesUniquenessOf('code', {
message: `The code already exists`
});
}; };

View File

@ -33,6 +33,11 @@ module.exports = Self => {
type: 'date', type: 'date',
description: `The to date filter` description: `The to date filter`
}, },
{
arg: 'shipped',
type: 'date',
description: `The shipped date filter`
},
{ {
arg: 'nickname', arg: 'nickname',
type: 'string', type: 'string',
@ -201,6 +206,7 @@ module.exports = Self => {
case 'clientFk': case 'clientFk':
case 'agencyModeFk': case 'agencyModeFk':
case 'warehouseFk': case 'warehouseFk':
case 'shipped':
param = `t.${param}`; param = `t.${param}`;
return {[param]: value}; return {[param]: value};
} }

View File

@ -3,7 +3,7 @@ let UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.rewriteDbError(function(err) { Self.rewriteDbError(function(err) {
if (err.code === 'ER_DUP_ENTRY') if (err.code === 'ER_DUP_ENTRY')
return new UserError(`duplicateWarehouse`); return new UserError(`The introduced warehouse already exists`);
return err; return err;
}); });
}; };