SET TERM ^ ;

CREATE OR ALTER trigger ttbpdv_cfe_b03i for tbpdv_cfe
active before insert or update position 3
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;
BEGIN
    :CHECK_ACTION = 0;
    IF(INSERTING AND (NEW.TIPO = 1 OR NEW.TIPO = 2) AND COALESCE(NEW.OFFLINE_ID, 0) = 0) THEN
    BEGIN
        :CHECK_ACTION = 1;

    END ELSE IF(UPDATING AND OLD.TIPO <> NEW.TIPO AND (NEW.TIPO = 1 OR NEW.TIPO = 2) AND COALESCE(NEW.OFFLINE_ID, 0) = 0) 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_ID
                            AND T.SERIE = NEW.SERIE), '');

        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);
            IF(:FLAG_SEQUENCIA_NF = 1) THEN
            BEGIN
                /* DEFINIR NUMERO NF MINIMO COM BASE NO DIA ANTERIOR */
                :NUMERO_NF_MIN = COALESCE((SELECT MAX(T.NUMERO_CFE)
                    FROM TBPDV_CFE T
                    WHERE CAST(T.SERIE AS INTEGER) = :SERIE_NF
                    AND T.TIPO = NEW.TIPO
                    AND T.DATA_EMISSAO BETWEEN CURRENT_DATE - 5 AND CURRENT_DATE - 1
                    AND T.ESTABELECIMENTO_ID = NEW.ESTABELECIMENTO_ID
                    AND T.CHAVE_ACESSO IS NOT NULL
                    AND T.SITUACAO = 2), 0);
    
                IF(:NUMERO_NF_MIN = 0) THEN
                BEGIN
                    /* DEFINIR NUMERO NF MINIMO COM BASE NO DIA ATUAL */
                    :NUMERO_NF_MIN = COALESCE((SELECT MIN(T.NUMERO_CFE)
                        FROM TBPDV_CFE T
                        WHERE CAST(T.SERIE AS INTEGER) = :SERIE_NF
                        AND T.TIPO = NEW.TIPO
                        AND T.DATA_EMISSAO = CURRENT_DATE
                        AND T.ESTABELECIMENTO_ID = NEW.ESTABELECIMENTO_ID
                        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_CFE)
                    FROM TBPDV_CFE T
                    WHERE  CAST(T.SERIE AS INTEGER) = :SERIE_NF
                    AND T.TIPO = NEW.TIPO
                    AND T.DATA_EMISSAO = CURRENT_DATE
                    AND T.ESTABELECIMENTO_ID = NEW.ESTABELECIMENTO_ID
                    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
                    WHERE T.NUMERO_CFE = :NUMERO_NF
                    AND T.SITUACAO = 2
                    AND T.TIPO = NEW.TIPO
                    AND T.CHAVE_ACESSO IS NOT NULL
                    AND T.ESTABELECIMENTO_ID = NEW.ESTABELECIMENTO_ID
                    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
                        WHERE T.NUMERO_NOTAFISCAL = :CHECK_NF
                        AND T.SITUACAO = 2
                        AND T.CHAVE_ACESSO IS NOT NULL
                        AND T.ESTABELECIMENTO_CODIGO = NEW.ESTABELECIMENTO_ID
                        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


            IF(:NUMERO_NF_UTILIZADO > 0) THEN
            BEGIN
                /* CASO ENCONTRAR ALGUM BURACO */
                :CHECK_NF = COALESCE((SELECT FIRST 1
                        T.ID
                FROM TBPDV_CFE T
                WHERE T.NUMERO_CFE = :NUMERO_NF_UTILIZADO
                AND T.TIPO = NEW.TIPO
                AND T.ESTABELECIMENTO_ID = NEW.ESTABELECIMENTO_ID
                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
                    WHERE T.NUMERO_NOTAFISCAL = :NUMERO_NF_UTILIZADO
                    AND T.SITUACAO = 2
                    AND T.CHAVE_ACESSO IS NOT NULL
                    AND T.ESTABELECIMENTO_CODIGO = NEW.ESTABELECIMENTO_ID
                    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_CFE = FN_EXECUTE_SQL('GEN_ID('||:GEN_NUMERO_NF||', 1)');
                        END ELSE
                        BEGIN
                            NEW.NUMERO_CFE = :NUMERO_NF_UTILIZADO;
                        END
                    END ELSE
                    BEGIN
                        NEW.NUMERO_CFE = FN_EXECUTE_SQL('GEN_ID('||:GEN_NUMERO_NF||', 1)');
                    END
                END ELSE
                BEGIN
                    NEW.NUMERO_CFE = FN_EXECUTE_SQL('GEN_ID('||:GEN_NUMERO_NF||', 1)');
                END

            END ELSE
            BEGIN
                /* SE NENHUM BURACO FOR ENCONTRADO, O GENERATOR E DISPARADO */
                NEW.NUMERO_CFE = FN_EXECUTE_SQL('GEN_ID('||:GEN_NUMERO_NF||', 1)');
            END

        END

    END
END
^

SET TERM ; ^

