CREATE OR ALTER PROCEDURE SP_NF_CONTABIL (
    ORIGEM VARCHAR(3),
    NF_ID INTEGER)
RETURNS (
    ESTABELECIMENTO_ID INTEGER,
    NUMERO_NOTAFISCAL INTEGER,
    NFE_ID INTEGER,
    NFS_ID INTEGER,
    DATA DATE,
    HISTORICO_CONTABIL VARCHAR(100),
    CONTA_DEBITO VARCHAR(50),
    CONTA_CREDITO VARCHAR(50),
    VALOR NUMERIC(18,2),
    VFALHAS VARCHAR(100))
AS
DECLARE VARIABLE CONTA_PARCELA VARCHAR(50);
DECLARE VARIABLE SALDO_PARCELA NUMERIC(18,2);
DECLARE VARIABLE VALOR_SALDO NUMERIC(18,2);
BEGIN

    CONTA_DEBITO = 'FALHA, PARCELAMENTO SEM CONTA CONTABIL';
    SALDO_PARCELA = 0;
    NFS_ID = 0;
    NFE_ID = 0;
    DELETE FROM TMP_SPI_NF_CONTABIL;

  IF (ORIGEM = 'NFS') THEN
      BEGIN

      FOR SELECT ESTABELECIMENTO_CODIGO,NUMERO_NOTAFISCAL,CONTROLE
            FROM TBNFS
           WHERE CONTROLE = :NF_ID
             AND (NATUREZA = 1 AND SITUACAO = 2 OR
                  NATUREZA = 2 AND SITUACAO = 1)
      INTO :ESTABELECIMENTO_ID,:NUMERO_NOTAFISCAL,:NFS_ID
      DO BEGIN

            FOR
            SELECT IIF(O.CONTA_DEBITO='0' AND O.TIPO_DEBITO = 'A',E.CONTA_CONTABIL,
                   IIF(O.CONTA_DEBITO='0' AND O.TIPO_DEBITO = 'P',E.CONTA_CONTABIL2,
                   IIF(CHAR_LENGTH(O.CONTA_DEBITO) > 1, O.CONTA_DEBITO, ''))) CONTA_DEBITO,
                   SUM(N.VALOR) VALOR
              FROM TBEMPRESA E, TBNFS_PARCELAMENTO N, TBCONTA_RECEBER_OPERACAO O
             WHERE E.CODIGO = N.EMPRESA_CODIGO
               AND N.CONTA_RECEBER_OPERACAO = O.CODIGO
               AND N.NFS_CONTROLE = :NFS_ID
             GROUP BY 1
             INTO :CONTA_PARCELA, :SALDO_PARCELA
             DO BEGIN
                INSERT INTO TMP_SPI_NF_CONTABIL (CONTA, VALOR) VALUES (:CONTA_PARCELA, :SALDO_PARCELA);
                END

            FOR
                SELECT NFS_ID,DATA,HISTORICO_CONTABIL,CONTA_DEBITO, CONTA_CREDITO, SUM(VALOR) VALOR
                FROM (
                SELECT I.NFS_CONTROLE AS NFS_ID,
                       I.DATA_EMISSAO AS DATA,
                       V.HISTORICO_CONTABIL||' NF.'||I.NUMERO_NOTAFISCAL HISTORICO_CONTABIL,
                       IIF(V.CONTA_DEBITO = '3' AND CHAR_LENGTH(PC.CONTA_CONTABIL) > 1,PC.CONTA_CONTABIL,
                       IIF(V.CONTA_DEBITO = '3' AND NOT CHAR_LENGTH(PC.CONTA_CONTABIL) > 1,'FALHA, PRODUTO SEM CONTA CONTABIL!',
                       IIF(V.CONTA_DEBITO = '2', 'PARCELAMENTO',
                       IIF(V.CONTA_DEBITO = '0' AND V.TIPO_DEBITO = 'A' AND CHAR_LENGTH(E.CONTA_CONTABIL) > 1,E.CONTA_CONTABIL,
                       IIF(V.CONTA_DEBITO = '0' AND V.TIPO_DEBITO = 'A' AND NOT CHAR_LENGTH(E.CONTA_CONTABIL) > 1,'FALHA, DESTINATARIO SEM CONTA CONTABIL(A)',
                       IIF(V.CONTA_DEBITO = '0' AND V.TIPO_DEBITO = 'P' AND CHAR_LENGTH(E.CONTA_CONTABIL2) > 1,E.CONTA_CONTABIL2,
                       IIF(V.CONTA_DEBITO = '0' AND V.TIPO_DEBITO = 'P' AND NOT CHAR_LENGTH(E.CONTA_CONTABIL2) > 1,'FALHA, DESTINATARIO SEM CONTA CONTABIL(P)',
                       IIF(CHAR_LENGTH(V.CONTA_DEBITO) > 1, V.CONTA_DEBITO, 'FALHA, OPERACAO SEM CONTA CONTABIL CONFIGURADA(D)')))))))) CONTA_DEBITO,
                
                       IIF(V.CONTA_CREDITO = '3' AND CHAR_LENGTH(PC.CONTA_CONTABIL) > 1,PC.CONTA_CONTABIL,
                       IIF(V.CONTA_CREDITO = '3' AND NOT CHAR_LENGTH(PC.CONTA_CONTABIL) > 1,'FALHA, PRODUTO SEM CONTA CONTABIL!',
                       IIF(V.CONTA_CREDITO = '2', 'PARCELAMENTO',
                       IIF(V.CONTA_CREDITO = '0' AND V.TIPO_CREDITO = 'A' AND CHAR_LENGTH(E.CONTA_CONTABIL) > 1,E.CONTA_CONTABIL,
                       IIF(V.CONTA_CREDITO = '0' AND V.TIPO_CREDITO = 'A' AND NOT CHAR_LENGTH(E.CONTA_CONTABIL) > 1,'FALHA, DESTINATARIO SEM CONTA CONTABIL(A)',
                       IIF(V.CONTA_CREDITO = '0' AND V.TIPO_CREDITO = 'P' AND CHAR_LENGTH(E.CONTA_CONTABIL2) > 1,E.CONTA_CONTABIL2,
                       IIF(V.CONTA_CREDITO = '0' AND V.TIPO_CREDITO = 'P' AND NOT CHAR_LENGTH(E.CONTA_CONTABIL2) > 1,'FALHA, DESTINATARIO SEM CONTA CONTABIL(P)',
                       IIF(CHAR_LENGTH(V.CONTA_CREDITO) > 1, V.CONTA_CREDITO, 'FALHA, OPERACAO SEM CONTA CONTABIL CONFIGURADA(D)')))))))) CONTA_CREDITO,
                
                       ABS(IIF(V.VALOR_ITEM = '+', I.VALOR_TOTAL,      IIF(V.VALOR_ITEM = '-', I.VALOR_TOTAL * (-1), 0))+
                       IIF(V.VALOR_ICMS = '+', I.VALOR_ICMS,       IIF(V.VALOR_ICMS = '-', I.VALOR_ICMS * (-1), 0))+
                       IIF(V.VALOR_ICMS_ST = '+', I.VALOR_ICMS_ST, IIF(V.VALOR_ICMS_ST = '-', I.VALOR_ICMS_ST * (-1), 0))+
                       IIF(V.VALOR_IPI = '+', I.VALOR_IPI,         IIF(V.VALOR_IPI = '-', I.VALOR_IPI * (-1), 0))+
                       IIF(V.VALOR_PIS = '+', I.VALOR_PIS,         IIF(V.VALOR_PIS = '-', I.VALOR_PIS * (-1), 0))+
                       IIF(V.VALOR_COFINS = '+', I.VALOR_COFINS,   IIF(V.VALOR_COFINS = '-', I.VALOR_COFINS * (-1), 0))+
                       IIF(V.VALOR_ACRESCIMOS = '+', I.VALOR_ACRESCIMO, IIF(V.VALOR_ACRESCIMOS = '-', I.VALOR_ACRESCIMO * (-1), 0))+
                       IIF(V.VALOR_DESCONTOS = '+', I.VALOR_DESCONTO,   IIF(V.VALOR_DESCONTOS = '-', I.VALOR_DESCONTO * (-1), 0))+
                       IIF(V.VALOR_FRETE = '+', I.VALOR_FRETE,     IIF(V.VALOR_FRETE = '-', I.VALOR_FRETE * (-1), 0))+
                       IIF(V.VALOR_SEGURO = '+', I.VALOR_SEGURO,   IIF(V.VALOR_SEGURO = '-', I.VALOR_SEGURO * (-1), 0))) VALOR
                
                  FROM TBOPERACAO_VINCULO_CONTABIL V,
                       TBEMPRESA E,
                       TBNFS_ITEM I
                       LEFT JOIN (SELECT POC.PRODUTO_ID, POC.OPERACAO_CODIGO, POC.CCUSTO, MAX(POC.CONTA_CONTABIL) CONTA_CONTABIL
                                    FROM TBPRODUTO_OPERACAO_CONTABIL POC GROUP BY 1,2,3) PC
                                      ON I.PRODUTO_CODIGO = PC.PRODUTO_ID AND I.OPERACAO_CODIGO = PC.OPERACAO_CODIGO AND PC.CCUSTO = I.CCUSTO
                
                 WHERE I.ESTABELECIMENTO_CODIGO = V.ESTABELECIMENTO_CODIGO
                   AND I.OPERACAO_CODIGO = V.OPERACAO_CODIGO
                   AND I.EMPRESA_CODIGO = E.CODIGO
                   AND I.NFS_CONTROLE = :NFS_ID

                ) GROUP BY NFS_ID, DATA, HISTORICO_CONTABIL, CONTA_DEBITO, CONTA_CREDITO
             INTO :NFS_ID,:DATA,:HISTORICO_CONTABIL,:CONTA_DEBITO,:CONTA_CREDITO,:VALOR
             DO
                BEGIN

                VFALHAS = '';
                IF (:CONTA_DEBITO LIKE 'FALHA%') THEN
                    BEGIN
                    VFALHAS = :CONTA_DEBITO;
                    CONTA_DEBITO = '';
                    END

                IF (:CONTA_CREDITO LIKE 'FALHA%') THEN
                    BEGIN
                    VFALHAS = :CONTA_CREDITO;
                    CONTA_DEBITO = '';
                    END

                IF (VALOR > 0) THEN
                    BEGIN
                    VALOR_SALDO = VALOR;

                    IF (CONTA_DEBITO = 'PARCELAMENTO') THEN
                        BEGIN
    
                          FOR
                          SELECT CONTA, VALOR
                            FROM TMP_SPI_NF_CONTABIL
                           WHERE VALOR > 0
                             AND CHAR_LENGTH(CONTA) > 0
                           ORDER BY VALOR DESC
                            INTO :CONTA_PARCELA, :SALDO_PARCELA
                              DO BEGIN

                                 IF (:VALOR_SALDO = :SALDO_PARCELA) THEN
                                     BEGIN
                                      VALOR = :VALOR_SALDO;
                                      CONTA_DEBITO = :CONTA_PARCELA;
                                      UPDATE TMP_SPI_NF_CONTABIL SET VALOR = 0 WHERE CONTA = :CONTA_PARCELA;
                                      SUSPEND;
                                      VALOR_SALDO = :VALOR_SALDO - :VALOR;
                                      BREAK;
                                     END ELSE
                                 IF (:VALOR_SALDO < :SALDO_PARCELA) THEN
                                     BEGIN
                                      VALOR = :VALOR_SALDO;
                                      CONTA_DEBITO = :CONTA_PARCELA;
                                      UPDATE TMP_SPI_NF_CONTABIL SET VALOR = VALOR - :VALOR WHERE CONTA = :CONTA_PARCELA;
                                      SUSPEND;
                                      VALOR_SALDO = :VALOR_SALDO - :VALOR;
                                      BREAK;
                                     END ELSE
                                 IF (:VALOR_SALDO > :SALDO_PARCELA) THEN
                                     BEGIN
                                      VALOR = :SALDO_PARCELA;
                                      CONTA_DEBITO = :CONTA_PARCELA;
                                      UPDATE TMP_SPI_NF_CONTABIL SET VALOR = 0 WHERE CONTA = :CONTA_PARCELA;
                                      SUSPEND;
                                      VALOR_SALDO = :VALOR_SALDO - :VALOR;
                                     END

                                 END

                        IF (VALOR_SALDO > 0) THEN
                            BEGIN
                               CONTA_DEBITO  = :CONTA_PARCELA;
                               VALOR         = :VALOR_SALDO;
                               VFALHAS = 'FALHA, ITENS COM VALORES A MAIOR';
                               SUSPEND;
                            END

                        END --IF (CONTA_DEBITO = 'PARCELAMENTO') THEN
                        ELSE
                        BEGIN
                        SUSPEND;
                        END
                    END --IF (VALOR > 0) THEN

                END
         END --FOR TBNFS
      END --IF (ORIGEM = 'NFS') THEN

  IF (ORIGEM = 'NFE') THEN
      BEGIN

      FOR SELECT ESTABELECIMENTO_CODIGO,NUMERO_NOTAFISCAL,CONTROLE
            FROM TBNFE
           WHERE CONTROLE = :NF_ID
             AND (NATUREZA = 1 AND SITUACAO = 2 OR
                  NATUREZA = 2 AND SITUACAO = 1)
      INTO :ESTABELECIMENTO_ID,:NUMERO_NOTAFISCAL,:NFE_ID
      DO BEGIN

            FOR
            SELECT IIF(O.CONTA_CREDITO='0' AND O.TIPO_CREDITO = 'A',E.CONTA_CONTABIL,
                   IIF(O.CONTA_CREDITO='0' AND O.TIPO_CREDITO = 'P',E.CONTA_CONTABIL2,
                   IIF(CHAR_LENGTH(O.CONTA_CREDITO) > 1, O.CONTA_CREDITO, ''))) CONTA_CREDITO,
                   SUM(N.VALOR) VALOR
              FROM TBEMPRESA E, TBNFE_PARCELAMENTO N, TBCONTA_PAGAR_OPERACAO O
             WHERE E.CODIGO = N.EMPRESA_CODIGO
               AND N.CONTA_PAGAR_OPERACAO = O.CODIGO
               AND N.NFE_CONTROLE = :NFE_ID
             GROUP BY 1
             INTO :CONTA_PARCELA, :SALDO_PARCELA
             DO BEGIN
                INSERT INTO TMP_SPI_NF_CONTABIL (CONTA, VALOR) VALUES (:CONTA_PARCELA, :SALDO_PARCELA);
                END

            FOR
                SELECT NFE_ID,DATA,HISTORICO_CONTABIL, CONTA_DEBITO, CONTA_CREDITO, SUM(VALOR) VALOR
                FROM (
                SELECT I.NFE_CONTROLE AS NFE_ID,
                       I.DATA_ENTRADA AS DATA,
                       V.HISTORICO_CONTABIL||' NF.'||I.NUMERO_NOTAFISCAL HISTORICO_CONTABIL,
                       IIF(V.CONTA_DEBITO = '3' AND CHAR_LENGTH(PC.CONTA_CONTABIL) > 1,PC.CONTA_CONTABIL,
                       IIF(V.CONTA_DEBITO = '3' AND NOT CHAR_LENGTH(PC.CONTA_CONTABIL) > 1,'FALHA, PRODUTO SEM CONTA CONTABIL!',
                       IIF(V.CONTA_DEBITO = '2', 'PARCELAMENTO',
                       IIF(V.CONTA_DEBITO = '0' AND V.TIPO_DEBITO = 'A' AND CHAR_LENGTH(E.CONTA_CONTABIL) > 1,E.CONTA_CONTABIL,
                       IIF(V.CONTA_DEBITO = '0' AND V.TIPO_DEBITO = 'A' AND NOT CHAR_LENGTH(E.CONTA_CONTABIL) > 1,'FALHA, EMITENTE SEM CONTA CONTABIL(A)',
                       IIF(V.CONTA_DEBITO = '0' AND V.TIPO_DEBITO = 'P' AND CHAR_LENGTH(E.CONTA_CONTABIL2) > 1,E.CONTA_CONTABIL2,
                       IIF(V.CONTA_DEBITO = '0' AND V.TIPO_DEBITO = 'P' AND NOT CHAR_LENGTH(E.CONTA_CONTABIL2) > 1,'FALHA, EMITENTE SEM CONTA CONTABIL(P)',
                       IIF(CHAR_LENGTH(V.CONTA_DEBITO) > 1, V.CONTA_DEBITO, 'FALHA, OPERACAO SEM CONTA CONTABIL CONFIGURADA(D)')))))))) CONTA_DEBITO,
                
                       IIF(V.CONTA_CREDITO = '3' AND CHAR_LENGTH(PC.CONTA_CONTABIL) > 1,PC.CONTA_CONTABIL,
                       IIF(V.CONTA_CREDITO = '3' AND NOT CHAR_LENGTH(PC.CONTA_CONTABIL) > 1,'FALHA, PRODUTO SEM CONTA CONTABIL!',
                       IIF(V.CONTA_CREDITO = '2', 'PARCELAMENTO',
                       IIF(V.CONTA_CREDITO = '0' AND V.TIPO_CREDITO = 'A' AND CHAR_LENGTH(E.CONTA_CONTABIL) > 1,E.CONTA_CONTABIL,
                       IIF(V.CONTA_CREDITO = '0' AND V.TIPO_CREDITO = 'A' AND NOT CHAR_LENGTH(E.CONTA_CONTABIL) > 1,'FALHA, EMITENTE SEM CONTA CONTABIL(A)',
                       IIF(V.CONTA_CREDITO = '0' AND V.TIPO_CREDITO = 'P' AND CHAR_LENGTH(E.CONTA_CONTABIL2) > 1,E.CONTA_CONTABIL2,
                       IIF(V.CONTA_CREDITO = '0' AND V.TIPO_CREDITO = 'P' AND NOT CHAR_LENGTH(E.CONTA_CONTABIL2) > 1,'FALHA, EMITENTE SEM CONTA CONTABIL(P)',
                       IIF(CHAR_LENGTH(V.CONTA_CREDITO) > 1, V.CONTA_CREDITO, 'FALHA, OPERACAO SEM CONTA CONTABIL CONFIGURADA(D)')))))))) CONTA_CREDITO,
                
                       ABS(IIF(V.VALOR_ITEM = '+', I.VALOR_TOTAL,      IIF(V.VALOR_ITEM = '-', I.VALOR_TOTAL * (-1), 0))+
                       IIF(V.VALOR_ICMS = '+', I.VALOR_ICMS,       IIF(V.VALOR_ICMS = '-', I.VALOR_ICMS * (-1), 0))+
                       IIF(V.VALOR_ICMS_ST = '+', I.VALOR_ICMS_ST, IIF(V.VALOR_ICMS_ST = '-', I.VALOR_ICMS_ST * (-1), 0))+
                       IIF(V.VALOR_IPI = '+', I.VALOR_IPI,         IIF(V.VALOR_IPI = '-', I.VALOR_IPI * (-1), 0))+
                       IIF(V.VALOR_PIS = '+', I.VALOR_PIS,         IIF(V.VALOR_PIS = '-', I.VALOR_PIS * (-1), 0))+
                       IIF(V.VALOR_COFINS = '+', I.VALOR_COFINS,   IIF(V.VALOR_COFINS = '-', I.VALOR_COFINS * (-1), 0))+
                       IIF(V.VALOR_ACRESCIMOS = '+', I.VALOR_ACRESCIMO, IIF(V.VALOR_ACRESCIMOS = '-', I.VALOR_ACRESCIMO * (-1), 0))+
                       IIF(V.VALOR_DESCONTOS = '+', I.VALOR_DESCONTO,   IIF(V.VALOR_DESCONTOS = '-', I.VALOR_DESCONTO * (-1), 0))+
                       IIF(V.VALOR_FRETE = '+', I.VALOR_FRETE,     IIF(V.VALOR_FRETE = '-', I.VALOR_FRETE * (-1), 0))+
                       IIF(V.VALOR_SEGURO = '+', I.VALOR_SEGURO,   IIF(V.VALOR_SEGURO = '-', I.VALOR_SEGURO * (-1), 0))) VALOR
                
                  FROM TBOPERACAO_VINCULO_CONTABIL V,
                       TBEMPRESA E,
                       TBNFE_ITEM I
                       LEFT JOIN (SELECT POC.PRODUTO_ID, POC.OPERACAO_CODIGO, POC.CCUSTO, MAX(POC.CONTA_CONTABIL) CONTA_CONTABIL
                                    FROM TBPRODUTO_OPERACAO_CONTABIL POC GROUP BY 1,2,3) PC
                                      ON I.PRODUTO_CODIGO = PC.PRODUTO_ID AND I.OPERACAO_CODIGO = PC.OPERACAO_CODIGO AND PC.CCUSTO = I.CCUSTO
                
                 WHERE I.ESTABELECIMENTO_CODIGO = V.ESTABELECIMENTO_CODIGO
                   AND I.OPERACAO_CODIGO = V.OPERACAO_CODIGO
                   AND I.EMPRESA_CODIGO = E.CODIGO
                   AND I.NFE_CONTROLE = :NFE_ID

                ) GROUP BY NFE_ID, DATA, HISTORICO_CONTABIL, CONTA_DEBITO, CONTA_CREDITO
             INTO :NFE_ID,:DATA,HISTORICO_CONTABIL,:CONTA_DEBITO,:CONTA_CREDITO,:VALOR
             DO
                BEGIN

                VFALHAS = '';
                IF (:CONTA_DEBITO LIKE 'FALHA%') THEN
                    BEGIN
                    VFALHAS = :CONTA_DEBITO;
                    CONTA_DEBITO = '';
                    END

                IF (:CONTA_CREDITO LIKE 'FALHA%') THEN
                    BEGIN
                    VFALHAS = :CONTA_CREDITO;
                    CONTA_DEBITO = '';
                    END

                IF (VALOR > 0) THEN
                    BEGIN
                    VALOR_SALDO = VALOR;

                    IF (CONTA_CREDITO = 'PARCELAMENTO') THEN
                        BEGIN

                          FOR
                          SELECT CONTA, VALOR
                            FROM TMP_SPI_NF_CONTABIL
                           WHERE VALOR > 0
                             AND CHAR_LENGTH(CONTA) > 0
                           ORDER BY VALOR DESC
                            INTO :CONTA_PARCELA, :SALDO_PARCELA
                              DO BEGIN

                                 IF (:VALOR_SALDO = :SALDO_PARCELA) THEN
                                     BEGIN
                                      VALOR = :VALOR_SALDO;
                                      CONTA_CREDITO = :CONTA_PARCELA;
                                      UPDATE TMP_SPI_NF_CONTABIL SET VALOR = 0 WHERE CONTA = :CONTA_PARCELA;
                                      SUSPEND;
                                      VALOR_SALDO = :VALOR_SALDO - :VALOR;
                                      BREAK;
                                     END ELSE
                                 IF (:VALOR_SALDO < :SALDO_PARCELA) THEN
                                     BEGIN
                                      VALOR = :VALOR_SALDO;
                                      CONTA_CREDITO = :CONTA_PARCELA;
                                      UPDATE TMP_SPI_NF_CONTABIL SET VALOR = VALOR - :VALOR WHERE CONTA = :CONTA_PARCELA;
                                      SUSPEND;
                                      VALOR_SALDO = :VALOR_SALDO - :VALOR;
                                      BREAK;
                                     END ELSE
                                 IF (:VALOR_SALDO > :SALDO_PARCELA) THEN
                                     BEGIN
                                      VALOR = :SALDO_PARCELA;
                                      CONTA_CREDITO = :CONTA_PARCELA;
                                      UPDATE TMP_SPI_NF_CONTABIL SET VALOR = 0 WHERE CONTA = :CONTA_PARCELA;
                                      SUSPEND;
                                      VALOR_SALDO = :VALOR_SALDO - :VALOR;
                                     END

                                 END

                        IF (VALOR_SALDO > 0) THEN
                            BEGIN
                               CONTA_CREDITO = :CONTA_PARCELA;
                               VALOR         = :VALOR_SALDO;
                               VFALHAS = 'FALHA, ITENS COM VALORES A MAIOR';
                               SUSPEND;
                            END

                        END ELSE
                        BEGIN
                        SUSPEND;
                        END
                    END
                END
         END
      END --IF (ORIGEM = 'NFE') THEN

   FOR
   SELECT CONTA, VALOR
     FROM TMP_SPI_NF_CONTABIL
    WHERE VALOR > 0
     INTO :CONTA_PARCELA, :SALDO_PARCELA
       DO BEGIN
           CONTA_CREDITO = :CONTA_PARCELA;
           VALOR         = :SALDO_PARCELA;
           VFALHAS = 'FALHA, PARCELAMENTOS COM VALORES A MAIOR';
           SUSPEND;
          END

END;