--Hash:17C9A5A90BCE36C15018C53EAB2BB460

-- Bloqueo exclusivo por base de datos
--//
SET NOCOUNT ON;

DECLARE @__ZiurDbScriptLockResource NVARCHAR(200) = N'ZiurSoft:DbScriptLock:' + CAST(DB_ID() AS NVARCHAR(20));
DECLARE @__ZiurDbScriptLockResult INT;
EXEC @__ZiurDbScriptLockResult = sp_getapplock
    @Resource = @__ZiurDbScriptLockResource,
    @LockMode = N'Exclusive',
    @LockOwner = N'Session',
    @LockTimeout = 600000; -- 10 min

IF (@__ZiurDbScriptLockResult < 0)
BEGIN
    RAISERROR(N'No se pudo obtener el bloqueo exclusivo de actualizacion para esta base de datos.', 16, 1);
    SET NOEXEC ON;
END

/* Idempotencia a nivel de script: si la version ya existe, no ejecutar nada. */
IF EXISTS (SELECT 1 FROM dbo.ZiurVersiones WHERE NumVersion = 983)
BEGIN
    PRINT N'Scripts_983.sql: la version 983 ya esta aplicada. Se omite ejecucion.';
    EXEC sp_releaseapplock @Resource = @__ZiurDbScriptLockResource, @LockOwner = N'Session';
    SET NOEXEC ON;
END

SET XACT_ABORT ON;

GO

SET DATEFORMAT mdy;

--Validar que no existan scripts que no se hayan ejecutado
--//
IF EXISTS
(
	SELECT a.NumVersion + 1 AS HuecoInicio
	FROM ZiurVersiones a
	LEFT JOIN ZiurVersiones b ON a.NumVersion + 1 = b.NumVersion
	WHERE a.NumVersion>830 AND b.NumVersion IS NULL
	AND a.NumVersion + 1 < 983
)
RAISERROR('Error : hay un script que no se ejecuto , debe ejecutarlo manualmente.', 20, -1) with log
--//

--Colocar contenido de script diferencial aqui (Ziur.Database.publish.sql)

GO
/*
 Plantilla de script anterior a la implementación							
--------------------------------------------------------------------------------------
 Este archivo contiene instrucciones de SQL que se ejecutarán antes del script de compilación	
 Use la sintaxis de SQLCMD para incluir un archivo en el script anterior a la implementación			
 Ejemplo:      :r .\miArchivo.sql								
 Use la sintaxis de SQLCMD para hacer referencia a una variable en el script anterior a la implementación		
 Ejemplo:      :setvar TableName miTabla							
               SELECT * FROM [$(TableName)]					
--------------------------------------------------------------------------------------
*/
GO

GO
PRINT N'Altering Table [dbo].[DocElectronicos_Equivalencias]...';


GO
IF OBJECT_ID(N'dbo.DocElectronicos_Equivalencias', N'U') IS NOT NULL
AND COL_LENGTH(N'dbo.DocElectronicos_Equivalencias', N'TipoSaludable') IS NULL
BEGIN
    ALTER TABLE [dbo].[DocElectronicos_Equivalencias]
        ADD [TipoSaludable] INT NULL;
END

IF OBJECT_ID(N'dbo.DocElectronicos_Equivalencias', N'U') IS NOT NULL
AND COL_LENGTH(N'dbo.DocElectronicos_Equivalencias', N'ValorConsumo') IS NULL
BEGIN
    ALTER TABLE [dbo].[DocElectronicos_Equivalencias]
        ADD [ValorConsumo] NUMERIC(28, 6) NULL;
END


GO
PRINT N'Altering Procedure [dbo].[GenerarDocumentos]...';

IF OBJECT_ID(N'dbo.GenerarDocumentos', N'P') IS NULL
    EXEC(N'CREATE PROCEDURE dbo.GenerarDocumentos AS BEGIN SET NOCOUNT ON; RETURN 0; END');


GO
ALTER PROCEDURE GenerarDocumentos
    @IdDoc INT,
    @TipoImplementacion INT, -- 0=GenerarDoc, 1=GenerarEquiv
    @PrefijoSelec NVARCHAR(10) = NULL,
    @IdEncabNew INT OUTPUT,
    @Exito INT = 0 OUTPUT,
    @MensajeError NVARCHAR(200) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    BEGIN TRY

        IF @TipoImplementacion IS NULL
			SET @TipoImplementacion = 0;

        DECLARE @IdEncab INT;
        DECLARE @XML XML;
        DECLARE @NumeroFacturaFull VARCHAR(50);
        DECLARE @NumeroFactura VARCHAR(50);
        DECLARE @FechaFactura DATE;
        DECLARE @ValorTotal DECIMAL(18,2);
        DECLARE @Mensaje VARCHAR(500);
        DECLARE @TipoDocSincro  INT;
		DECLARE @Prefijo VARCHAR (10);
        
        -- Variables para datos del XML
        DECLARE @NitProveedor VARCHAR(50);
        DECLARE @NombreProveedor VARCHAR(200);
        DECLARE @CodigoMoneda VARCHAR(10);
        DECLARE @IdDocumento INT;
        DECLARE @TipoDocumento VARCHAR(10);
        DECLARE @UnidadMedida VARCHAR(10);
        DECLARE @TipoIdentProveedor VARCHAR(10);
        DECLARE @IdCreditNote INT;

        -- Variables para dirección del cliente
        DECLARE @DireccionCliente VARCHAR(500);
        DECLARE @TelefonoCliente VARCHAR(50);
        DECLARE @EmailCliente VARCHAR(100);
        DECLARE @IdCiudadCliente VARCHAR(20);
        DECLARE @IdFormaPago VARCHAR(10);
        DECLARE @PlazoCliente INT;
        DECLARE @Vence DATE;
        
        -- Variables para cálculos
        DECLARE @Cantidad DECIMAL(18,6);
        DECLARE @BaseImpuesto DECIMAL(18,2);
        DECLARE @ValorImpuesto DECIMAL(18,2);
        DECLARE @ValorIva DECIMAL(18,2);
        DECLARE @ValorINC DECIMAL(18,2);
		DECLARE @ValorIBUA DECIMAL(18,2);
        DECLARE @ValorICUI DECIMAL (18,2);
		DECLARE @ValorICL DECIMAL (18,2);
		DECLARE @ValorADV DECIMAL (18,2);
		DECLARE @ValorIC DECIMAL (18,2);
        DECLARE @TipoImpuestoSaludable INT;
        DECLARE @SubTotal DECIMAL(18,2);
        DECLARE @DescuentoTotal DECIMAL(18,2);
        DECLARE @FactorDescuento DECIMAL(18,6);

        -- Variables para datos del XML
        DECLARE @NitEmpresa VARCHAR(50);
        DECLARE @CiudadBodega VARCHAR(50);
        DECLARE @CodigoCiudad VARCHAR(10);

        DECLARE @IdTipoIdent INT;
        DECLARE @TaxLevelCode VARCHAR(200);
        DECLARE @IdTipoRegimen INT;
        DECLARE @RespoTributaria VARCHAR(10);

        -- Obtenemos el XML
        SELECT @XML = CAST(PR.Recurso AS XML)
        FROM dbo.DocElectronicos DE 
        INNER JOIN dbo.DocElectronicos_DocRecursos DR ON DE.IdDoc = DR.IdDoc 
        INNER JOIN dbo.Parametros_Recursos PR ON DR.IdRecurso = PR.IdRecurso
        WHERE DE.IdDoc = @IdDoc
        AND DR.IdTipo = 0;

        IF @XML IS NULL
        BEGIN
            RAISERROR('No se encontró el documento XML para el ID especificado.', 16, 1);
            RETURN;
        END;

        SELECT @TipoDocSincro = TipoDocSincro FROM DocElectronicos WHERE IdDoc=@IdDoc;

        -- Extraemos todos los datos relevantes del XML
        WITH XMLNAMESPACES (
            'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2' as inv,
            'urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2' as cn,
            'urn:oasis:names:specification:ubl:schema:xsd:DebitNote-2' as dn,
            'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' as cbc,
            'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' as cac,
			'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2' AS ext,
			'dian:gov:co:facturaelectronica:Structures-2-1' AS sts
        )
        SELECT 
            -- Datos básicos del documento
            @NumeroFactura = COALESCE(
                @XML.value('(/inv:Invoice/cbc:ID)[1]', 'varchar(50)'),
                @XML.value('(/cn:CreditNote/cbc:ID)[1]', 'varchar(50)'),
                @XML.value('(/dn:DebitNote/cbc:ID)[1]', 'varchar(50)')
            ),
			@Prefijo = COALESCE(
                @XML.value('(/inv:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:InvoiceControl/sts:AuthorizedInvoices/sts:Prefix)[1]', 'varchar(10)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PartyLegalEntity/cac:CorporateRegistrationScheme/cbc:ID)[1]', 'varchar(10)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PartyLegalEntity/cac:CorporateRegistrationScheme/cbc:ID)[1]', 'varchar(10)')
            ),
            @FechaFactura  = COALESCE(
                @XML.value('(/inv:Invoice/cbc:IssueDate)[1]', 'date'),
                @XML.value('(/cn:CreditNote/cbc:IssueDate)[1]', 'date'),
                @XML.value('(/dn:DebitNote/cbc:IssueDate)[1]', 'date')
            ),
            @TipoDocumento = COALESCE(
                @XML.value('(/inv:Invoice/cbc:InvoiceTypeCode)[1]', 'varchar(10)'),
                @XML.value('(/cn:CreditNote/cbc:CreditNoteTypeCode)[1]', 'varchar(10)'),
                @XML.value('(/dn:DebitNote/cbc:DebitNoteTypeCode)[1]', 'varchar(10)')
            ),
            @CodigoMoneda  = COALESCE(
                @XML.value('(/inv:Invoice/cbc:DocumentCurrencyCode)[1]', 'varchar(10)'),
                @XML.value('(/cn:CreditNote/cbc:DocumentCurrencyCode)[1]', 'varchar(10)'),
                @XML.value('(/dn:DebitNote/cbc:DocumentCurrencyCode)[1]', 'varchar(10)')
            ),
            @NitEmpresa = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)')
            ),
            @CiudadBodega = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CityName)[1]','varchar(50)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CityName)[1]','varchar(50)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CityName)[1]','varchar(50)')
            ),
            @CodigoCiudad = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(10)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(10)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(10)')
            ),
            @NitProveedor = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)')
            ),
            @NombreProveedor = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name)[1]','varchar(200)'),
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:RegistrationName)[1]','varchar(200)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:RegistrationName)[1]','varchar(200)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name)[1]','varchar(200)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:RegistrationName)[1]','varchar(200)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name)[1]','varchar(200)')
            ),
            @TipoIdentProveedor = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID/@schemeName)[1]','varchar(10)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID/@schemeName)[1]','varchar(10)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID/@schemeName)[1]','varchar(10)')
            ),
            @UnidadMedida = COALESCE(
                @XML.value('(/inv:Invoice/cac:InvoiceLine/cbc:InvoicedQuantity/@unitCode)[1]','varchar(10)'),
                @XML.value('(/cn:CreditNote/cac:CreditNoteLine/cbc:CreditedQuantity/@unitCode)[1]','varchar(10)'),
                @XML.value('(/dn:DebitNote/cac:DebitNoteLine/cbc:DebitedQuantity/@unitCode)[1]','varchar(10)')
            ),
            @DireccionCliente = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:AddressLine/cbc:Line)[1]','varchar(500)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:AddressLine/cbc:Line)[1]','varchar(500)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:AddressLine/cbc:Line)[1]','varchar(500)')
            ),
            @TelefonoCliente = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:Contact/cbc:Telephone)[1]','varchar(50)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:Contact/cbc:Telephone)[1]','varchar(50)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:Contact/cbc:Telephone)[1]','varchar(50)')
            ),
            @EmailCliente = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:Contact/cbc:ElectronicMail)[1]','varchar(100)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:Contact/cbc:ElectronicMail)[1]','varchar(100)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:Contact/cbc:ElectronicMail)[1]','varchar(100)')
            ),
            @IdCiudadCliente = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(20)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(20)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(20)')
            ),
            @IdFormaPago = COALESCE(
                @XML.value('(/inv:Invoice/cac:PaymentMeans/cbc:ID)[1]','varchar(10)'),
                @XML.value('(/cn:CreditNote/cac:PaymentMeans/cbc:ID)[1]','varchar(10)'),
                @XML.value('(/dn:DebitNote/cac:PaymentMeans/cbc:ID)[1]','varchar(10)')
            ),
            @Cantidad = COALESCE(
                @XML.value('(/inv:Invoice/cac:InvoiceLine/cbc:InvoicedQuantity)[1]','decimal(18,6)'),
                @XML.value('(/cn:CreditNote/cac:CreditNoteLine/cbc:CreditedQuantity)[1]','decimal(18,6)'),
                @XML.value('(/dn:DebitNote/cac:DebitNoteLine/cbc:DebitedQuantity)[1]','decimal(18,6)')
            ),
            @BaseImpuesto = COALESCE(
                @XML.value('(/inv:Invoice/cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount)[1]','decimal(18,2)'),
                @XML.value('(/cn:CreditNote/cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount)[1]','decimal(18,2)'),
                @XML.value('(/dn:DebitNote/cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount)[1]','decimal(18,2)')
            ),
            @ValorImpuesto = COALESCE(
                @XML.value('(/inv:Invoice/cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount)[1]','decimal(18,2)'),
                @XML.value('(/cn:CreditNote/cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount)[1]','decimal(18,2)'),
                @XML.value('(/dn:DebitNote/cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount)[1]','decimal(18,2)')
            ),
            @SubTotal = COALESCE(
                @XML.value('(/inv:Invoice/cac:LegalMonetaryTotal/cbc:LineExtensionAmount)[1]','decimal(18,2)'),
                @XML.value('(/cn:CreditNote/cac:LegalMonetaryTotal/cbc:LineExtensionAmount)[1]','decimal(18,2)'),
                @XML.value('(/dn:DebitNote/cac:LegalMonetaryTotal/cbc:LineExtensionAmount)[1]','decimal(18,2)')
            ),
            @DescuentoTotal = COALESCE(
                @XML.value('(/inv:Invoice/cac:LegalMonetaryTotal/cbc:AllowanceTotalAmount)[1]','decimal(18,2)'),
                @XML.value('(/cn:CreditNote/cac:LegalMonetaryTotal/cbc:AllowanceTotalAmount)[1]','decimal(18,2)'),
                @XML.value('(/dn:DebitNote/cac:LegalMonetaryTotal/cbc:AllowanceTotalAmount)[1]','decimal(18,2)')
            ),
            @ValorTotal = COALESCE(
                @XML.value('(/inv:Invoice/cac:LegalMonetaryTotal/cbc:PayableAmount)[1]','decimal(18,2)'),
                @XML.value('(/cn:CreditNote/cac:LegalMonetaryTotal/cbc:PayableAmount)[1]','decimal(18,2)'),
                @XML.value('(/dn:DebitNote/cac:RequestedMonetaryTotal/cbc:PayableAmount)[1]','decimal(18,2)')
            ),
            @IdTipoIdent = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID/@schemeName)[1]', 'int'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID/@schemeName)[1]', 'int'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID/@schemeName)[1]', 'int')
            ),
            @TaxLevelCode = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode)[1]', 'varchar(50)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode)[1]', 'varchar(50)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode)[1]', 'varchar(50)')
            ),
            @RespoTributaria = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID)[1]', 'varchar(10)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID)[1]', 'varchar(10)')
            ),
            @IdCreditNote = @XML.value('(/dn:DebitNote/cbc:CustomizationID)[1]','int'),

            @IdTipoRegimen =
            CASE
                WHEN @IdTipoIdent = 42 THEN 9 -- Tercero del Exterior
                WHEN @IdTipoIdent = 13 AND @TaxLevelCode LIKE '%O-15%' THEN 10 -- Gran Contribuyente Persona Natural
                WHEN @IdTipoIdent = 13 AND @TaxLevelCode = 'R-99-PN' THEN 6 -- Persona Natural No Responsable de IVA
                WHEN @IdTipoIdent = 13 THEN 2 -- Persona Natural Responsable de IVA
                WHEN @IdTipoIdent = 31 AND @TaxLevelCode LIKE '%O-15%' THEN 4 -- Gran Contribuyente
                WHEN @IdTipoIdent = 31 THEN 3 -- Persona Jurídica
                ELSE 6
            END

		IF @TipoDocSincro=1
		BEGIN

		WITH XMLNAMESPACES (
            'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2' as inv,
            'urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2' as cn,
            'urn:oasis:names:specification:ubl:schema:xsd:DebitNote-2' as dn,
            'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' as cbc,
            'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' as cac
        )
        SELECT        
			@NitEmpresa = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)')
            ),
            @CiudadBodega = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CityName)[1]','varchar(50)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CityName)[1]','varchar(50)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CityName)[1]','varchar(50)')
            ),
            @CodigoCiudad = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(10)'),
                @XML.value('(/cn:CreditNote/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(10)'),
                @XML.value('(/dn:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(10)')
            ),
            @NitProveedor = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID)[1]','varchar(50)')
            ),
            @NombreProveedor = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyName/cbc:Name)[1]','varchar(200)'),
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:RegistrationName)[1]','varchar(200)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:RegistrationName)[1]','varchar(200)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PartyName/cbc:Name)[1]','varchar(200)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:RegistrationName)[1]','varchar(200)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PartyName/cbc:Name)[1]','varchar(200)')
            ),
            @TipoIdentProveedor = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID/@schemeName)[1]','varchar(10)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID/@schemeName)[1]','varchar(10)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID/@schemeName)[1]','varchar(10)')
            ),
            @DireccionCliente = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:AddressLine/cbc:Line)[1]','varchar(500)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:AddressLine/cbc:Line)[1]','varchar(500)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:AddressLine/cbc:Line)[1]','varchar(500)')
            ),
            @TelefonoCliente = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:Contact/cbc:Telephone)[1]','varchar(50)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:Contact/cbc:Telephone)[1]','varchar(50)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:Contact/cbc:Telephone)[1]','varchar(50)')
            ),
            @EmailCliente = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:Contact/cbc:ElectronicMail)[1]','varchar(100)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:Contact/cbc:ElectronicMail)[1]','varchar(100)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:Contact/cbc:ElectronicMail)[1]','varchar(100)')
            ),
            @IdCiudadCliente = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(20)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(20)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID)[1]','varchar(20)')
            ),
            @TaxLevelCode = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode)[1]', 'varchar(50)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode)[1]', 'varchar(50)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode)[1]', 'varchar(50)')
            ),
            @RespoTributaria = COALESCE(
                @XML.value('(/inv:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID)[1]', 'varchar(10)'),
                @XML.value('(/cn:CreditNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID)[1]', 'varchar(10)'),
                @XML.value('(/dn:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID)[1]', 'varchar(10)')
            )
		END;

        SET @TipoDocumento = COALESCE(@TipoDocumento,'');

        IF @IdCreditNote IN (30,32)
        BEGIN
            SET @TipoDocumento = '92'; -- Nota Débito
        END;
        
        SELECT @IdDocumento = CASE 
            WHEN @TipoDocumento IN ('01', '40','92') THEN 1
            WHEN @TipoDocumento = '91' THEN 16
            ELSE NULL -- o algún valor por defecto si lo necesitas
        END
        

        SET @NumeroFacturaFull = (CASE WHEN @TipoDocumento = '01' THEN '' ELSE @TipoDocumento + '-' END) + @NumeroFactura;

        IF @TipoImplementacion = 0
        BEGIN
            -- Validamos que solo se puedan procesar facturas(01), Peajes(40; Sin probar) y notas crédito(91)
            IF @TipoDocSincro=0
            BEGIN
                IF @TipoDocumento NOT IN ('01','40','91','92')
                BEGIN
                    RAISERROR('No se pueden procesar documentos que no sean ''Factura electrónica'' o ''Doc cobro peajes'' o ''Nota Crédito'' o ''Nota Débito''.', 16, 1);
                    RETURN;
                END;

                -- Validamos que el documento no exista
                --//
                IF EXISTS (SELECT 1 FROM Encabezados WHERE NumDocumentoExt = @NumeroFacturaFull)
                BEGIN
                    RAISERROR('El documento %s ya existe en el sistema !', 16, 1, @NumeroFacturaFull);
                    RETURN;
                END;
                --//
            END;
            ELSE
            BEGIN
                DECLARE @IdPrefijo VARCHAR(10);
                SELECT @IdPrefijo = IdPrefijo FROM Prefijos WHERE NomPrefijo = @Prefijo;

                IF @IdPrefijo IS NULL
                BEGIN
                    RAISERROR('El prefijo "%s" no existe en el sistema, debe crearlo!', 16, 1, @Prefijo);
                    RETURN;
                END;

                SELECT @IdDocumento = CASE  --Esto es para documento enviado para generar distintos documentos
                    WHEN @TipoDocumento IN ('01') THEN 2  --FV se convierte a FV
                    WHEN @TipoDocumento = '91' THEN 15 -- ND se cpnvierte a ND
                END 
                IF @TipoDocumento NOT IN ('01','91')
                BEGIN
                    RAISERROR('No se pueden procesar documentos que no sean ''Factura electrónica'' o "Nota Crédito".', 16, 1);
                    RETURN;
                END;
            END;
            
            -- Validamos que tengamos los datos mínimos necesarios
            IF @NumeroFactura IS NULL OR @FechaFactura IS NULL OR @ValorTotal IS NULL OR @NitProveedor IS NULL
            BEGIN
                RAISERROR('No se pudieron extraer todos los datos necesarios de la factura.', 16, 1);
                RETURN;
            END;

            --Se inicia aqui la transaccion para que se haga el insert de DocElectronicos_Equivalencias
            BEGIN TRANSACTION;

            -- Buscamos o creamos el proveedor si no existe
            DECLARE @IdCliente INT;
            SELECT TOP 1 @IdCliente = IdCliente FROM Clientes WHERE Identificacion = @NitProveedor;

            -- Si el cliente no existe, lo creamos junto con su dirección
            IF @IdCliente IS NULL
            BEGIN
                -- Calculamos el DV
                DECLARE @DVCliente VARCHAR(2) = NULL;
                IF @TipoIdentProveedor=31
                    SET @DVCliente = dbo.GetDigitoVerificacion(@NitProveedor);

                -- Insertamos el cliente
                INSERT INTO Clientes (
                    Identificacion,
                    Nombre1,
                    EsActivo,
                    IdTipoIdent,
                    DVCliente,
                    IdCiudad,
                    IdTipoRegimen,
                    TarifaIca,
                    CupoCreditoPlazo,
                    ComisionTiene,
                    IdPais,
                    FechaCreacion,
                    FechaUltModificacion
                )
                VALUES (
                    @NitProveedor,
                    @NombreProveedor,
                    1,
                    @IdTipoIdent,
                    @DVCliente,
                    @IdCiudadCliente,
                    @IdTipoRegimen,
                    NULL,
                    NULL,
                    NULL,
                    48,
                    GETDATE(),
                    GETDATE()
                );
            
                SET @IdCliente = SCOPE_IDENTITY();

                -- Obtenemos el IdTipoDir mínimo
                DECLARE @IdTipoDir INT;
                SELECT @IdTipoDir = MIN(IdTipoDir) FROM Clientes_TiposDireccion;

                -- Insertamos la dirección del cliente
                INSERT INTO Clientes_Direcciones (
                    IdCliente,
                    IdTipoDir,
                    Direccion,
                    DireccionFormato1,
                    DireccionFormato2,
                    Telefonos,
                    Celular,
                    Email,
                    IdCiudad,
                    Nota,
                    EsDirPrincipal,
                    Subdivision,
                    CodigoPostal
                )
                VALUES (
                    @IdCliente,
                    @IdTipoDir,
                    @DireccionCliente,
                    @DireccionCliente,
                    @DireccionCliente,
                    @TelefonoCliente,
                    @TelefonoCliente,
                    @EmailCliente,
                    @IdCiudadCliente,
                    NULL,
                    1,
                    NULL,
                    @CodigoCiudad
                );

                -- Insertamos las asociaciones del cliente
                INSERT INTO Clientes_Asociacion (IdCliente, IdTipo) VALUES (@IdCliente, 5);
                INSERT INTO Clientes_Asociacion (IdCliente, IdTipo) VALUES (@IdCliente, 8);

                --Insertamos las Responsabilidades Fiscales
                INSERT INTO Clientes_ResponFiscal (IdCliente, IdResFiscal)
				SELECT 
					@IdCliente,
					RF.IdResFiscal
				FROM [iter$charlist_to_tbl](@TaxLevelCode, ';') AS C
				INNER JOIN FacturacionElectronica_ResponsabilidadFiscal RF
					ON RF.CodResFiscal = LTRIM(RTRIM(C.str));

                --Insertamos la responsabilidad tributaria
                DECLARE @IdResponsabilidadTributaria INT;
                SELECT @IdResponsabilidadTributaria = IdTipo FROM Impuestos_Tipos WHERE CodTipo = @RespoTributaria
                INSERT INTO Clientes_Tributos (IdCliente, IdTipo) VALUES (@IdCliente,@IdResponsabilidadTributaria);

            END;

            -- Obtenemos el IdClienteDir principal
            DECLARE @IdClienteDir INT;
            SELECT @IdClienteDir = MAX(idclientedir) 
            FROM Clientes_Direcciones 
            WHERE EsDirPrincipal = 1 AND IdCliente = @IdCliente;

            -- Obtenemos el plazo del cliente
            SELECT @PlazoCliente = ISNULL(CupoCreditoPlazo, 0) 
            FROM Clientes 
            WHERE IdCliente = @IdCliente;

            -- Buscamos el ID de la moneda
            DECLARE @IdMoneda INT;
            IF @CodigoMoneda = 'COP'
                SET @IdMoneda = 1; -- Asumimos que 1 es el ID para COP
            ELSE
            BEGIN
                SELECT TOP 1 @IdMoneda = IdMoneda
                FROM Monedas
                WHERE Abrev = @CodigoMoneda
                OR NomMoneda1 = @CodigoMoneda;

                IF @IdMoneda IS NULL
                    SET @IdMoneda = 1; -- Default a COP si no se encuentra
            END;


            -- Buscamos la empresa por su NIT
            DECLARE @IdEmpresa INT;
            SELECT TOP 1 @IdEmpresa = IdEmpresa
            FROM Empresas
            WHERE EmpresaNit = @NitEmpresa;

            IF @IdEmpresa IS NULL
            BEGIN
                RAISERROR('No se encontró la empresa con NIT: %s', 16, 1, @NitEmpresa);
                RETURN;
            END;

            IF @TipoDocSincro=1
            BEGIN

				SET @NumeroFactura = SUBSTRING(@NumeroFactura, LEN(@Prefijo) + 1, LEN(@NumeroFactura));

				DECLARE @EsAnulado BIT;
				SELECT @EsAnulado = CAST(ISNULL((SELECT TOP 1 ValParametro FROM Parametros WHERE CodParametro = 46), '1' ) AS BIT );

				IF EXISTS (
					SELECT 1
					FROM Encabezados
					WHERE IdEmpresa = @IdEmpresa
						AND NumDocumento = @NumeroFactura
						AND IdDocumento = @IdDocumento
						AND IdPrefijo = @IdPrefijo
						AND ((@EsAnulado = 1 AND EsAnulado = 0) OR (@EsAnulado = 0))
						AND IdEncab <> 0
				)
				BEGIN
					RAISERROR('El documento %s ya existe en el sistema!', 16, 1, @NumeroFactura);
					RETURN;
				END;
            END;

            -- Bodega principal predterminada
            DECLARE @IdBodega INT = 1; -- Valor por defecto
            SET @Vence = DATEADD(day, @PlazoCliente, @FechaFactura)

			IF @TipoDocSincro=0 --Documentos Recibidos
			BEGIN

            SET @PrefijoSelec = NULLIF(@PrefijoSelec, '');
            
            -- Insertar en Encabezados
            INSERT INTO Encabezados 
            (
                IdEmpresa,
                IdDocumento,
                IdPrefijo,
                NumDocumentoExt,
                Fecha,
                IdCliente1,
                IdCliente1_IdDir,
                IdMoneda,
                ValorTRM,
                ValorPago,
                Nota,
                IdFormaPago,
                Vence,
                FechaCreacion,
                FechaUltModificacion
            )
            VALUES (
                @IdEmpresa,
                @IdDocumento,
                @PrefijoSelec,
                @NumeroFacturaFull,
                @FechaFactura,
                @IdCliente,
                @IdClienteDir,
                @IdMoneda,
                0,                  -- ValorTRM siempre 0
                0,
                'Importado automáticamente',
                @IdFormaPago,
                @Vence,
                GETDATE(),
                GETDATE()
            );
			END;
			ELSE -- Documentos Enviados
			BEGIN 

			INSERT INTO Encabezados 
            (
                IdEmpresa,
                IdDocumento,
                NumDocumento,
				IdPrefijo,
                Fecha,
                IdCliente1,
                IdCliente1_IdDir,
                IdMoneda,
                ValorTRM,
                ValorPago,
                Nota,
                IdFormaPago,
                Vence,
                FechaCreacion,
                FechaUltModificacion
            )
            VALUES (
                @IdEmpresa,
                @IdDocumento,
                @NumeroFactura,
				@IdPrefijo,
                @FechaFactura,
                @IdCliente,
                @IdClienteDir,
                @IdMoneda,
                0,                  -- ValorTRM siempre 0
                0,
                'Importado automáticamente',
                @IdFormaPago,
                @Vence,
                GETDATE(),
                GETDATE()
            );
			END;

            SET @IdEncab = SCOPE_IDENTITY();
        
        END; -- Fin If TipoImplementacion = 0

        --*************************************************************************
		--ITERAR ITEMS
        DECLARE @TotalItems INT
        DECLARE @Index INT = 1
        DECLARE @IdInventario INT;
        DECLARE @IdUnidad INT = 1; -- Valor por defecto
        DECLARE @CodInventario VARCHAR(50);
        DECLARE @CodInventario2 VARCHAR(50);
        DECLARE @CodInventario3 VARCHAR(50);
        DECLARE @NomInventario VARCHAR(500);
        DECLARE @ValorUnitario NUMERIC(18,2);

        --Equivalencias
        DECLARE @EqSenFind                 BIT;
        DECLARE @EqIdEquiv                 INT;
        DECLARE @EqIdInventario            INT;
        DECLARE @EqIdTipoInv               INT;
        DECLARE @EqIdContab               INT;
        DECLARE @EqCodInventario_Pref      NVARCHAR(50);     

        -- Crear tabla temporal para los ítems
		CREATE TABLE #ItemsXML (
			RowNum INT PRIMARY KEY,
			CodInventario VARCHAR(20),
			CodInventario2 VARCHAR(20),
			CodInventario3 VARCHAR(20),
			NomInventario VARCHAR(500),
			Cantidad DECIMAL(18,2),
			ValorTotal DECIMAL(18,2),
			ValorUnitario NUMERIC(18,2),
			ValorIva DECIMAL(18,2),
			ValorINC DECIMAL(18,2),
			ValorIC DECIMAL(18,2),
			ValorIBUA DECIMAL(18,2),
			ValorICUI DECIMAL(18,2),
			ValorICL DECIMAL(18,2),
			ValorADV DECIMAL(18,2),
			FactorDescuento DECIMAL(18,2)
		);

		-- Extraer todos los ítems del XML en bloque
		WITH XMLNAMESPACES (
			'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' AS cac,
			'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' AS cbc
		)
		INSERT INTO #ItemsXML
		SELECT
			ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum,
			X.value('(cbc:ID)[1]', 'varchar(20)'),
			X.value('(cac:Item/cac:SellersItemIdentification/cbc:ID)[1]', 'varchar(20)'),
			X.value('(cac:Item/cac:StandardItemIdentification/cbc:ID)[1]', 'varchar(20)'),
			X.value('(cac:Item/cbc:Description)[1]', 'varchar(500)'),
			COALESCE(
				X.value('(cbc:InvoicedQuantity)[1]', 'decimal(18,2)'),
				X.value('(cbc:CreditedQuantity)[1]', 'decimal(18,2)'),
                X.value('(cbc:DebitedQuantity )[1]', 'decimal(18,2)')
			),
			X.value('(cbc:LineExtensionAmount)[1]', 'decimal(18,2)'),
			X.value('(cac:Price/cbc:PriceAmount)[1]', 'numeric(18,2)'),
			X.value('(cac:TaxTotal/cac:TaxSubtotal[cac:TaxCategory/cac:TaxScheme/cbc:ID="01"]/cac:TaxCategory/cbc:Percent)[1]', 'decimal(18,2)'), --Valor IVA
			X.value('(cac:TaxTotal/cac:TaxSubtotal[cac:TaxCategory/cac:TaxScheme/cbc:ID="04"]/cbc:TaxAmount)[1]', 'decimal(18,2)'), --Valor INC
			X.value('(cac:TaxTotal/cac:TaxSubtotal[cac:TaxCategory/cac:TaxScheme/cbc:ID="02"]/cbc:TaxAmount)[1]', 'decimal(18,2)'), --Valor IC
			X.value('(cac:TaxTotal/cac:TaxSubtotal[cac:TaxCategory/cac:TaxScheme/cbc:ID="34"]/cbc:TaxAmount)[1]', 'decimal(18,2)'), --Valor IBUA
			X.value('(cac:TaxTotal/cac:TaxSubtotal[cac:TaxCategory/cac:TaxScheme/cbc:ID="35"]/cac:TaxCategory/cbc:Percent)[1]', 'decimal(18,2)'), --Valor ICUI
			X.value('(cac:TaxTotal/cac:TaxSubtotal[cac:TaxCategory/cac:TaxScheme/cbc:ID="32"]/cbc:TaxAmount)[1]', 'decimal(18,2)'), --Valor ICL
			X.value('(cac:TaxTotal/cac:TaxSubtotal[cac:TaxCategory/cac:TaxScheme/cbc:ID="36"]/cbc:TaxAmount)[1]', 'decimal(18,2)'), --Valor ADV
			X.value('(cac:AllowanceCharge/cbc:MultiplierFactorNumeric)[1]', 'decimal(18,2)')
		FROM @XML.nodes('/*[local-name()="Invoice" or local-name()="CreditNote" or local-name()="DebitNote"]/cac:*[local-name()="InvoiceLine" or local-name()="CreditNoteLine" or local-name()="DebitNoteLine"]') AS T(X);


        SET @TotalItems = (SELECT COUNT(*) FROM #ItemsXML);

 
        -- Bucle para procesar cada uno
        WHILE @Index <= @TotalItems
        BEGIN
            -- Inicializar
            SET @EqSenFind                 = 0;
            SET @EqIdEquiv                 = NULL;
            SET @EqIdInventario            = NULL;
            SET @EqIdTipoInv               = NULL;
            SET @EqIdContab                = NULL;
            SET @EqCodInventario_Pref      = NULL;
            SET @IdInventario              = NULL;

           SELECT
                @CodInventario  = COALESCE(CodInventario3, CodInventario2, CodInventario),
                @NomInventario  = NomInventario,
                @Cantidad       = Cantidad,
                @ValorTotal     = ValorTotal,
                @ValorUnitario  = ValorUnitario,
                @ValorIva       = ISNULL(ValorIva, 0),
                @ValorINC       = ISNULL(ValorINC, 0),
                @ValorIC        = ISNULL(ValorIC, 0),
                @ValorIBUA      = ISNULL(ValorIBUA, 0),
                @ValorICUI      = ISNULL(ValorICUI, 0),
                @ValorICL       = ISNULL(ValorICL, 0),
                @ValorADV       = ISNULL(ValorADV, 0),
                @FactorDescuento = ISNULL(FactorDescuento, 0)
            FROM #ItemsXML
            WHERE RowNum = @Index;

                SET @ValorINC = COALESCE(@ValorINC, @ValorIC, 0);
				SET @ValorIC = COALESCE(@ValorIC, 0);
                SET @ValorIBUA = COALESCE(@ValorIBUA, 0);
                SET @ValorICUI = COALESCE(@ValorICUI, 0);
				SET @ValorICL = COALESCE(@ValorICL, 0);
				SET @ValorADV = COALESCE(@ValorADV, 0);
				SET @ValorINC = @ValorINC+@ValorICL+@ValorADV;
                SET @TipoImpuestoSaludable = 0; --0 = Impuesto ICUI, 1 = Impuesto IBUA
                IF @ValorIBUA > 0
                    SET @TipoImpuestoSaludable = 1;

            -- Revisa si tiene el codigo personalizado o uno generico
            SET @CodInventario = COALESCE(@CodInventario3,@CodInventario2, @CodInventario);
            SET @ValorIva = COALESCE(@ValorIva, 0);
            SET @FactorDescuento = COALESCE(@FactorDescuento, 0);

            IF @TipoImplementacion = 0
                BEGIN
                --Caso Equivalencias NomInventario
                --//
                IF (@EqSenFind=0)
                BEGIN
                    SELECT @EqIdEquiv = IdEquiv , @EqIdInventario = IdInventario,  @EqIdTipoInv = IdTipoInv, @EqIdContab= IdContab, @EqCodInventario_Pref = CodInventario_Pref
                    FROM DocElectronicos_Equivalencias 
                    WHERE 
                    (IdTipoIdent = @IdTipoIdent AND Identificacion=@NitProveedor) AND 
                    (NomInventario_Operador IS NOT NULL AND NomInventario IS NOT NULL) AND 
                    (
                        (NomInventario_Operador = 0 AND @NomInventario = NomInventario ) OR
                        (NomInventario_Operador = 1 AND @NomInventario LIKE '%' + NomInventario + '%') OR
                        (NomInventario_Operador = 2 AND @NomInventario LIKE NomInventario + '%') OR
                        (NomInventario_Operador = 3 AND @NomInventario LIKE '%' + NomInventario)
                    ) AND
                    (ValorIva = @ValorIva OR ValorIva IS NULL)
                    ORDER BY CASE WHEN ValorIva = @ValorIva THEN 1 WHEN ValorIva IS NULL THEN 2 END;

                    IF @EqIdEquiv IS NOT NULL
                        SET @EqSenFind = 1
                END
                --//

                --Caso Equivalencias CodInventario
                --//
                IF (@EqSenFind=0)
                BEGIN
                    SELECT @EqIdEquiv = IdEquiv , @EqIdInventario = IdInventario,  @EqIdTipoInv = IdTipoInv, @EqIdContab= IdContab, @EqCodInventario_Pref = CodInventario_Pref
                    FROM DocElectronicos_Equivalencias 
                    WHERE 
                    (IdTipoIdent = @IdTipoIdent AND Identificacion=@NitProveedor) AND 
                    (CodInventario_Operador IS NOT NULL AND CodInventario IS NOT NULL) AND 
                    (
                        (CodInventario_Operador = 0 AND @CodInventario = CodInventario ) OR
                        (CodInventario_Operador = 1 AND @CodInventario LIKE '%' + CodInventario + '%') OR
                        (CodInventario_Operador = 2 AND @CodInventario LIKE CodInventario + '%') OR
                        (CodInventario_Operador = 3 AND @CodInventario LIKE '%' + CodInventario)
                    ) AND
                    (ValorIva = @ValorIva OR ValorIva IS NULL)
                    ORDER BY CASE WHEN ValorIva = @ValorIva THEN 1 WHEN ValorIva IS NULL THEN 2 END;
                
                    IF @EqIdEquiv IS NOT NULL
                        SET @EqSenFind = 1
                END
                --//
            
                --Caso Equivalencias General por TipoIdent y Proveedor
                --//
                IF (@EqSenFind=0)
                BEGIN
                    SELECT TOP 1 @EqIdEquiv = IdEquiv , @EqIdInventario = IdInventario,  @EqIdTipoInv = IdTipoInv, @EqIdContab= IdContab, @EqCodInventario_Pref = CodInventario_Pref
                    FROM DocElectronicos_Equivalencias 
                    WHERE 
                    (IdTipoIdent = @IdTipoIdent AND Identificacion=@NitProveedor) AND
                    (ValorIva = @ValorIva OR ValorIva IS NULL)
                    ORDER BY CASE WHEN ValorIva = @ValorIva THEN 1 WHEN ValorIva IS NULL THEN 2 END;

                    IF @EqIdEquiv IS NOT NULL
                        SET @EqSenFind = 1
                END
                --//

                --Caso Equivalencias General
                --//
                IF (@EqSenFind=0)
                BEGIN
                    SELECT TOP 1 @EqIdEquiv = IdEquiv , @EqIdInventario = IdInventario,  @EqIdTipoInv = IdTipoInv, @EqIdContab= IdContab, @EqCodInventario_Pref = CodInventario_Pref
                    FROM DocElectronicos_Equivalencias 
                    WHERE 
                    (ValorIva = @ValorIva OR ValorIva IS NULL)
                    ORDER BY CASE WHEN ValorIva = @ValorIva THEN 1 WHEN ValorIva IS NULL THEN 2 END;

                    IF @EqIdEquiv IS NOT NULL
                        SET @EqSenFind = 1
                END
                --//

                IF (@EqSenFind =0)
                BEGIN
                    DECLARE @NomTipoIdent NVARCHAR(100);
                    SELECT @NomTipoIdent = NomTipoIdent FROM Clientes_TiposIdent WHERE IdTipoIdent = @IdTipoIdent;

                    DECLARE @strValorIVA NVARCHAR(200) = CAST(@ValorIva AS NVARCHAR(200));
                    RAISERROR('Doc %s : No se encontró equivalencia con TipoIdent: %s, Número: %s, Inventario: %s, ValorIva: %s', 16, 1, @NumeroFacturaFull, @NomTipoIdent, @NitProveedor, @CodInventario, @strValorIVA);
                    RETURN;
                END;

                --Obtener el id del inventario
                --//
                DECLARE @CodInventarioFull NVARCHAR(50);
                DECLARE @tIdTipoInv INT = NULL;

                SET @CodInventarioFull = COALESCE(@EqCodInventario_Pref, '') + @CodInventario;

                IF (@EqIdInventario IS NULL)
                BEGIN
                    SELECT TOP 1 @IdInventario = IdInventario, @tIdTipoInv = IdTipoInv FROM Inventarios WHERE CodInventario = @CodInventarioFull;


                    DECLARE @TipoInvMovCSV varchar(200);
                    SELECT @TipoInvMovCSV = REPLACE(ISNULL(TipoInvMov,''),' ','')
                    FROM dbo.Documentos
                    WHERE IdDocumento = @IdDocumento;
                    --Validar el tipo de inventario permitido de manera dinámica
                    --//
                    IF (@IdInventario IS NOT NULL)
                       AND CHARINDEX(',' + CAST(@tIdTipoInv AS varchar(10)) + ',', ',' + @TipoInvMovCSV + ',') = 0
                    BEGIN
                        RAISERROR('Doc %s : El inventario %s (TipoInv %d) no está permitido para el doc %d. Permitidos: %s',16, 1, @NumeroFacturaFull, @CodInventarioFull, @tIdTipoInv, @IdDocumento, @TipoInvMovCSV);
                        RETURN;
                    END
                    --//

                    --Validar si toca crear un producto y no tiene una contabilizacion definida
                    --//
                    IF (@IdInventario IS NULL) AND (@EqIdContab IS NULL)
                    BEGIN
                        RAISERROR('Doc %s : No existe una contabilización definida, para la creación del producto %s', 16, 1, @NumeroFacturaFull, @CodInventarioFull);
                        RETURN;
                    END
                    --//

                    IF @IdInventario IS NULL
                    BEGIN
                        -- Aquí deberíamos insertar el nuevo producto
                        INSERT INTO Inventarios 
                        (
                            CodInventario,
                            NomInventario,
                            EsActivo,
                            CantMaxima,
                            CantMinima, 
                            PuntoReorden,
                            IdUnidad,
                            ValorIva,
							TipoImptoConsumo,
                            ValorImptoConsumo,
                            ImptoSaludableTipo,
                            IdTipoInv,
                            IdContab,
                            ValorUtilidadEst,
                            TipoVentaKit,
                            FechaCreacion,
                            FechaUltModificacion
                        )
                        VALUES (
                            @CodInventarioFull,
                            @NomInventario,
                            1,
                            NULL,
                            NULL,
                            NULL,
                            1,
                            @ValorIva,
							1,
                            @ValorINC/@Cantidad,
                            @TipoImpuestoSaludable,
                            COALESCE(@EqIdTipoInv,1),
                            @EqIdContab,
                            NULL,
                            NULL,
                            GETDATE(),
                            GETDATE()
                        );
            
                        SET @IdInventario = SCOPE_IDENTITY();
                    END;
                END;
                ELSE
                BEGIN
                    SET @IdInventario = @EqIdInventario;
                END;
                --//

                --Verificar si el producto tiene contabilizacion
                --//
                DECLARE @tIdContab INT = NULL
                SELECT @tIdContab = IdContab from Inventarios where IdInventario = @IdInventario
                IF (@tIdContab IS NULL)
                BEGIN
                    RAISERROR('Doc %s : No se encontró una contabilización para el inventario : %s', 16, 1, @NumeroFacturaFull, @CodInventarioFull);
                    RETURN;
                END
                --//

                -- Insertar movimiento inventario
                INSERT INTO Encabezados_Mov 
				    (
					    IdEncab,
					    IdInventario,
					    IdBodega,
					    IdLote,
					    Cantidad,
					    CantidadFisica,
					    IdUnidad,
					    FactorCantidad,
					    FactorMovim,
					    ValorUnitario,
					    ValorUnitarioExt,
					    ValorIva,
						TipoImptoConsumo,
					    ValorImptoConsumo,
					    ImptoSaludableValor,
					    ImptoSaludableTipo,
					    TotalMov,
					    IdCliente,
					    IdMoneda,
					    Nota,
					    Vence,
					    IdCentroCosto,
					    Dcto,
					    FechaCreacion,
					    FechaUltModificacion
				    )
				    VALUES (
					    @IdEncab,
					    @IdInventario,     -- Ya era dinámico
					    @IdBodega,         -- Ahora dinámico basado en la ubicación
					    NULL,              -- IdLote
					    @Cantidad,         -- Ya era dinámico
					    NULL,              -- CantidadFisica
					    @IdUnidad,         -- Ya era dinámico
					    1,         -- Ya era dinámico
					    1,                 -- FactorMovim
					    @ValorUnitario,    -- Ya era dinámico
					    NULL,              -- ValorUnitarioExt
					    @ValorIva, -- Ya era dinámico
						1,
					    @ValorINC/@Cantidad,          -- ValorImptoConsumo
					    CASE WHEN @TipoImpuestoSaludable = 0 THEN @ValorICUI ELSE @ValorIBUA/@Cantidad END,
					    @TipoImpuestoSaludable,
					    NULL,       -- Ya era dinámico
					    @IdCliente,        -- Ya era dinámico
					    1,
					    'Factura XML: ' + @NumeroFacturaFull + ' - ' + @NomInventario,
					    @Vence,              -- Vence
					    NULL,              -- IdCentroCosto
					    @FactorDescuento,   -- Ya era dinámico
					    GETDATE(),
					    GETDATE()
				    );
                END -- Fin If TipoImplementacion = 0
                ELSE
                BEGIN
			        -- 3) Insertar equivalencia 
			        INSERT INTO DocElectronicos_Equivalencias (
				        IdTipoIdent, 
				        Identificacion, 
				        NombreCompleto,
				        NomInventario_Operador, 
				        NomInventario,
				        CodInventario_Operador, 
				        CodInventario,
				        ValorIva, 
                        ValorConsumo,
						TipoSaludable,
				        IdInventario, 
				        IdTipoInv, 
				        IdContab, 
				        CodInventario_Pref
			        )
			        SELECT
				        @IdTipoIdent, 
				        @NitProveedor, 
				        @NombreProveedor,
				        0, 
				        @NomInventario,
				        0, 
				        @CodInventario,
				        @ValorIva, 
                        @ValorINC,
                        CASE 
                            WHEN @ValorICUI > 0 THEN 0 -- Impuesto ICUI
                            WHEN @ValorIbua > 0 THEN 1 -- Impuesto IBUA
                            ELSE NULL
                        END,
				        NULL, 
				        NULL, 
				        NULL, 
				        NULL
			        WHERE NOT EXISTS (
				        SELECT 1
				        FROM DocElectronicos_Equivalencias e
				        WHERE ISNULL(LTRIM(RTRIM(e.Identificacion)),'') = ISNULL(LTRIM(RTRIM(@NitProveedor)),'')
				          AND ISNULL(LTRIM(RTRIM(e.CodInventario)),'') = ISNULL(LTRIM(RTRIM(@CodInventario)),'')
                          AND ISNULL(LTRIM(RTRIM(e.NomInventario)),'') = ISNULL(LTRIM(RTRIM(@NomInventario)),'')
			        );

                END; -- Fin Else TipoImplementacion = 1
                SET @Index = @Index + 1
            END

            IF @TipoImplementacion = 0
            BEGIN
                -- Retornamos el ID del encabezado creado
                SELECT @IdEncab as IdEncabezado;
                SET @IdEncabNew = @IdEncab;

                --Contabilizar Documento
                --//
                EXEC [dbo].[ContabilizarDoc] @IdEncab = @IdEncab, @Exito = @Exito OUTPUT, @InfoUsuario = N'0,--BASEDATOS--';
                --//

                COMMIT TRANSACTION;

                -- Si todo sale bien, establecemos el éxito
                --//
                SET @Exito = 1
                SET @MensajeError = FORMATMESSAGE(N'Documento ''%s'', procesado correctamente', @NumeroFacturaFull);
                RETURN
            END
            ELSE
            BEGIN
             -- Si todo sale bien, establecemos el éxito
                --//
                SET @Exito = 1
                SET @MensajeError = FORMATMESSAGE(N'Equivalencia del Documento ''%s'', copiada correctamente', @NumeroFacturaFull);
                RETURN
                --//
            END;
            --//
    END TRY
    BEGIN CATCH
        --si hay error hace rollback de la transacción
        IF XACT_STATE() <> 0    
            ROLLBACK TRANSACTION;

        -- Si hay error, enviamos el msg de error
        --//
        DECLARE @ErrorMsg NVARCHAR(4000) = ERROR_MESSAGE();
        SET @Exito = 0
        SET @MensajeError = @ErrorMsg;
        --//
    END CATCH;
END;
GO
PRINT N'Refreshing Procedure [dbo].[GenerarEquivalencia]...';


GO
EXECUTE sp_refreshsqlmodule N'[dbo].[GenerarEquivalencia]';


GO
	/*
	Plantilla de script posterior a la implementación							
	--------------------------------------------------------------------------------------
	 Este archivo contiene instrucciones de SQL que se anexarán al script de compilación.		
	 Use la sintaxis de SQLCMD para incluir un archivo en el script posterior a la implementación.			
	 Ejemplo:      :r .\miArchivo.sql								
	 Use la sintaxis de SQLCMD para hacer referencia a una variable en el script posterior a la implementación.		
	 Ejemplo:      :setvar TableName miTabla							
				   SELECT * FROM [$(TableName)]					
	--------------------------------------------------------------------------------------
	*/
GO

GO
PRINT N'Update complete.';


GO

--Actualizar datos de la version

IF NOT EXISTS (SELECT 1 FROM dbo.ZiurVersiones WHERE NumVersion = 983)
BEGIN
    INSERT INTO dbo.ZiurVersiones (IdVersion, NumVersion, Descripcion)
    VALUES (393, 983, 'Columnas TipoSaludable y valorConsumo en Equivalencias y generacion de documentos.');
END
GO


/* Liberar bloqueo exclusivo por base de datos */
DECLARE @__ZiurDbScriptLockResourceEnd NVARCHAR(200) = N'ZiurSoft:DbScriptLock:' + CAST(DB_ID() AS NVARCHAR(20));
EXEC sp_releaseapplock
    @Resource = @__ZiurDbScriptLockResourceEnd,
    @LockOwner = N'Session';
GO
