SET TERM ^ ;

CREATE OR ALTER trigger ttbnfs_b05iu for tbnfs
active before insert or update position 1
AS
DECLARE VARIABLE GEN_NUMERO_NF VARCHAR(20);
DECLARE VARIABLE ULTIMO_NF INTEGER;
DECLARE VARIABLE SERIE_NF INTEGER;
DECLARE VARIABLE NUMERO_NF INTEGER;
DECLARE VARIABLE NUMERO_NF_UTILIZADO INTEGER;
DECLARE VARIABLE NUMERO_NF_MAX INTEGER;
DECLARE VARIABLE NUMERO_NF_MIN INTEGER;
DECLARE VARIABLE CHECK_NF INTEGER;
DECLARE VARIABLE CHECK_ACTION INTEGER;
DECLARE VARIABLE FLAG_SEQUENCIA_NF INTEGER;
DECLARE VARIABLE CNPJ_ESTAB VARCHAR(20);
BEGIN

    IF(COALESCE(NEW.GC_WEB, 0) = 1) THEN
    BEGIN

        :CHECK_ACTION = 0;
        IF(INSERTING AND COALESCE(NEW.NUMERO_NOTAFISCAL, 0) = 0) THEN
        BEGIN
            :CHECK_ACTION = 1;
    
        END ELSE IF(UPDATING AND (
                    OLD.ESTABELECIMENTO_CODIGO <> NEW.ESTABELECIMENTO_CODIGO
                    OR OLD.SERIE <> NEW.SERIE
                    OR OLD.NATUREZA <> NEW.NATUREZA)) THEN
        BEGIN
            :CHECK_ACTION = 1;
        END
    
        IF(:CHECK_ACTION = 1) THEN
        BEGIN
            :GEN_NUMERO_NF = COALESCE((SELECT FIRST 1
                                    T."GENERATOR"
                                FROM TBCONFIGURACAO_NF T
                                WHERE T.ESTABELECIMENTO_ID = NEW.ESTABELECIMENTO_CODIGO
                                AND T.SERIE = CAST(NEW.SERIE AS INTEGER)), '');
    
            IF(:GEN_NUMERO_NF <> '') THEN
            BEGIN
                :NUMERO_NF_UTILIZADO = 0;
    
                :ULTIMO_NF = FN_EXECUTE_SQL('GEN_ID('||:GEN_NUMERO_NF||', 0)');
                :SERIE_NF  = NEW.SERIE;
    
                :FLAG_SEQUENCIA_NF  = CAST(FN_PARAMETRO('SISTEMA.SEQUENCIA_NF') AS INTEGER);
                :CNPJ_ESTAB         = COALESCE((SELECT FIRST 1 E.CNPJ FROM TBESTABELECIMENTO E WHERE E.CODIGO = NEW.ESTABELECIMENTO_CODIGO), '');
    
                IF(:FLAG_SEQUENCIA_NF = 1) THEN
                BEGIN
    
    
                    IF(:CNPJ_ESTAB <> '') THEN
                    BEGIN
                        /* DEFINIR NUMERO NF MINIMO COM BASE NO DIA ANTERIOR */
                        :NUMERO_NF_MIN = COALESCE((SELECT MAX(T.NUMERO_NOTAFISCAL)
                            FROM TBNFS T, TBESTABELECIMENTO V
                            WHERE CAST(T.SERIE AS INTEGER) = :SERIE_NF
                            AND T.NATUREZA = NEW.NATUREZA
                            AND T.DATA_EMISSAO BETWEEN CURRENT_DATE - 5 AND CURRENT_DATE - 1
                            AND T.ESTABELECIMENTO_CODIGO = V.CODIGO
                            AND V.CNPJ = :CNPJ_ESTAB
                            AND T.CHAVE_ACESSO IS NOT NULL
                            AND T.SITUACAO = 2), 0);
            
                        IF(:NUMERO_NF_MIN = 0) THEN
                        BEGIN

                            :NUMERO_NF_MIN = COALESCE((SELECT MIN(T.NUMERO_NOTAFISCAL)
                                FROM TBNFS T, TBESTABELECIMENTO V
                                WHERE CAST(T.SERIE AS INTEGER) = :SERIE_NF
                                AND T.NATUREZA = NEW.NATUREZA
                                AND T.DATA_EMISSAO = CURRENT_DATE
                                AND T.ESTABELECIMENTO_CODIGO = V.CODIGO
                                AND V.CNPJ = :CNPJ_ESTAB
                                AND T.CHAVE_ACESSO IS NOT NULL
                                AND T.SITUACAO = 2), 0);
                        END
            
                        /* DEFINIR NUMERO NF MAXIMO COM BASE NO DIA ATUAL */


                        :NUMERO_NF_MAX = COALESCE((SELECT MAX(T.NUMERO_NOTAFISCAL)
                                FROM TBNFS T, TBESTABELECIMENTO V
                                WHERE CAST(T.SERIE AS INTEGER) = :SERIE_NF
                                AND T.NATUREZA = NEW.NATUREZA
                                AND T.DATA_EMISSAO = CURRENT_DATE
                                AND T.ESTABELECIMENTO_CODIGO = V.CODIGO
                                AND V.CNPJ = :CNPJ_ESTAB
                                AND T.CHAVE_ACESSO IS NOT NULL
                                AND T.SITUACAO = 2), 0);
            
                        IF(:NUMERO_NF_MAX = 0) THEN
                        BEGIN
                            /* DEFINIR NUMERO MAXIMO COM BASE GENERATOR */
                            :NUMERO_NF_MAX = :ULTIMO_NF;
                        END
            
                        IF(:NUMERO_NF_MIN = 0) THEN
                        BEGIN
                            /* DEFINIR NUMERO MINIMO COM BASE GENERATOR */
                           :NUMERO_NF_MIN = :ULTIMO_NF;
                        END
            
                        /* RANGE PARA MINIMO/MAXIMO NF */
                        FOR SELECT
                            OUTPUTVALUE
                        FROM GENERATE_RANGE(:NUMERO_NF_MIN, :NUMERO_NF_MAX)
                        INTO :NUMERO_NF
                        DO BEGIN
                            /* CHECAGEM SE O NUMERO SEQUENCIAL EXISTE */
                            :CHECK_NF = COALESCE((SELECT FIRST 1
                                    T.ID
                            FROM TBPDV_CFE T, TBESTABELECIMENTO V
                            WHERE T.NUMERO_CFE = :NUMERO_NF
                            AND T.SITUACAO <> 1
                            AND T.TIPO = 1
                            AND T.CHAVE_ACESSO IS NOT NULL
                            AND T.ESTABELECIMENTO_ID = V.CODIGO
                            AND V.CNPJ = :CNPJ_ESTAB
                            AND CAST(T.SERIE AS INTEGER) = :SERIE_NF),0);
            
                            IF(COALESCE(:CHECK_NF, 0) = 0) THEN
                            BEGIN
                                /* CHECAGEM SE O NUMERO SEQUENCIAL EXISTE */
                                :CHECK_NF = COALESCE((SELECT FIRST 1
                                        T.CONTROLE
                                FROM TBNFS T, TBESTABELECIMENTO V
                                WHERE T.NUMERO_NOTAFISCAL = :CHECK_NF
                                AND T.SITUACAO <> 1
                                AND T.CHAVE_ACESSO IS NOT NULL
                                AND T.ESTABELECIMENTO_CODIGO = V.CODIGO
                                AND V.CNPJ = :CNPJ_ESTAB
                                AND CAST(T.SERIE AS INTEGER) = :SERIE_NF),0);
            
                                IF(COALESCE(:CHECK_NF, 0) = 0) THEN
                                BEGIN
                                    :NUMERO_NF_UTILIZADO = :NUMERO_NF;
                                    BREAK;
                                END
                                /* CASO NAO ENCONTRAR NENHUMA NUMERACAO, ESSE NUMERO E UM BURACO E O LACO E INTERROMPIDO */
            
                            END
            
                        END
                     END
                END
    
    
                IF(:NUMERO_NF_UTILIZADO > 0) THEN
                BEGIN
                    /* CASO ENCONTRAR ALGUM BURACO */
                    :CHECK_NF = COALESCE((SELECT FIRST 1
                            T.ID
                    FROM TBPDV_CFE T, TBESTABELECIMENTO V
                    WHERE T.NUMERO_CFE = :NUMERO_NF_UTILIZADO
                    AND T.TIPO = 1
                    AND T.ESTABELECIMENTO_ID = V.CODIGO
                    AND V.CNPJ = :CNPJ_ESTAB
                    AND CAST(T.SERIE AS INTEGER) = :SERIE_NF),0);
    
                    IF(COALESCE(:CHECK_NF, 0) = 0) THEN
                    BEGIN
                        /* CHECAGEM SE O NUMERO SEQUENCIAL EXISTE NA TBNFS */
                        :CHECK_NF = COALESCE((SELECT FIRST 1
                                T.CONTROLE
                        FROM TBNFS T, TBESTABELECIMENTO V
                        WHERE T.NUMERO_NOTAFISCAL = :NUMERO_NF_UTILIZADO
                        AND T.SITUACAO <> 1
                        AND T.CHAVE_ACESSO IS NOT NULL
                        AND T.ESTABELECIMENTO_CODIGO = V.CODIGO
                        AND V.CNPJ = :CNPJ_ESTAB
                        AND CAST(T.SERIE AS INTEGER) = :SERIE_NF),0);
    
                        IF(COALESCE(:CHECK_NF, 0) = 0) THEN
                        BEGIN
                            IF(:ULTIMO_NF = :NUMERO_NF_UTILIZADO) THEN
                            BEGIN
                                NEW.NUMERO_NOTAFISCAL = FN_EXECUTE_SQL('GEN_ID('||:GEN_NUMERO_NF||', 1)');
                            END ELSE
                            BEGIN
                                NEW.NUMERO_NOTAFISCAL = :NUMERO_NF_UTILIZADO;
                            END
                        END ELSE
                        BEGIN
                            NEW.NUMERO_NOTAFISCAL = FN_EXECUTE_SQL('GEN_ID('||:GEN_NUMERO_NF||', 1)');
                        END
                    END ELSE
                    BEGIN
                        NEW.NUMERO_NOTAFISCAL = FN_EXECUTE_SQL('GEN_ID('||:GEN_NUMERO_NF||', 1)');
                    END
    
                END ELSE
                BEGIN
                    /* SE NENHUM BURACO FOR ENCONTRADO, O GENERATOR E DISPARADO */
                    NEW.NUMERO_NOTAFISCAL = FN_EXECUTE_SQL('GEN_ID('||:GEN_NUMERO_NF||', 1)');
                END
    
            END
    
        END
    END
END
^

SET TERM ; ^

