DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`report_print`(
	vReportName VARCHAR(100),
	vPrinterFk INT,
	vUserFk INT,
	vParams JSON,
	vPriorityName VARCHAR(100)
	)
BEGIN
/**
 * Inserts in the print queue the report to be printed and the necessary parameters for this 
 * one taking into account the paper size of both the printer and the report.
 *
 * @param vReportName the report to be printed.
 * @param vPrinterFk the printer selected.
 * @param vUserFk user id.
 * @param vParams JSON with report parameters.
 * @param vPriorityName the printing priority.
 */
	DECLARE vI INT DEFAULT 0;
	DECLARE vKeys TEXT DEFAULT JSON_KEYS(vParams);
	DECLARE vLength INT DEFAULT JSON_LENGTH(vKeys);
	DECLARE vKey VARCHAR(255);
	DECLARE vVal VARCHAR(255);
	DECLARE vPrintQueueFk INT;
	DECLARE vReportSize VARCHAR(255);
	DECLARE vIsThePrinterReal INT;
	DECLARE vPrinteSize VARCHAR(255);
	DECLARE vPriorityFk INT;
	DECLARE vReportFk INT;
	DECLARE EXIT HANDLER FOR SQLEXCEPTION
		BEGIN
			ROLLBACK;
			RESIGNAL;
		END;

	SELECT id, paperSizeFk INTO vReportFk, vReportSize
		FROM report
		WHERE name = vReportName;

	SELECT id, paperSizeFk INTO vIsThePrinterReal, vPrinteSize
		FROM printer
		WHERE id = vPrinterFk;

	SELECT id INTO vPriorityFk
		FROM queuePriority
		WHERE code = vPriorityName;

	IF vIsThePrinterReal IS NULL THEN
		CALL util.throw('printerNotExists');
	END IF;

	IF vReportFk IS NULL THEN
		CALL util.throw('reportNotExists');	
	END IF;

	IF vReportSize <> vPrinteSize THEN
		CALL util.throw('incorrectSize');		
	END IF;

	START TRANSACTION;
		INSERT INTO printQueue
			SET printerFk = vPrinterFk,
				priorityFk = vPriorityFk,
				reportFk = vReportFk,
				workerFk = vUserFk;
				
		SET vPrintQueueFk = LAST_INSERT_ID();

		WHILE vI < vLength DO
			SET vKey = JSON_VALUE(vKeys, CONCAT('$[', vI ,']'));
			SET vVal = JSON_VALUE(vParams, CONCAT('$.', vKey));

			INSERT INTO printQueueArgs
				SET printQueueFk = vPrintQueueFk,
					name = vKey,
					value = vVal;

			SET vI = vI + 1;
		END WHILE;
	COMMIT;
END$$
DELIMITER ;