133 lines
2.8 KiB
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 ;
|