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

76 lines
2.2 KiB
SQL

DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`zone_getOptionsForShipment`(vShipped DATE, vShowExpiredZones BOOLEAN)
BEGIN
/**
* Gets computed options for the passed zones and shipping date.
*
* @table tmp.zones(id) The zones ids
* @param vShipped The shipping date
* @return tmp.zoneOption(zoneFk, hour, travelingDays, price, bonus, specificity) The computed options
*/
DECLARE vHour TIME DEFAULT TIME(util.VN_NOW());
DROP TEMPORARY TABLE IF EXISTS tLandings;
CREATE TEMPORARY TABLE tLandings
(INDEX (eventFk))
ENGINE = MEMORY
SELECT e.id eventFk,
@travelingDays := IFNULL(e.travelingDays, z.travelingDays) travelingDays,
TIMESTAMPADD(DAY, @travelingDays, vShipped) landed
FROM tmp.zone t
JOIN zone z ON z.id = t.id
JOIN zoneEvent e ON e.zoneFk = t.id;
DROP TEMPORARY TABLE IF EXISTS tmp.zoneOption;
CREATE TEMPORARY TABLE tmp.zoneOption
ENGINE = MEMORY
SELECT *
FROM (
SELECT t.id zoneFk,
TIME(IFNULL(e.`hour`, z.`hour`)) `hour`,
l.travelingDays,
IFNULL(e.price, z.price) price,
IFNULL(e.bonus, z.bonus) bonus,
l.landed,
vShipped shipped
FROM tmp.zone t
JOIN zone z ON z.id = t.id
JOIN zoneEvent e ON e.zoneFk = t.id
JOIN tLandings l ON l.eventFk = e.id
WHERE (
e.`type` = 'day'
AND e.`dated` = l.landed
) OR (
e.`type` != 'day'
AND e.weekDays & (1 << WEEKDAY(l.landed))
AND (e.`started` IS NULL OR l.landed >= e.`started`)
AND (e.`ended` IS NULL OR l.landed <= e.`ended`)
)
ORDER BY
zoneFk,
CASE
WHEN e.`type` = 'day'
THEN 1
WHEN e.`type` = 'range'
THEN 2
ELSE 3
END
LIMIT 10000000000000000000
) t
GROUP BY zoneFk;
DROP TEMPORARY TABLE tLandings;
DELETE t FROM tmp.zoneOption t
JOIN zoneExclusion e ON e.zoneFk = t.zoneFk AND e.`dated` = t.landed
LEFT JOIN zoneExclusionGeo eg ON eg.zoneExclusionFk = e.id
WHERE eg.zoneExclusionFk IS NULL;
IF NOT vShowExpiredZones THEN
DELETE FROM tmp.zoneOption
WHERE vShipped < util.VN_CURDATE()
OR (vShipped = util.VN_CURDATE() AND util.VN_CURTIME() > `hour`);
END IF;
END$$
DELIMITER ;