-- +goose Up
-- +goose StatementBegin
CREATE OR REPLACE PROCEDURE VITRUVIO.PRC_FLASH_CARGA_DADOS_VENDA (
    p_data_inicial IN DATE,
    p_data_final   IN DATE,
    p_empresa      IN NUMBER,
    p_divisao      IN VARCHAR2 DEFAULT NULL,
    p_cgos         IN VARCHAR2 DEFAULT NULL
) AS
    v_id_empresa   NUMBER;
    v_id_cat1      NUMBER;
    v_id_cat2      NUMBER;
    v_id_cat3      NUMBER;
    v_id_cat4      NUMBER;
    v_id_cat5      NUMBER;
    v_id_produto   NUMBER;
    v_contador     NUMBER := 0;

    FUNCTION FN_GET_OR_CREATE_NODO (
        p_id_nodo_pai    IN NUMBER,
        p_tipo_nodo      IN VARCHAR2,
        p_codigo         IN VARCHAR2,
        p_nome           IN VARCHAR2,
        p_nivel          IN NUMBER,
        p_cod_empresa    IN NUMBER DEFAULT NULL,
        p_cod_produto    IN NUMBER DEFAULT NULL,
        p_seqprodutobase IN NUMBER DEFAULT NULL
    ) RETURN NUMBER
    IS
        v_id_nodo NUMBER;
    BEGIN
        SELECT n.id_nodo
          INTO v_id_nodo
          FROM TB_FLASH_NODO n
         WHERE (
                  n.id_nodo_pai = p_id_nodo_pai
               OR (n.id_nodo_pai IS NULL AND p_id_nodo_pai IS NULL)
               )
           AND n.tipo_nodo = p_tipo_nodo
           AND n.codigo = p_codigo
           AND (
                  p_tipo_nodo <> 'PRODUTO'
               OR (
                       n.cod_empresa = p_cod_empresa
                    OR (n.cod_empresa IS NULL AND p_cod_empresa IS NULL)
                  )
               );

        UPDATE TB_FLASH_NODO n
           SET n.nome             = p_nome,
               n.cod_empresa      = p_cod_empresa,
               n.cod_produto      = p_cod_produto,
               n.seqprodutobase   = p_seqprodutobase,
               n.data_atualizacao = SYSDATE
         WHERE n.id_nodo = v_id_nodo
           AND (
                  NVL(n.nome, '#') <> NVL(p_nome, '#')
               OR NVL(n.cod_empresa, -1) <> NVL(p_cod_empresa, -1)
               OR NVL(n.cod_produto, -1) <> NVL(p_cod_produto, -1)
               OR NVL(n.seqprodutobase, -1) <> NVL(p_seqprodutobase, -1)
               );

        RETURN v_id_nodo;

    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            v_id_nodo := SEQ_TB_FLASH_NODO.NEXTVAL;

            INSERT INTO TB_FLASH_NODO (
                id_nodo, id_nodo_pai, tipo_nodo, codigo, nome, nivel,
                ordem_exibicao, ativo, cod_empresa, cod_produto, seqprodutobase,
                data_cadastro, data_atualizacao
            ) VALUES (
                v_id_nodo, p_id_nodo_pai, p_tipo_nodo, p_codigo, p_nome, p_nivel,
                NULL, 'S', p_cod_empresa, p_cod_produto, p_seqprodutobase,
                SYSDATE, NULL
            );

            RETURN v_id_nodo;
    END;

BEGIN
    DELETE FROM TB_FLASH_FATO_VENDA
     WHERE data_referencia BETWEEN p_data_inicial AND p_data_final
       AND cod_empresa = p_empresa;

    FOR r IN (
        WITH pg AS (
            SELECT MAX(indutilicmstaresugprabc) AS indutilicmstaresugprabc
              FROM consinco.max_paramgeral
        ),
        cat AS (
            SELECT dc.nrodivisao,
                   dc.seqfamilia,
                   MAX(CASE WHEN cc.nivelhierarquia = 1 THEN dc.seqcategoria END) AS codcatn1,
                   MAX(CASE WHEN cc.nivelhierarquia = 1 THEN cc.categoria END) AS nomecatn1,
                   MAX(CASE WHEN cc.nivelhierarquia = 2 THEN dc.seqcategoria END) AS codcatn2,
                   MAX(CASE WHEN cc.nivelhierarquia = 2 THEN cc.categoria END) AS nomecatn2,
                   MAX(CASE WHEN cc.nivelhierarquia = 3 THEN dc.seqcategoria END) AS codcatn3,
                   MAX(CASE WHEN cc.nivelhierarquia = 3 THEN cc.categoria END) AS nomecatn3,
                   MAX(CASE WHEN cc.nivelhierarquia = 4 THEN dc.seqcategoria END) AS codcatn4,
                   MAX(CASE WHEN cc.nivelhierarquia = 4 THEN cc.categoria END) AS nomecatn4,
                   MAX(CASE WHEN cc.nivelhierarquia = 5 THEN dc.seqcategoria END) AS codcatn5,
                   MAX(CASE WHEN cc.nivelhierarquia = 5 THEN cc.categoria END) AS nomecatn5
              FROM consinco.map_famdivcateg dc
              JOIN consinco.map_categoria cc
                ON cc.seqcategoria = dc.seqcategoria
               AND cc.nrodivisao = dc.nrodivisao
               AND cc.statuscategor = 'A'
               AND cc.tipcategoria = 'M'
               AND cc.nivelhierarquia BETWEEN 1 AND 5
             WHERE dc.status = 'A'
             GROUP BY dc.nrodivisao, dc.seqfamilia
        )
        SELECT dv.nrodivisao,
               seg1.nrosegmento,
               seg1.descsegmento,
               e.nroempresa AS empresa,
               e.nomereduzido AS nomeempresa,
               a.seqproduto AS cod_produto,
               a.seqprodutobase,
               a.desccompleta AS descricao,
               z.dtaentradasaida AS data_referencia,
               TO_NUMBER(TO_CHAR(z.dtaentradasaida, 'D')) AS dia_semana,
               TO_NUMBER(TO_CHAR(z.dtaentradasaida, 'DD')) AS dia,
               TO_NUMBER(TO_CHAR(z.dtaentradasaida, 'MM')) AS mes,
               TO_NUMBER(TO_CHAR(z.dtaentradasaida, 'YYYY')) AS ano,
               0 AS nro_tickets,
               SUM(
                   DECODE(y.qtdvda, 0, 0,
                       (
                           y.vlrimpostovda
                           + NVL(
                               DECODE(pg.indutilicmstaresugprabc,
                                   'S', COALESCE(y.vlricmsvdasolicit, y.vlricmsvda),
                                   y.vlricmsvda
                               ), 0
                             )
                           + NVL(y.vlrpisvda, 0)
                           + NVL(y.vlrcofinsvda, 0)
                       ) / y.qtdvda
                   ) * z.qtdvda
               )
               +
               SUM(
                   DECODE(NVL(y.qtddevol, 0), 0, 0,
                       (
                           NVL(y.vlrimpostodevol, 0)
                           + NVL(
                               DECODE(pg.indutilicmstaresugprabc,
                                   'S',
                                   DECODE(y.qtdvda, 0, 0,
                                       COALESCE(
                                           (y.vlricmsvdasolicit / y.qtdvda) * y.qtddevol,
                                           y.vlricmsdevol
                                       )
                                   ),
                                   ((z.vlricmsvda / GREATEST(z.qtdvda, 1)) * NVL(z.qtddevol, 0))
                               ), 0
                             )
                           + NVL(y.vlrpisdevol, 0)
                           + NVL(y.vlrcofinsdevol, 0)
                       ) / y.qtddevol
                   ) * (0 - NVL(z.qtddevol, 0))
               ) AS vlr_imp_venda,
               SUM((z.qtdvda - NVL(z.qtddevol, 0)) / k.qtdembalagem) AS qtde_venda,
               SUM(z.vlrtotalvda) - SUM(NVL(z.vlrtotaldevol, 0)) AS vlr_venda,
               0 AS vl_ticket_medio,
               a.propqtdprodutobase,
               cat.codcatn1,
               cat.nomecatn1,
               cat.codcatn2,
               cat.nomecatn2,
               cat.codcatn3,
               cat.nomecatn3,
               cat.codcatn4,
               cat.nomecatn4,
               cat.codcatn5,
               cat.nomecatn5
          FROM consinco.mrl_custodia z
          JOIN consinco.max_empresa e
            ON e.nroempresa = z.nroempresa
          JOIN consinco.mrl_custodia y
            ON y.seqproduto = z.seqproduto
           AND y.dtaentradasaida = z.dtaentradasaida
           AND y.nroempresa = z.nroempresa
          JOIN consinco.map_famdivisao d
            ON d.seqfamilia = z.seqfamilia
           AND d.nrodivisao = e.nrodivisao
          JOIN consinco.max_divisao dv
            ON dv.nrodivisao = d.nrodivisao
          JOIN consinco.mad_segmento seg1
            ON seg1.nrodivisao = d.nrodivisao
          JOIN consinco.mad_famsegmento h
            ON h.seqfamilia = z.seqfamilia
           AND h.nrosegmento = e.nrosegmentoprinc
           AND h.nrosegmento = seg1.nrosegmento
          JOIN consinco.map_famembalagem k
            ON k.seqfamilia = h.seqfamilia
           AND k.qtdembalagem = 1
          JOIN consinco.map_produto a
            ON a.seqproduto = z.seqproduto
           AND a.seqfamilia = d.seqfamilia
          JOIN cat
            ON cat.nrodivisao = d.nrodivisao
           AND cat.seqfamilia = d.seqfamilia
         CROSS JOIN pg
         WHERE z.dtaentradasaida BETWEEN p_data_inicial AND p_data_final
           AND z.nroempresa = p_empresa
           AND (p_divisao IS NULL OR INSTR(',' || p_divisao || ',', ',' || TO_CHAR(d.nrodivisao) || ',') > 0)
           AND (z.vlrtotalvda > 0 OR z.vlrtotaldevol > 0)
           AND EXISTS (
               SELECT 1
                 FROM consinco.maxv_abcdistribbase b
                WHERE b.seqproduto = z.seqproduto
                  AND b.nroempresa = z.nroempresa
                  AND b.dtavda = z.dtaentradasaida
                  AND (p_cgos IS NULL OR INSTR(',' || p_cgos || ',', ',' || TO_CHAR(b.codgeraloper) || ',') > 0)
           )
         GROUP BY dv.nrodivisao,
                  seg1.nrosegmento,
                  seg1.descsegmento,
                  e.nroempresa,
                  e.nomereduzido,
                  a.seqproduto,
                  a.seqprodutobase,
                  a.desccompleta,
                  z.dtaentradasaida,
                  a.propqtdprodutobase,
                  cat.codcatn1,
                  cat.nomecatn1,
                  cat.codcatn2,
                  cat.nomecatn2,
                  cat.codcatn3,
                  cat.nomecatn3,
                  cat.codcatn4,
                  cat.nomecatn4,
                  cat.codcatn5,
                  cat.nomecatn5
    ) LOOP

        v_id_empresa := FN_GET_OR_CREATE_NODO(NULL, 'EMPRESA', TO_CHAR(r.empresa), r.nomeempresa, 1, r.empresa);

        IF r.codcatn1 IS NOT NULL THEN
            v_id_cat1 := FN_GET_OR_CREATE_NODO(v_id_empresa, 'CATEGORIA', TO_CHAR(r.codcatn1), r.nomecatn1, 2, r.empresa);
        ELSE v_id_cat1 := v_id_empresa; END IF;

        IF r.codcatn2 IS NOT NULL THEN
            v_id_cat2 := FN_GET_OR_CREATE_NODO(v_id_cat1, 'CATEGORIA', TO_CHAR(r.codcatn2), r.nomecatn2, 3, r.empresa);
        ELSE v_id_cat2 := v_id_cat1; END IF;

        IF r.codcatn3 IS NOT NULL THEN
            v_id_cat3 := FN_GET_OR_CREATE_NODO(v_id_cat2, 'CATEGORIA', TO_CHAR(r.codcatn3), r.nomecatn3, 4, r.empresa);
        ELSE v_id_cat3 := v_id_cat2; END IF;

        IF r.codcatn4 IS NOT NULL THEN
            v_id_cat4 := FN_GET_OR_CREATE_NODO(v_id_cat3, 'CATEGORIA', TO_CHAR(r.codcatn4), r.nomecatn4, 5, r.empresa);
        ELSE v_id_cat4 := v_id_cat3; END IF;

        IF r.codcatn5 IS NOT NULL THEN
            v_id_cat5 := FN_GET_OR_CREATE_NODO(v_id_cat4, 'CATEGORIA', TO_CHAR(r.codcatn5), r.nomecatn5, 6, r.empresa);
        ELSE v_id_cat5 := v_id_cat4; END IF;

        v_id_produto := FN_GET_OR_CREATE_NODO(v_id_cat5, 'PRODUTO', TO_CHAR(r.cod_produto), r.descricao, 7, r.empresa, r.cod_produto, r.seqprodutobase);

        INSERT INTO TB_FLASH_FATO_VENDA (
            id_fato, data_referencia, ano_referencia, mes_referencia, dia_referencia, dia_semana,
            id_nodo, id_nodo_empresa, cod_empresa, nome_empresa, cod_produto, descricao_produto,
            seqprodutobase, nrodivisao, nrosegmento, nro_tickets, vlr_imp_venda, qtde_venda,
            vlr_venda, vl_ticket_medio, propqtdprodutobase, data_cadastro, nome_segmento
        ) VALUES (
            SEQ_TB_FLASH_FATO_VENDA.NEXTVAL,
            r.data_referencia, r.ano, r.mes, r.dia, r.dia_semana,
            v_id_produto, v_id_empresa, r.empresa, r.nomeempresa, r.cod_produto, r.descricao,
            r.seqprodutobase, r.nrodivisao, r.nrosegmento, r.nro_tickets, r.vlr_imp_venda,
            r.qtde_venda, r.vlr_venda, r.vl_ticket_medio, r.propqtdprodutobase, SYSDATE, r.descsegmento
        );

    END LOOP;

    COMMIT;
END;
-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
CREATE OR REPLACE PROCEDURE VITRUVIO.PRC_FLASH_CARGA_DADOS_VENDA (
    p_data_inicial IN DATE,
    p_data_final   IN DATE,
    p_empresa      IN NUMBER
) AS
    v_id_empresa   NUMBER;
    v_id_cat1      NUMBER;
    v_id_cat2      NUMBER;
    v_id_cat3      NUMBER;
    v_id_cat4      NUMBER;
    v_id_cat5      NUMBER;
    v_id_produto   NUMBER;
    v_contador     NUMBER := 0;

    FUNCTION FN_GET_OR_CREATE_NODO (
        p_id_nodo_pai    IN NUMBER,
        p_tipo_nodo      IN VARCHAR2,
        p_codigo         IN VARCHAR2,
        p_nome           IN VARCHAR2,
        p_nivel          IN NUMBER,
        p_cod_empresa    IN NUMBER DEFAULT NULL,
        p_cod_produto    IN NUMBER DEFAULT NULL,
        p_seqprodutobase IN NUMBER DEFAULT NULL
    ) RETURN NUMBER
    IS
        v_id_nodo NUMBER;
    BEGIN
        SELECT n.id_nodo
          INTO v_id_nodo
          FROM TB_FLASH_NODO n
         WHERE (
                  n.id_nodo_pai = p_id_nodo_pai
               OR (n.id_nodo_pai IS NULL AND p_id_nodo_pai IS NULL)
               )
           AND n.tipo_nodo = p_tipo_nodo
           AND n.codigo = p_codigo
           AND (
                  p_tipo_nodo <> 'PRODUTO'
               OR (
                       n.cod_empresa = p_cod_empresa
                    OR (n.cod_empresa IS NULL AND p_cod_empresa IS NULL)
                  )
               );

        UPDATE TB_FLASH_NODO n
           SET n.nome             = p_nome,
               n.cod_empresa      = p_cod_empresa,
               n.cod_produto      = p_cod_produto,
               n.seqprodutobase   = p_seqprodutobase,
               n.data_atualizacao = SYSDATE
         WHERE n.id_nodo = v_id_nodo
           AND (
                  NVL(n.nome, '#') <> NVL(p_nome, '#')
               OR NVL(n.cod_empresa, -1) <> NVL(p_cod_empresa, -1)
               OR NVL(n.cod_produto, -1) <> NVL(p_cod_produto, -1)
               OR NVL(n.seqprodutobase, -1) <> NVL(p_seqprodutobase, -1)
               );

        RETURN v_id_nodo;

    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            v_id_nodo := SEQ_TB_FLASH_NODO.NEXTVAL;

            INSERT INTO TB_FLASH_NODO (
                id_nodo, id_nodo_pai, tipo_nodo, codigo, nome, nivel,
                ordem_exibicao, ativo, cod_empresa, cod_produto, seqprodutobase,
                data_cadastro, data_atualizacao
            ) VALUES (
                v_id_nodo, p_id_nodo_pai, p_tipo_nodo, p_codigo, p_nome, p_nivel,
                NULL, 'S', p_cod_empresa, p_cod_produto, p_seqprodutobase,
                SYSDATE, NULL
            );

            RETURN v_id_nodo;
    END;

BEGIN
    DELETE FROM TB_FLASH_FATO_VENDA
     WHERE data_referencia BETWEEN p_data_inicial AND p_data_final
       AND cod_empresa = p_empresa;

    FOR r IN (
        SELECT dv.nrodivisao,
               seg1.nrosegmento,
               e.nroempresa AS empresa,
               e.nomereduzido AS nomeempresa,
               a.seqproduto AS cod_produto,
               a.seqprodutobase,
               a.desccompleta AS descricao,
               z.dtaentradasaida AS data_referencia,
               TO_NUMBER(TO_CHAR(z.dtaentradasaida,'D')) AS dia_semana,
               TO_NUMBER(TO_CHAR(z.dtaentradasaida,'DD')) AS dia,
               TO_NUMBER(TO_CHAR(z.dtaentradasaida,'MM')) AS mes,
               TO_NUMBER(TO_CHAR(z.dtaentradasaida,'YYYY')) AS ano,
               0 AS nro_tickets,
               SUM(DECODE(y.qtdvda, 0, 0,
                   ((y.vlrimpostovda +
                     NVL(DECODE(pg.indutilicmstaresugprabc,
                         'S', COALESCE(y.vlricmsvdasolicit, y.vlricmsvda),
                         y.vlricmsvda), 0)
                     + NVL(y.vlrpisvda, 0)
                     + NVL(y.vlrcofinsvda, 0)) / y.qtdvda)) * z.qtdvda)
               +
               SUM(DECODE(NVL(y.qtddevol, 0), 0, 0,
                   ((NVL(y.vlrimpostodevol, 0) +
                     NVL(DECODE(pg.indutilicmstaresugprabc,
                         'S',
                         DECODE(y.qtdvda, 0, 0,
                             COALESCE((y.vlricmsvdasolicit / y.qtdvda) * y.qtddevol,
                                      y.vlricmsdevol)),
                         ((z.vlricmsvda / GREATEST(z.qtdvda, 1)) * NVL(z.qtddevol, 0))),
                         0)
                     + NVL(y.vlrpisdevol, 0)
                     + NVL(y.vlrcofinsdevol, 0)) / y.qtddevol)) * (0 - NVL(z.qtddevol, 0))
               ) AS vlr_imp_venda,
               SUM((z.qtdvda - NVL(z.qtddevol, 0)) / k.qtdembalagem) AS qtde_venda,
               (SUM(z.vlrtotalvda) - SUM(NVL(z.vlrtotaldevol, 0))) AS vlr_venda,
               0 AS vl_ticket_medio,
               a.propqtdprodutobase,
               ( SELECT dc.seqcategoria FROM map_famdivcateg dc JOIN map_categoria cc ON cc.seqcategoria = dc.seqcategoria AND cc.statuscategor = 'A' AND cc.nivelhierarquia = 1 AND cc.nrodivisao = dc.nrodivisao AND cc.tipcategoria = 'M' WHERE dc.nrodivisao = e.nrodivisao AND dc.status = 'A' AND dc.seqfamilia = a.seqfamilia ) AS codcatn1,
               ( SELECT cc.categoria FROM map_famdivcateg dc JOIN map_categoria cc ON cc.seqcategoria = dc.seqcategoria AND cc.statuscategor = 'A' AND cc.nivelhierarquia = 1 AND cc.nrodivisao = dc.nrodivisao AND cc.tipcategoria = 'M' WHERE dc.nrodivisao = e.nrodivisao AND dc.status = 'A' AND dc.seqfamilia = a.seqfamilia ) AS nomecatn1,
               ( SELECT dc.seqcategoria FROM map_famdivcateg dc JOIN map_categoria cc ON cc.seqcategoria = dc.seqcategoria AND cc.statuscategor = 'A' AND cc.nivelhierarquia = 2 AND cc.nrodivisao = dc.nrodivisao AND cc.tipcategoria = 'M' WHERE dc.nrodivisao = e.nrodivisao AND dc.status = 'A' AND dc.seqfamilia = a.seqfamilia ) AS codcatn2,
               ( SELECT cc.categoria FROM map_famdivcateg dc JOIN map_categoria cc ON cc.seqcategoria = dc.seqcategoria AND cc.statuscategor = 'A' AND cc.nivelhierarquia = 2 AND cc.nrodivisao = dc.nrodivisao AND cc.tipcategoria = 'M' WHERE dc.nrodivisao = e.nrodivisao AND dc.status = 'A' AND dc.seqfamilia = a.seqfamilia ) AS nomecatn2,
               ( SELECT dc.seqcategoria FROM map_famdivcateg dc JOIN map_categoria cc ON cc.seqcategoria = dc.seqcategoria AND cc.statuscategor = 'A' AND cc.nivelhierarquia = 3 AND cc.nrodivisao = dc.nrodivisao AND cc.tipcategoria = 'M' WHERE dc.nrodivisao = e.nrodivisao AND dc.status = 'A' AND dc.seqfamilia = a.seqfamilia ) AS codcatn3,
               ( SELECT cc.categoria FROM map_famdivcateg dc JOIN map_categoria cc ON cc.seqcategoria = dc.seqcategoria AND cc.statuscategor = 'A' AND cc.nivelhierarquia = 3 AND cc.nrodivisao = dc.nrodivisao AND cc.tipcategoria = 'M' WHERE dc.nrodivisao = e.nrodivisao AND dc.status = 'A' AND dc.seqfamilia = a.seqfamilia ) AS nomecatn3,
               ( SELECT dc.seqcategoria FROM map_famdivcateg dc JOIN map_categoria cc ON cc.seqcategoria = dc.seqcategoria AND cc.statuscategor = 'A' AND cc.nivelhierarquia = 4 AND cc.nrodivisao = dc.nrodivisao AND cc.tipcategoria = 'M' WHERE dc.nrodivisao = e.nrodivisao AND dc.status = 'A' AND dc.seqfamilia = a.seqfamilia ) AS codcatn4,
               ( SELECT cc.categoria FROM map_famdivcateg dc JOIN map_categoria cc ON cc.seqcategoria = dc.seqcategoria AND cc.statuscategor = 'A' AND cc.nivelhierarquia = 4 AND cc.nrodivisao = dc.nrodivisao AND cc.tipcategoria = 'M' WHERE dc.nrodivisao = e.nrodivisao AND dc.status = 'A' AND dc.seqfamilia = a.seqfamilia ) AS nomecatn4,
               ( SELECT dc.seqcategoria FROM map_famdivcateg dc JOIN map_categoria cc ON cc.seqcategoria = dc.seqcategoria AND cc.statuscategor = 'A' AND cc.nivelhierarquia = 5 AND cc.nrodivisao = dc.nrodivisao AND cc.tipcategoria = 'M' WHERE dc.nrodivisao = e.nrodivisao AND dc.status = 'A' AND dc.seqfamilia = a.seqfamilia ) AS codcatn5,
               ( SELECT cc.categoria FROM map_famdivcateg dc JOIN map_categoria cc ON cc.seqcategoria = dc.seqcategoria AND cc.statuscategor = 'A' AND cc.nivelhierarquia = 5 AND cc.nrodivisao = dc.nrodivisao AND cc.tipcategoria = 'M' WHERE dc.nrodivisao = e.nrodivisao AND dc.status = 'A' AND dc.seqfamilia = a.seqfamilia ) AS nomecatn5
          FROM maxv_categoria g, map_famdivcateg u, map_produto a, map_famdivisao d,
               map_famembalagem k, mad_segmento seg1, mrl_produtoempresa c,
               mad_famsegmento h, max_empresa e, mrl_custodia y, mrl_custodia z,
               mrlv_descontoregra re, max_divisao dv, max_paramgeral pg
         WHERE z.dtaentradasaida BETWEEN p_data_inicial AND p_data_final
           AND z.nroempresa = p_empresa
           AND e.nroempresa = z.nroempresa
           AND e.nrodivisao = d.nrodivisao
           AND z.seqproduto = c.seqproduto
           AND e.nroempresa = c.nroempresa
           AND y.seqproduto = z.seqproduto
           AND y.dtaentradasaida = z.dtaentradasaida
           AND y.nroempresa = z.nroempresa
           AND (z.vlrtotalvda > 0 OR z.vlrtotaldevol > 0)
           AND seg1.nrodivisao = d.nrodivisao
           AND h.seqfamilia = z.seqfamilia
           AND h.nrosegmento = e.nrosegmentoprinc
           AND h.nrosegmento = seg1.nrosegmento
           AND d.seqfamilia = z.seqfamilia
           AND d.nrodivisao IN (1)
           AND dv.nrodivisao = d.nrodivisao
           AND k.seqfamilia = h.seqfamilia
           AND k.qtdembalagem = 1
           AND z.seqproduto = re.seqproduto(+)
           AND z.dtaentradasaida = re.datafaturamento(+)
           AND z.nroempresa = re.nroempresa(+)
           AND g.nrodivisao = u.nrodivisao
           AND g.nivelhierarquia = 1
           AND g.tipcategoria = 'M'
           AND g.statuscategor != 'I'
           AND u.seqfamilia = d.seqfamilia
           AND u.nrodivisao = d.nrodivisao
           AND u.seqcategoria = g.seqcategoria
           AND u.status = 'A'
           AND a.seqproduto = z.seqproduto
           AND a.seqfamilia = d.seqfamilia
         GROUP BY dv.nrodivisao, seg1.nrosegmento, e.nroempresa, e.nomereduzido,
                  a.seqproduto, a.seqprodutobase, a.desccompleta, z.dtaentradasaida,
                  a.propqtdprodutobase, e.nrodivisao, a.seqfamilia
    ) LOOP

        v_id_empresa := FN_GET_OR_CREATE_NODO(NULL, 'EMPRESA', TO_CHAR(r.empresa), r.nomeempresa, 1, r.empresa);

        IF r.codcatn1 IS NOT NULL THEN
            v_id_cat1 := FN_GET_OR_CREATE_NODO(v_id_empresa, 'CATEGORIA', TO_CHAR(r.codcatn1), r.nomecatn1, 2, r.empresa);
        ELSE v_id_cat1 := v_id_empresa; END IF;

        IF r.codcatn2 IS NOT NULL THEN
            v_id_cat2 := FN_GET_OR_CREATE_NODO(v_id_cat1, 'CATEGORIA', TO_CHAR(r.codcatn2), r.nomecatn2, 3, r.empresa);
        ELSE v_id_cat2 := v_id_cat1; END IF;

        IF r.codcatn3 IS NOT NULL THEN
            v_id_cat3 := FN_GET_OR_CREATE_NODO(v_id_cat2, 'CATEGORIA', TO_CHAR(r.codcatn3), r.nomecatn3, 4, r.empresa);
        ELSE v_id_cat3 := v_id_cat2; END IF;

        IF r.codcatn4 IS NOT NULL THEN
            v_id_cat4 := FN_GET_OR_CREATE_NODO(v_id_cat3, 'CATEGORIA', TO_CHAR(r.codcatn4), r.nomecatn4, 5, r.empresa);
        ELSE v_id_cat4 := v_id_cat3; END IF;

        IF r.codcatn5 IS NOT NULL THEN
            v_id_cat5 := FN_GET_OR_CREATE_NODO(v_id_cat4, 'CATEGORIA', TO_CHAR(r.codcatn5), r.nomecatn5, 6, r.empresa);
        ELSE v_id_cat5 := v_id_cat4; END IF;

        v_id_produto := FN_GET_OR_CREATE_NODO(v_id_cat5, 'PRODUTO', TO_CHAR(r.cod_produto), r.descricao, 7, r.empresa, r.cod_produto, r.seqprodutobase);

        INSERT INTO TB_FLASH_FATO_VENDA (
            id_fato, data_referencia, ano_referencia, mes_referencia, dia_referencia, dia_semana,
            id_nodo, id_nodo_empresa, cod_empresa, nome_empresa, cod_produto, descricao_produto,
            seqprodutobase, nrodivisao, nrosegmento, nro_tickets, vlr_imp_venda, qtde_venda,
            vlr_venda, vl_ticket_medio, propqtdprodutobase, data_cadastro
        ) VALUES (
            SEQ_TB_FLASH_FATO_VENDA.NEXTVAL,
            r.data_referencia, r.ano, r.mes, r.dia, r.dia_semana,
            v_id_produto, v_id_empresa, r.empresa, r.nomeempresa, r.cod_produto, r.descricao,
            r.seqprodutobase, r.nrodivisao, r.nrosegmento, r.nro_tickets, r.vlr_imp_venda,
            r.qtde_venda, r.vlr_venda, r.vl_ticket_medio, r.propqtdprodutobase, SYSDATE
        );

    END LOOP;

    COMMIT;
END;
-- +goose StatementEnd
