DROP PROCEDURE IF EXISTS `vn`.`invoiceOut_new`;
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceOut_new`(
	vSerial VARCHAR(255),
	vInvoiceDate DATETIME,
	vTaxArea VARCHAR(25),
	OUT vNewInvoiceId INT)
BEGIN
/**
 * Creación de facturas emitidas.
 * requiere previamente tabla ticketToInvoice(id).
 *
 * @param vSerial serie a la cual se hace la factura
 * @param vInvoiceDate fecha de la factura
 * @param vTaxArea tipo de iva en relacion a la empresa y al cliente
 * @param vNewInvoiceId id de la factura que se acaba de generar
 * @return vNewInvoiceId
 */
	DECLARE vSpainCountryCode INT DEFAULT 1;
	DECLARE vIsAnySaleToInvoice BOOL;
	DECLARE vIsAnyServiceToInvoice BOOL;
	DECLARE vNewRef VARCHAR(255);
	DECLARE vWorker INT DEFAULT account.myUser_getId();
	DECLARE vCompany INT;
	DECLARE vSupplier INT;
	DECLARE vClient INT;
	DECLARE vCplusStandardInvoiceTypeFk INT DEFAULT 1;
	DECLARE vCplusCorrectingInvoiceTypeFk INT DEFAULT 6;
	DECLARE vCplusSimplifiedInvoiceTypeFk INT DEFAULT 2;
	DECLARE vCorrectingSerial VARCHAR(1) DEFAULT 'R';
	DECLARE vSimplifiedSerial VARCHAR(1) DEFAULT 'S';
	DECLARE vNewInvoiceInId INT;
	DECLARE vIsInterCompany BOOL;

	SET vInvoiceDate = IFNULL(vInvoiceDate,CURDATE());

	SELECT t.clientFk, t.companyFk
			INTO vClient, vCompany
		FROM ticketToInvoice tt
			JOIN ticket t ON t.id = tt.id
		LIMIT 1;

	-- Eliminem de ticketToInvoice els tickets que no han de ser facturats
	DELETE ti.*
		FROM ticketToInvoice ti
			JOIN ticket t ON t.id = ti.id
			JOIN sale s ON s.ticketFk = t.id
			JOIN item i ON i.id = s.itemFk
			JOIN supplier su ON su.id = t.companyFk
			JOIN client c ON c.id = t.clientFk
			LEFT JOIN itemTaxCountry itc ON itc.itemFk = i.id AND itc.countryFk = su.countryFk
		WHERE YEAR(t.shipped) < 2001
			OR c.isTaxDataChecked = FALSE
			OR t.isDeleted
			OR c.hasToInvoice = FALSE
			OR itc.id IS NULL;

	SELECT SUM(s.quantity * s.price * (100 - s.discount)/100), ts.id
			INTO vIsAnySaleToInvoice, vIsAnyServiceToInvoice
		FROM ticketToInvoice t
			LEFT JOIN sale s ON s.ticketFk = t.id
			LEFT JOIN ticketService ts ON ts.ticketFk = t.id;

	IF (vIsAnySaleToInvoice OR vIsAnyServiceToInvoice)
		AND (vCorrectingSerial = vSerial OR NOT hasAnyNegativeBase())
	THEN

		-- el trigger añade el siguiente Id_Factura correspondiente a la vSerial
		INSERT INTO invoiceOut
		(
			ref,
			serial,
			issued,
			clientFk,
			dued,
			companyFk,
			cplusInvoiceType477Fk
		)
		SELECT
				1,
				vSerial,
				vInvoiceDate,
				vClient,
				getDueDate(vInvoiceDate, dueDay),
				vCompany,
				IF(vSerial = vCorrectingSerial,
					vCplusCorrectingInvoiceTypeFk,
					IF(vSerial = vSimplifiedSerial,
						vCplusSimplifiedInvoiceTypeFk,
						vCplusStandardInvoiceTypeFk))
			FROM client
			WHERE id = vClient;


		SET vNewInvoiceId = LAST_INSERT_ID();

		SELECT `ref`
				INTO vNewRef
			FROM invoiceOut
			WHERE id = vNewInvoiceId;

		UPDATE ticket t
				JOIN ticketToInvoice ti ON ti.id = t.id
			SET t.refFk = vNewRef;

		DROP TEMPORARY TABLE IF EXISTS tmp.updateInter;
		CREATE TEMPORARY TABLE tmp.updateInter ENGINE = MEMORY
			SELECT s.id,ti.id ticket_id,vWorker Id_Trabajador
				FROM ticketToInvoice ti
					LEFT JOIN ticketState ts ON ti.id = ts.ticket
					JOIN state s
				WHERE IFNULL(ts.alertLevel,0) < 3 and s.`code` = getAlert3State(ti.id);

		INSERT INTO vncontrol.inter(state_id,Id_Ticket,Id_Trabajador)
			SELECT * FROM tmp.updateInter;

		INSERT INTO ticketLog (action, userFk, originFk, description)
			SELECT 'UPDATE', account.myUser_getId(), ti.id, CONCAT('Crea factura ', vNewRef)
				FROM ticketToInvoice ti;

		CALL invoiceExpenceMake(vNewInvoiceId);
		CALL invoiceTaxMake(vNewInvoiceId,vTaxArea);

		UPDATE invoiceOut io
				JOIN (
					SELECT SUM(amount) AS total
						FROM invoiceOutExpence
						WHERE invoiceOutFk = vNewInvoiceId
					) base
				JOIN (
					SELECT SUM(vat) AS total
						FROM invoiceOutTax
						WHERE invoiceOutFk = vNewInvoiceId
					) vat
			SET io.amount = base.total + vat.total
			WHERE io.id = vNewInvoiceId;

		DROP TEMPORARY TABLE tmp.updateInter;

		SELECT ios.isCEE INTO vIsInterCompany
			FROM vn.ticket t
				JOIN vn.invoiceOut io ON io.`ref` = t.refFk
				JOIN vn.invoiceOutSerial ios ON ios.code = io.serial
			WHERE t.refFk = vNewRef
            LIMIT 1;

		IF (vIsInterCompany) THEN

			SELECT vCompany INTO vSupplier;
			SELECT id INTO vCompany FROM company WHERE clientFk = vClient;

			INSERT INTO invoiceIn(supplierFk, supplierRef, issued, companyFk)
				SELECT vSupplier, vNewRef, vInvoiceDate, vCompany;

			SET vNewInvoiceInId = LAST_INSERT_ID();

			DROP TEMPORARY TABLE IF EXISTS tmp.ticket;
			CREATE TEMPORARY TABLE tmp.ticket
				(KEY (ticketFk))
				ENGINE = MEMORY
				SELECT id ticketFk
					FROM ticketToInvoice;

			CALL `ticket_getTax`('NATIONAL');

			SET @vTaxableBaseServices := 0.00;
			SET @vTaxCodeGeneral := NULL;

			INSERT INTO vn.invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
				SELECT vNewInvoiceInId, @vTaxableBaseServices, sub.expenceFk, sub.taxTypeSageFk , sub.transactionTypeSageFk
					FROM (
						SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase, i.expenceFk, i.taxTypeSageFk , i.transactionTypeSageFk, @vTaxCodeGeneral := i.taxClassCodeFk
							FROM tmp.ticketServiceTax tst
								JOIN vn.invoiceOutTaxConfig i ON i.taxClassCodeFk = tst.code
							WHERE i.isService
							HAVING taxableBase
						) sub;

			INSERT INTO vn.invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
				SELECT  vNewInvoiceInId, SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral, @vTaxableBaseServices, 0) taxableBase, i.expenceFk, i.taxTypeSageFk , i.transactionTypeSageFk
					FROM tmp.ticketTax tt
						JOIN vn.invoiceOutTaxConfig i ON i.taxClassCodeFk = tt.code
					WHERE !i.isService
					GROUP BY tt.pgcFk
					HAVING taxableBase
					ORDER BY tt.priority;

			CALL invoiceInDueDay_calculate(vNewInvoiceInId);

			INSERT INTO invoiceInIntrastat (
					invoiceInFk,
					intrastatFk,
					amount,
					stems,
					countryFk,
					net)
				SELECT
					vNewInvoiceInId invoiceInFk,
					i.intrastatFk,
					CAST(SUM((s.quantity * s.price * (100 - s.discount) / 100 )) AS DECIMAL(10,2)) subtotal,
					CAST(SUM(IFNULL(i.stems, 1) * s.quantity) AS DECIMAL(10,2)) stems,
					su.countryFk,
					CAST(SUM(IFNULL(i.stems, 1)
							* s.quantity
							* IF(ic.grams, ic.grams, i.weightByPiece) / 1000) AS DECIMAL(10,2)) netKg
				FROM sale s
					JOIN ticket t ON s.ticketFk = t.id
					JOIN supplier su ON su.id = t.companyFk
					JOIN item i ON i.id = s.itemFk
					JOIN vn.itemCost ic ON ic.itemFk = i.id AND ic.warehouseFk = t.warehouseFk
					JOIN intrastat ir ON ir.id = i.intrastatFk
				WHERE t.refFk = vNewRef;

			DROP TEMPORARY TABLE tmp.ticket;
			DROP TEMPORARY TABLE tmp.ticketAmount;
			DROP TEMPORARY TABLE tmp.ticketTax;
			DROP TEMPORARY TABLE tmp.ticketServiceTax;

		END IF;

	END IF;

	DROP TEMPORARY TABLE `ticketToInvoice`;
END$$
DELIMITER ;