salix/db/routines/vn/procedures/collection_new.sql

319 lines
8.2 KiB
MySQL
Raw Normal View History

DELIMITER $$
2024-08-27 08:47:09 +00:00
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`collection_new`(
vUserFk INT,
OUT vCollectionFk INT
)
BEGIN
/**
* Genera colecciones de tickets sin asignar trabajador.
*
* @param vUserFk Identificador de account.user
*/
DECLARE vWarehouseFk INT;
DECLARE vWagons INT;
DECLARE vTrainFk INT;
2024-08-27 11:31:07 +00:00
DECLARE vLinesLimit INT;
2024-01-25 16:33:54 +00:00
DECLARE vTicketLines INT;
2024-08-27 11:31:07 +00:00
DECLARE vVolumeLimit DECIMAL;
DECLARE vSizeLimit INT;
2024-01-25 16:33:54 +00:00
DECLARE vTicketVolume DECIMAL;
DECLARE vMaxTickets INT;
2024-08-27 11:36:06 +00:00
DECLARE vStateCode VARCHAR(45);
DECLARE vFirstTicketFk INT;
DECLARE vWorkerCode VARCHAR(3);
2024-08-27 08:47:09 +00:00
DECLARE vWagonCounter INT DEFAULT 1;
DECLARE vTicketFk INT;
DECLARE vItemPackingTypeFk VARCHAR(1);
2024-08-27 08:47:09 +00:00
DECLARE vHasAssignedTickets BOOL;
DECLARE vHasUniqueCollectionTime BOOL;
2024-08-27 08:47:09 +00:00
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;
2024-08-27 08:47:09 +00:00
DECLARE vDone INT DEFAULT FALSE;
2024-08-27 08:47:09 +00:00
DECLARE vTickets CURSOR FOR
2024-01-25 16:33:54 +00:00
SELECT ticketFk, `lines`, m3
FROM tmp.productionBuffer
2024-01-25 16:33:54 +00:00
ORDER BY HH,
mm,
productionOrder DESC,
m3 DESC,
agency,
zona,
routeFk,
ticketFk
LIMIT vMaxTickets;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
2024-01-25 16:33:54 +00:00
SELECT pc.ticketTrolleyMax * o.numberOfWagons,
pc.hasUniqueCollectionTime,
w.code,
o.warehouseFk,
o.itemPackingTypeFk,
st.code,
o.numberOfWagons,
o.trainFk,
o.linesLimit,
2024-08-27 11:31:07 +00:00
o.volumeLimit,
o.sizeLimit
2024-01-25 16:33:54 +00:00
INTO vMaxTickets,
2024-08-27 08:47:09 +00:00
vHasUniqueCollectionTime,
vWorkerCode,
vWarehouseFk,
vItemPackingTypeFk,
2024-08-27 11:36:06 +00:00
vStateCode,
2024-08-27 08:47:09 +00:00
vWagons,
vTrainFk,
vLinesLimit,
2024-08-27 11:31:07 +00:00
vVolumeLimit,
vSizeLimit
2024-08-27 08:47:09 +00:00
FROM worker w
JOIN operator o ON o.workerFk = w.id
JOIN state st ON st.`code` = 'ON_PREPARATION'
2024-08-27 08:47:09 +00:00
JOIN productionConfig pc
WHERE w.id = vUserFk;
-- Se prepara el tren, con tantos vagones como sea necesario.
2024-08-27 08:47:09 +00:00
CREATE OR REPLACE TEMPORARY TABLE tTrain
(wagon INT,
shelve INT,
liters INT,
`lines`INT,
height INT,
ticketFk INT,
PRIMARY KEY(wagon, shelve))
ENGINE = MEMORY;
2024-08-27 08:47:09 +00:00
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;
-- Esto desaparecerá cuando tengamos la table cache.ticket
2024-08-27 08:47:09 +00:00
CALL productionControl(vWarehouseFk, 0);
ALTER TABLE tmp.productionBuffer
ADD COLUMN liters INT,
ADD COLUMN height INT;
-- Los tickets de recogida en Algemesí sólo se sacan si están asignados.
-- Los pedidos con riesgo no se sacan aunque se asignen.
2024-08-27 08:47:09 +00:00
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%';
2024-08-27 08:47:09 +00:00
-- 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
LIMIT 1
) INTO vHasAssignedTickets;
-- Se dejan en la tabla tmp.productionBuffer sólo aquellos tickets adecuados
2024-08-27 08:47:09 +00:00
IF vHasAssignedTickets THEN
2024-08-27 08:47:09 +00:00
DELETE pb
FROM tmp.productionBuffer pb
JOIN state s ON s.id = pb.state
2024-01-25 16:33:54 +00:00
WHERE s.code <> 'PICKER_DESIGNED'
OR pb.workerCode <> vWorkerCode;
ELSE
2024-08-27 08:47:09 +00:00
DELETE pb
FROM tmp.productionBuffer pb
JOIN state s ON s.id = pb.state
JOIN agencyMode am ON am.id = pb.agencyModeFk
JOIN agency a ON a.id = am.agencyFk
JOIN productionConfig pc
WHERE pb.shipped <> util.VN_CURDATE()
2024-01-25 16:33:54 +00:00
OR (pb.ubicacion IS NULL AND a.isOwn)
OR (NOT s.isPreparable AND NOT s.isPrintable)
OR pb.collectionH IS NOT NULL
OR pb.collectionV IS NOT NULL
OR pb.collectionN IS NOT NULL
2024-01-25 16:33:54 +00:00
OR (NOT pb.H AND pb.V > 0 AND vItemPackingTypeFk = 'H')
OR (NOT pb.V AND vItemPackingTypeFk = 'V')
OR (pc.isPreviousPreparationRequired AND pb.previousWithoutParking)
2024-01-25 16:33:54 +00:00
OR LENGTH(pb.problem) > 0
2024-08-27 11:43:20 +00:00
OR pb.lines > vLinesLimit
OR pb.m3 > vVolumeLimit
2024-08-27 11:31:07 +00:00
OR sub.maxSize > vSizeLimit;
END IF;
-- Hay que excluir aquellos que no tengan la misma hora de preparacion, si procede
IF vHasUniqueCollectionTime THEN
2024-08-27 08:47:09 +00:00
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);
END IF;
2024-08-27 08:47:09 +00:00
OPEN vTickets;
l: LOOP
SET vDone = FALSE;
2024-08-27 08:47:09 +00:00
FETCH vTickets INTO vTicketFk, vTicketLines, vTicketVolume;
IF vDone THEN
LEAVE l;
END IF;
2024-01-25 16:33:54 +00:00
-- Buscamos un ticket que cumpla con los requisitos en el listado
2024-08-27 08:47:09 +00:00
IF (vLinesLimit IS NULL OR (vTotalLines + vTicketLines) <= vLinesLimit)
AND (vVolumeLimit IS NULL OR (vTotalVolume + vTicketVolume) <= vVolumeLimit) THEN
2024-01-25 16:33:54 +00:00
CALL ticket_splitItemPackingType(vTicketFk, vItemPackingTypeFk);
DROP TEMPORARY TABLE tmp.ticketIPT;
2024-08-27 08:47:09 +00:00
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;
2024-01-25 16:33:54 +00:00
UPDATE tmp.productionBuffer pb
2024-08-27 08:47:09 +00:00
SET pb.liters = vLiters,
pb.`lines` = vLines,
pb.height = vHeight
2024-01-25 16:33:54 +00:00
WHERE pb.ticketFk = vTicketFk;
UPDATE tTrain tt
JOIN tmp.productionBuffer pb ON pb.ticketFk = vTicketFk
SET tt.ticketFk = pb.ticketFk
WHERE tt.liters >= pb.liters
AND tt.`lines` >= pb.`lines`
AND (tt.height >= pb.height OR vItemPackingTypeFk <> 'V')
AND tt.ticketFk IS NULL
ORDER BY wagon,
shelve,
tt.liters,
tt.`lines`,
tt.height
LIMIT 1;
2024-08-27 08:47:09 +00:00
-- Si no le encuentra una balda, intentamos darle un carro entero libre
2024-01-25 16:33:54 +00:00
IF NOT (SELECT COUNT(*) FROM tTrain WHERE ticketFk) THEN
2024-08-27 08:47:09 +00:00
SELECT wagon INTO vFreeWagonFk
FROM tTrain
GROUP BY wagon
HAVING SUM(IFNULL(ticketFk, 0)) = 0
2024-01-25 16:33:54 +00:00
ORDER BY wagon
LIMIT 1;
IF vFreeWagonFk THEN
UPDATE tTrain
SET ticketFk = vFirstTicketFk
WHERE wagon = vFreeWagonFk;
2024-08-27 08:47:09 +00:00
-- Se anulan el resto de carros libres,
-- máximo un carro con pedido excesivo
DELETE tt
2024-01-25 16:33:54 +00:00
FROM tTrain tt
2024-08-27 08:47:09 +00:00
JOIN (SELECT wagon
FROM tTrain
GROUP BY wagon
HAVING SUM(IFNULL(ticketFk, 0)) = 0
) sub ON sub.wagon = tt.wagon;
2024-01-25 16:33:54 +00:00
END IF;
2024-08-27 08:47:09 +00:00
END IF;
END IF;
END LOOP;
2024-08-27 08:47:09 +00:00
CLOSE vTickets;
IF (SELECT COUNT(*) FROM tTrain WHERE ticketFk) THEN
2024-08-27 08:47:09 +00:00
-- 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
2024-08-27 08:47:09 +00:00
INSERT IGNORE INTO ticketCollection(ticketFk, collectionFk, `level`, wagon, liters)
SELECT tt.ticketFk, vCollectionFk, tt.shelve, tt.wagon, tt.liters
FROM tTrain tt
WHERE tt.ticketFk IS NOT NULL
ORDER BY tt.wagon, tt.shelve;
-- Actualiza el estado de los tickets
2024-08-27 08:47:09 +00:00
2024-08-27 11:36:06 +00:00
CALL collection_setState(vCollectionFk, vStateCode);
-- Aviso para la preparacion previa
2024-08-27 08:47:09 +00:00
INSERT INTO ticketDown(ticketFk, collectionFk)
SELECT tc.ticketFk, tc.collectionFk
FROM ticketCollection tc
WHERE tc.collectionFk = vCollectionFk;
2024-08-27 08:47:09 +00:00
CALL collection_mergeSales(vCollectionFk);
2024-01-25 16:33:54 +00:00
UPDATE `collection` c
2024-08-27 08:47:09 +00:00
JOIN(
2024-01-25 16:33:54 +00:00
SELECT COUNT(*) saleTotalCount,
SUM(s.isPicked <> 0) salePickedCount
FROM ticketCollection tc
JOIN sale s ON s.ticketFk = tc.ticketFk
2024-08-27 08:47:09 +00:00
WHERE tc.collectionFk = vCollectionFk
AND s.quantity > 0
)sub
SET c.saleTotalCount = sub.saleTotalCount,
c.salePickedCount = sub.salePickedCount
WHERE c.id = vCollectionFk;
ELSE
2024-08-27 08:47:09 +00:00
SET vCollectionFk = NULL;
END IF;
DROP TEMPORARY TABLE
tTrain,
tmp.productionBuffer;
END$$
DELIMITER ;