Merge branch 'dev' into 8645-addSupplierRefToAgencyTermFilter
gitea/salix/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Jose Antonio Tubau 2025-02-27 11:21:09 +00:00
commit 93862fecfc
12 changed files with 146 additions and 99 deletions

View File

@ -278,6 +278,15 @@ INSERT INTO `hedera`.`tpvConfig` (currency, terminal, transactionType, maxAmount
INSERT INTO hedera.tpvMerchantEnable (merchantFk, companyFk)
VALUES (1, 442);
/* UPDATE vn.ticket t
JOIN vn.zone z ON z.id = t.zoneFk
SET t.shipped = DATE(t.shipped) +
INTERVAL HOUR(z.hour) HOUR +
INTERVAL MINUTE(z.hour) MINUTE;
*/
UPDATE vn.travel
SET availabled = landed
WHERE availabled IS NULL;
-- XXX
SET foreign_key_checks = 1;

View File

@ -6,7 +6,15 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `cache`.`available_refresh`
`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;

View File

@ -2,7 +2,7 @@ DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `cache`.`stock_refresh`(v_refresh BOOL)
proc: BEGIN
/**
* Crea o actualiza la cache con el disponible hasta el ­a de
* Crea o actualiza la cache con el disponible hasta el a de
* ayer. Esta cache es usada como base para otros procedimientos
* como el cálculo del visible o del ATP.
*
@ -36,15 +36,19 @@ proc: BEGIN
(
SELECT itemFk AS item_id, warehouseFk AS warehouse_id, quantity AS amount
FROM vn.itemTicketOut
WHERE shipped >= v_date_inv AND shipped < vCURDATE
WHERE shipped >= v_date_inv
AND shipped < vCURDATE
UNION ALL
SELECT itemFk ASitem_id, warehouseInFk AS warehouse_id, quantity AS amount
FROM vn.itemEntryIn
WHERE landed >= v_date_inv AND landed < vCURDATE AND isVirtualStock is FALSE
WHERE availabled >= v_date_inv
AND availabled < vCURDATE
AND isVirtualStock is FALSE
UNION ALL
SELECT itemFk AS item_id ,warehouseOutFk AS warehouse_id, quantity AS amount
FROM vn.itemEntryOut
WHERE shipped >= v_date_inv AND shipped < vCURDATE
WHERE shipped >= v_date_inv
AND shipped < vCURDATE
) t
GROUP BY item_id, warehouse_id HAVING amount != 0;

View File

@ -4,7 +4,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`catalog_calculate`(
vAddressFk INT,
vAgencyModeFk INT,
vShowExpiredZones BOOLEAN)
BEGIN
BEGIN
/**
* Calcula los articulos disponibles y sus precios
*
@ -12,7 +12,7 @@ BEGIN
* @param vLanded Fecha de recepcion de mercancia
* @param vAddressFk Id del consignatario
* @param vAgencyModeFk Id de la agencia
* @return tmp.ticketCalculateItem(itemFk, available, producer,
* @return tmp.ticketCalculateItem(itemFk, available, producer,
* item, size, stems, category, inkFk, image, origin, price)
* @return tmp.ticketLot(warehouseFk, itemFk, available, buyFk)
* @return tmp.ticketComponent
@ -48,34 +48,34 @@ BEGIN
CALL catalog_componentPrepare();
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem(
itemFk INT(11) NOT NULL,
itemFk INT(11) NOT NULL,
available INT(11),
producer VARCHAR(50),
item VARCHAR(50),
size INT(10) UNSIGNED,
stems INT(11),
category VARCHAR(3),
inkFk VARCHAR(3),
producer VARCHAR(50),
item VARCHAR(50),
size INT(10) UNSIGNED,
stems INT(11),
category VARCHAR(3),
inkFk VARCHAR(3),
image VARCHAR(50),
origin VARCHAR(3),
origin VARCHAR(3),
price DECIMAL(10,2),
priceKg DECIMAL(10,2),
`grouping` INT(10) UNSIGNED,
minQuantity INT(10) UNSIGNED,
PRIMARY KEY `itemFk` (`itemFk`)
) ENGINE = MEMORY DEFAULT CHARSET=utf8;
OPEN cTravelTree;
l: LOOP
SET vDone = FALSE;
FETCH cTravelTree INTO vZoneFk, vWarehouseFk, vShipped, vHour;
SET vAvailabled = vShipped + INTERVAL HOUR(vHour) HOUR;
IF vDone THEN
LEAVE l;
END IF;
CALL `cache`.available_refresh(vAvailableCalc, FALSE, vWarehouseFk, vAvailabled);
CALL buy_getUltimate(NULL, vWarehouseFk, vShipped);
@ -89,25 +89,25 @@ BEGIN
JOIN tmp.item i ON i.itemFk = a.item_id
JOIN item it ON it.id = i.itemFk
JOIN `zone` z ON z.id = vZoneFk
LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = a.item_id
LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = a.item_id
JOIN agencyMode am ON am.id = vAgencyModeFk
JOIN agency ag ON ag.id = am.agencyFk
JOIN itemType itt ON itt.id = it.typeFk
JOIN itemCategory itc on itc.id = itt.categoryFk
JOIN address ad ON ad.id = vAddressFk
LEFT JOIN clientItemType cit
LEFT JOIN clientItemType cit
ON cit.clientFk = ad.clientFk
AND cit.itemTypeFk = itt.id
LEFT JOIN zoneItemType zit
LEFT JOIN zoneItemType zit
ON zit.zoneFk = vZoneFk
AND zit.itemTypeFk = itt.id
LEFT JOIN agencyModeItemType ait
LEFT JOIN agencyModeItemType ait
ON ait.agencyModeFk = vAgencyModeFk
AND ait.itemTypeFk = itt.id
LEFT JOIN (
SELECT i.id
FROM item i
JOIN priceDelta pd
JOIN priceDelta pd
ON pd.itemTypeFk = i.typeFk
AND (pd.minSize IS NULL OR pd.minSize <= i.`size`)
AND (pd.maxSize IS NULL OR pd.maxSize >= i.`size`)
@ -132,8 +132,7 @@ BEGIN
AND cit.id IS NULL
AND zit.id IS NULL
AND ait.id IS NULL
AND pd.id IS NULL
;
AND pd.id IS NULL;
DROP TEMPORARY TABLE tmp.buyUltimate;

View File

@ -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 ;

View File

@ -1,7 +1,7 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getMinacum`(
vWarehouseFk TINYINT,
vDated DATE,
vAvailabled DATETIME,
vRange INT,
vItemFk INT
)
@ -11,11 +11,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 +28,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 +59,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 +85,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))

View File

@ -1,21 +1,21 @@
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 +28,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 +44,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 ;

View File

@ -6,7 +6,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 +25,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
);

View File

@ -0,0 +1,4 @@
-- Place your SQL code here
ALTER TABLE vn.priceDelta ADD IF NOT EXISTS isHidden BOOL
DEFAULT FALSE NOT NULL
COMMENT 'Hides the itemType when building de catalog recordset';

View File

@ -0,0 +1,4 @@
-- Place your SQL code here
ALTER TABLE vn.priceDelta ADD IF NOT EXISTS isHidden BOOL
DEFAULT FALSE NOT NULL
COMMENT 'Hides the itemType when building de catalog recordset';

View File

@ -167,7 +167,7 @@ module.exports = Self => {
}
smtp.send({
to: config.app.reportEmail,
to: 'administracion@verdnatura.es', // #8687
subject: '[API] Nightly ticket closure report',
html: body,
}).catch(err => console.error(err));

View File

@ -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) {