DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`duaInvoiceInBooking`(
	vDuaFk INT
)
BEGIN
/**
* Genera el asiento de un DUA y marca las entradas como confirmadas
*
* @param vDuaFk Id del dua a recalcular
*/
	DECLARE vDone BOOL DEFAULT FALSE;
	DECLARE vInvoiceFk INT;
	DECLARE vBookEntry INT;
	DECLARE vFiscalYear INT;

	DECLARE vInvoicesIn CURSOR FOR
		SELECT DISTINCT e.invoiceInFk
			FROM entry e
				JOIN duaEntry de ON de.entryFk = e.id
				JOIN invoiceIn ii ON ii.id = e.invoiceInFk
			WHERE de.duaFk = vDuaFk
				AND de.customsValue
				AND ii.isBooked = FALSE;

	DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;

	SELECT ASIEN INTO vBookEntry FROM dua WHERE id = vDuaFk;

	IF vBookEntry IS NULL THEN 
		SELECT YEAR(IFNULL(ii.bookEntried, d.bookEntried)) INTO vFiscalYear
			FROM invoiceIn ii
				JOIN `entry` e ON e.invoiceInFk = ii.id
				JOIN duaEntry de ON de.entryFk = e.id
				JOIN dua d ON d.id = de.duaFk
			WHERE d.id = vDuaFk
			LIMIT 1;
		CALL ledger_nextTx(vFiscalYear, vBookEntry);
	END IF; 

	OPEN vInvoicesIn;

l: 	LOOP
		SET vDone = FALSE;
		FETCH vInvoicesIn INTO vInvoiceFk;

		IF vDone THEN
			LEAVE l;
		END IF;

		CALL invoiceIn_booking(vInvoiceFk, vBookEntry);
	END LOOP;

	CLOSE vInvoicesIn;

	UPDATE dua
		SET ASIEN = vBookEntry
		WHERE id = vDuaFk;

	UPDATE invoiceIn ii
			JOIN duaInvoiceIn dii ON dii.invoiceInFk = ii.id
		SET ii.isBooked = TRUE
		WHERE dii.duaFk = vDuaFk;

	UPDATE `entry` e
			JOIN (
				WITH entries AS (
					SELECT e.id, de.duaFk
						FROM `entry` e 
							JOIN duaEntry de ON de.entryFk = e.id
						WHERE de.duaFk = vDuaFk
							AND (NOT e.isBooked OR NOT e.isConfirmed)
				),
				notBookedEntries AS (
					SELECT e.id
						FROM entries e
							JOIN duaEntry de ON de.entryFk = e.id
							JOIN dua d ON d.id = de.duaFk 
						WHERE d.ASIEN IS NULL)
				SELECT e.id 
					FROM entries e
						LEFT JOIN notBookedEntries nbe ON nbe.id = e.id
					WHERE nbe.id IS NULL
			) sub ON sub.id = e.id
		SET e.isBooked = TRUE,
			e.isConfirmed = TRUE;
END$$
DELIMITER ;
