DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `stock`.`stock_syncItem`(
	vItemFk INT,
	vWarehouseFk INT,
	vWait INT)
myProc: BEGIN
/**
 * Synchronizes out of sync item. It generates a lock for each item and
 * warehouse synchronization process.
 *
 * @param vItemFk The item id
 * @param vWarehouseFk The item warehouse id
 * @param vWait Maximum waiting time, see GET_LOCK()
 */
	DECLARE vDone BOOL;
	DECLARE vHasPendingSync BOOL;
	DECLARE vLotFk INT;
	DECLARE vOutFk INT;
	DECLARE vLock VARCHAR(255);

	DECLARE vLots CURSOR FOR
		SELECT lotFk FROM buyLot
			WHERE NOT isSync
				AND (itemFk, warehouseFk) = (vItemFk, vWarehouseFk)
			ORDER BY dated, lotFk;

	DECLARE vOuts CURSOR FOR
		SELECT outFk FROM buyOut
			WHERE NOT isSync
				AND (itemFk, warehouseFk) = (vItemFk, vWarehouseFk)
			ORDER BY dated, created, outFk;

	DECLARE CONTINUE HANDLER FOR NOT FOUND
		SET vDone = TRUE;

	DECLARE EXIT HANDLER FOR SQLEXCEPTION
	BEGIN
		DO RELEASE_LOCK(vLock);
		ROLLBACK;
		RESIGNAL;
	END;

	SET vLock = CONCAT_WS('/', 'stock.stock_syncItem', vWarehouseFk, vItemFk);

	IF NOT GET_LOCK(vLock, vWait) THEN
		LEAVE myProc;
	END IF;

	REPEAT
		SET vHasPendingSync = FALSE;

		OPEN vLots;
		lotLoop: LOOP
			SET vDone = FALSE;
			FETCH vLots INTO vLotFk;

			IF vDone THEN
				LEAVE lotLoop;
			END IF;

			START TRANSACTION;
			CALL buyLot_sync(vLotFk);
			COMMIT;

			SET vHasPendingSync = TRUE;
		END LOOP;
		CLOSE vLots;

		OPEN vOuts;
		outLoop: LOOP
			SET vDone = FALSE;
			FETCH vOuts INTO vOutFk;

			IF vDone THEN
				LEAVE outLoop;
			END IF;

			START TRANSACTION;
			CALL buyOut_sync(vOutFk);
			COMMIT;

			SET vHasPendingSync = TRUE;
		END LOOP;
		CLOSE vOuts;

	UNTIL NOT vHasPendingSync END REPEAT;
END$$
DELIMITER ;
