From 91fac11fa0ac19c03fb8cfde516c7a47c44e5d49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Mon, 16 Sep 2024 18:21:12 +0200 Subject: [PATCH 01/84] fix: refs #7760 tmp.ticketIPT --- .../vn/procedures/prepareTicketList.sql | 8 +- .../vn/procedures/productionControl.sql | 43 ++-- .../vn/procedures/sale_getProblems.sql | 233 ----------------- .../procedures/sale_getProblemsByTicket.sql | 23 +- .../vn/procedures/ticket_getProblems.sql | 239 +++++++++++++++--- .../back/methods/sales-monitor/salesFilter.js | 11 +- modules/ticket/back/methods/ticket/filter.js | 10 +- .../back/methods/ticket/getTicketsFuture.js | 10 +- 8 files changed, 250 insertions(+), 327 deletions(-) delete mode 100644 db/routines/vn/procedures/sale_getProblems.sql diff --git a/db/routines/vn/procedures/prepareTicketList.sql b/db/routines/vn/procedures/prepareTicketList.sql index 7c44bb9946..cfe9492ee0 100644 --- a/db/routines/vn/procedures/prepareTicketList.sql +++ b/db/routines/vn/procedures/prepareTicketList.sql @@ -1,16 +1,18 @@ DELIMITER $$ -CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`prepareTicketList`(vStartingDate DATETIME, vEndingDate DATETIME) +CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`prepareTicketList`( + vStartingDate DATETIME, + vEndingDate DATETIME +) BEGIN DROP TEMPORARY TABLE IF EXISTS tmp.productionTicket; CREATE TEMPORARY TABLE tmp.productionTicket (PRIMARY KEY (ticketFk)) ENGINE = MEMORY - SELECT t.id ticketFk, t.clientFk + SELECT t.id ticketFk FROM ticket t JOIN alertLevel al ON al.code = 'DELIVERED' LEFT JOIN ticketState ts ON ts.ticketFk = t.id JOIN client c ON c.id = t.clientFk - WHERE c.typeFk IN ('normal','handMaking','internalUse') AND ( t.shipped BETWEEN util.VN_CURDATE() AND vEndingDate diff --git a/db/routines/vn/procedures/productionControl.sql b/db/routines/vn/procedures/productionControl.sql index e5323e84ef..88ed42e837 100644 --- a/db/routines/vn/procedures/productionControl.sql +++ b/db/routines/vn/procedures/productionControl.sql @@ -15,7 +15,7 @@ proc: BEGIN DECLARE vEndingDate DATETIME; DECLARE vIsTodayRelative BOOLEAN; - SELECT util.dayEnd(util.VN_CURDATE()) + INTERVAL LEAST(vScopeDays, maxProductionScopeDays) DAY + SELECT util.dayEnd(util.VN_CURDATE() + INTERVAL LEAST(vScopeDays, maxProductionScopeDays) DAY) INTO vEndingDate FROM productionConfig; @@ -26,16 +26,10 @@ proc: BEGIN CALL prepareTicketList(util.yesterday(), vEndingDate); CREATE OR REPLACE TEMPORARY TABLE tmp.ticket - SELECT * FROM tmp.productionTicket; - - CALL prepareClientList(); - - CREATE OR REPLACE TEMPORARY TABLE tmp.sale_getProblems (INDEX (ticketFk)) ENGINE = MEMORY - SELECT tt.ticketFk, tt.clientFk, t.warehouseFk, t.shipped - FROM tmp.productionTicket tt - JOIN ticket t ON t.id = tt.ticketFk; + SELECT ticketFk + FROM tmp.productionTicket; CALL ticket_getProblems(vIsTodayRelative); @@ -43,7 +37,7 @@ proc: BEGIN (PRIMARY KEY(ticketFk), previaParking VARCHAR(255)) ENGINE = MEMORY SELECT tt.ticketFk, - tt.clientFk, + t.clientFk, t.warehouseFk, t.nickname, t.packages, @@ -61,7 +55,17 @@ proc: BEGIN 0 `lines`, CAST( 0 AS DECIMAL(5,2)) m3, CAST( 0 AS DECIMAL(5,2)) preparationRate, - "" problem, + TRIM(CAST(CONCAT( IFNULL(tpr.itemShortage, ''), + IFNULL(tpr.itemDelay, ''), + IFNULL(tpr.itemLost, ''), + IF(tpr.isFreezed, ' CONGELADO',''), + IF(tpr.hasHighRisk, ' RIESGO',''), + IF(tpr.hasTicketRequest, ' COD 100',''), + IF(tpr.isTaxDataChecked, '',' FICHA INCOMPLETA'), + IF(tpr.hasComponentLack, ' COMPONENTES', ''), + IF(HOUR(util.VN_NOW()) < IF(HOUR(t.shipped), HOUR(t.shipped), COALESCE(HOUR(zc.hour),HOUR(z.hour))) + AND tpr.isTooLittle, ' PEQUEÑO', '') + ) AS char(255))) problem, IFNULL(tls.state,2) state, w.code workerCode, DATE(t.shipped) shipped, @@ -101,6 +105,7 @@ proc: BEGIN AND DATE(t.shipped) = zc.dated LEFT JOIN ticketParking tp ON tp.ticketFk = t.id LEFT JOIN parking pk ON pk.id = tp.parkingFk + LEFT JOIN tmp.ticketProblem tpr ON tpr.ticketFk = tt.ticketFk WHERE t.warehouseFk = vWarehouseFk AND dm.code IN ('AGENCY', 'DELIVERY', 'PICKUP'); @@ -123,19 +128,6 @@ proc: BEGIN ADD COLUMN `collectionV` INT, ADD COLUMN `collectionN` INT; - UPDATE tmp.productionBuffer pb - JOIN tmp.ticket_problems tp ON tp.ticketFk = pb.ticketFk - SET pb.problem = TRIM(CAST(CONCAT( IFNULL(tp.itemShortage, ''), - IFNULL(tp.itemDelay, ''), - IFNULL(tp.itemLost, ''), - IF(tp.isFreezed, ' CONGELADO',''), - IF(tp.hasHighRisk, ' RIESGO',''), - IF(tp.hasTicketRequest, ' COD 100',''), - IF(tp.isTaxDataChecked, '',' FICHA INCOMPLETA'), - IF(tp.hasComponentLack, ' COMPONENTES', ''), - IF(HOUR(util.VN_NOW()) < pb.HH AND tp.isTooLittle, ' PEQUEÑO', '') - ) AS char(255))); - -- Clientes Nuevos o Recuperados UPDATE tmp.productionBuffer pb LEFT JOIN bs.clientNewBorn cnb ON cnb.clientFk = pb.clientFk @@ -267,8 +259,7 @@ proc: BEGIN DROP TEMPORARY TABLE tmp.productionTicket, - tmp.ticket, - tmp.ticket_problems, + tmp.ticketProblems, tmp.ticketWithPrevia, tItemShelvingStock, tItemPackingType; diff --git a/db/routines/vn/procedures/sale_getProblems.sql b/db/routines/vn/procedures/sale_getProblems.sql deleted file mode 100644 index 2bba8fbc39..0000000000 --- a/db/routines/vn/procedures/sale_getProblems.sql +++ /dev/null @@ -1,233 +0,0 @@ -DELIMITER $$ -CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`sale_getProblems`( - vIsTodayRelative tinyint(1) -) -BEGIN -/** - * Calcula los problemas de cada venta para un conjunto de tickets. - * - * @param vIsTodayRelative Indica si se calcula el disponible como si todo saliera hoy - * @table tmp.sale_getProblems(ticketFk, clientFk, warehouseFk, shipped) Tickets a calcular - * @return tmp.sale_problems - */ - DECLARE vWarehouseFk INT; - DECLARE vDate DATE; - DECLARE vAvailableCache INT; - DECLARE vVisibleCache INT; - DECLARE vDone BOOL; - DECLARE vCursor CURSOR FOR - SELECT DISTINCT warehouseFk, IF(vIsTodayRelative, util.VN_CURDATE(), DATE(shipped)) - FROM tmp.sale_getProblems - WHERE shipped BETWEEN util.VN_CURDATE() - AND util.dayEnd(util.VN_CURDATE() + INTERVAL IF(vIsTodayRelative, 9.9, 1.9) DAY); - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - - CREATE OR REPLACE TEMPORARY TABLE tmp.sale_problems ( - ticketFk INT(11), - saleFk INT(11), - isFreezed INTEGER(1) DEFAULT 0, - risk DECIMAL(10,1) DEFAULT 0, - hasRisk TINYINT(1) DEFAULT 0, - hasHighRisk TINYINT(1) DEFAULT 0, - hasTicketRequest INTEGER(1) DEFAULT 0, - itemShortage VARCHAR(255), - isTaxDataChecked INTEGER(1) DEFAULT 1, - itemDelay VARCHAR(255), - itemLost VARCHAR(255), - hasComponentLack INTEGER(1), - hasRounding VARCHAR(255), - isTooLittle BOOL DEFAULT FALSE, - isVip BOOL DEFAULT FALSE, - PRIMARY KEY (ticketFk, saleFk) - ) ENGINE = MEMORY; - - INSERT INTO tmp.sale_problems(ticketFk, - saleFk, - isFreezed, - risk, - hasRisk, - hasHighRisk, - hasTicketRequest, - isTaxDataChecked, - hasComponentLack, - isTooLittle) - SELECT sgp.ticketFk, - s.id, - IF(FIND_IN_SET('isFreezed', t.problem), TRUE, FALSE) isFreezed, - t.risk, - IF(FIND_IN_SET('hasRisk', t.problem), TRUE, FALSE) hasRisk, - IF(FIND_IN_SET('hasHighRisk', t.problem), TRUE, FALSE) hasHighRisk, - IF(FIND_IN_SET('hasTicketRequest', t.problem), TRUE, FALSE) hasTicketRequest, - IF(FIND_IN_SET('isTaxDataChecked', t.problem), FALSE, TRUE) isTaxDataChecked, - IF(FIND_IN_SET('hasComponentLack', s.problem), TRUE, FALSE) hasComponentLack, - IF(FIND_IN_SET('isTooLittle', t.problem) - AND util.VN_NOW() < (util.VN_CURDATE() + INTERVAL HOUR(zc.`hour`) HOUR) + INTERVAL MINUTE(zc.`hour`) MINUTE, - TRUE, FALSE) isTooLittle - FROM tmp.sale_getProblems sgp - JOIN ticket t ON t.id = sgp.ticketFk - LEFT JOIN sale s ON s.ticketFk = t.id - LEFT JOIN item i ON i.id = s.itemFk - LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk - AND zc.dated = util.VN_CURDATE() - WHERE s.problem <> '' OR t.problem <> '' OR t.risk - GROUP BY t.id, s.id; - - INSERT INTO tmp.sale_problems(ticketFk, isVip) - SELECT sgp.ticketFk, TRUE - FROM tmp.sale_getProblems sgp - JOIN client c ON c.id = sgp.clientFk - WHERE c.businessTypeFk = 'VIP' - ON DUPLICATE KEY UPDATE isVIP = TRUE; - - CREATE OR REPLACE TEMPORARY TABLE tItemShelvingStock_byWarehouse - (INDEX (itemFk, warehouseFk)) - ENGINE = MEMORY - SELECT ish.itemFk itemFk, - SUM(ish.visible) visible, - s.warehouseFk warehouseFk - FROM itemShelving ish - JOIN shelving sh ON sh.code = ish.shelvingFk - JOIN parking p ON p.id = sh.parkingFk - JOIN sector s ON s.id = p.sectorFk - GROUP BY ish.itemFk, s.warehouseFk; - - -- Disponible, faltas, inventario y retrasos - OPEN vCursor; - l: LOOP - SET vDone = FALSE; - FETCH vCursor INTO vWarehouseFk, vDate; - - IF vDone THEN - LEAVE l; - END IF; - - -- Disponible: no va a haber suficiente producto para preparar todos los pedidos - CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouseFk, vDate); - - -- Faltas: visible, disponible y ubicado son menores que la cantidad vendida - CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouseFk); - - INSERT INTO tmp.sale_problems(ticketFk, itemShortage, saleFk) - SELECT ticketFk, problem, saleFk - FROM ( - SELECT sgp.ticketFk, - LEFT(CONCAT('F: ', GROUP_CONCAT(i.id, ' ', i.longName, ' ')), 250) problem, - s.id saleFk - FROM tmp.sale_getProblems sgp - JOIN ticket t ON t.id = sgp.ticketFk - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - JOIN itemType it ON it.id = i.typeFk - JOIN itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN cache.visible v ON v.item_id = i.id - AND v.calc_id = vVisibleCache - LEFT JOIN cache.available av ON av.item_id = i.id - AND av.calc_id = vAvailableCache - LEFT JOIN tItemShelvingStock_byWarehouse issw ON issw.itemFk = i.id - AND issw.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible, 0) < s.quantity - AND IFNULL(av.available, 0) < s.quantity - AND IFNULL(issw.visible, 0) < s.quantity - AND NOT s.isPicked - AND NOT s.reserved - AND ic.merchandise - AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) - AND NOT i.generic - AND util.VN_CURDATE() = vDate - AND t.warehouseFk = vWarehouseFk - GROUP BY sgp.ticketFk) sub - ON DUPLICATE KEY UPDATE itemShortage = sub.problem, saleFk = sub.saleFk; - - -- Inventario: Visible suficiente, pero ubicado menor a la cantidad vendida - INSERT INTO tmp.sale_problems(ticketFk, itemLost, saleFk) - SELECT ticketFk, problem, saleFk - FROM ( - SELECT sgp.ticketFk, - LEFT(GROUP_CONCAT('I: ', i.id, ' ', i.longName, ' '), 250) problem, - s.id saleFk - FROM tmp.sale_getProblems sgp - JOIN ticket t ON t.id = sgp.ticketFk - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - JOIN itemType it ON it.id = i.typeFk - JOIN itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN cache.visible v ON v.item_id = s.itemFk - AND v.calc_id = vVisibleCache - LEFT JOIN tItemShelvingStock_byWarehouse issw ON issw.itemFk = i.id - AND issw.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible, 0) >= s.quantity - AND IFNULL(issw.visible, 0) < s.quantity - AND s.quantity > 0 - AND NOT s.isPicked - AND NOT s.reserved - AND ic.merchandise - AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) - AND NOT i.generic - AND util.VN_CURDATE() = vDate - AND t.warehouseFk = vWarehouseFk - GROUP BY sgp.ticketFk - ) sub - ON DUPLICATE KEY UPDATE itemLost = sub.problem, saleFk = sub.saleFk; - - -- Retraso: Disponible suficiente, pero no visible ni ubicado - INSERT INTO tmp.sale_problems(ticketFk, itemDelay, saleFk) - SELECT ticketFk, problem, saleFk - FROM ( - SELECT sgp.ticketFk, - LEFT(GROUP_CONCAT('R: ', i.id, ' ', i.longName, ' '), 250) problem, - s.id saleFk - FROM tmp.sale_getProblems sgp - JOIN ticket t ON t.id = sgp.ticketFk - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - JOIN itemType it ON it.id = i.typeFk - JOIN itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN cache.visible v ON v.item_id = s.itemFk - AND v.calc_id = vVisibleCache - LEFT JOIN cache.available av ON av.item_id = i.id - AND av.calc_id = vAvailableCache - LEFT JOIN tItemShelvingStock_byWarehouse issw ON issw.itemFk = i.id - AND issw.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible, 0) < s.quantity - AND IFNULL(av.available, 0) >= s.quantity - AND IFNULL(issw.visible, 0) < s.quantity - AND s.quantity > 0 - AND NOT s.isPicked - AND NOT s.reserved - AND ic.merchandise - AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) - AND NOT i.generic - AND util.VN_CURDATE() = vDate - AND t.warehouseFk = vWarehouseFk - GROUP BY sgp.ticketFk - ) sub - 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; - CLOSE vCursor; - - DROP TEMPORARY TABLE tItemShelvingStock_byWarehouse; -END$$ -DELIMITER ; diff --git a/db/routines/vn/procedures/sale_getProblemsByTicket.sql b/db/routines/vn/procedures/sale_getProblemsByTicket.sql index ff419989d4..af69e84300 100644 --- a/db/routines/vn/procedures/sale_getProblemsByTicket.sql +++ b/db/routines/vn/procedures/sale_getProblemsByTicket.sql @@ -1,5 +1,8 @@ DELIMITER $$ -CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`sale_getProblemsByTicket`(IN vTicketFk INT, IN vIsTodayRelative TINYINT(1)) +CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`sale_getProblemsByTicket`( + IN vTicketFk INT, + IN vIsTodayRelative TINYINT(1) +) BEGIN /** * Calcula los problemas de cada venta @@ -7,19 +10,17 @@ BEGIN * * @return Problems result */ - CREATE OR REPLACE TEMPORARY TABLE tmp.sale_getProblems - (INDEX (ticketFk)) - ENGINE = MEMORY - SELECT t.id ticketFk, t.clientFk, t.warehouseFk, t.shipped - FROM ticket t - WHERE t.id = vTicketFk; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticket + (INDEX (ticketFk)) + ENGINE = MEMORY + SELECT vTicketFk ticketFk; - CALL sale_getProblems(vIsTodayRelative); + CALL ticket_getProblems(vIsTodayRelative); - SELECT * FROM tmp.sale_problems; + SELECT * FROM tmp.saleProblems; DROP TEMPORARY TABLE - tmp.sale_getProblems, - tmp.sale_problems; + tmp.ticket, + tmp.ticketProblems; END$$ DELIMITER ; diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index 1851bce47f..00a8ee7278 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -1,53 +1,216 @@ DELIMITER $$ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_getProblems`( - vIsTodayRelative tinyint(1) + vIsTodayRelative TINYINT(1) ) BEGIN /** * Calcula los problemas para un conjunto de tickets. * Agrupados por ticket * - * @table tmp.sale_getProblems(ticketFk, clientFk, warehouseFk, shipped) Identificadores de los tickets a calcular - * @return tmp.ticket_problems + * @table tmp.tmp.ticket(ticketFk) Identificadores de los tickets a calcular + * @return tmp.ticketProblems */ - CALL sale_getProblems(vIsTodayRelative); + DECLARE vWarehouseFk INT; + DECLARE vDate DATE; + DECLARE vAvailableCache INT; + DECLARE vVisibleCache INT; + DECLARE vDone BOOL; + DECLARE vCursor CURSOR FOR + SELECT DISTINCT t.warehouseFk, IF(vIsTodayRelative, util.VN_CURDATE(), DATE(t.shipped)) + FROM tmp.ticket t + JOIN ticket t ON t.id = t.ticketFk + WHERE t.shipped BETWEEN util.VN_CURDATE() + AND util.dayEnd(util.VN_CURDATE() + INTERVAL IF(vIsTodayRelative, 9.9, 1.9) DAY); - CREATE OR REPLACE TEMPORARY TABLE tmp.ticket_problems - (PRIMARY KEY (ticketFk)) + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + + CREATE OR REPLACE TEMPORARY TABLE tmp.saleProblems( + ticketFk INT(11), + saleFk INT(11), + hasItemShortage BOOL DEFAULT FALSE, + hasItemLost BOOL DEFAULT FALSE, + hasItemDelay BOOL DEFAULT FALSE, + hasRounding BOOL DEFAULT FALSE, + PRIMARY KEY (ticketFk, saleFk) + ) ENGINE = MEMORY; + + CREATE OR REPLACE TEMPORARY TABLE tItemShelving + (INDEX (itemFk, warehouseFk)) ENGINE = MEMORY - SELECT ticketFk, - MAX(isFreezed) isFreezed, - MAX(risk) risk, - MAX(hasRisk) hasRisk, - MAX(hasHighRisk) hasHighRisk, - MAX(hasTicketRequest) hasTicketRequest, - MAX(itemShortage) itemShortage, - MIN(isTaxDataChecked) isTaxDataChecked, - MAX(hasComponentLack) hasComponentLack, - MAX(isTooLittle) isTooLittle, - MAX(itemDelay) itemDelay, - MAX(hasRounding) hasRounding, - MAX(itemLost) itemLost, - MAX(isVip) isVip, - 0 totalProblems - FROM tmp.sale_problems - GROUP BY ticketFk; + SELECT ish.itemFk itemFk, + SUM(ish.visible) visible, + s.warehouseFk warehouseFk + FROM itemShelving ish + JOIN shelving sh ON sh.code = ish.shelvingFk + JOIN parking p ON p.id = sh.parkingFk + JOIN sector s ON s.id = p.sectorFk + GROUP BY ish.itemFk, s.warehouseFk; + + -- Disponible, faltas, inventario y retrasos + OPEN vCursor; + l: LOOP + SET vDone = FALSE; + FETCH vCursor INTO vWarehouseFk, vDate; - UPDATE tmp.ticket_problems - SET totalProblems = ( - (isFreezed) + - (hasHighRisk) + - (hasTicketRequest) + - (!isTaxDataChecked) + - (hasComponentLack) + - (itemDelay IS NOT NULL) + - (isTooLittle) + - (itemLost IS NOT NULL) + - (hasRounding IS NOT NULL) + - (itemShortage IS NOT NULL) + - (isVip) - ); + IF vDone THEN + LEAVE l; + END IF; + + -- Disponible: no va a haber suficiente producto para preparar todos los pedidos + CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouseFk, vDate); + + -- Faltas: visible, disponible y ubicado son menores que la cantidad vendida + CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouseFk); - DROP TEMPORARY TABLE tmp.sale_problems; + INSERT INTO tmp.saleProblems(ticketFk, saleFk, hasItemShortage) + SELECT tt.ticketFk, s.id, TRUE + FROM tmp.ticket tt + JOIN ticket t ON t.id = tt.ticketFk + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it ON it.id = i.typeFk + JOIN itemCategory ic ON ic.id = it.categoryFk + LEFT JOIN cache.visible v ON v.item_id = i.id + AND v.calc_id = vVisibleCache + LEFT JOIN cache.available av ON av.item_id = i.id + AND av.calc_id = vAvailableCache + LEFT JOIN tItemShelving tis ON tis.itemFk = i.id + AND tis.warehouseFk = t.warehouseFk + WHERE IFNULL(v.visible, 0) < s.quantity + AND IFNULL(av.available, 0) < s.quantity + AND IFNULL(tis.visible, 0) < s.quantity + AND NOT s.isPicked + AND NOT s.reserved + AND ic.merchandise + AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) + AND NOT i.generic + AND util.VN_CURDATE() = vDate + AND t.warehouseFk = vWarehouseFk + GROUP BY s.id; + + -- Inventario: Visible suficiente, pero ubicado menor a la cantidad vendida + INSERT INTO tmp.saleProblems(ticketFk, saleFk, hasItemLost) + SELECT tt.ticketFk, s.id, TRUE + FROM tmp.ticket tt + JOIN ticket t ON t.id = tt.ticketFk + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it ON it.id = i.typeFk + JOIN itemCategory ic ON ic.id = it.categoryFk + LEFT JOIN cache.visible v ON v.item_id = s.itemFk + AND v.calc_id = vVisibleCache + LEFT JOIN tItemShelving tis ON tis.itemFk = i.id + AND tis.warehouseFk = t.warehouseFk + WHERE IFNULL(v.visible, 0) >= s.quantity + AND IFNULL(tis.visible, 0) < s.quantity + AND s.quantity > 0 + AND NOT s.isPicked + AND NOT s.reserved + AND ic.merchandise + AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) + AND NOT i.generic + AND util.VN_CURDATE() = vDate + AND t.warehouseFk = vWarehouseFk + GROUP BY s.id + ON DUPLICATE KEY UPDATE hasItemLost = TRUE; + + -- Retraso: Disponible suficiente, pero no visible ni ubicado + INSERT INTO tmp.saleProblems(ticketFk, saleFk, hasItemDelay) + SELECT tt.ticketFk, s.id, TRUE + FROM tmp.ticket tt + JOIN ticket t ON t.id = tt.ticketFk + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it ON it.id = i.typeFk + JOIN itemCategory ic ON ic.id = it.categoryFk + LEFT JOIN cache.visible v ON v.item_id = s.itemFk + AND v.calc_id = vVisibleCache + LEFT JOIN cache.available av ON av.item_id = i.id + AND av.calc_id = vAvailableCache + LEFT JOIN tItemShelving tis ON tis.itemFk = i.id + AND tis.warehouseFk = t.warehouseFk + WHERE IFNULL(v.visible, 0) < s.quantity + AND IFNULL(av.available, 0) >= s.quantity + AND IFNULL(tis.visible, 0) < s.quantity + AND s.quantity > 0 + AND NOT s.isPicked + AND NOT s.reserved + AND ic.merchandise + AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) + AND NOT i.generic + AND util.VN_CURDATE() = vDate + AND t.warehouseFk = vWarehouseFk + GROUP BY s.id + ON DUPLICATE KEY UPDATE hasItemDelay = TRUE; + + -- Redondeo: cantidad incorrecta con respecto al grouping + CALL buy_getUltimate(NULL, vWarehouseFk, vDate); + + INSERT INTO tmp.saleProblems(ticketFk, saleFk, hasRounding) + SELECT tt.ticketFk, s.id, TRUE + FROM tmp.ticket tt + JOIN ticket t ON t.id = tt.ticketFk + AND t.warehouseFk = vWarehouseFk + JOIN sale s ON s.ticketFk = tt.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 s.id + ON DUPLICATE KEY UPDATE hasRounding = TRUE; + + DROP TEMPORARY TABLE tmp.buyUltimate; + END LOOP; + CLOSE vCursor; + + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketProblem ( + ticketFk INT(11), + isFreezed BOOL DEFAULT FALSE, + risk DECIMAL(10,1) DEFAULT 0, + hasRisk BOOL DEFAULT FALSE, + hasHighRisk BOOL DEFAULT FALSE, + hasTicketRequest BOOL DEFAULT FALSE, + isTaxDataChecked BOOL DEFAULT FALSE, + isTooLittle BOOL DEFAULT FALSE, + isVip BOOL DEFAULT FALSE, + hasItemShortage BOOL DEFAULT FALSE, + hasItemDelay BOOL DEFAULT FALSE, + hasItemLost BOOL DEFAULT FALSE, + hasComponentLack BOOL DEFAULT FALSE, + hasRounding BOOL DEFAULT FALSE, + PRIMARY KEY (ticketFk) + ) ENGINE = MEMORY + SELECT tt.ticketFk, + IF(FIND_IN_SET('isFreezed', t.problem), TRUE, FALSE) isFreezed, + t.risk, + IF(FIND_IN_SET('hasRisk', t.problem), TRUE, FALSE) hasRisk, + IF(FIND_IN_SET('hasHighRisk', t.problem), TRUE, FALSE) hasHighRisk, + IF(FIND_IN_SET('hasTicketRequest', t.problem), TRUE, FALSE) hasTicketRequest, + IF(FIND_IN_SET('isTaxDataChecked', t.problem), FALSE, TRUE) isTaxDataChecked, + IF(FIND_IN_SET('isTooLittle', t.problem) + AND util.VN_NOW() < (util.VN_CURDATE() + INTERVAL HOUR(zc.`hour`) HOUR) + INTERVAL MINUTE(zc.`hour`) MINUTE, + TRUE, FALSE) isTooLittle, + IF(c.businessTypeFk = 'VIP', TRUE, FALSE) isVip, + SUM(IFNULL(ts.hasItemShortage,0)) hasItemShortage, + SUM(IFNULL(ts.hasItemDelay,0)) hasItemDelay, + SUM(IFNULL(ts.hasItemLost,0)) hasItemLost, + IF(FIND_IN_SET('hasComponentLack', s.problem), TRUE, FALSE) hasComponentLack, + SUM(IFNULL(ts.hasRounding,0)) hasRounding, + LEFT(CONCAT('F: ',GROUP_CONCAT(CONCAT(i.id, ' ', i.longName) SEPARATOR ', ')), 250) itemShortage, + LEFT(CONCAT('R: ',GROUP_CONCAT(CONCAT(i2.id, ' ', i2.longName) SEPARATOR ', ')), 250) itemDelay, + LEFT(CONCAT('I: ',GROUP_CONCAT(CONCAT(i3.id, ' ', i3.longName) SEPARATOR ', ')), 250) itemLost, + LEFT(CONCAT('RE: ',GROUP_CONCAT(CONCAT(i4.id, ' ', i4.longName) SEPARATOR ', ')), 250) componentLack, + LEFT(CONCAT('RE: ',GROUP_CONCAT(CONCAT(i5.id, ' ', i5.longName) SEPARATOR ', ')), 250) rounding + FROM tmp.ticket tt + JOIN ticket t ON t.id = tt.ticketFk + JOIN client c ON c.id = t.clientFk + LEFT JOIN sale s ON s.ticketFk = t.id + LEFT JOIN tmp.saleProblems ts ON ts.saleFk = s.id + LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk + AND zc.dated = util.VN_CURDATE() + WHERE s.problem <> '' OR t.problem <> '' OR t.risk + GROUP BY t.id; + + DROP TEMPORARY TABLE tItemShelving; END$$ DELIMITER ; diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 927f49999f..9b22cb2d26 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -239,10 +239,10 @@ module.exports = Self => { stmts.push(`SET SESSION optimizer_search_depth = @_optimizer_search_depth`); stmt = new ParameterizedSQL(` - CREATE OR REPLACE TEMPORARY TABLE tmp.sale_getProblems + CREATE OR REPLACE TEMPORARY TABLE tmp.ticket (INDEX (ticketFk)) ENGINE = MEMORY - SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped + SELECT f.id ticketFk FROM tmp.filter f LEFT JOIN alertLevel al ON al.id = f.alertLevel WHERE (al.code = 'FREE' OR f.alertLevel IS NULL) @@ -263,7 +263,7 @@ module.exports = Self => { stmts.push('CALL ticket_getWarnings()'); stmt = new ParameterizedSQL(` - UPDATE tmp.ticket_problems + UPDATE tmp.ticketProblems SET risk = IF(hasRisk, risk, 0) `); stmts.push(stmt); @@ -271,7 +271,7 @@ module.exports = Self => { stmt = new ParameterizedSQL(` SELECT * FROM tmp.filter f - LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id + LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id LEFT JOIN tmp.ticket_warnings tw ON tw.ticketFk = f.id `); stmts.push(stmt); @@ -376,8 +376,7 @@ module.exports = Self => { stmts.push(` DROP TEMPORARY TABLE tmp.filter, - tmp.ticket_problems, - tmp.sale_getProblems, + tmp.ticketProblem, tmp.sale_getWarnings, tmp.ticket_warnings `); diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js index c98ddaab60..9ac239be77 100644 --- a/modules/ticket/back/methods/ticket/filter.js +++ b/modules/ticket/back/methods/ticket/filter.js @@ -293,10 +293,10 @@ module.exports = Self => { stmts.push(stmt); stmt = new ParameterizedSQL(` - CREATE OR REPLACE TEMPORARY TABLE tmp.sale_getProblems + CREATE OR REPLACE TEMPORARY TABLE tmp.ticket (INDEX (ticketFk)) ENGINE = MEMORY - SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped + SELECT f.id ticketFk FROM tmp.filter f LEFT JOIN alertLevel al ON al.id = f.alertLevel WHERE (al.code = 'FREE' OR f.alertLevel IS NULL) @@ -307,7 +307,7 @@ module.exports = Self => { stmts.push('CALL ticket_getProblems(FALSE)'); stmt = new ParameterizedSQL(` - UPDATE tmp.ticket_problems + UPDATE tmp.ticketProblems SET risk = IF(hasRisk, risk, 0) `); stmts.push(stmt); @@ -315,7 +315,7 @@ module.exports = Self => { stmt = new ParameterizedSQL(` SELECT f.*, tp.* FROM tmp.filter f - LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id + LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id `); if (args.problems != undefined && (!args.from && !args.to)) @@ -371,7 +371,7 @@ module.exports = Self => { stmts.push( `DROP TEMPORARY TABLE tmp.filter, - tmp.ticket_problems`); + tmp.ticketProblems`); const sql = ParameterizedSQL.join(stmts, ';'); const result = await conn.executeStmt(sql, myOptions); diff --git a/modules/ticket/back/methods/ticket/getTicketsFuture.js b/modules/ticket/back/methods/ticket/getTicketsFuture.js index 2479245912..1c31da057c 100644 --- a/modules/ticket/back/methods/ticket/getTicketsFuture.js +++ b/modules/ticket/back/methods/ticket/getTicketsFuture.js @@ -146,10 +146,10 @@ module.exports = Self => { stmts.push(stmt); stmt = new ParameterizedSQL(` - CREATE OR REPLACE TEMPORARY TABLE tmp.sale_getProblems + CREATE OR REPLACE TEMPORARY TABLE tmp.ticket (INDEX (ticketFk)) ENGINE = MEMORY - SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped, f.lines, f.liters + SELECT f.id ticketFk FROM tmp.filter f LEFT JOIN alertLevel al ON al.id = f.alertLevel WHERE (al.code = 'FREE' OR f.alertLevel IS NULL) @@ -159,7 +159,7 @@ module.exports = Self => { stmts.push('CALL ticket_getProblems(FALSE)'); stmt = new ParameterizedSQL(` - UPDATE tmp.ticket_problems + UPDATE tmp.ticketProblems SET risk = IF(hasRisk, risk, 0) `); stmts.push(stmt); @@ -167,7 +167,7 @@ module.exports = Self => { stmt = new ParameterizedSQL(` SELECT f.*, tp.* FROM tmp.filter f - LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id + LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id `); if (args.problems != undefined && (!args.originScopeDays && !args.futureScopeDays)) @@ -217,7 +217,7 @@ module.exports = Self => { stmts.push( `DROP TEMPORARY TABLE tmp.filter, - tmp.ticket_problems`); + tmp.ticketProblems`); const sql = ParameterizedSQL.join(stmts, ';'); const result = await conn.executeStmt(sql, myOptions); From 750b83bb45efd8be2f95d148567a511a9288417e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Mon, 16 Sep 2024 19:03:12 +0200 Subject: [PATCH 02/84] fix: refs #7760 tmp.ticketIPT --- db/routines/vn/procedures/productionControl.sql | 2 +- db/routines/vn/procedures/ticket_getProblems.sql | 11 ++++++++--- .../monitor/back/methods/sales-monitor/salesFilter.js | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/db/routines/vn/procedures/productionControl.sql b/db/routines/vn/procedures/productionControl.sql index 88ed42e837..b33224e80c 100644 --- a/db/routines/vn/procedures/productionControl.sql +++ b/db/routines/vn/procedures/productionControl.sql @@ -105,7 +105,7 @@ proc: BEGIN AND DATE(t.shipped) = zc.dated LEFT JOIN ticketParking tp ON tp.ticketFk = t.id LEFT JOIN parking pk ON pk.id = tp.parkingFk - LEFT JOIN tmp.ticketProblem tpr ON tpr.ticketFk = tt.ticketFk + LEFT JOIN tmp.ticketProblems tpr ON tpr.ticketFk = tt.ticketFk WHERE t.warehouseFk = vWarehouseFk AND dm.code IN ('AGENCY', 'DELIVERY', 'PICKUP'); diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index 00a8ee7278..f718893eb1 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -7,7 +7,7 @@ BEGIN * Calcula los problemas para un conjunto de tickets. * Agrupados por ticket * - * @table tmp.tmp.ticket(ticketFk) Identificadores de los tickets a calcular + * @table tmp.ticket(ticketFk) Identificadores de los tickets a calcular * @return tmp.ticketProblems */ DECLARE vWarehouseFk INT; @@ -163,7 +163,7 @@ BEGIN END LOOP; CLOSE vCursor; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketProblem ( + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketProblems ( ticketFk INT(11), isFreezed BOOL DEFAULT FALSE, risk DECIMAL(10,1) DEFAULT 0, @@ -199,13 +199,18 @@ BEGIN LEFT(CONCAT('F: ',GROUP_CONCAT(CONCAT(i.id, ' ', i.longName) SEPARATOR ', ')), 250) itemShortage, LEFT(CONCAT('R: ',GROUP_CONCAT(CONCAT(i2.id, ' ', i2.longName) SEPARATOR ', ')), 250) itemDelay, LEFT(CONCAT('I: ',GROUP_CONCAT(CONCAT(i3.id, ' ', i3.longName) SEPARATOR ', ')), 250) itemLost, - LEFT(CONCAT('RE: ',GROUP_CONCAT(CONCAT(i4.id, ' ', i4.longName) SEPARATOR ', ')), 250) componentLack, + LEFT(CONCAT('C: ',GROUP_CONCAT(CONCAT(i4.id, ' ', i4.longName) SEPARATOR ', ')), 250) componentLack, LEFT(CONCAT('RE: ',GROUP_CONCAT(CONCAT(i5.id, ' ', i5.longName) SEPARATOR ', ')), 250) rounding FROM tmp.ticket tt JOIN ticket t ON t.id = tt.ticketFk JOIN client c ON c.id = t.clientFk LEFT JOIN sale s ON s.ticketFk = t.id LEFT JOIN tmp.saleProblems ts ON ts.saleFk = s.id + LEFT JOIN item i ON i.id = s.itemFk AND ts.hasItemShortage + LEFT JOIN item i2 ON i2.id = s.itemFk AND ts.hasItemDelay + LEFT JOIN item i3 ON i3.id = s.itemFk AND ts.hasItemLost + LEFT JOIN item i4 ON i4.id = s.itemFk AND FIND_IN_SET('hasComponentLack', s.problem) + LEFT JOIN item i5 ON i5.id = s.itemFk AND ts.hasRounding LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk AND zc.dated = util.VN_CURDATE() WHERE s.problem <> '' OR t.problem <> '' OR t.risk diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 9b22cb2d26..70c750ef57 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -376,7 +376,7 @@ module.exports = Self => { stmts.push(` DROP TEMPORARY TABLE tmp.filter, - tmp.ticketProblem, + tmp.ticketProblems, tmp.sale_getWarnings, tmp.ticket_warnings `); From 712bfe73680a149bb6b292a18ef99a058db66616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 19 Sep 2024 20:15:38 +0200 Subject: [PATCH 03/84] fix: refs #7965 UnifyProblems --- .../vn/procedures/productionControl.sql | 61 +++--- .../vn/procedures/sale_getProblems.sql | 168 +++++++++++++++++ .../procedures/sale_getProblemsByTicket.sql | 19 +- .../vn/procedures/ticket_getProblems.sql | 177 ++---------------- 4 files changed, 226 insertions(+), 199 deletions(-) create mode 100644 db/routines/vn/procedures/sale_getProblems.sql diff --git a/db/routines/vn/procedures/productionControl.sql b/db/routines/vn/procedures/productionControl.sql index b33224e80c..294ac3486f 100644 --- a/db/routines/vn/procedures/productionControl.sql +++ b/db/routines/vn/procedures/productionControl.sql @@ -36,6 +36,19 @@ proc: BEGIN CREATE OR REPLACE TEMPORARY TABLE tmp.productionBuffer (PRIMARY KEY(ticketFk), previaParking VARCHAR(255)) ENGINE = MEMORY + WITH saleProblemsDescription AS( + SELECT s.ticketFk, + LEFT(CONCAT('F: ', GROUP_CONCAT(CONCAT(i.id, ' ', i.longName) SEPARATOR ', ')), 250) itemShortage, + LEFT(CONCAT('R: ', GROUP_CONCAT(CONCAT(i2.id, ' ', i2.longName) SEPARATOR ', ')), 250) itemDelay, + LEFT(CONCAT('I: ', GROUP_CONCAT(CONCAT(i3.id, ' ', i3.longName) SEPARATOR ', ')), 250) itemLost + FROM tmp.saleProblems sp + JOIN vn.sale s ON s.id = sp.saleFk + LEFT JOIN vn.item i ON i.id = s.itemFk AND sp.hasItemShortage + LEFT JOIN vn.item i2 ON i2.id = s.itemFk AND sp.hasItemDelay + LEFT JOIN vn.item i3 ON i3.id = s.itemFk AND sp.hasItemLost + WHERE hasItemShortage OR hasItemDelay OR hasItemLost + GROUP BY s.ticketFk + ) SELECT tt.ticketFk, t.clientFk, t.warehouseFk, @@ -55,9 +68,9 @@ proc: BEGIN 0 `lines`, CAST( 0 AS DECIMAL(5,2)) m3, CAST( 0 AS DECIMAL(5,2)) preparationRate, - TRIM(CAST(CONCAT( IFNULL(tpr.itemShortage, ''), - IFNULL(tpr.itemDelay, ''), - IFNULL(tpr.itemLost, ''), + TRIM(CAST(CONCAT( IFNULL(sp.itemShortage, ''), + IFNULL(sp.itemDelay, ''), + IFNULL(sp.itemLost, ''), IF(tpr.isFreezed, ' CONGELADO',''), IF(tpr.hasHighRisk, ' RIESGO',''), IF(tpr.hasTicketRequest, ' COD 100',''), @@ -85,30 +98,31 @@ proc: BEGIN ag.isOwn, rm.bufferFk FROM tmp.productionTicket tt - JOIN ticket t ON tt.ticketFk = t.id - JOIN alertLevel al ON al.code = 'FREE' - LEFT JOIN ticketStateToday tst ON tst.ticketFk = t.id - LEFT JOIN `state` st ON st.id = tst.state - LEFT JOIN client c ON c.id = t.clientFk - LEFT JOIN worker wk ON wk.id = c.salesPersonFk - JOIN address a ON a.id = t.addressFk - LEFT JOIN province p ON p.id = a.provinceFk - JOIN agencyMode am ON am.id = t.agencyModeFk - JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk - JOIN agency ag ON ag.id = am.agencyFk - LEFT JOIN ticketState tls ON tls.ticketFk = tt.ticketFk - LEFT JOIN ticketLastUpdated tlu ON tlu.ticketFk = tt.ticketFk - LEFT JOIN worker w ON w.id = tls.userFk - LEFT JOIN routesMonitor rm ON rm.routeFk = t.routeFk - LEFT JOIN `zone` z ON z.id = t.zoneFk - LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk + JOIN vn.ticket t ON tt.ticketFk = t.id + JOIN vn.alertLevel al ON al.code = 'FREE' + LEFT JOIN vn.ticketStateToday tst ON tst.ticketFk = t.id + LEFT JOIN vn.`state` st ON st.id = tst.state + LEFT JOIN vn.client c ON c.id = t.clientFk + LEFT JOIN vn.worker wk ON wk.id = c.salesPersonFk + JOIN vn.address a ON a.id = t.addressFk + LEFT JOIN vn.province p ON p.id = a.provinceFk + JOIN vn.agencyMode am ON am.id = t.agencyModeFk + JOIN vn.deliveryMethod dm ON dm.id = am.deliveryMethodFk + JOIN vn.agency ag ON ag.id = am.agencyFk + LEFT JOIN vn.ticketState tls ON tls.ticketFk = tt.ticketFk + LEFT JOIN vn.ticketLastUpdated tlu ON tlu.ticketFk = tt.ticketFk + LEFT JOIN vn.worker w ON w.id = tls.userFk + LEFT JOIN vn.routesMonitor rm ON rm.routeFk = t.routeFk + LEFT JOIN vn.`zone` z ON z.id = t.zoneFk + LEFT JOIN vn.zoneClosure zc ON zc.zoneFk = t.zoneFk AND DATE(t.shipped) = zc.dated - LEFT JOIN ticketParking tp ON tp.ticketFk = t.id - LEFT JOIN parking pk ON pk.id = tp.parkingFk + LEFT JOIN vn.ticketParking tp ON tp.ticketFk = t.id + LEFT JOIN vn.parking pk ON pk.id = tp.parkingFk LEFT JOIN tmp.ticketProblems tpr ON tpr.ticketFk = tt.ticketFk + LEFT JOIN saleProblemsDescription sp ON sp.ticketFk = tt.ticketFk WHERE t.warehouseFk = vWarehouseFk AND dm.code IN ('AGENCY', 'DELIVERY', 'PICKUP'); - + UPDATE tmp.productionBuffer pb JOIN ( SELECT pb.ticketFk, GROUP_CONCAT(p.code) previaParking @@ -260,6 +274,7 @@ proc: BEGIN DROP TEMPORARY TABLE tmp.productionTicket, tmp.ticketProblems, + tmp.saleProblems, tmp.ticketWithPrevia, tItemShelvingStock, tItemPackingType; diff --git a/db/routines/vn/procedures/sale_getProblems.sql b/db/routines/vn/procedures/sale_getProblems.sql new file mode 100644 index 0000000000..a8388034f9 --- /dev/null +++ b/db/routines/vn/procedures/sale_getProblems.sql @@ -0,0 +1,168 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`sale_getProblems`( + vIsTodayRelative TINYINT(1) +) +BEGIN +/** + * Calcula los problemas para un conjunto de sale + * + * @table tmp.sale(saleFk) Identificadores de los sale a calcular + * @return tmp.saleProblems + */ + DECLARE vWarehouseFk INT; + DECLARE vDate DATE; + DECLARE vAvailableCache INT; + DECLARE vVisibleCache INT; + DECLARE vDone BOOL; + DECLARE vCursor CURSOR FOR + SELECT t.warehouseFk, IF(vIsTodayRelative, util.VN_CURDATE(), DATE(t.shipped)) dated + FROM tmp.sale ts + JOIN sale s ON s.id = ts.saleFk + JOIN ticket t ON t.id = s.ticketFk + WHERE t.shipped BETWEEN util.VN_CURDATE() + AND util.dayEnd(util.VN_CURDATE() + INTERVAL IF(vIsTodayRelative, 9.9, 1.9) DAY) + GROUP BY warehouseFk, dated; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + + CREATE OR REPLACE TEMPORARY TABLE tmp.saleProblems( + saleFk INT(11), + hasItemShortage BOOL DEFAULT FALSE, + hasItemLost BOOL DEFAULT FALSE, + hasItemDelay BOOL DEFAULT FALSE, + hasRounding BOOL DEFAULT FALSE, + PRIMARY KEY (saleFk) + ) ENGINE = MEMORY; + + CREATE OR REPLACE TEMPORARY TABLE tItemShelving + (INDEX (itemFk, warehouseFk)) + ENGINE = MEMORY + SELECT ish.itemFk itemFk, + SUM(ish.visible) visible, + s.warehouseFk warehouseFk + FROM itemShelving ish + JOIN shelving sh ON sh.code = ish.shelvingFk + JOIN parking p ON p.id = sh.parkingFk + JOIN sector s ON s.id = p.sectorFk + GROUP BY ish.itemFk, s.warehouseFk; + + -- Disponible, faltas, inventario y retrasos + OPEN vCursor; + l: LOOP + SET vDone = FALSE; + FETCH vCursor INTO vWarehouseFk, vDate; + + IF vDone THEN + LEAVE l; + END IF; + + -- Disponible: no va a haber suficiente producto para preparar todos los pedidos + CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouseFk, vDate); + + -- Faltas: visible, disponible y ubicado son menores que la cantidad vendida + CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouseFk); + + INSERT INTO tmp.saleProblems(saleFk, hasItemShortage) + SELECT s.id, TRUE + FROM tmp.sale ts + JOIN sale s ON s.id = ts.saleFk + JOIN ticket t ON t.id = s.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 + LEFT JOIN cache.visible v ON v.item_id = i.id + AND v.calc_id = vVisibleCache + LEFT JOIN cache.available av ON av.item_id = i.id + AND av.calc_id = vAvailableCache + LEFT JOIN tItemShelving tis ON tis.itemFk = i.id + AND tis.warehouseFk = t.warehouseFk + WHERE IFNULL(v.visible, 0) < s.quantity + AND IFNULL(av.available, 0) < s.quantity + AND IFNULL(tis.visible, 0) < s.quantity + AND NOT s.isPicked + AND NOT s.reserved + AND ic.merchandise + AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) + AND NOT i.generic + AND util.VN_CURDATE() = vDate + AND t.warehouseFk = vWarehouseFk + GROUP BY s.id; + + -- Inventario: Visible suficiente, pero ubicado menor a la cantidad vendida + INSERT INTO tmp.saleProblems(saleFk, hasItemLost) + SELECT s.id, TRUE + FROM tmp.sale ts + JOIN sale s ON s.id = ts.saleFk + JOIN ticket t ON t.id = s.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 + LEFT JOIN cache.visible v ON v.item_id = s.itemFk + AND v.calc_id = vVisibleCache + LEFT JOIN tItemShelving tis ON tis.itemFk = i.id + AND tis.warehouseFk = t.warehouseFk + WHERE IFNULL(v.visible, 0) >= s.quantity + AND IFNULL(tis.visible, 0) < s.quantity + AND s.quantity > 0 + AND NOT s.isPicked + AND NOT s.reserved + AND ic.merchandise + AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) + AND NOT i.generic + AND util.VN_CURDATE() = vDate + AND t.warehouseFk = vWarehouseFk + GROUP BY s.id + ON DUPLICATE KEY UPDATE hasItemLost = TRUE; + + -- Retraso: Disponible suficiente, pero no visible ni ubicado + INSERT INTO tmp.saleProblems(saleFk, hasItemDelay) + SELECT s.id, TRUE + FROM tmp.sale ts + JOIN sale s ON s.id = ts.saleFk + JOIN ticket t ON t.id = s.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 + LEFT JOIN cache.visible v ON v.item_id = s.itemFk + AND v.calc_id = vVisibleCache + LEFT JOIN cache.available av ON av.item_id = i.id + AND av.calc_id = vAvailableCache + LEFT JOIN tItemShelving tis ON tis.itemFk = i.id + AND tis.warehouseFk = t.warehouseFk + WHERE IFNULL(v.visible, 0) < s.quantity + AND IFNULL(av.available, 0) >= s.quantity + AND IFNULL(tis.visible, 0) < s.quantity + AND s.quantity > 0 + AND NOT s.isPicked + AND NOT s.reserved + AND ic.merchandise + AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) + AND NOT i.generic + AND util.VN_CURDATE() = vDate + AND t.warehouseFk = vWarehouseFk + GROUP BY s.id + ON DUPLICATE KEY UPDATE hasItemDelay = TRUE; + + -- Redondeo: cantidad incorrecta con respecto al grouping + CALL buy_getUltimate(NULL, vWarehouseFk, vDate); + + INSERT INTO tmp.saleProblems(saleFk, hasRounding) + SELECT s.id, TRUE + FROM tmp.sale ts + JOIN sale s ON s.id = ts.saleFk + JOIN ticket t ON t.id = s.ticketFk + AND t.warehouseFk = vWarehouseFk + 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 s.id + ON DUPLICATE KEY UPDATE hasRounding = TRUE; + + DROP TEMPORARY TABLE tmp.buyUltimate; + END LOOP; + CLOSE vCursor; + + DROP TEMPORARY TABLE tItemShelving, tmp.sale; +END$$ +DELIMITER ; diff --git a/db/routines/vn/procedures/sale_getProblemsByTicket.sql b/db/routines/vn/procedures/sale_getProblemsByTicket.sql index af69e84300..708938cba0 100644 --- a/db/routines/vn/procedures/sale_getProblemsByTicket.sql +++ b/db/routines/vn/procedures/sale_getProblemsByTicket.sql @@ -5,22 +5,19 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`sale_getProblemsByTic ) BEGIN /** - * Calcula los problemas de cada venta - * para un conjunto de tickets. + * Calcula los problemas de cada venta para un tickets. * * @return Problems result */ - CREATE OR REPLACE TEMPORARY TABLE tmp.ticket - (INDEX (ticketFk)) - ENGINE = MEMORY - SELECT vTicketFk ticketFk; + CREATE OR REPLACE TEMPORARY TABLE tmp.sale + (INDEX (saleFk)) + ENGINE = MEMORY + SELECT id saleFk FROM sale WHERE ticketFk = vTicketFk; - CALL ticket_getProblems(vIsTodayRelative); + CALL sale_getProblems(vIsTodayRelative); - SELECT * FROM tmp.saleProblems; + SELECT * FROM tmp.saleProblems; - DROP TEMPORARY TABLE - tmp.ticket, - tmp.ticketProblems; + DROP TEMPORARY TABLE tmp.saleProblems; END$$ DELIMITER ; diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index f718893eb1..c5a1532ff7 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -5,163 +5,23 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_getProblems`( BEGIN /** * Calcula los problemas para un conjunto de tickets. - * Agrupados por ticket * * @table tmp.ticket(ticketFk) Identificadores de los tickets a calcular - * @return tmp.ticketProblems + * @return tmp.ticketProblems, tmp.saleProblems */ - DECLARE vWarehouseFk INT; - DECLARE vDate DATE; - DECLARE vAvailableCache INT; - DECLARE vVisibleCache INT; - DECLARE vDone BOOL; - DECLARE vCursor CURSOR FOR - SELECT DISTINCT t.warehouseFk, IF(vIsTodayRelative, util.VN_CURDATE(), DATE(t.shipped)) - FROM tmp.ticket t - JOIN ticket t ON t.id = t.ticketFk - WHERE t.shipped BETWEEN util.VN_CURDATE() - AND util.dayEnd(util.VN_CURDATE() + INTERVAL IF(vIsTodayRelative, 9.9, 1.9) DAY); - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - - CREATE OR REPLACE TEMPORARY TABLE tmp.saleProblems( - ticketFk INT(11), + CREATE OR REPLACE TEMPORARY TABLE tmp.sale ( saleFk INT(11), - hasItemShortage BOOL DEFAULT FALSE, - hasItemLost BOOL DEFAULT FALSE, - hasItemDelay BOOL DEFAULT FALSE, - hasRounding BOOL DEFAULT FALSE, - PRIMARY KEY (ticketFk, saleFk) - ) ENGINE = MEMORY; - - CREATE OR REPLACE TEMPORARY TABLE tItemShelving - (INDEX (itemFk, warehouseFk)) - ENGINE = MEMORY - SELECT ish.itemFk itemFk, - SUM(ish.visible) visible, - s.warehouseFk warehouseFk - FROM itemShelving ish - JOIN shelving sh ON sh.code = ish.shelvingFk - JOIN parking p ON p.id = sh.parkingFk - JOIN sector s ON s.id = p.sectorFk - GROUP BY ish.itemFk, s.warehouseFk; - - -- Disponible, faltas, inventario y retrasos - OPEN vCursor; - l: LOOP - SET vDone = FALSE; - FETCH vCursor INTO vWarehouseFk, vDate; - - IF vDone THEN - LEAVE l; - END IF; - - -- Disponible: no va a haber suficiente producto para preparar todos los pedidos - CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouseFk, vDate); - - -- Faltas: visible, disponible y ubicado son menores que la cantidad vendida - CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouseFk); - - INSERT INTO tmp.saleProblems(ticketFk, saleFk, hasItemShortage) - SELECT tt.ticketFk, s.id, TRUE - FROM tmp.ticket tt - JOIN ticket t ON t.id = tt.ticketFk - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - JOIN itemType it ON it.id = i.typeFk - JOIN itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN cache.visible v ON v.item_id = i.id - AND v.calc_id = vVisibleCache - LEFT JOIN cache.available av ON av.item_id = i.id - AND av.calc_id = vAvailableCache - LEFT JOIN tItemShelving tis ON tis.itemFk = i.id - AND tis.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible, 0) < s.quantity - AND IFNULL(av.available, 0) < s.quantity - AND IFNULL(tis.visible, 0) < s.quantity - AND NOT s.isPicked - AND NOT s.reserved - AND ic.merchandise - AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) - AND NOT i.generic - AND util.VN_CURDATE() = vDate - AND t.warehouseFk = vWarehouseFk + PRIMARY KEY (saleFk) + ) ENGINE = MEMORY + SELECT DISTINCT s.id saleFk + FROM tmp.ticket tt + JOIN ticket t ON t.id = tt.ticketFk + JOIN sale s ON s.ticketFk = t.id + WHERE t.shipped BETWEEN util.VN_CURDATE() + AND util.dayEnd(util.VN_CURDATE() + INTERVAL IF(vIsTodayRelative, 9.9, 1.9) DAY) GROUP BY s.id; - -- Inventario: Visible suficiente, pero ubicado menor a la cantidad vendida - INSERT INTO tmp.saleProblems(ticketFk, saleFk, hasItemLost) - SELECT tt.ticketFk, s.id, TRUE - FROM tmp.ticket tt - JOIN ticket t ON t.id = tt.ticketFk - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - JOIN itemType it ON it.id = i.typeFk - JOIN itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN cache.visible v ON v.item_id = s.itemFk - AND v.calc_id = vVisibleCache - LEFT JOIN tItemShelving tis ON tis.itemFk = i.id - AND tis.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible, 0) >= s.quantity - AND IFNULL(tis.visible, 0) < s.quantity - AND s.quantity > 0 - AND NOT s.isPicked - AND NOT s.reserved - AND ic.merchandise - AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) - AND NOT i.generic - AND util.VN_CURDATE() = vDate - AND t.warehouseFk = vWarehouseFk - GROUP BY s.id - ON DUPLICATE KEY UPDATE hasItemLost = TRUE; - - -- Retraso: Disponible suficiente, pero no visible ni ubicado - INSERT INTO tmp.saleProblems(ticketFk, saleFk, hasItemDelay) - SELECT tt.ticketFk, s.id, TRUE - FROM tmp.ticket tt - JOIN ticket t ON t.id = tt.ticketFk - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - JOIN itemType it ON it.id = i.typeFk - JOIN itemCategory ic ON ic.id = it.categoryFk - LEFT JOIN cache.visible v ON v.item_id = s.itemFk - AND v.calc_id = vVisibleCache - LEFT JOIN cache.available av ON av.item_id = i.id - AND av.calc_id = vAvailableCache - LEFT JOIN tItemShelving tis ON tis.itemFk = i.id - AND tis.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible, 0) < s.quantity - AND IFNULL(av.available, 0) >= s.quantity - AND IFNULL(tis.visible, 0) < s.quantity - AND s.quantity > 0 - AND NOT s.isPicked - AND NOT s.reserved - AND ic.merchandise - AND IF(vIsTodayRelative, TRUE, DATE(t.shipped) = vDate) - AND NOT i.generic - AND util.VN_CURDATE() = vDate - AND t.warehouseFk = vWarehouseFk - GROUP BY s.id - ON DUPLICATE KEY UPDATE hasItemDelay = TRUE; - - -- Redondeo: cantidad incorrecta con respecto al grouping - CALL buy_getUltimate(NULL, vWarehouseFk, vDate); - - INSERT INTO tmp.saleProblems(ticketFk, saleFk, hasRounding) - SELECT tt.ticketFk, s.id, TRUE - FROM tmp.ticket tt - JOIN ticket t ON t.id = tt.ticketFk - AND t.warehouseFk = vWarehouseFk - JOIN sale s ON s.ticketFk = tt.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 s.id - ON DUPLICATE KEY UPDATE hasRounding = TRUE; - - DROP TEMPORARY TABLE tmp.buyUltimate; - END LOOP; - CLOSE vCursor; + CALL sale_getProblems(vIsTodayRelative); CREATE OR REPLACE TEMPORARY TABLE tmp.ticketProblems ( ticketFk INT(11), @@ -195,27 +55,14 @@ BEGIN SUM(IFNULL(ts.hasItemDelay,0)) hasItemDelay, SUM(IFNULL(ts.hasItemLost,0)) hasItemLost, IF(FIND_IN_SET('hasComponentLack', s.problem), TRUE, FALSE) hasComponentLack, - SUM(IFNULL(ts.hasRounding,0)) hasRounding, - LEFT(CONCAT('F: ',GROUP_CONCAT(CONCAT(i.id, ' ', i.longName) SEPARATOR ', ')), 250) itemShortage, - LEFT(CONCAT('R: ',GROUP_CONCAT(CONCAT(i2.id, ' ', i2.longName) SEPARATOR ', ')), 250) itemDelay, - LEFT(CONCAT('I: ',GROUP_CONCAT(CONCAT(i3.id, ' ', i3.longName) SEPARATOR ', ')), 250) itemLost, - LEFT(CONCAT('C: ',GROUP_CONCAT(CONCAT(i4.id, ' ', i4.longName) SEPARATOR ', ')), 250) componentLack, - LEFT(CONCAT('RE: ',GROUP_CONCAT(CONCAT(i5.id, ' ', i5.longName) SEPARATOR ', ')), 250) rounding + SUM(IFNULL(ts.hasRounding,0)) hasRounding FROM tmp.ticket tt JOIN ticket t ON t.id = tt.ticketFk JOIN client c ON c.id = t.clientFk LEFT JOIN sale s ON s.ticketFk = t.id LEFT JOIN tmp.saleProblems ts ON ts.saleFk = s.id - LEFT JOIN item i ON i.id = s.itemFk AND ts.hasItemShortage - LEFT JOIN item i2 ON i2.id = s.itemFk AND ts.hasItemDelay - LEFT JOIN item i3 ON i3.id = s.itemFk AND ts.hasItemLost - LEFT JOIN item i4 ON i4.id = s.itemFk AND FIND_IN_SET('hasComponentLack', s.problem) - LEFT JOIN item i5 ON i5.id = s.itemFk AND ts.hasRounding LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk AND zc.dated = util.VN_CURDATE() - WHERE s.problem <> '' OR t.problem <> '' OR t.risk GROUP BY t.id; - - DROP TEMPORARY TABLE tItemShelving; END$$ DELIMITER ; From 69cafd5a0457f7a6e5b50aa3b57e45132b49fa2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Mon, 30 Sep 2024 14:30:15 +0200 Subject: [PATCH 04/84] fix: refs #7965 UnifyProblems --- modules/monitor/back/methods/sales-monitor/salesFilter.js | 4 ++-- modules/ticket/back/methods/ticket/filter.js | 2 +- modules/ticket/back/methods/ticket/getTicketsFuture.js | 5 +---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 70c750ef57..4f81f59b9e 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -289,7 +289,7 @@ module.exports = Self => { {'tp.hasTicketRequest': true}, {'tp.hasComponentLack': true}, {'tp.isTaxDataChecked': false}, - {'tp.itemShortage': {neq: null}}, + {'tp.hasItemShortage': true}, {'tp.isTooLittle': true} ]}; } else if (hasProblems === false) { @@ -299,7 +299,7 @@ module.exports = Self => { {'tp.hasTicketRequest': false}, {'tp.hasComponentLack': false}, {'tp.isTaxDataChecked': true}, - {'tp.itemShortage': null}, + {'tp.hasItemShortage': false}, {'tp.isTooLittle': false} ]}; } diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js index 9ac239be77..77da770a24 100644 --- a/modules/ticket/back/methods/ticket/filter.js +++ b/modules/ticket/back/methods/ticket/filter.js @@ -345,7 +345,7 @@ module.exports = Self => { {'tp.isFreezed': hasProblem}, {'tp.hasRisk': hasProblem}, {'tp.hasTicketRequest': hasProblem}, - {'tp.itemShortage': range}, + {'tp.hasItemShortage': range}, {'tp.hasRounding': hasProblem} ]}; diff --git a/modules/ticket/back/methods/ticket/getTicketsFuture.js b/modules/ticket/back/methods/ticket/getTicketsFuture.js index 1c31da057c..af3acff13e 100644 --- a/modules/ticket/back/methods/ticket/getTicketsFuture.js +++ b/modules/ticket/back/methods/ticket/getTicketsFuture.js @@ -175,20 +175,17 @@ module.exports = Self => { let condition; let hasProblem; - let range; let hasWhere; switch (args.problems) { case true: condition = `or`; hasProblem = true; - range = {neq: null}; hasWhere = true; break; case false: condition = `and`; hasProblem = null; - range = null; hasWhere = true; break; } @@ -198,7 +195,7 @@ module.exports = Self => { {'tp.isFreezed': hasProblem}, {'tp.hasRisk': hasProblem}, {'tp.hasTicketRequest': hasProblem}, - {'tp.itemShortage': range}, + {'tp.hasItemShortage': hasProblem}, {'tp.hasComponentLack': hasProblem}, {'tp.isTooLittle': hasProblem}, {'tp.hasRounding': hasProblem} From bb1695eac69b8449280bdc30a7108c2174c6dfd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Mon, 30 Sep 2024 16:39:55 +0200 Subject: [PATCH 05/84] fix: refs #7965 UnifyProblems --- .../vn/procedures/ticket_getProblems.sql | 18 +++++++++++++++++- modules/ticket/back/methods/ticket/filter.js | 5 +---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index c5a1532ff7..e58d49a5a3 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -55,7 +55,8 @@ BEGIN SUM(IFNULL(ts.hasItemDelay,0)) hasItemDelay, SUM(IFNULL(ts.hasItemLost,0)) hasItemLost, IF(FIND_IN_SET('hasComponentLack', s.problem), TRUE, FALSE) hasComponentLack, - SUM(IFNULL(ts.hasRounding,0)) hasRounding + SUM(IFNULL(ts.hasRounding,0)) hasRounding, + 0 totalProblems FROM tmp.ticket tt JOIN ticket t ON t.id = tt.ticketFk JOIN client c ON c.id = t.clientFk @@ -64,5 +65,20 @@ BEGIN LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk AND zc.dated = util.VN_CURDATE() GROUP BY t.id; + + UPDATE tmp.ticketProblems + SET totalProblems = ( + (isFreezed) + + (hasHighRisk) + + (hasTicketRequest) + + (!isTaxDataChecked) + + (hasComponentLack) + + (hasItemDelay IS NOT NULL) + + (isTooLittle) + + (hasItemLost IS NOT NULL) + + (hasRounding IS NOT NULL) + + (hasItemShortage IS NOT NULL) + + (isVip) + ); END$$ DELIMITER ; diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js index eccec735ff..2571213070 100644 --- a/modules/ticket/back/methods/ticket/filter.js +++ b/modules/ticket/back/methods/ticket/filter.js @@ -325,20 +325,17 @@ module.exports = Self => { let condition; let hasProblem; - let range; let hasWhere; switch (args.problems) { case true: condition = `or`; hasProblem = true; - range = {neq: null}; hasWhere = true; break; case false: condition = `and`; hasProblem = null; - range = null; hasWhere = true; break; } @@ -347,7 +344,7 @@ module.exports = Self => { {'tp.isFreezed': hasProblem}, {'tp.hasRisk': hasProblem}, {'tp.hasTicketRequest': hasProblem}, - {'tp.hasItemShortage': range}, + {'tp.hasItemShortage': hasProblem}, {'tp.hasRounding': hasProblem} ]}; From 6a5cf1a57ff787e94032391c315b44f88c5aaa9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Tue, 1 Oct 2024 15:46:51 +0200 Subject: [PATCH 06/84] fix: refs #7965 UnifyProblems --- db/dump/fixtures.before.sql | 34 +++--- .../vn/procedures/ticket_getProblems.sql | 101 +++++++++++------- .../sales-monitor/specs/salesFilter.spec.js | 2 +- .../back/methods/ticket/specs/filter.spec.js | 6 +- 4 files changed, 84 insertions(+), 59 deletions(-) diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index ffbc6a864d..e8b89afa93 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -1072,12 +1072,12 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric (5, 1, 2, 'Ranged weapon longbow 200cm', 1, 110.33, 0, 0, 0, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 'hasComponentLack'), (6, 1, 3, 'Ranged weapon longbow 200cm', 1, 110.33, 0, 0, 0, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), 'hasComponentLack'), (7, 2, 11, 'Melee weapon combat fist 15cm', 15, 7.74, 0, 0, 0, util.VN_CURDATE(), NULL), - (8, 4, 11, 'Melee weapon heavy shield 100cm', 10, 1.79, 0, 0, 0, util.VN_CURDATE(), NULL), + (8, 4, 11, 'Melee weapon heavy shield 100cm', 10, 1.79, 0, 0, 0, util.VN_CURDATE(), 'hasItemLost,hasRounding'), (9, 1, 16, 'Ranged weapon longbow 200cm', 1, 103.49, 0, 0, 0, util.VN_CURDATE(), NULL), (10, 2, 16, 'Melee weapon combat fist 15cm', 10, 7.09, 0, 0, 0, util.VN_CURDATE(), NULL), (11, 1, 16, 'Ranged weapon longbow 200cm', 1, 103.49, 0, 0, 0, util.VN_CURDATE(), NULL), - (12, 4, 16, 'Melee weapon heavy shield 100cm', 20, 1.71, 0, 0, 0, util.VN_CURDATE(), NULL), - (13, 2, 8, 'Melee weapon combat fist 15cm', 10, 7.08, 0, 0, 0, util.VN_CURDATE(), NULL), + (12, 4, 16, 'Melee weapon heavy shield 100cm', 20, 1.71, 0, 0, 0, util.VN_CURDATE(), 'hasItemLost'), + (13, 2, 8, 'Melee weapon combat fist 15cm', 10, 7.08, 0, 0, 0, util.VN_CURDATE(), 'hasItemLost'), (14, 1, 8, 'Ranged weapon longbow 200cm', 2, 103.49, 0, 0, 0, util.VN_CURDATE(), NULL), (15, 1, 19, 'Ranged weapon longbow 200cm', 1, 103.49, 0, 0, 0, util.VN_CURDATE(), NULL), (16, 2, 20, 'Melee weapon combat fist 15cm', 20, 7.07, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), @@ -1088,25 +1088,25 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric (21, 1, 6, 'Ranged weapon longbow 200cm', 1, 8.07, 0, 0, 0, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 'hasComponentLack'), (22, 1, 7, 'Ranged weapon longbow 200cm', 1, 8.07, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), (23, 1, 9, 'Ranged weapon longbow 200cm', 1, 8.07, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (24, 1, 10, 'Ranged weapon longbow 200cm', 1, 8.07, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (25, 4, 12, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (26, 4, 13, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (27, 4, 14, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (28, 4, 15, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (29, 4, 17, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (30, 4, 18, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (31, 2, 23, 'Melee weapon combat fist 15cm', -5, 7.08, 0, 0, 0, util.VN_CURDATE(), NULL), + (24, 1, 10, 'Ranged weapon longbow 200cm', 1, 8.07, 0, 0, 0, util.VN_CURDATE(), 'hasItemShortage,hasComponentLack'), + (25, 4, 12, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasItemLost'), + (26, 4, 13, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasItemLost'), + (27, 4, 14, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasItemShortage,hasComponentLack,hasItemLost'), + (28, 4, 15, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasItemLost'), + (29, 4, 17, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasItemShortage,hasComponentLack'), + (30, 4, 18, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasItemShortage,hasComponentLack'), + (31, 2, 23, 'Melee weapon combat fist 15cm', -5, 7.08, 0, 0, 0, util.VN_CURDATE(), 'hasRounding'), (32, 1, 24, 'Ranged weapon longbow 200cm', -1, 8.07, 0, 0, 0, util.VN_CURDATE(), NULL), (33, 5, 14, 'Ranged weapon pistol 9mm', 50, 1.79, 0, 0, 0, util.VN_CURDATE(), NULL), - (34, 4, 28, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (35, 4, 29, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), + (34, 4, 28, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasItemLost'), + (35, 4, 29, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasItemLost'), (37, 4, 31, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), NULL), - (36, 4, 30, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), + (36, 4, 30, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasItemLost'), (38, 2, 32, 'Melee weapon combat fist 15cm', 30, 7.07, 0, 0, 0, DATE_ADD(util.VN_CURDATE(), INTERVAL +1 MONTH), 'hasComponentLack'), (39, 1, 32, 'Ranged weapon longbow 200cm', 2, 103.49, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (40, 2, 34, 'Melee weapon combat fist 15cm', 10.00, 3.91, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (41, 2, 35, 'Melee weapon combat fist 15cm', 8.00, 3.01, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'), - (42, 2, 36, 'Melee weapon combat fist 15cm', 6.00, 2.50, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'); + (40, 2, 34, 'Melee weapon combat fist 15cm', 10.00, 3.91, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasItemLost'), + (41, 2, 35, 'Melee weapon combat fist 15cm', 8.00, 3.01, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasRounding,hasItemLost'), + (42, 2, 36, 'Melee weapon combat fist 15cm', 6.00, 2.50, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasRounding,hasItemLost'); INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`) VALUES diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index e58d49a5a3..3855c3a1df 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -40,45 +40,70 @@ BEGIN hasRounding BOOL DEFAULT FALSE, PRIMARY KEY (ticketFk) ) ENGINE = MEMORY - SELECT tt.ticketFk, - IF(FIND_IN_SET('isFreezed', t.problem), TRUE, FALSE) isFreezed, - t.risk, - IF(FIND_IN_SET('hasRisk', t.problem), TRUE, FALSE) hasRisk, - IF(FIND_IN_SET('hasHighRisk', t.problem), TRUE, FALSE) hasHighRisk, - IF(FIND_IN_SET('hasTicketRequest', t.problem), TRUE, FALSE) hasTicketRequest, - IF(FIND_IN_SET('isTaxDataChecked', t.problem), FALSE, TRUE) isTaxDataChecked, - IF(FIND_IN_SET('isTooLittle', t.problem) - AND util.VN_NOW() < (util.VN_CURDATE() + INTERVAL HOUR(zc.`hour`) HOUR) + INTERVAL MINUTE(zc.`hour`) MINUTE, - TRUE, FALSE) isTooLittle, - IF(c.businessTypeFk = 'VIP', TRUE, FALSE) isVip, - SUM(IFNULL(ts.hasItemShortage,0)) hasItemShortage, - SUM(IFNULL(ts.hasItemDelay,0)) hasItemDelay, - SUM(IFNULL(ts.hasItemLost,0)) hasItemLost, - IF(FIND_IN_SET('hasComponentLack', s.problem), TRUE, FALSE) hasComponentLack, - SUM(IFNULL(ts.hasRounding,0)) hasRounding, - 0 totalProblems - FROM tmp.ticket tt - JOIN ticket t ON t.id = tt.ticketFk - JOIN client c ON c.id = t.clientFk - LEFT JOIN sale s ON s.ticketFk = t.id - LEFT JOIN tmp.saleProblems ts ON ts.saleFk = s.id - LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk - AND zc.dated = util.VN_CURDATE() - GROUP BY t.id; + WITH hasItemShortage AS( + SELECT s.ticketFk + FROM tmp.saleProblems sp + JOIN vn.sale s ON s.id = sp.saleFk + WHERE sp.hasItemShortage + GROUP BY s.ticketFk + ),hasItemLost AS( + SELECT s.ticketFk + FROM tmp.saleProblems sp + JOIN vn.sale s ON s.id = sp.saleFk + WHERE sp.hasItemLost + GROUP BY s.ticketFk + ),hasRounding AS( + SELECT s.ticketFk + FROM tmp.saleProblems sp + JOIN vn.sale s ON s.id = sp.saleFk + WHERE sp.hasRounding + GROUP BY s.ticketFk + ), hasItemDelay AS( + SELECT s.ticketFk + FROM tmp.saleProblems sp + JOIN vn.sale s ON s.id = sp.saleFk + WHERE sp.hasItemDelay + GROUP BY s.ticketFk + ), hasComponentLack AS( + SELECT s.ticketFk + FROM tmp.saleProblems sp + JOIN vn.sale s ON s.id = sp.saleFk + WHERE FIND_IN_SET('hasComponentLack', s.problem) + GROUP BY s.ticketFk + )SELECT tt.ticketFk, + IF(FIND_IN_SET('isFreezed', t.problem), TRUE, FALSE) isFreezed, + t.risk, + IF(FIND_IN_SET('hasRisk', t.problem), TRUE, FALSE) hasRisk, + IF(FIND_IN_SET('hasHighRisk', t.problem), TRUE, FALSE) hasHighRisk, + IF(FIND_IN_SET('hasTicketRequest', t.problem), TRUE, FALSE) hasTicketRequest, + IF(FIND_IN_SET('isTaxDataChecked', t.problem), TRUE, FALSE) isTaxDataChecked, + IF(FIND_IN_SET('isTooLittle', t.problem) + AND util.VN_NOW() < (util.VN_CURDATE() + + INTERVAL HOUR(zc.`hour`) HOUR) + + INTERVAL MINUTE(zc.`hour`) MINUTE, + TRUE, FALSE) isTooLittle, + IF(c.businessTypeFk = 'VIP', TRUE, FALSE) isVip, + IF(his.ticketFk IS NULL, FALSE, TRUE) hasItemShortage, + IF(hid.ticketFk IS NULL, FALSE, TRUE) hasItemDelay, + IF(hil.ticketFk IS NULL, FALSE, TRUE) hasItemLost, + IF(hcl.ticketFk IS NULL, FALSE, TRUE) hasComponentLack, + IF(hr.ticketFk IS NULL, FALSE, TRUE) hasRounding, + 0 totalProblems + FROM tmp.ticket tt + JOIN vn.ticket t ON t.id = tt.ticketFk + JOIN vn.client c ON c.id = t.clientFk + LEFT JOIN hasItemShortage his ON his.ticketFk = t.id + LEFT JOIN hasItemLost hil ON hil.ticketFk = t.id + LEFT JOIN hasRounding hr ON hr.ticketFk = t.id + LEFT JOIN hasItemDelay hid ON hid.ticketFk = t.id + LEFT JOIN hasComponentLack hcl ON hcl.ticketFk = t.id + LEFT JOIN vn.zoneClosure zc ON zc.zoneFk = t.zoneFk + AND zc.dated = util.VN_CURDATE() + GROUP BY t.id; UPDATE tmp.ticketProblems - SET totalProblems = ( - (isFreezed) + - (hasHighRisk) + - (hasTicketRequest) + - (!isTaxDataChecked) + - (hasComponentLack) + - (hasItemDelay IS NOT NULL) + - (isTooLittle) + - (hasItemLost IS NOT NULL) + - (hasRounding IS NOT NULL) + - (hasItemShortage IS NOT NULL) + - (isVip) - ); + SET totalProblems = isFreezed + hasHighRisk + hasTicketRequest + + isTaxDataChecked + hasComponentLack + hasItemDelay + + isTooLittle + hasItemLost + hasRounding + hasItemShortage + isVip; END$$ DELIMITER ; diff --git a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js index 738af52199..908c446a68 100644 --- a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js +++ b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js @@ -48,7 +48,7 @@ describe('SalesMonitor salesFilter()', () => { } }); - it('should now return the tickets matching the problems on false', async() => { + fit('should now return the tickets matching the problems on false', async() => { const tx = await models.SalesMonitor.beginTransaction({}); try { diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js index d0edb24e39..44bfbb7e3f 100644 --- a/modules/ticket/back/methods/ticket/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js @@ -45,8 +45,8 @@ describe('ticket filter()', () => { ticket.isFreezed === true || ticket.hasRisk === true || ticket.hasTicketRequest === true || - (typeof ticket.hasRounding === 'string' && ticket.hasRounding.trim().length > 0) || - (typeof ticket.itemShortage === 'string' && ticket.itemShortage.trim().length > 0) + ticket.hasRounding === true || + ticket.hasItemShortage === true ); expect(hasProblemTicket).toBe(true); @@ -83,7 +83,7 @@ describe('ticket filter()', () => { expect(ticket.isFreezed).toEqual(null); expect(ticket.hasRisk).toEqual(null); expect(ticket.hasTicketRequest).toEqual(null); - expect(ticket.itemShortage).toEqual(null); + expect(ticket.hasItemShortage).toEqual(null); expect(ticket.hasRounding).toEqual(null); }); From 99c70a533a3fed301ce3427d4b7e61558e0ee2fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Wed, 2 Oct 2024 14:25:27 +0200 Subject: [PATCH 07/84] fix: test --- db/dump/fixtures.before.sql | 2 +- .../monitor/back/methods/sales-monitor/salesFilter.js | 4 ++-- .../methods/sales-monitor/specs/salesFilter.spec.js | 4 ++-- .../ticket/back/methods/ticket/specs/filter.spec.js | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 63d395e861..550a790158 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -1076,7 +1076,7 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric (9, 1, 16, 'Ranged weapon longbow 200cm', 1, 103.49, 0, 0, 0, util.VN_CURDATE(), NULL), (10, 2, 16, 'Melee weapon combat fist 15cm', 10, 7.09, 0, 0, 0, util.VN_CURDATE(), NULL), (11, 1, 16, 'Ranged weapon longbow 200cm', 1, 103.49, 0, 0, 0, util.VN_CURDATE(), NULL), - (12, 4, 16, 'Melee weapon heavy shield 100cm', 20, 1.71, 0, 0, 0, util.VN_CURDATE(), 'hasItemLost'), + (12, 4, 16, 'Melee weapon heavy shield 100cm', 20, 1.71, 0, 0, 0, util.VN_CURDATE(), NULL), (13, 2, 8, 'Melee weapon combat fist 15cm', 10, 7.08, 0, 0, 0, util.VN_CURDATE(), 'hasItemLost'), (14, 1, 8, 'Ranged weapon longbow 200cm', 2, 103.49, 0, 0, 0, util.VN_CURDATE(), NULL), (15, 1, 19, 'Ranged weapon longbow 200cm', 1, 103.49, 0, 0, 0, util.VN_CURDATE(), NULL), diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 4f81f59b9e..36e2c40aa5 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -288,7 +288,7 @@ module.exports = Self => { {'tp.hasRisk': true}, {'tp.hasTicketRequest': true}, {'tp.hasComponentLack': true}, - {'tp.isTaxDataChecked': false}, + {'tp.isTaxDataChecked': true}, {'tp.hasItemShortage': true}, {'tp.isTooLittle': true} ]}; @@ -298,7 +298,7 @@ module.exports = Self => { {'tp.hasRisk': false}, {'tp.hasTicketRequest': false}, {'tp.hasComponentLack': false}, - {'tp.isTaxDataChecked': true}, + {'tp.isTaxDataChecked': false}, {'tp.hasItemShortage': false}, {'tp.isTooLittle': false} ]}; diff --git a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js index 908c446a68..1b4616de73 100644 --- a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js +++ b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js @@ -48,7 +48,7 @@ describe('SalesMonitor salesFilter()', () => { } }); - fit('should now return the tickets matching the problems on false', async() => { + it('should now return the tickets matching the problems on false', async() => { const tx = await models.SalesMonitor.beginTransaction({}); try { @@ -68,7 +68,7 @@ describe('SalesMonitor salesFilter()', () => { const filter = {}; const result = await models.SalesMonitor.salesFilter(ctx, filter, options); - expect(result.length).toEqual(4); + expect(result.length).toEqual(5); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js index 44bfbb7e3f..d06d02f23a 100644 --- a/modules/ticket/back/methods/ticket/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js @@ -42,11 +42,11 @@ describe('ticket filter()', () => { const result = await models.Ticket.filter(ctx, filter, options); const hasProblemTicket = result.some(ticket => - ticket.isFreezed === true || - ticket.hasRisk === true || - ticket.hasTicketRequest === true || - ticket.hasRounding === true || - ticket.hasItemShortage === true + ticket.isFreezed == true || + ticket.hasRisk == true || + ticket.hasTicketRequest == true || + ticket.hasRounding == true || + ticket.hasItemShortage == true ); expect(hasProblemTicket).toBe(true); From 4e0a81464c6e0dc410d8c87091bbfe2f9aa06df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Wed, 2 Oct 2024 15:12:57 +0200 Subject: [PATCH 08/84] fix: test --- db/routines/vn/procedures/productionControl.sql | 1 + db/routines/vn/procedures/sale_getProblems.sql | 2 +- db/routines/vn/procedures/sale_getProblemsByTicket.sql | 4 +++- db/routines/vn/procedures/ticket_getProblems.sql | 2 ++ modules/monitor/back/methods/sales-monitor/salesFilter.js | 1 + modules/ticket/back/methods/ticket/filter.js | 1 + modules/ticket/back/methods/ticket/getTicketsFuture.js | 1 + 7 files changed, 10 insertions(+), 2 deletions(-) diff --git a/db/routines/vn/procedures/productionControl.sql b/db/routines/vn/procedures/productionControl.sql index 29abc8044e..b9550d62c8 100644 --- a/db/routines/vn/procedures/productionControl.sql +++ b/db/routines/vn/procedures/productionControl.sql @@ -283,6 +283,7 @@ proc: BEGIN DROP TEMPORARY TABLE tmp.productionTicket, + tmp.ticket, tmp.ticketProblems, tmp.saleProblems, tmp.ticketWithPrevia, diff --git a/db/routines/vn/procedures/sale_getProblems.sql b/db/routines/vn/procedures/sale_getProblems.sql index a8388034f9..79b548c2c6 100644 --- a/db/routines/vn/procedures/sale_getProblems.sql +++ b/db/routines/vn/procedures/sale_getProblems.sql @@ -163,6 +163,6 @@ BEGIN END LOOP; CLOSE vCursor; - DROP TEMPORARY TABLE tItemShelving, tmp.sale; + DROP TEMPORARY TABLE tItemShelving; END$$ DELIMITER ; diff --git a/db/routines/vn/procedures/sale_getProblemsByTicket.sql b/db/routines/vn/procedures/sale_getProblemsByTicket.sql index 708938cba0..fdfd5c8bc8 100644 --- a/db/routines/vn/procedures/sale_getProblemsByTicket.sql +++ b/db/routines/vn/procedures/sale_getProblemsByTicket.sql @@ -18,6 +18,8 @@ BEGIN SELECT * FROM tmp.saleProblems; - DROP TEMPORARY TABLE tmp.saleProblems; + DROP TEMPORARY TABLE + tmp.saleProblems, + tmp.sale; END$$ DELIMITER ; diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index 3855c3a1df..fe77ed57bd 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -105,5 +105,7 @@ BEGIN SET totalProblems = isFreezed + hasHighRisk + hasTicketRequest + isTaxDataChecked + hasComponentLack + hasItemDelay + isTooLittle + hasItemLost + hasRounding + hasItemShortage + isVip; + + DROP TEMPORARY TABLE tmp.sale; END$$ DELIMITER ; diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 36e2c40aa5..27a3083117 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -375,6 +375,7 @@ module.exports = Self => { stmts.push(` DROP TEMPORARY TABLE + tmp.ticket, tmp.filter, tmp.ticketProblems, tmp.sale_getWarnings, diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js index 2571213070..3ca52337d0 100644 --- a/modules/ticket/back/methods/ticket/filter.js +++ b/modules/ticket/back/methods/ticket/filter.js @@ -369,6 +369,7 @@ module.exports = Self => { stmts.push( `DROP TEMPORARY TABLE + tmp.ticket, tmp.filter, tmp.ticketProblems`); diff --git a/modules/ticket/back/methods/ticket/getTicketsFuture.js b/modules/ticket/back/methods/ticket/getTicketsFuture.js index af3acff13e..88f40bc3ef 100644 --- a/modules/ticket/back/methods/ticket/getTicketsFuture.js +++ b/modules/ticket/back/methods/ticket/getTicketsFuture.js @@ -213,6 +213,7 @@ module.exports = Self => { stmts.push( `DROP TEMPORARY TABLE + tmp.ticket, tmp.filter, tmp.ticketProblems`); From 9113f2e3e568b2d4b5e9751535c659ace503d81b Mon Sep 17 00:00:00 2001 From: Jon Date: Wed, 13 Nov 2024 08:30:09 +0100 Subject: [PATCH 09/84] feat: refs #7127 modify days when adding lines to a claim --- db/dump/fixtures.before.sql | 4 ++-- .../11334-grayRoebelini/00-firstScript.sql | 2 ++ .../specs/claim-beginning.spec.js | 2 +- .../claim/specs/createFromSales.spec.js | 24 ++++++++----------- modules/claim/back/models/claim-beginning.js | 24 +++++++++++++++++++ .../methods/sale/getClaimableFromTicket.js | 8 +++---- 6 files changed, 42 insertions(+), 22 deletions(-) create mode 100644 db/versions/11334-grayRoebelini/00-firstScript.sql diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 8544686e8b..4c13b37cc7 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -1931,9 +1931,9 @@ INSERT INTO `vn`.`claimEnd`(`id`, `saleFk`, `claimFk`, `workerFk`, `claimDestina (1, 31, 4, 21, 2), (2, 32, 3, 21, 3); -INSERT INTO `vn`.`claimConfig`(`id`, `maxResponsibility`, `monthsToRefund`, `minShipped`) +INSERT INTO `vn`.`claimConfig`(`id`, `maxResponsibility`, `monthsToRefund`, `minShipped`,`daysToClaim`) VALUES - (1, 5, 4, '2016-10-01'); + (1, 5, 4, '2016-10-01', 7); INSERT INTO `vn`.`claimRatio`(`clientFk`, `yearSale`, `claimAmount`, `claimingRate`, `priceIncreasing`, `packingRate`) VALUES diff --git a/db/versions/11334-grayRoebelini/00-firstScript.sql b/db/versions/11334-grayRoebelini/00-firstScript.sql new file mode 100644 index 0000000000..5eb1076947 --- /dev/null +++ b/db/versions/11334-grayRoebelini/00-firstScript.sql @@ -0,0 +1,2 @@ +-- Place your SQL code here +ALTER TABLE vn.claimConfig ADD IF NOT EXISTS daysToClaim int(11) NOT NULL DEFAULT 7 COMMENT 'Dias para reclamar'; diff --git a/modules/claim/back/methods/claim-beginning/specs/claim-beginning.spec.js b/modules/claim/back/methods/claim-beginning/specs/claim-beginning.spec.js index b7974ad237..8b56f3a1c3 100644 --- a/modules/claim/back/methods/claim-beginning/specs/claim-beginning.spec.js +++ b/modules/claim/back/methods/claim-beginning/specs/claim-beginning.spec.js @@ -4,7 +4,7 @@ const LoopBackContext = require('loopback-context'); describe('ClaimBeginning model()', () => { const claimFk = 1; const activeCtx = { - accessToken: {userId: 18}, + accessToken: {userId: 72}, headers: {origin: 'localhost:5000'}, __: () => {} }; diff --git a/modules/claim/back/methods/claim/specs/createFromSales.spec.js b/modules/claim/back/methods/claim/specs/createFromSales.spec.js index 25414d1db7..75caf278ef 100644 --- a/modules/claim/back/methods/claim/specs/createFromSales.spec.js +++ b/modules/claim/back/methods/claim/specs/createFromSales.spec.js @@ -3,22 +3,18 @@ const LoopBackContext = require('loopback-context'); describe('Claim createFromSales()', () => { const ticketId = 23; - const newSale = [{ - id: 31, - instance: 0, - quantity: 10 - }]; - const activeCtx = { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - }; - - const ctx = { - req: activeCtx - }; + const newSale = [{id: 31, instance: 0, quantity: 10}]; + let activeCtx; + let ctx; beforeEach(() => { + activeCtx = { + accessToken: {userId: 72}, + headers: {origin: 'localhost:5000'}, + __: () => {} + }; + ctx = {req: activeCtx}; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ active: activeCtx }); diff --git a/modules/claim/back/models/claim-beginning.js b/modules/claim/back/models/claim-beginning.js index 3dc9261c3d..40d66c33ea 100644 --- a/modules/claim/back/models/claim-beginning.js +++ b/modules/claim/back/models/claim-beginning.js @@ -1,6 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); const LoopBackContext = require('loopback-context'); +const moment = require('moment'); module.exports = Self => { require('../methods/claim-beginning/importToNewRefundTicket')(Self); @@ -13,8 +14,31 @@ module.exports = Self => { const options = ctx.options; const models = Self.app.models; const saleFk = ctx?.currentInstance?.saleFk || ctx?.instance?.saleFk; + const loopBackContext = LoopBackContext.getCurrentContext(); + const accessToken = loopBackContext.active.accessToken; + const user = await models.VnUser.findById(accessToken.userId); + const role = await models.VnRole.findById(user.roleFk); const sale = await models.Sale.findById(saleFk, {fields: ['ticketFk', 'quantity']}, options); + if (role.name !== 'salesPerson' && role.name !== 'claimManager') + throw new UserError(`You don't have permission to modify this claim`); + + if (role.name === 'salesPerson') { + const query = ` + SELECT daysToClaim + FROM vn.claimConfig`; + const res = await Self.rawSql(query); + const daysToClaim = res[0]?.daysToClaim; + + const claim = await models.Claim.findById(ctx?.currentInstance?.claimFk, {fields: ['created']}, options); + const claimDate = moment.utc(claim.created); + const currentDate = moment.utc(); + const daysSinceSale = currentDate.diff(claimDate, 'days'); + + if (daysSinceSale > daysToClaim) + throw new UserError(`You can't modify this claim because the deadline has already passed`); + } + if (ctx.isNewInstance) { const claim = await models.Claim.findById(ctx.instance.claimFk, {fields: ['ticketFk']}, options); if (sale.ticketFk != claim.ticketFk) diff --git a/modules/ticket/back/methods/sale/getClaimableFromTicket.js b/modules/ticket/back/methods/sale/getClaimableFromTicket.js index c51781f595..cb10bdb0e0 100644 --- a/modules/ticket/back/methods/sale/getClaimableFromTicket.js +++ b/modules/ticket/back/methods/sale/getClaimableFromTicket.js @@ -30,7 +30,6 @@ module.exports = Self => { SELECT s.id AS saleFk, t.id AS ticketFk, - t.landed, s.concept, s.itemFk, s.quantity, @@ -41,11 +40,10 @@ module.exports = Self => { INNER JOIN vn.sale s ON s.ticketFk = t.id LEFT JOIN vn.claimBeginning cb ON cb.saleFk = s.id - WHERE (t.landed) >= TIMESTAMPADD(DAY, -7, ?) - AND t.id = ? AND cb.id IS NULL - ORDER BY t.landed DESC, t.id DESC`; + WHERE t.id = ? + AND cb.id IS NULL`; - const claimableSales = await Self.rawSql(query, [date, ticketFk], myOptions); + const claimableSales = await Self.rawSql(query, [ticketFk], myOptions); return claimableSales; }; From 568661021a265f6e39f3c2b4557f5d83fa2b7060 Mon Sep 17 00:00:00 2001 From: Jon Date: Fri, 29 Nov 2024 11:54:53 +0100 Subject: [PATCH 10/84] feat: refs #7965 added #6242 back to unify PR --- .../11306-greenMonstera/00-firstScript.sql | 3 + modules/ticket/back/methods/ticket/filter.js | 37 ++------- .../ticket/back/methods/ticket/getSales.js | 9 +- .../back/methods/ticket/getTicketProblems.js | 83 +++++++++++++++++++ .../ticket/specs/getTicketProblems.spec.js | 21 +++++ modules/ticket/back/models/ticket-methods.js | 1 + 6 files changed, 116 insertions(+), 38 deletions(-) create mode 100644 db/versions/11306-greenMonstera/00-firstScript.sql create mode 100644 modules/ticket/back/methods/ticket/getTicketProblems.js create mode 100644 modules/ticket/back/methods/ticket/specs/getTicketProblems.spec.js diff --git a/db/versions/11306-greenMonstera/00-firstScript.sql b/db/versions/11306-greenMonstera/00-firstScript.sql new file mode 100644 index 0000000000..c9edc6bfb9 --- /dev/null +++ b/db/versions/11306-greenMonstera/00-firstScript.sql @@ -0,0 +1,3 @@ +-- Place your SQL code here +INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId) + VALUES ('Ticket','getTicketProblems','READ','ALLOW','ROLE','employee'); diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js index 50481f05b6..f0116424ab 100644 --- a/modules/ticket/back/methods/ticket/filter.js +++ b/modules/ticket/back/methods/ticket/filter.js @@ -306,11 +306,7 @@ module.exports = Self => { (INDEX (ticketFk)) ENGINE = MEMORY SELECT f.id ticketFk - FROM tmp.filter f - LEFT JOIN alertLevel al ON al.id = f.alertLevel - WHERE (al.code = 'FREE' OR f.alertLevel IS NULL) - AND f.shipped >= ? - `, [date]); + FROM tmp.filter f`); stmts.push(stmt); stmts.push('CALL ticket_getProblems(FALSE)'); @@ -330,34 +326,13 @@ module.exports = Self => { if (args.problems != undefined && (!args.from && !args.to)) throw new UserError('Choose a date range or days forward'); - let condition; - let hasProblem; - let hasWhere; - switch (args.problems) { - case true: - condition = `or`; - hasProblem = true; - hasWhere = true; - break; - - case false: - condition = `and`; - hasProblem = null; - hasWhere = true; - break; + if (typeof args.problems == 'boolean') { + let condition = 0; + if (args.problems) + condition = {neq: condition}; + stmt.merge(conn.makeWhere({'tp.totalProblems': condition})); } - const problems = {[condition]: [ - {'tp.isFreezed': hasProblem}, - {'tp.hasRisk': hasProblem}, - {'tp.hasTicketRequest': hasProblem}, - {'tp.hasItemShortage': hasProblem}, - {'tp.hasRounding': hasProblem} - ]}; - - if (hasWhere) - stmt.merge(conn.makeWhere(problems)); - if (filter.order) { if (typeof filter.order == 'string') filter.order = [filter.order]; const index = filter.order.findIndex(o => o.includes('stateFk')); diff --git a/modules/ticket/back/methods/ticket/getSales.js b/modules/ticket/back/methods/ticket/getSales.js index 5b2288d317..3b5ee21a67 100644 --- a/modules/ticket/back/methods/ticket/getSales.js +++ b/modules/ticket/back/methods/ticket/getSales.js @@ -98,14 +98,9 @@ module.exports = Self => { for (let sale of sales) { const problems = saleProblems.get(sale.id); - const itemStock = itemAvailable.get(sale.itemFk); - sale.available = itemStock.available; - sale.visible = itemStock.visible; - sale.claim = claimedSales.get(sale.id); if (problems) { - sale.itemShortage = problems.itemShortage; - sale.hasTicketRequest = problems.hasTicketRequest; - sale.hasComponentLack = problems.hasComponentLack; + for (const problem in problems) + sale[problem] = problems[problem]; } if (salesWithLogs.includes(sale.id)) sale.$hasLogs = true; diff --git a/modules/ticket/back/methods/ticket/getTicketProblems.js b/modules/ticket/back/methods/ticket/getTicketProblems.js new file mode 100644 index 0000000000..351e07b679 --- /dev/null +++ b/modules/ticket/back/methods/ticket/getTicketProblems.js @@ -0,0 +1,83 @@ +const {buildFilter} = require('vn-loopback/util/filter'); + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; + +module.exports = Self => { + Self.remoteMethodCtx('getTicketProblems', { + description: 'Get problems for a ticket', + accessType: 'READ', + accepts: [{ + arg: 'id', + type: 'number', + required: true, + description: 'The ticket id', + http: {source: 'path'} + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/:id/getTicketProblems`, + verb: 'get' + } + }); + + Self.getTicketProblems = async(ctx, id, options) => { + const myOptions = {}; + const stmts = []; + const conn = Self.dataSource.connector; + let stmt; + const ticketId = id; + const where = buildFilter(ctx.args, param => { + switch (param) { + case 'id': + return {'t.id': ticketId}; + } + }); + + if (typeof options == 'object') + Object.assign(myOptions, options); + + stmt = new ParameterizedSQL(` + CREATE OR REPLACE TEMPORARY TABLE tmp.filter + (INDEX (id)) + ENGINE = MEMORY + SELECT t.id + FROM ticket t + `); + + stmt.merge(conn.makeWhere(where)); + stmts.push(stmt); + + stmt = new ParameterizedSQL(` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticket + (INDEX (ticketFk)) + ENGINE = MEMORY + SELECT f.id AS ticketFk + FROM tmp.filter f + `); + stmts.push(stmt); + + stmts.push('CALL ticket_getProblems(FALSE)'); + + stmt = new ParameterizedSQL(` + SELECT f.*, tp.* + FROM tmp.filter f + LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id + `); + const ticketsIndex = stmts.push(stmt) - 1; + + stmts.push(` + DROP TEMPORARY TABLE IF EXISTS + tmp.filter, + tmp.ticket, + tmp.ticketProblems + `); + + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql, myOptions); + + return result[ticketsIndex]; + }; +}; diff --git a/modules/ticket/back/methods/ticket/specs/getTicketProblems.spec.js b/modules/ticket/back/methods/ticket/specs/getTicketProblems.spec.js new file mode 100644 index 0000000000..56c3edc1b9 --- /dev/null +++ b/modules/ticket/back/methods/ticket/specs/getTicketProblems.spec.js @@ -0,0 +1,21 @@ +const models = require('vn-loopback/server/server').models; + +fdescribe('ticket getTicketProblems()', () => { + const ctx = {req: {accessToken: 9}}; + it('should return the problems of a ticket', async() => { + const tx = await models.Ticket.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const problems = await models.Ticket.getTicketProblems(ctx, 11, options); + + expect(problems[7].totalProblems).toEqual(3); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/ticket/back/models/ticket-methods.js b/modules/ticket/back/models/ticket-methods.js index 620b3e1841..995fa2da3c 100644 --- a/modules/ticket/back/models/ticket-methods.js +++ b/modules/ticket/back/models/ticket-methods.js @@ -46,4 +46,5 @@ module.exports = function(Self) { require('../methods/ticket/docuwareDownload')(Self); require('../methods/ticket/myLastModified')(Self); require('../methods/ticket/setWeight')(Self); + require('../methods/ticket/getTicketProblems')(Self); }; From 8fedd7893883f356b4a0f873ec356ded9709bb7b Mon Sep 17 00:00:00 2001 From: Jon Date: Fri, 29 Nov 2024 12:47:24 +0100 Subject: [PATCH 11/84] fix: refs #7965 filter and sales back tests --- .../ticket/back/methods/ticket/specs/filter.spec.js | 10 +++++----- .../ticket/back/methods/ticket/specs/getSales.spec.js | 1 - .../methods/ticket/specs/getTicketProblems.spec.js | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js index d06d02f23a..cbd799431e 100644 --- a/modules/ticket/back/methods/ticket/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js @@ -80,11 +80,11 @@ describe('ticket filter()', () => { const result = await models.Ticket.filter(ctx, filter, options); result.forEach(ticket => { - expect(ticket.isFreezed).toEqual(null); - expect(ticket.hasRisk).toEqual(null); - expect(ticket.hasTicketRequest).toEqual(null); - expect(ticket.hasItemShortage).toEqual(null); - expect(ticket.hasRounding).toEqual(null); + expect(ticket.isFreezed).toEqual(0); + expect(ticket.hasRisk).toEqual(0); + expect(ticket.hasTicketRequest).toEqual(0); + expect(ticket.hasItemShortage).toEqual(0); + expect(ticket.hasRounding).toEqual(0); }); await tx.rollback(); diff --git a/modules/ticket/back/methods/ticket/specs/getSales.spec.js b/modules/ticket/back/methods/ticket/specs/getSales.spec.js index 7c0a67d451..f0a99b90b6 100644 --- a/modules/ticket/back/methods/ticket/specs/getSales.spec.js +++ b/modules/ticket/back/methods/ticket/specs/getSales.spec.js @@ -15,7 +15,6 @@ describe('ticket getSales()', () => { expect(sales[1].item).toBeDefined(); expect(sales[2].item).toBeDefined(); expect(sales[3].item).toBeDefined(); - expect(sales[0].claim).toBeDefined(); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket/specs/getTicketProblems.spec.js b/modules/ticket/back/methods/ticket/specs/getTicketProblems.spec.js index 56c3edc1b9..f46c27e4dc 100644 --- a/modules/ticket/back/methods/ticket/specs/getTicketProblems.spec.js +++ b/modules/ticket/back/methods/ticket/specs/getTicketProblems.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; -fdescribe('ticket getTicketProblems()', () => { +describe('ticket getTicketProblems()', () => { const ctx = {req: {accessToken: 9}}; it('should return the problems of a ticket', async() => { const tx = await models.Ticket.beginTransaction({}); From 086b7aed4b2e2fcf25db2f5b7ddfbdc7075ec09c Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 24 Dec 2024 10:40:17 +0100 Subject: [PATCH 12/84] feat: refs #7119 add VehicleState model with data source configuration --- modules/route/back/model-config.json | 3 ++ modules/route/back/models/vehicle-state.json | 29 ++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 modules/route/back/models/vehicle-state.json diff --git a/modules/route/back/model-config.json b/modules/route/back/model-config.json index fb1c5d7fdd..8b47c5347d 100644 --- a/modules/route/back/model-config.json +++ b/modules/route/back/model-config.json @@ -35,6 +35,9 @@ "Vehicle": { "dataSource": "vn" }, + "VehicleState": { + "dataSource": "vn" + }, "RoutesMonitor": { "dataSource": "vn" } diff --git a/modules/route/back/models/vehicle-state.json b/modules/route/back/models/vehicle-state.json new file mode 100644 index 0000000000..1f71333eb9 --- /dev/null +++ b/modules/route/back/models/vehicle-state.json @@ -0,0 +1,29 @@ +{ + "name": "VehicleState", + "base": "VnModel", + "options": { + "mysql": { + "table": "vehicleState" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "state": { + "type": "string" + }, + "hasToNotify": { + "type": "number" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] +} \ No newline at end of file From 39fc19646471d0607bdcfa9170de1b2c34694ef3 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 24 Dec 2024 13:01:23 +0100 Subject: [PATCH 13/84] feat: refs #7119 add VehicleEvent and VehicleState models with associated methods and SQL fixtures --- db/dump/fixtures.before.sql | 30 ++++++++--- .../11394-brownAsparagus/00-firstScript.sql | 2 + modules/route/back/methods/vehicle/filter.js | 52 +++++++++++++++++++ modules/route/back/model-config.json | 3 ++ modules/route/back/models/vehicle-event.json | 51 ++++++++++++++++++ modules/route/back/models/vehicle.js | 1 + modules/route/back/models/vehicle.json | 22 ++++++-- 7 files changed, 150 insertions(+), 11 deletions(-) create mode 100644 db/versions/11394-brownAsparagus/00-firstScript.sql create mode 100644 modules/route/back/methods/vehicle/filter.js create mode 100644 modules/route/back/models/vehicle-event.json diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 97ed0ae47e..cb9160b6d9 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -849,14 +849,14 @@ INSERT INTO `vn`.`deliveryPoint` (`id`, `name`, `ubication`) VALUES (1, 'Gotham','1007 Mountain Drive, Gotham'); -INSERT INTO `vn`.`vehicle`(`id`, `numberPlate`, `tradeMark`, `model`, `companyFk`, `warehouseFk`, `description`, `m3`, `isActive`, `deliveryPointFk`) +INSERT INTO `vn`.`vehicle`(`id`, `numberPlate`, `tradeMark`, `model`, `companyFk`, `warehouseFk`, `description`, `m3`, `isActive`, `deliveryPointFk`, `chassis`, `leasing`) VALUES - (1, '3333-BAT', 'WAYNE INDUSTRIES', 'BATMOBILE', 442, 1, 'The ultimate war machine', 50, 1, 1), - (2, '1111-IMK', 'STARK INDUSTRIES', 'MARK-III', 442, 1, 'Iron-Man Heavy Armor MARK-III', 18, 1, 1), - (3, '2222-IMK', 'STARK INDUSTRIES', 'MARK-VI', 442, 1, 'Iron-Man Heavy Armor MARK-VI', 16, 1, 1), - (4, '3333-IMK', 'STARK INDUSTRIES', 'MARK-VII', 442, 1, 'Iron-Man Heavy Armor MARK-VII', 14, 1, 1), - (5, '4444-IMK', 'STARK INDUSTRIES', 'MARK-XLII', 442, 1, 'Iron-Man Heavy Armor MARK-XLII', 13, 1, 1), - (6, '5555-IMK', 'STARK INDUSTRIES', 'MARK-XLV', 442, 1, 'Iron-Man Heavy Armor MARK-XLV', 12, 0, 1); + (1, '3333-BAT', 'WAYNE INDUSTRIES', 'BATMOBILE', 442, 1, 'The ultimate war machine', 50, 1, 1, 'XCSC133C60', 'Wayne leasing'), + (2, '1111-IMK', 'STARK INDUSTRIES', 'MARK-III', 442, 1, 'Iron-Man Heavy Armor MARK-III', 18, 1, 1, '', ''), + (3, '2222-IMK', 'STARK INDUSTRIES', 'MARK-VI', 442, 1, 'Iron-Man Heavy Armor MARK-VI', 16, 1, 1, '', ''), + (4, '3333-IMK', 'STARK INDUSTRIES', 'MARK-VII', 442, 1, 'Iron-Man Heavy Armor MARK-VII', 14, 1, 1, '', ''), + (5, '4444-IMK', 'STARK INDUSTRIES', 'MARK-XLII', 442, 1, 'Iron-Man Heavy Armor MARK-XLII', 13, 1, 1, '', ''), + (6, '5555-IMK', 'STARK INDUSTRIES', 'MARK-XLV', 442, 1, 'Iron-Man Heavy Armor MARK-XLV', 12, 0, 1, '', ''); INSERT INTO `vn`.`config`(`id`, `mdbServer`, `fakeEmail`, `defaultersMaxAmount`, `inventoried`) VALUES @@ -4049,3 +4049,19 @@ INSERT IGNORE INTO vn.osrmConfig (id,url,tolerance) INSERT IGNORE INTO vn.inventoryConfig SET id = 1, supplierFk = 4; + +INSERT INTO vn.vehicleState (state, hasToNotify) +VALUES + ('Operativo', NULL), + ('Prestado', NULL), + ('Robado', NULL), + ('Taller', NULL), + ('Targeta SOLRED', NULL), + ('Via T SOLRED', NULL), + ('ITV', NULL); + +INSERT INTO vn.vehicleEvent (started, finished, vehicleStateFk, description, vehicleFk, userFk, notified) +VALUES + ('2000-12-01', '2000-12-02', 4, 'cambio de aceite', 5, 103, NULL), + ('2000-12-15', '2000-12-18', 2, 'viaje fin de curso', 5, 103, NULL), + ('2000-12-20', '2001-01-01', 3, 'llaves puestas', 203, 103, NULL); \ No newline at end of file diff --git a/db/versions/11394-brownAsparagus/00-firstScript.sql b/db/versions/11394-brownAsparagus/00-firstScript.sql new file mode 100644 index 0000000000..c7137bc7b6 --- /dev/null +++ b/db/versions/11394-brownAsparagus/00-firstScript.sql @@ -0,0 +1,2 @@ +INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) + VALUES('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'); \ No newline at end of file diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js new file mode 100644 index 0000000000..9f92ee5ac4 --- /dev/null +++ b/modules/route/back/methods/vehicle/filter.js @@ -0,0 +1,52 @@ +module.exports = Self => { + Self.remoteMethod('filter', { + description: 'Find all instances of the model matched by filter from the data source.', + accessType: 'READ', + accepts: [{ + arg: 'id', + type: 'number' + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/filter`, + verb: `GET` + } + }); + + Self.filter = async id => { + const filter = { + fields: ['id', 'numberPlate', 'tradeMark', 'model', 'm3', 'description', 'isActive', 'warehouseFk', 'companyFk', 'countryCodeFk', 'chassis', 'leasing'], + include: [ + { + relation: 'warehouse', + scope: { + fields: ['id', 'name'] + } + }, + { + relation: 'company', + scope: { + fields: ['id', 'code'] + } + }, + { + relation: 'event', + scope: { + fields: ['vehicleFk', 'vehicleStateFk'], + include: { + relation: 'state', + scope: { + fields: ['id', 'state'] + } + } + } + }, + ] + }; + + return Self.find(filter); + }; +}; diff --git a/modules/route/back/model-config.json b/modules/route/back/model-config.json index 8b47c5347d..b951d2560a 100644 --- a/modules/route/back/model-config.json +++ b/modules/route/back/model-config.json @@ -35,6 +35,9 @@ "Vehicle": { "dataSource": "vn" }, + "VehicleEvent": { + "dataSource": "vn" + }, "VehicleState": { "dataSource": "vn" }, diff --git a/modules/route/back/models/vehicle-event.json b/modules/route/back/models/vehicle-event.json new file mode 100644 index 0000000000..324076723c --- /dev/null +++ b/modules/route/back/models/vehicle-event.json @@ -0,0 +1,51 @@ +{ + "name": "VehicleEvent", + "base": "VnModel", + "options": { + "mysql": { + "table": "vehicleEvent" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "started": { + "type": "date" + }, + "finished": { + "type": "date" + }, + "vehicleStateFk": { + "type": "number" + }, + "description": { + "type": "string" + }, + "vehicleFk": { + "type": "number" + }, + "userFk": { + "type": "number" + }, + "notified": { + "type": "date" + } + }, + "relations": { + "state": { + "type": "belongsTo", + "model": "VehicleState", + "foreignKey": "vehicleStateFk" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] +} \ No newline at end of file diff --git a/modules/route/back/models/vehicle.js b/modules/route/back/models/vehicle.js index 73e3214435..59aa7cb8b7 100644 --- a/modules/route/back/models/vehicle.js +++ b/modules/route/back/models/vehicle.js @@ -1,3 +1,4 @@ module.exports = Self => { require('../methods/vehicle/sorted')(Self); + require('../methods/vehicle/filter')(Self); }; diff --git a/modules/route/back/models/vehicle.json b/modules/route/back/models/vehicle.json index 34a376b897..7dd172017c 100644 --- a/modules/route/back/models/vehicle.json +++ b/modules/route/back/models/vehicle.json @@ -3,7 +3,7 @@ "base": "VnModel", "options": { "mysql": { - "table": "vehicle" + "table": "vehicle" } }, "properties": { @@ -29,6 +29,15 @@ }, "isActive": { "type": "number" + }, + "countryCodeFk": { + "type": "string" + }, + "chassis": { + "type": "string" + }, + "leasing": { + "type": "string" } }, "relations": { @@ -46,14 +55,19 @@ "type": "belongsTo", "model": "DeliveryPoint", "foreignKey": "deliveryPointFk" + }, + "event": { + "type": "belongsTo", + "model": "VehicleEvent", + "foreignKey": "id" } }, "scope": { "where": { "isActive": { - "neq": false - } + "neq": false } + } }, "acls": [ { @@ -63,4 +77,4 @@ "permission": "ALLOW" } ] -} +} \ No newline at end of file From 9aa790ecfd5c0fb67ec0b17d65a59bc8457957bf Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 24 Dec 2024 13:27:32 +0100 Subject: [PATCH 14/84] feat: refs #7119 add isKmTruckRate field to Vehicle model and filter --- modules/route/back/methods/vehicle/filter.js | 2 +- modules/route/back/models/vehicle.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index 9f92ee5ac4..608139a4c9 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -18,7 +18,7 @@ module.exports = Self => { Self.filter = async id => { const filter = { - fields: ['id', 'numberPlate', 'tradeMark', 'model', 'm3', 'description', 'isActive', 'warehouseFk', 'companyFk', 'countryCodeFk', 'chassis', 'leasing'], + fields: ['id', 'numberPlate', 'tradeMark', 'model', 'm3', 'description', 'isActive', 'warehouseFk', 'companyFk', 'countryCodeFk', 'chassis', 'leasing', 'isKmTruckRate'], include: [ { relation: 'warehouse', diff --git a/modules/route/back/models/vehicle.json b/modules/route/back/models/vehicle.json index 7dd172017c..a98c7cab74 100644 --- a/modules/route/back/models/vehicle.json +++ b/modules/route/back/models/vehicle.json @@ -38,6 +38,9 @@ }, "leasing": { "type": "string" + }, + "isKmTruckRate": { + "type": "number" } }, "relations": { From f8c1e2aacfd2071716d6030ce1224b3bad35b3de Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 26 Dec 2024 16:36:50 +0100 Subject: [PATCH 15/84] feat: refs #7119 add search and filter capabilities to Vehicle model and update related SQL fixtures --- db/dump/fixtures.before.sql | 2 +- modules/route/back/methods/vehicle/filter.js | 88 ++++++++++++++++++-- modules/route/back/models/vehicle.json | 5 +- 3 files changed, 87 insertions(+), 8 deletions(-) diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 5516f13290..0189b1137c 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -4064,4 +4064,4 @@ INSERT INTO vn.vehicleEvent (started, finished, vehicleStateFk, description, veh VALUES ('2000-12-01', '2000-12-02', 4, 'cambio de aceite', 5, 103, NULL), ('2000-12-15', '2000-12-18', 2, 'viaje fin de curso', 5, 103, NULL), - ('2000-12-20', '2001-01-01', 3, 'llaves puestas', 203, 103, NULL); \ No newline at end of file + ('2000-12-20', '2001-01-01', 3, 'llaves puestas', 2, 103, NULL); \ No newline at end of file diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index 608139a4c9..b6ba306ac9 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -3,8 +3,48 @@ module.exports = Self => { description: 'Find all instances of the model matched by filter from the data source.', accessType: 'READ', accepts: [{ + arg: 'filter', + type: 'object', + description: 'Filter defining where, order, skip and limit - must be a JSON-encoded string', + http: {source: 'query'} + }, { + arg: 'search', + type: 'string', + description: 'Searchs the vehicle by id or numberPlate', + http: {source: 'query'} + }, { arg: 'id', type: 'number' + }, { + arg: 'description', + type: 'string' + }, { + arg: 'companyFk', + type: 'number' + }, { + arg: 'tradeMark', + type: 'string' + }, { + arg: 'numberPlate', + type: 'string' + }, { + arg: 'warehouseFk', + type: 'number' + }, { + arg: 'chassis', + type: 'string' + }, { + arg: 'leasing', + type: 'string' + }, { + arg: 'countryCodeFk', + type: 'string' + }, { + arg: 'isKmTruckRate', + type: 'boolean' + }, { + arg: 'vehicleStateFk', + type: 'number' }], returns: { type: ['object'], @@ -16,8 +56,37 @@ module.exports = Self => { } }); - Self.filter = async id => { - const filter = { + Self.filter = async(filter, search, id, description, companyFk, tradeMark, numberPlate, warehouseFk, chassis, leasing, countryCodeFk, isKmTruckRate, vehicleStateFk, options) => { + const models = Self.app.models; + const myOptions = {}; + const myWhere = {}; + const ids = []; + const {limit, order, skip, where} = filter; + + if (typeof options == 'object') Object.assign(myOptions, options); + + if (search) myWhere.or = [{id: search}, {numberPlate: {like: `%${numberPlate}%`}}]; + if (id) ids.push(id); + if (description) myWhere.description = {like: `%${description}%`}; + if (companyFk) myWhere.companyFk = companyFk; + if (tradeMark) myWhere.tradeMark = {like: `%${tradeMark}%`}; + if (numberPlate) myWhere.numberPlate = {like: `%${numberPlate}%`}; + if (warehouseFk) myWhere.warehouseFk = warehouseFk; + if (chassis) myWhere.chassis = {like: `%${chassis}%`}; + if (leasing) myWhere.leasing = {like: `%${leasing}%`}; + if (countryCodeFk) myWhere.countryCodeFk = countryCodeFk; + if (isKmTruckRate) myWhere.isKmTruckRate = isKmTruckRate; + if (vehicleStateFk) { + ids.push(...await models.VehicleEvent.find({ + fields: ['vehicleFk', 'vehicleStateFk'], + where: {vehicleStateFk}}).map(v => v.vehicleFk)); + } + + const idsLeng = ids.length; + if (idsLeng) myWhere.id = idsLeng == 1 ? ids[0] : {inq: ids}; + Object.assign(where || {}, myWhere); + + const myFilter = { fields: ['id', 'numberPlate', 'tradeMark', 'model', 'm3', 'description', 'isActive', 'warehouseFk', 'companyFk', 'countryCodeFk', 'chassis', 'leasing', 'isKmTruckRate'], include: [ { @@ -41,12 +110,21 @@ module.exports = Self => { scope: { fields: ['id', 'state'] } - } + }, + order: ['started DESC'], + limit: 1 } }, - ] + ], + where: myWhere, + order, + limit, + skip, }; - return Self.find(filter); + return Self.find(myFilter, myOptions).map(v => { + v.__data.event = v.event()[0]; + return v; + }); }; }; diff --git a/modules/route/back/models/vehicle.json b/modules/route/back/models/vehicle.json index a98c7cab74..8419ee6840 100644 --- a/modules/route/back/models/vehicle.json +++ b/modules/route/back/models/vehicle.json @@ -60,9 +60,10 @@ "foreignKey": "deliveryPointFk" }, "event": { - "type": "belongsTo", + "type": "hasMany", "model": "VehicleEvent", - "foreignKey": "id" + "foreignKey": "vehicleFk", + "property": "id" } }, "scope": { From b01e4894c9c3a46e3385be2ebeaeb55589fd2aea Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 26 Dec 2024 17:02:37 +0100 Subject: [PATCH 16/84] feat: refs #7119 remove vehicleStateFk argument from filter method and simplify search logic --- modules/route/back/methods/vehicle/filter.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index b6ba306ac9..a6cec02940 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -42,9 +42,6 @@ module.exports = Self => { }, { arg: 'isKmTruckRate', type: 'boolean' - }, { - arg: 'vehicleStateFk', - type: 'number' }], returns: { type: ['object'], @@ -56,17 +53,15 @@ module.exports = Self => { } }); - Self.filter = async(filter, search, id, description, companyFk, tradeMark, numberPlate, warehouseFk, chassis, leasing, countryCodeFk, isKmTruckRate, vehicleStateFk, options) => { - const models = Self.app.models; + Self.filter = async(filter, search, id, description, companyFk, tradeMark, numberPlate, warehouseFk, chassis, leasing, countryCodeFk, isKmTruckRate, options) => { const myOptions = {}; const myWhere = {}; - const ids = []; const {limit, order, skip, where} = filter; if (typeof options == 'object') Object.assign(myOptions, options); - if (search) myWhere.or = [{id: search}, {numberPlate: {like: `%${numberPlate}%`}}]; - if (id) ids.push(id); + if (search) myWhere.or = [{id: search}, {numberPlate: {like: `%${search}%`}}]; + if (id) myWhere.id = id; if (description) myWhere.description = {like: `%${description}%`}; if (companyFk) myWhere.companyFk = companyFk; if (tradeMark) myWhere.tradeMark = {like: `%${tradeMark}%`}; @@ -76,14 +71,7 @@ module.exports = Self => { if (leasing) myWhere.leasing = {like: `%${leasing}%`}; if (countryCodeFk) myWhere.countryCodeFk = countryCodeFk; if (isKmTruckRate) myWhere.isKmTruckRate = isKmTruckRate; - if (vehicleStateFk) { - ids.push(...await models.VehicleEvent.find({ - fields: ['vehicleFk', 'vehicleStateFk'], - where: {vehicleStateFk}}).map(v => v.vehicleFk)); - } - const idsLeng = ids.length; - if (idsLeng) myWhere.id = idsLeng == 1 ? ids[0] : {inq: ids}; Object.assign(where || {}, myWhere); const myFilter = { From 4d7387af18954d4b599bca6d48d0b78421e0e790 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 26 Dec 2024 17:52:36 +0100 Subject: [PATCH 17/84] feat: refs #7119 add deleteById permission for deliveryBoss role in ACL for Vehicle model --- db/versions/11394-brownAsparagus/00-firstScript.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/versions/11394-brownAsparagus/00-firstScript.sql b/db/versions/11394-brownAsparagus/00-firstScript.sql index c7137bc7b6..dfc07411ed 100644 --- a/db/versions/11394-brownAsparagus/00-firstScript.sql +++ b/db/versions/11394-brownAsparagus/00-firstScript.sql @@ -1,2 +1,3 @@ INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) - VALUES('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'); \ No newline at end of file + VALUES('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'), + ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss'); \ No newline at end of file From 9731d13a9ac401e1f031087f8d7ca1b7045f5340 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 27 Dec 2024 12:21:46 +0100 Subject: [PATCH 18/84] feat: refs #7119 add updateAttributes ACL --- db/versions/11394-brownAsparagus/00-firstScript.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/db/versions/11394-brownAsparagus/00-firstScript.sql b/db/versions/11394-brownAsparagus/00-firstScript.sql index dfc07411ed..84d6001995 100644 --- a/db/versions/11394-brownAsparagus/00-firstScript.sql +++ b/db/versions/11394-brownAsparagus/00-firstScript.sql @@ -1,3 +1,4 @@ INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) VALUES('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'), + ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss'); \ No newline at end of file From 0de4ce9b3c6e005851899930f68f9eb6431fd916 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 27 Dec 2024 15:36:19 +0100 Subject: [PATCH 19/84] feat: refs #7119 add BankPolicy and FuelType models --- db/dump/fixtures.before.sql | 30 ++++++++++++++----- .../11394-brownAsparagus/00-firstScript.sql | 3 +- modules/route/back/model-config.json | 6 ++++ modules/route/back/models/bank-policy.json | 18 +++++++++++ modules/route/back/models/fuel-type.json | 30 +++++++++++++++++++ modules/route/back/models/vehicle.json | 29 ++++++++++++++++++ 6 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 modules/route/back/models/bank-policy.json create mode 100644 modules/route/back/models/fuel-type.json diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 0189b1137c..b2d11999dd 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -849,14 +849,14 @@ INSERT INTO `vn`.`deliveryPoint` (`id`, `name`, `ubication`) VALUES (1, 'Gotham','1007 Mountain Drive, Gotham'); -INSERT INTO `vn`.`vehicle`(`id`, `numberPlate`, `tradeMark`, `model`, `companyFk`, `warehouseFk`, `description`, `m3`, `isActive`, `deliveryPointFk`, `chassis`, `leasing`) +INSERT INTO `vn`.`vehicle`(`id`, `numberPlate`, `tradeMark`, `model`, `companyFk`, `warehouseFk`, `description`, `m3`, `isActive`, `deliveryPointFk`, `chassis`, `leasing`, `supplierFk`, `fuelTypeFk`, `bankPolicyFk`) VALUES - (1, '3333-BAT', 'WAYNE INDUSTRIES', 'BATMOBILE', 442, 1, 'The ultimate war machine', 50, 1, 1, 'XCSC133C60', 'Wayne leasing'), - (2, '1111-IMK', 'STARK INDUSTRIES', 'MARK-III', 442, 1, 'Iron-Man Heavy Armor MARK-III', 18, 1, 1, '', ''), - (3, '2222-IMK', 'STARK INDUSTRIES', 'MARK-VI', 442, 1, 'Iron-Man Heavy Armor MARK-VI', 16, 1, 1, '', ''), - (4, '3333-IMK', 'STARK INDUSTRIES', 'MARK-VII', 442, 1, 'Iron-Man Heavy Armor MARK-VII', 14, 1, 1, '', ''), - (5, '4444-IMK', 'STARK INDUSTRIES', 'MARK-XLII', 442, 1, 'Iron-Man Heavy Armor MARK-XLII', 13, 1, 1, '', ''), - (6, '5555-IMK', 'STARK INDUSTRIES', 'MARK-XLV', 442, 1, 'Iron-Man Heavy Armor MARK-XLV', 12, 0, 1, '', ''); + (1, '3333-BAT', 'WAYNE INDUSTRIES', 'BATMOBILE', 442, 1, 'The ultimate war machine', 50, 1, 1, 'XCSC133C60', 'Wayne leasing', 1, 1, 1), + (2, '1111-IMK', 'STARK INDUSTRIES', 'MARK-III', 442, 1, 'Iron-Man Heavy Armor MARK-III', 18, 1, 1, '', '', 2, 2, 2), + (3, '2222-IMK', 'STARK INDUSTRIES', 'MARK-VI', 442, 1, 'Iron-Man Heavy Armor MARK-VI', 16, 1, 1, '', '', 442, 2, null), + (4, '3333-IMK', 'STARK INDUSTRIES', 'MARK-VII', 442, 1, 'Iron-Man Heavy Armor MARK-VII', 14, 1, 1, '', '', 442, 3, null), + (5, '4444-IMK', 'STARK INDUSTRIES', 'MARK-XLII', 442, 1, 'Iron-Man Heavy Armor MARK-XLII', 13, 1, 1, '', '', 442, 4, null), + (6, '5555-IMK', 'STARK INDUSTRIES', 'MARK-XLV', 442, 1, 'Iron-Man Heavy Armor MARK-XLV', 12, 0, 1, '', '', 442, 5, null); INSERT INTO `vn`.`config`(`id`, `mdbServer`, `fakeEmail`, `defaultersMaxAmount`, `inventoried`) VALUES @@ -4064,4 +4064,18 @@ INSERT INTO vn.vehicleEvent (started, finished, vehicleStateFk, description, veh VALUES ('2000-12-01', '2000-12-02', 4, 'cambio de aceite', 5, 103, NULL), ('2000-12-15', '2000-12-18', 2, 'viaje fin de curso', 5, 103, NULL), - ('2000-12-20', '2001-01-01', 3, 'llaves puestas', 2, 103, NULL); \ No newline at end of file + ('2000-12-20', '2001-01-01', 3, 'llaves puestas', 2, 103, NULL); + +INSERT INTO vn.fuelType (id, name, code) +VALUES + (1, 'gasoil', 'gasoil'), + (2, 'gas', 'gas'), + (3, 'adblue', 'adblue'), + (4, 'gasolina', 'gasolina'), + (5, 'gasoil-frigo', 'gasoil-frigo'), + (6, 'electrico', 'electric'); + +INSERT INTO vn.bankPolicy (id, `ref`, amount, committedFee, nonCommittedFee, annualFee, started, ended, accountingFk, companyFk, supplierFk, description, hasGuarantee, dmsFk, notaryFk, currencyFk, amortizationTypeFk, periodicityTypeFk, insuranceExpired) +VALUES + (1, '11112222', 500000.0, 0.028, 0.0, 0.001, '2001-01-01', '2001-02-01', 1, 442, NULL, NULL, 0, NULL, NULL, 1, NULL, NULL, NULL), + (2, '33334444', 100000.0, 0.017, 0.0, 0.0, '2001-01-01', '2001-02-01', 1, 2, NULL, NULL, 0, NULL, NULL, 2, NULL, NULL, NULL); \ No newline at end of file diff --git a/db/versions/11394-brownAsparagus/00-firstScript.sql b/db/versions/11394-brownAsparagus/00-firstScript.sql index 84d6001995..d02482efdd 100644 --- a/db/versions/11394-brownAsparagus/00-firstScript.sql +++ b/db/versions/11394-brownAsparagus/00-firstScript.sql @@ -1,4 +1,5 @@ INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) - VALUES('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'), + VALUES ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'), ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), + ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery'), ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss'); \ No newline at end of file diff --git a/modules/route/back/model-config.json b/modules/route/back/model-config.json index b951d2560a..42b71f5f1e 100644 --- a/modules/route/back/model-config.json +++ b/modules/route/back/model-config.json @@ -5,12 +5,18 @@ "AgencyTermConfig": { "dataSource": "vn" }, + "BankPolicy": { + "dataSource": "vn" + }, "Cmr": { "dataSource": "vn" }, "DeliveryPoint": { "dataSource": "vn" }, + "FuelType": { + "dataSource": "vn" + }, "RoadmapAddress": { "dataSource": "vn" }, diff --git a/modules/route/back/models/bank-policy.json b/modules/route/back/models/bank-policy.json new file mode 100644 index 0000000000..edbc636ffa --- /dev/null +++ b/modules/route/back/models/bank-policy.json @@ -0,0 +1,18 @@ +{ + "name": "BankPolicy", + "base": "VnModel", + "options": { + "mysql": { + "table": "bankPolicy" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "ref": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/modules/route/back/models/fuel-type.json b/modules/route/back/models/fuel-type.json new file mode 100644 index 0000000000..c7f96b3253 --- /dev/null +++ b/modules/route/back/models/fuel-type.json @@ -0,0 +1,30 @@ +{ + "name": "FuelType", + "base": "VnModel", + "options": { + "mysql": { + "table": "fuelType" + } + }, + "properties": { + "id": { + "type": "number", + "id": true, + "description": "Identifier" + }, + "name": { + "type": "string" + }, + "code": { + "type": "string" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "employee", + "permission": "ALLOW" + } + ] +} \ No newline at end of file diff --git a/modules/route/back/models/vehicle.json b/modules/route/back/models/vehicle.json index 8419ee6840..c5b6eab5ba 100644 --- a/modules/route/back/models/vehicle.json +++ b/modules/route/back/models/vehicle.json @@ -41,6 +41,15 @@ }, "isKmTruckRate": { "type": "number" + }, + "fuelTypeFk": { + "type": "number" + }, + "import": { + "type": "number" + }, + "vin": { + "type": "string" } }, "relations": { @@ -64,6 +73,26 @@ "model": "VehicleEvent", "foreignKey": "vehicleFk", "property": "id" + }, + "supplier": { + "type": "belongsTo", + "model": "Supplier", + "foreignKey": "supplierFk" + }, + "supplierCooler": { + "type": "belongsTo", + "model": "Supplier", + "foreignKey": "supplierCoolerFk" + }, + "bankPolicy": { + "type": "belongsTo", + "model": "BankPolicy", + "foreignKey": "bankPolicyFk" + }, + "fuelType": { + "type": "belongsTo", + "model": "FuelType", + "foreignKey": "fuelTypeFk" } }, "scope": { From 921edb238cdb1eb700e46429f6ec3db3846c0d85 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 27 Dec 2024 16:55:59 +0100 Subject: [PATCH 20/84] feat: refs #7119 add Ppe model and establish relationships in Vehicle model --- db/dump/fixtures.before.sql | 49 ++++++++++++++------------ modules/route/back/model-config.json | 3 ++ modules/route/back/models/ppe.json | 23 ++++++++++++ modules/route/back/models/vehicle.json | 6 ++++ 4 files changed, 59 insertions(+), 22 deletions(-) create mode 100644 modules/route/back/models/ppe.json diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index b2d11999dd..d5562d0009 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -4051,31 +4051,36 @@ INSERT IGNORE INTO vn.inventoryConfig supplierFk = 4; INSERT INTO vn.vehicleState (state, hasToNotify) -VALUES - ('Operativo', NULL), - ('Prestado', NULL), - ('Robado', NULL), - ('Taller', NULL), - ('Targeta SOLRED', NULL), - ('Via T SOLRED', NULL), - ('ITV', NULL); + VALUES + ('Operativo', NULL), + ('Prestado', NULL), + ('Robado', NULL), + ('Taller', NULL), + ('Targeta SOLRED', NULL), + ('Via T SOLRED', NULL), + ('ITV', NULL); INSERT INTO vn.vehicleEvent (started, finished, vehicleStateFk, description, vehicleFk, userFk, notified) -VALUES - ('2000-12-01', '2000-12-02', 4, 'cambio de aceite', 5, 103, NULL), - ('2000-12-15', '2000-12-18', 2, 'viaje fin de curso', 5, 103, NULL), - ('2000-12-20', '2001-01-01', 3, 'llaves puestas', 2, 103, NULL); + VALUES + ('2000-12-01', '2000-12-02', 4, 'cambio de aceite', 5, 103, NULL), + ('2000-12-15', '2000-12-18', 2, 'viaje fin de curso', 5, 103, NULL), + ('2000-12-20', '2001-01-01', 3, 'llaves puestas', 2, 103, NULL); INSERT INTO vn.fuelType (id, name, code) -VALUES - (1, 'gasoil', 'gasoil'), - (2, 'gas', 'gas'), - (3, 'adblue', 'adblue'), - (4, 'gasolina', 'gasolina'), - (5, 'gasoil-frigo', 'gasoil-frigo'), - (6, 'electrico', 'electric'); + VALUES + (1, 'gasoil', 'gasoil'), + (2, 'gas', 'gas'), + (3, 'adblue', 'adblue'), + (4, 'gasolina', 'gasolina'), + (5, 'gasoil-frigo', 'gasoil-frigo'), + (6, 'electrico', 'electric'); INSERT INTO vn.bankPolicy (id, `ref`, amount, committedFee, nonCommittedFee, annualFee, started, ended, accountingFk, companyFk, supplierFk, description, hasGuarantee, dmsFk, notaryFk, currencyFk, amortizationTypeFk, periodicityTypeFk, insuranceExpired) -VALUES - (1, '11112222', 500000.0, 0.028, 0.0, 0.001, '2001-01-01', '2001-02-01', 1, 442, NULL, NULL, 0, NULL, NULL, 1, NULL, NULL, NULL), - (2, '33334444', 100000.0, 0.017, 0.0, 0.0, '2001-01-01', '2001-02-01', 1, 2, NULL, NULL, 0, NULL, NULL, 2, NULL, NULL, NULL); \ No newline at end of file + VALUES + (1, '11112222', 500000.0, 0.028, 0.0, 0.001, '2001-01-01', '2001-02-01', 1, 442, NULL, NULL, 0, NULL, NULL, 1, NULL, NULL, NULL), + (2, '33334444', 100000.0, 0.017, 0.0, 0.0, '2001-01-01', '2001-02-01', 1, 2, NULL, NULL, 0, NULL, NULL, 2, NULL, NULL, NULL); + +INSERT INTO vn.ppe (id, amortization, firstAmortizated, lastAmortizated, finished, value, planFk, groupFk, account, endowment, elementAccount, nature, location, discharged, cause, isInvestmentAsset, workerFk, companyFk, description, isDone) + VALUES + (1, 0.00, '2001-01-01', NULL, NULL, 700.95, 16, 4, '3456000000', '4320000000', '12345', 'INMOVILIZADO', 'V02', NULL, NULL, 0, NULL, 442, 'UTILLAJE LASER ROTATIVO AUTONIVELANTE 500M', NULL), + (2, 0.00, '2001-01-01', NULL, NULL, 400.00, 16, 4, '5678000000', '1230000000', '67891', 'INMOVILIZADO', 'V02', NULL, NULL, 0, NULL, 442, 'UTILLAJE BALANZA Z100 150KILOS', NULL); \ No newline at end of file diff --git a/modules/route/back/model-config.json b/modules/route/back/model-config.json index 42b71f5f1e..c8c67a361e 100644 --- a/modules/route/back/model-config.json +++ b/modules/route/back/model-config.json @@ -17,6 +17,9 @@ "FuelType": { "dataSource": "vn" }, + "Ppe": { + "dataSource": "vn" + }, "RoadmapAddress": { "dataSource": "vn" }, diff --git a/modules/route/back/models/ppe.json b/modules/route/back/models/ppe.json new file mode 100644 index 0000000000..7af5cb6844 --- /dev/null +++ b/modules/route/back/models/ppe.json @@ -0,0 +1,23 @@ +{ + "name": "Ppe", + "base": "VnModel", + "options": { + "mysql": { + "table": "ppe" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "delivery", + "permission": "ALLOW" + } + ] +} \ No newline at end of file diff --git a/modules/route/back/models/vehicle.json b/modules/route/back/models/vehicle.json index c5b6eab5ba..dbf78f7d12 100644 --- a/modules/route/back/models/vehicle.json +++ b/modules/route/back/models/vehicle.json @@ -93,6 +93,12 @@ "type": "belongsTo", "model": "FuelType", "foreignKey": "fuelTypeFk" + }, + "ppe": { + "type": "hasOne", + "model": "Ppe", + "foreignKey": "id", + "property": "ppeFk" } }, "scope": { From 68e42206c8f2054084112505871e2596f5a1f345 Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 30 Dec 2024 17:31:56 +0100 Subject: [PATCH 21/84] feat: refs #7119 enhance vehicle filter method with additional parameters and improve SQL query structure --- modules/route/back/methods/vehicle/filter.js | 133 +++++++++++-------- modules/route/back/models/vehicle.json | 3 + 2 files changed, 79 insertions(+), 57 deletions(-) diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index a6cec02940..bc2186e3a6 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -1,5 +1,8 @@ +const {ParameterizedSQL} = require('loopback-connector'); +const {buildFilter, mergeFilters} = require('vn-loopback/util/filter'); + module.exports = Self => { - Self.remoteMethod('filter', { + Self.remoteMethodCtx('filter', { description: 'Find all instances of the model matched by filter from the data source.', accessType: 'READ', accepts: [{ @@ -42,6 +45,9 @@ module.exports = Self => { }, { arg: 'isKmTruckRate', type: 'boolean' + }, { + arg: 'vehicleStateFk', + type: 'number' }], returns: { type: ['object'], @@ -53,66 +59,79 @@ module.exports = Self => { } }); - Self.filter = async(filter, search, id, description, companyFk, tradeMark, numberPlate, warehouseFk, chassis, leasing, countryCodeFk, isKmTruckRate, options) => { + Self.filter = async(ctx, filter, options) => { + const conn = Self.dataSource.connector; const myOptions = {}; - const myWhere = {}; - const {limit, order, skip, where} = filter; if (typeof options == 'object') Object.assign(myOptions, options); - if (search) myWhere.or = [{id: search}, {numberPlate: {like: `%${search}%`}}]; - if (id) myWhere.id = id; - if (description) myWhere.description = {like: `%${description}%`}; - if (companyFk) myWhere.companyFk = companyFk; - if (tradeMark) myWhere.tradeMark = {like: `%${tradeMark}%`}; - if (numberPlate) myWhere.numberPlate = {like: `%${numberPlate}%`}; - if (warehouseFk) myWhere.warehouseFk = warehouseFk; - if (chassis) myWhere.chassis = {like: `%${chassis}%`}; - if (leasing) myWhere.leasing = {like: `%${leasing}%`}; - if (countryCodeFk) myWhere.countryCodeFk = countryCodeFk; - if (isKmTruckRate) myWhere.isKmTruckRate = isKmTruckRate; - - Object.assign(where || {}, myWhere); - - const myFilter = { - fields: ['id', 'numberPlate', 'tradeMark', 'model', 'm3', 'description', 'isActive', 'warehouseFk', 'companyFk', 'countryCodeFk', 'chassis', 'leasing', 'isKmTruckRate'], - include: [ - { - relation: 'warehouse', - scope: { - fields: ['id', 'name'] - } - }, - { - relation: 'company', - scope: { - fields: ['id', 'code'] - } - }, - { - relation: 'event', - scope: { - fields: ['vehicleFk', 'vehicleStateFk'], - include: { - relation: 'state', - scope: { - fields: ['id', 'state'] - } - }, - order: ['started DESC'], - limit: 1 - } - }, - ], - where: myWhere, - order, - limit, - skip, - }; - - return Self.find(myFilter, myOptions).map(v => { - v.__data.event = v.event()[0]; - return v; + const where = buildFilter(ctx.args, (param, value) => { + switch (param) { + case 'search': + return {or: [{'v.id': value}, {numberPlate: {like: `%${value}%`}}]}; + case 'id': + return {id: value}; + case 'description': + return {description: {like: `%${value}%`}}; + case 'companyFk': + return {companyFk: value}; + case 'tradeMark': + return {tradeMark: {like: `%${value}%`}}; + case 'numberPlate': + return {numberPlate: {like: `%${value}%`}}; + case 'warehouseFk': + return {warehouseFk: value}; + case 'chassis': + return {chassis: {like: `%${value}%`}}; + case 'leasing': + return {leasing: {like: `%${value}%`}}; + case 'countryCodeFk': + return {countryCodeFk: value}; + case 'isKmTruckRate': + return {isKmTruckRate: value}; + case 'vehicleStateFk': + return {vehicleStateFk: value}; + } }); + + const myFilter = mergeFilters(filter, {where}); + + const stmt = new ParameterizedSQL(` + SELECT v.id, + v.numberPlate, + v.tradeMark, + v.model, + v.m3, + v.description, + v.isActive, + v.countryCodeFk, + v.chassis, + v.leasing, + v.isKmTruckRate, + w.name as warehouse, + c.code as company, + sub.state + FROM vehicle v + LEFT JOIN warehouse w ON w.id = v.warehouseFk + LEFT JOIN company c ON c.id = v.companyFk + LEFT JOIN ( + SELECT e.vehicleFk, + e.vehicleStateFk, + s.state, + ROW_NUMBER() OVER (PARTITION BY e.vehicleFk ORDER BY e.started DESC) as rn + FROM vehicleEvent e + LEFT JOIN vehicleState s ON e.vehicleStateFk = s.id + ) sub ON sub.vehicleFk = v.id AND sub.rn = 1 + ` + ); + + const sqlWhere = conn.makeWhere(myFilter.where); + stmt.merge(sqlWhere); + stmt.merge(conn.makePagination(myFilter)); + + const sql = ParameterizedSQL.join([stmt], ';'); + const result = await conn.executeStmt(sql, myOptions); + + return result; }; }; diff --git a/modules/route/back/models/vehicle.json b/modules/route/back/models/vehicle.json index dbf78f7d12..9269cdebbc 100644 --- a/modules/route/back/models/vehicle.json +++ b/modules/route/back/models/vehicle.json @@ -50,6 +50,9 @@ }, "vin": { "type": "string" + }, + "ppeFk": { + "type": "number" } }, "relations": { From bc495ed51e947e45072610e37ca2a6f18aedcca4 Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 30 Dec 2024 17:55:27 +0100 Subject: [PATCH 22/84] feat: refs #7119 add VehicleNotes model and update vehicle filter SQL query --- modules/route/back/methods/vehicle/filter.js | 2 +- modules/route/back/model-config.json | 3 ++ modules/route/back/models/vehicle-notes.json | 35 ++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 modules/route/back/models/vehicle-notes.json diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index bc2186e3a6..17c132c2c8 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -118,7 +118,7 @@ module.exports = Self => { SELECT e.vehicleFk, e.vehicleStateFk, s.state, - ROW_NUMBER() OVER (PARTITION BY e.vehicleFk ORDER BY e.started DESC) as rn + ROW_NUMBER() OVER (PARTITION BY e.vehicleFk ORDER BY e.started DESC) rn FROM vehicleEvent e LEFT JOIN vehicleState s ON e.vehicleStateFk = s.id ) sub ON sub.vehicleFk = v.id AND sub.rn = 1 diff --git a/modules/route/back/model-config.json b/modules/route/back/model-config.json index c8c67a361e..07054061fd 100644 --- a/modules/route/back/model-config.json +++ b/modules/route/back/model-config.json @@ -47,6 +47,9 @@ "VehicleEvent": { "dataSource": "vn" }, + "VehicleNotes": { + "dataSource": "vn" + }, "VehicleState": { "dataSource": "vn" }, diff --git a/modules/route/back/models/vehicle-notes.json b/modules/route/back/models/vehicle-notes.json new file mode 100644 index 0000000000..922f9b14b9 --- /dev/null +++ b/modules/route/back/models/vehicle-notes.json @@ -0,0 +1,35 @@ +{ + "name": "VehicleNotes", + "base": "VnModel", + "options": { + "mysql": { + "table": "vehicleNotes" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "vehicleFk": { + "type": "number" + }, + "created": { + "type": "date" + }, + "note": { + "type": "string" + }, + "userFk": { + "type": "number" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "delivery", + "permission": "ALLOW" + } + ] +} \ No newline at end of file From 8f99b145100964de144469be2f820e8d723ebc5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 9 Jan 2025 08:43:14 +0100 Subject: [PATCH 23/84] fix: refs #7965 UnifyProblems --- .../vn/procedures/sale_getProblems.sql | 43 +++++++++-------- .../vn/procedures/ticket_getProblems.sql | 48 +++++++++---------- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/db/routines/vn/procedures/sale_getProblems.sql b/db/routines/vn/procedures/sale_getProblems.sql index ce6117ec5f..483cacb1ff 100644 --- a/db/routines/vn/procedures/sale_getProblems.sql +++ b/db/routines/vn/procedures/sale_getProblems.sql @@ -6,6 +6,7 @@ BEGIN /** * Calcula los problemas para un conjunto de sale * + * @param vIsTodayRelative Indica si se calcula el disponible como si todo saliera hoy * @table tmp.sale(saleFk) Identificadores de los sale a calcular * @return tmp.saleProblems */ @@ -45,7 +46,7 @@ BEGIN JOIN parking p ON p.id = sh.parkingFk JOIN sector s ON s.id = p.sectorFk GROUP BY ish.itemFk, s.warehouseFk; - + -- Disponible, faltas, inventario y retrasos OPEN vCursor; l: LOOP @@ -55,11 +56,11 @@ BEGIN IF vDone THEN LEAVE l; END IF; - + -- Disponible: no va a haber suficiente producto para preparar todos los pedidos CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouseFk, vDate); - - -- Faltas: visible, disponible y ubicado son menores que la cantidad vendida + + -- Faltas: visible, disponible y ubicado son menores que la cantidad vendida CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouseFk); INSERT INTO tmp.saleProblems(saleFk, hasItemShortage) @@ -69,16 +70,16 @@ BEGIN JOIN ticket t ON t.id = s.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 itemCategory ic ON ic.id = it.categoryFk LEFT JOIN cache.visible v ON v.item_id = i.id AND v.calc_id = vVisibleCache LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache LEFT JOIN tItemShelving tis ON tis.itemFk = i.id - AND tis.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible, 0) < s.quantity - AND IFNULL(av.available, 0) < s.quantity - AND IFNULL(tis.visible, 0) < s.quantity + AND tis.warehouseFk = t.warehouseFk + WHERE (v.visible < s.quantity AND v.visible IS NOT NULL) + AND (av.available < s.quantity AND av.available IS NOT NULL) + AND (tis.visible < s.quantity AND tis.visible IS NOT NULL) AND NOT s.isPicked AND NOT s.reserved AND ic.merchandise @@ -87,7 +88,7 @@ BEGIN AND util.VN_CURDATE() = vDate AND t.warehouseFk = vWarehouseFk GROUP BY s.id; - + -- Inventario: Visible suficiente, pero ubicado menor a la cantidad vendida INSERT INTO tmp.saleProblems(saleFk, hasItemLost) SELECT s.id, TRUE @@ -100,9 +101,9 @@ BEGIN LEFT JOIN cache.visible v ON v.item_id = s.itemFk AND v.calc_id = vVisibleCache LEFT JOIN tItemShelving tis ON tis.itemFk = i.id - AND tis.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible, 0) >= s.quantity - AND IFNULL(tis.visible, 0) < s.quantity + AND tis.warehouseFk = t.warehouseFk + WHERE (v.visible >= s.quantity AND v.visible IS NOT NULL) + AND (tis.visible < s.quantity AND tis.visible IS NOT NULL) AND s.quantity > 0 AND NOT s.isPicked AND NOT s.reserved @@ -116,7 +117,7 @@ BEGIN -- Retraso: Disponible suficiente, pero no visible ni ubicado INSERT INTO tmp.saleProblems(saleFk, hasItemDelay) - SELECT s.id, TRUE + SELECT s.id, TRUE FROM tmp.sale ts JOIN sale s ON s.id = ts.saleFk JOIN ticket t ON t.id = s.ticketFk @@ -128,10 +129,10 @@ BEGIN LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache LEFT JOIN tItemShelving tis ON tis.itemFk = i.id - AND tis.warehouseFk = t.warehouseFk - WHERE IFNULL(v.visible, 0) < s.quantity - AND IFNULL(av.available, 0) >= s.quantity - AND IFNULL(tis.visible, 0) < s.quantity + AND tis.warehouseFk = t.warehouseFk + WHERE (v.visible < s.quantity AND v.visible IS NOT NULL) + AND (av.available < s.quantity AND av.available IS NOT NULL) + AND (tis.visible < s.quantity AND tis.visible IS NOT NULL) AND s.quantity > 0 AND NOT s.isPicked AND NOT s.reserved @@ -141,9 +142,9 @@ BEGIN AND util.VN_CURDATE() = vDate AND t.warehouseFk = vWarehouseFk GROUP BY s.id - ON DUPLICATE KEY UPDATE hasItemDelay = TRUE; + ON DUPLICATE KEY UPDATE hasItemDelay = TRUE; - -- Redondeo: cantidad incorrecta con respecto al grouping + -- Redondeo: cantidad incorrecta con respecto al grouping CALL buy_getUltimate(NULL, vWarehouseFk, vDate); INSERT INTO tmp.saleProblems(saleFk, hasRounding) @@ -155,7 +156,7 @@ BEGIN 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`) + WHERE MOD(s.quantity, b.`grouping`) GROUP BY s.id ON DUPLICATE KEY UPDATE hasRounding = TRUE; diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index fe77ed57bd..1094a9d491 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -6,6 +6,7 @@ BEGIN /** * Calcula los problemas para un conjunto de tickets. * + * @param vIsTodayRelative Indica si se calcula el disponible como si todo saliera hoy * @table tmp.ticket(ticketFk) Identificadores de los tickets a calcular * @return tmp.ticketProblems, tmp.saleProblems */ @@ -13,14 +14,14 @@ BEGIN saleFk INT(11), PRIMARY KEY (saleFk) ) ENGINE = MEMORY - SELECT DISTINCT s.id saleFk + SELECT DISTINCT s.id saleFk FROM tmp.ticket tt - JOIN ticket t ON t.id = tt.ticketFk + JOIN ticket t ON t.id = tt.ticketFk JOIN sale s ON s.ticketFk = t.id WHERE t.shipped BETWEEN util.VN_CURDATE() AND util.dayEnd(util.VN_CURDATE() + INTERVAL IF(vIsTodayRelative, 9.9, 1.9) DAY) GROUP BY s.id; - + CALL sale_getProblems(vIsTodayRelative); CREATE OR REPLACE TEMPORARY TABLE tmp.ticketProblems ( @@ -57,7 +58,7 @@ BEGIN FROM tmp.saleProblems sp JOIN vn.sale s ON s.id = sp.saleFk WHERE sp.hasRounding - GROUP BY s.ticketFk + GROUP BY s.ticketFk ), hasItemDelay AS( SELECT s.ticketFk FROM tmp.saleProblems sp @@ -71,23 +72,22 @@ BEGIN WHERE FIND_IN_SET('hasComponentLack', s.problem) GROUP BY s.ticketFk )SELECT tt.ticketFk, - IF(FIND_IN_SET('isFreezed', t.problem), TRUE, FALSE) isFreezed, + FIND_IN_SET('isFreezed', t.problem) isFreezed, t.risk, - IF(FIND_IN_SET('hasRisk', t.problem), TRUE, FALSE) hasRisk, - IF(FIND_IN_SET('hasHighRisk', t.problem), TRUE, FALSE) hasHighRisk, - IF(FIND_IN_SET('hasTicketRequest', t.problem), TRUE, FALSE) hasTicketRequest, - IF(FIND_IN_SET('isTaxDataChecked', t.problem), TRUE, FALSE) isTaxDataChecked, - IF(FIND_IN_SET('isTooLittle', t.problem) - AND util.VN_NOW() < (util.VN_CURDATE() + - INTERVAL HOUR(zc.`hour`) HOUR) + - INTERVAL MINUTE(zc.`hour`) MINUTE, - TRUE, FALSE) isTooLittle, - IF(c.businessTypeFk = 'VIP', TRUE, FALSE) isVip, - IF(his.ticketFk IS NULL, FALSE, TRUE) hasItemShortage, - IF(hid.ticketFk IS NULL, FALSE, TRUE) hasItemDelay, - IF(hil.ticketFk IS NULL, FALSE, TRUE) hasItemLost, - IF(hcl.ticketFk IS NULL, FALSE, TRUE) hasComponentLack, - IF(hr.ticketFk IS NULL, FALSE, TRUE) hasRounding, + FIND_IN_SET('hasRisk', t.problem) hasRisk, + FIND_IN_SET('hasHighRisk', t.problem) hasHighRisk, + FIND_IN_SET('hasTicketRequest', t.problem) hasTicketRequest, + FIND_IN_SET('isTaxDataChecked', t.problem) isTaxDataChecked, + FIND_IN_SET('isTooLittle', t.problem) + AND util.VN_NOW() < (util.VN_CURDATE() + + INTERVAL HOUR(zc.`hour`) HOUR) + + INTERVAL MINUTE(zc.`hour`) MINUTE isTooLittle, + c.businessTypeFk = 'VIP' isVip, + NOT (his.ticketFk IS NULL) hasItemShortage, + NOT (hid.ticketFk IS NULL) hasItemDelay, + NOT (hil.ticketFk IS NULL) hasItemLost, + NOT (hcl.ticketFk IS NULL) hasComponentLack, + NOT (hr.ticketFk IS NULL) hasRounding, 0 totalProblems FROM tmp.ticket tt JOIN vn.ticket t ON t.id = tt.ticketFk @@ -100,12 +100,12 @@ BEGIN LEFT JOIN vn.zoneClosure zc ON zc.zoneFk = t.zoneFk AND zc.dated = util.VN_CURDATE() GROUP BY t.id; - + UPDATE tmp.ticketProblems - SET totalProblems = isFreezed + hasHighRisk + hasTicketRequest + - isTaxDataChecked + hasComponentLack + hasItemDelay + + SET totalProblems = isFreezed + hasHighRisk + hasTicketRequest + + isTaxDataChecked + hasComponentLack + hasItemDelay + isTooLittle + hasItemLost + hasRounding + hasItemShortage + isVip; - + DROP TEMPORARY TABLE tmp.sale; END$$ DELIMITER ; From 638a8e344dbd8843be3db6ea842b2b70d552c506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 9 Jan 2025 10:34:49 +0100 Subject: [PATCH 24/84] fix: refs #7965 UnifyProblems --- db/routines/vn/procedures/sale_getProblems.sql | 10 ++++++++++ db/routines/vn/procedures/ticket_getProblems.sql | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/db/routines/vn/procedures/sale_getProblems.sql b/db/routines/vn/procedures/sale_getProblems.sql index 483cacb1ff..7f7050897e 100644 --- a/db/routines/vn/procedures/sale_getProblems.sql +++ b/db/routines/vn/procedures/sale_getProblems.sql @@ -30,6 +30,7 @@ BEGIN saleFk INT(11), hasItemShortage BOOL DEFAULT FALSE, hasItemLost BOOL DEFAULT FALSE, + hasComponentLack BOOL DEFAULT FALSE, hasItemDelay BOOL DEFAULT FALSE, hasRounding BOOL DEFAULT FALSE, PRIMARY KEY (saleFk) @@ -115,6 +116,15 @@ BEGIN GROUP BY s.id ON DUPLICATE KEY UPDATE hasItemLost = TRUE; + -- Componentes: Algún componente obligatorio no se ha calcualdo + INSERT INTO tmp.saleProblems(saleFk, hasComponentLack) + SELECT s.id, TRUE + FROM tmp.sale ts + JOIN sale s ON s.id = ts.saleFk + WHERE FIND_IN_SET('hasComponentLack', s.problem) + GROUP BY s.id + ON DUPLICATE KEY UPDATE hasComponentLack = TRUE; + -- Retraso: Disponible suficiente, pero no visible ni ubicado INSERT INTO tmp.saleProblems(saleFk, hasItemDelay) SELECT s.id, TRUE diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index 1094a9d491..744db46410 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -69,7 +69,7 @@ BEGIN SELECT s.ticketFk FROM tmp.saleProblems sp JOIN vn.sale s ON s.id = sp.saleFk - WHERE FIND_IN_SET('hasComponentLack', s.problem) + WHERE sp.hasComponentLack GROUP BY s.ticketFk )SELECT tt.ticketFk, FIND_IN_SET('isFreezed', t.problem) isFreezed, From 09b4b2cf1b29d3b31390608cba4aea7ccabe1fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 9 Jan 2025 11:52:30 +0100 Subject: [PATCH 25/84] fix: refs #7965 UnifyProblems --- db/routines/vn/procedures/ticket_getProblems.sql | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index 744db46410..4144570f74 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -72,13 +72,13 @@ BEGIN WHERE sp.hasComponentLack GROUP BY s.ticketFk )SELECT tt.ticketFk, - FIND_IN_SET('isFreezed', t.problem) isFreezed, + FIND_IN_SET('isFreezed', t.problem) > 0 isFreezed, t.risk, - FIND_IN_SET('hasRisk', t.problem) hasRisk, - FIND_IN_SET('hasHighRisk', t.problem) hasHighRisk, - FIND_IN_SET('hasTicketRequest', t.problem) hasTicketRequest, - FIND_IN_SET('isTaxDataChecked', t.problem) isTaxDataChecked, - FIND_IN_SET('isTooLittle', t.problem) + FIND_IN_SET('hasRisk', t.problem) > 0 hasRisk, + FIND_IN_SET('hasHighRisk', t.problem) > 0 hasHighRisk, + FIND_IN_SET('hasTicketRequest', t.problem) > 0 hasTicketRequest, + FIND_IN_SET('isTaxDataChecked', t.problem) > 0 isTaxDataChecked, + FIND_IN_SET('isTooLittle', t.problem) > 0 AND util.VN_NOW() < (util.VN_CURDATE() + INTERVAL HOUR(zc.`hour`) HOUR) + INTERVAL MINUTE(zc.`hour`) MINUTE isTooLittle, From 2d8bda2b56af541102a30453eed9ead691b4af12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 9 Jan 2025 15:46:04 +0100 Subject: [PATCH 26/84] fix: refs #7965 UnifyProblems --- .../vn/procedures/sale_getProblems.sql | 36 +++++++++---------- .../vn/procedures/ticket_getProblems.sql | 2 -- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/db/routines/vn/procedures/sale_getProblems.sql b/db/routines/vn/procedures/sale_getProblems.sql index 7f7050897e..ca81660b8d 100644 --- a/db/routines/vn/procedures/sale_getProblems.sql +++ b/db/routines/vn/procedures/sale_getProblems.sql @@ -48,6 +48,14 @@ BEGIN JOIN sector s ON s.id = p.sectorFk GROUP BY ish.itemFk, s.warehouseFk; + -- Componentes: Algún componente obligatorio no se ha calcualdo + INSERT INTO tmp.saleProblems(saleFk, hasComponentLack) + SELECT s.id, TRUE + FROM tmp.sale ts + JOIN sale s ON s.id = ts.saleFk + WHERE FIND_IN_SET('hasComponentLack', s.problem) + GROUP BY s.id; + -- Disponible, faltas, inventario y retrasos OPEN vCursor; l: LOOP @@ -78,9 +86,9 @@ BEGIN AND av.calc_id = vAvailableCache LEFT JOIN tItemShelving tis ON tis.itemFk = i.id AND tis.warehouseFk = t.warehouseFk - WHERE (v.visible < s.quantity AND v.visible IS NOT NULL) - AND (av.available < s.quantity AND av.available IS NOT NULL) - AND (tis.visible < s.quantity AND tis.visible IS NOT NULL) + WHERE (s.quantity > v.visible OR (s.quantity > 0 AND v.visible IS NULL)) + AND (av.available < 0 OR av.available IS NULL) + AND (s.quantity > tis.visible OR tis.visible IS NULL) AND NOT s.isPicked AND NOT s.reserved AND ic.merchandise @@ -88,7 +96,8 @@ BEGIN AND NOT i.generic AND util.VN_CURDATE() = vDate AND t.warehouseFk = vWarehouseFk - GROUP BY s.id; + GROUP BY s.id + ON DUPLICATE KEY UPDATE hasItemShortage = TRUE; -- Inventario: Visible suficiente, pero ubicado menor a la cantidad vendida INSERT INTO tmp.saleProblems(saleFk, hasItemLost) @@ -103,8 +112,8 @@ BEGIN AND v.calc_id = vVisibleCache LEFT JOIN tItemShelving tis ON tis.itemFk = i.id AND tis.warehouseFk = t.warehouseFk - WHERE (v.visible >= s.quantity AND v.visible IS NOT NULL) - AND (tis.visible < s.quantity AND tis.visible IS NOT NULL) + WHERE (v.visible >= s.quantity OR v.visible IS NULL) + AND (s.quantity > tis.visible AND tis.visible IS NOT NULL) AND s.quantity > 0 AND NOT s.isPicked AND NOT s.reserved @@ -116,15 +125,6 @@ BEGIN GROUP BY s.id ON DUPLICATE KEY UPDATE hasItemLost = TRUE; - -- Componentes: Algún componente obligatorio no se ha calcualdo - INSERT INTO tmp.saleProblems(saleFk, hasComponentLack) - SELECT s.id, TRUE - FROM tmp.sale ts - JOIN sale s ON s.id = ts.saleFk - WHERE FIND_IN_SET('hasComponentLack', s.problem) - GROUP BY s.id - ON DUPLICATE KEY UPDATE hasComponentLack = TRUE; - -- Retraso: Disponible suficiente, pero no visible ni ubicado INSERT INTO tmp.saleProblems(saleFk, hasItemDelay) SELECT s.id, TRUE @@ -140,9 +140,9 @@ BEGIN AND av.calc_id = vAvailableCache LEFT JOIN tItemShelving tis ON tis.itemFk = i.id AND tis.warehouseFk = t.warehouseFk - WHERE (v.visible < s.quantity AND v.visible IS NOT NULL) - AND (av.available < s.quantity AND av.available IS NOT NULL) - AND (tis.visible < s.quantity AND tis.visible IS NOT NULL) + WHERE (s.quantity > v.visible AND v.visible IS NULL) + AND (av.available >= 0 OR av.available IS NULL) + AND (s.quantity > tis.visible AND tis.visible IS NOT NULL) AND s.quantity > 0 AND NOT s.isPicked AND NOT s.reserved diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index 4144570f74..a65413f5f8 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -18,8 +18,6 @@ BEGIN FROM tmp.ticket tt JOIN ticket t ON t.id = tt.ticketFk JOIN sale s ON s.ticketFk = t.id - WHERE t.shipped BETWEEN util.VN_CURDATE() - AND util.dayEnd(util.VN_CURDATE() + INTERVAL IF(vIsTodayRelative, 9.9, 1.9) DAY) GROUP BY s.id; CALL sale_getProblems(vIsTodayRelative); From a167e7fada35749dbdf28bcd2b6f7076b9c9e079 Mon Sep 17 00:00:00 2001 From: jtubau Date: Fri, 10 Jan 2025 13:42:29 +0100 Subject: [PATCH 27/84] feat: refs #8304 add ACL entry for WorkerDms with high privileges --- db/versions/11404-azureAnthurium/00-firstScript.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 db/versions/11404-azureAnthurium/00-firstScript.sql diff --git a/db/versions/11404-azureAnthurium/00-firstScript.sql b/db/versions/11404-azureAnthurium/00-firstScript.sql new file mode 100644 index 0000000000..7a4dfe9bcb --- /dev/null +++ b/db/versions/11404-azureAnthurium/00-firstScript.sql @@ -0,0 +1,2 @@ +INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) +VALUES('WorkerDms', 'hasHighPrivs', 'READ', 'ALLOW', 'ROLE', 'hr'); \ No newline at end of file From 0e8d9137edfdcffebf73f84672c1d58ccd3a10a5 Mon Sep 17 00:00:00 2001 From: jtubau Date: Fri, 10 Jan 2025 13:48:03 +0100 Subject: [PATCH 28/84] feat: refs #8304 add privilege check for WorkerDms filter method --- modules/worker/back/methods/worker-dms/filter.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/worker/back/methods/worker-dms/filter.js b/modules/worker/back/methods/worker-dms/filter.js index 240a905d28..a6e5d67e76 100644 --- a/modules/worker/back/methods/worker-dms/filter.js +++ b/modules/worker/back/methods/worker-dms/filter.js @@ -1,5 +1,6 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const {mergeFilters, mergeWhere} = require('vn-loopback/util/filter'); +const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('filter', { @@ -33,7 +34,10 @@ module.exports = Self => { const conn = Self.dataSource.connector; const userId = ctx.req.accessToken.userId; const models = Self.app.models; + const hasPrivs = await models.ACL.checkAccessAcl(ctx, 'WorkerDms', 'hasHighPrivs', '*'); + if (!hasPrivs && userId !== id) + throw new UserError('You don\'t have enough privileges'); // Get ids alloweds const account = await models.VnUser.findById(userId); From 477646ba311893f8a22e47785fdd5dbd7fff597e Mon Sep 17 00:00:00 2001 From: guillermo Date: Mon, 20 Jan 2025 14:43:14 +0100 Subject: [PATCH 29/84] feat: refs #8227 Roadmap changes --- .../procedures/vehicle_checkNumberPlate.sql | 27 ++++++++++++++----- .../vn/triggers/roadmap_beforeInsert.sql | 2 ++ .../vn/triggers/roadmap_beforeUpdate.sql | 2 ++ .../11416-goldenTulip/00-firstScript.sql | 5 ++++ 4 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 db/versions/11416-goldenTulip/00-firstScript.sql diff --git a/db/routines/vn/procedures/vehicle_checkNumberPlate.sql b/db/routines/vn/procedures/vehicle_checkNumberPlate.sql index cbbcbec639..613dda3682 100644 --- a/db/routines/vn/procedures/vehicle_checkNumberPlate.sql +++ b/db/routines/vn/procedures/vehicle_checkNumberPlate.sql @@ -1,17 +1,30 @@ DELIMITER $$ -CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`vehicle_checkNumberPlate`(vNumberPlate VARCHAR(10), vCountryCodeFk VARCHAR(2)) +CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`vehicle_checkNumberPlate`( + vNumberPlate VARCHAR(10), + vCountryCodeFk VARCHAR(2) +) BEGIN /** - * Comprueba si la matricula pasada tiene el formato correcto dependiendo del pais del vehiculo + * Comprueba si la matricula pasada tiene el formato + * correcto dependiendo del pais del vehiculo. + * + * @param vNumberPlate Número de matricula + * @param vCountryCodeFk Código de pais */ DECLARE vRegex VARCHAR(45); - SELECT vp.regex INTO vRegex - FROM vehiclePlateRegex vp - WHERE vp.countryCodeFk = vCountryCodeFk; - + IF vCountryCodeFk IS NULL THEN + SET vRegex = '^[A-Z0-9 -]{6,12}$'; + ELSE + SELECT regex INTO vRegex + FROM vehiclePlateRegex + WHERE countryCodeFk = vCountryCodeFk; + END IF; + IF NOT vNumberPlate REGEXP BINARY (vRegex)THEN - CALL util.throw(CONCAT('Error: la matricula ', vNumberPlate, ' no es valida para ',vCountryCodeFk)); + CALL util.throw(CONCAT('La matricula ', vNumberPlate, + ' no es valida', IF(vCountryCodeFk IS NOT NULL, + CONCAT(' para ', vCountryCodeFk), ''))); END IF; END$$ DELIMITER ; diff --git a/db/routines/vn/triggers/roadmap_beforeInsert.sql b/db/routines/vn/triggers/roadmap_beforeInsert.sql index 2f9481140a..0a4386e633 100644 --- a/db/routines/vn/triggers/roadmap_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmap_beforeInsert.sql @@ -3,6 +3,8 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_beforeInsert` BEFORE INSERT ON `roadmap` FOR EACH ROW BEGIN + CALL vehicle_checkNumberPlate(NEW.tractorPlate, NULL); + CALL vehicle_checkNumberPlate(NEW.trailerPlate, NULL); IF NEW.driver1Fk IS NOT NULL THEN SET NEW.driverName = (SELECT firstName FROM worker WHERE id = NEW.driver1Fk); ELSE diff --git a/db/routines/vn/triggers/roadmap_beforeUpdate.sql b/db/routines/vn/triggers/roadmap_beforeUpdate.sql index a2a02e96a5..b381854ed5 100644 --- a/db/routines/vn/triggers/roadmap_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmap_beforeUpdate.sql @@ -3,6 +3,8 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_beforeUpdate` BEFORE UPDATE ON `roadmap` FOR EACH ROW BEGIN + CALL vehicle_checkNumberPlate(NEW.tractorPlate, NULL); + CALL vehicle_checkNumberPlate(NEW.trailerPlate, NULL); IF NEW.driver1Fk IS NOT NULL THEN SET NEW.driverName = (SELECT firstName FROM worker WHERE id = NEW.driver1Fk); ELSE diff --git a/db/versions/11416-goldenTulip/00-firstScript.sql b/db/versions/11416-goldenTulip/00-firstScript.sql new file mode 100644 index 0000000000..9b89fcfa6f --- /dev/null +++ b/db/versions/11416-goldenTulip/00-firstScript.sql @@ -0,0 +1,5 @@ +ALTER TABLE vn.roadmap + MODIFY COLUMN m3 int(10) unsigned DEFAULT NULL NULL COMMENT 'Capacidad máxima del remolque'; +ALTER TABLE vn.route + ADD roadmapStopFk int(11) NULL, + ADD CONSTRAINT route_roadmapStop_FK FOREIGN KEY (roadmapStopFk) REFERENCES vn.roadmapStop(id) ON DELETE RESTRICT ON UPDATE CASCADE; From 946d08e5432a34e0259ac0fa01e90c5da76780c7 Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 20 Jan 2025 17:29:18 +0100 Subject: [PATCH 30/84] feat: refs #7119 update ACLs and remove unused models for vehicle management --- .../11394-brownAsparagus/00-firstScript.sql | 2 + modules/route/back/methods/vehicle/filter.js | 10 ++-- modules/route/back/model-config.json | 6 --- modules/route/back/models/fuel-type.json | 2 +- modules/route/back/models/ppe.json | 10 +--- modules/route/back/models/vehicle-event.json | 51 ------------------- modules/route/back/models/vehicle-notes.json | 35 ------------- modules/route/back/models/vehicle-state.json | 10 +--- 8 files changed, 9 insertions(+), 117 deletions(-) delete mode 100644 modules/route/back/models/vehicle-event.json delete mode 100644 modules/route/back/models/vehicle-notes.json diff --git a/db/versions/11394-brownAsparagus/00-firstScript.sql b/db/versions/11394-brownAsparagus/00-firstScript.sql index d02482efdd..4d6cedb69b 100644 --- a/db/versions/11394-brownAsparagus/00-firstScript.sql +++ b/db/versions/11394-brownAsparagus/00-firstScript.sql @@ -2,4 +2,6 @@ INSERT INTO salix.ACL (model, property, accessType, permission, principalType, p VALUES ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'), ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery'), + ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery' ), + ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery' ), ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss'); \ No newline at end of file diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index 17c132c2c8..ea2a94281a 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -92,9 +92,9 @@ module.exports = Self => { case 'vehicleStateFk': return {vehicleStateFk: value}; } - }); + }) || {}; - const myFilter = mergeFilters(filter, {where}); + const myFilter = mergeFilters(filter, {where: {...where, isActive: true}}); const stmt = new ParameterizedSQL(` SELECT v.id, @@ -122,16 +122,14 @@ module.exports = Self => { FROM vehicleEvent e LEFT JOIN vehicleState s ON e.vehicleStateFk = s.id ) sub ON sub.vehicleFk = v.id AND sub.rn = 1 - ` - ); + `); const sqlWhere = conn.makeWhere(myFilter.where); stmt.merge(sqlWhere); stmt.merge(conn.makePagination(myFilter)); const sql = ParameterizedSQL.join([stmt], ';'); - const result = await conn.executeStmt(sql, myOptions); - return result; + return conn.executeStmt(sql, myOptions); }; }; diff --git a/modules/route/back/model-config.json b/modules/route/back/model-config.json index 07054061fd..16e6d69677 100644 --- a/modules/route/back/model-config.json +++ b/modules/route/back/model-config.json @@ -44,12 +44,6 @@ "Vehicle": { "dataSource": "vn" }, - "VehicleEvent": { - "dataSource": "vn" - }, - "VehicleNotes": { - "dataSource": "vn" - }, "VehicleState": { "dataSource": "vn" }, diff --git a/modules/route/back/models/fuel-type.json b/modules/route/back/models/fuel-type.json index c7f96b3253..d426148371 100644 --- a/modules/route/back/models/fuel-type.json +++ b/modules/route/back/models/fuel-type.json @@ -23,7 +23,7 @@ { "accessType": "READ", "principalType": "ROLE", - "principalId": "employee", + "principalId": "$everyone", "permission": "ALLOW" } ] diff --git a/modules/route/back/models/ppe.json b/modules/route/back/models/ppe.json index 7af5cb6844..0825d348ca 100644 --- a/modules/route/back/models/ppe.json +++ b/modules/route/back/models/ppe.json @@ -11,13 +11,5 @@ "type": "number", "id": true } - }, - "acls": [ - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "delivery", - "permission": "ALLOW" - } - ] + } } \ No newline at end of file diff --git a/modules/route/back/models/vehicle-event.json b/modules/route/back/models/vehicle-event.json deleted file mode 100644 index 324076723c..0000000000 --- a/modules/route/back/models/vehicle-event.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "VehicleEvent", - "base": "VnModel", - "options": { - "mysql": { - "table": "vehicleEvent" - } - }, - "properties": { - "id": { - "type": "number", - "id": true - }, - "started": { - "type": "date" - }, - "finished": { - "type": "date" - }, - "vehicleStateFk": { - "type": "number" - }, - "description": { - "type": "string" - }, - "vehicleFk": { - "type": "number" - }, - "userFk": { - "type": "number" - }, - "notified": { - "type": "date" - } - }, - "relations": { - "state": { - "type": "belongsTo", - "model": "VehicleState", - "foreignKey": "vehicleStateFk" - } - }, - "acls": [ - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - } - ] -} \ No newline at end of file diff --git a/modules/route/back/models/vehicle-notes.json b/modules/route/back/models/vehicle-notes.json deleted file mode 100644 index 922f9b14b9..0000000000 --- a/modules/route/back/models/vehicle-notes.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "VehicleNotes", - "base": "VnModel", - "options": { - "mysql": { - "table": "vehicleNotes" - } - }, - "properties": { - "id": { - "type": "number", - "id": true - }, - "vehicleFk": { - "type": "number" - }, - "created": { - "type": "date" - }, - "note": { - "type": "string" - }, - "userFk": { - "type": "number" - } - }, - "acls": [ - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "delivery", - "permission": "ALLOW" - } - ] -} \ No newline at end of file diff --git a/modules/route/back/models/vehicle-state.json b/modules/route/back/models/vehicle-state.json index 1f71333eb9..b53719f631 100644 --- a/modules/route/back/models/vehicle-state.json +++ b/modules/route/back/models/vehicle-state.json @@ -17,13 +17,5 @@ "hasToNotify": { "type": "number" } - }, - "acls": [ - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - } - ] + } } \ No newline at end of file From 3d2a7cfb6695e3243a7a926ac164f9f2392d104a Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 20 Jan 2025 18:05:33 +0100 Subject: [PATCH 31/84] feat: refs #7119 update ACLs for vehicle management and refine vehicle filter logic --- .../11394-brownAsparagus/00-firstScript.sql | 15 +++++++----- modules/route/back/methods/vehicle/filter.js | 2 +- modules/route/back/models/vehicle.json | 24 +++++++++---------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/db/versions/11394-brownAsparagus/00-firstScript.sql b/db/versions/11394-brownAsparagus/00-firstScript.sql index 4d6cedb69b..72fb6b13d1 100644 --- a/db/versions/11394-brownAsparagus/00-firstScript.sql +++ b/db/versions/11394-brownAsparagus/00-firstScript.sql @@ -1,7 +1,10 @@ INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) - VALUES ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'), - ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), - ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery'), - ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery' ), - ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery' ), - ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss'); \ No newline at end of file + VALUES ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', 'findById', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), + ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative' ), + ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative' ), + ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', '__get__active', 'READ', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index ea2a94281a..11cc4d82af 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -94,7 +94,7 @@ module.exports = Self => { } }) || {}; - const myFilter = mergeFilters(filter, {where: {...where, isActive: true}}); + const myFilter = mergeFilters(filter, {where}); const stmt = new ParameterizedSQL(` SELECT v.id, diff --git a/modules/route/back/models/vehicle.json b/modules/route/back/models/vehicle.json index 9269cdebbc..e6d58de99e 100644 --- a/modules/route/back/models/vehicle.json +++ b/modules/route/back/models/vehicle.json @@ -104,19 +104,17 @@ "property": "ppeFk" } }, - "scope": { - "where": { - "isActive": { - "neq": false + "scopes": { + "active": { + "fields": [ + "id", + "numberPlate" + ], + "where": { + "isActive": { + "neq": false + } } } - }, - "acls": [ - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - } - ] + } } \ No newline at end of file From 55a0a5bc9a317f46b22ec3d5ae19eecc8f4f8d5c Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 21 Jan 2025 11:52:09 +0100 Subject: [PATCH 32/84] feat: refs #7119 add delivery role permissions --- db/versions/11394-brownAsparagus/00-firstScript.sql | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/db/versions/11394-brownAsparagus/00-firstScript.sql b/db/versions/11394-brownAsparagus/00-firstScript.sql index 72fb6b13d1..77dfab7d34 100644 --- a/db/versions/11394-brownAsparagus/00-firstScript.sql +++ b/db/versions/11394-brownAsparagus/00-firstScript.sql @@ -1,10 +1,17 @@ INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) VALUES ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'), ('Vehicle', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery'), ('Vehicle', 'findById', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), - ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative' ), + ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery'), + ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery'), ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative' ), + ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery' ), ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), ('Vehicle', '__get__active', 'READ', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file From b20dee8382b896965cfd8bdbf0fb35d3305e3437 Mon Sep 17 00:00:00 2001 From: jtubau Date: Tue, 21 Jan 2025 12:28:34 +0100 Subject: [PATCH 33/84] feat: refs #8304 add notes field to business model --- modules/client/back/models/business.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/client/back/models/business.json b/modules/client/back/models/business.json index 58e989ae08..4168458425 100644 --- a/modules/client/back/models/business.json +++ b/modules/client/back/models/business.json @@ -13,7 +13,10 @@ }, "workcenterFk" : { "type": "number" - } + }, + "notes" : { + "type": "string" + } }, "relations": { "worker": { From 482fe77159f72144b3f733f7b86df44509586987 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 21 Jan 2025 14:03:50 +0100 Subject: [PATCH 34/84] feat: refs #8227 Roadmap changes --- db/dump/fixtures.before.sql | 4 ++-- db/routines/vn/triggers/roadmapStop_beforeInsert.sql | 3 +-- db/routines/vn/triggers/roadmapStop_beforeUpdate.sql | 3 +-- db/routines/vn/triggers/roadmap_beforeInsert.sql | 12 ++++++------ db/routines/vn/triggers/roadmap_beforeUpdate.sql | 12 ++++++------ db/versions/11416-goldenTulip/00-firstScript.sql | 8 ++++---- db/versions/11416-goldenTulip/01-firstScript.sql | 1 + db/versions/11416-goldenTulip/02-firstScript.sql | 4 ++++ 8 files changed, 25 insertions(+), 22 deletions(-) create mode 100644 db/versions/11416-goldenTulip/01-firstScript.sql create mode 100644 db/versions/11416-goldenTulip/02-firstScript.sql diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 590fe34b67..cc1a9fc6f1 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -2749,13 +2749,13 @@ INSERT INTO `vn`.`roadmapAddress` (`addressFk`) (3), (4); -INSERT INTO `vn`.`roadmap` (`id`, `name`, `tractorPlate`, `trailerPlate`, `phone`, `supplierFk`, `etd`, `observations`, `userFk`, `price`, `driverName`) +INSERT INTO `vn`.`roadmap` (`id`, `name`, `tractorPlate`, `trailerPlate`, `phone`, `supplierFk`, `etd`, `observations`, `editorFk`, `price`, `driverName`) VALUES (1, 'val-algemesi', '1234-BCD', '9876-BCD', '111111111', 1, util.VN_NOW(), 'this is test observation', 1, 15, 'Batman'), (2, 'alg-valencia', '2345-CDF', '8765-BCD', '111111111', 1, util.VN_NOW(), 'test observation', 1, 20, 'Robin'), (3, 'alz-algemesi', '3456-DFG', '7654-BCD', '222222222', 2, DATE_ADD(util.VN_NOW(), INTERVAL 2 DAY), 'observations...', 2, 25, 'Driverman'); -INSERT INTO `vn`.`roadmapStop` (`id`, `roadmapFk`, `addressFk`, `eta`, `description`, `userFk`) +INSERT INTO `vn`.`roadmapStop` (`id`, `roadmapFk`, `addressFk`, `eta`, `description`, `editorFk`) VALUES (1, 1, 1, DATE_ADD(util.VN_NOW(), INTERVAL 1 DAY), 'Best truck in fleet', 1), (2, 1, 2, DATE_ADD(util.VN_NOW(), INTERVAL '1 2' DAY_HOUR), 'Second truck in fleet', 1), diff --git a/db/routines/vn/triggers/roadmapStop_beforeInsert.sql b/db/routines/vn/triggers/roadmapStop_beforeInsert.sql index d71942feab..b87a52bdc8 100644 --- a/db/routines/vn/triggers/roadmapStop_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmapStop_beforeInsert.sql @@ -3,8 +3,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmapStop_beforeInser BEFORE INSERT ON `roadmapStop` FOR EACH ROW BEGIN - + SET NEW.editorFk = account.myUser_getId(); SET NEW.description = UCASE(NEW.description); - END$$ DELIMITER ; diff --git a/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql b/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql index c3cbf25976..ec4dbe5baa 100644 --- a/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql @@ -3,8 +3,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmapStop_beforeUpdat BEFORE UPDATE ON `roadmapStop` FOR EACH ROW BEGIN - + SET NEW.editorFk = account.myUser_getId(); SET NEW.description = UCASE(NEW.description); - END$$ DELIMITER ; diff --git a/db/routines/vn/triggers/roadmap_beforeInsert.sql b/db/routines/vn/triggers/roadmap_beforeInsert.sql index 0a4386e633..118653d44f 100644 --- a/db/routines/vn/triggers/roadmap_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmap_beforeInsert.sql @@ -3,12 +3,12 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_beforeInsert` BEFORE INSERT ON `roadmap` FOR EACH ROW BEGIN - CALL vehicle_checkNumberPlate(NEW.tractorPlate, NULL); - CALL vehicle_checkNumberPlate(NEW.trailerPlate, NULL); - IF NEW.driver1Fk IS NOT NULL THEN - SET NEW.driverName = (SELECT firstName FROM worker WHERE id = NEW.driver1Fk); - ELSE - SET NEW.driverName = NULL; + SET NEW.editorFk = account.myUser_getId(); + IF NEW.tractorPlate IS NOT NULL THEN + CALL vehicle_checkNumberPlate(NEW.tractorPlate, NULL); + END IF; + IF NEW.trailerPlate IS NOT NULL THEN + CALL vehicle_checkNumberPlate(NEW.trailerPlate, NULL); END IF; END$$ DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/triggers/roadmap_beforeUpdate.sql b/db/routines/vn/triggers/roadmap_beforeUpdate.sql index b381854ed5..a60b1e892e 100644 --- a/db/routines/vn/triggers/roadmap_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmap_beforeUpdate.sql @@ -3,12 +3,12 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_beforeUpdate` BEFORE UPDATE ON `roadmap` FOR EACH ROW BEGIN - CALL vehicle_checkNumberPlate(NEW.tractorPlate, NULL); - CALL vehicle_checkNumberPlate(NEW.trailerPlate, NULL); - IF NEW.driver1Fk IS NOT NULL THEN - SET NEW.driverName = (SELECT firstName FROM worker WHERE id = NEW.driver1Fk); - ELSE - SET NEW.driverName = NULL; + SET NEW.editorFk = account.myUser_getId(); + IF NEW.tractorPlate IS NOT NULL THEN + CALL vehicle_checkNumberPlate(NEW.tractorPlate, NULL); + END IF; + IF NEW.trailerPlate IS NOT NULL THEN + CALL vehicle_checkNumberPlate(NEW.trailerPlate, NULL); END IF; END$$ DELIMITER ; \ No newline at end of file diff --git a/db/versions/11416-goldenTulip/00-firstScript.sql b/db/versions/11416-goldenTulip/00-firstScript.sql index 9b89fcfa6f..d06f25493b 100644 --- a/db/versions/11416-goldenTulip/00-firstScript.sql +++ b/db/versions/11416-goldenTulip/00-firstScript.sql @@ -1,5 +1,5 @@ ALTER TABLE vn.roadmap - MODIFY COLUMN m3 int(10) unsigned DEFAULT NULL NULL COMMENT 'Capacidad máxima del remolque'; -ALTER TABLE vn.route - ADD roadmapStopFk int(11) NULL, - ADD CONSTRAINT route_roadmapStop_FK FOREIGN KEY (roadmapStopFk) REFERENCES vn.roadmapStop(id) ON DELETE RESTRICT ON UPDATE CASCADE; + MODIFY COLUMN m3 int(10) unsigned DEFAULT NULL NULL COMMENT 'Capacidad máxima del remolque', + CHANGE driver1Fk driverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Conductor principal' AFTER driverName, + CHANGE driver2Fk codriverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Copiloto' AFTER driverFk, + CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER m3; \ No newline at end of file diff --git a/db/versions/11416-goldenTulip/01-firstScript.sql b/db/versions/11416-goldenTulip/01-firstScript.sql new file mode 100644 index 0000000000..76b69387c4 --- /dev/null +++ b/db/versions/11416-goldenTulip/01-firstScript.sql @@ -0,0 +1 @@ +ALTER TABLE vn.roadmapStop CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL; \ No newline at end of file diff --git a/db/versions/11416-goldenTulip/02-firstScript.sql b/db/versions/11416-goldenTulip/02-firstScript.sql new file mode 100644 index 0000000000..89833fe8b4 --- /dev/null +++ b/db/versions/11416-goldenTulip/02-firstScript.sql @@ -0,0 +1,4 @@ +ALTER TABLE vn.route + ADD roadmapStopFk int(11) NULL, + ADD CONSTRAINT route_roadmapStop_FK FOREIGN KEY (roadmapStopFk) REFERENCES vn.roadmapStop(id) ON DELETE RESTRICT ON UPDATE CASCADE, + CHANGE editorFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER roadmapStopFk; From 7f5224ebcabe7c504ac67123aed95e5b079877fd Mon Sep 17 00:00:00 2001 From: jtubau Date: Tue, 21 Jan 2025 14:45:13 +0100 Subject: [PATCH 35/84] feat: refs #8304 add ACL entries for Business and Worker models and update worker model relationships --- db/versions/11404-azureAnthurium/00-firstScript.sql | 6 +++++- modules/worker/back/models/worker.json | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/db/versions/11404-azureAnthurium/00-firstScript.sql b/db/versions/11404-azureAnthurium/00-firstScript.sql index 7a4dfe9bcb..58e74cbfb6 100644 --- a/db/versions/11404-azureAnthurium/00-firstScript.sql +++ b/db/versions/11404-azureAnthurium/00-firstScript.sql @@ -1,2 +1,6 @@ INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) -VALUES('WorkerDms', 'hasHighPrivs', 'READ', 'ALLOW', 'ROLE', 'hr'); \ No newline at end of file +VALUES + ('WorkerDms', 'hasHighPrivs', 'READ', 'ALLOW', 'ROLE', 'hr'), + ('Business', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'hr'), + ('Worker', '__get__business', 'READ', 'ALLOW', 'ROLE', 'hr') + ; \ No newline at end of file diff --git a/modules/worker/back/models/worker.json b/modules/worker/back/models/worker.json index 705851963a..fbba4c2279 100644 --- a/modules/worker/back/models/worker.json +++ b/modules/worker/back/models/worker.json @@ -142,6 +142,11 @@ "type": "hasMany", "model": "WorkerRelative", "foreignKey": "workerFK" + }, + "business": { + "type": "hasMany", + "model": "Business", + "foreignKey": "workerFk" } }, "acls": [ From 2ae0097fa821b1335f382d63fe503fa5d28f139a Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 21 Jan 2025 15:48:20 +0100 Subject: [PATCH 36/84] feat: refs #7119 add vehicle type management and delivery role permissions --- db/dump/fixtures.before.sql | 11 +++++++++- .../11394-brownAsparagus/00-firstScript.sql | 21 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 2899446366..17f7cdf2ff 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -4090,4 +4090,13 @@ INSERT INTO vn.bankPolicy (id, `ref`, amount, committedFee, nonCommittedFee, ann INSERT INTO vn.ppe (id, amortization, firstAmortizated, lastAmortizated, finished, value, planFk, groupFk, account, endowment, elementAccount, nature, location, discharged, cause, isInvestmentAsset, workerFk, companyFk, description, isDone) VALUES (1, 0.00, '2001-01-01', NULL, NULL, 700.95, 16, 4, '3456000000', '4320000000', '12345', 'INMOVILIZADO', 'V02', NULL, NULL, 0, NULL, 442, 'UTILLAJE LASER ROTATIVO AUTONIVELANTE 500M', NULL), - (2, 0.00, '2001-01-01', NULL, NULL, 400.00, 16, 4, '5678000000', '1230000000', '67891', 'INMOVILIZADO', 'V02', NULL, NULL, 0, NULL, 442, 'UTILLAJE BALANZA Z100 150KILOS', NULL); \ No newline at end of file + (2, 0.00, '2001-01-01', NULL, NULL, 400.00, 16, 4, '5678000000', '1230000000', '67891', 'INMOVILIZADO', 'V02', NULL, NULL, 0, NULL, 442, 'UTILLAJE BALANZA Z100 150KILOS', NULL); + +INSERT IGNORE INTO vn.vehicleType (id, name) + VALUES (1,'vehículo empresa'), + (2, 'furgoneta'), + (3, 'cabeza tractora'), + (4, 'remolque'); + + + \ No newline at end of file diff --git a/db/versions/11394-brownAsparagus/00-firstScript.sql b/db/versions/11394-brownAsparagus/00-firstScript.sql index 77dfab7d34..51034c86b2 100644 --- a/db/versions/11394-brownAsparagus/00-firstScript.sql +++ b/db/versions/11394-brownAsparagus/00-firstScript.sql @@ -1,3 +1,4 @@ +USE vn; INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) VALUES ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'), @@ -14,4 +15,22 @@ INSERT INTO salix.ACL (model, property, accessType, permission, principalType, p ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery' ), ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), - ('Vehicle', '__get__active', 'READ', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file + ('Vehicle', '__get__active', 'READ', 'ALLOW', 'ROLE', 'employee'); + +ALTER TABLE vehicle ADD COLUMN importCooler decimal(10,2) DEFAULT NULL; + + +CREATE TABLE IF NOT EXISTS vehicleType ( + id INT(11) PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(45) NOT NULL +); + +INSERT IGNORE INTO vehicleType (id, name) + VALUES (1,'vehículo empresa'), + (2, 'furgoneta'), + (3, 'cabeza tractora'), + (4, 'remolque'); +ALTER TABLE vehicle ADD COLUMN vehicleTypeFk INT(11) DEFAULT 1; + +ALTER TABLE vehicle ADD CONSTRAINT fk_vehicle_vehicleType FOREIGN KEY (vehicleTypeFk) REFERENCES vehicleType(id); + From 052630d268139c62573f0e5430fcc0c54277fade Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 22 Jan 2025 12:40:58 +0100 Subject: [PATCH 37/84] feat: refs #8227 Roadmap changes --- db/routines/vn/triggers/roadmapStop_beforeInsert.sql | 5 +++++ db/routines/vn/triggers/roadmapStop_beforeUpdate.sql | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/db/routines/vn/triggers/roadmapStop_beforeInsert.sql b/db/routines/vn/triggers/roadmapStop_beforeInsert.sql index b87a52bdc8..9ec8b72cfa 100644 --- a/db/routines/vn/triggers/roadmapStop_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmapStop_beforeInsert.sql @@ -5,5 +5,10 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmapStop_beforeInser BEGIN SET NEW.editorFk = account.myUser_getId(); SET NEW.description = UCASE(NEW.description); + IF NEW.roadmapFk IS NOT NULL THEN + IF NEW.eta < (SELECT etd FROM roadmap WHERE id = NEW.roadmapFk) THEN + CALL util.throw('Departure time can not be after arrival time'); + END IF; + END IF; END$$ DELIMITER ; diff --git a/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql b/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql index ec4dbe5baa..cff48846ae 100644 --- a/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql @@ -5,5 +5,12 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmapStop_beforeUpdat BEGIN SET NEW.editorFk = account.myUser_getId(); SET NEW.description = UCASE(NEW.description); + IF (NOT (NEW.roadmapFk <=> OLD.roadmapFk) AND NEW.roadmapFk IS NOT NULL) + OR (NOT (NEW.eta <=> OLD.eta) AND NEW.eta IS NOT NULL) THEN + + IF NEW.eta < (SELECT etd FROM roadmap WHERE id = NEW.roadmapFk) THEN + CALL util.throw('Departure time can not be after arrival time'); + END IF; + END IF; END$$ DELIMITER ; From 3ea67675dad4bb7b9def51ce4acb56367524a352 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 23 Jan 2025 10:53:53 +0100 Subject: [PATCH 38/84] feat: refs #7119 add VehicleType model and update vehicle permissions for delivery roles --- .../11394-brownAsparagus/00-firstScript.sql | 22 ++++++------- modules/route/back/methods/vehicle/filter.js | 32 +++++++------------ modules/route/back/model-config.json | 3 ++ modules/route/back/models/vehicle-type.json | 19 +++++++++++ modules/route/back/models/vehicle.json | 9 ++++++ 5 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 modules/route/back/models/vehicle-type.json diff --git a/db/versions/11394-brownAsparagus/00-firstScript.sql b/db/versions/11394-brownAsparagus/00-firstScript.sql index 51034c86b2..6862627273 100644 --- a/db/versions/11394-brownAsparagus/00-firstScript.sql +++ b/db/versions/11394-brownAsparagus/00-firstScript.sql @@ -1,25 +1,24 @@ USE vn; + INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) VALUES ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'administrative'), - ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'delivery'), + ('Vehicle', 'filter', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant'), ('Vehicle', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), - ('Vehicle', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery'), + ('Vehicle', 'find', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant'), ('Vehicle', 'findById', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), - ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), + ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'deliveryAssistant'), ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), - ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery'), + ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant'), ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), - ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery'), + ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant'), ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative' ), - ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'delivery' ), + ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant' ), ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), - ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), + ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'deliveryAssistant'), + ('VehicleType', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Vehicle', '__get__active', 'READ', 'ALLOW', 'ROLE', 'employee'); -ALTER TABLE vehicle ADD COLUMN importCooler decimal(10,2) DEFAULT NULL; - - CREATE TABLE IF NOT EXISTS vehicleType ( id INT(11) PRIMARY KEY AUTO_INCREMENT, name VARCHAR(45) NOT NULL @@ -30,7 +29,8 @@ INSERT IGNORE INTO vehicleType (id, name) (2, 'furgoneta'), (3, 'cabeza tractora'), (4, 'remolque'); -ALTER TABLE vehicle ADD COLUMN vehicleTypeFk INT(11) DEFAULT 1; +ALTER TABLE vehicle ADD COLUMN importCooler decimal(10,2) DEFAULT NULL; +ALTER TABLE vehicle ADD COLUMN vehicleTypeFk INT(11) DEFAULT 1; ALTER TABLE vehicle ADD CONSTRAINT fk_vehicle_vehicleType FOREIGN KEY (vehicleTypeFk) REFERENCES vehicleType(id); diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index 11cc4d82af..7e8fb36415 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -43,8 +43,8 @@ module.exports = Self => { arg: 'countryCodeFk', type: 'string' }, { - arg: 'isKmTruckRate', - type: 'boolean' + arg: 'vehicleTypeFk', + type: 'number' }, { arg: 'vehicleStateFk', type: 'number' @@ -69,28 +69,19 @@ module.exports = Self => { switch (param) { case 'search': return {or: [{'v.id': value}, {numberPlate: {like: `%${value}%`}}]}; - case 'id': - return {id: value}; case 'description': - return {description: {like: `%${value}%`}}; - case 'companyFk': - return {companyFk: value}; case 'tradeMark': - return {tradeMark: {like: `%${value}%`}}; case 'numberPlate': - return {numberPlate: {like: `%${value}%`}}; - case 'warehouseFk': - return {warehouseFk: value}; case 'chassis': - return {chassis: {like: `%${value}%`}}; case 'leasing': - return {leasing: {like: `%${value}%`}}; + return {[param]: {like: `%${value}%`}}; + case 'id': + case 'companyFk': + case 'warehouseFk': case 'countryCodeFk': - return {countryCodeFk: value}; - case 'isKmTruckRate': - return {isKmTruckRate: value}; case 'vehicleStateFk': - return {vehicleStateFk: value}; + case 'vehicleTypeFk': + return {[param]: value}; } }) || {}; @@ -107,11 +98,12 @@ module.exports = Self => { v.countryCodeFk, v.chassis, v.leasing, - v.isKmTruckRate, - w.name as warehouse, - c.code as company, + vt.name type, + w.name warehouse, + c.code company, sub.state FROM vehicle v + JOIN vehicleType vt ON vt.id = v.vehicleTypeFk LEFT JOIN warehouse w ON w.id = v.warehouseFk LEFT JOIN company c ON c.id = v.companyFk LEFT JOIN ( diff --git a/modules/route/back/model-config.json b/modules/route/back/model-config.json index 16e6d69677..3a7c9e06b5 100644 --- a/modules/route/back/model-config.json +++ b/modules/route/back/model-config.json @@ -47,6 +47,9 @@ "VehicleState": { "dataSource": "vn" }, + "VehicleType": { + "dataSource": "vn" + }, "RoutesMonitor": { "dataSource": "vn" } diff --git a/modules/route/back/models/vehicle-type.json b/modules/route/back/models/vehicle-type.json new file mode 100644 index 0000000000..34beb6dfba --- /dev/null +++ b/modules/route/back/models/vehicle-type.json @@ -0,0 +1,19 @@ +{ + "name": "VehicleType", + "base": "VnModel", + "options": { + "mysql": { + "table": "vehicleType" + } + }, + "properties": { + "id": { + "type": "number", + "id": true, + "description": "Identifier" + }, + "name": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/modules/route/back/models/vehicle.json b/modules/route/back/models/vehicle.json index e6d58de99e..95eac7251c 100644 --- a/modules/route/back/models/vehicle.json +++ b/modules/route/back/models/vehicle.json @@ -53,6 +53,9 @@ }, "ppeFk": { "type": "number" + }, + "vehicleTypeFk": { + "type": "number" } }, "relations": { @@ -102,6 +105,12 @@ "model": "Ppe", "foreignKey": "id", "property": "ppeFk" + }, + "type": { + "type": "hasOne", + "model": "VehicleType", + "foreignKey": "id", + "property": "vehicleTypeFk" } }, "scopes": { From 162cd4d69ebe1dc4c803a636375e4e31de151fd2 Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 23 Jan 2025 14:54:59 +0100 Subject: [PATCH 39/84] feat: refs #8227 Roadmap major changes --- .../getTimeBetweenRoadmapAddresses.sql | 35 +++++++++++++++++++ .../vn/triggers/roadmap_beforeInsert.sql | 4 +++ .../vn/triggers/roadmap_beforeUpdate.sql | 4 +++ .../11416-goldenTulip/00-firstScript.sql | 7 +++- .../11416-goldenTulip/01-firstScript.sql | 8 ++++- .../11416-goldenTulip/02-firstScript.sql | 7 ++-- .../11416-goldenTulip/03-firstScript.sql | 4 +++ .../11416-goldenTulip/04-firstScript.sql | 2 ++ 8 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 db/routines/vn/functions/getTimeBetweenRoadmapAddresses.sql create mode 100644 db/versions/11416-goldenTulip/03-firstScript.sql create mode 100644 db/versions/11416-goldenTulip/04-firstScript.sql diff --git a/db/routines/vn/functions/getTimeBetweenRoadmapAddresses.sql b/db/routines/vn/functions/getTimeBetweenRoadmapAddresses.sql new file mode 100644 index 0000000000..5a647d51b7 --- /dev/null +++ b/db/routines/vn/functions/getTimeBetweenRoadmapAddresses.sql @@ -0,0 +1,35 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`vn`@`localhost` FUNCTION `vn`.`getTimeBetweenRoadmapAddresses`( + vRoadmapAddressFrom INT, + vRoadmapAddressTo INT +) + RETURNS int(11) + DETERMINISTIC +BEGIN +/** + * Retorna el tiempo en segundos que se suele tardar en ir + * de un punto de distribución a otro en una ruta troncal. + * + * @param vRoadmapAddressFrom Punto de distribución de origen + * @param vRoadmapAddressTo Punto de distribución de destino + * @return Tiempo en segundos + */ + DECLARE vSeconds INT; + + WITH wRoadmap AS ( + SELECT ROW_NUMBER() OVER(PARTITION BY roadmapFk ORDER BY eta) `sequence`, + roadmapFk, + roadmapAddressFk, + eta + FROM vn.roadmapStop + ) + SELECT AVG(TIME_TO_SEC(TIMEDIFF(rTo.eta, rFrom.eta))) INTO vSeconds + FROM wRoadmap rFrom + JOIN wRoadmap rTo ON rTo.roadmapFk = rFrom.roadmapFk + WHERE rFrom.roadmapAddressFk = vRoadmapAddressFrom + AND rTo.roadmapAddressFk = vRoadmapAddressTo + AND rFrom.`sequence` + 1 = rTo.`sequence`; + + RETURN vSeconds; +END$$ +DELIMITER ; diff --git a/db/routines/vn/triggers/roadmap_beforeInsert.sql b/db/routines/vn/triggers/roadmap_beforeInsert.sql index 118653d44f..884fe0bbcf 100644 --- a/db/routines/vn/triggers/roadmap_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmap_beforeInsert.sql @@ -4,6 +4,10 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_beforeInsert` FOR EACH ROW BEGIN SET NEW.editorFk = account.myUser_getId(); + IF NEW.etd > NEW.eta THEN + CALL util.throw('Departure time can not be after arrival time'); + END IF; + IF NEW.tractorPlate IS NOT NULL THEN CALL vehicle_checkNumberPlate(NEW.tractorPlate, NULL); END IF; diff --git a/db/routines/vn/triggers/roadmap_beforeUpdate.sql b/db/routines/vn/triggers/roadmap_beforeUpdate.sql index a60b1e892e..96eec2aaf9 100644 --- a/db/routines/vn/triggers/roadmap_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmap_beforeUpdate.sql @@ -4,6 +4,10 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_beforeUpdate` FOR EACH ROW BEGIN SET NEW.editorFk = account.myUser_getId(); + IF NEW.etd > NEW.eta THEN + CALL util.throw('Departure time can not be after arrival time'); + END IF; + IF NEW.tractorPlate IS NOT NULL THEN CALL vehicle_checkNumberPlate(NEW.tractorPlate, NULL); END IF; diff --git a/db/versions/11416-goldenTulip/00-firstScript.sql b/db/versions/11416-goldenTulip/00-firstScript.sql index d06f25493b..e2962592cf 100644 --- a/db/versions/11416-goldenTulip/00-firstScript.sql +++ b/db/versions/11416-goldenTulip/00-firstScript.sql @@ -1,5 +1,10 @@ ALTER TABLE vn.roadmap + COMMENT='Rutas troncales (trailers)', MODIFY COLUMN m3 int(10) unsigned DEFAULT NULL NULL COMMENT 'Capacidad máxima del remolque', + MODIFY COLUMN trailerPlate varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL NULL, + MODIFY COLUMN etd datetime NOT NULL COMMENT 'Tiempo estimado de salida', CHANGE driver1Fk driverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Conductor principal' AFTER driverName, CHANGE driver2Fk codriverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Copiloto' AFTER driverFk, - CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER m3; \ No newline at end of file + CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER m3, + ADD eta datetime NOT NULL AFTER etd COMMENT 'Tiempo estimado de llegada', + ADD roadmapAddressFk int(11) NOT NULL AFTER `name`; diff --git a/db/versions/11416-goldenTulip/01-firstScript.sql b/db/versions/11416-goldenTulip/01-firstScript.sql index 76b69387c4..58cd44f0dd 100644 --- a/db/versions/11416-goldenTulip/01-firstScript.sql +++ b/db/versions/11416-goldenTulip/01-firstScript.sql @@ -1 +1,7 @@ -ALTER TABLE vn.roadmapStop CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL; \ No newline at end of file +UPDATE vn.roadmap + SET roadmapAddressFk = (SELECT MIN(addressFk) FROM vn.roadmapAddress), + eta = etd + INTERVAL 1 DAY; + +ALTER TABLE vn.roadmap + ADD CONSTRAINT roadmap_roadmapAddress_FK FOREIGN KEY (roadmapAddressFk) + REFERENCES vn.roadmapAddress(addressFk) ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/db/versions/11416-goldenTulip/02-firstScript.sql b/db/versions/11416-goldenTulip/02-firstScript.sql index 89833fe8b4..8713c50908 100644 --- a/db/versions/11416-goldenTulip/02-firstScript.sql +++ b/db/versions/11416-goldenTulip/02-firstScript.sql @@ -1,4 +1,3 @@ -ALTER TABLE vn.route - ADD roadmapStopFk int(11) NULL, - ADD CONSTRAINT route_roadmapStop_FK FOREIGN KEY (roadmapStopFk) REFERENCES vn.roadmapStop(id) ON DELETE RESTRICT ON UPDATE CASCADE, - CHANGE editorFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER roadmapStopFk; +ALTER TABLE vn.roadmapStop + CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL, + CHANGE addressFk roadmapAddressFk int(11) DEFAULT NULL NULL; diff --git a/db/versions/11416-goldenTulip/03-firstScript.sql b/db/versions/11416-goldenTulip/03-firstScript.sql new file mode 100644 index 0000000000..89833fe8b4 --- /dev/null +++ b/db/versions/11416-goldenTulip/03-firstScript.sql @@ -0,0 +1,4 @@ +ALTER TABLE vn.route + ADD roadmapStopFk int(11) NULL, + ADD CONSTRAINT route_roadmapStop_FK FOREIGN KEY (roadmapStopFk) REFERENCES vn.roadmapStop(id) ON DELETE RESTRICT ON UPDATE CASCADE, + CHANGE editorFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER roadmapStopFk; diff --git a/db/versions/11416-goldenTulip/04-firstScript.sql b/db/versions/11416-goldenTulip/04-firstScript.sql new file mode 100644 index 0000000000..588810ded9 --- /dev/null +++ b/db/versions/11416-goldenTulip/04-firstScript.sql @@ -0,0 +1,2 @@ +ALTER TABLE vn.roadmapAddress + COMMENT='Direcciones de los troncales o también llamados puntos de distribución'; From 3a449896cdbe15900c8021100d301405cb1481b7 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 23 Jan 2025 18:02:53 +0100 Subject: [PATCH 40/84] feat: refs #7119 update vehicle permissions and enhance vehicle model with new fields --- db/versions/11394-brownAsparagus/00-firstScript.sql | 13 +++++++++---- modules/route/back/models/vehicle.json | 6 ++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/db/versions/11394-brownAsparagus/00-firstScript.sql b/db/versions/11394-brownAsparagus/00-firstScript.sql index 6862627273..13b6cfa0dd 100644 --- a/db/versions/11394-brownAsparagus/00-firstScript.sql +++ b/db/versions/11394-brownAsparagus/00-firstScript.sql @@ -6,19 +6,24 @@ INSERT INTO salix.ACL (model, property, accessType, permission, principalType, p ('Vehicle', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('Vehicle', 'find', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant'), ('Vehicle', 'findById', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', 'findById', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant'), + ('Vehicle', '__get__active', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), ('Vehicle', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'deliveryAssistant'), + ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'deliveryAssistant'), + ('Vehicle', 'create', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), + ('Vehicle', 'create', 'WRITE', 'ALLOW', 'ROLE', 'deliveryAssistant'), ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('BankPolicy', 'find', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant'), ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'), ('VehicleState', 'find', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant'), ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative' ), ('Ppe', 'find', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant' ), - ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'administrative'), - ('Vehicle', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'deliveryAssistant'), ('VehicleType', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), - ('Vehicle', '__get__active', 'READ', 'ALLOW', 'ROLE', 'employee'); - + ('DeliveryPoint', 'find', 'READ', 'ALLOW', 'ROLE', 'deliveryAssistant'), + ('DeliveryPoint', 'find', 'READ', 'ALLOW', 'ROLE', 'administrative'); + CREATE TABLE IF NOT EXISTS vehicleType ( id INT(11) PRIMARY KEY AUTO_INCREMENT, name VARCHAR(45) NOT NULL diff --git a/modules/route/back/models/vehicle.json b/modules/route/back/models/vehicle.json index 95eac7251c..d64f3df794 100644 --- a/modules/route/back/models/vehicle.json +++ b/modules/route/back/models/vehicle.json @@ -48,6 +48,9 @@ "import": { "type": "number" }, + "importCooler": { + "type": "number" + }, "vin": { "type": "string" }, @@ -56,6 +59,9 @@ }, "vehicleTypeFk": { "type": "number" + }, + "deliveryPointFk": { + "type": "number" } }, "relations": { From 306eb6a0599490a82672be7ae8ab18aa377efab3 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 24 Jan 2025 07:26:25 +0100 Subject: [PATCH 41/84] feat: refs #8227 Roadmap fix version --- db/dump/fixtures.before.sql | 10 +++++----- .../11416-goldenTulip/00-firstScript.sql | 12 +++--------- .../11416-goldenTulip/01-firstScript.sql | 18 ++++++++++++------ .../11416-goldenTulip/02-firstScript.sql | 16 +++++++++++++--- .../11416-goldenTulip/03-firstScript.sql | 7 +++---- .../11416-goldenTulip/04-firstScript.sql | 6 ++++-- .../11416-goldenTulip/05-firstScript.sql | 2 ++ 7 files changed, 42 insertions(+), 29 deletions(-) create mode 100644 db/versions/11416-goldenTulip/05-firstScript.sql diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index cc1a9fc6f1..eb11264e70 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -2749,13 +2749,13 @@ INSERT INTO `vn`.`roadmapAddress` (`addressFk`) (3), (4); -INSERT INTO `vn`.`roadmap` (`id`, `name`, `tractorPlate`, `trailerPlate`, `phone`, `supplierFk`, `etd`, `observations`, `editorFk`, `price`, `driverName`) +INSERT INTO `vn`.`roadmap` (`id`, `name`, `tractorPlate`, `trailerPlate`, `phone`, `supplierFk`, `etd`, `eta`, `observations`, `editorFk`, `price`, `driverName`) VALUES - (1, 'val-algemesi', '1234-BCD', '9876-BCD', '111111111', 1, util.VN_NOW(), 'this is test observation', 1, 15, 'Batman'), - (2, 'alg-valencia', '2345-CDF', '8765-BCD', '111111111', 1, util.VN_NOW(), 'test observation', 1, 20, 'Robin'), - (3, 'alz-algemesi', '3456-DFG', '7654-BCD', '222222222', 2, DATE_ADD(util.VN_NOW(), INTERVAL 2 DAY), 'observations...', 2, 25, 'Driverman'); + (1, 'val-algemesi', '1234-BCD', '9876-BCD', '111111111', 1, util.VN_NOW(), DATE_ADD(util.VN_NOW(), INTERVAL 2 DAY), 'this is test observation', 1, 15, 'Batman'), + (2, 'alg-valencia', '2345-CDF', '8765-BCD', '111111111', 1, util.VN_NOW(), DATE_ADD(util.VN_NOW(), INTERVAL 5 DAY), 'test observation', 1, 20, 'Robin'), + (3, 'alz-algemesi', '3456-DFG', '7654-BCD', '222222222', 2, DATE_ADD(util.VN_NOW(), INTERVAL 3 DAY), DATE_ADD(util.VN_NOW(), INTERVAL 6 DAY), 'observations...', 2, 25, 'Driverman'); -INSERT INTO `vn`.`roadmapStop` (`id`, `roadmapFk`, `addressFk`, `eta`, `description`, `editorFk`) +INSERT INTO `vn`.`roadmapStop` (`id`, `roadmapFk`, `roadmapAddressFk`, `eta`, `description`, `editorFk`) VALUES (1, 1, 1, DATE_ADD(util.VN_NOW(), INTERVAL 1 DAY), 'Best truck in fleet', 1), (2, 1, 2, DATE_ADD(util.VN_NOW(), INTERVAL '1 2' DAY_HOUR), 'Second truck in fleet', 1), diff --git a/db/versions/11416-goldenTulip/00-firstScript.sql b/db/versions/11416-goldenTulip/00-firstScript.sql index e2962592cf..aa410c52f9 100644 --- a/db/versions/11416-goldenTulip/00-firstScript.sql +++ b/db/versions/11416-goldenTulip/00-firstScript.sql @@ -1,10 +1,4 @@ ALTER TABLE vn.roadmap - COMMENT='Rutas troncales (trailers)', - MODIFY COLUMN m3 int(10) unsigned DEFAULT NULL NULL COMMENT 'Capacidad máxima del remolque', - MODIFY COLUMN trailerPlate varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL NULL, - MODIFY COLUMN etd datetime NOT NULL COMMENT 'Tiempo estimado de salida', - CHANGE driver1Fk driverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Conductor principal' AFTER driverName, - CHANGE driver2Fk codriverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Copiloto' AFTER driverFk, - CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER m3, - ADD eta datetime NOT NULL AFTER etd COMMENT 'Tiempo estimado de llegada', - ADD roadmapAddressFk int(11) NOT NULL AFTER `name`; + DROP FOREIGN KEY roadmap_worker_FK_2, + DROP FOREIGN KEY roadmap_worker_FK, + DROP FOREIGN KEY roadmap_ibfk_2; diff --git a/db/versions/11416-goldenTulip/01-firstScript.sql b/db/versions/11416-goldenTulip/01-firstScript.sql index 58cd44f0dd..68c369800f 100644 --- a/db/versions/11416-goldenTulip/01-firstScript.sql +++ b/db/versions/11416-goldenTulip/01-firstScript.sql @@ -1,7 +1,13 @@ -UPDATE vn.roadmap - SET roadmapAddressFk = (SELECT MIN(addressFk) FROM vn.roadmapAddress), - eta = etd + INTERVAL 1 DAY; - ALTER TABLE vn.roadmap - ADD CONSTRAINT roadmap_roadmapAddress_FK FOREIGN KEY (roadmapAddressFk) - REFERENCES vn.roadmapAddress(addressFk) ON DELETE RESTRICT ON UPDATE CASCADE; + COMMENT='Rutas troncales (trailers)', + MODIFY COLUMN m3 int(10) unsigned DEFAULT NULL NULL COMMENT 'Capacidad máxima del remolque', + MODIFY COLUMN trailerPlate varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL NULL, + MODIFY COLUMN etd datetime NOT NULL COMMENT 'Tiempo estimado de salida', + ADD eta datetime NOT NULL COMMENT 'Tiempo estimado de llegada' AFTER etd, + ADD roadmapAddressFk int(11) NOT NULL AFTER `name`; + +-- Separamos los CHANGE por que si no arriba no se aplican +ALTER TABLE vn.roadmap + CHANGE driver1Fk driverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Conductor principal' AFTER driverName, + CHANGE driver2Fk codriverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Copiloto' AFTER driverFk, + CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER m3; \ No newline at end of file diff --git a/db/versions/11416-goldenTulip/02-firstScript.sql b/db/versions/11416-goldenTulip/02-firstScript.sql index 8713c50908..f99334e9b9 100644 --- a/db/versions/11416-goldenTulip/02-firstScript.sql +++ b/db/versions/11416-goldenTulip/02-firstScript.sql @@ -1,3 +1,13 @@ -ALTER TABLE vn.roadmapStop - CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL, - CHANGE addressFk roadmapAddressFk int(11) DEFAULT NULL NULL; +UPDATE vn.roadmap + SET roadmapAddressFk = (SELECT MIN(addressFk) FROM vn.roadmapAddress), + eta = etd + INTERVAL 1 DAY; + +ALTER TABLE vn.roadmap + ADD CONSTRAINT roadmap_roadmapAddress_FK FOREIGN KEY (roadmapAddressFk) + REFERENCES vn.roadmapAddress(addressFk) ON DELETE RESTRICT ON UPDATE CASCADE, + ADD CONSTRAINT roadmap_driver_FK FOREIGN KEY (driverFk) + REFERENCES vn.worker(id) ON DELETE RESTRICT ON UPDATE CASCADE, + ADD CONSTRAINT roadmap_driver_FK2 FOREIGN KEY (codriverFk) + REFERENCES vn.worker(id) ON DELETE RESTRICT ON UPDATE CASCADE, + ADD CONSTRAINT roadmap_user_Fk FOREIGN KEY (editorFk) + REFERENCES account.user(id) ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/db/versions/11416-goldenTulip/03-firstScript.sql b/db/versions/11416-goldenTulip/03-firstScript.sql index 89833fe8b4..8713c50908 100644 --- a/db/versions/11416-goldenTulip/03-firstScript.sql +++ b/db/versions/11416-goldenTulip/03-firstScript.sql @@ -1,4 +1,3 @@ -ALTER TABLE vn.route - ADD roadmapStopFk int(11) NULL, - ADD CONSTRAINT route_roadmapStop_FK FOREIGN KEY (roadmapStopFk) REFERENCES vn.roadmapStop(id) ON DELETE RESTRICT ON UPDATE CASCADE, - CHANGE editorFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER roadmapStopFk; +ALTER TABLE vn.roadmapStop + CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL, + CHANGE addressFk roadmapAddressFk int(11) DEFAULT NULL NULL; diff --git a/db/versions/11416-goldenTulip/04-firstScript.sql b/db/versions/11416-goldenTulip/04-firstScript.sql index 588810ded9..89833fe8b4 100644 --- a/db/versions/11416-goldenTulip/04-firstScript.sql +++ b/db/versions/11416-goldenTulip/04-firstScript.sql @@ -1,2 +1,4 @@ -ALTER TABLE vn.roadmapAddress - COMMENT='Direcciones de los troncales o también llamados puntos de distribución'; +ALTER TABLE vn.route + ADD roadmapStopFk int(11) NULL, + ADD CONSTRAINT route_roadmapStop_FK FOREIGN KEY (roadmapStopFk) REFERENCES vn.roadmapStop(id) ON DELETE RESTRICT ON UPDATE CASCADE, + CHANGE editorFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER roadmapStopFk; diff --git a/db/versions/11416-goldenTulip/05-firstScript.sql b/db/versions/11416-goldenTulip/05-firstScript.sql new file mode 100644 index 0000000000..588810ded9 --- /dev/null +++ b/db/versions/11416-goldenTulip/05-firstScript.sql @@ -0,0 +1,2 @@ +ALTER TABLE vn.roadmapAddress + COMMENT='Direcciones de los troncales o también llamados puntos de distribución'; From 6da004e7cf1e0e908bfbe08fffec8c32059723e1 Mon Sep 17 00:00:00 2001 From: Jon Date: Fri, 24 Jan 2025 09:29:58 +0100 Subject: [PATCH 42/84] fix: fixed shipped date when it is null --- modules/ticket/back/methods/ticket/priceDifference.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 7db03e2685..7e4fe82835 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -108,7 +108,10 @@ module.exports = Self => { // Get items movable const ticketOrigin = await models.Ticket.findById(args.id, null, myOptions); - const differenceShipped = ticketOrigin.shipped.getTime() > args.shipped.getTime(); + let shipped = ticketOrigin.shipped ?? ticketOrigin.updated; + + const differenceShipped = shipped.getTime() > args.shipped.getTime(); + const differenceWarehouse = ticketOrigin.warehouseFk != args.warehouseId; salesObj.haveDifferences = differenceShipped || differenceWarehouse; From 3fba81b41e8bc7ae1162dabcd41944fa525e76d3 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 24 Jan 2025 10:46:35 +0100 Subject: [PATCH 43/84] feat: refs #7119 add 'id' filter option and enhance bank policy model with dmsFk field --- modules/route/back/methods/vehicle/filter.js | 11 ++++++----- modules/route/back/models/bank-policy.json | 3 +++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index 7e8fb36415..cb55f5f3ca 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -69,13 +69,14 @@ module.exports = Self => { switch (param) { case 'search': return {or: [{'v.id': value}, {numberPlate: {like: `%${value}%`}}]}; + case 'id': + return {'v.id': value}; case 'description': case 'tradeMark': case 'numberPlate': case 'chassis': case 'leasing': return {[param]: {like: `%${value}%`}}; - case 'id': case 'companyFk': case 'warehouseFk': case 'countryCodeFk': @@ -83,9 +84,9 @@ module.exports = Self => { case 'vehicleTypeFk': return {[param]: value}; } - }) || {}; + }); - const myFilter = mergeFilters(filter, {where}); + filter = mergeFilters(filter, {where}); const stmt = new ParameterizedSQL(` SELECT v.id, @@ -116,9 +117,9 @@ module.exports = Self => { ) sub ON sub.vehicleFk = v.id AND sub.rn = 1 `); - const sqlWhere = conn.makeWhere(myFilter.where); + const sqlWhere = conn.makeWhere(filter.where); stmt.merge(sqlWhere); - stmt.merge(conn.makePagination(myFilter)); + stmt.merge(conn.makePagination(filter)); const sql = ParameterizedSQL.join([stmt], ';'); diff --git a/modules/route/back/models/bank-policy.json b/modules/route/back/models/bank-policy.json index edbc636ffa..55a409a671 100644 --- a/modules/route/back/models/bank-policy.json +++ b/modules/route/back/models/bank-policy.json @@ -13,6 +13,9 @@ }, "ref": { "type": "string" + }, + "dmsFk": { + "type": "number" } } } \ No newline at end of file From e9f1e28ac0dcadf5b93848e1623a04d5ed474147 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 24 Jan 2025 11:20:16 +0100 Subject: [PATCH 44/84] feat: refs #8227 Added roadmap_cloneDay --- .../vn/procedures/roadmap_cloneDay.sql | 71 +++++++++++++++++++ .../vn/triggers/roadmap_beforeInsert.sql | 1 + .../vn/triggers/roadmap_beforeUpdate.sql | 1 + .../11416-goldenTulip/01-firstScript.sql | 1 + .../11416-goldenTulip/03-firstScript.sql | 6 +- 5 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 db/routines/vn/procedures/roadmap_cloneDay.sql diff --git a/db/routines/vn/procedures/roadmap_cloneDay.sql b/db/routines/vn/procedures/roadmap_cloneDay.sql new file mode 100644 index 0000000000..51d6ba1aba --- /dev/null +++ b/db/routines/vn/procedures/roadmap_cloneDay.sql @@ -0,0 +1,71 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`roadmap_cloneDay`( + vDateToCopy DATE, + vDateToPaste DATE +) +BEGIN +/** + * Clona roadmaps de un día a otro, incluyendo las paradas y sin algunos + * campos de la tabla principal, como matrículas, conductores... + * + * @param vDateToCopy Fecha para copiar + * @param vDateToPaste Fecha para pegar + */ + DECLARE vDaysDiff INT; + DECLARE vNextRoadmapId INT; + + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + ROLLBACK; + RESIGNAL; + END; + + SET vDaysDiff = DATEDIFF(vDateToPaste, vDateToCopy); + + IF vDaysDiff IS NULL OR NOT vDaysDiff THEN + CALL util.throw("No valid dates"); + END IF; + + START TRANSACTION; + + SELECT AUTO_INCREMENT INTO vNextRoadmapId + FROM information_schema.tables + WHERE table_name = 'roadmap' + AND table_schema = 'vn'; + + CREATE OR REPLACE TEMPORARY TABLE tmp.roadmapsToCopy + ENGINE = MEMORY + SELECT ROW_NUMBER() OVER(ORDER BY id) rowOrder, + id, + `name`, + roadmapAddressFk, + etd, + eta, + observations, + price + FROM roadmap + WHERE etd BETWEEN vDateToCopy AND util.dayEnd(vDateToCopy); + + INSERT INTO roadmap (`name`, roadmapAddressFk, etd, eta, observations, price) + SELECT `name`, + roadmapAddressFk, + etd + INTERVAL vDaysDiff DAY, + eta + INTERVAL vDaysDiff DAY, + observations, + price + FROM tmp.roadmapsToCopy; + + INSERT INTO roadmapStop (roadmapFk, roadmapAddressFk, eta, `description`, bufferFk) + SELECT (rtc.rowOrder - 1) + vNextRoadmapId, + rs.roadmapAddressFk, + rs.eta + INTERVAL vDaysDiff DAY, + rs.description, + rs.bufferFk + FROM tmp.roadmapsToCopy rtc + JOIN roadmapStop rs ON rs.roadmapFk = rtc.id; + + COMMIT; + + DROP TEMPORARY TABLE tmp.roadmapsToCopy; +END$$ +DELIMITER ; diff --git a/db/routines/vn/triggers/roadmap_beforeInsert.sql b/db/routines/vn/triggers/roadmap_beforeInsert.sql index 884fe0bbcf..4b0a1c847a 100644 --- a/db/routines/vn/triggers/roadmap_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmap_beforeInsert.sql @@ -14,5 +14,6 @@ BEGIN IF NEW.trailerPlate IS NOT NULL THEN CALL vehicle_checkNumberPlate(NEW.trailerPlate, NULL); END IF; + SET NEW.name = UCASE(NEW.name); END$$ DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/triggers/roadmap_beforeUpdate.sql b/db/routines/vn/triggers/roadmap_beforeUpdate.sql index 96eec2aaf9..1ad547f556 100644 --- a/db/routines/vn/triggers/roadmap_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmap_beforeUpdate.sql @@ -14,5 +14,6 @@ BEGIN IF NEW.trailerPlate IS NOT NULL THEN CALL vehicle_checkNumberPlate(NEW.trailerPlate, NULL); END IF; + SET NEW.name = UCASE(NEW.name); END$$ DELIMITER ; \ No newline at end of file diff --git a/db/versions/11416-goldenTulip/01-firstScript.sql b/db/versions/11416-goldenTulip/01-firstScript.sql index 68c369800f..0cd7942297 100644 --- a/db/versions/11416-goldenTulip/01-firstScript.sql +++ b/db/versions/11416-goldenTulip/01-firstScript.sql @@ -3,6 +3,7 @@ ALTER TABLE vn.roadmap MODIFY COLUMN m3 int(10) unsigned DEFAULT NULL NULL COMMENT 'Capacidad máxima del remolque', MODIFY COLUMN trailerPlate varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL NULL, MODIFY COLUMN etd datetime NOT NULL COMMENT 'Tiempo estimado de salida', + MODIFY COLUMN `name` varchar(45) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL, ADD eta datetime NOT NULL COMMENT 'Tiempo estimado de llegada' AFTER etd, ADD roadmapAddressFk int(11) NOT NULL AFTER `name`; diff --git a/db/versions/11416-goldenTulip/03-firstScript.sql b/db/versions/11416-goldenTulip/03-firstScript.sql index 8713c50908..4df73139a6 100644 --- a/db/versions/11416-goldenTulip/03-firstScript.sql +++ b/db/versions/11416-goldenTulip/03-firstScript.sql @@ -1,3 +1,7 @@ ALTER TABLE vn.roadmapStop CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL, - CHANGE addressFk roadmapAddressFk int(11) DEFAULT NULL NULL; + CHANGE addressFk roadmapAddressFk int(11) DEFAULT NULL NULL, + DROP FOREIGN KEY expeditionTruck_FK_2; + +ALTER TABLE vn.roadmapStop ADD CONSTRAINT roadmapStop_roadmap_FK + FOREIGN KEY (roadmapFk) REFERENCES vn.roadmap(id) ON DELETE CASCADE ON UPDATE CASCADE; From 75b0589561a54024ec5f305cc9209e1f2d244ec6 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 24 Jan 2025 12:34:08 +0100 Subject: [PATCH 45/84] feat: refs #8227 Undo vehicle_checkNumberPlate change and triggers checks --- .../vn/procedures/vehicle_checkNumberPlate.sql | 16 +++++----------- db/routines/vn/triggers/roadmap_beforeInsert.sql | 7 ------- db/routines/vn/triggers/roadmap_beforeUpdate.sql | 7 ------- 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/db/routines/vn/procedures/vehicle_checkNumberPlate.sql b/db/routines/vn/procedures/vehicle_checkNumberPlate.sql index 613dda3682..b7444cac89 100644 --- a/db/routines/vn/procedures/vehicle_checkNumberPlate.sql +++ b/db/routines/vn/procedures/vehicle_checkNumberPlate.sql @@ -13,18 +13,12 @@ BEGIN */ DECLARE vRegex VARCHAR(45); - IF vCountryCodeFk IS NULL THEN - SET vRegex = '^[A-Z0-9 -]{6,12}$'; - ELSE - SELECT regex INTO vRegex - FROM vehiclePlateRegex - WHERE countryCodeFk = vCountryCodeFk; - END IF; - + SELECT regex INTO vRegex + FROM vehiclePlateRegex + WHERE countryCodeFk = vCountryCodeFk; + IF NOT vNumberPlate REGEXP BINARY (vRegex)THEN - CALL util.throw(CONCAT('La matricula ', vNumberPlate, - ' no es valida', IF(vCountryCodeFk IS NOT NULL, - CONCAT(' para ', vCountryCodeFk), ''))); + CALL util.throw(CONCAT('Error: la matricula ', vNumberPlate, ' no es valida para ',vCountryCodeFk)); END IF; END$$ DELIMITER ; diff --git a/db/routines/vn/triggers/roadmap_beforeInsert.sql b/db/routines/vn/triggers/roadmap_beforeInsert.sql index 4b0a1c847a..9e783e711c 100644 --- a/db/routines/vn/triggers/roadmap_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmap_beforeInsert.sql @@ -7,13 +7,6 @@ BEGIN IF NEW.etd > NEW.eta THEN CALL util.throw('Departure time can not be after arrival time'); END IF; - - IF NEW.tractorPlate IS NOT NULL THEN - CALL vehicle_checkNumberPlate(NEW.tractorPlate, NULL); - END IF; - IF NEW.trailerPlate IS NOT NULL THEN - CALL vehicle_checkNumberPlate(NEW.trailerPlate, NULL); - END IF; SET NEW.name = UCASE(NEW.name); END$$ DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/triggers/roadmap_beforeUpdate.sql b/db/routines/vn/triggers/roadmap_beforeUpdate.sql index 1ad547f556..4824170ec4 100644 --- a/db/routines/vn/triggers/roadmap_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmap_beforeUpdate.sql @@ -7,13 +7,6 @@ BEGIN IF NEW.etd > NEW.eta THEN CALL util.throw('Departure time can not be after arrival time'); END IF; - - IF NEW.tractorPlate IS NOT NULL THEN - CALL vehicle_checkNumberPlate(NEW.tractorPlate, NULL); - END IF; - IF NEW.trailerPlate IS NOT NULL THEN - CALL vehicle_checkNumberPlate(NEW.trailerPlate, NULL); - END IF; SET NEW.name = UCASE(NEW.name); END$$ DELIMITER ; \ No newline at end of file From ec7bbd13b131330caad46ebfaa2b81bd5aaa4b2e Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 24 Jan 2025 16:37:35 +0100 Subject: [PATCH 46/84] refactor: refs #7119 update vehicle filter logic and improve test cases --- modules/route/back/methods/vehicle/filter.js | 2 - .../back/methods/vehicle/specs/filter.spec.js | 93 ++++++++++--------- 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index ef87c1448e..fa0b847580 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -71,8 +71,6 @@ module.exports = Self => { return /^\d+$/.test(value) ? {'v.id': value} : {numberPlate: {like: `%${value}%`}}; - case 'id': - return {'v.id': value}; case 'description': case 'tradeMark': case 'numberPlate': diff --git a/modules/route/back/methods/vehicle/specs/filter.spec.js b/modules/route/back/methods/vehicle/specs/filter.spec.js index ab718f06e4..52e0b8a397 100644 --- a/modules/route/back/methods/vehicle/specs/filter.spec.js +++ b/modules/route/back/methods/vehicle/specs/filter.spec.js @@ -1,6 +1,6 @@ const {models} = require('vn-loopback/server/server'); -fdescribe('Vehicle filter()', () => { +describe('Vehicle filter()', () => { const deliveryAssiId = 123; const ctx = beforeAll.getCtx(deliveryAssiId); let options; @@ -30,7 +30,7 @@ fdescribe('Vehicle filter()', () => { expect(searchResult2.numberPlate).toEqual(numberPlate); }); - it('should return the vehicles matching "company"', async() => { + it('should return the vehicles matching "companyFk"', async() => { const company = await models.Company.findOne({where: {code: 'VNL'}}, options); ctx.args = {companyFk: company.id}; const searchResult = await models.Vehicle.filter(ctx, null, options); @@ -64,59 +64,64 @@ fdescribe('Vehicle filter()', () => { ctx.args = {warehouseFk: warehouse.id}; const searchResult = await models.Vehicle.filter(ctx); searchResult.forEach(record => { - expect(record.warehouseFk).toEqual(warehouse.id); + expect(record.warehouse).toEqual(warehouse.name); }); }); - // it('should return the vehicles matching "chassis"', async() => { - // const ctx = { - // args: { - // chassis: 'CH12345', - // } - // }; + it('should return the vehicles matching "chassis"', async() => { + const {chassis} = await models.Vehicle.findById(1, null, options); + ctx.args = {chassis}; + const [searchResult] = await models.Vehicle.filter(ctx); - // const result = await models.Vehicle.filter(ctx); + expect(searchResult.chassis).toEqual(chassis); + }); - // expect(result.length).toBeGreaterThan(0); - // expect(result[0].chassis).toEqual('CH12345'); - // }); + it('should return the vehicles matching "leasing"', async() => { + const leasing = 'Wayne leasing'; + ctx.args = {leasing}; + const searchResult = await models.Vehicle.filter(ctx); + searchResult.forEach(record => { + expect(record.leasing).toEqual(leasing); + }); + }); - // it('should return the vehicles matching "leasing"', async() => { - // const ctx = { - // args: { - // leasing: 'LeasingCompany', - // } - // }; + it('should return the vehicles matching "countryCodeFk"', async() => { + const countryCodeFk = 'ES'; + ctx.args = {countryCodeFk}; - // const result = await models.Vehicle.filter(ctx); + const searchResult = await models.Vehicle.filter(ctx); + searchResult.forEach(record => { + expect(record.countryCodeFk).toEqual(countryCodeFk); + }); + }); - // expect(result.length).toBeGreaterThan(0); - // expect(result[0].leasing).toEqual('LeasingCompany'); - // }); + it('should return the vehicles matching "vehicleTypeFk"', async() => { + const {name, id} = await models.VehicleType.findById(1, null, options); + ctx.args = {vehicleTypeFk: id}; - // it('should return the vehicles matching "countryCodeFk"', async() => { - // const ctx = { - // args: { - // countryCodeFk: 'US', - // } - // }; + const searchResult = await models.Vehicle.filter(ctx); + searchResult.forEach(record => { + expect(record.type).toEqual(name); + }); + }); - // const result = await models.Vehicle.filter(ctx); + it('should return the vehicles matching "vehicleStateFk"', async() => { + const {state, id} = await models.VehicleState.findById(3); + ctx.args = {vehicleStateFk: id}; - // expect(result.length).toBeGreaterThan(0); - // expect(result[0].countryCodeFk).toEqual('US'); - // }); + const searchResult = await models.Vehicle.filter(ctx); + searchResult.forEach(record => { + expect(record.state).toEqual(state); + }); + }); - // it('should return the vehicles matching "vehicleTypeFk"', async() => { - // const ctx = { - // args: { - // vehicleTypeFk: 3, - // } - // }; + it('should return the vehicles matching "description"', async() => { + const {description} = await models.Vehicle.findById(2); + ctx.args = {description}; - // const result = await models.Vehicle.filter(ctx); - - // expect(result.length).toBeGreaterThan(0); - // expect(result[0].vehicleTypeFk).toEqual(3); - // }); + const searchResult = await models.Vehicle.filter(ctx); + searchResult.forEach(record => { + expect(record.description).toEqual(description); + }); + }); }); From fb653c1eca52d3563e5d31d04283d4b28ec7363a Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 24 Jan 2025 16:42:10 +0100 Subject: [PATCH 47/84] fix: refs #7119 rollback --- modules/route/back/methods/vehicle/filter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index fa0b847580..ef87c1448e 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -71,6 +71,8 @@ module.exports = Self => { return /^\d+$/.test(value) ? {'v.id': value} : {numberPlate: {like: `%${value}%`}}; + case 'id': + return {'v.id': value}; case 'description': case 'tradeMark': case 'numberPlate': From 609df986148c5e9e7e526cb8a076ea29d7247d0f Mon Sep 17 00:00:00 2001 From: guillermo Date: Mon, 27 Jan 2025 09:02:37 +0100 Subject: [PATCH 48/84] feat: refs #8227 Added grants --- db/versions/11416-goldenTulip/06-firstScript.sql | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 db/versions/11416-goldenTulip/06-firstScript.sql diff --git a/db/versions/11416-goldenTulip/06-firstScript.sql b/db/versions/11416-goldenTulip/06-firstScript.sql new file mode 100644 index 0000000000..58563cfd5b --- /dev/null +++ b/db/versions/11416-goldenTulip/06-firstScript.sql @@ -0,0 +1,10 @@ +GRANT SELECT ON TABLE vn.roadmap TO 'delivery'; +GRANT SELECT ON TABLE vn.roadmapStop TO 'delivery'; +GRANT SELECT ON TABLE vn.roadmapAddress TO 'delivery'; + +GRANT DELETE, UPDATE, INSERT ON TABLE vn.roadmap TO 'deliveryBoss'; +GRANT DELETE, UPDATE, INSERT ON TABLE vn.roadmapStop TO 'deliveryBoss'; +GRANT DELETE, UPDATE, INSERT ON TABLE vn.roadmapAddress TO 'deliveryBoss'; + +GRANT EXECUTE ON PROCEDURE vn.roadmap_cloneDay TO 'deliveryBoss'; +GRANT EXECUTE ON FUNCTION vn.getTimeBetweenRoadmapAddresses TO 'deliveryBoss'; From 75168eef91c723d99b369c7afe0dca174bad0d4d Mon Sep 17 00:00:00 2001 From: guillermo Date: Mon, 27 Jan 2025 11:04:34 +0100 Subject: [PATCH 49/84] feat: refs #8227 Roadmap changes --- db/routines/vn/procedures/roadmap_cloneDay.sql | 2 +- db/routines/vn/triggers/roadmap_beforeInsert.sql | 3 +++ db/routines/vn/triggers/roadmap_beforeUpdate.sql | 3 +++ db/versions/11416-goldenTulip/01-firstScript.sql | 4 +++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/db/routines/vn/procedures/roadmap_cloneDay.sql b/db/routines/vn/procedures/roadmap_cloneDay.sql index 51d6ba1aba..4247b881e8 100644 --- a/db/routines/vn/procedures/roadmap_cloneDay.sql +++ b/db/routines/vn/procedures/roadmap_cloneDay.sql @@ -22,7 +22,7 @@ BEGIN SET vDaysDiff = DATEDIFF(vDateToPaste, vDateToCopy); - IF vDaysDiff IS NULL OR NOT vDaysDiff THEN + IF vDaysDiff IS NULL THEN CALL util.throw("No valid dates"); END IF; diff --git a/db/routines/vn/triggers/roadmap_beforeInsert.sql b/db/routines/vn/triggers/roadmap_beforeInsert.sql index 9e783e711c..1f046ec143 100644 --- a/db/routines/vn/triggers/roadmap_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmap_beforeInsert.sql @@ -8,5 +8,8 @@ BEGIN CALL util.throw('Departure time can not be after arrival time'); END IF; SET NEW.name = UCASE(NEW.name); + IF NEW.`trailerPlate` IS NOT NULL THEN + SET NEW.m3 = (SELECT m3 FROM vehicle WHERE numberPlate = NEW.trailerPlate); + END IF; END$$ DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/triggers/roadmap_beforeUpdate.sql b/db/routines/vn/triggers/roadmap_beforeUpdate.sql index 4824170ec4..45b0d5e9e0 100644 --- a/db/routines/vn/triggers/roadmap_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmap_beforeUpdate.sql @@ -8,5 +8,8 @@ BEGIN CALL util.throw('Departure time can not be after arrival time'); END IF; SET NEW.name = UCASE(NEW.name); + IF NOT (NEW.`trailerPlate` <=> OLD.`trailerPlate`) THEN + SET NEW.m3 = (SELECT m3 FROM vehicle WHERE numberPlate = NEW.trailerPlate); + END IF; END$$ DELIMITER ; \ No newline at end of file diff --git a/db/versions/11416-goldenTulip/01-firstScript.sql b/db/versions/11416-goldenTulip/01-firstScript.sql index 0cd7942297..9fa580ef90 100644 --- a/db/versions/11416-goldenTulip/01-firstScript.sql +++ b/db/versions/11416-goldenTulip/01-firstScript.sql @@ -11,4 +11,6 @@ ALTER TABLE vn.roadmap ALTER TABLE vn.roadmap CHANGE driver1Fk driverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Conductor principal' AFTER driverName, CHANGE driver2Fk codriverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Copiloto' AFTER driverFk, - CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER m3; \ No newline at end of file + CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER m3; + +CREATE INDEX roadmap_etd_IDX USING BTREE ON vn.roadmap (etd); From a29de13ab364425732847e91c055d12f3d3f689b Mon Sep 17 00:00:00 2001 From: sergiodt Date: Tue, 28 Jan 2025 09:54:26 +0100 Subject: [PATCH 50/84] fix: refs #7569 saveSign use smtp.send and fix link --- loopback/locale/en.json | 2 +- loopback/locale/es.json | 2 +- loopback/locale/fr.json | 2 +- loopback/locale/pt.json | 2 +- .../ticket/back/methods/ticket/saveSign.js | 51 +++++++++---------- .../methods/ticket/specs/saveSign.spec.js | 2 +- 6 files changed, 29 insertions(+), 32 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 06428475fc..eeb32f545e 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -253,5 +253,5 @@ "Sales already moved": "Sales already moved", "Holidays to past days not available": "Holidays to past days not available", "Incorrect delivery order alert on route": "Incorrect delivery order alert on route: {{ route }} zone: {{ zone }}", - "Ticket has been delivered out of order": "The ticket {{ticket}} {{{fullUrl}}} has been delivered out of order." + "Ticket has been delivered out of order": "The ticket {{ticket}} of route {{{fullUrl}}} has been delivered out of order." } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index abd2f79a0d..2ead6fa105 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -395,6 +395,6 @@ "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", "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 sigo entregado en su orden.", + "Ticket has been delivered out of order": "El ticket {{ticket}} de la ruta {{{fullUrl}}} no ha sigo entregado en su orden.", "Price cannot be blank": "El precio no puede estar en blanco" } \ No newline at end of file diff --git a/loopback/locale/fr.json b/loopback/locale/fr.json index d7d5b7710e..378b0d2671 100644 --- a/loopback/locale/fr.json +++ b/loopback/locale/fr.json @@ -368,5 +368,5 @@ "ticketLostExpedition": "Le ticket [{{ticketId}}]({{{ticketUrl}}}) a l'expédition perdue suivante : {{expeditionId}}", "The web user's email already exists": "L'email de l'internaute existe déjà", "Incorrect delivery order alert on route": "Alerte de bon de livraison incorrect sur l'itinéraire: {{ route }} zone : {{ zone }}", - "Ticket has been delivered out of order": "Le ticket {{ticket}} {{{fullUrl}}} a été livré hors ordre." + "Ticket has been delivered out of order": "Le ticket {{ticket}} de la route {{{fullUrl}}} a été livré hors service." } \ No newline at end of file diff --git a/loopback/locale/pt.json b/loopback/locale/pt.json index d1ac2ef236..35fe3d4f17 100644 --- a/loopback/locale/pt.json +++ b/loopback/locale/pt.json @@ -367,5 +367,5 @@ "ticketLostExpedition": "O ticket [{{ticketId}}]({{{ticketUrl}}}) tem a seguinte expedição perdida: {{expeditionId}}", "The web user's email already exists": "O e-mail do utilizador da web já existe.", "Incorrect delivery order alert on route": "Alerta de ordem de entrega incorreta na rota: {{ route }} zona: {{ zone }}", - "Ticket has been delivered out of order": "O ticket {{ticket}} {{{fullUrl}}} foi entregue fora de ordem." + "Ticket has been delivered out of order": "O ticket {{ticket}} da rota {{{fullUrl}}} foi entregue fora de ordem." } \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/saveSign.js b/modules/ticket/back/methods/ticket/saveSign.js index f99311c392..93202d042f 100644 --- a/modules/ticket/back/methods/ticket/saveSign.js +++ b/modules/ticket/back/methods/ticket/saveSign.js @@ -1,4 +1,5 @@ const UserError = require('vn-loopback/util/user-error'); +const smtp = require('vn-print/core/smtp'); module.exports = Self => { Self.remoteMethodCtx('saveSign', { @@ -31,6 +32,7 @@ module.exports = Self => { Self.saveSign = async(ctx, tickets, location, signedTime, options) => { const models = Self.app.models; const myOptions = {userId: ctx.req.accessToken.userId}; + const url = await Self.app.models.Url.getUrl('lilium'); let tx; let ticket; let dms; @@ -146,11 +148,11 @@ module.exports = Self => { await ticket.updateAttribute('isSigned', true, myOptions); const [{stateCode}] = await Self.rawSql(` - SELECT + SELECT IF((SUM(CASE WHEN est.code = 'DELIVERED' THEN 1 ELSE 0 END) = COUNT(*)), 'DELIVERED','PARTIAL_DELIVERED') stateCode FROM vn.expedition e - JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk + JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk WHERE e.ticketFk = ?; `, [ticketId], myOptions); @@ -167,15 +169,15 @@ module.exports = Self => { FROM ticket t JOIN ticketState ts ON ts.ticketFk = t.id JOIN state s ON s.code = ts.code - WHERE t.routeFk = ? - AND s.\`order\` < ? - AND priority <(SELECT t.priority + WHERE t.routeFk = ? + AND s.\`order\` < ? + AND priority <(SELECT t.priority FROM ticket t WHERE t.id = ?)` , [ticket.routeFk, orderState.id, ticket.id], myOptions); if (ticketIncorrect?.length > 0) - await sendMail(ctx, ticket.routeFk, ticket.id, ticket.zone().name); + await sendMail(ticket.routeFk, ticket.id, ticket.zone().name); } if (ticket?.address()?.province()?.country()?.code != 'ES' && ticket.$cmrFk) { @@ -189,26 +191,21 @@ module.exports = Self => { throw e; } await models.Ticket.sendCmrEmail(ctx, externalTickets); + + async function sendMail(route, ticket, zoneName) { + const $t = ctx.req.__; + const fullUrl = `${route}`; + await smtp.send({ + to: 'repartos@verdnatura.es', + subject: $t('Incorrect delivery order alert on route', { + route, + zone: zoneName + }), + html: $t('Ticket has been delivered out of order', { + ticket, + fullUrl + }) + }); + } }; - - async function sendMail(ctx, route, ticket, zoneName) { - const $t = ctx.req.__; - const url = await Self.app.models.Url.getUrl(); - const sendTo = 'repartos@verdnatura.es'; - const fullUrl = `${url}route/${route}/summary`; - const emailSubject = $t('Incorrect delivery order alert on route', { - route, - zone: zoneName - }); - const emailBody = $t('Ticket has been delivered out of order', { - ticket, - fullUrl - }); - - await Self.app.models.Mail.create({ - receiver: sendTo, - subject: emailSubject, - body: emailBody - }); - } }; diff --git a/modules/ticket/back/methods/ticket/specs/saveSign.spec.js b/modules/ticket/back/methods/ticket/specs/saveSign.spec.js index 3b426c2cf9..092ff95fdb 100644 --- a/modules/ticket/back/methods/ticket/specs/saveSign.spec.js +++ b/modules/ticket/back/methods/ticket/specs/saveSign.spec.js @@ -6,7 +6,7 @@ describe('Ticket saveSign()', () => { getLocale: () => { return 'en'; }, - __: () => {}, + __: t => t, accessToken: {userId: 9} } }; From 79ea19a36040bc9111fa8485d4e86cdbadf66873 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Tue, 28 Jan 2025 11:14:08 +0100 Subject: [PATCH 51/84] fix: refs #7569 saveSign use lastState --- modules/ticket/back/methods/ticket/saveSign.js | 13 +++++++------ .../back/methods/ticket/specs/saveSign.spec.js | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/ticket/back/methods/ticket/saveSign.js b/modules/ticket/back/methods/ticket/saveSign.js index 93202d042f..fd5a95e689 100644 --- a/modules/ticket/back/methods/ticket/saveSign.js +++ b/modules/ticket/back/methods/ticket/saveSign.js @@ -161,20 +161,21 @@ module.exports = Self => { if (stateCode == 'DELIVERED' && ticket.priority) { const orderState = await models.State.findOne({ where: {code: 'DELIVERED'}, - fields: ['id'] + fields: ['order'] }, myOptions); const ticketIncorrect = await Self.rawSql(` - SELECT t.id - FROM ticket t - JOIN ticketState ts ON ts.ticketFk = t.id - JOIN state s ON s.code = ts.code + SELECT tls.ticketFk + FROM ticketLastState tls + JOIN ticketTracking tt ON tt.id = tls.ticketTrackingFk + JOIN ticket t ON t.id = tt.ticketFk + JOIN state s ON s.id = tt.stateFk WHERE t.routeFk = ? AND s.\`order\` < ? AND priority <(SELECT t.priority FROM ticket t WHERE t.id = ?)` - , [ticket.routeFk, orderState.id, ticket.id], myOptions); + , [ticket.routeFk, orderState.order, ticket.id], myOptions); if (ticketIncorrect?.length > 0) await sendMail(ticket.routeFk, ticket.id, ticket.zone().name); diff --git a/modules/ticket/back/methods/ticket/specs/saveSign.spec.js b/modules/ticket/back/methods/ticket/specs/saveSign.spec.js index 092ff95fdb..66ab39d0da 100644 --- a/modules/ticket/back/methods/ticket/specs/saveSign.spec.js +++ b/modules/ticket/back/methods/ticket/specs/saveSign.spec.js @@ -60,7 +60,7 @@ describe('Ticket saveSign()', () => { expect(ticketTrackingAfter.name).toBe('Entregado en parte'); }); - it('should send an email to notify that the delivery order is not correct', async() => { + fit('should send an email to notify that the delivery order is not correct', async() => { const tx = await models.Ticket.beginTransaction({}); const ticketFk = 8; const priority = 5; From 3f0f155113b8c8f7c1d0da37a611584e636af154 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Tue, 28 Jan 2025 11:15:29 +0100 Subject: [PATCH 52/84] fix: refs #7569 saveSign use lastState --- modules/ticket/back/methods/ticket/specs/saveSign.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket/specs/saveSign.spec.js b/modules/ticket/back/methods/ticket/specs/saveSign.spec.js index 66ab39d0da..092ff95fdb 100644 --- a/modules/ticket/back/methods/ticket/specs/saveSign.spec.js +++ b/modules/ticket/back/methods/ticket/specs/saveSign.spec.js @@ -60,7 +60,7 @@ describe('Ticket saveSign()', () => { expect(ticketTrackingAfter.name).toBe('Entregado en parte'); }); - fit('should send an email to notify that the delivery order is not correct', async() => { + it('should send an email to notify that the delivery order is not correct', async() => { const tx = await models.Ticket.beginTransaction({}); const ticketFk = 8; const priority = 5; From 1575c509d13e952067d6e219820aaf9d68059bd2 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Tue, 28 Jan 2025 11:19:45 +0100 Subject: [PATCH 53/84] fix: refs #7569 saveSign use lastState --- .../ticket/back/methods/ticket/saveSign.js | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/ticket/back/methods/ticket/saveSign.js b/modules/ticket/back/methods/ticket/saveSign.js index fd5a95e689..d619e20379 100644 --- a/modules/ticket/back/methods/ticket/saveSign.js +++ b/modules/ticket/back/methods/ticket/saveSign.js @@ -166,16 +166,16 @@ module.exports = Self => { const ticketIncorrect = await Self.rawSql(` SELECT tls.ticketFk - FROM ticketLastState tls - JOIN ticketTracking tt ON tt.id = tls.ticketTrackingFk - JOIN ticket t ON t.id = tt.ticketFk - JOIN state s ON s.id = tt.stateFk - WHERE t.routeFk = ? - AND s.\`order\` < ? - AND priority <(SELECT t.priority - FROM ticket t - WHERE t.id = ?)` - , [ticket.routeFk, orderState.order, ticket.id], myOptions); + FROM ticketLastState tls + JOIN ticketTracking tt ON tt.id = tls.ticketTrackingFk + JOIN ticket t ON t.id = tt.ticketFk + JOIN state s ON s.id = tt.stateFk + WHERE t.routeFk = ? + AND s.\`order\` < ? + AND priority < (SELECT priority + FROM ticket + WHERE id = ?) + `, [ticket.routeFk, orderState.order, ticket.id], myOptions); if (ticketIncorrect?.length > 0) await sendMail(ticket.routeFk, ticket.id, ticket.zone().name); From 051c6ffcbc7649e63e3d866d6da4c7f34f20db3e Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 28 Jan 2025 12:23:24 +0100 Subject: [PATCH 54/84] refactor(vehicle filter): refs #7119 simplify search condition to use logical OR for ID and number plate --- modules/route/back/methods/vehicle/filter.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/route/back/methods/vehicle/filter.js b/modules/route/back/methods/vehicle/filter.js index ef87c1448e..cb55f5f3ca 100644 --- a/modules/route/back/methods/vehicle/filter.js +++ b/modules/route/back/methods/vehicle/filter.js @@ -68,9 +68,7 @@ module.exports = Self => { const where = buildFilter(ctx.args, (param, value) => { switch (param) { case 'search': - return /^\d+$/.test(value) - ? {'v.id': value} - : {numberPlate: {like: `%${value}%`}}; + return {or: [{'v.id': value}, {numberPlate: {like: `%${value}%`}}]}; case 'id': return {'v.id': value}; case 'description': From 56b0baebaa28e4b6054044e9493e3b0d0aeaea33 Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 29 Jan 2025 07:53:41 +0100 Subject: [PATCH 55/84] feat: refs #8227 Roadmap changes --- db/dump/fixtures.before.sql | 16 ++++++++-------- db/versions/11416-goldenTulip/06-firstScript.sql | 5 +++-- db/versions/11416-goldenTulip/07-firstScript.sql | 2 ++ modules/route/back/models/route.json | 7 +------ 4 files changed, 14 insertions(+), 16 deletions(-) create mode 100644 db/versions/11416-goldenTulip/07-firstScript.sql diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index eb11264e70..a1e6fbcc3a 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -745,15 +745,15 @@ INSERT INTO `vn`.`zoneClosure` (`zoneFk`, `dated`, `hour`) INSERT INTO `vn`.`zoneConfig` (`id`, `scope`) VALUES (1, '1'); -INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`, `zoneFk`, `dated`) +INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`, `dated`) VALUES - (1, '1899-12-30 12:15:00', 56, util.VN_CURDATE(), 1, 1, 'first route', 1.8, 10, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1, util.VN_CURDATE()), - (2, '1899-12-30 13:20:00', 56, util.VN_CURDATE(), 1, 2, 'second route', 0.2, 20, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 9, util.VN_CURDATE()), - (3, '1899-12-30 14:30:00', 56, util.VN_CURDATE(), 2, 3, 'third route', 0.5, 30, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 10, util.VN_CURDATE()), - (4, '1899-12-30 15:45:00', 56, util.VN_CURDATE(), 3, 4, 'fourth route', 0, 40, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 12, util.VN_CURDATE()), - (5, '1899-12-30 16:00:00', 56, util.VN_CURDATE(), 4, 5, 'fifth route', 0.1, 50, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 13, util.VN_CURDATE()), - (6, NULL, 57, util.VN_CURDATE(), 5, 7, 'sixth route', 1.7, 60, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 3, util.VN_CURDATE()), - (7, NULL, 57, util.VN_CURDATE(), 6, 8, 'seventh route', 0, 70, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 5, util.VN_CURDATE()); + (1, '1899-12-30 12:15:00', 56, util.VN_CURDATE(), 1, 1, 'first route', 1.8, 10, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), + (2, '1899-12-30 13:20:00', 56, util.VN_CURDATE(), 1, 2, 'second route', 0.2, 20, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), + (3, '1899-12-30 14:30:00', 56, util.VN_CURDATE(), 2, 3, 'third route', 0.5, 30, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), + (4, '1899-12-30 15:45:00', 56, util.VN_CURDATE(), 3, 4, 'fourth route', 0, 40, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), + (5, '1899-12-30 16:00:00', 56, util.VN_CURDATE(), 4, 5, 'fifth route', 0.1, 50, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), + (6, NULL, 57, util.VN_CURDATE(), 5, 7, 'sixth route', 1.7, 60, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), + (7, NULL, 57, util.VN_CURDATE(), 6, 8, 'seventh route', 0, 70, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()); INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `zonePrice`, `zoneBonus`, `created`, `weight`, `cmrFk`, `problem`, `risk`) VALUES diff --git a/db/versions/11416-goldenTulip/06-firstScript.sql b/db/versions/11416-goldenTulip/06-firstScript.sql index 58563cfd5b..82de52c674 100644 --- a/db/versions/11416-goldenTulip/06-firstScript.sql +++ b/db/versions/11416-goldenTulip/06-firstScript.sql @@ -6,5 +6,6 @@ GRANT DELETE, UPDATE, INSERT ON TABLE vn.roadmap TO 'deliveryBoss'; GRANT DELETE, UPDATE, INSERT ON TABLE vn.roadmapStop TO 'deliveryBoss'; GRANT DELETE, UPDATE, INSERT ON TABLE vn.roadmapAddress TO 'deliveryBoss'; -GRANT EXECUTE ON PROCEDURE vn.roadmap_cloneDay TO 'deliveryBoss'; -GRANT EXECUTE ON FUNCTION vn.getTimeBetweenRoadmapAddresses TO 'deliveryBoss'; +-- Comentado debido a que da error porque ejecuta primero el script de la versión +-- GRANT EXECUTE ON PROCEDURE vn.roadmap_cloneDay TO 'deliveryBoss'; +-- GRANT EXECUTE ON FUNCTION vn.getTimeBetweenRoadmapAddresses TO 'deliveryBoss'; diff --git a/db/versions/11416-goldenTulip/07-firstScript.sql b/db/versions/11416-goldenTulip/07-firstScript.sql new file mode 100644 index 0000000000..13cb9df894 --- /dev/null +++ b/db/versions/11416-goldenTulip/07-firstScript.sql @@ -0,0 +1,2 @@ +ALTER TABLE vn.route DROP FOREIGN KEY fk_route_1; +ALTER TABLE vn.route DROP COLUMN zoneFk; diff --git a/modules/route/back/models/route.json b/modules/route/back/models/route.json index 8f4eab7611..9483525718 100644 --- a/modules/route/back/models/route.json +++ b/modules/route/back/models/route.json @@ -75,11 +75,6 @@ "type": "hasMany", "model": "Ticket", "foreignKey": "routeFk" - }, - "zone": { - "type": "belongsTo", - "model": "Zone", - "foreignKey": "zoneFk" - } + } } } From 9a6b89793c7eba0a3fab6967314917a1091a8478 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Wed, 29 Jan 2025 10:35:06 +0100 Subject: [PATCH 56/84] fix: refs #8494 Fix ZoneIncluded logs --- db/routines/vn/triggers/zoneIncluded_afterDelete.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/db/routines/vn/triggers/zoneIncluded_afterDelete.sql b/db/routines/vn/triggers/zoneIncluded_afterDelete.sql index 2990626cad..d3caedb13f 100644 --- a/db/routines/vn/triggers/zoneIncluded_afterDelete.sql +++ b/db/routines/vn/triggers/zoneIncluded_afterDelete.sql @@ -6,8 +6,7 @@ BEGIN INSERT INTO zoneLog SET `action` = 'delete', `changedModel` = 'zoneIncluded', - `changedModelId` = OLD.zoneFk, + `changedModelId` = OLD.id, `userFk` = account.myUser_getId(); - END$$ DELIMITER ; From f088f1776fa5e30b0887f46fb95e4dd0fdb16d6c Mon Sep 17 00:00:00 2001 From: Jon Date: Wed, 29 Jan 2025 10:45:29 +0100 Subject: [PATCH 57/84] fix: fixed manual invoice --- .../invoiceOut/back/methods/invoiceOut/createManualInvoice.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js index a06128848a..c4e336818a 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js @@ -109,7 +109,8 @@ module.exports = Self => { where: { clientFk: clientFk, shipped: {lte: maxShipped} - } + }, + order: 'shipped DESC' }, myOptions); companyFk = company.companyFk; } From a14d6227a11d7384483eb28c5a1d382b470203c3 Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 29 Jan 2025 14:15:22 +0100 Subject: [PATCH 58/84] feat: refs #8227 Roadmap changes --- .../getTimeBetweenRoadmapAddresses.sql | 41 ++++++++++++++--- .../vn/triggers/roadmap_afterUpdate.sql | 17 +++++++ .../vn/triggers/roadmap_beforeInsert.sql | 26 +++++++++-- .../vn/triggers/roadmap_beforeUpdate.sql | 45 +++++++++++++++++-- .../11416-goldenTulip/01-firstScript.sql | 12 +++-- .../11416-goldenTulip/02-firstScript.sql | 6 ++- .../11416-goldenTulip/08-firstScript.sql | 2 + 7 files changed, 130 insertions(+), 19 deletions(-) create mode 100644 db/routines/vn/triggers/roadmap_afterUpdate.sql create mode 100644 db/versions/11416-goldenTulip/08-firstScript.sql diff --git a/db/routines/vn/functions/getTimeBetweenRoadmapAddresses.sql b/db/routines/vn/functions/getTimeBetweenRoadmapAddresses.sql index 5a647d51b7..354aeb835f 100644 --- a/db/routines/vn/functions/getTimeBetweenRoadmapAddresses.sql +++ b/db/routines/vn/functions/getTimeBetweenRoadmapAddresses.sql @@ -16,19 +16,46 @@ BEGIN */ DECLARE vSeconds INT; - WITH wRoadmap AS ( + WITH wRoadmapStop AS ( SELECT ROW_NUMBER() OVER(PARTITION BY roadmapFk ORDER BY eta) `sequence`, roadmapFk, roadmapAddressFk, eta FROM vn.roadmapStop + WHERE roadmapFk IS NOT NULL + AND roadmapAddressFk IS NOT NULL + AND eta IS NOT NULL ) - SELECT AVG(TIME_TO_SEC(TIMEDIFF(rTo.eta, rFrom.eta))) INTO vSeconds - FROM wRoadmap rFrom - JOIN wRoadmap rTo ON rTo.roadmapFk = rFrom.roadmapFk - WHERE rFrom.roadmapAddressFk = vRoadmapAddressFrom - AND rTo.roadmapAddressFk = vRoadmapAddressTo - AND rFrom.`sequence` + 1 = rTo.`sequence`; + SELECT AVG(TIME_TO_SEC(TIMEDIFF(rsTo.eta, rsFrom.eta))) INTO vSeconds + FROM wRoadmapStop rsFrom + JOIN wRoadmapStop rsTo ON rsTo.roadmapFk = rsFrom.roadmapFk + WHERE rsFrom.roadmapAddressFk = vRoadmapAddressFrom + AND rsTo.roadmapAddressFk = vRoadmapAddressTo + AND rsFrom.`sequence` + 1 = rsTo.`sequence`; + + IF NOT IFNULL(vSeconds, 0) THEN + WITH wRoadmap AS ( + SELECT id, + roadmapAddressFk, + etd + FROM vn.roadmap + WHERE roadmapAddressFk = vRoadmapAddressFrom + AND etd IS NOT NULL + ), wRoadmapStop AS ( + SELECT ROW_NUMBER() OVER(PARTITION BY roadmapFk ORDER BY eta) `sequence`, + roadmapFk, + roadmapAddressFk, + eta + FROM vn.roadmapStop + WHERE roadmapFk IS NOT NULL + AND roadmapAddressFk = vRoadmapAddressTo + AND eta IS NOT NULL + ) + SELECT AVG(TIME_TO_SEC(TIMEDIFF(rsTo.eta, rFrom.etd))) INTO vSeconds + FROM wRoadmap rFrom + JOIN wRoadmapStop rsTo ON rsTo.roadmapFk = rFrom.id + AND rsTo.`sequence` = 1; + END IF; RETURN vSeconds; END$$ diff --git a/db/routines/vn/triggers/roadmap_afterUpdate.sql b/db/routines/vn/triggers/roadmap_afterUpdate.sql new file mode 100644 index 0000000000..7fcc31d922 --- /dev/null +++ b/db/routines/vn/triggers/roadmap_afterUpdate.sql @@ -0,0 +1,17 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_afterUpdate` + AFTER UPDATE ON `roadmap` + FOR EACH ROW +BEGIN + DECLARE vSeconds INT; + + IF NOT (NEW.etd <=> OLD.etd) THEN + SET vSeconds = TIME_TO_SEC(TIMEDIFF(NEW.etd, OLD.etd)); + IF vSeconds IS NOT NULL AND vSeconds <> 0 THEN + UPDATE roadmapStop + SET eta = eta + INTERVAL vSeconds SECOND + WHERE roadmapFk = NEW.id; + END IF; + END IF; +END$$ +DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/triggers/roadmap_beforeInsert.sql b/db/routines/vn/triggers/roadmap_beforeInsert.sql index 1f046ec143..a9b837e6b9 100644 --- a/db/routines/vn/triggers/roadmap_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmap_beforeInsert.sql @@ -4,12 +4,32 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_beforeInsert` FOR EACH ROW BEGIN SET NEW.editorFk = account.myUser_getId(); - IF NEW.etd > NEW.eta THEN + + IF NEW.name IS NOT NULL THEN + SET NEW.name = UCASE(NEW.name); + END IF; + + IF NEW.etd > NEW.eta AND NEW.etd IS NOT NULL AND NEW.eta IS NOT NULL THEN CALL util.throw('Departure time can not be after arrival time'); END IF; - SET NEW.name = UCASE(NEW.name); - IF NEW.`trailerPlate` IS NOT NULL THEN + + IF NEW.trailerPlate IS NOT NULL THEN SET NEW.m3 = (SELECT m3 FROM vehicle WHERE numberPlate = NEW.trailerPlate); END IF; + + IF NEW.tugPlate IS NOT NULL THEN + SET NEW.m3 = NEW.m3 + (SELECT m3 FROM vehicle WHERE numberPlate = NEW.tugPlate); + END IF; + + IF NEW.driver1Fk IS NOT NULL THEN + SET NEW.driverName = (SELECT CONCAT(w.firstName, ' ', w.lastName) + FROM worker w + WHERE w.id = NEW.driver1Fk); + + SET NEW.phone = (SELECT COALESCE(w.phone, c.mobile, c.phone, c.mobile) + FROM worker w + LEFT JOIN client c ON c.id = w.id + WHERE w.id = NEW.driver1Fk); + END IF; END$$ DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/triggers/roadmap_beforeUpdate.sql b/db/routines/vn/triggers/roadmap_beforeUpdate.sql index 45b0d5e9e0..46065129d1 100644 --- a/db/routines/vn/triggers/roadmap_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmap_beforeUpdate.sql @@ -4,12 +4,51 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_beforeUpdate` FOR EACH ROW BEGIN SET NEW.editorFk = account.myUser_getId(); - IF NEW.etd > NEW.eta THEN + + IF NOT (NEW.name <=> OLD.name) THEN + SET NEW.name = UCASE(NEW.name); + END IF; + + IF NEW.etd > NEW.eta AND NEW.etd IS NOT NULL AND NEW.eta IS NOT NULL THEN CALL util.throw('Departure time can not be after arrival time'); END IF; - SET NEW.name = UCASE(NEW.name); - IF NOT (NEW.`trailerPlate` <=> OLD.`trailerPlate`) THEN + + IF NOT (NEW.trailerPlate <=> OLD.trailerPlate) THEN SET NEW.m3 = (SELECT m3 FROM vehicle WHERE numberPlate = NEW.trailerPlate); END IF; + + IF NOT (NEW.tugPlate <=> OLD.tugPlate) THEN + SET NEW.m3 = NEW.m3 + (SELECT m3 FROM vehicle WHERE numberPlate = NEW.tugPlate); + END IF; + + IF NOT (NEW.driverName <=> OLD.driverName) THEN + SET NEW.driver1Fk = NULL; + END IF; + + IF NOT (NEW.driver1Fk <=> OLD.driver1Fk) AND NEW.driver1Fk IS NOT NULL THEN + SET NEW.driverName = (SELECT CONCAT(w.firstName, ' ', w.lastName) + FROM worker w + WHERE w.id = NEW.driver1Fk); + + SET NEW.phone = (SELECT COALESCE(w.phone, c.mobile, c.phone, c.mobile) + FROM worker w + LEFT JOIN client c ON c.id = w.id + WHERE w.id = NEW.driver1Fk); + END IF; + + IF NOT (NEW.driverChangeName <=> OLD.driverChangeName) THEN + SET NEW.driverChangeFk = NULL; + END IF; + + IF NOT (NEW.driverChangeFk <=> OLD.driverChangeFk) AND NEW.driverChangeFk IS NOT NULL THEN + SET NEW.driverChangeName = (SELECT CONCAT(w.firstName, ' ', w.lastName) + FROM worker w + WHERE w.id = NEW.driverChangeFk); + + SET NEW.phone = (SELECT COALESCE(w.phone, c.mobile, c.phone, c.mobile) + FROM worker w + LEFT JOIN client c ON c.id = w.id + WHERE w.id = NEW.driverChangeFk); + END IF; END$$ DELIMITER ; \ No newline at end of file diff --git a/db/versions/11416-goldenTulip/01-firstScript.sql b/db/versions/11416-goldenTulip/01-firstScript.sql index 9fa580ef90..565bf0f555 100644 --- a/db/versions/11416-goldenTulip/01-firstScript.sql +++ b/db/versions/11416-goldenTulip/01-firstScript.sql @@ -4,13 +4,17 @@ ALTER TABLE vn.roadmap MODIFY COLUMN trailerPlate varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL NULL, MODIFY COLUMN etd datetime NOT NULL COMMENT 'Tiempo estimado de salida', MODIFY COLUMN `name` varchar(45) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL, - ADD eta datetime NOT NULL COMMENT 'Tiempo estimado de llegada' AFTER etd, - ADD roadmapAddressFk int(11) NOT NULL AFTER `name`; + MODIFY COLUMN driver1Fk int(10) unsigned DEFAULT NULL NULL AFTER driverName, + MODIFY COLUMN driver2Fk int(10) unsigned DEFAULT NULL NULL AFTER driver1Fk, + ADD eta datetime DEFAULT NULL NULL COMMENT 'Tiempo estimado de llegada' AFTER etd, + ADD roadmapAddressFk int(11) DEFAULT NULL NULL AFTER `name`, + ADD dollyPlate varchar(10) DEFAULT NULL AFTER trailerPlate, + ADD tugPlate varchar(10) DEFAULT NULL AFTER dollyPlate, + ADD driverChangeName varchar(45) DEFAULT NULL AFTER driver2Fk, + ADD driverChangeFk int(10) unsigned DEFAULT NULL NULL AFTER driverChangeName; -- Separamos los CHANGE por que si no arriba no se aplican ALTER TABLE vn.roadmap - CHANGE driver1Fk driverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Conductor principal' AFTER driverName, - CHANGE driver2Fk codriverFk int(10) unsigned DEFAULT NULL NULL COMMENT 'Copiloto' AFTER driverFk, CHANGE userFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER m3; CREATE INDEX roadmap_etd_IDX USING BTREE ON vn.roadmap (etd); diff --git a/db/versions/11416-goldenTulip/02-firstScript.sql b/db/versions/11416-goldenTulip/02-firstScript.sql index f99334e9b9..c729c3de2f 100644 --- a/db/versions/11416-goldenTulip/02-firstScript.sql +++ b/db/versions/11416-goldenTulip/02-firstScript.sql @@ -5,9 +5,11 @@ UPDATE vn.roadmap ALTER TABLE vn.roadmap ADD CONSTRAINT roadmap_roadmapAddress_FK FOREIGN KEY (roadmapAddressFk) REFERENCES vn.roadmapAddress(addressFk) ON DELETE RESTRICT ON UPDATE CASCADE, - ADD CONSTRAINT roadmap_driver_FK FOREIGN KEY (driverFk) + ADD CONSTRAINT roadmap_driver_FK FOREIGN KEY (driver1Fk) REFERENCES vn.worker(id) ON DELETE RESTRICT ON UPDATE CASCADE, - ADD CONSTRAINT roadmap_driver_FK2 FOREIGN KEY (codriverFk) + ADD CONSTRAINT roadmap_driver_FK2 FOREIGN KEY (driver2Fk) + REFERENCES vn.worker(id) ON DELETE RESTRICT ON UPDATE CASCADE, + ADD CONSTRAINT roadmap_driverChange_FK FOREIGN KEY (driverChangeFk) REFERENCES vn.worker(id) ON DELETE RESTRICT ON UPDATE CASCADE, ADD CONSTRAINT roadmap_user_Fk FOREIGN KEY (editorFk) REFERENCES account.user(id) ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/db/versions/11416-goldenTulip/08-firstScript.sql b/db/versions/11416-goldenTulip/08-firstScript.sql new file mode 100644 index 0000000000..a7fdd5b86e --- /dev/null +++ b/db/versions/11416-goldenTulip/08-firstScript.sql @@ -0,0 +1,2 @@ +ALTER TABLE vn.vehicle + ADD typeFk enum('car','van','truck','trailer','tug', 'tugDolly','dolly') DEFAULT 'van' NOT NULL; From c96d083467a152c6030083330d86bdb0894e2d04 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Thu, 30 Jan 2025 09:16:54 +0100 Subject: [PATCH 59/84] fix: refs #7920 shelvingFkByCode --- db/routines/vn/procedures/itemShelving_inventory.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/routines/vn/procedures/itemShelving_inventory.sql b/db/routines/vn/procedures/itemShelving_inventory.sql index 9ae96c7a89..b2179f4f84 100644 --- a/db/routines/vn/procedures/itemShelving_inventory.sql +++ b/db/routines/vn/procedures/itemShelving_inventory.sql @@ -24,7 +24,7 @@ BEGIN SELECT ish.id, p.pickingOrder, p.code parking, - ish.shelvingFk, + sh.code, ish.itemFk, i.longName, ish.visible, From 123f28055e265645c70b2ef65210a113d0295834 Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 30 Jan 2025 09:28:44 +0100 Subject: [PATCH 60/84] feat: refs #8227 Roadmap changes --- db/routines/vn/triggers/roadmap_beforeInsert.sql | 14 ++++++++------ db/routines/vn/triggers/roadmap_beforeUpdate.sql | 13 ++----------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/db/routines/vn/triggers/roadmap_beforeInsert.sql b/db/routines/vn/triggers/roadmap_beforeInsert.sql index a9b837e6b9..bfbb4f8792 100644 --- a/db/routines/vn/triggers/roadmap_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmap_beforeInsert.sql @@ -13,12 +13,8 @@ BEGIN CALL util.throw('Departure time can not be after arrival time'); END IF; - IF NEW.trailerPlate IS NOT NULL THEN - SET NEW.m3 = (SELECT m3 FROM vehicle WHERE numberPlate = NEW.trailerPlate); - END IF; - - IF NEW.tugPlate IS NOT NULL THEN - SET NEW.m3 = NEW.m3 + (SELECT m3 FROM vehicle WHERE numberPlate = NEW.tugPlate); + IF NEW.trailerPlate IS NOT NULL OR NEW.tugPlate IS NOT NULL THEN + SET NEW.m3 = (SELECT SUM(m3) FROM vehicle WHERE numberPlate IN (NEW.trailerPlate, NEW.tugPlate)); END IF; IF NEW.driver1Fk IS NOT NULL THEN @@ -31,5 +27,11 @@ BEGIN LEFT JOIN client c ON c.id = w.id WHERE w.id = NEW.driver1Fk); END IF; + + IF NEW.driverChangeFk IS NOT NULL THEN + SET NEW.driverChangeName = (SELECT CONCAT(w.firstName, ' ', w.lastName) + FROM worker w + WHERE w.id = NEW.driverChangeFk); + END IF; END$$ DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/triggers/roadmap_beforeUpdate.sql b/db/routines/vn/triggers/roadmap_beforeUpdate.sql index 46065129d1..f888d3a6f0 100644 --- a/db/routines/vn/triggers/roadmap_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmap_beforeUpdate.sql @@ -13,12 +13,8 @@ BEGIN CALL util.throw('Departure time can not be after arrival time'); END IF; - IF NOT (NEW.trailerPlate <=> OLD.trailerPlate) THEN - SET NEW.m3 = (SELECT m3 FROM vehicle WHERE numberPlate = NEW.trailerPlate); - END IF; - - IF NOT (NEW.tugPlate <=> OLD.tugPlate) THEN - SET NEW.m3 = NEW.m3 + (SELECT m3 FROM vehicle WHERE numberPlate = NEW.tugPlate); + IF NOT (NEW.trailerPlate <=> OLD.trailerPlate) OR NOT (NEW.tugPlate <=> OLD.tugPlate) THEN + SET NEW.m3 = (SELECT SUM(m3) FROM vehicle WHERE numberPlate IN (NEW.trailerPlate, NEW.tugPlate)); END IF; IF NOT (NEW.driverName <=> OLD.driverName) THEN @@ -44,11 +40,6 @@ BEGIN SET NEW.driverChangeName = (SELECT CONCAT(w.firstName, ' ', w.lastName) FROM worker w WHERE w.id = NEW.driverChangeFk); - - SET NEW.phone = (SELECT COALESCE(w.phone, c.mobile, c.phone, c.mobile) - FROM worker w - LEFT JOIN client c ON c.id = w.id - WHERE w.id = NEW.driverChangeFk); END IF; END$$ DELIMITER ; \ No newline at end of file From 77623b489bbd8d3c4c56afc472ddca86dc05ab0a Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 30 Jan 2025 10:55:36 +0100 Subject: [PATCH 61/84] feat: refs #7119 add new vehicle --- db/dump/fixtures.before.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 695347d617..c409eb692f 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -863,7 +863,8 @@ INSERT INTO `vn`.`vehicle`(`id`, `numberPlate`, `tradeMark`, `model`, `companyFk (3, '2222-IMK', 'STARK INDUSTRIES', 'MARK-VI', 442, 1, 'Iron-Man Heavy Armor MARK-VI', 16, 1, 1, '', '', 442, 2, null), (4, '3333-IMK', 'STARK INDUSTRIES', 'MARK-VII', 442, 1, 'Iron-Man Heavy Armor MARK-VII', 14, 1, 1, '', '', 442, 3, null), (5, '4444-IMK', 'STARK INDUSTRIES', 'MARK-XLII', 442, 1, 'Iron-Man Heavy Armor MARK-XLII', 13, 1, 1, '', '', 442, 4, null), - (6, '5555-IMK', 'STARK INDUSTRIES', 'MARK-XLV', 442, 1, 'Iron-Man Heavy Armor MARK-XLV', 12, 0, 1, '', '', 442, 5, null); + (6, '5555-IMK', 'STARK INDUSTRIES', 'MARK-XLV', 442, 1, 'Iron-Man Heavy Armor MARK-XLV', 12, 0, 1, '', '', 442, 5, null), + (7, '5555-SHI', 'SHIELD', 'Quinjet', 442, 1, 'High-speed jet used by the Avengers', 30, 1, 1, 'QJ12345', 'SHIELD leasing', 1, 1, 1); INSERT INTO `vn`.`config`(`id`, `mdbServer`, `fakeEmail`, `defaultersMaxAmount`, `inventoried`) VALUES From 855600811e15a752a1df1c4f629f5a3ab6bacdc5 Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 30 Jan 2025 15:00:19 +0100 Subject: [PATCH 62/84] feat: refs #8227 Roadmap changes --- .../vn/triggers/roadmapStop_beforeDelete.sql | 21 ++++++++++++++++++ .../vn/triggers/roadmapStop_beforeInsert.sql | 22 +++++++++++++++++-- .../vn/triggers/roadmapStop_beforeUpdate.sql | 18 ++++++++++++++- .../vn/triggers/roadmap_beforeInsert.sql | 4 ---- .../vn/triggers/roadmap_beforeUpdate.sql | 4 ---- 5 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 db/routines/vn/triggers/roadmapStop_beforeDelete.sql diff --git a/db/routines/vn/triggers/roadmapStop_beforeDelete.sql b/db/routines/vn/triggers/roadmapStop_beforeDelete.sql new file mode 100644 index 0000000000..3449e56218 --- /dev/null +++ b/db/routines/vn/triggers/roadmapStop_beforeDelete.sql @@ -0,0 +1,21 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmapStop_beforeDelete` + BEFORE DELETE ON `roadmapStop` + FOR EACH ROW +BEGIN + DECLARE vMaxEta DATETIME; + + IF OLD.roadmapFk IS NOT NULL THEN + SELECT MAX(eta) INTO vMaxEta + FROM roadmapStop + WHERE roadmapFk = OLD.roadmapFk + AND id <> OLD.id; + + IF OLD.eta > vMaxEta OR vMaxEta IS NULL THEN + UPDATE roadmap + SET eta = COALESCE(vMaxEta, OLD.eta) + WHERE id = OLD.roadmapFk; + END IF; + END IF; +END$$ +DELIMITER ; diff --git a/db/routines/vn/triggers/roadmapStop_beforeInsert.sql b/db/routines/vn/triggers/roadmapStop_beforeInsert.sql index 9ec8b72cfa..00d17fcced 100644 --- a/db/routines/vn/triggers/roadmapStop_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmapStop_beforeInsert.sql @@ -3,12 +3,30 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmapStop_beforeInser BEFORE INSERT ON `roadmapStop` FOR EACH ROW BEGIN + DECLARE vMaxEta DATETIME; + SET NEW.editorFk = account.myUser_getId(); - SET NEW.description = UCASE(NEW.description); + + IF NEW.description IS NOT NULL THEN + SET NEW.description = UCASE(NEW.description); + END IF; + IF NEW.roadmapFk IS NOT NULL THEN IF NEW.eta < (SELECT etd FROM roadmap WHERE id = NEW.roadmapFk) THEN CALL util.throw('Departure time can not be after arrival time'); END IF; END IF; + + IF NEW.roadmapFk IS NOT NULL AND NEW.eta IS NOT NULL THEN + SELECT MAX(eta) INTO vMaxEta + FROM roadmapStop + WHERE roadmapFk = NEW.roadmapFk; + + IF NEW.eta > vMaxEta OR vMaxEta IS NOT NULL THEN + UPDATE roadmap + SET eta = GREATEST(COALESCE(vMaxEta, NEW.eta), NEW.eta) + WHERE id = NEW.roadmapFk; + END IF; + END IF; END$$ -DELIMITER ; +DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql b/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql index cff48846ae..0560ed5eb1 100644 --- a/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql @@ -3,14 +3,30 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmapStop_beforeUpdat BEFORE UPDATE ON `roadmapStop` FOR EACH ROW BEGIN + DECLARE vMaxEta DATETIME; + SET NEW.editorFk = account.myUser_getId(); - SET NEW.description = UCASE(NEW.description); + + IF NOT (NEW.description <=> OLD.description) THEN + SET NEW.description = UCASE(NEW.description); + END IF; + IF (NOT (NEW.roadmapFk <=> OLD.roadmapFk) AND NEW.roadmapFk IS NOT NULL) OR (NOT (NEW.eta <=> OLD.eta) AND NEW.eta IS NOT NULL) THEN IF NEW.eta < (SELECT etd FROM roadmap WHERE id = NEW.roadmapFk) THEN CALL util.throw('Departure time can not be after arrival time'); END IF; + + SELECT MAX(eta) INTO vMaxEta + FROM roadmapStop + WHERE roadmapFk = NEW.roadmapFk; + + IF NEW.eta > vMaxEta OR vMaxEta IS NULL THEN + UPDATE roadmap + SET eta = COALESCE(vMaxEta, NEW.eta) + WHERE id = NEW.roadmapFk; + END IF; END IF; END$$ DELIMITER ; diff --git a/db/routines/vn/triggers/roadmap_beforeInsert.sql b/db/routines/vn/triggers/roadmap_beforeInsert.sql index bfbb4f8792..4dd9e686ce 100644 --- a/db/routines/vn/triggers/roadmap_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmap_beforeInsert.sql @@ -9,10 +9,6 @@ BEGIN SET NEW.name = UCASE(NEW.name); END IF; - IF NEW.etd > NEW.eta AND NEW.etd IS NOT NULL AND NEW.eta IS NOT NULL THEN - CALL util.throw('Departure time can not be after arrival time'); - END IF; - IF NEW.trailerPlate IS NOT NULL OR NEW.tugPlate IS NOT NULL THEN SET NEW.m3 = (SELECT SUM(m3) FROM vehicle WHERE numberPlate IN (NEW.trailerPlate, NEW.tugPlate)); END IF; diff --git a/db/routines/vn/triggers/roadmap_beforeUpdate.sql b/db/routines/vn/triggers/roadmap_beforeUpdate.sql index f888d3a6f0..4f355915bc 100644 --- a/db/routines/vn/triggers/roadmap_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmap_beforeUpdate.sql @@ -9,10 +9,6 @@ BEGIN SET NEW.name = UCASE(NEW.name); END IF; - IF NEW.etd > NEW.eta AND NEW.etd IS NOT NULL AND NEW.eta IS NOT NULL THEN - CALL util.throw('Departure time can not be after arrival time'); - END IF; - IF NOT (NEW.trailerPlate <=> OLD.trailerPlate) OR NOT (NEW.tugPlate <=> OLD.tugPlate) THEN SET NEW.m3 = (SELECT SUM(m3) FROM vehicle WHERE numberPlate IN (NEW.trailerPlate, NEW.tugPlate)); END IF; From be93ea3a0713d52d005aad63e9b89984ec381a03 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Thu, 30 Jan 2025 17:55:10 +0100 Subject: [PATCH 63/84] fix: refs #6964 visibleGreaterThanZero --- .../item-shelving/getItemsByReviewOrder.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/item/back/methods/item-shelving/getItemsByReviewOrder.js b/modules/item/back/methods/item-shelving/getItemsByReviewOrder.js index 7a960a8c8f..7154565119 100644 --- a/modules/item/back/methods/item-shelving/getItemsByReviewOrder.js +++ b/modules/item/back/methods/item-shelving/getItemsByReviewOrder.js @@ -52,7 +52,9 @@ module.exports = Self => { JOIN vn.shelving sh ON sh.id = is2.shelvingFk LEFT JOIN vn.parking p ON p.id = sh.parkingFk LEFT JOIN vn.sector s ON s.id = p.sectorFk - WHERE sh.code = ? AND (? IS NULL OR is2.itemFk = ?) + WHERE sh.code = ? + AND (? IS NULL OR is2.itemFk = ?) + AND is2.visible > 0 ), itemShelvings AS ( SELECT is2.itemFk, is2.created, sh.code, p.pickingOrder, p.code AS parkingFk @@ -61,15 +63,16 @@ module.exports = Self => { JOIN vn.shelving sh ON sh.id = is2.shelvingFk AND ai.code <> sh.code JOIN vn.parking p ON p.id = sh.parkingFk JOIN vn.sector s ON s.id = p.sectorFk + WHERE is2.visible > 0 ), parkingDestiny AS ( SELECT ? AS pickingOrder ) SELECT ish.*, - CASE - WHEN ish.pickingOrder < d.pickingOrder AND aish.created < ish.created + CASE + WHEN ish.pickingOrder < d.pickingOrder AND aish.created < ish.created AND ABS(TIMESTAMPDIFF(HOUR, aish.created, ish.created)) > ? THEN "old" - WHEN ish.pickingOrder > d.pickingOrder AND aish.created > ish.created + WHEN ish.pickingOrder > d.pickingOrder AND aish.created > ish.created AND ABS(TIMESTAMPDIFF(HOUR, aish.created, ish.created)) > ? THEN "new" END AS itemCreated FROM itemShelvings ish @@ -77,8 +80,8 @@ module.exports = Self => { JOIN currentItemShelving aish ON ish.itemFk = aish.itemFk WHERE ABS(TIMESTAMPDIFF(HOUR, aish.created, ish.created)) > ? AND ( - (ish.pickingOrder < d.pickingOrder AND aish.created < ish.created) - OR + (ish.pickingOrder < d.pickingOrder AND aish.created < ish.created) + OR (ish.pickingOrder > d.pickingOrder AND aish.created > ish.created) ); `, From 672ef36501a9e96c7ffef7540360e6b5a2e811cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 30 Jan 2025 18:11:30 +0100 Subject: [PATCH 64/84] fix: refs #8511 ref #8511 ensure entry is editable for new entryFk in buy_beforeUpdate trigger --- db/routines/vn/triggers/buy_beforeUpdate.sql | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/db/routines/vn/triggers/buy_beforeUpdate.sql b/db/routines/vn/triggers/buy_beforeUpdate.sql index 24246329bc..c67d44f6f3 100644 --- a/db/routines/vn/triggers/buy_beforeUpdate.sql +++ b/db/routines/vn/triggers/buy_beforeUpdate.sql @@ -20,6 +20,7 @@ trig:BEGIN THEN CALL entry_isEditable(OLD.entryFk); + CALL entry_isEditable(NEW.entryFk); END IF; SET NEW.editorFk = account.myUser_getId(); @@ -88,11 +89,11 @@ trig:BEGIN SET NEW.buyerFk = vBuyerFk; END IF; - IF NOT (NEW.itemFk <=> OLD.itemFk) OR - NOT (OLD.entryFk <=> NEW.entryFk) THEN + IF NOT (NEW.itemFk <=> OLD.itemFk) OR + NOT (OLD.entryFk <=> NEW.entryFk) THEN CREATE OR REPLACE TEMPORARY TABLE tmp.buysToCheck SELECT NEW.id; - CALL buy_checkItem(); + CALL buy_checkItem(); END IF; END$$ DELIMITER ; From f437b3285a81d5652bd1244451b11b91b8097eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Fri, 31 Jan 2025 09:34:44 +0000 Subject: [PATCH 65/84] Actualizar print/templates/reports/invoice-incoterms/sql/incoterms.sql --- print/templates/reports/invoice-incoterms/sql/incoterms.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/print/templates/reports/invoice-incoterms/sql/incoterms.sql b/print/templates/reports/invoice-incoterms/sql/incoterms.sql index 5354516745..77a7daad11 100644 --- a/print/templates/reports/invoice-incoterms/sql/incoterms.sql +++ b/print/templates/reports/invoice-incoterms/sql/incoterms.sql @@ -1,9 +1,9 @@ WITH tickets AS( -SELECT id, addressFk, packages, refFk +SELECT id, addressFk, packages, refFk, weight FROM vn.ticket WHERE refFk = ? ), volume AS( -SELECT SUM(volume) volume, MAX(weight)weight +SELECT SUM(sv.volume) volume, MAX(t.weight)weight FROM tickets t JOIN vn.saleVolume sv ON sv.ticketFk = t.id ), intrastat AS( From b40f145613220e92635de22a4739eeaae91c4b14 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 31 Jan 2025 10:57:44 +0100 Subject: [PATCH 66/84] feat: refs #8227 Roadmap changes --- .../vn/triggers/roadmapStop_beforeDelete.sql | 13 +++++++++---- .../vn/triggers/roadmapStop_beforeInsert.sql | 12 ++++++------ .../vn/triggers/roadmapStop_beforeUpdate.sql | 18 ++++++++++++++---- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/db/routines/vn/triggers/roadmapStop_beforeDelete.sql b/db/routines/vn/triggers/roadmapStop_beforeDelete.sql index 3449e56218..f0faeb8bef 100644 --- a/db/routines/vn/triggers/roadmapStop_beforeDelete.sql +++ b/db/routines/vn/triggers/roadmapStop_beforeDelete.sql @@ -4,18 +4,23 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmapStop_beforeDelet FOR EACH ROW BEGIN DECLARE vMaxEta DATETIME; + DECLARE vRoadmapEta DATETIME; IF OLD.roadmapFk IS NOT NULL THEN - SELECT MAX(eta) INTO vMaxEta + SELECT MAX(eta) INTO vMaxEta FROM roadmapStop WHERE roadmapFk = OLD.roadmapFk AND id <> OLD.id; - IF OLD.eta > vMaxEta OR vMaxEta IS NULL THEN + SELECT eta INTO vRoadmapEta + FROM roadmap + WHERE id = OLD.roadmapFk; + + IF vMaxEta <> vRoadmapEta OR vMaxEta IS NULL THEN UPDATE roadmap - SET eta = COALESCE(vMaxEta, OLD.eta) + SET eta = vMaxEta WHERE id = OLD.roadmapFk; END IF; END IF; END$$ -DELIMITER ; +DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/triggers/roadmapStop_beforeInsert.sql b/db/routines/vn/triggers/roadmapStop_beforeInsert.sql index 00d17fcced..012702f3ed 100644 --- a/db/routines/vn/triggers/roadmapStop_beforeInsert.sql +++ b/db/routines/vn/triggers/roadmapStop_beforeInsert.sql @@ -3,7 +3,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmapStop_beforeInser BEFORE INSERT ON `roadmapStop` FOR EACH ROW BEGIN - DECLARE vMaxEta DATETIME; + DECLARE vRoadmapEta DATETIME; SET NEW.editorFk = account.myUser_getId(); @@ -18,13 +18,13 @@ BEGIN END IF; IF NEW.roadmapFk IS NOT NULL AND NEW.eta IS NOT NULL THEN - SELECT MAX(eta) INTO vMaxEta - FROM roadmapStop - WHERE roadmapFk = NEW.roadmapFk; + SELECT eta INTO vRoadmapEta + FROM roadmap + WHERE id = NEW.roadmapFk; - IF NEW.eta > vMaxEta OR vMaxEta IS NOT NULL THEN + IF vRoadmapEta < NEW.eta OR vRoadmapEta IS NULL THEN UPDATE roadmap - SET eta = GREATEST(COALESCE(vMaxEta, NEW.eta), NEW.eta) + SET eta = NEW.eta WHERE id = NEW.roadmapFk; END IF; END IF; diff --git a/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql b/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql index 0560ed5eb1..d9016a1708 100644 --- a/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql @@ -4,6 +4,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmapStop_beforeUpdat FOR EACH ROW BEGIN DECLARE vMaxEta DATETIME; + DECLARE vCurrentEta DATETIME; SET NEW.editorFk = account.myUser_getId(); @@ -18,13 +19,22 @@ BEGIN CALL util.throw('Departure time can not be after arrival time'); END IF; - SELECT MAX(eta) INTO vMaxEta + SELECT MAX(eta) INTO vMaxEta FROM roadmapStop - WHERE roadmapFk = NEW.roadmapFk; + WHERE roadmapFk = NEW.roadmapFk + AND id <> OLD.id; - IF NEW.eta > vMaxEta OR vMaxEta IS NULL THEN + IF vMaxEta IS NULL OR NEW.eta > vMaxEta THEN + SET vMaxEta = NEW.eta; + END IF; + + SELECT eta INTO vCurrentEta + FROM roadmap + WHERE id = NEW.roadmapFk; + + IF vMaxEta <> vCurrentEta THEN UPDATE roadmap - SET eta = COALESCE(vMaxEta, NEW.eta) + SET eta = vMaxEta WHERE id = NEW.roadmapFk; END IF; END IF; From 8dc803b5df54167009735596fc59e2d434c913dd Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 31 Jan 2025 14:25:23 +0100 Subject: [PATCH 67/84] feat: refs #8227 Roadmap changes --- db/routines/vn/triggers/roadmapStop_beforeUpdate.sql | 6 +++--- db/versions/11416-goldenTulip/09-firstScript.sql | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 db/versions/11416-goldenTulip/09-firstScript.sql diff --git a/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql b/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql index d9016a1708..c3142c8acc 100644 --- a/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql +++ b/db/routines/vn/triggers/roadmapStop_beforeUpdate.sql @@ -13,7 +13,7 @@ BEGIN END IF; IF (NOT (NEW.roadmapFk <=> OLD.roadmapFk) AND NEW.roadmapFk IS NOT NULL) - OR (NOT (NEW.eta <=> OLD.eta) AND NEW.eta IS NOT NULL) THEN + OR (NOT (NEW.eta <=> OLD.eta)) THEN IF NEW.eta < (SELECT etd FROM roadmap WHERE id = NEW.roadmapFk) THEN CALL util.throw('Departure time can not be after arrival time'); @@ -24,7 +24,7 @@ BEGIN WHERE roadmapFk = NEW.roadmapFk AND id <> OLD.id; - IF vMaxEta IS NULL OR NEW.eta > vMaxEta THEN + IF vMaxEta < NEW.eta OR vMaxEta IS NULL THEN SET vMaxEta = NEW.eta; END IF; @@ -32,7 +32,7 @@ BEGIN FROM roadmap WHERE id = NEW.roadmapFk; - IF vMaxEta <> vCurrentEta THEN + IF (vMaxEta <> vCurrentEta OR vMaxEta IS NULL) OR vMaxEta IS NOT NULL THEN UPDATE roadmap SET eta = vMaxEta WHERE id = NEW.roadmapFk; diff --git a/db/versions/11416-goldenTulip/09-firstScript.sql b/db/versions/11416-goldenTulip/09-firstScript.sql new file mode 100644 index 0000000000..5e61de07a7 --- /dev/null +++ b/db/versions/11416-goldenTulip/09-firstScript.sql @@ -0,0 +1 @@ +CREATE INDEX route_dated_IDX USING BTREE ON vn.route (dated); From 6b9c8300fb3509e7f7c5fd89b354488eefb3a5b6 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Mon, 3 Feb 2025 12:41:56 +0100 Subject: [PATCH 68/84] feat: refs #7412 notificationMisAllocation --- db/dump/fixtures.before.sql | 6 ++++-- db/versions/11430-salmonRaphis/00-firstScript.sql | 5 +++++ .../misallocation-warehouse/assets/css/import.js | 11 +++++++++++ .../email/misallocation-warehouse/locale/en.yml | 3 +++ .../email/misallocation-warehouse/locale/es.yml | 3 +++ .../email/misallocation-warehouse/locale/fr.yml | 3 +++ .../email/misallocation-warehouse/locale/pt.yml | 3 +++ .../misallocation-warehouse.html | 9 +++++++++ .../misallocation-warehouse.js | 15 +++++++++++++++ 9 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 db/versions/11430-salmonRaphis/00-firstScript.sql create mode 100644 print/templates/email/misallocation-warehouse/assets/css/import.js create mode 100644 print/templates/email/misallocation-warehouse/locale/en.yml create mode 100644 print/templates/email/misallocation-warehouse/locale/es.yml create mode 100644 print/templates/email/misallocation-warehouse/locale/fr.yml create mode 100644 print/templates/email/misallocation-warehouse/locale/pt.yml create mode 100644 print/templates/email/misallocation-warehouse/misallocation-warehouse.html create mode 100755 print/templates/email/misallocation-warehouse/misallocation-warehouse.js diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index c08938f043..afcacbcc4d 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -2926,7 +2926,8 @@ INSERT INTO `util`.`notification` (`id`, `name`, `description`) (7, 'zone-included','An email to notify zoneCollisions'), (8, 'backup-printer-selected','A backup printer has been selected'), (9, 'mrw-deadline','The MRW deadline has passed'), - (10,'invoice-ticket-closure','Tickets not invoiced during the nightly closure ticket process'); + (10,'invoice-ticket-closure','Tickets not invoiced during the nightly closure ticket process'), + (11,'misallocation-warehouse','Misallocation of items in the warehouse.'); TRUNCATE `util`.`notificationAcl`; INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`) @@ -2940,7 +2941,8 @@ INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`) (6, 9), (7, 9), (8, 66), - (9, 56); + (9, 56), + (11, 9); TRUNCATE `util`.`notificationQueue`; INSERT INTO `util`.`notificationQueue` (`id`, `notificationFk`, `params`, `authorFk`, `status`, `created`) diff --git a/db/versions/11430-salmonRaphis/00-firstScript.sql b/db/versions/11430-salmonRaphis/00-firstScript.sql new file mode 100644 index 0000000000..65f8fa43b1 --- /dev/null +++ b/db/versions/11430-salmonRaphis/00-firstScript.sql @@ -0,0 +1,5 @@ + + +INSERT IGNORE INTO util.notification + SET name = 'misallocation-warehouse', + description = 'Misallocation in warehouse'; diff --git a/print/templates/email/misallocation-warehouse/assets/css/import.js b/print/templates/email/misallocation-warehouse/assets/css/import.js new file mode 100644 index 0000000000..4b4bb70869 --- /dev/null +++ b/print/templates/email/misallocation-warehouse/assets/css/import.js @@ -0,0 +1,11 @@ +const Stylesheet = require(`vn-print/core/stylesheet`); + +const path = require('path'); +const vnPrintPath = path.resolve('print'); + +module.exports = new Stylesheet([ + `${vnPrintPath}/common/css/spacing.css`, + `${vnPrintPath}/common/css/misc.css`, + `${vnPrintPath}/common/css/layout.css`, + `${vnPrintPath}/common/css/email.css`]) + .mergeStyles(); diff --git a/print/templates/email/misallocation-warehouse/locale/en.yml b/print/templates/email/misallocation-warehouse/locale/en.yml new file mode 100644 index 0000000000..b16d9bd50a --- /dev/null +++ b/print/templates/email/misallocation-warehouse/locale/en.yml @@ -0,0 +1,3 @@ +subject: Misallocation of articles +title: Misallocation of articles +body: Misallocated articles have been placed in the warehouse that do not correspond to the entry location. diff --git a/print/templates/email/misallocation-warehouse/locale/es.yml b/print/templates/email/misallocation-warehouse/locale/es.yml new file mode 100644 index 0000000000..fbb1c74f16 --- /dev/null +++ b/print/templates/email/misallocation-warehouse/locale/es.yml @@ -0,0 +1,3 @@ +subject: Artículos mal ubicados +title: Artículos mal ubicados +body: Artículos mal ubicados han sido colocados en el almacén que no corresponden a la ubicación de la entrada. diff --git a/print/templates/email/misallocation-warehouse/locale/fr.yml b/print/templates/email/misallocation-warehouse/locale/fr.yml new file mode 100644 index 0000000000..0c8f155d6b --- /dev/null +++ b/print/templates/email/misallocation-warehouse/locale/fr.yml @@ -0,0 +1,3 @@ +subject: Artículos mal placés +title: Artículos mal placés +body: Artículos mal placés ont été stockés dans l’entrepôt qui ne correspond pas à l’emplacement de l’entrée. diff --git a/print/templates/email/misallocation-warehouse/locale/pt.yml b/print/templates/email/misallocation-warehouse/locale/pt.yml new file mode 100644 index 0000000000..129960ba69 --- /dev/null +++ b/print/templates/email/misallocation-warehouse/locale/pt.yml @@ -0,0 +1,3 @@ +subject: Artículos mal colocados +title: Artículos mal colocados +body: Artículos mal colocados foram armazenados no armazém que não corresponde à localização da entrada. diff --git a/print/templates/email/misallocation-warehouse/misallocation-warehouse.html b/print/templates/email/misallocation-warehouse/misallocation-warehouse.html new file mode 100644 index 0000000000..ad68ae0b63 --- /dev/null +++ b/print/templates/email/misallocation-warehouse/misallocation-warehouse.html @@ -0,0 +1,9 @@ + +
+
+

{{ $t('title') }}

+

{{$t('body')}}

+

{{action}}

+
+
+
diff --git a/print/templates/email/misallocation-warehouse/misallocation-warehouse.js b/print/templates/email/misallocation-warehouse/misallocation-warehouse.js new file mode 100755 index 0000000000..f61cef8192 --- /dev/null +++ b/print/templates/email/misallocation-warehouse/misallocation-warehouse.js @@ -0,0 +1,15 @@ +const Component = require(`vn-print/core/component`); +const emailBody = new Component('email-body'); + +module.exports = { + name: 'misallocation-warehouse', + components: { + 'email-body': emailBody.build(), + }, + props: { + action: { + type: String, + required: true + } + } +}; From 9adb160f2da8d12ef193303d0cdb835495e97a67 Mon Sep 17 00:00:00 2001 From: sergiodt Date: Mon, 3 Feb 2025 16:14:48 +0100 Subject: [PATCH 69/84] feat: refs #7412 refs#7569 sendEmailNotificationChangeText --- loopback/locale/es.json | 796 ++++++++++++++++++++-------------------- 1 file changed, 398 insertions(+), 398 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index f79dad236e..b8c3d6a564 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -1,400 +1,400 @@ { - "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", - "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", - "Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado", - "Can't be blank": "No puede estar en blanco", - "Invalid TIN": "NIF/CIF inválido", - "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", - "Is invalid": "Es inválido", - "Quantity cannot be zero": "La cantidad no puede ser cero", - "Enter an integer different to zero": "Introduce un entero distinto de cero", - "Package cannot be blank": "El embalaje no puede estar en blanco", - "The company name must be unique": "La razón social debe ser única", - "Invalid email": "Correo electrónico inválido", - "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 a BIC": "El método de pago seleccionado requiere un BIC", - "State cannot be blank": "El estado 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", - "can't be blank": "El campo no puede estar vacío", - "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 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", - "Name cannot be blank": "El nombre 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", - "Choose a company": "Selecciona una empresa", - "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", - "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", - "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", - "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 be a number": "El valor debe ser un numero", - "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 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", - "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 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", - "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", - "Warehouse cannot be blank": "El almacén 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", - "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 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", - "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 ñ", - "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", - "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", - "ORDER_EMPTY": "Cesta vacía", - "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", - "Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido", - "Street cannot be empty": "Dirección 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", - "You cannot remove this department": "No puedes eliminar este departamento", - "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", - "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", - "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", - "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", - "The introduced hour already exists": "Esta hora ya ha sido introducida", - "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", - "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", - "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 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)", - "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", - "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", - "This item doesn't exists": "El artículo no existe", - "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", - "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 postcode already exists": "Este código postal ya existe", - "Concept cannot be blank": "El concepto no puede quedar en blanco", - "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", - "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", - "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", - "The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto", - "Invalid quantity": "Cantidad invalida", - "This postal code is not valid": "Este código postal no es vá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 department name can't be repeated": "El nombre del departamento no puede repetirse", - "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 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 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 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", - "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", - "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", - "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}}}", - "Changed sale discount": "He cambiado el descuento de las siguientes lineas al 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}}})", - "Changed sale quantity": "He cambiado {{changes}} del ticket [{{ticketId}}]({{{ticketUrl}}})", - "Changes in sales": "la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}*", - "State": "Estado", - "regular": "normal", - "reserved": "reservado", - "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}}})", - "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}} €*", - "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}}})", - "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 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}}", - "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", - "Distance must be lesser than 4000": "La distancia debe ser inferior a 4000", - "This ticket is deleted": "Este ticket está eliminado", - "Unable to clone this travel": "No ha sido posible clonar este travel", - "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", - "ORDER_ALREADY_CONFIRMED": "ORDEN YA CONFIRMADA", - "Invalid password": "Invalid password", - "Password does not meet requirements": "La contraseña no cumple los requisitos", - "Role already assigned": "Rol ya asignado", - "Invalid role name": "Nombre de rol no válido", - "Role name must be written in camelCase": "El nombre del rol debe escribirse en camelCase", - "Email already exists": "El correo 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", - "Record of hours week": "Registro de horas semana {{week}} año {{year}} ", - "Created absence": "El empleado {{author}} ha añadido una ausencia de tipo '{{absenceType}}' a {{employee}} para el día {{dated}}.", - "Deleted absence": "El empleado {{author}} ha eliminado una ausencia de tipo '{{absenceType}}' a {{employee}} del día {{dated}}.", - "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}}})", - "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}}}", - "agencyModeFk": "Agencia", - "clientFk": "Cliente", - "zoneFk": "Zona", - "warehouseFk": "Almacén", - "shipped": "F. envío", - "landed": "F. entrega", - "addressFk": "Consignatario", - "companyFk": "Empresa", - "agency": "Agencia", - "delivery": "Reparto", - "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", - "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", - "Amount cannot be zero": "El importe no puede ser cero", - "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", - "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", - "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}}*", - "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", - "This BIC already exist.": "Este BIC ya existe.", - "That item doesn't exists": "Ese artículo no existe", - "There's a new urgent ticket:": "Hay un nuevo ticket urgente:", - "Invalid account": "Cuenta inválida", - "Compensation account is empty": "La cuenta para compensar está vacia", - "This genus already exist": "Este genus 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}}})", - "None": "Ninguno", - "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'", - "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", - "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", - "nickname": "nickname", - "INACTIVE_PROVIDER": "Proveedor inactivo", - "This client is not invoiceable": "Este cliente no es facturable", - "serial non editable": "Esta serie no permite asignar la referencia", - "Max shipped required": "La fecha límite es requerida", - "Can't invoice to future": "No se puede facturar a futuro", - "Can't invoice to past": "No se puede facturar a pasado", - "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 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", - "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", - "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", - "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 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", - "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", - "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", - "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", - "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", - "date in the future": "Fecha en el futuro", - "reference duplicated": "Referencia duplicada", - "This ticket is already a refund": "Este ticket ya es un abono", - "isWithoutNegatives": "Sin negativos", - "routeFk": "routeFk", - "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 se permite fichar a futuro": "No se permite fichar a futuro", - "No está permitido trabajar": "No está permitido trabajar", - "Fichadas impares": "Fichadas impares", - "Descanso diario 12h.": "Descanso diario 12h.", - "Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.", - "Dirección incorrecta": "Dirección incorrecta", - "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", - "Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente", - "This route does not exists": "Esta ruta no existe", - "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 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}}})", - "Already has this status": "Ya tiene este estado", - "There aren't records for this week": "No existen registros para esta semana", - "Empty data source": "Origen de datos vacio", - "App locked": "Aplicación bloqueada por el usuario {{userId}}", - "Email verify": "Correo de verificación", - "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", - "This receipt was not compensated": "Este recibo no ha sido compensado", - "Client's email was not found": "No se encontró el email del cliente", - "Negative basis": "Base negativa", - "This worker code already exists": "Este codigo de trabajador ya existe", - "This personal mail already exists": "Este correo personal ya existe", - "This worker already exists": "Este trabajador ya existe", - "App name does not exist": "El nombre de aplicación no es válido", - "Try again": "Vuelve a intentarlo", - "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}}", - "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 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", - "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", - "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", - "Warehouse inventory not set": "El almacén inventario no está establecido", - "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", - "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", - "Collection does not exist": "La colección no existe", - "Cannot obtain exclusive lock": "No se puede obtener un bloqueo exclusivo", - "Insert a date range": "Inserte un rango de fechas", - "Added observation": "{{user}} añadió esta observacion: {{text}} {{defaulterId}} ({{{defaulterUrl}}})", - "Comment added to client": "Observación añadida al cliente {{clientFk}}", - "Invalid auth code": "Código de verificación incorrecto", - "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", - "company": "Compañía", - "country": "País", - "clientId": "Id cliente", - "clientSocialName": "Cliente", - "amount": "Importe", - "taxableBase": "Base", - "ticketFk": "Id ticket", - "isActive": "Activo", - "hasToInvoice": "Facturar", - "isTaxDataChecked": "Datos comprobados", - "comercialId": "Id comercial", - "comercialName": "Comercial", - "Pass expired": "La contraseña ha caducado, cambiela desde Salix", - "Invalid NIF for VIES": "Invalid NIF for VIES", - "Ticket does not exist": "Este ticket no existe", - "Ticket is already signed": "Este ticket ya ha sido firmado", - "Authentication failed": "Autenticación fallida", - "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", - "Fecha fuera de rango": "Fecha fuera de rango", - "Error while generating PDF": "Error al generar PDF", - "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", - "The renew period has not been exceeded": "El periodo de renovación no ha sido superado", - "Valid priorities": "Prioridades válidas: %d", - "hasAnyNegativeBase": "Base negativa 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", - "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", - "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", - "You don't have enough privileges.": "No tienes suficientes permisos.", - "This ticket is locked": "Este ticket está bloqueado.", - "This ticket is not editable.": "Este ticket no es editable.", - "The ticket doesn't exist.": "No existe el ticket.", - "Social name should be uppercase": "La razón social debe ir en mayúscula", - "Street should be uppercase": "La dirección fiscal debe ir en mayúscula", - "Ticket without Route": "Ticket sin ruta", - "Select a different client": "Seleccione un cliente distinto", - "Fill all the fields": "Rellene todos los campos", - "The response is not a PDF": "La respuesta no es un PDF", - "Booking completed": "Reserva completada", - "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", - "User disabled": "Usuario desactivado", - "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", - "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}}", - "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", - "Field are invalid": "El campo '{{tag}}' no es válido", - "Incorrect pin": "Pin incorrecto.", - "You already have the mailAlias": "Ya tienes este alias de correo", - "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", - "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", - "Name should be uppercase": "El nombre debe ir en mayúscula", - "Bank entity must be specified": "La entidad bancaria es obligatoria", - "An email is necessary": "Es necesario un email", - "You cannot update these fields": "No puedes actualizar estos campos", - "CountryFK cannot be empty": "El país no puede estar vacío", - "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", - "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", - "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", - "They're not your subordinate": "No es tu subordinado/a.", - "No results found": "No se han encontrado resultados", - "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", - "Select ticket or client": "Elija un ticket o un client", - "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", - "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", - "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", - "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", - "Cannot send mail": "Não é possível enviar o email", - "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 entry not have stickers": "La entrada no tiene etiquetas", - "Too many records": "Demasiados registros", - "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", - "Weight already set": "El peso ya está establecido", - "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", - "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 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", - "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", - "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 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", - "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", - "Sales already moved": "Ya han sido transferidas", - "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", - "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", - "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 }}", - "Ticket has been delivered out of order": "El ticket {{ticket}} {{{fullUrl}}} no ha sigo entregado en su orden.", - "Price cannot be blank": "El precio no puede estar en blanco" + "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", + "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", + "Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado", + "Can't be blank": "No puede estar en blanco", + "Invalid TIN": "NIF/CIF inválido", + "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", + "Is invalid": "Es inválido", + "Quantity cannot be zero": "La cantidad no puede ser cero", + "Enter an integer different to zero": "Introduce un entero distinto de cero", + "Package cannot be blank": "El embalaje no puede estar en blanco", + "The company name must be unique": "La razón social debe ser única", + "Invalid email": "Correo electrónico inválido", + "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 a BIC": "El método de pago seleccionado requiere un BIC", + "State cannot be blank": "El estado 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", + "can't be blank": "El campo no puede estar vacío", + "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 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", + "Name cannot be blank": "El nombre 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", + "Choose a company": "Selecciona una empresa", + "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", + "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", + "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", + "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 be a number": "El valor debe ser un numero", + "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 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", + "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 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", + "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", + "Warehouse cannot be blank": "El almacén 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", + "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 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", + "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 ñ", + "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", + "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", + "ORDER_EMPTY": "Cesta vacía", + "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", + "Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido", + "Street cannot be empty": "Dirección 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", + "You cannot remove this department": "No puedes eliminar este departamento", + "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", + "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", + "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", + "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", + "The introduced hour already exists": "Esta hora ya ha sido introducida", + "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", + "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", + "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 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)", + "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", + "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", + "This item doesn't exists": "El artículo no existe", + "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", + "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 postcode already exists": "Este código postal ya existe", + "Concept cannot be blank": "El concepto no puede quedar en blanco", + "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", + "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", + "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", + "The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto", + "Invalid quantity": "Cantidad invalida", + "This postal code is not valid": "Este código postal no es vá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 department name can't be repeated": "El nombre del departamento no puede repetirse", + "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 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 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 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", + "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", + "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", + "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}}}", + "Changed sale discount": "He cambiado el descuento de las siguientes lineas al 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}}})", + "Changed sale quantity": "He cambiado {{changes}} del ticket [{{ticketId}}]({{{ticketUrl}}})", + "Changes in sales": "la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}*", + "State": "Estado", + "regular": "normal", + "reserved": "reservado", + "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}}})", + "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}} €*", + "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}}})", + "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 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}}", + "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", + "Distance must be lesser than 4000": "La distancia debe ser inferior a 4000", + "This ticket is deleted": "Este ticket está eliminado", + "Unable to clone this travel": "No ha sido posible clonar este travel", + "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", + "ORDER_ALREADY_CONFIRMED": "ORDEN YA CONFIRMADA", + "Invalid password": "Invalid password", + "Password does not meet requirements": "La contraseña no cumple los requisitos", + "Role already assigned": "Rol ya asignado", + "Invalid role name": "Nombre de rol no válido", + "Role name must be written in camelCase": "El nombre del rol debe escribirse en camelCase", + "Email already exists": "El correo 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", + "Record of hours week": "Registro de horas semana {{week}} año {{year}} ", + "Created absence": "El empleado {{author}} ha añadido una ausencia de tipo '{{absenceType}}' a {{employee}} para el día {{dated}}.", + "Deleted absence": "El empleado {{author}} ha eliminado una ausencia de tipo '{{absenceType}}' a {{employee}} del día {{dated}}.", + "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}}})", + "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}}}", + "agencyModeFk": "Agencia", + "clientFk": "Cliente", + "zoneFk": "Zona", + "warehouseFk": "Almacén", + "shipped": "F. envío", + "landed": "F. entrega", + "addressFk": "Consignatario", + "companyFk": "Empresa", + "agency": "Agencia", + "delivery": "Reparto", + "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", + "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", + "Amount cannot be zero": "El importe no puede ser cero", + "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", + "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", + "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}}*", + "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", + "This BIC already exist.": "Este BIC ya existe.", + "That item doesn't exists": "Ese artículo no existe", + "There's a new urgent ticket:": "Hay un nuevo ticket urgente:", + "Invalid account": "Cuenta inválida", + "Compensation account is empty": "La cuenta para compensar está vacia", + "This genus already exist": "Este genus 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}}})", + "None": "Ninguno", + "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'", + "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", + "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", + "nickname": "nickname", + "INACTIVE_PROVIDER": "Proveedor inactivo", + "This client is not invoiceable": "Este cliente no es facturable", + "serial non editable": "Esta serie no permite asignar la referencia", + "Max shipped required": "La fecha límite es requerida", + "Can't invoice to future": "No se puede facturar a futuro", + "Can't invoice to past": "No se puede facturar a pasado", + "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 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", + "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", + "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", + "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 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", + "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", + "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", + "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", + "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", + "date in the future": "Fecha en el futuro", + "reference duplicated": "Referencia duplicada", + "This ticket is already a refund": "Este ticket ya es un abono", + "isWithoutNegatives": "Sin negativos", + "routeFk": "routeFk", + "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 se permite fichar a futuro": "No se permite fichar a futuro", + "No está permitido trabajar": "No está permitido trabajar", + "Fichadas impares": "Fichadas impares", + "Descanso diario 12h.": "Descanso diario 12h.", + "Descanso semanal 36h. / 72h.": "Descanso semanal 36h. / 72h.", + "Dirección incorrecta": "Dirección incorrecta", + "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", + "Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente", + "This route does not exists": "Esta ruta no existe", + "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 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}}})", + "Already has this status": "Ya tiene este estado", + "There aren't records for this week": "No existen registros para esta semana", + "Empty data source": "Origen de datos vacio", + "App locked": "Aplicación bloqueada por el usuario {{userId}}", + "Email verify": "Correo de verificación", + "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", + "This receipt was not compensated": "Este recibo no ha sido compensado", + "Client's email was not found": "No se encontró el email del cliente", + "Negative basis": "Base negativa", + "This worker code already exists": "Este codigo de trabajador ya existe", + "This personal mail already exists": "Este correo personal ya existe", + "This worker already exists": "Este trabajador ya existe", + "App name does not exist": "El nombre de aplicación no es válido", + "Try again": "Vuelve a intentarlo", + "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}}", + "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 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", + "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", + "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", + "Warehouse inventory not set": "El almacén inventario no está establecido", + "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", + "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", + "Collection does not exist": "La colección no existe", + "Cannot obtain exclusive lock": "No se puede obtener un bloqueo exclusivo", + "Insert a date range": "Inserte un rango de fechas", + "Added observation": "{{user}} añadió esta observacion: {{text}} {{defaulterId}} ({{{defaulterUrl}}})", + "Comment added to client": "Observación añadida al cliente {{clientFk}}", + "Invalid auth code": "Código de verificación incorrecto", + "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", + "company": "Compañía", + "country": "País", + "clientId": "Id cliente", + "clientSocialName": "Cliente", + "amount": "Importe", + "taxableBase": "Base", + "ticketFk": "Id ticket", + "isActive": "Activo", + "hasToInvoice": "Facturar", + "isTaxDataChecked": "Datos comprobados", + "comercialId": "Id comercial", + "comercialName": "Comercial", + "Pass expired": "La contraseña ha caducado, cambiela desde Salix", + "Invalid NIF for VIES": "Invalid NIF for VIES", + "Ticket does not exist": "Este ticket no existe", + "Ticket is already signed": "Este ticket ya ha sido firmado", + "Authentication failed": "Autenticación fallida", + "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", + "Fecha fuera de rango": "Fecha fuera de rango", + "Error while generating PDF": "Error al generar PDF", + "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", + "The renew period has not been exceeded": "El periodo de renovación no ha sido superado", + "Valid priorities": "Prioridades válidas: %d", + "hasAnyNegativeBase": "Base negativa 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", + "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", + "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", + "You don't have enough privileges.": "No tienes suficientes permisos.", + "This ticket is locked": "Este ticket está bloqueado.", + "This ticket is not editable.": "Este ticket no es editable.", + "The ticket doesn't exist.": "No existe el ticket.", + "Social name should be uppercase": "La razón social debe ir en mayúscula", + "Street should be uppercase": "La dirección fiscal debe ir en mayúscula", + "Ticket without Route": "Ticket sin ruta", + "Select a different client": "Seleccione un cliente distinto", + "Fill all the fields": "Rellene todos los campos", + "The response is not a PDF": "La respuesta no es un PDF", + "Booking completed": "Reserva completada", + "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", + "User disabled": "Usuario desactivado", + "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", + "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}}", + "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", + "Field are invalid": "El campo '{{tag}}' no es válido", + "Incorrect pin": "Pin incorrecto.", + "You already have the mailAlias": "Ya tienes este alias de correo", + "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", + "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", + "Name should be uppercase": "El nombre debe ir en mayúscula", + "Bank entity must be specified": "La entidad bancaria es obligatoria", + "An email is necessary": "Es necesario un email", + "You cannot update these fields": "No puedes actualizar estos campos", + "CountryFK cannot be empty": "El país no puede estar vacío", + "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", + "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", + "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", + "They're not your subordinate": "No es tu subordinado/a.", + "No results found": "No se han encontrado resultados", + "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", + "Select ticket or client": "Elija un ticket o un client", + "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", + "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", + "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", + "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", + "Cannot send mail": "Não é possível enviar o email", + "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 entry not have stickers": "La entrada no tiene etiquetas", + "Too many records": "Demasiados registros", + "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", + "Weight already set": "El peso ya está establecido", + "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", + "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 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", + "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", + "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 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", + "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", + "Sales already moved": "Ya han sido transferidas", + "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", + "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", + "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 }}", + "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" } From 9cecdab5a823c2d45d50beb9771c93d94ba32478 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 4 Feb 2025 07:17:11 +0100 Subject: [PATCH 70/84] refactor: refs #8227 Fix tests --- db/dump/fixtures.before.sql | 6 +++--- .../back/methods/agency-term/specs/filter.spec.js | 10 +++++----- modules/route/back/methods/route/specs/filter.spec.js | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index 5e23178ecd..98c7f42f85 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -752,11 +752,11 @@ INSERT INTO `vn`.`zoneConfig` (`id`, `scope`) VALUES (1, '1'); INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`, `dated`) VALUES - (1, '1899-12-30 12:15:00', 56, util.VN_CURDATE(), 1, 1, 'first route', 1.8, 10, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), + (1, '1899-12-30 12:15:00', 133, util.VN_CURDATE(), 1, 1, 'first route', 1.8, 10, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), (2, '1899-12-30 13:20:00', 56, util.VN_CURDATE(), 1, 2, 'second route', 0.2, 20, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), - (3, '1899-12-30 14:30:00', 56, util.VN_CURDATE(), 2, 3, 'third route', 0.5, 30, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), + (3, '1899-12-30 14:30:00', 133, util.VN_CURDATE(), 2, 3, 'third route', 0.5, 30, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), (4, '1899-12-30 15:45:00', 56, util.VN_CURDATE(), 3, 4, 'fourth route', 0, 40, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), - (5, '1899-12-30 16:00:00', 56, util.VN_CURDATE(), 4, 5, 'fifth route', 0.1, 50, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), + (5, '1899-12-30 16:00:00', 133, util.VN_CURDATE(), 4, 5, 'fifth route', 0.1, 50, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), (6, NULL, 57, util.VN_CURDATE(), 5, 7, 'sixth route', 1.7, 60, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()), (7, NULL, 57, util.VN_CURDATE(), 6, 8, 'seventh route', 0, 70, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), util.VN_CURDATE()); diff --git a/modules/route/back/methods/agency-term/specs/filter.spec.js b/modules/route/back/methods/agency-term/specs/filter.spec.js index aa27438688..41e696157d 100644 --- a/modules/route/back/methods/agency-term/specs/filter.spec.js +++ b/modules/route/back/methods/agency-term/specs/filter.spec.js @@ -18,7 +18,7 @@ describe('AgencyTerm filter()', () => { const firstAgencyTerm = agencyTerms[0]; expect(firstAgencyTerm.routeFk).toEqual(1); - expect(agencyTerms.length).toEqual(7); + expect(agencyTerms.length).toEqual(5); await tx.rollback(); } catch (e) { @@ -49,7 +49,7 @@ describe('AgencyTerm filter()', () => { let result = await app.models.AgencyTerm.filter(ctx); - expect(result.length).toEqual(4); + expect(result.length).toEqual(2); }); it('should return results matching "from" and "to"', async() => { @@ -72,7 +72,7 @@ describe('AgencyTerm filter()', () => { const results = await models.AgencyTerm.filter(ctx, options); - expect(results.length).toBe(7); + expect(results.length).toBe(5); await tx.rollback(); } catch (e) { @@ -90,7 +90,7 @@ describe('AgencyTerm filter()', () => { let result = await app.models.AgencyTerm.filter(ctx); - expect(result.length).toEqual(2); + expect(result.length).toEqual(1); expect(result[0].routeFk).toEqual(1); }); @@ -103,7 +103,7 @@ describe('AgencyTerm filter()', () => { let result = await app.models.AgencyTerm.filter(ctx); - expect(result.length).toEqual(2); + expect(result.length).toEqual(1); expect(result[0].routeFk).toEqual(2); }); }); diff --git a/modules/route/back/methods/route/specs/filter.spec.js b/modules/route/back/methods/route/specs/filter.spec.js index 11bf0b7b0a..ddc2fe893d 100644 --- a/modules/route/back/methods/route/specs/filter.spec.js +++ b/modules/route/back/methods/route/specs/filter.spec.js @@ -59,7 +59,7 @@ describe('Route filter()', () => { }; const results = await models.Route.filter(ctx, options); - expect(results.length).toBe(9); + expect(results.length).toBe(7); await tx.rollback(); } catch (e) { @@ -115,7 +115,7 @@ describe('Route filter()', () => { }; const result = await app.models.Route.filter(ctx); - expect(result.length).toEqual(4); + expect(result.length).toEqual(2); }); it('should return the routes matching "warehouseFk"', async() => { @@ -132,7 +132,7 @@ describe('Route filter()', () => { let result = await app.models.Route.filter(ctx); - expect(result.length).toEqual(9); + expect(result.length).toEqual(7); ctx.args.warehouseFk = 2; From fb8973a35834f6983e7dc8393a1072a56be46733 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 4 Feb 2025 07:47:28 +0100 Subject: [PATCH 71/84] fix: refs #8515 Fix test optimizePriority --- .../methods/route/specs/optimizePriority.spec.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/route/back/methods/route/specs/optimizePriority.spec.js b/modules/route/back/methods/route/specs/optimizePriority.spec.js index c1c2dc45e2..f3f939645b 100644 --- a/modules/route/back/methods/route/specs/optimizePriority.spec.js +++ b/modules/route/back/methods/route/specs/optimizePriority.spec.js @@ -1,7 +1,16 @@ const models = require('vn-loopback/server/server').models; const routeId = 1; -describe('route optimizePriority())', function() { +fdescribe('route optimizePriority()', function() { + beforeEach(() => { + spyOn(models.OsrmConfig, 'optimize').and.returnValue( + Promise.resolve([ + {addressId: 1, position: 0}, + {addressId: 2, position: 1} + ]) + ); + }); + it('should execute without throwing errors', async function() { const tx = await models.Route.beginTransaction({}); let error; @@ -20,9 +29,10 @@ describe('route optimizePriority())', function() { } expect(error).toBeUndefined(); + expect(models.OsrmConfig.optimize).toHaveBeenCalled(); }); - it('should execute with error', async function() { + it('should execute with error when all tickets have a route order', async function() { let error; try { await models.Route.optimizePriority(routeId); From 49e5da5547a705b00a4a28a7dc984b6678a02943 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 4 Feb 2025 07:48:56 +0100 Subject: [PATCH 72/84] fix: refs #8515 Fix test optimizePriority --- modules/route/back/methods/route/specs/optimizePriority.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/route/back/methods/route/specs/optimizePriority.spec.js b/modules/route/back/methods/route/specs/optimizePriority.spec.js index f3f939645b..94072fd884 100644 --- a/modules/route/back/methods/route/specs/optimizePriority.spec.js +++ b/modules/route/back/methods/route/specs/optimizePriority.spec.js @@ -1,7 +1,7 @@ const models = require('vn-loopback/server/server').models; const routeId = 1; -fdescribe('route optimizePriority()', function() { +describe('route optimizePriority()', function() { beforeEach(() => { spyOn(models.OsrmConfig, 'optimize').and.returnValue( Promise.resolve([ From eb9d3a7b21b8371e9ae14115fc3282e859d05242 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 4 Feb 2025 08:27:21 +0100 Subject: [PATCH 73/84] refactor: refs #8227 Requested changes --- .../vn/procedures/roadmap_cloneDay.sql | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/db/routines/vn/procedures/roadmap_cloneDay.sql b/db/routines/vn/procedures/roadmap_cloneDay.sql index 4247b881e8..8c38039473 100644 --- a/db/routines/vn/procedures/roadmap_cloneDay.sql +++ b/db/routines/vn/procedures/roadmap_cloneDay.sql @@ -12,8 +12,15 @@ BEGIN * @param vDateToPaste Fecha para pegar */ DECLARE vDaysDiff INT; - DECLARE vNextRoadmapId INT; + DECLARE vRoadmapFk INT; + DECLARE vNewRoadmapFk INT; + DECLARE vDone BOOL DEFAULT FALSE; + DECLARE vRoadmaps CURSOR FOR + SELECT id + FROM roadmap + WHERE etd BETWEEN vDateToCopy AND util.dayEnd(vDateToCopy); + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; @@ -28,23 +35,14 @@ BEGIN START TRANSACTION; - SELECT AUTO_INCREMENT INTO vNextRoadmapId - FROM information_schema.tables - WHERE table_name = 'roadmap' - AND table_schema = 'vn'; + OPEN vRoadmaps; + l: LOOP + SET vDone = FALSE; + FETCH vRoadmaps INTO vRoadmapFk; - CREATE OR REPLACE TEMPORARY TABLE tmp.roadmapsToCopy - ENGINE = MEMORY - SELECT ROW_NUMBER() OVER(ORDER BY id) rowOrder, - id, - `name`, - roadmapAddressFk, - etd, - eta, - observations, - price - FROM roadmap - WHERE etd BETWEEN vDateToCopy AND util.dayEnd(vDateToCopy); + IF vDone THEN + LEAVE l; + END IF; INSERT INTO roadmap (`name`, roadmapAddressFk, etd, eta, observations, price) SELECT `name`, @@ -53,19 +51,22 @@ BEGIN eta + INTERVAL vDaysDiff DAY, observations, price - FROM tmp.roadmapsToCopy; + FROM roadmap + WHERE id = vRoadmapFk; + + SET vNewRoadmapFk = LAST_INSERT_ID(); INSERT INTO roadmapStop (roadmapFk, roadmapAddressFk, eta, `description`, bufferFk) - SELECT (rtc.rowOrder - 1) + vNextRoadmapId, - rs.roadmapAddressFk, - rs.eta + INTERVAL vDaysDiff DAY, - rs.description, - rs.bufferFk - FROM tmp.roadmapsToCopy rtc - JOIN roadmapStop rs ON rs.roadmapFk = rtc.id; + SELECT vNewRoadmapFk, + roadmapAddressFk, + eta + INTERVAL vDaysDiff DAY, + `description`, + bufferFk + FROM roadmapStop + WHERE roadmapFk = vRoadmapFk; + END LOOP; + CLOSE vRoadmaps; COMMIT; - - DROP TEMPORARY TABLE tmp.roadmapsToCopy; END$$ DELIMITER ; From 5258e5ba2ab08a38086d33b94ba6f973f9292e57 Mon Sep 17 00:00:00 2001 From: Jon Date: Tue, 4 Feb 2025 13:55:01 +0100 Subject: [PATCH 74/84] refactor: refs #7127 modified checkAccessAcl instead of using VnRole --- modules/claim/back/models/claim-beginning.js | 38 ++++++++++++++------ 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/modules/claim/back/models/claim-beginning.js b/modules/claim/back/models/claim-beginning.js index 40d66c33ea..41c064c751 100644 --- a/modules/claim/back/models/claim-beginning.js +++ b/modules/claim/back/models/claim-beginning.js @@ -14,33 +14,51 @@ module.exports = Self => { const options = ctx.options; const models = Self.app.models; const saleFk = ctx?.currentInstance?.saleFk || ctx?.instance?.saleFk; - const loopBackContext = LoopBackContext.getCurrentContext(); - const accessToken = loopBackContext.active.accessToken; - const user = await models.VnUser.findById(accessToken.userId); - const role = await models.VnRole.findById(user.roleFk); + const claimFk = ctx?.instance?.claimFk || ctx?.currentInstance?.claimFk; + const myOptions = {}; + const accessToken = ctx?.options?.accessToken || LoopBackContext.getCurrentContext().active.accessToken; + const ctxToken = {req: {accessToken}}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + const sale = await models.Sale.findById(saleFk, {fields: ['ticketFk', 'quantity']}, options); - if (role.name !== 'salesPerson' && role.name !== 'claimManager') + const canCreateClaimAfterDeadline = models.ACL.checkAccessAcl( + ctxToken, + 'Claim', + 'createAfterDeadline', + myOptions + ); + + const canUpdateClaim = models.ACL.checkAccessAcl( + ctxToken, + 'Claim', + 'updateClaim', + myOptions + ); + + if (!canUpdateClaim && !canCreateClaimAfterDeadline) throw new UserError(`You don't have permission to modify this claim`); - if (role.name === 'salesPerson') { + if (canUpdateClaim) { const query = ` SELECT daysToClaim FROM vn.claimConfig`; const res = await Self.rawSql(query); const daysToClaim = res[0]?.daysToClaim; - const claim = await models.Claim.findById(ctx?.currentInstance?.claimFk, {fields: ['created']}, options); + const claim = await models.Claim.findById(claimFk, {fields: ['created']}, options); const claimDate = moment.utc(claim.created); const currentDate = moment.utc(); const daysSinceSale = currentDate.diff(claimDate, 'days'); - if (daysSinceSale > daysToClaim) + if (daysSinceSale > daysToClaim && !canCreateClaimAfterDeadline) throw new UserError(`You can't modify this claim because the deadline has already passed`); } if (ctx.isNewInstance) { - const claim = await models.Claim.findById(ctx.instance.claimFk, {fields: ['ticketFk']}, options); + const claim = await models.Claim.findById(claimFk, {fields: ['ticketFk']}, options); if (sale.ticketFk != claim.ticketFk) throw new UserError(`Cannot create a new claimBeginning from a different ticket`); } @@ -65,7 +83,7 @@ module.exports = Self => { if (ctx.options && ctx.options.transaction) myOptions.transaction = ctx.options.transaction; - const claimBeginning = ctx.instance ?? await Self.findById(ctx.where.id); + const claimBeginning = ctx.instance ?? await Self.findById(ctx?.where?.id); const filter = { where: {id: claimBeginning.claimFk}, From da36016f5b0ba384eb95589e69b82d908f880137 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 4 Feb 2025 14:43:31 +0100 Subject: [PATCH 75/84] build: init version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 72f8e2d1ba..7f2025552a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "25.06.0", + "version": "25.08.0", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From f216166806fd32da6059bad7038e2ab3e4c0d925 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 5 Feb 2025 10:16:14 +0100 Subject: [PATCH 76/84] fix: refs #7943 better "relation": "business", --- modules/worker/back/models/worker.json | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/modules/worker/back/models/worker.json b/modules/worker/back/models/worker.json index 346c70d567..4ecce9ef26 100644 --- a/modules/worker/back/models/worker.json +++ b/modules/worker/back/models/worker.json @@ -272,7 +272,8 @@ "relation": "department", "scope": { "fields": [ - "id" + "id", + "name" ] } } @@ -289,14 +290,23 @@ "departmentFk", "workerBusinessProfessionalCategoryFk" ], - "include": [ + "include":[ + { + "relation": "department", + "scope": { + "fields": ["id", "name"] + } + }, { "relation": "reasonEnd", "scope": { - "fields": [ - "id", - "reason" - ] + "fields": ["id", "reason"] + } + }, + { + "relation": "workerBusinessProfessionalCategory", + "scope": { + "fields": ["id", "description"] } } ] From e89c12f75334896f9e721851613e9f03051335d6 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 5 Feb 2025 10:52:20 +0100 Subject: [PATCH 77/84] fix: refs #7943 better "relation": "business", --- modules/worker/back/models/worker.json | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/modules/worker/back/models/worker.json b/modules/worker/back/models/worker.json index 346c70d567..4ecce9ef26 100644 --- a/modules/worker/back/models/worker.json +++ b/modules/worker/back/models/worker.json @@ -272,7 +272,8 @@ "relation": "department", "scope": { "fields": [ - "id" + "id", + "name" ] } } @@ -289,14 +290,23 @@ "departmentFk", "workerBusinessProfessionalCategoryFk" ], - "include": [ + "include":[ + { + "relation": "department", + "scope": { + "fields": ["id", "name"] + } + }, { "relation": "reasonEnd", "scope": { - "fields": [ - "id", - "reason" - ] + "fields": ["id", "reason"] + } + }, + { + "relation": "workerBusinessProfessionalCategory", + "scope": { + "fields": ["id", "description"] } } ] From 37b735b98869c9ce3cd80cf8814be8c271aeb5e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Wed, 5 Feb 2025 17:21:36 +0100 Subject: [PATCH 78/84] feat: refs #8535 sistema de warnings --- .../vn/triggers/mandate_afterDelete.sql | 12 ++++++++++ .../vn/triggers/mandate_beforeInsert.sql | 10 ++++---- .../vn/triggers/mandate_beforeUpdate.sql | 8 +++++++ .../11432-yellowRoebelini/00-firstScript.sql | 23 +++++++++++++++++++ .../client/back/locale/client-sample/es.yml | 2 +- modules/client/back/locale/mandate/en.yml | 10 ++++++++ modules/client/back/locale/mandate/es.yml | 10 ++++++++ modules/client/back/models/mandate.json | 5 +++- 8 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 db/routines/vn/triggers/mandate_afterDelete.sql create mode 100644 db/routines/vn/triggers/mandate_beforeUpdate.sql create mode 100644 db/versions/11432-yellowRoebelini/00-firstScript.sql create mode 100644 modules/client/back/locale/mandate/en.yml create mode 100644 modules/client/back/locale/mandate/es.yml diff --git a/db/routines/vn/triggers/mandate_afterDelete.sql b/db/routines/vn/triggers/mandate_afterDelete.sql new file mode 100644 index 0000000000..6ef27bb108 --- /dev/null +++ b/db/routines/vn/triggers/mandate_afterDelete.sql @@ -0,0 +1,12 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`mandate_afterDelete` + AFTER DELETE ON `mandate` + FOR EACH ROW +BEGIN + INSERT INTO mandateLog + SET `action` = 'delete', + `changedModel` = 'mandate', + `changedModelId` = OLD.id, + `userFk` = account.myUser_getId(); +END$$ +DELIMITER ; diff --git a/db/routines/vn/triggers/mandate_beforeInsert.sql b/db/routines/vn/triggers/mandate_beforeInsert.sql index bfc36cc31f..6fe26604aa 100644 --- a/db/routines/vn/triggers/mandate_beforeInsert.sql +++ b/db/routines/vn/triggers/mandate_beforeInsert.sql @@ -4,9 +4,11 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`mandate_beforeInsert` FOR EACH ROW BEGIN IF (NEW.code IS NULL) THEN - SET NEW.code=CONCAT(NEW.clientFk,'-',(SELECT AUTO_INCREMENT - FROM information_schema.TABLES - WHERE TABLE_SCHEMA='vn' and TABLE_NAME='mandate')); - END IF; + SET NEW.code=CONCAT(NEW.clientFk,'-',(SELECT AUTO_INCREMENT + FROM information_schema.TABLES + WHERE TABLE_SCHEMA='vn' and TABLE_NAME='mandate')); + END IF; + + SET NEW.editorFk = account.myUser_getId(); END$$ DELIMITER ; diff --git a/db/routines/vn/triggers/mandate_beforeUpdate.sql b/db/routines/vn/triggers/mandate_beforeUpdate.sql new file mode 100644 index 0000000000..0932fda393 --- /dev/null +++ b/db/routines/vn/triggers/mandate_beforeUpdate.sql @@ -0,0 +1,8 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`mandate_beforeUpdate` + BEFORE INSERT ON `mandate` + FOR EACH ROW +BEGIN + SET NEW.editorFk = account.myUser_getId(); +END$$ +DELIMITER ; diff --git a/db/versions/11432-yellowRoebelini/00-firstScript.sql b/db/versions/11432-yellowRoebelini/00-firstScript.sql new file mode 100644 index 0000000000..15652d3375 --- /dev/null +++ b/db/versions/11432-yellowRoebelini/00-firstScript.sql @@ -0,0 +1,23 @@ +CREATE OR REPLACE TABLE vn.mandateLog ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `originFk` int(11) DEFAULT NULL, + `userFk` int(10) unsigned DEFAULT NULL, + `action` set('insert','update','delete','select') NOT NULL, + `creationDate` timestamp NULL DEFAULT current_timestamp(), + `description` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + `changedModel` enum('client') NOT NULL DEFAULT 'client', + `oldInstance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`oldInstance`)), + `newInstance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`newInstance`)), + `changedModelId` int(11) NOT NULL, + `changedModelValue` varchar(45) DEFAULT NULL, + `summaryId` varchar(30) DEFAULT NULL, + `reason` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `logMandate_userFk` (`userFk`), + KEY `mandateLog_changedModel` (`changedModel`,`changedModelId`,`creationDate`), + KEY `mandateLog_originFk` (`originFk`,`creationDate`), + KEY `mandateLog_creationDate_IDX` (`creationDate` DESC) USING BTREE, + CONSTRAINT `mandateUserFk` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +ALTER TABLE vn.mandate ADD editorFk INT UNSIGNED DEFAULT NULL NULL; diff --git a/modules/client/back/locale/client-sample/es.yml b/modules/client/back/locale/client-sample/es.yml index 5293adaa8b..5f400c8687 100644 --- a/modules/client/back/locale/client-sample/es.yml +++ b/modules/client/back/locale/client-sample/es.yml @@ -1,4 +1,4 @@ -name: muestra +name: plantilla columns: id: id created: creado diff --git a/modules/client/back/locale/mandate/en.yml b/modules/client/back/locale/mandate/en.yml new file mode 100644 index 0000000000..6a43ebb5e1 --- /dev/null +++ b/modules/client/back/locale/mandate/en.yml @@ -0,0 +1,10 @@ +name: mandate +columns: + id: id + clientFk: client + companyFk: company + code: code + created: created + finished: finished + mandateTypeFk: mandate type + editorFk: editor diff --git a/modules/client/back/locale/mandate/es.yml b/modules/client/back/locale/mandate/es.yml new file mode 100644 index 0000000000..efe6465dc2 --- /dev/null +++ b/modules/client/back/locale/mandate/es.yml @@ -0,0 +1,10 @@ +name: mandate +columns: + id: id + clientFk: cliente + companyFk: empresa + code: código + created: creado + finished: finalizado + mandateTypeFk: tipo de mandato + editorFk: editor diff --git a/modules/client/back/models/mandate.json b/modules/client/back/models/mandate.json index 914b23ce27..89a18fd7e2 100644 --- a/modules/client/back/models/mandate.json +++ b/modules/client/back/models/mandate.json @@ -1,6 +1,9 @@ { "name": "Mandate", "base": "VnModel", + "mixins": { + "Loggable": true + }, "options": { "mysql": { "table": "mandate" @@ -39,4 +42,4 @@ "foreignKey": "mandateTypeFk" } } - } \ No newline at end of file + } From 8df36f296a6a71feff001db66efe4060d41402c3 Mon Sep 17 00:00:00 2001 From: Jbreso Date: Thu, 6 Feb 2025 09:11:48 +0100 Subject: [PATCH 79/84] feat: refs #269518 isFragile item and itemType --- db/routines/vn/procedures/ticket_getWarnings.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/routines/vn/procedures/ticket_getWarnings.sql b/db/routines/vn/procedures/ticket_getWarnings.sql index d817a92bbb..5f675e7f27 100644 --- a/db/routines/vn/procedures/ticket_getWarnings.sql +++ b/db/routines/vn/procedures/ticket_getWarnings.sql @@ -25,7 +25,7 @@ BEGIN LEFT JOIN agencyMode am ON am.id = tt.agencyModeFk LEFT JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk WHERE dm.code IN ('AGENCY') - AND it.isFragile; + AND (it.isFragile OR i.isFragile); CREATE OR REPLACE TEMPORARY TABLE tmp.ticket_warnings (PRIMARY KEY (ticketFk)) From 9b2c0f1c487c957febd5fbcb9990f265c08d7a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 6 Feb 2025 11:46:39 +0100 Subject: [PATCH 80/84] feat: refs #8535 log table mandate --- db/routines/vn/triggers/mandate_beforeInsert.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/routines/vn/triggers/mandate_beforeInsert.sql b/db/routines/vn/triggers/mandate_beforeInsert.sql index 6fe26604aa..090133eef1 100644 --- a/db/routines/vn/triggers/mandate_beforeInsert.sql +++ b/db/routines/vn/triggers/mandate_beforeInsert.sql @@ -3,12 +3,12 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`mandate_beforeInsert` BEFORE INSERT ON `mandate` FOR EACH ROW BEGIN + SET NEW.editorFk = account.myUser_getId(); + IF (NEW.code IS NULL) THEN SET NEW.code=CONCAT(NEW.clientFk,'-',(SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA='vn' and TABLE_NAME='mandate')); END IF; - - SET NEW.editorFk = account.myUser_getId(); END$$ DELIMITER ; From 110a5212c03748e6fcee086cf72a9093b96a7de3 Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 6 Feb 2025 12:55:01 +0100 Subject: [PATCH 81/84] fix: refs #8535 deploy --- back/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/back/Dockerfile b/back/Dockerfile index 0f75f6949f..b2c3298966 100644 --- a/back/Dockerfile +++ b/back/Dockerfile @@ -13,6 +13,7 @@ RUN apt-get update \ graphicsmagick \ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && apt-get install -y --no-install-recommends nodejs \ + && npm install -g corepack@0.31.0 \ && corepack enable pnpm # Puppeteer From beed658f618439e4612a5cd3fe31bc7925fc2d6c Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 6 Feb 2025 13:21:32 +0100 Subject: [PATCH 82/84] fix: refs #8535 deploy --- back/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/back/Dockerfile b/back/Dockerfile index 0f75f6949f..b2c3298966 100644 --- a/back/Dockerfile +++ b/back/Dockerfile @@ -13,6 +13,7 @@ RUN apt-get update \ graphicsmagick \ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && apt-get install -y --no-install-recommends nodejs \ + && npm install -g corepack@0.31.0 \ && corepack enable pnpm # Puppeteer From f12a690bef081c28ee224e30da4143b6d4a42de9 Mon Sep 17 00:00:00 2001 From: ivanm Date: Thu, 6 Feb 2025 13:28:44 +0100 Subject: [PATCH 83/84] feat: refs #8487 delete appointment from travel view --- db/routines/vn2008/views/travel.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/db/routines/vn2008/views/travel.sql b/db/routines/vn2008/views/travel.sql index 38dfd40eaf..5dc993d330 100644 --- a/db/routines/vn2008/views/travel.sql +++ b/db/routines/vn2008/views/travel.sql @@ -16,7 +16,6 @@ AS SELECT `t`.`id` AS `id`, `t`.`kg` AS `kg`, `t`.`cargoSupplierFk` AS `cargoSupplierFk`, `t`.`totalEntries` AS `totalEntries`, - `t`.`appointment` AS `appointment`, `t`.`awbFk` AS `awbFk`, `t`.`isRaid` AS `isRaid`, `t`.`daysInForward` AS `daysInForward` From 2e8e2329ec57a67c46c7fb7305c785d8e3615c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 6 Feb 2025 13:44:22 +0100 Subject: [PATCH 84/84] fix: refs #8535 deploy --- db/versions/11433-chocolateIvy/00-firstScript.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 db/versions/11433-chocolateIvy/00-firstScript.sql diff --git a/db/versions/11433-chocolateIvy/00-firstScript.sql b/db/versions/11433-chocolateIvy/00-firstScript.sql new file mode 100644 index 0000000000..25e8b376c3 --- /dev/null +++ b/db/versions/11433-chocolateIvy/00-firstScript.sql @@ -0,0 +1 @@ +ALTER TABLE vn.recovery DROP FOREIGN KEY cliente333;