salix/db/routines/hedera/procedures/order_addItem.sql

133 lines
2.8 KiB
SQL

DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `hedera`.`order_addItem`(
vSelf INT,
vWarehouse INT,
vItem INT,
vAmount INT)
BEGIN
/**
* Adds an item to the order, checking availability and grouping.
*
* @param vSelf The order id
* @param vWarehouse The warehouse id
* @param vItem The item id
* @param vAmount The amount to add
*/
DECLARE vRow INT;
DECLARE vAdd INT;
DECLARE vAvailable INT;
DECLARE vMinQuantity INT;
DECLARE vDone BOOL;
DECLARE vGrouping INT;
DECLARE vRate INT;
DECLARE vShipment DATE;
DECLARE vPrice DECIMAL(10,2);
DECLARE cur CURSOR FOR
SELECT `grouping`, price, rate
FROM tmp.ticketComponentPrice
WHERE warehouseFk = vWarehouse
AND itemFk = vItem
ORDER BY `grouping` DESC;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET vDone = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
CALL order_calcCatalogFromItem(vSelf, vItem);
START TRANSACTION;
CALL order_checkEditable(vSelf);
SELECT shipped INTO vShipment
FROM tmp.zoneGetShipped
WHERE warehouseFk = vWarehouse;
SELECT available INTO vAvailable
FROM tmp.ticketLot
WHERE warehouseFk = vWarehouse
AND itemFk = vItem;
IF vAvailable IS NULL THEN
SET vAvailable = 0;
END IF;
IF vAmount > vAvailable THEN
CALL util.throw ('ORDER_ROW_UNAVAILABLE');
END IF;
WITH itemMinQuantityPriority AS (
SELECT quantity,
ROW_NUMBER() OVER (
PARTITION BY itemFk
ORDER BY warehouseFk IS NULL
) priority
FROM vn.itemMinimumQuantity
WHERE itemFk = vItem
AND `started` <= vShipment
AND (`ended` >= vShipment OR `ended` IS NULL)
AND (warehouseFk = vWarehouse OR warehouseFk IS NULL)
)
SELECT quantity INTO vMinQuantity
FROM itemMinQuantityPriority
WHERE priority = 1;
IF vAmount < LEAST(IFNULL(vMinQuantity, 0), vAvailable) THEN
CALL util.throw ('quantityLessThanMin');
END IF;
OPEN cur;
l: LOOP
SET vDone = FALSE;
FETCH cur INTO vGrouping, vPrice, vRate;
IF vDone THEN
LEAVE l;
END IF;
SET vAdd = vAmount - MOD(vAmount, vGrouping);
SET vAmount = vAmount - vAdd;
IF vAdd = 0 THEN
ITERATE l;
END IF;
INSERT INTO orderRow SET
orderFk = vSelf,
itemFk = vItem,
warehouseFk = vWarehouse,
shipment = vShipment,
rate = vRate,
amount = vAdd,
price = vPrice;
CALL cache.available_updateItem(vItem, vWarehouse, vShipment, vAdd);
SET vRow = LAST_INSERT_ID();
INSERT INTO orderRowComponent (rowFk, componentFk, price)
SELECT vRow, c.componentFk, c.cost
FROM tmp.ticketComponent c
JOIN vn.component t
ON t.id = c.componentFk
AND (t.classRate IS NULL OR t.classRate = vRate)
WHERE c.warehouseFk = vWarehouse
AND c.itemFk = vItem;
END LOOP;
CLOSE cur;
IF vAmount > 0 THEN
CALL util.throw ('AMOUNT_NOT_MATCH_GROUPING');
END IF;
COMMIT;
CALL vn.ticketCalculatePurge;
END$$
DELIMITER ;