Merge branch 'dev' into 8244-floricode
gitea/salix/pipeline/pr-dev There was a failure building this commit
Details
gitea/salix/pipeline/pr-dev There was a failure building this commit
Details
This commit is contained in:
commit
f4842827a6
|
@ -13,6 +13,11 @@ module.exports = Self => {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Origin model from insert'
|
description: 'Origin model from insert'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
arg: 'description',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Action description'
|
||||||
|
},
|
||||||
|
|
||||||
],
|
],
|
||||||
http: {
|
http: {
|
||||||
|
@ -21,7 +26,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.add = async(ctx, code, model, options) => {
|
Self.add = async(ctx, code, model, description, options) => {
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
|
||||||
|
@ -29,8 +34,8 @@ module.exports = Self => {
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
return await Self.rawSql(`
|
return await Self.rawSql(`
|
||||||
INSERT INTO workerActivity (workerFk, workerActivityTypeFk, model)
|
INSERT INTO workerActivity (workerFk, workerActivityTypeFk, model, description)
|
||||||
SELECT ?, ?, ?
|
SELECT ?, ?, ?, ?
|
||||||
FROM workerTimeControlConfig wtcc
|
FROM workerTimeControlConfig wtcc
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT wa.workerFk,
|
SELECT wa.workerFk,
|
||||||
|
@ -43,8 +48,8 @@ module.exports = Self => {
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
) sub ON TRUE
|
) sub ON TRUE
|
||||||
WHERE sub.workerFk IS NULL
|
WHERE sub.workerFk IS NULL
|
||||||
OR sub.code <> ?
|
OR sub.code <> ?
|
||||||
OR TIMESTAMPDIFF(SECOND, sub.created, util.VN_NOW()) > wtcc.dayBreak;`
|
OR TIMESTAMPDIFF(SECOND, sub.created, util.VN_NOW()) > wtcc.dayBreak;`
|
||||||
, [userId, code, model, userId, code], myOptions);
|
, [userId, code, model, description, userId, code], myOptions);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,7 +13,7 @@ describe('workerActivity insert()', () => {
|
||||||
{'code': 'TEST', 'description': 'TEST'}, options
|
{'code': 'TEST', 'description': 'TEST'}, options
|
||||||
);
|
);
|
||||||
|
|
||||||
await models.WorkerActivity.add(ctx, 'TEST', 'APP', options);
|
await models.WorkerActivity.add(ctx, 'TEST', 'APP', 'description', options);
|
||||||
|
|
||||||
count = await models.WorkerActivity.count(
|
count = await models.WorkerActivity.count(
|
||||||
{'workerFK': 1106}, options
|
{'workerFK': 1106}, options
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
"relations": {
|
"relations": {
|
||||||
"agency": {
|
"agency": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "WorkCenter",
|
"model": "Agency",
|
||||||
"foreignKey": "agencyFk"
|
"foreignKey": "agencyFk"
|
||||||
},
|
},
|
||||||
"workCenter": {
|
"workCenter": {
|
||||||
|
|
|
@ -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
|
||||||
|
@ -853,7 +854,8 @@ INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `userFk`, `created`)
|
||||||
|
|
||||||
INSERT INTO `vn`.`deliveryPoint` (`id`, `name`, `ubication`)
|
INSERT INTO `vn`.`deliveryPoint` (`id`, `name`, `ubication`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'Gotham','1007 Mountain Drive, Gotham');
|
(1, 'Gotham','1007 Mountain Drive, Gotham'),
|
||||||
|
(6, 'Stark Tower','200 Park Avenue, Nueva York');
|
||||||
|
|
||||||
INSERT INTO `vn`.`vehicle`(`id`, `numberPlate`, `tradeMark`, `model`, `companyFk`, `warehouseFk`, `description`, `m3`, `isActive`, `deliveryPointFk`, `chassis`, `leasing`, `supplierFk`, `fuelTypeFk`, `bankPolicyFk`)
|
INSERT INTO `vn`.`vehicle`(`id`, `numberPlate`, `tradeMark`, `model`, `companyFk`, `warehouseFk`, `description`, `m3`, `isActive`, `deliveryPointFk`, `chassis`, `leasing`, `supplierFk`, `fuelTypeFk`, `bankPolicyFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1302,9 +1304,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 +1618,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 +1961,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 +1980,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 +3067,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
|
||||||
|
@ -4145,3 +4150,6 @@ INSERT IGNORE INTO vn.vehicleType (id, name)
|
||||||
|
|
||||||
INSERT INTO edi.tableMultiConfig (fileName, toTable, file, `method`, updated)
|
INSERT INTO edi.tableMultiConfig (fileName, toTable, file, `method`, updated)
|
||||||
VALUES ('FG', 'genus', 'florecompc2', 'VBN/Genus', '2001-01-01');
|
VALUES ('FG', 'genus', 'florecompc2', 'VBN/Genus', '2001-01-01');
|
||||||
|
|
||||||
|
INSERT INTO vn.addressWaste (addressFk, type)
|
||||||
|
VALUES (11, 'fault');
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` EVENT `stock`.`log_clean`
|
|
||||||
ON SCHEDULE EVERY 1 DAY
|
|
||||||
STARTS '2022-01-28 09:29:18.000'
|
|
||||||
ON COMPLETION PRESERVE
|
|
||||||
ENABLE
|
|
||||||
DO CALL log_clean$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,8 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` EVENT `stock`.`log_syncNoWait`
|
|
||||||
ON SCHEDULE EVERY 5 SECOND
|
|
||||||
STARTS '2017-06-27 17:15:02.000'
|
|
||||||
ON COMPLETION NOT PRESERVE
|
|
||||||
DISABLE
|
|
||||||
DO CALL log_syncNoWait$$
|
|
||||||
DELIMITER ;
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` EVENT `stock`.`stock_clean`
|
||||||
|
ON SCHEDULE EVERY 60 SECOND
|
||||||
|
STARTS '2025-01-01 00:00:00.000'
|
||||||
|
ON COMPLETION PRESERVE
|
||||||
|
ENABLE
|
||||||
|
DO CALL stock_clean$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,8 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` EVENT `stock`.`stock_sync`
|
||||||
|
ON SCHEDULE EVERY 5 SECOND
|
||||||
|
STARTS '2025-01-01 00:00:00.000'
|
||||||
|
ON COMPLETION PRESERVE
|
||||||
|
DISABLE
|
||||||
|
DO CALL stock_sync$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,91 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyLot_refresh`(
|
||||||
|
`vTable` ENUM('lot', 'entry', 'travel'),
|
||||||
|
`vId` INT)
|
||||||
|
BEGIN
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK;
|
||||||
|
RESIGNAL;
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE tBuyAlive
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT
|
||||||
|
t.id travelFk,
|
||||||
|
t.landed,
|
||||||
|
t.landingHour,
|
||||||
|
t.warehouseInFk,
|
||||||
|
t.isReceived,
|
||||||
|
t.isRaid,
|
||||||
|
e.id entryFk,
|
||||||
|
b.lotFk,
|
||||||
|
b.itemFk,
|
||||||
|
b.life,
|
||||||
|
b.quantity
|
||||||
|
FROM tLotStatus ls
|
||||||
|
JOIN vn.buy b ON b.lotFk = ls.lotFk
|
||||||
|
JOIN vn.entry e ON e.id = b.entryFk
|
||||||
|
JOIN vn.travel t ON t.id = e.travelFk
|
||||||
|
WHERE ls.isIncluded;
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
|
-- Delete excluded/deleted/dead lots
|
||||||
|
|
||||||
|
DELETE l FROM buyLot l
|
||||||
|
JOIN tLotStatus ls USING(lotFk)
|
||||||
|
WHERE NOT ls.isIncluded;
|
||||||
|
|
||||||
|
-- Delete undead lot picks
|
||||||
|
|
||||||
|
UPDATE buyOut o
|
||||||
|
JOIN buyPick p ON p.outFk = o.outFk
|
||||||
|
JOIN tLotStatus ls ON ls.lotFk = p.lotFk
|
||||||
|
SET o.isSync = FALSE,
|
||||||
|
o.lack = o.lack + p.quantity
|
||||||
|
WHERE ls.isExcluded OR ls.isIncluded;
|
||||||
|
|
||||||
|
DELETE p FROM buyPick p
|
||||||
|
JOIN tLotStatus ls USING(lotFk)
|
||||||
|
WHERE ls.isExcluded OR ls.isIncluded;
|
||||||
|
|
||||||
|
-- Update alive outs
|
||||||
|
|
||||||
|
INSERT INTO buyLot (
|
||||||
|
lotFk,
|
||||||
|
isSync,
|
||||||
|
isPicked,
|
||||||
|
warehouseFk,
|
||||||
|
itemFk,
|
||||||
|
dated,
|
||||||
|
expired,
|
||||||
|
quantity,
|
||||||
|
available
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
lotFk,
|
||||||
|
FALSE,
|
||||||
|
isReceived,
|
||||||
|
warehouseInFk,
|
||||||
|
itemFk,
|
||||||
|
@dated := ADDTIME(landed, IFNULL(landingHour, '00:00:00')),
|
||||||
|
@dated + INTERVAL life DAY,
|
||||||
|
quantity,
|
||||||
|
NULL
|
||||||
|
FROM tBuyAlive
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
isSync = VALUES(isSync),
|
||||||
|
isPicked = VALUES(isPicked),
|
||||||
|
warehouseFk = VALUES(warehouseFk),
|
||||||
|
itemFk = VALUES(itemFk),
|
||||||
|
dated = VALUES(dated),
|
||||||
|
expired = VALUES(expired),
|
||||||
|
quantity = VALUES(quantity),
|
||||||
|
available = VALUES(available);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE tBuyAlive;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,64 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyLot_requestQuantity`(
|
||||||
|
vSelf INT,
|
||||||
|
vRequested INT,
|
||||||
|
vDated DATETIME,
|
||||||
|
vOutFk INT,
|
||||||
|
OUT vSupplied INT)
|
||||||
|
BEGIN
|
||||||
|
/**
|
||||||
|
* Disassociates lot picks after the given date until the demanded quantity is
|
||||||
|
* satisfied.
|
||||||
|
*
|
||||||
|
* @param vSelf The buyLot reference
|
||||||
|
* @param vRequested The requested quantity
|
||||||
|
* @param vDate The starting date for the associated outs
|
||||||
|
* @param vOutFk The if of requesting out
|
||||||
|
* @param vSupplied The supplied quantity
|
||||||
|
*/
|
||||||
|
DECLARE vPickFk INT;
|
||||||
|
DECLARE vPickOutFk INT;
|
||||||
|
DECLARE vPickQuantity INT;
|
||||||
|
DECLARE vPickGranted INT;
|
||||||
|
DECLARE vDone BOOL;
|
||||||
|
|
||||||
|
DECLARE vPicks CURSOR FOR
|
||||||
|
SELECT p.id, o.outFk, p.quantity
|
||||||
|
FROM buyPick p
|
||||||
|
JOIN buyOut o USING(outFk)
|
||||||
|
WHERE p.lotFk = vSelf
|
||||||
|
AND (o.dated, o.outFk) > (vDated, vOutFk)
|
||||||
|
ORDER BY o.dated DESC, o.created DESC, o.outFk DESC;
|
||||||
|
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
||||||
|
SET vDone = TRUE;
|
||||||
|
|
||||||
|
SET vSupplied = 0;
|
||||||
|
|
||||||
|
OPEN vPicks;
|
||||||
|
|
||||||
|
myLoop: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vPicks INTO vPickFk, vPickOutFk, vPickQuantity;
|
||||||
|
|
||||||
|
IF vDone THEN
|
||||||
|
LEAVE myLoop;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SET vPickGranted = LEAST(vRequested - vSupplied, vPickQuantity);
|
||||||
|
SET vSupplied = vSupplied + vPickGranted;
|
||||||
|
CALL buyPick_remove(vPickFk, vPickGranted, vPickQuantity);
|
||||||
|
|
||||||
|
UPDATE buyOut
|
||||||
|
SET isSync = FALSE,
|
||||||
|
lack = lack + vPickGranted
|
||||||
|
WHERE outFk = vPickOutFk;
|
||||||
|
|
||||||
|
IF vSupplied >= vRequested THEN
|
||||||
|
LEAVE myLoop;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
CLOSE vPicks;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -1,10 +1,10 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`inbound_sync`(vSelf INT)
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyLot_sync`(vSelf INT)
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
* Associates a inbound with their possible outbounds, updating it's available.
|
* Associates a lot with their possible outs, updating it's available.
|
||||||
*
|
*
|
||||||
* @param vSelf The inbound identifier
|
* @param vSelf The lot id
|
||||||
*/
|
*/
|
||||||
DECLARE vDated DATETIME;
|
DECLARE vDated DATETIME;
|
||||||
DECLARE vExpired DATETIME;
|
DECLARE vExpired DATETIME;
|
||||||
|
@ -14,37 +14,37 @@ BEGIN
|
||||||
DECLARE vAvailable INT;
|
DECLARE vAvailable INT;
|
||||||
DECLARE vSupplied INT;
|
DECLARE vSupplied INT;
|
||||||
DECLARE vSuppliedFromRequest INT;
|
DECLARE vSuppliedFromRequest INT;
|
||||||
DECLARE vOutboundFk INT;
|
DECLARE vOutFk INT;
|
||||||
DECLARE vLack INT;
|
DECLARE vLack INT;
|
||||||
DECLARE vHasPicks BOOL;
|
DECLARE vHasPicks BOOL;
|
||||||
DECLARE vDone BOOL;
|
DECLARE vDone BOOL;
|
||||||
|
|
||||||
DECLARE vOutbounds CURSOR FOR
|
DECLARE vOuts CURSOR FOR
|
||||||
SELECT id, lack, lack < quantity
|
SELECT outFk, lack, lack < quantity
|
||||||
FROM outbound
|
FROM buyOut
|
||||||
WHERE warehouseFk = vWarehouse
|
WHERE warehouseFk = vWarehouse
|
||||||
AND itemFk = vItem
|
AND itemFk = vItem
|
||||||
AND dated >= vDated
|
AND dated >= vDated
|
||||||
AND (vExpired IS NULL OR dated < vExpired)
|
AND (vExpired IS NULL OR dated < vExpired)
|
||||||
ORDER BY dated, created;
|
ORDER BY dated, created, outFk;
|
||||||
|
|
||||||
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
||||||
SET vDone = TRUE;
|
SET vDone = TRUE;
|
||||||
|
|
||||||
SELECT warehouseFk, itemFk, available, quantity, expired, dated
|
SELECT warehouseFk, itemFk, available, quantity, expired, dated
|
||||||
INTO vWarehouse, vItem, vAvailable, vQuantity, vExpired, vDated
|
INTO vWarehouse, vItem, vAvailable, vQuantity, vExpired, vDated
|
||||||
FROM inbound
|
FROM buyLot
|
||||||
WHERE id = vSelf;
|
WHERE lotFk = vSelf;
|
||||||
|
|
||||||
IF vAvailable IS NULL THEN
|
IF vAvailable IS NULL THEN
|
||||||
SET vAvailable = vQuantity;
|
SET vAvailable = vQuantity;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
OPEN vOutbounds;
|
OPEN vOuts;
|
||||||
|
|
||||||
myLoop: LOOP
|
myLoop: LOOP
|
||||||
SET vDone = FALSE;
|
SET vDone = FALSE;
|
||||||
FETCH vOutbounds INTO vOutboundFk, vLack, vHasPicks;
|
FETCH vOuts INTO vOutFk, vLack, vHasPicks;
|
||||||
|
|
||||||
IF vDone THEN
|
IF vDone THEN
|
||||||
LEAVE myLoop;
|
LEAVE myLoop;
|
||||||
|
@ -54,19 +54,19 @@ BEGIN
|
||||||
|
|
||||||
IF vSupplied > 0 THEN
|
IF vSupplied > 0 THEN
|
||||||
SET vAvailable = vAvailable - vSupplied;
|
SET vAvailable = vAvailable - vSupplied;
|
||||||
UPDATE outbound
|
UPDATE buyOut
|
||||||
SET lack = lack - vSupplied
|
SET lack = lack - vSupplied
|
||||||
WHERE id = vOutboundFk;
|
WHERE outFk = vOutFk;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF vHasPicks AND vAvailable > 0 THEN
|
IF vHasPicks AND vAvailable > 0 THEN
|
||||||
CALL outbound_requestQuantity(vOutboundFk, vAvailable, vDated, vSuppliedFromRequest);
|
CALL buyOut_requestQuantity(vOutFk, vAvailable, vDated, vSelf, vSuppliedFromRequest);
|
||||||
SET vSupplied = vSupplied + vSuppliedFromRequest;
|
SET vSupplied = vSupplied + vSuppliedFromRequest;
|
||||||
SET vAvailable = vAvailable - vSuppliedFromRequest;
|
SET vAvailable = vAvailable - vSuppliedFromRequest;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF vSupplied > 0 THEN
|
IF vSupplied > 0 THEN
|
||||||
CALL inbound_addPick(vSelf, vOutboundFk, vSupplied);
|
CALL buyPick_add(vSelf, vOutFk, vSupplied);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF vAvailable <= 0 THEN
|
IF vAvailable <= 0 THEN
|
||||||
|
@ -74,11 +74,11 @@ BEGIN
|
||||||
END IF;
|
END IF;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
CLOSE vOutbounds;
|
CLOSE vOuts;
|
||||||
|
|
||||||
UPDATE inbound
|
UPDATE buyLot
|
||||||
SET isSync = TRUE,
|
SET isSync = TRUE,
|
||||||
available = vAvailable
|
available = vAvailable
|
||||||
WHERE id = vSelf;
|
WHERE lotFk = vSelf;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
|
@ -0,0 +1,95 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyOut_refresh`(
|
||||||
|
`vTable` VARCHAR(255),
|
||||||
|
`vId` INT,
|
||||||
|
`vSource` VARCHAR(255))
|
||||||
|
BEGIN
|
||||||
|
/**
|
||||||
|
* This procedure contains the common code used to refresh the out lot cache.
|
||||||
|
*
|
||||||
|
* @param vTable The id source table
|
||||||
|
* @param vId The lot id
|
||||||
|
* @param vSource The lot source
|
||||||
|
* @table tLotStatus Lots to modify
|
||||||
|
* @table tLotAlive Updated/Created alive lots data
|
||||||
|
*/
|
||||||
|
DECLARE vHasLots BOOL;
|
||||||
|
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK;
|
||||||
|
RESIGNAL;
|
||||||
|
END;
|
||||||
|
|
||||||
|
IF vTable = 'lot' THEN
|
||||||
|
SELECT COUNT(*) > 0 INTO vHasLots FROM tLotStatus;
|
||||||
|
|
||||||
|
IF NOT vHasLots THEN
|
||||||
|
INSERT INTO tLotStatus
|
||||||
|
SET lotFk = vId,
|
||||||
|
isExcluded = TRUE,
|
||||||
|
isIncluded = FALSE;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
|
-- Delete excluded/deleted/dead outs
|
||||||
|
|
||||||
|
DELETE o FROM buyOut o
|
||||||
|
JOIN tLotStatus ls ON ls.lotFk = o.outFk
|
||||||
|
WHERE NOT ls.isIncluded;
|
||||||
|
|
||||||
|
-- Delete undead out picks
|
||||||
|
|
||||||
|
UPDATE buyLot l
|
||||||
|
JOIN buyPick p ON p.lotFk = l.lotFk
|
||||||
|
JOIN tLotStatus ls ON ls.lotFk = p.outFk
|
||||||
|
SET l.isSync = FALSE,
|
||||||
|
l.available = l.available + p.quantity
|
||||||
|
WHERE ls.isExcluded OR ls.isIncluded;
|
||||||
|
|
||||||
|
DELETE p FROM buyPick p
|
||||||
|
JOIN tLotStatus ls ON ls.lotFk = p.outFk
|
||||||
|
WHERE ls.isExcluded OR ls.isIncluded;
|
||||||
|
|
||||||
|
-- Update alive outs
|
||||||
|
|
||||||
|
INSERT INTO buyOut (
|
||||||
|
outFk,
|
||||||
|
source,
|
||||||
|
isSync,
|
||||||
|
warehouseFk,
|
||||||
|
dated,
|
||||||
|
itemFk,
|
||||||
|
quantity,
|
||||||
|
lack,
|
||||||
|
created,
|
||||||
|
isPicked
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
lotFk,
|
||||||
|
vSource,
|
||||||
|
FALSE,
|
||||||
|
warehouseFk,
|
||||||
|
dated,
|
||||||
|
itemFk,
|
||||||
|
quantity,
|
||||||
|
quantity,
|
||||||
|
created,
|
||||||
|
isPicked
|
||||||
|
FROM tLotAlive
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
source = VALUES(source),
|
||||||
|
warehouseFk = VALUES(warehouseFk),
|
||||||
|
dated = VALUES(dated),
|
||||||
|
itemFk = VALUES(itemFk),
|
||||||
|
quantity = VALUES(quantity),
|
||||||
|
lack = VALUES(lack),
|
||||||
|
created = VALUES(created),
|
||||||
|
isPicked = VALUES(isPicked),
|
||||||
|
isSync = VALUES(isSync);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,39 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyOut_refreshBuy`(
|
||||||
|
`vTable` VARCHAR(255),
|
||||||
|
`vId` INT)
|
||||||
|
BEGIN
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE tLotStatus
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT lotFk,
|
||||||
|
@isExcluded := b.quantity <= 0 isExcluded,
|
||||||
|
NOT @isExcluded AND b.isAlive isIncluded
|
||||||
|
FROM vn.buy b
|
||||||
|
JOIN vn.entry e ON e.id = b.entryFk
|
||||||
|
WHERE
|
||||||
|
(vTable = 'lot' AND b.lotFk = vId)
|
||||||
|
OR (vTable = 'entry' AND e.id = vId)
|
||||||
|
OR (vTable = 'travel' AND e.travelFk = vId);
|
||||||
|
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE tLotAlive
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT
|
||||||
|
ls.lotFk,
|
||||||
|
t.warehouseOutFk warehouseFk,
|
||||||
|
ADDTIME(t.shipped, IFNULL(shipmentHour, '00:00:00')) dated,
|
||||||
|
t.isDelivered isPicked,
|
||||||
|
b.itemFk,
|
||||||
|
b.quantity,
|
||||||
|
b.created
|
||||||
|
FROM tLotStatus ls
|
||||||
|
JOIN vn.buy b ON b.lotFk = ls.lotFk
|
||||||
|
JOIN vn.entry e ON e.id = b.entryFk
|
||||||
|
JOIN vn.travel t ON t.id = e.travelFk
|
||||||
|
WHERE ls.isIncluded;
|
||||||
|
|
||||||
|
CALL buyOut_refresh(vTable, vId, 'buy');
|
||||||
|
CALL buyLot_refresh(vTable, vId);
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE tLotStatus, tLotAlive;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,36 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyOut_refreshOrder`(
|
||||||
|
`vTable` VARCHAR(255),
|
||||||
|
`vId` INT)
|
||||||
|
BEGIN
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE tLotStatus
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT lotFk,
|
||||||
|
@isExcluded := o.confirmed OR NOT isReserved OR r.amount <= 0 isExcluded,
|
||||||
|
NOT @isExcluded isIncluded
|
||||||
|
FROM hedera.orderRow r
|
||||||
|
JOIN hedera.`order` o ON o.id = r.orderFk
|
||||||
|
WHERE
|
||||||
|
(vTable = 'lot' AND r.lotFk = vId)
|
||||||
|
OR (vTable = 'order' AND o.id = vId);
|
||||||
|
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE tLotAlive
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT
|
||||||
|
ls.lotFk,
|
||||||
|
r.warehouseFk,
|
||||||
|
r.shipment dated,
|
||||||
|
r.itemFk,
|
||||||
|
r.amount quantity,
|
||||||
|
r.created,
|
||||||
|
FALSE isPicked
|
||||||
|
FROM tLotStatus ls
|
||||||
|
JOIN hedera.orderRow r ON r.lotFk = ls.lotFk
|
||||||
|
JOIN hedera.`order` o ON o.id = r.orderFk
|
||||||
|
WHERE ls.isIncluded;
|
||||||
|
|
||||||
|
CALL buyOut_refresh(vTable, vId, 'orderRow');
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE tLotStatus, tLotAlive;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,42 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyOut_refreshSale`(
|
||||||
|
`vTable` VARCHAR(255),
|
||||||
|
`vId` INT)
|
||||||
|
BEGIN
|
||||||
|
DECLARE vAliveDate DATE;
|
||||||
|
|
||||||
|
SELECT util.VN_CURDATE() - INTERVAL saleLife MONTH
|
||||||
|
INTO vAliveDate
|
||||||
|
FROM config LIMIT 1;
|
||||||
|
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE tLotStatus
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT lotFk,
|
||||||
|
@isExcluded := s.quantity < 0 isExcluded,
|
||||||
|
NOT @isExcluded AND t.isAlive isIncluded
|
||||||
|
FROM vn.sale s
|
||||||
|
JOIN vn.ticket t ON t.id = s.ticketFk
|
||||||
|
WHERE
|
||||||
|
(vTable = 'lot' AND s.lotFk = vId)
|
||||||
|
OR (vTable = 'ticket' AND t.id = vId);
|
||||||
|
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE tLotAlive
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT
|
||||||
|
ls.lotFk,
|
||||||
|
t.warehouseFk,
|
||||||
|
t.shipped dated,
|
||||||
|
s.itemFk,
|
||||||
|
s.quantity,
|
||||||
|
s.created,
|
||||||
|
s.isPicked
|
||||||
|
FROM tLotStatus ls
|
||||||
|
JOIN vn.sale s ON s.lotFk = ls.lotFk
|
||||||
|
JOIN vn.ticket t ON t.id = s.ticketFk
|
||||||
|
WHERE ls.isIncluded;
|
||||||
|
|
||||||
|
CALL buyOut_refresh(vTable, vId, 'sale');
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE tLotStatus, tLotAlive;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,64 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyOut_requestQuantity`(
|
||||||
|
vSelf INT,
|
||||||
|
vRequested INT,
|
||||||
|
vDated DATETIME,
|
||||||
|
vLotFk INT,
|
||||||
|
OUT vSupplied INT)
|
||||||
|
BEGIN
|
||||||
|
/**
|
||||||
|
* Disassociates out picks after the given date until the demanded quantity is
|
||||||
|
* satisfied.
|
||||||
|
*
|
||||||
|
* @param vSelf The buyOut reference
|
||||||
|
* @param vRequested The requested quantity
|
||||||
|
* @param vDate The starting date for the associated lots
|
||||||
|
* @param vLotFk The if of requesting lot
|
||||||
|
* @param vSupplied The supplied quantity
|
||||||
|
*/
|
||||||
|
DECLARE vPickFk INT;
|
||||||
|
DECLARE vPickLotFk INT;
|
||||||
|
DECLARE vPickQuantity INT;
|
||||||
|
DECLARE vPickGranted INT;
|
||||||
|
DECLARE vDone BOOL;
|
||||||
|
|
||||||
|
DECLARE vPicks CURSOR FOR
|
||||||
|
SELECT p.id, p.lotFk, p.quantity
|
||||||
|
FROM buyPick p
|
||||||
|
JOIN buyLot l USING(lotFk)
|
||||||
|
WHERE p.outFk = vSelf
|
||||||
|
AND (l.dated, p.lotFk) > (vDated, vLotFk)
|
||||||
|
ORDER BY l.dated, p.lotFk;
|
||||||
|
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
||||||
|
SET vDone = TRUE;
|
||||||
|
|
||||||
|
SET vSupplied = 0;
|
||||||
|
|
||||||
|
OPEN vPicks;
|
||||||
|
|
||||||
|
myLoop: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vPicks INTO vPickFk, vPickLotFk, vPickQuantity;
|
||||||
|
|
||||||
|
IF vDone THEN
|
||||||
|
LEAVE myLoop;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SET vPickGranted = LEAST(vRequested - vSupplied, vPickQuantity);
|
||||||
|
SET vSupplied = vSupplied + vPickGranted;
|
||||||
|
CALL buyPick_remove(vPickFk, vPickGranted, vPickQuantity);
|
||||||
|
|
||||||
|
UPDATE buyLot
|
||||||
|
SET isSync = FALSE,
|
||||||
|
available = available + vPickGranted
|
||||||
|
WHERE lotFk = vPickLotFk;
|
||||||
|
|
||||||
|
IF vSupplied >= vRequested THEN
|
||||||
|
LEAVE myLoop;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
CLOSE vPicks;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -1,10 +1,10 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`outbound_sync`(vSelf INT)
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyOut_sync`(vSelf INT)
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
* Attaches a outbound with available inbounds.
|
* Attaches an out with available lots.
|
||||||
*
|
*
|
||||||
* @param vSelf The outbound reference
|
* @param vSelf The buyOut reference
|
||||||
*/
|
*/
|
||||||
DECLARE vDated DATETIME;
|
DECLARE vDated DATETIME;
|
||||||
DECLARE vItem INT;
|
DECLARE vItem INT;
|
||||||
|
@ -12,33 +12,33 @@ BEGIN
|
||||||
DECLARE vLack INT;
|
DECLARE vLack INT;
|
||||||
DECLARE vSupplied INT;
|
DECLARE vSupplied INT;
|
||||||
DECLARE vSuppliedFromRequest INT;
|
DECLARE vSuppliedFromRequest INT;
|
||||||
DECLARE vInboundFk INT;
|
DECLARE vLotFk INT;
|
||||||
DECLARE vAvailable INT;
|
DECLARE vAvailable INT;
|
||||||
DECLARE vHasPicks BOOL;
|
DECLARE vHasPicks BOOL;
|
||||||
DECLARE vDone BOOL;
|
DECLARE vDone BOOL;
|
||||||
|
|
||||||
DECLARE vInbounds CURSOR FOR
|
DECLARE vBuyLots CURSOR FOR
|
||||||
SELECT id, available, available < quantity
|
SELECT lotFk, available, available < quantity
|
||||||
FROM inbound
|
FROM buyLot
|
||||||
WHERE warehouseFk = vWarehouse
|
WHERE warehouseFk = vWarehouse
|
||||||
AND itemFk = vItem
|
AND itemFk = vItem
|
||||||
AND dated <= vDated
|
AND dated <= vDated
|
||||||
AND (expired IS NULL OR expired > vDated)
|
AND (expired IS NULL OR expired > vDated)
|
||||||
ORDER BY dated;
|
ORDER BY dated, lotFk;
|
||||||
|
|
||||||
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
||||||
SET vDone = TRUE;
|
SET vDone = TRUE;
|
||||||
|
|
||||||
SELECT warehouseFk, itemFk, dated, lack
|
SELECT warehouseFk, itemFk, dated, lack
|
||||||
INTO vWarehouse, vItem, vDated, vLack
|
INTO vWarehouse, vItem, vDated, vLack
|
||||||
FROM outbound
|
FROM buyOut
|
||||||
WHERE id = vSelf;
|
WHERE outFk = vSelf;
|
||||||
|
|
||||||
OPEN vInbounds;
|
OPEN vBuyLots;
|
||||||
|
|
||||||
myLoop: LOOP
|
myLoop: LOOP
|
||||||
SET vDone = FALSE;
|
SET vDone = FALSE;
|
||||||
FETCH vInbounds INTO vInboundFk, vAvailable, vHasPicks;
|
FETCH vBuyLots INTO vLotFk, vAvailable, vHasPicks;
|
||||||
|
|
||||||
IF vDone THEN
|
IF vDone THEN
|
||||||
LEAVE myLoop;
|
LEAVE myLoop;
|
||||||
|
@ -48,19 +48,19 @@ BEGIN
|
||||||
|
|
||||||
IF vSupplied > 0 THEN
|
IF vSupplied > 0 THEN
|
||||||
SET vLack = vLack - vSupplied;
|
SET vLack = vLack - vSupplied;
|
||||||
UPDATE inbound
|
UPDATE buyLot
|
||||||
SET available = available - vSupplied
|
SET available = available - vSupplied
|
||||||
WHERE id = vInboundFk;
|
WHERE lotFk = vLotFk;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF vHasPicks AND vLack > 0 THEN
|
IF vHasPicks AND vLack > 0 THEN
|
||||||
CALL inbound_requestQuantity(vInboundFk, vLack, vDated, vSuppliedFromRequest);
|
CALL buyLot_requestQuantity(vLotFk, vLack, vDated, vSelf, vSuppliedFromRequest);
|
||||||
SET vSupplied = vSupplied + vSuppliedFromRequest;
|
SET vSupplied = vSupplied + vSuppliedFromRequest;
|
||||||
SET vLack = vLack - vSuppliedFromRequest;
|
SET vLack = vLack - vSuppliedFromRequest;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF vSupplied > 0 THEN
|
IF vSupplied > 0 THEN
|
||||||
CALL inbound_addPick(vInboundFk, vSelf, vSupplied);
|
CALL buyPick_add(vLotFk, vSelf, vSupplied);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF vLack = 0 THEN
|
IF vLack = 0 THEN
|
||||||
|
@ -68,11 +68,11 @@ BEGIN
|
||||||
END IF;
|
END IF;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
CLOSE vInbounds;
|
CLOSE vBuyLots;
|
||||||
|
|
||||||
UPDATE outbound
|
UPDATE buyOut
|
||||||
SET isSync = TRUE,
|
SET isSync = TRUE,
|
||||||
lack = vLack
|
lack = vLack
|
||||||
WHERE id = vSelf;
|
WHERE outFk = vSelf;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
|
@ -0,0 +1,15 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyPick_add`(
|
||||||
|
vLotFk INT,
|
||||||
|
vOutFk INT,
|
||||||
|
vQuantity INT
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO buyPick
|
||||||
|
SET lotFk = vLotFk,
|
||||||
|
outFk = vOutFk,
|
||||||
|
quantity = vQuantity
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
quantity = quantity + vQuantity;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,17 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`buyPick_remove`(
|
||||||
|
vSelf INT,
|
||||||
|
vQuantity INT,
|
||||||
|
vTotalQuantity INT
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
IF vQuantity < vTotalQuantity THEN
|
||||||
|
UPDATE buyPick
|
||||||
|
SET quantity = quantity - vQuantity
|
||||||
|
WHERE id = vSelf;
|
||||||
|
ELSE
|
||||||
|
DELETE FROM buyPick
|
||||||
|
WHERE id = vSelf;
|
||||||
|
END IF;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -1,16 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`inbound_addPick`(
|
|
||||||
vSelf INT,
|
|
||||||
vOutboundFk INT,
|
|
||||||
vQuantity INT
|
|
||||||
)
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO inboundPick
|
|
||||||
SET
|
|
||||||
inboundFk = vSelf,
|
|
||||||
outboundFk = vOutboundFk,
|
|
||||||
quantity = vQuantity
|
|
||||||
ON DUPLICATE KEY UPDATE
|
|
||||||
quantity = quantity + vQuantity;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,20 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`inbound_removePick`(
|
|
||||||
vSelf INT,
|
|
||||||
vOutboundFk INT,
|
|
||||||
vQuantity INT,
|
|
||||||
vTotalQuantity INT
|
|
||||||
)
|
|
||||||
BEGIN
|
|
||||||
IF vQuantity < vTotalQuantity THEN
|
|
||||||
UPDATE inboundPick
|
|
||||||
SET quantity = quantity - vQuantity
|
|
||||||
WHERE inboundFk = vSelf
|
|
||||||
AND outboundFk = vOutboundFk;
|
|
||||||
ELSE
|
|
||||||
DELETE FROM inboundPick
|
|
||||||
WHERE inboundFk = vSelf
|
|
||||||
AND outboundFk = vOutboundFk;
|
|
||||||
END IF;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,61 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`inbound_requestQuantity`(
|
|
||||||
vSelf INT,
|
|
||||||
vRequested INT,
|
|
||||||
vDated DATETIME,
|
|
||||||
OUT vSupplied INT)
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Disassociates inbound picks after the given date until the
|
|
||||||
* demanded quantity is satisfied.
|
|
||||||
*
|
|
||||||
* @param vSelf The inbound reference
|
|
||||||
* @param vRequested The requested quantity
|
|
||||||
* @param vDate The starting date for the associated outbounds
|
|
||||||
* @param vSupplied The supplied quantity
|
|
||||||
*/
|
|
||||||
DECLARE vOutboundFk INT;
|
|
||||||
DECLARE vPickQuantity INT;
|
|
||||||
DECLARE vPickGranted INT;
|
|
||||||
DECLARE vDone BOOL;
|
|
||||||
|
|
||||||
DECLARE vPicks CURSOR FOR
|
|
||||||
SELECT p.outboundFk, p.quantity
|
|
||||||
FROM inboundPick p
|
|
||||||
JOIN outbound o ON o.id = p.outboundFk
|
|
||||||
WHERE p.inboundFk = vSelf
|
|
||||||
AND o.dated > vDated
|
|
||||||
ORDER BY o.dated DESC, o.created DESC;
|
|
||||||
|
|
||||||
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
|
||||||
SET vDone = TRUE;
|
|
||||||
|
|
||||||
SET vSupplied = 0;
|
|
||||||
|
|
||||||
OPEN vPicks;
|
|
||||||
|
|
||||||
myLoop: LOOP
|
|
||||||
SET vDone = FALSE;
|
|
||||||
FETCH vPicks INTO vOutboundFk, vPickQuantity;
|
|
||||||
|
|
||||||
IF vDone THEN
|
|
||||||
LEAVE myLoop;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
SET vPickGranted = LEAST(vRequested - vSupplied, vPickQuantity);
|
|
||||||
SET vSupplied = vSupplied + vPickGranted;
|
|
||||||
CALL inbound_removePick(vSelf, vOutboundFk, vPickGranted, vPickQuantity);
|
|
||||||
|
|
||||||
UPDATE outbound
|
|
||||||
SET isSync = FALSE,
|
|
||||||
lack = lack + vPickGranted
|
|
||||||
WHERE id = vOutboundFk;
|
|
||||||
|
|
||||||
IF vSupplied >= vRequested THEN
|
|
||||||
LEAVE myLoop;
|
|
||||||
END IF;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
CLOSE vPicks;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,7 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`log_clean`()
|
|
||||||
BEGIN
|
|
||||||
DELETE FROM inbound WHERE dated = vn.getInventoryDate();
|
|
||||||
DELETE FROM outbound WHERE dated = vn.getInventoryDate();
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,19 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`log_delete`(vTableName VARCHAR(255), vTableId INT)
|
|
||||||
proc: BEGIN
|
|
||||||
/**
|
|
||||||
* Processes orphan transactions.
|
|
||||||
*/
|
|
||||||
IF vTableName NOT IN ('buy', 'sale', 'orderRow') THEN
|
|
||||||
LEAVE proc;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
DELETE FROM inbound
|
|
||||||
WHERE tableName = vTableName COLLATE utf8_general_ci
|
|
||||||
AND tableId = vTableId;
|
|
||||||
|
|
||||||
DELETE FROM outbound
|
|
||||||
WHERE tableName = vTableName COLLATE utf8_general_ci
|
|
||||||
AND tableId = vTableId;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,33 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`log_refreshAll`()
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Recalculates the entire cache. It takes a considerable time,
|
|
||||||
* please avoid calls to this procedure from commonly used operations.
|
|
||||||
*/
|
|
||||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
|
||||||
BEGIN
|
|
||||||
DO RELEASE_LOCK('stock.log_sync');
|
|
||||||
RESIGNAL;
|
|
||||||
END;
|
|
||||||
|
|
||||||
IF !GET_LOCK('stock.log_sync', 30) THEN
|
|
||||||
CALL util.throw('Lock timeout exceeded');
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
TRUNCATE TABLE stock.`log`;
|
|
||||||
TRUNCATE TABLE stock.`inbound`;
|
|
||||||
TRUNCATE TABLE stock.`inboundPick`;
|
|
||||||
TRUNCATE TABLE stock.`outbound`;
|
|
||||||
TRUNCATE TABLE stock.`visible`;
|
|
||||||
|
|
||||||
CALL log_refreshSale(NULL, NULL);
|
|
||||||
CALL log_refreshBuy(NULL, NULL);
|
|
||||||
CALL log_refreshOrder(NULL, NULL);
|
|
||||||
|
|
||||||
UPDATE outbound SET isSync = TRUE;
|
|
||||||
CALL log_sync(TRUE);
|
|
||||||
|
|
||||||
DO RELEASE_LOCK('stock.log_sync');
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,73 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`log_refreshBuy`(
|
|
||||||
`vTableName` VARCHAR(255),
|
|
||||||
`vTableId` INT)
|
|
||||||
BEGIN
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tValues;
|
|
||||||
CREATE TEMPORARY TABLE tValues
|
|
||||||
ENGINE = MEMORY
|
|
||||||
SELECT b.id buyFk,
|
|
||||||
e.id entryFk,
|
|
||||||
t.id travelFk,
|
|
||||||
b.itemFk,
|
|
||||||
t.isRaid,
|
|
||||||
ADDTIME(t.shipped,
|
|
||||||
IFNULL(t.shipmentHour, '00:00:00')) shipped,
|
|
||||||
t.warehouseOutFk,
|
|
||||||
t.isDelivered,
|
|
||||||
ADDTIME(t.landed,
|
|
||||||
IFNULL(t.landingHour, '00:00:00')) landed,
|
|
||||||
t.warehouseInFk,
|
|
||||||
t.isReceived,
|
|
||||||
tp.life,
|
|
||||||
ABS(b.quantity) quantity,
|
|
||||||
b.created,
|
|
||||||
b.quantity > 0 isIn,
|
|
||||||
t.shipped < vn.getInventoryDate() lessThanInventory
|
|
||||||
FROM vn.buy b
|
|
||||||
JOIN vn.entry e ON e.id = b.entryFk
|
|
||||||
JOIN vn.travel t ON t.id = e.travelFk
|
|
||||||
JOIN vn.item i ON i.id = b.itemFk
|
|
||||||
JOIN vn.itemType tp ON tp.id = i.typeFk
|
|
||||||
WHERE (
|
|
||||||
vTableId IS NULL
|
|
||||||
OR (vTableName = 'travel' AND t.id = vTableId)
|
|
||||||
OR (vTableName = 'entry' AND e.id = vTableId)
|
|
||||||
OR (vTableName = 'buy' AND b.id = vTableId)
|
|
||||||
)
|
|
||||||
AND t.landed >= vn.getInventoryDate()
|
|
||||||
AND b.quantity != 0;
|
|
||||||
|
|
||||||
REPLACE INTO inbound (
|
|
||||||
tableName, tableId, warehouseFk, dated,
|
|
||||||
itemFk, expired, quantity, isPicked
|
|
||||||
)
|
|
||||||
SELECT 'buy',
|
|
||||||
buyFk,
|
|
||||||
IF(isIn, warehouseInFk, warehouseOutFk),
|
|
||||||
@dated := IF(isIn, landed, shipped),
|
|
||||||
itemFk,
|
|
||||||
TIMESTAMPADD(DAY, life, @dated),
|
|
||||||
quantity,
|
|
||||||
IF(isIn, isReceived, isDelivered) AND NOT isRaid
|
|
||||||
FROM tValues
|
|
||||||
WHERE isIn OR !lessThanInventory;
|
|
||||||
|
|
||||||
REPLACE INTO outbound (
|
|
||||||
tableName, tableId, warehouseFk, dated,
|
|
||||||
itemFk, created, quantity, isPicked
|
|
||||||
)
|
|
||||||
SELECT 'buy',
|
|
||||||
buyFk,
|
|
||||||
IF(isIn, warehouseOutFk, warehouseInFk),
|
|
||||||
IF(isIn, shipped, landed),
|
|
||||||
itemFk,
|
|
||||||
created,
|
|
||||||
quantity,
|
|
||||||
IF(isIn, isDelivered, isReceived) AND NOT isRaid
|
|
||||||
FROM tValues
|
|
||||||
WHERE !isIn OR !lessThanInventory;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tValues;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,47 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`log_refreshOrder`(
|
|
||||||
`vTableName` VARCHAR(255),
|
|
||||||
`vTableId` INT)
|
|
||||||
BEGIN
|
|
||||||
DECLARE vExpireTime INT DEFAULT 20;
|
|
||||||
DECLARE vExpired DATETIME DEFAULT TIMESTAMPADD(MINUTE, -vExpireTime, util.VN_NOW());
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tValues;
|
|
||||||
CREATE TEMPORARY TABLE tValues
|
|
||||||
ENGINE = MEMORY
|
|
||||||
SELECT
|
|
||||||
r.id rowFk,
|
|
||||||
r.itemFk,
|
|
||||||
r.warehouseFk,
|
|
||||||
r.shipment shipped,
|
|
||||||
r.amount quantity,
|
|
||||||
r.created
|
|
||||||
FROM hedera.orderRow r
|
|
||||||
JOIN hedera.`order` o ON o.id = r.orderFk
|
|
||||||
WHERE (
|
|
||||||
vTableId IS NULL
|
|
||||||
OR (vTableName = 'order' AND o.id = vTableId)
|
|
||||||
OR (vTableName = 'orderRow' AND r.id = vTableId)
|
|
||||||
)
|
|
||||||
AND !o.confirmed
|
|
||||||
AND r.shipment >= vn.getInventoryDate()
|
|
||||||
AND r.created >= vExpired
|
|
||||||
AND r.amount != 0;
|
|
||||||
|
|
||||||
REPLACE INTO outbound (
|
|
||||||
tableName, tableId, warehouseFk, dated,
|
|
||||||
itemFk, created, expired, quantity
|
|
||||||
)
|
|
||||||
SELECT 'orderRow',
|
|
||||||
rowFk,
|
|
||||||
warehouseFk,
|
|
||||||
shipped,
|
|
||||||
itemFk,
|
|
||||||
created,
|
|
||||||
TIMESTAMPADD(MINUTE, vExpireTime, created),
|
|
||||||
quantity
|
|
||||||
FROM tValues;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tValues;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,66 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`log_refreshSale`(
|
|
||||||
`vTableName` VARCHAR(255),
|
|
||||||
`vTableId` INT)
|
|
||||||
BEGIN
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tValues;
|
|
||||||
CREATE TEMPORARY TABLE tValues
|
|
||||||
ENGINE = MEMORY
|
|
||||||
SELECT
|
|
||||||
m.id saleFk,
|
|
||||||
m.ticketFk,
|
|
||||||
m.itemFk,
|
|
||||||
t.warehouseFk,
|
|
||||||
t.shipped,
|
|
||||||
ABS(m.quantity) quantity,
|
|
||||||
m.created,
|
|
||||||
TIMESTAMPADD(DAY, tp.life, t.shipped) expired,
|
|
||||||
m.quantity < 0 isIn,
|
|
||||||
m.isPicked OR s.alertLevel > al.id isPicked
|
|
||||||
FROM vn.sale m
|
|
||||||
JOIN vn.ticket t ON t.id = m.ticketFk
|
|
||||||
JOIN vn.ticketState s ON s.ticketFk = t.id
|
|
||||||
JOIN vn.item i ON i.id = m.itemFk
|
|
||||||
JOIN vn.itemType tp ON tp.id = i.typeFk
|
|
||||||
JOIN vn.alertLevel al ON al.code = 'ON_PREPARATION'
|
|
||||||
WHERE (
|
|
||||||
vTableId IS NULL
|
|
||||||
OR (vTableName = 'ticket' AND t.id = vTableId)
|
|
||||||
OR (vTableName = 'sale' AND m.id = vTableId)
|
|
||||||
)
|
|
||||||
AND t.shipped >= vn.getInventoryDate()
|
|
||||||
AND m.quantity != 0;
|
|
||||||
|
|
||||||
REPLACE INTO inbound (
|
|
||||||
tableName, tableId, warehouseFk, dated,
|
|
||||||
itemFk, expired, quantity, isPicked
|
|
||||||
)
|
|
||||||
SELECT 'sale',
|
|
||||||
saleFk,
|
|
||||||
warehouseFk,
|
|
||||||
shipped,
|
|
||||||
itemFk,
|
|
||||||
expired,
|
|
||||||
quantity,
|
|
||||||
isPicked
|
|
||||||
FROM tValues
|
|
||||||
WHERE isIn;
|
|
||||||
|
|
||||||
REPLACE INTO outbound (
|
|
||||||
tableName, tableId, warehouseFk, dated,
|
|
||||||
itemFk, created, quantity, isPicked
|
|
||||||
)
|
|
||||||
SELECT 'sale',
|
|
||||||
saleFk,
|
|
||||||
warehouseFk,
|
|
||||||
shipped,
|
|
||||||
itemFk,
|
|
||||||
created,
|
|
||||||
quantity,
|
|
||||||
isPicked
|
|
||||||
FROM tValues
|
|
||||||
WHERE !isIn;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tValues;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,123 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`log_sync`(vSync BOOL)
|
|
||||||
proc: BEGIN
|
|
||||||
DECLARE vDone BOOL;
|
|
||||||
DECLARE vLogId INT;
|
|
||||||
DECLARE vHasPendingSync BOOL;
|
|
||||||
DECLARE vOperation VARCHAR(255);
|
|
||||||
DECLARE vTableName VARCHAR(255);
|
|
||||||
DECLARE vTableId VARCHAR(255);
|
|
||||||
DECLARE vInboundFk INT;
|
|
||||||
DECLARE vOutboundFk INT;
|
|
||||||
|
|
||||||
DECLARE cInbound CURSOR FOR
|
|
||||||
SELECT id FROM inbound
|
|
||||||
WHERE !isSync
|
|
||||||
ORDER BY dated;
|
|
||||||
|
|
||||||
DECLARE cOutbound CURSOR FOR
|
|
||||||
SELECT id FROM outbound
|
|
||||||
WHERE !isSync
|
|
||||||
ORDER BY dated;
|
|
||||||
|
|
||||||
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
|
||||||
SET vDone = TRUE;
|
|
||||||
|
|
||||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
|
||||||
BEGIN
|
|
||||||
ROLLBACK;
|
|
||||||
RESIGNAL;
|
|
||||||
END;
|
|
||||||
|
|
||||||
-- Applies changes
|
|
||||||
|
|
||||||
opsLoop: LOOP
|
|
||||||
START TRANSACTION;
|
|
||||||
|
|
||||||
SET vDone = FALSE;
|
|
||||||
SELECT id, operation, tableName, tableId
|
|
||||||
INTO vLogId, vOperation, vTableName, vTableId
|
|
||||||
FROM `log`
|
|
||||||
ORDER BY id LIMIT 1
|
|
||||||
FOR UPDATE;
|
|
||||||
|
|
||||||
IF vDone THEN
|
|
||||||
COMMIT;
|
|
||||||
LEAVE opsLoop;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
CALL log_delete(vTableName, vTableId);
|
|
||||||
|
|
||||||
IF vOperation = 'insert' THEN
|
|
||||||
IF vTableName IN ('travel', 'entry', 'buy') THEN
|
|
||||||
CALL log_refreshBuy(vTableName, vTableId);
|
|
||||||
ELSEIF vTableName IN ('ticket', 'sale') THEN
|
|
||||||
CALL log_refreshSale(vTableName, vTableId);
|
|
||||||
ELSEIF vTableName IN ('order', 'orderRow') THEN
|
|
||||||
CALL log_refreshOrder(vTableName, vTableId);
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
DELETE FROM `log` WHERE id = vLogId;
|
|
||||||
SET vSync = TRUE;
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
IF !vSync THEN
|
|
||||||
LEAVE proc;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Deletes expired outbounds
|
|
||||||
|
|
||||||
DELETE FROM outbound WHERE expired <= util.VN_NOW();
|
|
||||||
|
|
||||||
-- Attaches desync inbounds
|
|
||||||
|
|
||||||
REPEAT
|
|
||||||
OPEN cInbound;
|
|
||||||
SET vHasPendingSync = FALSE;
|
|
||||||
|
|
||||||
inboundLoop: LOOP
|
|
||||||
SET vDone = FALSE;
|
|
||||||
FETCH cInbound INTO vInboundFk;
|
|
||||||
|
|
||||||
IF vDone THEN
|
|
||||||
LEAVE inboundLoop;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
START TRANSACTION;
|
|
||||||
CALL inbound_sync(vInboundFk);
|
|
||||||
COMMIT;
|
|
||||||
|
|
||||||
SET vHasPendingSync = TRUE;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
CLOSE cInbound;
|
|
||||||
UNTIL !vHasPendingSync END REPEAT;
|
|
||||||
|
|
||||||
-- Attaches desync outbounds
|
|
||||||
|
|
||||||
REPEAT
|
|
||||||
OPEN cOutbound;
|
|
||||||
SET vHasPendingSync = FALSE;
|
|
||||||
|
|
||||||
outboundLoop: LOOP
|
|
||||||
SET vDone = FALSE;
|
|
||||||
FETCH cOutbound INTO vOutboundFk;
|
|
||||||
|
|
||||||
IF vDone THEN
|
|
||||||
LEAVE outboundLoop;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
START TRANSACTION;
|
|
||||||
CALL outbound_sync(vOutboundFk);
|
|
||||||
COMMIT;
|
|
||||||
|
|
||||||
SET vHasPendingSync = TRUE;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
CLOSE cOutbound;
|
|
||||||
UNTIL !vHasPendingSync END REPEAT;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,16 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`log_syncNoWait`()
|
|
||||||
BEGIN
|
|
||||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
|
||||||
BEGIN
|
|
||||||
DO RELEASE_LOCK('stock.log_sync');
|
|
||||||
RESIGNAL;
|
|
||||||
END;
|
|
||||||
|
|
||||||
IF GET_LOCK('stock.log_sync', 0) THEN
|
|
||||||
CALL log_sync(FALSE);
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
DO RELEASE_LOCK('stock.log_sync');
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,61 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`outbound_requestQuantity`(
|
|
||||||
vSelf INT,
|
|
||||||
vRequested INT,
|
|
||||||
vDated DATETIME,
|
|
||||||
OUT vSupplied INT)
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Disassociates outbound picks after the given date until the
|
|
||||||
* demanded quantity is satisfied.
|
|
||||||
*
|
|
||||||
* @param vSelf The outbound reference
|
|
||||||
* @param vRequested The requested quantity
|
|
||||||
* @param vDate The starting date for the associated inbounds
|
|
||||||
* @param vSupplied The supplied quantity
|
|
||||||
*/
|
|
||||||
DECLARE vInboundFk INT;
|
|
||||||
DECLARE vPickQuantity INT;
|
|
||||||
DECLARE vPickGranted INT;
|
|
||||||
DECLARE vDone BOOL;
|
|
||||||
|
|
||||||
DECLARE vPicks CURSOR FOR
|
|
||||||
SELECT p.inboundFk, p.quantity
|
|
||||||
FROM inboundPick p
|
|
||||||
JOIN inbound i ON i.id = p.inboundFk
|
|
||||||
WHERE p.outboundFk = vSelf
|
|
||||||
AND i.dated > vDated
|
|
||||||
ORDER BY i.dated DESC;
|
|
||||||
|
|
||||||
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
|
||||||
SET vDone = TRUE;
|
|
||||||
|
|
||||||
SET vSupplied = 0;
|
|
||||||
|
|
||||||
OPEN vPicks;
|
|
||||||
|
|
||||||
myLoop: LOOP
|
|
||||||
SET vDone = FALSE;
|
|
||||||
FETCH vPicks INTO vInboundFk, vPickQuantity;
|
|
||||||
|
|
||||||
IF vDone THEN
|
|
||||||
LEAVE myLoop;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
SET vPickGranted = LEAST(vRequested - vSupplied, vPickQuantity);
|
|
||||||
SET vSupplied = vSupplied + vPickGranted;
|
|
||||||
CALL inbound_removePick(vInboundFk, vSelf, vPickGranted, vPickQuantity);
|
|
||||||
|
|
||||||
UPDATE inbound
|
|
||||||
SET isSync = FALSE,
|
|
||||||
available = available + vPickGranted
|
|
||||||
WHERE id = vInboundFk;
|
|
||||||
|
|
||||||
IF vSupplied >= vRequested THEN
|
|
||||||
LEAVE myLoop;
|
|
||||||
END IF;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
CLOSE vPicks;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`stock_clean`()
|
||||||
|
BEGIN
|
||||||
|
/**
|
||||||
|
* Cleans current time dependent cache records.
|
||||||
|
*/
|
||||||
|
DECLARE vExpired DATETIME;
|
||||||
|
DECLARE vAliveDate DATE;
|
||||||
|
|
||||||
|
-- Expired order reserves
|
||||||
|
|
||||||
|
SELECT SUBTIME(util.VN_NOW(), reserveTime)
|
||||||
|
INTO vExpired
|
||||||
|
FROM hedera.orderConfig LIMIT 1;
|
||||||
|
|
||||||
|
UPDATE hedera.order
|
||||||
|
SET isReserved = FALSE
|
||||||
|
WHERE created < vExpired
|
||||||
|
AND isReserved;
|
||||||
|
|
||||||
|
-- Frozen old sales
|
||||||
|
|
||||||
|
SELECT util.VN_CURDATE() - INTERVAL saleLife DAY
|
||||||
|
INTO vAliveDate
|
||||||
|
FROM config LIMIT 1;
|
||||||
|
|
||||||
|
UPDATE vn.ticket
|
||||||
|
SET isAlive = FALSE
|
||||||
|
WHERE shipped < vAliveDate
|
||||||
|
AND isAlive;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,87 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`stock_refreshAll`()
|
||||||
|
BEGIN
|
||||||
|
/**
|
||||||
|
* Recalculates the entire cache. It takes a considerable time,
|
||||||
|
* please avoid calls to this procedure from commonly used operations.
|
||||||
|
*/
|
||||||
|
DECLARE vDone BOOL;
|
||||||
|
DECLARE vId INT;
|
||||||
|
|
||||||
|
DECLARE vBuys CURSOR FOR
|
||||||
|
SELECT lotFk FROM vn.buy WHERE isAlive;
|
||||||
|
|
||||||
|
DECLARE vTickets CURSOR FOR
|
||||||
|
SELECT id FROM vn.ticket WHERE isAlive;
|
||||||
|
|
||||||
|
DECLARE vOrders CURSOR FOR
|
||||||
|
SELECT lotFk FROM hedera.orderRow WHERE isReserved;
|
||||||
|
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
||||||
|
SET vDone = TRUE;
|
||||||
|
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
DO RELEASE_LOCK('stock.stock_refreshAll');
|
||||||
|
RESIGNAL;
|
||||||
|
END;
|
||||||
|
|
||||||
|
IF NOT GET_LOCK('stock.stock_refreshAll', 30) THEN
|
||||||
|
CALL util.throw('Lock timeout exceeded');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Prune cache
|
||||||
|
|
||||||
|
DELETE p FROM buyPick p JOIN buyLot l USING(lotFk);
|
||||||
|
TRUNCATE TABLE buyLot;
|
||||||
|
TRUNCATE TABLE buyOut;
|
||||||
|
|
||||||
|
-- Populate cache
|
||||||
|
|
||||||
|
OPEN vBuys;
|
||||||
|
buyLoop: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vBuys INTO vId;
|
||||||
|
|
||||||
|
IF vDone THEN
|
||||||
|
LEAVE buyLoop;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
CALL buyOut_refreshBuy('lot', vId);
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vBuys;
|
||||||
|
|
||||||
|
OPEN vOrders;
|
||||||
|
orderLoop: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vOrders INTO vId;
|
||||||
|
|
||||||
|
IF vDone THEN
|
||||||
|
LEAVE orderLoop;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
CALL buyOut_refreshOrder('lot', vId);
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vOrders;
|
||||||
|
|
||||||
|
OPEN vTickets;
|
||||||
|
saleLoop: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vTickets INTO vId;
|
||||||
|
|
||||||
|
IF vDone THEN
|
||||||
|
LEAVE saleLoop;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
CALL buyOut_refreshSale('ticket', vId);
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vTickets;
|
||||||
|
|
||||||
|
-- Synchronize
|
||||||
|
|
||||||
|
UPDATE buyOut SET isSync = TRUE;
|
||||||
|
CALL stock_sync;
|
||||||
|
|
||||||
|
DO RELEASE_LOCK('stock.stock_refreshAll');
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,34 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`stock_sync`()
|
||||||
|
BEGIN
|
||||||
|
/**
|
||||||
|
* Synchronizes all out of sync items. It can be called in parallel
|
||||||
|
* since it generates a lock for each item (and warehouse) synchronization
|
||||||
|
* process, see stock_syncItem().
|
||||||
|
*/
|
||||||
|
DECLARE vDone BOOL;
|
||||||
|
DECLARE vWarehouseFk INT;
|
||||||
|
DECLARE vItemFk INT;
|
||||||
|
|
||||||
|
DECLARE vItems CURSOR FOR
|
||||||
|
SELECT itemFk, warehouseFk FROM buyLot WHERE NOT isSync
|
||||||
|
UNION
|
||||||
|
SELECT itemFk, warehouseFk FROM buyOut WHERE NOT isSync;
|
||||||
|
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
||||||
|
SET vDone = TRUE;
|
||||||
|
|
||||||
|
OPEN vItems;
|
||||||
|
itemLoop: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vItems INTO vItemFk, vWarehouseFk;
|
||||||
|
|
||||||
|
IF vDone THEN
|
||||||
|
LEAVE itemLoop;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
CALL stock_syncItem(vItemFk, vWarehouseFk, 0);
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vItems;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,88 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`stock_syncItem`(
|
||||||
|
vItemFk INT,
|
||||||
|
vWarehouseFk INT,
|
||||||
|
vWait INT)
|
||||||
|
myProc: BEGIN
|
||||||
|
/**
|
||||||
|
* Synchronizes out of sync item. It generates a lock for each item and
|
||||||
|
* warehouse synchronization process.
|
||||||
|
*
|
||||||
|
* @param vItemFk The item id
|
||||||
|
* @param vWarehouseFk The item warehouse id
|
||||||
|
* @param vWait Maximum waiting time, see GET_LOCK()
|
||||||
|
*/
|
||||||
|
DECLARE vDone BOOL;
|
||||||
|
DECLARE vHasPendingSync BOOL;
|
||||||
|
DECLARE vLotFk INT;
|
||||||
|
DECLARE vOutFk INT;
|
||||||
|
DECLARE vLock VARCHAR(255);
|
||||||
|
|
||||||
|
DECLARE vLots CURSOR FOR
|
||||||
|
SELECT lotFk FROM buyLot
|
||||||
|
WHERE NOT isSync
|
||||||
|
AND (itemFk, warehouseFk) = (vItemFk, vWarehouseFk)
|
||||||
|
ORDER BY dated, lotFk;
|
||||||
|
|
||||||
|
DECLARE vOuts CURSOR FOR
|
||||||
|
SELECT outFk FROM buyOut
|
||||||
|
WHERE NOT isSync
|
||||||
|
AND (itemFk, warehouseFk) = (vItemFk, vWarehouseFk)
|
||||||
|
ORDER BY dated, created, outFk;
|
||||||
|
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND
|
||||||
|
SET vDone = TRUE;
|
||||||
|
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
DO RELEASE_LOCK(vLock);
|
||||||
|
ROLLBACK;
|
||||||
|
RESIGNAL;
|
||||||
|
END;
|
||||||
|
|
||||||
|
SET vLock = CONCAT_WS('/', 'stock.stock_syncItem', vWarehouseFk, vItemFk);
|
||||||
|
|
||||||
|
IF NOT GET_LOCK(vLock, vWait) THEN
|
||||||
|
LEAVE myProc;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
REPEAT
|
||||||
|
SET vHasPendingSync = FALSE;
|
||||||
|
|
||||||
|
OPEN vLots;
|
||||||
|
lotLoop: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vLots INTO vLotFk;
|
||||||
|
|
||||||
|
IF vDone THEN
|
||||||
|
LEAVE lotLoop;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
CALL buyLot_sync(vLotFk);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
SET vHasPendingSync = TRUE;
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vLots;
|
||||||
|
|
||||||
|
OPEN vOuts;
|
||||||
|
outLoop: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vOuts INTO vOutFk;
|
||||||
|
|
||||||
|
IF vDone THEN
|
||||||
|
LEAVE outLoop;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
CALL buyOut_sync(vOutFk);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
SET vHasPendingSync = TRUE;
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vOuts;
|
||||||
|
|
||||||
|
UNTIL NOT vHasPendingSync END REPEAT;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -1,20 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`visible_log`(
|
|
||||||
vIsPicked BOOL,
|
|
||||||
vWarehouseFk INT,
|
|
||||||
vItemFk INT,
|
|
||||||
vQuantity INT
|
|
||||||
)
|
|
||||||
proc: BEGIN
|
|
||||||
IF !vIsPicked THEN
|
|
||||||
LEAVE proc;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
INSERT INTO visible
|
|
||||||
SET itemFk = vItemFk,
|
|
||||||
warehouseFk = vWarehouseFk,
|
|
||||||
quantity = vQuantity
|
|
||||||
ON DUPLICATE KEY UPDATE
|
|
||||||
quantity = quantity + VALUES(quantity);
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,22 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `stock`.`inbound_afterDelete`
|
|
||||||
AFTER DELETE ON `inbound`
|
|
||||||
FOR EACH ROW
|
|
||||||
BEGIN
|
|
||||||
UPDATE outbound o
|
|
||||||
JOIN inboundPick ou ON ou.outboundFk = o.id
|
|
||||||
SET o.lack = o.lack + ou.quantity,
|
|
||||||
o.isSync = FALSE
|
|
||||||
WHERE ou.inboundFk = OLD.id;
|
|
||||||
|
|
||||||
DELETE FROM inboundPick
|
|
||||||
WHERE inboundFk = OLD.id;
|
|
||||||
|
|
||||||
CALL visible_log(
|
|
||||||
OLD.isPicked,
|
|
||||||
OLD.warehouseFk,
|
|
||||||
OLD.itemFk,
|
|
||||||
-OLD.quantity
|
|
||||||
);
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,15 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `stock`.`inbound_beforeInsert`
|
|
||||||
BEFORE INSERT ON `inbound`
|
|
||||||
FOR EACH ROW
|
|
||||||
BEGIN
|
|
||||||
SET NEW.isPicked = NEW.isPicked OR NEW.dated < util.VN_CURDATE();
|
|
||||||
|
|
||||||
CALL visible_log(
|
|
||||||
NEW.isPicked,
|
|
||||||
NEW.warehouseFk,
|
|
||||||
NEW.itemFk,
|
|
||||||
NEW.quantity
|
|
||||||
);
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,22 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `stock`.`outbound_afterDelete`
|
|
||||||
AFTER DELETE ON `outbound`
|
|
||||||
FOR EACH ROW
|
|
||||||
BEGIN
|
|
||||||
UPDATE inbound i
|
|
||||||
JOIN inboundPick ou ON ou.inboundFk = i.id
|
|
||||||
SET i.available = i.available + ou.quantity,
|
|
||||||
i.isSync = FALSE
|
|
||||||
WHERE ou.outboundFk = OLD.id;
|
|
||||||
|
|
||||||
DELETE FROM inboundPick
|
|
||||||
WHERE outboundFk = OLD.id;
|
|
||||||
|
|
||||||
CALL visible_log(
|
|
||||||
OLD.isPicked,
|
|
||||||
OLD.warehouseFk,
|
|
||||||
OLD.itemFk,
|
|
||||||
OLD.quantity
|
|
||||||
);
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,16 +0,0 @@
|
||||||
DELIMITER $$
|
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `stock`.`outbound_beforeInsert`
|
|
||||||
BEFORE INSERT ON `outbound`
|
|
||||||
FOR EACH ROW
|
|
||||||
BEGIN
|
|
||||||
SET NEW.lack = NEW.quantity;
|
|
||||||
SET NEW.isPicked = NEW.isPicked OR NEW.dated < util.VN_CURDATE();
|
|
||||||
|
|
||||||
CALL visible_log(
|
|
||||||
NEW.isPicked,
|
|
||||||
NEW.warehouseFk,
|
|
||||||
NEW.itemFk,
|
|
||||||
-NEW.quantity
|
|
||||||
);
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` FUNCTION `vn`.`item_getLife`(vItemFk INT)
|
||||||
|
RETURNS INT
|
||||||
|
NOT DETERMINISTIC
|
||||||
|
BEGIN
|
||||||
|
DECLARE vLife INT;
|
||||||
|
|
||||||
|
SELECT t.life INTO vLife
|
||||||
|
FROM itemType t
|
||||||
|
JOIN item i ON i.typeFk = t.id
|
||||||
|
WHERE i.id = vItemFk;
|
||||||
|
|
||||||
|
RETURN vLife;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -104,6 +104,24 @@ BEGIN
|
||||||
LEFT JOIN agencyModeItemType ait
|
LEFT JOIN agencyModeItemType ait
|
||||||
ON ait.agencyModeFk = vAgencyModeFk
|
ON ait.agencyModeFk = vAgencyModeFk
|
||||||
AND ait.itemTypeFk = itt.id
|
AND ait.itemTypeFk = itt.id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT i.id
|
||||||
|
FROM item i
|
||||||
|
JOIN priceDelta pd
|
||||||
|
ON pd.itemTypeFk = i.typeFk
|
||||||
|
AND (pd.minSize IS NULL OR pd.minSize <= i.`size`)
|
||||||
|
AND (pd.maxSize IS NULL OR pd.maxSize >= i.`size`)
|
||||||
|
AND (pd.inkFk IS NULL OR pd.inkFk = i.inkFk)
|
||||||
|
AND (pd.originFk IS NULL OR pd.originFk = i.originFk)
|
||||||
|
AND (pd.producerFk IS NULL OR pd.producerFk = i.producerFk)
|
||||||
|
AND (pd.warehouseFk IS NULL OR pd.warehouseFk = vWarehouseFk)
|
||||||
|
LEFT JOIN zoneGeo zg ON zg.id = pd.zoneGeoFk
|
||||||
|
LEFT JOIN zoneGeo zg2 ON zg2.id = address_getGeo(vAddressFk)
|
||||||
|
WHERE (pd.fromDated IS NULL OR pd.fromDated <= vShipped)
|
||||||
|
AND (pd.toDated IS NULL OR pd.toDated >= vShipped)
|
||||||
|
AND (pd.zoneGeoFk IS NULL OR zg2.lft BETWEEN zg.lft AND zg.rgt)
|
||||||
|
AND pd.isHidden
|
||||||
|
GROUP BY i.id) pd ON pd.id = i.itemFk
|
||||||
WHERE a.calc_id = vAvailableCalc
|
WHERE a.calc_id = vAvailableCalc
|
||||||
AND a.available > 0
|
AND a.available > 0
|
||||||
AND (ag.isAnyVolumeAllowed OR NOT itt.isUnconventionalSize)
|
AND (ag.isAnyVolumeAllowed OR NOT itt.isUnconventionalSize)
|
||||||
|
@ -113,7 +131,9 @@ BEGIN
|
||||||
it.size <= z.itemMaxSize OR z.itemMaxSize IS NULL))
|
it.size <= z.itemMaxSize OR z.itemMaxSize IS NULL))
|
||||||
AND cit.id IS NULL
|
AND cit.id IS NULL
|
||||||
AND zit.id IS NULL
|
AND zit.id IS NULL
|
||||||
AND ait.id IS NULL;
|
AND ait.id IS NULL
|
||||||
|
AND pd.id IS NULL
|
||||||
|
;
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tmp.buyUltimate;
|
DROP TEMPORARY TABLE tmp.buyUltimate;
|
||||||
|
|
||||||
|
|
|
@ -1,83 +1,86 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`report_print`(
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`report_print`(
|
||||||
vReportName VARCHAR(100),
|
vReportName VARCHAR(100),
|
||||||
vPrinterFk INT,
|
vPrinterFk INT,
|
||||||
vUserFk INT,
|
vUserFk INT,
|
||||||
vParams JSON,
|
vParams JSON,
|
||||||
vPriorityName VARCHAR(100)
|
vPriorityName VARCHAR(100)
|
||||||
)
|
)
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
* Inserts in the print queue the report to be printed and the necessary parameters for this
|
* Inserts in the print queue the report to be printed and the necessary parameters for this
|
||||||
* one taking into account the paper size of both the printer and the report.
|
* one taking into account the paper size of both the printer and the report.
|
||||||
*
|
*
|
||||||
* @param vReportName the report to be printed.
|
* @param vReportName the report to be printed.
|
||||||
* @param vPrinterFk the printer selected.
|
* @param vPrinterFk the printer selected.
|
||||||
* @param vUserFk user id.
|
* @param vUserFk user id.
|
||||||
* @param vParams JSON with report parameters.
|
* @param vParams JSON with report parameters.
|
||||||
* @param vPriorityName the printing priority.
|
* @param vPriorityName the printing priority.
|
||||||
*/
|
*/
|
||||||
DECLARE vI INT DEFAULT 0;
|
DECLARE vI INT DEFAULT 0;
|
||||||
DECLARE vKeys TEXT DEFAULT JSON_KEYS(vParams);
|
DECLARE vKeys TEXT DEFAULT JSON_KEYS(vParams);
|
||||||
DECLARE vLength INT DEFAULT JSON_LENGTH(vKeys);
|
DECLARE vLength INT DEFAULT JSON_LENGTH(vKeys);
|
||||||
DECLARE vKey VARCHAR(255);
|
DECLARE vKey VARCHAR(255);
|
||||||
DECLARE vVal VARCHAR(255);
|
DECLARE vVal VARCHAR(255);
|
||||||
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 EXIT HANDLER FOR SQLEXCEPTION
|
DECLARE vTx BOOLEAN DEFAULT NOT @@in_transaction;
|
||||||
BEGIN
|
|
||||||
ROLLBACK;
|
|
||||||
RESIGNAL;
|
|
||||||
END;
|
|
||||||
|
|
||||||
SELECT id, paperSizeFk INTO vReportFk, vReportSize
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
FROM report
|
BEGIN
|
||||||
WHERE name = vReportName;
|
CALL util.tx_rollback(vTx);
|
||||||
|
RESIGNAL;
|
||||||
|
END;
|
||||||
|
|
||||||
SELECT id, paperSizeFk INTO vIsThePrinterReal, vPrinteSize
|
|
||||||
FROM printer
|
|
||||||
WHERE id = vPrinterFk;
|
|
||||||
|
|
||||||
SELECT id INTO vPriorityFk
|
SELECT id, paperSizeFk INTO vReportFk, vReportSize
|
||||||
FROM queuePriority
|
FROM report
|
||||||
WHERE code = vPriorityName;
|
WHERE name = vReportName;
|
||||||
|
|
||||||
IF vIsThePrinterReal IS NULL THEN
|
SELECT id, paperSizeFk INTO vIsThePrinterReal, vPrinterSize
|
||||||
CALL util.throw('printerNotExists');
|
FROM printer
|
||||||
END IF;
|
WHERE id = vPrinterFk;
|
||||||
|
|
||||||
IF vReportFk IS NULL THEN
|
SELECT id INTO vPriorityFk
|
||||||
CALL util.throw('reportNotExists');
|
FROM queuePriority
|
||||||
END IF;
|
WHERE code = vPriorityName;
|
||||||
|
|
||||||
IF vReportSize <> vPrinteSize THEN
|
IF vIsThePrinterReal IS NULL THEN
|
||||||
CALL util.throw('incorrectSize');
|
CALL util.throw('printerNotExists');
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
START TRANSACTION;
|
IF vReportFk IS NULL THEN
|
||||||
INSERT INTO printQueue
|
CALL util.throw('reportNotExists');
|
||||||
SET printerFk = vPrinterFk,
|
END IF;
|
||||||
priorityFk = vPriorityFk,
|
|
||||||
reportFk = vReportFk,
|
|
||||||
workerFk = vUserFk;
|
|
||||||
|
|
||||||
SET vPrintQueueFk = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
WHILE vI < vLength DO
|
IF vReportSize <> vPrinterSize THEN
|
||||||
SET vKey = JSON_VALUE(vKeys, CONCAT('$[', vI ,']'));
|
CALL util.throw('incorrectSize');
|
||||||
SET vVal = JSON_VALUE(vParams, CONCAT('$.', vKey));
|
END IF;
|
||||||
|
CALL util.tx_start(vTx);
|
||||||
|
INSERT INTO printQueue
|
||||||
|
SET printerFk = vPrinterFk,
|
||||||
|
priorityFk = vPriorityFk,
|
||||||
|
reportFk = vReportFk,
|
||||||
|
workerFk = vUserFk;
|
||||||
|
|
||||||
INSERT INTO printQueueArgs
|
SET vPrintQueueFk = LAST_INSERT_ID();
|
||||||
SET printQueueFk = vPrintQueueFk,
|
|
||||||
name = vKey,
|
|
||||||
value = vVal;
|
|
||||||
|
|
||||||
SET vI = vI + 1;
|
WHILE vI < vLength DO
|
||||||
END WHILE;
|
SET vKey = JSON_VALUE(vKeys, CONCAT('$[', vI ,']'));
|
||||||
COMMIT;
|
SET vVal = JSON_VALUE(vParams, CONCAT('$.', vKey));
|
||||||
|
|
||||||
|
INSERT INTO printQueueArgs
|
||||||
|
SET printQueueFk = vPrintQueueFk,
|
||||||
|
name = vKey,
|
||||||
|
value = vVal;
|
||||||
|
|
||||||
|
SET vI = vI + 1;
|
||||||
|
END WHILE;
|
||||||
|
|
||||||
|
CALL util.tx_commit(vTx);
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -22,6 +22,10 @@ trig: BEGIN
|
||||||
|
|
||||||
SET NEW.editorFk = account.myUser_getId();
|
SET NEW.editorFk = account.myUser_getId();
|
||||||
|
|
||||||
|
IF NEW.life IS NULL THEN
|
||||||
|
SET NEW.life = item_getLife(NEW.itemFk);
|
||||||
|
END IF;
|
||||||
|
|
||||||
SELECT it.workerFk INTO vBuyerFk
|
SELECT it.workerFk INTO vBuyerFk
|
||||||
FROM item i
|
FROM item i
|
||||||
JOIN itemType it ON it.id = i.typeFk
|
JOIN itemType it ON it.id = i.typeFk
|
||||||
|
@ -57,7 +61,7 @@ trig: BEGIN
|
||||||
IF NEW.groupingMode IS NULL THEN
|
IF NEW.groupingMode IS NULL THEN
|
||||||
SET NEW.groupingMode = vGroupingMode;
|
SET NEW.groupingMode = vGroupingMode;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Generics
|
-- Generics
|
||||||
SELECT i.genericFk INTO vGenericFk
|
SELECT i.genericFk INTO vGenericFk
|
||||||
FROM item i
|
FROM item i
|
||||||
|
@ -78,7 +82,7 @@ trig: BEGIN
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF NEW.quantity < 0 THEN
|
IF NEW.quantity < 0 THEN
|
||||||
SET NEW.isIgnored = TRUE;
|
SET NEW.isIgnored = TRUE;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF NEW.weight AND NEW.packing
|
IF NEW.weight AND NEW.packing
|
||||||
|
|
|
@ -25,6 +25,10 @@ trig:BEGIN
|
||||||
|
|
||||||
SET NEW.editorFk = account.myUser_getId();
|
SET NEW.editorFk = account.myUser_getId();
|
||||||
|
|
||||||
|
IF NOT (NEW.itemFk <=> OLD.itemFk) AND NEW.life <=> OLD.life THEN
|
||||||
|
SET NEW.life = item_getLife(NEW.itemFk);
|
||||||
|
END IF;
|
||||||
|
|
||||||
SELECT defaultEntry INTO vDefaultEntry
|
SELECT defaultEntry INTO vDefaultEntry
|
||||||
FROM entryConfig;
|
FROM entryConfig;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
DROP TABLE stock.log;
|
|
@ -0,0 +1,16 @@
|
||||||
|
DROP TABLE IF EXISTS stock.inboundPick;
|
||||||
|
|
||||||
|
CREATE TABLE stock.buyPick (
|
||||||
|
id INT UNSIGNED auto_increment NOT NULL,
|
||||||
|
lotFk INT(11) NOT NULL
|
||||||
|
COMMENT 'Buy id',
|
||||||
|
outFk INT(11) NOT NULL
|
||||||
|
COMMENT 'Out id',
|
||||||
|
quantity INT UNSIGNED NOT NULL
|
||||||
|
COMMENT 'Picked quantity',
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
CONSTRAINT buyPick_unique UNIQUE KEY (lotFk, outFk)
|
||||||
|
)
|
||||||
|
ENGINE=InnoDB
|
||||||
|
DEFAULT CHARSET=utf8mb3
|
||||||
|
COLLATE=utf8mb3_unicode_ci;
|
|
@ -0,0 +1,6 @@
|
||||||
|
ALTER TABLE vn.buy
|
||||||
|
ADD life INT UNSIGNED NULL
|
||||||
|
COMMENT 'Lot life expressed in days',
|
||||||
|
ADD isAlive BOOL NOT NULL DEFAULT TRUE
|
||||||
|
COMMENT 'Whether it is alive',
|
||||||
|
ADD INDEX(isAlive);
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE hedera.orderRow
|
||||||
|
ADD isReserved BOOL NOT NULL DEFAULT TRUE
|
||||||
|
COMMENT 'Whether has an available reservation',
|
||||||
|
ADD INDEX(isReserved);
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE vn.ticket
|
||||||
|
ADD isAlive BOOL NOT NULL DEFAULT TRUE
|
||||||
|
COMMENT 'Whether it is alive',
|
||||||
|
ADD INDEX(isAlive);
|
|
@ -0,0 +1,10 @@
|
||||||
|
RENAME TABLE IF EXISTS stock.inbound TO stock.buyLot;
|
||||||
|
|
||||||
|
ALTER TABLE stock.buyLot
|
||||||
|
DROP KEY source,
|
||||||
|
DROP COLUMN tableName,
|
||||||
|
CHANGE tableId lotFk int(10) unsigned NOT NULL,
|
||||||
|
CHANGE isSync isSync tinyint(4) NOT NULL AFTER lotFk,
|
||||||
|
DROP PRIMARY KEY,
|
||||||
|
DROP COLUMN id,
|
||||||
|
ADD PRIMARY KEY (lotFk);
|
|
@ -0,0 +1 @@
|
||||||
|
DROP TABLE stock.visible;
|
|
@ -0,0 +1,10 @@
|
||||||
|
RENAME TABLE IF EXISTS stock.outbound TO stock.buyOut;
|
||||||
|
|
||||||
|
ALTER TABLE stock.buyOut
|
||||||
|
CHANGE IF EXISTS tableName source enum('buy','sale','orderRow') CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
|
||||||
|
CHANGE IF EXISTS id outFk int(10) UNSIGNED NOT NULL,
|
||||||
|
DROP INDEX IF EXISTS source,
|
||||||
|
DROP COLUMN IF EXISTS tableId,
|
||||||
|
DROP INDEX IF EXISTS expired,
|
||||||
|
DROP COLUMN IF EXISTS expired,
|
||||||
|
ADD INDEX IF NOT EXISTS (source);
|
|
@ -0,0 +1,8 @@
|
||||||
|
CREATE TABLE stock.config (
|
||||||
|
id INT UNSIGNED auto_increment NOT NULL,
|
||||||
|
saleLife INT UNSIGNED NOT NULL COMMENT 'Maximum sales cache lifetime in days',
|
||||||
|
CONSTRAINT config_pk PRIMARY KEY (id)
|
||||||
|
)
|
||||||
|
ENGINE=InnoDB
|
||||||
|
DEFAULT CHARSET=utf8mb3
|
||||||
|
COLLATE=utf8mb3_general_ci;
|
|
@ -0,0 +1,2 @@
|
||||||
|
INSERT INTO stock.config (id, saleLife)
|
||||||
|
VALUES (1, 90);
|
|
@ -0,0 +1 @@
|
||||||
|
CREATE SEQUENCE IF NOT EXISTS vn.buyLot;
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE vn.sale
|
||||||
|
ADD COLUMN IF NOT EXISTS lotFk INT UNSIGNED NOT NULL DEFAULT nextval(vn.buyLot) AFTER id;
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE hedera.orderRow
|
||||||
|
ADD COLUMN IF NOT EXISTS lotFk INT UNSIGNED NOT NULL DEFAULT nextval(vn.buyLot) AFTER id;
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE vn.buy
|
||||||
|
ADD COLUMN IF NOT EXISTS lotFk INT UNSIGNED NOT NULL DEFAULT nextval(vn.buyLot) AFTER id;
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE vn.sale
|
||||||
|
ADD UNIQUE IF NOT EXISTS (lotFk);
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE hedera.orderRow
|
||||||
|
ADD UNIQUE IF NOT EXISTS (lotFk);
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE vn.buy
|
||||||
|
ADD UNIQUE IF NOT EXISTS (lotFk);
|
|
@ -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`);
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
INSERT IGNORE INTO vn.state (name,`order`,alertLevel,code,isPreviousPreparable,isPicked)
|
||||||
|
VALUES ('Recogido',3,4,'PICKED_UP',0,1)
|
|
@ -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;
|
|
@ -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');
|
|
@ -0,0 +1,8 @@
|
||||||
|
UPDATE vn.claimEnd ce
|
||||||
|
JOIN(
|
||||||
|
SELECT id
|
||||||
|
FROM vn.claimEnd
|
||||||
|
WHERE claimDestinationFk NOT IN
|
||||||
|
(SELECT id FROM vn.claimDestination WHERE id IS NOT NULL)
|
||||||
|
) s ON ce.id = s.id
|
||||||
|
SET ce.claimDestinationFk = 1;
|
|
@ -0,0 +1,9 @@
|
||||||
|
ALTER TABLE vn.claimEnd
|
||||||
|
MODIFY COLUMN claimDestinationFk tinyint(3) unsigned NOT NULL DEFAULT 1;
|
||||||
|
|
||||||
|
ALTER TABLE vn.claimEnd
|
||||||
|
ADD CONSTRAINT fk_claimEnd_claimDestination
|
||||||
|
FOREIGN KEY (claimDestinationFk)
|
||||||
|
REFERENCES claimDestination(id)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE RESTRICT;
|
|
@ -0,0 +1,3 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
|
||||||
|
VALUES ('Worker','getWorkerBusiness','READ','ALLOW','ROLE','hr');
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
USE vn;
|
||||||
|
|
||||||
|
INSERT INTO vn.workerActivityType (code, description)
|
||||||
|
VALUES('SHELVING_CLEAN_START', 'SE INICIA LIMPIEZA CARRO'),
|
||||||
|
('SHELVING_CLEAN_STOP', 'SE FINALIZA LIMPIEZA CARRO');
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
ALTER TABLE vn.priceDelta ADD IF NOT EXISTS isHidden BOOL
|
||||||
|
DEFAULT FALSE NOT NULL
|
||||||
|
COMMENT 'Hides the itemType when building de catalog recordset';
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,403 +1,404 @@
|
||||||
{
|
{
|
||||||
"Phone format is invalid": "El formato del teléfono no es correcto",
|
"Phone format is invalid": "El formato del teléfono no es correcto",
|
||||||
"You are not allowed to change the credit": "No tienes privilegios para modificar el crédito",
|
"You are not allowed to change the credit": "No tienes privilegios para modificar el crédito",
|
||||||
"Unable to mark the equivalence surcharge": "No se puede marcar el recargo de equivalencia",
|
"Unable to mark the equivalence surcharge": "No se puede marcar el recargo de equivalencia",
|
||||||
"The default consignee can not be unchecked": "No se puede desmarcar el consignatario predeterminado",
|
"The default consignee can not be unchecked": "No se puede desmarcar el consignatario predeterminado",
|
||||||
"Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado",
|
"Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado",
|
||||||
"Can't be blank": "No puede estar en blanco",
|
"Can't be blank": "No puede estar en blanco",
|
||||||
"Invalid TIN": "NIF/CIF inválido",
|
"Invalid TIN": "NIF/CIF inválido",
|
||||||
"TIN must be unique": "El NIF/CIF debe ser único",
|
"TIN must be unique": "El NIF/CIF debe ser único",
|
||||||
"A client with that Web User name already exists": "Ya existe un cliente con ese Usuario Web",
|
"A client with that Web User name already exists": "Ya existe un cliente con ese Usuario Web",
|
||||||
"Is invalid": "Es inválido",
|
"Is invalid": "Es inválido",
|
||||||
"Quantity cannot be zero": "La cantidad no puede ser cero",
|
"Quantity cannot be zero": "La cantidad no puede ser cero",
|
||||||
"Enter an integer different to zero": "Introduce un entero distinto de cero",
|
"Enter an integer different to zero": "Introduce un entero distinto de cero",
|
||||||
"Package cannot be blank": "El embalaje no puede estar en blanco",
|
"Package cannot be blank": "El embalaje no puede estar en blanco",
|
||||||
"The company name must be unique": "La razón social debe ser única",
|
"The company name must be unique": "La razón social debe ser única",
|
||||||
"Invalid email": "Correo electrónico inválido",
|
"Invalid email": "Correo electrónico inválido",
|
||||||
"The IBAN does not have the correct format": "El IBAN no tiene el formato correcto",
|
"The IBAN does not have the correct format": "El IBAN no tiene el formato correcto",
|
||||||
"That payment method requires an IBAN": "El método de pago seleccionado requiere un IBAN",
|
"That payment method requires an IBAN": "El método de pago seleccionado requiere un IBAN",
|
||||||
"That payment method requires a BIC": "El método de pago seleccionado requiere un BIC",
|
"That payment method requires a BIC": "El método de pago seleccionado requiere un BIC",
|
||||||
"State cannot be blank": "El estado no puede estar en blanco",
|
"State cannot be blank": "El estado no puede estar en blanco",
|
||||||
"Worker cannot be blank": "El trabajador no puede estar en blanco",
|
"Worker cannot be blank": "El trabajador no puede estar en blanco",
|
||||||
"Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado",
|
"Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado",
|
||||||
"can't be blank": "El campo no puede estar vacío",
|
"can't be blank": "El campo no puede estar vacío",
|
||||||
"Observation type must be unique": "El tipo de observación no puede repetirse",
|
"Observation type must be unique": "El tipo de observación no puede repetirse",
|
||||||
"The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero",
|
"The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero",
|
||||||
"The grade must be similar to the last one": "El grade debe ser similar al último",
|
"The grade must be similar to the last one": "El grade debe ser similar al último",
|
||||||
"Only manager can change the credit": "Solo el gerente puede cambiar el credito de este cliente",
|
"Only manager can change the credit": "Solo el gerente puede cambiar el credito de este cliente",
|
||||||
"Name cannot be blank": "El nombre no puede estar en blanco",
|
"Name cannot be blank": "El nombre no puede estar en blanco",
|
||||||
"Phone cannot be blank": "El teléfono no puede estar en blanco",
|
"Phone cannot be blank": "El teléfono no puede estar en blanco",
|
||||||
"Period cannot be blank": "El periodo no puede estar en blanco",
|
"Period cannot be blank": "El periodo no puede estar en blanco",
|
||||||
"Choose a company": "Selecciona una empresa",
|
"Choose a company": "Selecciona una empresa",
|
||||||
"Se debe rellenar el campo de texto": "Se debe rellenar el campo de texto",
|
"Se debe rellenar el campo de texto": "Se debe rellenar el campo de texto",
|
||||||
"Description should have maximum of 45 characters": "La descripción debe tener maximo 45 caracteres",
|
"Description should have maximum of 45 characters": "La descripción debe tener maximo 45 caracteres",
|
||||||
"Cannot be blank": "El campo no puede estar en blanco",
|
"Cannot be blank": "El campo no puede estar en blanco",
|
||||||
"The grade must be an integer greater than or equal to zero": "El grade debe ser un entero mayor o igual a cero",
|
"The grade must be an integer greater than or equal to zero": "El grade debe ser un entero mayor o igual a cero",
|
||||||
"Sample type cannot be blank": "El tipo de plantilla no puede quedar en blanco",
|
"Sample type cannot be blank": "El tipo de plantilla no puede quedar en blanco",
|
||||||
"Description cannot be blank": "Se debe rellenar el campo de texto",
|
"Description cannot be blank": "Se debe rellenar el campo de texto",
|
||||||
"The price of the item changed": "El precio del artículo cambió",
|
"The price of the item changed": "El precio del artículo cambió",
|
||||||
"The value should not be greater than 100%": "El valor no debe de ser mayor de 100%",
|
"The value should not be greater than 100%": "El valor no debe de ser mayor de 100%",
|
||||||
"The value should be a number": "El valor debe ser un numero",
|
"The value should be a number": "El valor debe ser un numero",
|
||||||
"This order is not editable": "Esta orden no se puede modificar",
|
"This order is not editable": "Esta orden no se puede modificar",
|
||||||
"You can't create an order for a frozen client": "No puedes crear una orden para un cliente congelado",
|
"You can't create an order for a frozen client": "No puedes crear una orden para un cliente congelado",
|
||||||
"You can't create an order for a client that has a debt": "No puedes crear una orden para un cliente con deuda",
|
"You can't create an order for a client that has a debt": "No puedes crear una orden para un cliente con deuda",
|
||||||
"is not a valid date": "No es una fecha valida",
|
"is not a valid date": "No es una fecha valida",
|
||||||
"Barcode must be unique": "El código de barras debe ser único",
|
"Barcode must be unique": "El código de barras debe ser único",
|
||||||
"The warehouse can't be repeated": "El almacén no puede repetirse",
|
"The warehouse can't be repeated": "El almacén no puede repetirse",
|
||||||
"The tag or priority can't be repeated for an item": "El tag o prioridad no puede repetirse para un item",
|
"The tag or priority can't be repeated for an item": "El tag o prioridad no puede repetirse para un item",
|
||||||
"The observation type can't be repeated": "El tipo de observación no puede repetirse",
|
"The observation type can't be repeated": "El tipo de observación no puede repetirse",
|
||||||
"A claim with that sale already exists": "Ya existe una reclamación para esta línea",
|
"A claim with that sale already exists": "Ya existe una reclamación para esta línea",
|
||||||
"You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo",
|
"You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo",
|
||||||
"Warehouse cannot be blank": "El almacén no puede quedar en blanco",
|
"Warehouse cannot be blank": "El almacén no puede quedar en blanco",
|
||||||
"Agency cannot be blank": "La agencia no puede quedar en blanco",
|
"Agency cannot be blank": "La agencia no puede quedar en blanco",
|
||||||
"Not enough privileges to edit a client with verified data": "No tienes permisos para hacer cambios en un cliente con datos comprobados",
|
"Not enough privileges to edit a client with verified data": "No tienes permisos para hacer cambios en un cliente con datos comprobados",
|
||||||
"This address doesn't exist": "Este consignatario no existe",
|
"This address doesn't exist": "Este consignatario no existe",
|
||||||
"You must delete the claim id %d first": "Antes debes borrar la reclamación %d",
|
"You must delete the claim id %d first": "Antes debes borrar la reclamación %d",
|
||||||
"You don't have enough privileges": "No tienes suficientes permisos",
|
"You don't have enough privileges": "No tienes suficientes permisos",
|
||||||
"Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF",
|
"Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF",
|
||||||
"You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos básicos de una orden con artículos",
|
"You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos básicos de una orden con artículos",
|
||||||
"INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no está permitido el uso de la letra ñ",
|
"INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no está permitido el uso de la letra ñ",
|
||||||
"You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado",
|
"You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado",
|
||||||
"You can't create a ticket for an inactive client": "No puedes crear un ticket para un cliente inactivo",
|
"You can't create a ticket for an inactive client": "No puedes crear un ticket para un cliente inactivo",
|
||||||
"Tag value cannot be blank": "El valor del tag no puede quedar en blanco",
|
"Tag value cannot be blank": "El valor del tag no puede quedar en blanco",
|
||||||
"ORDER_EMPTY": "Cesta vacía",
|
"ORDER_EMPTY": "Cesta vacía",
|
||||||
"You don't have enough privileges to do that": "No tienes permisos para cambiar esto",
|
"You don't have enough privileges to do that": "No tienes permisos para cambiar esto",
|
||||||
"NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT",
|
"NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT",
|
||||||
"Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido",
|
"Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido",
|
||||||
"Street cannot be empty": "Dirección no puede estar en blanco",
|
"Street cannot be empty": "Dirección no puede estar en blanco",
|
||||||
"City cannot be empty": "Ciudad no puede estar en blanco",
|
"City cannot be empty": "Ciudad no puede estar en blanco",
|
||||||
"Code cannot be blank": "Código no puede estar en blanco",
|
"Code cannot be blank": "Código no puede estar en blanco",
|
||||||
"You cannot remove this department": "No puedes eliminar este departamento",
|
"You cannot remove this department": "No puedes eliminar este departamento",
|
||||||
"The extension must be unique": "La extensión debe ser unica",
|
"The extension must be unique": "La extensión debe ser unica",
|
||||||
"The secret can't be blank": "La contraseña no puede estar en blanco",
|
"The secret can't be blank": "La contraseña no puede estar en blanco",
|
||||||
"We weren't able to send this SMS": "No hemos podido enviar el SMS",
|
"We weren't able to send this SMS": "No hemos podido enviar el SMS",
|
||||||
"This client can't be invoiced": "Este cliente no puede ser facturado",
|
"This client can't be invoiced": "Este cliente no puede ser facturado",
|
||||||
"You must provide the correction information to generate a corrective invoice": "Debes informar la información de corrección para generar una factura rectificativa",
|
"You must provide the correction information to generate a corrective invoice": "Debes informar la información de corrección para generar una factura rectificativa",
|
||||||
"This ticket can't be invoiced": "Este ticket no puede ser facturado",
|
"This ticket can't be invoiced": "Este ticket no puede ser facturado",
|
||||||
"You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado",
|
"You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado",
|
||||||
"This ticket can not be modified": "Este ticket no puede ser modificado",
|
"This ticket can not be modified": "Este ticket no puede ser modificado",
|
||||||
"The introduced hour already exists": "Esta hora ya ha sido introducida",
|
"The introduced hour already exists": "Esta hora ya ha sido introducida",
|
||||||
"INFINITE_LOOP": "Existe una dependencia entre dos Jefes",
|
"INFINITE_LOOP": "Existe una dependencia entre dos Jefes",
|
||||||
"The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas",
|
"The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas",
|
||||||
"NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros",
|
"NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros",
|
||||||
"ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado",
|
"ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado",
|
||||||
"The current ticket can't be modified": "El ticket actual no puede ser modificado",
|
"The current ticket can't be modified": "El ticket actual no puede ser modificado",
|
||||||
"The current claim can't be modified": "La reclamación actual no puede ser modificada",
|
"The current claim can't be modified": "La reclamación actual no puede ser modificada",
|
||||||
"The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas",
|
"The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas",
|
||||||
"The sales do not exists": "La(s) línea(s) seleccionada(s) no existe(n)",
|
"The sales do not exists": "La(s) línea(s) seleccionada(s) no existe(n)",
|
||||||
"Please select at least one sale": "Por favor selecciona al menos una linea",
|
"Please select at least one sale": "Por favor selecciona al menos una linea",
|
||||||
"All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket",
|
"All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket",
|
||||||
"NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada",
|
"NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada",
|
||||||
"This item doesn't exists": "El artículo no existe",
|
"This item doesn't exists": "El artículo no existe",
|
||||||
"NOT_ZONE_WITH_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada",
|
"NOT_ZONE_WITH_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada",
|
||||||
"Extension format is invalid": "El formato de la extensión es inválido",
|
"Extension format is invalid": "El formato de la extensión es inválido",
|
||||||
"Invalid parameters to create a new ticket": "Parámetros inválidos para crear un nuevo ticket",
|
"Invalid parameters to create a new ticket": "Parámetros inválidos para crear un nuevo ticket",
|
||||||
"This item is not available": "Este artículo no está disponible",
|
"This item is not available": "Este artículo no está disponible",
|
||||||
"This postcode already exists": "Este código postal ya existe",
|
"This postcode already exists": "Este código postal ya existe",
|
||||||
"Concept cannot be blank": "El concepto no puede quedar en blanco",
|
"Concept cannot be blank": "El concepto no puede quedar en blanco",
|
||||||
"File doesn't exists": "El archivo no existe",
|
"File doesn't exists": "El archivo no existe",
|
||||||
"You don't have privileges to change the zone": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias",
|
"You don't have privileges to change the zone": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias",
|
||||||
"This ticket is already on weekly tickets": "Este ticket ya está en tickets programados",
|
"This ticket is already on weekly tickets": "Este ticket ya está en tickets programados",
|
||||||
"Ticket id cannot be blank": "El id de ticket no puede quedar en blanco",
|
"Ticket id cannot be blank": "El id de ticket no puede quedar en blanco",
|
||||||
"Weekday cannot be blank": "El día de la semana no puede quedar en blanco",
|
"Weekday cannot be blank": "El día de la semana no puede quedar en blanco",
|
||||||
"You can't delete a confirmed order": "No puedes borrar un pedido confirmado",
|
"You can't delete a confirmed order": "No puedes borrar un pedido confirmado",
|
||||||
"The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto",
|
"The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto",
|
||||||
"Invalid quantity": "Cantidad invalida",
|
"Invalid quantity": "Cantidad invalida",
|
||||||
"This postal code is not valid": "Este código postal no es válido",
|
"This postal code is not valid": "Este código postal no es válido",
|
||||||
"is invalid": "es inválido",
|
"is invalid": "es inválido",
|
||||||
"The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto",
|
"The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto",
|
||||||
"The department name can't be repeated": "El nombre del departamento no puede repetirse",
|
"The department name can't be repeated": "El nombre del departamento no puede repetirse",
|
||||||
"This phone already exists": "Este teléfono ya existe",
|
"This phone already exists": "Este teléfono ya existe",
|
||||||
"You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos",
|
"You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos",
|
||||||
"You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado",
|
"You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado",
|
||||||
"You cannot delete a ticket that part of it is being prepared": "No puedes eliminar un ticket en el que una parte que está siendo preparada",
|
"You cannot delete a ticket that part of it is being prepared": "No puedes eliminar un ticket en el que una parte que está siendo preparada",
|
||||||
"You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero",
|
"You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero",
|
||||||
"You should specify a date": "Debes especificar una fecha",
|
"You should specify a date": "Debes especificar una fecha",
|
||||||
"You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fin",
|
"You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fin",
|
||||||
"Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fin",
|
"Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fin",
|
||||||
"You should mark at least one week day": "Debes marcar al menos un día de la semana",
|
"You should mark at least one week day": "Debes marcar al menos un día de la semana",
|
||||||
"Swift / BIC can't be empty": "Swift / BIC no puede estar vacío",
|
"Swift / BIC can't be empty": "Swift / BIC no puede estar vacío",
|
||||||
"Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios",
|
"Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios",
|
||||||
"Incoterms is required for a non UEE member": "El incoterms es requerido para los clientes extracomunitarios",
|
"Incoterms is required for a non UEE member": "El incoterms es requerido para los clientes extracomunitarios",
|
||||||
"Deleted sales from ticket": "He eliminado las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{deletions}}}",
|
"Deleted sales from ticket": "He eliminado las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{deletions}}}",
|
||||||
"Added sale to ticket": "He añadido la siguiente linea al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}",
|
"Added sale to ticket": "He añadido la siguiente linea al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}",
|
||||||
"Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}} {{ticketWeekly}}",
|
"Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}} {{ticketWeekly}}",
|
||||||
"Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}}) {{ticketWeekly}} ",
|
"Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}}) {{ticketWeekly}} ",
|
||||||
"Changed sale quantity": "He cambiado {{changes}} del ticket [{{ticketId}}]({{{ticketUrl}}}) {{ticketWeekly}}",
|
"Changed sale quantity": "He cambiado {{changes}} del ticket [{{ticketId}}]({{{ticketUrl}}}) {{ticketWeekly}}",
|
||||||
"Changes in sales": "la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}*",
|
"Changes in sales": "la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}*",
|
||||||
"State": "Estado",
|
"State": "Estado",
|
||||||
"regular": "normal",
|
"regular": "normal",
|
||||||
"reserved": "reservado",
|
"reserved": "reservado",
|
||||||
"Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})",
|
"Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})",
|
||||||
"Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}",
|
"Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}",
|
||||||
"MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*",
|
"MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*",
|
||||||
"Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})",
|
"Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})",
|
||||||
"Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})",
|
"Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Change quantity": "{{concept}} cambia de {{oldQuantity}} a {{newQuantity}}",
|
"Change quantity": "{{concept}} cambia de {{oldQuantity}} a {{newQuantity}}",
|
||||||
"Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*, con el tipo de recogida *{{claimPickup}}*",
|
"Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*, con el tipo de recogida *{{claimPickup}}*",
|
||||||
"Claim state has changed to": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *{{newState}}*",
|
"Claim state has changed to": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *{{newState}}*",
|
||||||
"Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}",
|
"Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}",
|
||||||
"ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto",
|
"ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto",
|
||||||
"Distance must be lesser than 4000": "La distancia debe ser inferior a 4000",
|
"Distance must be lesser than 4000": "La distancia debe ser inferior a 4000",
|
||||||
"This ticket is deleted": "Este ticket está eliminado",
|
"This ticket is deleted": "Este ticket está eliminado",
|
||||||
"Unable to clone this travel": "No ha sido posible clonar este travel",
|
"Unable to clone this travel": "No ha sido posible clonar este travel",
|
||||||
"This thermograph id already exists": "La id del termógrafo ya existe",
|
"This thermograph id already exists": "La id del termógrafo ya existe",
|
||||||
"Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante",
|
"Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante",
|
||||||
"ORDER_ALREADY_CONFIRMED": "ORDEN YA CONFIRMADA",
|
"ORDER_ALREADY_CONFIRMED": "ORDEN YA CONFIRMADA",
|
||||||
"Invalid password": "Invalid password",
|
"Invalid password": "Invalid password",
|
||||||
"Password does not meet requirements": "La contraseña no cumple los requisitos",
|
"Password does not meet requirements": "La contraseña no cumple los requisitos",
|
||||||
"Role already assigned": "Rol ya asignado",
|
"Role already assigned": "Rol ya asignado",
|
||||||
"Invalid role name": "Nombre de rol no válido",
|
"Invalid role name": "Nombre de rol no válido",
|
||||||
"Role name must be written in camelCase": "El nombre del rol debe escribirse en camelCase",
|
"Role name must be written in camelCase": "El nombre del rol debe escribirse en camelCase",
|
||||||
"Email already exists": "El correo ya existe",
|
"Email already exists": "El correo ya existe",
|
||||||
"User already exists": "El/La usuario/a ya existe",
|
"User already exists": "El/La usuario/a ya existe",
|
||||||
"Absence change notification on the labour calendar": "Notificación de cambio de ausencia en el calendario laboral",
|
"Absence change notification on the labour calendar": "Notificación de cambio de ausencia en el calendario laboral",
|
||||||
"Record of hours week": "Registro de horas semana {{week}} año {{year}} ",
|
"Record of hours week": "Registro de horas semana {{week}} año {{year}} ",
|
||||||
"Created absence": "El empleado <strong>{{author}}</strong> ha añadido una ausencia de tipo '{{absenceType}}' a <a href='{{{workerUrl}}}'><strong>{{employee}}</strong></a> para el día {{dated}}.",
|
"Created absence": "El empleado <strong>{{author}}</strong> ha añadido una ausencia de tipo '{{absenceType}}' a <a href='{{{workerUrl}}}'><strong>{{employee}}</strong></a> para el día {{dated}}.",
|
||||||
"Deleted absence": "El empleado <strong>{{author}}</strong> ha eliminado una ausencia de tipo '{{absenceType}}' a <a href='{{{workerUrl}}}'><strong>{{employee}}</strong></a> del día {{dated}}.",
|
"Deleted absence": "El empleado <strong>{{author}}</strong> ha eliminado una ausencia de tipo '{{absenceType}}' a <a href='{{{workerUrl}}}'><strong>{{employee}}</strong></a> del día {{dated}}.",
|
||||||
"I have deleted the ticket id": "He eliminado el ticket id [{{id}}]({{{url}}})",
|
"I have deleted the ticket id": "He eliminado el ticket id [{{id}}]({{{url}}})",
|
||||||
"I have restored the ticket id": "He restaurado el ticket id [{{id}}]({{{url}}})",
|
"I have restored the ticket id": "He restaurado el ticket id [{{id}}]({{{url}}})",
|
||||||
"You can only restore a ticket within the first hour after deletion": "Únicamente puedes restaurar el ticket dentro de la primera hora después de su eliminación",
|
"You can only restore a ticket within the first hour after deletion": "Únicamente puedes restaurar el ticket dentro de la primera hora después de su eliminación",
|
||||||
"Changed this data from the ticket": "He cambiado estos datos del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed this data from the ticket": "He cambiado estos datos del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"agencyModeFk": "Agencia",
|
"agencyModeFk": "Agencia",
|
||||||
"clientFk": "Cliente",
|
"clientFk": "Cliente",
|
||||||
"zoneFk": "Zona",
|
"zoneFk": "Zona",
|
||||||
"warehouseFk": "Almacén",
|
"warehouseFk": "Almacén",
|
||||||
"shipped": "F. envío",
|
"shipped": "F. envío",
|
||||||
"landed": "F. entrega",
|
"landed": "F. entrega",
|
||||||
"addressFk": "Consignatario",
|
"addressFk": "Consignatario",
|
||||||
"companyFk": "Empresa",
|
"companyFk": "Empresa",
|
||||||
"agency": "Agencia",
|
"agency": "Agencia",
|
||||||
"delivery": "Reparto",
|
"delivery": "Reparto",
|
||||||
"The social name cannot be empty": "La razón social no puede quedar en blanco",
|
"The social name cannot be empty": "La razón social no puede quedar en blanco",
|
||||||
"The nif cannot be empty": "El NIF no puede quedar en blanco",
|
"The nif cannot be empty": "El NIF no puede quedar en blanco",
|
||||||
"You need to fill sage information before you check verified data": "Debes rellenar la información de sage antes de marcar datos comprobados",
|
"You need to fill sage information before you check verified data": "Debes rellenar la información de sage antes de marcar datos comprobados",
|
||||||
"ASSIGN_ZONE_FIRST": "Asigna una zona primero",
|
"ASSIGN_ZONE_FIRST": "Asigna una zona primero",
|
||||||
"Amount cannot be zero": "El importe no puede ser cero",
|
"Amount cannot be zero": "El importe no puede ser cero",
|
||||||
"Company has to be official": "Empresa inválida",
|
"Company has to be official": "Empresa inválida",
|
||||||
"You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria",
|
"You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria",
|
||||||
"Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas",
|
"Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas",
|
||||||
"The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta",
|
"The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta",
|
||||||
"New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*",
|
"New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*",
|
||||||
"New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*",
|
"New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*",
|
||||||
"Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío",
|
"Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío",
|
||||||
"This BIC already exist.": "Este BIC ya existe.",
|
"This BIC already exist.": "Este BIC ya existe.",
|
||||||
"That item doesn't exists": "Ese artículo no existe",
|
"That item doesn't exists": "Ese artículo no existe",
|
||||||
"There's a new urgent ticket:": "Hay un nuevo ticket urgente:",
|
"There's a new urgent ticket:": "Hay un nuevo ticket urgente:",
|
||||||
"Invalid account": "Cuenta inválida",
|
"Invalid account": "Cuenta inválida",
|
||||||
"Compensation account is empty": "La cuenta para compensar está vacia",
|
"Compensation account is empty": "La cuenta para compensar está vacia",
|
||||||
"This genus already exist": "Este genus ya existe",
|
"This genus already exist": "Este genus ya existe",
|
||||||
"This specie already exist": "Esta especie ya existe",
|
"This specie already exist": "Esta especie ya existe",
|
||||||
"Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})",
|
"Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})",
|
||||||
"None": "Ninguno",
|
"None": "Ninguno",
|
||||||
"The contract was not active during the selected date": "El contrato no estaba activo durante la fecha seleccionada",
|
"The contract was not active during the selected date": "El contrato no estaba activo durante la fecha seleccionada",
|
||||||
"Cannot add more than one '1/2 day vacation'": "No puedes añadir más de un 'Vacaciones 1/2 dia'",
|
"Cannot add more than one '1/2 day vacation'": "No puedes añadir más de un 'Vacaciones 1/2 dia'",
|
||||||
"This document already exists on this ticket": "Este documento ya existe en el ticket",
|
"This document already exists on this ticket": "Este documento ya existe en el ticket",
|
||||||
"Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables",
|
"Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables",
|
||||||
"You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes",
|
"You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes",
|
||||||
"nickname": "nickname",
|
"nickname": "nickname",
|
||||||
"INACTIVE_PROVIDER": "Proveedor inactivo",
|
"INACTIVE_PROVIDER": "Proveedor inactivo",
|
||||||
"This client is not invoiceable": "Este cliente no es facturable",
|
"This client is not invoiceable": "Este cliente no es facturable",
|
||||||
"serial non editable": "Esta serie no permite asignar la referencia",
|
"serial non editable": "Esta serie no permite asignar la referencia",
|
||||||
"Max shipped required": "La fecha límite es requerida",
|
"Max shipped required": "La fecha límite es requerida",
|
||||||
"Can't invoice to future": "No se puede facturar a futuro",
|
"Can't invoice to future": "No se puede facturar a futuro",
|
||||||
"Can't invoice to past": "No se puede facturar a pasado",
|
"Can't invoice to past": "No se puede facturar a pasado",
|
||||||
"This ticket is already invoiced": "Este ticket ya está facturado",
|
"This ticket is already invoiced": "Este ticket ya está facturado",
|
||||||
"A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero",
|
"A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero",
|
||||||
"A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa",
|
"A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa",
|
||||||
"Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes",
|
"Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes",
|
||||||
"Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes",
|
"Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes",
|
||||||
"Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio",
|
"Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio",
|
||||||
"You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito",
|
"You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito",
|
||||||
"You can't change the credit set to zero from a financialBoss": "No puedes cambiar el cŕedito establecido a cero por un jefe de finanzas",
|
"You can't change the credit set to zero from a financialBoss": "No puedes cambiar el cŕedito establecido a cero por un jefe de finanzas",
|
||||||
"Amounts do not match": "Las cantidades no coinciden",
|
"Amounts do not match": "Las cantidades no coinciden",
|
||||||
"The PDF document does not exist": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'",
|
"The PDF document does not exist": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'",
|
||||||
"The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos",
|
"The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos",
|
||||||
"You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días",
|
"You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días",
|
||||||
"The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día",
|
"The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día",
|
||||||
"The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día",
|
"The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día",
|
||||||
"You can not modify is pay method checked": "No se puede modificar el campo método de pago validado",
|
"You can not modify is pay method checked": "No se puede modificar el campo método de pago validado",
|
||||||
"The account size must be exactly 10 characters": "El tamaño de la cuenta debe ser exactamente de 10 caracteres",
|
"The account size must be exactly 10 characters": "El tamaño de la cuenta debe ser exactamente de 10 caracteres",
|
||||||
"Can't transfer claimed sales": "No puedes transferir lineas reclamadas",
|
"Can't transfer claimed sales": "No puedes transferir lineas reclamadas",
|
||||||
"You don't have privileges to create refund": "No tienes permisos para crear un abono",
|
"You don't have privileges to create refund": "No tienes permisos para crear un abono",
|
||||||
"The item is required": "El artículo es requerido",
|
"The item is required": "El artículo es requerido",
|
||||||
"The agency is already assigned to another autonomous": "La agencia ya está asignada a otro autónomo",
|
"The agency is already assigned to another autonomous": "La agencia ya está asignada a otro autónomo",
|
||||||
"date in the future": "Fecha en el futuro",
|
"date in the future": "Fecha en el futuro",
|
||||||
"reference duplicated": "Referencia duplicada",
|
"reference duplicated": "Referencia duplicada",
|
||||||
"This ticket is already a refund": "Este ticket ya es un abono",
|
"This ticket is already a refund": "Este ticket ya es un abono",
|
||||||
"isWithoutNegatives": "Sin negativos",
|
"isWithoutNegatives": "Sin negativos",
|
||||||
"routeFk": "routeFk",
|
"routeFk": "routeFk",
|
||||||
"Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador",
|
"Can't change the password of another worker": "No se puede cambiar la contraseña de otro trabajador",
|
||||||
"No hay un contrato en vigor": "No hay un contrato en vigor",
|
"No hay un contrato en vigor": "No hay un contrato en vigor",
|
||||||
"No se permite fichar a futuro": "No se permite fichar a futuro",
|
"No se permite fichar a futuro": "No se permite fichar a futuro",
|
||||||
"No está permitido trabajar": "No está permitido trabajar",
|
"No está permitido trabajar": "No está permitido trabajar",
|
||||||
"Fichadas impares": "Fichadas impares",
|
"Fichadas impares": "Fichadas impares",
|
||||||
"Descanso diario 12h.": "Descanso diario 12h.",
|
"Descanso diario 12h.": "Descanso diario 12h.",
|
||||||
"Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.",
|
"Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.",
|
||||||
"Dirección incorrecta": "Dirección incorrecta",
|
"Dirección incorrecta": "Dirección incorrecta",
|
||||||
"Modifiable user details only by an administrator": "Detalles de usuario modificables solo por un administrador",
|
"Modifiable user details only by an administrator": "Detalles de usuario modificables solo por un administrador",
|
||||||
"Modifiable password only via recovery or by an administrator": "Contraseña modificable solo a través de la recuperación o por un administrador",
|
"Modifiable password only via recovery or by an administrator": "Contraseña modificable solo a través de la recuperación o por un administrador",
|
||||||
"Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente",
|
"Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente",
|
||||||
"This route does not exists": "Esta ruta no existe",
|
"This route does not exists": "Esta ruta no existe",
|
||||||
"Claim pickup order sent": "Reclamación Orden de recogida enviada [{{claimId}}]({{{claimUrl}}}) al cliente *{{clientName}}*",
|
"Claim pickup order sent": "Reclamación Orden de recogida enviada [{{claimId}}]({{{claimUrl}}}) al cliente *{{clientName}}*",
|
||||||
"You don't have grant privilege": "No tienes privilegios para dar privilegios",
|
"You don't have grant privilege": "No tienes privilegios para dar privilegios",
|
||||||
"You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario",
|
"You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario",
|
||||||
"Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) fusionado con [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})",
|
"Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) fusionado con [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})",
|
||||||
"Already has this status": "Ya tiene este estado",
|
"Already has this status": "Ya tiene este estado",
|
||||||
"There aren't records for this week": "No existen registros para esta semana",
|
"There aren't records for this week": "No existen registros para esta semana",
|
||||||
"Empty data source": "Origen de datos vacio",
|
"Empty data source": "Origen de datos vacio",
|
||||||
"App locked": "Aplicación bloqueada por el usuario {{userId}}",
|
"App locked": "Aplicación bloqueada por el usuario {{userId}}",
|
||||||
"Email verify": "Correo de verificación",
|
"Email verify": "Correo de verificación",
|
||||||
"Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment",
|
"Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment",
|
||||||
"Receipt's bank was not found": "No se encontró el banco del recibo",
|
"Receipt's bank was not found": "No se encontró el banco del recibo",
|
||||||
"This receipt was not compensated": "Este recibo no ha sido compensado",
|
"This receipt was not compensated": "Este recibo no ha sido compensado",
|
||||||
"Client's email was not found": "No se encontró el email del cliente",
|
"Client's email was not found": "No se encontró el email del cliente",
|
||||||
"Negative basis": "Base negativa",
|
"Negative basis": "Base negativa",
|
||||||
"This worker code already exists": "Este codigo de trabajador ya existe",
|
"This worker code already exists": "Este codigo de trabajador ya existe",
|
||||||
"This personal mail already exists": "Este correo personal ya existe",
|
"This personal mail already exists": "Este correo personal ya existe",
|
||||||
"This worker already exists": "Este trabajador ya existe",
|
"This worker already exists": "Este trabajador ya existe",
|
||||||
"App name does not exist": "El nombre de aplicación no es válido",
|
"App name does not exist": "El nombre de aplicación no es válido",
|
||||||
"Try again": "Vuelve a intentarlo",
|
"Try again": "Vuelve a intentarlo",
|
||||||
"Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9",
|
"Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9",
|
||||||
"Failed to upload delivery note": "Error al subir albarán {{id}}",
|
"Failed to upload delivery note": "Error al subir albarán {{id}}",
|
||||||
"The DOCUWARE PDF document does not exists": "El documento PDF Docuware no existe",
|
"The DOCUWARE PDF document does not exists": "El documento PDF Docuware no existe",
|
||||||
"It is not possible to modify tracked sales": "No es posible modificar líneas de pedido que se hayan empezado a preparar",
|
"It is not possible to modify tracked sales": "No es posible modificar líneas de pedido que se hayan empezado a preparar",
|
||||||
"It is not possible to modify sales that their articles are from Floramondo": "No es posible modificar líneas de pedido cuyos artículos sean de Floramondo",
|
"It is not possible to modify sales that their articles are from Floramondo": "No es posible modificar líneas de pedido cuyos artículos sean de Floramondo",
|
||||||
"It is not possible to modify cloned sales": "No es posible modificar líneas de pedido clonadas",
|
"It is not possible to modify cloned sales": "No es posible modificar líneas de pedido clonadas",
|
||||||
"A supplier with the same name already exists. Change the country.": "Un proveedor con el mismo nombre ya existe. Cambie el país.",
|
"A supplier with the same name already exists. Change the country.": "Un proveedor con el mismo nombre ya existe. Cambie el país.",
|
||||||
"There is no assigned email for this client": "No hay correo asignado para este cliente",
|
"There is no assigned email for this client": "No hay correo asignado para este cliente",
|
||||||
"Exists an invoice with a future date": "Existe una factura con fecha posterior",
|
"Exists an invoice with a future date": "Existe una factura con fecha posterior",
|
||||||
"Invoice date can't be less than max date": "La fecha de factura no puede ser inferior a la fecha límite",
|
"Invoice date can't be less than max date": "La fecha de factura no puede ser inferior a la fecha límite",
|
||||||
"Warehouse inventory not set": "El almacén inventario no está establecido",
|
"Warehouse inventory not set": "El almacén inventario no está establecido",
|
||||||
"This locker has already been assigned": "Esta taquilla ya ha sido asignada",
|
"This locker has already been assigned": "Esta taquilla ya ha sido asignada",
|
||||||
"Tickets with associated refunds": "No se pueden borrar tickets con abonos asociados. Este ticket está asociado al abono Nº %s",
|
"Tickets with associated refunds": "No se pueden borrar tickets con abonos asociados. Este ticket está asociado al abono Nº %s",
|
||||||
"Not exist this branch": "La rama no existe",
|
"Not exist this branch": "La rama no existe",
|
||||||
"This ticket cannot be signed because it has not been boxed": "Este ticket no puede firmarse porque no ha sido encajado",
|
"This ticket cannot be signed because it has not been boxed": "Este ticket no puede firmarse porque no ha sido encajado",
|
||||||
"Collection does not exist": "La colección no existe",
|
"Collection does not exist": "La colección no existe",
|
||||||
"Cannot obtain exclusive lock": "No se puede obtener un bloqueo exclusivo",
|
"Cannot obtain exclusive lock": "No se puede obtener un bloqueo exclusivo",
|
||||||
"Insert a date range": "Inserte un rango de fechas",
|
"Insert a date range": "Inserte un rango de fechas",
|
||||||
"Added observation": "{{user}} añadió esta observacion: {{text}} {{defaulterId}} ({{{defaulterUrl}}})",
|
"Added observation": "{{user}} añadió esta observacion: {{text}} {{defaulterId}} ({{{defaulterUrl}}})",
|
||||||
"Comment added to client": "Observación añadida al cliente {{clientFk}}",
|
"Comment added to client": "Observación añadida al cliente {{clientFk}}",
|
||||||
"Invalid auth code": "Código de verificación incorrecto",
|
"Invalid auth code": "Código de verificación incorrecto",
|
||||||
"Invalid or expired verification code": "Código de verificación incorrecto o expirado",
|
"Invalid or expired verification code": "Código de verificación incorrecto o expirado",
|
||||||
"Cannot create a new claimBeginning from a different ticket": "No se puede crear una línea de reclamación de un ticket diferente al origen",
|
"Cannot create a new claimBeginning from a different ticket": "No se puede crear una línea de reclamación de un ticket diferente al origen",
|
||||||
"company": "Compañía",
|
"company": "Compañía",
|
||||||
"country": "País",
|
"country": "País",
|
||||||
"clientId": "Id cliente",
|
"clientId": "Id cliente",
|
||||||
"clientSocialName": "Cliente",
|
"clientSocialName": "Cliente",
|
||||||
"amount": "Importe",
|
"amount": "Importe",
|
||||||
"taxableBase": "Base",
|
"taxableBase": "Base",
|
||||||
"ticketFk": "Id ticket",
|
"ticketFk": "Id ticket",
|
||||||
"isActive": "Activo",
|
"isActive": "Activo",
|
||||||
"hasToInvoice": "Facturar",
|
"hasToInvoice": "Facturar",
|
||||||
"isTaxDataChecked": "Datos comprobados",
|
"isTaxDataChecked": "Datos comprobados",
|
||||||
"comercialId": "Id comercial",
|
"comercialId": "Id comercial",
|
||||||
"comercialName": "Comercial",
|
"comercialName": "Comercial",
|
||||||
"Pass expired": "La contraseña ha caducado, cambiela desde Salix",
|
"Pass expired": "La contraseña ha caducado, cambiela desde Salix",
|
||||||
"Invalid NIF for VIES": "Invalid NIF for VIES",
|
"Invalid NIF for VIES": "Invalid NIF for VIES",
|
||||||
"Ticket does not exist": "Este ticket no existe",
|
"Ticket does not exist": "Este ticket no existe",
|
||||||
"Ticket is already signed": "Este ticket ya ha sido firmado",
|
"Ticket is already signed": "Este ticket ya ha sido firmado",
|
||||||
"Authentication failed": "Autenticación fallida",
|
"Authentication failed": "Autenticación fallida",
|
||||||
"You can't use the same password": "No puedes usar la misma contraseña",
|
"You can't use the same password": "No puedes usar la misma contraseña",
|
||||||
"You can only add negative amounts in refund tickets": "Solo se puede añadir cantidades negativas en tickets abono",
|
"You can only add negative amounts in refund tickets": "Solo se puede añadir cantidades negativas en tickets abono",
|
||||||
"Fecha fuera de rango": "Fecha fuera de rango",
|
"Fecha fuera de rango": "Fecha fuera de rango",
|
||||||
"Error while generating PDF": "Error al generar PDF",
|
"Error while generating PDF": "Error al generar PDF",
|
||||||
"Error when sending mail to client": "Error al enviar el correo al cliente",
|
"Error when sending mail to client": "Error al enviar el correo al cliente",
|
||||||
"Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico",
|
"Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico",
|
||||||
"The renew period has not been exceeded": "El periodo de renovación no ha sido superado",
|
"The renew period has not been exceeded": "El periodo de renovación no ha sido superado",
|
||||||
"Valid priorities": "Prioridades válidas: %d",
|
"Valid priorities": "Prioridades válidas: %d",
|
||||||
"hasAnyNegativeBase": "Base negativa para los tickets: {{ticketsIds}}",
|
"hasAnyNegativeBase": "Base negativa para los tickets: {{ticketsIds}}",
|
||||||
"hasAnyPositiveBase": "Base positivas para los tickets: {{ticketsIds}}",
|
"hasAnyPositiveBase": "Base positivas para los tickets: {{ticketsIds}}",
|
||||||
"You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado",
|
"You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado",
|
||||||
"This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s",
|
"This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s",
|
||||||
"The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias",
|
"The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias",
|
||||||
"You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado",
|
"You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado",
|
||||||
"This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado",
|
"This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado",
|
||||||
"You don't have enough privileges.": "No tienes suficientes permisos.",
|
"You don't have enough privileges.": "No tienes suficientes permisos.",
|
||||||
"This ticket is locked": "Este ticket está bloqueado.",
|
"This ticket is locked": "Este ticket está bloqueado.",
|
||||||
"This ticket is not editable.": "Este ticket no es editable.",
|
"This ticket is not editable.": "Este ticket no es editable.",
|
||||||
"The ticket doesn't exist.": "No existe el ticket.",
|
"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",
|
"Street should be uppercase": "La dirección fiscal debe ir en mayúscula",
|
||||||
"Ticket without Route": "Ticket sin ruta",
|
"Ticket without Route": "Ticket sin ruta",
|
||||||
"Select a different client": "Seleccione un cliente distinto",
|
"Select a different client": "Seleccione un cliente distinto",
|
||||||
"Fill all the fields": "Rellene todos los campos",
|
"Fill all the fields": "Rellene todos los campos",
|
||||||
"The response is not a PDF": "La respuesta no es un PDF",
|
"The response is not a PDF": "La respuesta no es un PDF",
|
||||||
"Booking completed": "Reserva completada",
|
"Booking completed": "Reserva completada",
|
||||||
"The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación",
|
"The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación",
|
||||||
"The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada",
|
"The notification subscription of this worker cant be modified": "La subscripción a la notificación de este trabajador no puede ser modificada",
|
||||||
"User disabled": "Usuario desactivado",
|
"User disabled": "Usuario desactivado",
|
||||||
"The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima",
|
"The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima",
|
||||||
"quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima",
|
"quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima",
|
||||||
"Cannot past travels with entries": "No se pueden pasar envíos con entradas",
|
"Cannot past travels with entries": "No se pueden pasar envíos con entradas",
|
||||||
"It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}",
|
"It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}",
|
||||||
"This claim has been updated": "La reclamación con Id: {{claimId}}, ha sido actualizada",
|
"This claim has been updated": "La reclamación con Id: {{claimId}}, ha sido actualizada",
|
||||||
"This user does not have an assigned tablet": "Este usuario no tiene tablet asignada",
|
"This user does not have an assigned tablet": "Este usuario no tiene tablet asignada",
|
||||||
"Field are invalid": "El campo '{{tag}}' no es válido",
|
"Field are invalid": "El campo '{{tag}}' no es válido",
|
||||||
"Incorrect pin": "Pin incorrecto.",
|
"Incorrect pin": "Pin incorrecto.",
|
||||||
"You already have the mailAlias": "Ya tienes este alias de correo",
|
"You already have the mailAlias": "Ya tienes este alias de correo",
|
||||||
"The alias cant be modified": "Este alias de correo no puede ser modificado",
|
"The alias cant be modified": "Este alias de correo no puede ser modificado",
|
||||||
"No tickets to invoice": "No hay tickets para facturar que cumplan los requisitos de facturación",
|
"No tickets to invoice": "No hay tickets para facturar que cumplan los requisitos de facturación",
|
||||||
"this warehouse has not dms": "El Almacén no acepta documentos",
|
"this warehouse has not dms": "El Almacén no acepta documentos",
|
||||||
"This ticket already has a cmr saved": "Este ticket ya tiene un cmr guardado",
|
"This ticket already has a cmr saved": "Este ticket ya tiene un cmr guardado",
|
||||||
"Name should be uppercase": "El nombre debe ir en mayúscula",
|
"Name should be uppercase": "El nombre debe ir en mayúscula",
|
||||||
"Bank entity must be specified": "La entidad bancaria es obligatoria",
|
"Bank entity must be specified": "La entidad bancaria es obligatoria",
|
||||||
"An email is necessary": "Es necesario un email",
|
"An email is necessary": "Es necesario un email",
|
||||||
"You cannot update these fields": "No puedes actualizar estos campos",
|
"You cannot update these fields": "No puedes actualizar estos campos",
|
||||||
"CountryFK cannot be empty": "El país no puede estar vacío",
|
"CountryFK cannot be empty": "El país no puede estar vacío",
|
||||||
"Cmr file does not exist": "El archivo del cmr no existe",
|
"Cmr file does not exist": "El archivo del cmr no existe",
|
||||||
"You are not allowed to modify the alias": "No estás autorizado a modificar el alias",
|
"You are not allowed to modify the alias": "No estás autorizado a modificar el alias",
|
||||||
"The address of the customer must have information about Incoterms and Customs Agent": "El consignatario del cliente debe tener informado Incoterms y Agente de aduanas",
|
"The address of the customer must have information about Incoterms and Customs Agent": "El consignatario del cliente debe tener informado Incoterms y Agente de aduanas",
|
||||||
"No invoice series found for these parameters": "No se encontró una serie para estos parámetros",
|
"No invoice series found for these parameters": "No se encontró una serie para estos parámetros",
|
||||||
"The line could not be marked": "La linea no puede ser marcada",
|
"The line could not be marked": "La linea no puede ser marcada",
|
||||||
"Through this procedure, it is not possible to modify the password of users with verified email": "Mediante este procedimiento, no es posible modificar la contraseña de usuarios con correo verificado",
|
"Through this procedure, it is not possible to modify the password of users with verified email": "Mediante este procedimiento, no es posible modificar la contraseña de usuarios con correo verificado",
|
||||||
"They're not your subordinate": "No es tu subordinado/a.",
|
"They're not your subordinate": "No es tu subordinado/a.",
|
||||||
"No results found": "No se han encontrado resultados",
|
"No results found": "No se han encontrado resultados",
|
||||||
"InvoiceIn is already booked": "La factura recibida está contabilizada",
|
"InvoiceIn is already booked": "La factura recibida está contabilizada",
|
||||||
"This workCenter is already assigned to this agency": "Este centro de trabajo ya está asignado a esta agencia",
|
"This workCenter is already assigned to this agency": "Este centro de trabajo ya está asignado a esta agencia",
|
||||||
"Select ticket or client": "Elija un ticket o un client",
|
"Select ticket or client": "Elija un ticket o un client",
|
||||||
"It was not able to create the invoice": "No se pudo crear la factura",
|
"It was not able to create the invoice": "No se pudo crear la factura",
|
||||||
"Incoterms and Customs agent are required for a non UEE member": "Se requieren Incoterms y agente de aduanas para un no miembro de la UEE",
|
"Incoterms and Customs agent are required for a non UEE member": "Se requieren Incoterms y agente de aduanas para un no miembro de la UEE",
|
||||||
"You can not use the same password": "No puedes usar la misma contraseña",
|
"You can not use the same password": "No puedes usar la misma contraseña",
|
||||||
"This PDA is already assigned to another user": "Este PDA ya está asignado a otro usuario",
|
"This PDA is already assigned to another user": "Este PDA ya está asignado a otro usuario",
|
||||||
"You can only have one PDA": "Solo puedes tener un PDA",
|
"You can only have one PDA": "Solo puedes tener un PDA",
|
||||||
"The invoices have been created but the PDFs could not be generated": "Se ha facturado pero no se ha podido generar el PDF",
|
"The invoices have been created but the PDFs could not be generated": "Se ha facturado pero no se ha podido generar el PDF",
|
||||||
"It has been invoiced but the PDF of refund not be generated": "Se ha facturado pero no se ha podido generar el PDF del abono",
|
"It has been invoiced but the PDF of refund not be generated": "Se ha facturado pero no se ha podido generar el PDF del abono",
|
||||||
"Payment method is required": "El método de pago es obligatorio",
|
"Payment method is required": "El método de pago es obligatorio",
|
||||||
"Cannot send mail": "Não é possível enviar o email",
|
"Cannot send mail": "Não é possível enviar o email",
|
||||||
"CONSTRAINT `supplierAccountTooShort` failed for `vn`.`supplier`": "La cuenta debe tener exactamente 10 dígitos",
|
"CONSTRAINT `supplierAccountTooShort` failed for `vn`.`supplier`": "La cuenta debe tener exactamente 10 dígitos",
|
||||||
"The sale not exists in the item shelving": "La venta no existe en la estantería del artículo",
|
"The sale not exists in the item shelving": "La venta no existe en la estantería del artículo",
|
||||||
"The entry not have stickers": "La entrada no tiene etiquetas",
|
"The entry not have stickers": "La entrada no tiene etiquetas",
|
||||||
"Too many records": "Demasiados registros",
|
"Too many records": "Demasiados registros",
|
||||||
"Original invoice not found": "Factura original no encontrada",
|
"Original invoice not found": "Factura original no encontrada",
|
||||||
"The entry has no lines or does not exist": "La entrada no tiene lineas o no existe",
|
"The entry has no lines or does not exist": "La entrada no tiene lineas o no existe",
|
||||||
"Weight already set": "El peso ya está establecido",
|
"Weight already set": "El peso ya está establecido",
|
||||||
"This ticket is not allocated to your department": "Este ticket no está asignado a tu departamento",
|
"This ticket is not allocated to your department": "Este ticket no está asignado a tu departamento",
|
||||||
"There is already a tray with the same height": "Ya existe una bandeja con la misma altura",
|
"There is already a tray with the same height": "Ya existe una bandeja con la misma altura",
|
||||||
"The height must be greater than 50cm": "La altura debe ser superior a 50cm",
|
"The height must be greater than 50cm": "La altura debe ser superior a 50cm",
|
||||||
"The maximum height of the wagon is 200cm": "La altura máxima es 200cm",
|
"The maximum height of the wagon is 200cm": "La altura máxima es 200cm",
|
||||||
"The entry does not have stickers": "La entrada no tiene etiquetas",
|
"The entry does not have stickers": "La entrada no tiene etiquetas",
|
||||||
"This buyer has already made a reservation for this date": "Este comprador ya ha hecho una reserva para esta fecha",
|
"This buyer has already made a reservation for this date": "Este comprador ya ha hecho una reserva para esta fecha",
|
||||||
"No valid travel thermograph found": "No se encontró un termógrafo válido",
|
"No valid travel thermograph found": "No se encontró un termógrafo válido",
|
||||||
"The quantity claimed cannot be greater than the quantity of the line": "La cantidad reclamada no puede ser mayor que la cantidad de la línea",
|
"The quantity claimed cannot be greater than the quantity of the line": "La cantidad reclamada no puede ser mayor que la cantidad de la línea",
|
||||||
"type cannot be blank": "Se debe rellenar el tipo",
|
"type cannot be blank": "Se debe rellenar el tipo",
|
||||||
"There are tickets for this area, delete them first": "Hay tickets para esta sección, borralos primero",
|
"There are tickets for this area, delete them first": "Hay tickets para esta sección, borralos primero",
|
||||||
"There is no company associated with that warehouse": "No hay ninguna empresa asociada a ese almacén",
|
"There is no company associated with that warehouse": "No hay ninguna empresa asociada a ese almacén",
|
||||||
"You do not have permission to modify the booked field": "No tienes permisos para modificar el campo contabilizada",
|
"You do not have permission to modify the booked field": "No tienes permisos para modificar el campo contabilizada",
|
||||||
"ticketLostExpedition": "El ticket [{{ticketId}}]({{{ticketUrl}}}) tiene la siguiente expedición perdida:{{ expeditionId }}",
|
"ticketLostExpedition": "El ticket [{{ticketId}}]({{{ticketUrl}}}) tiene la siguiente expedición perdida:{{ expeditionId }}",
|
||||||
"The web user's email already exists": "El correo del usuario web ya existe",
|
"The web user's email already exists": "El correo del usuario web ya existe",
|
||||||
"Sales already moved": "Ya han sido transferidas",
|
"Sales already moved": "Ya han sido transferidas",
|
||||||
"The raid information is not correct": "La información de la redada no es correcta",
|
"The raid information is not correct": "La información de la redada no es correcta",
|
||||||
"An item type with the same code already exists": "Un tipo con el mismo código ya existe",
|
"An item type with the same code already exists": "Un tipo con el mismo código ya existe",
|
||||||
"Holidays to past days not available": "Las vacaciones a días pasados no están disponibles",
|
"Holidays to past days not available": "Las vacaciones a días pasados no están disponibles",
|
||||||
"All tickets have a route order": "Todos los tickets tienen orden de ruta",
|
"All tickets have a route order": "Todos los tickets tienen orden de ruta",
|
||||||
"There are tickets to be invoiced": "La zona tiene tickets por facturar",
|
"There are tickets to be invoiced": "La zona tiene tickets por facturar",
|
||||||
"Incorrect delivery order alert on route": "Alerta de orden de entrega incorrecta en ruta: {{ route }} zona: {{ zone }}",
|
"Incorrect delivery order alert on route": "Alerta de orden de entrega incorrecta en ruta: {{ route }} zona: {{ zone }}",
|
||||||
"Ticket has been delivered out of order": "El ticket {{ticket}} {{{fullUrl}}} no ha sido entregado en su orden.",
|
"Ticket has been delivered out of order": "El ticket {{ticket}} {{{fullUrl}}} no ha sido entregado en su orden.",
|
||||||
"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"
|
||||||
|
}
|
|
@ -74,66 +74,77 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const worker = await models.Worker.findOne({
|
|
||||||
where: {id: userId}
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
const obsevationType = await models.ObservationType.findOne({
|
|
||||||
where: {code: 'salesPerson'}
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
const agencyMode = await models.AgencyMode.findOne({
|
|
||||||
where: {code: 'refund'}
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
const state = await models.State.findOne({
|
|
||||||
where: {code: 'DELIVERED'}
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
const zone = await models.Zone.findOne({
|
|
||||||
where: {agencyModeFk: agencyMode.id}
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
const claim = await models.Claim.findOne(filter, myOptions);
|
const claim = await models.Claim.findOne(filter, myOptions);
|
||||||
const today = Date.vnNew();
|
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);
|
||||||
|
const agencyMode = await models.AgencyMode.findOne({
|
||||||
|
where: {code: 'refund'}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
agencyModeFk = agencyMode.id;
|
||||||
|
nickname = `Abono del: ${claim.ticketFk}`;
|
||||||
|
} else {
|
||||||
|
discountValue = 100;
|
||||||
|
packages = 1;
|
||||||
|
state = await models.State.findOne({
|
||||||
|
where: {code: 'WAITING_FOR_PICKUP'}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
nickname = `Recogida pendiente del: ${claim.ticketFk}`;
|
||||||
|
|
||||||
|
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.shipped,
|
||||||
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({
|
||||||
return await Self.app.models.Sale.create(formatedSales, options);
|
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;
|
||||||
|
});
|
||||||
|
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) {
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -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({shipped: 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);
|
||||||
|
});
|
||||||
|
});
|
|
@ -40,21 +40,24 @@ module.exports = Self => {
|
||||||
const stmt = new ParameterizedSQL(
|
const stmt = new ParameterizedSQL(
|
||||||
`SELECT *
|
`SELECT *
|
||||||
FROM (
|
FROM (
|
||||||
SELECT
|
SELECT
|
||||||
ce.id,
|
ce.id,
|
||||||
ce.claimFk,
|
ce.claimFk,
|
||||||
s.itemFk,
|
s.itemFk,
|
||||||
s.ticketFk,
|
s.ticketFk,
|
||||||
ce.claimDestinationFk,
|
ce.claimDestinationFk,
|
||||||
t.landed,
|
t.landed,
|
||||||
s.quantity,
|
s.quantity,
|
||||||
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`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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',
|
{
|
||||||
type: 'number',
|
arg: 'id',
|
||||||
description: 'The claim id',
|
type: 'number',
|
||||||
http: {source: 'path'}
|
description: 'The claim id',
|
||||||
}],
|
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},
|
||||||
relation: 'claimDestination',
|
include: [
|
||||||
fields: ['addressFk']
|
{
|
||||||
},
|
relation: 'claimDestination',
|
||||||
where: {claimFk: claimFk}
|
scope: {fields: ['addressFk']}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
|
|
@ -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,84 +49,73 @@ 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({});
|
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
|
||||||
|
|
||||||
try {
|
claimEnds = await importTicket(ticketId, claimId, userId, options);
|
||||||
const options = {transaction: tx};
|
|
||||||
|
|
||||||
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
|
for (const claimEnd of claimEnds)
|
||||||
|
await claimEnd.updateAttributes({claimDestinationFk: trashDestination}, options);
|
||||||
|
|
||||||
claimEnds = await importTicket(ticketId, claimId, userId, options);
|
let claimBefore = await models.Claim.findById(claimId, null, options);
|
||||||
|
await models.Claim.regularizeClaim(ctx, claimId, options);
|
||||||
|
let claimAfter = await models.Claim.findById(claimId, null, options);
|
||||||
|
|
||||||
for (const claimEnd of claimEnds)
|
expect(claimBefore.claimStateFk).toEqual(pendentState);
|
||||||
await claimEnd.updateAttributes({claimDestinationFk: trashDestination}, options);
|
expect(claimAfter.claimStateFk).toEqual(resolvedState);
|
||||||
|
|
||||||
let claimBefore = await models.Claim.findById(claimId, null, options);
|
|
||||||
await models.Claim.regularizeClaim(ctx, claimId, 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(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);
|
||||||
|
|
||||||
await models.Claim.regularizeClaim(ctx, claimId, options);
|
const sale = await models.Sale.findOne({
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'ticket',
|
||||||
|
scope: {
|
||||||
|
fields: ['clientFk', 'companyFk']
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
where: {id: claimEnds[0].saleFk}
|
||||||
|
}, options);
|
||||||
|
|
||||||
expect(chatModel.sendCheckingPresence).toHaveBeenCalledWith(ctx, 18, 'Bueno');
|
await models.Claim.regularizeClaim(ctx, claimId, options);
|
||||||
expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(4);
|
|
||||||
|
|
||||||
await tx.rollback();
|
const ticket = await models.Ticket.findOne({
|
||||||
} catch (e) {
|
where: {
|
||||||
await tx.rollback();
|
addressFk: addressMissingFk,
|
||||||
throw e;
|
companyFk: sale.ticket().companyFk,
|
||||||
}
|
warehouseFk: warehouseFk,
|
||||||
});
|
shipped: {between: [minDate, maxDate]},
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}, options);
|
||||||
|
|
||||||
try {
|
const claimBeginning = await models.ClaimBeginning.findOne({
|
||||||
const options = {transaction: tx};
|
where: {
|
||||||
|
claimFk: claimId
|
||||||
|
}
|
||||||
|
}, options);
|
||||||
|
|
||||||
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
|
expect(missingSale.quantity).toBe(claimBeginning.quantity);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
"Claim": {
|
"Claim": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"ClaimConfig": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"ClaimContainer": {
|
"ClaimContainer": {
|
||||||
"dataSource": "claimStorage"
|
"dataSource": "claimStorage"
|
||||||
},
|
},
|
||||||
|
@ -43,5 +46,5 @@
|
||||||
},
|
},
|
||||||
"ClaimObservation": {
|
"ClaimObservation": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,6 +41,11 @@
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "ClaimDestination",
|
"model": "ClaimDestination",
|
||||||
"foreignKey": "claimDestinationFk"
|
"foreignKey": "claimDestinationFk"
|
||||||
|
},
|
||||||
|
"shelving": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Shelving",
|
||||||
|
"foreignKey": "shelvingFk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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},
|
||||||
|
|
|
@ -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,33 +61,30 @@ 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: {
|
relation: 'autonomy'
|
||||||
relation: 'autonomy'
|
}
|
||||||
}
|
}, options);
|
||||||
}, options);
|
|
||||||
|
|
||||||
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(province.autonomy().hasDailyInvoice).toBeTruthy();
|
expect(account.roleFk).toEqual(supplierRole.id);
|
||||||
expect(account.name).toEqual(newAccount.userName);
|
expect(province.autonomy().hasDailyInvoice).toBeTruthy();
|
||||||
expect(client.id).toEqual(account.id);
|
expect(account.name).toEqual(newAccount.userName);
|
||||||
expect(client.name).toEqual(newAccount.name);
|
expect(client.id).toEqual(account.id);
|
||||||
expect(client.email).toEqual(newAccount.email);
|
expect(client.name).toEqual(newAccount.name);
|
||||||
expect(client.fi).toEqual(newAccount.fi);
|
expect(client.email).toEqual(newAccount.email);
|
||||||
expect(client.socialName).toEqual(newAccount.socialName);
|
expect(client.fi).toEqual(newAccount.fi);
|
||||||
expect(client.businessTypeFk).toEqual(newAccount.businessTypeFk);
|
expect(client.socialName).toEqual(newAccount.socialName);
|
||||||
expect(client.hasDailyInvoice).toBeTruthy();
|
expect(client.businessTypeFk).toEqual(newAccount.businessTypeFk);
|
||||||
} catch (e) {
|
expect(client.hasDailyInvoice).toBeTruthy();
|
||||||
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,22 +97,20 @@ 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: {
|
relation: 'autonomy'
|
||||||
relation: 'autonomy'
|
}
|
||||||
}
|
}, 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(province.autonomy.hasDailyInvoice).toBeFalsy();
|
expect(vnUser.roleFk).toEqual(customerRole.id);
|
||||||
expect(client.hasDailyInvoice).toBeFalsy();
|
expect(province.autonomy.hasDailyInvoice).toBeFalsy();
|
||||||
} catch (e) {
|
expect(client.hasDailyInvoice).toBeFalsy();
|
||||||
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() => {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.validatesUniquenessOf('code', {
|
||||||
|
message: `The code already exists`
|
||||||
|
});
|
||||||
|
};
|
|
@ -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`
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const smtp = require('vn-print/core/smtp');
|
const smtp = require('vn-print/core/smtp');
|
||||||
const config = require('vn-print/core/config');
|
const config = require('vn-print/core/config');
|
||||||
|
const Email = require('vn-print/core/email');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('closeAll', {
|
Self.remoteMethodCtx('closeAll', {
|
||||||
|
@ -44,8 +45,7 @@ module.exports = Self => {
|
||||||
LIMIT 1`, [toDate, toDate], myOptions);
|
LIMIT 1`, [toDate, toDate], myOptions);
|
||||||
|
|
||||||
await Self.rawSql(`
|
await Self.rawSql(`
|
||||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close;
|
CREATE OR REPLACE TEMPORARY TABLE tmp.ticket_close
|
||||||
CREATE TEMPORARY TABLE tmp.ticket_close
|
|
||||||
ENGINE = MEMORY
|
ENGINE = MEMORY
|
||||||
WITH wTickets AS(
|
WITH wTickets AS(
|
||||||
SELECT t.id ticketFk
|
SELECT t.id ticketFk
|
||||||
|
@ -63,11 +63,12 @@ module.exports = Self => {
|
||||||
FROM wTicketsTracking wt
|
FROM wTicketsTracking wt
|
||||||
JOIN ticketTracking tt ON tt.id = wt.maxTracking
|
JOIN ticketTracking tt ON tt.id = wt.maxTracking
|
||||||
) SELECT tls.ticketFk,
|
) SELECT tls.ticketFk,
|
||||||
t.clientFk,
|
t.clientFk clientId,
|
||||||
c.name clientName,
|
c.name clientName,
|
||||||
c.email recipient,
|
c.email recipient,
|
||||||
|
c.isToBeMailed,
|
||||||
eu.email salesPersonEmail,
|
eu.email salesPersonEmail,
|
||||||
t.addressFk,
|
t.addressFk addressId,
|
||||||
c.hasDailyInvoice,
|
c.hasDailyInvoice,
|
||||||
c.hasToInvoiceByAddress,
|
c.hasToInvoiceByAddress,
|
||||||
t.totalWithVat,
|
t.totalWithVat,
|
||||||
|
@ -79,7 +80,7 @@ module.exports = Self => {
|
||||||
JOIN agencyMode am ON am.id = t.agencyModeFk
|
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||||
JOIN client c ON c.id = t.clientFk
|
JOIN client c ON c.id = t.clientFk
|
||||||
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
|
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
|
||||||
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered'));
|
WHERE al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered');
|
||||||
CALL ticket_close();
|
CALL ticket_close();
|
||||||
`, [dateFrom, dateTo], myOptions);
|
`, [dateFrom, dateTo], myOptions);
|
||||||
|
|
||||||
|
@ -98,21 +99,27 @@ module.exports = Self => {
|
||||||
AND tob.id IS NULL
|
AND tob.id IS NULL
|
||||||
AND t.routeFk`, [dateFrom, dateTo], myOptions);
|
AND t.routeFk`, [dateFrom, dateTo], myOptions);
|
||||||
|
|
||||||
const [clients] = await Self.rawSql(`
|
const clients = await Self.rawSql(`
|
||||||
SELECT clientFk clientId,
|
SELECT *,
|
||||||
clientName,
|
|
||||||
recipient,
|
|
||||||
salesPersonEmail,
|
|
||||||
addressFk addressId,
|
|
||||||
companyFk,
|
|
||||||
SUM(totalWithVat) total,
|
SUM(totalWithVat) total,
|
||||||
'quick' serialType
|
'quick' serialType
|
||||||
FROM tmp.ticket_close
|
FROM tmp.ticket_close
|
||||||
WHERE hasDailyInvoice
|
WHERE hasDailyInvoice
|
||||||
GROUP BY IF (hasToInvoiceByAddress, addressFk, clientFk), companyFk
|
GROUP BY IF (hasToInvoiceByAddress, addressId, clientId), companyFk
|
||||||
HAVING total > 0;
|
HAVING total > 0
|
||||||
|
`, [], myOptions);
|
||||||
|
|
||||||
|
const [ticketsToMail] = await Self.rawSql(`
|
||||||
|
SELECT *
|
||||||
|
FROM tmp.ticket_close
|
||||||
|
WHERE NOT hasDailyInvoice
|
||||||
|
AND isToBeMailed
|
||||||
|
AND salesPersonEmail IS NOT NULL
|
||||||
|
AND salesPersonEmail <> ''
|
||||||
|
AND recipient IS NOT NULL
|
||||||
|
AND recipient <> '';
|
||||||
DROP TEMPORARY TABLE tmp.ticket_close;
|
DROP TEMPORARY TABLE tmp.ticket_close;
|
||||||
`, [], myOptions);
|
`, [], myOptions);
|
||||||
|
|
||||||
if (tx)
|
if (tx)
|
||||||
await tx.commit();
|
await tx.commit();
|
||||||
|
@ -130,21 +137,23 @@ module.exports = Self => {
|
||||||
if (id)
|
if (id)
|
||||||
await Self.app.models.InvoiceOut.makePdfAndNotify(ctx, id, null, nestedTransaction);
|
await Self.app.models.InvoiceOut.makePdfAndNotify(ctx, id, null, nestedTransaction);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await Self.rawSql(`
|
await handleInvoicingError(error, client, failedClients);
|
||||||
INSERT INTO util.debug (variable, value)
|
}
|
||||||
VALUES ('invoicingTicketError', ?)
|
}
|
||||||
`, [client.clientId + ' - ' + error]);
|
|
||||||
|
|
||||||
if (error.responseCode == 450) {
|
for (const ticket of ticketsToMail) {
|
||||||
await invalidEmail(client);
|
const args = {
|
||||||
continue;
|
id: ticket.ticketFk,
|
||||||
}
|
recipientId: ticket.clientId,
|
||||||
|
recipient: ticket.recipient,
|
||||||
|
replyTo: ticket.salesPersonEmail,
|
||||||
|
};
|
||||||
|
|
||||||
failedClients.push({
|
try {
|
||||||
id: client.clientId,
|
const email = new Email('delivery-note-link', args);
|
||||||
address: client.addressId,
|
await email.send();
|
||||||
error
|
} catch (error) {
|
||||||
});
|
await handleInvoicingError(error, ticket, failedClients);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,4 +197,22 @@ module.exports = Self => {
|
||||||
html: body,
|
html: body,
|
||||||
}).catch(err => console.error(err));
|
}).catch(err => console.error(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleInvoicingError(error, entity, failedClients) {
|
||||||
|
await Self.rawSql(`
|
||||||
|
INSERT INTO util.debug (variable, value)
|
||||||
|
VALUES ('invoicingTicketError', ?)
|
||||||
|
`, [entity.clientId + ' - ' + error]);
|
||||||
|
|
||||||
|
if (error.responseCode == 450) {
|
||||||
|
await invalidEmail(entity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
failedClients.push({
|
||||||
|
id: entity.clientId,
|
||||||
|
address: entity.addressId,
|
||||||
|
error
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||||
|
const buildFilter = require('vn-loopback/util/filter').buildFilter;
|
||||||
|
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('getWorkerBusiness', {
|
||||||
|
description: 'Returns an array of business from an specified worker',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The worker id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'filter',
|
||||||
|
type: 'object',
|
||||||
|
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'started',
|
||||||
|
type: 'date',
|
||||||
|
description: 'started',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'ended',
|
||||||
|
type: 'date',
|
||||||
|
description: 'ended',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'companyCodeFk',
|
||||||
|
type: 'string',
|
||||||
|
description: 'companyCodeFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'reasonEndFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'reasonEndFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'reasondEnd',
|
||||||
|
type: 'string',
|
||||||
|
description: 'reasondEnd',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'departmentFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'departmentFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'department',
|
||||||
|
type: 'string',
|
||||||
|
description: 'department',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessProfessionalCategoryFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'workerBusinessProfessionalCategoryFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessProfessionalCategory',
|
||||||
|
type: 'string',
|
||||||
|
description: 'workerBusinessProfessionalCategory',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'calendarTypeFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'calendarTypeFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'calendarType',
|
||||||
|
type: 'string',
|
||||||
|
description: 'calendarType',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workcenterFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'workcenterFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workCenter',
|
||||||
|
type: 'string',
|
||||||
|
description: 'workCenter',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessCategoryFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'WorkerBusinessCategoryFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessCategory',
|
||||||
|
type: 'string',
|
||||||
|
description: 'workerBusinessCategory',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'occupationCodeFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'occupationCodeFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'occupationCode',
|
||||||
|
type: 'string',
|
||||||
|
description: 'occupationCode',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'rate',
|
||||||
|
type: 'number',
|
||||||
|
description: 'rate',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessTypeFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'workerBusinessTypeFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessType',
|
||||||
|
type: 'string',
|
||||||
|
description: 'workerBusinessType',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'amount',
|
||||||
|
type: 'number',
|
||||||
|
description: 'amount',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'basicSalary',
|
||||||
|
type: 'number',
|
||||||
|
description: 'amount',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'notes',
|
||||||
|
type: 'string',
|
||||||
|
description: 'notes',
|
||||||
|
http: {source: 'query'}
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: '/:id/getWorkerBusiness',
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getWorkerBusiness = async(ctx, id, filter, options) => {
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
let conn = Self.dataSource.connector;
|
||||||
|
let where = buildFilter(ctx.args, (param, value) => {
|
||||||
|
switch (param) {
|
||||||
|
case 'started':
|
||||||
|
case 'ended':
|
||||||
|
case 'companyCodeFk':
|
||||||
|
case 'reasonEndFk':
|
||||||
|
case 'reasondEnd':
|
||||||
|
case 'departmentFk':
|
||||||
|
case 'department':
|
||||||
|
case 'workerBusinessProfessionalCategoryFk':
|
||||||
|
case 'workerBusinessProfessionalCategory':
|
||||||
|
case 'calendarTypeFk':
|
||||||
|
case 'calendarType':
|
||||||
|
case 'workcenterFk':
|
||||||
|
case 'workCenter':
|
||||||
|
case 'workerBusinessCategoryFk':
|
||||||
|
case 'workerBusinessCategory':
|
||||||
|
case 'occupationCodeFk':
|
||||||
|
case 'occupationCode':
|
||||||
|
case 'rate':
|
||||||
|
case 'workerBusinessTypeFk':
|
||||||
|
case 'workerBusinessType':
|
||||||
|
case 'amount':
|
||||||
|
case 'basicSalary':
|
||||||
|
case 'notes':
|
||||||
|
}
|
||||||
|
});
|
||||||
|
where = {...where, ...{workerFk: id}};
|
||||||
|
filter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
|
let stmts = [];
|
||||||
|
let stmt;
|
||||||
|
|
||||||
|
stmt = new ParameterizedSQL(
|
||||||
|
`SELECT * FROM(
|
||||||
|
SELECT b.id,
|
||||||
|
b.workerFk,
|
||||||
|
b.started,
|
||||||
|
b.ended,
|
||||||
|
b.companyCodeFk,
|
||||||
|
b.reasonEndFk,
|
||||||
|
bre.reason,
|
||||||
|
b.departmentFk,
|
||||||
|
d.name departmentName,
|
||||||
|
b.occupationCodeFk,
|
||||||
|
oc.name occupationName,
|
||||||
|
b.workerBusinessProfessionalCategoryFk,
|
||||||
|
pf.description professionalDescription,
|
||||||
|
b.calendarTypeFk,
|
||||||
|
ct.description calendarTypeDescription,
|
||||||
|
b.workcenterFk,
|
||||||
|
wc.name workCenterName,
|
||||||
|
b.workerBusinessCategoryFk,
|
||||||
|
py.description payrollDescription,
|
||||||
|
b.workerBusinessTypeFk,
|
||||||
|
wt.name workerBusinessTypeName,
|
||||||
|
b.amount,
|
||||||
|
b.basicSalary,
|
||||||
|
b.notes
|
||||||
|
FROM business b
|
||||||
|
LEFT JOIN businessReasonEnd bre ON bre.id = b.reasonEndFk
|
||||||
|
LEFT JOIN occupationCode oc ON oc.code = b.occupationCodeFk
|
||||||
|
LEFT JOIN department d ON d.id = b.departmentFk
|
||||||
|
LEFT JOIN professionalCategory pf ON pf.id = b.workerBusinessProfessionalCategoryFk
|
||||||
|
JOIN calendarType ct ON ct.id = b.calendarTypeFk
|
||||||
|
LEFT JOIN workCenter wc ON wc.id = b.workcenterFk
|
||||||
|
LEFT JOIN payrollCategories py ON py.id = b.workerBusinessCategoryFk
|
||||||
|
LEFT JOIN workerBusinessType wt ON wt.id = b.workerBusinessTypeFk
|
||||||
|
) sub
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
|
stmts.push(stmt);
|
||||||
|
|
||||||
|
let sql = ParameterizedSQL.join(stmts, ';');
|
||||||
|
let result = await conn.executeStmt(sql, myOptions);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
|
@ -21,6 +21,7 @@ module.exports = Self => {
|
||||||
require('../methods/worker/setPassword')(Self);
|
require('../methods/worker/setPassword')(Self);
|
||||||
require('../methods/worker/getAvailablePda')(Self);
|
require('../methods/worker/getAvailablePda')(Self);
|
||||||
require('../methods/worker/myTeam')(Self);
|
require('../methods/worker/myTeam')(Self);
|
||||||
|
require('../methods/worker/getWorkerBusiness')(Self);
|
||||||
|
|
||||||
Self.canModifyAbsenceInPast = async(ctx, time) => {
|
Self.canModifyAbsenceInPast = async(ctx, time) => {
|
||||||
const hasPrivs = await Self.app.models.ACL.checkAccessAcl(ctx, 'Worker', 'canModifyAbsenceInPast', 'WRITE');
|
const hasPrivs = await Self.app.models.ACL.checkAccessAcl(ctx, 'Worker', 'canModifyAbsenceInPast', 'WRITE');
|
||||||
|
|
|
@ -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;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
buttons:
|
||||||
|
webAcccess: Visita la nostra Web
|
||||||
|
info: Ajuda'ns a millorar
|
||||||
|
fiscalAddress: VERDNATURA LEVANTE SL, B97367486 C/ Fenollar, 2. 46680 ALGEMESÍ
|
||||||
|
· verdnatura.es · clientes@verdnatura.es
|
||||||
|
disclaimer: '- AVÍS - Aquest missatge és privat i confidencial, i ha de ser utilitzat
|
||||||
|
exclusivament per la persona destinatària del mateix. Si has rebut aquest missatge
|
||||||
|
per error, et preguem que ho comuniquis al remitent i esborres aquest missatge
|
||||||
|
i qualsevol document adjunt que pugui contenir. Verdnatura Levante SL no renuncia
|
||||||
|
a la confidencialitat ni a cap privilegi per causa de transmissió errònia o mal
|
||||||
|
funcionament. Igualment, no es fa responsable dels canvis, alteracions, errors
|
||||||
|
o omissions que es puguin fer al missatge un cop enviat.'
|
||||||
|
privacy: En compliment del que disposa la Llei Orgànica 15/1999, de Protecció de
|
||||||
|
Dades de Caràcter Personal, et comuniquem que les dades personals que facilitis
|
||||||
|
s'inclouran en fitxers automatitzats de VERDNATURA LEVANTE S.L., podent en tot
|
||||||
|
moment exercir els drets d'accés, rectificació, cancel·lació i oposició,
|
||||||
|
comunicant-ho per escrit al domicili social de l'entitat. La finalitat del
|
||||||
|
fitxer és la gestió administrativa, comptabilitat i facturació.
|
|
@ -0,0 +1,11 @@
|
||||||
|
subject: El teu albarà
|
||||||
|
title: El teu albarà
|
||||||
|
dear: Estimat client
|
||||||
|
description: Ja està disponible l'albarà corresponent a la comanda <strong>{0}</strong>. <br/>
|
||||||
|
Pots veure'l fent clic <a href="https://shop.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">en aquest enllaç</a>.
|
||||||
|
copyLink: 'Com a alternativa, pots copiar el següent enllaç al teu navegador:'
|
||||||
|
poll: Si ho desitges, pots respondre a la nostra enquesta de satisfacció per
|
||||||
|
ajudar-nos a oferir un millor servei. La teva opinió és molt important per a nosaltres!
|
||||||
|
help: Qualsevol dubte que tinguis, no dubtis a consultar-nos, <strong>estem aquí
|
||||||
|
per atendre't!</strong>
|
||||||
|
conclusion: Gràcies per la teva atenció!
|
Loading…
Reference in New Issue