salix/db/routines/vn/procedures/item_ValuateInventory.sql

238 lines
7.4 KiB
SQL

DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_ValuateInventory`(vDated DATE, vIsDetailed BOOLEAN)
BEGIN
DECLARE vInventoried DATE;
DECLARE vHasNotInventory BOOLEAN DEFAULT FALSE;
DECLARE vInventoryClone DATE;
DECLARE vDateDayEnd DATETIME;
DECLARE vInventorySupplierFk INT;
SELECT inventorySupplierFk INTO vInventorySupplierFk
FROM entryConfig;
SET vDateDayEnd = util.dayEnd(vDated);
SELECT tr.landed INTO vInventoried
FROM travel tr
JOIN `entry` e ON e.travelFk = tr.id
JOIN entryConfig ec
WHERE landed <= vDateDayEnd
AND e.supplierFk = vInventorySupplierFk
ORDER BY tr.landed DESC
LIMIT 1;
SET vHasNotInventory = (vInventoried IS NULL);
IF vHasNotInventory THEN
SELECT landed INTO vInventoryClone
FROM travel tr
JOIN `entry` e ON e.travelFk = tr.id
JOIN entryConfig ec
WHERE landed >= vDated
AND e.supplierFk = vInventorySupplierFk
ORDER BY landed ASC
LIMIT 1;
SET vInventoried = vDated + INTERVAL 1 DAY;
SET vDateDayEnd = vInventoryClone;
END IF;
CREATE OR REPLACE TEMPORARY TABLE tInventory(
warehouseFk SMALLINT,
itemFk BIGINT,
quantity INT,
cost DOUBLE DEFAULT 0,
total DOUBLE DEFAULT 0,
warehouseInventory VARCHAR(20),
PRIMARY KEY (warehouseInventory, itemFk) USING HASH
)
ENGINE = MEMORY;
-- Inventario inicial
IF vHasNotInventory THEN
INSERT INTO tInventory(warehouseFk, itemFk, quantity, warehouseInventory)
SELECT tr.warehouseInFk,
b.itemFk,
SUM(b.quantity),
w.name
FROM buy b
JOIN item i ON i.id = b.itemFk
JOIN `entry` e ON e.id = b.entryFk
JOIN travel tr ON tr.id = e.travelFk
JOIN itemType t ON t.id = i.typeFk
JOIN warehouse w ON w.id = warehouseInFk
JOIN entryConfig ec
WHERE landed = vDateDayEnd
AND e.supplierFk = vInventorySupplierFk
AND w.valuatedInventory
AND t.isInventory
GROUP BY tr.warehouseInFk, b.itemFk;
ELSE
INSERT INTO tInventory(warehouseFk, itemFk, quantity, warehouseInventory)
SELECT tr.warehouseInFk,
b.itemFk,
SUM(b.quantity),
w.name
FROM buy b
JOIN item i ON i.id = b.itemFk
JOIN `entry` e ON e.id = b.entryFk
JOIN travel tr ON tr.id = e.travelFk
JOIN itemType t ON t.id = i.typeFk
JOIN warehouse w ON w.id = warehouseInFk
JOIN entryConfig ec
WHERE landed = vInventoried
AND e.supplierFk = vInventorySupplierFk
AND w.valuatedInventory
AND t.isInventory
GROUP BY tr.warehouseInFk, b.itemFk;
END IF;
-- Añadimos las entradas
INSERT INTO tInventory(warehouseFk, itemFk, quantity, warehouseInventory)
SELECT tr.warehouseInFk,
b.itemFk,
b.quantity * IF(vHasNotInventory, -1, 1),
w.name
FROM buy b
JOIN item i ON i.id = b.itemFk
JOIN `entry` e ON e.id = b.entryFk
JOIN travel tr ON tr.id = e.travelFk
JOIN itemType t ON t.id = i.typeFk
JOIN warehouse w ON w.id = tr.warehouseInFk
JOIN entryConfig ec
WHERE tr.landed BETWEEN vInventoried AND vDateDayEnd
AND IF(tr.landed = util.VN_CURDATE(), tr.isReceived, TRUE)
AND NOT e.isRaid
AND w.valuatedInventory
AND t.isInventory
AND e.supplierFk <> vInventorySupplierFk
ON DUPLICATE KEY UPDATE tInventory.quantity = tInventory.quantity + (b.quantity * IF(vHasNotInventory, -1, 1));
-- Descontamos las salidas
INSERT INTO tInventory(warehouseFk, itemFk, quantity, warehouseInventory)
SELECT tr.warehouseOutFk,
b.itemFk,
b.quantity * IF(vHasNotInventory, 1, -1),
w.name
FROM buy b
JOIN item i ON i.id = b.itemFk
JOIN `entry` e ON e.id = b.entryFk
JOIN travel tr ON tr.id = e.travelFk
JOIN itemType t ON t.id = i.typeFk
JOIN warehouse w ON w.id = tr.warehouseOutFk
WHERE tr.shipped BETWEEN vInventoried AND vDateDayEnd
AND NOT e.isRaid
AND w.valuatedInventory
AND t.isInventory
ON DUPLICATE KEY UPDATE tInventory.quantity = tInventory.quantity + (b.quantity * IF(vHasNotInventory,1,-1));
-- Descontamos las lineas de venta
INSERT INTO tInventory(warehouseFk, itemFk, quantity, warehouseInventory)
SELECT w.id,
s.itemFk,
s.quantity * IF(vHasNotInventory, 1, -1),
w.name
FROM sale s
JOIN ticket t ON t.id = s.ticketFk
JOIN `client` c ON c.id = t.clientFk
JOIN item i ON i.id = s.itemFk
JOIN itemType it ON it.id = i.typeFk
JOIN warehouse w ON w.id = t.warehouseFk
WHERE t.shipped BETWEEN vInventoried AND vDateDayEnd
AND w.valuatedInventory
AND it.isInventory
ON DUPLICATE KEY UPDATE tInventory.quantity = tInventory.quantity + s.quantity * IF(vHasNotInventory, 1, -1);
-- Volver a poner lo que esta aun en las estanterias
IF vDated = util.VN_CURDATE() THEN
INSERT INTO tInventory(warehouseFk, itemFk, quantity, warehouseInventory)
SELECT w.id,
s.itemFk,
s.quantity * IF(vHasNotInventory, 0, 1),
w.name
FROM sale s
JOIN ticket t ON t.id = s.ticketFk
JOIN `client` c ON c.id = t.clientFk
JOIN item i ON i.id = s.itemFk
JOIN itemType it ON it.id = i.typeFk
JOIN warehouse w ON w.id = t.warehouseFk
WHERE t.shipped BETWEEN vDated AND vDateDayEnd
AND NOT (s.isPicked OR t.isLabeled)
AND w.valuatedInventory
AND it.isInventory
ON DUPLICATE KEY UPDATE tInventory.quantity = tInventory.quantity + s.quantity * IF(vHasNotInventory, 0, 1);
END IF;
-- Mercancia en transito
INSERT INTO tInventory(warehouseFk, itemFk, quantity, warehouseInventory)
SELECT tr.warehouseInFk,
b.itemFk,
b.quantity,
CONCAT(wOut.`name`, ' - ', wIn.`name`)
FROM buy b
JOIN item i ON i.id = b.itemFk
JOIN `entry` e ON e.id = b.entryFk
JOIN travel tr ON tr.id = e.travelFk
JOIN itemType t ON t.id = i.typeFk
JOIN warehouse wIn ON wIn.id = tr.warehouseInFk
JOIN warehouse wOut ON wOut.id = tr.warehouseOutFk
WHERE vDated >= tr.shipped AND vDated < tr.landed
AND NOT isRaid
AND wIn.valuatedInventory
AND t.isInventory
AND e.isConfirmed
ON DUPLICATE KEY UPDATE tInventory.quantity = tInventory.quantity + (b.quantity);
CALL vn.buyUltimate(NULL, vDateDayEnd);
UPDATE tInventory i
JOIN tmp.buyUltimate bu ON i.warehouseFk = bu.warehouseFk AND i.itemFk = bu.itemFk
JOIN buy b ON b.id = bu.buyFk
SET total = i.quantity * (IFNULL(b.buyingValue, 0) + IFNULL(b.packageValue, 0) + IFNULL(b.freightValue, 0) + IFNULL(b.comissionValue, 0)),
cost = IFNULL(b.buyingValue, 0) + IFNULL(b.packageValue, 0) + IFNULL(b.freightValue, 0) + IFNULL(b.comissionValue, 0)
WHERE i.quantity;
DELETE FROM tInventory
WHERE quantity IS NULL OR NOT quantity;
IF vIsDetailed THEN
SELECT ti.warehouseFk,
i.id itemFk,
i.longName,
i.size,
ti.quantity,
tp.name Tipo,
ic.name Reino,
ti.cost,
CAST(ti.total AS DECIMAL(10, 2)) total,
ti.warehouseInventory almacen
FROM tInventory ti
JOIN warehouse w ON w.id = warehouseFk
JOIN item i ON i.id = ti.itemFk
JOIN itemType tp ON tp.id = i.typeFk
JOIN itemCategory ic ON ic.id = tp.categoryFk
WHERE w.valuatedInventory
AND ti.total > 0
ORDER BY ti.total DESC;
ELSE
SELECT i.warehouseInventory Almacen,
ic.name Reino,
CAST(i.total AS DECIMAL(10, 2)) Euros,
w.code Comprador,
it.id
FROM tInventory i
JOIN warehouse wh ON wh.id = warehouseFk
JOIN item it ON it.id = i.itemFk
JOIN itemType itp ON itp.id = it.typeFk
LEFT JOIN worker w ON w.id = itp.workerFk
JOIN itemCategory ic ON ic.id = itp.categoryFk
WHERE wh.valuatedInventory
AND i.total > 0;
END IF;
DROP TEMPORARY TABLE
tmp.buyUltimate,
tInventory;
END$$
DELIMITER ;