DROP TABLE TEMPESTOQUE;

DROP PROCEDURE ADD_GERA_TEMP_ESTOQUE;

DROP TABLE TEMPINVENTARIOESTXFISCAL;

-- TEMPINVENTARIOESTXFISCAL
CREATE GLOBAL TEMPORARY TABLE TEMPINVENTARIOESTXFISCAL
  (
    uniqueMachineID               VARCHAR (18) DEFAULT ' ' NOT NULL,
    contadorSessao                NUMERIC (14,0) DEFAULT 0 NOT NULL,
    contador                      NUMERIC (14,0) DEFAULT 0 NOT NULL,
    estabelecimento               NUMERIC (4,0) DEFAULT 0 NOT NULL,
    gradeProduto                  NUMERIC (14,0) DEFAULT 0 NOT NULL,
    indicadorPropriedadePosseItem CHAR (1) DEFAULT ' ' NOT NULL,
    pessoaParticipante            NUMERIC (14,0) DEFAULT 0 NOT NULL,
    quantidade                    NUMERIC (15,6) DEFAULT 0 NOT NULL,
    precoUnitarioCMV              NUMERIC (15,7) DEFAULT 0 NOT NULL,
    stICMS                        CHAR (2) DEFAULT '  ' NOT NULL,
    baseICMS                      NUMERIC (15,2) DEFAULT 0 NOT NULL,
    valorICMS                     NUMERIC (15,2) DEFAULT 0 NOT NULL
  ) ON COMMIT PRESERVE ROWS;
ALTER TABLE TEMPINVENTARIOESTXFISCAL ADD CONSTRAINT TEMPINVENTARIOESTXFISCAL_PK1 PRIMARY KEY (uniqueMachineID, contadorSessao, contador);
CREATE UNIQUE INDEX TEMPINVENTARIOESTXFISCAL_K2 ON TEMPINVENTARIOESTXFISCAL (uniqueMachineID, contadorSessao, estabelecimento, gradeProduto, indicadorPropriedadePosseItem, pessoaParticipante);

DROP TABLE TEMPINVENTARIOESTXGERENC;

-- TEMPINVENTARIOESTXGERENC
CREATE GLOBAL TEMPORARY TABLE TEMPINVENTARIOESTXGERENC
  (
    uniqueMachineID               VARCHAR (18) DEFAULT ' ' NOT NULL,
    contadorSessao                NUMERIC (14,0) DEFAULT 0 NOT NULL,
    contador                      NUMERIC (14,0) DEFAULT 0 NOT NULL,
    estabelecimento               NUMERIC (4,0) DEFAULT 0 NOT NULL,
    gradeProduto                  NUMERIC (14,0) DEFAULT 0 NOT NULL,
    indicadorPropriedadePosseItem CHAR (1) DEFAULT ' ' NOT NULL,
    pessoaParticipante            NUMERIC (14,0) DEFAULT 0 NOT NULL,
    localEstoque                  NUMERIC (4,0) DEFAULT 0 NOT NULL,
    personalizacao                NUMERIC (7,0) DEFAULT 0 NOT NULL,
    idLoteEstoque                 NUMERIC (14,0) DEFAULT 0 NOT NULL,
    idEnderecoEstoque             NUMERIC (14,0) DEFAULT 0 NOT NULL,
    idNumeroSerie                 NUMERIC (14,0) DEFAULT 0 NOT NULL,
    quantidade                    NUMERIC (15,6) DEFAULT 0 NOT NULL,
    precoUnitarioCMV              NUMERIC (15,7) DEFAULT 0 NOT NULL,
    precoUnitarioUltimaCompra     NUMERIC (15,7) DEFAULT 0 NOT NULL,
    precoCustoUltimaCompra        NUMERIC (15,7) DEFAULT 0 NOT NULL,
    precoCustoUltimaFormacao      NUMERIC (15,7) DEFAULT 0 NOT NULL
  ) ON COMMIT PRESERVE ROWS;
ALTER TABLE TEMPINVENTARIOESTXGERENC ADD CONSTRAINT TEMPINVENTARIOESTXGERENC_PK1 PRIMARY KEY (uniqueMachineID, contadorSessao, contador);
CREATE UNIQUE INDEX TEMPINVENTARIOESTXGERENC_K2 ON TEMPINVENTARIOESTXGERENC (uniqueMachineID, contadorSessao, estabelecimento, gradeProduto, indicadorPropriedadePosseItem, pessoaParticipante, localEstoque, personalizacao, idLoteEstoque, idEnderecoEstoque, idNumeroSerie);

create or replace PROCEDURE ADD_GERA_TEMP_INVENTARIO (
  p_config_209_filtrarGrupoEcon  IN NUMBER,
  p_config_335_cmvGerencIgualFis IN NUMBER,
  p_config_362_calcCustoPorGrade IN NUMBER,
  p_uniqueMachineID              IN VARCHAR2,
  p_contadorSessaoFiscal         IN NUMBER,
  p_contadorSessaoGerencial      IN NUMBER,
  p_gerandoInventario            IN NUMBER,
  p_buscarPrecoUnitarioCMV       IN NUMBER,
  p_buscarPrecoUnitUltimaCompra  IN NUMBER,
  p_buscarPrecoCustoUltimaCompra IN NUMBER,
  p_buscarPrecoCustoUltimaFormac IN NUMBER,
  p_buscarICMS                   IN NUMBER,
  p_invEst_data                  IN DATE,
  p_invEst_motivoInventario      IN CHAR,
  p_inEstabelecimentos           IN VARCHAR2,
  p_produto                      IN NUMBER,
  p_prod_join                    IN VARCHAR2,
  p_prod_andWhere                IN VARCHAR2,
  p_filtroProduto                IN NUMBER,
  p_inventario_join              IN VARCHAR2,
  p_inventario_andWhere          IN VARCHAR2,
  p_movimentos_join              IN VARCHAR2,
  p_movimentos_andWhere          IN VARCHAR2,
  p_docFiscal_join               IN VARCHAR2,
  p_docFiscal_andWhere           IN VARCHAR2,
  p_docFiscalFilho_join          IN VARCHAR2,
  p_docFiscalFilho_andWhere      IN VARCHAR2)
IS
  v_prod_join     CLOB;
  v_prod_andWhere CLOB;
BEGIN
  v_prod_join := '
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto'
|| CASE
     WHEN p_prod_join IS NULL OR p_prod_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_prod_join)
   END
|| CASE
     WHEN p_produto <> 0 OR p_filtroProduto = 0
     THEN ''
     ELSE '
    JOIN PAFILTROSPRODUTO filtrProd
    ON filtrProd.filtroProduto = ' || TO_CHAR(p_filtroProduto)
   END;
  v_prod_andWhere := '
      AND gradProd.produto '
|| CASE
     WHEN  p_produto = 0
     THEN '> 0'
       || CASE
            WHEN p_prod_andWhere IS NULL OR p_prod_andWhere = ' '
            THEN '
    AND prod.controleEstoque IN (1,5,11,12,13)'
            ELSE '
    ' || RTRIM(p_prod_andWhere)
          END
       || CASE
            WHEN p_filtroProduto = 0
            THEN ''
            ELSE '
    AND filtrProd.filtrarVendedores              = 0
    AND filtrProd.filtrarLocaisEstoque           = 0
    AND filtrProd.filtrarPersonalizacoes         = 0
    AND (filtrProd.filtrarProdutos               = 0
      AND filtrProd.filtrarCategoriasProdutos    = 0
      AND filtrProd.filtrarSubcategoriasProdutos = 0
      AND filtrProd.filtrarMarcas                = 0
      AND filtrProd.filtrarCaracteristicasA      = 0
      AND filtrProd.filtrarCaracteristicasB      = 0
      AND filtrProd.filtrarCaracteristicasC      = 0
      AND filtrProd.filtrarCaracteristicasD      = 0
      AND filtrProd.filtrarCaracteristicasE      = 0
      AND filtrProd.filtrarCores                 = 0
      AND filtrProd.filtrarTamanhos              = 0
      AND filtrProd.filtrarNCMs                  = 0
      AND filtrProd.filtrarListasServicos        = 0
      OR filtrProd.filtrarProdutos               = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS filtrProdX
        WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
        AND filtrProdX.produto = prod.produto
        AND filtrProdX.ativo = 1)
      OR (filtrProd.filtrarCategoriasProdutos     = 1
        OR filtrProd.filtrarSubcategoriasProdutos = 1
        OR filtrProd.filtrarMarcas                = 1
        OR filtrProd.filtrarCaracteristicasA      = 1
        OR filtrProd.filtrarCaracteristicasB      = 1
        OR filtrProd.filtrarCaracteristicasC      = 1
        OR filtrProd.filtrarCaracteristicasD      = 1
        OR filtrProd.filtrarCaracteristicasE      = 1
        OR filtrProd.filtrarCores                 = 1
        OR filtrProd.filtrarTamanhos              = 1
        OR filtrProd.filtrarNCMs                  = 1
        OR filtrProd.filtrarListasServicos        = 1)
      AND (filtrProd.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD filtrProdX
          JOIN PASUBCATEGORIASPRODUTO subCatX
          ON subCatX.categoriaProduto = filtrProdX.categoriaProduto
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND subCatX.subcategoriaProduto = prod.subcategoriaProduto
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.subcategoriaProduto = prod.subcategoriaProduto
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.marca = prod.marca
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.caracteristicaA = prod.caracteristicaA
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.caracteristicaB = prod.caracteristicaB
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.caracteristicaC = prod.caracteristicaC
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.caracteristicaD = prod.caracteristicaD
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.caracteristicaE = prod.caracteristicaE
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.cor = gradProd.Cor
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.tamanho = gradProd.tamanho
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.idNcm = prod.idNcm
          AND filtrProdX.ativo = 1))
      AND (filtrProd.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE filtrProdX
          WHERE filtrProdX.filtroProduto = filtrProd.filtroProduto
          AND filtrProdX.listaServicos = prod.listaServicos
          AND filtrProdX.ativo = 1)))'
          END
     ELSE ' = ' || TO_CHAR(p_produto)
   END;
  IF p_contadorSessaoFiscal <> 0 THEN
    DELETE TEMPINVENTARIOESTXFISCAL
    WHERE uniqueMachineID = p_uniqueMachineID
    AND contadorSessao = p_contadorSessaoFiscal;
    EXECUTE IMMEDIATE 'INSERT INTO TEMPINVENTARIOESTXFISCAL (
  uniqueMachineID,
  contadorSessao,
  contador,
  estabelecimento,
  gradeProduto,
  indicadorPropriedadePosseItem,
  pessoaParticipante,
  quantidade,
  precoUnitarioCMV,
  stICMS,
  baseICMS,
  valorICMS)
WITH
DATAINVENTARIOSESTOQUE AS (
  SELECT
    a.inventarioEstoque,
    a.estabelecimento,
    TRUNC(a.data) data
  FROM (
    SELECT
      inventarioEstoque,
      estabelecimento,
      data,
      ROW_NUMBER() OVER (
        PARTITION BY estabelecimento
        ORDER BY
          estabelecimento ASC,
          data DESC,
          inventarioEstoque DESC
        ) ordenacao
    FROM MOINVENTARIOSESTOQUE
    WHERE motivoInventarioEstoque = ''01''
    AND data < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'')'
|| CASE
     WHEN p_gerandoInventario = 0
     THEN ' + 1'
     ELSE ''
   END
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     ELSE '
    AND estabelecimento IN (' || TRIM(p_inEstabelecimentos) || ')'
   END
|| ') a
  WHERE a.ordenacao = 1),
DATAINVENTARIOESTOQUEXFISC AS (
  SELECT
    a.inventarioEstoque,
    a.estabelecimento,
    a.produto,
    TRUNC(a.data) data
  FROM (
    SELECT
      invEst.inventarioEstoque,
      invEst.estabelecimento,
      gradProd.produto,
      invEst.data,
      ROW_NUMBER() OVER (
        PARTITION BY
          invEst.estabelecimento,
          gradProd.produto
        ORDER BY
          invEst.estabelecimento ASC,
          gradProd.produto ASC,
          invEst.data DESC,
          itemInv.inventarioEstoque DESC
        ) ordenacao
    FROM MOINVENTARIOESTOQUEXFISC itemInv
    JOIN MOINVENTARIOSESTOQUE invEst
    ON invEst.inventarioEstoque = itemInv.inventarioEstoque
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = itemInv.gradeProduto'
|| v_prod_join
|| CASE
     WHEN p_inventario_join IS NULL OR p_inventario_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_join)
   END
|| '
    WHERE invEst.motivoInventarioEstoque <> ''01''
    AND invEst.data < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'')
    AND invEst.data >= COALESCE((
      SELECT MAX (dataInv.data) + 1
      FROM DATAINVENTARIOSESTOQUE dataInv
      WHERE dataInv.estabelecimento = invEst.estabelecimento),
      TO_DATE (''01/01/1900'',''DD/MM/YYYY''))'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     ELSE '
    AND invEst.estabelecimento IN (' || TRIM(p_inEstabelecimentos) || ')'
   END
|| v_prod_andWhere
|| CASE
     WHEN p_inventario_andWhere IS NULL OR p_inventario_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_andWhere)
   END
|| ') a
  WHERE a.ordenacao = 1),
DATAESTOQUEINICIAL AS (
  SELECT
    a.estabelecimento,
    TRUNC(a.data) data,
    a.produto
  FROM (
    SELECT
      mov.estabelecimento,
      mov.data,
      gradProd.produto,
      ROW_NUMBER() OVER (
        PARTITION BY
          mov.estabelecimento,
          gradProd.produto
        ORDER BY
          mov.estabelecimento ASC,
          gradProd.produto ASC,
          mov.data DESC,
          mov.idEstoque DESC
        ) ordenacao
    FROM MOESTOQUES mov
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = mov.gradeProduto'
|| v_prod_join
|| CASE
     WHEN p_movimentos_join IS NULL OR p_movimentos_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_movimentos_join)
   END
|| '
    WHERE mov.operacaoInternaEstoque = 1
    AND mov.data < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1
    AND mov.data >= COALESCE((
      SELECT MAX (dataInvFisc.data) + 1
      FROM DATAINVENTARIOESTOQUEXFISC dataInvFisc
      WHERE dataInvFisc.estabelecimento = mov.estabelecimento
      AND dataInvFisc.produto = gradProd.produto),
      COALESCE((
        SELECT MAX (dataInv.data) + 1
        FROM DATAINVENTARIOSESTOQUE dataInv
        WHERE dataInv.estabelecimento = mov.estabelecimento),
        TO_DATE (''01/01/1900'',''DD/MM/YYYY'')))'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     ELSE '
    AND mov.estabelecimento IN (' || TRIM(p_inEstabelecimentos) || ')'
   END
|| v_prod_andWhere
|| CASE
     WHEN p_movimentos_andWhere IS NULL OR p_movimentos_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_movimentos_andWhere)
   END
|| ') a
  WHERE a.ordenacao = 1)
SELECT
  ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || ''',
  ' || TO_CHAR(p_contadorSessaoFiscal) || ',
  ROW_NUMBER() OVER (
    ORDER BY
      a.estabelecimento,
      a.gradeProduto,
      a.indicadorPropriedadePosseItem,
      a.pessoaParticipante),
  a.estabelecimento,
  a.gradeProduto,
  a.indicadorPropriedadePosseItem,
  a.pessoaParticipante,
  SUM (a.quantidade),
  0 precoUnitarioCMV,
  ''00'' stICMS,
  0 baseICMS,
  0 valorICMS
FROM (
  SELECT DISTINCT
    itemInv.id,
    invEst.estabelecimento,
    itemInv.indicadorPropriedadePosseItem,
    itemInv.pessoaParticipante,
    itemInv.gradeProduto,
    itemInv.quantidade,
    gradProd.produto,
    gradProd.cor,
    gradProd.tamanho
  FROM MOINVENTARIOESTOQUEXFISC itemInv
  JOIN MOINVENTARIOSESTOQUE invEst
  ON invEst.inventarioEstoque = itemInv.inventarioEstoque
  JOIN DATAINVENTARIOSESTOQUE dataInv
  ON dataInv.inventarioEstoque = itemInv.inventarioEstoque
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = itemInv.gradeProduto'
|| v_prod_join
|| CASE
     WHEN p_inventario_join IS NULL OR p_inventario_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_join)
   END
|| '
  WHERE NOT (EXISTS(
    SELECT 1
    FROM DATAINVENTARIOESTOQUEXFISC dataInvFisc
    WHERE dataInvFisc.estabelecimento = invEst.estabelecimento
    AND dataInvFisc.produto = gradProd.produto))
  AND NOT (EXISTS(
    SELECT 1
    FROM DATAESTOQUEINICIAL dataEstInic
    WHERE dataEstInic.estabelecimento = invEst.estabelecimento
    AND dataEstInic.produto = gradProd.produto))'
|| v_prod_andWhere
|| CASE
     WHEN p_inventario_andWhere IS NULL OR p_inventario_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_andWhere)
   END
|| '
  UNION ALL
  SELECT DISTINCT
    itemInv.id,
    invEst.estabelecimento,
    itemInv.indicadorPropriedadePosseItem,
    itemInv.pessoaParticipante,
    itemInv.gradeProduto,
    itemInv.quantidade,
    gradProd.produto,
    gradProd.cor,
    gradProd.tamanho
  FROM MOINVENTARIOESTOQUEXFISC itemInv
  JOIN MOINVENTARIOSESTOQUE invEst
  ON invEst.inventarioEstoque = itemInv.inventarioEstoque
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = itemInv.gradeProduto
  JOIN DATAINVENTARIOESTOQUEXFISC dataInvFisc
  ON dataInvFisc.inventarioEstoque = itemInv.inventarioEstoque
  AND dataInvFisc.produto = gradProd.produto'
|| v_prod_join
|| CASE
     WHEN p_inventario_join IS NULL OR p_inventario_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_join)
   END
|| '
  WHERE NOT (EXISTS(
    SELECT 1
    FROM DATAESTOQUEINICIAL dataEstInic
    WHERE dataEstInic.estabelecimento = dataInvFisc.estabelecimento
    AND dataEstInic.produto = gradProd.produto))'
|| v_prod_andWhere
|| CASE
     WHEN p_inventario_andWhere IS NULL OR p_inventario_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_andWhere)
   END
|| '
  UNION ALL
  SELECT DISTINCT
    mov.idEstoque id,
    mov.estabelecimento,
    mov.indicadorPropriedadePosseItem,
    mov.pessoaParticipante,
    mov.gradeProduto,
    mov.quantidade * CASE WHEN mov.entradaSaida = ''S'' THEN -1 ELSE 1 END quantidade,
    gradProd.produto,
    gradProd.cor,
    gradProd.tamanho
  FROM MOESTOQUES mov
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = mov.gradeProduto'
|| v_prod_join
|| CASE
     WHEN p_movimentos_join IS NULL OR p_movimentos_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_movimentos_join)
   END
|| '
  WHERE mov.operacaoInternaEstoque IN (1,900)
  AND mov.data < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1
  AND mov.data >= COALESCE((
    SELECT MAX (dataEstInic.data)
    FROM DATAESTOQUEINICIAL dataEstInic
    WHERE dataEstInic.estabelecimento = mov.estabelecimento
    AND dataEstInic.produto = gradProd.produto),
    COALESCE((
      SELECT MAX (dataInvFisc.data) + 1
      FROM DATAINVENTARIOESTOQUEXFISC dataInvFisc
      WHERE dataInvFisc.estabelecimento = mov.estabelecimento
      AND dataInvFisc.produto = gradProd.produto),
      COALESCE((
        SELECT MAX (dataInv.data) + 1
        FROM DATAINVENTARIOSESTOQUE dataInv
        WHERE dataInv.estabelecimento = mov.estabelecimento),
        TO_DATE (''01/01/1900'',''DD/MM/YYYY''))))'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     ELSE '
  AND mov.estabelecimento IN (' || TRIM(p_inEstabelecimentos) || ')'
   END
|| v_prod_andWhere
|| CASE
     WHEN p_movimentos_andWhere IS NULL OR p_movimentos_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_movimentos_andWhere)
   END
|| '
  UNION ALL
  SELECT DISTINCT
    itemDoc.idItemDocFiscal id,
    cabDoc.estabelecimento,
    locEst.indicadorPropriedadePosseItem,
    itemDoc.pessoaParticipante,
    itemDoc.gradeProduto,
    itemDoc.quantidade * CASE WHEN cabDoc.entradaSaida = ''S'' THEN -1 ELSE 1 END quantidade,
    gradProd.produto,
    gradProd.cor,
    gradProd.tamanho
  FROM MODOCFISCALXITENS itemDoc
  JOIN MODOCUMENTOSFISCAIS cabDoc
  ON cabDoc.idDocumentoFiscal = itemDoc.idDocumentoFiscal
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = itemDoc.gradeProduto
  JOIN PALOCAISESTOQUE locEst
  ON locEst.localEstoque = itemDoc.localEstoque'
|| v_prod_join
|| CASE
     WHEN p_docFiscal_join IS NULL OR p_docFiscal_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_docFiscal_join)
   END
|| '
  WHERE itemDoc.cancelado = 0
  AND itemDoc.movimentaEstoqueFiscal = 1
  AND cabDoc.situacaoDocumentoFiscal BETWEEN 21 AND 23
  AND cabDoc.dataEntradaSaida < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1
  AND cabDoc.dataEntradaSaida >= COALESCE((
    SELECT MAX (dataEstInic.data)
    FROM DATAESTOQUEINICIAL dataEstInic
    WHERE dataEstInic.estabelecimento = cabDoc.estabelecimento
    AND dataEstInic.produto = gradProd.produto),
    COALESCE((
      SELECT MAX (dataInvFisc.data) + 1
      FROM DATAINVENTARIOESTOQUEXFISC dataInvFisc
      WHERE dataInvFisc.estabelecimento = cabDoc.estabelecimento
      AND dataInvFisc.produto = gradProd.produto),
      COALESCE((
        SELECT MAX (dataInv.data) + 1
        FROM DATAINVENTARIOSESTOQUE dataInv
        WHERE dataInv.estabelecimento = cabDoc.estabelecimento),
        TO_DATE (''01/01/1900'',''DD/MM/YYYY''))))
  AND NOT(EXISTS(
    SELECT 1
    FROM MODOCFISCALXPRODUTOFILHO filhoDoc
    WHERE filhoDoc.idItemDocFiscal = itemDoc.idItemDocFiscal))'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     ELSE '
  AND cabDoc.estabelecimento IN (' || TRIM(p_inEstabelecimentos) || ')'
   END
|| v_prod_andWhere
|| CASE
     WHEN p_docFiscal_andWhere IS NULL OR p_docFiscal_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_docFiscal_andWhere)
   END
|| '
  UNION ALL
  SELECT DISTINCT
    filhoDoc.id,
    cabDoc.estabelecimento,
    locEst.indicadorPropriedadePosseItem,
    itemDoc.pessoaParticipante,
    filhoDoc.gradeProduto,
    filhoDoc.quantidade * CASE WHEN cabDoc.entradaSaida = ''S'' THEN -1 ELSE 1 END quantidade,
    gradProd.produto,
    gradProd.cor,
    gradProd.tamanho
  FROM MODOCFISCALXPRODUTOFILHO filhoDoc
  JOIN MODOCFISCALXITENS itemDoc
  ON itemDoc.idItemDocFiscal = filhoDoc.idItemDocFiscal
  JOIN MODOCUMENTOSFISCAIS cabDoc
  ON cabDoc.idDocumentoFiscal = itemDoc.idDocumentoFiscal
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = filhoDoc.gradeProduto
  JOIN PALOCAISESTOQUE locEst
  ON locEst.localEstoque = itemDoc.localEstoque'
|| v_prod_join
|| CASE
     WHEN p_inventario_join IS NULL OR p_inventario_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_join)
   END
|| '
  WHERE itemDoc.cancelado = 0
  AND itemDoc.movimentaEstoqueFiscal = 1
  AND cabDoc.situacaoDocumentoFiscal BETWEEN 21 AND 23
  AND cabDoc.dataEntradaSaida < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1
  AND cabDoc.dataEntradaSaida >= COALESCE((
    SELECT MAX (dataEstInic.data)
    FROM DATAESTOQUEINICIAL dataEstInic
    WHERE dataEstInic.estabelecimento = cabDoc.estabelecimento
    AND dataEstInic.produto = gradProd.produto),
    COALESCE((
      SELECT MAX (dataInvFisc.data) + 1
      FROM DATAINVENTARIOESTOQUEXFISC dataInvFisc
      WHERE dataInvFisc.estabelecimento = cabDoc.estabelecimento
      AND dataInvFisc.produto = gradProd.produto),
      COALESCE((
        SELECT MAX (dataInv.data) + 1
        FROM DATAINVENTARIOSESTOQUE dataInv
        WHERE dataInv.estabelecimento = cabDoc.estabelecimento),
        TO_DATE (''01/01/1900'',''DD/MM/YYYY''))))'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     ELSE '
  AND cabDoc.estabelecimento IN (' || TRIM(p_inEstabelecimentos) || ')'
   END
|| v_prod_andWhere
|| CASE
     WHEN p_inventario_andWhere IS NULL OR p_inventario_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_andWhere)
   END
|| ') a
GROUP BY
  a.gradeProduto,
  a.estabelecimento,
  a.indicadorPropriedadePosseItem,
  a.pessoaParticipante,
  a.produto,
  a.cor,
  a.tamanho';
    IF p_buscarPrecoUnitarioCMV = 1 THEN
      EXECUTE IMMEDIATE 'BEGIN
  FOR a IN (
    SELECT
      a.uniqueMachineID,
      a.contadorSessao,
      a.estabelecimento,
      a.indicadorPropriedadePosseItem,
      a.pessoaParticipante,
      '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'a.gradeProduto'
           ELSE 'a.produto'
          END
      || ',
      FUNC_ADD_BUSCA_PRECO_MEDIO_FIS(
        ' || TO_CHAR(p_config_209_filtrarGrupoEcon) || ', -- p_config_209_filtrarGrupoEcon
        ' || TO_CHAR(p_config_362_calcCustoPorGrade) || ', -- p_config_362_calcCustoPorGrade
        a.estabelecimento,
        TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY''), -- p_dataFinal
        a.pessoaParticipante,
        a.produto,
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.cor' ELSE '0' END || ',
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.tamanho' ELSE ''' ''' END || ',
        a.indicadorPropriedadePosseItem,
        ' || TO_CHAR(p_gerandoInventario) || ' -- p_gerandoInventario
      ) precoUnitarioCMV
    FROM (
      SELECT
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        MIN(a.estabelecimento) estabelecimento
      FROM TEMPINVENTARIOESTXFISCAL a
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = a.gradeProduto
      JOIN PAESTABELECIMENTOS est
      ON est.estabelecimento = a.estabelecimento
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      WHERE a.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
      AND a.contadorSessao = ' || TO_CHAR(p_contadorSessaoFiscal) || '
      GROUP BY
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        CASE'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
          WHEN est.pessoaEstabelecimento <> 0
            AND pessEst.grupoEconomico <> 0
          THEN pessEst.grupoEconomico'
           ELSE ''
         END
      || '
          WHEN est.pessoaEstabelecimento <> 0
          THEN est.pessoaEstabelecimento
          ELSE a.estabelecimento
        END) a)
  LOOP
    UPDATE TEMPINVENTARIOESTXFISCAL b
    SET b.precoUnitarioCMV = a.precoUnitarioCMV
    WHERE b.uniqueMachineID = a.uniqueMachineID 
    AND b.contadorSessao = a.contadorSessao
    AND (b.estabelecimento = a.estabelecimento
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst
        ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2
        ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND pessEst.grupoEconomico > 0
        AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
    AND b.indicadorPropriedadePosseItem = a.indicadorPropriedadePosseItem
    AND b.pessoaParticipante = a.pessoaParticipante'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN '
    AND b.gradeProduto = a.gradeProduto'
           ELSE '
    AND EXISTS(
      SELECT 1
      FROM CAGRADESPRODUTO gradProd
      WHERE gradProd.gradeProduto = b.gradeProduto
      AND gradProd.produto = a.produto)'
          END
      || ';
  END LOOP;
END;';
    END IF;
    IF p_buscarICMS = 1 THEN
      EXECUTE IMMEDIATE 'DECLARE
  v_stICMS           CHAR (2);
  v_baseICMS         NUMBER;
  v_valorICMS        NUMBER;
  v_existeEntrada    NUMBER;
  v_precoUnitarioCMV NUMBER;
BEGIN
  FOR a IN (
    SELECT
      a.uniqueMachineID,
      a.contadorSessao,
      a.estabelecimento,
      a.indicadorPropriedadePosseItem,
      a.pessoaParticipante,
      a.produto,'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN '
      a.gradeProduto,
      a.cor,
      a.tamanho,'
           ELSE ''
          END
      || '
      a.precoUnitarioCMV
    FROM (
      SELECT
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        MIN(a.estabelecimento) estabelecimento,
        MAX(a.precoUnitarioCMV) precoUnitarioCMV
      FROM TEMPINVENTARIOESTXFISCAL a
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = a.gradeProduto
      JOIN PAESTABELECIMENTOS est
      ON est.estabelecimento = a.estabelecimento
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      WHERE a.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
      AND a.contadorSessao = ' || TO_CHAR(p_contadorSessaoFiscal) || '
      GROUP BY
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        CASE'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
          WHEN est.pessoaEstabelecimento <> 0
            AND pessEst.grupoEconomico <> 0
          THEN pessEst.grupoEconomico'
           ELSE ''
         END
      || '
          WHEN est.pessoaEstabelecimento <> 0
          THEN est.pessoaEstabelecimento
          ELSE a.estabelecimento
        END) a)
  LOOP
    v_stICMS           := ''00'';
    v_baseICMS         := 0;
    v_valorICMS        := 0;
    v_existeEntrada    := 0;
    v_precoUnitarioCMV := 0;
    SELECT
      COALESCE(MAX(b.stICMS),''00''),
      COALESCE(MAX(b.baseICMS),0),
      COALESCE(MAX(b.valorICMS),0),
      COALESCE(MAX(b.existeEntrada),0)
    INTO
      v_stICMS,
      v_baseICMS,
      v_valorICMS,
      v_existeEntrada
    FROM (
      SELECT
        CASE
          WHEN b.nfFornecedor = 1
            AND b.stICMSEscrituracao <> ''  ''
          THEN b.stICMSEscrituracao
          WHEN b.stICMS <> ''  ''
          THEN b.stICMS
          ELSE ''90''
        END stICMS,
        ROUND((
          CASE
            WHEN b.nfFornecedor = 1
            AND (b.stICMSEscrituracao IN(''10'',''30'',''70'')
                OR b.stICMSEscrituracao = ''90''
                AND b.aliquotaICMSSTEscrituracao > 0)
              OR (b.nfFornecedor = 0
                OR b.stICMSEscrituracao = ''  ''
                OR b.stICMSEscrituracao = ''60'')
              AND (b.stICMS IN(''10'',''30'',''70'')
                OR b.stICMS = ''90''
                AND b.aliquotaICMSST > 0
                OR b.stSimplesNacional IN(''201'',''202'')
                OR b.stSimplesNacional = ''900''
                AND b.aliquotaICMSST > 0)
            THEN
              CASE
                WHEN b.nfFornecedor = 1 AND b.baseICMSSTEscrituracao <> 0
                THEN b.baseICMSSTEscrituracao
                WHEN b.baseICMSST <> 0
                THEN b.baseICMSST
                ELSE b.baseICMS
              END *
                CASE
                  WHEN b.valorCustoOperacao = 0 OR b.totalCustoOperacao = 0
                  THEN 1 / b.quantidade
                  ELSE (1 / b.quantidadeEstoque)
                    * (b.totalCustoOperacao / b.valorCustoOperacao)
                END
            ELSE 0
          END),2) baseICMS,
        ROUND((
          CASE
            WHEN b.nfFornecedor = 1
            AND (b.stICMSEscrituracao IN(''10'',''30'',''70'')
                OR b.stICMSEscrituracao = ''90''
                AND b.aliquotaICMSSTEscrituracao > 0)
              OR (b.nfFornecedor = 0
                OR b.stICMSEscrituracao = ''  ''
                OR b.stICMSEscrituracao = ''60'')
              AND (b.stICMS IN(''10'',''30'',''70'')
                OR b.stICMS = ''90''
                AND b.aliquotaICMSST > 0
                OR b.stSimplesNacional IN(''201'',''202'')
                OR b.stSimplesNacional = ''900''
                AND b.aliquotaICMSST > 0)
            THEN
              CASE
                WHEN b.nfFornecedor = 1 AND b.baseICMSSTEscrituracao <> 0
                THEN b.valorICMSEscrituracao + b.valorICMSSTEscrituracao
                ELSE b.valorICMS + b.valorICMSST
              END *
                CASE
                  WHEN b.valorCustoOperacao = 0 OR b.totalCustoOperacao = 0
                  THEN 1 / b.quantidade
                  ELSE (1 / b.quantidadeEstoque)
                    * (b.totalCustoOperacao / b.valorCustoOperacao)
                END
            ELSE 0
          END),2) valorICMS,
        1 existeEntrada,
        ROW_NUMBER() OVER (
          ORDER BY b.dataEntradaSaida DESC) ordenacao
      FROM (
        SELECT
          b.idDocumentoFiscal,
          b.estabelecimento,
          b.dataEntradaSaida,
          b.nfFornecedor,
          b.produto,
          b.stSimplesNacional,
          b.stICMS,
          b.aliquotaICMSST,
          b.stICMSEscrituracao,
          b.aliquotaICMSSTEscrituracao,
          SUM(b.quantidade) quantidade,
          SUM(b.baseICMS) baseICMS,
          SUM(b.valorICMS) valorICMS,
          SUM(b.baseICMSST) baseICMSST,
          SUM(b.valorICMSST) valorICMSST,
          SUM(b.valorICMSEscrituracao) valorICMSEscrituracao,
          SUM(b.baseICMSSTEscrituracao) baseICMSSTEscrituracao,
          SUM(b.valorICMSSTEscrituracao) valorICMSSTEscrituracao,
          SUM(b.valorCustoOperacao) valorCustoOperacao,
          SUM(b.quantidadeEstoque) quantidadeEstoque,
          SUM(b.totalCustoOperacao) totalCustoOperacao
        FROM (
          SELECT
            itemDoc.idDocumentoFiscal,
            cabDoc.estabelecimento,
            cabDoc.dataEntradaSaida,
            cabDoc.nfFornecedor,
            docXEst.idItemDocFiscal,
            gradProd.Produto,
            itemDoc.stSimplesNacional,
            itemDoc.stICMS,
            itemDoc.aliquotaICMSST,
            itemDoc.stICMSEscrituracao,
            itemDoc.aliquotaICMSSTEscrituracao,
            itemDoc.quantidade,
            itemDoc.baseICMS,
            itemDoc.valorICMS,
            itemDoc.baseICMSST,
            itemDoc.valorICMSST,
            itemDoc.valorICMSEscrituracao,
            itemDoc.baseICMSSTEscrituracao,
            itemDoc.valorICMSSTEscrituracao,
            itemDoc.valorCustoOperacao,
            SUM(est.quantidade) quantidadeEstoque,
            SUM(est.totalCustoOperacao) totalCustoOperacao
          FROM MOESTOQUES est
          JOIN CAGRADESPRODUTO gradProd
          on gradProd.gradeProduto = est.gradeProduto
          JOIN MODOCFISCALXESTOQUE docXEst
          ON docXEst.idEstoque = est.idEstoque
          JOIN MODOCFISCALXITENS itemDoc
          ON itemDoc.idItemDocFiscal = docXEst.idItemDocFiscal
          JOIN MODOCUMENTOSFISCAIS cabDoc
          ON cabDoc.idDocumentoFiscal = itemDoc.idDocumentoFiscal
          WHERE est.entradaSaida = ''E''
          AND est.atualizaUltimaCompra = 1
          AND cabDoc.dataEntradaSaida < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1
          AND (est.gradeProduto = itemDoc.gradeProduto
            OR NOT(EXISTS(
              SELECT 1
              FROM CAGRADEPRODUTOXKITSCOMBOS kit
              WHERE kit.gradeProduto = itemDoc.gradeProduto
              AND kit.gradeProdutoFilho = est.gradeProduto
              AND kit.ativo = 1
              AND kit.manterUltimoCusto = 1)))
          GROUP BY
            itemDoc.idDocumentoFiscal,
            cabDoc.estabelecimento,
            cabDoc.dataEntradaSaida,
            cabDoc.nfFornecedor,
            docXEst.idItemDocFiscal,
            gradProd.Produto,
            itemDoc.stSimplesNacional,
            itemDoc.stICMS,
            itemDoc.aliquotaICMSST,
            itemDoc.stICMSEscrituracao,
            itemDoc.aliquotaICMSSTEscrituracao,
            itemDoc.quantidade,
            itemDoc.baseICMS,
            itemDoc.valorICMS,
            itemDoc.baseICMSST,
            itemDoc.valorICMSST,
            itemDoc.valorICMSEscrituracao,
            itemDoc.baseICMSSTEscrituracao,
            itemDoc.valorICMSSTEscrituracao,
            itemDoc.valorCustoOperacao) b
      GROUP BY
        b.idDocumentoFiscal,
        b.estabelecimento,
        b.dataEntradaSaida,
        b.nfFornecedor,
        b.produto,
        b.stSimplesNacional,
        b.stICMS,
        b.aliquotaICMSST,
        b.stICMSEscrituracao,
        b.aliquotaICMSSTEscrituracao) b
      WHERE b.produto = a.produto
      AND (b.estabelecimento = a.estabelecimento
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
          WHERE est.estabelecimento = b.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND est2.estabelecimento = a.estabelecimento)'
        || CASE
             WHEN p_config_209_filtrarGrupoEcon = 1
             THEN '
        OR EXISTS (
          SELECT 1
          FROM PAESTABELECIMENTOS est
          JOIN CAPESSOAS pessEst
          ON pessEst.pessoa = est.pessoaEstabelecimento
          JOIN CAPESSOAS pessEst2
          ON pessEst2.grupoEconomico = pessEst.grupoEconomico
          JOIN PAESTABELECIMENTOS est2
          ON est2.pessoaEstabelecimento = pessEst2.pessoa
          WHERE est.estabelecimento = b.estabelecimento
          AND est.ativo = 1
          AND est.pessoaEstabelecimento > 0
          AND pessEst.grupoEconomico > 0
          AND est2.estabelecimento = a.estabelecimento)'
             ELSE ''
           END
        || ')) b
    WHERE b.ordenacao = 1;
    IF (v_existeEntrada = 0 OR v_stICMS = ''00'') AND v_valorICMS = 0 THEN
      v_stICMS   := ''00'';
      v_baseICMS := ROUND(FUNC_ADD_BUSCA_PRECO_ULT_COMPR(
        ' || TO_CHAR(p_config_209_filtrarGrupoEcon) || ', -- p_config_209_filtrarGrupoEcon
        ' || TO_CHAR(p_config_362_calcCustoPorGrade) || ', -- p_config_362_calcCustoPorGrade
        a.estabelecimento,
        NULL, -- p_dataInicial
        TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY''), -- p_dataFinal
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.personalizacao' ELSE '0' END || ',
        a.produto,
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.cor' ELSE '0' END || ',
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.tamanho' ELSE ''' ''' END || ',
        0, -- p_retornarPrecoBruto
        ' || TO_CHAR(p_gerandoInventario) || '),2);
      IF v_baseICMS = 0 THEN
        v_baseICMS := ROUND(FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
        ' || TO_CHAR(p_config_209_filtrarGrupoEcon) || ', -- p_config_209_filtrarGrupoEcon
        ' || TO_CHAR(p_config_362_calcCustoPorGrade) || ', -- p_config_362_calcCustoPorGrade
        a.estabelecimento,
        NULL, -- p_dataInicial
        TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY''), -- p_dataFinal
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.personalizacao' ELSE '0' END || ',
        a.pessoaParticipante,
        a.produto,
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.cor' ELSE '0' END || ',
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.tamanho' ELSE ''' ''' END || ',
        a.indicadorPropriedadePosseItem,
        ' || TO_CHAR(p_gerandoInventario) || '),2);
      END IF;
      IF v_baseICMS = 0 THEN
        v_baseICMS := ROUND(FUNC_ADD_BUSCA_PRECO_FORMACAO(
        ' || TO_CHAR(p_config_209_filtrarGrupoEcon) || ', -- p_config_209_filtrarGrupoEcon
        ' || TO_CHAR(p_config_362_calcCustoPorGrade) || ', -- p_config_362_calcCustoPorGrade
        a.estabelecimento,
        NULL, -- p_dataInicial
        TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY''), -- p_dataFinal
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.personalizacao' ELSE '0' END || ',
        a.produto,
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.cor' ELSE '0' END || ',
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.tamanho' ELSE ''' ''' END || ',
        ' || TO_CHAR(p_gerandoInventario) || '),2);
      END IF;
      IF v_baseICMS = 0 THEN
        v_baseICMS := a.precoUnitarioCmv;
      END IF;
      v_valorICMS := ROUND(v_baseICMS * 0.17,2);
    END IF;'
      || CASE
           WHEN p_invEst_motivoInventario = '02'
           THEN '
    IF v_valorICMS > 0 THEN
      v_precoUnitarioCMV := a.precoUnitarioCMV - v_valorICMS;
      IF v_precoUnitarioCMV < 0 THEN
        v_precoUnitarioCMV := 0;
      END IF;
    ELSE
      v_precoUnitarioCMV := a.precoUnitarioCMV;
    END IF;'
           ELSE '
    v_precoUnitarioCMV := a.precoUnitarioCMV;'
         END
      || '
    UPDATE TEMPINVENTARIOESTXFISCAL b SET
      b.stICMS           = v_stICMS,
      b.baseICMS         = v_baseICMS,
      b.valorICMS        = v_valorICMS'
      || CASE
           WHEN p_invEst_motivoInventario = '02'
           THEN ',
      b.precoUnitarioCMV = v_precoUnitarioCMV'
           ELSE ''
         END
      || '
    WHERE b.uniqueMachineID = a.uniqueMachineID 
    AND b.contadorSessao = a.contadorSessao
    AND (b.estabelecimento = a.estabelecimento
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst
        ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2
        ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND pessEst.grupoEconomico > 0
        AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
    AND b.indicadorPropriedadePosseItem = a.indicadorPropriedadePosseItem
    AND b.pessoaParticipante = a.pessoaParticipante'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN '
    AND b.gradeProduto = a.gradeProduto'
           ELSE '
    AND EXISTS(
      SELECT 1
      FROM CAGRADESPRODUTO gradProd
      WHERE gradProd.gradeProduto = b.gradeProduto
      AND gradProd.produto = a.produto)'
          END
      || ';
  END LOOP;
END;';
    END IF;
  END IF;
  IF p_contadorSessaoGerencial <> 0 THEN
    DELETE TEMPINVENTARIOESTXGERENC
    WHERE uniqueMachineID = p_uniqueMachineID
    AND contadorSessao = p_contadorSessaoGerencial;
    EXECUTE IMMEDIATE 'INSERT INTO TEMPINVENTARIOESTXGERENC (
  uniqueMachineID,
  contadorSessao,
  contador,
  estabelecimento,
  gradeProduto,
  indicadorPropriedadePosseItem,
  pessoaParticipante,
  localEstoque,
  personalizacao,
  idLoteEstoque,
  idEnderecoEstoque,
  idNumeroSerie,
  quantidade,
  precoUnitarioCMV,
  precoUnitarioUltimaCompra,
  precoCustoUltimaCompra,
  precoCustoUltimaFormacao)
WITH
DATAINVENTARIOSESTOQUE AS (
  SELECT
    a.inventarioEstoque,
    a.estabelecimento,
    TRUNC(a.data) data
  FROM (
    SELECT
      inventarioEstoque,
      estabelecimento,
      data,
      ROW_NUMBER() OVER (
        PARTITION BY estabelecimento
        ORDER BY
          estabelecimento ASC,
          data DESC,
          inventarioEstoque DESC
        ) ordenacao
    FROM MOINVENTARIOSESTOQUE
    WHERE motivoInventarioEstoque = ''01''
    AND data < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'')'
|| CASE
     WHEN p_gerandoInventario = 0
     THEN ' + 1'
     ELSE ''
   END
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     ELSE '
    AND estabelecimento IN (' || TRIM(p_inEstabelecimentos) || ')'
   END
|| ') a
  WHERE a.ordenacao = 1),
DATAINVENTARIOESTOQUEXITENS AS (
  SELECT
    a.inventarioEstoque,
    a.estabelecimento,
    a.produto,
    TRUNC(a.data) data
  FROM (
    SELECT
      invEst.inventarioEstoque,
      invEst.estabelecimento,
      gradProd.produto,
      invEst.data,
      ROW_NUMBER() OVER (
        PARTITION BY
          invEst.estabelecimento,
          gradProd.produto
        ORDER BY
          invEst.estabelecimento ASC,
          gradProd.produto ASC,
          invEst.data DESC,
          itemInv.inventarioEstoque DESC
        ) ordenacao
    FROM MOINVENTARIOESTOQUEXITENS itemInv
    JOIN MOINVENTARIOSESTOQUE invEst
    ON invEst.inventarioEstoque = itemInv.inventarioEstoque
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = itemInv.gradeProduto'
|| v_prod_join
|| CASE
     WHEN p_inventario_join IS NULL OR p_inventario_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_join)
   END
|| '
    WHERE invEst.motivoInventarioEstoque <> ''01''
    AND invEst.data < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'')
    AND invEst.data >= COALESCE((
      SELECT MAX (dataInv.data) + 1
      FROM DATAINVENTARIOSESTOQUE dataInv
      WHERE dataInv.estabelecimento = invEst.estabelecimento),
      TO_DATE (''01/01/1900'',''DD/MM/YYYY''))'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     ELSE '
    AND invEst.estabelecimento IN (' || TRIM(p_inEstabelecimentos) || ')'
   END
|| v_prod_andWhere
|| CASE
     WHEN p_inventario_andWhere IS NULL OR p_inventario_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_andWhere)
   END
|| ') a
  WHERE a.ordenacao = 1),
DATAESTOQUEINICIAL AS (
  SELECT
    a.estabelecimento,
    TRUNC(a.data) data,
    a.produto
  FROM (
    SELECT
      mov.estabelecimento,
      mov.data,
      gradProd.produto,
      ROW_NUMBER() OVER (
        PARTITION BY
          mov.estabelecimento,
          gradProd.produto
        ORDER BY
          mov.estabelecimento ASC,
          gradProd.produto ASC,
          mov.data DESC,
          mov.idEstoque DESC
        ) ordenacao
    FROM MOESTOQUES mov
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = mov.gradeProduto'
|| v_prod_join
|| CASE
     WHEN p_movimentos_join IS NULL OR p_movimentos_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_movimentos_join)
   END
|| '
    WHERE mov.operacaoInternaEstoque = 1
    AND mov.data < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1
    AND mov.data >= COALESCE((
      SELECT MAX (dataInvGer.data) + 1
      FROM DATAINVENTARIOESTOQUEXITENS dataInvGer
      WHERE dataInvGer.estabelecimento = mov.estabelecimento
      AND dataInvGer.produto = gradProd.produto),
      COALESCE((
        SELECT MAX (dataInv.data) + 1
        FROM DATAINVENTARIOSESTOQUE dataInv
        WHERE dataInv.estabelecimento = mov.estabelecimento),
        TO_DATE (''01/01/1900'',''DD/MM/YYYY'')))'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     ELSE '
    AND mov.estabelecimento IN (' || TRIM(p_inEstabelecimentos) || ')'
   END
|| v_prod_andWhere
|| CASE
     WHEN p_movimentos_andWhere IS NULL OR p_movimentos_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_movimentos_andWhere)
   END
|| ') a
  WHERE a.ordenacao = 1)
SELECT
  ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || ''',
  ' || TO_CHAR(p_contadorSessaoGerencial) || ',
  ROW_NUMBER() OVER (
    ORDER BY
      a.estabelecimento,
      a.gradeProduto,
      a.indicadorPropriedadePosseItem,
      a.pessoaParticipante,
      a.localEstoque,
      a.personalizacao,
      a.idLoteEstoque,
      a.idEnderecoEstoque,
      a.idNumeroSerie),
  a.estabelecimento,
  a.gradeProduto,
  a.indicadorPropriedadePosseItem,
  a.pessoaParticipante,
  a.localEstoque,
  a.personalizacao,
  a.idLoteEstoque,
  a.idEnderecoEstoque,
  a.idNumeroSerie,
  SUM (a.quantidade),
  0 precoUnitarioCMV,
  0 precoUnitarioUltimaCompra,
  0 precoCustoUltimaCompra,
  0 precoCustoUltimaFormacao
FROM (
  SELECT DISTINCT
    itemInv.idItemInventarioEstoque id,
    invEst.estabelecimento,
    itemInv.localEstoque,
    itemInv.indicadorPropriedadePosseItem,
    itemInv.pessoaParticipante,
    itemInv.gradeProduto,
    itemInv.personalizacao,
    itemInv.idLoteEstoque,
    itemInv.idEnderecoEstoque,
    CASE WHEN prod.controlaNumeroSerie = 1 THEN itemInv.idNumeroSerie ELSE 0 END idNumeroSerie,
    itemInv.quantidade,
    gradProd.produto,
    gradProd.cor,
    gradProd.tamanho
  FROM MOINVENTARIOESTOQUEXITENS itemInv
  JOIN MOINVENTARIOSESTOQUE invEst
  ON invEst.inventarioEstoque = itemInv.inventarioEstoque
  JOIN DATAINVENTARIOSESTOQUE dataInv
  ON dataInv.inventarioEstoque = itemInv.inventarioEstoque
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = itemInv.gradeProduto'
|| v_prod_join
|| CASE
     WHEN p_inventario_join IS NULL OR p_inventario_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_join)
   END
|| '
  WHERE NOT (EXISTS(
    SELECT 1
    FROM DATAINVENTARIOESTOQUEXITENS dataInvGer
    WHERE dataInvGer.estabelecimento = invEst.estabelecimento
    AND dataInvGer.produto = gradProd.produto))
  AND NOT (EXISTS(
    SELECT 1
    FROM DATAESTOQUEINICIAL dataEstInic
    WHERE dataEstInic.estabelecimento = invEst.estabelecimento
    AND dataEstInic.produto = gradProd.produto))'
|| v_prod_andWhere
|| CASE
     WHEN p_inventario_andWhere IS NULL OR p_inventario_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_andWhere)
   END
|| '
  UNION ALL
  SELECT DISTINCT
    itemInv.idItemInventarioEstoque id,
    invEst.estabelecimento,
    itemInv.localEstoque,
    itemInv.indicadorPropriedadePosseItem,
    itemInv.pessoaParticipante,
    itemInv.gradeProduto,
    itemInv.personalizacao,
    itemInv.idLoteEstoque,
    itemInv.idEnderecoEstoque,
    CASE WHEN prod.controlaNumeroSerie = 1 THEN itemInv.idNumeroSerie ELSE 0 END idNumeroSerie,
    itemInv.quantidade,
    gradProd.produto,
    gradProd.cor,
    gradProd.tamanho
  FROM MOINVENTARIOESTOQUEXITENS itemInv
  JOIN MOINVENTARIOSESTOQUE invEst
  ON invEst.inventarioEstoque = itemInv.inventarioEstoque
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = itemInv.gradeProduto
  JOIN DATAINVENTARIOESTOQUEXITENS dataInvGer
  ON dataInvGer.inventarioEstoque = itemInv.inventarioEstoque
  AND dataInvGer.produto = gradProd.produto'
|| v_prod_join
|| CASE
     WHEN p_inventario_join IS NULL OR p_inventario_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_join)
   END
|| '
  WHERE NOT (EXISTS(
    SELECT 1
    FROM DATAESTOQUEINICIAL dataEstInic
    WHERE dataEstInic.estabelecimento = invEst.estabelecimento
    AND dataEstInic.produto = gradProd.produto))'
|| v_prod_andWhere
|| CASE
     WHEN p_inventario_andWhere IS NULL OR p_inventario_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_inventario_andWhere)
   END
|| '
  UNION ALL
  SELECT DISTINCT
    mov.idEstoque id,
    mov.estabelecimento,
    mov.localEstoque,
    mov.indicadorPropriedadePosseItem,
    mov.pessoaParticipante,
    mov.gradeProduto,
    mov.personalizacao,
    mov.idLoteEstoque,
    mov.idEnderecoEstoque,
    CASE WHEN prod.controlaNumeroSerie = 1 THEN mov.idNumeroSerie ELSE 0 END idNumeroSerie,
    mov.quantidade * CASE WHEN mov.entradaSaida = ''S'' THEN -1 ELSE 1 END quantidade,
    gradProd.produto,
    gradProd.cor,
    gradProd.tamanho
  FROM MOESTOQUES mov
  JOIN CAGRADESPRODUTO gradProd
  ON gradProd.gradeProduto = mov.gradeProduto'
|| v_prod_join
|| CASE
     WHEN p_movimentos_join IS NULL OR p_movimentos_join = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_movimentos_join)
   END
|| '
  WHERE mov.data < TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY'') + 1
  AND mov.data >= COALESCE((
    SELECT MAX (dataEstInic.data)
    FROM DATAESTOQUEINICIAL dataEstInic
    WHERE dataEstInic.estabelecimento = mov.estabelecimento
    AND dataEstInic.produto = gradProd.produto),
    COALESCE((
      SELECT MAX (dataInvGer.data) + 1
      FROM DATAINVENTARIOESTOQUEXITENS dataInvGer
      WHERE dataInvGer.estabelecimento = mov.estabelecimento
      AND dataInvGer.produto = gradProd.produto),
      COALESCE((
        SELECT MAX (dataInv.data) + 1
        FROM DATAINVENTARIOSESTOQUE dataInv
        WHERE dataInv.estabelecimento = mov.estabelecimento),
        TO_DATE (''01/01/1900'',''DD/MM/YYYY''))))'
|| CASE
     WHEN p_inEstabelecimentos IS NULL OR p_inEstabelecimentos = ' ' OR p_inEstabelecimentos = '0'
     THEN ''
     ELSE '
  AND mov.estabelecimento IN (' || TRIM(p_inEstabelecimentos) || ')'
   END
|| v_prod_andWhere
|| CASE
     WHEN p_movimentos_andWhere IS NULL OR p_movimentos_andWhere = ' '
     THEN ''
     ELSE '
    ' || RTRIM(p_movimentos_andWhere)
   END
|| ') a
GROUP BY
  a.gradeProduto,
  a.estabelecimento,
  a.localEstoque,
  a.indicadorPropriedadePosseItem,
  a.pessoaParticipante,
  a.personalizacao,
  a.idLoteEstoque,
  a.idEnderecoEstoque,
  a.idNumeroSerie,
  a.produto,
  a.cor,
  a.tamanho';
    IF p_buscarPrecoUnitarioCMV = 1
      AND p_config_335_cmvGerencIgualFis = 1
      AND p_contadorSessaoFiscal <> 0
    THEN
      EXECUTE IMMEDIATE 'BEGIN
  FOR a IN (
    SELECT
      a.uniqueMachineID,
      a.contadorSessao,
      a.estabelecimento,
      a.indicadorPropriedadePosseItem,
      a.pessoaParticipante,
      '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'a.gradeProduto'
           ELSE 'a.produto'
          END
      || ',
      COALESCE((
            SELECT MAX(b.precoUnitarioCMV)
            FROM TEMPINVENTARIOESTXFISCAL b'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ''
           ELSE '
            JOIN CAGRADESPRODUTO gradProd
            ON gradProd.gradeProduto = b.gradeProduto'
          END
      || '
            WHERE b.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
            AND b.contadorSessao = ' || TO_CHAR(p_contadorSessaoFiscal) || '
            AND (b.estabelecimento = a.estabelecimento
              OR EXISTS (
                SELECT 1
                FROM PAESTABELECIMENTOS est
                JOIN PAESTABELECIMENTOS est2
                ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
                WHERE est.estabelecimento = b.estabelecimento
                AND est.ativo = 1
                AND est.pessoaEstabelecimento > 0
                AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
              OR EXISTS (
                SELECT 1
                FROM PAESTABELECIMENTOS est
                JOIN CAPESSOAS pessEst
                ON pessEst.pessoa = est.pessoaEstabelecimento
                JOIN CAPESSOAS pessEst2
                ON pessEst2.grupoEconomico = pessEst.grupoEconomico
                JOIN PAESTABELECIMENTOS est2
                ON est2.pessoaEstabelecimento = pessEst2.pessoa
                WHERE est.estabelecimento = b.estabelecimento
                AND est.ativo = 1
                AND est.pessoaEstabelecimento > 0
                AND pessEst.grupoEconomico > 0
                AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
            AND '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'b.gradeProduto = a.gradeProduto'
           ELSE 'gradProd.produto = a.produto'
          END
      || '),0) precoUnitarioCMV
    FROM (
      SELECT
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        MIN(a.estabelecimento) estabelecimento
      FROM TEMPINVENTARIOESTXGERENC a
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = a.gradeProduto
      JOIN PAESTABELECIMENTOS est
      ON est.estabelecimento = a.estabelecimento
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      WHERE a.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
      AND a.contadorSessao = ' || TO_CHAR(p_contadorSessaoGerencial) || '
      GROUP BY
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        CASE'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
          WHEN est.pessoaEstabelecimento <> 0
            AND pessEst.grupoEconomico <> 0
          THEN pessEst.grupoEconomico'
           ELSE ''
         END
      || '
          WHEN est.pessoaEstabelecimento <> 0
          THEN est.pessoaEstabelecimento
          ELSE a.estabelecimento
        END) a)
  LOOP
    UPDATE TEMPINVENTARIOESTXGERENC b
    SET b.precoUnitarioCMV = a.precoUnitarioCMV
    WHERE b.uniqueMachineID = a.uniqueMachineID 
    AND b.contadorSessao = a.contadorSessao
    AND (b.estabelecimento = a.estabelecimento
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst
        ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2
        ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND pessEst.grupoEconomico > 0
        AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
    AND b.indicadorPropriedadePosseItem = a.indicadorPropriedadePosseItem
    AND b.pessoaParticipante = a.pessoaParticipante'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN '
    AND b.gradeProduto = a.gradeProduto'
           ELSE '
    AND EXISTS(
      SELECT 1
      FROM CAGRADESPRODUTO gradProd
      WHERE gradProd.gradeProduto = b.gradeProduto
      AND gradProd.produto = a.produto)'
          END
      || ';
  END LOOP;
END;';
    ELSIF p_buscarPrecoUnitarioCMV = 1
      AND p_config_335_cmvGerencIgualFis = 1
    THEN
      EXECUTE IMMEDIATE 'BEGIN
  FOR a IN (
    SELECT
      a.uniqueMachineID,
      a.contadorSessao,
      a.estabelecimento,
      a.indicadorPropriedadePosseItem,
      a.pessoaParticipante,
      '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'a.gradeProduto'
           ELSE 'a.produto'
          END
      || ',
      FUNC_ADD_BUSCA_PRECO_MEDIO_FIS(
        ' || TO_CHAR(p_config_209_filtrarGrupoEcon) || ', -- p_config_209_filtrarGrupoEcon
        ' || TO_CHAR(p_config_362_calcCustoPorGrade) || ', -- p_config_362_calcCustoPorGrade
        a.estabelecimento,
        TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY''), -- p_dataFinal
        a.pessoaParticipante,
        a.produto,
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.cor' ELSE '0' END || ',
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.tamanho' ELSE ''' ''' END || ',
        a.indicadorPropriedadePosseItem,
        ' || TO_CHAR(p_gerandoInventario) || ' -- p_gerandoInventario
      ) precoUnitarioCMV
    FROM (
      SELECT
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        MIN(a.estabelecimento) estabelecimento
      FROM TEMPINVENTARIOESTXGERENC a
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = a.gradeProduto
      JOIN PAESTABELECIMENTOS est
      ON est.estabelecimento = a.estabelecimento
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      WHERE a.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
      AND a.contadorSessao = ' || TO_CHAR(p_contadorSessaoGerencial) || '
      GROUP BY
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        CASE'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
          WHEN est.pessoaEstabelecimento <> 0
            AND pessEst.grupoEconomico <> 0
          THEN pessEst.grupoEconomico'
           ELSE ''
         END
      || '
          WHEN est.pessoaEstabelecimento <> 0
          THEN est.pessoaEstabelecimento
          ELSE a.estabelecimento
        END) a)
  LOOP
    UPDATE TEMPINVENTARIOESTXGERENC b
    SET b.precoUnitarioCMV = a.precoUnitarioCMV
    WHERE b.uniqueMachineID = a.uniqueMachineID 
    AND b.contadorSessao = a.contadorSessao
    AND (b.estabelecimento = a.estabelecimento
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst
        ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2
        ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND pessEst.grupoEconomico > 0
        AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
    AND b.indicadorPropriedadePosseItem = a.indicadorPropriedadePosseItem
    AND b.pessoaParticipante = a.pessoaParticipante'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN '
    AND b.gradeProduto = a.gradeProduto'
           ELSE '
    AND EXISTS(
      SELECT 1
      FROM CAGRADESPRODUTO gradProd
      WHERE gradProd.gradeProduto = b.gradeProduto
      AND gradProd.produto = a.produto)'
          END
      || ';
  END LOOP;
END;';
     ELSIF p_buscarPrecoUnitarioCMV = 1
     THEN
      EXECUTE IMMEDIATE 'BEGIN
  FOR a IN (
    SELECT
      a.uniqueMachineID,
      a.contadorSessao,
      a.estabelecimento,
      a.indicadorPropriedadePosseItem,
      a.pessoaParticipante,
      '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'a.gradeProduto,
      a.personalizacao'
           ELSE 'a.produto'
          END
      || ',
      (FUNC_ADD_BUSCA_PRECO_MEDIO_GER(
        ' || TO_CHAR(p_config_209_filtrarGrupoEcon) || ', -- p_config_209_filtrarGrupoEcon
        ' || TO_CHAR(p_config_362_calcCustoPorGrade) || ', -- p_config_362_calcCustoPorGrade
        a.estabelecimento,
        TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY''), -- p_dataFinal
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.personalizacao' ELSE '0' END || ',
        a.pessoaParticipante,
        a.produto,
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.cor' ELSE '0' END || ',
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.tamanho' ELSE ''' ''' END || ',
        a.indicadorPropriedadePosseItem,
        ' || TO_CHAR(p_gerandoInventario) || ') -- p_gerandoInventario'
      || CASE
           WHEN p_contadorSessaoFiscal <> 0
             AND p_invEst_motivoInventario = '02'
           THEN '
        - COALESCE((
            SELECT MAX(b.valorICMS)
            FROM TEMPINVENTARIOESTXFISCAL b'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ''
           ELSE '
            JOIN CAGRADESPRODUTO gradProd
            ON gradProd.gradeProduto = b.gradeProduto'
          END
      || '
            WHERE b.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
            AND b.contadorSessao = ' || TO_CHAR(p_contadorSessaoFiscal) || '
            AND (b.estabelecimento = a.estabelecimento
              OR EXISTS (
                SELECT 1
                FROM PAESTABELECIMENTOS est
                JOIN PAESTABELECIMENTOS est2
                ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
                WHERE est.estabelecimento = b.estabelecimento
                AND est.ativo = 1
                AND est.pessoaEstabelecimento > 0
                AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
              OR EXISTS (
                SELECT 1
                FROM PAESTABELECIMENTOS est
                JOIN CAPESSOAS pessEst
                ON pessEst.pessoa = est.pessoaEstabelecimento
                JOIN CAPESSOAS pessEst2
                ON pessEst2.grupoEconomico = pessEst.grupoEconomico
                JOIN PAESTABELECIMENTOS est2
                ON est2.pessoaEstabelecimento = pessEst2.pessoa
                WHERE est.estabelecimento = b.estabelecimento
                AND est.ativo = 1
                AND est.pessoaEstabelecimento > 0
                AND pessEst.grupoEconomico > 0
                AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
            AND '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'b.gradeProduto = a.gradeProduto'
           ELSE 'gradProd.produto = a.produto'
          END
      || '),0)'
           ELSE ''
         END
      || '
      ) precoUnitarioCMV
    FROM (
      SELECT
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        a.personalizacao,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        MIN(a.estabelecimento) estabelecimento
      FROM TEMPINVENTARIOESTXGERENC a
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = a.gradeProduto
      JOIN PAESTABELECIMENTOS est
      ON est.estabelecimento = a.estabelecimento
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      WHERE a.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
      AND a.contadorSessao = ' || TO_CHAR(p_contadorSessaoGerencial) || '
      GROUP BY
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        a.personalizacao,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        CASE'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
          WHEN est.pessoaEstabelecimento <> 0
            AND pessEst.grupoEconomico <> 0
          THEN pessEst.grupoEconomico'
           ELSE ''
         END
      || '
          WHEN est.pessoaEstabelecimento <> 0
          THEN est.pessoaEstabelecimento
          ELSE a.estabelecimento
        END) a)
  LOOP
    UPDATE TEMPINVENTARIOESTXGERENC b
    SET b.precoUnitarioCMV = a.precoUnitarioCMV
    WHERE b.uniqueMachineID = a.uniqueMachineID 
    AND b.contadorSessao = a.contadorSessao
    AND (b.estabelecimento = a.estabelecimento
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst
        ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2
        ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND pessEst.grupoEconomico > 0
        AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
    AND b.indicadorPropriedadePosseItem = a.indicadorPropriedadePosseItem
    AND b.pessoaParticipante = a.pessoaParticipante'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN '
    AND b.gradeProduto = a.gradeProduto
    AND b.personalizacao = a.personalizacao'
           ELSE '
    AND EXISTS(
      SELECT 1
      FROM CAGRADESPRODUTO gradProd
      WHERE gradProd.gradeProduto = b.gradeProduto
      AND gradProd.produto = a.produto)'
          END
      || ';
  END LOOP;
END;';
   END IF;
    IF p_buscarPrecoUnitUltimaCompra = 1 THEN
      EXECUTE IMMEDIATE 'BEGIN
  FOR a IN (
    SELECT
      a.uniqueMachineID,
      a.contadorSessao,
      a.estabelecimento,
      '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'a.gradeProduto,
      a.personalizacao'
           ELSE 'a.produto'
          END
      || ',
      (FUNC_ADD_BUSCA_PRECO_ULT_COMPR(
        ' || TO_CHAR(p_config_209_filtrarGrupoEcon) || ', -- p_config_209_filtrarGrupoEcon
        ' || TO_CHAR(p_config_362_calcCustoPorGrade) || ', -- p_config_362_calcCustoPorGrade
        a.estabelecimento,
        NULL, -- p_dataInicial
        TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY''), -- p_dataFinal
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.personalizacao' ELSE '0' END || ',
        a.produto,
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.cor' ELSE '0' END || ',
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.tamanho' ELSE ''' ''' END || ',
        0, -- p_retornarPrecoBruto
        ' || TO_CHAR(p_gerandoInventario) || ') -- p_gerandoInventario'
      || CASE
           WHEN p_contadorSessaoFiscal <> 0
             AND p_invEst_motivoInventario = '02'
           THEN '
        - COALESCE((
            SELECT MAX(b.valorICMS)
            FROM TEMPINVENTARIOESTXFISCAL b'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ''
           ELSE '
            JOIN CAGRADESPRODUTO gradProd
            ON gradProd.gradeProduto = b.gradeProduto'
          END
      || '
            WHERE b.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
            AND b.contadorSessao = ' || TO_CHAR(p_contadorSessaoFiscal) || '
            AND (b.estabelecimento = a.estabelecimento
              OR EXISTS (
                SELECT 1
                FROM PAESTABELECIMENTOS est
                JOIN PAESTABELECIMENTOS est2
                ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
                WHERE est.estabelecimento = b.estabelecimento
                AND est.ativo = 1
                AND est.pessoaEstabelecimento > 0
                AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
              OR EXISTS (
                SELECT 1
                FROM PAESTABELECIMENTOS est
                JOIN CAPESSOAS pessEst
                ON pessEst.pessoa = est.pessoaEstabelecimento
                JOIN CAPESSOAS pessEst2
                ON pessEst2.grupoEconomico = pessEst.grupoEconomico
                JOIN PAESTABELECIMENTOS est2
                ON est2.pessoaEstabelecimento = pessEst2.pessoa
                WHERE est.estabelecimento = b.estabelecimento
                AND est.ativo = 1
                AND est.pessoaEstabelecimento > 0
                AND pessEst.grupoEconomico > 0
                AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
            AND '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'b.gradeProduto = a.gradeProduto'
           ELSE 'gradProd.produto = a.produto'
          END
      || '),0)'
           ELSE ''
         END
      || '
      ) precoUnitarioUltimaCompra
    FROM (
      SELECT
        a.uniqueMachineID,
        a.contadorSessao,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        a.personalizacao,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        MIN(a.estabelecimento) estabelecimento
      FROM TEMPINVENTARIOESTXGERENC a
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = a.gradeProduto
      JOIN PAESTABELECIMENTOS est
      ON est.estabelecimento = a.estabelecimento
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      WHERE a.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
      AND a.contadorSessao = ' || TO_CHAR(p_contadorSessaoGerencial) || '
      GROUP BY
        a.uniqueMachineID,
        a.contadorSessao,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        a.personalizacao,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        CASE'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
          WHEN est.pessoaEstabelecimento <> 0
            AND pessEst.grupoEconomico <> 0
          THEN pessEst.grupoEconomico'
           ELSE ''
         END
      || '
          WHEN est.pessoaEstabelecimento <> 0
          THEN est.pessoaEstabelecimento
          ELSE a.estabelecimento
        END) a)
  LOOP
    UPDATE TEMPINVENTARIOESTXGERENC b
    SET b.precoUnitarioUltimaCompra = a.precoUnitarioUltimaCompra
    WHERE b.uniqueMachineID = a.uniqueMachineID 
    AND b.contadorSessao = a.contadorSessao
    AND (b.estabelecimento = a.estabelecimento
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst
        ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2
        ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND pessEst.grupoEconomico > 0
        AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN '
    AND b.gradeProduto = a.gradeProduto
    AND b.personalizacao = a.personalizacao'
           ELSE '
    AND EXISTS(
      SELECT 1
      FROM CAGRADESPRODUTO gradProd
      WHERE gradProd.gradeProduto = b.gradeProduto
      AND gradProd.produto = a.produto)'
          END
      || ';
  END LOOP;
END;';
    END IF;
    IF p_buscarPrecoCustoUltimaCompra = 1 THEN
      EXECUTE IMMEDIATE 'BEGIN
  FOR a IN (
    SELECT
      a.uniqueMachineID,
      a.contadorSessao,
      a.estabelecimento,
      a.indicadorPropriedadePosseItem,
      a.pessoaParticipante,
      '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'a.gradeProduto,
      a.personalizacao'
           ELSE 'a.produto'
          END
      || ',
      (FUNC_ADD_BUSCA_PRECO_ULT_CUSTO(
        ' || TO_CHAR(p_config_209_filtrarGrupoEcon) || ', -- p_config_209_filtrarGrupoEcon
        ' || TO_CHAR(p_config_362_calcCustoPorGrade) || ', -- p_config_362_calcCustoPorGrade
        a.estabelecimento,
        NULL, -- p_dataInicial
        TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY''), -- p_dataFinal
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.personalizacao' ELSE '0' END || ',
        a.pessoaParticipante,
        a.produto,
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.cor' ELSE '0' END || ',
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.tamanho' ELSE ''' ''' END || ',
        a.indicadorPropriedadePosseItem,
        ' || TO_CHAR(p_gerandoInventario) || ') -- p_gerandoInventario'
      || CASE
           WHEN p_contadorSessaoFiscal <> 0
             AND p_invEst_motivoInventario = '02'
           THEN '
        - COALESCE((
            SELECT MAX(b.valorICMS)
            FROM TEMPINVENTARIOESTXFISCAL b'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ''
           ELSE '
            JOIN CAGRADESPRODUTO gradProd
            ON gradProd.gradeProduto = b.gradeProduto'
          END
      || '
            WHERE b.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
            AND b.contadorSessao = ' || TO_CHAR(p_contadorSessaoFiscal) || '
            AND (b.estabelecimento = a.estabelecimento
              OR EXISTS (
                SELECT 1
                FROM PAESTABELECIMENTOS est
                JOIN PAESTABELECIMENTOS est2
                ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
                WHERE est.estabelecimento = b.estabelecimento
                AND est.ativo = 1
                AND est.pessoaEstabelecimento > 0
                AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
              OR EXISTS (
                SELECT 1
                FROM PAESTABELECIMENTOS est
                JOIN CAPESSOAS pessEst
                ON pessEst.pessoa = est.pessoaEstabelecimento
                JOIN CAPESSOAS pessEst2
                ON pessEst2.grupoEconomico = pessEst.grupoEconomico
                JOIN PAESTABELECIMENTOS est2
                ON est2.pessoaEstabelecimento = pessEst2.pessoa
                WHERE est.estabelecimento = b.estabelecimento
                AND est.ativo = 1
                AND est.pessoaEstabelecimento > 0
                AND pessEst.grupoEconomico > 0
                AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
            AND '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'b.gradeProduto = a.gradeProduto'
           ELSE 'gradProd.produto = a.produto'
          END
      || '),0)'
           ELSE ''
         END
      || '
      ) precoCustoUltimaCompra
    FROM (
      SELECT
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        a.personalizacao,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        MIN(a.estabelecimento) estabelecimento
      FROM TEMPINVENTARIOESTXGERENC a
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = a.gradeProduto
      JOIN PAESTABELECIMENTOS est
      ON est.estabelecimento = a.estabelecimento
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      WHERE a.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
      AND a.contadorSessao = ' || TO_CHAR(p_contadorSessaoGerencial) || '
      GROUP BY
        a.uniqueMachineID,
        a.contadorSessao,
        a.indicadorPropriedadePosseItem,
        a.pessoaParticipante,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        a.personalizacao,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        CASE'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
          WHEN est.pessoaEstabelecimento <> 0
            AND pessEst.grupoEconomico <> 0
          THEN pessEst.grupoEconomico'
           ELSE ''
         END
      || '
          WHEN est.pessoaEstabelecimento <> 0
          THEN est.pessoaEstabelecimento
          ELSE a.estabelecimento
        END) a)
  LOOP
    UPDATE TEMPINVENTARIOESTXGERENC b
    SET b.precoCustoUltimaCompra = a.precoCustoUltimaCompra
    WHERE b.uniqueMachineID = a.uniqueMachineID 
    AND b.contadorSessao = a.contadorSessao
    AND (b.estabelecimento = a.estabelecimento
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst
        ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2
        ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND pessEst.grupoEconomico > 0
        AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
    AND b.indicadorPropriedadePosseItem = a.indicadorPropriedadePosseItem
    AND b.pessoaParticipante = a.pessoaParticipante'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN '
    AND b.gradeProduto = a.gradeProduto
    AND b.personalizacao = a.personalizacao'
           ELSE '
    AND EXISTS(
      SELECT 1
      FROM CAGRADESPRODUTO gradProd
      WHERE gradProd.gradeProduto = b.gradeProduto
      AND gradProd.produto = a.produto)'
          END
      || ';
  END LOOP;
END;';
    END IF;
    IF p_buscarPrecoCustoUltimaFormac = 1 THEN
      EXECUTE IMMEDIATE 'BEGIN
  FOR a IN (
    SELECT
      a.uniqueMachineID,
      a.contadorSessao,
      a.estabelecimento,
      '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'a.gradeProduto,
      a.personalizacao'
           ELSE 'a.produto'
          END
      || ',
      (FUNC_ADD_BUSCA_PRECO_FORMACAO(
        ' || TO_CHAR(p_config_209_filtrarGrupoEcon) || ', -- p_config_209_filtrarGrupoEcon
        ' || TO_CHAR(p_config_362_calcCustoPorGrade) || ', -- p_config_362_calcCustoPorGrade
        a.estabelecimento,
        NULL, -- p_dataInicial
        TO_DATE(''' || TO_CHAR(p_invEst_data, 'DD/MM/YYYY') || ''', ''DD/MM/YYYY''), -- p_dataFinal
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.personalizacao' ELSE '0' END || ',
        a.produto,
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.cor' ELSE '0' END || ',
        ' || CASE WHEN p_config_362_calcCustoPorGrade = 1 THEN 'a.tamanho' ELSE ''' ''' END || ',
        ' || TO_CHAR(p_gerandoInventario) || ') -- p_gerandoInventario'
      || CASE
           WHEN p_contadorSessaoFiscal <> 0
             AND p_invEst_motivoInventario = '02'
           THEN '
        - COALESCE((
            SELECT MAX(b.valorICMS)
            FROM TEMPINVENTARIOESTXFISCAL b'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ''
           ELSE '
            JOIN CAGRADESPRODUTO gradProd
            ON gradProd.gradeProduto = b.gradeProduto'
          END
      || '
            WHERE b.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
            AND b.contadorSessao = ' || TO_CHAR(p_contadorSessaoFiscal) || '
            AND (b.estabelecimento = a.estabelecimento
              OR EXISTS (
                SELECT 1
                FROM PAESTABELECIMENTOS est
                JOIN PAESTABELECIMENTOS est2
                ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
                WHERE est.estabelecimento = b.estabelecimento
                AND est.ativo = 1
                AND est.pessoaEstabelecimento > 0
                AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
              OR EXISTS (
                SELECT 1
                FROM PAESTABELECIMENTOS est
                JOIN CAPESSOAS pessEst
                ON pessEst.pessoa = est.pessoaEstabelecimento
                JOIN CAPESSOAS pessEst2
                ON pessEst2.grupoEconomico = pessEst.grupoEconomico
                JOIN PAESTABELECIMENTOS est2
                ON est2.pessoaEstabelecimento = pessEst2.pessoa
                WHERE est.estabelecimento = b.estabelecimento
                AND est.ativo = 1
                AND est.pessoaEstabelecimento > 0
                AND pessEst.grupoEconomico > 0
                AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')
            AND '
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN 'b.gradeProduto = a.gradeProduto'
           ELSE 'gradProd.produto = a.produto'
          END
      || '),0)'
           ELSE ''
         END
      || '
      ) precoCustoUltimaFormacao
    FROM (
      SELECT
        a.uniqueMachineID,
        a.contadorSessao,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        a.personalizacao,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        MIN(a.estabelecimento) estabelecimento
      FROM TEMPINVENTARIOESTXGERENC a
      JOIN CAGRADESPRODUTO gradProd
      ON gradProd.gradeProduto = a.gradeProduto
      JOIN PAESTABELECIMENTOS est
      ON est.estabelecimento = a.estabelecimento
      JOIN CAPESSOAS pessEst
      ON pessEst.pessoa = est.pessoaEstabelecimento
      WHERE a.uniqueMachineID = ''' || CASE WHEN p_uniqueMachineID IS NULL OR p_uniqueMachineID = ' ' THEN ' ' ELSE RTRIM(p_uniqueMachineID) END || '''
      AND a.contadorSessao = ' || TO_CHAR(p_contadorSessaoGerencial) || '
      GROUP BY
        a.uniqueMachineID,
        a.contadorSessao,
        gradProd.produto'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN ',
        a.gradeProduto,
        a.personalizacao,
        gradProd.cor,
        gradProd.tamanho'
           ELSE ''
          END
      || ',
        CASE'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
          WHEN est.pessoaEstabelecimento <> 0
            AND pessEst.grupoEconomico <> 0
          THEN pessEst.grupoEconomico'
           ELSE ''
         END
      || '
          WHEN est.pessoaEstabelecimento <> 0
          THEN est.pessoaEstabelecimento
          ELSE a.estabelecimento
        END) a)
  LOOP
    UPDATE TEMPINVENTARIOESTXGERENC b
    SET b.precoCustoUltimaFormacao = a.precoCustoUltimaFormacao
    WHERE b.uniqueMachineID = a.uniqueMachineID 
    AND b.contadorSessao = a.contadorSessao
    AND (b.estabelecimento = a.estabelecimento
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = est.pessoaEstabelecimento
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND est2.estabelecimento = a.estabelecimento)'
      || CASE
           WHEN p_config_209_filtrarGrupoEcon = 1
           THEN '
      OR EXISTS (
        SELECT 1
        FROM PAESTABELECIMENTOS est
        JOIN CAPESSOAS pessEst
        ON pessEst.pessoa = est.pessoaEstabelecimento
        JOIN CAPESSOAS pessEst2
        ON pessEst2.grupoEconomico = pessEst.grupoEconomico
        JOIN PAESTABELECIMENTOS est2
        ON est2.pessoaEstabelecimento = pessEst2.pessoa
        WHERE est.estabelecimento = b.estabelecimento
        AND est.ativo = 1
        AND est.pessoaEstabelecimento > 0
        AND pessEst.grupoEconomico > 0
        AND est2.estabelecimento = a.estabelecimento)'
           ELSE ''
         END
      || ')'
      || CASE
           WHEN p_config_362_calcCustoPorGrade = 1
           THEN '
    AND b.gradeProduto = a.gradeProduto
    AND b.personalizacao = a.personalizacao'
           ELSE '
    AND EXISTS(
      SELECT 1
      FROM CAGRADESPRODUTO gradProd
      WHERE gradProd.gradeProduto = b.gradeProduto
      AND gradProd.produto = a.produto)'
          END
      || ';
  END LOOP;
END;';
    END IF;
  END IF;
END ADD_GERA_TEMP_INVENTARIO;

/

create or replace PROCEDURE ADD_EFETIVA_TEMP_INVENTARIO (
  p_uniqueMachineID              IN VARCHAR2,
  p_estabelecimentoAtivo         IN NUMBER,
  p_contadorSessaoFiscal         IN NUMBER,
  p_contadorSessaoGerencial      IN NUMBER,
  p_invEst_data                  IN DATE,
  p_invEst_motivoInventario      IN CHAR,
  p_invEst_observacoes           IN VARCHAR2,
  p_inEstabelecimentos           IN VARCHAR2)
IS
  v_idInventarioEstoque NUMBER;
BEGIN
  FOR estab IN (
    SELECT estabelecimento
    FROM PAESTABELECIMENTOS
    WHERE estabelecimento > 0
    AND ((p_inEstabelecimentos IS NULL
        OR p_inEstabelecimentos = ' '
        OR p_inEstabelecimentos = '0')
      AND ativo = 1
      OR NOT(p_inEstabelecimentos IS NULL)
      AND p_inEstabelecimentos <> ' '
      AND p_inEstabelecimentos <> '0'
      AND INSTR(',' || RTRIM(p_inEstabelecimentos) || ',', ',' || TRIM(TO_CHAR(estabelecimento)) || ',') > 0)
    ORDER BY estabelecimento)
  LOOP
    v_idInventarioEstoque := FUNC_ADD_BUSCA_PROXIMO_ID('MOINVENTARIOSESTOQUE', 'inventarioEstoque', 0, p_estabelecimentoAtivo, NULL);
    INSERT INTO MOINVENTARIOSESTOQUE (
      inventarioEstoque,
      estabelecimento,
      data,
      motivoInventarioEstoque,
      observacoes)
    VALUES (
      v_idInventarioEstoque,
      estab.estabelecimento,
      p_invEst_data,
      COALESCE(p_invEst_motivoInventario,'01'),
      COALESCE(p_invEst_observacoes,' '));
    INSERT INTO MOINVENTARIOESTOQUEXFISC (
      id,
      inventarioEstoque,
      gradeProduto,
      indicadorPropriedadePosseItem,
      pessoaParticipante,
      quantidade,
      precoUnitarioCMV,
      stICMS,
      baseICMS,
      valorICMS)
    SELECT
      FUNC_ADD_BUSCA_PROXIMO_ID('MOINVENTARIOESTOQUEXFISC', 'id', 0, p_estabelecimentoAtivo, NULL),
      v_idInventarioEstoque,
      temp.gradeProduto,
      temp.indicadorPropriedadePosseItem,
      temp.pessoaParticipante,
      CASE WHEN temp.quantidade < 0 THEN 0 ELSE temp.quantidade END,
      temp.precoUnitarioCMV,
      temp.stICMS,
      temp.baseICMS,
      temp.valorICMS
    FROM TEMPINVENTARIOESTXFISCAL temp
    WHERE temp.uniqueMachineID = p_uniqueMachineID
    AND temp.contadorSessao = p_contadorSessaoFiscal
    AND temp.estabelecimento = estab.estabelecimento;
    INSERT INTO MOINVENTARIOESTOQUEXITENS (
      idItemInventarioEstoque,
      inventarioEstoque,
      gradeProduto,
      indicadorPropriedadePosseItem,
      pessoaParticipante,
      localEstoque,
      personalizacao,
      idLoteEstoque,
      idEnderecoEstoque,
      idNumeroSerie,
      quantidade,
      precoUnitarioCMV,
      precoUnitarioUltimaCompra,
      precoCustoUltimaCompra,
      precoCustoUltimaFormacao)
    SELECT
      FUNC_ADD_BUSCA_PROXIMO_ID('MOINVENTARIOESTOQUEXITENS', 'idItemInventarioEstoque', 0, p_estabelecimentoAtivo, NULL),
      v_idInventarioEstoque,
      temp.gradeProduto,
      temp.indicadorPropriedadePosseItem,
      temp.pessoaParticipante,
      temp.localEstoque,
      temp.personalizacao,
      temp.idLoteEstoque,
      temp.idEnderecoEstoque,
      temp.idNumeroSerie,
      CASE WHEN temp.quantidade < 0 THEN 0 ELSE temp.quantidade END,
      temp.precoUnitarioCMV,
      temp.precoUnitarioUltimaCompra,
      temp.precoCustoUltimaCompra,
      temp.precoCustoUltimaFormacao
    FROM TEMPINVENTARIOESTXGERENC temp
    WHERE temp.uniqueMachineID = p_uniqueMachineID
    AND temp.contadorSessao = p_contadorSessaoGerencial
    AND temp.estabelecimento = estab.estabelecimento;
  END LOOP;
END ADD_EFETIVA_TEMP_INVENTARIO;

/

create or replace PROCEDURE ADD_ORCAMENTO_REGRA_DESC_PAG (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_246_baseDescontoPagam IN CHAR,
  p_config_337_descontoSobreFret IN NUMBER,
  p_orcamento                    IN NUMBER,
  p_soma_valorPagamentoBruto     IN NUMBER,
  p_pag_meioPagamento            IN NUMBER,
  p_pag_condicaoPagamento        IN NUMBER,
  p_pag_valorPagamentoBruto      IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_percentualDescontoSugestao   OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      CASE
        WHEN p_config_246_baseDescontoPagam = 'S'
        THEN a.valorBasePagamento
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE a.valorFreteTotal + a.valorSeguroTotal
            END
        WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
        THEN 0
        WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
        THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * (a.valorBasePagamento - p_soma_valorPagamentoBruto)
                / a.valorBasePagamento,2)
            END
        ELSE p_pag_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * p_pag_valorPagamentoBruto
                / a.valorBasePagamento,2)
            END
      END valorBaseDesconto,
      ( CASE
          WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
          THEN 0
          WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
          THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          ELSE p_pag_valorPagamentoBruto
        END
        / a.valorBasePagamento) proporcaoPagamento
    FROM (
      SELECT
        a.estabelecimento,
        a.pessoa,
        a.valorBasePagamento,
        a.tipoPagamentoFrete,
        a.valorFreteTotal,
        a.valorSeguroTotal
      FROM MOORCAMENTOS a
      WHERE a.orcamento = p_orcamento
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MOORCAMENTOXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.orcamento = p_orcamento
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBaseDesconto,
      cab.proporcaoPagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'P'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))
    -- Filtro Pagamento
    AND (a.filtroPagamento = 0
      OR (filtroPag.filtrarMeiosPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXMEIOPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.meioPagamento = p_pag_meioPagamento
          AND filtroPagX.ativo = 1))
      AND (filtroPag.filtrarCondicoesPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXCONDPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.condicaoPagamento = p_pag_condicaoPagamento
          AND filtroPagX.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem,
      b.valorDescontoGeral
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBaseDesconto,
      a.proporcaoPagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND((
      CASE
        WHEN MIN (a.valorDescontoSugestao) < 0
          OR SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
          OR SUM(a.valorBaseDescontoSugestao) <> MAX(a.valorBaseDesconto)
          OR SUM(a.valorDescontoItem) <> 0
          OR SUM(a.valorDescontoGeral) <> 0
          OR SUM(a.possuiRegra) > 1
        THEN 100
          * ROUND(
              CASE
                WHEN SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END) >= p_pag_valorPagamentoBruto
                THEN p_pag_valorPagamentoBruto - 0.01
                ELSE SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END)
              END, 2) / MAX(a.valorBaseDesconto)
        ELSE MAX(a.percentualDescontoSugestao)
      END), 8), 0) percentualDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_percentualDescontoSugestao,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBaseDesconto,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra
          -- Desconto em valor
          WHEN 2
          THEN a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseDesconto
          ELSE 0
        END, 2) valorBaseDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorSugestao
          -- Desconto em valor
          WHEN 2
          THEN 100 * a.valorSugestao * a.multiplicador / a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN 100 * (a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)) / a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.idade
          -- Desconto igual a idade em valor
          WHEN 5
          THEN 100 * a.idade * a.multiplicador / a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN 100 * a.valorBaseRegra / a.valorBaseDesconto
          ELSE 0
        END, 8) percentualDescontoSugestao,
      ROUND (
        ( CASE a.tipoRegraDescontoMargem
            -- Desconto em percentual
            WHEN 1
            THEN a.valorBaseRegra * a.valorSugestao / 100
            -- Desconto em valor
            WHEN 2
            THEN a.valorSugestao * a.multiplicador
             -- Preço unitário fixo
            WHEN 3
            THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
            -- Desconto igual a idade em percentual
            WHEN 4
            THEN a.valorBaseRegra * a.idade / 100
            -- Desconto igual a idade em valor
            WHEN 5
            THEN a.idade * a.multiplicador
            -- Preço total fixado
            WHEN 6
            THEN a.valorBaseRegra
            ELSE 0
          END
          - a.valorDescontoItem
          - a.valorDescontoGeral)
        * a.proporcaoPagamento, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END * a.proporcaoPagamento, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem - a.valorDescontoGeral)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem,
        SUM (a.valorDescontoGeral) valorDescontoGeral
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          0 valorDescontoGeral,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos,
          b.valorDescontoGeral valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento) a) a;
END ADD_ORCAMENTO_REGRA_DESC_PAG;

/

create or replace PROCEDURE ADD_PRE_DOC_REGRA_DESC_PAG (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_config_246_baseDescontoPagam IN CHAR,
  p_config_337_descontoSobreFret IN NUMBER,
  p_preDocumento                 IN NUMBER,
  p_soma_valorPagamentoBruto     IN NUMBER,
  p_orc_pessoa                   IN NUMBER,
  p_pag_meioPagamento            IN NUMBER,
  p_pag_condicaoPagamento        IN NUMBER,
  p_pag_valorPagamentoBruto      IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_percentualDescontoSugestao   OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      CASE
        WHEN p_config_246_baseDescontoPagam = 'S'
        THEN a.valorBasePagamento
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE a.valorFreteTotal + a.valorSeguroTotal
            END
        WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
        THEN 0
        WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
        THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * (a.valorBasePagamento - p_soma_valorPagamentoBruto)
                / a.valorBasePagamento,2)
            END
        ELSE p_pag_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * p_pag_valorPagamentoBruto
                / a.valorBasePagamento,2)
            END
      END valorBaseDesconto,
      ( CASE
          WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
          THEN 0
          WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
          THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          ELSE p_pag_valorPagamentoBruto
        END
        / a.valorBasePagamento) proporcaoPagamento
    FROM (
      SELECT
        a.estabelecimento,
        CASE
          WHEN p_orc_pessoa = 0
            OR p_config_227_manterPessoaOrcam = 1
          THEN a.pessoa
          ELSE p_orc_pessoa
        END pessoa,
        a.valorBasePagamento,
        a.tipoPagamentoFrete,
        a.valorFreteTotal,
        a.valorSeguroTotal
      FROM MOPREDOCUMENTOS a
      WHERE a.preDocumento = p_preDocumento
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MOPREDOCUMXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.preDocumento = p_preDocumento
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBaseDesconto,
      cab.proporcaoPagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'P'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))
    -- Filtro Pagamento
    AND (a.filtroPagamento = 0
      OR (filtroPag.filtrarMeiosPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXMEIOPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.meioPagamento = p_pag_meioPagamento
          AND filtroPagX.ativo = 1))
      AND (filtroPag.filtrarCondicoesPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXCONDPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.condicaoPagamento = p_pag_condicaoPagamento
          AND filtroPagX.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem,
      b.valorDescontoGeral
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBaseDesconto,
      a.proporcaoPagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND((
      CASE
        WHEN MIN (a.valorDescontoSugestao) < 0
          OR SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
          OR SUM(a.valorBaseDescontoSugestao) <> MAX(a.valorBaseDesconto)
          OR SUM(a.valorDescontoItem) <> 0
          OR SUM(a.valorDescontoGeral) <> 0
          OR SUM(a.possuiRegra) > 1
        THEN 100
          * ROUND(
              CASE
                WHEN SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END) >= p_pag_valorPagamentoBruto
                THEN p_pag_valorPagamentoBruto - 0.01
                ELSE SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END)
              END, 2) / MAX(a.valorBaseDesconto)
        ELSE MAX(a.percentualDescontoSugestao)
      END), 8), 0) percentualDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_percentualDescontoSugestao,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBaseDesconto,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra
          -- Desconto em valor
          WHEN 2
          THEN a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseDesconto
          ELSE 0
        END, 2) valorBaseDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorSugestao
          -- Desconto em valor
          WHEN 2
          THEN 100 * a.valorSugestao * a.multiplicador / a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN 100 * (a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)) / a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.idade
          -- Desconto igual a idade em valor
          WHEN 5
          THEN 100 * a.idade * a.multiplicador / a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN 100 * a.valorBaseRegra / a.valorBaseDesconto
          ELSE 0
        END, 8) percentualDescontoSugestao,
      ROUND (
        ( CASE a.tipoRegraDescontoMargem
            -- Desconto em percentual
            WHEN 1
            THEN a.valorBaseRegra * a.valorSugestao / 100
            -- Desconto em valor
            WHEN 2
            THEN a.valorSugestao * a.multiplicador
             -- Preço unitário fixo
            WHEN 3
            THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
            -- Desconto igual a idade em percentual
            WHEN 4
            THEN a.valorBaseRegra * a.idade / 100
            -- Desconto igual a idade em valor
            WHEN 5
            THEN a.idade * a.multiplicador
            -- Preço total fixado
            WHEN 6
            THEN a.valorBaseRegra
            ELSE 0
          END
          - a.valorDescontoItem
          - a.valorDescontoGeral)
        * a.proporcaoPagamento, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END * a.proporcaoPagamento, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem - a.valorDescontoGeral)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem,
        SUM (a.valorDescontoGeral) valorDescontoGeral
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          0 valorDescontoGeral,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos,
          b.valorDescontoGeral valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento) a) a;
END ADD_PRE_DOC_REGRA_DESC_PAG;

/

create or replace PROCEDURE ADD_DOC_FISC_REGRA_DESC_PAG (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_config_246_baseDescontoPagam IN CHAR,
  p_config_337_descontoSobreFret IN NUMBER,
  p_idDocumentoFiscal            IN NUMBER,
  p_soma_valorPagamentoBruto     IN NUMBER,
  p_orc_pessoa                   IN NUMBER,
  p_pag_meioPagamento            IN NUMBER,
  p_pag_condicaoPagamento        IN NUMBER,
  p_pag_valorPagamentoBruto      IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_percentualDescontoSugestao   OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      CASE
        WHEN p_config_246_baseDescontoPagam = 'S'
        THEN a.valorBasePagamento
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE a.valorFreteTotal + a.valorSeguroTotal
            END
        WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
        THEN 0
        WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
        THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * (a.valorBasePagamento - p_soma_valorPagamentoBruto)
                / a.valorBasePagamento,2)
            END
        ELSE p_pag_valorPagamentoBruto
          - CASE
              WHEN p_config_337_descontoSobreFret = 1
                OR a.tipoPagamentoFrete = 'V'
              THEN 0
              ELSE ROUND (
                (a.valorFreteTotal + a.valorSeguroTotal)
                * p_pag_valorPagamentoBruto
                / a.valorBasePagamento,2)
            END
      END valorBaseDesconto,
      ( CASE
          WHEN p_soma_valorPagamentoBruto >= a.valorBasePagamento
          THEN 0
          WHEN p_soma_valorPagamentoBruto + p_pag_valorPagamentoBruto > a.valorBasePagamento
          THEN a.valorBasePagamento - p_soma_valorPagamentoBruto
          ELSE p_pag_valorPagamentoBruto
        END
        / a.valorBasePagamento) proporcaoPagamento
    FROM (
      SELECT
        a.estabelecimento,
        CASE
          WHEN p_orc_pessoa = 0
            OR p_config_227_manterPessoaOrcam = 1
          THEN a.pessoa
          ELSE p_orc_pessoa
        END pessoa,
        a.valorBasePagamento,
        a.tipoPagamentoFrete,
        a.valorFreteTotal,
        a.valorSeguroTotal
      FROM MODOCUMENTOSFISCAIS a
      WHERE a.idDocumentoFiscal = p_idDocumentoFiscal
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MODOCFISCALXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.idDocumentoFiscal = p_idDocumentoFiscal
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBaseDesconto,
      cab.proporcaoPagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'P'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))
    -- Filtro Pagamento
    AND (a.filtroPagamento = 0
      OR (filtroPag.filtrarMeiosPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXMEIOPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.meioPagamento = p_pag_meioPagamento
          AND filtroPagX.ativo = 1))
      AND (filtroPag.filtrarCondicoesPagamento = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPAGAMENTOXCONDPAG filtroPagX
          WHERE filtroPagX.filtroPagamento = a.filtroPagamento
          AND filtroPagX.condicaoPagamento = p_pag_condicaoPagamento
          AND filtroPagX.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem,
      b.valorDescontoGeral
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBaseDesconto,
      a.proporcaoPagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND((
      CASE
        WHEN MIN (a.valorDescontoSugestao) < 0
          OR SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
          OR SUM(a.valorBaseDescontoSugestao) <> MAX(a.valorBaseDesconto)
          OR SUM(a.valorDescontoItem) <> 0
          OR SUM(a.valorDescontoGeral) <> 0
          OR SUM(a.possuiRegra) > 1
        THEN 100
          * ROUND(
              CASE
                WHEN SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END) >= p_pag_valorPagamentoBruto
                THEN p_pag_valorPagamentoBruto - 0.01
                ELSE SUM (
                  CASE
                    WHEN a.valorDescontoSugestao < 0
                    THEN 0
                    ELSE a.valorDescontoSugestao
                  END)
              END, 2) / MAX(a.valorBaseDesconto)
        ELSE MAX(a.percentualDescontoSugestao)
      END), 8), 0) percentualDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= p_pag_valorPagamentoBruto
        THEN p_pag_valorPagamentoBruto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_percentualDescontoSugestao,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBaseDesconto,
      a.valorDescontoItem,
      a.valorDescontoGeral,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra
          -- Desconto em valor
          WHEN 2
          THEN a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseDesconto
          ELSE 0
        END, 2) valorBaseDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorSugestao
          -- Desconto em valor
          WHEN 2
          THEN 100 * a.valorSugestao * a.multiplicador / a.valorBaseDesconto
          -- Preço unitário fixo
          WHEN 3
          THEN 100 * (a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)) / a.valorBaseDesconto
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.idade
          -- Desconto igual a idade em valor
          WHEN 5
          THEN 100 * a.idade * a.multiplicador / a.valorBaseDesconto
          -- Preço total fixado
          WHEN 6
          THEN 100 * a.valorBaseRegra / a.valorBaseDesconto
          ELSE 0
        END, 8) percentualDescontoSugestao,
      ROUND (
        ( CASE a.tipoRegraDescontoMargem
            -- Desconto em percentual
            WHEN 1
            THEN a.valorBaseRegra * a.valorSugestao / 100
            -- Desconto em valor
            WHEN 2
            THEN a.valorSugestao * a.multiplicador
             -- Preço unitário fixo
            WHEN 3
            THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
            -- Desconto igual a idade em percentual
            WHEN 4
            THEN a.valorBaseRegra * a.idade / 100
            -- Desconto igual a idade em valor
            WHEN 5
            THEN a.idade * a.multiplicador
            -- Preço total fixado
            WHEN 6
            THEN a.valorBaseRegra
            ELSE 0
          END
          - a.valorDescontoItem
          - a.valorDescontoGeral)
        * a.proporcaoPagamento, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END * a.proporcaoPagamento, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem - a.valorDescontoGeral)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos - a.valorDescontoGeralTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem,
        SUM (a.valorDescontoGeral) valorDescontoGeral
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          b.valorDescontoGeral,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos,
          0 valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBaseDesconto,
          a.proporcaoPagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          0 valorDescontoGeral,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos,
          b.valorDescontoGeral valorDescontoGeralTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBaseDesconto,
        a.proporcaoPagamento) a) a;
END ADD_DOC_FISC_REGRA_DESC_PAG;

/

create or replace PROCEDURE ADD_ORCAMENTO_REGRA_DESC_CAB (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_orcamento                    IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      a.valorBasePagamento
    FROM (
      SELECT
        a.estabelecimento,
        a.pessoa,
        a.valorBasePagamento
      FROM MOORCAMENTOS a
      WHERE a.orcamento = p_orcamento
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MOORCAMENTOXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.orcamento = p_orcamento
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBasePagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'C'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBasePagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBasePagamento,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorSugestao / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorSugestao * a.multiplicador
           -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END - a.valorDescontoItem, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento) a) a;
END ADD_ORCAMENTO_REGRA_DESC_CAB;

/

create or replace PROCEDURE ADD_PRE_DOC_REGRA_DESC_CAB (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_preDocumento                 IN NUMBER,
  p_orc_pessoa                   IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      a.valorBasePagamento
    FROM (
      SELECT
        a.estabelecimento,
        CASE
          WHEN p_orc_pessoa = 0
            OR p_config_227_manterPessoaOrcam = 1
          THEN a.pessoa
          ELSE p_orc_pessoa
        END pessoa,
        a.valorBasePagamento
      FROM MOPREDOCUMENTOS a
      WHERE a.preDocumento = p_preDocumento
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MOPREDOCUMXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.preDocumento = p_preDocumento
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBasePagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'C'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBasePagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBasePagamento,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorSugestao / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorSugestao * a.multiplicador
           -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END - a.valorDescontoItem, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento) a) a;
END ADD_PRE_DOC_REGRA_DESC_CAB;

/

create or replace PROCEDURE ADD_DOC_FISC_REGRA_DESC_CAB (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_idDocumentoFiscal            IN NUMBER,
  p_orc_pessoa                   IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
BEGIN
  WITH
  CABECALHO AS (
    SELECT
      a.estabelecimento,
      a.pessoa,
      COALESCE((
        CASE
          WHEN a.pessoa = 0
          THEN (
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1)
          ELSE COALESCE((
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = a.pessoa
            AND endPess.ativo = 1
            AND endPess.principal = 1),(
            SELECT MAX(munPess.uf)
            FROM CAENDERECOSPESSOA endPess
            JOIN SIMUNICIPIOS munPess
            ON munPess.municipio = endPess.municipio
            WHERE endPess.pessoa = est.pessoaEstabelecimento
            AND endPess.ativo = 1
            AND endPess.principal = 1))
        END
      ),'  ') uf,
      CASE
        WHEN pess.nascimentoFundacao IS NULL
          OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
        THEN 0
        ELSE TRUNC (SYSDATE, 'YYYY')
          - TRUNC (pess.nascimentoFundacao, 'YYYY')
          - CASE
              WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
              THEN 1
              ELSE 0
            END
      END idade,
      a.valorBasePagamento
    FROM (
      SELECT
        a.estabelecimento,
        CASE
          WHEN p_orc_pessoa = 0
            OR p_config_227_manterPessoaOrcam = 1
          THEN a.pessoa
          ELSE p_orc_pessoa
        END pessoa,
        a.valorBasePagamento
      FROM MODOCUMENTOSFISCAIS a
      WHERE a.idDocumentoFiscal = p_idDocumentoFiscal
      AND a.valorBasePagamento > 0) a
    JOIN PAESTABELECIMENTOS est
    ON est.estabelecimento = a.estabelecimento
    JOIN CAPESSOAS pess
    ON pess.pessoa = a.pessoa),
  ITENS AS (
    SELECT
      a.sequencia,
      a.vendedor,
      a.gradeProduto,
      a.localEstoque,
      a.personalizacao,
      a.quantidade,
      ROUND (a.quantidade * (a.precoUnitarioBruto + a.acrescimoUnitarioComposicao),2) valorBaseRegra,
      a.valorDescontoItem,
      a.tabelaPreco,
      gradProd.produto,
      gradProd.cor,
      gradProd.tamanho,
      prod.subcategoriaProduto,
      prod.marca,
      prod.caracteristicaA,
      prod.caracteristicaB,
      prod.caracteristicaC,
      prod.caracteristicaD,
      prod.caracteristicaE,
      prod.idNcm,
      prod.listaServicos,
      subCatProd.categoriaProduto
    FROM MODOCFISCALXITENS a
    JOIN CAGRADESPRODUTO gradProd
    ON gradProd.gradeProduto = a.gradeProduto
    JOIN CAPRODUTOS prod
    ON prod.produto = gradProd.produto
    JOIN PASUBCATEGORIASPRODUTO subCatProd
    ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
    WHERE a.idDocumentoFiscal = p_idDocumentoFiscal
    AND a.cancelado = 0
    AND a.quantidade > 0),
  REGRAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      cab.idade,
      cab.valorBasePagamento
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN CABECALHO cab
    ON 1=1
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    JOIN CAPESSOAS pess
    ON pess.pessoa = cab.pessoa
    JOIN PAFILTROSPAGAMENTO filtroPag
    ON filtroPag.filtroPagamento = a.filtroPagamento
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'C'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = cab.estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = cab.uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = cab.pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = pess.indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (cab.pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = cab.pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND cab.pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = cab.pessoa
          AND colab.ativo = 1)))),
  FILTROSPRODUTOS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      b.quantidadeMinima,
      b.quantidadeMaxima,
      b.filtrarVendedores,
      b.filtrarLocaisEstoque,
      b.filtrarPersonalizacoes,
      b.filtrarProdutos,
      b.filtrarCategoriasProdutos,
      b.filtrarSubcategoriasProdutos,
      b.filtrarMarcas,
      b.filtrarCaracteristicasA,
      b.filtrarCaracteristicasB,
      b.filtrarCaracteristicasC,
      b.filtrarCaracteristicasD,
      b.filtrarCaracteristicasE,
      b.filtrarCores,
      b.filtrarTamanhos,
      b.filtrarNCMs,
      b.filtrarListasServicos,
      c.filtrarTabelaPreco
    FROM PAREGRADESCMARGXFILTPROD a
    JOIN PAFILTROSPRODUTO b
    ON b.filtroProduto = a.filtroProduto
    JOIN REGRAS c
    ON c.regraDescontoMargem = a.regraDescontoMargem
    AND a.filtroProduto > 0
    AND a.ativo = 1),
  REGRASXITENS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto,
      a.quantidadeMinima,
      a.quantidadeMaxima,
      b.sequencia,
      b.quantidade,
      b.valorBaseRegra,
      b.valorDescontoItem
    FROM FILTROSPRODUTOS a
    JOIN ITENS b
	  ON 1=1
    WHERE (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = b.tabelaPreco
        AND x.ativo = 1))
    AND (a.filtrarVendedores = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXVENDEDOR x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.vendedor = b.vendedor
      AND x.ativo = 1))
    AND (a.filtrarLocaisEstoque = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXLOCAISEST x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.localEstoque = b.localEstoque
      AND x.ativo = 1))
    AND (a.filtrarPersonalizacoes = 0
    OR EXISTS (
      SELECT 1
      FROM PAFILTROPRODUTOXPERSONAL x
      WHERE x.filtroProduto = a.filtroProduto
      AND x.personalizacao = b.personalizacao
      AND x.ativo = 1))
    AND (a.filtrarProdutos = 0
      AND a.filtrarCategoriasProdutos = 0
      AND a.filtrarSubcategoriasProdutos = 0
      AND a.filtrarMarcas = 0
      AND a.filtrarCaracteristicasA = 0
      AND a.filtrarCaracteristicasB = 0
      AND a.filtrarCaracteristicasC = 0
      AND a.filtrarCaracteristicasD = 0
      AND a.filtrarCaracteristicasE = 0
      AND a.filtrarCores = 0
      AND a.filtrarTamanhos = 0
      AND a.filtrarNCMs = 0
      AND a.filtrarListasServicos = 0
      OR a.filtrarProdutos = 1
      AND EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPRODUTOS x
        WHERE x.filtroProduto = a.filtroProduto
        AND x.produto = b.produto
        AND x.ativo = 1)
      OR (a.filtrarCategoriasProdutos = 1
        OR a.filtrarSubcategoriasProdutos = 1
        OR a.filtrarMarcas = 1
        OR a.filtrarCaracteristicasA = 1
        OR a.filtrarCaracteristicasB = 1
        OR a.filtrarCaracteristicasC = 1
        OR a.filtrarCaracteristicasD = 1
        OR a.filtrarCaracteristicasE = 1
        OR a.filtrarCores = 1
        OR a.filtrarTamanhos = 1
        OR a.filtrarNCMs = 1
        OR a.filtrarListasServicos = 1)
      AND (a.filtrarCategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCATEGPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.categoriaProduto = b.categoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarSubcategoriasProdutos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXSUBCAPROD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.subcategoriaProduto = b.subcategoriaProduto
          AND x.ativo = 1))
      AND (a.filtrarMarcas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXMARCAS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.marca = b.marca
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasA = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERA x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaA = b.caracteristicaA
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasB = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERB x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaB = b.caracteristicaB
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasC = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERC x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaC = b.caracteristicaC
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasD = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERD x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaD = b.caracteristicaD
          AND x.ativo = 1))
      AND (a.filtrarCaracteristicasE = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCARACTERE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.caracteristicaE = b.caracteristicaE
          AND x.ativo = 1))
      AND (a.filtrarCores = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXCORES x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.cor = b.cor
          AND x.ativo = 1))
      AND (a.filtrarTamanhos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXTAMANHOS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.tamanho = b.tamanho
          AND x.ativo = 1))
      AND (a.filtrarNCMs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXNCMS x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.idNcm = b.idNcm
          AND x.ativo = 1))
      AND (a.filtrarListasServicos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXLISTASSE x
          WHERE x.filtroProduto = a.filtroProduto
          AND x.listaServicos = b.listaServicos
          AND x.ativo = 1)))),
  REGRASXFILTROS AS (
    SELECT
      a.regraDescontoMargem,
      a.filtroProduto
    FROM (
      SELECT
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima,
        SUM (a.quantidade) quantidade
      FROM REGRASXITENS a
      GROUP BY
        a.regraDescontoMargem,
        a.filtroProduto,
        a.quantidadeMinima,
        a.quantidadeMaxima) a
    WHERE a.quantidade >= a.quantidadeMinima
    AND (a.quantidadeMaxima = 0
      OR a.quantidade <= a.quantidadeMaxima)),
  REGRASVALIDAS AS (
    SELECT
      a.regraDescontoMargem,
      a.ordenacao,
      a.tipoRegraDescontoMargem,
      a.valorSugestao,
      a.valorMaximoSemSenha,
      a.filtrarTabelaPreco,
      a.idade,
      a.valorBasePagamento,
      COALESCE((
        SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem),0) filtrosProdutos
    FROM REGRAS a
    WHERE
      ( SELECT COUNT(1)
        FROM FILTROSPRODUTOS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem)
    = ( SELECT COUNT(1)
        FROM REGRASXFILTROS b
        WHERE b.regraDescontoMargem = a.regraDescontoMargem))
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END, 2), 0) valorDescontoSugestao,
    COALESCE (ROUND(
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= MAX(a.valorBasePagamento)
        THEN MAX(a.valorBasePagamento) - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END, 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.valorBasePagamento,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorSugestao / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorSugestao * a.multiplicador
           -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorSugestao,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END - a.valorDescontoItem, 2) valorDescontoSugestao,
      ROUND (
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorBaseRegra * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha * a.multiplicador
          -- Preço unitário fixo
          WHEN 3
          THEN a.valorBaseRegra-ROUND (a.quantidadeRegra*a.valorMaximoSemSenha,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN a.valorBaseRegra * a.idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN a.idade * a.multiplicador
          -- Preço total fixado
          WHEN 6
          THEN a.valorBaseRegra
          ELSE 0
        END, 2) valorDescontoMaximoSemSenha
    FROM (
      SELECT
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento,
        SUM(a.quantidade) quantidadeRegra,
        CASE
          WHEN SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos) = 0
          THEN 0
          ELSE SUM (a.valorBaseRegra - a.valorDescontoItem)
            / SUM (a.valorBaseRegraTodos - a.valorDescontoItemTodos)
        END multiplicador,
        SUM (a.valorBaseRegra) valorBaseRegra,
        SUM (a.valorDescontoItem) valorDescontoItem
      FROM (
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1
        WHERE a.filtrosProdutos = 0
        AND (a.filtrarTabelaPreco = 0
          OR EXISTS (
            SELECT 1
            FROM PAREGRADESCMARGXTABELASPR x
            WHERE x.regraDescontoMargem = a.regraDescontoMargem
            AND x.tabelaPreco = b.tabelaPreco
            AND x.ativo = 1))
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          b.valorBaseRegra,
          b.valorDescontoItem,
          0 valorBaseRegraTodos,
          0 valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN REGRASXITENS b
        ON b.regraDescontoMargem = a.regraDescontoMargem
        WHERE a.filtrosProdutos > 0
        UNION ALL
        SELECT DISTINCT
          a.regraDescontoMargem,
          a.ordenacao,
          a.tipoRegraDescontoMargem,
          a.valorSugestao,
          a.valorMaximoSemSenha,
          a.idade,
          a.valorBasePagamento,
          b.sequencia,
          b.quantidade,
          0 valorBaseRegra,
          0 valorDescontoItem,
          b.valorBaseRegra valorBaseRegraTodos,
          b.valorDescontoItem valorDescontoItemTodos
        FROM REGRASVALIDAS a
        JOIN ITENS b
        ON 1=1) a
      GROUP BY
        a.regraDescontoMargem,
        a.ordenacao,
        a.tipoRegraDescontoMargem,
        a.valorSugestao,
        a.valorMaximoSemSenha,
        a.idade,
        a.valorBasePagamento) a) a;
END ADD_DOC_FISC_REGRA_DESC_CAB;

/

create or replace PROCEDURE ADD_BUSCA_REGRA_DESCONTO_ITEM (
  p_usuarioLogado                IN NUMBER,
  p_perfilUsuarioLogado          IN NUMBER,
  p_config_227_manterPessoaOrcam IN NUMBER,
  p_cab_entradaSaida             IN CHAR,
  p_cab_devolucaoAnulacaoRetorno IN NUMBER,
  p_cab_estabelecimento          IN NUMBER,
  p_cab_pessoa                   IN NUMBER,
  p_orc_pessoa                   IN NUMBER,
  p_item_modeloDocumento         IN NUMBER,
  p_item_vendedor                IN NUMBER,
  p_item_gradeProduto            IN NUMBER,
  p_item_personalizacao          IN NUMBER,
  p_item_localEstoque            IN NUMBER,
  p_item_quantidade              IN NUMBER,
  p_item_tabelaPreco             IN VARCHAR2,
  p_item_valorProdutoServicoBrut IN NUMBER,
  p_item_valorProdutoServico     IN NUMBER,
  /* Retornos */
  r_possuiRegra                  OUT NUMBER,
  r_percentualDescontoSugestao   OUT NUMBER,
  r_valorDescontoSugestao        OUT NUMBER,
  r_valorDescontoMaximoSemSenha  OUT NUMBER)
IS
  v_pessoa              NUMBER;
  v_indicadorPessoa     CHAR(1);
  v_idade               NUMBER;
  v_uf                  CHAR(2);
  v_produto             NUMBER;
  v_cor                 NUMBER;
  v_tamanho             VARCHAR2(10);
  v_categoriaProduto    NUMBER;
  v_subcategoriaProduto NUMBER;
  v_marca               NUMBER;
  v_caracteristicaA     NUMBER;
  v_caracteristicaB     NUMBER;
  v_caracteristicaC     NUMBER;
  v_caracteristicaD     NUMBER;
  v_caracteristicaE     NUMBER;
  v_idNcm               NUMBER;
  v_listaServicos       NUMBER;
  v_baseDesconto        NUMBER;
BEGIN
  SELECT
    pess.pessoa,
    pess.indicadorPessoa,
    CASE
      WHEN pess.nascimentoFundacao IS NULL
        OR TRUNC (pess.nascimentoFundacao) > TRUNC (SYSDATE)
      THEN 0
      ELSE TRUNC (SYSDATE, 'YYYY')
        - TRUNC (pess.nascimentoFundacao, 'YYYY')
        - CASE
            WHEN TO_CHAR (SYSDATE, 'MMDD') < TO_CHAR (pess.nascimentoFundacao, 'MMDD')
            THEN 1
            ELSE 0
          END
    END idade,
    COALESCE((
      CASE
        WHEN pess.pessoa = 0
        THEN (
          SELECT MAX(munPess.uf)
          FROM PAESTABELECIMENTOS est
          JOIN CAENDERECOSPESSOA endPess
          ON endPess.pessoa = est.pessoaEstabelecimento
          JOIN SIMUNICIPIOS munPess
          ON munPess.municipio = endPess.municipio
          WHERE est.estabelecimento = p_cab_estabelecimento
          AND endPess.ativo = 1
          AND endPess.principal = 1)
        ELSE COALESCE((
          SELECT MAX(munPess.uf)
          FROM CAENDERECOSPESSOA endPess
          JOIN SIMUNICIPIOS munPess
          ON munPess.municipio = endPess.municipio
          WHERE endPess.pessoa = pess.pessoa
          AND endPess.ativo = 1
          AND endPess.principal = 1),(
          SELECT MAX(munPess.uf)
          FROM PAESTABELECIMENTOS est
          JOIN CAENDERECOSPESSOA endPess
          ON endPess.pessoa = est.pessoaEstabelecimento
          JOIN SIMUNICIPIOS munPess
          ON munPess.municipio = endPess.municipio
          WHERE est.estabelecimento = p_cab_estabelecimento
          AND endPess.ativo = 1
          AND endPess.principal = 1))
      END),'  ') uf
  INTO
    v_pessoa,
    v_indicadorPessoa,
    v_idade,
    v_uf
  FROM CAPESSOAS pess
  WHERE pess.pessoa =
    CASE
      WHEN p_orc_pessoa = 0
        OR p_config_227_manterPessoaOrcam = 1
      THEN p_cab_pessoa
      ELSE p_orc_pessoa
    END;
  SELECT
    gradProd.produto,
    gradProd.cor,
    gradProd.tamanho,
    subCatProd.categoriaProduto,
    prod.subcategoriaProduto,
    prod.marca,
    prod.caracteristicaA,
    prod.caracteristicaB,
    prod.caracteristicaC,
    prod.caracteristicaD,
    prod.caracteristicaE,
    prod.idNcm,
    prod.listaServicos,
    CASE
      WHEN modDoc.diminuiDescontoPrUnit= 1
        OR modDoc.somaAcrescimosPrUnit = 1
        OR modDoc.somaFreteSeguroPrUnit = 1
        OR p_cab_entradaSaida =
          CASE
            WHEN p_cab_devolucaoAnulacaoRetorno = 1
            THEN 'E'
            ELSE 'S'
          END
        AND EXISTS (
          SELECT 1
          FROM CAPRODUTOXCOMPOSICOESPREC compPres
          WHERE compPres.produto = gradProd.produto
          AND compPres.ativo = 1)
      THEN p_item_valorProdutoServicoBrut
      ELSE p_item_valorProdutoServico
    END baseDesconto
  INTO
    v_produto,
    v_cor,
    v_tamanho,
    v_categoriaProduto,
    v_subcategoriaProduto,
    v_marca,
    v_caracteristicaA,
    v_caracteristicaB,
    v_caracteristicaC,
    v_caracteristicaD,
    v_caracteristicaE,
    v_idNcm,
    v_listaServicos,
    v_baseDesconto
  FROM CAGRADESPRODUTO gradProd
  JOIN CAPRODUTOS prod
  ON prod.produto = gradProd.produto
  JOIN PASUBCATEGORIASPRODUTO subCatProd
  ON subCatProd.subCategoriaProduto = prod.subCategoriaProduto
  JOIN PAMODELOSDOCUMENTO modDoc
  ON modDoc.modeloDocumento = p_item_modeloDocumento
  WHERE gradProd.gradeProduto = p_item_gradeProduto;
  SELECT
    COALESCE (MAX(a.possuiRegra), 0) possuiRegra,
    COALESCE (ROUND((
      CASE
        WHEN SUM (
            CASE
              WHEN a.valorDescontoSugestao < 0
              THEN 0
              ELSE a.valorDescontoSugestao
            END) >= v_baseDesconto
        THEN 100
        WHEN MIN (a.valorDescontoSugestao) < 0
          OR SUM(a.possuiRegra) > 1
        THEN
          CASE
            WHEN v_baseDesconto <= 0
            THEN 0
            ELSE 100 * COALESCE (SUM (
              CASE
                WHEN a.valorDescontoSugestao < 0
                THEN 0
                ELSE a.valorDescontoSugestao
              END), 0) / v_baseDesconto
          END
        ELSE MAX(a.percentualDescontoSugestao)
      END), 8), 0) percentualDescontoSugestao,
    COALESCE (ROUND((
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END) >= v_baseDesconto
        THEN v_baseDesconto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoSugestao < 0
            THEN 0
            ELSE a.valorDescontoSugestao
          END)
      END), 2), 0) valorDescontoSugestao,
    COALESCE (ROUND((
      CASE
        WHEN SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END) >= v_baseDesconto
        THEN v_baseDesconto - 0.01
        ELSE SUM (
          CASE
            WHEN a.valorDescontoMaximoSemSenha < 0
            THEN 0
            ELSE a.valorDescontoMaximoSemSenha
          END)
      END), 2), 0) valorDescontoMaximoSemSenha
  INTO
    r_possuiRegra,
    r_percentualDescontoSugestao,
    r_valorDescontoSugestao,
    r_valorDescontoMaximoSemSenha
  FROM (
    SELECT
      1 possuiRegra,
      a.tipoRegraDescontoMargem,
      ROUND ((
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN a.valorSugestao
          -- Desconto em valor
          WHEN 2
          THEN
            CASE
              WHEN v_baseDesconto <= 0
              THEN 0
              ELSE 100 * a.valorSugestao / v_baseDesconto
            END
          -- Preço unitário fixo
          WHEN 3
          THEN
            CASE
              WHEN v_baseDesconto <= 0
              THEN 0
              ELSE 100 * (v_baseDesconto - ROUND (p_item_quantidade * a.valorMaximoSemSenha,2)) / v_baseDesconto
            END
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN v_idade
          -- Desconto igual a idade em valor
          WHEN 5
          THEN
            CASE
              WHEN v_baseDesconto <= 0
              THEN 0
              ELSE 100 * v_idade / v_baseDesconto
            END
          -- Preço total fixado
          WHEN 6
          THEN 100
          ELSE 0
        END), 8) percentualDescontoSugestao,
      ROUND ((
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN v_baseDesconto * a.valorSugestao / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorSugestao
           -- Preço unitário fixo
          WHEN 3
          THEN v_baseDesconto - ROUND (p_item_quantidade * a.valorSugestao,2)
          -- Desconto igual a idade em percentual
          WHEN 4
          THEN v_baseDesconto * v_idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN v_idade
          -- Preço total fixado
          WHEN 6
          THEN v_baseDesconto
          ELSE 0
        END), 2) valorDescontoSugestao,
      ROUND ((
        CASE a.tipoRegraDescontoMargem
          -- Desconto em percentual
          WHEN 1
          THEN v_baseDesconto * a.valorMaximoSemSenha / 100
          -- Desconto em valor
          WHEN 2
          THEN a.valorMaximoSemSenha
          -- Preço unitário fixo
          WHEN 3
          THEN v_baseDesconto - ROUND (p_item_quantidade * a.valorMaximoSemSenha,2)
          WHEN 4
          THEN v_baseDesconto * v_idade / 100
          -- Desconto igual a idade em valor
          WHEN 5
          THEN v_idade
          -- Preço total fixado
          WHEN 6
          THEN v_baseDesconto
          ELSE 0
        END), 2) valorDescontoMaximoSemSenha
    FROM PAREGRASDESCONTOSMARGEM a
    JOIN PAFILTROSCABECALHO filtroCab
    ON filtroCab.filtroCabecalho = a.filtroCabecalho
    WHERE a.regraDescontoMargem > 0
    AND a.ativo = 1
    AND a.dataValidadeInicial <= TRUNC(SYSDATE)
    AND a.dataValidadeFinal >= TRUNC(SYSDATE)
    AND a.cabecalhoItemPagamento = 'I'
    AND a.tipoRegraDescontoMargem BETWEEN 1 AND 6
    -- Filtro Cabeçalho
    AND (a.filtroCabecalho = 0
      OR (filtroCab.filtrarEstabelecimentos = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXESTABELEC filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.estabelecimento = p_cab_estabelecimento
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarUfs = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUFS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.uf = v_uf
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPessoas = 0
        OR EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPESSOAS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.pessoa = v_pessoa
          AND filtroCabX.ativo = 1))
      AND (filtroCab.filtrarPerfisUsuario = 0
        AND filtroCab.filtrarUsuarios = 0
        OR filtroCab.filtrarPerfisUsuario = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXPERFISUSUAR filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.perfilUsuario = p_perfilUsuarioLogado
          AND filtroCabX.ativo = 1)
        OR filtroCab.filtrarUsuarios = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROCABECXUSUARIOS filtroCabX
          WHERE filtroCabX.filtroCabecalho = a.filtroCabecalho
          AND filtroCabX.usuario = p_usuarioLogado
          AND filtroCabX.ativo = 1))
      AND (filtroCab.indicadorPessoa = ' '
        OR filtroCab.indicadorPessoa = v_indicadorPessoa)
      AND (filtroCab.colaborador = ' '
        OR filtroCab.colaborador = 'N'
        AND (v_pessoa = 0
          OR NOT (EXISTS (
            SELECT 1
            FROM CACOLABORADORES colab
            WHERE colab.colaborador = v_pessoa
            AND colab.ativo = 1 )))
        OR filtroCab.colaborador = 'S'
        AND v_pessoa <> 0
        AND EXISTS (
          SELECT 1
          FROM CACOLABORADORES colab
          WHERE colab.colaborador = v_pessoa
          AND colab.ativo = 1)))
    -- Tabela de Preço
    AND (a.filtrarTabelaPreco = 0
      OR EXISTS (
        SELECT 1
        FROM PAREGRADESCMARGXTABELASPR x
        WHERE x.regraDescontoMargem = a.regraDescontoMargem
        AND x.tabelaPreco = p_item_tabelaPreco
        AND x.ativo = 1))
    -- Filtro Produto
    AND (
      SELECT COUNT(1)
      FROM PAREGRADESCMARGXFILTPROD b
      WHERE b.regraDescontoMargem = a.regraDescontoMargem
      AND b.filtroProduto > 0
      AND b.ativo = 1) = (
      SELECT COUNT(1)
      FROM PAREGRADESCMARGXFILTPROD b
      JOIN PAFILTROSPRODUTO c
      ON c.filtroProduto = b.filtroProduto
      WHERE b.regraDescontoMargem = a.regraDescontoMargem
      AND b.filtroProduto > 0
      AND b.ativo = 1
      AND (c.filtrarVendedores = 0
      OR EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXVENDEDOR x
        WHERE x.filtroProduto = b.filtroProduto
        AND x.vendedor = p_item_vendedor
        AND x.ativo = 1))
      AND (c.filtrarLocaisEstoque = 0
      OR EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXLOCAISEST x
        WHERE x.filtroProduto = b.filtroProduto
        AND x.localEstoque = p_item_localEstoque
        AND x.ativo = 1))
      AND (c.filtrarPersonalizacoes = 0
      OR EXISTS (
        SELECT 1
        FROM PAFILTROPRODUTOXPERSONAL x
        WHERE x.filtroProduto = b.filtroProduto
        AND x.personalizacao = p_item_personalizacao
        AND x.ativo = 1))
      AND (c.filtrarProdutos = 0
        AND c.filtrarCategoriasProdutos = 0
        AND c.filtrarSubcategoriasProdutos = 0
        AND c.filtrarMarcas = 0
        AND c.filtrarCaracteristicasA = 0
        AND c.filtrarCaracteristicasB = 0
        AND c.filtrarCaracteristicasC = 0
        AND c.filtrarCaracteristicasD = 0
        AND c.filtrarCaracteristicasE = 0
        AND c.filtrarCores = 0
        AND c.filtrarTamanhos = 0
        AND c.filtrarNCMs = 0
        AND c.filtrarListasServicos = 0
        OR c.filtrarProdutos = 1
        AND EXISTS (
          SELECT 1
          FROM PAFILTROPRODUTOXPRODUTOS x
          WHERE x.filtroProduto = b.filtroProduto
          AND x.produto = v_produto
          AND x.ativo = 1)
        OR (c.filtrarCategoriasProdutos = 1
          OR c.filtrarSubcategoriasProdutos = 1
          OR c.filtrarMarcas = 1
          OR c.filtrarCaracteristicasA = 1
          OR c.filtrarCaracteristicasB = 1
          OR c.filtrarCaracteristicasC = 1
          OR c.filtrarCaracteristicasD = 1
          OR c.filtrarCaracteristicasE = 1
          OR c.filtrarCores = 1
          OR c.filtrarTamanhos = 1
          OR c.filtrarNCMs = 1
          OR c.filtrarListasServicos = 1)
        AND (c.filtrarCategoriasProdutos = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCATEGPROD x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.categoriaProduto = v_categoriaProduto
            AND x.ativo = 1))
        AND (c.filtrarSubcategoriasProdutos = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXSUBCAPROD x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.subcategoriaProduto = v_subcategoriaProduto
            AND x.ativo = 1))
        AND (c.filtrarMarcas = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXMARCAS x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.marca = v_marca
            AND x.ativo = 1))
        AND (c.filtrarCaracteristicasA = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCARACTERA x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.caracteristicaA = v_caracteristicaA
            AND x.ativo = 1))
        AND (c.filtrarCaracteristicasB = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCARACTERB x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.caracteristicaB = v_caracteristicaB
            AND x.ativo = 1))
        AND (c.filtrarCaracteristicasC = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCARACTERC x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.caracteristicaC = v_caracteristicaC
            AND x.ativo = 1))
        AND (c.filtrarCaracteristicasD = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCARACTERD x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.caracteristicaD = v_caracteristicaD
            AND x.ativo = 1))
        AND (c.filtrarCaracteristicasE = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCARACTERE x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.caracteristicaE = v_caracteristicaE
            AND x.ativo = 1))
        AND (c.filtrarCores = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXCORES x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.cor = v_cor
            AND x.ativo = 1))
        AND (c.filtrarTamanhos = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXTAMANHOS x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.tamanho = v_tamanho
            AND x.ativo = 1))
        AND (c.filtrarNCMs = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXNCMS x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.idNcm = v_idNcm
            AND x.ativo = 1))
        AND (c.filtrarListasServicos = 0
          OR EXISTS (
            SELECT 1
            FROM PAFILTROPRODUTOXLISTASSE x
            WHERE x.filtroProduto = b.filtroProduto
            AND x.listaServicos = v_listaServicos
            AND x.ativo = 1))
        AND p_item_quantidade >= c.quantidadeMinima
        AND (c.quantidadeMaxima = 0
          OR p_item_quantidade <= c.quantidadeMaxima)))) a;
END ADD_BUSCA_REGRA_DESCONTO_ITEM;

/

DROP TABLE TEMPBLOQDESCONTOMARGEM;
DROP TABLE TEMPBLOQDESCONTOMARGEMB;

UPDATE MODISTRIBUICOESDFE
SET xmlDfe = ' '
WHERE xmlDfe LIKE '<resNFe%';

COMMIT;

DELETE PACONFIGURACAOXCONTEUDOS WHERE configuracao = 330;
DELETE SICONFIGURACOES WHERE configuracao = 330;

COMMIT;

UPDATE SIUFS SET
  urlConsultaNFCeProducao = 'https://sat.sef.sc.gov.br/nfce/consulta',
  urlConsultaNFCeHomologacao = 'https://hom.sat.sef.sc.gov.br/nfce/consulta',
  urlQrCodeNFCeProducao = 'https://sat.sef.sc.gov.br/nfce/consulta',
  urlQrCodeNFCeHomologacao = 'https://hom.sat.sef.sc.gov.br/nfce/consulta'
WHERE UF = 'SC';

COMMIT;

INSERT INTO SIVERSOESSISTEMA (idVersaoSistema, versaoAplicativo, dataLiberacaoVersao, possuiConversaoTabelas, atualizada, dataAtualizacaoVersao, observacoes) VALUES (2023002012, '2023.2.12', TO_DATE('18/04/2023','DD/MM/YYYY'), 1, 1, sysdate, ' ');

COMMIT;

--exec dbms_utility.compile_schema('ADDERI');
--exec dbms_stats.gather_schema_stats('ADDERI');

/*
*/