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 IFNULL(available, 0) INTO vAvailable FROM tmp.ticketLot WHERE warehouseFk = vWarehouse AND itemFk = vItem; 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; 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 ;