diff --git a/db/routines/cache/procedures/available_refresh.sql b/db/routines/cache/procedures/available_refresh.sql index 2f105e29cc..de3e85e20b 100644 --- a/db/routines/cache/procedures/available_refresh.sql +++ b/db/routines/cache/procedures/available_refresh.sql @@ -6,7 +6,15 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `cache`.`available_refres `vAvailabled` DATETIME ) proc: BEGIN - DECLARE vStartDate DATE; +/** + * Calculates the availability of all items by warehouse and date + * + * @param vCalc Returns cache.cache_calc.id + * @param vRefresh Forces the calculation + * @param vWarehouse vn.warehouse.id + * @param vAvailabled Moment in time for required availability + * + */ DECLARE vReserveDate DATETIME; DECLARE vParams CHAR(100); DECLARE vInventoryDate DATE; @@ -28,7 +36,7 @@ proc: BEGIN SET vAvailabled = vDated + INTERVAL HOUR(vAvailabled) HOUR; - CALL vn.item_getStock(vWarehouse, vDated, NULL); + CALL vn.item_getStock(vWarehouse, vAvailabled, NULL); SET vParams = CONCAT_WS('/', vWarehouse, vAvailabled); CALL cache_calc_start (vCalc, vRefresh, 'available', vParams); @@ -38,10 +46,16 @@ proc: BEGIN END IF; -- Calcula algunos parámetros necesarios - SET vStartDate = TIMESTAMP(vDated, '00:00:00'); - SELECT inventoried INTO vInventoryDate FROM vn.config; - SELECT DATE_SUB(vStartDate, INTERVAL MAX(life) DAY) INTO vLifeScope FROM vn.itemType; - SELECT SUBTIME(util.VN_NOW(), reserveTime) INTO vReserveDate + SELECT inventoried + INTO vInventoryDate + FROM vn.config; + + SELECT DATE_SUB(vDated, INTERVAL MAX(life) DAY) + INTO vLifeScope + FROM vn.itemType; + + SELECT SUBTIME(util.VN_NOW(), reserveTime) + INTO vReserveDate FROM hedera.orderConfig; SELECT w.id INTO vWarehouseFkInventory @@ -49,22 +63,22 @@ proc: BEGIN WHERE w.code = 'inv'; -- Calcula el ultimo dia de vida para cada producto - DROP TEMPORARY TABLE IF EXISTS itemRange; - CREATE TEMPORARY TABLE itemRange + CREATE OR REPLACE TEMPORARY TABLE itemRange (PRIMARY KEY (itemFk)) ENGINE = MEMORY - SELECT i.id itemFk, - util.dayEnd(DATE_ADD(c.maxLanded, INTERVAL it.life DAY)) ended, it.life + SELECT i.id itemFk, + util.dayEnd(DATE_ADD(c.maxLanded, INTERVAL it.life DAY)) ended, + it.life FROM vn.item i LEFT JOIN ( - SELECT b.itemFk, MAX(t.landed) maxLanded + SELECT b.itemFk, MAX(t.availabled) maxLanded FROM vn.buy b JOIN vn.entry e ON b.entryFk = e.id JOIN vn.travel t ON t.id = e.travelFk JOIN vn.warehouse w ON w.id = t.warehouseInFk JOIN vn.item i ON i.id = b.itemFk JOIN vn.itemType it ON it.id = i.typeFk - WHERE t.landed BETWEEN vLifeScope AND vStartDate + WHERE t.landed BETWEEN vLifeScope AND vDated AND t.warehouseInFk = vWarehouse AND t.warehouseOutFk <> vWarehouseFkInventory AND it.life @@ -72,62 +86,78 @@ proc: BEGIN GROUP BY b.itemFk ) c ON i.id = c.itemFk JOIN vn.itemType it ON it.id = i.typeFk - HAVING ended >= vStartDate OR life IS NULL; + HAVING ended >= vDated OR life IS NULL; - -- Calcula el ATP + -- Calcula el ATP (Available to Promise) DELETE FROM available WHERE calc_id = vCalc; - DROP TEMPORARY TABLE IF EXISTS tmp.itemCalc; - CREATE TEMPORARY TABLE tmp.itemCalc + CREATE OR REPLACE TEMPORARY TABLE tmp.itemCalc (INDEX (itemFk,warehouseFk)) ENGINE = MEMORY - SELECT itemFk, vWarehouse warehouseFk, DATE(dated) dated, SUM(quantity) quantity - FROM (SELECT i.itemFk, i.shipped dated, i.quantity + SELECT itemFk, + vWarehouse warehouseFk, + dated, + SUM(quantity) quantity + FROM ( + SELECT i.itemFk, + i.shipped dated, + i.quantity FROM vn.itemTicketOut i JOIN itemRange ir ON ir.itemFk = i.itemFk - WHERE i.shipped >= vStartDate - AND (ir.ended IS NULL OR i.shipped <= ir.ended) + WHERE i.shipped >= vAvailabled + AND (ir.ended IS NULL + OR i.shipped <= ir.ended) AND i.warehouseFk = vWarehouse UNION ALL - SELECT i.itemFk, IFNULL(i.availabled, i.landed), i.quantity + SELECT i.itemFk, + i.availabled, + i.quantity FROM vn.itemEntryIn i JOIN itemRange ir ON ir.itemFk = i.itemFk - LEFT JOIN edi.warehouseFloramondo wf ON wf.entryFk = i.entryFk - WHERE IFNULL(i.availabled, i.landed) >= vStartDate - AND IFNULL(i.availabled, i.landed) <= vAvailabled - AND (ir.ended IS NULL OR IFNULL(i.availabled, i.landed) <= ir.ended) + WHERE i.availabled >= vAvailabled + AND (ir.ended IS NULL + OR i.availabled <= ir.ended) AND i.warehouseInFk = vWarehouse - AND wf.entryFk IS NULL - UNION ALL - SELECT i.itemFk, i.shipped, i.quantity + UNION ALL + SELECT i.itemFk, + i.shipped, + i.quantity FROM vn.itemEntryOut i JOIN itemRange ir ON ir.itemFk = i.itemFk - WHERE i.shipped >= vStartDate - AND (ir.ended IS NULL OR i.shipped <= ir.ended) + WHERE i.shipped >= vAvailabled + AND (ir.ended IS NULL + OR i.shipped <= ir.ended) AND i.warehouseOutFk = vWarehouse UNION ALL - SELECT r.item_id, r.shipment, -r.amount + SELECT r.item_id, + r.shipment, + -r.amount FROM hedera.order_row r JOIN hedera.`order` o ON o.id = r.order_id JOIN itemRange ir ON ir.itemFk = r.item_id - WHERE r.shipment >= vStartDate - AND (ir.ended IS NULL OR r.shipment <= ir.ended) + WHERE r.shipment >= vDated + AND (ir.ended IS NULL + OR r.shipment <= ir.ended) AND r.warehouse_id = vWarehouse AND r.created >= vReserveDate AND NOT o.confirmed ) t GROUP BY itemFk, dated; - CALL vn.item_getAtp(vDated); + CALL vn.item_getAtp(vAvailabled); INSERT INTO available (calc_id, item_id, available) - SELECT vCalc, sub.itemFk, SUM(sub.quantity) + SELECT vCalc, + sub.itemFk, + SUM(sub.quantity) FROM ( - SELECT ir.itemFk, stock quantity + SELECT ir.itemFk, + stock quantity FROM tmp.itemList il JOIN itemRange ir ON ir.itemFk = il.itemFk UNION ALL - SELECT itemFk, quantity + SELECT itemFk, + quantity FROM tmp.itemAtp )sub GROUP BY sub.itemFk; diff --git a/db/routines/vn/procedures/item_getAtp.sql b/db/routines/vn/procedures/item_getAtp.sql index 3e90a7f58e..5e07450b3c 100644 --- a/db/routines/vn/procedures/item_getAtp.sql +++ b/db/routines/vn/procedures/item_getAtp.sql @@ -1,11 +1,10 @@ DELIMITER $$ -CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getAtp`(vDated DATE) +CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getAtp`(vAvailabled DATETIME) BEGIN /** - * Calcula el valor mínimo acumulado para cada artículo ordenado por fecha y - * almacén. + * Calcula el valor mínimo acumulado para cada artículo por almacén. * - * @param vDated Si no hay movimientos en la fecha indicada, debe devolver 0 + * @param vAvailabled Starting time for calculation * @table tmp.itemCalc(itemFk, wareHouseFk, dated, quantity) * @return tmp.itemAtp(itemFk, warehouseFk, quantity) */ @@ -17,7 +16,7 @@ BEGIN SELECT itemFk, warehouseFk, dated, quantity FROM tmp.itemCalc UNION ALL - SELECT itemFk, warehouseFk, vDated, 0 + SELECT itemFk, warehouseFk, vAvailabled, 0 FROM (SELECT DISTINCT itemFk, warehouseFk FROM tmp.itemCalc) t2 ) t1 GROUP BY itemFk, warehouseFk, dated @@ -28,7 +27,7 @@ BEGIN SET @lastQuantity := 0; CREATE OR REPLACE TEMPORARY TABLE tmp.itemAtp - (INDEX (itemFk, wareHouseFk)) + (PRIMARY KEY (itemFk, wareHouseFk)) SELECT itemFk, wareHouseFk, MIN(quantityAccumulated) quantity FROM ( SELECT @@ -43,6 +42,10 @@ BEGIN )sub GROUP BY itemFk, wareHouseFk; + INSERT IGNORE INTO tmp.itemAtp(itemFk, warehouseFk, quantity) + SELECT DISTINCT ic.itemFk, ic.warehouseFk, 0 + FROM tmp.itemCalc ic; + DROP TEMPORARY TABLE tItemOrdered; END$$ DELIMITER ; diff --git a/db/routines/vn/procedures/item_getBalance.sql b/db/routines/vn/procedures/item_getBalance.sql index a68724eb50..2b3956bf4d 100644 --- a/db/routines/vn/procedures/item_getBalance.sql +++ b/db/routines/vn/procedures/item_getBalance.sql @@ -1,4 +1,5 @@ DELIMITER $$ +$$ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getBalance`( vItemFk INT, vWarehouseFk INT, @@ -99,7 +100,7 @@ BEGIN ), sales AS ( WITH itemSales AS ( - SELECT DATE(t.shipped) + INTERVAL HOUR(z.`hour`) HOUR shipped, + SELECT DATE(t.shipped) + INTERVAL HOUR(IFNULL(z.`hour`,0)) HOUR shipped, s.quantity, st2.alertLevel, st2.name, @@ -114,7 +115,7 @@ BEGIN cb.claimFk FROM vn.sale s JOIN vn.ticket t ON t.id = s.ticketFk - JOIN vn.`zone` z ON z.id = t.zoneFk + LEFT JOIN vn.`zone` z ON z.id = t.zoneFk LEFT JOIN vn.ticketState ts ON ts.ticketFk = t.id LEFT JOIN vn.state st ON st.code = ts.code JOIN vn.client c ON c.id = t.clientFk diff --git a/db/routines/vn/procedures/item_getMinacum.sql b/db/routines/vn/procedures/item_getMinacum.sql index e3c9158200..8a07b43fc7 100644 --- a/db/routines/vn/procedures/item_getMinacum.sql +++ b/db/routines/vn/procedures/item_getMinacum.sql @@ -1,7 +1,8 @@ DELIMITER $$ +$$ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getMinacum`( vWarehouseFk TINYINT, - vDated DATE, + vAvailabled DATETIME, vRange INT, vItemFk INT ) @@ -11,11 +12,12 @@ BEGIN * especificado, en caso de NULL para todos. * * @param vWarehouseFk Id warehouse - * @param vDated Fecha inicio + * @param vAvailabled Fecha inicio * @param vRange Número de días a considerar * @param vItemFk Id de artículo * @return tmp.itemMinacum */ + DECLARE vDated DATE DEFAULT DATE(vAvailabled); DECLARE vDatedTo DATETIME DEFAULT util.dayEnd(vDated + INTERVAL vRange DAY); CREATE OR REPLACE TEMPORARY TABLE tmp.itemCalc @@ -27,25 +29,25 @@ BEGIN sub.warehouseFk FROM ( SELECT s.itemFk, - DATE(t.shipped) dated, + t.shipped dated, -s.quantity quantity, t.warehouseFk FROM sale s JOIN ticket t ON t.id = s.ticketFk - WHERE t.shipped BETWEEN vDated AND vDatedTo + WHERE t.shipped BETWEEN vAvailabled AND vDatedTo AND t.warehouseFk AND s.quantity <> 0 AND (vItemFk IS NULL OR s.itemFk = vItemFk) AND (vWarehouseFk IS NULL OR t.warehouseFk = vWarehouseFk) UNION ALL SELECT b.itemFk, - t.landed, + t.availabled, b.quantity, t.warehouseInFk FROM buy b JOIN entry e ON e.id = b.entryFk JOIN travel t ON t.id = e.travelFk - WHERE t.landed BETWEEN vDated AND vDatedTo + WHERE t.availabled BETWEEN vAvailabled AND vDatedTo AND (vWarehouseFk IS NULL OR t.warehouseInFk = vWarehouseFk) AND NOT e.isExcludedFromAvailable AND b.quantity <> 0 @@ -58,7 +60,7 @@ BEGIN FROM buy b JOIN entry e ON e.id = b.entryFk JOIN travel t ON t.id = e.travelFk - WHERE t.shipped BETWEEN vDated AND vDatedTo + WHERE t.shipped BETWEEN vAvailabled AND vDatedTo AND (vWarehouseFk IS NULL OR t.warehouseOutFk = vWarehouseFk) AND NOT e.isExcludedFromAvailable AND b.quantity <> 0 @@ -84,7 +86,7 @@ BEGIN ) sub GROUP BY sub.itemFk, sub.warehouseFk, sub.dated; - CALL item_getAtp(vDated); + CALL item_getAtp(vAvailabled); CREATE OR REPLACE TEMPORARY TABLE tmp.itemMinacum (INDEX(itemFk)) diff --git a/db/routines/vn/procedures/item_getStock.sql b/db/routines/vn/procedures/item_getStock.sql index 4639521857..166b2f511e 100644 --- a/db/routines/vn/procedures/item_getStock.sql +++ b/db/routines/vn/procedures/item_getStock.sql @@ -1,21 +1,22 @@ DELIMITER $$ +$$ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getStock`( vWarehouseFk SMALLINT, - vDated DATE, + vAvailabled DATETIME, vItemFk INT ) BEGIN /** * Calcula el stock de un artículo de un vWarehouseFk, - * desde la fecha del inventario hasta vDated + * desde la fecha del inventario hasta el momento anterior a vAvailabled * * @param vWarehouse Warehouse id - * @param vDated Max date to filter + * @param vAvailabled Maximum time to filter * @param vItemFk Item id * * @return tmp.itemList(itemFk, stock, visible, available) */ - SET vDated = TIMESTAMP(vDated, '00:00:00'); + CALL cache.stock_refresh(FALSE); CREATE OR REPLACE TEMPORARY TABLE tmp.itemList (UNIQUE INDEX i USING HASH (itemFk)) @@ -28,15 +29,15 @@ BEGIN SELECT itemFk, quantity FROM itemTicketOut WHERE shipped >= util.VN_CURDATE() - AND shipped < vDated + AND shipped < vAvailabled AND warehouseFk = vWarehouseFk AND (vItemFk IS NULL OR itemFk = vItemFk) UNION ALL SELECT iei.itemFk, iei.quantity FROM itemEntryIn iei JOIN item i ON i.id = iei.itemFk - WHERE IFNULL(iei.availabled, iei.landed) >= util.VN_CURDATE() - AND IFNULL(iei.availabled, iei.landed) < vDated + WHERE iei.availabled >= util.VN_CURDATE() + AND iei.availabled < vAvailabled AND iei.warehouseInFk = vWarehouseFk AND (vItemFk IS NULL OR iei.itemFk = vItemFk) UNION ALL @@ -44,23 +45,16 @@ BEGIN FROM itemEntryOut ieo JOIN item i ON i.id = ieo.itemFk WHERE ieo.shipped >= util.VN_CURDATE() - AND ieo.shipped < vDated + AND ieo.shipped < vAvailabled AND ieo.warehouseOutFk = vWarehouseFk AND (vItemFk IS NULL OR ieo.itemFk = vItemFk) + UNION ALL + SELECT item_id, amount + FROM cache.stock + WHERE warehouse_id = vWarehouseFk ) sub GROUP BY itemFk HAVING stock; - CALL cache.stock_refresh(FALSE); - - INSERT INTO tmp.itemList(itemFk, stock, visible, available) - SELECT item_id, amount, amount, amount - FROM cache.stock - WHERE warehouse_id = vWarehouseFk - AND (vItemFk IS NULL OR vItemFk = item_id) - ON DUPLICATE KEY UPDATE - stock = stock + VALUES(stock), - visible = visible + VALUES(visible), - available = available + VALUES(available); END$$ DELIMITER ; diff --git a/db/routines/vn/procedures/ticket_getMovable.sql b/db/routines/vn/procedures/ticket_getMovable.sql index cf56316f1f..06841f0f22 100644 --- a/db/routines/vn/procedures/ticket_getMovable.sql +++ b/db/routines/vn/procedures/ticket_getMovable.sql @@ -1,4 +1,5 @@ DELIMITER $$ +$$ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_getMovable`( vTicketFk INT, vNewShipped DATETIME, @@ -6,7 +7,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_getMovable`( ) BEGIN /** - * Cálcula el stock movible para los artículos de un ticket + * Cálcula el stock que se puede adelantar para los artículos de un ticket. * vNewShipped debe ser menor que vOldShipped, en los otros casos se * asume que siempre es posible * @@ -25,7 +26,7 @@ BEGIN CALL item_getMinacum( vWarehouseFk, vNewShipped, - DATEDIFF(DATE_SUB(vOldShipped, INTERVAL 1 DAY), vNewShipped), + DATEDIFF(DATE_SUB(vOldShipped, INTERVAL 1 DAY), DATE(vNewShipped)), NULL ); diff --git a/db/routines/vn/triggers/ticket_beforeInsert.sql b/db/routines/vn/triggers/ticket_beforeInsert.sql index 02b60b6b3b..585a383344 100644 --- a/db/routines/vn/triggers/ticket_beforeInsert.sql +++ b/db/routines/vn/triggers/ticket_beforeInsert.sql @@ -3,6 +3,16 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`ticket_beforeInsert` BEFORE INSERT ON `ticket` FOR EACH ROW BEGIN + DECLARE vTime TIME DEFAULT NULL; + SET NEW.editorFk = account.myUser_getId(); + + SELECT TIME(hour) INTO vTime + FROM zone + WHERE id = NEW.zoneFk; + + IF vTime IS NOT NULL THEN + SET NEW.shipped = ADDTIME(DATE(NEW.shipped), vTime); + END IF; END$$ DELIMITER ; diff --git a/db/routines/vn/triggers/ticket_beforeUpdate.sql b/db/routines/vn/triggers/ticket_beforeUpdate.sql index f86f50485c..4afa77f556 100644 --- a/db/routines/vn/triggers/ticket_beforeUpdate.sql +++ b/db/routines/vn/triggers/ticket_beforeUpdate.sql @@ -4,6 +4,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`ticket_beforeUpdate` FOR EACH ROW BEGIN DECLARE vNewTime TIME; + DECLARE vZoneTime TIME; SET NEW.editorFk = account.myUser_getId(); @@ -72,5 +73,19 @@ BEGIN CALL vn.routeUpdateM3(NEW.routeFk); END IF; + + IF DATE(NEW.shipped) <> DATE(OLD.shipped) THEN + SET NEW.shipped = ADDTIME(DATE(NEW.shipped), TIME(OLD.shipped)); + END IF; + + IF NEW.zoneFk <> OLD.zoneFk THEN + SELECT TIME(hour) INTO vZoneTime + FROM zone + WHERE id = NEW.zoneFk; + + IF vZoneTime IS NOT NULL THEN + SET NEW.shipped = ADDTIME(DATE(NEW.shipped), vZoneTime); + END IF; + END IF; END$$ DELIMITER ; diff --git a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js index 7dc1c8ed29..d996810cc9 100644 --- a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js +++ b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js @@ -84,8 +84,8 @@ describe('sale priceDifference()', () => { const {items} = await models.Ticket.priceDifference(ctx, options); - expect(items[0].movable).toEqual(386); - expect(items[1].movable).toEqual(1810); + expect(items[0].movable).toEqual(356); + expect(items[1].movable).toEqual(1790); await tx.rollback(); } catch (e) {