From 1d42f58c39b9ecaea22067585a1dc8da3404d827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Mon, 16 Sep 2024 15:09:34 +0200 Subject: [PATCH 01/10] fix: refs #7760 tmp.ticketIPT --- db/routines/vn/procedures/ticket_splitItemPackingType.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/db/routines/vn/procedures/ticket_splitItemPackingType.sql b/db/routines/vn/procedures/ticket_splitItemPackingType.sql index 6a974ea39..dd03ef692 100644 --- a/db/routines/vn/procedures/ticket_splitItemPackingType.sql +++ b/db/routines/vn/procedures/ticket_splitItemPackingType.sql @@ -80,6 +80,8 @@ BEGIN SELECT ticketFk, itemPackingTypeFk FROM tSalesToMove GROUP BY ticketFk; + UNION + SELECT vSelf, vOriginalItemPackingTypeFk; DROP TEMPORARY TABLE tSalesToMove; END$$ From faf963ba524a8f0d49fa9b68d993a513057c30b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Mon, 16 Sep 2024 15:11:51 +0200 Subject: [PATCH 02/10] fix: refs #7760 tmp.ticketIPT --- db/routines/vn/procedures/ticket_splitItemPackingType.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/routines/vn/procedures/ticket_splitItemPackingType.sql b/db/routines/vn/procedures/ticket_splitItemPackingType.sql index dd03ef692..407b8cdde 100644 --- a/db/routines/vn/procedures/ticket_splitItemPackingType.sql +++ b/db/routines/vn/procedures/ticket_splitItemPackingType.sql @@ -79,7 +79,7 @@ BEGIN ) ENGINE=MEMORY SELECT ticketFk, itemPackingTypeFk FROM tSalesToMove - GROUP BY ticketFk; + GROUP BY ticketFk UNION SELECT vSelf, vOriginalItemPackingTypeFk; From 8f9a7802ab854a82683cd58a06b499b623cca03b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Tue, 17 Sep 2024 15:50:51 +0200 Subject: [PATCH 03/10] fix: refs #7760 tmp.ticketIPT --- .../vn/procedures/productionControl.sql | 21 ++++++++----------- .../ticket_splitItemPackingType.sql | 4 ++-- .../11241-grayPalmetto/00-firstScript.sql | 2 ++ 3 files changed, 13 insertions(+), 14 deletions(-) create mode 100644 db/versions/11241-grayPalmetto/00-firstScript.sql diff --git a/db/routines/vn/procedures/productionControl.sql b/db/routines/vn/procedures/productionControl.sql index 5d97e3f55..ffc8040d5 100644 --- a/db/routines/vn/procedures/productionControl.sql +++ b/db/routines/vn/procedures/productionControl.sql @@ -99,7 +99,7 @@ proc: BEGIN LEFT JOIN `zone` z ON z.id = t.zoneFk LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk AND DATE(t.shipped) = zc.dated - LEFT JOIN ticketParking tp ON tp.ticketFk = t.id + LEFT JOIN ticketParking tp ON tp.ticketFk = t.id LEFT JOIN parking pk ON pk.id = tp.parkingFk WHERE t.warehouseFk = vWarehouseFk AND dm.code IN ('AGENCY', 'DELIVERY', 'PICKUP'); @@ -124,8 +124,8 @@ proc: BEGIN 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, ''), + 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',''), @@ -141,7 +141,7 @@ proc: BEGIN LEFT JOIN bs.clientNewBorn cnb ON cnb.clientFk = pb.clientFk JOIN productionConfig pc SET pb.problem = TRIM(CAST(CONCAT('NUEVO ', pb.problem) AS CHAR(255))) - WHERE (cnb.clientFk IS NULL OR cnb.isRookie) + WHERE (cnb.clientFk IS NULL OR cnb.isRookie) AND pc.rookieDays; -- Líneas y volumen por ticket @@ -268,16 +268,13 @@ proc: BEGIN UPDATE tmp.productionBuffer pb JOIN sale s ON s.ticketFk = pb.ticketFk JOIN item i ON i.id = s.itemFk - JOIN itemType it ON it.id = i.typeFk - JOIN itemCategory ic ON ic.id = it.categoryFk - JOIN cache.last_buy lb ON lb.warehouse_id = vWarehouseFk AND lb.item_id = s.itemFk + JOIN cache.last_buy lb ON lb.warehouse_id = vWarehouseFk + AND lb.item_id = s.itemFk JOIN buy b ON b.id = lb.buy_id JOIN packaging p ON p.id = b.packagingFk - JOIN productionConfig pc - SET hasPlantTray = TRUE - WHERE ic.code = 'plant' - AND p.`depth` >= pc.minPlantTrayLength - AND pb.isOwn; + SET pb.hasPlantTray = TRUE + WHERE p.isPlantTray + AND pb.isOwn; DROP TEMPORARY TABLE tmp.productionTicket, diff --git a/db/routines/vn/procedures/ticket_splitItemPackingType.sql b/db/routines/vn/procedures/ticket_splitItemPackingType.sql index 407b8cdde..7839b0008 100644 --- a/db/routines/vn/procedures/ticket_splitItemPackingType.sql +++ b/db/routines/vn/procedures/ticket_splitItemPackingType.sql @@ -3,7 +3,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_splitItemPacki vSelf INT, vOriginalItemPackingTypeFk VARCHAR(1) ) -BEGIN +proc: BEGIN /** * Clona y reparte las líneas de ventas de un ticket en funcion del tipo de empaquetado. * Respeta el id de ticket inicial para el tipo de empaquetado propuesto. @@ -31,7 +31,7 @@ BEGIN AND i.itemPackingTypeFk = vOriginalItemPackingTypeFk; IF NOT vHasItemPackingType THEN - CALL util.throw('The ticket has not sales with the itemPackingType'); + LEAVE proc; END IF; CREATE OR REPLACE TEMPORARY TABLE tSalesToMove ( diff --git a/db/versions/11241-grayPalmetto/00-firstScript.sql b/db/versions/11241-grayPalmetto/00-firstScript.sql new file mode 100644 index 000000000..b9ae692c6 --- /dev/null +++ b/db/versions/11241-grayPalmetto/00-firstScript.sql @@ -0,0 +1,2 @@ +ALTER TABLE vn.packaging ADD IF NOT EXISTS isPlantTray BOOL DEFAULT FALSE NOT NULL + COMMENT 'The container is a plant tray. Used to restrict the picking of full plant trays, to make previous picking.'; \ No newline at end of file From ba6b6572c38139feb6bce0858a2b6fdbb5824f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Wed, 18 Sep 2024 09:45:12 +0200 Subject: [PATCH 04/10] fix: collection_new --- db/routines/vn/procedures/collection_new.sql | 28 +++++++++----------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/db/routines/vn/procedures/collection_new.sql b/db/routines/vn/procedures/collection_new.sql index 53f5500a0..41f1a1028 100644 --- a/db/routines/vn/procedures/collection_new.sql +++ b/db/routines/vn/procedures/collection_new.sql @@ -173,26 +173,24 @@ BEGIN -- Hay que excluir aquellos que no tengan la misma hora de preparacion, si procede IF vHasUniqueCollectionTime THEN - - SELECT ticketFk INTO vFirstTicketFk - FROM tmp.productionBuffer - ORDER BY HH, - mm, - productionOrder DESC, - m3 DESC, - agency, - zona, - routeFk, - ticketFk - LIMIT 1; - DELETE pb FROM tmp.productionBuffer pb JOIN tmp.productionBuffer pb2 ON pb2.ticketFk = vFirstTicketFk - AND (pb.HH <> pb2.HH OR pb.mm <> pb2.mm); - + AND (pb.HH <> pb2.HH OR pb.mm <> pb2.mm); END IF; + SELECT ticketFk INTO vFirstTicketFk + FROM tmp.productionBuffer + ORDER BY HH, + mm, + productionOrder DESC, + m3 DESC, + agency, + zona, + routeFk, + ticketFk + LIMIT 1; + OPEN vTickets; l: LOOP SET vDone = FALSE; From d5f18b918778976bc8df0f5e1b3bef2daf3397e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Wed, 18 Sep 2024 10:25:21 +0200 Subject: [PATCH 05/10] fix: collection_new --- .../ticket_splitItemPackingType.sql | 92 +++++++------------ 1 file changed, 34 insertions(+), 58 deletions(-) diff --git a/db/routines/vn/procedures/ticket_splitItemPackingType.sql b/db/routines/vn/procedures/ticket_splitItemPackingType.sql index 6baf944ee..63e219764 100644 --- a/db/routines/vn/procedures/ticket_splitItemPackingType.sql +++ b/db/routines/vn/procedures/ticket_splitItemPackingType.sql @@ -5,23 +5,21 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_splitItemPacki ) proc: BEGIN /** - * Clona y reparte las ventas de un ticket en funcion del tipo de empaquetado. - * Respeta el id inicial para el tipo propuesto. + * Clona y reparte las líneas de ventas de un ticket en funcion del tipo de empaquetado. + * Respeta el id de ticket inicial para el tipo de empaquetado propuesto. * * @param vSelf Id ticket - * @param vOriginalItemPackingTypeFk Tipo para el que se reserva el número de ticket original + * @param vOriginalItemPackingTypeFk Tipo empaquetado al que se mantiene el ticket original * @return table tmp.ticketIPT(ticketFk, itemPackingTypeFk) */ - DECLARE vItemPackingTypeFk VARCHAR(1) DEFAULT 'H'; - DECLARE vNewTicketFk INT; - DECLARE vPackingTypesToSplit INT; DECLARE vDone INT DEFAULT FALSE; + DECLARE vHasItemPackingType BOOL; + DECLARE vItemPackingTypeFk INT; + DECLARE vNewTicketFk INT; - DECLARE vSaleGroup CURSOR FOR - SELECT itemPackingTypeFk - FROM tSaleGroup - WHERE itemPackingTypeFk IS NOT NULL - ORDER BY (itemPackingTypeFk = vOriginalItemPackingTypeFk) DESC; + DECLARE vItemPackingTypes CURSOR FOR + SELECT DISTINCT itemPackingTypeFk + FROM tSalesToMove; DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; @@ -36,59 +34,39 @@ proc: BEGIN LEAVE proc; END IF; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketIPT( + CREATE OR REPLACE TEMPORARY TABLE tSalesToMove ( ticketFk INT, - itemPackingTypeFk VARCHAR(1) - ) ENGINE = MEMORY; + saleFk INT, + itemPackingTypeFk INT + ) ENGINE=MEMORY; - CASE vPackingTypesToSplit - WHEN 0 THEN - INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) - VALUES(vSelf, vItemPackingTypeFk); - WHEN 1 THEN - INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) - SELECT vSelf, itemPackingTypeFk - FROM tSaleGroup - WHERE itemPackingTypeFk IS NOT NULL; - ELSE - OPEN vSaleGroup; - FETCH vSaleGroup INTO vItemPackingTypeFk; + INSERT INTO tSalesToMove (saleFk, itemPackingTypeFk) + SELECT s.id, i.itemPackingTypeFk + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + WHERE t.id = vSelf + AND i.itemPackingTypeFk <> vOriginalItemPackingTypeFk; - INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) - VALUES(vSelf, vItemPackingTypeFk); + OPEN vItemPackingTypes; - l: LOOP - SET vDone = FALSE; - FETCH vSaleGroup INTO vItemPackingTypeFk; + l: LOOP + SET vDone = FALSE; + FETCH vItemPackingTypes INTO vItemPackingTypeFk; - IF vDone THEN - LEAVE l; - END IF; + IF vDone THEN + LEAVE l; + END IF; - CALL ticket_Clone(vSelf, vNewTicketFk); + CALL ticket_Clone(vSelf, vNewTicketFk); - INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) - VALUES(vNewTicketFk, vItemPackingTypeFk); - END LOOP; + UPDATE tSalesToMove + SET ticketFk = vNewTicketFk + WHERE itemPackingTypeFk = vItemPackingTypeFk; - CLOSE vSaleGroup; + END LOOP; - SELECT s.id - FROM sale s - JOIN tSale ts ON ts.id = s.id - JOIN tmp.ticketIPT t ON t.itemPackingTypeFk = ts.itemPackingTypeFk - FOR UPDATE; - - UPDATE sale s - JOIN tSale ts ON ts.id = s.id - JOIN tmp.ticketIPT t ON t.itemPackingTypeFk = ts.itemPackingTypeFk - SET s.ticketFk = t.ticketFk; - - SELECT itemPackingTypeFk INTO vItemPackingTypeFk - FROM tSaleGroup sg - WHERE sg.itemPackingTypeFk IS NOT NULL - ORDER BY sg.itemPackingTypeFk - LIMIT 1; + CLOSE vItemPackingTypes; UPDATE sale s JOIN tSalesToMove stm ON stm.saleFk = s.id @@ -105,8 +83,6 @@ proc: BEGIN UNION SELECT vSelf, vOriginalItemPackingTypeFk; - DROP TEMPORARY TABLE - tSale, - tSaleGroup; + DROP TEMPORARY TABLE tSalesToMove; END$$ DELIMITER ; From 4f9b6030e8ed1d2dbabc3b93a21692b6f7872751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Wed, 18 Sep 2024 10:30:16 +0200 Subject: [PATCH 06/10] fix: collection_new --- db/routines/vn/procedures/collection_new.sql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/db/routines/vn/procedures/collection_new.sql b/db/routines/vn/procedures/collection_new.sql index 6a15ce73c..782243c03 100644 --- a/db/routines/vn/procedures/collection_new.sql +++ b/db/routines/vn/procedures/collection_new.sql @@ -200,14 +200,6 @@ BEGIN OR pb.hasPlantTray; END IF; - -- Hay que excluir aquellos que no tengan la misma hora de preparacion, si procede - IF vHasUniqueCollectionTime THEN - DELETE pb - FROM tmp.productionBuffer pb - JOIN tmp.productionBuffer pb2 ON pb2.ticketFk = vFirstTicketFk - AND (pb.HH <> pb2.HH OR pb.mm <> pb2.mm); - END IF; - SELECT ticketFk INTO vFirstTicketFk FROM tmp.productionBuffer ORDER BY HH, @@ -219,6 +211,14 @@ BEGIN routeFk, ticketFk LIMIT 1; + + -- Hay que excluir aquellos que no tengan la misma hora de preparacion, si procede + IF vHasUniqueCollectionTime THEN + DELETE pb + FROM tmp.productionBuffer pb + JOIN tmp.productionBuffer pb2 ON pb2.ticketFk = vFirstTicketFk + AND (pb.HH <> pb2.HH OR pb.mm <> pb2.mm); + END IF; SET vTicketFk = vFirstTicketFk; SET @lines = 0; From 26a078504f8ccb4e63cbb31d50a1b42658a7a450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Wed, 18 Sep 2024 11:27:57 +0200 Subject: [PATCH 07/10] fix: collection_new --- db/routines/vn/procedures/collection_new.sql | 290 ++++++++---------- .../vn/procedures/ticket_mergeSales.sql | 38 ++- 2 files changed, 146 insertions(+), 182 deletions(-) diff --git a/db/routines/vn/procedures/collection_new.sql b/db/routines/vn/procedures/collection_new.sql index 782243c03..eef0cc9f6 100644 --- a/db/routines/vn/procedures/collection_new.sql +++ b/db/routines/vn/procedures/collection_new.sql @@ -12,30 +12,29 @@ BEGIN DECLARE vLinesLimit INT; DECLARE vTicketLines INT; DECLARE vVolumeLimit DECIMAL; - DECLARE vTicketVolume DECIMAL; DECLARE vSizeLimit INT; + DECLARE vTicketVolume DECIMAL; DECLARE vMaxTickets INT; - DECLARE vStateFk VARCHAR(45); + DECLARE vStateCode VARCHAR(45); DECLARE vFirstTicketFk INT; - DECLARE vHour INT; - DECLARE vMinute INT; DECLARE vWorkerCode VARCHAR(3); - DECLARE vWagonCounter INT DEFAULT 0; + DECLARE vWagonCounter INT DEFAULT 1; DECLARE vTicketFk INT; DECLARE vItemPackingTypeFk VARCHAR(1); - DECLARE vHasAssignedTickets BOOLEAN; + DECLARE vHasAssignedTickets BOOL; DECLARE vHasUniqueCollectionTime BOOL; - DECLARE vDone INT DEFAULT FALSE; - DECLARE vLockName VARCHAR(215); - DECLARE vLockTime INT DEFAULT 30; + DECLARE vHeight INT; + DECLARE vVolume INT; + DECLARE vLiters INT; + DECLARE vLines INT; + DECLARE vTotalLines INT DEFAULT 0; + DECLARE vTotalVolume INT DEFAULT 0; DECLARE vFreeWagonFk INT; - DECLARE vErrorNumber INT; - DECLARE vErrorMsg TEXT; + DECLARE vDone INT DEFAULT FALSE; - DECLARE c1 CURSOR FOR + DECLARE vTickets CURSOR FOR SELECT ticketFk, `lines`, m3 FROM tmp.productionBuffer - WHERE ticketFk <> vFirstTicketFk ORDER BY HH, mm, productionOrder DESC, @@ -48,26 +47,6 @@ BEGIN DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - DECLARE EXIT HANDLER FOR SQLEXCEPTION - BEGIN - GET DIAGNOSTICS CONDITION 1 - vErrorNumber = MYSQL_ERRNO, - vErrorMsg = MESSAGE_TEXT; - - CALL util.debugAdd('collection_new', JSON_OBJECT( - 'errorNumber', vErrorNumber, - 'errorMsg', vErrorMsg, - 'lockName', vLockName, - 'userFk', vUserFk, - 'ticketFk', vTicketFk - )); -- Tmp - - IF vLockName IS NOT NULL THEN - DO RELEASE_LOCK(vLockName); - END IF; - RESIGNAL; - END; - SELECT pc.ticketTrolleyMax * o.numberOfWagons, pc.hasUniqueCollectionTime, w.code, @@ -78,36 +57,26 @@ BEGIN o.trainFk, o.linesLimit, o.volumeLimit, - o.sizeLimit, - pc.collection_new_lockname + o.sizeLimit INTO vMaxTickets, - vHasUniqueCollectionTime, - vWorkerCode, - vWarehouseFk, - vItemPackingTypeFk, - vStateFk, - vWagons, - vTrainFk, - vLinesLimit, - vVolumeLimit, - vSizeLimit, - vLockName - FROM productionConfig pc - JOIN worker w ON w.id = vUserFk + vHasUniqueCollectionTime, + vWorkerCode, + vWarehouseFk, + vItemPackingTypeFk, + vStateCode, + vWagons, + vTrainFk, + vLinesLimit, + vVolumeLimit, + vSizeLimit + FROM worker w + JOIN operator o ON o.workerFk = w.id JOIN state st ON st.`code` = 'ON_PREPARATION' - JOIN operator o ON o.workerFk = vUserFk; - - SET vLockName = CONCAT_WS('/', - vLockName, - vWarehouseFk, - vItemPackingTypeFk - ); - - IF NOT GET_LOCK(vLockName, vLockTime) THEN - CALL util.throw(CONCAT('Cannot get lock: ', vLockName)); - END IF; + JOIN productionConfig pc + WHERE w.id = vUserFk; -- Se prepara el tren, con tantos vagones como sea necesario. + CREATE OR REPLACE TEMPORARY TABLE tTrain (wagon INT, shelve INT, @@ -118,59 +87,58 @@ BEGIN PRIMARY KEY(wagon, shelve)) ENGINE = MEMORY; - WHILE vWagons > vWagonCounter DO - SET vWagonCounter = vWagonCounter + 1; - - INSERT INTO tTrain(wagon, shelve, liters, `lines`, height) - SELECT vWagonCounter, cv.`level` , cv.liters , cv.`lines` , cv.height - FROM collectionVolumetry cv - WHERE cv.trainFk = vTrainFk + INSERT INTO tTrain (wagon, shelve, liters, `lines`, height) + WITH RECURSIVE wagonSequence AS ( + SELECT vWagonCounter wagon + UNION ALL + SELECT wagon + 1 wagon + FROM wagonSequence + WHERE wagon < vWagonCounter + vWagons -1 + ) + SELECT ws.wagon, cv.`level`, cv.liters, cv.`lines`, cv.height + FROM wagonSequence ws + JOIN vn.collectionVolumetry cv ON cv.trainFk = vTrainFk AND cv.itemPackingTypeFk = vItemPackingTypeFk; - END WHILE; -- Esto desaparecerá cuando tengamos la table cache.ticket + CALL productionControl(vWarehouseFk, 0); ALTER TABLE tmp.productionBuffer ADD COLUMN liters INT, ADD COLUMN height INT; - -- Se obtiene nº de colección. - INSERT INTO collection - SET itemPackingTypeFk = vItemPackingTypeFk, - trainFk = vTrainFk, - wagons = vWagons, - warehouseFk = vWarehouseFk; - - SELECT LAST_INSERT_ID() INTO vCollectionFk; - -- Los tickets de recogida en Algemesí sólo se sacan si están asignados. -- Los pedidos con riesgo no se sacan aunque se asignen. - DELETE pb.* + + DELETE pb FROM tmp.productionBuffer pb JOIN state s ON s.id = pb.state WHERE (pb.agency = 'REC_ALGEMESI' AND s.code <> 'PICKER_DESIGNED') OR pb.problem LIKE '%RIESGO%'; - -- Comprobamos si hay tickets asignados. En ese caso, nos centramos - -- exclusivamente en esos tickets y los sacamos independientemente - -- de problemas o tamaños - SELECT COUNT(*) INTO vHasAssignedTickets - FROM tmp.productionBuffer pb - JOIN state s ON s.id = pb.state - WHERE s.code = 'PICKER_DESIGNED' - AND pb.workerCode = vWorkerCode; + -- Si hay tickets asignados, nos centramos exclusivamente en esos tickets + -- y los sacamos independientemente de problemas o tamaños + + SELECT EXISTS ( + SELECT TRUE + FROM tmp.productionBuffer pb + JOIN state s ON s.id = pb.state + WHERE s.code = 'PICKER_DESIGNED' + AND pb.workerCode = vWorkerCode + ) INTO vHasAssignedTickets; -- Se dejan en la tabla tmp.productionBuffer sólo aquellos tickets adecuados + IF vHasAssignedTickets THEN - DELETE pb.* + DELETE pb FROM tmp.productionBuffer pb JOIN state s ON s.id = pb.state WHERE s.code <> 'PICKER_DESIGNED' OR pb.workerCode <> vWorkerCode; ELSE - DELETE pb.* + DELETE pb FROM tmp.productionBuffer pb JOIN state s ON s.id = pb.state JOIN agencyMode am ON am.id = pb.agencyModeFk @@ -193,13 +161,21 @@ BEGIN OR (NOT pb.H AND pb.V > 0 AND vItemPackingTypeFk = 'H') OR (NOT pb.V AND vItemPackingTypeFk = 'V') OR (pc.isPreviousPreparationRequired AND pb.previousWithoutParking) - OR LENGTH(pb.problem) > 0 + OR LENGTH(pb.problem) OR pb.lines > vLinesLimit OR pb.m3 > vVolumeLimit OR sub.maxSize > vSizeLimit OR pb.hasPlantTray; END IF; + -- Hay que excluir aquellos que no tengan la misma hora de preparacion, si procede + IF vHasUniqueCollectionTime THEN + DELETE pb + FROM tmp.productionBuffer pb + JOIN tmp.productionBuffer pb2 ON pb2.ticketFk = vFirstTicketFk + AND (pb.HH <> pb2.HH OR pb.mm <> pb2.mm); + END IF; + SELECT ticketFk INTO vFirstTicketFk FROM tmp.productionBuffer ORDER BY HH, @@ -211,46 +187,38 @@ BEGIN routeFk, ticketFk LIMIT 1; - - -- Hay que excluir aquellos que no tengan la misma hora de preparacion, si procede - IF vHasUniqueCollectionTime THEN - DELETE pb - FROM tmp.productionBuffer pb - JOIN tmp.productionBuffer pb2 ON pb2.ticketFk = vFirstTicketFk - AND (pb.HH <> pb2.HH OR pb.mm <> pb2.mm); - END IF; - SET vTicketFk = vFirstTicketFk; - SET @lines = 0; - SET @volume = 0; - - OPEN c1; - read_loop: LOOP + OPEN vTickets; + l: LOOP SET vDone = FALSE; + FETCH vTickets INTO vTicketFk, vTicketLines, vTicketVolume; + + IF vDone THEN + LEAVE l; + END IF; -- Buscamos un ticket que cumpla con los requisitos en el listado - IF ((vTicketLines + @lines) <= vLinesLimit OR vLinesLimit IS NULL) - AND ((vTicketVolume + @volume) <= vVolumeLimit OR vVolumeLimit IS NULL) THEN + + IF (vLinesLimit IS NULL OR (vTotalLines + vTicketLines) <= vLinesLimit) + AND (vVolumeLimit IS NULL OR (vTotalVolume + vTicketVolume) <= vVolumeLimit) THEN CALL ticket_splitItemPackingType(vTicketFk, vItemPackingTypeFk); DROP TEMPORARY TABLE tmp.ticketIPT; + SELECT COUNT(*), SUM(litros), MAX(i.`size`), SUM(sv.volume) + INTO vLines, vLiters, vHeight, vVolume + FROM saleVolume sv + JOIN sale s ON s.id = sv.saleFk + JOIN item i ON i.id = s.itemFk + WHERE sv.ticketFk = vTicketFk; + + SET vTotalVolume = vTotalVolume + vVolume, + vTotalLines = vTotalLines + vLines; + UPDATE tmp.productionBuffer pb - JOIN ( - SELECT SUM(litros) liters, - @lines:= COUNT(*) + @lines, - COUNT(*) `lines`, - MAX(i.`size`) height, - @volume := SUM(sv.volume) + @volume, - SUM(sv.volume) volume - FROM saleVolume sv - JOIN sale s ON s.id = sv.saleFk - JOIN item i ON i.id = s.itemFk - WHERE sv.ticketFk = vTicketFk - ) sub - SET pb.liters = sub.liters, - pb.`lines` = sub.`lines`, - pb.height = sub.height + SET pb.liters = vLiters, + pb.`lines` = vLines, + pb.height = vHeight WHERE pb.ticketFk = vTicketFk; UPDATE tTrain tt @@ -267,17 +235,13 @@ BEGIN tt.height LIMIT 1; - -- Si no le encuentra una balda adecuada, intentamos darle un carro entero si queda alguno libre + -- Si no le encuentra una balda, intentamos darle un carro entero libre + IF NOT (SELECT COUNT(*) FROM tTrain WHERE ticketFk) THEN - SELECT tt.wagon - INTO vFreeWagonFk - FROM tTrain tt - LEFT JOIN ( - SELECT DISTINCT wagon - FROM tTrain - WHERE ticketFk IS NOT NULL - ) nn ON nn.wagon = tt.wagon - WHERE nn.wagon IS NULL + SELECT wagon INTO vFreeWagonFk + FROM tTrain + GROUP BY wagon + HAVING SUM(IFNULL(ticketFk, 0)) = 0 ORDER BY wagon LIMIT 1; @@ -286,38 +250,35 @@ BEGIN SET ticketFk = vFirstTicketFk WHERE wagon = vFreeWagonFk; - -- Se anulan el resto de carros libres para que sólo uno lleve un pedido excesivo - DELETE tt.* - FROM tTrain tt - LEFT JOIN ( - SELECT DISTINCT wagon - FROM tTrain - WHERE ticketFk IS NOT NULL - ) nn ON nn.wagon = tt.wagon - WHERE nn.wagon IS NULL; - END IF; - END IF; + -- Se anulan el resto de carros libres, + -- máximo un carro con pedido excesivo - FETCH c1 INTO vTicketFk, vTicketLines, vTicketVolume; - IF vDone OR NOT (SELECT COUNT(*) FROM tTrain WHERE ticketFk IS NULL) THEN - LEAVE read_loop; - END IF; - ELSE - FETCH c1 INTO vTicketFk, vTicketLines, vTicketVolume; - IF vDone THEN - LEAVE read_loop; - END IF; + DELETE tt + FROM tTrain tt + JOIN (SELECT wagon + FROM tTrain + GROUP BY wagon + HAVING SUM(IFNULL(ticketFk, 0)) = 0 + ) sub ON sub.wagon = tt.wagon; + END IF; + END IF; END IF; END LOOP; - CLOSE c1; + CLOSE vTickets; IF (SELECT COUNT(*) FROM tTrain WHERE ticketFk) THEN - UPDATE collection c - JOIN state st ON st.code = 'ON_PREPARATION' - SET c.stateFk = st.id - WHERE c.id = vCollectionFk; + -- Se obtiene nº de colección + + INSERT INTO collection + SET itemPackingTypeFk = vItemPackingTypeFk, + trainFk = vTrainFk, + wagons = vWagons, + warehouseFk = vWarehouseFk; + + SELECT LAST_INSERT_ID() INTO vCollectionFk; -- Asigna las bandejas + INSERT IGNORE INTO ticketCollection(ticketFk, collectionFk, `level`, wagon, liters) SELECT tt.ticketFk, vCollectionFk, tt.shelve, tt.wagon, tt.liters FROM tTrain tt @@ -325,37 +286,34 @@ BEGIN ORDER BY tt.wagon, tt.shelve; -- Actualiza el estado de los tickets - CALL collection_setState(vCollectionFk, vStateFk); + + CALL collection_setState(vCollectionFk, vStateCode); -- Aviso para la preparacion previa + INSERT INTO ticketDown(ticketFk, collectionFk) SELECT tc.ticketFk, tc.collectionFk FROM ticketCollection tc WHERE tc.collectionFk = vCollectionFk; - CALL sales_mergeByCollection(vCollectionFk); + CALL collection_mergeSales(vCollectionFk); UPDATE `collection` c - JOIN ( + JOIN( SELECT COUNT(*) saleTotalCount, SUM(s.isPicked <> 0) salePickedCount FROM ticketCollection tc JOIN sale s ON s.ticketFk = tc.ticketFk - WHERE tc.collectionFk = vCollectionFk - AND s.quantity > 0 - ) sub + WHERE tc.collectionFk = vCollectionFk + AND s.quantity > 0 + )sub SET c.saleTotalCount = sub.saleTotalCount, c.salePickedCount = sub.salePickedCount WHERE c.id = vCollectionFk; - ELSE - DELETE FROM `collection` - WHERE id = vCollectionFk; - SET vCollectionFk = NULL; + SET vCollectionFk = NULL; END IF; - DO RELEASE_LOCK(vLockName); - DROP TEMPORARY TABLE tTrain, tmp.productionBuffer; diff --git a/db/routines/vn/procedures/ticket_mergeSales.sql b/db/routines/vn/procedures/ticket_mergeSales.sql index 28b2dc1c0..2dc3a39da 100644 --- a/db/routines/vn/procedures/ticket_mergeSales.sql +++ b/db/routines/vn/procedures/ticket_mergeSales.sql @@ -3,41 +3,47 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_mergeSales`( vSelf INT ) BEGIN + DECLARE vHasSalesToMerge BOOL; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; RESIGNAL; END; + START TRANSACTION; + + SELECT id INTO vSelf + FROM ticket + WHERE id = vSelf FOR UPDATE; + CREATE OR REPLACE TEMPORARY TABLE tSalesToPreserve (PRIMARY KEY (id)) ENGINE = MEMORY - SELECT s.id, s.itemFk, SUM(s.quantity) newQuantity + SELECT s.id, s.itemFk, SUM(s.quantity) newQuantity FROM sale s JOIN item i ON i.id = s.itemFk JOIN itemType it ON it.id = i.typeFk WHERE s.ticketFk = vSelf AND it.isMergeable - GROUP BY s.itemFk, s.price, s.discount; + GROUP BY s.itemFk, s.price, s.discount + HAVING COUNT(*) > 1; - START TRANSACTION; + SELECT COUNT(*) INTO vHasSalesToMerge + FROM tSalesToPreserve; - UPDATE sale s - JOIN tSalesToPreserve stp ON stp.id = s.id - SET s.quantity = newQuantity - WHERE s.ticketFk = vSelf; + IF vHasSalesToMerge THEN + UPDATE sale s + JOIN tSalesToPreserve stp ON stp.id = s.id + SET s.quantity = newQuantity; - DELETE s.* - FROM sale s - LEFT JOIN tSalesToPreserve stp ON stp.id = s.id - JOIN item i ON i.id = s.itemFk - JOIN itemType it ON it.id = i.typeFk - WHERE s.ticketFk = vSelf - AND stp.id IS NULL - AND it.isMergeable; + DELETE s + FROM sale s + JOIN tSalesToPreserve stp ON stp.itemFk = s.itemFk + WHERE s.ticketFk = vSelf + AND s.id <> stp.id; + END IF; COMMIT; - DROP TEMPORARY TABLE tSalesToPreserve; END$$ DELIMITER ; From e8a203efc701f415bb7b5032f57e43f2404bad58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 19 Sep 2024 12:09:36 +0200 Subject: [PATCH 08/10] fix: ticket_splitItemPackingType --- .../vn/procedures/ticket_splitItemPackingType.sql | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/db/routines/vn/procedures/ticket_splitItemPackingType.sql b/db/routines/vn/procedures/ticket_splitItemPackingType.sql index 63e219764..c0b3d9625 100644 --- a/db/routines/vn/procedures/ticket_splitItemPackingType.sql +++ b/db/routines/vn/procedures/ticket_splitItemPackingType.sql @@ -30,6 +30,12 @@ proc: BEGIN WHERE t.id = vSelf AND i.itemPackingTypeFk = vOriginalItemPackingTypeFk; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketIPT( + ticketFk INT, + itemPackingTypeFk VARCHAR(1) + ) ENGINE=MEMORY + SELECT vSelf, vOriginalItemPackingTypeFk; + IF NOT vHasItemPackingType THEN LEAVE proc; END IF; @@ -73,15 +79,10 @@ proc: BEGIN SET s.ticketFk = stm.ticketFk WHERE stm.ticketFk; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketIPT( - ticketFk INT, - itemPackingTypeFk VARCHAR(1) - ) ENGINE=MEMORY + INSERT INTO tmp.ticketIPT SELECT ticketFk, itemPackingTypeFk FROM tSalesToMove - GROUP BY ticketFk - UNION - SELECT vSelf, vOriginalItemPackingTypeFk; + GROUP BY ticketFk; DROP TEMPORARY TABLE tSalesToMove; END$$ From 889b86644bb0e4fbdc20bbc0a42284fba2dd998a Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 20 Sep 2024 09:14:38 +0200 Subject: [PATCH 09/10] fix: refs #6898 filter fix --- modules/supplier/back/methods/supplier/filter.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/supplier/back/methods/supplier/filter.js b/modules/supplier/back/methods/supplier/filter.js index 0b473f7df..a52eb6444 100644 --- a/modules/supplier/back/methods/supplier/filter.js +++ b/modules/supplier/back/methods/supplier/filter.js @@ -81,7 +81,7 @@ module.exports = Self => { let stmts = []; let stmt; stmt = new ParameterizedSQL( - `SELECT + `SELECT s.id, s.name AS socialName, s.nickname AS alias, @@ -92,10 +92,13 @@ module.exports = Self => { s.payDay, s.phone, s.city, + s.countryFk, + c.name country, pm.name AS payMethod, pd.payDem AS payDem FROM vn.supplier s LEFT JOIN vn.payMethod pm ON pm.id = s.payMethodFk + LEFT JOIN vn.country c ON c.id = s.countryFk LEFT JOIN vn.payDem pd ON pd.id = s.payDemFk` ); From 633766e58b1ab6c6668e673518c6f8d0520ab91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Fri, 20 Sep 2024 10:06:10 +0200 Subject: [PATCH 10/10] fix: recupero version anterior --- db/routines/vn/procedures/collection_new.sql | 301 ++++++++++-------- .../vn/procedures/productionControl.sql | 16 +- .../vn/procedures/ticket_mergeSales.sql | 38 +-- .../ticket_splitItemPackingType.sql | 147 +++++---- 4 files changed, 293 insertions(+), 209 deletions(-) diff --git a/db/routines/vn/procedures/collection_new.sql b/db/routines/vn/procedures/collection_new.sql index eef0cc9f6..dc1280373 100644 --- a/db/routines/vn/procedures/collection_new.sql +++ b/db/routines/vn/procedures/collection_new.sql @@ -12,29 +12,30 @@ BEGIN DECLARE vLinesLimit INT; DECLARE vTicketLines INT; DECLARE vVolumeLimit DECIMAL; - DECLARE vSizeLimit INT; DECLARE vTicketVolume DECIMAL; + DECLARE vSizeLimit INT; DECLARE vMaxTickets INT; - DECLARE vStateCode VARCHAR(45); + DECLARE vStateFk VARCHAR(45); DECLARE vFirstTicketFk INT; + DECLARE vHour INT; + DECLARE vMinute INT; DECLARE vWorkerCode VARCHAR(3); - DECLARE vWagonCounter INT DEFAULT 1; + DECLARE vWagonCounter INT DEFAULT 0; DECLARE vTicketFk INT; DECLARE vItemPackingTypeFk VARCHAR(1); - DECLARE vHasAssignedTickets BOOL; + DECLARE vHasAssignedTickets BOOLEAN; DECLARE vHasUniqueCollectionTime BOOL; - DECLARE vHeight INT; - DECLARE vVolume INT; - DECLARE vLiters INT; - DECLARE vLines INT; - DECLARE vTotalLines INT DEFAULT 0; - DECLARE vTotalVolume INT DEFAULT 0; - DECLARE vFreeWagonFk INT; DECLARE vDone INT DEFAULT FALSE; + DECLARE vLockName VARCHAR(215); + DECLARE vLockTime INT DEFAULT 30; + DECLARE vFreeWagonFk INT; + DECLARE vErrorNumber INT; + DECLARE vErrorMsg TEXT; - DECLARE vTickets CURSOR FOR + DECLARE c1 CURSOR FOR SELECT ticketFk, `lines`, m3 FROM tmp.productionBuffer + WHERE ticketFk <> vFirstTicketFk ORDER BY HH, mm, productionOrder DESC, @@ -47,6 +48,26 @@ BEGIN DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + GET DIAGNOSTICS CONDITION 1 + vErrorNumber = MYSQL_ERRNO, + vErrorMsg = MESSAGE_TEXT; + + CALL util.debugAdd('collection_new', JSON_OBJECT( + 'errorNumber', vErrorNumber, + 'errorMsg', vErrorMsg, + 'lockName', vLockName, + 'userFk', vUserFk, + 'ticketFk', vTicketFk + )); -- Tmp + + IF vLockName IS NOT NULL THEN + DO RELEASE_LOCK(vLockName); + END IF; + RESIGNAL; + END; + SELECT pc.ticketTrolleyMax * o.numberOfWagons, pc.hasUniqueCollectionTime, w.code, @@ -57,26 +78,36 @@ BEGIN o.trainFk, o.linesLimit, o.volumeLimit, - o.sizeLimit + o.sizeLimit, + pc.collection_new_lockname INTO vMaxTickets, - vHasUniqueCollectionTime, - vWorkerCode, - vWarehouseFk, - vItemPackingTypeFk, - vStateCode, - vWagons, - vTrainFk, - vLinesLimit, - vVolumeLimit, - vSizeLimit - FROM worker w - JOIN operator o ON o.workerFk = w.id + vHasUniqueCollectionTime, + vWorkerCode, + vWarehouseFk, + vItemPackingTypeFk, + vStateFk, + vWagons, + vTrainFk, + vLinesLimit, + vVolumeLimit, + vSizeLimit, + vLockName + FROM productionConfig pc + JOIN worker w ON w.id = vUserFk JOIN state st ON st.`code` = 'ON_PREPARATION' - JOIN productionConfig pc - WHERE w.id = vUserFk; + JOIN operator o ON o.workerFk = vUserFk; + + SET vLockName = CONCAT_WS('/', + vLockName, + vWarehouseFk, + vItemPackingTypeFk + ); + + IF NOT GET_LOCK(vLockName, vLockTime) THEN + CALL util.throw(CONCAT('Cannot get lock: ', vLockName)); + END IF; -- Se prepara el tren, con tantos vagones como sea necesario. - CREATE OR REPLACE TEMPORARY TABLE tTrain (wagon INT, shelve INT, @@ -87,58 +118,59 @@ BEGIN PRIMARY KEY(wagon, shelve)) ENGINE = MEMORY; - INSERT INTO tTrain (wagon, shelve, liters, `lines`, height) - WITH RECURSIVE wagonSequence AS ( - SELECT vWagonCounter wagon - UNION ALL - SELECT wagon + 1 wagon - FROM wagonSequence - WHERE wagon < vWagonCounter + vWagons -1 - ) - SELECT ws.wagon, cv.`level`, cv.liters, cv.`lines`, cv.height - FROM wagonSequence ws - JOIN vn.collectionVolumetry cv ON cv.trainFk = vTrainFk + WHILE vWagons > vWagonCounter DO + SET vWagonCounter = vWagonCounter + 1; + + INSERT INTO tTrain(wagon, shelve, liters, `lines`, height) + SELECT vWagonCounter, cv.`level` , cv.liters , cv.`lines` , cv.height + FROM collectionVolumetry cv + WHERE cv.trainFk = vTrainFk AND cv.itemPackingTypeFk = vItemPackingTypeFk; + END WHILE; -- Esto desaparecerá cuando tengamos la table cache.ticket - CALL productionControl(vWarehouseFk, 0); ALTER TABLE tmp.productionBuffer ADD COLUMN liters INT, ADD COLUMN height INT; + -- Se obtiene nº de colección. + INSERT INTO collection + SET itemPackingTypeFk = vItemPackingTypeFk, + trainFk = vTrainFk, + wagons = vWagons, + warehouseFk = vWarehouseFk; + + SELECT LAST_INSERT_ID() INTO vCollectionFk; + -- Los tickets de recogida en Algemesí sólo se sacan si están asignados. -- Los pedidos con riesgo no se sacan aunque se asignen. - - DELETE pb + DELETE pb.* FROM tmp.productionBuffer pb JOIN state s ON s.id = pb.state WHERE (pb.agency = 'REC_ALGEMESI' AND s.code <> 'PICKER_DESIGNED') OR pb.problem LIKE '%RIESGO%'; - -- Si hay tickets asignados, nos centramos exclusivamente en esos tickets - -- y los sacamos independientemente de problemas o tamaños - - SELECT EXISTS ( - SELECT TRUE - FROM tmp.productionBuffer pb - JOIN state s ON s.id = pb.state - WHERE s.code = 'PICKER_DESIGNED' - AND pb.workerCode = vWorkerCode - ) INTO vHasAssignedTickets; + -- Comprobamos si hay tickets asignados. En ese caso, nos centramos + -- exclusivamente en esos tickets y los sacamos independientemente + -- de problemas o tamaños + SELECT COUNT(*) INTO vHasAssignedTickets + FROM tmp.productionBuffer pb + JOIN state s ON s.id = pb.state + WHERE s.code = 'PICKER_DESIGNED' + AND pb.workerCode = vWorkerCode; -- Se dejan en la tabla tmp.productionBuffer sólo aquellos tickets adecuados - IF vHasAssignedTickets THEN - DELETE pb + DELETE pb.* FROM tmp.productionBuffer pb JOIN state s ON s.id = pb.state WHERE s.code <> 'PICKER_DESIGNED' OR pb.workerCode <> vWorkerCode; ELSE - DELETE pb + DELETE pb.* FROM tmp.productionBuffer pb JOIN state s ON s.id = pb.state JOIN agencyMode am ON am.id = pb.agencyModeFk @@ -161,24 +193,26 @@ BEGIN OR (NOT pb.H AND pb.V > 0 AND vItemPackingTypeFk = 'H') OR (NOT pb.V AND vItemPackingTypeFk = 'V') OR (pc.isPreviousPreparationRequired AND pb.previousWithoutParking) - OR LENGTH(pb.problem) + OR LENGTH(pb.problem) > 0 OR pb.lines > vLinesLimit OR pb.m3 > vVolumeLimit OR sub.maxSize > vSizeLimit OR pb.hasPlantTray; END IF; - -- Hay que excluir aquellos que no tengan la misma hora de preparacion, si procede - IF vHasUniqueCollectionTime THEN - DELETE pb - FROM tmp.productionBuffer pb - JOIN tmp.productionBuffer pb2 ON pb2.ticketFk = vFirstTicketFk - AND (pb.HH <> pb2.HH OR pb.mm <> pb2.mm); - END IF; - - SELECT ticketFk INTO vFirstTicketFk + -- Es importante que el primer ticket se coja en todos los casos + SELECT ticketFk, + HH, + mm, + `lines`, + m3 + INTO vFirstTicketFk, + vHour, + vMinute, + vTicketLines, + vTicketVolume FROM tmp.productionBuffer - ORDER BY HH, + ORDER BY HH, mm, productionOrder DESC, m3 DESC, @@ -188,37 +222,44 @@ BEGIN ticketFk LIMIT 1; - OPEN vTickets; - l: LOOP - SET vDone = FALSE; - FETCH vTickets INTO vTicketFk, vTicketLines, vTicketVolume; + -- Hay que excluir aquellos que no tengan la misma hora de preparacion, si procede + IF vHasUniqueCollectionTime THEN + DELETE FROM tmp.productionBuffer + WHERE HH <> vHour + OR mm <> vMinute; + END IF; - IF vDone THEN - LEAVE l; - END IF; + SET vTicketFk = vFirstTicketFk; + SET @lines = 0; + SET @volume = 0; + + OPEN c1; + read_loop: LOOP + SET vDone = FALSE; -- Buscamos un ticket que cumpla con los requisitos en el listado - - IF (vLinesLimit IS NULL OR (vTotalLines + vTicketLines) <= vLinesLimit) - AND (vVolumeLimit IS NULL OR (vTotalVolume + vTicketVolume) <= vVolumeLimit) THEN + IF ((vTicketLines + @lines) <= vLinesLimit OR vLinesLimit IS NULL) + AND ((vTicketVolume + @volume) <= vVolumeLimit OR vVolumeLimit IS NULL) THEN CALL ticket_splitItemPackingType(vTicketFk, vItemPackingTypeFk); DROP TEMPORARY TABLE tmp.ticketIPT; - SELECT COUNT(*), SUM(litros), MAX(i.`size`), SUM(sv.volume) - INTO vLines, vLiters, vHeight, vVolume - FROM saleVolume sv - JOIN sale s ON s.id = sv.saleFk - JOIN item i ON i.id = s.itemFk - WHERE sv.ticketFk = vTicketFk; - - SET vTotalVolume = vTotalVolume + vVolume, - vTotalLines = vTotalLines + vLines; - UPDATE tmp.productionBuffer pb - SET pb.liters = vLiters, - pb.`lines` = vLines, - pb.height = vHeight + JOIN ( + SELECT SUM(litros) liters, + @lines:= COUNT(*) + @lines, + COUNT(*) `lines`, + MAX(i.`size`) height, + @volume := SUM(sv.volume) + @volume, + SUM(sv.volume) volume + FROM saleVolume sv + JOIN sale s ON s.id = sv.saleFk + JOIN item i ON i.id = s.itemFk + WHERE sv.ticketFk = vTicketFk + ) sub + SET pb.liters = sub.liters, + pb.`lines` = sub.`lines`, + pb.height = sub.height WHERE pb.ticketFk = vTicketFk; UPDATE tTrain tt @@ -235,13 +276,17 @@ BEGIN tt.height LIMIT 1; - -- Si no le encuentra una balda, intentamos darle un carro entero libre - + -- Si no le encuentra una balda adecuada, intentamos darle un carro entero si queda alguno libre IF NOT (SELECT COUNT(*) FROM tTrain WHERE ticketFk) THEN - SELECT wagon INTO vFreeWagonFk - FROM tTrain - GROUP BY wagon - HAVING SUM(IFNULL(ticketFk, 0)) = 0 + SELECT tt.wagon + INTO vFreeWagonFk + FROM tTrain tt + LEFT JOIN ( + SELECT DISTINCT wagon + FROM tTrain + WHERE ticketFk IS NOT NULL + ) nn ON nn.wagon = tt.wagon + WHERE nn.wagon IS NULL ORDER BY wagon LIMIT 1; @@ -250,35 +295,38 @@ BEGIN SET ticketFk = vFirstTicketFk WHERE wagon = vFreeWagonFk; - -- Se anulan el resto de carros libres, - -- máximo un carro con pedido excesivo - - DELETE tt + -- Se anulan el resto de carros libres para que sólo uno lleve un pedido excesivo + DELETE tt.* FROM tTrain tt - JOIN (SELECT wagon - FROM tTrain - GROUP BY wagon - HAVING SUM(IFNULL(ticketFk, 0)) = 0 - ) sub ON sub.wagon = tt.wagon; + LEFT JOIN ( + SELECT DISTINCT wagon + FROM tTrain + WHERE ticketFk IS NOT NULL + ) nn ON nn.wagon = tt.wagon + WHERE nn.wagon IS NULL; END IF; - END IF; + END IF; + + FETCH c1 INTO vTicketFk, vTicketLines, vTicketVolume; + IF vDone OR NOT (SELECT COUNT(*) FROM tTrain WHERE ticketFk IS NULL) THEN + LEAVE read_loop; + END IF; + ELSE + FETCH c1 INTO vTicketFk, vTicketLines, vTicketVolume; + IF vDone THEN + LEAVE read_loop; + END IF; END IF; END LOOP; - CLOSE vTickets; + CLOSE c1; IF (SELECT COUNT(*) FROM tTrain WHERE ticketFk) THEN - -- Se obtiene nº de colección - - INSERT INTO collection - SET itemPackingTypeFk = vItemPackingTypeFk, - trainFk = vTrainFk, - wagons = vWagons, - warehouseFk = vWarehouseFk; - - SELECT LAST_INSERT_ID() INTO vCollectionFk; + UPDATE collection c + JOIN state st ON st.code = 'ON_PREPARATION' + SET c.stateFk = st.id + WHERE c.id = vCollectionFk; -- Asigna las bandejas - INSERT IGNORE INTO ticketCollection(ticketFk, collectionFk, `level`, wagon, liters) SELECT tt.ticketFk, vCollectionFk, tt.shelve, tt.wagon, tt.liters FROM tTrain tt @@ -286,34 +334,37 @@ BEGIN ORDER BY tt.wagon, tt.shelve; -- Actualiza el estado de los tickets - - CALL collection_setState(vCollectionFk, vStateCode); + CALL collection_setState(vCollectionFk, vStateFk); -- Aviso para la preparacion previa - INSERT INTO ticketDown(ticketFk, collectionFk) SELECT tc.ticketFk, tc.collectionFk FROM ticketCollection tc WHERE tc.collectionFk = vCollectionFk; - CALL collection_mergeSales(vCollectionFk); + CALL sales_mergeByCollection(vCollectionFk); UPDATE `collection` c - JOIN( + JOIN ( SELECT COUNT(*) saleTotalCount, SUM(s.isPicked <> 0) salePickedCount FROM ticketCollection tc JOIN sale s ON s.ticketFk = tc.ticketFk - WHERE tc.collectionFk = vCollectionFk - AND s.quantity > 0 - )sub + WHERE tc.collectionFk = vCollectionFk + AND s.quantity > 0 + ) sub SET c.saleTotalCount = sub.saleTotalCount, c.salePickedCount = sub.salePickedCount WHERE c.id = vCollectionFk; + ELSE - SET vCollectionFk = NULL; + DELETE FROM `collection` + WHERE id = vCollectionFk; + SET vCollectionFk = NULL; END IF; + DO RELEASE_LOCK(vLockName); + DROP TEMPORARY TABLE tTrain, tmp.productionBuffer; diff --git a/db/routines/vn/procedures/productionControl.sql b/db/routines/vn/procedures/productionControl.sql index de4339454..a654d35a3 100644 --- a/db/routines/vn/procedures/productionControl.sql +++ b/db/routines/vn/procedures/productionControl.sql @@ -99,7 +99,7 @@ proc: BEGIN LEFT JOIN `zone` z ON z.id = t.zoneFk LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk AND DATE(t.shipped) = zc.dated - LEFT JOIN ticketParking tp ON tp.ticketFk = t.id + LEFT JOIN ticketParking tp ON tp.ticketFk = t.id LEFT JOIN parking pk ON pk.id = tp.parkingFk WHERE t.warehouseFk = vWarehouseFk AND dm.code IN ('AGENCY', 'DELIVERY', 'PICKUP'); @@ -124,8 +124,8 @@ proc: BEGIN 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, ''), + 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',''), @@ -141,7 +141,7 @@ proc: BEGIN LEFT JOIN bs.clientNewBorn cnb ON cnb.clientFk = pb.clientFk JOIN productionConfig pc SET pb.problem = TRIM(CAST(CONCAT('NUEVO ', pb.problem) AS CHAR(255))) - WHERE (cnb.clientFk IS NULL OR cnb.isRookie) + WHERE (cnb.clientFk IS NULL OR cnb.isRookie) AND pc.rookieDays; -- Líneas y volumen por ticket @@ -268,10 +268,12 @@ proc: BEGIN UPDATE tmp.productionBuffer pb JOIN sale s ON s.ticketFk = pb.ticketFk JOIN item i ON i.id = s.itemFk - JOIN cache.last_buy lb ON lb.warehouse_id = vWarehouseFk - AND lb.item_id = s.itemFk + JOIN itemType it ON it.id = i.typeFk + JOIN itemCategory ic ON ic.id = it.categoryFk + JOIN cache.last_buy lb ON lb.warehouse_id = vWarehouseFk AND lb.item_id = s.itemFk JOIN buy b ON b.id = lb.buy_id JOIN packaging p ON p.id = b.packagingFk + JOIN productionConfig pc SET pb.hasPlantTray = TRUE WHERE p.isPlantTray AND s.quantity >= b.packing @@ -285,4 +287,4 @@ proc: BEGIN tItemShelvingStock, tItemPackingType; END$$ -DELIMITER ; +DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/procedures/ticket_mergeSales.sql b/db/routines/vn/procedures/ticket_mergeSales.sql index 2dc3a39da..28b2dc1c0 100644 --- a/db/routines/vn/procedures/ticket_mergeSales.sql +++ b/db/routines/vn/procedures/ticket_mergeSales.sql @@ -3,47 +3,41 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_mergeSales`( vSelf INT ) BEGIN - DECLARE vHasSalesToMerge BOOL; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; RESIGNAL; END; - START TRANSACTION; - - SELECT id INTO vSelf - FROM ticket - WHERE id = vSelf FOR UPDATE; - CREATE OR REPLACE TEMPORARY TABLE tSalesToPreserve (PRIMARY KEY (id)) ENGINE = MEMORY - SELECT s.id, s.itemFk, SUM(s.quantity) newQuantity + SELECT s.id, s.itemFk, SUM(s.quantity) newQuantity FROM sale s JOIN item i ON i.id = s.itemFk JOIN itemType it ON it.id = i.typeFk WHERE s.ticketFk = vSelf AND it.isMergeable - GROUP BY s.itemFk, s.price, s.discount - HAVING COUNT(*) > 1; + GROUP BY s.itemFk, s.price, s.discount; - SELECT COUNT(*) INTO vHasSalesToMerge - FROM tSalesToPreserve; + START TRANSACTION; - IF vHasSalesToMerge THEN - UPDATE sale s - JOIN tSalesToPreserve stp ON stp.id = s.id - SET s.quantity = newQuantity; + UPDATE sale s + JOIN tSalesToPreserve stp ON stp.id = s.id + SET s.quantity = newQuantity + WHERE s.ticketFk = vSelf; - DELETE s - FROM sale s - JOIN tSalesToPreserve stp ON stp.itemFk = s.itemFk - WHERE s.ticketFk = vSelf - AND s.id <> stp.id; - END IF; + DELETE s.* + FROM sale s + LEFT JOIN tSalesToPreserve stp ON stp.id = s.id + JOIN item i ON i.id = s.itemFk + JOIN itemType it ON it.id = i.typeFk + WHERE s.ticketFk = vSelf + AND stp.id IS NULL + AND it.isMergeable; COMMIT; + DROP TEMPORARY TABLE tSalesToPreserve; END$$ DELIMITER ; diff --git a/db/routines/vn/procedures/ticket_splitItemPackingType.sql b/db/routines/vn/procedures/ticket_splitItemPackingType.sql index c0b3d9625..0ee865af5 100644 --- a/db/routines/vn/procedures/ticket_splitItemPackingType.sql +++ b/db/routines/vn/procedures/ticket_splitItemPackingType.sql @@ -3,87 +3,124 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_splitItemPacki vSelf INT, vOriginalItemPackingTypeFk VARCHAR(1) ) -proc: BEGIN +BEGIN /** - * Clona y reparte las líneas de ventas de un ticket en funcion del tipo de empaquetado. - * Respeta el id de ticket inicial para el tipo de empaquetado propuesto. + * Clona y reparte las ventas de un ticket en funcion del tipo de empaquetado. + * Respeta el id inicial para el tipo propuesto. * * @param vSelf Id ticket - * @param vOriginalItemPackingTypeFk Tipo empaquetado al que se mantiene el ticket original + * @param vOriginalItemPackingTypeFk Tipo para el que se reserva el número de ticket original * @return table tmp.ticketIPT(ticketFk, itemPackingTypeFk) */ - DECLARE vDone INT DEFAULT FALSE; - DECLARE vHasItemPackingType BOOL; - DECLARE vItemPackingTypeFk INT; + DECLARE vItemPackingTypeFk VARCHAR(1) DEFAULT 'H'; DECLARE vNewTicketFk INT; + DECLARE vPackingTypesToSplit INT; + DECLARE vDone INT DEFAULT FALSE; - DECLARE vItemPackingTypes CURSOR FOR - SELECT DISTINCT itemPackingTypeFk - FROM tSalesToMove; + DECLARE vSaleGroup CURSOR FOR + SELECT itemPackingTypeFk + FROM tSaleGroup + WHERE itemPackingTypeFk IS NOT NULL + ORDER BY (itemPackingTypeFk = vOriginalItemPackingTypeFk) DESC; DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - SELECT COUNT(*) INTO vHasItemPackingType - FROM ticket t - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - WHERE t.id = vSelf - AND i.itemPackingTypeFk = vOriginalItemPackingTypeFk; + START TRANSACTION; + + SELECT id + FROM sale + WHERE ticketFk = vSelf + AND NOT quantity + FOR UPDATE; + + DELETE FROM sale + WHERE NOT quantity + AND ticketFk = vSelf; + + CREATE OR REPLACE TEMPORARY TABLE tSale + (PRIMARY KEY (id)) + ENGINE = MEMORY + SELECT s.id, i.itemPackingTypeFk, IFNULL(sv.litros, 0) litros + FROM sale s + JOIN item i ON i.id = s.itemFk + LEFT JOIN saleVolume sv ON sv.saleFk = s.id + WHERE s.ticketFk = vSelf; + + CREATE OR REPLACE TEMPORARY TABLE tSaleGroup + ENGINE = MEMORY + SELECT itemPackingTypeFk, SUM(litros) totalLitros + FROM tSale + GROUP BY itemPackingTypeFk; + + SELECT COUNT(*) INTO vPackingTypesToSplit + FROM tSaleGroup + WHERE itemPackingTypeFk IS NOT NULL; CREATE OR REPLACE TEMPORARY TABLE tmp.ticketIPT( ticketFk INT, itemPackingTypeFk VARCHAR(1) - ) ENGINE=MEMORY - SELECT vSelf, vOriginalItemPackingTypeFk; + ) ENGINE = MEMORY; - IF NOT vHasItemPackingType THEN - LEAVE proc; - END IF; + CASE vPackingTypesToSplit + WHEN 0 THEN + INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) + VALUES(vSelf, vItemPackingTypeFk); + WHEN 1 THEN + INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) + SELECT vSelf, itemPackingTypeFk + FROM tSaleGroup + WHERE itemPackingTypeFk IS NOT NULL; + ELSE + OPEN vSaleGroup; + FETCH vSaleGroup INTO vItemPackingTypeFk; - CREATE OR REPLACE TEMPORARY TABLE tSalesToMove ( - ticketFk INT, - saleFk INT, - itemPackingTypeFk INT - ) ENGINE=MEMORY; + INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) + VALUES(vSelf, vItemPackingTypeFk); - INSERT INTO tSalesToMove (saleFk, itemPackingTypeFk) - SELECT s.id, i.itemPackingTypeFk - FROM ticket t - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - WHERE t.id = vSelf - AND i.itemPackingTypeFk <> vOriginalItemPackingTypeFk; + l: LOOP + SET vDone = FALSE; + FETCH vSaleGroup INTO vItemPackingTypeFk; - OPEN vItemPackingTypes; + IF vDone THEN + LEAVE l; + END IF; - l: LOOP - SET vDone = FALSE; - FETCH vItemPackingTypes INTO vItemPackingTypeFk; + CALL ticket_Clone(vSelf, vNewTicketFk); - IF vDone THEN - LEAVE l; - END IF; + INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) + VALUES(vNewTicketFk, vItemPackingTypeFk); + END LOOP; - CALL ticket_Clone(vSelf, vNewTicketFk); + CLOSE vSaleGroup; - UPDATE tSalesToMove - SET ticketFk = vNewTicketFk - WHERE itemPackingTypeFk = vItemPackingTypeFk; + SELECT s.id + FROM sale s + JOIN tSale ts ON ts.id = s.id + JOIN tmp.ticketIPT t ON t.itemPackingTypeFk = ts.itemPackingTypeFk + FOR UPDATE; - END LOOP; + UPDATE sale s + JOIN tSale ts ON ts.id = s.id + JOIN tmp.ticketIPT t ON t.itemPackingTypeFk = ts.itemPackingTypeFk + SET s.ticketFk = t.ticketFk; - CLOSE vItemPackingTypes; + SELECT itemPackingTypeFk INTO vItemPackingTypeFk + FROM tSaleGroup sg + WHERE sg.itemPackingTypeFk IS NOT NULL + ORDER BY sg.itemPackingTypeFk + LIMIT 1; - UPDATE sale s - JOIN tSalesToMove stm ON stm.saleFk = s.id - SET s.ticketFk = stm.ticketFk - WHERE stm.ticketFk; + UPDATE sale s + JOIN tSale ts ON ts.id = s.id + JOIN tmp.ticketIPT t ON t.itemPackingTypeFk = vItemPackingTypeFk + SET s.ticketFk = t.ticketFk + WHERE ts.itemPackingTypeFk IS NULL; + END CASE; - INSERT INTO tmp.ticketIPT - SELECT ticketFk, itemPackingTypeFk - FROM tSalesToMove - GROUP BY ticketFk; + COMMIT; - DROP TEMPORARY TABLE tSalesToMove; + DROP TEMPORARY TABLE + tSale, + tSaleGroup; END$$ DELIMITER ;