diff --git a/db/routines/vn/procedures/collection_new.sql b/db/routines/vn/procedures/collection_new.sql index eef0cc9f6..782243c03 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,21 +193,13 @@ 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 FROM tmp.productionBuffer ORDER BY HH, @@ -187,38 +211,46 @@ 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; - OPEN vTickets; - l: LOOP + SET vTicketFk = vFirstTicketFk; + SET @lines = 0; + SET @volume = 0; + + OPEN c1; + read_loop: 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 (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 +267,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 +286,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 +325,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..71536e12e 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 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 ;