DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`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 ;
