
-- StoreProcedure {lancamento_integra_itens_before()} Versao {223} Esquema {padrao} Descricao {Grava integracao itens do documento}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.lancamento_integra_itens_before()
  RETURNS trigger AS
$BODY$

DECLARE
 --Variaveis
   d11_perc_comissao     NUMERIC(14,5);
   d12_natureza          CHAR(1); --Natureza: Entrada/Saida
   d13_tipo_docto        CHAR(1); --Tipo Docto: Nota Fiscao/Pedido/Orcamento
   d14_calcularICMS      CHAR(1); --Calcular ICMS: Sim/Nao
   d15_calcularIPI       CHAR(1); --Calcular IPI: Sim/Nao
   d16_calcularFUNRURAL  CHAR(1); --Calcular FUNRURAL: Sim/Nao
   d17_CFOP              VARCHAR; --Classificacao Fiscal(CFOP) da transacao
   d18_usarCFOP          CHAR(1); --Usar classificacao fiscal(CFOP) do:(1-Cadastro de Transacao/2-Cadastro do produtos
   d19_devolucao         CHAR(1); --devolucao de mercadorias (Sim - Nao)
   d115_NFE              CHAR(1); --Nota Fiscal Eletronica: (Sim/Nao)
   d118_classgerencialproduto   CHAR(1); --Class.Gerencial do Produto: (Sim/Nao)
   d119_NFe               CHAR(1); --Nota Fiscal eletronica: (Sim/Nao)
   d127_UsarClassTrib     CHAR(1); --Usar classificacao tributaria do:(1-Cadastro de Transacao/2-Cadastro do produtos
   d128_ClassTrib         CHAR(1); --Classificacao tributaria da transacao
   d133_InformeCongPg     CHAR(1); --Informe  cond. Pgto Cadastro (1-Nao Obrigatorio 2-Somente Avisar 3-Obrigatorio
   d134_InformeTabPreco   CHAR(1); --Informe Preco tabela (1-Nao Obrigatorio 2-Somente Avisar 3-Obrigatorio
   d143_PermitePrecoZero  CHAR(1); --Permitir Item Valor Unitario (Zero):Sim/Nao
 --Estoque
   d26_atualiza_estoque  CHAR(1); --Atualiza estoque:(Sim/Nao)
   d27_tipo_mvto         CHAR(1); --Tipo de Movimento :0-Normal/1-Consignacao - Envio/ ...
   d28_alterarCM         CHAR(1); --Alterar Custo Medio : Sim/Nao
   d29_alterrrCUC        CHAR(1); --Alterar Custo Ultima compra: Sim/Nao
   d210_checarestoque    CHAR(1); --Checar Estoque: 0-Checar saldo negativo/1-Vetar saida com saldo negativo
 --Financeiro
   d49_lancarCRP         CHAR(1); --Lancar contas a receber/pagar: Sim/Nao
   d410_atualizarsaldoCC CHAR(1); --Atualizar saldo do C/C: Sim/Nao
   d411_tipolcto         CHAR(1); --Tipo lancamento: 0-Normal/1-Transferencia
   d412_natureza         CHAR(1); --Natureza: Creditol/Debito
   d413_comissao         CHAR(1); --Comissao: 0-Creditar comissao/1-Debitar comissao/2-Nao comissionar
   d414_conciliar        CHAR(1); --Conciliar automatico: Sim/Nao
 --Classificacao Gerencial
   d71_codigoclasse1      VARCHAR(5); --Codigo classificacacao gerencial 1
   d72_codigoclasse2      VARCHAR(5); --Codigo classificacacao gerencial 2
   d73_codigoclasse3      VARCHAR(5); --Codigo classificacacao gerencial 3

   custoTotalCalculo     NUMERIC(14,4);
   rateio                NUMERIC(14,4);
   rateioInfoCusto       NUMERIC(14,4);
   custo                 NUMERIC(14,4);
   custoNF               NUMERIC(14,4);
   custoInventario       NUMERIC(14,4);
   custoDigitado         NUMERIC(14,4);
   custoReal             NUMERIC(14,4);
   V_ICMS                NUMERIC(14,4);
   dif_per               NUMERIC(14,4);
   dif_val               NUMERIC(14,2);
   dif_icms              NUMERIC(14,2);

   rateio_desc_valor_nf       NUMERIC(14,6); --  Rateio Valor Desconto total docto
   rateio_desc_valor_nf_perc  NUMERIC(14,6); --  Rateio Valor Desconto total docto
   rateio_vl_unit_liq         NUMERIC(14,6); --  Rateio Valor unitario liquido
   rateio_vl_total_liq        NUMERIC(14,6); --  Rateio Valor total liquido

   r_transacao      RECORD; -- Transacao
   r_parameters     RECORD; -- Parametros
   r_doctoc         RECORD; -- DoctoC
   r_consistencia   RECORD; -- cosisencia somatario dos produtos
   r_produto        RECORD; -- Cadastro Produto
   r_listapre       RECORD; -- Lista de preco
   r_listapretab    RECORD; -- Lista de preco - tabela
   r_condpgto       RECORD; -- Condicao de pagamento
   r_cad            RECORD; -- Cadastro Cadastro Destinatario
   r_filial         RECORD; -- Cadastro Cadastro Emitente

BEGIN

--Posiciona Cabecalho
   IF TG_OP = 'INSERT'  THEN
        SELECT controle,fat_transacao_id, seriedocto_codigo, seriedocto_id, (SELECT seriemodelo FROM padrao.fat_serie WHERE id=seriedocto_id) AS seriemodelo,
          cad_filial_id, numero_docto,cad_cadastro_id,emissao,
          dataentradasaida, infocustodescpgto, statuslcto, fat_listapre_id, fat_listapre_tabela_tabela, fat_condpg_id,
          infocustojurosvendor, infocustooutrasdesp, infocustofretepagar, frete_valor, despesa_valor, seguro_Valor,
          icmssubst_valor,ipi_valor,COALESCE(totalliquidoprodutos,totalprodutos) AS totalliquidoprodutos, totalprodutos, valortotal_docto, COALESCE(descontodocto_valor,0) AS descontodocto_valor,
          (SELECT SUM(valor_total_liquido) FROM fat_docto_i WHERE SUBSTRING(icms_classtrib from 1 for 1) IN ('2','9','A','F','G','H','K') AND fat_docto_c_controle=fat_docto_c.controle) AS total_prod_st
        INTO r_doctoc
        FROM fat_docto_c
        WHERE controle = NEW.fat_docto_c_controle;
   ELSE
         SELECT controle,fat_transacao_id, seriedocto_codigo, seriedocto_id, (SELECT seriemodelo FROM padrao.fat_serie WHERE id=seriedocto_id) AS seriemodelo,
          cad_filial_id, numero_docto,cad_cadastro_id,emissao,
          dataentradasaida, infocustodescpgto, statuslcto, fat_listapre_id, fat_listapre_tabela_tabela, fat_condpg_id,
          infocustojurosvendor, infocustooutrasdesp, infocustofretepagar, frete_valor, despesa_valor, seguro_Valor,
          icmssubst_valor,ipi_valor,COALESCE(totalliquidoprodutos,totalprodutos) AS totalliquidoprodutos, totalprodutos, valortotal_docto, COALESCE(descontodocto_valor,0) AS descontodocto_valor,
          (SELECT SUM(valor_total_liquido) FROM fat_docto_i WHERE SUBSTRING(icms_classtrib from 1 for 1) IN ('2','9','A','F','G','H','K') AND fat_docto_c_controle=fat_docto_c.controle) AS total_prod_st
        INTO r_doctoc
        FROM fat_docto_c
        WHERE controle = OLD.fat_docto_c_controle;
   END IF;

-- Posiciona Cadastro (Destinatario)
   SELECT cad_cadastro.id, razaosocial, nomefantasia, pessoa, cad_mun_id,padrao.cad_mun.municipio AS municipio,
          fat_listapre_id, fat_listapre_tabela_tabela, fat_condpg_id,
          padrao.cad_mun.uf AS uf,contribuinteicms, COALESCE(calculoicmssobre_ipi, false) AS calculoicmssobre_ipi ,
          CASE WHEN contribuinteicms = 'Sim' THEN 1 ELSE 2 END AS tipoa,  CASE WHEN contribuinteicms = 'Sim' THEN 3 ELSE 4 END AS tipoadif
     INTO r_cad
     FROM cad_cadastro
     LEFT JOIN padrao.cad_mun ON cad_cadastro.cad_mun_id = padrao.cad_mun.id
    WHERE cad_cadastro.id = r_doctoc.cad_cadastro_id;

-- Posiciona Filial (Emitente)
   SELECT cad_filial.id, razaosocial, nomefantasia, pessoa, cad_mun_id,padrao.cad_mun.municipio AS municipio, padrao.cad_mun.uf AS uf,substring(regimetributacao from 1 for 1) AS regimetributacao
     INTO r_filial
     FROM cad_filial
     LEFT JOIN padrao.cad_mun ON cad_filial.cad_mun_id = padrao.cad_mun.id
    WHERE cad_filial.id = r_doctoc.cad_filial_id;

-- Posiciona parameters
   SELECT *
   INTO r_parameters
   FROM fat_parameters
   LIMIT 1 ;

    d143_PermitePrecoZero = 'N';

-- LOOP
   FOR r_transacao IN SELECT * FROM view_transacao WHERE codigo_transacao = r_doctoc.fat_transacao_id ORDER BY diretiva LOOP
       --RAISE NOTICE 'Propriedade:% (%)',  r_transacao.diretiva, r_transacao.propriedade;
    -- diretiva/Regra 11 -( (%) Comissao vendedores)
       IF r_transacao.diretiva = 11 THEN

       	  d11_perc_comissao = CAST(r_transacao.propriedade AS DECIMAL(14,5));
       END IF;

    -- diretiva/Regra 12 - ( Natureza: Entrada/Saida)
       IF r_transacao.diretiva = 12 THEN
       	  d12_natureza = substring(r_transacao.propriedade from 1 for 1);
       END IF;

    -- diretiva/Regra 13 - ( Tipo Docto: Nota Fiscao/Pedido/Orcamento)
       IF r_transacao.diretiva = 13 THEN
       	  d13_tipo_docto = substring(r_transacao.propriedade from 1 for 1);
       END IF;

    -- diretiva/Regra 14 - ( Calcular ICMS: Sim/Nao)
       IF r_transacao.diretiva = 14 THEN
       	  d14_calcularICMS = substring(r_transacao.propriedade from 1 for 1);
       END IF;

    -- diretiva/Regra 15 - ( Calcular IPI: Sim/Nao)
       IF r_transacao.diretiva = 15 THEN
       	  d15_calcularIPI = substring(r_transacao.propriedade from 1 for 1);
       END IF;

    -- diretiva/Regra 16 - ( Calcular FUNRURAL: Sim/Nao)
       IF r_transacao.diretiva = 16 THEN
       	  d16_calcularFUNRURAL = substring(r_transacao.propriedade from 1 for 1);
       END IF;

    -- diretiva/Regra 17 - ( Classificacao Fiscal(CFOP))
       IF r_transacao.diretiva = 17 THEN
       	  d17_CFOP = Trim(both ' ' from r_transacao.propriedade);
       END IF;

    -- diretiva/Regra 18 - ( Usar classificacao fiscal(CFOP) do:(1-Cadastro de Transacao/2-Cadastro do produtos )
       IF r_transacao.diretiva = 18 THEN
       	  d18_usarCFOP = substring(r_transacao.propriedade from 1 for 1);
       END IF;
	-- diretiva/Regra 19 - (Devolucao:( Sim/Nao )
       IF r_transacao.diretiva = 19 THEN
       	  d19_devolucao = substring(r_transacao.propriedade from 1 for 1);
       END IF;
     -- diretiva/Regra 115 - (Nota Fiscal Eletronica: Sim/Nao)
       IF r_transacao.diretiva = 115 THEN
       	  d115_NFE = substring(r_transacao.propriedade from 1 for 1);
       END IF;
       -- diretiva/Regra 118 - (Class.Gerencial do Produto: Sim/Nao)
       IF r_transacao.diretiva = 118 THEN
       	  d118_classgerencialproduto = substring(r_transacao.propriedade from 1 for 1);
       END IF;
       -- diretiva/Regra 119 - (Nota Fiscal eletornica: Sim/Nao)
       IF r_transacao.diretiva = 119 THEN
       	  d119_NFe = substring(r_transacao.propriedade from 1 for 1);
       END IF;
    -- diretiva/Regra 26 - ( Atualiza estoque: Sim/Nao.)
       IF r_transacao.diretiva = 26 THEN
       	  d26_atualiza_estoque = substring(r_transacao.propriedade from 1 for 1);
       END IF;
 	-- diretiva/Regra 27 - ( Tipo de Movimentacao: 0-Normal/1-Consignacao - Envio/ ...)
       IF r_transacao.diretiva = 27 THEN
       	  d27_tipo_mvto = substring(r_transacao.propriedade from 1 for 1);
       END IF;

  	-- diretiva/Regra 28 - ( Alterar Custo Medio: Sim/Nao)
       IF r_transacao.diretiva = 28 THEN
       	  d28_alterarCM = substring(r_transacao.propriedade from 1 for 1) ;
       END IF;

  	-- diretiva/Regra 29 - ( Alterar Custo Ultima compra: Sim/Nao)
       IF r_transacao.diretiva = 29 THEN
       	  d29_alterrrCUC = substring(r_transacao.propriedade from 1 for 1) ;
       END IF;
   -- diretiva/Regra 210 - ( Checar Saldo Negativo:  0-Checar saldo negativo/1-Vetar saida com saldo negativo)
       IF r_transacao.diretiva = 210 THEN
       	  d210_checarestoque = substring(r_transacao.propriedade from 1 for 1) ;
       END IF;
  	-- diretiva/Regra 49 - ( Lancar contas a receber/pagar: Sim/Nao)
       IF r_transacao.diretiva = 49 THEN
       	 d49_lancarCRP =  substring(r_transacao.propriedade from 1 for 1);
       END IF;
    -- diretiva/Regra 71 - ( -codigo classificacacao gerencial 1 )
       IF r_transacao.diretiva = 71 THEN
       	 d71_codigoclasse1 =  r_transacao.propriedade;
       END IF;
    -- diretiva/Regra 72 - ( -codigo classificacacao gerencial 2 )
       IF r_transacao.diretiva = 72 THEN
       	 d72_codigoclasse2 =  r_transacao.propriedade;
       END IF;
     -- diretiva/Regra 73 - ( -codigo classificacacao gerencial 3 )
       IF r_transacao.diretiva = 73 THEN
       	 d73_codigoclasse3 =  r_transacao.propriedade;
       END IF;

     --Usar classificacao tributaria do:(1-Cadastro de Transacao/2-Cadastro do produtos
       IF r_transacao.diretiva = 127 THEN
       	  d127_UsarClassTrib = substring(r_transacao.propriedade from 1 for 1)  ;
       END IF;

     --Classificacao tributaria da transacao
       IF r_transacao.diretiva = 128 THEN
       	  d128_ClassTrib = substring(r_transacao.propriedade from 1 for 1)  ;
       END IF;
       --Informe Cond.Pgto Cadastro (1-Nao Obrigatorio 2-Somente Avisar 3-Obrigatorio
       IF r_transacao.diretiva = 133 THEN
       	  d133_InformeCongPg = substring(r_transacao.propriedade from 1 for 1)  ;
       END IF;
      --Informe Preco tabela (1-Nao Obrigatorio 2-Somente Avisar 3-Obrigatorio
       IF r_transacao.diretiva = 134 THEN
       	  d134_InformeTabPreco = substring(r_transacao.propriedade from 1 for 1)  ;
       END IF;
       --Permitir Item Valor Unitario (Zero):Sim/Nao
       IF r_transacao.diretiva = 143 THEN
       	  d143_PermitePrecoZero = substring(r_transacao.propriedade from 1 for 1)  ;
       END IF;
   	-- diretiva/Regra 410 - ( Atualiza saldo do C/C: Sim/Nao)
       IF r_transacao.diretiva = 410 THEN
       	  d410_atualizarsaldoCC = substring(r_transacao.propriedade from 1 for 1)  ;
       END IF;

  	-- diretiva/Regra 411 - ( Tipo lancamento: 0-Normal/1-Transferencia)
       IF r_transacao.diretiva = 411 THEN
       	  d411_tipolcto =  substring(r_transacao.propriedade from 1 for 1);
       END IF;

  	-- diretiva/Regra 412 - ( Natureza: Creditol/Debito)
       IF r_transacao.diretiva = 412 THEN
       	  d412_natureza = substring(r_transacao.propriedade from 1 for 1);
       END IF;

  	-- diretiva/Regra 413 - ( Comissao: 0-Creditar comissao/1-Debitar comissao/2-Nao comissionar)
       IF r_transacao.diretiva = 413 THEN
       	  d413_comissao =  substring(r_transacao.propriedade from 1 for 1);
       END IF;

    -- diretiva/Regra 414 - (Regra Conciliar automatico: Sim/Nao)
       IF r_transacao.diretiva = 414 THEN
       	  d414_conciliar = substring(r_transacao.propriedade from 1 for 1);
       END IF;
   END LOOP;

--posiciona produto
  IF TG_OP = 'INSERT'  THEN
      SELECT fat_produto.id AS id,fat_produto.codigobarra1 AS codigobarra1,
             LEFT(fat_produto.descricao, 20) AS descricao, unidadepadraovenda,
             fat_marca.descricao AS marca,CAST(padrao.getpreco(r_doctoc.fat_listapre_id,r_doctoc.fat_listapre_tabela_tabela,fat_produto.id) AS NUMERIC(12,2)) AS preco,
             fat_produto.referencia AS referencia,localizacao,volume,pesoliquido,pesobruto,
             CAST(padrao.getestoque(r_doctoc.cad_filial_id,fat_produto.id) AS NUMERIC(12,3)) AS saldo,
             classtipi_codigonbm AS ncm, fat_produto.aliquota_ipi_saida AS aliquota_ipi_saida,
             fat_produto.aliquota_ipi_entrada AS aliquota_ipi_entrada, fat_classtipi.aliqnac AS ncm_aliqnac,
             classtipi_codigonbm, fat_classtipi.aliqimp AS ncm_aliqimp,
             CAST(COALESCE(padrao.geticms(fat_produto.aliquotas_normal_id,r_cad.uf,r_cad.tipoa),0) AS NUMERIC(5,3)) AS icms,
             CAST(COALESCE(padrao.geticms(fat_produto.aliquotas_normal_id,r_filial.uf,r_cad.tipoa),0) AS NUMERIC(5,3))
              AS icms_subst_aliq_prop,
           --  fat_classtipi.aliquota AS icms_subst_mva,
             CAST(COALESCE(padrao.geticms(fat_produto.aliquotas_normal_id,r_cad.uf, 5),0) AS NUMERIC(5,3)) AS icms_subst_mva,
            -- CAST(COALESCE(padrao.geticms(fat_classtipi.aliq_dest_id,r_cad.uf,r_cad.tipoa), 0) AS NUMERIC(5,3)) AS icms_subst_aliq_dest,
             CAST( COALESCE( padrao.geticms( CAST(COALESCE(padrao.geticms(fat_produto.aliquotas_normal_id,r_cad.uf, 8), 0) AS int4)  , r_cad.uf, r_cad.tipoa), 0) AS NUMERIC(5,3)) AS icms_subst_aliq_dest,

             CAST(padrao.getCustoProd(r_doctoc.cad_filial_id,fat_produto.id, CURRENT_DATE,r_doctoc.fat_listapre_tabela_tabela) AS NUMERIC(12,4)) AS custodigitado,
             CAST(padrao.getmovtoprod(r_doctoc.cad_cadastro_id, fat_produto.id,
             CASE WHEN d27_tipo_mvto = '2' OR d27_tipo_mvto = 'C' THEN '1'
                  WHEN d27_tipo_mvto = '4'                        THEN '3'
                  WHEN d27_tipo_mvto = '6'                        THEN '5'
                  WHEN d27_tipo_mvto = '8'                        THEN '7'
              END,
             CASE WHEN d27_tipo_mvto = 'C' THEN '2' ELSE d27_tipo_mvto END) AS NUMERIC(12,3)) AS saldomovto,
             CAST(COALESCE(padrao.geticms(aliquotas_reducaos_id,r_cad.uf,r_cad.tipoa),0) AS NUMERIC(5,3)) As icmsredsai,
             CAST(COALESCE(padrao.geticms(aliquotas_reducaoe_id,r_cad.uf,r_cad.tipoa),0) AS NUMERIC(5,3)) As icmsredent,
             CAST(COALESCE(padrao.geticms(aliquotas_diferimento_id,r_cad.uf,r_cad.tipoa),0) AS NUMERIC(5,3)) As icmsdife,
             CAST(COALESCE(padrao.geticms(fat_produto.aliquotas_normal_id,r_cad.uf,r_cad.tipoadif),0) AS NUMERIC(5,3)) AS icmsdifp,
             CAST(COALESCE(padrao.geticms(aliquotas_reducaos_id,r_cad.uf,r_cad.tipoadif),0) AS NUMERIC(5,3)) As icmsredsaiDifP,
             CAST(COALESCE(padrao.geticms(aliquotas_reducaoe_id,r_cad.uf,r_cad.tipoadif),0) AS NUMERIC(5,3)) As icmsredentdifp,
             CAST(COALESCE(padrao.geticms(aliquotas_diferimento_id,r_cad.uf,r_cad.tipoadif),0) AS NUMERIC(5,3)) As icmsdifedifp,
             classfiscal_id, classfiscal_entrada_id,
             CASE WHEN fat_produto_classtrib.uf IS NULL THEN r_cad.uf ELSE fat_produto_classtrib.uf END AS uf,
             CASE WHEN r_cad.tipoa = 1 THEN
			      CASE WHEN fat_produto_classtrib.classtributaria_id IS NULL OR '65' = r_doctoc.seriemodelo THEN fat_produto.classtributaria_id ELSE fat_produto_classtrib.classtributaria_id END
			           ELSE
				  CASE WHEN fat_produto_classtrib.classtributaria_ncontrib_id IS NULL OR '65' = r_doctoc.seriemodelo THEN fat_produto.classtributaria_ncontrib_id ELSE fat_produto_classtrib.classtributaria_ncontrib_id END
			  END AS classificacao_trib,
             fat_produto.classorigem_id AS classorigem_id ,
             padrao.fat_classtributaria.codigoricms AS ricms,
             COALESCE(padrao.fat_aliqinss.aliquotapfisica, 0.00) AS aliq_funrural_inss_fisica,
             COALESCE(padrao.fat_aliqinss.aliquotapjuridica, 0.00) AS aliq_funrural_inss_juridica,
             aliquota_cofins, aliquota_pis,cst_pis,cst_cofins,
             COALESCE(fat_aliqissqn.aliquota, 0.00) AS iss_perc
         INTO r_produto
         FROM fat_produto
         LEFT JOIN padrao.fat_marca ON fat_produto.fat_marca_id = fat_marca.id
         LEFT JOIN padrao.fat_aliqissqn ON fat_produto.aliqissqn_id = fat_aliqissqn.id
         LEFT JOIN padrao.fat_classtipi ON fat_produto.classtipi_codigonbm = fat_classtipi.codigoncm
         LEFT JOIN fat_produto_classtrib ON fat_produto.id = fat_produto_classtrib.fat_produto_id AND r_cad.uf = fat_produto_classtrib.uf
         LEFT JOIN padrao.fat_classtributaria ON
              CASE WHEN r_cad.tipoa = 1 THEN
			      CASE WHEN fat_produto_classtrib.classtributaria_id IS NULL OR '65' = r_doctoc.seriemodelo THEN fat_produto.classtributaria_id ELSE fat_produto_classtrib.classtributaria_id END
			           ELSE
				  CASE WHEN fat_produto_classtrib.classtributaria_ncontrib_id IS NULL OR '65' = r_doctoc.seriemodelo THEN fat_produto.classtributaria_ncontrib_id ELSE fat_produto_classtrib.classtributaria_ncontrib_id END
			  END  = padrao.fat_classtributaria.id
         LEFT JOIN padrao.fat_aliqinss ON aliqinss_id = padrao.fat_aliqinss.id
        WHERE fat_produto.id = NEW.fat_produto_id ;
    ELSE
        SELECT fat_produto.id AS id,fat_produto.codigobarra1 AS codigobarra1,
             LEFT(fat_produto.descricao, 20) AS descricao, unidadepadraovenda,
             fat_marca.descricao AS marca,CAST(padrao.getpreco(r_doctoc.fat_listapre_id,r_doctoc.fat_listapre_tabela_tabela,fat_produto.id) AS NUMERIC(12,2)) AS preco,
             fat_produto.referencia AS referencia,localizacao,volume,pesoliquido,pesobruto,
             CAST(padrao.getestoque(r_doctoc.cad_filial_id,fat_produto.id) AS NUMERIC(12,3)) AS saldo,
             classtipi_codigonbm AS ncm, fat_produto.aliquota_ipi_saida AS aliquota_ipi_saida,
             fat_produto.aliquota_ipi_entrada AS aliquota_ipi_entrada, fat_classtipi.aliqnac AS ncm_aliqnac,
             classtipi_codigonbm, fat_classtipi.aliqimp AS ncm_aliqimp,
             CAST(COALESCE(padrao.geticms(fat_produto.aliquotas_normal_id,r_cad.uf,r_cad.tipoa),0) AS NUMERIC(5,3)) AS icms,
             CAST(COALESCE(padrao.geticms(fat_produto.aliquotas_normal_id,r_filial.uf,r_cad.tipoa),0) AS NUMERIC(5,3)) AS icms_subst_aliq_prop,
           --  CAST(COALESCE(padrao.geticms(fat_classtipi.aliq_dest_id,r_cad.uf,r_cad.tipoa), 0) AS NUMERIC(5,3)) AS icms_subst_aliq_dest,
            -- fat_classtipi.aliquota AS icms_subst_mva,
             CAST(COALESCE(padrao.geticms(fat_produto.aliquotas_normal_id,r_cad.uf, 5),0) AS NUMERIC(5,3)) AS icms_subst_mva,
             CAST( COALESCE( padrao.geticms( CAST(COALESCE(padrao.geticms(fat_produto.aliquotas_normal_id,r_cad.uf, 8), 0) AS int4) , r_cad.uf, r_cad.tipoa), 0) AS NUMERIC(5,3)) AS icms_subst_aliq_dest,
             CAST(padrao.getCustoProd(r_doctoc.cad_filial_id,fat_produto.id, CURRENT_DATE,r_doctoc.fat_listapre_tabela_tabela) AS NUMERIC(12,4)) AS custodigitado,
             CAST(padrao.getmovtoprod(r_doctoc.cad_cadastro_id, fat_produto.id,
             CASE WHEN d27_tipo_mvto = '2' OR d27_tipo_mvto = 'C' THEN '1'
                  WHEN d27_tipo_mvto = '4'                        THEN '3'
                  WHEN d27_tipo_mvto = '6'                        THEN '5'
                  WHEN d27_tipo_mvto = '8'                        THEN '7'
              END,
             CASE WHEN d27_tipo_mvto = 'C' THEN '2' ELSE d27_tipo_mvto END) AS NUMERIC(12,3)) AS saldomovto,
             CAST(COALESCE(padrao.geticms(aliquotas_reducaos_id,r_cad.uf,r_cad.tipoa),0) AS NUMERIC(5,3)) As icmsredsai,
             CAST(COALESCE(padrao.geticms(aliquotas_reducaoe_id,r_cad.uf,r_cad.tipoa),0) AS NUMERIC(5,3)) As icmsredent,
             CAST(COALESCE(padrao.geticms(aliquotas_diferimento_id,r_cad.uf,r_cad.tipoa),0) AS NUMERIC(5,3)) As icmsdife,
             CAST(COALESCE(padrao.geticms(fat_produto.aliquotas_normal_id,r_cad.uf,r_cad.tipoadif),0) AS NUMERIC(5,3)) AS icmsdifp,
             CAST(COALESCE(padrao.geticms(aliquotas_reducaos_id,r_cad.uf,r_cad.tipoadif),0) AS NUMERIC(5,3)) As icmsredsaiDifP,
             CAST(COALESCE(padrao.geticms(aliquotas_reducaoe_id,r_cad.uf,r_cad.tipoadif),0) AS NUMERIC(5,3)) As icmsredentdifp,
             CAST(COALESCE(padrao.geticms(aliquotas_diferimento_id,r_cad.uf,r_cad.tipoadif),0) AS NUMERIC(5,3)) As icmsdifedifp,
             classfiscal_id, classfiscal_entrada_id,
             CASE WHEN fat_produto_classtrib.uf IS NULL THEN r_cad.uf ELSE fat_produto_classtrib.uf END AS uf,
             CASE WHEN r_cad.tipoa = 1 THEN
			      CASE WHEN fat_produto_classtrib.classtributaria_id IS NULL OR '65' = r_doctoc.seriemodelo THEN fat_produto.classtributaria_id ELSE fat_produto_classtrib.classtributaria_id END
			           ELSE
				  CASE WHEN fat_produto_classtrib.classtributaria_ncontrib_id IS NULL OR '65' = r_doctoc.seriemodelo THEN fat_produto.classtributaria_ncontrib_id ELSE fat_produto_classtrib.classtributaria_ncontrib_id END
			  END AS classificacao_trib,
             fat_produto.classorigem_id AS classorigem_id
             , padrao.fat_classtributaria.codigoricms AS ricms,
             COALESCE(padrao.fat_aliqinss.aliquotapfisica, 0.00) AS aliq_funrural_inss_fisica,
             COALESCE(padrao.fat_aliqinss.aliquotapjuridica, 0.00) AS aliq_funrural_inss_juridica,
             aliquota_cofins, aliquota_pis,cst_pis,cst_cofins,
             COALESCE(fat_aliqissqn.aliquota, 0.00) AS iss_perc
         INTO r_produto
         FROM fat_produto
         LEFT JOIN padrao.fat_marca ON fat_produto.fat_marca_id = fat_marca.id
         LEFT JOIN padrao.fat_aliqissqn ON fat_produto.aliqissqn_id = fat_aliqissqn.id
         LEFT JOIN padrao.fat_classtipi ON fat_produto.classtipi_codigonbm = fat_classtipi.codigoncm
         LEFT JOIN fat_produto_classtrib ON fat_produto.id = fat_produto_classtrib.fat_produto_id AND r_cad.uf = fat_produto_classtrib.uf
         LEFT JOIN padrao.fat_classtributaria ON
               CASE WHEN r_cad.tipoa = 1 THEN
			      CASE WHEN fat_produto_classtrib.classtributaria_id IS NULL OR '65' = r_doctoc.seriemodelo THEN fat_produto.classtributaria_id ELSE fat_produto_classtrib.classtributaria_id END
			           ELSE
				  CASE WHEN fat_produto_classtrib.classtributaria_ncontrib_id IS NULL OR '65' = r_doctoc.seriemodelo THEN fat_produto.classtributaria_ncontrib_id ELSE fat_produto_classtrib.classtributaria_ncontrib_id END
			  END  = padrao.fat_classtributaria.id
         LEFT JOIN padrao.fat_aliqinss ON aliqinss_id = padrao.fat_aliqinss.id
        WHERE fat_produto.id = OLD.fat_produto_id ;
    END IF;
   /*
    * Classificacao Tributaria
    */
    NEW.icms_classtrib  := r_produto.classificacao_trib;
    NEW.icms_classorigem:= r_produto.classorigem_id;
    NEW.icms_ricms      := r_produto.ricms;

    IF d127_UsarClassTrib = '1' THEN
       NEW.icms_classtrib := d128_ClassTrib;
       NEW.icms_ricms     := (SELECT codigoricms FROM padrao.fat_classtributaria WHERE id = d128_ClassTrib);
       r_produto.classificacao_trib  := d128_ClassTrib;
       r_produto.ricms := NEW.icms_ricms;
    END IF;


   /*
    + Checa Precos
    */

     --Informe Preco tabela (1-Nao Obrigatorio 2-Somente Avisar 3-Obrigatorio

     IF d12_natureza = 'S' THEN
        IF d133_InformeCongPg = '3'THEN
	   --fat_listapre_id, fat_listapre_tabela_tabela, fat_condpg_id
	   SELECT id INTO r_condpgto from fat_condpg WHERE id = r_doctoc.fat_condpg_id;
	   IF NOT FOUND THEN
	      RAISE EXCEPTION 'CONDICAO PGTO ( % ) NAO CADASTRADA. VERIFIQUE!',  r_doctoc.fat_condpg_id;
	   END IF;
	   IF r_cad.fat_condpg_id != r_doctoc.fat_condpg_id THEN
	       RAISE EXCEPTION 'CONDICAO PGTO ( % ) DIFERENTE DA CONDICAO PGTO PERMITIDA ( % ). VERIFIQUE!',  r_doctoc.fat_condpg_id, r_cad.fat_condpg_id;
	   END IF;

    END IF;
	IF d134_InformeTabPreco= '3'THEN
	   SELECT id INTO r_listapre from fat_listapre WHERE id = r_doctoc.fat_listapre_id;
	   IF NOT FOUND THEN
		  RAISE EXCEPTION 'LISTA DE PRECO ( % ) NAO CADASTRADA. VERIFIQUE!',  r_doctoc.fat_listapre_id;
	   END IF;

	   SELECT tabela_id INTO r_listapretab from fat_listapre_tabela WHERE tabela_id =  r_doctoc.fat_listapre_id AND fat_listapre_id = r_doctoc.fat_listapre_tabela_tabela;
	   IF NOT FOUND THEN
		  RAISE EXCEPTION 'TABELA ( % ) DA LISTA DE PRECO ( % ) NAO CADASTRADA. VERIFIQUE!',  r_doctoc.fat_listapre_tabela_tabela, r_doctoc.fat_listapre_id;
	   END IF;

       IF r_cad.fat_listapre_id != r_doctoc.fat_listapre_id THEN
	      RAISE EXCEPTION 'LISTA DE PRECO ( % ) DIFERENTE DA LISTA DE PRECO PERMITIDA ( % ). VERIFIQUE!',  r_doctoc.fat_listapre_id, r_cad.fat_listapre_id;
	   END IF;

	   IF r_cad.fat_listapre_tabela_tabela != r_doctoc.fat_listapre_tabela_tabela THEN
	      RAISE EXCEPTION 'TABELA DE PRECO ( % ) DIFERENTE DA TABELA DE PRECO PERMITIDA ( % ). VERIFIQUE!',  r_doctoc.fat_listapre_tabela_tabela, r_cad.fat_listapre_tabela_tabela;
	   END IF;

	   IF New.valor_unitario  < r_produto.preco THEN
	      RAISE EXCEPTION 'Produto:% - % ESTA COM PRECO INCORRETO. VERIFIQUE! (%) - (%)',  r_produto.id, r_produto.descricao, r_produto.preco, new.valor_unitario;
	   END IF;
	END IF;
    END IF;

    --Permitir Item Valor Unitario (Zero):Sim/Nao
    IF d143_PermitePrecoZero= 'N'THEN
       IF New.valor_unitario  <= 0  THEN
          RAISE EXCEPTION 'Produto:% - % ESTA COM PRECO ZERADO. VERIFIQUE! (%) - (%)',  r_produto.id, r_produto.descricao, r_produto.preco, new.valor_unitario;
       END IF;
        IF New.valor_total  <= 0  THEN
          RAISE EXCEPTION 'Produto:% - % ESTA COM VALOR TOTAL  ZERADO. VERIFIQUE! VALOR TOTAL (%)',  r_produto.id, r_produto.descricao, new.valor_total;
       END IF;

	END IF;

   /*
    * Monta CFOP
    */
   IF d18_usarCFOP = '2' AND d12_natureza = 'E' THEN
        NEW.tabcfop_id    := CASE WHEN r_cad.uf = r_filial.uf THEN '1'|| r_produto.classfiscal_entrada_id
			         WHEN r_cad.uf = 'EX'        THEN '3'|| r_produto.classfiscal_entrada_id
			         ELSE '2'|| r_produto.classfiscal_entrada_id
			    END;
        NEW.icms_preducao = r_produto.icmsredent;
        NEW.ipi_percentual= r_produto.aliquota_ipi_entrada;
   END IF;
   IF d18_usarCFOP = '2' AND d12_natureza = 'S' THEN
        NEW.tabcfop_id    := CASE WHEN r_cad.uf = r_filial.uf THEN '5'|| r_produto.classfiscal_id
			         WHEN r_cad.uf = 'EX'        THEN '7'|| r_produto.classfiscal_id
			         ELSE '6'|| r_produto.classfiscal_id
			    END;
        NEW.icms_preducao := r_produto.icmsredsai;
        NEW.ipi_percentual:= r_produto.aliquota_ipi_saida;
        --RAISE EXCEPTION 'IPI ( % ) !', r_produto.aliquota_ipi_saida;

   END IF;

   IF d18_usarCFOP = '1' AND d12_natureza = 'E' THEN
        NEW.tabcfop_id   := CASE WHEN r_cad.uf = r_filial.uf THEN '1'|| d17_CFOP
			         WHEN r_cad.uf = 'EX'        THEN '3'|| d17_CFOP
			         ELSE '2'|| d17_CFOP
			    END;
        NEW.icms_preducao := r_produto.icmsredent;
        NEW.ipi_percentual:= r_produto.aliquota_ipi_entrada;
   END IF;
   IF d18_usarCFOP = '1' AND d12_natureza = 'S' THEN
        NEW.tabcfop_id    := CASE WHEN r_cad.uf = r_filial.uf THEN '5'|| d17_CFOP
			         WHEN r_cad.uf = 'EX'        THEN '7'|| d17_CFOP
			         ELSE '6'|| d17_CFOP
			    END;
        NEW.icms_preducao := r_produto.icmsredsai;
        NEW.ipi_percentual:= r_produto.aliquota_ipi_saida;
   END IF;
   --Verifica CFOP para produtos c/ ST
   IF r_cad.uf != r_filial.uf AND NEW.tabcfop_id = '6405' THEN
        NEW.tabcfop_id := '6403';
   END IF;
   --Checa desconto item
   --IF coalesce(NEW.desc_perc_unitario,0) > 0 AND coalesce(NEW.desc_valor_unitario,0) = 0 THEN
   --     NEW.desc_valor_unitario = ROUND(NEW.valor_unitario * NEW.desc_perc_unitario / 100,5);
   --END IF;
   --IF coalesce(NEW.desc_perc_unitario,0) = 0 AND coalesce(NEW.desc_valor_unitario,0) > 0 THEN
   --     NEW.desc_perc_unitario = ROUND(NEW.desc_perc_unitario / NEW.valor_unitario * 100,5);
   --END IF;


   NEW.valor_unitario_liquido   := COALESCE(NEW.valor_unitario_liquido, NEW.valor_unitario);
   NEW.valor_total_liquido      := COALESCE(NEW.valor_total_liquido, NEW.valor_total);
   NEW.desc_perc_unitario       := COALESCE(NEW.desc_perc_unitario,0);
   NEW.desc_valor_unitario      := COALESCE(NEW.desc_valor_unitario,0);


  /*
   * Consiste Desconto Item
   */
  IF NEW.desc_perc_unitario > 0 THEN
     IF  NEW.desc_valor_unitario = 0 THEN
         NEW.desc_valor_unitario = ROUND(NEW.valor_unitario * NEW.desc_perc_unitario / 100,3);

     END IF;
  END IF;

  IF NEW.desc_valor_unitario > 0 THEN
     IF  NEW.desc_perc_unitario = 0 THEN
         NEW.desc_perc_unitario = ROUND(NEW.desc_valor_unitario / NEW.valor_unitario * 100,3);
     END IF;
  END IF;

  --IF NEW.desc_perc_unitario > 0 OR NEW.desc_valor_unitario > 0 THEN
     NEW.valor_unitario_liquido := ROUND(NEW.valor_unitario - NEW.desc_valor_unitario,6) ;
     NEW.valor_total_liquido    := ROUND(NEW.valor_unitario_liquido * NEW.qtde, 2) ;
     NEW.valor_unitario_rateio  := NEW.valor_unitario_liquido;
     NEW.classtributaria_id     := r_produto.classificacao_trib;
  --END IF;

  --RAISE EXCEPTION 'VALOR LIQUIDO:[ % ] - Valor Unitario Rateio: [ % ]',NEW.valor_unitario_liquido, NEW.valor_unitario_rateio ;

  /*
   * Rateio desconto total nos itens
   */
  IF r_doctoc.descontodocto_valor >= 0 AND NEW.valor_unitario > 0 AND NEW.valor_unitario_liquido > 0 THEN
      IF COALESCE(r_doctoc.totalliquidoprodutos,0) > 0 THEN
        rateio_desc_valor_nf := (r_doctoc.descontodocto_valor * (((NEW.valor_unitario-
       												COALESCE(NEW.desc_valor_unitario,0)-
       												COALESCE(NEW.desc_valor_promocao,0)-
       												COALESCE(NEW.desc_valor_cliente,0)-
       												COALESCE(NEW.desc_valor_avista,0)-
       												COALESCE(NEW.desc_valor_avista,0)) * NEW. qtde) / COALESCE(r_doctoc.totalliquidoprodutos,0)  * 100) / 100) / NEW. qtde;
        												---COALESCE(NEW.desc_valor_avista,0)) * NEW. qtde) / COALESCE(r_doctoc.totalliquidoprodutos,r_doctoc.totalprodutos)  * 100) / 100) / NEW. qtde;

          IF NEW.valor_unitario_liquido > 0 THEN
            rateio_desc_valor_nf_perc :=  rateio_desc_valor_nf /  NEW.valor_unitario_liquido * 100;
          END IF;

          rateio_vl_unit_liq  := Round(NEW.valor_unitario-
                                   COALESCE(NEW.desc_valor_unitario,0)-
                                   COALESCE(NEW.desc_valor_promocao,0)-
                                   COALESCE(NEW.desc_valor_cliente,0)-
                                   COALESCE(NEW.desc_valor_avista,0)-
                                   COALESCE(NEW.desc_valor_avista,0)-
                                   rateio_desc_valor_nf,6);

          rateio_vl_total_liq        := Round(rateio_vl_unit_liq * NEW. qtde,6);

          NEW.desc_valor_nf          := rateio_desc_valor_nf;
          NEW.desc_perc_nf           := rateio_desc_valor_nf_perc;
          NEW.valor_unitario_rateio  := rateio_vl_unit_liq ;
      END IF;

      --NEW.valor_unitario_liquido := rateio_vl_unit_liq ;
      --NEW.valor_total_liquido    := rateio_vl_total_liq;
  END IF;


   NEW.icms_pdiferimento        := r_produto.icmsdife;
   NEW.icms_pdiferimentoparcial := r_produto.icmsdifedifp;

   NEW.funrural_perc            := r_produto.aliq_funrural_inss_fisica;

   IF substring(r_cad.pessoa from 1 for 1) = 'J'  AND (d16_calcularFUNRURAL = 'S' OR  d16_calcularFUNRURAL = 'D') THEN
    NEW.funrural_perc           := r_produto.aliq_funrural_inss_juridica;
   END IF;
   IF COALESCE(NEW.ipi_digitacaomanual,FALSE) = FALSE THEN
   	  --Calcula IPI
   	  IF d15_calcularIPI = 'S' THEN
		 NEW.ipi_basecalculo := NEW.valor_unitario_rateio * NEW.qtde;
		 NEW.ipi_valor       := (NEW.ipi_basecalculo *  NEW.ipi_percentual) / 100;
	  END IF;
   END IF;

   IF COALESCE(NEW.funrural_digitacaomanual,FALSE) = FALSE THEN
   	  --Calcula FUNRURAL
   	  IF d16_calcularFUNRURAL = 'S' OR  d16_calcularFUNRURAL = 'D' THEN
		 NEW.funrural_basecalculo := NEW.valor_unitario_rateio * NEW.qtde;
		 NEW.funrural_valor       := (NEW.funrural_basecalculo *  NEW.funrural_perc) / 100;
	  END IF;
   END IF;

   IF COALESCE(NEW.icms_digitacaomanual,FALSE) = FALSE THEN
   	  --Calcula ICMS
      NEW.icms_outros      := 0;
   	  --IF d14_calcularICMS = 'S' AND r_cad.contribuinteicms = 'Sim' THEN
   	  IF d14_calcularICMS = 'S' AND  r_doctoc.totalprodutos > 0 THEN
   	     --NEW.icms_basecalculo := NEW.valor_total_liquido;
   	     NEW.icms_basecalculo := Round((NEW.valor_unitario_rateio * NEW.qtde) + ((NEW.valor_unitario / r_doctoc.totalprodutos) * r_doctoc.frete_valor),2);
   	  	 IF r_cad.calculoicmssobre_ipi THEN
   	  	    --NEW.icms_basecalculo := NEW.valor_total_liquido + NEW.ipi_valor;
   	  	    NEW.icms_basecalculo := NEW.icms_basecalculo + NEW.ipi_valor;
   	  	 END IF;


		/*
		 * 1,2,8,A,B - Tributado / Diferido / Substituicao Tributuria / Diferido Parcial / Outros
		 */
   	  	IF SUBSTRING(r_produto.classificacao_trib from 1 for 1) IN ('1','2','8','A', 'B') THEN
   	  	   --RAISE NOTICE 'r_produto.classificacao_trib:(%)', r_produto.classificacao_trib;
   	  	   NEW.icms_perc := r_produto.icms;
   	  	   NEW.icms_valor := Round(NEW.icms_basecalculo * r_produto.icms / 100, 2);
   	  	   ---RAISE EXCEPTION

   	  	 /*
		  * 2-Calculo ICMS ST (ricms-10)
		  */
		  IF r_produto.classificacao_trib = '2' THEN
		     NEW.icms_subst_basecalculo := 0;
		     NEW.icms_subst_valor       := 0;
		     IF d12_natureza = 'S' THEN
		        NEW.icms_subst_basecalculo := NEW.icms_basecalculo * (1+ (r_produto.icms_subst_mva / 100));
                NEW.icms_subst_basecalculo := Round(NEW.icms_basecalculo * (1+ (r_produto.icms_subst_mva / 100)),2);
		        NEW.icms_subst_valor       := ABS(Round((NEW.icms_subst_basecalculo * r_produto.icms_subst_aliq_dest / 100) - (NEW.icms_basecalculo * r_produto.icms_subst_aliq_prop / 100 ),2)) ;
		        --RAISE EXCEPTION 'BASE CALC ICMS:[ % ] - MVA: [ % ]',NEW.icms_basecalculo, r_produto.icms_subst_mva  ;
		  	 END IF;
		  END IF;
   	  	  /*
		   * 8-Diferido Total dentro do estado
		   */
		   --IF r_produto.classificacao_trib = '8' THEN
		   --	  NEW.icms_perc        := 0;
		   --	  NEW.icms_basecalculo := 0;
		   --	  NEW.icms_valor       := 0;
		   --END IF;

		  /*
		   * 8-Diferido Total/Parcial
		   */
		   IF r_produto.classificacao_trib = '8' THEN
		   	  NEW.icms_perc        := r_produto.icms;
			  NEW.icms_basecalculo := NEW.valor_unitario_rateio * NEW.qtde;

			  --RAISE NOTICE 'icms_basecalculo: %',NEW.icms_basecalculo;
			  --RAISE NOTICE 'NEW.icms_perc...: %',NEW.icms_perc;
			  --RAISE NOTICE 'NEW.icms_perc...: %',NEW.icms_basecalculo * NEW.icms_perc;
			  --RAISE NOTICE 'NEW.icms_perc  Round: %',Round(NEW.icms_basecalculo * NEW.icms_perc,2);
			  --RAISE NOTICE 'NEW.icms_perc  tRUNC: %',Trunc(NEW.icms_basecalculo * NEW.icms_perc,2);
        /*            BigDecimal bcIcms = ObjectUtils.defaultIfNull(item.getIcmsBasecalculo(), BigDecimal.ZERO)
                            .setScale(2, RoundingMode.HALF_DOWN);
        --                BigDecimal icmsPer = ObjectUtils.defaultIfNull(item.getIcmsPerc(), BigDecimal.ZERO);
        --                BigDecimal icms = FatOperationUtils.round(bcIcms.multiply(icmsPer)
        .divide(new BigDecimal(100), BigDecimal.ROUND_HALF_DOWN), 2, false);
        --                BigDecimal difPer = FatOperationUtils.round(ObjectUtils.defaultIfNull(item.getIcmsPdiferimentoparcial()
        , BigDecimal.ZERO), 4, false);
        --                BigDecimal difVal = FatOperationUtils.round(icms.multiply(difPer).divide(new BigDecimal(100), BigDecimal.ROUND_HALF_DOWN), 2, false);
                        BigDecimal icmsDif = FatOperationUtils.round(icms.subtract(difVal), 2, false);
         */



			  V_ICMS           := round(NEW.icms_basecalculo * NEW.icms_perc / 100,2);

			  NEW.icms_valor   := V_ICMS;

			  --RAISE NOTICE 'V_ICMS===: %', V_ICMS;
                dif_per  :=  round(r_produto.icmsdifedifp, 4);
                NEW.icms_diferimento_operacao  :=  round((NEW.icms_basecalculo * NEW.icms_perc) / 100,2);
                NEW.icms_diferimento_valor := round((V_ICMS * dif_per)/100, 2) ;
                dif_icms:=   round(V_ICMS - dif_val, 2);
                --RAISE NOTICE 'dif_per===: %', dif_per;
                --RAISE NOTICE 'dif_val===: %',  NEW.icms_diferimento_valor;
                --RAISE NOTICE 'dif_icms===: %', dif_icms;


			  --RAISE NOTICE 'NEW.icms_valor: %',NEW.icms_valor;
			  --RAISE NOTICE 'r_produto.icmsdifedifp: %',r_produto.icmsdifedifp;


			  IF r_produto.icmsdifedifp > 0 THEN
                 NEW.icms_valor       := Round(NEW.icms_valor * (100 - r_produto.icmsdifedifp) / 100, 2);
			     --RAISE NOTICE ' NEW.icms_valor: %', NEW.icms_valor;


              END IF;
              IF r_produto.icmsdifedifp = 100 THEN
                 NEW.icms_perc        := 0;
		   	     NEW.icms_basecalculo := 0;
		   	     NEW.icms_valor       := 0;
              END IF;
		   END IF;
   	  	END IF;
		/*
		 * 5 - Isento 6 - Nao Tributado
		 */

   	  	IF SUBSTRING(r_produto.classificacao_trib from 1 for 1) IN ('5','6') THEN
		   NEW.icms_isentos     := NEW.valor_unitario_rateio * NEW.qtde;
		   NEW.icms_perc        :=  r_produto.icms;
		   NEW.icms_basecalculo := 0;
		   NEW.icms_valor       := 0;
		   NEW.icms_outros      := 0;
   	  	END IF;

   	  	/*
		 * 3 - Reducao
		 */
   	  	IF r_produto.classificacao_trib = '3' THEN

   	  	   --IF r_cad.uf = r_filial.uf AND NEW.icms_preducao > 0 THEN
   	  	      NEW.icms_basecalculo       := Round(NEW.icms_basecalculo - (NEW.icms_basecalculo * NEW.icms_preducao  /100), 2) ;
   	  	      NEW.icms_valor             := Round(NEW.icms_basecalculo * r_produto.icms / 100,2);
   	  	      NEW.icms_perc              := r_produto.icms;
   	  	      NEW.icms_isentos           := 0;
			  NEW.icms_outros            := 0;
			  NEW.icms_subst_basecalculo := 0;
			  NEW.icms_subst_valor       := 0;
   	  	   --END IF;
   	  	END IF;
   	  	/*
		 * 9 - ST cobrado anteriormente
		 */
   	  	IF r_produto.classificacao_trib = '9' THEN
   	  	   NEW.icms_basecalculo       := 0;
           NEW.icms_perc              := r_produto.icms;
   	  	   NEW.icms_valor             := 0;
   	  	   NEW.icms_isentos           := 0;
		   NEW.icms_outros            := NEW.valor_unitario_rateio * NEW.qtde;
		   NEW.icms_subst_basecalculo := 0;
		   NEW.icms_subst_valor       := 0;

   	  	END IF;
   	   /*
   	    *  F,G-Calculo ICMS ST (CSOSN-201, 202, 203)
   	    */
   	  	IF r_filial.regimetributacao = 'S' THEN
   	  	   NEW.icms_subst_basecalculo := 0;
           NEW.icms_subst_valor       := 0;
	   	   IF SUBSTRING(r_produto.classificacao_trib from 1 for 1) IN ('F','G','H') THEN

		      IF d12_natureza = 'S' THEN
		         NEW.icms_subst_basecalculo := Round(NEW.icms_basecalculo * (1+ (r_produto.icms_subst_mva / 100)),2);
 		         NEW.icms_subst_valor       := ABS(Round((NEW.icms_subst_basecalculo * r_produto.icms_subst_aliq_dest / 100) - (NEW.icms_basecalculo * r_produto.icms_subst_aliq_prop / 100 ),2)) ;
		         NEW.icms_perc              := 0;
                 NEW.icms_basecalculo       := 0;
                 NEW.icms_valor             := 0;
              END IF;
	   	   ELSE
		      NEW.icms_isentos           := 0;
		      NEW.icms_perc              := 0;
		      IF  r_cad.contribuinteicms = 'Nao' AND r_cad.uf <> r_filial.uf THEN
   	  	           NEW.icms_perc         := r_produto.icms;
   	  	      END IF;
		      NEW.icms_basecalculo       := 0;
		      NEW.icms_subst_basecalculo := 0;
		      NEW.icms_subst_valor       := 0;
		      NEW.icms_valor             := 0;
		      NEW.icms_outros            := NEW.valor_unitario_rateio * NEW.qtde;
	   	   END IF;
   	  	END IF;

	  END IF;

    -- COFINS
    IF coalesce(r_produto.aliquota_cofins, 0) > 0 THEN
        NEW.cofins_basecalculo := NEW.valor_unitario_rateio * NEW.qtde;
        NEW.cofins_perc  := r_produto.aliquota_cofins;
        NEW.cofins_valor := ROUND(NEW.cofins_basecalculo * (r_produto.aliquota_cofins / 100),2);
    ELSE
        NEW.cofins_basecalculo := 0;
        NEW.cofins_perc  := 0;
        NEW.cofins_valor := 0;
    END IF;

    -- PIS
    IF coalesce(r_produto.aliquota_pis, 0) > 0 THEN
        NEW.pis_basecalculo := NEW.valor_unitario_rateio * NEW.qtde;
        NEW.pis_perc  = r_produto.aliquota_pis;
        NEW.pis_valor = ROUND(NEW.pis_basecalculo * ( r_produto.aliquota_pis / 100),2);
    ELSE
      NEW.pis_basecalculo := 0;
        NEW.pis_perc  = 0;
        NEW.pis_valor = 0;
    END IF;

END IF;



   /*
    * Calcula Custo
    */

   custoTotalCalculo =
        coalesce(r_doctoc.infocustofretepagar,0)
      +	coalesce(r_doctoc.infocustojurosvendor,0)
      + coalesce(r_doctoc.infocustooutrasdesp,0)
      - coalesce(r_doctoc.infocustodescpgto,0)
      +	coalesce(r_doctoc.frete_valor,0)
      + coalesce(r_doctoc.despesa_valor,0)
      + coalesce(r_doctoc.seguro_valor,0)
      + CASE WHEN SUBSTRING(NEW.icms_classtrib from 1 for 1) IN ('2','9','A','F','G','H','K') THEN coalesce(r_doctoc.icmssubst_valor,0) ELSE 0 END;


            --CASE WHEN SUBSTRING(NEW.icms_classtrib from 1 for 1) IN ('2','9','A','F','G','H','K') AND  COALESCE(NEW.icms_digitacaomanual,FALSE) = FALSE THEN coalesce(r_doctoc.icmssubst_valor,0)
			--     WHEN SUBSTRING(NEW.icms_classtrib from 1 for 1) IN ('2','9','A','F','G','H','K') AND  COALESCE(NEW.icms_digitacaomanual,FALSE) = TRUE  THEN NEW.icms_subst_valor ELSE 0 END;


   --RAISE NOTICE ' + <BEFORE> r_doctoc.infocustojurosvendor  :(%)', r_doctoc.infocustojurosvendor;
   --RAISE NOTICE ' + <BEFORE> r_doctoc.infocustooutrasdesp   :(%)', r_doctoc.infocustooutrasdesp ;
   --RAISE NOTICE ' - <BEFORE> r_doctoc.infocustodescpgto     :(%)', r_doctoc.infocustodescpgto   ;
   --RAISE NOTICE ' + <BEFORE> r_doctoc.frete_valor           :(%)', r_doctoc.frete_valor         ;
   --RAISE NOTICE ' + <BEFORE> r_doctoc.despesa_valor         :(%)', r_doctoc.despesa_valor       ;
   --RAISE NOTICE ' + <BEFORE> r_doctoc.seguro_valor          :(%)', r_doctoc.seguro_valor        ;
   --RAISE NOTICE ' = <BEFORE> custoTotalCalculo              :(%)', custoTotalCalculo;
  rateio          = 0;
  rateioInfoCusto = 0;
  custoNF         = 0;

  IF COALESCE(NEW.valor_total_liquido,0)>0 AND COALESCE(NEW.qtde, 0) > 0 AND COALESCE(r_doctoc.totalliquidoprodutos,0) > 0 THEN
     rateio = custoTotalCalculo *	(NEW.valor_total_liquido / r_doctoc.totalliquidoprodutos);
     --RAISE NOTICE 'rateio 1:(%)', rateio;
     IF SUBSTRING(NEW.icms_classtrib from 1 for 1) IN ('2','9','A','F','G','H','K') THEN
        IF(COALESCE(NEW.icms_subst_valor, 0) > 0) THEN
          rateio = NEW.icms_subst_valor + ((custoTotalCalculo - coalesce(r_doctoc.icmssubst_valor,0)) * (NEW.valor_total_liquido / r_doctoc.totalliquidoprodutos)) ;
        ELSE
          IF d27_tipo_mvto <> 'X' THEN
             rateio = custoTotalCalculo * (NEW.valor_total_liquido / r_doctoc.total_prod_st);
          END IF;
        END IF;
        --RAISE NOTICE 'r_doctoc.total_prod_st:(%)', r_doctoc.total_prod_st;
        --RAISE NOTICE 'rateio ST:(%)', rateio;
     END IF;
     custoNF = coalesce(NEW.ipi_valor/NEW.qtde,0) + (rateio/NEW.qtde) + NEW.valor_unitario_liquido;
     --RAISE NOTICE 'IPI                       ( % ): ', coalesce(NEW.ipi_valor/NEW.qtde,0);
     --RAISE NOTICE '(rateio/NEW.qtde)         ( % ): ', (rateio/NEW.qtde);
     --RAISE NOTICE 'NEW.valor_unitario_liquido( % ): ', NEW.valor_unitario_liquido;
     --RAISE NOTICE 'custoNF                   ( % ): ', custoNF;
  END IF;

  custoInventario = custoNF;
  custoDigitado = custoNF;
  custoReal = custoNF;

  NEW.custo_real := custoReal;
  NEW.custo_digitado := custoDigitado;
  new.custo_inventario := custoInventario;



   RETURN NEW;
END;



$BODY$

LANGUAGE 'plpgsql' VOLATILE;

-- Gatilho {lancamento_integra_itens_before()} Versao {002} Esquema {empresa} Descricao {Grava integracao itens do documento }
-- ------------------------------------------------------------

CREATE TRIGGER lancamento_integra_itens_before BEFORE INSERT OR UPDATE ON fat_docto_i
       FOR EACH ROW EXECUTE PROCEDURE padrao.lancamento_integra_itens_before();



