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 `time` WHERE dated <= vDate GROUP BY period ORDER BY dated desc LIMIT 1 OFFSET vWeekRange; SELECT MAX(dated) INTO vDayRangeEnd FROM `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 `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 (vWarehouseFk IS NULL OR vWarehouseFk = 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 2 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 (vWarehouseFk IS NULL OR vWarehouseFk = 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 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 FORCE INDEX (Fecha) 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 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 (vWarehouseFk IS NULL OR vWarehouseFk = w.id) AND (vCountryFk IS NULL OR p.countryFk = vCountryFk) AND w.isComparative 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 (i.sd IS NULL OR i.sd = 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 JOIN itemType tp ON tp.id = it.typeFk 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 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; DROP TEMPORARY TABLE IF EXISTS tmp.itemInventory, tTwoYearsAgo, tLastYear, tCurrentYear, tTable; END$$ DELIMITER ;