
-- StoreProcedure {lancamento_integra()} Versao {220} Esquema {padrao} Descricao {Grava integracao do documento}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.lancamento_integra()
  RETURNS trigger AS

 $BODY$



DECLARE
 --Variaveis
   dia                   double precision;
   mes                   double precision;
   ano                   double precision;
   ultimoVcto            DATE;
   emissao               DATE;
   vencimento            DATE;
   valorNFsaldo          NUMERIC(14,2); -- Valor Total da NF
   valorPA               NUMERIC(14,2); -- Valor da PArcela
   valorComissao         NUMERIC(14,2); -- Valor da Comissao pelo recebimento
   pjurosmora            NUMERIC(14,6); -- (%)Juros Mora
   pmulta                NUMERIC(14,6); -- (%)multa por atraso
   pacrescimo            NUMERIC(14,6); -- (%)acrescimo
   ncarencia             NUMERIC( 4,0); -- (%)carencia
   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
   total_prod2            NUMERIC(14,6);
   rateio_totalprod_bruto      NUMERIC(14,6);
   rateio_totalprod_liquido    NUMERIC(14,6);

   r_lctoitens_valor_unitario       NUMERIC(9,6);
   r_lctoitens_desc_valor_unitario  NUMERIC(9,6);
   r_lctoitens_desc_valor_promocao  NUMERIC(9,6);
   r_lctoitens_desc_valor_cliente   NUMERIC(9,6);
   r_lctoitens_desc_valor_avista    NUMERIC(9,6);
   r_lctoitens_qtde                 NUMERIC(14,6);


   Receber_Pagar         CHAR(1);
   aCampos               character varying[];
   aDados                character varying[];
   aCamposCl             character varying[];
   aDadosCl              character varying[];
   aCamposPed            character varying[];
   aDadosPed             character varying[];
   sCampos               VARCHAR;
   sDados                VARCHAR;
   totParcelas           NUMERIC(14,2);
   qtdeParcelas          integer;
   valorTotalNF          NUMERIC(14,2); -- Valor Total da NF
   rp_id_seq             integer;

 --Faturamento
   d11_perc_comissao     NUMERIC(14,5);
   d12_natureza          CHAR(1); --Natureza: Entrada/Saida
   d13_tipo_docto        CHAR(1); --Tipo Docto: Nota Fiscal/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 Fiasal 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
 --Estoque
   d26_atualiza_estoque  CHAR(1); --Atualiza estouque:(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

   r_transacao      RECORD;
   r_lctoitens      RECORD;
   r_condpgto       RECORD; -- Condicao de pgto
   r_condpgtop      RECORD; -- Condicao de pgto - parcelas
   r_finaceiro      RECORD; -- Financeiro - Gravar classificacao gerencial
   r_tipocobranca   RECORD; -- Tipo de cobranca
   r_parameters     RECORD; -- Parametros padrao do sistema
   r_doctoI         RECORD; -- Documento Itens
   r_unidade        RECORD; -- Cadastro de unidade p/ sincronizacao
   r_detail_sync    RECORD; -- Cadastro de faixas para sincronizacao
   r_listapre       RECORD; -- Lista de preco
   r_listapretab    RECORD; -- Lista de preco - tabela
   r_cad            RECORD; -- Cadastro Cadastro Destinatario
   r_filial         RECORD; -- Cadastro Cadastro Emitente
   r_doctoI_tot_prod   RECORD; -- Documento Itens
   r_tot_rp            RECORD; -- Total RP
   r_contem_Baixa      RECORD; -- Total RP




BEGIN



-- SE FOR UMA EXCLUSAO
   IF TG_OP = 'DELETE'  THEN
   -- DELETE  CONTAS A RECEBE/PAGAR
      --EXECUTE 'DELETE FROM ' || getesquema('pagar')||'.pagar WHERE cad_cadastro_id = '|| OLD.cad_cadastro_id ||'AND fatura = '|| OLD.fat_docto_c_controle ;

	  DELETE FROM fat_docto_pc WHERE fat_docto_c_controle = old.controle;
	  DELETE FROM financ_rp WHERE status_reg = 'A' AND fatura = old.controle;

      IF LENGTH(TRIM(COALESCE(OLD.ctrl_agrupados,''))) > 0  THEN
         EXECUTE 'UPDATE fat_docto_c SET statuslcto = 94, statusdocto = ''LCTO DESAGRUPADO->'' WHERE controle IN '|| OLD.ctrl_agrupados ;
         EXECUTE 'UPDATE fat_docto_i SET qtde = qtde WHERE fat_docto_c_controle IN '|| OLD.ctrl_agrupados ;
      END IF;
      RETURN NULL;
   END IF;



   IF NEW.statuslcto = 7    OR
      NEW.statuslcto = 8    OR
      NEW.statuslcto = 135  OR
      NEW.statuslcto = 205  OR
      NEW.statuslcto = 302  THEN
      -- LOOP PRODUTOS
      FOR r_doctoI IN SELECT fat_docto_c_controle, fat_produto_id
                        FROM fat_docto_i
                       WHERE fat_docto_c_controle  = old.controle
                       LOOP

   	      EXECUTE 'DELETE FROM fat_produto_movto WHERE fat_docto_c_controle = '|| r_doctoI.fat_docto_c_controle || 'and fat_produto_id = ' || r_doctoI.fat_produto_id;

	      IF NOT padrao.gravaEstoque(r_doctoI.fat_produto_id, old.cad_filial_id, old.dataentradasaida, false)THEN
	         RAISE EXCEPTION 'Nao foi possivel persistir estoque do produto (Cod.:% NF:% - CTRL:%)!', r_doctoI.fat_produto_id,OLD.numero_docto ,OLD.fat_docto_c_controle ;
	      END IF;
      END LOOP;

      DELETE FROM financ_rp    WHERE status_reg =  'A' AND fatura =  old.controle;
      DELETE FROM fat_docto_pc WHERE fat_docto_c_controle = old.controle;

      IF LENGTH(TRIM(COALESCE(OLD.ctrl_agrupados,''))) > 0  THEN
         EXECUTE 'UPDATE fat_docto_c SET statuslcto = 94, statusdocto = ''LCTO DESAGRUPADO->'' WHERE controle IN '|| OLD.ctrl_agrupados ;
         EXECUTE 'UPDATE fat_docto_i SET qtde = qtde WHERE fat_docto_c_controle IN '|| OLD.ctrl_agrupados ;
      END IF;

      RETURN NULL;
   END IF;


-- LOOP
   FOR r_transacao IN SELECT * FROM view_transacao WHERE codigo_transacao = NEW.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);
       	  --RAISE EXCEPTION 'd12_natureza:(%)',  d12_natureza;
       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/Deduzir)
       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;
   	-- 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 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 = NEW.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 = NEW.cad_filial_id;

--   IF d12_natureza = 'S' THEN
--       -- Verifica Condicao de Pagamento
--       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 = NEW.fat_condpg_id;
--	      IF NOT FOUND THEN
--	        RAISE EXCEPTION 'CONDICAO PGTO ( % ) NAO CADASTRADA. VERIFIQUE!',  NEW.fat_condpg_id;
--	      END IF;
--	      IF r_cad.fat_condpg_id != NEW.fat_condpg_id THEN
--	         RAISE EXCEPTION 'CONDICAO PGTO ( % ) DIFERENTE DA CONDICAO PGTO PERMITIDA ( % ). VERIFIQUE!',  NEW.fat_condpg_id, r_cad.fat_condpg_id;
--	     END IF;
--       END IF;
--
--       -- Verifica Lista e Tabela de Precos
--       IF d134_InformeTabPreco= '3'THEN
--	      SELECT id INTO r_listapre from fat_listapre WHERE id = NEW.fat_listapre_id;
--	      IF NOT FOUND THEN
--		     RAISE EXCEPTION 'LISTA DE PRECO ( % ) NAO CADASTRADA. VERIFIQUE!',  NEW.fat_listapre_id;
--	      END IF;
--
--	      SELECT tabela_id INTO r_listapretab from fat_listapre_tabela WHERE tabela_id =  NEW.fat_listapre_id AND fat_listapre_id = NEW.fat_listapre_tabela_tabela;
--	      IF NOT FOUND THEN
--		     RAISE EXCEPTION 'TABELA ( % ) DA LISTA DE PRECO ( % ) NAO CADASTRADA. VERIFIQUE!',  NEW.fat_listapre_tabela_tabela, NEW.fat_listapre_id;
--	      END IF;
--
--          IF r_cad.fat_listapre_id != NEW.fat_listapre_id THEN
--	         RAISE EXCEPTION 'LISTA DE PRECO ( % ) DIFERENTE DA LISTA DE PRECO PERMITIDA ( % ). VERIFIQUE!',  NEW.fat_listapre_id, r_cad.fat_listapre_id;
--	      END IF;
--
--	      IF r_cad.fat_listapre_tabela_tabela != NEW.fat_listapre_tabela_tabela THEN
--	         RAISE EXCEPTION 'TABELA DE PRECO ( % ) DIFERENTE DA TABELA DE PRECO PERMITIDA ( % ). VERIFIQUE!', r_cad.fat_listapre_tabela_tabela,NEW.fat_listapre_tabela_tabela;
--	      END IF;
--	   END IF;
--
--   END IF;


   --RAISE EXCEPTION 'numero doc:% (%)', new.seriedocto_codigo, new.numero_docto;

    IF d26_atualiza_estoque = 'S' THEN
    	IF d29_alterrrCUC = 'S'  OR d28_alterarCM = 'S' THEN
       		UPDATE fat_docto_i SET qtde = qtde,custo_nf = valor_unitario_liquido, dataalteracao = current_date, horaalteracao = current_time WHERE fat_docto_c_controle = NEW.controle;
   		END IF;
   END IF;




   --
   -- grava consignacao/entrega futura
   --


      IF d27_tipo_mvto = '1' OR d27_tipo_mvto = '3' OR d27_tipo_mvto = '5' OR d27_tipo_mvto = '7' OR d27_tipo_mvto = 'O' OR d27_tipo_mvto = 'P' THEN
	       aCamposPed =  '{ fat_docto_c_controle,
		                   tipo,
		                   cad_cadastro_id,
		                   cad_filial_id,
		                   data_p,
		                   status_p}';


		      aDadosPed  =   '{' || to_char(NEW.controle,  '9999999999')   ||','
		     			         || cast(d27_tipo_mvto ||d12_natureza as varchar)  ||','
		     			         || to_Char(NEW.cad_cadastro_id, '999999999')  ||','
		     			         || to_Char(NEW.cad_filial_id, '999')      ||','
		     			         || to_Char(NEW.emissao, 'dd/MM/yyyy')     ||','
		     			         || 'P'                                    ||'}';

		     --RAISE NOTICE 'aCamposPed: (%)',     aCamposPed;
		     --RAISE NOTICE 'aDadosPed: (%)',      aDados;

		     IF NOT padrao.gravaPC(aCamposPed, aDadosPed)THEN
		        RAISE EXCEPTION 'nao possivel persistir saldo ds pedidos-fat_docto_pc (NF:% - CTRL:% - Tipo:%)!',NEW.numero_docto , New.controle, cast(d27_tipo_mvto ||d12_natureza as varchar) ;
		     END IF;
        END IF;

   -- -------------------------------------------------------
   -- Rateio Desconto Total
   -- -------------------------------------------------------


  SELECT SUM(((
        coalesce(valor_unitario,0)-
        coalesce(desc_valor_unitario,0)-
        coalesce(desc_valor_promocao,0)-
        coalesce(desc_valor_cliente,0)-
        coalesce(desc_valor_avista,0)-
        coalesce(desc_valor_avista,0))))   As total_produto
   INTO r_doctoI_tot_prod
   FROM fat_docto_i
  WHERE fat_docto_c_controle = NEW.controle;

  rateio_totalprod_bruto   := 0;
  rateio_totalprod_liquido := 0;

  IF coalesce(NEW.descontodocto_valor,0) > 0 AND TG_OP = 'INSERT' THEN
	   FOR r_lctoitens IN SELECT * FROM fat_docto_i WHERE fat_docto_c_controle = NEW.controle LOOP


	        rateio_desc_valor_nf := (coalesce(NEW.descontodocto_valor,0) * (((coalesce(r_lctoitens.valor_unitario,0)-
		          												coalesce(r_lctoitens.desc_valor_unitario,0)-
		          												coalesce(r_lctoitens.desc_valor_promocao,0)-
		          												coalesce(r_lctoitens.desc_valor_cliente,0)-
		          												coalesce(r_lctoitens.desc_valor_avista,0)-
		          												coalesce(r_lctoitens.desc_valor_avista,0)) * r_lctoitens.qtde) /  r_doctoI_tot_prod.total_produto * 100) / 100) / r_lctoitens.qtde;


			rateio_desc_valor_nf_perc :=  rateio_desc_valor_nf /  r_lctoitens.valor_unitario * 100;


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

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

			rateio_totalprod_bruto   =   Round(rateio_totalprod_bruto   + (r_lctoitens.valor_unitario * r_lctoitens.qtde),6)    ;
            rateio_totalprod_liquido =   Round(rateio_totalprod_liquido + rateio_vl_total_liq, 6);


	      EXECUTE 'UPDATE fat_docto_i '||
	               '   SET desc_valor_nf = '|| COALESCE(rateio_desc_valor_nf, 0)||', desc_perc_nf ='|| COALESCE(rateio_desc_valor_nf_perc,0) || ', valor_unitario_liquido=' || COALESCE(rateio_vl_unit_liq,0) || ', valor_total_liquido =' || COALESCE(rateio_vl_total_liq,0) ||
	               ' WHERE fat_docto_c_controle ='|| r_lctoitens.fat_docto_c_controle||
	               '   AND fat_produto_id ='|| r_lctoitens.fat_produto_id;


	   END LOOP ;

   ELSEIF TG_OP = 'UPDATE'  THEN
   	   IF coalesce(NEW.descontodocto_valor,0) > 0 THEN
		   FOR r_lctoitens IN SELECT * FROM fat_docto_i WHERE fat_docto_c_controle = NEW.controle LOOP

		        rateio_desc_valor_nf := (coalesce(NEW.descontodocto_valor,0) * (((coalesce(r_lctoitens.valor_unitario,0)-
		          												coalesce(r_lctoitens.desc_valor_unitario,0)-
		          												coalesce(r_lctoitens.desc_valor_promocao,0)-
		          												coalesce(r_lctoitens.desc_valor_cliente,0)-
		          												coalesce(r_lctoitens.desc_valor_avista,0)-
		          												coalesce(r_lctoitens.desc_valor_avista,0)) * r_lctoitens.qtde) / r_doctoI_tot_prod.total_produto * 100) / 100) / r_lctoitens.qtde;

				rateio_desc_valor_nf_perc :=  rateio_desc_valor_nf /  r_lctoitens.valor_unitario * 100;


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

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

				rateio_totalprod_bruto   =   Round(rateio_totalprod_bruto   + (r_lctoitens.valor_unitario * r_lctoitens.qtde),6)    ;
                rateio_totalprod_liquido =   Round(rateio_totalprod_liquido + rateio_vl_total_liq, 6);

		        EXECUTE 'UPDATE fat_docto_i '||
		               '   SET desc_valor_nf = '|| COALESCE(rateio_desc_valor_nf,0)||', desc_perc_nf ='|| COALESCE(rateio_desc_valor_nf_perc,0) || ', valor_unitario_liquido=' || COALESCE(rateio_vl_unit_liq,0) || ', valor_total_liquido =' || COALESCE(rateio_vl_total_liq,0) ||
		               ' WHERE fat_docto_c_controle ='|| r_lctoitens.fat_docto_c_controle||
		               '   AND fat_produto_id ='|| r_lctoitens.fat_produto_id;


		   END LOOP ;

	   END IF;
   END IF;



   --********************************************************
   -- Lanca Contas a receber/ Pagar
   --********************************************************


    IF d49_lancarCRP != 'S'  OR
       NEW.statuslcto = 7    OR
       NEW.statuslcto = 8    OR
       NEW.statuslcto = 95   OR
       NEW.statuslcto = 135  OR
       NEW.statuslcto = 205  OR
       NEW.statuslcto = 302  THEN
	  IF TG_OP = 'UPDATE'  THEN
	   	 -- Exclui Financeiro caso nao haja integracao com o mesmo
	   	 DELETE FROM financ_rp WHERE fatura = OLD.controle;



	   	 RETURN NULL;
	  END IF;
   END IF;
   IF d49_lancarCRP = 'S' THEN
       IF TG_OP = 'INSERT'  THEN
          --Posiciona cadastro de unidade (sync)
		   SELECT id
		     INTO r_unidade
		     FROM cad_unidade
		    ORDER BY id
		    LIMIT 1;
		   IF FOUND THEN
		      -- Checa Faixa sync financ_rp
		      SELECT *
		      INTO   r_detail_sync
		      FROM   sync_table_details
		      WHERE  unidade_id = r_unidade.id
		        AND  nome_table = 'fat_docto_c';
		      IF FOUND THEN
		         IF NOT (NEW.controle >= r_detail_sync.faixa_inicio AND NEW.controle <= r_detail_sync.faixa_fim) THEN
		            RETURN NULL;
		         END IF;
		      END IF;
		   END IF;
	   END IF;

       --exlcuir contas a receber/pagar
       IF TG_OP = 'UPDATE' THEN
        --Consiste Saldo
          UPDATE financ_rp_baixas SET  datapgto = datapgto  WHERE fat_docto_c_controle = OLD.controle;
        --Soma RP
--          SELECT SUM(round(coalesce(valor_saldo),2)) As total_saldo
--          INTO r_tot_rp
--          FROM financ_rp
--          WHERE fatura = OLD.controle AND (OLD.statuslcto = 6 OR OLD.statuslcto = 100) ;

       	    SELECT fat_docto_c_controle FROM financ_rp_baixas
              INTO r_contem_Baixa
             WHERE fat_docto_c_controle =  NEW.controle;

    	  IF FOUND AND d13_tipo_docto = 'N' THEN
       	     --RAISE EXCEPTION 'DOCUMENTO CONTEM BAIXA - CONTROLE:(%). VERIFIQUE !!!', OLD.controle;
	         RETURN NULL;
	      END IF;



	       --Posiciona condpg
			SELECT parcelas,prazoparcelas,vctoapartir
			  INTO r_condpgto
			  FROM fat_condpg
			 WHERE id = NEW.fat_condpg_id;

           --Corrige documento no financ
           UPDATE financ_rp        SET docto = NEW.seriedocto_codigo||'-'||ltrim(to_char(NEW.numero_docto,'0999999'))||'-'||ltrim(to_char(financ_rp.parcela,'09'))||'/'||ltrim(to_char(r_condpgto.parcelas,'09')), prorrogacao = vcto, valor_saldo = valor_total  WHERE fatura = OLD.controle;
           --Consiste Itens do documento
           UPDATE fat_docto_i      SET qtde = qtde  WHERE fat_docto_c_controle = OLD.controle;
           --UPDATE financ_rp_baixas SET  datapgto = datapgto  WHERE fatura = OLD.controle;

           IF NEW.fat_condpg_id     = OLD.fat_condpg_id    AND
              NEW.valortotal_docto  = OLD.valortotal_docto AND
              NEW.cad_cadastro_id   = OLD.cad_cadastro_id  AND
              NEW.cad_filial_id     = OLD.cad_filial_id    AND
              NEW.emissao           = OLD.emissao          AND
              NEW.fat_transacao_id  = OLD.fat_transacao_id THEN


              RETURN NULL;
           END IF;

--	       IF NEW.fat_condpg_id     != OLD.fat_condpg_id    OR
--	          NEW.valortotal_docto  != OLD.valortotal_docto OR
--	          NEW.nfesituacao       != OLD.nfesituacao      OR
--	          OLD.nfesituacao        = 'Cancelada'          OR
--              NEW.numero_docto      != OLD.numero_docto     THEN

	          --IF d12_natureza = 'E' THEN -- Entrada
	              DELETE FROM financ_rp WHERE cad_cadastro_id =  OLD.cad_cadastro_id  AND fatura = OLD.controle;
	          --END IF;

--	       END IF;
	       IF NEW.nfesituacao = 'Cancelada' THEN
	          RETURN NULL;
	       END IF;
	   END IF;
	 --Posiciona condpg
	   SELECT parcelas,prazoparcelas,vctoapartir
	     INTO r_condpgto
	     FROM fat_condpg
	    WHERE id = NEW.fat_condpg_id;


	 --Valor Nota Fiscal
	   valorNFsaldo = NEW.valortotal_docto;
	   valorTotalNF = NEW.valortotal_docto;
	   IF d16_calcularFUNRURAL = 'S' THEN
	      valorNFsaldo = valorNFsaldo - COALESCE(NEW.funrural_valor,0);
	      valorTotalNF = valorTotalNF - COALESCE(NEW.funrural_valor,0);
	   END IF;
	 --Loop parcelas
	  dia 		  = EXTRACT(DAY   FROM NEW.emissao);
	  mes         = EXTRACT(MONTH FROM NEW.emissao);
	  ano         = EXTRACT(YEAR  FROM NEW.emissao);
	  ultimoVcto  = NEW.emissao;
	  emissao     = NEW.emissao;
	  qtdeParcelas= 0;
	  FOR r_condpgtop IN SELECT *
	                       FROM fat_condpg_p
	                      WHERE fat_condpg_id = NEW.fat_condpg_id
	                      ORDER BY parcela LOOP



	       --RAISE NOTICE 'dia: (%)',     dia;
	       --RAISE NOTICE 'mes: (%)',     mes;
	       --RAISE NOTICE 'ano: (%)',     ano;
	       --RAISE NOTICE 'ultimoVcto: (%)',     ultimoVcto;
	     --Periodo (em construcao)
	       IF r_condpgto.prazoparcelas = 'Periodo' THEN
	          RAISE EXCEPTION 'Condicao de pagamento por periodo ainda em construcao' ;
	       END IF;
	     --Mensal
	       IF r_condpgto.prazoparcelas = 'Mensal' THEN
	          mes = mes + 1;
	          IF mes > 12 THEN
	             mes = 1;
	             ano = ano + 1;
	          END IF;
	          --RAISE EXCEPTION 'Condicao de pagamento por periodo ainda em construcao % %', vencimento ,to_Char(ano,'9999')||'-'||to_Char(mes,'99'||'/'||to_Char(dia,'99');
	          vencimento = to_Date(to_Char(ano,'0999')||'-'||Trim(to_Char(mes,'09'))||'-'||Trim(to_Char(dia,'09')),'YYYY-MM-DD');
	          --RAISE EXCEPTION 'Condicao de pagamento por periodo ainda em construcao %', vencimento ;
	          IF vencimento IS NULL THEN
	             vencimento = getLastDay(NEW.emissao);
	          END IF;
	       END IF;

	    --Diario
	      IF r_condpgto.prazoparcelas = 'Diario' THEN
	         --vencimento = ultimoVcto + r_condpgtop.diasemissao;
	         vencimento = emissao + r_condpgtop.diasemissao;
	         ultimoVcto = vencimento;
	      END IF;

	     valorPA      = (valorTotalNF  * r_condpgtop.percentual) / 100;
	     valorNFsaldo = valorNFsaldo - valorPA;
	     qtdeParcelas = qtdeParcelas + 1;



	     IF qtdeParcelas = r_condpgto.parcelas THEN
	       IF valorNFsaldo <> 0 THEN
	       	valorPA = valorPA + valorNFsaldo;
	       END IF;
	     END IF;

	     --RAISE EXCEPTION 'valorTotalNF:%  - valorPA:%',valorTotalNF,valorPA ;

	     if valorPA IS NULL THEN
	        valorPA = COALESCE(valorPA, 0);
	        --RAISE EXCEPTION 'Valor parcela NULL: %  - ValorSaldo: % Prazo Parcela: %', valorPA, valorNFsaldo, r_condpgto.prazoparcelas ;
	     END IF;
	     --mCm          = Comissao * FaCondI->fpe / 100;
	   --Grava contas Receber/Pagar
	     Receber_Pagar = (CASE WHEN d12_natureza = 'E' THEN 'P' ELSE 'R' END);
	     Receber_Pagar = (CASE WHEN d13_tipo_docto <> 'N' THEN 'O' ELSE Receber_Pagar END);
	     --RAISE EXCEPTION 'Receber_Pagar:( % )',  Receber_Pagar;
	   --Checa constrant
	     IF vencimento IS NULL THEN
	        RAISE EXCEPTION 'Vencimento nulo. Nao possivel persistir financeiro (NF:% - CTRL:%)!',NEW.numero_docto , New.controle ;
	     END IF;

	     IF r_condpgtop.financ_portador_id IS NULL THEN
	        RAISE EXCEPTION 'Portador nulo. Verique condicao de pgto (NF:% - CTRL:% C.Pgto.:%) !',NEW.numero_docto , New.controle, NEW.fat_condpg_id ;
	     END IF;

	     IF r_condpgtop.financ_tipocobranca_id IS NULL THEN
	        RAISE EXCEPTION 'Tipo de cobranca nulo. Verique condicao de pgto (NF:% - CTRL:% C.Pgto.:%) !',NEW.numero_docto , New.controle, NEW.fat_condpg_id ;
	     END IF;

	     --Posiciona Tipo de Cobranca
	     SELECT multa, juro, desconto, def_juros,acrescimo,carencia
	       INTO r_tipocobranca
	       FROM padrao.financ_tipocobranca
	      WHERE id = r_condpgtop.financ_tipocobranca_id;

	     --Posiciona Tipo de Cobranca
	     SELECT *
	       INTO r_parameters
	       FROM fat_parameters
	      LIMIT 1 ;
	     --Checa JurosMora/Multa/Acrescimo
	     pjurosmora = CASE WHEN r_parameters.financjurosmora IS NULL THEN 0 ELSE r_parameters.financjurosmora END;
	     pmulta     = CASE WHEN r_parameters.financmulta     IS NULL THEN 0 ELSE r_parameters.financmulta     END;
	     pacrescimo = CASE WHEN r_parameters.financacrescimo IS NULL THEN 0 ELSE r_parameters.financacrescimo END;
	     ncarencia  = CASE WHEN r_parameters.financcarencia  IS NULL THEN 0 ELSE r_parameters.financcarencia  END;

	     IF substring(r_tipocobranca.def_juros from 1 for 1) = '1' THEN -- Juros pelo Tipo de Cobranca
	        pjurosmora = CASE WHEN r_tipocobranca.juro      IS NULL THEN 0 ELSE r_tipocobranca.juro      END;
	        pmulta     = CASE WHEN r_tipocobranca.multa     IS NULL THEN 0 ELSE r_tipocobranca.multa     END;
	        pacrescimo = CASE WHEN r_tipocobranca.acrescimo IS NULL THEN 0 ELSE r_tipocobranca.acrescimo END;
	        ncarencia  = CASE WHEN r_tipocobranca.carencia  IS NULL THEN 0 ELSE r_tipocobranca.carencia  END;
	     END IF;



	     aCampos =  '{ cad_cadastro_id,
	                   fatura,
	                   parcela,
	                   cad_filial_id,
	                   emissao,
	                   vcto,
	                   prorrogacao,
	                   docto,
	                   portador_id,
	                   tipocobranca_id,
	                   status_reg,
	                   moeda_id,
                       vendedor_id,
					   per_acrescimo,
					   per_jurosmora,
					   per_multa,
                       carencia,
	                   valor_desconto,
					   valor_jurosmora,
					   valor_acrescimo,
	                   valor_total,
	                   valor_saldo}';



	      aDados  =   '{' || to_char(NEW.cad_cadastro_id, '999999999')   ||','
	                      || to_char(NEW.controle,  '9999999999')           ||','
	                      || to_char(r_condpgtop.parcela,  '999')           ||','
	     			      || to_Char(NEW.cad_filial_id, '999')              ||','
	     			      || to_Char(NEW.emissao, 'dd/MM/yyyy')             ||','
	     			      || to_Char(vencimento::DATE, 'dd/MM/yyyy')          ||','
	     			      || to_Char(vencimento::DATE, 'dd/MM/yyyy')          ||','
	     			      || NEW.seriedocto_codigo||'-'||ltrim(to_char(NEW.numero_docto,'0999999'))||'-'||ltrim(to_char(r_condpgtop.parcela,'09'))||'/'||ltrim(to_char(r_condpgto.parcelas,'09'))  ||','
	     			      || to_Char(r_condpgtop.financ_portador_id, '999')    ||','
	     			      || to_Char(r_condpgtop.financ_tipocobranca_id, '999')||','
	     			      || 'A'                                            ||','
	     			      || 'R$'                                           ||','
	     			      || to_char(NEW.cadastro_vendedor_id,'99999')   ||','
	     			      || to_Char(pacrescimo, '999999999.99')            ||','
	     			      || to_Char(pjurosmora, '999999999.99')            ||','
	     			      || to_Char(pmulta, '999999999.99')                ||','
	     			      || to_Char(ncarencia, '999999999')              ||','
	     			      || '0.00'                                         ||','
	     			      || '0.00'                                         ||','
	     			      || '0.00'                                         ||','
	     			      || to_Char(valorPA, '999999999.99')               ||','
	     			      || to_Char(valorPA, '999999999.99')               ||'}';

	     --RAISE NOTICE 'aCampos fianc_rp: (%)',     aCampos;
	     --RAISE NOTICE 'aDados financ_rp: (%)',      aDados;

	     IF aDados IS NULL THEN
	        RAISE EXCEPTION 'Nao sera possivel gravar docto.
                             Dados para financeiro incompleto. Verifique campos <NULL>:
                            (cad_cadastro_id:%
                              fatura:%
                              parcela:%
                              cad_filial_id:%
                              emissao:%
                              vcto:%
                              prorrogacao:%
                              docto:%
                              portador_id:%
                              tipocobranca_id:%
                              status_reg:%
                              moeda_id:%
							  cadastro_vendedor_id:%
                              per_acrescimo:%
					          per_jurosmora:%
					          per_multa:%
                              carencia:%
                              valor_desconto:%
                              valor_jurosmora:%
                              valor_acrescimo:%
                              valor_total:%
                              valor_saldo:%)',
                               to_char(NEW.cad_cadastro_id, '999999999')   ,
                               to_char(NEW.controle,  '9999999999')           ,
                               to_char(r_condpgtop.parcela,  '999')           ,
                               to_Char(NEW.cad_filial_id, '999')              ,
                               to_Char(NEW.emissao, 'dd/MM/yyyy')             ,
                               to_Char(vencimento::DATE, 'dd/MM/yyyy')          ,
                               to_Char(vencimento::DATE, 'dd/MM/yyyy')          ,
                               NEW.seriedocto_codigo||'-'||NEW.numero_docto||'-'||to_char(r_condpgtop.parcela,  '99')||'/'||to_char(r_condpgto.parcelas, '99'),
                               to_Char(r_condpgtop.financ_portador_id, '999')    ,
                               to_Char(r_condpgtop.financ_tipocobranca_id, '999'),
                               'A'                                            ,
                               'R$'                                           ,
                               to_char(NEW.cadastro_vendedor_id,'99999')   ,
                               to_Char(pacrescimo, '999999999.99')            ,
	     			           to_Char(pjurosmora, '999999999.99')            ,
	     			           to_Char(pmulta, '999999999.99')               ,
	     			           to_Char(ncarencia, '999999999')               ,
                               '0.00'                                         ,
                               '0.00'                                         ,
                               '0.00'                                         ,
                               to_Char(valorPA, '999999999.99')               ,
                               to_Char(valorPA, '999999999.99')               ;

	     END IF;

	     --RAISE NOTICE 'aDados: (%)',      aDados;


	     IF NOT padrao.gravarp(Receber_Pagar, aCampos, aDados)THEN
	        RAISE EXCEPTION 'nao possivel persistir financeiro (NF:% - CTRL:%)!',NEW.numero_docto , New.controle ;
	     END IF;
	  END LOOP;
   END IF;

   RETURN NULL;
END;


$BODY$

LANGUAGE 'plpgsql' VOLATILE;





CREATE OR REPLACE FUNCTION padrao.log_to_auditoria()
	RETURNS TRIGGER AS
$BODY$

DECLARE
    _DTHAUD     timestamp;     -- data hora da acao
    _USUAUD     name;          -- usuario da acao
    _HOSAUD     inet;          -- Host onde se encontra o banco de dados
    _BANAUD     name;          -- banco de dados onde ocorreu a acao
    _SCHAUD     VARCHAR[];     -- schema onde ocorreu a acao
    _TABAUD     name;          -- tabela onde ocorreu a acao
    _CAMAUD     text;          -- campos da tabela
    _TACAUD     text;          -- Tipo da acao ocorrida na tabela (insert, update ou delete)
    _MAQAUD     inet;          -- ip da m�quina que fez a acao
    _VNOAUD     text;          -- valor novo do campo afetado
    _VANAUD     text;          -- valor antigo do campo afetado
    _QUEAUD     text;          -- query executada durante a acao

      --pega os nomes das chaves primarias e coloca dentro de um array.
     _PK_NAMES CONSTANT VARCHAR[] := ARRAY(SELECT a.attname AS pk_name FROM pg_class c, pg_attribute a,                                                                                                pg_index i
     WHERE c.oid = i.indrelid
     AND a.attrelid = i.indexrelid
     AND a.attisdropped = FALSE
     AND a.attnum > 0
     AND i.indisprimary = TRUE
     AND c.oid = TG_RELID);

     --pega o nome dos campos da tabela e coloca dentro de um array
    _FIELD_NAMES CONSTANT VARCHAR[] := ARRAY(SELECT a.attname AS pk_name FROM pg_class c, pg_attribute a
     WHERE c.oid = a.attrelid
     AND a.attisdropped = FALSE
     AND a.attnum > 0
     AND c.oid = TG_RELID );

    _PK_VALUES VARCHAR[];

    --pega os nomes das chaves unicas e coloca dentro de um array.
     _UK_NAMES CONSTANT VARCHAR[] := ARRAY(SELECT a.attname AS pk_name FROM pg_class c, pg_attribute a,                                                                                                pg_index i
     WHERE c.oid = i.indrelid
     AND a.attrelid = i.indexrelid
     AND a.attisdropped = FALSE
     AND a.attnum > 0
     AND i.indisprimary = FALSE
     AND i.indisunique = TRUE
     AND c.oid = TG_RELID);


    _UK_VALUES VARCHAR[];

    BEGIN

    --utiliza a fun��o assert para checar que a trigger ser� executada apenas ap�s as a��es
    PERFORM padrao.assert(TG_WHEN = 'AFTER', 'Wrong execution of fnc_audit(): should only be executed AFTER an event!');
    --utiliza a fun��o assert para checar que a trigger ser� executada por cada linha
    PERFORM padrao.assert(TG_LEVEL = 'ROW', 'Wrong execution of fnc_audit(): should only be executed FOR EACH ROW!');
    --utiliza a fun��o assert para checar que o nome da tabela n�o est� nulo
    PERFORM padrao.assert(TG_TABLE_NAME IS NOT NULL, 'TG_TABLE_NAME IS NULL');
    --utiliza a fun��o assert para chegar se a tabela possui chaves prim�rias. N�o pode ser nulo.
    PERFORM padrao.assert(_PK_NAMES IS NOT NULL AND array_length(_PK_NAMES, 1) IS NOT NULL, 'Table ' || TG_TABLE_NAME || ' can not be logged: it has no PK!');
    --utiliza a fun��o assert para chegar se a tabela possui chaves prim�rias. N�o pode ser nulo.
    --PERFORM padrao.assert(_UK_NAMES IS NOT NULL AND array_length(_UK_NAMES, 1) IS NOT NULL, 'Table ' || TG_TABLE_NAME || ' can not be logged: it has no UNIQUE!');


    --Se por acidente a trigger for atribuida a pr�pria tabela de auditoria finaliza sem fazer nada.
    IF TG_TABLE_NAME = 'auditoria' THEN
    RETURN NULL;
    END IF;

    _DTHAUD := current_timestamp;  --pega a data/hora atual
    _MAQAUD := inet_client_addr(); --pega o ip da m�quina que praticou a acao
    _USUAUD := current_user;       --pega o usu�rio que praticou a acao
    _HOSAUD := inet_server_addr(); --pega o ip do servidor onde est� o banco de dados
    _BANAUD := current_database(); --pega o nome do banco de dados
    ---_SCHAUD := ARRAY(SELECT schemaname AS esquema FROM pg_catalog.pg_tables WHERE tablename =   TG_TABLE_NAME AND schemaname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') ORDER BY schemaname); --pega o nome do schema onde a tabela que est� sendo auditada est�
    _SCHAUD := current_schemas(false); --pega o nome do schema onde a tabela que est� sendo auditada est�
    _TABAUD := TG_TABLE_NAME; --pega o nome da tabela
    _CAMAUD := (SELECT string_agg(column_name,',') FROM information_schema.columns WHERE table_name = TG_RELNAME); --pega o nome dos campos da tabela
    _TACAUD := TG_OP; --pega a acao executada (INSERT, UPDATE ou DELETE)
    _QUEAUD := (SELECT current_query()); --pega a query executada
 --pega os valores das chaves prim�rias
	FOR i IN 1 .. array_length(_PK_NAMES, 1)
	LOOP
	 DECLARE
	  tmp text;
	  tmp_record record;
	 BEGIN
	  CASE TG_OP
	  WHEN 'UPDATE', 'INSERT' THEN tmp_record = NEW;
	  WHEN 'DELETE' THEN tmp_record = OLD;
	  END CASE;

	  EXECUTE 'SELECT $1.' || quote_ident(_PK_NAMES[i]) INTO STRICT tmp USING tmp_record;
	  _PK_VALUES[i] := tmp;
	 END;
	END LOOP;

	--pega os valores das chaves unica
	IF _UK_NAMES IS NOT NULL AND array_length(_UK_NAMES, 1) IS NOT NULL THEN
		FOR i IN 1 .. array_length(_UK_NAMES, 1)
		LOOP
		 DECLARE
		  tmp text;
		  tmp_record record;
		 BEGIN
		  CASE TG_OP
		  WHEN 'UPDATE', 'INSERT' THEN tmp_record = NEW;
		  WHEN 'DELETE' THEN tmp_record = OLD;
		  END CASE;

		  EXECUTE 'SELECT $1.' || quote_ident(_UK_NAMES[i]) INTO STRICT tmp USING tmp_record;
		  _UK_VALUES[i] := tmp;
		 END;
		END LOOP;
	 END IF;

 --utiliza a fun��o assert para checar se os valores das chaves prim�rias n�o s�o nulos.
 PERFORM padrao.assert(_PK_VALUES IS NOT NULL AND array_length(_PK_VALUES, 1) IS NOT NULL, '_PK_VALUES IS NULL');

 --utiliza a fun��o assert para checar se est� correta a mesma quantidade de nomes e valores de chaves prim�rias.
 PERFORM padrao.assert(array_length(_PK_VALUES, 1) = array_length(_PK_NAMES, 1), '_PK_VALUES
  count not equal to _PK_NAMES count in table ' || TG_TABLE_NAME);


  --insere os dados coletados de acordo com a acao executada
    IF (TG_OP = 'INSERT') THEN
          INSERT INTO padrao.auditoria(dthaud, usuaud, hosaud, banaud, scmaud, tabaud, camaud, npkaud, vpkaud, nukaud, vukaud,tacaud, maqaud, vanaud, vnoaud, queaud, data_hora_sync)
               VALUES (_DTHAUD, _USUAUD, _HOSAUD::text, _BANAUD::text, _SCHAUD, _TABAUD, _CAMAUD,_PK_NAMES, _PK_VALUES,_UK_NAMES, _UK_VALUES, _TACAUD, _MAQAUD, NULL, NEW, _QUEAUD, CAST('01/01/1969' AS DATE) + INTERVAL '0 DAYS');
          RETURN NEW;
     ELSIF (TG_OP = 'UPDATE') THEN
         INSERT INTO padrao.auditoria(dthaud, usuaud, hosaud, banaud, scmaud, tabaud, camaud, npkaud, vpkaud, nukaud, vukaud,tacaud, maqaud, vanaud, vnoaud, queaud, data_hora_sync)
               VALUES (_DTHAUD, _USUAUD, _HOSAUD::text, _BANAUD::text, _SCHAUD, _TABAUD, _CAMAUD, _PK_NAMES, _PK_VALUES, _UK_NAMES, _UK_VALUES, _TACAUD, _MAQAUD, OLD, NEW, _QUEAUD, CAST('01/01/1969' AS DATE) + INTERVAL '0 DAYS');
          RETURN NEW;
     ELSIF (TG_OP = 'DELETE') THEN
          INSERT INTO padrao.auditoria(dthaud, usuaud, hosaud, banaud, scmaud, tabaud, camaud, npkaud, vpkaud, nukaud, vukaud,tacaud, maqaud, vanaud, vnoaud, queaud, data_hora_sync)
               VALUES (_DTHAUD, _USUAUD, _HOSAUD::text, _BANAUD::text, _SCHAUD, _TABAUD, _CAMAUD,_PK_NAMES, _PK_VALUES,_UK_NAMES, _UK_VALUES, _TACAUD, _MAQAUD, OLD, NULL, _QUEAUD, CAST('01/01/1969' AS DATE) + INTERVAL '0 DAYS');
          RETURN OLD;
        END IF;
        RETURN NULL; -- o resultado � ignorado uma vez que este � um gatilho AFTER
    END;

$BODY$
LANGUAGE 'plpgsql' VOLATILE STRICT;



-- StoreProcedure {lancamento_integra_itens()} Versao {150} Esquema {padrao} Descricao {Grava integracao itens do documento}
-- ------------------------------------------------------------

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

DECLARE
 --Variaveis
   dia                   double precision;
   mes                   double precision;
   ano                   double precision;
   ultimoVcto            DATE;
   vencimento            DATE;
   valorNFsaldo          NUMERIC(14,2); -- Valor Total da NF
   valorPA               NUMERIC(14,2); -- Valor da Parcela
   indicePA              NUMERIC(14,5); -- Valor da PArcela equivalente ao total da venda
   valorComissao         NUMERIC(14,2); -- Valor da Comissao pelo recebimento

   custoTotalCalculo     NUMERIC(14,4);
   rateio                NUMERIC(14,4);
   custo                 NUMERIC(14,4);
   custoNF               NUMERIC(14,4);
   custoInventario       NUMERIC(14,4);
   custoDigitado         NUMERIC(14,4);
   custoReal             NUMERIC(14,4);


   Receber_Pagar          CHAR(1);
   aCampos                character varying[];
   aDados                 character varying[];
   aCamposcl              character varying[];
   aDadoscl               character varying[];
   aCamposSaldo           character varying[];
   aDadosSaldo            character varying[];
   aCamposPed             character varying[];
   aDadosPed              character varying[];
   aCamposPedC            character varying[];
   aDadosPedC             character varying[];
   sCampos                VARCHAR;
   sDados                 VARCHAR;
   rp_id_seq              INTEGER;



 --Faturamento
   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)
 --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

   r_transacao      RECORD;
   r_lctoitens      RECORD;
   r_condpgto       RECORD; -- Condicao de pgto
   r_condpgtop      RECORD; -- Condicao de pgto - parcelas
   r_doctoc         RECORD; -- Documento Cabecalho
   r_doctoI         RECORD; -- Documento Itens
   r_doctoPA        RECORD; -- Documento Pedidos Atendidos
   r_parameters     RECORD; -- Parametros padrao do sistema
   r_serie          RECORD; -- Cadastro de Serie de docto
   r_consistencia   RECORD; -- cosisencia somatario dos produtos
   r_produto        RECORD; -- Cadastro Produto
   r_cad            RECORD; -- Cadastro Cadastro Destinatario
   r_filial         RECORD; -- Cadastro Cadastro Emitente

BEGIN
-- SE FOR UMA EXCLUSAO
   IF TG_OP = 'DELETE'  THEN


      --checa existencia de produtos atendido
      SELECT fat_produto_id, fat_docto_pc_controle, fat_docto_c_controle,qtde
        INTO r_doctoPA
        FROM fat_docto_pa
       WHERE fat_docto_pc_controle = OLD.fat_docto_c_controle
         AND fat_produto_id        = OLD.fat_produto_id;

      --RAISE DEBUG '(Ctrl : % Produto Codigo: % - Qtde Atendida %" )', OLD.fat_docto_c_controle, OLD.fat_produto_id, r_doctoPA.qtde;
      --RAISE DEBUG 'NAO SERA POSSIVEL A EXCLUSAO, EXISTE PRODUTO ATENDIDO PARA ESSE DOCUMENTO (Ctrl Atendido: % Produto Codigo: % - Qtde Atendida %" )', r_doctoPA.fat_docto_c_controle, r_doctoPA.fat_produto_id, r_doctoPA.qtde;

      IF FOUND  THEN
         RAISE EXCEPTION 'NAO SERA POSSIVEL A EXCLUSAO, EXISTE PRODUTO ATENDIDO PARA ESSE DOCUMENTO (Ctrl Atendido: % Produto Codigo: % - Qtde Atendida %" )', r_doctoPA.fat_docto_c_controle, r_doctoPA.fat_produto_id, r_doctoPA.qtde;
      END IF;



	  EXECUTE 'DELETE FROM fat_produto_movto WHERE fat_docto_c_controle = '|| OLD.fat_docto_c_controle || 'and fat_produto_id = ' || OLD.fat_produto_id;

	  EXECUTE 'DELETE FROM fat_docto_pi WHERE fat_docto_pc_fat_docto_c_controle = '|| OLD.fat_docto_c_controle || 'and fat_produto_id = ' || OLD.fat_produto_id;

	  EXECUTE 'DELETE FROM fat_docto_pa WHERE fat_docto_c_controle = '|| OLD.fat_docto_c_controle || 'and fat_produto_id = ' || OLD.fat_produto_id;

	  IF NOT padrao.gravaEstoque(OLD.fat_produto_id, OLD.cad_filial_id, OLD.dataentradasaida, false)THEN
	    RAISE EXCEPTION 'Nao foi possivel persistir estoque do produto (Cod.:% NF:% - CTRL:%)!', OLD.fat_produto_id,OLD.numero_docto ,OLD.fat_docto_c_controle ;
	  END IF;

      RETURN NULL;
   END IF;

 --Posiciona Cabecalho
   SELECT controle,fat_transacao_id, seriedocto_codigo, seriedocto_id, cad_filial_id, numero_docto,cad_cadastro_id,emissao,
          dataentradasaida, infocustodescpgto, statuslcto, fat_listapre_id, fat_listapre_tabela_tabela,
          infocustojurosvendor, infocustooutrasdesp, infocustofretepagar, frete_valor, despesa_valor, seguro_Valor,
          icmssubst_valor,totalliquidoprodutos, totalprodutos, valortotal_docto, descontodocto_valor
   INTO r_doctoc
   FROM fat_docto_c
   WHERE controle = NEW.fat_docto_c_controle;

-- Posiciona Cadastro (Destinatario)
   SELECT cad_cadastro.id, razaosocial, nomefantasia, pessoa, cad_mun_id,padrao.cad_mun.municipio AS municipio,padrao.cad_mun.uf AS uf,contribuinteicms, 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,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 ;




-- Documento Cancelado, agrupado, Denegado
    IF TG_OP = 'UPDATE'  THEN
	      IF r_doctoc.statuslcto = 7
	         OR r_doctoc.statuslcto = 8
	         OR r_doctoc.statuslcto = 95
	         OR r_doctoc.statuslcto = 135
	         OR r_doctoc.statuslcto = 136
	         OR r_doctoc.statuslcto = 205
	         OR r_doctoc.statuslcto = 302 THEN
		     EXECUTE 'DELETE FROM fat_docto_pa WHERE fat_docto_c_controle = '|| OLD.fat_docto_c_controle || 'and fat_produto_id = ' || OLD.fat_produto_id;
		  END IF;
	      EXECUTE 'DELETE FROM fat_produto_movto WHERE fat_docto_c_controle = '|| OLD.fat_docto_c_controle || 'and fat_produto_id = ' || OLD.fat_produto_id;


		  --IF NOT padrao.gravaEstoque(OLD.fat_produto_id, OLD.cad_filial_id, OLD.dataentradasaida, false)THEN
		  --  RAISE EXCEPTION 'Nao foi possivel persistir estoque do produto (Cod.:% NF:% - CTRL:%)!', OLD.fat_produto_id,OLD.numero_docto ,OLD.fat_docto_c_controle ;
		  --END IF;

	      IF r_doctoc.statuslcto = 7
	         OR r_doctoc.statuslcto = 8
	         OR r_doctoc.statuslcto = 95
	         OR r_doctoc.statuslcto = 135
	         OR r_doctoc.statuslcto = 136
	         OR r_doctoc.statuslcto = 205
	         OR r_doctoc.statuslcto = 302 THEN
	         IF NOT padrao.gravaEstoque(OLD.fat_produto_id, OLD.cad_filial_id, OLD.dataentradasaida, false)THEN
	           RAISE EXCEPTION 'Nao foi possivel persistir estoque do produto (Cod.:% NF:% - CTRL:%)!', OLD.fat_produto_id,OLD.numero_docto ,OLD.fat_docto_c_controle ;
	         END IF;
	         RETURN NULL;
	      END IF;
    END IF;
-- 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;
   	-- 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;


  --RAISE EXCEPTION 'Estqoue:% produto: %	custo:% (%) total:%',d26_atualiza_estoque,new.fat_produto_id, custoTotalCalculo, rateio,NEW.valor_total_liquido;

   /****************************************************
    * Estoque / Movimentacao de produtos
    ****************************************************/
	-- Grava ProdutoMovto
   aCampos =  '{fat_produto_id,
	            fat_docto_c_controle,
	            cad_filial_id,
                seriedocto_codigo,
	            numero_docto,
	            cad_cadastro_id,
	            fat_transacao_id,
	            datamovto,
	            natureza,
	            tipomovto,
                devolucao,
	            atualizaestoque,
                alteracustomedio,
                alteracustoultimacompra,
	            fat_almoxarifado_id_origem,
	            fat_almoxarifado_id_destino,
                qtde,
	            valorunitario,
	            valortotal,
	            custoinventario,
                custoinventariototal,
                custonf,
                custodigitado,
                custoreal,
                customedio,
                customediototal,
                saldo,
                saldo2,
                saldoinventario,
                usuarioalteracao,
                usuarioinclusao}';

    -- RAISE EXCEPTION 'chegou ate aqui)!custo_inventario: %, custo_nf:%, custo_digitado:%, custo_real:%',new.custo_inventario,NEW.custo_nf,NEW.custo_digitado,NEW.custo_real ;

    aDados  =  '{'|| to_char(NEW.fat_produto_id,'99999')                                ||','
    			  || to_char(NEW.fat_docto_c_controle,  '99999999999999999999')               ||','
    			  || to_Char(r_doctoc.cad_filial_id, '999')                                   ||','
    			  || r_doctoc.seriedocto_codigo                                                    ||','
    			  || to_Char(r_doctoc.numero_docto, '99999999999')                               ||','
    			  || to_char(r_doctoc.cad_cadastro_id, '999999999')                                ||','
    			  || to_Char(r_doctoc.fat_transacao_id, '99999')                              ||','
    			  || to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy')                   ||','
    			  || d12_natureza                                                        ||','
    			  || d27_tipo_mvto                                                       ||','
                  || (CASE WHEN d19_devolucao = 'S' THEN 'true' ELSE 'false' END)        ||','
                  || (CASE WHEN d26_atualiza_estoque = 'S' THEN 'true' ELSE 'false' END) ||','
    			  || (CASE WHEN d28_alterarCM = 'S' THEN 'true' ELSE 'false' END)        ||','
    			  || (CASE WHEN d29_alterrrCUC = 'S' THEN 'true' ELSE 'false' END)       ||','
    			  || '0'                                                                 ||','
    			  || '0'                                                                 ||','
    			  || to_Char(NEW.qtde, '9999999.9999')                                   ||','
    			  || to_Char(Coalesce(NEW.valor_unitario_liquido,NEW.valor_unitario) , '999999999.9999')                 ||','
    			  || to_Char(Coalesce(NEW.valor_total_liquido,NEW.valor_total), '999999999.9999')                    ||','
    			  || (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_inventario,0), '999999999.999')           ELSE '0' END) ||','
				  || (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_inventario,0)*NEW.qtde, '999999999.999')  ELSE '0' END) ||','
				  || (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_nf,0), '999999999.999')                   ELSE '0' END) ||','
				  || (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_digitado,0), '999999999.999')             ELSE '0' END) ||','
				  || (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_real,0), '999999999.999')                 ELSE '0' END) ||','
    		      || '0'                                                                 ||','
    			  || '0'                                                                 ||','
    			  || '0'                                                                 ||','
    			  || '0'                                                                 ||','
    			  || '0'                                                                 ||','
    			  || (CASE WHEN NEW.usuarioalteracao IS NULL THEN  '??' ELSE  NEW.usuarioalteracao END) ||','
 			      || (CASE WHEN NEW.usuarioinclusao  IS NULL THEN  '??' ELSE  NEW.usuarioinclusao  END)  ||'}';



 	 --RAISE EXCEPTION 'custos nf:% digitado:% real:% custo inventario:% custo inventario total:%', to_Char(NEW.custo_nf, '999999999D999'),  to_Char(NEW.custo_digitado, '999999999D999'),NEW.custo_real,NEW.custo_inventario, NEW.custo_inventario*NEW.qtde ;
 	 --RAISE EXCEPTION 'custos nf:% digitado:% real:% custo inventario:% custo inventario total:%', to_Char(custoNF, '999999999D999'),  to_Char(custoDigitado, '999999999D999'),custoReal,custoInventario, custoInventario*NEW.qtde ;
     ----RAISE NOTICE 'aCampos: (%)',     aCampos;
     --RAISE EXCEPTION 'aDados: (%)',      aDados;

     IF aDados IS NULL THEN
	    RAISE EXCEPTION 'Nao sera possivel persistir movimentacao do produto.
                         Dados para movimentacao esta incompleto.Verifique Campos <NULL>:
                        (fat_produto_id:%
                         fat_docto_c_controle:%
                         cad_filial_id:%
                         seriedocto_codigo:%
                         numero_docto:%
                         cad_cadastro_id:%
                         fat_transacao_id:%
                         datamovto:%
                         natureza:%
                         tipomovto:%
                         devolucao:%
                         atualizaestoque:%
                         alteracustomedio:%
                         alteracustoultimacompra:%
                         fat_almoxarifado_id_origem:%
                         fat_almoxarifado_id_destino:%
                         qtde:%
                         valorunitario:%
                         valortotal:%
                         custoinventario:%
                         custoinventariototal:%
                         custonf:%
                         custodigitado:%
                         custoreal:%
                         customedio:%
                         customediototal:%
                         saldo:%
                         saldo2:%
                         saldoinventario:%
                         usuarioalteracao:%
                         usuarioinclusao:%

                        )!',
                        to_char(NEW.fat_produto_id,':%9999')                                ,
                        to_char(NEW.fat_docto_c_controle,  '99999999999999999999')             ,
                        to_Char(r_doctoc.cad_filial_id, '999')                                  ,
	                    r_doctoc.seriedocto_codigo                                                   ,
	                    to_Char(r_doctoc.numero_docto, '99999999')                              ,
	                    to_char(r_doctoc.cad_cadastro_id, '999999999')                               ,
	                    to_Char(r_doctoc.fat_transacao_id, '99999')                             ,
	                    to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy')                   ,
	                    d12_natureza                                                       ,
	                    d27_tipo_mvto                                                      ,
	                    (CASE WHEN d19_devolucao = 'S' THEN 'true' ELSE 'false' END)       ,
                        (CASE WHEN d26_atualiza_estoque = 'S' THEN 'true' ELSE 'false' END),
	                    (CASE WHEN d28_alterarCM = 'S' THEN 'true' ELSE 'false' END)       ,
	                    (CASE WHEN d29_alterrrCUC = 'S' THEN 'true' ELSE 'false' END)      ,
	                    '0'                                                                ,
	                    '0'                                                                ,
	                    to_Char(NEW.qtde, '9999999.9999')                                  ,
	                    to_Char(NEW.valor_unitario_liquido, '999999999.999')               ,
	                    to_Char(NEW.valor_total_liquido, '999999999.999')                  ,
	                    (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_inventario,0), '999999999.999')           ELSE '0' END),
				        (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_inventario,0)*NEW.qtde, '999999999.999')  ELSE '0' END),
				        (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_nf,0), '999999999.999')                   ELSE '0' END),
				        (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_digitado,0), '999999999.999')             ELSE '0' END),
				        (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_real,0), '999999999.999')                 ELSE '0' END),
	                    '0'                                                                 ,
	                    '0'                                                                 ,
	                    '0'                                                                 ,
	                    '0'                                                                 ,
	                    '0'                                                                 ,
	                    (CASE WHEN NEW.usuarioalteracao IS NULL THEN  '??' ELSE  NEW.usuarioalteracao END) ,
	                    (CASE WHEN NEW.usuarioinclusao  IS NULL THEN  '??' ELSE  NEW.usuarioinclusao  END) ;
	        END IF;


	 IF NOT padrao.gravamovtoestoque(aCampos, aDados)THEN
	    RAISE EXCEPTION 'nao possivel persistir movimentacao produto ->gravaMovtoEstoque<- (Cod.:% NF:% - CTRL:% ARRAY:%)!', NEW.fat_produto_id,r_doctoc.numero_docto ,NEW.fat_docto_c_controle, aDados ;
	 END IF;


   /****************************************************
    * Estoque / Movimentacao de produtos
    ****************************************************/
   -- Grava ProdutoSaldo
	aCamposSaldo =  '{fat_produto_id,
	                  cad_filial_id,
	                  almoxarifado_codigo,
                      ultimaentrada,
	                  ultimasaida,
	                  ultimomovto,
                      usuarioalteracao,
                      usuarioinclusao}';

    aDadosSaldo  =  '{'|| to_char(NEW.fat_produto_id,'99999')                                 ||','
    			       || to_Char(r_doctoc.cad_filial_id, '999')                                   ||','
    			       || '0'                                                                 ||','
    			       || CASE WHEN d19_devolucao <> 'S' AND d12_natureza = 'E'THEN to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy') ELSE '00/00/0000' END ||','
    			       || CASE WHEN d19_devolucao <> 'S' AND d12_natureza = 'S'THEN to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy') ELSE '00/00/0000' END ||','
    			       || to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy')                   ||','
    			  	   || (CASE WHEN NEW.usuarioalteracao IS NULL THEN  '??' ELSE  NEW.usuarioalteracao END) ||','
 			           || (CASE WHEN NEW.usuarioinclusao  IS NULL THEN  '??' ELSE  NEW.usuarioinclusao  END)  ||'}';


     --RAISE NOTICE 'aCamposSaldo: (%)',     aCamposSaldo;
     --RAISE NOTICE 'aDadosSaldo: (%)',      aDadosSaldo;


     --RAISE EXCEPTION 'teste: %',to_char(NEW.fat_produto_id,'99999');


     IF aDadosSaldo IS NULL THEN
	    RAISE EXCEPTION 'Nao sera possivel persistir saldo do produto.
                         Dados para persistencia esta incompleto. Verifique campo <NULL>:
						( fat_produto_id:%
                          cad_filial_id:%
                          almoxarifado_codigo:%
                          ultimaentrada:%
                          ultimasaida:%
                          ultimomovto:%
                          usuarioalteracao:%
                          usuarioinclusao:% )',
                          to_char(NEW.fat_produto_id,'99999')  ,
                          to_Char(r_doctoc.cad_filial_id, '999')   ,
                          '0'                                 ,
                          CASE WHEN d19_devolucao <> 'S' AND d12_natureza = 'E'THEN to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy') ELSE '00/00/1999' END ,
                          CASE WHEN d19_devolucao <> 'S' AND d12_natureza = 'S'THEN to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy') ELSE '00/00/1999' END ,
                          to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy')  ,
                          (CASE WHEN NEW.usuarioalteracao IS NULL THEN  '??' ELSE  NEW.usuarioalteracao END) ,
                          (CASE WHEN NEW.usuarioinclusao  IS NULL THEN  '??' ELSE  NEW.usuarioinclusao  END) ;



	 END IF;


	 IF NOT padrao.gravaSaldo(aCamposSaldo, aDadosSaldo)THEN
	    RAISE EXCEPTION 'Nao foi possivel persistir saldo do produto ->gravaSaldo<-(Cod.:% NF:% - CTRL:% ARRAY:%)!', NEW.fat_produto_id,r_doctoc.numero_docto ,NEW.fat_docto_c_controle , aDados;
	 END IF;

	 --RAISE EXCEPTION 'Nao foi possivel persistir saldo do produto ->gravaSaldo<-(Cod.:% NF:% - CTRL:% ARRAY:%)!', NEW.fat_produto_id,r_doctoc.numero_docto ,NEW.fat_docto_c_controle , aDados;

	 IF NOT padrao.gravaEstoque(NEW.fat_produto_id, r_doctoc.cad_filial_id, r_doctoc.dataentradasaida, false)THEN
	    RAISE EXCEPTION 'Nao foi possivel persistir estoque do produto ->gravaEstoque<- (Cod.:% NF:% - CTRL:%!', NEW.fat_produto_id,r_doctoc.numero_docto ,NEW.fat_docto_c_controle ;
	 END IF;



	 --
   -- grava consignacao/entrega futura/etc
   --
      IF d27_tipo_mvto = '1' OR d27_tipo_mvto = '3' OR d27_tipo_mvto = '5' OR d27_tipo_mvto = '7' OR d27_tipo_mvto = 'O' OR d27_tipo_mvto = 'P' THEN

	        aCamposPedC =  '{ fat_docto_c_controle,
		                   tipo,
		                   cad_cadastro_id,
		                   cad_filial_id,
		                   data_p,
		                   status_p}';


		      aDadosPedC  =   '{' || to_char(NEW.fat_docto_c_controle,  '9999999999')   ||','
		     			         || cast(d27_tipo_mvto ||d12_natureza as varchar)  ||','
		     			         || to_Char(r_doctoc.cad_cadastro_id, '999999999')  ||','
		     			         || to_Char(r_doctoc.cad_filial_id, '999')      ||','
		     			         || to_Char(r_doctoc.emissao::DATE, 'dd/MM/yyyy')     ||','
		     			         || 'P'                                    ||'}';

		     --RAISE NOTICE 'aCamposPedC: (%)',     aCamposPed;
		     --RAISE NOTICE 'aDadosPedC: (%)',      aDados;

		     IF NOT padrao.gravaPC(aCamposPedC, aDadosPedC)THEN
		        RAISE EXCEPTION 'nao possivel persistir saldo ds pedidos-fat_docto_pc (NF:% - CTRL:% - Tipo:%)!',NEW.numero_docto , New.controle, cast(d27_tipo_mvto ||d12_natureza as varchar) ;
		     END IF;


	       aCamposPed =  '{ fat_docto_pc_fat_docto_c_controle,
							fat_produto_id,
							cad_filial_id,
		                   	tipo,
							data_p,
		                   	qtde,
		                   	qtde_atendida,
		                   	qtde_naoatendida,
		                   	qtde_cancelada,
		                    qtde_pendente }';


		      aDadosPed  =   '{'|| to_char(NEW.fat_docto_c_controle,  '99999999999999')   ||','
		      					|| to_char(NEW.fat_produto_id,'99999')    ||','
		      					|| to_Char(r_doctoc.cad_filial_id, '999')      ||','
		     			        || cast(d27_tipo_mvto ||d12_natureza as varchar)  ||','
		     			        || to_Char(r_doctoc.emissao::DATE, 'dd/MM/yyyy')  ||','
		     			        || to_Char(NEW.qtde, '9999999.9999')              ||','
		     			        || to_Char(0, '9999999.9999')              ||','
		     			        || to_Char(0, '9999999.9999')              ||','
		     			        || to_Char(0, '9999999.9999')              ||','
		     			        || to_Char(NEW.qtde, '9999999.9999')       ||'}';

		     --RAISE NOTICE 'aCamposPed: (%)',     aCamposPed;
		     --RAISE NOTICE 'aDadosPed: (%)',      aDados;

		     IF NOT padrao.gravaPI(aCamposPed, aDadosPed)THEN
		        RAISE EXCEPTION 'nao possivel persistir itens dos pedidos-fat_docto_pi (NF:% - CTRL:% - Tipo:%)!',NEW.numero_docto , New.controle, cast(d27_tipo_mvto ||d12_natureza as varchar) ;
		     END IF;
        END IF;




	/*******************************************
	* grava regtorno consignacao
	********************************************/
	IF d27_tipo_mvto = 'C' THEN
		-- Grava ProdutoMovto
		aCampos =  '{	fat_produto_id,
			    		fat_docto_c_controle,
			    		cad_filial_id,
						seriedocto_codigo,
					    numero_docto,
					    cad_cadastro_id,
					    fat_transacao_id,
					    datamovto,
					    natureza,
					    tipomovto,
						devolucao,
					    atualizaestoque,
						alteracustomedio,
						alteracustoultimacompra,
					    fat_almoxarifado_id_origem,
					    fat_almoxarifado_id_destino,
						qtde,
					    valorunitario,
					    valortotal,
					    custoinventario,
						custoinventariototal,
						custonf,
						custodigitado,
						custoreal,
						customedio,
						customediototal,
						saldo,
						saldo2,
						saldoinventario,
						usuarioalteracao,
						usuarioinclusao	}';


	    aDados  =  '{'	|| to_char(NEW.fat_produto_id,'9999999')                                		||','
				  		|| to_char(NEW.fat_docto_c_controle,  '99999999999999999999')               ||','
				  		|| to_Char(r_doctoc.cad_filial_id, '999')                                   ||','
				  		|| r_doctoc.seriedocto_codigo                                                    	||','
				  		|| to_Char(r_doctoc.numero_docto, '99999999')                               ||','
				  		|| to_char(r_doctoc.cad_cadastro_id, '999999999')                                ||','
				  		|| to_Char(r_doctoc.fat_transacao_id, '99999')                              ||','
				  		|| to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy')                   ||','
				  		|| (CASE WHEN d12_natureza ='S' THEN 'E' ELSE 'S' END)                   	||','
				  		|| '2'                                                      				||','
			  			|| (CASE WHEN d19_devolucao = 'S' THEN 'true' ELSE 'false' END)       		||','
			  			|| (CASE WHEN d26_atualiza_estoque = 'S' THEN 'true' ELSE 'false' END)		||','
				  		|| (CASE WHEN d28_alterarCM = 'S' THEN 'true' ELSE 'false' END)        		||','
				  		|| (CASE WHEN d29_alterrrCUC = 'S' THEN 'true' ELSE 'false' END)       		||','
				  		|| '0'                                                                 		||','
				  		|| '0'                                                                 		||','
				  		|| to_Char(NEW.qtde, '9999999.9999')                                   		||','
				  		|| to_Char(NEW.valor_unitario_liquido, '999999999.999')                 	||','
				  		|| to_Char(NEW.valor_total_liquido, '999999999.999')                    			||','
						|| (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_inventario,0), '999999999.999')           ELSE '0' END) ||','
						|| (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_inventario,0)*NEW.qtde, '999999999.999')  ELSE '0' END) ||','
						|| (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_nf,0), '999999999.999')                   ELSE '0' END) ||','
						|| (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_digitado,0), '999999999.999')             ELSE '0' END) ||','
						|| (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_real,0), '999999999.999')                 ELSE '0' END) ||','
					    || '0'                                                                 ||','
						|| '0'                                                                 ||','
						|| '0'                                                                 ||','
						|| '0'                                                                 ||','
						|| '0'                                                                 ||','
						|| (CASE WHEN NEW.usuarioalteracao IS NULL THEN  '??' ELSE  NEW.usuarioalteracao END) ||','
						|| (CASE WHEN NEW.usuarioinclusao  IS NULL THEN  '??' ELSE  NEW.usuarioinclusao  END)  ||'}';

	     IF aDados IS NULL THEN
		    RAISE EXCEPTION 'Nao sera possivel persistir movimentacao do produto.
				 Dados para movimentacao esta incompleto.Verifique Campos <NULL>:
				(fat_produto_id:%
				 fat_docto_c_controle:%
				 cad_filial_id:%
				 seriedocto_codigo:%
				 numero_docto:%
				 cad_cadastro_id:%
				 fat_transacao_id:%
				 datamovto:%
				 natureza:%
				 tipomovto:%
				 devolucao:%
				 atualizaestoque:%
				 alteracustomedio:%
				 alteracustoultimacompra:%
				 fat_almoxarifado_id_origem:%
				 fat_almoxarifado_id_destino:%
				 qtde:%
				 valorunitario:%
				 valortotal:%
				 custoinventario:%
				 custoinventariototal:%
				 custonf:%
				 custodigitado:%
				 custoreal:%
				 customedio:%
				 customediototal:%
				 saldo:%
				 saldo2:%
				 saldoinventario:%
				 usuarioalteracao:%
				 usuarioinclusao:%

				)!',
				to_char(NEW.fat_produto_id,':%999999')                                ,
				to_char(NEW.fat_docto_c_controle,  '99999999999999999999')             ,
				to_Char(r_doctoc.cad_filial_id, '999')                                  ,
				    r_doctoc.seriedocto_codigo                                                   ,
				    to_Char(r_doctoc.numero_docto, '99999999')                              ,
				    to_char(r_doctoc.cad_cadastro_id, '999999999')                               ,
				    to_Char(r_doctoc.fat_transacao_id, '99999')                             ,
				    to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy')                   ,
				    (CASE WHEN d12_natureza ='S' THEN 'E' ELSE 'S' END)               ,
				    '2'                                                      ,
				    (CASE WHEN d19_devolucao = 'S' THEN 'true' ELSE 'false' END)       ,
				(CASE WHEN d26_atualiza_estoque = 'S' THEN 'true' ELSE 'false' END),
				    (CASE WHEN d28_alterarCM = 'S' THEN 'true' ELSE 'false' END)       ,
				    (CASE WHEN d29_alterrrCUC = 'S' THEN 'true' ELSE 'false' END)      ,
				    '0'                                                                ,
				    '0'                                                                ,
				    to_Char(NEW.qtde, '9999999.9999')                                  ,
				    to_Char(NEW.valor_unitario_liquido, '999999999.999')               ,
				    to_Char(NEW.valor_total_liquido, '999999999.999')                  ,
				    (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_inventario,0), '999999999.999')           ELSE '0' END),
				    (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_inventario,0)*NEW.qtde, '999999999.999')  ELSE '0' END),
				    (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_nf,0), '999999999.999')                   ELSE '0' END),
				    (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_digitado,0), '999999999.999')             ELSE '0' END),
				    (CASE WHEN d26_atualiza_estoque = 'S' THEN to_Char(coalesce(NEW.custo_real,0), '999999999.999')                 ELSE '0' END),
				    '0'                                                                 ,
				    '0'                                                                 ,
				    '0'                                                                 ,
				    '0'                                                                 ,
				    '0'                                                                 ,
				    (CASE WHEN NEW.usuarioalteracao IS NULL THEN  '??' ELSE  NEW.usuarioalteracao END) ,
				    (CASE WHEN NEW.usuarioinclusao  IS NULL THEN  '??' ELSE  NEW.usuarioinclusao  END) ;
			END IF;


		 IF NOT padrao.gravamovtoestoque(aCampos, aDados)THEN
		    RAISE EXCEPTION 'nao possivel persistir movimentacao produto (Cod.:% NF:% - CTRL:% ARRAY:%)!', NEW.fat_produto_id,NEW.numero_docto ,NEW.fat_docto_c_controle, aDados ;
		 END IF;


	   /****************************************************
	    * Estoque / Movimentacao de produtos
	    ****************************************************/
	-- Grava ProdutoSaldo
		aCamposSaldo =  '{fat_produto_id,
				  cad_filial_id,
				  almoxarifado_codigo,
			      ultimaentrada,
				  ultimasaida,
				  ultimomovto,
			      usuarioalteracao,
			      usuarioinclusao}';

	    aDadosSaldo  =  '{'	|| to_char(NEW.fat_produto_id,'99999')                                 ||','
				       		|| to_Char(r_parameters.fatfilialpadrao, '999')                        ||','
						    || '0'                                                                 ||','
						    || CASE WHEN d19_devolucao <> 'S' AND d12_natureza = 'E'THEN to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy') ELSE '00/00/0000' END ||','
						    || CASE WHEN d19_devolucao <> 'S' AND d12_natureza = 'S'THEN to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy') ELSE '00/00/0000' END ||','
						    || to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy')                   ||','
							|| (CASE WHEN NEW.usuarioalteracao IS NULL THEN  '??' ELSE  NEW.usuarioalteracao END) ||','
							|| (CASE WHEN NEW.usuarioinclusao  IS NULL THEN  '??' ELSE  NEW.usuarioinclusao  END)  ||'}';


	     --RAISE NOTICE 'aCamposSaldo: (%)',     aCamposSaldo;
	     --RAISE NOTICE 'aDadosSaldo: (%)',      aDadosSaldo;


	     --RAISE EXCEPTION 'teste: %',to_char(NEW.fat_produto_id,'99999');


	     IF aDadosSaldo IS NULL THEN
		    RAISE EXCEPTION 'Nao sera possivel persistir saldo do produto.
				 Dados para persistencia esta incompleto. Verifique campo <NULL>:
							( fat_produto_id:%
							  cad_filial_id:%
							  almoxarifado_codigo:%
							  ultimaentrada:%
							  ultimasaida:%
							  ultimomovto:%
							  usuarioalteracao:%
							  usuarioinclusao:% )',
							  to_char(NEW.fat_produto_id,'99999')  ,
							  to_Char(r_parameters.fatfilialpadrao, '999')   ,
							  '0'                                 ,
							  CASE WHEN d19_devolucao <> 'S' AND d12_natureza = 'E'THEN to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy') ELSE '00/00/0000' END ,
							  CASE WHEN d19_devolucao <> 'S' AND d12_natureza = 'S'THEN to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy') ELSE '00/00/0000' END ,
							  to_Char(r_doctoc.dataentradasaida::DATE, 'dd/MM/yyyy')  ,
							  (CASE WHEN NEW.usuarioalteracao IS NULL THEN  '??' ELSE  NEW.usuarioalteracao END) ,
							  (CASE WHEN NEW.usuarioinclusao  IS NULL THEN  '??' ELSE  NEW.usuarioinclusao  END) ;



		 END IF;


		 IF NOT padrao.gravaSaldo(aCamposSaldo, aDadosSaldo)THEN
		    RAISE EXCEPTION 'Nao foi possivel persistir saldo do produto (Cod.:% NF:% - CTRL:% ARRAY:%)!', NEW.fat_produto_id,NEW.numero_docto ,NEW.fat_docto_c_controle , aDados;
		 END IF;

		 IF NOT padrao.gravaEstoque(NEW.fat_produto_id, r_doctoc.cad_filial_id, r_doctoc.dataentradasaida, false)THEN
		    RAISE EXCEPTION 'Nao foi possivel persistir estoque do produto (Cod.:% NF:% - CTRL:% ARRAY:%)!', NEW.fat_produto_id,NEW.numero_docto ,NEW.fat_docto_c_controle, aDados ;
		 END IF;

	END IF;

   --Consiste desconto item

--   IF COALESCE(r_doctoc.descontodocto_valor,0) = 0 THEN
--
--      SELECT SUM(qtde * valor_unitario_liquido) AS valor_total_liquido,
--             SUM(qtde * valor_unitario)         AS valor_total_bruto
--        INTO r_consistencia
--        FROM fat_docto_i
--       WHERE fat_docto_c_controle = NEW.fat_docto_c_controle;
--
--      IF Round(r_doctoc.totalprodutos,2) != Round(r_consistencia.valor_total_bruto,2) OR  Round(r_doctoc.totalliquidoprodutos,2) != Round(r_consistencia.valor_total_liquido,2) THEN
--         RAISE EXCEPTION 'A T E N C A O  CHECANDO SOMATORIA ITEM(S)!!
--                         Total dos Produtos nao batem.
--                         Verifique
--                        TOTAL BRUTO  : ( % <-> %)
--                        TOTAL LIQUIDO  : ( % <-> %)
--                          ',ROUND(r_doctoc.totalprodutos,2) , ROUND(r_consistencia.valor_total_bruto,2), Round(r_doctoc.totalliquidoprodutos,2), Round(r_consistencia.valor_total_liquido,2)  ;
--      END IF;
--   END IF;
--
--
     --Atualiza/grava classes
     IF d118_classgerencialproduto = 'S' THEN
        UPDATE financ_rp set valor_total = valor_total WHERE fatura = NEW.fat_docto_c_controle;
     END IF;


   RETURN NULL;
END;

$BODY$

LANGUAGE 'plpgsql' VOLATILE;








-- StoreProcedure {rp_integra()} Versao {028} Esquema {padrao} Descricao {Integracao contas a receber/pagar}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.rp_integra()
RETURNS trigger AS

$BODY$

DECLARE
 --Variaveis
   dia                   double precision;
   mes                   double precision;
   ano                   double precision;
   ultimoVcto            DATE;
   vencimento            DATE;
   valorNFsaldo          NUMERIC(14,2); -- Valor Total da NF
   valorPA               NUMERIC(14,2); -- Valor da PArcela
   indicePA              NUMERIC(14,5); -- Valor da PArcela equivalente ao total da venda
   valorComissao         NUMERIC(14,2); -- Valor da Comissao pelo recebimento
   Receber_Pagar         CHAR(1);
   aCampos               character varying[];
   aDados                character varying[];
   aCamposCl             character varying[];
   aDadosCl              character varying[];
   sCampos               VARCHAR;
   sDados                VARCHAR;

 --Faturamento
   d11_perc_comissao     NUMERIC(14,5);
   d12_natureza          CHAR(1); --Natureza: Entrada/Saida
   d13_tipo_docto        CHAR(1); --Tipo Docto: Nota Fiscal/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)
 --Estoque
   d26_atualiza_estoque  CHAR(1); --Atualiza estouque:(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
   d423_gerar_fatura     CHAR(1); --Gerar Fatura: R/P=Receber/Pagar)
   d424_CondPgto         INTEGER; --Gerar Fatura: Condição de Pgto)
--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


   r_docto_c         RECORD;
   r_docto_i         RECORD;
   r_tipocobranca    RECORD;
   r_parameters      RECORD;
   r_baixa           RECORD;
   r_financ_rp_baixa RECORD;
   r_transacao       RECORD;
   r_classidicacaoG  RECORD;
   r_contem_Baixa    RECORD;
   r_classe          RECORD;
   r_cc_movto        RECORD;

   v_retorna        boolean;
BEGIN
   IF TG_OP <> 'DELETE' THEN
       IF NEW.status_reg = 'G' THEN
              --Posiciona financ_cc_movto
              SELECT controle,fat_transacao_id, valor
                INTO r_cc_movto
                FROM financ_cc_movto
                WHERE controle = new.financ_cc_movto_controle
                LIMIT 1 ;

              d118_classgerencialproduto =  'N';
              -- LOOP
              FOR r_transacao IN SELECT * FROM view_transacao WHERE codigo_transacao = r_cc_movto.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 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;
                -- 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;
               --Gerar Fatura: R/P=Receber/Pagar)
                 IF r_transacao.diretiva = 423 THEN
                    --d118_classgerencialproduto = 'N'; -- Se Diretiva Gera Fatura Classe Gerencia nao pode ser pelo produto
                    d423_gerar_fatura = substring(r_transacao.propriedade from 1 for 1);
                 END IF;
               --Gerar Fatura: Condicção de Pgto
                 IF r_transacao.diretiva = 424 THEN
                    d424_CondPgto = CAST(r_transacao.propriedade AS INTEGER);
                 END IF;

              END LOOP;

              --
              -- atualizar apuracao de resultados de competencia (classificacao gerencial)
              --

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




              --Gravar  classificacao gerencial
              BEGIN
                     aCamposCl =  '{
                        financ_rp_id,
                        cad_cadastro_id,
                        financ_classificacao_g_id,
                        tipo,
                        regimecaixa,
                        regimecompetencia,
                        natureza,
                        datalcto,
                        valor}';

                   --RAISE EXCEPTION 'd71_codigoclasse1:%',d71_codigoclasse1 ;

                     IF d71_codigoclasse1 IS NOT NULL AND
                        d72_codigoclasse2 IS NOT NULL AND
                        d73_codigoclasse3 IS NOT NULL THEN
                        FOR i IN 1..3 LOOP

                            --Posiciona  classe
                            SELECT id, natureza
                              INTO r_classe
                              FROM financ_classificacao_g
                              WHERE financ_classificacao_g.id = CASE WHEN i=1 THEN d71_codigoclasse1
                                                                    WHEN i=2 THEN d72_codigoclasse2
                                                                    ELSE          d73_codigoclasse3
                                                                END;

                            aDadosCL  =   '{' 	|| 	to_char(New.id,'9999999999')   			||','
                                                || 	to_char(NEW.cad_cadastro_id, '999999999')   	||','
                                                || 	CASE WHEN i=1 THEN d71_codigoclasse1
                                                         WHEN i=2 THEN d72_codigoclasse2
                                                         ELSE          d73_codigoclasse3
                                                    END                                   	||','
                                                ||  New.natureza                          	||','
                                                || 	'false'                                	||','
                                                || 	'true'                                 	||','
                                                || 	r_classe.natureza                      	||','
                                                || to_Char(NEW.emissao, 'dd/MM/yyyy')     	||','
                                                || to_Char(New.valor_total/3, '999999999.99')     	||'}';



        --                    aDadosCL  =   '{' 	|| 	to_char(New.id,'9999999999')   			||','
        --			                       		|| 	to_char(NEW.cad_cadastro_id, '999999999')   	||','
        --							       		|| 	CASE WHEN i=1 THEN d71_codigoclasse1
        --								           		 WHEN i=2 THEN d72_codigoclasse2
        --								       			 ELSE          d73_codigoclasse3
        --							           		END                                   	||','
        --							  			||  New.natureza                          	||','
        --							  			|| 	'false'                                	||','
        --							  			|| 	'true'                                 	||','
        --							  			|| 	CASE WHEN New.natureza = 'P' THEN 'Debito'
        --								  	   		ELSE 'Credito'
        --							     			END                                    	||','
        --							  			|| to_Char(NEW.emissao, 'dd/MM/yyyy')     	||','
        --							  			|| to_Char(New.valor_total/3, '999999999.99')     	||'}';

                            IF NOT padrao.gravarpCl(aCamposcl, aDadoscl)THEN
                                    RAISE EXCEPTION 'nao foi possivel persistir classificacao gerencial (NF:% - CTRL:% CLASSE:%)!',NEW.docto , New.fatura,
                                                                                    CASE WHEN i=1 THEN d71_codigoclasse1
                                                                                         WHEN i=2 THEN d72_codigoclasse2
                                                                                         ELSE          d73_codigoclasse3
                                                                                    END;
                            END IF;
                        END LOOP;
                     END IF;
                     IF d71_codigoclasse1 IS NOT NULL AND
                        d72_codigoclasse2 IS NOT NULL THEN
                        FOR i IN 1..2 LOOP
                            aDadosCL  =   '{' 	|| 	to_char(New.id,'9999999999')   			||','
                                                || 	to_char(NEW.cad_cadastro_id, '999999999')   	||','
                                                || 	CASE WHEN i=1 THEN d71_codigoclasse1
                                                         ELSE 	       d72_codigoclasse2
                                                    END                                   	||','
                                                || 	New.natureza                          	||','
                                                || 	'false'                                	||','
                                                || 	'true'                                 	||','
                                                || 	CASE WHEN New.natureza = 'P'THEN 'Debito'
                                                    ELSE 'Credito'
                                                    END                                    	||','
                                                || to_Char(NEW.emissao, 'dd/MM/yyyy')     	||','
                                                || to_Char(New.valor_total/2, '999999999.99')     	||'}';

                            IF NOT padrao.gravarpCl(aCamposcl, aDadoscl)THEN
                                    RAISE EXCEPTION 'nao possivel persistir classificacao gerencial (NF:% - CTRL:% CLASSE:%)!',NEW.docto , New.fatura,
                                                                                    CASE WHEN i=1 THEN d71_codigoclasse1
                                                                                         ELSE          d72_codigoclasse2
                                                                                    END;
                            END IF;
                        END LOOP;
                     END IF;
                     IF d71_codigoclasse1 IS NOT NULL THEN
                        aDadosCL  =   '{' 	|| 	to_char(New.id,'9999999999')   			||','
                                            || 	to_char(NEW.cad_cadastro_id, '999999999')   	||','
                                            || 	d71_codigoclasse1                      	||','
                                            || 	New.natureza                          	||','
                                            || 	'false'                                	||','
                                            || 	'true'                                 	||','
                                            || 	CASE WHEN New.natureza = 'P'THEN 'Debito'
                                                ELSE 'Credito'
                                                END                                    	||','
                                            || to_Char(NEW.emissao, 'dd/MM/yyyy')     	||','
                                            || to_Char(New.valor_total, '999999999.99')	||'}';

                            IF NOT padrao.gravarpCl(aCamposcl, aDadoscl)THEN
                                    RAISE EXCEPTION 'nao possivel persistir classificacao gerencial (NF:% - CTRL:% CLASSE:%)!',NEW.docto , New.fatura,d71_codigoclasse1;
                            END IF;
                     END IF;
              END;

       ELSE
               --Posiciona fat_docto_c
               SELECT controle,fat_transacao_id, fat_condpg_id, valortotal_docto
                 INTO r_docto_c
                 FROM fat_docto_c
                WHERE controle = new.fatura
                LIMIT 1 ;

              -- LOOP
              FOR r_transacao IN SELECT * FROM view_transacao WHERE codigo_transacao = r_docto_c.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 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;
                -- 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;
               --Gerar Fatura: R/P=Receber/Pagar)
                 IF r_transacao.diretiva = 423 THEN
                    --d118_classgerencialproduto = 'N'; -- Se Diretiva Gera Fatura Classe Gerencia nao pode ser pelo produto
                    d423_gerar_fatura = substring(r_transacao.propriedade from 1 for 1);
                 END IF;
               --Gerar Fatura: Condicção de Pgto
                 IF r_transacao.diretiva = 424 THEN
                    d424_CondPgto = CAST(r_transacao.propriedade AS INTEGER);
                 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;
              END LOOP;

               --
               -- atualizar apuracao de resultados de competencia (classificacao gerencial)
               --

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



              -- Classificacao gerencia pelo produto
              IF d118_classgerencialproduto = 'S' THEN


                 -- Campos
                  aCamposCl =  '{
                            financ_rp_id,
                            cad_cadastro_id,
                            financ_classificacao_g_id,
                            tipo,
                            regimecaixa,
                            regimecompetencia,
                            natureza,
                            datalcto,
                            valor}';
                 --Roda Itens do docto


                  FOR r_docto_i IN SELECT fat_produto.class_g_id as classe, sum(valor_total_liquido) as total_classe
                                     FROM fat_docto_i
                                     JOIN fat_produto ON id = fat_produto_id
                                    WHERE fat_docto_c_controle = r_docto_c.controle
                                    GROUP BY fat_produto.class_g_id
                                    LOOP



                      indicePA =  Round(NEW.valor_total / r_docto_c.valortotal_docto,5);

                      --RAISE EXCEPTION 'Teste: %',indicePA;

                      aDadosCL  =   '{' 	|| 	to_char(New.id,'9999999999')   			||','
                                            || 	to_char(NEW.cad_cadastro_id, '999999999')   	||','
                                            || 	r_docto_i.classe                       	||','
                                            || 	New.natureza                         	||','
                                            || 	'false'                                	||','
                                            || 	'true'                                 	||','
                                            || 	CASE WHEN d12_natureza = 'E'THEN 'Debito'
                                                    ELSE 'Credito'
                                                END                                    	||','
                                            || to_Char(NEW.emissao, 'dd/MM/yyyy')     	||','
                                            || to_Char(Round(r_docto_i.total_classe * indicePA,2), '999999999.99')     	||'}';
                                        --	|| to_Char(NEW.valor_total, '999999999.99')     	||'}';

                       IF aDadosCL IS NULL THEN
                            RAISE EXCEPTION 'Nao sera possivel gravar operacao.
                                     Dados para apauracao de resultaso incompleto. Verifique campos <NULL>:
                                    (id:%
                                      cad_cadastro_id:%
                                      classe:%
                                      tipo:%
                                      regimecaixa:%
                                      regimecompetencia:%
                                      natureza:%
                                      datalcto:%
                                      valor:%)',
                                       to_char(New.id,'9999999999')   ,
                                       to_char(NEW.cad_cadastro_id, '999999999')           ,
                                       r_docto_i.classe            ,
                                       New.natureza              ,
                                       'false'            ,
                                       'true'          ,
                                       CASE WHEN d12_natureza = 'E'THEN 'Debito'
                                            ELSE 'Credito'
                                       END,
                                       to_Char(NEW.emissao, 'dd/MM/yyyy')       ,
                                       to_Char(r_docto_i.total_classe, '999999999.99');
                      END IF;
                      IF NOT padrao.gravarpCl(aCamposcl, aDadoscl)THEN
                                    RAISE EXCEPTION 'nao foi possivel persistir classificacao gerencial (NF:% - CTRL:% CLASSE:%)!',NEW.docto , New.controle, r_docto_i.classe;
                      END IF;
                  END LOOP;
              ELSE
               --Gravar  classificacao gerencial
                 BEGIN
                     aCamposCl =  '{
                        financ_rp_id,
                        cad_cadastro_id,
                        financ_classificacao_g_id,
                        tipo,
                        regimecaixa,
                        regimecompetencia,
                        natureza,
                        datalcto,
                        valor}';

                   --RAISE EXCEPTION 'd71_codigoclasse1:%',d71_codigoclasse1 ;

                     IF d71_codigoclasse1 IS NOT NULL AND
                        d72_codigoclasse2 IS NOT NULL AND
                        d73_codigoclasse3 IS NOT NULL THEN
                        FOR i IN 1..3 LOOP

                            --Posiciona  classe
                            SELECT id, natureza
                             INTO r_classe
                             FROM financ_classificacao_g
                             WHERE financ_classificacao_g.id = CASE WHEN i=1 THEN d71_codigoclasse1
                                                                    WHEN i=2 THEN d72_codigoclasse2
                                                                    ELSE          d73_codigoclasse3
                                                                END;

                            aDadosCL  =   '{' 	|| 	to_char(New.id,'9999999999')   			||','
                                                || 	to_char(NEW.cad_cadastro_id, '999999999')   	||','
                                                || 	CASE WHEN i=1 THEN d71_codigoclasse1
                                                         WHEN i=2 THEN d72_codigoclasse2
                                                         ELSE          d73_codigoclasse3
                                                    END                                   	||','
                                                ||  New.natureza                          	||','
                                                || 	'false'                                	||','
                                                || 	'true'                                 	||','
                                                || 	r_classe.natureza                      	||','
                                                || to_Char(NEW.emissao, 'dd/MM/yyyy')     	||','
                                                || to_Char(New.valor_total/3, '999999999.99')     	||'}';



        --                    aDadosCL  =   '{' 	|| 	to_char(New.id,'9999999999')   			||','
        --			                       		|| 	to_char(NEW.cad_cadastro_id, '999999999')   	||','
        --							       		|| 	CASE WHEN i=1 THEN d71_codigoclasse1
        --								           		 WHEN i=2 THEN d72_codigoclasse2
        --								       			 ELSE          d73_codigoclasse3
        --							           		END                                   	||','
        --							  			||  New.natureza                          	||','
        --							  			|| 	'false'                                	||','
        --							  			|| 	'true'                                 	||','
        --							  			|| 	CASE WHEN New.natureza = 'P' THEN 'Debito'
        --								  	   		ELSE 'Credito'
        --							     			END                                    	||','
        --							  			|| to_Char(NEW.emissao, 'dd/MM/yyyy')     	||','
        --							  			|| to_Char(New.valor_total/3, '999999999.99')     	||'}';

                            IF NOT padrao.gravarpCl(aCamposcl, aDadoscl)THEN
                                    RAISE EXCEPTION 'nao foi possivel persistir classificacao gerencial (NF:% - CTRL:% CLASSE:%)!',NEW.docto , New.fatura,
                                                                                    CASE WHEN i=1 THEN d71_codigoclasse1
                                                                                         WHEN i=2 THEN d72_codigoclasse2
                                                                                         ELSE          d73_codigoclasse3
                                                                                    END;
                            END IF;
                        END LOOP;
                     END IF;
                     IF d71_codigoclasse1 IS NOT NULL AND
                        d72_codigoclasse2 IS NOT NULL THEN
                        FOR i IN 1..2 LOOP
                            aDadosCL  =   '{' 	|| 	to_char(New.id,'9999999999')   			||','
                                                || 	to_char(NEW.cad_cadastro_id, '999999999')   	||','
                                                || 	CASE WHEN i=1 THEN d71_codigoclasse1
                                                         ELSE 	       d72_codigoclasse2
                                                    END                                   	||','
                                                || 	New.natureza                          	||','
                                                || 	'false'                                	||','
                                                || 	'true'                                 	||','
                                                || 	CASE WHEN New.natureza = 'P'THEN 'Debito'
                                                    ELSE 'Credito'
                                                    END                                    	||','
                                                || to_Char(NEW.emissao, 'dd/MM/yyyy')     	||','
                                                || to_Char(New.valor_total/2, '999999999.99')     	||'}';

                            IF NOT padrao.gravarpCl(aCamposcl, aDadoscl)THEN
                                    RAISE EXCEPTION 'nao possivel persistir classificacao gerencial (NF:% - CTRL:% CLASSE:%)!',NEW.docto , New.fatura,
                                                                                    CASE WHEN i=1 THEN d71_codigoclasse1
                                                                                         ELSE          d72_codigoclasse2
                                                                                    END;
                            END IF;
                        END LOOP;
                     END IF;
                     IF d71_codigoclasse1 IS NOT NULL THEN
                        aDadosCL  =   '{' 	|| 	to_char(New.id,'9999999999')   			||','
                                            || 	to_char(NEW.cad_cadastro_id, '999999999')   	||','
                                            || 	d71_codigoclasse1                      	||','
                                            || 	New.natureza                          	||','
                                            || 	'false'                                	||','
                                            || 	'true'                                 	||','
                                            || 	CASE WHEN New.natureza = 'P'THEN 'Debito'
                                                ELSE 'Credito'
                                                END                                    	||','
                                            || to_Char(NEW.emissao, 'dd/MM/yyyy')     	||','
                                            || to_Char(New.valor_total, '999999999.99')	||'}';

                            IF NOT padrao.gravarpCl(aCamposcl, aDadoscl)THEN
                                    RAISE EXCEPTION 'nao possivel persistir classificacao gerencial (NF:% - CTRL:% CLASSE:%)!',NEW.docto , New.fatura,d71_codigoclasse1;
                            END IF;
                     END IF;
                 END;
              END IF;

       END IF;
   END IF;

   RETURN NULL;
END;

$BODY$

LANGUAGE 'plpgsql' VOLATILE;



-- Storeprocedure dados_tabela(varchar)} Versao {003} Esquema {padrao} Descricao {Retorna estrutura de uma tabela}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.dados_tabela(varchar(30))
RETURNS SETOF padrao.tabela_estrutura AS
$BODY$
 DECLARE
 r padrao.tabela_estrutura%ROWTYPE;
 rec RECORD;
 vTabela alias for $1;
 eSql TEXT;

 BEGIN

 eSql := 'SELECT
       CAST(rel.nspname as TEXT), CAST(rel.relname AS TEXT) , CAST(attrs.attname AS TEXT), CAST("Type" AS TEXT), CAST("Default" AS TEXT), attrs.attnotnull
        FROM
               (SELECT c.oid, n.nspname, c.relname
               FROM pg_catalog.pg_class c
               LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
               WHERE pg_catalog.pg_table_is_visible(c.oid) ) rel
        JOIN
               (SELECT a.attname, a.attrelid,
               pg_catalog.format_type(a.atttypid, a.atttypmod) as "Type",
                      (SELECT substring(d.adbin for 128) FROM pg_catalog.pg_attrdef d
                      WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)
               as "Default", a.attnotnull, a.attnum
               FROM pg_catalog.pg_attribute a
               WHERE a.attnum > 0 AND NOT a.attisdropped ) attrs
        ON (attrs.attrelid = rel.oid )
        WHERE relname LIKE ''%' || vTabela || '%''
        ORDER BY attrs.attnum';
FOR r IN EXECUTE eSql
 LOOP
 RETURN NEXT r;
END LOOP;
 IF NOT FOUND THEN
        RAISE EXCEPTION 'Tabela % nao encontrada', vTabela;
 END IF;
 RETURN;
 END
 $BODY$
 LANGUAGE 'plpgsql';


-- Storeprocedure {f_cnpjcpf(integer,bpchar)} Versao {001} Esquema {padrao} Descricao {Validar o n�mero do documento especificado(CPF,CNPJ)}
-- ------------------------------------------------------------

/*********************************************************
 Argumentos:
 Pessoa [Juridica(0),Fisica(1) ou
 Livre(2)] (integer), N�mero com digitos
 verificadores e sem pontuacao (bpchar)
 Retorno:
 1: Tipo de Documento invalido.
 2: Caracter invalido no numero do documento.
 3: Numero do Documento invalido.
 1: OK (smallint)
*****************************************************/

CREATE OR REPLACE FUNCTION padrao.f_cnpjcpf (integer,bpchar)
RETURNS integer AS
'
DECLARE
   pTipo         ALIAS FOR $1;
   pNumero       ALIAS FOR $2;
   i             INT4;
   iProd         INT4;
   iMult         INT4;
   iDigito       INT4;
   sNumero       VARCHAR(20);
BEGIN
   IF (pTipo < 0) OR (pTipo > 2) THEN
      RETURN -1;
   END IF;
   IF pTipo = 2 THEN
      RETURN 1;
   END IF;
   sNumero := trim(pNumero);
   FOR i IN 1..char_length(sNumero) LOOP
      IF position(substring(sNumero, i, 1) in ''1234567890'') = 0 THEN
         RETURN -2;
      END IF;
   END LOOP;
   sNumero := '''';

   IF (char_length(trim(pNumero)) = 14) AND (pTipo = 0) THEN
      sNumero := substring(pNumero from 1 for 12);
      iMult := 2;
      iProd := 0;

      FOR i IN REVERSE 12..1 LOOP
         iProd := iProd + to_number(substring(sNumero from i for 1),''9'') * iMult;
         IF iMult = 9 THEN
            iMult := 2;
         ELSE
            iMult := iMult + 1;
         END IF;
      END LOOP;

      iDigito := 11 - (iProd % 11);
      IF iDigito >= 10 THEN
         iDigito := 0;
      END IF;

      sNumero := substring(pNumero from 1 for 12) || trim(to_char(iDigito,''9'')) || ''0'';

      iMult := 2;
      iProd := 0;

      FOR i IN REVERSE 13..1 LOOP
         iProd := iProd + to_number(substring(sNumero from i for 1),''9'') * iMult;
         IF iMult = 9 THEN
            iMult := 2;
         ELSE
            iMult := iMult + 1;
         END IF;
      END LOOP;

      iDigito := 11 - (iProd % 11);
      IF iDigito >= 10 THEN
         iDigito := 0;
      END IF;

      sNumero := substring(sNumero from 1 for 13) || trim(to_char(iDigito,''9''));
   END IF;

   IF (char_length(trim(pNumero)) = 11) AND (pTipo = 1) THEN
      iDigito := 0;
      iProd := 0;
      sNumero := substring(pNumero from 1 for 9);

      FOR i IN 1..9 LOOP
         iProd := iProd + (to_number(substring(sNumero from i for 1),''9'') * (11 - i));
      END LOOP;
      iDigito := 11 - (iProd % 11);
      IF (iDigito) >= 10 THEN
         iDigito := 0;
      END IF;
      sNumero := substring(pNumero from 1 for 9) || trim(to_char(iDigito,''9'')) || ''0'';
      iProd := 0;
      FOR i IN 1..10 LOOP
         iProd := iProd + (to_number(substring(sNumero from i for 1),''9'') * (12 - i));
      END LOOP;
      iDigito := 11 - (iProd % 11);
      IF (iDigito) >= 10 THEN
         iDigito := 0;
      END IF;
      sNumero := substring(sNumero from 1 for 10) || trim(to_char(iDigito,''9''));

   END IF;
   IF pNumero = sNumero::bpchar THEN
      RETURN 1;
   ELSE
      RETURN -3;
   END IF;
END;
'
LANGUAGE 'plpgsql' VOLATILE;



-- Storeprocedure {isdiautil(date, int4, varchar)} Versao {001} Esquema {padrao} Descricao {Checa dia util}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.isdiautil( date,  int4,  varchar) RETURNS bool AS
$BODY$
 DECLARE
 p_data          alias for $1;
 p_municipio     alias for $2;
 p_diasuteis     alias for $3;
 v_diasuteis     varchar(7);
 v_retorna       boolean;
 v_dia           varchar(1);
 BEGIN
   v_dia       = to_char(p_data,'D');  -- 1-Domingo 2-Segunda 3-Quarta ... 7-Sabado
   v_diasuteis = p_diasuteis;
   If v_diasuteis is null then
      v_diasuteis = '23456';
   end if;
   If feriado(p_data, p_municipio, false) or not trim(v_diasuteis) like '%'||v_dia||'%' then
      v_retorna = false;
   Else
      v_retorna = true;
   end if;
    RETURN v_retorna;
 END;
 $BODY$
LANGUAGE 'plpgsql' VOLATILE;


-- Storeprocedure {getlastday(date)} Versao {001} Esquema {padrao} Descricao {Retorna Ultimo dia do mes}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.getlastday( date) RETURNS date AS
$BODY$
 DECLARE
 p_data        ALIAS FOR $1;
 v_data	      date;
 BEGIN
    v_data = p_data + interval '1 month';     -- avanca para o pr�ximo m�s
    v_data = DATE_TRUNC('month', v_data)::date - 1; -- trunca no m�s e retorna um dia voltando para o ultimo dia do mes anterior
    RETURN v_data;
 END;
 $BODY$
LANGUAGE 'plpgsql' IMMUTABLE;

-- Storeprocedure {getfirstday(date)} Versao {003} Esquema {padrao} Descricao {Retorna Primeiro dia do mes}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.getfirstday( date) RETURNS date AS
$BODY$
DECLARE
 p_data        ALIAS FOR $1;
 v_data	      date;
 BEGIN
    v_data = DATE_TRUNC('month', p_data)::date; -- trunca no m�s
    RETURN v_data;
 END;
$BODY$
LANGUAGE 'plpgsql' IMMUTABLE;

-- Storeprocedure {getpreco(int4,  int4,  int4)} Versao {004} Esquema {padrao} Descricao {Retorna precco}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.getpreco( int4,  int4,  int4) RETURNS Numeric(12,2) AS
$BODY$
DECLARE
 v_lispre_codigo         alias for $1;
 v_codigotabela          alias for $2;
 v_produto               alias for $3;
 r_resultado             RECORD;
 v_retornar              float8;
 BEGIN
    v_retornar := 0;

    select *
      into r_resultado
      from fat_produto_preco
     where fat_produto_preco.fat_produto_id = v_produto
       and fat_produto_preco.fat_listapre_tabela_fat_listapre_id = v_lispre_codigo
       and fat_produto_preco.fat_listapre_tabela_tabela_id  = v_codigotabela;

    If found then
       v_retornar := r_resultado.preco;
    End if;
    RETURN v_retornar;
 END;
 $BODY$
LANGUAGE 'plpgsql';

-- Storeprocedure {getultimaalteracaopreco(int4,  int4,  int4)} Versao {005} Esquema {padrao} Descricao {Retorna precco}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.getultimaalteracaopreco( int4,  int4,  int4) RETURNS TIMESTAMP AS
$BODY$
DECLARE
 v_lispre_codigo         alias for $1;
 v_codigotabela          alias for $2;
 v_produto               alias for $3;
 r_resultado             RECORD;
 v_retornar              TIMESTAMP;
 BEGIN
    --v_retornar := null;

    SELECT dthaud
      INTO r_resultado
      FROM auditoria
     WHERE tabaud = 'fat_produto_preco'
       AND (tacaud = 'UPDATE' OR tacaud = 'INSERT')
       AND v_produto       = vpkaud[1]::INT
       AND v_codigotabela  = vpkaud[2]::INT
       AND v_lispre_codigo = vpkaud[3]::INT
     ORDER BY dthaud DESC, pkyaud DESC LIMIT 1;

    If found then
       RETURN r_resultado.dthaud;
    End if;
    RETURN v_retornar;
 END;
 $BODY$
LANGUAGE 'plpgsql';

-- Storeprocedure {getdiasuteis(date,  date,  varchar)} Versao {001} Esquema {padrao} Descricao {Retorna dias uteis}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.getdiasuteis( date,  date,  varchar) RETURNS int8 AS
$BODY$
DECLARE
 p_dataInicial    alias for $1;
 p_dataFinal      alias for $2;
 p_diasuteis      alias for $3;
 v_data           date;
 v_retorno        int8;
 BEGIN
   v_data := p_dataInicial;
   v_retorno := 0;
   WHILE v_data <= p_dataFinal LOOP
     if isdiautil(v_data, null, p_diasuteis) is true then
       v_retorno := v_retorno + 1;
     end if;
     v_data := v_data + 1;
   END LOOP;
   RETURN v_retorno;
 END;
$BODY$
LANGUAGE 'plpgsql';

-- Storeprocedure {getestoque(int4,  int4, date)} Versao {012} Esquema {padrao} Descricao {Retorna estoque}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.getestoque( int4,  int4, date) RETURNS float8 AS
$BODY$
DECLARE
 v_filial                alias for $1;
 v_produto               alias for $2;
 v_database              alias for $3;
 v_retornar              float8;
 v_recno                 BigInt;
 r_resultado             RECORD;
 mSaldo                  NUMERIC(16,4);
 mSaldo2                 NUMERIC(16,4);
 mSaldoInv               NUMERIC(16,4);

 filial integer;
 filial2 integer;


 r_filial         RECORD;
 r_parameters     RECORD;

 BEGIN
   v_retornar := 0;

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

    --posiciona filial
    SELECT id, filialestoque
	  INTO r_filial
      FROM cad_filial
	 WHERE id = v_Filial;

    filial  = r_filial.id;
	filial2 = r_filial.filialestoque;

   -- acha saldo inicial
   SELECT saldo,     saldo2,   saldoinventario
     INTO r_resultado
     FROM fat_produto_movto
    WHERE (cad_filial_id  = filial OR fat_produto_movto.cad_filial_id  = filial2)
      AND fat_produto_id    = v_Produto
      AND DataMovto        <= v_DataBase
    ORDER BY DataMovto DESC, fat_docto_c_controle DESC
    LIMIT 1;

   IF FOUND THEN
      mSaldo          = r_resultado.saldo;
      mSaldo2         = r_resultado.saldo2;
      mSaldoInv       = r_resultado.saldoinventario;
   ELSE
      mSaldo          = 0;
      mSaldo2         = 0;
      mSaldoInv       = 0;
   END IF;

   v_retornar := mSaldo;
   RETURN v_retornar;
 END;
$BODY$
LANGUAGE 'plpgsql';

-- Storeprocedure {getestoque(int4,  int4)} Versao {012} Esquema {padrao} Descricao {Retorna estoque na data atual}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.getestoque( int4,  int4) RETURNS float8 AS
$BODY$
DECLARE
 v_filial                alias for $1;
 v_produto               alias for $2;
 v_database              Date;
 v_retornar              float8;
 v_recno                 BigInt;
 r_resultado             RECORD;
 mSaldo                  NUMERIC(16,4);
 mSaldo2                 NUMERIC(16,4);
 mSaldoInv               NUMERIC(16,4);

 filial integer;
 filial2 integer;


 r_filial         RECORD;
 r_parameters     RECORD;

 BEGIN
   v_retornar := 0;
   v_database := CURRENT_DATE;

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

   --posiciona filial
    SELECT id, filialestoque
	  INTO r_filial
      FROM cad_filial
	 WHERE id = v_Filial;

	filial  = r_filial.id;
	filial2 = r_filial.filialestoque;

-- acha saldo inicial
   SELECT saldo,     saldo2,   saldoinventario
     INTO r_resultado
     FROM fat_produto_movto
    WHERE (cad_filial_id  = filial OR fat_produto_movto.cad_filial_id  = filial2)
      AND fat_produto_id    = v_Produto
      AND DataMovto        <= v_DataBase
    ORDER BY DataMovto DESC, fat_docto_c_controle DESC
    LIMIT 1;

   IF FOUND THEN
      mSaldo          = r_resultado.saldo;
      mSaldo2         = r_resultado.saldo2;
      mSaldoInv       = r_resultado.saldoinventario;
   ELSE
      mSaldo          = 0;
      mSaldo2         = 0;
      mSaldoInv       = 0;
   END IF;

   v_retornar := mSaldo;
   RETURN v_retornar;
 END;
$BODY$
LANGUAGE 'plpgsql';

-- Storeprocedure {geticms(int4,  char(2), integer)} Versao {013} Esquema {padrao} Descricao {Aliquota Icms }
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.geticms( int4,  CHAR(2), integer) RETURNS float8 AS
$BODY$
DECLARE
 v_aliquota_codigo               alias for $1;
 v_uf                            alias for $2;
 v_campo                         alias for $3; -- 1)Aliq_icms_Contribuinte 2)Aliq_icms_NaoContribuinte 2)Aliq_dif_Contribuinte 3)Aliq_dif_NaoContribuinte 3)
 v_retornar                      float8;
 v_recno                         BigInt;
 r_resultado                     RECORD;
 r_parameters                    RECORD;
 r_filial                        RECORD;
 maliquota_icms_contribuinte     NUMERIC;
 maliquota_icms_naocontribuinte  NUMERIC;
 maliquota_dif_contribuinte      NUMERIC;
 maliquota_dif_naocontribuinte   NUMERIC;
 maliquota_mva                   NUMERIC; --)5
 mfator_mva                      NUMERIC; --)6
 mreducao_base                   NUMERIC; --)7
 maliq_dest_id                    float8; --)8

 BEGIN
   v_retornar := 0;
--Posiciona parameters
	SELECT *
	INTO r_parameters
	FROM fat_parameters
	LIMIT 1 ;

--Posiciona filial
   SELECT id, cast(substring(regimetributacao from 1 for 1) AS CHAR(1)) as trib
     INTO r_filial
	 FROM cad_filial
	WHERE id = r_parameters.fatfilialpadrao;

	--IF r_filial.trib = 'S' THEN
	--   RETURN v_retornar;
	--END IF;

-- acha aliquota
   SELECT aliquota_icms_contribuinte, aliquota_icms_naocontribuinte,
          aliquota_dif_contribuinte, aliquota_dif_naocontribuinte,
          aliquota_mva, fator_mva,
          reducao_base, aliq_dest_id
     FROM padrao.cad_estado_trib
     INTO r_resultado
    WHERE fat_aliquotas_id = v_aliquota_codigo
      AND uf = v_uf
    LIMIT 1;

   IF FOUND THEN
      IF v_campo = 1 THEN --Aliq_icms_Contribuinte
         v_retornar =  r_resultado.aliquota_icms_contribuinte;
      END IF;
      IF v_campo = 2 THEN --Aliq_icms_NaoContribuinte
         v_retornar =  r_resultado.aliquota_icms_naocontribuinte;
      END IF;
      IF v_campo = 3 THEN --Aliq_dif_Contribuinte
         v_retornar =  r_resultado.aliquota_dif_contribuinte;
      END IF;
      IF v_campo = 4 THEN --Aliq_dif_NaoContribuinte
         v_retornar =  r_resultado.aliquota_dif_naocontribuinte;
      END IF;
      IF v_campo = 5 THEN --
        v_retornar =  r_resultado.aliquota_mva;
      END IF;
      IF v_campo = 6 THEN --
        v_retornar =  r_resultado.fator_mva;
      END IF;
      IF v_campo = 7 THEN --
        v_retornar =  r_resultado.reducao_base;
      END IF;
      IF v_campo = 8 THEN --
        v_retornar =  r_resultado.aliq_dest_id;
      END IF;
   END IF;
   RETURN v_retornar;
 END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

-- Storeprocedure {getTextoPadrao(int4,  char(2), integer)} Versao {002} Esquema {padrao} Descricao {Retorna texto padaro conforme aliquota }
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.gettextopadrao( int4,  CHAR(2), integer) RETURNS TEXT AS
$BODY$
DECLARE
 v_aliquota_codigo               alias for $1;
 v_uf                            alias for $2;
 v_campo                         alias for $3; -- 1)TextoPadrao 2)TextoPadraoDiferimentoParcial
 v_retornar                      TEXT;
 v_recno                         BigInt;
 r_resultado                     RECORD;
 r_parameters                    RECORD;
 r_filial                        RECORD;
 maliquota_icms_contribuinte     NUMERIC;
 maliquota_icms_naocontribuinte  NUMERIC;
 maliquota_dif_contribuinte      NUMERIC;
 maliquota_dif_naocontribuinte   NUMERIC;

 BEGIN
   v_retornar := '';
--Posiciona parameters
	SELECT *
	INTO r_parameters
	FROM fat_parameters
	LIMIT 1 ;

--Posiciona filial
   SELECT id, cast(substring(regimetributacao from 1 for 1) AS CHAR(1)) as trib
     INTO r_filial
	 FROM cad_filial
	WHERE id = r_parameters.fatfilialpadrao;

-- acha aliquota
   SELECT textopadrao, textopadrao_dif
     FROM padrao.cad_estado_trib
     INTO r_resultado
    WHERE fat_aliquotas_id = v_aliquota_codigo
      AND uf = v_uf
    LIMIT 1;

   IF FOUND THEN
      IF v_campo = 1 THEN --TextoPadrao
         v_retornar =  r_resultado.textopadrao;
      END IF;
      IF v_campo = 2 THEN --TextoPadraoDiferimentoParcial
         v_retornar =  r_resultado.textopadrao_dif;
      END IF;
   END IF;
   RETURN v_retornar;
 END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

-- Storeprocedure {string_integer(varchar)} Versao {001} Esquema {padrao} Descricao {Converte String}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.string_integer(text) RETURNS INTEGER AS
$BODY$
DECLARE
 p_converter       alias for $1;
 v_retornar        integer;
 v_numero          varchar;

 BEGIN
    v_retornar = 0;
    v_numero = substring(p_converter from 1 for 1);
    --RAISE NOTICE 'v_numero: %', v_numero;
    IF v_numero = '0' THEN
       v_retornar = p_converter::INTEGER;
    END IF;
    IF v_numero = '1' THEN
       v_retornar = p_converter::INTEGER;
    END IF;
    IF v_numero = '2' THEN
       v_retornar = p_converter::INTEGER;
    END IF;
    IF v_numero = '3' THEN
       v_retornar = p_converter::INTEGER;
    END IF;
    IF v_numero = '4' THEN
       v_retornar = p_converter::INTEGER;
    END IF;
    IF v_numero = '5' THEN
       v_retornar = p_converter::INTEGER;
    END IF;
    IF v_numero = '6' THEN
       v_retornar = p_converter::INTEGER;
    END IF;
    IF v_numero = '7'THEN
       v_retornar = p_converter::INTEGER;
    END IF;
    IF v_numero = '8' THEN
       v_retornar = p_converter::INTEGER;
    END IF;
    IF v_numero = '9' THEN
       v_retornar = p_converter::INTEGER;
    END IF;

    return v_retornar;
 END;
 $BODY$
 LANGUAGE 'plpgsql' VOLATILE;

-- Storeprocedure {getsequencia(varchar)} Versao {003} Esquema {padrao} Descricao {Retorna sequencia}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.getsequencia(varchar) RETURNS int8 AS
$BODY$
DECLARE
 p_sequencia      alias for $1;
 v_retorno        int8;
 ref_seq          refcursor;
 r_seq            RECORD;
 BEGIN
    IF p_sequencia ISNULL THEN
        --RAISE NOTICE 'O campo data inicio n�o pode ser nulo.';
        RETURN 0;
    END IF;
     IF p_sequencia = '' THEN
        --RAISE NOTICE 'O campo data inicio n�o pode ser vazio.';
        RETURN 0;
    END IF;
   OPEN ref_seq FOR EXECUTE('SELECT last_value AS sequencia FROM '||p_sequencia);
   FETCH ref_seq INTO r_seq;
   IF r_seq.sequencia > 0 THEN
      v_retorno = r_seq.sequencia;
   END IF;
   RETURN v_retorno + 1;
 END;
 $BODY$
LANGUAGE 'plpgsql' VOLATILE;

-- StoreProcedure {gerar_solicitacao()} Versao {015} Esquema {padrao} Descricao {Gerar Solicitacoes de Clientes pelo atendimento}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.gerar_solicitacao()
RETURNS trigger AS
$BODY$
BEGIN
   IF NEW.gerarsolicitacao THEN
      -- Insert or update tabela sugestoes/correcoes row with the new values.
        LOOP
           UPDATE cad_sugestoes
              SET referente = NEW.assunto,
                  usuario   = NEW.usuario,
                  cad_cadastro_id = NEW.cad_cadastro_id,
                  cliente   = NEW.cliente,
                  descricao = NEW.relatorio,
                  doc_html_rtf = NEW.doc_html_rtf,
                  dataalteracao= NEW.dataalteracao,
                  horaalteracao= NEW.horaalteracao,
                  usuarioalteracao= NEW.usuarioalteracao,
                  emissao=NEW.dataatendimento,
                  horaemissao=NEW.hora,
                  solicitante=NEW.solicitante,
                  classificacao_atendimento = NEW.classificacao
              WHERE
              	  cad_atendimento_protocolo = NEW.protocolo;

            EXIT  WHEN found;

            BEGIN
                INSERT INTO cad_sugestoes (	cad_atendimento_protocolo,
                                referente,
                                classificacao,
                                classificacao_atendimento,
                                usuario,
                                cad_cadastro_id,
                                cliente,
                                descricao,
                                doc_html_rtf,
                                datainclusao,
                                horainclusao,
                                usuarioinclusao,
                                emissao,
                                horaemissao,
                                solicitante,
                                prioridade)
                     VALUES (NEW.protocolo,
                             NEW.assunto,
                             'Solicitacao de Clientes',
                             NEW.classificacao,
                             NEW.usuario,
                             NEW.cad_cadastro_id,
                             NEW.cliente,
                             NEW.relatorio,
                             NEW.doc_html_rtf,
                             NEW.datainclusao,
                             NEW.horainclusao,
                             NEW.usuarioinclusao,
                             NEW.dataatendimento,
                             NEW.hora,
                             NEW.solicitante,
                             '1 - Baixa');

                EXIT ;

            EXCEPTION
                WHEN UNIQUE_VIOLATION THEN
                    -- do nothing
            END;
        END LOOP;

   END IF;
   IF NOT NEW.gerarsolicitacao THEN
      DELETE FROM cad_sugestoes WHERE cad_atendimento_protocolo = NEW.protocolo;
   END IF;
   RETURN NULL;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;


-- StoreProcedure {grava_condpgp()} Versao {015} Esquema {padrao} Descricao {Grava/Sugere parcelas na Tabela CondPgP(condicoes de pgto)}
-- ------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.grava_condpgp()
RETURNS trigger AS
$BODY$
DECLARE
   contador    integer;
   totParcelas integer;
BEGIN
   contador := 0;
   totParcelas := NEW.parcelas;
   -- Update o sistema exclui as parcelas para reincluir
   IF TG_OP = 'UPDATE'  THEN
	  IF OLD.parcelas >  NEW.parcelas THEN
	     DELETE FROM fat_condpg_p WHERE fat_condpg_id = NEW.id AND parcela > NEW.parcelas ;
	  END IF;
   END IF;
   -- Insert or update tabela condpgp row with the new values.
   LOOP
       contador := contador + 1;
       EXIT WHEN contador > totParcelas;

       UPDATE fat_condpg_p
          SET diasemissao=30,
              percentual=round(100.00000/totParcelas,5),
              dataalteracao= NEW.dataalteracao,
              horaalteracao= NEW.horaalteracao,
              usuarioalteracao= NEW.usuarioalteracao
        WHERE fat_condpg_id = NEW.id AND parcela = contador;

       BEGIN
          INSERT INTO fat_condpg_p (fat_condpg_id,
                      parcela,
                      diasemissao,
                      percentual ,
                      financ_portador_id,
                      financ_tipocobranca_id,
                      datainclusao,
                      horainclusao,
                      usuarioinclusao)
                 VALUES (NEW.id,
                      contador,
                      30,
                      round(100.00000/totParcelas,5),
                      1,
					  1,
                      NEW.datainclusao,
                      NEW.horainclusao,
                      NEW.usuarioinclusao);

       EXCEPTION
           WHEN UNIQUE_VIOLATION THEN
                    -- do nothing
       END;
   END LOOP;
   RETURN NULL;
END;
$BODY$
LANGUAGE 'plpgsql';









-- StoreProcedure {padrao.incluitrib()} Versao {002} Esquema {padrao} Descricao {Inclui Class.Trib. por estado nos produtos}
-- ------------------------------------------------------------

	CREATE OR REPLACE FUNCTION padrao.incluitrib()
	RETURNS bool AS
	$BODY$
	DECLARE
	 r_fatproduto RECORD;
	 retorna boolean;
	BEGIN
	 retorna = false;
	 FOR r_fatproduto IN SELECT * FROM fat_produto LOOP
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'PR', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'RS', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'SC', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'SP', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'RJ', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'MG', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'ES', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'MS', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'MT', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'GO', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'DF', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'AC', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'AM', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'AP', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'RR', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'RO', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'PA', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'MA', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'CE', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'PI', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'RN', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'PB', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'PE', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'BA', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'SE', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'AL', 1);
		INSERT INTO fat_produto_classtrib (fat_produto_id, uf, classtributaria_id) VALUES(r_fatproduto.id, 'TO', 1);
		retorna = true;
	 END LOOP;
	 RETURN retorna;
	END;


	 $BODY$

	LANGUAGE 'plpgsql' VOLATILE;



-- StoreProcedure {lancamento_integra_itens_before()} Versao {175} 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);
   custo                 NUMERIC(14,4);
   custoNF               NUMERIC(14,4);
   custoInventario       NUMERIC(14,4);
   custoDigitado         NUMERIC(14,4);
   custoReal             NUMERIC(14,4);

   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, 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,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, 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,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_classtipi.aliq_dest_id,r_cad.uf,r_cad.tipoa), 0) AS NUMERIC(5,3)) AS icms_subst_aliq_dest,
             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(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,
             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 THEN fat_produto.classtributaria_id ELSE fat_produto_classtrib.classtributaria_id END
			           ELSE
				  CASE WHEN fat_produto_classtrib.classtributaria_ncontrib_id IS NULL 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,padrao.fat_aliqinss.aliquotapfisica AS aliq_funrural_inss_fisica,
             padrao.fat_aliqinss.aliquotapjuridica 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 THEN fat_produto.classtributaria_id ELSE fat_produto_classtrib.classtributaria_id END
			           ELSE
				  CASE WHEN fat_produto_classtrib.classtributaria_ncontrib_id IS NULL 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_classtipi.aliq_dest_id,r_cad.uf,r_cad.tipoa), 0) AS NUMERIC(5,3)) AS icms_subst_aliq_dest,
             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(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,
             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 THEN fat_produto.classtributaria_id ELSE fat_produto_classtrib.classtributaria_id END
			           ELSE
				  CASE WHEN fat_produto_classtrib.classtributaria_ncontrib_id IS NULL 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,padrao.fat_aliqinss.aliquotapfisica AS aliq_funrural_inss_fisica,
             padrao.fat_aliqinss.aliquotapjuridica 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 THEN fat_produto.classtributaria_id ELSE fat_produto_classtrib.classtributaria_id END
			           ELSE
				  CASE WHEN fat_produto_classtrib.classtributaria_ncontrib_id IS NULL 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);
    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_id
			         WHEN r_cad.uf = 'EX'        THEN '3'|| r_produto.classfiscal_id
			         ELSE '2'|| r_produto.classfiscal_id
			    END;
        NEW.icms_preducao = r_produto.icmsredent;
        NEW.ipi_percentual= CASE WHEN NEW.ipi_percentual IS NULL THEN r_produto.aliquota_ipi_entrada END;
   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:= CASE WHEN NEW.ipi_percentual IS NULL THEN r_produto.aliquota_ipi_saida END;
   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:= CASE WHEN NEW.ipi_percentual IS NULL THEN r_produto.aliquota_ipi_entrada END;
   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:= CASE WHEN NEW.ipi_percentual IS NULL THEN r_produto.aliquota_ipi_saida END;
   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;

  /*
   * Rateio desconto total nos itens
   */
  IF r_doctoc.descontodocto_valor > 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.totalprodutos,0)  * 100) / 100) / NEW. qtde;
        												---COALESCE(NEW.desc_valor_avista,0)) * NEW. qtde) / COALESCE(r_doctoc.totalliquidoprodutos,r_doctoc.totalprodutos)  * 100) / 100) / NEW. qtde;

      rateio_desc_valor_nf_perc :=  rateio_desc_valor_nf /  NEW.valor_unitario * 100;

      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_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;


   IF COALESCE(NEW.ipi_digitacaomanual,FALSE) = FALSE THEN
   	  --Calcula IPI
   	  IF d15_calcularIPI = 'S' THEN
		 NEW.ipi_basecalculo := NEW.valor_total_liquido;
		 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' THEN
		 NEW.funrural_basecalculo := NEW.valor_total_liquido;
		 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' THEN
   	     NEW.icms_basecalculo := NEW.valor_total_liquido;
   	  	 IF r_cad.calculoicmssobre_ipi THEN
   	  	    NEW.icms_basecalculo := NEW.valor_total_liquido + NEW.ipi_valor;
   	  	 END IF;

		/*
		 * 1,2,8,A - Tributado / Diferido / Substituicao Tributuria / Diferido Parcial
		 */
   	  	IF SUBSTRING(r_produto.classificacao_trib from 1 for 1) IN ('1','2','8','A') 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);

   	  	 /*
		  * 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 * ((NEW.icms_basecalculo + (NEW.icms_basecalculo * r_produto.icms_subst_mva / 100)) / 100);
		        NEW.icms_subst_valor       := (NEW.icms_subst_basecalculo * r_produto.icms_subst_aliq_dest / 100) - (NEW.icms_basecalculo * r_produto.icms_subst_aliq_prop / 100 ) ;
		  	 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_total_liquido;
			  NEW.icms_valor       := Round(NEW.icms_basecalculo * NEW.icms_perc / 100,2);
			  IF r_produto.icmsdifedifp > 0 THEN
                 NEW.icms_valor       := Round(NEW.icms_valor * (100 - r_produto.icmsdifedifp) / 100, 2);
              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_total_liquido;
		   NEW.icms_perc        := 0;
		   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_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_valor             := 0;
   	  	   NEW.icms_isentos           := 0;
		   NEW.icms_outros            := NEW.valor_total_liquido;
		   NEW.icms_subst_basecalculo := 0;
		   NEW.icms_subst_valor       := 0;

   	  	END IF;
   	   /*
   	    *  F,G-Calculo ICMS ST (CSOSN-201, 202)
   	    */
   	  	IF r_filial.regimetributacao = 'S' THEN
	   	   IF SUBSTRING(r_produto.classificacao_trib from 1 for 1) IN ('F','G') THEN
	   	      NEW.icms_subst_basecalculo := 0;
		      NEW.icms_subst_valor       := 0;
		      IF d12_natureza = 'S' THEN
		         NEW.icms_subst_basecalculo := NEW.icms_basecalculo * ((NEW.icms_basecalculo + (NEW.icms_basecalculo * r_produto.icms_subst_mva / 100)) / 100);
		         NEW.icms_subst_valor       := (NEW.icms_subst_basecalculo * r_produto.icms_subst_aliq_dest / 100) - (NEW.icms_basecalculo * r_produto.icms_subst_aliq_prop / 100 ) ;
		  	  END IF;
	   	   ELSE
		      NEW.icms_isentos           := 0;
		      NEW.icms_perc              := 0;
		      NEW.icms_basecalculo       := 0;
		      NEW.icms_subst_basecalculo := 0;
		      NEW.icms_subst_valor       := 0;
		      NEW.icms_valor             := 0;
		      NEW.icms_outros            := NEW.valor_total_liquido;
	   	   END IF;
   	  	END IF;

	  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) +
--			coalesce(r_doctoc.ipi_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 'custoTotalCalculo:(%)', custoTotalCalculo;
  rateio = 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 ;
        ELSE
          rateio = custoTotalCalculo * (NEW.valor_total_liquido / r_doctoc.total_prod_st);
        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 'custoNF:(%)', custoNF;
  END IF;

--  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
--        rateio = custoTotalCalculo  * (NEW.valor_total_liquido / r_doctoc.total_prod_st);
--        --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 '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;