DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`collection_assign`(
	vUserFk INT,
	OUT vCollectionFk INT
)
BEGIN   
/**
 * Comprueba si existen colecciones libres que se ajustan
 * al perfil del usuario y le asigna la más antigua.
 * Añade un registro al semillero de colecciones.
 *
 * @param vUserFk Id de usuario
 * @param vCollectionFk Id de colección
 */
	DECLARE vHasTooMuchCollections BOOL;
	DECLARE vDone BOOL DEFAULT FALSE;
	DECLARE vCollectionWorker INT;
	DECLARE vMaxNotAssignedCollectionLifeTime TIME;

	DECLARE vCollections CURSOR FOR
		WITH collections AS (			
			SELECT tc.collectionFk, 
					SUM(sv.volume) volume,
					c.saleTotalCount,
					c.itemPackingTypeFk,
					c.trainFk,
					c.warehouseFk,
					c.wagons
				FROM vn.ticketCollection tc
					JOIN vn.collection c ON c.id = tc.collectionFk 
					JOIN vn.saleVolume sv ON sv.ticketFk = tc.ticketFk
				WHERE c.workerFk IS NULL 
					AND sv.shipped >= util.VN_CURDATE()
				GROUP BY tc.collectionFk
		) SELECT c.collectionFk
			FROM collections c
				JOIN vn.operator o
			WHERE o.workerFk = vUserFk
				AND (c.saleTotalCount <= o.linesLimit OR o.linesLimit IS NULL)
				AND (c.itemPackingTypeFk = o.itemPackingTypeFk OR o.itemPackingTypeFk IS NULL)
				AND o.numberOfWagons = c.wagons
				AND o.trainFk = c.trainFk
				AND o.warehouseFk = c.warehouseFk;

	DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
	-- Si hay colecciones sin terminar, sale del proceso

	CALL collection_get(vUserFk);

	SELECT (pc.maxNotReadyCollections - COUNT(*)) <= 0, pc.maxNotAssignedCollectionLifeTime 
			INTO vHasTooMuchCollections, vMaxNotAssignedCollectionLifeTime
		FROM productionConfig pc
			LEFT JOIN tmp.collection ON TRUE;

	DROP TEMPORARY TABLE tmp.collection;

	IF vHasTooMuchCollections THEN
		CALL util.throw('Hay colecciones pendientes');
	END IF;

	-- Se eliminan las colecciones sin asignar que estan obsoletas

	INSERT INTO ticketTracking(stateFk, ticketFk)
		SELECT s.id, tc.ticketFk
			FROM `collection` c
				JOIN ticketCollection tc ON tc.collectionFk = c.id
				JOIN `state` s ON s.code = 'PRINTED_AUTO'
			WHERE c.workerFk IS NULL 
				AND TIMEDIFF(util.VN_NOW(), c.created) > vMaxNotAssignedCollectionLifeTime;

	DELETE FROM `collection` 
		WHERE workerFk IS NULL 
			AND TIMEDIFF(util.VN_NOW(), created) > vMaxNotAssignedCollectionLifeTime;

	-- Se añade registro al semillero

	INSERT INTO collectionHotbed(userFk) VALUES(vUserFk);

	-- Comprueba si hay colecciones disponibles que se ajustan a su configuracion

	OPEN vCollections;
	l: LOOP
		SET vDone = FALSE;
		FETCH vCollections INTO vCollectionFk;

		IF vDone THEN
			LEAVE l;
		END IF;

		BEGIN
			DECLARE EXIT HANDLER FOR SQLEXCEPTION
			BEGIN
				ROLLBACK;
				SET vCollectionFk = NULL;
				RESIGNAL;
			END;

			START TRANSACTION;

			SELECT workerFk INTO vCollectionWorker
				FROM `collection` 
				WHERE id = vCollectionFk FOR UPDATE;

			IF vCollectionWorker IS NULL THEN
				UPDATE `collection`
					SET workerFk = vUserFk
					WHERE id = vCollectionFk;

				COMMIT;
				LEAVE l;
			END IF;

			ROLLBACK;
		END;
	END LOOP;
	CLOSE vCollections;

	IF vCollectionFk IS NULL THEN
		CALL collection_new(vUserFk, vCollectionFk);

		UPDATE `collection`
			SET workerFk = vUserFk
			WHERE id = vCollectionFk;
	END IF;
END$$
DELIMITER ;