USE `vn`; DROP procedure IF EXISTS `zone_getOptionsForLanding`; DELIMITER $$ USE `vn`$$ CREATE DEFINER=`root`@`%` PROCEDURE `zone_getOptionsForLanding`(vLanded DATE, vShowExpiredZones BOOLEAN) BEGIN /** * Gets computed options for the passed zones and delivery date. * * @table tmp.zones(id) The zones ids * @param vLanded The delivery date * @return tmp.zoneOption The computed options */ DROP TEMPORARY TABLE IF EXISTS tmp.zoneOption; CREATE TEMPORARY TABLE tmp.zoneOption ENGINE = MEMORY SELECT zoneFk, `hour`, travelingDays, price, bonus, TIMESTAMPADD(DAY, -travelingDays, vLanded) shipped FROM ( SELECT t.id zoneFk, TIME(IFNULL(e.`hour`, z.`hour`)) `hour`, IFNULL(e.travelingDays, z.travelingDays) travelingDays, IFNULL(e.price, z.price) price, IFNULL(e.bonus, z.bonus) bonus FROM tmp.zone t JOIN zone z ON z.id = t.id JOIN zoneEvent e ON e.zoneFk = t.id WHERE ( e.`type` = 'day' AND e.dated = vLanded ) OR ( e.`type` != 'day' AND e.weekDays & (1 << WEEKDAY(vLanded)) AND (e.`started` IS NULL OR vLanded >= e.`started`) AND (e.`ended` IS NULL OR vLanded <= e.`ended`) ) ORDER BY zoneFk, CASE WHEN e.`type` = 'day' THEN 1 WHEN e.`type` = 'range' THEN 2 ELSE 3 END ) t GROUP BY zoneFk; DELETE t FROM tmp.zoneOption t JOIN zoneExclusion e ON e.zoneFk = t.zoneFk AND e.`dated` = vLanded; IF NOT vShowExpiredZones THEN DELETE FROM tmp.zoneOption WHERE shipped < CURDATE() OR (shipped = CURDATE() AND CURTIME() > `hour`); END IF; END$$ DELIMITER ;