DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`stock_refreshAll`()
BEGIN
/**
 * Recalculates the entire cache. It takes a considerable time,
 * please avoid calls to this procedure from commonly used operations.
 */
	DECLARE vDone BOOL;
	DECLARE vExpired DATETIME;
	DECLARE vAliveDate DATE;
	DECLARE vId INT;

	DECLARE vBuys CURSOR FOR
		SELECT lotFk FROM vn.buy
			WHERE isAlive;

	DECLARE vTickets CURSOR FOR
		SELECT id FROM vn.ticket
			WHERE shipped >= vAliveDate;

	DECLARE vOrders CURSOR FOR
		SELECT lotFk FROM hedera.orderRow
			WHERE created >= vExpired;

	DECLARE CONTINUE HANDLER FOR NOT FOUND
		SET vDone = TRUE;

	DECLARE EXIT HANDLER FOR SQLEXCEPTION
	BEGIN
		DO RELEASE_LOCK('stock.stock_sync');
		RESIGNAL;
	END;

	IF NOT GET_LOCK('stock.stock_sync', 30) THEN
		CALL util.throw('Lock timeout exceeded');
	END IF;

	-- Prune cache

	DELETE p FROM buyPick p JOIN buyLot l USING(lotFk);
	TRUNCATE TABLE buyLot;
	TRUNCATE TABLE buyOut;

	-- Buy

	OPEN vBuys;
	buyLoop: LOOP
		SET vDone = FALSE;
		FETCH vBuys INTO vId;

		IF vDone THEN
			LEAVE buyLoop;
		END IF;

		CALL buyOut_refreshBuy('lot', vId);
	END LOOP;
	CLOSE vBuys;

	-- Order

	SELECT SUBTIME(util.VN_NOW(), reserveTime)
		INTO vExpired
		FROM hedera.orderConfig LIMIT 1;

	OPEN vOrders;
	orderLoop: LOOP
		SET vDone = FALSE;
		FETCH vOrders INTO vId;

		IF vDone THEN
			LEAVE orderLoop;
		END IF;

		CALL buyOut_refreshOrder('lot', vId);
	END LOOP;
	CLOSE vOrders;

	-- Sale

	SELECT util.VN_CURDATE() - INTERVAL saleLife MONTH
		INTO vAliveDate
		FROM config LIMIT 1;

	OPEN vTickets;
	saleLoop: LOOP
		SET vDone = FALSE;
		FETCH vTickets INTO vId;

		IF vDone THEN
			LEAVE saleLoop;
		END IF;

		CALL buyOut_refreshSale('ticket', vId);
	END LOOP;
	CLOSE vTickets;

	-- Synchronize

	UPDATE buyOut SET isSync = TRUE;
	CALL stock_sync;

	DO RELEASE_LOCK('stock.stock_sync');
END$$
DELIMITER ;
