8032-devToTest_2440 #3009

Merged
alexm merged 262 commits from 8032-devToTest_2440 into test 2024-09-24 09:34:49 +00:00
80 changed files with 533 additions and 360 deletions
Showing only changes of commit 05b6c75a19 - Show all commits

View File

@ -2488,7 +2488,7 @@ INSERT INTO `vn`.`clientDms`(`clientFk`, `dmsFk`)
(1104, 2), (1104, 2),
(1104, 3); (1104, 3);
INSERT INTO `vn`.`workerDocument`(`id`, `worker`, `document`,`isReadableByWorker`) INSERT INTO `vn`.`workerDms`(`id`, `workerFk`, `dmsFk`,`isReadableByWorker`)
VALUES VALUES
(1, 1106, 4, TRUE), (1, 1106, 4, TRUE),
(2, 1107, 3, FALSE); (2, 1107, 3, FALSE);

View File

@ -0,0 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` EVENT `util`.`log_clean`
ON SCHEDULE EVERY 1 DAY
STARTS '2024-07-09 00:30:00.000'
ON COMPLETION PRESERVE
ENABLE
DO CALL util.log_clean$$
DELIMITER ;

View File

@ -0,0 +1,54 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `util`.`log_clean`()
BEGIN
/**
* Hace limpieza de los datos de las tablas log,
* dejando únicamente los días de retención configurados.
*/
DECLARE vSchemaName VARCHAR(65);
DECLARE vSchemaNameQuoted VARCHAR(65);
DECLARE vTableName VARCHAR(65);
DECLARE vTableNameQuoted VARCHAR(65);
DECLARE vRetentionDays INT;
DECLARE vStarted DATETIME;
DECLARE vDated DATE;
DECLARE vDone BOOL;
DECLARE vQueue CURSOR FOR
SELECT schemaName, tableName, retentionDays
FROM logCleanMultiConfig
ORDER BY `order`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
OPEN vQueue;
l: LOOP
SET vDone = FALSE;
FETCH vQueue INTO vSchemaName, vTableName, vRetentionDays;
IF vDone THEN
LEAVE l;
END IF;
IF vRetentionDays THEN
SET vStarted = VN_NOW();
SET vSchemaNameQuoted = quoteIdentifier(vSchemaName);
SET vTableNameQuoted = quoteIdentifier(vTableName);
SET vDated = VN_CURDATE() - INTERVAL vRetentionDays DAY;
EXECUTE IMMEDIATE CONCAT(
'DELETE FROM ', vSchemaNameQuoted,
'.', vTableNameQuoted,
" WHERE creationDate < '", vDated, "'"
);
UPDATE logCleanMultiConfig
SET `started` = vStarted,
`finished` = VN_NOW()
WHERE schemaName = vSchemaName
AND tableName = vTableName;
END IF;
END LOOP;
CLOSE vQueue;
END$$
DELIMITER ;

View File

@ -167,7 +167,8 @@ BEGIN
OR LENGTH(pb.problem) OR LENGTH(pb.problem)
OR pb.lines > vLinesLimit OR pb.lines > vLinesLimit
OR pb.m3 > vVolumeLimit OR pb.m3 > vVolumeLimit
OR sub.maxSize > vSizeLimit; OR sub.maxSize > vSizeLimit
OR pb.hasPlantTray;
END IF; END IF;
-- Hay que excluir aquellos que no tengan la misma hora de preparacion, si procede -- Hay que excluir aquellos que no tengan la misma hora de preparacion, si procede

View File

@ -10,7 +10,7 @@ BEGIN
SELECT * FROM ( SELECT * FROM (
SELECT cc.client clientFk, ci.grade SELECT cc.client clientFk, ci.grade
FROM creditClassification cc FROM creditClassification cc
JOIN creditInsurance ci ON cc.id = ci.creditClassification JOIN creditInsurance ci ON cc.id = ci.creditClassificationFk
WHERE dateEnd IS NULL WHERE dateEnd IS NULL
ORDER BY ci.creationDate DESC ORDER BY ci.creationDate DESC
LIMIT 10000000000000000000) t1 LIMIT 10000000000000000000) t1

View File

@ -30,6 +30,8 @@ BEGIN
FROM operator FROM operator
WHERE workerFk = account.myUser_getId(); WHERE workerFk = account.myUser_getId();
CALL util.debugAdd('itemShelvingSale_addBySectorCollection',CONCAT(vSectorCollectionFk,' - ', account.myUser_getId()));
OPEN vSales; OPEN vSales;
l: LOOP l: LOOP
SET vDone = FALSE; SET vDone = FALSE;

View File

@ -211,8 +211,6 @@ proc: BEGIN
salesInParkingCount INT DEFAULT 0) salesInParkingCount INT DEFAULT 0)
ENGINE = MEMORY; ENGINE = MEMORY;
-- Insertamos todos los tickets que tienen productos parkineados
-- en sectores de previa, segun el sector
CREATE OR REPLACE TEMPORARY TABLE tItemShelvingStock CREATE OR REPLACE TEMPORARY TABLE tItemShelvingStock
(PRIMARY KEY(itemFk, sectorFk)) (PRIMARY KEY(itemFk, sectorFk))
ENGINE = MEMORY ENGINE = MEMORY
@ -245,7 +243,6 @@ proc: BEGIN
AND s.quantity > 0 AND s.quantity > 0
GROUP BY pb.ticketFk; GROUP BY pb.ticketFk;
-- Se calcula la cantidad de productos que estan ya preparados porque su saleGroup está aparcado
UPDATE tmp.ticketWithPrevia twp UPDATE tmp.ticketWithPrevia twp
JOIN ( JOIN (
SELECT pb.ticketFk, COUNT(DISTINCT s.id) salesInParkingCount SELECT pb.ticketFk, COUNT(DISTINCT s.id) salesInParkingCount
@ -259,12 +256,28 @@ proc: BEGIN
) sub ON twp.ticketFk = sub.ticketFk ) sub ON twp.ticketFk = sub.ticketFk
SET twp.salesInParkingCount = sub.salesInParkingCount; SET twp.salesInParkingCount = sub.salesInParkingCount;
-- Marcamos como pendientes aquellos que no coinciden las cantidades
UPDATE tmp.productionBuffer pb UPDATE tmp.productionBuffer pb
JOIN tmp.ticketWithPrevia twp ON twp.ticketFk = pb.ticketFk JOIN tmp.ticketWithPrevia twp ON twp.ticketFk = pb.ticketFk
SET pb.previousWithoutParking = TRUE SET pb.previousWithoutParking = TRUE
WHERE twp.salesCount > twp.salesInParkingCount; WHERE twp.salesCount > twp.salesInParkingCount;
-- hasPlantTray
ALTER TABLE tmp.productionBuffer
ADD hasPlantTray BOOL DEFAULT FALSE;
UPDATE tmp.productionBuffer pb
JOIN sale s ON s.ticketFk = pb.ticketFk
JOIN item i ON i.id = s.itemFk
JOIN itemType it ON it.id = i.typeFk
JOIN itemCategory ic ON ic.id = it.categoryFk
JOIN cache.last_buy lb ON lb.warehouse_id = vWarehouseFk AND lb.item_id = s.itemFk
JOIN buy b ON b.id = lb.buy_id
JOIN packaging p ON p.id = b.packagingFk
JOIN productionConfig pc
SET hasPlantTray = TRUE
WHERE ic.code = 'plant'
AND p.`depth` >= pc.minPlantTrayLength;
DROP TEMPORARY TABLE DROP TEMPORARY TABLE
tmp.productionTicket, tmp.productionTicket,
tmp.ticket, tmp.ticket,

View File

@ -55,7 +55,6 @@ BEGIN
i.itemPackingTypeFk, i.itemPackingTypeFk,
isa.`size`, isa.`size`,
isa.Estado, isa.Estado,
isa.sectorProdPriority,
isa.available, isa.available,
isa.sectorFk, isa.sectorFk,
isa.matricula, isa.matricula,

View File

@ -51,7 +51,6 @@ BEGIN
hasTicketRequest, hasTicketRequest,
isTaxDataChecked, isTaxDataChecked,
hasComponentLack, hasComponentLack,
hasRounding,
isTooLittle) isTooLittle)
SELECT sgp.ticketFk, SELECT sgp.ticketFk,
s.id, s.id,
@ -62,10 +61,6 @@ BEGIN
IF(FIND_IN_SET('hasTicketRequest', t.problem), TRUE, FALSE) hasTicketRequest, IF(FIND_IN_SET('hasTicketRequest', t.problem), TRUE, FALSE) hasTicketRequest,
IF(FIND_IN_SET('isTaxDataChecked', t.problem), FALSE, TRUE) isTaxDataChecked, IF(FIND_IN_SET('isTaxDataChecked', t.problem), FALSE, TRUE) isTaxDataChecked,
IF(FIND_IN_SET('hasComponentLack', s.problem), TRUE, FALSE) hasComponentLack, IF(FIND_IN_SET('hasComponentLack', s.problem), TRUE, FALSE) hasComponentLack,
IF(FIND_IN_SET('hasRounding', s.problem),
LEFT(GROUP_CONCAT('RE: ', i.id, ' ', IFNULL(i.longName,'') SEPARATOR ', '), 250),
NULL
) hasRounding,
IF(FIND_IN_SET('isTooLittle', t.problem) IF(FIND_IN_SET('isTooLittle', t.problem)
AND util.VN_NOW() < (util.VN_CURDATE() + INTERVAL HOUR(zc.`hour`) HOUR) + INTERVAL MINUTE(zc.`hour`) MINUTE, AND util.VN_NOW() < (util.VN_CURDATE() + INTERVAL HOUR(zc.`hour`) HOUR) + INTERVAL MINUTE(zc.`hour`) MINUTE,
TRUE, FALSE) isTooLittle TRUE, FALSE) isTooLittle
@ -208,24 +203,31 @@ BEGIN
GROUP BY sgp.ticketFk GROUP BY sgp.ticketFk
) sub ) sub
ON DUPLICATE KEY UPDATE itemDelay = sub.problem, saleFk = sub.saleFk; ON DUPLICATE KEY UPDATE itemDelay = sub.problem, saleFk = sub.saleFk;
-- Redondeo: cantidad incorrecta con respecto al grouping
CALL buy_getUltimate(NULL, vWarehouseFk, vDate);
INSERT INTO tmp.sale_problems(ticketFk, hasRounding, saleFk)
SELECT ticketFk, problem, saleFk
FROM (
SELECT sgp.ticketFk,
s.id saleFk,
LEFT(GROUP_CONCAT('RE: ',i.id, ' ', IFNULL(i.longName,'') SEPARATOR ', '), 250) problem
FROM tmp.sale_getProblems sgp
JOIN ticket t ON t.id = sgp.ticketFk
AND t.warehouseFk = vWarehouseFk
JOIN sale s ON s.ticketFk = sgp.ticketFk
JOIN item i ON i.id = s.itemFk
JOIN tmp.buyUltimate bu ON bu.itemFk = s.itemFk
JOIN buy b ON b.id = bu.buyFk
WHERE MOD(s.quantity, b.`grouping`)
GROUP BY sgp.ticketFk
)sub
ON DUPLICATE KEY UPDATE hasRounding = sub.problem, saleFk = sub.saleFk;
DROP TEMPORARY TABLE tmp.buyUltimate;
END LOOP; END LOOP;
CLOSE vCursor; CLOSE vCursor;
INSERT INTO tmp.sale_problems(ticketFk, hasRounding, saleFk)
SELECT ticketFk, problem, saleFk
FROM (
SELECT sgp.ticketFk,
s.id saleFk,
LEFT(GROUP_CONCAT('RE: ', i.id, ' ', IFNULL(i.longName,'') SEPARATOR ', '), 250) problem
FROM tmp.sale_getProblems sgp
JOIN ticket t ON t.id = sgp.ticketFk
JOIN sale s ON s.ticketFk = sgp.ticketFk
JOIN item i ON i.id = s.itemFk
WHERE FIND_IN_SET('hasRounding', s.problem)
GROUP BY sgp.ticketFk
) sub
ON DUPLICATE KEY UPDATE hasRounding = sub.problem, saleFk = sub.saleFk;
DROP TEMPORARY TABLE tItemShelvingStock_byWarehouse; DROP TEMPORARY TABLE tItemShelvingStock_byWarehouse;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -1,37 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`sale_setProblemRounding`(
vSelf INT
)
BEGIN
/**
* Update the rounding problem for a sales line
* @param vSelf Id sale
*/
DECLARE vItemFk INT;
DECLARE vWarehouseFk INT;
DECLARE vShipped DATE;
DECLARE vQuantity INT;
DECLARE vIsProblemCalcNeeded BOOL;
SELECT s.itemFk, t.warehouseFk, t.shipped, s.quantity, ticket_isProblemCalcNeeded(t.id)
INTO vItemFk, vWarehouseFk, vShipped, vQuantity, vIsProblemCalcNeeded
FROM sale s
JOIN ticket t ON t.id = s.ticketFk
WHERE s.id = vSelf;
CALL buy_getUltimate(vItemFk, vWarehouseFk, vShipped);
CREATE OR REPLACE TEMPORARY TABLE tmp.sale
SELECT vSelf saleFk,
MOD(vQuantity, b.`grouping`) hasProblem,
vIsProblemCalcNeeded isProblemCalcNeeded
FROM tmp.buyUltimate bu
JOIN buy b ON b.id = bu.buyFk
WHERE bu.itemFk = vItemFk;
CALL sale_setProblem('hasRounding');
DROP TEMPORARY TABLE tmp.sale;
DROP TEMPORARY TABLE tmp.buyUltimate;
END$$
DELIMITER ;

View File

@ -1,75 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`sale_setProblemRoundingByBuy`(
vBuyFk INT
)
BEGIN
/**
* Update rounding problem for all sales related to a buy.
*
* @param vBuyFk Buy id
*/
DECLARE vItemFk INT;
DECLARE vWarehouseFk INT;
DECLARE vMaxDated DATE;
DECLARE vMinDated DATE;
DECLARE vLanding DATE;
DECLARE vLastBuy INT;
DECLARE vCurrentBuy INT;
DECLARE vGrouping INT;
SELECT b.itemFk, t.warehouseInFk
INTO vItemFk, vWarehouseFk
FROM buy b
JOIN entry e ON e.id = b.entryFk
JOIN travel t ON t.id = e.travelFk
WHERE b.id = vBuyFk;
IF vItemFk AND vWarehouseFk THEN
SELECT DATE(MAX(t.shipped)) + INTERVAL 1 DAY, DATE(MIN(t.shipped))
INTO vMaxDated, vMinDated
FROM sale s
JOIN ticket t ON t.id = s.ticketFk
WHERE t.shipped >= util.VN_CURDATE()
AND s.itemFk = vItemFk
AND s.quantity > 0;
CALL buy_getUltimate(vItemFk, vWarehouseFk, vMinDated);
SELECT bu.buyFk, b.grouping INTO vLastBuy, vGrouping
FROM tmp.buyUltimate bu
JOIN buy b ON b.id = bu.buyFk;
DROP TEMPORARY TABLE tmp.buyUltimate;
SET vLanding = vMaxDated;
WHILE vCurrentBuy <> vLastBuy OR vLanding > vMinDated DO
SET vMaxDated = vLanding - INTERVAL 1 DAY;
CALL buy_getUltimate(vItemFk, vWarehouseFk, vMaxDated);
SELECT buyFk, landing
INTO vCurrentBuy, vLanding
FROM tmp.buyUltimate;
DROP TEMPORARY TABLE tmp.buyUltimate;
END WHILE;
CREATE OR REPLACE TEMPORARY TABLE tmp.sale
(INDEX(saleFk, isProblemCalcNeeded))
ENGINE = MEMORY
SELECT s.id saleFk,
MOD(s.quantity, vGrouping) hasProblem,
ticket_isProblemCalcNeeded(t.id) isProblemCalcNeeded
FROM sale s
JOIN ticket t ON t.id = s.ticketFk
WHERE s.itemFk = vItemFk
AND s.quantity > 0
AND t.shipped BETWEEN vMinDated AND util.dayEnd(vMaxDated);
CALL sale_setProblem('hasRounding');
DROP TEMPORARY TABLE tmp.sale;
END IF;
END$$
DELIMITER ;

View File

@ -19,8 +19,7 @@ BEGIN
CREATE OR REPLACE TEMPORARY TABLE tmp.filter CREATE OR REPLACE TEMPORARY TABLE tmp.filter
(INDEX (id)) (INDEX (id))
SELECT SELECT origin.ticketFk futureId,
origin.ticketFk futureId,
dest.ticketFk id, dest.ticketFk id,
dest.state, dest.state,
origin.futureState, origin.futureState,
@ -51,48 +50,48 @@ BEGIN
origin.warehouseFk futureWarehouseFk, origin.warehouseFk futureWarehouseFk,
origin.companyFk futureCompanyFk, origin.companyFk futureCompanyFk,
IFNULL(dest.nickname, origin.nickname) nickname, IFNULL(dest.nickname, origin.nickname) nickname,
dest.landed dest.landed,
dest.preparation
FROM ( FROM (
SELECT SELECT s.ticketFk,
s.ticketFk, c.salesPersonFk workerFk,
c.salesPersonFk workerFk, t.shipped,
t.shipped, t.totalWithVat,
t.totalWithVat, st.name futureState,
st.name futureState, am.name futureAgency,
am.name futureAgency, count(s.id) futureLines,
count(s.id) futureLines, GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) futureIpt,
GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) futureIpt, CAST(SUM(litros) AS DECIMAL(10,0)) futureLiters,
CAST(SUM(litros) AS DECIMAL(10,0)) futureLiters, SUM(s.quantity <= (IFNULL(il.stock,0) + IFNULL(im.amount, 0))) hasStock,
SUM(s.quantity <= (IFNULL(il.stock,0) + IFNULL(im.amount, 0))) hasStock, z.id futureZoneFk,
z.id futureZoneFk, z.name futureZoneName,
z.name futureZoneName, st.classColor,
st.classColor, t.clientFk,
t.clientFk, t.nickname,
t.nickname, t.addressFk,
t.addressFk, t.warehouseFk,
t.warehouseFk, t.companyFk,
t.companyFk, t.agencyModeFk
t.agencyModeFk FROM ticket t
FROM ticket t JOIN client c ON c.id = t.clientFk
JOIN client c ON c.id = t.clientFk JOIN sale s ON s.ticketFk = t.id
JOIN sale s ON s.ticketFk = t.id JOIN saleVolume sv ON sv.saleFk = s.id
JOIN saleVolume sv ON sv.saleFk = s.id JOIN item i ON i.id = s.itemFk
JOIN item i ON i.id = s.itemFk JOIN ticketState ts ON ts.ticketFk = t.id
JOIN ticketState ts ON ts.ticketFk = t.id JOIN `state` st ON st.id = ts.stateFk
JOIN state st ON st.id = ts.stateFk JOIN agencyMode am ON t.agencyModeFk = am.id
JOIN agencyMode am ON t.agencyModeFk = am.id JOIN `zone` z ON t.zoneFk = z.id
JOIN zone z ON t.zoneFk = z.id LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk
LEFT JOIN itemPackingType ipt ON ipt.code = i.itemPackingTypeFk LEFT JOIN itemPackingType ipt ON ipt.code = i.itemPackingTypeFk
LEFT JOIN tmp.itemMinacum im ON im.itemFk = i.id LEFT JOIN tmp.itemMinacum im ON im.itemFk = i.id
AND im.warehouseFk = vWarehouseFk AND im.warehouseFk = vWarehouseFk
LEFT JOIN tmp.itemList il ON il.itemFk = i.id LEFT JOIN tmp.itemList il ON il.itemFk = i.id
WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture) WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture)
AND t.warehouseFk = vWarehouseFk AND t.warehouseFk = vWarehouseFk
GROUP BY t.id GROUP BY t.id
) origin ) origin
LEFT JOIN ( LEFT JOIN (
SELECT SELECT t.id ticketFk,
t.id ticketFk,
st.name state, st.name state,
GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt, GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt,
t.shipped, t.shipped,
@ -108,18 +107,25 @@ BEGIN
t.warehouseFk, t.warehouseFk,
t.companyFk, t.companyFk,
t.landed, t.landed,
t.agencyModeFk t.agencyModeFk,
SEC_TO_TIME(
COALESCE(HOUR(t.shipped), HOUR(zc.hour), HOUR(z.hour)) * 3600 +
COALESCE(MINUTE(t.shipped), MINUTE(zc.hour), MINUTE(z.hour)) * 60
) preparation
FROM ticket t FROM ticket t
JOIN sale s ON s.ticketFk = t.id JOIN sale s ON s.ticketFk = t.id
JOIN saleVolume sv ON sv.saleFk = s.id JOIN saleVolume sv ON sv.saleFk = s.id
JOIN item i ON i.id = s.itemFk JOIN item i ON i.id = s.itemFk
JOIN ticketState ts ON ts.ticketFk = t.id JOIN ticketState ts ON ts.ticketFk = t.id
JOIN state st ON st.id = ts.stateFk JOIN `state` st ON st.id = ts.stateFk
JOIN agencyMode am ON t.agencyModeFk = am.id JOIN agencyMode am ON t.agencyModeFk = am.id
LEFT JOIN itemPackingType ipt ON ipt.code = i.itemPackingTypeFk LEFT JOIN itemPackingType ipt ON ipt.code = i.itemPackingTypeFk
LEFT JOIN `zone` z ON z.id = t.zoneFk
LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk
JOIN ticketCanAdvanceConfig tc
WHERE t.shipped BETWEEN vDateToAdvance AND util.dayend(vDateToAdvance) WHERE t.shipped BETWEEN vDateToAdvance AND util.dayend(vDateToAdvance)
AND t.warehouseFk = vWarehouseFk AND t.warehouseFk = vWarehouseFk
AND st.order <= 5 AND st.order <= tc.destinationOrder
GROUP BY t.id GROUP BY t.id
) dest ON dest.addressFk = origin.addressFk ) dest ON dest.addressFk = origin.addressFk
WHERE origin.hasStock; WHERE origin.hasStock;

View File

@ -21,6 +21,7 @@ BEGIN
t.clientFk, t.clientFk,
t.warehouseFk, t.warehouseFk,
ts.alertLevel, ts.alertLevel,
sub2.alertLevel futureAlertLevel,
t.shipped, t.shipped,
t.totalWithVat, t.totalWithVat,
sub2.shipped futureShipped, sub2.shipped futureShipped,
@ -47,6 +48,7 @@ BEGIN
t.addressFk, t.addressFk,
t.id, t.id,
t.shipped, t.shipped,
ts.alertLevel,
st.name state, st.name state,
st.code, st.code,
st.classColor, st.classColor,

View File

@ -36,7 +36,7 @@ BEGIN
UPDATE tmp.ticket_problems UPDATE tmp.ticket_problems
SET totalProblems = ( SET totalProblems = (
(isFreezed) + (isFreezed) +
(hasRisk) + (hasHighRisk) +
(hasTicketRequest) + (hasTicketRequest) +
(!isTaxDataChecked) + (!isTaxDataChecked) +
(hasComponentLack) + (hasComponentLack) +

View File

@ -1,37 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_setProblemRounding`(
vSelf INT
)
BEGIN
/**
* Update the rounding problem for the sales lines of a ticket
*
* @param vSelf Id de ticket
*/
DECLARE vWarehouseFk INT;
DECLARE vDated DATE;
SELECT warehouseFk, shipped
INTO vWarehouseFk, vDated
FROM ticket
WHERE id = vSelf;
CALL buy_getUltimate(NULL, vWarehouseFk, vDated);
CREATE OR REPLACE TEMPORARY TABLE tmp.sale
(INDEX(saleFk, isProblemCalcNeeded))
SELECT s.id saleFk ,
MOD(s.quantity, b.`grouping`) hasProblem,
ticket_isProblemCalcNeeded(t.id) isProblemCalcNeeded
FROM ticket t
JOIN sale s ON s.ticketFk = t.id
JOIN tmp.buyUltimate bu ON bu.itemFk = s.itemFk
JOIN buy b ON b.id = bu.buyFk
WHERE t.id = vSelf;
CALL sale_setProblem('hasRounding');
DROP TEMPORARY TABLE tmp.sale;
DROP TEMPORARY TABLE tmp.buyUltimate;
END$$
DELIMITER ;

View File

@ -5,7 +5,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`creditInsurance_afterIn
BEGIN BEGIN
UPDATE `client` c UPDATE `client` c
JOIN vn.creditClassification cc ON cc.client = c.id JOIN vn.creditClassification cc ON cc.client = c.id
SET creditInsurance = NEW.credit WHERE cc.id = NEW.creditClassification; SET creditInsurance = NEW.credit WHERE cc.id = NEW.creditClassificationFk;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -1,10 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`creditInsurance_beforeInsert`
BEFORE INSERT ON `creditInsurance`
FOR EACH ROW
BEGIN
IF NEW.creditClassificationFk THEN
SET NEW.creditClassification = NEW.creditClassificationFk;
END IF;
END$$
DELIMITER ;

View File

@ -5,7 +5,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`solunionCAP_afterInsert
BEGIN BEGIN
UPDATE client c UPDATE client c
JOIN creditClassification cc ON cc.client = c.id JOIN creditClassification cc ON cc.client = c.id
JOIN creditInsurance ci ON ci.creditClassification = cc.id JOIN creditInsurance ci ON ci.creditClassificationFk = cc.id
SET creditInsurance = ci.credit * 2 WHERE ci.id = NEW.creditInsurance; SET creditInsurance = ci.credit * 2 WHERE ci.id = NEW.creditInsurance;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -6,12 +6,12 @@ BEGIN
IF NEW.dateLeaving IS NOT NULL THEN IF NEW.dateLeaving IS NOT NULL THEN
UPDATE client c UPDATE client c
JOIN creditClassification cc ON cc.client = c.id JOIN creditClassification cc ON cc.client = c.id
JOIN creditInsurance ci ON ci.creditClassification = cc.id JOIN creditInsurance ci ON ci.creditClassificationFk = cc.id
SET creditInsurance = ci.credit WHERE ci.id = OLD.creditInsurance; SET creditInsurance = ci.credit WHERE ci.id = OLD.creditInsurance;
ELSE ELSE
UPDATE client c UPDATE client c
JOIN creditClassification cc ON cc.client = c.id JOIN creditClassification cc ON cc.client = c.id
JOIN creditInsurance ci ON ci.creditClassification = cc.id JOIN creditInsurance ci ON ci.creditClassificationFk = cc.id
SET creditInsurance = ci.credit * 2 WHERE ci.id = OLD.creditInsurance; SET creditInsurance = ci.credit * 2 WHERE ci.id = OLD.creditInsurance;
END IF; END IF;
END$$ END$$

View File

@ -5,7 +5,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`solunionCAP_beforeDelet
BEGIN BEGIN
UPDATE client c UPDATE client c
JOIN creditClassification cc ON cc.client = c.id JOIN creditClassification cc ON cc.client = c.id
JOIN creditInsurance ci ON ci.creditClassification = cc.id JOIN creditInsurance ci ON ci.creditClassificationFk = cc.id
SET creditInsurance = ci.credit WHERE ci.id = OLD.creditInsurance; SET creditInsurance = ci.credit WHERE ci.id = OLD.creditInsurance;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -1,11 +1,11 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerDocument_afterDelete` CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerDms_afterDelete`
AFTER DELETE ON `workerDocument` AFTER DELETE ON `workerDms`
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
INSERT INTO workerLog INSERT INTO workerLog
SET `action` = 'delete', SET `action` = 'delete',
`changedModel` = 'WorkerDocument', `changedModel` = 'WorkerDms',
`changedModelId` = OLD.id, `changedModelId` = OLD.id,
`userFk` = account.myUser_getId(); `userFk` = account.myUser_getId();
END$$ END$$

View File

@ -1,6 +1,6 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerDocument_beforeInsert` CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerDms_beforeInsert`
BEFORE INSERT ON `workerDocument` BEFORE INSERT ON `workerDms`
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();

View File

@ -1,6 +1,6 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerDocument_beforeUpdate` CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerDms_beforeUpdate`
BEFORE UPDATE ON `workerDocument` BEFORE UPDATE ON `workerDms`
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();

View File

@ -10,7 +10,6 @@ AS SELECT `s`.`id` AS `saleFk`,
`s`.`concept` AS `concept`, `s`.`concept` AS `concept`,
`i`.`size` AS `size`, `i`.`size` AS `size`,
`st`.`name` AS `Estado`, `st`.`name` AS `Estado`,
`st`.`sectorProdPriority` AS `sectorProdPriority`,
`stock`.`visible` AS `available`, `stock`.`visible` AS `available`,
`stock`.`sectorFk` AS `sectorFk`, `stock`.`sectorFk` AS `sectorFk`,
`stock`.`shelvingFk` AS `matricula`, `stock`.`shelvingFk` AS `matricula`,

View File

@ -6,7 +6,6 @@ AS SELECT `s`.`id` AS `id`,
`s`.`order` AS `order`, `s`.`order` AS `order`,
`s`.`alertLevel` AS `alert_level`, `s`.`alertLevel` AS `alert_level`,
`s`.`code` AS `code`, `s`.`code` AS `code`,
`s`.`sectorProdPriority` AS `sectorProdPriority`,
`s`.`nextStateFk` AS `nextStateFk`, `s`.`nextStateFk` AS `nextStateFk`,
`s`.`isPreviousPreparable` AS `isPreviousPreparable`, `s`.`isPreviousPreparable` AS `isPreviousPreparable`,
`s`.`isPicked` AS `isPicked` `s`.`isPicked` AS `isPicked`

View File

@ -0,0 +1,13 @@
CREATE OR REPLACE TABLE `util`.`logCleanMultiConfig` (
`schemaName` varchar(64) NOT NULL,
`tableName` varchar(64) NOT NULL,
`retentionDays` int(11) DEFAULT NULL,
`order` int(11) DEFAULT NULL,
`started` datetime DEFAULT NULL,
`finished` datetime DEFAULT NULL,
PRIMARY KEY (`schemaName`,`tableName`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
INSERT INTO `util`.`logCleanMultiConfig` (`schemaName`, `tableName`)
SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.`COLUMNS`
WHERE COLUMN_NAME IN ('newInstance', 'newInstance');

View File

@ -0,0 +1 @@
CREATE INDEX userLog_creationDate_IDX USING BTREE ON account.userLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX roleLog_creationDate_IDX USING BTREE ON account.roleLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX ACLLog_creationDate_IDX USING BTREE ON salix.ACLLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX supplierLog_creationDate_IDX USING BTREE ON vn.supplierLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX deviceProductionLog_creationDate_IDX USING BTREE ON vn.deviceProductionLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX routeLog_creationDate_IDX USING BTREE ON vn.routeLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX itemLog_creationDate_IDX USING BTREE ON vn.itemLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX userLog_creationDate_IDX USING BTREE ON vn.userLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX invoiceInLog_creationDate_IDX USING BTREE ON vn.invoiceInLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX zoneLog_creationDate_IDX USING BTREE ON vn.zoneLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX clientLog_creationDate_IDX USING BTREE ON vn.clientLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX workerLog_creationDate_IDX USING BTREE ON vn.workerLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX rateLog_creationDate_IDX USING BTREE ON vn.rateLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX claimLog_creationDate_IDX USING BTREE ON vn.claimLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX packingSiteDeviceLog_creationDate_IDX USING BTREE ON vn.packingSiteDeviceLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX travelLog_creationDate_IDX USING BTREE ON vn.travelLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX shelvingLog_creationDate_IDX USING BTREE ON vn.shelvingLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX productionConfigLog_creationDate_IDX USING BTREE ON vn.productionConfigLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX entryLog_creationDate_IDX USING BTREE ON vn.entryLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX agencyLog_creationDate_IDX USING BTREE ON vn.agencyLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX parkingLog_creationDate_IDX USING BTREE ON vn.parkingLog (creationDate DESC);

View File

@ -0,0 +1 @@
CREATE INDEX bufferLog_creationDate_IDX USING BTREE ON srt.bufferLog (creationDate DESC);

View File

@ -0,0 +1,16 @@
ALTER TABLE IF EXISTS `vn`.`payrollWorker`
MODIFY COLUMN IF EXISTS `nss__` varchar(23) NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `codpuesto__` int(10) NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `codcontrato__` int(10) NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `FAntiguedad__` date NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `grupotarifa__` int(10) NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `codcategoria__` int(10) NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `ContratoTemporal__` tinyint(1) NOT NULL DEFAULT 0 COMMENT '@deprecated 2024-03-15';
ALTER TABLE IF EXISTS `vn`.`payrollWorkCenter`
MODIFY COLUMN IF EXISTS `Centro__` varchar(255) NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `nss_cotizacion__` varchar(15) NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `domicilio__` varchar(255) NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `poblacion__` varchar(45) NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `cp__` varchar(5) NOT NULL COMMENT '@deprecated 2024-03-15',
MODIFY COLUMN IF EXISTS `empresa_id__` int(10) NOT NULL COMMENT '@deprecated 2024-03-15';

View File

@ -0,0 +1,9 @@
-- Place your SQL code here
INSERT INTO salix.ACL
SET model = 'Ticket',
property = 'setWeight',
accessType = 'WRITE',
permission = 'ALLOW',
principalType = 'ROLE',
principalId = 'salesPerson';

View File

@ -0,0 +1 @@
CREATE INDEX saleGroupLog_creationDate_IDX USING BTREE ON vn.saleGroupLog (creationDate DESC);

View File

@ -0,0 +1,9 @@
-- Place your SQL code here
CREATE TABLE IF NOT EXISTS vn.ticketCanAdvanceConfig (
id int(10) unsigned NOT NULL,
destinationOrder INT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `ticketCanAdvanceConfig_check` CHECK (`id` = 1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
INSERT INTO vn.ticketCanAdvanceConfig SET id =1, destinationOrder = 5;

View File

@ -0,0 +1 @@
ALTER TABLE vn.state DROP COLUMN sectorProdPriority;

View File

@ -0,0 +1,3 @@
ALTER TABLE vn.creditInsurance DROP FOREIGN KEY CreditInsurance_Fk1;
ALTER TABLE vn.creditInsurance
CHANGE creditClassification creditClassification__ int(11) DEFAULT NULL COMMENT '@deprecated 2024-09-11';

View File

@ -0,0 +1 @@
ALTER TABLE vn.workerDocument CHANGE worker workerFk int(10) unsigned DEFAULT NULL NULL;

View File

@ -0,0 +1 @@
ALTER TABLE vn.workerDocument CHANGE document dmsFk int(11) DEFAULT NULL NULL;

View File

@ -0,0 +1 @@
RENAME TABLE vn.workerDocument TO vn.workerDms;

View File

@ -0,0 +1,3 @@
-- Place your SQL code here
ALTER TABLE vn.productionConfig ADD minPlantTrayLength INT DEFAULT 53 NOT NULL
COMMENT 'minimum length for plant tray restriction. Avoid to make collection of the ticket with this kind of item';

View File

@ -687,8 +687,8 @@ export default {
ticketFuture: { ticketFuture: {
searchResult: 'vn-ticket-future tbody tr', searchResult: 'vn-ticket-future tbody tr',
openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]', openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
originDated: 'vn-date-picker[label="Origin date"]', originScopeDays: 'vn-date-picker[label="Origin date"]',
futureDated: 'vn-date-picker[label="Destination date"]', futureScopeDays: 'vn-date-picker[label="Destination date"]',
linesMax: 'vn-textfield[label="Max Lines"]', linesMax: 'vn-textfield[label="Max Lines"]',
litersMax: 'vn-textfield[label="Max Liters"]', litersMax: 'vn-textfield[label="Max Liters"]',
ipt: 'vn-autocomplete[label="Origin IPT"]', ipt: 'vn-autocomplete[label="Origin IPT"]',

View File

@ -30,18 +30,18 @@ describe('Ticket Future path', () => {
expect(message.text).toContain('warehouseFk is a required argument'); expect(message.text).toContain('warehouseFk is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.futureDated); await page.clearInput(selectors.ticketFuture.futureScopeDays);
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar(); message = await page.waitForSnackbar();
expect(message.text).toContain('futureDated is a required argument'); expect(message.text).toContain('futureScopeDays is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.originDated); await page.clearInput(selectors.ticketFuture.originScopeDays);
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar(); message = await page.waitForSnackbar();
expect(message.text).toContain('originDated is a required argument'); expect(message.text).toContain('originScopeDays is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
@ -71,7 +71,7 @@ describe('Ticket Future path', () => {
await page.autocompleteSearch(selectors.ticketFuture.state, 'Free'); await page.autocompleteSearch(selectors.ticketFuture.state, 'Free');
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
expect(httpRequest).toContain('state=FREE'); expect(httpRequest).toContain('state=0');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
@ -80,7 +80,7 @@ describe('Ticket Future path', () => {
await page.autocompleteSearch(selectors.ticketFuture.futureState, 'Free'); await page.autocompleteSearch(selectors.ticketFuture.futureState, 'Free');
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
expect(httpRequest).toContain('futureState=FREE'); expect(httpRequest).toContain('futureState=0');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.state); await page.clearInput(selectors.ticketFuture.state);

View File

@ -33,7 +33,7 @@ module.exports = function(Self) {
const defaultLimit = this.app.orm.selectLimit; const defaultLimit = this.app.orm.selectLimit;
const filter = ctx.args.filter || {limit: defaultLimit}; const filter = ctx.args.filter || {limit: defaultLimit};
if (filter.limit > defaultLimit) { if (!filter.limit || filter.limit > defaultLimit) {
filter.limit = defaultLimit; filter.limit = defaultLimit;
ctx.args.filter = filter; ctx.args.filter = filter;
} }
@ -349,9 +349,10 @@ module.exports = function(Self) {
}, },
hasFilter(ctx) { hasFilter(ctx) {
return ctx.req.method.toUpperCase() === 'GET' && const {method, req} = ctx;
ctx.method.accepts.some(x => x.arg === 'filter' && x.type.toLowerCase() === 'object'); if (method.noLimit) return false;
} return req.method.toUpperCase() === 'GET' &&
method.accepts.some(x => x.arg === 'filter' && x.type.toLowerCase() === 'object');
},
}); });
}; };

View File

@ -372,5 +372,7 @@
"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",
"This ticket is not allocated to your department": "Este ticket no está asignado a tu departamento"
} }

View File

@ -16,7 +16,8 @@ module.exports = Self => {
http: { http: {
path: `/getBalance`, path: `/getBalance`,
verb: 'GET' verb: 'GET'
} },
noLimit: true
}); });
Self.getBalance = async(ctx, filter, options) => { Self.getBalance = async(ctx, filter, options) => {

View File

@ -105,13 +105,12 @@ module.exports = Self => {
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
`CALL vn.ticket_canAdvance(?,?,?)`, `CALL vn.ticket_canAdvance(?,?,?)`,
[args.dateFuture, args.dateToAdvance, args.warehouseFk]); [args.dateFuture, args.dateToAdvance, args.warehouseFk]
);
stmts.push(stmt); stmts.push(stmt);
stmt = new ParameterizedSQL(` stmt = new ParameterizedSQL(`SELECT f.* FROM tmp.filter f`);
SELECT f.*
FROM tmp.filter f`);
stmt.merge(conn.makeWhere(filter.where)); stmt.merge(conn.makeWhere(filter.where));
@ -119,9 +118,7 @@ module.exports = Self => {
stmt.merge(conn.makeLimit(filter)); stmt.merge(conn.makeLimit(filter));
const ticketsIndex = stmts.push(stmt) - 1; const ticketsIndex = stmts.push(stmt) - 1;
stmts.push( stmts.push(`DROP TEMPORARY TABLE tmp.filter`);
`DROP TEMPORARY TABLE
tmp.filter`);
const sql = ParameterizedSQL.join(stmts, ';'); const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql, myOptions); const result = await conn.executeStmt(sql, myOptions);

View File

@ -9,13 +9,13 @@ module.exports = Self => {
accessType: 'READ', accessType: 'READ',
accepts: [ accepts: [
{ {
arg: 'originDated', arg: 'originScopeDays',
type: 'date', type: 'date',
description: 'The date in question', description: 'The date in question',
required: true required: true
}, },
{ {
arg: 'futureDated', arg: 'futureScopeDays',
type: 'date', type: 'date',
description: 'The date to probe', description: 'The date to probe',
required: true required: true
@ -129,9 +129,9 @@ module.exports = Self => {
] ]
}; };
case 'state': case 'state':
return {'f.stateCode': {like: `%${value}%`}}; return {'f.alertLevel': value};
case 'futureState': case 'futureState':
return {'f.futureStateCode': {like: `%${value}%`}}; return {'f.futureAlertLevel': value};
} }
}); });
@ -141,7 +141,7 @@ module.exports = Self => {
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
`CALL vn.ticket_canbePostponed(?,?,?)`, `CALL vn.ticket_canbePostponed(?,?,?)`,
[args.originDated, args.futureDated, args.warehouseFk]); [args.originScopeDays, args.futureScopeDays, args.warehouseFk]);
stmts.push(stmt); stmts.push(stmt);
@ -170,7 +170,7 @@ module.exports = Self => {
LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id
`); `);
if (args.problems != undefined && (!args.originDated && !args.futureDated)) if (args.problems != undefined && (!args.originScopeDays && !args.futureScopeDays))
throw new UserError('Choose a date range or days forward'); throw new UserError('Choose a date range or days forward');
let condition; let condition;

View File

@ -138,7 +138,7 @@ module.exports = Self => {
id: id, id: id,
url: `${url}ticket/${id}/summary` url: `${url}ticket/${id}/summary`
}); });
await models.Chat.send(ctx, `@${salesPersonUser.name}`, message); await models.Chat.sendCheckingPresence(ctx, salesPersonUser.id, message);
} }
const updatedTicket = await ticket.updateAttribute('isDeleted', true, myOptions); const updatedTicket = await ticket.updateAttribute('isDeleted', true, myOptions);

View File

@ -0,0 +1,86 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('setWeight', {
description: 'Sets weight of a ticket',
accessType: 'WRITE',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'The ticket id',
http: {source: 'path'}
}, {
arg: 'weight',
type: 'number',
required: true,
description: 'The weight value',
}],
returns: {
type: 'Array',
root: true
},
http: {
path: `/:id/setWeight`,
verb: 'POST'
}
});
Self.setWeight = async(ctx, ticketId, weight, options) => {
const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const myOptions = {userId};
let tx;
if (typeof options == 'object') Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const ticket = await Self.findById(ticketId, null, myOptions);
if (ticket.weight) throw new UserError('Weight already set');
const canEdit = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'updateAttributes');
const client = await models.Client.findById(ticket.clientFk, {
include: {relation: 'salesPersonUser'}},
myOptions);
if (!canEdit) {
const salesPersonUser = client.salesPersonUser();
const workerDepartments = await models.WorkerDepartment.find({
include: {relation: 'department'},
where: {workerFk: {inq: [userId, salesPersonUser.id]}}
}, myOptions);
if (
workerDepartments.length == 2 &&
workerDepartments[0].departmentFk != workerDepartments[1].departmentFk
)
throw new UserError('This ticket is not allocated to your department');
}
await ticket.updateAttribute('weight', weight, myOptions);
const packedState = await models.State.findOne({where: {code: 'PACKED'}}, myOptions);
const ticketState = await models.TicketState.findOne({where: {ticketFk: ticketId}}, myOptions);
const [{taxArea}] = await Self.rawSql('SELECT clientTaxArea(?,?) taxArea',
[ticket.clientFk, ticket.warehouseFk], myOptions);
const isInvoiceable = ticketState.alertLevel >= packedState.alertLevel &&
taxArea == 'WORLD' && client.hasDailyInvoice;
if (tx) await tx.commit();
let invoiceIds = [];
if (isInvoiceable) invoiceIds = [...await Self.invoiceTicketsAndPdf(ctx, [ticketId])];
return invoiceIds;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -12,8 +12,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
}; };
@ -35,8 +35,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
problems: true problems: true
}; };
@ -60,8 +60,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
problems: false problems: false
}; };
@ -85,8 +85,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
problems: null problems: null
}; };
@ -110,8 +110,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
state: 'OK' state: 'OK'
}; };
@ -135,8 +135,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
futureState: 'OK' futureState: 'OK'
}; };
@ -160,8 +160,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
ipt: null ipt: null
}; };
@ -185,8 +185,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
ipt: 'H' ipt: 'H'
}; };
@ -210,8 +210,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
futureIpt: null futureIpt: null
}; };
@ -235,8 +235,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
futureIpt: 'H' futureIpt: 'H'
}; };
@ -260,8 +260,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
id: 13 id: 13
}; };
@ -285,8 +285,8 @@ describe('ticket getTicketsFuture()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const args = { const args = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: 1, warehouseFk: 1,
futureId: 12 futureId: 12
}; };

View File

@ -0,0 +1,70 @@
const {models} = require('vn-loopback/server/server');
describe('ticket setWeight()', () => {
const ctx = beforeAll.getCtx();
beforeAll.mockLoopBackContext();
let opts;
let tx;
const employeeId = 1;
const administrativeId = 5;
beforeEach(async() => {
opts = {transaction: tx};
tx = await models.Ticket.beginTransaction({});
opts.transaction = tx;
ctx.req.accessToken.userId = administrativeId;
});
afterEach(async() => await tx.rollback());
it('should throw an error if the weight is already set', async() => {
try {
const ticketId = 1;
const weight = 10;
await models.Ticket.setWeight(ctx, ticketId, weight, opts);
} catch (e) {
expect(e.message).toEqual('Weight already set');
}
});
it('should set the weight of a ticket', async() => {
const ticketId = 31;
const weight = 15;
await models.Ticket.setWeight(ctx, ticketId, weight, opts);
const ticket = await models.Ticket.findById(ticketId, null, opts);
expect(ticket.weight).toEqual(weight);
});
it('should throw an error if the user is not allocated to the same department', async() => {
ctx.req.accessToken.userId = employeeId;
try {
const ticketId = 10;
const weight = 20;
await models.Ticket.setWeight(ctx, ticketId, weight, opts);
} catch (e) {
expect(e.message).toEqual('This ticket is not allocated to your department');
}
});
it('should call invoiceTicketsAndPdf if the ticket is invoiceable', async() => {
const ticketId = 10;
const weight = 25;
spyOn(models.Client, 'findById').and.returnValue({
hasDailyInvoice: true,
salesPersonUser: () => ({id: 1})
});
spyOn(models.TicketState, 'findOne').and.returnValue({alertLevel: 3});
spyOn(models.Ticket, 'rawSql').and.returnValue([{taxArea: 'WORLD'}]);
spyOn(models.Ticket, 'invoiceTicketsAndPdf').and.returnValue([10]);
const invoiceIds = await models.Ticket.setWeight(ctx, ticketId, weight, opts);
expect(invoiceIds.length).toBeGreaterThan(0);
});
});

View File

@ -46,4 +46,5 @@ module.exports = function(Self) {
require('../methods/ticket/invoiceTicketsAndPdf')(Self); require('../methods/ticket/invoiceTicketsAndPdf')(Self);
require('../methods/ticket/docuwareDownload')(Self); require('../methods/ticket/docuwareDownload')(Self);
require('../methods/ticket/myLastModified')(Self); require('../methods/ticket/myLastModified')(Self);
require('../methods/ticket/setWeight')(Self);
}; };

View File

@ -39,14 +39,8 @@
<thead> <thead>
<tr second-header> <tr second-header>
<td></td> <td></td>
<th colspan="7"> <th colspan="9" translate>Destination</th>
<span translate>Destination</span> <th colspan="11" translate>Origin</th>
{{model.userParams.dateToAdvance| date: 'dd/MM/yyyy'}}
</th>
<th colspan="11">
<span translate>Origin</span>
{{model.userParams.dateFuture | date: 'dd/MM/yyyy'}}
</th>
</tr> </tr>
<tr> <tr>
<th shrink> <th shrink>
@ -56,14 +50,16 @@
check-field="checked"> check-field="checked">
</vn-multi-check> </vn-multi-check>
</th> </th>
<th shrink> <th shrink></th>
</th>
<th field="id"> <th field="id">
<span translate>ID</span> <span translate>ID</span>
</th> </th>
<th field="ipt" title="{{'Item Packing Type' | translate}}"> <th field="ipt" title="{{'Item Packing Type' | translate}}">
<span>IPT</span> <span>IPT</span>
</th> </th>
<th field="preparation">
<span translate>Preparation</span>
</th>
<th field="state"> <th field="state">
<span translate>State</span> <span translate>State</span>
</th> </th>
@ -125,6 +121,7 @@
</span> </span>
</td> </td>
<td>{{::ticket.ipt | dashIfEmpty}}</td> <td>{{::ticket.ipt | dashIfEmpty}}</td>
<td>{{::ticket.preparation | dashIfEmpty}}</td>
<td> <td>
<span <span
class="chip {{ticket.classColor}}"> class="chip {{ticket.classColor}}">
@ -165,7 +162,6 @@
{{::(ticket.futureTotalWithVat ? ticket.futureTotalWithVat : 0) | currency: 'EUR': 2}} {{::(ticket.futureTotalWithVat ? ticket.futureTotalWithVat : 0) | currency: 'EUR': 2}}
</span> </span>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -9,13 +9,13 @@
<vn-date-picker <vn-date-picker
vn-one vn-one
label="Origin date" label="Origin date"
ng-model="filter.originDated" ng-model="filter.originScopeDays"
required="true"> required="true">
</vn-date-picker> </vn-date-picker>
<vn-date-picker <vn-date-picker
vn-one vn-one
label="Destination date" label="Destination date"
ng-model="filter.futureDated" ng-model="filter.futureScopeDays"
required="true"> required="true">
</vn-date-picker> </vn-date-picker>
</vn-horizontal> </vn-horizontal>
@ -59,7 +59,7 @@
<vn-autocomplete vn-one <vn-autocomplete vn-one
data="$ctrl.groupedStates" data="$ctrl.groupedStates"
label="Origin Grouped State" label="Origin Grouped State"
value-field="code" value-field="id"
show-field="name" show-field="name"
ng-model="filter.state"> ng-model="filter.state">
<tpl-item> <tpl-item>
@ -69,7 +69,7 @@
<vn-autocomplete vn-one <vn-autocomplete vn-one
data="$ctrl.groupedStates" data="$ctrl.groupedStates"
label="Destination Grouped State" label="Destination Grouped State"
value-field="code" value-field="id"
show-field="name" show-field="name"
ng-model="filter.futureState"> ng-model="filter.futureState">
<tpl-item> <tpl-item>

View File

@ -65,8 +65,8 @@ export default class Controller extends Section {
this.$http.get(`UserConfigs/getUserConfig`) this.$http.get(`UserConfigs/getUserConfig`)
.then(res => { .then(res => {
this.filterParams = { this.filterParams = {
originDated: today, originScopeDays: today,
futureDated: today, futureScopeDays: today,
warehouseFk: res.data.warehouseFk warehouseFk: res.data.warehouseFk
}; };
this.$.model.applyFilter(null, this.filterParams); this.$.model.applyFilter(null, this.filterParams);

View File

@ -14,3 +14,4 @@ Success: Tickets movidos correctamente
IPT: Encajado IPT: Encajado
Origin Date: Fecha origen Origin Date: Fecha origen
Destination Date: Fecha destino Destination Date: Fecha destino
Preparation: Preparación

View File

@ -4,3 +4,4 @@ Client phone: Tel. cliente
Client mobile: Móv. cliente Client mobile: Móv. cliente
Go to the ticket: Ir al ticket Go to the ticket: Ir al ticket
Change state: Cambiar estado Change state: Cambiar estado
Weight: Peso

View File

@ -8,19 +8,19 @@ module.exports = Self => {
accepts: [ accepts: [
{ {
arg: 'id', arg: 'id',
type: 'Number', type: 'number',
description: 'The worker id', description: 'The worker id',
http: {source: 'path'} http: {source: 'path'}
}, },
{ {
arg: 'filter', arg: 'filter',
type: 'Object', type: 'object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
http: {source: 'query'} http: {source: 'query'}
} }
], ],
returns: { returns: {
type: ['Object'], type: ['object'],
root: true root: true
}, },
http: { http: {
@ -36,38 +36,50 @@ module.exports = Self => {
// Get ids alloweds // Get ids alloweds
const account = await models.VnUser.findById(userId); const account = await models.VnUser.findById(userId);
const stmt = new ParameterizedSQL( const stmt = new ParameterizedSQL(
`SELECT d.id, d.id dmsFk `SELECT d.id, d.id dmsFk
FROM workerDocument wd FROM workerDms wd
JOIN dms d ON d.id = wd.document JOIN dms d ON d.id = wd.dmsFk
JOIN dmsType dt ON dt.id = d.dmsTypeFk JOIN dmsType dt ON dt.id = d.dmsTypeFk
LEFT JOIN account.roleRole rr ON rr.inheritsFrom = dt.readRoleFk AND rr.role = ? LEFT JOIN account.roleRole rr ON rr.inheritsFrom = dt.readRoleFk
AND rr.role = ?
`, [account.roleFk] `, [account.roleFk]
); );
const yourOwnDms = {and: [{isReadableByWorker: true}, {worker: userId}]}; const yourOwnDms = {
const where = { or: [
or: [yourOwnDms, { {and: [
role: { {isReadableByWorker: true},
neq: null {'wd.workerFk': userId}
} ]},
}] {
role: {
neq: null
}
}]
}; };
stmt.merge(conn.makeSuffix(mergeWhere(filter.where, where)));
// Get workerDms alloweds const where = mergeWhere(filter.where, yourOwnDms);
stmt.merge(conn.makeSuffix({where}));
const dmsIds = await conn.executeStmt(stmt); const dmsIds = await conn.executeStmt(stmt);
const allowedIds = dmsIds.map(dms => dms.id); const allowedIds = dmsIds.map(dms => dms.id);
const allowedFilter = mergeFilters(filter, {where: {dmsFk: {inq: allowedIds}, workerFk: id}}); const allowedFilter = mergeFilters(filter, {where: {dmsFk: {inq: allowedIds}, workerFk: id}});
let workerDms = await models.WorkerDms.find(allowedFilter);
// Get docuware info const workerDms = await models.WorkerDms.find(allowedFilter);
const docuware = await models.Docuware.findOne({
fields: ['dmsTypeFk'], const workerDocuware = filter.skip ? [] : await getDocuware(ctx, id);
where: {code: 'hr', action: 'find'} return workerDms.concat(workerDocuware);
});
const docuwareDmsType = docuware.dmsTypeFk; async function getDocuware(ctx, id) {
let workerDocuware = []; const {dmsTypeFk} = await models.Docuware.findOne({
if (!filter.skip && (!docuwareDmsType || (docuwareDmsType && await models.DmsType.hasReadRole(ctx, docuwareDmsType)))) { fields: ['dmsTypeFk'],
where: {code: 'hr', action: 'find'}
});
if (!await models.DmsType.hasReadRole(ctx, dmsTypeFk)) return [];
let workerDocuware = [];
const worker = await models.Worker.findById(id, {fields: ['fi', 'firstName', 'lastName']}); const worker = await models.Worker.findById(id, {fields: ['fi', 'firstName', 'lastName']});
const docuwareParse = { const docuwareParse = {
'Filename': 'dmsFk', 'Filename': 'dmsFk',
@ -80,7 +92,7 @@ module.exports = Self => {
}; };
workerDocuware = workerDocuware =
await models.Docuware.getById('hr', worker.lastName + ' ' + worker.firstName, docuwareParse) ?? []; await models.Docuware.getById('hr', worker.lastName + ' ' + worker.firstName, docuwareParse) ?? [];
const url = (await Self.app.models.Url.getUrl('docuware')) + 'WebClient'; const url = (await Self.app.models.Url.getUrl('docuware')) + 'WebClient';
for (document of workerDocuware) { for (document of workerDocuware) {
const docuwareId = document.id; const docuwareId = document.id;
@ -105,7 +117,7 @@ module.exports = Self => {
}; };
Object.assign(document, defaultData); Object.assign(document, defaultData);
} }
return workerDocuware;
} }
return workerDms.concat(workerDocuware);
}; };
}; };

View File

@ -6,7 +6,7 @@
}, },
"options": { "options": {
"mysql": { "mysql": {
"table": "workerDocument" "table": "workerDms"
} }
}, },
"properties": { "properties": {
@ -16,17 +16,11 @@
}, },
"dmsFk": { "dmsFk": {
"type": "number", "type": "number",
"required": true, "required": true
"mysql": {
"columnName": "document"
}
}, },
"workerFk": { "workerFk": {
"type": "number", "type": "number",
"required": true, "required": true
"mysql": {
"columnName": "worker"
}
}, },
"isReadableByWorker": { "isReadableByWorker": {
"type": "boolean" "type": "boolean"

View File

@ -2,6 +2,7 @@ code: vn-database
versionSchema: util versionSchema: util
replace: true replace: true
sumViews: false sumViews: false
defaultDefiner: vn@localhost
mockDate: '2001-01-01 12:00:00' mockDate: '2001-01-01 12:00:00'
subdir: db subdir: db
schemas: schemas:
@ -375,7 +376,7 @@ localFixtures:
- workerBosses - workerBosses
- workerBusinessType - workerBusinessType
- workerConfig - workerConfig
- workerDocument - workerDms
- workerLog - workerLog
- workerMana - workerMana
- workerManaExcluded - workerManaExcluded

View File

@ -60,7 +60,7 @@
"@babel/register": "^7.7.7", "@babel/register": "^7.7.7",
"@commitlint/cli": "^19.2.1", "@commitlint/cli": "^19.2.1",
"@commitlint/config-conventional": "^19.1.0", "@commitlint/config-conventional": "^19.1.0",
"@verdnatura/myt": "^1.6.9", "@verdnatura/myt": "^1.6.11",
"angular-mocks": "^1.7.9", "angular-mocks": "^1.7.9",
"babel-jest": "^26.0.1", "babel-jest": "^26.0.1",
"babel-loader": "^8.2.4", "babel-loader": "^8.2.4",

View File

@ -143,8 +143,8 @@ devDependencies:
specifier: ^19.1.0 specifier: ^19.1.0
version: 19.1.0 version: 19.1.0
'@verdnatura/myt': '@verdnatura/myt':
specifier: ^1.6.9 specifier: ^1.6.11
version: 1.6.9 version: 1.6.11
angular-mocks: angular-mocks:
specifier: ^1.7.9 specifier: ^1.7.9
version: 1.8.3 version: 1.8.3
@ -2846,8 +2846,8 @@ packages:
dev: false dev: false
optional: true optional: true
/@verdnatura/myt@1.6.9: /@verdnatura/myt@1.6.11:
resolution: {integrity: sha512-29IauYra9igfdPWwV4+pVV/tBXvIg0fkVHEpSz8Zz3G3lRtzm286FN2Kv6hZkxmD/F1n52O37jN9WLiLHDTW1Q==} resolution: {integrity: sha512-uqdbSJSznBBzAoRkvBt600nUMEPL1PJ2v73eWMZbaoGUMiZiNAehYjs4gIrObP1cxC85JOx97XoLpG0BzPsaig==}
hasBin: true hasBin: true
dependencies: dependencies:
'@sqltools/formatter': 1.2.5 '@sqltools/formatter': 1.2.5
@ -3306,6 +3306,7 @@ packages:
/are-we-there-yet@1.1.7: /are-we-there-yet@1.1.7:
resolution: {integrity: sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==} resolution: {integrity: sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==}
deprecated: This package is no longer supported.
dependencies: dependencies:
delegates: 1.0.0 delegates: 1.0.0
readable-stream: 2.3.8 readable-stream: 2.3.8
@ -6593,6 +6594,7 @@ packages:
/gauge@2.7.4: /gauge@2.7.4:
resolution: {integrity: sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==} resolution: {integrity: sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==}
deprecated: This package is no longer supported.
dependencies: dependencies:
aproba: 1.2.0 aproba: 1.2.0
console-control-strings: 1.1.0 console-control-strings: 1.1.0
@ -10814,6 +10816,7 @@ packages:
/npmlog@4.1.2: /npmlog@4.1.2:
resolution: {integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==} resolution: {integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==}
deprecated: This package is no longer supported.
dependencies: dependencies:
are-we-there-yet: 1.1.7 are-we-there-yet: 1.1.7
console-control-strings: 1.1.0 console-control-strings: 1.1.0
@ -11055,6 +11058,7 @@ packages:
/osenv@0.1.5: /osenv@0.1.5:
resolution: {integrity: sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==} resolution: {integrity: sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==}
deprecated: This package is no longer supported.
dependencies: dependencies:
os-homedir: 1.0.2 os-homedir: 1.0.2
os-tmpdir: 1.0.2 os-tmpdir: 1.0.2