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

298 lines
9.9 KiB
SQL

DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_comparative`(
vDate DATETIME,
vDayRange TINYINT,
vWarehouseFk TINYINT,
vAvailableSince DATE,
vBuyerFk INT,
vIsFloramondo BOOL,
vCountryFk INT
)
proc: BEGIN
/**
* Genera una tabla de comparativa de artículos por itemType/comprador/fecha.
* Los datos se calculan en función de los parámetros proporcionados.
*
* @param vDate La fecha para la cual se generará la comparativa.
* @param vDayRange El rango de días a considerar para la comparativa.
* @param vWarehouseFk El identificador del almacén para filtrar los artículos.
* @param vAvailableSince La fecha de disponibilidad desde la cual se consideran los artículos disponibles.
* @param vBuyerFk El identificador del comprador para filtrar los artículos.
* @param vIsFloramondo Indica si se deben incluir solo los artículos de Floramondo (opcional).
* @param vCountryFk El identificador del país.
* @param tmp.comparativeFilterType(filterFk INT ,itemTypeFk INT)
* @return tmp.comparative
*/
DECLARE vDayRangeStart DATE;
DECLARE vDayRangeEnd DATE;
DECLARE w1, w2, w3, w4, w5, w6, w7 INT;
DECLARE y1, y2, y3, y4, y5, y6, y7 INT;
DECLARE z1, z2, z3, z4, z5, z6, z7 INT;
DECLARE vPeriod INT;
DECLARE i INT DEFAULT 0;
DECLARE vHasTypeFilter BOOL;
DECLARE vWeekRange INT;
DECLARE vWeekCount TINYINT;
DECLARE vMaxDayRange INT;
DECLARE vMinDayRange INT;
DECLARE vDefaultDayRange INT;
IF NOT(SELECT COUNT(*) FROM comparativeConfig)THEN
LEAVE proc;
END IF;
SELECT weekRange,
weekRange * 2 + 1,
maxDayRange,
minDayRange,
defaultDayRange
INTO vWeekRange,
vWeekCount,
vMaxDayRange,
vMinDayRange,
vDefaultDayRange
FROM comparativeConfig;
IF vDayRange < vMinDayRange OR vDayRange > vMaxDayRange THEN
SET vDayRange = vDefaultDayRange;
END IF;
SELECT MIN(dated) INTO vDayRangeStart
FROM vn.time
WHERE dated <= vDate
GROUP BY period
ORDER BY dated desc
LIMIT 1 OFFSET vWeekRange;
SELECT MAX(dated) INTO vDayRangeEnd
FROM vn.time
WHERE dated >= vDate
GROUP BY period
ORDER BY dated ASC
LIMIT 1 OFFSET vWeekRange;
SELECT COUNT(itemTypeFk) > 0 INTO vHasTypeFilter
FROM tmp.comparativeFilterType;
CREATE OR REPLACE TEMPORARY TABLE tmp.itemInventory
(PRIMARY KEY (id))
ENGINE = MEMORY
SELECT i.id
FROM item i
JOIN itemType t ON t.id = i.typeFk
JOIN itemCategory c ON c.id = t.categoryFk
LEFT JOIN worker w ON w.id = t.workerFk
WHERE (NOT vHasTypeFilter
OR t.id IN (SELECT itemTypeFk FROM tmp.comparativeFilterType))
AND (vBuyerFk IS NULL
OR t.workerFk = vBuyerFk)
AND (vIsFloramondo IS NULL
OR i.isFloramondo = vIsFloramondo);
IF vDate < util.VN_CURDATE() THEN
ALTER TABLE tmp.itemInventory
ADD `buy_id` INT NOT NULL DEFAULT 0,
ADD `buy_date` DATE DEFAULT '2000-01-01',
ADD `life` INT DEFAULT 0,
ADD `sd` INT DEFAULT 0,
ADD `avalaible` INT DEFAULT 0,
ADD `visible` INT DEFAULT 0;
ELSE
CALL multipleInventory(vAvailableSince, vWarehouseFk, vDayRange);
CALL item_multipleBuy(vDate, vWarehouseFk);
CALL item_multipleBuyByDate(vDate, vWarehouseFk);
END IF;
CREATE OR REPLACE TEMPORARY TABLE tTable (
cy INT(6) PRIMARY KEY,
ly INT(6),
zy INT(6),
INDEX (ly)
);
REPEAT
SET i = i + 1;
SELECT t.period INTO vPeriod
FROM vn.`time` t
WHERE t.dated = vDayRangeStart + INTERVAL (vWeekCount * (i - 1)) DAY;
INSERT IGNORE INTO tTable(cy, ly, zy) VALUES(vPeriod, vPeriod - 100, vPeriod - 200);
UNTIL i = vWeekCount END REPEAT;
SELECT cy, ly, zy INTO w1, y1, z1 FROM tTable LIMIT 1;
SELECT cy, ly, zy INTO w2, y2, z2 FROM tTable WHERE cy > w1 LIMIT 1;
SELECT cy, ly, zy INTO w3, y3, z3 FROM tTable WHERE cy > w2 LIMIT 1;
SELECT cy, ly, zy INTO w4, y4, z4 FROM tTable WHERE cy > w3 LIMIT 1;
SELECT cy, ly, zy INTO w5, y5, z5 FROM tTable WHERE cy > w4 LIMIT 1;
SELECT cy, ly, zy INTO w6, y6, z6 FROM tTable WHERE cy > w5 LIMIT 1;
SELECT cy, ly, zy INTO w7, y7, z7 FROM tTable WHERE cy > w6 LIMIT 1;
-- Genera una tabla con los datos del año pasado.
CREATE OR REPLACE TEMPORARY TABLE tLastYear
(KEY (lItemFk))
ENGINE = MEMORY
SELECT c.itemFk lItemFk,
SUM(IF(c.timePeriod = y1, c.quantity, 0)) lweek1,
SUM(IF(c.timePeriod = y2, c.quantity, 0)) lweek2,
SUM(IF(c.timePeriod = y3, c.quantity, 0)) lweek3,
SUM(IF(c.timePeriod = y4, c.quantity, 0)) lweek4,
SUM(IF(c.timePeriod = y5, c.quantity, 0)) lweek5,
SUM(IF(c.timePeriod = y6, c.quantity, 0)) lweek6,
SUM(IF(c.timePeriod = y7, c.quantity, 0)) lweek7,
SUM(IF(c.timePeriod = y1, c.price, 0)) lprice1,
SUM(IF(c.timePeriod = y2, c.price, 0)) lprice2,
SUM(IF(c.timePeriod = y3, c.price, 0)) lprice3,
SUM(IF(c.timePeriod = y4, c.price, 0)) lprice4,
SUM(IF(c.timePeriod = y5, c.price, 0)) lprice5,
SUM(IF(c.timePeriod = y6, c.price, 0)) lprice6,
SUM(IF(c.timePeriod = y7, c.price, 0)) lprice7
FROM tmp.itemInventory ai
JOIN comparative c ON c.itemFk = ai.id
JOIN warehouse w on w.id = c.warehouseFk
JOIN tTable wt ON c.timePeriod = wt.ly
WHERE IFNULL(vWarehouseFk, c.warehouseFk) = c.warehouseFk
AND w.isComparative
AND (vCountryFk IS NULL OR c.countryFk = vCountryFk)
GROUP BY ai.id;
-- Genera una tabla con los datos de hace DOS años.
CREATE OR REPLACE TEMPORARY TABLE tTwoYearsAgo
(KEY (tItemFk))
ENGINE = MEMORY
SELECT c.itemFk tItemFk,
SUM(IF(c.timePeriod = z1, c.quantity, 0)) vlweek1,
SUM(IF(c.timePeriod = z2, c.quantity, 0)) vlweek2,
SUM(IF(c.timePeriod = z3, c.quantity, 0)) vlweek3,
SUM(IF(c.timePeriod = z4, c.quantity, 0)) vlweek4,
SUM(IF(c.timePeriod = z5, c.quantity, 0)) vlweek5,
SUM(IF(c.timePeriod = z6, c.quantity, 0)) vlweek6,
SUM(IF(c.timePeriod = z7, c.quantity, 0)) vlweek7,
SUM(IF(c.timePeriod = z1, c.price, 0)) vlprice1,
SUM(IF(c.timePeriod = z2, c.price, 0)) vlprice2,
SUM(IF(c.timePeriod = z3, c.price, 0)) vlprice3,
SUM(IF(c.timePeriod = z4, c.price, 0)) vlprice4,
SUM(IF(c.timePeriod = z5, c.price, 0)) vlprice5,
SUM(IF(c.timePeriod = z6, c.price, 0)) vlprice6,
SUM(IF(c.timePeriod = z7, c.price, 0)) vlprice7
FROM tmp.itemInventory ai
JOIN comparative c ON c.itemFk = ai.id
JOIN warehouse w on w.id = c.warehouseFk
JOIN tTable wt ON c.timePeriod = wt.zy
WHERE IFNULL(vWarehouseFk, c.warehouseFk) = c.warehouseFk
AND w.isComparative
AND (vCountryFk IS NULL OR c.countryFk = vCountryFk)
GROUP BY ai.id;
-- Genera una tabla con los datos de este año.ss
CREATE OR REPLACE TEMPORARY TABLE tCurrentYear
(KEY (cItemFk))
ENGINE = MEMORY
SELECT t.itemFk cItemFk,
SUM(IF(week = w1, total, 0)) cweek1,
SUM(IF(week = w2, total, 0)) cweek2,
SUM(IF(week = w3, total, 0)) cweek3,
SUM(IF(week = w4, total, 0)) cweek4,
SUM(IF(week = w5, total, 0)) cweek5,
SUM(IF(week = w6, total, 0)) cweek6,
SUM(IF(week = w7, total, 0)) cweek7,
SUM(IF(week = w1, price, 0)) cprice1,
SUM(IF(week = w2, price, 0)) cprice2,
SUM(IF(week = w3, price, 0)) cprice3,
SUM(IF(week = w4, price, 0)) cprice4,
SUM(IF(week = w5, price, 0)) cprice5,
SUM(IF(week = w6, price, 0)) cprice6,
SUM(IF(week = w7, price, 0)) cprice7
FROM (
SELECT s.itemFk,
ti.period `week`,
SUM(s.quantity) total,
TRUNCATE(SUM(s.quantity * s.priceFixed),0) price
FROM ticket t
JOIN sale s ON t.id = s.ticketFk
JOIN tmp.itemInventory it ON it.id = s.itemFk
JOIN time ti ON ti.dated = DATE(t.shipped)
JOIN item i ON i.id = s.itemFk
JOIN itemType tp ON tp.id = i.typeFk
JOIN itemCategory ic ON ic.id = tp.categoryFk
JOIN warehouse w ON w.id = t.warehouseFk
STRAIGHT_JOIN address ad ON ad.id = t.addressFk
JOIN province p ON p.id = ad.provinceFk
JOIN `client` c ON c.id = ad.clientFk
WHERE t.shipped BETWEEN vDayRangeStart AND util.dayEnd(vDayRangeEnd)
AND c.typeFk IN ('Normal','handMaking')
AND w.id = COALESCE(vWarehouseFk, w.id)
AND w.isComparative
AND (vCountryFk IS NULL OR p.countryFk = vCountryFk)
GROUP BY i.id, week
) t
GROUP BY t.itemFk;
-- Genera la tabla con la comparativa.
CREATE OR REPLACE TEMPORARY TABLE tmp.comparative
ENGINE = MEMORY
SELECT it.subName productor,
b.packing,
b.buyingValue costefijo,
b.groupingMode caja,
it.image ArticleImage,
IFNULL(it.inkFk,"?") color,
tp.code tipo,
it.typeFk tipo_id,
o.code origen,
it.category categoria,
it.stems tallos,
it.size medida,
it.name article,
w.code codigoTrabajador,
tp.categoryFk reino_id,
ly.*,
cy.*,
zy.*,
it.*,
it.id Id_Article,
i.buy_id,
tp.life,
IFNULL(i.sd,0) sd,
i.avalaible,
i.visible,
i.buy_date,
e.id provider_id,
it.comment comments,
it.description itemDescription,
IF(cy.cItemFk IS NULL AND i.visible = 0 AND i.avalaible = 0
AND IFNULL(i.sd, 0) = 0, FALSE, TRUE) filtret,
IF(it.hasMinPrice, FORMAT(it.minPrice, 2), "") pvp,
s.company_name
FROM tmp.itemInventory i
JOIN item it ON it.id = i.id
LEFT JOIN itemType tp ON tp.id = it.typeFk
LEFT JOIN worker w ON w.id = tp.workerFk
LEFT JOIN buy b ON b.id = i.buy_id
LEFT JOIN entry e ON e.id = b.entryFk
LEFT JOIN origin o ON o.id = it.originFk
LEFT JOIN tLastYear ly ON ly.lItemFk = it.id
LEFT JOIN tCurrentYear cy ON cy.cItemFk = it.id
LEFT JOIN tTwoYearsAgo zy ON zy.tItemFk = it.id
LEFT JOIN edi.ekt e2 ON e2.id = b.ektFk
LEFT JOIN edi.supplier s ON s.supplier_id = e2.pro
WHERE i.avalaible
OR i.visible
OR i.sd
OR cy.cweek1 OR cy.cweek2 OR cy.cweek3 OR cy.cweek4 OR cy.cweek5 OR cy.cweek6 OR cy.cweek7
OR ly.lweek1 OR ly.lweek2 OR ly.lweek3 OR ly.lweek4 OR ly.lweek5 OR ly.lweek6 OR ly.lweek7
OR zy.vlweek1 OR zy.vlweek2 OR zy.vlweek3 OR zy.vlweek4 OR zy.vlweek5 OR zy.vlweek6 OR zy.vlweek7;
-- Elimina las tablas temporales creadas...
DROP TEMPORARY TABLE IF EXISTS tmp.itemInventory,
tTwoYearsAgo,
tLastYear,
tCurrentYear,
tTable;
END$$
DELIMITER ;