-------------------------------------------------------------
-- REVISADO POR JCS EM 03/06/2016 AS 13:55                 --
-- VALIDAÇÕES NF                                           --
-- VALIDAÇÕES DO DPEC, CAMPOS QUE NÃO PODEM SER ALTERADOS  --
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.valida_nf()
  RETURNS "trigger" AS
$BODY$
    DECLARE vid    TEXT;
            vl_ctr NUMERIC(15,2);
    BEGIN
	IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
	  --REMOVE ACENTOS E OUTROS CARACTERES FORA DO ASCII
	  NEW.nat_op		        = TRIM(TO_ASCII(NEW.nat_op));
	  NEW.motivo_cancelamento	= TRIM(TO_ASCII(NEW.motivo_cancelamento));
	  NEW.nome_emitente		= TRIM(TO_ASCII(NEW.nome_emitente));
	  NEW.fantasia_emitente		= TRIM(TO_ASCII(NEW.fantasia_emitente));
	  NEW.im_emitente		= TRIM(TO_ASCII(NEW.im_emitente));
	  NEW.nome_desrem		= TRIM(TO_ASCII(NEW.nome_desrem));
	  NEW.nome_transp		= TRIM(TO_ASCII(NEW.nome_transp));
	  NEW.ender_transp		= TRIM(TO_ASCII(NEW.ender_transp));
	  NEW.munic_transp		= TRIM(TO_ASCII(NEW.munic_transp));
	  NEW.num_fatura		= TRIM(TO_ASCII(NEW.num_fatura));
	  NEW.local_emb_exp		= TRIM(TO_ASCII(NEW.local_emb_exp));
	  NEW.inf_nota_empenho		= TRIM(TO_ASCII(NEW.inf_nota_empenho));
	  NEW.inf_pedido		= TRIM(TO_ASCII(NEW.inf_pedido));
	  NEW.inf_contrato		= TRIM(TO_ASCII(NEW.inf_contrato));
	  NEW.email_desrem		= TRIM(TO_ASCII(NEW.email_desrem));
	  NEW.justificativa_contingencia= TRIM(TO_ASCII(NEW.justificativa_contingencia));

	  -- VALIDA CRT
	  IF TG_OP='INSERT' AND (NEW.crt IS NULL OR NOT (NEW.crt IN (1,2,3))) THEN
	    RAISE EXCEPTION 'Código de Regime Tributário (%) inválido!',NEW.crt;
	  END IF;

	  -- GRAVA CAMPOS NULOS
	  IF length(NEW.uf_emb_exp)=0 THEN
	    NEW.uf_emb_exp = NULL;
	  END IF;	  
	  IF NEW.num_pedido=0 THEN
	    NEW.num_pedido = NULL;
	  END IF;
	  IF NEW.num_entrega=0 THEN
	    NEW.num_pedido = NULL;
	  END IF;
	  IF NEW.uf_transp='  ' THEN
	    NEW.uf_transp = NULL;
	  END IF;
      IF NEW.chave_acesso_nfe='' THEN
        NEW.chave_acesso_nfe=NULL;
      END IF;
      IF NEW.cod_agrupador=0 THEN
        NEW.cod_agrupador=NULL;
      END IF;
	  
	  
      -- EXCLUI MOVIMENTO DE ESTOQUE DO PEDIDO/OS/ENTREGA PARA DEPOIS LANÇAR PELA NF
      IF NEW.sistema IN ('GERENTE','BALCAO') AND NEW.num_pedido>0 THEN
        DELETE FROM gestao.estmovto WHERE id_empresa=NEW.id_empresa AND origem_prefixo='PE' AND origem_id IN (SELECT id_pedido FROM gerente.pedidos WHERE id_empresa=NEW.id_empresa AND numero=NEW.num_pedido);
        DELETE FROM gestao.estmovto WHERE id_empresa=NEW.id_empresa AND origem_prefixo='OS' AND origem_id IN (SELECT numero FROM gestao.os WHERE id_empresa=NEW.id_empresa AND nr_venda=NEW.num_pedido);
      ELSIF NEW.sistema IN ('GERENTE','BALCAO') AND NEW.cod_agrupador>0 THEN  
        DELETE FROM gestao.estmovto WHERE id_empresa=NEW.id_empresa AND origem_prefixo='PE' AND origem_id IN (SELECT id_pedido FROM gerente.pedidos WHERE id_empresa=NEW.id_empresa AND cod_agrupador=NEW.cod_agrupador);
      ELSIF NEW.sistema IN ('JCSFAT') AND NEW.num_entrega>0 THEN
        DELETE FROM gestao.estmovto WHERE id_empresa=NEW.id_empresa AND origem_prefixo='FT' AND origem_id IN (SELECT id_pedido FROM sig.pedidos WHERE id_empresa=NEW.id_empresa AND numero=NEW.num_entrega AND tipo='E');
      END IF;

	  -- ROTINA PARA ENTRADA EM FORMA DE EMISSAO=SCAN
	  -- IMPLEMENTADA POR JCS EM 11/01/2010
	  IF NEW.forma_emissao=3 THEN
	    IF OLD.forma_emissao=1 THEN
	      IF (SELECT numero_nfe FROM gestao.empresa WHERE id_empresa=NEW.id_empresa)>=OLD.numero THEN
		UPDATE gestao.empresa SET numero_nfe=(OLD.numero-1) WHERE id_empresa=NEW.id_empresa;
	      END IF;
	      NEW.numero=(SELECT COALESCE(MAX(numero),0)+1 FROM gestao.nf WHERE id_empresa=NEW.id_empresa AND serie='900');
	    END IF;
	    NEW.serie=900;
	    IF NEW.sistema IN ('JCSFAT','JCSEM','JCSAVE') THEN
	      UPDATE sig.ctr SET numero=to_char(NEW.numero,'000009FM')||substring(numero,7,2),prefixo=NEW.serie WHERE id_nf=NEW.id_nf;
	    END IF;
	    IF NEW.sistema IN ('GERENTE') THEN
	      UPDATE gerente.ctr SET numero=to_char(NEW.numero,'000009FM')||substring(numero,7,2),prefixo=NEW.serie WHERE id_nf=NEW.id_nf;
	    END IF;
	    IF NEW.sistema IN ('BALCAO') THEN
	      UPDATE gerente.ctr SET numero=to_char(NEW.numero,'000009FM')||substring(numero,7,2),prefixo=NEW.serie+500 WHERE id_nf=NEW.id_nf;
	    END IF;
	  END IF;

	  -- VALIDAÇÃO DE CAMPOS
	  IF NEW.serie='000' THEN
	    RAISE EXCEPTION 'Série (%) da NF inválida!',NEW.serie;
	  END IF;

	  IF (SELECT integrado_siscon FROM gestao.empresa WHERE id_empresa=NEW.id_empresa) = 'S' THEN

--            IF (SELECT relname FROM pg_catalog.pg_class c WHERE relname='secao' AND pg_catalog.pg_table_is_visible(c.oid)) IS NULL THEN
--              CREATE TEMP TABLE secao (nome_cpd CHAR(15), nome_usuario CHAR(15));
--              INSERT INTO secao (nome_cpd,nome_usuario) VALUES ('NFe','NFe');
--            END IF;

        IF TG_OP='UPDATE' THEN
	      IF NOT NEW.chave_acesso_nfe=' ' AND NOT NEW.chave_acesso_nfe=COALESCE(OLD.chave_acesso_nfe,' ') THEN
	        -- ATUALIZA CHAVE NFE NO SISCON - SAIDAS
	        UPDATE siscon.saidas SET chave_nfe=NEW.chave_acesso_nfe  WHERE id_empresa=NEW.id_empresa AND num1=NEW.numero AND serie=NEW.serie AND modelo=NEW.modelo AND emitente='P';
	        -- ATUALIZA CHAVE NFE NO SISCON - ENTRADAS
	        UPDATE siscon.entradas SET chave_nfe=NEW.chave_acesso_nfe  WHERE id_empresa=NEW.id_empresa AND numer=NEW.numero AND serie=NEW.serie AND modelo=NEW.modelo AND emitente='P';
	      END IF;
        END IF;

	    -- CANCELA LANÇAMENTO NO SISCON CASO STATUS DA NF = CANCELADA
	    IF NEW.status='C' THEN
	      IF NEW.tp_docto='S' THEN
		vid = to_char(NEW.id_empresa,'000009FM')||'.'||to_char(NEW.id_nf,'00000009FM');
		UPDATE siscon.saidas SET doc_cancelado=1,situacao='02',vl_fcp_uf_dest=0,vl_icms_uf_dest=0,vl_icms_uf_rem=0 WHERE id_saida=vid;
		DELETE FROM siscon.saidadet WHERE id_saida=vid;
		DELETE FROM gestao.itemdocto WHERE id_saisiscon=vid;
		vid = 'SAI'||vid;
	      ELSIF NEW.tp_docto='E' THEN
		vid = 'NF'||to_char(NEW.id_empresa,'000009FM')||'.'||to_char(NEW.id_nf,'00000009FM');
		UPDATE siscon.entradas SET doc_cancelado=1,situacao='02',vl_fcp_uf_dest=0,vl_icms_uf_dest=0,vl_icms_uf_rem=0 WHERE id_entrada=vid;
		DELETE FROM siscon.entradet WHERE id_entrada=vid;
		DELETE FROM gestao.itemdocto WHERE id_entsiscon=vid;
		vid = 'ENT'||vid;
	      END IF;
	      DELETE FROM siscon.ctblanct WHERE id_ctblote IN (SELECT id_ctblote FROM siscon.ctblotes WHERE id_origem=vid);
	    END IF;

	    -- CANCELA LANÇAMENTO NO SISCON CASO STATUS DA NF = DENEGADA
	    IF NEW.status='D' THEN
	      IF NEW.tp_docto='S' THEN
		vid = to_char(NEW.id_empresa,'000009FM')||'.'||to_char(NEW.id_nf,'00000009FM');
		UPDATE siscon.saidas SET doc_cancelado=1,situacao='04',vl_fcp_uf_dest=0,vl_icms_uf_dest=0,vl_icms_uf_rem=0 WHERE id_saida=vid;
		DELETE FROM siscon.saidadet WHERE id_saida=vid;
		DELETE FROM gestao.itemdocto WHERE id_saisiscon=vid;
		vid = 'SAI'||vid;
	      ELSIF NEW.tp_docto='E' THEN
		vid = 'NF'||to_char(NEW.id_empresa,'000009FM')||'.'||to_char(NEW.id_nf,'00000009FM');
		UPDATE siscon.entradas SET doc_cancelado=1,situacao='04',vl_fcp_uf_dest=0,vl_icms_uf_dest=0,vl_icms_uf_rem=0 WHERE id_entrada=vid;
		DELETE FROM siscon.entradet WHERE id_entrada=vid;
		DELETE FROM gestao.itemdocto WHERE id_entsiscon=vid;
		vid = 'ENT'||vid;
	      END IF;
	      DELETE FROM siscon.ctblanct WHERE id_ctblote IN (SELECT id_ctblote FROM siscon.ctblotes WHERE id_origem=vid);
	    END IF;

	  END IF;
 
	  -- GRAVA NULOS DOS CAMPOS NUM PEDIDO E NUM ENTREGA CASO NF CANCELADA OU DENEGADA
	  IF NEW.status='C' OR NEW.status='D' THEN
            IF NEW.sistema IN ('GERENTE','BALCAO') AND NEW.num_pedido>0 THEN
               --Cancela Fiscal
               UPDATE gerente.pedidos SET situa=4 WHERE id_empresa=NEW.id_empresa and numero=NEW.num_pedido;
               DELETE FROM gestao.estmovto WHERE origem_id IN (SELECT id_pedido FROM gerente.pedidos WHERE id_empresa=NEW.id_empresa and numero=NEW.num_pedido) AND origem_prefixo='PE';
               --Cancela Gerencial
               UPDATE gerente.pedidos SET situa=4 WHERE id_empresa=NEW.id_empresa+9000 and numero=NEW.num_pedido and clien=NEW.id_desrem;
               DELETE FROM gestao.estmovto WHERE origem_id IN (SELECT id_pedido FROM gerente.pedidos WHERE id_empresa=NEW.id_empresa+9000 and numero=NEW.num_pedido and clien=NEW.id_desrem) AND origem_prefixo='PE';
            ELSIF NEW.sistema IN ('GERENTE','BALCAO') AND NEW.cod_agrupador>0 THEN               
               --Cancela Fiscal
               UPDATE gerente.pedidos SET situa=4 WHERE id_empresa=NEW.id_empresa and cod_agrupador=NEW.cod_agrupador;
               DELETE FROM gestao.estmovto WHERE origem_id IN (SELECT id_pedido FROM gerente.pedidos WHERE id_empresa=NEW.id_empresa and cod_agrupador=NEW.cod_agrupador) AND origem_prefixo='PE';
               --Cancela Gerencial
               UPDATE gerente.pedidos SET situa=4 WHERE id_empresa=NEW.id_empresa+9000 and cod_agrupador=NEW.cod_agrupador and clien=NEW.id_desrem;
               DELETE FROM gestao.estmovto WHERE origem_id IN (SELECT id_pedido FROM gerente.pedidos WHERE id_empresa=NEW.id_empresa+9000 and cod_agrupador=NEW.cod_agrupador and clien=NEW.id_desrem) AND origem_prefixo='PE';			   
            ELSIF NEW.sistema IN ('JCSFAT') AND NEW.num_entrega>0 THEN                             
           --    UPDATE sig.pedidos SET situa=5,data_estoque=NULL,numer_ped_vinc=NULL,carga=NULL WHERE id_empresa IN (NEW.id_empresa,NEW.id_empresa+9000) and numero=NEW.num_entrega AND tipo='E';
               DELETE FROM gestao.estmovto WHERE origem_id IN (SELECT id_pedido FROM sig.pedidos WHERE id_empresa IN (NEW.id_empresa,NEW.id_empresa+9000) and numero=NEW.num_entrega AND tipo='E') AND origem_prefixo='FT';
	       DELETE FROM gestao.estmovto WHERE origem_prefixo='NF' AND origem_id=NEW.id_nf; --Deleta movimento da nota antes para não dar erro de empenho negativo.
               UPDATE sig.pedidos SET situa=1,data_emissao=NULL,data_estoque=NULL WHERE id_empresa IN (NEW.id_empresa,NEW.id_empresa+9000) and numero=NEW.num_entrega AND tipo='E';
	       --RAISE NOTICE 'TESTE';
            ELSIF NEW.sistema IN ('AUTOCOM') THEN               
               UPDATE gerente.orc SET id_nf=null WHERE id_nf=NEW.id_nf;  
            END IF;
	    NEW.num_pedido=NULL;
	    NEW.num_entrega=NULL;
        NEW.cod_agrupador=NULL;		
	    UPDATE gestao.nfrastro SET tp_movto='X' WHERE id_nfdet in (SELECT id_nfdet FROM gestao.nfdet WHERE id_nf=NEW.id_nf);
	  END IF;

	  -- CONFERE SITUAÇÃO DA ENTREGA = 3 (EMITIDA)
  	  IF NEW.status='L' AND NEW.sistema IN ('JCSFAT','JCSEM') AND NEW.num_entrega>0 THEN
	    IF NOT (SELECT situa FROM sig.pedidos WHERE id_empresa=NEW.id_empresa AND tipo='E' AND numero=NEW.num_entrega)=3 THEN
     	    RAISE EXCEPTION 'Situação do entrega # % é inválida!',NEW.num_entrega;
		END IF;
	  END IF;


	  -- GRAVA CAMPOS FIXOS NO CASO EMISSÃO EM HOMOLOGAÇÃO
	  IF NEW.tp_amb=2 THEN
	    IF NEW.tipo_inscr_desrem=3 THEN
	      NEW.inscr_desrem='';
	    ELSE
	      --NEW.tipo_inscr_desrem=1;
	      --NEW.inscr_desrem='99999999000191';
	    END IF;
	    NEW.nome_desrem='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL';
	    --NEW.ie_desrem='';
	  END IF;
	END IF;

	IF TG_OP='DELETE'  THEN

	  IF OLD.cod_status_dpec = 124 THEN          
	     RAISE EXCEPTION 'DPEC enviado e autorizado! Impossivel excluir!';
	  END IF;

	  IF OLD.cod_status_nfe = 204 THEN
	     RAISE EXCEPTION 'Nota Fiscal com status 204 Rejeicao: Duplicidade de NF-e! Impossivel excluir!';                             
	  END IF;

          IF OLD.sistema IN ('AUTOCOM') THEN
            UPDATE gerente.orc SET id_nf=null WHERE id_nf=OLD.id_nf;
          END IF;

	ELSIF TG_OP='UPDATE' THEN
          --- VALIDA CTR - JCSFAT - POR JCS 31/05/2016----------------------------------------------------------
          IF NEW.sistema='JCSFAT' AND NEW.tp_docto='S' AND NEW.status='V' AND NEW.ind_formapag IN (0,1) AND NEW.modelo='55' THEN
            SELECT sum(valor) INTO vl_ctr FROM sig.ctr WHERE origem_lancto IN ('FT','DV') AND id_nf=NEW.id_nf AND situacao='A' AND id_empresa=NEW.id_empresa;
            IF vl_ctr IS NULL THEN
              vl_ctr=0;
            END IF;
--            IF NOT (NEW.vl_orig_fatura)=vl_ctr THEN
            --  RAISE EXCEPTION 'Total da Nota Fiscal # % (%) não confere com Total dos Títulos a Receber (%)!',NEW.numero,NEW.vl_orig_fatura,vl_ctr;                             
            --END IF;
          END IF;
          --- VALIDA CTR - JCSEM - POR JCS 03/06/2016----------------------------------------------------------
          IF NEW.sistema='JCSEM' AND NEW.tp_docto='S' AND NEW.status='V' AND NEW.ind_formapag IN (0,1) AND NEW.modelo='55' THEN
            SELECT sum(valor) INTO vl_ctr FROM sig.ctr WHERE origem_lancto IN ('FT','DV') AND  id_nf=NEW.id_nf AND situacao='A' AND id_empresa=NEW.id_empresa;
            IF vl_ctr IS NULL THEN
              vl_ctr=0;
            END IF;
            IF NOT (NEW.vl_orig_fatura)=vl_ctr THEN
              RAISE EXCEPTION 'Total da Fatura da NF # % (%) não confere com Total dos Títulos a Receber (%)!',NEW.numero,NEW.vl_orig_fatura,vl_ctr;                             
            END IF;
          END IF;
          ------------------------------------------------------------------------------------------------------
	  IF OLD.cod_status_dpec = 124 THEN          

		IF NOT NEW.cod_status_dpec = OLD.cod_status_dpec THEN
		  RAISE EXCEPTION 'Código de status DPEC não pode ser modificado!';
		END IF;

		IF NOT NEW.desc_status_dpec = OLD.desc_status_dpec THEN
		  RAISE EXCEPTION 'Descrição de status DPEC não pode ser modificada!';
		END IF;

		IF NOT NEW.num_registro_dpec = OLD.num_registro_dpec THEN
		  RAISE EXCEPTION 'Número do registro da DPEC não pode ser modificado!';
		END IF;

		IF NOT NEW.dt_registro_dpec = OLD.dt_registro_dpec THEN
		  RAISE EXCEPTION 'Data do registro da DPEC não pode ser modificada!';
		END IF;

		IF NOT NEW.hr_registro_dpec = OLD.hr_registro_dpec THEN
		  RAISE EXCEPTION 'Hora do registro da DPEC não pode ser modificada!';
		END IF;

		IF NOT NEW.chave_acesso_nfe = OLD.chave_acesso_nfe THEN
		  RAISE EXCEPTION 'Chave de acesso não pode ser modificada!';
		END IF;

		IF NOT NEW.inscr_desrem = OLD.inscr_desrem THEN
		  RAISE EXCEPTION 'Inscrição do Destinatário não pode ser modificado!';
		END IF;

		IF NOT NEW.vl_icms = OLD.vl_icms THEN
		  RAISE EXCEPTION 'Valor do ICMS não pode ser modificado';
		END IF;

		IF NOT NEW.vl_icmsst = OLD.vl_icmsst THEN
		  RAISE EXCEPTION 'Valor do ICMSST não pode ser modificado';
		END IF;

		IF NOT NEW.vl_nf = OLD.vl_nf THEN
		  RAISE EXCEPTION 'Valor Total da NF não pode ser modificado';
		END IF;		
		
	  END IF;
	END IF;


	IF TG_OP='DELETE' THEN
	  RETURN OLD;
	ELSE
	  RETURN NEW;
	END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_nf ON gestao.nf;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_nf
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.nf
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_nf();
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_nf_after()
  RETURNS "trigger" AS
$BODY$
    BEGIN
        IF TG_OP='UPDATE' THEN
          -- CANCELA CTR CASO STATUS DA NF = DENEGADA OU CANCELADA
          IF NEW.status IN ('D','C') THEN
 	    IF NEW.tp_docto='S' THEN
	      IF NEW.sistema IN ('JCSFAT','JCSEM','JCSAVE') THEN
                UPDATE sig.ctr SET situacao='C', id_entrega=NULL WHERE id_nf=NEW.id_nf AND id_empresa=NEW.id_empresa AND recbt=0 AND desco=0;
                UPDATE sig.ctr SET situacao='C', id_entrega=NULL WHERE id_nf=NEW.id_nf AND NOT id_empresa=NEW.id_empresa AND recbt=0 AND desco=0;
              END IF;
	      IF NEW.sistema IN ('GERENTE','BALCAO') THEN
                UPDATE gerente.ctr SET situacao='C',id_pedido=null WHERE id_nf=NEW.id_nf AND id_empresa=NEW.id_empresa AND recbt=0 AND desco=0;
                UPDATE gerente.ctr SET situacao='C',id_pedido=null WHERE id_nf=NEW.id_nf AND NOT id_empresa=NEW.id_empresa AND recbt=0 AND desco=0;
                --Cancela CTR gerencial
                UPDATE gerente.ctr SET situacao='C' WHERE id_empresa=NEW.id_empresa+9000 AND recbt=0 AND
                                  id_pedido in (select id_pedido from gerente.pedidos where id_empresa=NEW.id_empresa+9000 and numero=OLD.num_pedido and clien=NEW.id_desrem);
              END IF;                
	    END IF; 
	    DELETE FROM gestao.estterceiro WHERE id_empresa=NEW.id_empresa AND data=NEW.dt_emissao AND docto='NF '||new.numero::text AND origem LIKE 'PEDITEM%';             
          END IF;                         
        END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--



DROP TRIGGER valida_nf_after ON gestao.nf;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_nf_after
  AFTER INSERT OR UPDATE 
  ON gestao.nf
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_nf_after();
--RUN--

-------------------------------------------------------------
-- REVISADO POR JCS EM 04/02/2016 AS 15:30                 --
-- VALIDAÇÕES NFDET                                        --
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.valida_nfdet()
  RETURNS "trigger" AS
$BODY$
    DECLARE vid_emp_st    INT4;
            vid_emp_mat   INT4;
            vreg_tributacao INT4;
	    vtp_st        CHAR(1);
	    vestado       CHAR(2);
	    vuf_emitente  CHAR(2);
	    vnf           RECORD;
	    vvl_confere   NUMERIC(15,2);

    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          --REMOVE ACENTOS E OUTROS CARACTERES FORA DO ASCII
	  NEW.cod_produto		= TRIM(TO_ASCII(NEW.cod_produto));
	  NEW.cod_ean			= TRIM(TO_ASCII(NEW.cod_ean));
	  NEW.descricao			= TRIM(TO_ASCII(NEW.descricao));
	  NEW.und_comercial		= TRIM(TO_ASCII(NEW.und_comercial));
	  NEW.cod_ean_tributavel	= TRIM(TO_ASCII(NEW.cod_ean_tributavel));
	  NEW.und_tributavel		= TRIM(TO_ASCII(NEW.und_tributavel));
	  NEW.inf_adicionais		= REPLACE(TRIM(TO_ASCII(NEW.inf_adicionais)),CHR(9),'');
	  NEW.num_pedido		= TRIM(TO_ASCII(NEW.num_pedido));
	  NEW.cod_ncm                   = TRIM(TO_ASCII(NEW.cod_ncm));
	  NEW.ex_tipi                   = TRIM(TO_ASCII(NEW.ex_tipi));
	  NEW.classe_enq_ipi            = TRIM(TO_ASCII(NEW.classe_enq_ipi));
	  NEW.codigo_enq_ipi            = TRIM(TO_ASCII(NEW.codigo_enq_ipi));
	  NEW.codigo_selo               = TRIM(TO_ASCII(NEW.codigo_selo));
	  NEW.ndi                       = TRIM(TO_ASCII(NEW.ndi));
	  NEW.local_desembaraco         = TRIM(TO_ASCII(NEW.local_desembaraco));
	  NEW.uf_desembaraco            = TRIM(TO_ASCII(NEW.uf_desembaraco));
	  NEW.cod_exportador            = TRIM(TO_ASCII(NEW.cod_exportador));
	  NEW.cod_fabricante            = TRIM(TO_ASCII(NEW.cod_fabricante));
	  NEW.codif                     = TRIM(TO_ASCII(NEW.codif));
	  NEW.num_fci                   = TRIM(TO_ASCII(NEW.num_fci));

	  IF NEW.tp_calc_pisst IS NULL THEN
	    NEW.tp_calc_pisst		= ' ';
	  END IF;
	  IF NEW.tp_calc_cofinsst IS NULL THEN
	    NEW.tp_calc_cofinsst 	= ' ';
	  END IF;	  

          IF NEW.indic_exigi_issqn=' ' THEN
            NEW.indic_exigi_issqn='2';
          END IF;

          IF NEW.modal_bc_icmsst= ' ' THEN
	    NEW.modal_bc_icmsst = NULL;
	  END IF;
          -- BUSCA DADOS DA NF
          SELECT id_empresa,tp_docto,dt_emissao,crt,cod_uf_emitente,desc_status_nfe  INTO vnf FROM gestao.nf WHERE id_nf=NEW.id_nf;

	  --CONFERENCIA DA ST COMPATIVEL COM EMPRESA MATRIZ
          SELECT id_empresa,tp_operacao,reg_tributacao,uf_emitente INTO vid_emp_st,vtp_st,vreg_tributacao,vuf_emitente FROM gestao.st WHERE id_st=NEW.id_st;
          SELECT id_matriz INTO vid_emp_mat FROM gestao.empresa WHERE id_empresa=vnf.id_empresa;
          IF vid_emp_mat=0 OR vid_emp_mat IS NULL THEN
            vid_emp_mat = vnf.id_empresa;
          END IF;
          
	  SELECT sigla INTO vestado FROM gestao.estado WHERE codigo_ibge=vnf.cod_uf_emitente;
	  
	  IF NOT vestado=vuf_emitente THEN 
   	      RAISE EXCEPTION 'Estado (%) da Situação Tributária (Id: %) diverge do estado (%) do emitinte da NF!',vuf_emitente,NEW.id_st,vestado;
	  END IF;

          --CONFERENCIA CFOP
          IF vnf.tp_docto='E' THEN
            IF substring(NEW.cfop::text,1,1) NOT IN ('1','2','3') THEN
              RAISE EXCEPTION 'CFOP (%) inválido para operação (%)!',NEW.cfop,vnf.tp_docto;
            END IF;
          ELSIF vnf.tp_docto='S' THEN
            IF substring(NEW.cfop::text,1,1) NOT IN ('5','6','7') THEN
              RAISE EXCEPTION 'CFOP (%) inválido para operação (%)!',NEW.cfop,vnf.tp_docto;
            END IF;
          ELSE
            RAISE EXCEPTION 'Tipo de operação (%) inválido para a NF!',vnf.tp_docto;
          END IF;

          -- CONFERENCIA PARTILHA DO ICMS
          IF NEW.perc_icms_inter_part>0 THEN
            IF vnf.tp_docto='E' THEN
               vvl_confere = ((NEW.vl_bc_icms_uf_dest*(NEW.aliq_icms_uf_dest-NEW.aliq_icms_inter)/100)*NEW.perc_icms_inter_part/100);
               IF abs(NEW.vl_icms_uf_remet-vvl_confere)>0.01 THEN
                 --RAISE EXCEPTION 'Cálculo da Partilha do ICMS para UF do Remetente, não confere! Nas devoluções/entradas os valores devem ser invertidos!|Valor Informado: % - Valor Esperado: %',NEW.vl_icms_uf_remet,vvl_confere;
               END IF;
               vvl_confere = ((NEW.vl_bc_icms_uf_dest*(NEW.aliq_icms_uf_dest-NEW.aliq_icms_inter)/100)-vvl_confere);
               IF abs(NEW.vl_icms_uf_dest-vvl_confere)>0.01 THEN
                 --RAISE EXCEPTION 'Cálculo da Partilha do ICMS para UF do Destino, não confere! Nas devoluções/entradas os valores devem ser invertidos!|Valor Informado: % - Valor Esperado: %',NEW.vl_icms_uf_dest,vvl_confere;
               END IF;
            ELSIF vnf.tp_docto='S' THEN
               vvl_confere = ((NEW.vl_bc_icms_uf_dest*(NEW.aliq_icms_uf_dest-NEW.aliq_icms_inter)/100)*NEW.perc_icms_inter_part/100);
               IF abs(NEW.vl_icms_uf_dest-vvl_confere)>0.01 THEN
                 --RAISE EXCEPTION 'Cálculo da Partilha do ICMS para UF do Destino, não confere!|Valor Informado: % - Valor Esperado: %',NEW.vl_icms_uf_dest,vvl_confere;
               END IF;
               vvl_confere = ((NEW.vl_bc_icms_uf_dest*(NEW.aliq_icms_uf_dest-NEW.aliq_icms_inter)/100)-vvl_confere);
               IF abs(NEW.vl_icms_uf_remet-vvl_confere)>0.01 THEN
                 --RAISE EXCEPTION 'Cálculo da Partilha do ICMS para UF do Remetente, não confere!|Valor Informado: % - Valor Esperado: %',NEW.vl_icms_uf_remet,vvl_confere;
               END IF;
            END IF;
          
          END IF;

        
	  IF NEW.id_st IS NOT NULL THEN
            IF NOT vid_emp_st=vid_emp_mat OR vid_emp_st IS NULL THEN
   	      RAISE EXCEPTION 'Situação Tributária (Id: %) inválida para a empresa (Id: %) da NF!',NEW.id_st,vid_emp_mat;
            END IF;
            IF NOT vnf.tp_docto=vtp_st THEN
   	      -- RAISE EXCEPTION 'Tipo de operação (%) da Situação Tributária (Id: %) inválida para tipo de docto (%) da NF!',vtp_st,NEW.id_st,vnf.tp_docto;
            END IF;
	  END IF;

          IF NEW.modal_bc_icms=' ' THEN
	    NEW.modal_bc_icms=NULL;
	  END IF;

	  -- ST - REGIME TRIBUTAÇÃO SIMPLES/TRIBUTAÇÃO NORMAL
	  IF (vnf.crt=1 AND NOT vreg_tributacao=2) OR (vnf.crt IN (2,3) AND NOT vreg_tributacao=1) THEN
   	    RAISE EXCEPTION 'Regime de tributação na ST (%) inválido para Código de Regime Tributário (%)!',vreg_tributacao,vnf.crt;
      	  END IF;

	  -- VALIDA CST COFINS
	  IF NOT vnf.desc_status_nfe='*IMPXML*' AND (SELECT id_cst FROM gestao.cst 
	       WHERE tributo='COFINS'  AND tp_operacao IN (vnf.tp_docto,'A') AND codigo=NEW.cst_cofins AND dt1<=vnf.dt_emissao AND (dt2 IS NULL or dt2>=vnf.dt_emissao)) IS NULL THEN
   	    RAISE EXCEPTION 'CST do COFINS (%) inválido para operação (%)!',NEW.cst_cofins,vnf.tp_docto;
      	  END IF;

	  -- VALIDA CST PIS
	  IF NOT vnf.desc_status_nfe='*IMPXML*' AND (SELECT id_cst FROM gestao.cst 
	       WHERE tributo='PIS'  AND tp_operacao IN (vnf.tp_docto,'A') AND codigo=NEW.cst_pis AND dt1<=vnf.dt_emissao AND (dt2 IS NULL or dt2>=vnf.dt_emissao)) IS NULL THEN
   	    RAISE EXCEPTION 'CST do PIS (%) inválido para operação (%)!',NEW.cst_pis,vnf.tp_docto;
      	  END IF;

	  -- VALIDA CST SIMPLES
	  IF vnf.crt=1 AND NOT NEW.csosn='NA' AND (SELECT id_cst FROM gestao.cst 
	       WHERE tributo='SIMPLES'  AND tp_operacao IN (vnf.tp_docto,'A') AND codigo=NEW.csosn AND dt1<=vnf.dt_emissao AND (dt2 IS NULL or dt2>=vnf.dt_emissao)) IS NULL THEN
   	    RAISE EXCEPTION 'CST do SIMPLES (%) inválido para operação (%)!',NEW.csosn,vnf.tp_docto;
   	  ELSIF vnf.crt=1 AND NOT (NEW.cst_icms='' OR NEW.cst_icms IS NULL) THEN
   	    RAISE EXCEPTION 'CST do ICMS (%) não deve ser informado para CRT %!',NEW.cst_icms,vnf.crt;
      	  END IF;
      	  
          -- VALIDA CST ICMS
	  IF vnf.crt IN (2,3) AND NOT NEW.cst_icms='NA' AND (SELECT id_cst FROM gestao.cst 
	       WHERE tributo='ICMS'  AND tp_operacao IN (vnf.tp_docto,'A') AND codigo=NEW.cst_icms AND dt1<=vnf.dt_emissao AND (dt2 IS NULL or dt2>=vnf.dt_emissao)) IS NULL THEN
   	    RAISE EXCEPTION 'CST do ICMS (%) inválido para operação (%)!',NEW.cst_icms,vnf.tp_docto;
   	  ELSIF vnf.crt IN (2,3) AND NOT (NEW.csosn='' OR NEW.csosn IS NULL) THEN
   	    RAISE EXCEPTION 'CST do SIMPLES (%) não deve ser informado para CRT %!',NEW.csosn,vnf.crt;
      	  END IF;                	  

          -- VALIDA NCM
          IF substring(NEW.cfop::text,1,1) IN ('3','7') OR NOT NEW.cst_ipi='NA' THEN
            IF (NEW.cod_ncm=' ' OR NEW.cod_ncm IS NULL) THEN
              RAISE EXCEPTION 'Código do NCM (%) inválido!',NEW.cod_ncm;
            END IF;
          ELSE
            IF ((NEW.genero=00 AND NEW.tipo='P') OR NEW.genero IS NULL) THEN
              RAISE EXCEPTION 'Código do genero (%) inválido!',NEW.genero;
            END IF;
          END IF;

          -- CREDITO ICMS SIMPLES NACIONAL
      	  IF vnf.crt=1 AND NEW.csosn IN ('101','201') AND (NEW.vl_total_bruto-NEW.vl_desconto)>0 THEN
      	    IF NEW.aliq_cred_icms=0 OR NEW.aliq_cred_icms IS NULL THEN
              RAISE EXCEPTION 'Informar alíquota do crédito do ICMS para o CST (%)!',NEW.csosn ;
      	    END IF;

      	    IF NEW.vl_cred_icms=0 OR NEW.vl_cred_icms IS NULL THEN
              RAISE EXCEPTION 'Informar valor do crédito do ICMS para o CST (%)!',NEW.csosn ;
      	    END IF;    
      	  ELSIF NOT NEW.csosn IN ('900') THEN
      	    IF NEW.aliq_cred_icms>0  THEN
              RAISE EXCEPTION 'Não informar alíquota do crédito do ICMS para o CST (%)!',NEW.csosn ;
      	    END IF;

      	    IF NEW.vl_cred_icms>0 THEN
              RAISE EXCEPTION 'Não informar valor do crédito do ICMS para o CST (%)!',NEW.csosn ;
      	    END IF;    
       	  END IF;

	  --ALIQUOTA DO ICMS
	  IF NEW.bc_icms>0 AND NEW.aliq_icms=0 THEN
   	     RAISE EXCEPTION 'Alíquota do ICMS não pode ser zero quando existir BC do ICMS';
	  END IF;

	  --VALOR DO ICMS
	  IF NEW.bc_icms>0 AND NEW.vl_icms=0 AND NOT NEW.cst_icms='51' THEN
   	     RAISE EXCEPTION 'Valor do ICMS não pode ser zero quando existir BC do ICMS';
	  END IF;

	  --ALIQUOTA DO IPI
	  IF NEW.bc_ipi>0 AND NEW.aliq_ipi=0 THEN
   	     RAISE EXCEPTION 'Alíquota do IPI não pode ser zero quando existir BC do IPI';
	  END IF;

	  --VALOR DO IPI
	  IF NEW.bc_ipi>0 AND NEW.vl_ipi=0 THEN
   	     RAISE EXCEPTION 'Valor do IPI não pode ser zero quando existir BC do IPI';
	  END IF;

        END IF;	
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_nfdet ON gestao.nfdet;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_nfdet
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.nfdet
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_nfdet();
--RUN--

-- --------------------------------------------------------- --
--  FUNÇÃO PARA LANÇAR ESTMOVTO DO REQD                      --
-- --------------------------------------------------------- --
CREATE OR REPLACE FUNCTION gestao.gera_estmovto_reqd()
  RETURNS trigger AS
$BODY$

    DECLARE rREQ             RECORD;
            rESTOQUE         RECORD;
            vqtdade          NUMERIC(15,3);
            vorigem          CHAR(20);
            vcod_ccusto_estoque  INTEGER;
            vtpmovto         CHAR(1);
            vtitulo          TEXT;
            vsemaforo        text;
            vlote            int;
            vorigem_lote     character varying (20);
            vorigem_lote_tmp character varying (20);
            vid_emp_prod     int;
            vtp_mov_lote     int;
            vretorno         int;


    BEGIN
      IF TG_OP='DELETE' THEN
        IF OLD.qtd_dev_estterceiro>0 THEN
--      RAISE EXCEPTION 'Excluir não permitida! Já existe qtdade devolução para terceiro (%)!',OLD.qtd_dev_estterceiro;
        END IF;
        DELETE FROM gestao.estmovto WHERE origem_prefixo='RQ' AND origem_id=OLD.id_req AND origem_ordem=OLD.ordem;
        vorigem = 'REQD'||OLD.id_reqd;
        DELETE FROM gestao.estterceiro WHERE origem=vorigem;

        vorigem_lote     = 'REQD#'||OLD.id_reqd;
        DELETE FROM gestao.lotemov WHERE origem=vorigem_lote;
        RETURN OLD;
      ELSIF TG_OP='UPDATE' THEN
         SELECT INTO vsemaforo CURRENT_SETTING('jcs.semaforo');
		 IF vsemaforo='1' THEN
		   RETURN NEW;
		 END IF;

		 IF vsemaforo='2' THEN
		   vretorno = (SELECT SET_CONFIG('jcs.semaforo', '0', FALSE));  
		   RETURN NEW;
		 END IF;


         IF NEW.qtd_dev_estterceiro>0 THEN
           IF NEW.qtd_dev_estterceiro>NEW.qtdade THEN
             RAISE EXCEPTION 'Qtdade não pode ser inferior a qtdade já devolvida para terceiro (%)!',NEW.qtd_dev_estterceiro;
           END IF;
           IF NOT NEW.id_produto=OLD.id_produto THEN
             RAISE EXCEPTION 'Produto não pode ser alterado! Já existe qtdade devolução para terceiro (%)!',NEW.qtd_dev_estterceiro;
           END IF;
           IF NOT NEW.num_rem_estterceiro=OLD.num_rem_estterceiro THEN
             RAISE EXCEPTION 'Número da remessa não pode ser alterado! Já existe qtdade devolução para terceiro (%)!',NEW.qtd_dev_estterceiro;
           END IF;
        END IF;
        DELETE FROM gestao.estmovto WHERE origem_prefixo='RQ' AND origem_id=OLD.id_req AND origem_ordem=OLD.ordem;
      END IF;

      IF NEW.num_rem_estterceiro IS NULL OR NEW.num_rem_estterceiro=0 THEN
        NEW.sit_estterceiro='N';
      ELSIF NEW.qtd_dev_estterceiro=NEW.qtdade THEN
        NEW.sit_estterceiro='D';
      ELSIF NEW.sit_estterceiro='N' OR NEW.sit_estterceiro=' ' OR NEW.sit_estterceiro IS NULL THEN
        NEW.sit_estterceiro='S';
      END IF;

      -- BUSCA DADOS DA REQUISIÇÃO
      SELECT id_empresa,numero,tipo,data,usuario,status,situacao,id_destino,numero_op
        INTO rREQ
        FROM gestao.req WHERE id_req=NEW.id_req;

      IF NEW.num_rem_estterceiro>0 and rREQ.tipo=2 THEN
        RAISE EXCEPTION 'Número da remessa não deve ser informado na operação de reposição!';
      END IF;

      -- NÃO DEIXA VARIANTE FICAR NULO
      IF NEW.variante IS NULL THEN
        NEW.variante = '';
      END IF;

      -- DEFINE NULO SE id_ctbconta_desp = 0
      IF NEW.id_ctbconta_desp=0 THEN
        NEW.id_ctbconta_desp = NULL;
      END IF;

      -- DEFINE NULO SE COD CENTRO CUSTO =0
      IF NEW.cod_ccusto=0 THEN
        NEW.cod_ccusto = NULL;
      END IF;

      -- DEFINE NULO SE COD MAQUINA EM BRANCO
      IF NEW.cod_maquina='' THEN
        NEW.cod_maquina = NULL;
      END IF;

      -- CONFERE QTDADE ESTOQUE
      IF NEW.qtd_estoque=0 AND NOT NEW.qtdade=0 THEN
        RAISE EXCEPTION 'Qtdade do movimento de estoque está zerado!';
      ELSIF NEW.qtd_estoque IS NULL THEN
        NEW.qtd_estoque = NEW.qtdade;
      END IF;

      IF TG_OP='INSERT' THEN
        -- ATUALIZA LOTE TEMPORARIO
        vorigem_lote_tmp = 'REQ#'||NEW.id_req||NEW.id_produto||NEW.ordem;
        vorigem_lote     = 'REQD#'||NEW.id_reqd;
        UPDATE gestao.lotemov SET origem=vorigem_lote WHERE origem=vorigem_lote_tmp;
      END IF;

      -- NÃO LANÇA - POIS REQUISIÇÃO É CANCELADA OU PENDENTE. CRISTIANO 20/10/2015
      IF rREQ.situacao='C' OR rREQ.situacao='P' THEN
        RETURN NEW;
      END IF;

      -- BUSCA ID EMPRESA DO PRODUTO
      vid_emp_prod = 0;
      SELECT id_empresa_tabcomp INTO vid_emp_prod FROM gestao.tabcomp WHERE nome_tabcomp='produtos' AND id_empresa=NEW.id_empresa;
      IF vid_emp_prod IS NULL OR vid_emp_prod=0 THEN
        vid_emp_prod = NEW.id_empresa;
      END IF;

      -- VERIFICA TIPO MOVIMENTO DO LOTE
      SELECT lote INTO vtp_mov_lote FROM gestao.produto WHERE id_erp=NEW.id_produto and id_empresa=vid_emp_prod;
      IF vtp_mov_lote IS NULL THEN
        vtp_mov_lote=0;
      END IF;

      ----------------------------------------------
      -- EXCLUIR EMPENHO OPINS - JCS
      ----------------------------------------------
      IF rREQ.numero_op IS NOT NULL THEN
        DELETE FROM gestao.estmovto WHERE origem_prefixo='OPI' AND origem_id=(SELECT id_opins FROM gestao.opins WHERE id_empresa=NEW.id_empresa AND numero_op=rREQ.numero_op AND id_produto=NEW.id_produto);
      END IF;
      -----------------------------------------------

      IF (vtp_mov_lote=1 or vtp_mov_lote=2) or (vtp_mov_lote=3 and rREQ.id_empresa>9000) THEN -- VERIFICA SE TEM LOTE
        vorigem_lote     = 'REQD#'||NEW.id_reqd;
        SELECT id_lote INTO vlote from gestao.lotemov where origem=vorigem_lote;
        IF vlote IS NULL OR vlote=0 THEN
          --SE NÃO TEM LOTE VINCULADO PROCURA LOTE COM ESTOQUE DISPONIVEL
          SELECT a.id_lote
            INTO vlote
            FROM gestao.estsaldo A
            LEFT OUTER JOIN gestao.lote B ON (b.id_lote=a.id_lote)
            WHERE a.id_empresa=rREQ.id_empresa AND a.id_produto=NEW.id_produto AND a.id_estlocal=NEW.id_estlocal AND a.id_lote>0 AND (a.qtdade-a.qtd_empenhada)>=NEW.qtd_estoque AND b.situacao='L'
            ORDER BY b.dt_validade LIMIT 1;
              
            IF vlote IS NULL OR vlote=0 THEN
              RAISE EXCEPTION 'Não Existe Lote com Saldo Disponivel para o Produto (%)!',NEW.id_produto;
            END IF;
              
            vorigem_lote = 'REQD#'||NEW.id_reqd;
            INSERT INTO gestao.lotemov(id_lote, qtd, origem) VALUES (vlote, NEW.qtd_estoque, vorigem_lote);
        END IF;        
      ELSE
        vlote = 0;
      END IF;
      
      -- BUSCA / CONFERE CENTRO CUSTO ESTOQUE
      SELECT cod_ccusto_estoque
        INTO vcod_ccusto_estoque
        FROM gestao.empresa
       WHERE id_empresa=rREQ.id_empresa;
      IF vcod_ccusto_estoque=NEW.cod_ccusto THEN
         RAISE EXCEPTION 'Centro de custo da requisição inválido por ser o mesmo código do centro de custo do estoque que está definido no cadastro da empresa!';
      END IF;

      IF NOT NEW.qtd_estoque=0 AND NOT NEW.poder_terc IN ('2','3') THEN

        vorigem = 'reqd'||NEW.id_reqd;
        DELETE FROM gestao.estterceiro WHERE origem=vorigem;

        -- CONFERE ESTOQUE
        IF rREQ.tipo=1 OR rREQ.tipo=3 THEN
        
          IF vlote>0 THEN
            SELECT qtdade
              INTO rESTOQUE
              FROM gestao.estsaldo WHERE id_empresa=rREQ.id_empresa AND id_produto=NEW.id_produto AND id_estlocal=NEW.id_estlocal AND id_lote=vlote;
          ELSE
            SELECT qtdade
              INTO rESTOQUE
              FROM gestao.estsaldo WHERE id_empresa=rREQ.id_empresa AND id_produto=NEW.id_produto AND id_estlocal=NEW.id_estlocal AND variante=NEW.variante AND validade=COALESCE(NEW.validade::char(10),' ') AND id_lote is null;
          END IF;

          IF rESTOQUE.qtdade IS NULL THEN
            rESTOQUE.qtdade        = 0;
          END IF;
          
          IF (rESTOQUE.qtdade)<NEW.qtd_estoque THEN
             RAISE EXCEPTION 'Qtdade em estoque % é insuficiente!|Produto: % - Local: %|Qtdade requisitada: %|Nº Requisição: %',rESTOQUE.qtdade,NEW.id_produto,NEW.id_estlocal,NEW.qtd_estoque,rREQ.numero;
          END IF;
          
          vqtdade = NEW.qtd_estoque;
          
          IF rREQ.tipo=3 THEN
            vtitulo = 'Transferência # ';
          ELSE
            vtitulo = 'Requisição # ';
          END IF;
        ELSE
          vtitulo = 'Reposição # ';
          IF COALESCE((select valor from gestao.registro where chave='Requisição.'||rREQ.id_empresa AND nome='Usar Custo de Reposição')::int,0)=1 THEN
            vtpmovto = 'E';
            vqtdade  = NEW.qtd_estoque;
            NEW.valor    = COALESCE((select valor from gestao.cstpadrao where id_empresa=rREQ.id_empresa AND id_produto=NEW.id_produto AND data<=rREQ.data order by data DESC,hora DESC, id_cstpadrao DESC LIMIT 1),0);
            NEW.vl_total = NEW.valor * vqtdade;
          ELSE
            vqtdade = -NEW.qtd_estoque;
          END IF;
        END IF;

        IF vtpmovto IS NULL THEN
          IF rREQ.situacao='E' THEN
            vtpmovto='M';
          ELSE
            vtpmovto='S';
          END IF;
        END IF;

        -- LANÇA MOVIMENTO
        IF vlote>0 THEN
          INSERT INTO gestao.estmovto(
                      id_empresa, id_estlocal, id_produto, variante, validade,
                      docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                      historico, tipo, qtdade, valor, vl_ajuste,
                      status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador, id_lote)
              VALUES (rREQ.id_empresa, NEW.id_estlocal, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                      'I', 'REQ', '', rREQ.numero, rREQ.data,
                      vtitulo||rREQ.numero, vtpmovto, vqtdade, NEW.vl_total, 0,
                      1, 'RQ', NEW.id_req, NEW.ordem, 1,rREQ.usuario, vlote);
        ELSE
          INSERT INTO gestao.estmovto(
                      id_empresa, id_estlocal, id_produto, variante, validade,
                      docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                      historico, tipo, qtdade, valor, vl_ajuste,
                      status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador)
              VALUES (rREQ.id_empresa, NEW.id_estlocal, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                      'I', 'REQ', '', rREQ.numero, rREQ.data,
                      vtitulo||rREQ.numero, vtpmovto, vqtdade, NEW.vl_total, 0,
                      1, 'RQ', NEW.id_req, NEW.ordem, 1,rREQ.usuario);
        END IF;
        -- AJUSTA VALOR DO MOVIMENTO
        SELECT valor INTO rESTOQUE FROM gestao.estmovto WHERE id_empresa=rREQ.id_empresa AND origem_prefixo='RQ' AND origem_id=NEW.id_req AND origem_ordem=NEW.ordem AND origem_seq=1;

        IF rESTOQUE.valor IS NOT NULL THEN
          NEW.vl_total = rESTOQUE.valor;
          NEW.valor    = rESTOQUE.valor / NEW.qtdade;
        END IF;

        IF rREQ.tipo=3 THEN
                -- LANÇA MOVIMENTO TRANSFERENCIA
                IF vlote>0 THEN
                  INSERT INTO gestao.estmovto(
                              id_empresa, id_estlocal, id_produto, variante, validade,
                              docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                              historico, tipo, qtdade, valor, vl_ajuste,
                              status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador, id_lote)
                      VALUES (rREQ.id_empresa, rREQ.id_destino, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                              'I', 'REQ', '', rREQ.numero, rREQ.data,
                              vtitulo||rREQ.numero, 'E', vqtdade, NEW.vl_total, 0,
                              1, 'RQ', NEW.id_req, NEW.ordem, 2,rREQ.usuario, vlote);
               ELSE
                  INSERT INTO gestao.estmovto(
                              id_empresa, id_estlocal, id_produto, variante, validade,
                              docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                              historico, tipo, qtdade, valor, vl_ajuste,
                              status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador)
                      VALUES (rREQ.id_empresa, rREQ.id_destino, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                              'I', 'REQ', '', rREQ.numero, rREQ.data,
                              vtitulo||rREQ.numero, 'E', vqtdade, NEW.vl_total, 0,
                              1, 'RQ', NEW.id_req, NEW.ordem, 2,rREQ.usuario);
               END IF;
        END IF;

        IF rREQ.status=1 AND rREQ.id_empresa>9000 THEN
          -- LANÇA MOVIMENTO / FISCAL
          IF vlote>0 THEN
            INSERT INTO gestao.estmovto(
                        id_empresa, id_estlocal, id_produto, variante, validade,
                        docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                        historico, tipo, qtdade, valor, vl_ajuste,
                        status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador, id_lote)
                VALUES ((rREQ.id_empresa-9000), NEW.id_estlocal, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                        'I', 'REQ', '', rREQ.numero, rREQ.data,
                        vtitulo||rREQ.numero, vtpmovto, vqtdade, 0, 0,
                        1, 'RQ', NEW.id_req, NEW.ordem, 1,rREQ.usuario, vlote);
          ELSE
            INSERT INTO gestao.estmovto(
                        id_empresa, id_estlocal, id_produto, variante, validade,
                        docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                        historico, tipo, qtdade, valor, vl_ajuste,
                        status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador)
                VALUES ((rREQ.id_empresa-9000), NEW.id_estlocal, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                        'I', 'REQ', '', rREQ.numero, rREQ.data,
                        vtitulo||rREQ.numero, vtpmovto, vqtdade, 0, 0,
                        1, 'RQ', NEW.id_req, NEW.ordem, 1,rREQ.usuario);
          END IF;

          IF rREQ.tipo=3 THEN
                -- LANÇA MOVIMENTO TRANSFERENCIA
                IF vlote>0 THEN
                  INSERT INTO gestao.estmovto(
                              id_empresa, id_estlocal, id_produto, variante, validade,
                              docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                              historico, tipo, qtdade, valor, vl_ajuste,
                              status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador, id_lote)
                      VALUES ((rREQ.id_empresa-9000), rREQ.id_destino, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                              'I', 'REQ', '', rREQ.numero, rREQ.data,
                              vtitulo||rREQ.numero, 'E', vqtdade, NEW.vl_total, 0,
                              1, 'RQ', NEW.id_req, NEW.ordem, 2,rREQ.usuario, vlote);
                ELSE
                  INSERT INTO gestao.estmovto(
                              id_empresa, id_estlocal, id_produto, variante, validade,
                              docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                              historico, tipo, qtdade, valor, vl_ajuste,
                              status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador)
                      VALUES ((rREQ.id_empresa-9000), rREQ.id_destino, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                              'I', 'REQ', '', rREQ.numero, rREQ.data,
                              vtitulo||rREQ.numero, 'E', vqtdade, NEW.vl_total, 0,
                              1, 'RQ', NEW.id_req, NEW.ordem, 2,rREQ.usuario);
                END IF;
          END IF;

        END IF;
      END IF;
      RETURN NEW;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.gera_estmovto_reqd()
  OWNER TO postgres;
--RUN--

DROP TRIGGER gera_estmovto_reqd ON gestao.reqd;

--RUN--IGNORE ERRO

-- CRIA TRIGGER PARA ATUALIZAR SALDOS DO ESTOQUE
CREATE TRIGGER gera_estmovto_reqd
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.reqd
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.gera_estmovto_reqd();
--RUN--

-- FUNÇÃO PARA LANÇAR ESTMOVTO DO NFDET
CREATE OR REPLACE FUNCTION gestao.gera_estmovto_nfdet()
  RETURNS trigger AS
$BODY$

    DECLARE rNF                RECORD;
            rESTOQUE           RECORD;
            emp                RECORD;
            videmp1            INTEGER;
            videmp2            INTEGER;
            rTes               RECORD;
            v_bloq_estoque_neg smallint;
            vfatorconv         NUMERIC(15,6);
            vqtdestoque        NUMERIC(15,3);
            vvalor             NUMERIC(15,2);
            v_idestoque        CHAR(22);
            vdt_troca_est      DATE;
            vtp_trx            CHAR(1);
            rNFRef             RECORD;
            vfrete             NUMERIC(15,2);
            vlote              record;
            vid_lote           int;
            vorigem_lote       character varying (20);
            vorigem_lote_tmp   character varying (20);
            vid_emp_prod       int;
            vtp_mov_lote       int;
            vseq               int;

    BEGIN

      IF TG_OP<>'INSERT' THEN
        SELECT id_empresa,status,especie_docto,serie,numero,dt_emissao,tp_docto,sistema,num_pedido,usuario_emissao,num_entrega
        INTO rNF
        FROM gestao.nf WHERE id_nf=OLD.id_nf;
      ELSE
        SELECT id_empresa,status,especie_docto,serie,numero,dt_emissao,tp_docto,sistema,num_pedido,usuario_emissao,num_entrega
        INTO rNF
        FROM gestao.nf WHERE id_nf=NEW.id_nf;
      END IF;

      -- troca estoque de entrega para nf
      SELECT valor::DATE into vdt_troca_est FROM gestao.registro WHERE chave='Estoque.'||rNF.id_empresa::text AND nome='Data Troca Processamento Estoque de Entrega para NF';
      IF rNF.num_entrega>0 AND vdt_troca_est IS NOT NULL AND rNF.dt_emissao<=vdt_troca_est AND (TG_OP='INSERT' OR TG_OP='UPDATE') THEN
        RETURN NEW;
      END IF;

      IF TG_OP='DELETE' THEN
        IF rNF.sistema='AUTOCOM' THEN
          DELETE FROM gerente.estoqued WHERE id_nfdet=old.id_nfdet;
        ELSE
          DELETE FROM gestao.estmovto WHERE origem_prefixo='NF' AND origem_id=OLD.id_nf AND origem_ordem=OLD.num_item;
        END IF;
        RETURN OLD;
      ELSIF TG_OP='UPDATE' THEN
        IF rNF.sistema='AUTOCOM' THEN
          DELETE FROM gerente.estoqued WHERE id_nfdet=old.id_nfdet;
        ELSE
          IF ( SELECT b.id_estinventario FROM gestao.estmovto A
                 LEFT OUTER JOIN gestao.estinventario B ON (a.id_empresa=b.id_empresa AND a.id_produto=b.id_produto AND a.id_estlocal=b.id_estlocal AND a.variante=b.variante AND a.validade=COALESCE(b.validade::char(10),' '::char(10)))
                 WHERE origem_prefixo='NF' AND origem_id=OLD.id_nf AND origem_ordem=OLD.num_item AND a.data<=b.data LIMIT 1) IS NOT NULL THEN
            RETURN NEW;
          END IF;
          DELETE FROM gestao.estmovto WHERE origem_prefixo='NF' AND origem_id=OLD.id_nf AND origem_ordem=OLD.num_item;
        END IF;
      END IF;

      -- NÃO DEIXA VARIANTE FICAR NULO
      IF NEW.variante IS NULL THEN
        NEW.variante = '';
      END IF;

      SELECT id_empresa,status,especie_docto,serie,numero,dt_emissao,tp_docto,sistema,num_pedido,num_entrega,usuario_emissao,finalidade_emissao,vl_nf,dt_estoque
        INTO rNF
        FROM gestao.nf WHERE id_nf=NEW.id_nf;

     -- BUSCA ID EMPRESA DO PRODUTO
      vid_emp_prod = 0;
      SELECT id_empresa_tabcomp INTO vid_emp_prod FROM gestao.tabcomp WHERE nome_tabcomp='produtos' AND id_empresa=rNF.id_empresa;
      IF vid_emp_prod IS NULL OR vid_emp_prod=0 THEN
        vid_emp_prod = rNF.id_empresa;
      END IF;

      -- VERIFICA TIPO MOVIMENTO DO LOTE
      SELECT lote INTO vtp_mov_lote FROM gestao.produto WHERE id_erp=NEW.id_produto and id_empresa=vid_emp_prod;
      IF vtp_mov_lote IS NULL THEN
        vtp_mov_lote=0;
      END IF;

      IF vtp_mov_lote=1 OR vtp_mov_lote=2 THEN
        --ATUALIZA lOTE TEMPORARIO
        vorigem_lote_tmp = 'NF#'||NEW.id_nf||NEW.id_produto||NEW.num_item;
        vorigem_lote     = 'NFD#'||NEW.id_nfdet;
        UPDATE gestao.lotemov SET origem=vorigem_lote WHERE origem=vorigem_lote_tmp;
      END IF;
       
--      videmp1 = (SELECT id_empmovto FROM gestao.estlocal WHERE id_empmovto<9000 AND id_estlocal=NEW.id_estlocal);
      videmp1 = (SELECT CASE WHEN id_empmovto>9000 THEN id_empmovto-9000 ELSE id_empmovto END FROM gestao.estlocal WHERE id_empmovto>000 AND id_estlocal=NEW.id_estlocal);
      IF videmp1 IS NULL OR videmp1=0 THEN
        videmp1 = rNF.id_empresa;
      END IF;

      IF rNF.sistema<>'AUTOCOM' THEN
        IF (rNF.num_pedido=0 OR rNF.num_pedido IS NULL) AND (rNF.num_entrega=0 OR rNF.num_entrega IS NULL) THEN
          videmp2 = videmp1+9000;
        END IF;
      END IF;

--      IF rNF.status IN ('V','T','E') AND NEW.gerar_estoque IN ('S','T') AND NOT NEW.qtd_comercial=0 THEN
      IF rNF.status IN ('L','V','T','E') AND NEW.gerar_estoque IN ('S','T') THEN

        IF NEW.qtd_estoque=0 OR NEW.qtd_estoque IS NULL THEN
          -- CONVERTE QUANTIDADE CONFORME FATOR DE CONVERSÃO
          vfatorconv = (SELECT fator
                          FROM gestao.fatconversao A
                          LEFT OUTER JOIN gestao.produto B ON (a.id_produto=b.id_produto)
                          WHERE b.id_empresa=videmp1 AND b.codigo=NEW.cod_produto AND unid_conv=NEW.und_comercial);
          IF vfatorconv IS NULL OR vfatorconv=0 OR substring(NEW.variante,1,4)='UND:' THEN
            vqtdestoque = NEW.qtd_comercial;
          ELSE
            vqtdestoque = NEW.qtd_comercial * vfatorconv;
          END IF;
        ELSE
          vqtdestoque = NEW.qtd_estoque;
        END IF;

        -- CONFERE ESTOQUE
        IF rNF.sistema='AUTOCOM' THEN

          -- confere validade
          IF NEW.validade IS NULL THEN
            NEW.validade='3000-01-01';
          END IF;

          IF rNF.tp_docto='S' THEN
            SELECT qtdade_fis
              INTO rESTOQUE
              FROM gerente.estoque WHERE id_empresa=videmp1 AND id_produto=NEW.id_produto AND lote_serie_etc=NEW.variante AND validade=NEW.validade ORDER BY validade LIMIT 1;

            IF rESTOQUE.qtdade_fis IS NULL THEN
              rESTOQUE.qtdade_fis = 0;
            END IF;
            IF rESTOQUE.qtdade_fis<vqtdestoque THEN
               --COMENTADO TEMPORARIAMENTE 27-06-2023 
               --RAISE EXCEPTION 'Qtdade em estoque % é insuficiente para emissão NF!|Produto: % %|Qtdade requisitada: %',rESTOQUE.qtdade_fis,NEW.cod_produto,NEW.descricao,vqtdestoque;
            END IF;
          END IF;
        ELSE

          -- busca dados da empresa
          SELECT bloq_estoque_neg INTO v_bloq_estoque_neg FROM gestao.empresa WHERE id_empresa=rNF.id_empresa;

          IF rNF.tp_docto='S' AND NOT v_bloq_estoque_neg=0 THEN

            IF NEW.id_produto is null or new.id_produto=0 THEN
              RAISE EXCEPTION 'Id do produto inválido. Código Produto: %',NEW.cod_produto;
            end if;

            IF vtp_mov_lote=1 or vtp_mov_lote=2 THEN

              -- VERIFICA SE TEM LOTE
              vorigem_lote     = 'NFD#'||NEW.id_nfdet;
              SELECT id_lote INTO vid_lote from gestao.lotemov where origem=vorigem_lote;
              IF vid_lote IS NULL OR vid_lote=0 THEN
                RAISE EXCEPTION 'Lote do Produto (%) não foi Encontrado!',NEW.id_produto;
              END IF;
                          
              FOR vlote IN select id_lote,qtd from gestao.lotemov where origem=vorigem_lote
              LOOP                        
                SELECT qtdade
                  INTO rESTOQUE
                  FROM gestao.estsaldo WHERE id_empresa=videmp1 AND id_produto=NEW.id_produto AND id_estlocal=NEW.id_estlocal AND variante=NEW.variante AND validade=COALESCE(NEW.validade::char(10),' ') and id_lote=vlote.id_lote;
                IF rESTOQUE.qtdade IS NULL THEN
                  rESTOQUE.qtdade = 0;
                END IF;
                IF rESTOQUE.qtdade<vlote.qtd THEN
                   RAISE EXCEPTION 'Qtdade em estoque do Lote(%) % é insuficiente para emissão NF!|Produto: % %|Qtdade requisitada do Lote: %',vlote.id_lote,rESTOQUE.qtdade,NEW.cod_produto,NEW.descricao,vlote.qtd;
                END IF;
              END LOOP;            
            ELSE
              SELECT qtdade
                INTO rESTOQUE
                FROM gestao.estsaldo WHERE id_empresa=videmp1 AND id_produto=NEW.id_produto AND id_estlocal=NEW.id_estlocal AND variante=NEW.variante AND validade=COALESCE(NEW.validade::char(10),' ') and id_lote is null;
              IF rESTOQUE.qtdade IS NULL THEN
                rESTOQUE.qtdade = 0;
              END IF;
              IF rESTOQUE.qtdade<vqtdestoque THEN
                RAISE EXCEPTION 'Qtdade em estoque % é insuficiente para emissão NF!|Produto: % %|Qtdade requisitada: %',rESTOQUE.qtdade,NEW.cod_produto,NEW.descricao,vqtdestoque;
              END IF;
            END IF;  
          END IF;
        END IF;

        IF rNF.sistema IN ('JCSEM','JCSFAT','JCSAVE') THEN
          SELECT codigo,natureza,tipo,cred_icms INTO rTes FROM gestao.tes  WHERE id_tes=NEW.id_tes;
        ELSIF rNF.sistema IS NOT NULL THEN
          SELECT codigo,natureza,tipo,cred_icms INTO rTes FROM gestao.tes WHERE id_tes=NEW.id_tes;
        END IF;

        IF rNF.sistema='AUTOCOM' THEN

          -- busca dados do estoque
          SELECT id_estoque INTO v_idestoque FROM gerente.estoque
          WHERE id_empresa=rNF.id_empresa AND id_produto=NEW.id_produto AND validade=NEW.validade AND lote_serie_etc=NEW.variante;

          -- grava novo estoque caso não exista
          IF v_idestoque IS NULL THEN
            INSERT INTO gerente.estoque (id_empresa,id_produto,validade,lote_serie_etc,qtdade,valor,qtd_empenhada)
            VALUES (rNF.id_empresa,NEW.id_produto,NEW.validade,NEW.variante,0,0,0);
            SELECT currval('gerente.id_estoque_seq') INTO v_idestoque;
          END IF;

          --grava movimento de estoque
          INSERT INTO gerente.estoqued (id_estoque,data,tipo,qtdade,valor,origem,id_nfdet,status)
          VALUES (v_idestoque,rNF.dt_emissao,rNF.tp_docto,vqtdestoque,-1,'NF',new.id_nfdet,2);

        ELSE

           --BUSCA VALOR DO CONHECIMENTO DE FRETE DA ENTRADA
           vfrete=0;
           IF rNF.tp_docto='E' AND rNF.finalidade_emissao=1 THEN
             SELECT id_nfref, modelo_nf, chave_acesso_nfe, numero, serie, dt_emissao
              INTO rNFRef
              FROM gestao.nfref WHERE id_nf=NEW.id_nf;

             IF rNFRef.id_nfref>0 THEN
               IF rNFRef.modelo_nf='55' THEN
                 vfrete =(SELECT cf_tot-cf_icms+despadic FROM gestao.entradas WHERE id_empresa=rNF.id_empresa AND chave_nfe=rNFRef.chave_acesso_nfe);
               ELSIF rNFRef.numero>0 THEN
                 vfrete =(SELECT cf_tot-cf_icms+despadic FROM gestao.entradas WHERE id_empresa=rNF.id_empresa AND modelo=rNFRef.modelo_nf AND serie=rNFRef.serie AND numero=rNFRef.numero AND emiss=rNFRef.dt_emissao and not abs(total-rNF.vl_nf)>1);
               END IF;

               IF vfrete>0 THEN
                 vfrete = (vfrete/rNF.vl_nf)*(NEW.vl_total_bruto-NEW.vl_desconto);
               END IF;
             END IF;

             IF vfrete IS NULL THEN
               vfrete = 0;
             END IF;

           END IF;

          vvalor = (NEW.vl_total_bruto+vfrete+NEW.vl_frete+NEW.vl_seguro+NEW.vl_desp_acessorias-NEW.vl_desconto-(CASE WHEN rTES.cred_icms=1 THEN NEW.vl_icms ELSE 0 END)-NEW.vl_pis-NEW.vl_cofins+NEW.vl_ii);

          --DEVOLUÇÃO DE ENTRADA LANÇA PELO CUSTO DA SAÍDA.
          IF (rTES.tipo = 'E' AND rTES.natureza = 'D') THEN
            vqtdestoque  = -vqtdestoque;
            vvalor       = -vvalor;
            rNF.tp_docto = 'S';
	      ELSIF (rTES.tipo = 'S' AND rTES.natureza = 'D') THEN
            vqtdestoque  = -vqtdestoque;
            vvalor       = -vvalor;
            rNF.tp_docto = 'E';
         END IF;

          FOR emp IN SELECT id_empresa FROM gestao.empresa WHERE id_empresa IN (videmp1,videmp2)
          LOOP
            IF rNF.especie_docto='' THEN
              rNF.especie_docto='NF';
            END IF;

            -- LANÇA MOVIMENTO
            IF vtp_mov_lote=1 or vtp_mov_lote=2 THEN
              vseq         = 0;  
              vorigem_lote = 'NFD#'||NEW.id_nfdet;
              FOR vlote IN select id_lote,qtd from gestao.lotemov where origem=vorigem_lote
              LOOP                        

                IF (rTES.tipo = 'E' AND rTES.natureza = 'D') THEN
                   vlote.qtd  = -vlote.qtd;
        	    ELSIF (rTES.tipo = 'S' AND rTES.natureza = 'D') THEN
                   vlote.qtd  = -vlote.qtd;
                END IF;   

                vseq = vseq+1;
                INSERT INTO gestao.estmovto(
                  id_empresa, id_estlocal, id_produto, variante, validade,
                  docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                  historico, tipo, qtdade, valor, vl_ajuste,
                  status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador, cod_tes,id_lote)
                  VALUES (emp.id_empresa, NEW.id_estlocal, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                  'F', SUBSTRING(rNF.especie_docto,1,3), rNF.serie, rNF.numero, COALESCE(rNF.dt_estoque,rNF.dt_emissao),
                  rNF.especie_docto||' # '||rNF.numero, rNF.tp_docto, vlote.qtd, vvalor , 0,
                  1, 'NF', NEW.id_nf, NEW.num_item, vseq, COALESCE(rNF.usuario_emissao,' '), rTes.codigo, vlote.id_lote);              
              END LOOP;
            ELSE
              INSERT INTO gestao.estmovto(
                id_empresa, id_estlocal, id_produto, variante, validade,
                docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                historico, tipo, qtdade, valor, vl_ajuste,
                status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador, cod_tes)
                VALUES (emp.id_empresa, NEW.id_estlocal, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                'F', SUBSTRING(rNF.especie_docto,1,3), rNF.serie, rNF.numero, COALESCE(rNF.dt_estoque,rNF.dt_emissao),
                rNF.especie_docto||' # '||rNF.numero, rNF.tp_docto, vqtdestoque, vvalor , 0,
                1, 'NF', NEW.id_nf, NEW.num_item, 0, COALESCE(rNF.usuario_emissao,' '), rTes.codigo);
                
              IF NEW.gerar_estoque='T' THEN
                    IF rNF.tp_docto='E' THEN
                      vtp_trx= 'S';
                    ELSE
                      vtp_trx= 'E';
                    END IF;
					
                    vvalor = (SELECT valor FROM gestao.estmovto WHERE origem_id=NEW.id_nf AND origem_prefixo='NF' AND origem_ordem=NEW.num_item AND origem_seq=0); 
					
                    -- LANÇA TRANSFERENCIA
                    INSERT INTO gestao.estmovto(
                      id_empresa, id_estlocal, id_produto, variante, validade,
                      docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                      historico, tipo, qtdade, valor, vl_ajuste,
                      status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador, cod_tes)
                      VALUES (emp.id_empresa, NEW.id_estlocal_trx, NEW.id_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                      'F', SUBSTRING(rNF.especie_docto,1,3), rNF.serie, rNF.numero, COALESCE(rNF.dt_estoque,rNF.dt_emissao),
                      rNF.especie_docto||' # '||rNF.numero, vtp_trx, vqtdestoque, vvalor, 0,
                      1, 'NF', NEW.id_nf, NEW.num_item, 1, COALESCE(rNF.usuario_emissao,' '), rTes.codigo);
              END IF;                
            END IF;    

          END LOOP;
        END IF;
      END IF;
      RETURN NEW;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.gera_estmovto_nfdet()
  OWNER TO postgres;
--RUN--


DROP TRIGGER gera_estmovto_nfdet ON gestao.nfdet;
--RUN--IGNORE ERRO

-- CRIA TRIGGER PARA ATUALIZAR SALDOS DO ESTOQUE
CREATE TRIGGER gera_estmovto_nfdet
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.nfdet
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.gera_estmovto_nfdet();
--RUN--

CREATE OR REPLACE FUNCTION gestao.atual_qtd_requisitada_opins()
  RETURNS "trigger" AS
$BODY$
    DECLARE vqtdade     NUMERIC(15,3);
            vtipo       smallint;
            vnumero_op  INT;
            vitem       INT;
	    vsitua      CHAR(1);

    BEGIN

        IF TG_OP='DELETE' THEN
          SELECT tipo,numero_op,situacao INTO vtipo,vnumero_op,vsitua FROM gestao.req WHERE id_req=OLD.id_req;
          IF vsitua='L' THEN
            IF vtipo=1 THEN
              UPDATE gestao.opins SET qtd_requisitada=qtd_requisitada-OLD.qtdade WHERE qtd_requisitada>=OLD.qtdade AND id_empresa=OLD.id_empresa AND numero_op=vnumero_op AND id_produto = OLD.id_produto;
            ELSE
              UPDATE gestao.opins SET qtd_requisitada=qtd_requisitada+OLD.qtdade WHERE id_empresa=OLD.id_empresa AND numero_op=vnumero_op AND id_produto = OLD.id_produto;
            END IF;
          END IF;  
        END IF;

        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          -- BUSCA TIPO E NUMERO DA OP NA REQ
          SELECT tipo,numero_op,situacao INTO vtipo,vnumero_op,vsitua FROM gestao.req WHERE id_req=NEW.id_req;

          IF vnumero_op IS NOT NULL THEN

            -- BUSCA QTDADE EM OUTRAS REQUISIÇÕES
            SELECT SUM(CASE WHEN B.tipo=1 THEN a.qtdade ELSE a.qtdade END) INTO vqtdade 
              FROM gestao.reqd A 
              LEFT OUTER JOIN gestao.req B ON (a.id_req=b.id_req)
              WHERE NOT A.id_reqd=NEW.id_reqd AND A.id_produto=NEW.id_produto AND B.id_empresa=NEW.id_empresa AND B.numero_op=vnumero_op AND B.situacao='L';

            IF vqtdade IS NULL THEN
              vqtdade = 0;
            END IF;

            IF vsitua='L' THEN
              IF vtipo=1 THEN
                vqtdade = vqtdade + NEW.qtdade;
              ELSE
                vqtdade = vqtdade - NEW.qtdade;
              END IF;
            END IF;

            -- ATUALIZA QTDADE REQUISITADA NA OPINS
			IF vqtdade>0 THEN
              UPDATE gestao.opins SET qtd_requisitada=vqtdade WHERE id_empresa=NEW.id_empresa AND numero_op=vnumero_op AND id_produto = NEW.id_produto;
			END IF;

            -- SE NÃO ENCONTRADO LANÇA NOVA NA OPINS            
            IF NOT FOUND AND vqtdade>0 THEN
              SELECT COALESCE(MAX(item),0)+1 INTO vitem FROM gestao.opins WHERE id_empresa=NEW.id_empresa AND numero_op=vnumero_op;
			  IF vitem<901 THEN
			    vitem=901;
			  END IF;
              
              INSERT INTO gestao.opins(id_empresa, numero_op, item, id_produto, qtd_und_prod, 
                          unidade, qtd_prevista, qtd_requisitada, inf_usuario)
              VALUES (NEW.id_empresa, vnumero_op, vitem, NEW.id_produto, 0, '', 0, vqtdade, 0);
            END IF;              
          END IF;
        END IF;

        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER atual_qtd_requisitada_opins ON gestao.reqd;
--RUN--IGNORE ERRO

CREATE TRIGGER atual_qtd_requisitada_opins
   AFTER INSERT OR UPDATE OR DELETE
   ON gestao.reqd FOR EACH ROW
   EXECUTE PROCEDURE gestao.atual_qtd_requisitada_opins();
--RUN--


DROP TRIGGER atual_qtd_requisitada_opins_after ON gestao.reqd;
--RUN--IGNORE ERRO

-- --------------------------------------------------------- --
--  FUNÇÃO PARA ATUALIZAR TABELA DE ESTOQUE EM/DE TERCEIROS  --
--  REVISADA POR JCS EM 19/01/2016 13:50
-- --------------------------------------------------------- --
CREATE OR REPLACE FUNCTION gestao.nfdet_controle_estterceiro()
  RETURNS trigger AS
$BODY$
    DECLARE
      vnf            RECORD;
      vtes           RECORD;
      vorigem        CHAR(20);
      vnum_remessa   INTEGER;
      vqtd_peca      INTEGER;
      vtamanho       INTEGER;
      p1             INTEGER;
      p2             INTEGER;
      p3             INTEGER;
      vqtd_perda     NUMERIC(15,3);
      vindic_prop    SMALLINT;

    BEGIN
      IF TG_OP='DELETE' THEN
        vorigem = 'NFDET'||OLD.id_nfdet;
        DELETE FROM gestao.estterceiro WHERE origem=vorigem;
        RETURN OLD;
      END IF;

      vorigem = 'NFDET'||NEW.id_nfdet;

      SELECT a.id_empresa, a.status, a.numero, a.dt_emissao, a.tp_docto, a.id_desrem, a.sistema, COALESCE(a.op_cancelada,'N') AS op_cancelada
        INTO vnf
        FROM gestao.nf A
        WHERE id_nf=NEW.id_nf;

      IF vnf.sistema='JCSFAT' OR vnf.sistema='JCSEM' OR vnf.sistema='JCSAVE' THEN
        SELECT poder_terc INTO vtes FROM gestao.tes WHERE id_tes=NEW.id_tes;
      ELSIF vnf.sistema IN('GERENTE','BALCAO') OR vnf.sistema='AUTOCOM'  THEN
        SELECT poder_terc INTO vtes FROM gestao.tes WHERE id_tes=NEW.id_tes;
      ELSIF vnf.sistema IS NULL THEN
         RETURN NEW;
      ELSE
        RAISE EXCEPTION 'Sistema (%) desconhecido!',vnf.sistema;
      END IF;

      -- SE CAMPO vtes.poder_terc É NULO SAI DA ROTINA
      IF vtes.poder_terc IS NULL THEN
        RETURN NEW;
      END IF;

      IF NOT (vnf.status IN ('L','V','T','E')) OR vtes.poder_terc NOT IN ('R','D') OR vnf.op_cancelada='S' THEN
        DELETE FROM gestao.estterceiro WHERE origem=vorigem;
        RETURN NEW;
      END IF;

      IF vtes.poder_terc='R' THEN
        IF NEW.id_produto IS NULL OR NEW.id_produto=0 THEN
          RAISE EXCEPTION 'Identificador do produto inválido!';
        END IF;

        p1=POSITION('mm ' IN  NEW.inf_adicionais);
        p2=POSITION(' x ' IN  NEW.inf_adicionais);
        p3=POSITION('pc' IN  NEW.inf_adicionais);

        IF p1>0 AND p2>0 AND p3>0 THEN
          vtamanho  = SUBSTRING(NEW.inf_adicionais,1,p1-1)::integer;
          vqtd_peca = SUBSTRING(NEW.inf_adicionais,p2+3,p3-p2-3)::integer;
        END IF;

        IF vnf.tp_docto='S' THEN          
          vindic_prop=1; --Item de propriedade do estabelecimento em posse de terceiros
        ELSE
          vindic_prop=2; --Item de propriedade de terceiros em posse do estabelecimento
        END IF; 

        IF (SELECT id_estterceiro FROM gestao.estterceiro WHERE origem=vorigem) IS NULL THEN
          SELECT max(num_remessa)+1 INTO vnum_remessa FROM gestao.estterceiro WHERE id_empresa=vnf.id_empresa;
          IF vnum_remessa IS NULL THEN
            vnum_remessa = 1;
          END IF;

          INSERT INTO gestao.estterceiro(
                      id_empresa, data, indic_prop, tipo, id_correntista,
                      cod_produto, variante, validade, docto, qtdade, valor, num_remessa,
                      qtd_saldo, usuario, origem, sistema, qtd_peca, tamanho, unidade)
              VALUES ( vnf.id_empresa, vnf.dt_emissao, vindic_prop, vtes.poder_terc, vnf.id_desrem,
                      NEW.id_produto, ' ', NULL, 'NF '||vnf.numero, NEW.qtd_comercial, (NEW.vl_total_bruto - NEW.vl_desconto), vnum_remessa,
                      NEW.qtd_comercial, 'SISTEMA', vorigem, vnf.sistema, vqtd_peca, COALESCE(vtamanho,0), NEW.und_comercial);
        ELSE
          UPDATE gestao.estterceiro
             SET id_empresa=vnf.id_empresa, data=vnf.dt_emissao, indic_prop=vindic_prop, tipo=vtes.poder_terc,
                 id_correntista=vnf.id_desrem, cod_produto=NEW.id_produto, variante=' ', validade=NULL, docto='NF '||vnf.numero,
                 qtdade=NEW.qtd_comercial, valor=(NEW.vl_total_bruto - NEW.vl_desconto), qtd_saldo=NEW.qtd_comercial, usuario='SISTEMA', qtd_peca=vqtd_peca, tamanho=COALESCE(vtamanho,0)
           WHERE origem=vorigem;
        END IF;

      ELSIF vtes.poder_terc='D' THEN
        IF NEW.id_produto IS NULL OR NEW.id_produto=0 THEN
          RAISE EXCEPTION 'Identificador do produto inválido!';
        END IF;
        IF NEW.num_rem_terc IS NULL OR NEW.num_rem_terc=0 THEN
		  --ALTERADO POR JCS EM 02/02/2017 - DUVIDAS PERGUNTAR (ALUMASA)
          --RAISE EXCEPTION 'Número da remessa do estoque terceiro é inválida!';
          DELETE FROM gestao.estterceiro WHERE origem=vorigem;
          RETURN NEW;
        END IF;

        IF (SELECT id_estterceiro FROM gestao.estterceiro WHERE origem=vorigem) IS NOT NULL THEN
          DELETE FROM gestao.estterceiro WHERE origem=vorigem;
        END IF;

        IF NEW.cfop%1000=903 THEN
          vqtd_perda = NEW.qtd_comercial;
        ELSE
          vqtd_perda = 0;
        END IF;

        IF vnf.tp_docto='S' THEN
          vindic_prop=2; --Item de propriedade de terceiros em posse do estabelecimento
        ELSE
          vindic_prop=1; --Item de propriedade do estabelecimento em posse de terceiros          
        END IF; 

        INSERT INTO gestao.estterceiro(
                    id_empresa, data, indic_prop, tipo, id_correntista,
                    cod_produto, variante, validade, docto, qtdade, valor, num_remessa,
                    qtd_saldo, usuario, origem, sistema, qtd_peca, tamanho, unidade, qtd_perda_proc)
            VALUES ( vnf.id_empresa, vnf.dt_emissao, vindic_prop, vtes.poder_terc, vnf.id_desrem,
                    NEW.id_produto, ' ', NULL, 'NF '||vnf.numero, NEW.qtd_comercial, (NEW.vl_total_bruto - NEW.vl_desconto), NEW.num_rem_terc,
                    0, 'SISTEMA', vorigem, vnf.sistema, vqtd_peca, COALESCE(vtamanho,0), NEW.und_comercial, vqtd_perda);

      END IF;
      RETURN NEW;

    END;
$BODY$
  LANGUAGE 'plpgsql';
--RUN--

DROP TRIGGER nfdet_controle_estterceiro ON gestao.nfdet;
--RUN--IGNORE ERRO

CREATE TRIGGER nfdet_controle_estterceiro
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.nfdet
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.nfdet_controle_estterceiro();
--RUN--

-------------------------------------------------------------
-- REVISADO POR JCS EM 22/04/2014 AS 17:02                 -- 
-- VALIDAÇÕES ITEMDOCTO                                    --
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.valida_itemdocto()
  RETURNS "trigger" AS
$BODY$
    DECLARE voperacao  CHAR(1);
            vdata      DATE;
            vobs       TEXT;
	    vcst_icms  INTEGER;

    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN

          IF NEW.id_entsiscon IS NOT NULL THEN
            voperacao='E';
            SELECT dtent,TRIM(obs) INTO vdata,vobs FROM siscon.entradas WHERE id_entrada=NEW.id_entsiscon;
          END IF;         

          IF NEW.id_saisiscon IS NOT NULL THEN
            voperacao='S';
            SELECT dtdoc,TRIM(obs) INTO vdata,vobs FROM siscon.saidas WHERE id_saida=NEW.id_saisiscon;
          END IF;        

	  NEW.unidade = upper(NEW.unidade);

          -- VALIDADÇÃO DO CST SOMENTE A PARTIR DE JANEIRO/2009
          IF vdata>='2009-01-01' AND NOT vobs='*IMPXML*' THEN

	          IF TG_OP='UPDATE' THEN
		    vcst_icms = OLD.cst_icms;
		  ELSE
		    vcst_icms = -1;
		  END IF;

		  -- VALIDA CST ICMS (SOMENTE SE MUDOU)
		  IF NOT NEW.cst_icms=vcst_icms THEN
		    IF NEW.cst_icms<100 THEN
  		      IF (SELECT id_cst FROM gestao.cst 
		           WHERE tributo='ICMS'  AND tp_operacao IN (voperacao,'A') AND codigo=TO_CHAR(NEW.cst_icms,'FM09') AND dt1<=vdata AND (dt2 IS NULL or dt2>=vdata)) IS NULL THEN
		        RAISE EXCEPTION 'CST do ICMS (%) inválido para operação (%)!',TO_CHAR(NEW.cst_icms,'FM09'),voperacao;
                      END IF;
		    ELSE
		      IF (SELECT id_cst FROM gestao.cst 
	  		 WHERE tributo='SIMPLES'  AND tp_operacao IN (voperacao,'A') AND codigo=TO_CHAR(NEW.cst_icms,'FM009') AND dt1<=vdata AND (dt2 IS NULL or dt2>=vdata)) IS NULL THEN
		        RAISE EXCEPTION 'CSOSN (%) inválido para operação (%)!',TO_CHAR(NEW.cst_icms,'FM009'),voperacao;
		     END IF;                	  		  
		    END IF;
		  END IF;

		  -- VALIDA CST IPI
		  IF NEW.cst_ipi='NA' THEN
			NEW.cst_ipi='  ';
		  ELSIF NOT NEW.cst_ipi='  ' THEN
			IF (SELECT id_cst FROM gestao.cst
				 WHERE tributo='IPI'  AND tp_operacao IN (voperacao,'A') AND codigo=NEW.cst_ipi AND dt1<=vdata AND (dt2 IS NULL or dt2>=vdata)) IS NULL THEN
			  RAISE EXCEPTION 'CST do IPI (%) inválido para operação (%)!',NEW.cst_ipi,voperacao;
			END IF;
		  END IF;

		  -- VALIDA CST PIS
		  IF NOT NEW.cst_pis='  ' THEN
  		    IF (SELECT id_cst FROM gestao.cst 
		         WHERE tributo='PIS'  AND tp_operacao IN (voperacao,'A') AND codigo=NEW.cst_pis AND dt1<=vdata AND (dt2 IS NULL or dt2>=vdata)) IS NULL THEN
		      RAISE EXCEPTION 'CST do PIS (%) inválido para operação (%)!',NEW.cst_pis,voperacao;
		    END IF;
		  END IF;

		  -- VALIDA CST COFINS
		  IF NOT NEW.cst_cofins='  ' THEN
  		    IF (SELECT id_cst FROM gestao.cst 
		         WHERE tributo='COFINS'  AND tp_operacao IN (voperacao,'A') AND codigo=NEW.cst_cofins AND dt1<=vdata AND (dt2 IS NULL or dt2>=vdata)) IS NULL THEN
		      RAISE EXCEPTION 'CST do COFINS (%) inválido para operação (%)!',NEW.cst_cofins,voperacao;
		    END IF;
		  END IF;
	  END IF;

	  IF NEW.cst_pis IN ('70','71','72','73','74','75') AND (NEW.vl_pis>0 OR NEW.bc_pis>0) THEN
            RAISE EXCEPTION 'Base de Cálculo e/ou Valor do PIS não deve ser informado para o CST "%"!',NEW.cst_pis;
	  END IF;

	  IF NEW.cst_cofins IN ('70','71','72','73','74','75') AND (NEW.vl_cofins>0 OR NEW.bc_cofins>0) THEN
            RAISE EXCEPTION 'Base de Cálculo e/ou Valor do COFINS não deve ser informado para o CST "%"!',NEW.cst_cofins;
	  END IF;

        END IF;	
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_itemdocto ON gestao.itemdocto;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_itemdocto
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.itemdocto
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_itemdocto();
--RUN--

-- --------------------------------------------------------- --
--  FUNÇÃO PARA LANÇAR ESTMOVTO DA PRODUCAO         
--  REVISADA POR JCS EM 17/07/2025 15:11                    
-- --------------------------------------------------------- --
CREATE OR REPLACE FUNCTION gestao.gera_estmovto_producao()
  RETURNS trigger AS
$BODY$
    DECLARE
      vqtd             NUMERIC(15,3);
      vvalor           NUMERIC(15,2);
      vid_produto      INT;
      vid_estlocal     INT;
      vlixo            INT;
      vcusto_rep       NUMERIC(15,6);
      vlote            int;
      vorigem_lote     character varying (20);
      vorigem_lote_tmp character varying (20);
      vid_emp_prod     int;
      vtp_mov_lote     int;
      vid_emp_cstpadrao int;
      

    BEGIN
      IF TG_OP='DELETE' THEN
        DELETE FROM gestao.estmovto WHERE origem_prefixo='PRO' AND origem_id=OLD.id_producao;
        RETURN OLD;
      ELSIF TG_OP='UPDATE' THEN
        DELETE FROM gestao.estmovto WHERE origem_prefixo='PRO' AND origem_id=OLD.id_producao;
      END IF;

      IF NEW.id_varprod=0 OR NEW.id_varprod IS NULL THEN
        vid_produto = NEW.id_produto;
      ELSE
        vid_produto = NEW.id_varprod;
      END IF;

      IF TG_OP='INSERT' THEN
        -- ATUALIZA LOTE TEMPORARIO
        vorigem_lote_tmp = 'PRO#'||NEW.id_produto||NEW.hora;
        vorigem_lote     = 'PROD#'||NEW.id_producao;
        UPDATE gestao.lotemov SET origem=vorigem_lote WHERE origem=vorigem_lote_tmp;
      END IF;
      
      IF NEW.tipo=1 THEN
        vqtd=NEW.qtd;
      ELSIF NEW.tipo=2 THEN
        vqtd=-NEW.qtd;
      END IF;

      IF NEW.custo_total=0 OR NEW.custo_total IS NULL THEN
        vid_emp_cstpadrao = (SELECT id_empresa_tabcomp FROM gestao.tabcomp WHERE nome_tabcomp='cstpadrao' AND id_empresa=NEW.id_empresa AND id_empresa_tabcomp>0);
        SELECT valor INTO vcusto_rep FROM gestao.cstpadrao WHERE id_empresa=COALESCE(vid_emp_cstpadrao,NEW.id_empresa) AND id_produto=vid_produto AND data<=NEW.data ORDER BY data DESC LIMIT 1;
        vvalor = vqtd * vcusto_rep;
        IF vvalor IS NULL THEN
          vvalor = 0;
        END IF;
      ELSE
        vvalor = NEW.custo_total;
      END IF;

      IF NEW.id_prodbalanca=0 THEN
          NEW.id_prodbalanca = NULL;
      END IF;

      -- BLOQUEIO TABELA EMPRESAS PARA ATUALIZAÇÃO - POR JCS EM 08/04/3013 13:54
      SELECT 1 INTO vlixo FROM gestao.empresa x WHERE id_empresa IN (NEW.id_empresa,NEW.id_empresa-9000) FOR SHARE OF x;

      -- BUSCA ID EMPRESA DO PRODUTO
      vid_emp_prod = 0;
      SELECT id_empresa_tabcomp INTO vid_emp_prod FROM gestao.tabcomp WHERE nome_tabcomp='produtos' AND id_empresa=NEW.id_empresa;
      IF vid_emp_prod IS NULL OR vid_emp_prod=0 THEN
        vid_emp_prod = NEW.id_empresa;
      END IF;

      -- VERIFICA TIPO MOVIMENTO DO LOTE
      SELECT lote INTO vtp_mov_lote FROM gestao.produto WHERE id_erp=NEW.id_produto and id_empresa=vid_emp_prod;
      IF vtp_mov_lote IS NULL THEN
        vtp_mov_lote=0;
      END IF;

     IF vtp_mov_lote=1 or vtp_mov_lote=2 THEN
        -- VERIFICA SE TEM LOTE
        vorigem_lote     = 'PROD#'||NEW.id_producao;
        SELECT id_lote INTO vlote from gestao.lotemov where origem=vorigem_lote;
        IF vlote IS NULL OR vlote=0 THEN
          RAISE EXCEPTION 'Lote do Produto (%) não foi Encontrado!',NEW.id_produto;
        END IF;
      ELSE
        vlote = 0;
      END IF;

      
      IF (NEW.id_empresa>9000 AND NEW.status IN (0,1,3)) OR (NEW.id_empresa<9000 AND NEW.status IN (0,1,2)) THEN

        IF vlote>0 THEN
              INSERT INTO gestao.estmovto(
                          id_empresa, id_estlocal, id_produto, variante, validade,
                          docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                          historico, tipo, qtdade, valor, vl_ajuste, operador,
                          status, origem_prefixo, origem_id, origem_ordem, origem_seq,id_lote)
                  VALUES (NEW.id_empresa, NEW.id_estlocal, vid_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                          'I', 'PRO', '', NEW.numero, NEW.data,
                          'Produção # '||NEW.numero||' Turno: '||NEW.turno||' Maq: '||COALESCE(NEW.cod_maq,''), 'E', vqtd, vvalor,0 , NEW.usuario,
                          1, 'PRO', NEW.id_producao, 0, 0,vlote);        
        ELSE      
              INSERT INTO gestao.estmovto(
                          id_empresa, id_estlocal, id_produto, variante, validade,
                          docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                          historico, tipo, qtdade, valor, vl_ajuste, operador,
                          status, origem_prefixo, origem_id, origem_ordem, origem_seq)
                  VALUES (NEW.id_empresa, NEW.id_estlocal, vid_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                          'I', 'PRO', '', NEW.numero, NEW.data,
                          'Produção # '||NEW.numero||' Turno: '||NEW.turno||' Maq: '||COALESCE(NEW.cod_maq,''), 'E', vqtd, vvalor,0 , NEW.usuario,
                          1, 'PRO', NEW.id_producao, 0, 0);
        END IF;                 
      END IF;

      IF NEW.id_empresa>9000 AND NEW.status IN (0,1,2) THEN
        IF vlote>0 THEN      
              INSERT INTO gestao.estmovto(
                          id_empresa, id_estlocal, id_produto, variante, validade,
                          docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                          historico, tipo, qtdade, valor, vl_ajuste, operador,
                          status, origem_prefixo, origem_id, origem_ordem, origem_seq,id_lote)
                  VALUES (NEW.id_empresa-9000, NEW.id_estlocal, vid_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                          'I', 'PRO', '', NEW.numero, NEW.data,
                          'Produção # '||NEW.numero||' Turno: '||NEW.turno||' Maq: '||COALESCE(NEW.cod_maq,''), 'E', vqtd, vvalor,0 , NEW.usuario,
                          1, 'PRO', NEW.id_producao, 0, 0,vlote);        
        ELSE
              INSERT INTO gestao.estmovto(
                          id_empresa, id_estlocal, id_produto, variante, validade,
                          docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                          historico, tipo, qtdade, valor, vl_ajuste, operador,
                          status, origem_prefixo, origem_id, origem_ordem, origem_seq)
                  VALUES (NEW.id_empresa-9000, NEW.id_estlocal, vid_produto, NEW.variante, COALESCE(NEW.validade::char(10),' '),
                          'I', 'PRO', '', NEW.numero, NEW.data,
                          'Produção # '||NEW.numero||' Turno: '||NEW.turno||' Maq: '||COALESCE(NEW.cod_maq,''), 'E', vqtd, vvalor,0 , NEW.usuario,
                          1, 'PRO', NEW.id_producao, 0, 0);
        END IF;
      END IF;


      RETURN NEW;
    END;

$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER gera_estmovto_producao ON gestao.producao;

--RUN--IGNORE ERRO

-- CRIA TRIGGER PARA ATUALIZAR SALDOS DO ESTOQUE
CREATE TRIGGER gera_estmovto_producao
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.producao  FOR EACH ROW
  EXECUTE PROCEDURE gestao.gera_estmovto_producao();
--RUN--

CREATE OR REPLACE FUNCTION gestao.lanca_empenho_opins_estmovto()
  RETURNS trigger AS
$BODY$
    DECLARE vqtdade      NUMERIC(15,3);
            vsituacao    smallint;
            vfluxo_continuo smallint;
            vid_estlocal integer;
            vdata        DATE;
            vvariante    char(10);
            vid_emp_prod int;
            vtp_mov_lote int;
            vsaldo_lote  record;
            vqtd_lote    numeric (15,3);
            vqtd_emp     numeric (15,3);
            vqtd_disp    numeric (15,3);
            vseq         int;

    BEGIN
        IF TG_OP='DELETE' OR TG_OP='UPDATE' THEN
          -- EXCLUIR MOIMENTO DO ESTOQUE ANTES DE LANÇAR NOVAMENTE
          DELETE FROM gestao.estmovto WHERE origem_prefixo='OPI' AND origem_id=OLD.id_opins;
        END IF;

        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
		
		
          IF NEW.id_op2=0 THEN
             NEW.id_op2 = NULL;
          END IF;
		
          -- BUSCA ID EMPRESA DO PRODUTO
          vid_emp_prod = 0;
          SELECT id_empresa_tabcomp INTO vid_emp_prod FROM gestao.tabcomp WHERE nome_tabcomp='produtos' AND id_empresa=NEW.id_empresa;
          IF vid_emp_prod IS NULL OR vid_emp_prod=0 THEN
            vid_emp_prod = NEW.id_empresa;
          END IF;

          -- DEFINE LOCAL DO ESTOQUE
          vid_estlocal = NEW.id_estlocal;
          IF vid_estlocal IS NULL OR vid_estlocal=0 THEN
            --SELECT cod_estlocal INTO vid_estlocal FROM gestao.produto WHERE id_erp=NEW.id_produto AND id_empresa IN (NEW.id_empresa,NEW.id_empresa-9000);
            SELECT cod_estlocal INTO vid_estlocal FROM gestao.produto WHERE id_erp=NEW.id_produto AND id_empresa=vid_emp_prod;
          END IF;
          IF vid_estlocal IS NULL THEN
            vid_estlocal = 1;
          END IF;

          -- VERIFICA TIPO MOVIMENTO DO LOTE
          SELECT lote INTO vtp_mov_lote FROM gestao.produto WHERE id_erp=NEW.id_produto and id_empresa=vid_emp_prod;
          IF vtp_mov_lote IS NULL THEN
            vtp_mov_lote=0;
          END IF;

          -- BUSCA SITUACAO DA OP
          SELECT situacao,data,COALESCE(fluxo_continuo,0) INTO vsituacao,vdata,vfluxo_continuo FROM gestao.op WHERE id_empresa=NEW.id_empresa AND numero=NEW.numero_op;

          IF substring(NEW.unidade,1,2) IN ('BR','B1') AND length(trim(NEW.unidade))=6 THEN
            vvariante = 'UND:'||NEW.unidade;
          ELSE
            vvariante = '';
          END IF;

          -- ESTOQUE DISPONIVEL
          vqtd_disp  = (SELECT sum(qtdade-qtd_empenhada) FROM gestao.estsaldo WHERE id_empresa=NEW.id_empresa AND id_produto=NEW.id_produto and id_estlocal=vid_estlocal and variante=vvariante);
		  --vqtd_disp  = (SELECT sum(qtdade-qtd_empenhada+qtd_op) FROM gestao.estsaldo WHERE id_empresa=NEW.id_empresa AND id_produto=NEW.id_produto and id_estlocal=vid_estlocal and variante=vvariante);
          IF vqtd_disp IS NULL THEN
             vqtd_disp=0;
          END IF;   
		  

          -- CALCULA QTDADE PARA EMPENHO
          vqtdade = NEW.qtd_prevista - NEW.qtd_requisitada;

          IF vqtdade>vqtd_disp THEN
            vqtdade = vqtd_disp;
          END IF;

          -- EMPENHA ESTOQUE SE QTDADE FOR POSITIVA E SITUACAO = PENDENTE EMITIDA OU EM PRODUCAO
          IF vqtdade>0 AND vsituacao IN (1,2) AND vfluxo_continuo=0 THEN
            IF substring(NEW.unidade,1,2) IN ('BR','B1') AND length(trim(NEW.unidade))=6 THEN
              vvariante = 'UND:'||NEW.unidade;
            ELSE
              vvariante = '';
            END IF;
            NEW.qtd_empenhada = vqtdade;

            IF vtp_mov_lote=1 or vtp_mov_lote=2 THEN
              vqtd_emp = 0;
              vseq     = 0;
              FOR vsaldo_lote IN SELECT a.id_lote as id_lote,(a.qtdade-a.qtd_empenhada) AS qtd FROM gestao.estsaldo A
                                   LEFT OUTER JOIN gestao.lote B ON (b.id_lote=a.id_lote AND a.id_produto=b.id_produto)
                                   WHERE a.id_empresa=NEW.id_empresa AND a.id_estlocal=vid_estlocal AND a.id_produto=NEW.id_produto AND a.id_lote>0
                                   ORDER BY b.dt_validade
              LOOP
                IF vqtd_emp = vqtdade THEN
                  RETURN NEW;
                END IF;
                vseq = vseq + 1;

                vqtd_lote = vqtdade - vqtd_emp;
                IF vsaldo_lote.qtd>=vqtd_lote THEN
                  vqtd_lote = vqtd_lote;
                ELSE
                  vqtd_lote = vsaldo_lote.qtd;
                END IF;
                vqtd_emp = vqtd_emp + vqtd_lote;

                INSERT INTO gestao.estmovto(
                           id_empresa, id_estlocal, id_produto, docto_natureza,
                           docto_tipo, docto_serie, docto_numero, data, historico, tipo,
                           qtdade, valor, vl_ajuste, custo_medio, operador, status, origem_prefixo,
                           origem_id, origem_ordem, origem_seq, variante, validade,id_lote)
                 VALUES   (NEW.id_empresa, vid_estlocal, NEW.id_produto,'I',
                          'OP','', NEW.numero_op, vdata,'Insumo OP # '|| NEW.numero_op, 'M',
                          vqtd_lote, 0, 0, 0, '', 1, 'OPI',
                          NEW.id_opins, 1, vseq,vvariante,'',vsaldo_lote.id_lote);

              END LOOP;
            ELSE
              INSERT INTO gestao.estmovto(
                          id_empresa, id_estlocal, id_produto, docto_natureza,
                          docto_tipo, docto_serie, docto_numero, data, historico, tipo,
                          qtdade, valor, vl_ajuste, custo_medio, operador, status, origem_prefixo,
                          origem_id, origem_ordem, origem_seq, variante, validade)
                 VALUES  (NEW.id_empresa, vid_estlocal, NEW.id_produto,'I',
                         'OP','', NEW.numero_op, vdata,'Insumo OP # '|| NEW.numero_op, 'M',
                         vqtdade, 0, 0, 0, '', 1, 'OPI',
                         NEW.id_opins, 1, 0,vvariante,'');
            END IF;
          ELSE
            NEW.qtd_empenhada = 0;
            DELETE FROM gestao.estmovto WHERE origem_prefixo='OPI' AND origem_id=NEW.id_opins;
          END IF;

        END IF;

        IF TG_OP='DELETE' THEN
          DELETE FROM gestao.estmovto WHERE origem_prefixo='OPI' AND origem_id=OLD.id_opins;
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.lanca_empenho_opins_estmovto()
  OWNER TO postgres;
--RUN--

DROP TRIGGER lanca_empenho_opins_estmovto ON gestao.opins;
--RUN--IGNORE ERRO

CREATE TRIGGER lanca_empenho_opins_estmovto BEFORE INSERT OR UPDATE OR DELETE
   ON gestao.opins FOR EACH ROW
   EXECUTE PROCEDURE gestao.lanca_empenho_opins_estmovto();
--RUN--

CREATE OR REPLACE FUNCTION gestao.atual_situacao_ocd()
  RETURNS trigger AS
$BODY$
    DECLARE vsituacao     char(1);
            vsitorig      char(1);
            voc_recebida  smallint;
            vqtd          integer;
            vnumoc        integer;
            vid_empresa   integer;
            vnumero       integer;
            vqtd_comprada numeric(12,4);
            vvar_qtd      numeric(5,2);

    BEGIN

        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN

          IF NEW.id_pcpmaq=0 THEN
             NEW.id_pcpmaq = NULL;
          END IF;

          -- BUSCA SITUACAO DA OC
          SELECT situacao,oc_recebida INTO vsituacao,voc_recebida FROM gestao.oc WHERE id_oc=NEW.id_oc;
          vsitorig = vsituacao;

          -- AJUSTE ARREDONTAMENTO
          IF (NEW.qtd_cancelada+NEW.qtd_recebida)-NEW.qtd_comprada=0.001 THEN
            NEW.qtd_recebida = NEW.qtd_recebida-0.001;
          END IF;

          -- BUSCA PERCENTUAL DE VARIAÇÃO DA QUANTIDADE NA OC
	  select d.var_qtd_oc INTO vvar_qtd from gestao.oc as a
	  left outer join gestao.tabcomp as b ON(b.id_empresa=a.id_empresa AND b.nome_tabcomp='produtos')
	  left outer join gestao.produto as c ON((CASE WHEN b.id_empresa>0 THEN b.id_empresa ELSE a.id_empresa END=a.id_empresa) and c.id_erp=NEW.id_produto)
	  left outer join gestao.produto1 as d ON(d.id_produto=c.id_produto)
	  where a.id_oc=NEW.id_oc and d.var_qtd_oc>0;

          if vvar_qtd is null then
            vvar_qtd=0;
          end if;

          if vvar_qtd>0 then
            vqtd_comprada=NEW.qtd_comprada+((NEW.qtd_comprada*vvar_qtd)/100);
          else
            vqtd_comprada=NEW.qtd_comprada;
          end if;

          -- CONFERE SE QTDADE CANCELADA+QTDADE RECEBIDA NÃO É MAIOR QUE QTD COMPRADA
          --IF NEW.qtd_cancelada+NEW.qtd_recebida>NEW.qtd_comprada THEN
          IF NEW.qtd_cancelada+NEW.qtd_recebida>vqtd_comprada THEN
            --RAISE EXCEPTION 'Qtdade cancelada (%) + qtdade recebida (%) é maior que qtdade comprada (%). Operação cancelada!',NEW.qtd_cancelada,NEW.qtd_recebida,NEW.qtd_comprada;
            RAISE EXCEPTION 'Qtdade cancelada (%) + qtdade recebida (%) é maior que qtdade comprada (%). Operação cancelada!',NEW.qtd_cancelada,NEW.qtd_recebida,vqtd_comprada;
          ELSIF NEW.qtd_cancelada>NEW.qtd_comprada THEN
            RAISE EXCEPTION 'Qtdade cancelada (%) é maior que qtdade comprada (%). Operação cancelada!',NEW.qtd_cancelada,NEW.qtd_comprada;          
          -- CONFERE SE QTDADE CANCELADA TOTAL
          ELSIF NEW.qtd_cancelada=NEW.qtd_comprada THEN
          --ELSIF (not vvar_qtd>0 and NEW.qtd_cancelada=NEW.qtd_comprada) or (vvar_qtd>0 and NEW.qtd_cancelada>=NEW.qtd_comprada and NEW.qtd_cancelada<=vqtd_comprada) THEN
            NEW.situacao='C';
            --CONSULTA SITUACAO DAS OUTRAS ITENS DA OC
            SELECT COUNT(*) INTO vqtd FROM gestao.ocd WHERE NOT situacao='C' AND id_oc=NEW.id_oc AND NOT id_ocd=NEW.id_ocd;
            IF vqtd=0 THEN
              vsituacao='C';
            ELSE
              SELECT COUNT(*) INTO vqtd FROM gestao.ocd WHERE NOT situacao IN ('C','R') AND id_oc=NEW.id_oc AND NOT id_ocd=NEW.id_ocd;
              IF vqtd=0 THEN
                vsituacao='R';
              END IF;
            END IF;
          -- CONFERE SE RECEBIDA TOTAL
          --ELSIF NEW.qtd_cancelada+NEW.qtd_recebida=NEW.qtd_comprada THEN          
          ELSIF (not vvar_qtd>0 and NEW.qtd_cancelada+NEW.qtd_recebida=NEW.qtd_comprada) or (vvar_qtd>0 and NEW.qtd_cancelada+NEW.qtd_recebida>=NEW.qtd_comprada and NEW.qtd_cancelada+NEW.qtd_recebida<=vqtd_comprada) THEN
            NEW.situacao='R';
            --CONSULTA SITUACAO DAS OUTRAS ITENS DA OC
            SELECT COUNT(*) INTO vqtd FROM gestao.ocd WHERE NOT situacao IN ('C','R') AND id_oc=NEW.id_oc AND NOT id_ocd=NEW.id_ocd;
            IF vqtd=0 OR vqtd IS NULL THEN
              vsituacao='R';
            ELSIF (SELECT COUNT(*) FROM gestao.ocd WHERE situacao='A' AND id_oc=NEW.id_oc AND NOT id_ocd=NEW.id_ocd)>0 THEN
              vsituacao='A';
            END IF;
          --CONFERE SE RECEBIDA PARCIAL
          ELSIF NEW.qtd_recebida>0 AND NEW.qtd_cancelada+NEW.qtd_recebida<NEW.qtd_comprada THEN
            NEW.situacao='A';
            vsituacao='A';
          ELSE
            IF vsituacao IN ('C','R','A','Z') THEN
              vsituacao='E';
            END IF;
            NEW.situacao=vsituacao;
          END IF;

          -- força situação para já recebida - por JCS em 12/01/2017 as 15:00
          IF voc_recebida=1 THEN
            NEW.situacao ='R';
            vsituacao    ='R';
          ELSE
            IF NEW.situacao='C' AND (SELECT COUNT(*) FROM gestao.ocd WHERE situacao NOT IN  ('C') AND id_oc=NEW.id_oc AND NOT id_ocd=NEW.id_ocd)=0 THEN
              vsituacao = 'C';
            END IF;
            IF NEW.situacao='A'THEN
              vsituacao = 'A';
            END IF;
            IF NEW.situacao='R' AND (SELECT COUNT(*) FROM gestao.ocd WHERE situacao NOT IN ('C','R') AND id_oc=NEW.id_oc AND NOT id_ocd=NEW.id_ocd)=0 THEN
              vsituacao = 'R';
            END IF;
            IF NEW.situacao='R' AND (SELECT COUNT(*) FROM gestao.ocd WHERE situacao NOT IN ('C','R') AND id_oc=NEW.id_oc AND NOT id_ocd=NEW.id_ocd)>0 THEN
              vsituacao = 'A';
            END IF;
            IF NEW.situacao='E' AND (SELECT COUNT(*) FROM gestao.ocd WHERE situacao IN ('R','A') AND id_oc=NEW.id_oc AND NOT id_ocd=NEW.id_ocd)>0 THEN
              vsituacao = 'A';
            END IF;
            IF NEW.situacao IN ('P','L','E') AND (SELECT COUNT(*) FROM gestao.ocd WHERE situacao IN ('R','A') AND id_oc=NEW.id_oc AND NOT id_ocd=NEW.id_ocd)=0 THEN
              if vsitorig IN ('P','L','E') THEN
                     vsituacao = vsitorig;
              ELSE
                vsituacao = 'E';
              END IF;
            END IF;


          END IF;


          --ATUALIZA SITUACAO NA OC
          IF NOT vsitorig=vsituacao THEN
            UPDATE gestao.oc SET situacao=vsituacao WHERE id_oc=NEW.id_oc;
          END IF;
        END IF;

        --- VERIFICA LANÇAMENTO EM ENTRADA
        IF TG_OP='DELETE' THEN
          SELECT id_empresa,numero INTO vid_empresa,vnumoc FROM gestao.oc WHERE id_oc=OLD.id_oc;
          vnumero = (SELECT b.numero FROM gestao.entradet A
                     LEFT OUTER JOIN gestao.entradas B ON (a.id_entrada=b.id_entrada)
                     WHERE a.num_oc=vnumoc AND a.item_oc=OLD.item AND b.id_empresa=vid_empresa LIMIT 1);
          IF vnumero IS NOT NULL THEN
            RAISE EXCEPTION 'Item % da OC % já lançado na NF de Entrada %!',OLD.item,vnumoc,vnumero;
          END IF;
        END IF;

        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE COST 100;
ALTER FUNCTION gestao.atual_situacao_ocd() OWNER TO postgres;
--RUN--

DROP TRIGGER atual_situacao_ocd ON gestao.ocd;
--RUN--IGNORE ERRO

CREATE TRIGGER atual_situacao_ocd BEFORE INSERT OR UPDATE OR DELETE
   ON gestao.ocd FOR EACH ROW
   EXECUTE PROCEDURE gestao.atual_situacao_ocd();
--RUN--


CREATE OR REPLACE FUNCTION gestao.bloq_alteracao_req()
  RETURNS "trigger" AS
$BODY$

    BEGIN
      IF NOT NEW.id_empresa=OLD.id_empresa THEN
        RAISE EXCEPTION 'Não pode alterar empresa!';
      ELSIF NOT NEW.numero=OLD.numero THEN
        RAISE EXCEPTION 'Não pode alterar número!';
      ELSIF NOT NEW.tipo=OLD.tipo THEN
        RAISE EXCEPTION 'Não pode alterar tipo!';
      ELSIF NOT NEW.numero_op=OLD.numero_op THEN
        RAISE EXCEPTION 'Não pode alterar número ordem de produção!';
      END IF;

      RETURN NEW;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER bloq_alteracao_req ON gestao.req;
--RUN--IGNORE ERRO

CREATE TRIGGER bloq_alteracao_req
   BEFORE UPDATE
   ON gestao.req FOR EACH ROW
   EXECUTE PROCEDURE gestao.bloq_alteracao_req();
--RUN--


CREATE OR REPLACE FUNCTION gestao.alteracao_situacao_op()
  RETURNS "trigger" AS
$BODY$
    BEGIN      
      IF NEW.situacao=5 THEN -- QUANDO SITUACAO=5 (CANCELADA) EXCLUI OPINS
        DELETE FROM gestao.opins WHERE id_empresa=NEW.id_empresa AND numero_op=NEW.numero;
      ELSIF NOT NEW.situacao=OLD.situacao THEN -- QUANDO ALTERAR SITUACAO DISPARA TRIGGER OPSINS P/ATUALIZAR EMPENHOS
        UPDATE gestao.opins SET qtd_prevista=qtd_prevista WHERE id_empresa=NEW.id_empresa AND numero_op=NEW.numero;
      END IF;
      RETURN NEW;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER alteracao_situacao_op ON gestao.op;
--RUN--IGNORE ERRO

CREATE TRIGGER alteracao_situacao_op
   AFTER UPDATE
   ON gestao.op FOR EACH ROW
   EXECUTE PROCEDURE gestao.alteracao_situacao_op();
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_nfdetmed()
  RETURNS "trigger" AS
$BODY$
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          --REMOVE ACENTOS E OUTROS CARACTERES FORA DO ASCII
          NEW.num_lote		= TRIM(TO_ASCII(NEW.num_lote));
        END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_nfdetmed ON gestao.nfdetmed;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_nfdetmed
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.nfdetmed
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_nfdetmed();
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_nfendereco()
  RETURNS "trigger" AS
$BODY$
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          --REMOVE ACENTOS E OUTROS CARACTERES FORA DO ASCII
	  NEW.logradouro	= TRIM(TO_ASCII(NEW.logradouro));
	  NEW.numero		= TRIM(TO_ASCII(NEW.numero));
	  NEW.complemento	= TRIM(TO_ASCII(NEW.complemento));
	  NEW.bairro		= TRIM(TO_ASCII(NEW.bairro));
	  NEW.nome_municipio	= TRIM(TO_ASCII(NEW.nome_municipio));
	  NEW.nome_pais		= TRIM(TO_ASCII(NEW.nome_pais));

	  -- VALIDAÇÃO DE CAMPOS
	  IF length(NEW.numero)=0 THEN
	    RAISE EXCEPTION 'Número do endereço não pode ser brancos!';
	  END IF;
	  IF length(NEW.bairro)=0 THEN
	    RAISE EXCEPTION 'Bairro do endereço não pode ser brancos!';
	  END IF;
	  IF NEW.tipo IN ('E','D') THEN
            IF NOT length(NEW.cep::text)=8 AND NOT length(NEW.cep::text)=7 AND NOT NEW.uf='EX' THEN
	      RAISE EXCEPTION 'CEP (%) do endereço tem que ter sete ou oito posições!', NEW.cep::text;
	    END IF;
	  END IF;
	  IF NEW.tipo IN ('N','R') THEN
            IF (length(TRIM(NEW.cnpj))=0 OR NEW.cnpj IS NULL) AND (length(TRIM(NEW.cpf))=0 OR NEW.cpf IS NULL) THEN
	      RAISE EXCEPTION 'CNPJ/CPF do endereço não pode ser brancos!';
	    END IF;
	  END IF;	  
	  
        END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_nfendereco ON gestao.nfendereco;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_nfendereco
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.nfendereco
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_nfendereco();
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_nfobs()
  RETURNS "trigger" AS
$BODY$
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          --REMOVE ACENTOS E OUTROS CARACTERES FORA DO ASCII
          NEW.campo		= TRIM(TO_ASCII(NEW.campo));
          NEW.texto		= TRIM(TO_ASCII(NEW.texto));
        END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_nfobs ON gestao.nfobs;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_nfobs
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.nfobs
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_nfobs();
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_nfvol()
  RETURNS "trigger" AS
$BODY$
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
	  --REMOVE ACENTOS E OUTROS CARACTERES FORA DO ASCII
	  NEW.especie		= TRIM(TO_ASCII(NEW.especie));
	  NEW.marca		= TRIM(TO_ASCII(NEW.marca));
	  NEW.numeracao		= TRIM(TO_ASCII(NEW.numeracao));
	  NEW.lacre1		= TRIM(TO_ASCII(NEW.lacre1));
	  NEW.lacre2		= TRIM(TO_ASCII(NEW.lacre2));
	  NEW.lacre3		= TRIM(TO_ASCII(NEW.lacre3));
	  NEW.lacre4		= TRIM(TO_ASCII(NEW.lacre4));
	  NEW.lacre5		= TRIM(TO_ASCII(NEW.lacre5));        

	  -- GRAVA CAMPOS NULOS
	  IF NEW.qtdade=0 THEN
	    NEW.qtdade = NULL;
	  END IF;
	  IF length(NEW.especie)=0 THEN
	    NEW.especie = NULL;
	  END IF;
	  IF length(NEW.marca)=0 THEN
	    NEW.marca = NULL;
	  END IF;
	  IF length(NEW.numeracao)=0 THEN
	    NEW.numeracao = NULL;
	  END IF;	  

	END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_nfvol ON gestao.nfvol;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_nfvol
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.nfvol
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_nfvol();
--RUN--

-- FUNÇÃO PARA ATUALIZAR O SALDO DO ESTOQUE
CREATE OR REPLACE FUNCTION gestao.atual_estsaldo()
  RETURNS trigger AS
$BODY$
    DECLARE rAnt              RECORD;
            vdt_invent        DATE;
            vdata             DATE;
            vid_inventario    INT4;
            vid_produto       INT;

    BEGIN
      -- INCLUSÃO REGISTRO TABELA ESTMOVTO
      IF TG_OP='INSERT' THEN

        -- LOTE
        IF NEW.id_lote=0 THEN
          NEW.id_lote=null;
        END IF;

        -- CONFERE PRODUTO DO LOTE
        IF NEW.id_lote IS NOT NULL THEN
          SELECT id_produto INTO vid_produto FROM gestao.lote where id_lote=NEW.id_lote;
          IF vid_produto IS NOT NULL AND NOT vid_produto=NEW.id_produto THEN
            RAISE EXCEPTION 'Produto (%) do Lote Difere do Produto (%) do Movimento! Lote # %|%',vid_produto,NEW.id_produto,NEW.id_lote,new.historico;
          END IF;
        END IF;

        -- CONFERE DATA DO LANÇAMENTO (BLOQUEIO)
        IF NEW.tipo IN ('E','S') AND NEW.data<=(SELECT dt_bloq_estoque FROM gestao.empresa WHERE id_empresa=NEW.id_empresa) THEN
          RAISE EXCEPTION 'Data do movimento (%) igual ou anterior a data de bloqueio de estoque!', to_char(NEW.data,'DD/MM/YYYY');
        END IF;

        -- CONFERE DATA DO LANÇAMENTO DO INVENTÁRIO
        IF NEW.origem_prefixo='INV' THEN
          vid_inventario=NEW.origem_id;
        ELSE
          vid_inventario = 0;
        END IF;
        IF NEW.id_lote>0 THEN
          SELECT data INTO vdt_invent
            FROM gestao.estinventario
            WHERE id_empresa=new.id_empresa AND id_estlocal=new.id_estlocal AND id_produto=new.id_produto AND data>=new.data AND NOT id_estinventario=vid_inventario AND COALESCE(variante,' ')=new.variante AND COALESCE(validade::char(10),' ')=NEW.validade AND id_lote=NEW.id_lote
            ORDER BY data DESC LIMIT 1;        
        ELSE
          SELECT data INTO vdt_invent
            FROM gestao.estinventario
            WHERE id_empresa=new.id_empresa AND id_estlocal=new.id_estlocal AND id_produto=new.id_produto AND data>=new.data AND NOT id_estinventario=vid_inventario AND COALESCE(variante,' ')=new.variante AND COALESCE(validade::char(10),' ')=NEW.validade 
            ORDER BY data DESC LIMIT 1;
        END IF;    
        IF vdt_invent IS NOT NULL AND NEW.tipo IN ('E','S') THEN
          RAISE EXCEPTION 'Produto % já tem inventário informado em %! Movimento do estoque não permitido!', new.id_produto, to_char(vdt_invent,'DD/MM/YYYY');
        END IF;

        -- CONFERE SE DATA ESTÁ OK
        -- SE NÃO TIVER A TRIGGER/SGBD GERA ERRO
        IF NOT NEW.validade='          ' THEN
          vdata = NEW.validade;
        END IF;

        -- DETERMINA ORDEM DE PROCESSMENTO DO CÁLCULO DO ESTOQUE
        IF NEW.origem_prefixo='INV' THEN
          IF NEW.tipo='E' THEN
             NEW.ordem_proc = 90;
          ELSE
             NEW.ordem_proc = 80;
          END IF;
        ELSE
          IF NEW.tipo='S' THEN
             NEW.ordem_proc = 20;
          ELSE
             NEW.ordem_proc = 10;
          END IF;
        END IF;

        -- BUSCA DADOS DO SALDO DO ESTOQUE
        SELECT id_estsaldo,qtdade,valor,qtd_empenhada,qtd_op INTO rAnt
          FROM gestao.estsaldo
         WHERE id_empresa=NEW.id_empresa AND id_estlocal=NEW.id_estlocal AND id_produto=NEW.id_produto AND variante=NEW.variante AND validade=NEW.validade AND CASE WHEN NEW.id_lote>0 THEN id_lote=NEW.id_lote ELSE id_lote IS NULL END;
        -- SE NÃO TEM SALDO ESTOQUE CRIA NOVO REGISTRO
        IF rAnt.id_estsaldo IS NULL THEN
          INSERT INTO gestao.estsaldo (id_empresa, id_estlocal, id_produto, variante, validade,
                                        qtdade, custo_medio, valor,
                                        qtd_empenhada, qtd_pedidos, id_lote)
                                VALUES (new.id_empresa, new.id_estlocal, new.id_produto, new.variante, new.validade,
                                        0,0,0,
                                        0,0,new.id_lote);
          SELECT id_estsaldo,qtdade,valor,qtd_empenhada,qtd_op INTO rAnt
            FROM gestao.estsaldo
           WHERE id_empresa=NEW.id_empresa AND id_estlocal=NEW.id_estlocal AND id_produto=NEW.id_produto AND variante=NEW.variante AND validade=NEW.validade AND CASE WHEN NEW.id_lote>0 THEN id_lote=NEW.id_lote ELSE id_lote IS NULL END;
        END IF;        
        -- ATUALIZA SALDO ESTOQUE: ENTRADA
        IF NEW.tipo='E' THEN
          IF NOT (rAnt.qtdade+NEW.qtdade)=0 AND ((rAnt.valor+NEW.valor+NEW.vl_ajuste) / (rAnt.qtdade+NEW.qtdade))>0 THEN
            NEW.custo_medio = (rAnt.valor+NEW.valor+NEW.vl_ajuste) / (rAnt.qtdade+NEW.qtdade);
          ELSE
            NEW.custo_medio = 0;
          END IF;
          UPDATE gestao.estsaldo SET qtdade     = qtdade+NEW.qtdade,
                                      valor     = valor+NEW.valor+NEW.vl_ajuste
                                WHERE id_estsaldo = rAnt.id_estsaldo;
        -- ATUALIZA SALDO ESTOQUE: SAÍDA
        ELSIF NEW.tipo='S' THEN
          UPDATE gestao.estsaldo SET qtdade     = qtdade-NEW.qtdade,
                                      valor      = valor-(NEW.valor+NEW.vl_ajuste)
                                WHERE id_estsaldo = rAnt.id_estsaldo;
        -- ATUALIZA SALDO ESTOQUE: EMPENHA
        ELSIF NEW.tipo='M' THEN
          NEW.valor 	= 0;
          NEW.vl_ajuste = 0;
          IF (rAnt.qtd_empenhada+NEW.qtdade)>(rAnt.qtdade+rAnt.qtd_op) AND (SELECT bloq_estoque_neg FROM gestao.empresa WHERE id_empresa = NEW.id_empresa)>0 THEN
            RAISE EXCEPTION 'Qtdade empenhada (%) é maior que qtdade diponível (%)! Produto: %',NEW.qtdade,(rAnt.qtdade-rAnt.qtd_empenhada+rAnt.qtd_op),NEW.id_produto;
          END IF;
          UPDATE gestao.estsaldo SET qtd_empenhada = qtd_empenhada+NEW.qtdade
                                WHERE id_estsaldo = rAnt.id_estsaldo;
        -- ATUALIZA SALDO ESTOQUE: PEDIDOS PENDENTES
        ELSIF NEW.tipo='P' THEN
          NEW.valor = 0;
          NEW.vl_ajuste = 0;
          UPDATE gestao.estsaldo SET qtd_pedidos = qtd_pedidos+NEW.qtdade
                                WHERE id_estsaldo = rAnt.id_estsaldo;
        ELSE
          RAISE EXCEPTION 'Tipo de movimento (%) desconhecido!',NEW.tipo;
        END IF;

        RETURN NEW;
      -- ALTERAÇÃO REGISTRO TABELA ESTMOVTO
      ELSIF TG_OP='UPDATE' THEN

        -- LOTE
        IF NEW.id_lote=0 THEN
          NEW.id_lote=null;
        END IF;

        IF NOT OLD.id_empresa  = NEW.id_empresa  OR
           NOT OLD.id_estlocal = NEW.id_estlocal OR
           NOT OLD.id_produto  = NEW.id_produto  OR
           NOT OLD.variante    = NEW.variante    OR
           NOT OLD.validade    = NEW.validade    OR
           NOT OLD.id_lote     = NEW.id_lote     OR
           NOT OLD.tipo        = NEW.tipo        OR
           NOT OLD.qtdade      = NEW.qtdade      OR
           (NOT OLD.valor      = NEW.valor AND NEW.tipo='E' AND NOT NEW.origem_prefixo='TE') THEN
          RAISE EXCEPTION 'Operação de alteração não permitida para os campos: Empresa, Local, Produto, Tipo, Qtdade ou Valor!';
        END IF;
        RETURN NEW;
      -- EXCLUSÃO REGISTRO TABELA ESTMOVTO
      ELSIF TG_OP='DELETE' THEN

--        RAISE NOTICE 'LOG EXCLUSÃO ESTOQUE - DATA: % / PRODUTO: % / QTDADE: % / PREFIXO ORIGEM: % /  ID ORIGEM: %',OLD.data, OLD.id_produto, OLD.qtdade, OLD.origem_prefixo, OLD.origem_id;

        IF OLD.tipo IN ('E','S') AND OLD.data<=(SELECT dt_bloq_estoque FROM gestao.empresa WHERE id_empresa=OLD.id_empresa) THEN
          RAISE EXCEPTION 'Data do movimento (%) igual ou anterior a data de bloqueio de estoque!', to_char(OLD.data,'DD/MM/YYYY');
        END IF;

        -- CONFERE DATA DO LANÇAMENTO DO INVENTÁRIO
        IF OLD.origem_prefixo='INV' THEN
          vid_inventario=OLD.origem_id;
        ELSE
          vid_inventario = 0;
        END IF;
        SELECT data INTO vdt_invent
          FROM gestao.estinventario
          WHERE id_empresa=OLD.id_empresa AND id_estlocal=OLD.id_estlocal AND id_produto=OLD.id_produto AND data>=OLD.data AND NOT id_estinventario=vid_inventario AND COALESCE(variante,' ')=OLD.variante AND COALESCE(validade::char(10),' ')=OLD.validade
          ORDER BY data DESC LIMIT 1;
        IF vdt_invent IS NOT NULL AND OLD.tipo IN ('E','S') AND NOT (OLD.origem_prefixo='INV' AND vdt_invent=OLD.data) THEN
          RAISE EXCEPTION 'Produto % já tem inventário informado em %! Movimento do estoque não permitido!', OLD.id_produto, to_char(vdt_invent,'DD/MM/YYYY');
        END IF;

        -- BUSCA DADOS DO SALDO DO ESTOQUE
        SELECT id_estsaldo,qtdade,valor,qtd_empenhada,qtd_op INTO rAnt
          FROM gestao.estsaldo
         WHERE id_empresa=OLD.id_empresa AND id_estlocal=OLD.id_estlocal AND id_produto=OLD.id_produto AND variante=OLD.variante AND validade=OLD.validade AND CASE WHEN OLD.id_lote>0 THEN id_lote=OLD.id_lote ELSE id_lote IS NULL END;
        -- ESTORNA SALDO ESTOQUE: ENTRADA
        IF OLD.tipo='E' THEN
          UPDATE gestao.estsaldo SET qtdade     = qtdade-OLD.qtdade,
                                      valor      = valor-(OLD.valor+OLD.vl_ajuste)
                                WHERE id_estsaldo = rAnt.id_estsaldo;
        -- ESTORNA SALDO ESTOQUE: SAÍDA
        ELSIF OLD.tipo='S' THEN
          UPDATE gestao.estsaldo SET qtdade     = qtdade+OLD.qtdade,
                                      valor      = valor+(OLD.valor+OLD.vl_ajuste)
                                WHERE id_estsaldo = rAnt.id_estsaldo;

        -- ESTORNA SALDO ESTOQUE: EMPENHA
        ELSIF OLD.tipo='M' THEN
          UPDATE gestao.estsaldo SET qtd_empenhada = qtd_empenhada-OLD.qtdade
                                WHERE id_estsaldo = rAnt.id_estsaldo;
        -- ESTORNA SALDO ESTOQUE: PEDIDOS PENDENTES
        ELSIF OLD.tipo='P' THEN
          UPDATE gestao.estsaldo SET qtd_pedidos = qtd_pedidos-OLD.qtdade
                                WHERE id_estsaldo = rAnt.id_estsaldo;
        ELSE
          RAISE EXCEPTION 'Tipo de movimento (%) desconhecido!',OLD.tipo;
        END IF;
        RETURN OLD;
      END IF;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.atual_estsaldo()
  OWNER TO postgres;
--RUN--

DROP TRIGGER atual_estsaldo ON gestao.estmovto;

--RUN--IGNORE ERRO

-- CRIA TRIGGER PARA ATUALIZAR SALDOS DO ESTOQUE
CREATE TRIGGER atual_estsaldo
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.estmovto
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.atual_estsaldo();
--RUN--

-- FUNÇÃO PARA GERAR ESTMOVTO DO INVENTÁRIO DO ESTOQUE
-- REVISADO POR JCS EM 01/02/2012 18:30
CREATE OR REPLACE FUNCTION gestao.gera_estmovto_inventario()
  RETURNS trigger AS
$BODY$
DECLARE
    vqt         NUMERIC(15,3);
    vvl         NUMERIC(15,2);
    vqtm        NUMERIC(15,3);
    vvlm        NUMERIC(15,2);
    vvalidade   CHAR(10);
    vvariante   CHAR(30);
    vseq        INT;
    vtipo       CHAR(1);
    vcusto_medio NUMERIC(17,4);

BEGIN
  IF TG_OP='UPDATE' THEN
    DELETE FROM gestao.estmovto WHERE origem_prefixo='INV' AND origem_id=OLD.id_estinventario;
    IF NOT NEW.id_estinventario=OLD.id_estinventario THEN
      RAISE EXCEPTION 'Alteração do ID do Inventário não permitida. Operação cancelada!';
    END IF;
  ELSIF TG_OP='DELETE' THEN
    DELETE FROM gestao.estmovto WHERE origem_prefixo='INV' AND origem_id=OLD.id_estinventario;
    RETURN OLD;
  END IF;

  IF new.variante IS NULL THEN
    vvariante = ' ';
  ELSE
    vvariante = NEW.variante;
  END IF;

  IF new.validade IS NULL THEN
    vvalidade = ' ';
  ELSE
    vvalidade = NEW.validade;
  END IF;
  -- CALCULA SALDO DO ESTOQUE ATÉ A DATA ATUAL E ATUALIZA SALDO
  IF NEW.id_lote>0 THEN
    SELECT sum(CASE WHEN tipo='E' THEN qtdade WHEN tipo='S'  THEN -qtdade END) as qtd,
      sum(CASE WHEN tipo='E' THEN (valor+vl_ajuste) WHEN tipo='S' THEN -(valor+vl_ajuste) END) as valor
      INTO vqtm, vvlm
      FROM gestao.estmovto
      WHERE id_estlocal=new.id_estlocal AND id_produto=new.id_produto AND id_empresa=new.id_empresa AND variante=vvariante AND validade=vvalidade AND id_lote=NEW.id_lote
      AND tipo IN ('E','S');
  ELSE
    SELECT sum(CASE WHEN tipo='E' THEN qtdade WHEN tipo='S'  THEN -qtdade END) as qtd,
      sum(CASE WHEN tipo='E' THEN (valor+vl_ajuste) WHEN tipo='S' THEN -(valor+vl_ajuste) END) as valor
      INTO vqtm, vvlm
      FROM gestao.estmovto
      WHERE id_estlocal=new.id_estlocal AND id_produto=new.id_produto AND id_empresa=new.id_empresa AND variante=vvariante AND validade=vvalidade AND id_lote is null
      AND tipo IN ('E','S');    
  END IF;  
  IF vqtm IS NULL THEN
    vqtm = 0;
    vvlm = 0;
  END IF;
  -- ATUALIZA SALDO
  IF NEW.id_lote>0 THEN
    UPDATE gestao.estsaldo SET qtdade=vqtm,valor=vvlm WHERE  id_estlocal=new.id_estlocal AND id_produto=new.id_produto AND id_empresa=new.id_empresa AND variante=vvariante AND validade=vvalidade AND id_lote=NEW.id_lote;
  ELSE
    UPDATE gestao.estsaldo SET qtdade=vqtm,valor=vvlm WHERE  id_estlocal=new.id_estlocal AND id_produto=new.id_produto AND id_empresa=new.id_empresa AND variante=vvariante AND validade=vvalidade AND id_lote IS NULL;
  END IF;

  -- CALCULA SALDO DO ESTOQUE ATÉ A DATA DO AJUSTE
  IF NEW.id_lote>0 THEN
    SELECT sum(CASE WHEN tipo='E' THEN qtdade WHEN tipo='S'  THEN -qtdade END) as qtd,
      sum(CASE WHEN tipo='E' THEN (valor+vl_ajuste) WHEN tipo='S' THEN -(valor+vl_ajuste) END) as valor
      INTO vqtm, vvlm
      FROM gestao.estmovto
      WHERE id_estlocal=new.id_estlocal AND id_produto=new.id_produto AND id_empresa=new.id_empresa AND variante=vvariante AND validade=vvalidade AND id_lote=NEW.id_lote
      AND tipo IN ('E','S') AND data<=new.data;
  ELSE
    SELECT sum(CASE WHEN tipo='E' THEN qtdade WHEN tipo='S'  THEN -qtdade END) as qtd,
      sum(CASE WHEN tipo='E' THEN (valor+vl_ajuste) WHEN tipo='S' THEN -(valor+vl_ajuste) END) as valor
      INTO vqtm, vvlm
      FROM gestao.estmovto
      WHERE id_estlocal=new.id_estlocal AND id_produto=new.id_produto AND id_empresa=new.id_empresa AND variante=vvariante AND validade=vvalidade AND id_lote is null
      AND tipo IN ('E','S') AND data<=new.data;   
  END IF;   

  IF vqtm IS NULL THEN
    vqtm = 0;
    vvlm = 0;
  END IF;

  vseq = 0;
  IF (NEW.qtdade>vqtm AND NEW.valor>=vvlm) OR (NEW.qtdade=vqtm AND NEW.valor=vvlm) THEN
    -- VALOR E QUANTIDADE P/LANÇAMENTO
    vqt = new.qtdade - vqtm;
    vvl = new.valor - vvlm;
    vtipo = 'E';
  ELSE
    IF (vqtm=0 AND vvlm>0)THEN
      vqt=vqtm ;
      vvl=-vvlm;
      vtipo='E';
    ELSIF vqtm>0 THEN
      vqt=vqtm ;
      vvl=0;
      vtipo='S';
    ELSE
      vqt= -vqtm;
      IF vvlm>0 THEN
        vvl = -vvlm;
      ELSE
        vvl = vvlm;
      END IF;
      vtipo='E';
      IF vqt=0 AND vvl<0 THEN
        vvl = -vvl;
      END IF;
    END IF;
    -- LANÇAMENTO DE ZERAMENTO
    vseq = vseq +1 ;
    vcusto_medio = 0;
    IF NOT (vqt=0 AND vvl=0) THEN
      INSERT INTO gestao.estmovto (data,id_empresa,id_estlocal,id_produto,origem_prefixo,origem_id,origem_ordem,qtdade,valor,tipo,docto_natureza,docto_tipo,docto_serie,docto_numero,historico,vl_ajuste,operador,status,origem_seq,custo_medio,variante,validade,id_lote)
        VALUES (new.data,new.id_empresa,new.id_estlocal,new.id_produto,'INV',new.id_estinventario,vseq,vqt,vvl,vtipo,'I',' ',' ',' ','ZERADO P/INVENTÁRIO',0,new.operador,1,0,vcusto_medio,vvariante,vvalidade,NEW.id_lote);
    END IF;
    -- VALOR E QUANTIDADE P/LANÇAMENTO
    vqt = new.qtdade;
    vvl = new.valor;
    vtipo = 'E';
  END IF;

  IF NOT (vqt=0 AND vvl=0) THEN
    -- LANÇAMENTO DE AJUSTE
    vseq = vseq +1 ;
    INSERT INTO gestao.estmovto (data,id_empresa,id_estlocal,id_produto,origem_prefixo,origem_id,origem_ordem,qtdade,valor,tipo,docto_natureza,docto_tipo,docto_serie,docto_numero,historico,vl_ajuste,operador,status,origem_seq,custo_medio,variante,validade,id_lote)
      VALUES (new.data,new.id_empresa,new.id_estlocal,new.id_produto,'INV',new.id_estinventario,2,vqt,vvl,vtipo,'I',' ',' ',' ','AJUSTE P/INVENTÁRIO',0,new.operador,1,0,vcusto_medio,vvariante,vvalidade,NEW.id_lote);
  END IF;

  RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.gera_estmovto_inventario()
  OWNER TO postgres;
--RUN--

DROP TRIGGER gera_estmovto ON gestao.estinventario;

--RUN--IGNORE ERRO

CREATE TRIGGER gera_estmovto
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.estinventario
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.gera_estmovto_inventario();
--RUN--

DROP FUNCTION gestao.gera_inventario(integer, integer, integer, date, bpchar);
--RUN--IGNORE ERRO

-- FUNÇÃO PARA GERAR INVENTÁRIO DO ESTOQUE
CREATE OR REPLACE FUNCTION gestao.gera_inventario(integer, integer, integer, date, character, integer)
  RETURNS integer AS
$BODY$
DECLARE
    pidempresa  ALIAS FOR $1;
    pidlocal    ALIAS FOR $2;
    pidproduto  ALIAS FOR $3;
    pdata       ALIAS FOR $4;
    poperador   ALIAS FOR $5;
    pidemppro   ALIAS FOR $6;
    vqt         NUMERIC(15,3);
    vvl         NUMERIC(15,2);
    vdata       DATE;
    vqtm        NUMERIC(15,3);
    vvlm        NUMERIC(15,2);
    vest        RECORD;
    vunidade    CHAR(6);

BEGIN

  FOR vest IN SELECT variante,validade,id_lote
                FROM gestao.estsaldo A
                WHERE id_empresa=pidempresa AND id_estlocal=pidlocal AND id_produto=pidproduto
  LOOP
    IF vest.id_lote>0 THEN
      SELECT qtdade, valor, data INTO vqt, vvl, vdata
        FROM gestao.estinventario
        WHERE id_empresa=pidempresa AND id_estlocal=pidlocal AND id_produto=pidproduto AND COALESCE(variante,' ')=vest.variante AND COALESCE(validade::char(10),' ')=vest.validade AND data<=pdata AND id_lote=vest.id_lote
        ORDER BY data DESC LIMIT 1;    
    ELSE
      SELECT qtdade, valor, data INTO vqt, vvl, vdata
        FROM gestao.estinventario
        WHERE id_empresa=pidempresa AND id_estlocal=pidlocal AND id_produto=pidproduto AND COALESCE(variante,' ')=vest.variante AND COALESCE(validade::char(10),' ')=vest.validade AND data<=pdata AND id_lote IS NULL
        ORDER BY data DESC LIMIT 1;
    END IF;    
    IF NOT pdata=vdata OR vdata IS NULL THEN -- VERIFICA SE JÁ TEM INVENTÁRIO LANÇADO NESTA DATA
      vqt = 0;
      vvl = 0;
      vdata = '1980-01-01';
      
      IF vest.id_lote>0 THEN
        SELECT sum(CASE WHEN A.tipo='E' THEN A.qtdade WHEN A.tipo='S'  THEN -A.qtdade END) as qtd,
          sum(CASE WHEN A.tipo='E' THEN (A.valor+A.vl_ajuste) WHEN A.tipo='S' THEN -(A.valor+A.vl_ajuste) END) as valor
          INTO vqtm, vvlm
          FROM gestao.estmovto as A
          LEFT OUTER JOIN gestao.produto as B on(A.id_produto=B.id_erp and B.id_empresa=pidemppro)
          WHERE A.id_estlocal=pidlocal AND A.id_produto=pidproduto AND A.id_empresa=pidempresa AND A.variante=vest.variante AND A.validade=vest.validade AND A.id_lote=vest.id_lote
          AND A.tipo IN ('E','S') AND A.data<=pdata AND NOT B.tipo='08';
      ELSE
        SELECT sum(CASE WHEN A.tipo='E' THEN A.qtdade WHEN A.tipo='S'  THEN -A.qtdade END) as qtd,
          sum(CASE WHEN A.tipo='E' THEN (A.valor+A.vl_ajuste) WHEN A.tipo='S' THEN -(A.valor+A.vl_ajuste) END) as valor
          INTO vqtm, vvlm
          FROM gestao.estmovto as A
          LEFT OUTER JOIN gestao.produto as B on(A.id_produto=B.id_erp and B.id_empresa=pidemppro)
          WHERE A.id_estlocal=pidlocal AND A.id_produto=pidproduto AND A.id_empresa=pidempresa AND A.variante=vest.variante AND A.validade=vest.validade AND A.id_lote IS NULL
          AND A.tipo IN ('E','S') AND A.data<=pdata AND NOT B.tipo='08';
      END IF;  
      IF vqtm IS NULL THEN
        vqtm = 0;
        vvlm = 0;
      END IF;
      IF NOT (vqt+vqtm)=0 THEN
        IF (vqt+vqtm)<0 THEN
          vqt  = 0;
          vqtm = 0;
          vvl  = 0;
          vvlm = 0;
        END IF;
        IF (vvl+vvlm)<0 THEN
          vvl  = 0;
          vvlm = 0;
        END IF;
        IF vest.validade='          ' THEN
          vdata = NULL;
        ELSE
          vdata = vest.validade;
        END IF;
        IF (vqt+vqtm)>0 THEN
          IF substring(vest.variante,1,4)='UND:' THEN
            vunidade = substring(vest.variante,5,6);
          ELSE
            vunidade = NULL;
          END IF;
          INSERT INTO gestao.estinventario (id_empresa,id_estlocal,id_produto,data,qtdade,valor,operador,variante,validade,inf_usuario,unidade,id_lote)
              VALUES (pidempresa,pidlocal,pidproduto,pdata,(vqt+vqtm),(vvl+vvlm),poperador,vest.variante,vdata,0,vunidade,vest.id_lote);
        END IF;
      END IF;
    END IF;
  END LOOP;
  RETURN 1;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.gera_inventario(integer, integer, integer, date, character, integer)
  OWNER TO postgres;
--RUN--

-- FUNÇÃO PARA APAGAR MOVIMENTO DO ESTOQUE
CREATE OR REPLACE FUNCTION gestao.apaga_estmovto(int4,int4,int4,date) RETURNS integer AS 
$BODY$
DECLARE
    pidempresa 	ALIAS FOR $1;
    pidlocal	ALIAS FOR $2;
    pidproduto	ALIAS FOR $3;
    pdata	ALIAS FOR $4;
    vqt		NUMERIC(15,3);
    vvl		NUMERIC(15,2);
    vdata	DATE;
    vqtm	NUMERIC(15,3);
    vvlm	NUMERIC(15,2);
    vtipo       char(1);
    vest        RECORD;
    vseq        INT;


BEGIN

  vseq=0;
  FOR vest IN SELECT variante,validade
                FROM gestao.estsaldo A
                WHERE id_empresa=pidempresa AND id_estlocal=pidlocal AND id_produto=pidproduto
  LOOP

    SELECT qtdade, valor, data INTO vqt, vvl, vdata
      FROM gestao.estinventario 
      WHERE id_empresa=pidempresa AND id_estlocal=pidlocal AND id_produto=pidproduto AND COALESCE(variante,' ')=vest.variante AND ((validade IS NULL AND vest.validade=' ') OR validade=vest.validade::date) AND data<=data
      ORDER BY data DESC LIMIT 1;
    IF vqt IS NULL THEN
      vqt = 0;
      vvl = 0;
      vdata = '1900-01-01';
    END IF;
    SELECT sum(CASE WHEN tipo='E' THEN qtdade WHEN tipo='S'  THEN -qtdade END) as qtd, 
      sum(CASE WHEN tipo='E' THEN (valor+vl_ajuste) WHEN tipo='S' THEN -(valor+vl_ajuste) END) as valor 
      INTO vqtm, vvlm
      FROM gestao.estmovto 
      WHERE id_estlocal=pidlocal AND id_produto=pidproduto AND id_empresa=pidempresa AND variante=vest.variante AND validade=vest.validade
      AND tipo IN ('E','S') AND data>vdata AND data<=pdata;
    IF vqtm IS NULL THEN
      vqtm = 0;
      vvlm = 0;
    END IF;
    vseq = vseq + 1;
    ALTER TABLE gestao.estmovto DISABLE TRIGGER atual_estmovto_valor;
    ALTER TABLE gestao.estmovto DISABLE TRIGGER atual_estsaldo;
    DELETE FROM gestao.estmovto WHERE id_empresa=pidempresa AND id_estlocal=pidlocal AND id_produto=pidproduto AND variante=vest.variante AND validade=vest.validade AND data<=pdata;
    IF NOT (vqt+vqtm)=0 THEN
      IF (vqt+vqtm)>0 THEN
        vtipo= 'E';
        vqt  = (vqt+vqtm);
        vvl  = (vvl+vvlm);
      ELSE
        vtipo='S';
        vqt  = -(vqt+vqtm);
        vvl  = -(vvl+vvlm);  
      END IF;    
      INSERT INTO gestao.estmovto (id_empresa,id_estlocal,id_produto,data,qtdade,valor,tipo,vl_ajuste,docto_natureza,docto_tipo,docto_serie,docto_numero,historico,operador,status,origem_prefixo,origem_id,origem_ordem,origem_seq,variante,validade) 
          VALUES (pidempresa,pidlocal,pidproduto,pdata,vqt,vvl,vtipo,0,'I','','','','GERADO ROTINA APAGA ESTMOVTO','SISTEMA',1,'',pidproduto,pidlocal,vseq,vest.variante,vest.validade);
    END IF;
    ALTER TABLE gestao.estmovto ENABLE TRIGGER atual_estmovto_valor;
    ALTER TABLE gestao.estmovto ENABLE TRIGGER atual_estsaldo;

  END LOOP;

  RETURN 1;
END;
$BODY$
 LANGUAGE plpgsql;
--RUN--

-- FUNÇÃO PARA ATUALIZAR O CUSTO UNITÁRIO DO ESTOQUE
CREATE OR REPLACE FUNCTION gestao.atual_custo_estoque() RETURNS trigger AS 
$BODY$
    BEGIN
      IF NOT NEW.qtdade=0 AND (NEW.valor / NEW.qtdade)>0 THEN
        NEW.custo_medio = NEW.valor / NEW.qtdade;
      END IF;
      RETURN NEW;
    END;
$BODY$ LANGUAGE plpgsql;

--RUN--

DROP TRIGGER atual_custo_estoque ON gestao.estsaldo;

--RUN--IGNORE ERRO

-- CRIA TRIGGER PARA ATUALIZAR CUSTO UNITÁRIO DO ESTOQUE

CREATE TRIGGER atual_custo_estoque
  BEFORE INSERT OR UPDATE 
  ON gestao.estsaldo
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.atual_custo_estoque();

--RUN--


-- FUNÇÃO PARA LANÇAR ESTMOVTO NO MUDANÇA DE STATUS DA NF
CREATE OR REPLACE FUNCTION gestao.gera_estmovto_nf() RETURNS trigger AS 
$BODY$
    BEGIN
      -- UPDATE NO NFDET PARA DISPARAR TRIGGER PARA ATUALIZAR O ESTOQUE CASO MUDE O STATUS
      IF TG_OP='UPDATE' THEN
        IF (NEW.status IN ('L','V','T','E') AND OLD.status NOT IN ('L','V','T','E')) OR
	   (NEW.status NOT IN ('L','V','T','E') AND OLD.status IN ('L','V','T','E')) OR
	   NOT COALESCE(NEW.op_cancelada,'N')=COALESCE(OLD.op_cancelada,'N') OR
	    NOT NEW.dt_emissao=OLD.dt_emissao THEN
          UPDATE gestao.nfdet SET cfop=cfop WHERE id_nf=NEW.id_nf;
        END IF;
      END IF;
      RETURN NEW;
    END;
$BODY$ LANGUAGE plpgsql;

--RUN--

DROP TRIGGER gera_estmovto_nf ON gestao.nf;

--RUN--IGNORE ERRO

-- CRIA TRIGGER PARA ATUALIZAR SALDOS DO ESTOQUE
CREATE TRIGGER gera_estmovto_nf
  AFTER UPDATE 
  ON gestao.nf
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.gera_estmovto_nf();
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_lanctos()
  RETURNS "trigger" AS
$BODY$
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          IF NEW.id_lancto_vinculado=0 THEN
            NEW.id_lancto_vinculado = NULL;
          END IF;
        END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_lanctos ON gestao.lanctos;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_lanctos
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.lanctos
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_lanctos();
--RUN--

-- FUNÇÃO PARA LANÇAR ESTMOVTO MUDANÇA DE DATA/TIPO/SITUACAO NA REQ
CREATE OR REPLACE FUNCTION gestao.gera_estmovto_req() RETURNS trigger AS 
$BODY$
    BEGIN
      -- UPDATE NO REQD PARA DISPARAR TRIGGER PARA ATUALIZAR O ESTOQUE CASO MUDE A DATA/TIPO/SITUACAO
      IF TG_OP='INSERT' THEN
        IF NEW.numero=0 THEN
	  RAISE EXCEPTION 'Número da Requisição não pode ser zero!';
	END IF;
      END IF;
      IF NEW.data>now() THEN
        RAISE EXCEPTION 'Data % inválida!',to_char(NEW.data,'DD/MM/YYYY');
      END IF;
      IF TG_OP='UPDATE' THEN
        IF NOT NEW.tipo=OLD.tipo OR NOT NEW.data=OLD.data OR NOT NEW.situacao=OLD.situacao OR NOT NEW.status=OLD.status OR NOT COALESCE(NEW.id_destino,0)=COALESCE(OLD.id_destino,0) THEN
          UPDATE gestao.reqd SET qtdade=qtdade WHERE id_req=NEW.id_req;
        END IF;
      END IF;
      RETURN NEW;
    END;
$BODY$ LANGUAGE plpgsql;
--RUN--

DROP TRIGGER gera_estmovto_req ON gestao.req;
--RUN--IGNORE ERRO

-- CRIA TRIGGER PARA ATUALIZAR SALDOS DO ESTOQUE
CREATE TRIGGER gera_estmovto_req
  AFTER INSERT OR UPDATE 
  ON gestao.req
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.gera_estmovto_req();
--RUN--

CREATE OR REPLACE FUNCTION gestao.lanctos_atual_saldo2( integer, integer, date) RETURNS integer AS
$BODY$
    DECLARE
              pid_empresa  ALIAS FOR $1;
              pbanco       ALIAS FOR $2;
              pdata        ALIAS FOR $3;
              lan          RECORD;
              vsaldo       NUMERIC(15,2);
    BEGIN
      SELECT saldo INTO vsaldo 
          FROM gestao.lanctos 
          WHERE id_empresa=pid_empresa AND banco=pbanco AND dt_movto<pdata 
          ORDER BY dt_movto DESC,id DESC LIMIT 1;
      IF  vsaldo IS NULL THEN
        vsaldo = 0;
      END IF;
      FOR lan IN SELECT id,tipo,valor,saldo
          FROM gestao.lanctos
          WHERE id_empresa=pid_empresa AND banco=pbanco AND dt_movto>=pdata 
          ORDER BY dt_movto,id
      LOOP
        IF lan.tipo='E' THEN
          vsaldo = vsaldo + lan.valor;
        ELSIF  lan.tipo='S' THEN
          vsaldo = vsaldo - lan.valor;
        END IF;
        IF NOT vsaldo=lan.saldo THEN
          UPDATE gestao.lanctos SET saldo=vsaldo WHERE id=lan.id;
        END IF;     
      END LOOP;
      RETURN 1;
    END;
$BODY$
  LANGUAGE 'plpgsql';
--RUN--

CREATE OR REPLACE FUNCTION gestao.lanctos_atual_saldo()
  RETURNS "trigger" AS
$BODY$
    DECLARE
             vdata          DATE;
             vret           INTEGER;
    BEGIN
      IF TG_OP='INSERT'  THEN
        IF NOT NEW.saldo=987654321.21 THEN
           vret = gestao.lanctos_atual_saldo2(NEW.id_empresa,NEW.banco,NEW.dt_movto);
        END IF;
        RETURN NEW;
      ELSIF TG_OP='DELETE' THEN
        vret = gestao.lanctos_atual_saldo2(OLD.id_empresa,OLD.banco,OLD.dt_movto);
        RETURN OLD;
      ELSIF TG_OP='UPDATE' THEN
        IF NOT (NEW.id_empresa=OLD.id_empresa AND NEW.banco=OLD.banco AND 
                NEW.dt_movto=OLD.dt_movto AND NEW.valor=OLD.valor AND
                NEW.tipo=OLD.tipo) THEN
          IF NEW.id_empresa=OLD.id_empresa AND NEW.banco=OLD.banco THEN
            IF NEW.dt_movto<OLD.dt_movto THEN
              vdata = NEW.dt_movto;
            ELSE
              vdata = OLD.dt_movto;
            END IF;
            vret = gestao.lanctos_atual_saldo2(NEW.id_empresa,NEW.banco,vdata);
          ELSE
            vret = gestao.lanctos_atual_saldo2(OLD.id_empresa,OLD.banco,OLD.dt_movto);
            vret = gestao.lanctos_atual_saldo2(NEW.id_empresa,NEW.banco,NEW.dt_movto);
          END IF; 

        END IF;
        RETURN NEW;
      END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql';
--RUN--

DROP TRIGGER lanctos_atual_saldo ON gestao.lanctos;
--RUN--IGNORE ERRO

CREATE TRIGGER lanctos_atual_saldo
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.lanctos
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.lanctos_atual_saldo();
--RUN--

CREATE OR REPLACE FUNCTION gestao.estterceiro_calc_saldo()
  RETURNS "trigger" AS
$BODY$
    DECLARE
      vid_empresa    INTEGER;
      vnum_remessa   INTEGER;
      vsaldo         NUMERIC(15,3);
      vsaldoant      NUMERIC(15,3);
      vvl_saldo      NUMERIC(15,2);
      vdata          DATE;
      vdata_baixa    DATE;

    BEGIN
      IF TG_OP='INSERT' THEN
        vid_empresa  = NEW.id_empresa;
        vnum_remessa = NEW.num_remessa;
      ELSIF TG_OP='UPDATE' THEN
        vid_empresa  = NEW.id_empresa;
        vnum_remessa = NEW.num_remessa;
        IF NOT new.id_empresa=OLD.id_empresa THEN 
          RAISE EXCEPTION 'Empresa não pode ser alterada!';
        END IF;
        IF NOT new.num_remessa=OLD.num_remessa THEN 
          RAISE EXCEPTION 'Número da remessa não pode ser alterada!';
        END IF;
      ELSIF TG_OP='DELETE' THEN
        vid_empresa  = OLD.id_empresa;
        vnum_remessa = OLD.num_remessa;
      END IF;
      SELECT SUM(CASE WHEN tipo='R' THEN qtdade ELSE -qtdade END),SUM(CASE WHEN tipo='R' THEN valor ELSE -valor END),SUM(CASE WHEN tipo='R' THEN qtd_saldo END),MAX(data),MAX(CASE WHEN tipo='R' THEN data_baixa END) INTO vsaldo,vvl_saldo,vsaldoant,vdata,vdata_baixa
          FROM gestao.estterceiro 
          WHERE id_empresa=vid_empresa AND num_remessa=vnum_remessa;
      IF vsaldo<0 THEN
        RAISE EXCEPTION 'Qtdade devolvida é maior que a qtdade informada na remessa. Saldo (%) não pode ficar negativo!|Produto: % / Remessa: %',vsaldo,new.cod_produto,new.num_remessa;
      END IF;
      IF vvl_saldo<0 THEN
        RAISE EXCEPTION 'Valor devolvido é maior que o valor informado na remessa. Valor (%) não pode ficar negativo!|Produto: % / Remessa: %',vvl_saldo,new.cod_produto,new.num_remessa;
      END IF;
      IF vsaldo=0 AND (vvl_saldo>0.01 OR vvl_saldo<-0.01) THEN
        RAISE EXCEPTION 'Saldo para devolução ficou zerado porem existe valor pendente (%) para devoluçao!|Produto: % / Remessa: %',vvl_saldo,new.cod_produto,new.num_remessa;
      END IF;
      IF NOT vsaldoant=vsaldo OR (vsaldo=0 AND vdata_baixa IS NULL) OR (vsaldo>0 AND vdata_baixa IS NOT NULL) THEN
        UPDATE gestao.estterceiro SET qtd_saldo=vsaldo,data_baixa=(CASE WHEN vsaldo=0 THEN vdata ELSE NULL END) WHERE id_empresa=vid_empresa AND num_remessa=vnum_remessa AND tipo='R';
      END IF;
      IF TG_OP='DELETE' THEN
        RETURN OLD;
      ELSE
        RETURN NEW;
      END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql';
--RUN--

DROP TRIGGER estterceiro_calc_saldo ON gestao.estterceiro;
--RUN--IGNORE ERRO

CREATE TRIGGER estterceiro_calc_saldo
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.estterceiro
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.estterceiro_calc_saldo();
--RUN--


CREATE OR REPLACE FUNCTION gestao.valida_tabobsfiscal()
  RETURNS "trigger" AS
$BODY$
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          --REMOVE ACENTOS E OUTROS CARACTERES FORA DO ASCII
	  NEW.descricao    = TRIM(TO_ASCII(NEW.descricao));
        END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER tabobsfiscal_nf ON gestao.tabobsfiscal;
--RUN--IGNORE ERRO
DROP TRIGGER valida_tabobsfiscal ON gestao.tabobsfiscal;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_tabobsfiscal
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.tabobsfiscal
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_tabobsfiscal();
--RUN--


CREATE OR REPLACE FUNCTION gestao.valida_obsfiscal()
  RETURNS "trigger" AS
$BODY$
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          --REMOVE ACENTOS E OUTROS CARACTERES FORA DO ASCII
	  NEW.descr_compl  = TRIM(REPLACE(NEW.descr_compl,chr(31),chr(32)));
	  NEW.descr_compl  = TRIM(TO_ASCII(NEW.descr_compl));
          IF NEW.id_pedido=0 THEN 
              NEW.id_pedido=NULL;
          END IF;
	END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER obsfiscal_nf ON gestao.obsfiscal;
--RUN--IGNORE ERRO
DROP TRIGGER valida_obsfiscal ON gestao.obsfiscal;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_obsfiscal
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.obsfiscal
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_obsfiscal();
--RUN--

CREATE OR REPLACE FUNCTION gestao.to_alfanum(text) 
  RETURNS text AS
$BODY$ 
       DECLARE vret         TEXT;
               cc           INT;
               vtexto       TEXT;
               vletra       CHAR(1);
               vpar1        ALIAS FOR $1;
       BEGIN   
         vtexto = UPPER(vpar1);
         vret='';
         FOR cc IN 1..length(vtexto) LOOP
           vletra = substring(vtexto,cc,1);
           IF ((vletra>='0' AND vletra<='9') OR (vletra>='A' AND vletra<='Z')) THEN
             vret = vret||vletra;
           END IF;
         END LOOP;
         RETURN vret; 
         
       END;  
    $BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

CREATE OR REPLACE FUNCTION gestao.to_alfanum(text,integer) 
  RETURNS text AS
$BODY$ 
       DECLARE vret         TEXT;
               vtam         INTEGER;
               vpar1        ALIAS FOR $1;
               vpar2        ALIAS FOR $2;
       BEGIN   
         vret = gestao.to_alfanum(vpar1);
         vtam = length(vret);
         IF vtam>vpar2 THEN
           vret=substring(vret,1,vpar2);
         ELSIF vtam<vpar2 THEN 
           vret=vret||repeat(' ',vpar2-vtam);
         END IF;
         RETURN vret; 
         
       END;  
    $BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--


-- ------------------------------------------- --
--  FUNÇÃO PARA ATUALIZAR O VALOR DO ESTMOVTO  --
--  REVISADA POR JCS EM 08/01/2020 15:40       --
-- ------------------------------------------- --
CREATE OR REPLACE FUNCTION gestao.atual_estmovto_valor()
  RETURNS trigger AS
$BODY$
    DECLARE s              RECORD;
            m              RECORD;
            mv             RECORD;
            vid_empresa    INT4;
            vid_estlocal   INT4;
            vid_produto    INT4;
            vvariante      char(30);
            vvalidade      char(10);
            vdata          DATE;
            vcusto_medio   NUMERIC(17,4);
            vtot           NUMERIC(17,2);
            vvl_ajuste     NUMERIC(15,2);
            vvalor         NUMERIC(15,2);
            vdtatual       DATE;
            vid_lote       integer;

    BEGIN
      IF TG_OP='INSERT' THEN
        IF NEW.tipo='M' THEN
          RETURN NEW;
        END IF;
        vid_empresa     = NEW.id_empresa;
        vid_estlocal    = NEW.id_estlocal;
        vid_produto     = NEW.id_produto;
        vvariante       = NEW.variante;
        vvalidade       = NEW.validade;
        vdata           = NEW.data;
        vid_lote        = NEW.id_lote;
      ELSIF TG_OP='DELETE' THEN
        IF OLD.tipo='M' THEN
          RETURN OLD;
        END IF;
        vid_empresa     = OLD.id_empresa;
        vid_estlocal    = OLD.id_estlocal;
        vid_produto     = OLD.id_produto;
        vvariante       = OLD.variante;
        vvalidade       = OLD.validade;
        vdata           = OLD.data;
        vid_lote        = OLD.id_lote;
      END IF;
      SELECT id_estsaldo, qtdade, valor, custo_medio, data
          INTO s
          FROM gestao.estsaldo
          WHERE id_empresa=vid_empresa AND id_estlocal=vid_estlocal AND id_produto=vid_produto AND variante=vvariante AND validade=vvalidade AND CASE WHEN vid_lote>0 THEN id_lote=vid_lote ELSE id_lote IS NULL END;
      SELECT sum(CASE WHEN tipo='E' THEN qtdade ELSE -qtdade END) as qtdade,
             sum(CASE WHEN tipo='E' THEN (valor+vl_ajuste) ELSE -(valor+vl_ajuste) END) as valor
             INTO mv
             FROM gestao.estmovto
             WHERE id_empresa=vid_empresa AND id_estlocal=vid_estlocal AND id_produto=vid_produto AND variante=vvariante AND validade=vvalidade AND data>=vdata AND tipo IN ('E','S') AND CASE WHEN vid_lote>0 THEN id_lote=vid_lote ELSE id_lote IS NULL END;
      IF mv.qtdade IS NOT NULL THEN
        s.qtdade = s.qtdade - mv.qtdade;
        s.valor  = s.valor  - mv.valor;
      END IF;
      IF s.qtdade=0 or s.valor=0 THEN
        vcusto_medio =  (SELECT custo_medio
                           FROM gestao.estmovto
                          WHERE custo_medio>0 AND id_empresa=vid_empresa AND id_estlocal=vid_estlocal AND id_produto=vid_produto AND variante=vvariante AND validade=vvalidade AND data<vdata AND tipo IN ('E','S') AND CASE WHEN vid_lote>0 THEN id_lote=vid_lote ELSE id_lote IS NULL END
                          ORDER BY data DESC,ordem_proc DESC,tipo DESC,id_estmovto DESC LIMIT 1);
        IF vcusto_medio IS NULL THEN
          vcusto_medio = 0;
        END IF;
      ELSE
        vcusto_medio = s.valor/s.qtdade;
      END IF;

      vtot         = 0;
      FOR m IN SELECT id_estmovto, data, tipo, qtdade, valor, vl_ajuste, custo_medio, origem_prefixo, origem_id, origem_ordem
          FROM gestao.estmovto
          WHERE id_empresa=vid_empresa AND id_estlocal=vid_estlocal AND id_produto=vid_produto AND variante=vvariante AND validade=vvalidade AND data>=vdata AND tipo IN ('E','S') AND CASE WHEN vid_lote>0 THEN id_lote=vid_lote ELSE id_lote IS NULL END
          ORDER BY data,ordem_proc,tipo,id_estmovto
      LOOP

        IF vcusto_medio<0 THEN
          vcusto_medio = 0;
        END IF;

        vdtatual = m.data;
        IF m.tipo='E' THEN
          IF s.qtdade<0 AND NOT m.origem_prefixo='INV' AND m.qtdade>0 AND (m.qtdade+s.qtdade)>=0 THEN
            vvl_ajuste = (m.valor/m.qtdade*(m.qtdade+s.qtdade))-(s.valor+m.valor);
          ELSE
            vvl_ajuste = 0;
          END IF;

          IF m.origem_prefixo='TE' THEN
            vvalor   = (SELECT valor FROM gestao.estmovto WHERE id_empresa=vid_empresa AND origem_prefixo='TE' AND origem_id=m.origem_id AND origem_ordem=(m.origem_ordem-1) AND tipo='S' limit 1);
          ELSE
            vvalor   = m.valor;
          END IF ;

          s.qtdade = s.qtdade + m.qtdade;
          s.valor  = s.valor + vvalor + vvl_ajuste;

        ---- IMPLEMENTADO POR JCS EM 07/07/2021 AS 15:26 ------ 
          IF (s.qtdade=0 AND NOT s.valor=0) THEN            
            vvl_ajuste = (vvl_ajuste-s.valor);
            s.valor    = 0 ;            
          END IF;
        -------------------------------------------------------		  
		  
          vtot     = vtot + (vvl_ajuste-m.vl_ajuste) + (vvalor-m.valor);

        ELSE
          vvl_ajuste = 0;

          IF s.qtdade>=0 AND s.valor<0 THEN
            vvalor  = s.valor;
          ELSIF m.qtdade<0 AND vcusto_medio=0 AND m.valor>0 THEN
            vvalor   = m.valor ;
          ELSIF m.qtdade<0 AND vcusto_medio=0 AND m.valor<0 THEN
            vvalor   = m.valor ;
          ELSIF s.qtdade<0 AND m.qtdade<0 AND (s.qtdade-m.qtdade)=0 THEN
            vvalor   = s.valor ;
          ELSIF m.qtdade<0 AND (s.qtdade-m.qtdade)>0 THEN
            vvalor   = vcusto_medio * m.qtdade ;
            if m.origem_prefixo='NF' and vcusto_medio=0 then
              vvalor=-(select d.custo_medio from gestao.nfref as a
                      left outer join gestao.nf as b on(b.chave_acesso_nfe=a.chave_acesso_nfe)
                      left outer join gestao.nfdet as c on(c.id_nf=b.id_nf)
                      left outer join gestao.estmovto as d on(d.origem_id=b.id_nf and d.origem_prefixo='NF' and d.id_empresa=b.id_empresa and d.origem_ordem=c.num_item and d.id_produto=c.id_produto 
                                        and d.id_estlocal=c.id_estlocal and d.variante=c.variante and d.validade=COALESCE(c.validade::char(10),' '))
                      where a.id_nf=m.origem_id and c.id_produto=vid_produto limit 1);
            end if;
          ELSIF s.qtdade<=0 OR s.valor<=0 THEN
            -- POR JCS EM 13/03/2017 AS 16:05
            --vvalor   = vcusto_medio * m.qtdade ;
            vvalor   = 0 ;
          ELSE
            vvalor   = s.valor * m.qtdade / s.qtdade;
          END IF;

          s.qtdade = s.qtdade - m.qtdade;
          s.valor  = s.valor - vvalor;
          vtot     = vtot - (vvalor-m.valor);
        END IF;

        IF s.qtdade>0 THEN
          vcusto_medio = s.valor / s.qtdade;
        ELSIF NOT m.qtdade=0 THEN
          vcusto_medio = vvalor / m.qtdade;
        ELSE
          vcusto_medio = vvalor;
        END IF;

        IF NOT (m.valor=vvalor and m.vl_ajuste=vvl_ajuste AND m.custo_medio=vcusto_medio) THEN
          UPDATE gestao.estmovto SET valor=vvalor,vl_ajuste=vvl_ajuste,custo_medio=vcusto_medio WHERE id_estmovto=m.id_estmovto;
        END IF;
        IF m.origem_prefixo='RQ' AND NOT m.valor=vvalor THEN
          UPDATE gestao.req SET contabilizado='N' WHERE id_req=m.origem_id;
        END IF;
      END LOOP;
      IF NOT vtot=0 THEN
        UPDATE gestao.estsaldo SET valor=valor+vtot,data=vdtatual WHERE id_estsaldo=s.id_estsaldo;
      ELSIF NOT s.data=vdtatual OR s.data IS NULL THEN
        UPDATE gestao.estsaldo SET data=vdtatual WHERE id_estsaldo=s.id_estsaldo;
      END IF;
      RETURN NEW;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.atual_estmovto_valor()
  OWNER TO postgres;
--RUN--

DROP TRIGGER atual_estmovto_valor ON gestao.estmovto;

--RUN--IGNORE ERRO

-- CRIA TRIGGER PARA ATUALIZAR VALOR DO MOVTO DE ESTOQUE
CREATE TRIGGER atual_estmovto_valor
  AFTER INSERT OR DELETE 
  ON gestao.estmovto
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.atual_estmovto_valor();
--RUN--

/* *******************************************************
   * GERA REQ PELO LANÇTO REQRESUMIDA                    *
   * REVISADA EM 13/04/2015 17:22 POR JCS                *
   *******************************************************/
CREATE OR REPLACE FUNCTION gestao.reqresumida_gera_req()
  RETURNS trigger AS
$BODY$
    DECLARE vid_empresa  INTEGER;
            vnum_op      INTEGER;
            vdata        DATE;
            vnome        TEXT;
            vorigem      TEXT;
            vtotal       DECIMAL(15,3);
            vid_req      INTEGER;
            vnumero      INTEGER;
            vordem       INTEGER;
            m            RECORD;
            vid_emp_prod int;
            vtp_mov_lote int;
            VLOTE        INT;

    BEGIN
      IF TG_OP='UPDATE' THEN
        RAISE EXCEPTION 'Alteração não permitda!';
      ELSIF TG_OP='DELETE' THEN
        vid_empresa = OLD.id_empresa;
        vdata       = OLD.data;
        vnum_op     = OLD.numero_op;
        vnome       = OLD.nome_requisitante;
        vorigem     = OLD.dest_aplic;
      ELSE
        vid_empresa = NEW.id_empresa;
        vdata       = NEW.data;
        vnum_op     = NEW.numero_op;
        vnome       = NEW.nome_requisitante;
        vorigem     = NEW.dest_aplic;
      END IF;
      vid_req = (SELECT id_req FROM gestao.req WHERE id_empresa=vid_empresa AND data=vdata AND numero_op=vnum_op LIMIT 1);
      IF vid_req IS NULL AND TG_OP='INSERT' THEN
        vnumero = COALESCE((SELECT MAX(numero) FROM gestao.req WHERE id_empresa=vid_empresa),0)+1;
        INSERT INTO gestao.req(
                    id_empresa, numero, data, tipo, origem,
                    nome_requisitante, numero_op, anotacao, status, usuario, id_origem)
            VALUES (vid_empresa, vnumero, vdata, 1, vorigem,
                    vnome, vnum_op, 'LANÇADO SISTEMA', 1, vnome::char(15), new.id_estlocal);
        vid_req = (SELECT id_req FROM gestao.req WHERE id_empresa=vid_empresa AND data=vdata AND numero_op=vnum_op LIMIT 1);
      END IF;
      DELETE FROM gestao.reqd WHERE id_req=vid_req;
      vordem = 0;
      FOR m IN
        SELECT cod_produto,sum(qtdade_pecas) as qtdade_pecas,comprimento,sum(qtdade) as qtdade,id_estlocal, lote,
        (select cod_ccusto from gestao.pcpmaq where (codigo,id_empresa) in(select cod_maquina,vid_empresa from sig.pcpopperfil where numero=vnum_op and id_empresa=CASE WHEN vid_empresa>9000 THEN vid_empresa-9000 ELSE vid_empresa END)) as cod_ccusto,
        (select id_natureza from gestao.pcpmaq where (codigo,id_empresa) in(select cod_maquina,vid_empresa from sig.pcpopperfil where numero=vnum_op and id_empresa=CASE WHEN vid_empresa>9000 THEN vid_empresa-9000 ELSE vid_empresa END)) as id_natureza
        FROM gestao.reqresumida
          WHERE id_empresa=vid_empresa AND data=vdata AND numero_op=vnum_op
          GROUP BY id_empresa,cod_produto,comprimento,id_estlocal,lote
      LOOP
      
        vordem=vordem+1;
        if m.cod_ccusto=0 then
          m.cod_ccusto=null;
        end if;

        if m.id_natureza=0 then
          m.id_natureza=null;
        end if;

        IF TG_OP='INSERT' THEN

          -- BUSCA ID EMPRESA DO PRODUTO
          vid_emp_prod = 0;
          SELECT id_empresa_tabcomp INTO vid_emp_prod FROM gestao.tabcomp WHERE nome_tabcomp='produtos' AND id_empresa=vid_empresa;
          IF vid_emp_prod IS NULL OR vid_emp_prod=0 THEN
            vid_emp_prod = vid_empresa;
          END IF;

          -- VERIFICA TIPO MOVIMENTO DO LOTE
          SELECT lote INTO vtp_mov_lote FROM gestao.produto WHERE id_erp=m.cod_produto::INTEGER and id_empresa=vid_emp_prod;
          IF vtp_mov_lote IS NULL THEN
            vtp_mov_lote=0;
          END IF;

          IF vtp_mov_lote=1 OR vtp_mov_lote=2 THEN
            
            SELECT a.id_lote
              INTO vlote
              FROM gestao.estsaldo A
              LEFT OUTER JOIN gestao.lote B ON (b.id_lote=a.id_lote)
              WHERE a.id_empresa=vid_empresa AND a.id_produto=m.cod_produto::INTEGER AND a.id_estlocal=m.id_estlocal AND a.id_lote>0 AND (a.qtdade-a.qtd_empenhada)>=m.qtdade AND b.situacao='L'
              ORDER BY b.dt_validade LIMIT 1;
            
            IF vlote IS NULL OR vlote=0 THEN              
              UPDATE gestao.req SET situacao='P' WHERE id_req=vid_req;              
            END IF;
          END IF;
        END IF;

        INSERT INTO gestao.reqd (id_empresa, id_req, ordem, id_produto, qtdade, und,
                    comprimento, qtdade_pecas,id_estlocal, qtd_estoque,
                    largura, lastro,cod_ccusto,id_natureza, lote,VALOR)
            VALUES (vid_empresa,vid_req,vordem,m.cod_produto::INTEGER,m.qtdade,' ',
                    m.comprimento,m.qtdade_pecas,m.id_estlocal,m.qtdade,
                    0, 0,m.cod_ccusto,m.id_natureza, m.lote,0);
      END LOOP;

      -- atualiza OP perfil
      IF TG_OP='INSERT' AND NEW.dest_aplic='PERFIL' THEN
        UPDATE sig.pcpopperfil SET data_conclusao=NEW.data,hora_conclusao=to_char(now(),'HH24:MI:SS')::time,turno_conclusao=NEW.turno WHERE numero=NEW.numero_op;
      END IF;

      RETURN NEW;
   END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.reqresumida_gera_req()
  OWNER TO postgres;
--RUN--

DROP TRIGGER gera_req ON gestao.reqresumida;
--RUN--IGNORE ERRO

CREATE TRIGGER gera_req
  AFTER INSERT OR UPDATE OR DELETE 
  ON gestao.reqresumida
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.reqresumida_gera_req();
--RUN--



-------------------------------------------------------------
-- REVISADO POR JCS EM 28/09/2012 AS 18:05
-- VALIDAÇÃO PRODUTO
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.valida_produto()
  RETURNS "trigger" AS
$BODY$

    BEGIN
		IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
			NEW.dt_atual = now();
			NEW.unidade  = UPPER(NEW.unidade);
			NEW.data     = NOW();
			NEW.hora     = NOW();
			IF NEW.cod_contrib='  ' THEN
				NEW.cod_contrib=NULL;
			END IF;

            IF NEW.id_produto_grade=0 THEN
                NEW.id_produto_grade = NULL;
            END IF;

            IF NEW.tx_desc_lote IS NULL THEN
                NEW.tx_desc_lote = 0;
            END IF;
			IF NEW.TX_DESC_LOTE>0 AND NEW.LOTE_MUL_VENDA=0 THEN
				NEW.LOTE_MUL_VENDA = 1;
                NEW.PERMITIR_DIF_LOTE= 1;				
			END IF;			
        END IF;	
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_produto ON gestao.produto;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_produto
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.produto
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_produto();
--RUN--

-------------------------------------------------------------
-- REVISADO POR JCS EM 06/05/2011 AS 17:30
-- VALIAÇÃO FORMAPAG
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.valida_formapag()
  RETURNS "trigger" AS
$BODY$

    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
	  NEW.dt_atual=now();
        END IF;	
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_formapag ON gestao.formapag;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_formapag
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.formapag
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_formapag();
--RUN--

-------------------------------------------------------------
-- REVISADO POR JCS EM 09/05/2011 AS 11:30
-- VALIAÇÃO STICMS
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.valida_sticms()
  RETURNS "trigger" AS
$BODY$

    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
	  NEW.dt_atual=now();
        END IF;	
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_sticms ON gestao.sticms;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_sticms
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.sticms
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_formapag();
--RUN--

-------------------------------------------------------------
-- REVISADO POR JCS EM 08/12/2011 AS 08:52
-- VALIDAÇÃO UNIDADE
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.valida_unidade()
  RETURNS "trigger" AS
$BODY$

    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
	       NEW.unidade  = UPPER(NEW.unidade);
	       NEW.dt_atual = NOW();
        END IF;	
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_unidade ON gestao.unidade;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_unidade
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.unidade
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_unidade();
--RUN--

CREATE OR REPLACE FUNCTION gestao.ajusta_valor_ctpagrupado()
  RETURNS "trigger" AS
$BODY$
    DECLARE vtotal       DECIMAL(15,2);
            vvlagrupado  DECIMAL(15,2);
            vvalor       DECIMAL(15,2);
            vsoma        DECIMAL(15,2); 
            vqtd         INTEGER;
            rec          RECORD;

    BEGIN
      SELECT SUM(valor),count(*) INTO vtotal,vqtd FROM gestao.ctpagrupado WHERE id_entrada=NEW.id_entrada;
      vvlagrupado = NEW.v_fin-COALESCE((SELECT SUM(valor) FROM gestao.ctp WHERE id_ent=NEW.id_entrada),0);
--    Damian 02-03-21 Usar v_fin para agrupamento, pode existir itens que ñ gera ctp (conf. tes)
--    vvlagrupado = NEW.total-COALESCE((SELECT SUM(valor) FROM gestao.ctp WHERE id_ent=NEW.id_entrada),0);
      IF NOT vtotal=vvlagrupado THEN
        vsoma = 0;
        FOR rec IN SELECT id_ctpagrupado,valor FROM gestao.ctpagrupado WHERE id_entrada=NEW.id_entrada
        LOOP
          vqtd   = vqtd - 1;
          IF vqtd=0 THEN
            vvalor = vvlagrupado-vsoma;
          ELSE
            vvalor = rec.valor/vtotal*vvlagrupado;
          END IF;
          UPDATE gestao.ctpagrupado SET valor=vvalor WHERE id_ctpagrupado=rec.id_ctpagrupado;
          vsoma  = vsoma + vvalor;
        END LOOP;        
      END IF;  
      -- ATUALIZA DATA DE LANÇAMENTO
      UPDATE gestao.ctp SET data=NEW.entra WHERE id_ent=NEW.id_entrada;
      UPDATE gestao.ctp SET data=NEW.entra WHERE id_ctp IN (SELECT id_ctp FROM gestao.ctpagrupado WHERE id_entrada=NEW.id_entrada);
      RETURN NEW;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER ajusta_valor_ctpagrupado ON gestao.entradas;
--RUN--IGNORE ERRO

CREATE TRIGGER ajusta_valor_ctpagrupado
  BEFORE UPDATE
  ON gestao.entradas
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.ajusta_valor_ctpagrupado();
--RUN--

CREATE OR REPLACE FUNCTION gestao.atual_numero_entrada() RETURNS trigger AS 
$BODY$
    DECLARE vid_empresa       int4;
    BEGIN
	IF NOT NEW.id_empresa=OLD.id_empresa THEN
           RAISE EXCEPTION 'Impossivel alterar empresa!';
        END IF;
        IF NEW.id_empresa<9000 THEN
          vid_empresa = NEW.id_empresa+9000;
        ELSE
          vid_empresa = NEW.id_empresa-9000;
        END IF;
        IF NOT (NEW.numero   = OLD.numero AND
                NEW.espec    = OLD.espec  AND
                NEW.modelo   = OLD.modelo AND
                NEW.serie    = OLD.serie  AND
                NEW.subse    = OLD.subse  AND
                NEW.id_forne = OLD.id_forne) THEN 
          UPDATE gestao.entradas SET numero=NEW.numero, espec=NEW.espec, modelo=NEW.modelo, serie=NEW.serie, subse=NEW.subse, id_forne=NEW.id_forne
                            WHERE numero=OLD.numero AND modelo=OLD.modelo AND espec=OLD.espec AND serie=OLD.serie AND subse=OLD.subse AND id_forne=OLD.id_forne AND id_empresa=vid_empresa;
        END IF;          
        UPDATE gestao.ctp SET valor=valor WHERE id_ent=new.id_entrada;
        RETURN NEW;  
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER atual_numero_entrada ON gestao.entradas;
--RUN--IGNORE ERRO

CREATE TRIGGER atual_numero_entrada
  AFTER UPDATE
  ON gestao.entradas
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.atual_numero_entrada();
--RUN--

-------------------------------------
-- TABELA: ENTRADAS               --
-------------------------------------
CREATE OR REPLACE FUNCTION gestao.bloqmovto_entradas()
  RETURNS trigger AS
$BODY$
    DECLARE
      v_data1        DATE;
      v_data2        DATE;
      v_empresa      INT4;
      v_modulo       VARCHAR(30);
      v_bloq         CHAR(1);
      v_periodo      DATE;

    BEGIN
      -- parametros para consulta
      v_modulo = 'COMPRAS';
      IF TG_OP='INSERT' THEN
        v_data1      = NEW.entra;
        v_empresa    = NEW.id_empresa;
      ELSIF  TG_OP='UPDATE' THEN
        v_data1      = NEW.entra;
        v_data2      = OLD.entra;
        v_empresa = NEW.id_empresa;
      ELSE
        v_data1      = OLD.entra;
        v_empresa    = OLD.id_empresa;
      END IF;
      -- fim parametros

      -- AJUSTE MODELO PARA NULL, QUANDO VIER BRANCO
      IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
        IF new.modelo=' ' THEN
          new.modelo='';
        END IF;
      END IF;

      v_data1 = to_char(v_data1,'YYYY-MM')||'-01';
      v_data2 = to_char(v_data2,'YYYY-MM')||'-01';
      SELECT bloqueado,periodo INTO v_bloq,v_periodo FROM gestao.bloqmovto WHERE id_empresa=v_empresa AND modulo=v_modulo AND periodo IN (v_data1,v_data2) AND bloqueado='S' LIMIT 1;
      IF v_bloq='S' THEN
        RAISE EXCEPTION 'Movimento bloqueado para a tabela "%" do módulo "%" no período de %.', TG_RELNAME, v_modulo, to_char(v_periodo,'MM/YYYY');
      END IF;
      IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
        RETURN NEW; 
      ELSE
        RETURN OLD; 
      END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER bloqmovto_entradas ON gestao.entradas;
--RUN--IGNORE ERRO

CREATE TRIGGER bloqmovto_entradas
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.entradas
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.bloqmovto_entradas();
--RUN--

CREATE OR REPLACE FUNCTION gestao.atual_qtdade_recebida_ocd()
  RETURNS "trigger" AS
$BODY$
    DECLARE vid_empresa   int4;
            vid_oc        int4;
            vid_ocd       int4;
            vid_produto   int4;
            vqtd_rec      numeric(15,3);
            vdt_ult_entrada date;
            vfatorconv    NUMERIC(15,6);
            vund_oc       CHAR(6);
	    vrec          RECORD;
	    vsituacao     character(1);
            
    BEGIN

        IF TG_OP='DELETE' OR TG_OP='UPDATE' THEN
          IF OLD.num_oc IS NOT NULL THEN

            -- consulta empresa
            SELECT id_empresa,situacao INTO vid_empresa,vsituacao FROM gestao.entradas WHERE id_entrada=OLD.id_entrada;

	    IF NOT vsituacao='I' THEN --Não entra se for pré-importação

              -- consulta id_oc   
              SELECT id_oc INTO vid_oc FROM gestao.oc WHERE id_empresa=vid_empresa AND numero=OLD.num_oc;

              -- consulta id_ocd   
              SELECT id_ocd INTO vid_ocd FROM gestao.ocd WHERE id_oc=vid_oc AND item=OLD.item_oc;

              -- soma quantidade
              --SELECT sum(qtd) INTO vqtd_rec FROM gestao.entradet A 
              -- LEFT OUTER JOIN gestao.entradas B ON (a.id_entrada=b.id_entrada) 
              -- WHERE B.id_empresa=vid_empresa AND A.num_oc=OLD.num_oc AND A.item_oc=OLD.item_oc AND NOT A.id_entradet=OLD.id_entradet;

              SELECT id_ocd,und INTO vid_ocd,vund_oc FROM gestao.ocd WHERE id_oc=vid_oc AND item=OLD.item_oc;

              --IF vid_ocd IS NULL THEN
              --  RAISE EXCEPTION 'Item % não existe na OC %. Operação cancelada!',OLD.item_oc,OLD.num_oc;
              --END IF;

              -- soma quantidade recebida            
              vqtd_rec=0;
              FOR vrec IN SELECT sum(qtd) as qtd,a.und FROM gestao.entradet A
                          LEFT OUTER JOIN gestao.entradas B ON (a.id_entrada=b.id_entrada)
                          WHERE B.id_empresa=vid_empresa AND A.num_oc=OLD.num_oc AND A.item_oc=OLD.item_oc AND NOT A.id_entradet=OLD.id_entradet
                          GROUP BY a.und
              LOOP
                -- conversão unidade medida
                vfatorconv = (SELECT fator
                                FROM gestao.fatconversao A
                                LEFT OUTER JOIN gestao.produto B ON (a.id_produto=b.id_produto)
                                WHERE b.id_empresa=(CASE WHEN vid_empresa>9000 THEN vid_empresa-9000 ELSE vid_empresa END) AND b.id_erp=OLD.produ AND unid_conv=vrec.und);
                IF NOT vund_oc=OLD.und AND vfatorconv IS NOT NULL AND vfatorconv>0 THEN
                  vqtd_rec = vqtd_rec + (vrec.qtd * vfatorconv);
                ELSE
                  vqtd_rec = vqtd_rec + vrec.qtd;
                END IF;

              END LOOP;


              IF vqtd_rec IS NULL THEN
                vqtd_rec = 0;
              END IF;

              -- atualiza gestao.ocd
              IF vid_ocd IS NOT NULL THEN
                UPDATE gestao.ocd SET qtd_recebida=vqtd_rec WHERE id_ocd=vid_ocd;               
		      END IF;

            END IF;
          END IF;
        END IF;

        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          IF NEW.num_oc=0 THEN
            NEW.num_oc=null;
          END IF;
          IF NEW.num_oc IS NOT NULL THEN

            -- consulta empresa
            SELECT id_empresa,situacao INTO vid_empresa,vsituacao FROM gestao.entradas WHERE id_entrada=NEW.id_entrada;

	    IF NOT vsituacao='I' THEN --Não entra se for pré-importação

              -- consulta id_oc   
              SELECT id_oc INTO vid_oc FROM gestao.oc WHERE id_empresa=vid_empresa AND numero=NEW.num_oc;
              IF vid_oc IS NULL THEN
                RAISE EXCEPTION 'Número da OC (%) não existe. Operação cancelada!',NEW.num_oc;
              END IF;

              -- consulta id_ocd   
              SELECT id_ocd,und INTO vid_ocd,vund_oc FROM gestao.ocd WHERE id_oc=vid_oc AND item=NEW.item_oc;
              IF vid_ocd IS NULL THEN
                RAISE EXCEPTION 'Item % não existe na OC %. Operação cancelada!',NEW.item_oc,NEW.num_oc;
              END IF;
            
              -- confere produto
              IF vid_produto>0 AND NEW.produ>0 AND NOT vid_produto=NEW.produ THEN
                RAISE EXCEPTION 'Produto (%) informado no item % da OC % não confere com produto informado na entrada. Operação cancelada!',NEW.produ,NEW.num_oc,NEW.item_oc;
              END IF;

              -- soma quantidade
              --SELECT sum(qtd) INTO vqtd_rec FROM gestao.entradet A 
              -- LEFT OUTER JOIN gestao.entradas B ON (a.id_entrada=b.id_entrada) 
              -- WHERE B.id_empresa=vid_empresa AND A.num_oc=NEW.num_oc AND A.item_oc=NEW.item_oc AND NOT A.id_entradet=NEW.id_entradet;

              -- soma quantidade recebida            
              vqtd_rec=0;
              FOR vrec IN SELECT sum(qtd) as qtd,a.und FROM gestao.entradet A
                          LEFT OUTER JOIN gestao.entradas B ON (a.id_entrada=b.id_entrada)
                          WHERE B.id_empresa=vid_empresa AND A.num_oc=NEW.num_oc AND A.item_oc=NEW.item_oc AND NOT A.id_entradet=NEW.id_entradet
                          GROUP BY a.und
              LOOP
                -- conversão unidade medida
                vfatorconv = (SELECT fator
                                FROM gestao.fatconversao A
                                LEFT OUTER JOIN gestao.produto B ON (a.id_produto=b.id_produto)
                                WHERE b.id_empresa=(CASE WHEN vid_empresa>9000 THEN vid_empresa-9000 ELSE vid_empresa END) AND b.id_erp=NEW.produ AND unid_conv=vrec.und);
                IF NOT vund_oc=NEW.und AND vfatorconv IS NOT NULL AND vfatorconv>0 THEN
                  vqtd_rec = vqtd_rec + (vrec.qtd * vfatorconv);
                ELSE
                  vqtd_rec = vqtd_rec + vrec.qtd;
                END IF;
              END LOOP;

              -- busca data da ultima entrada da oc corrente
              SELECT max(b.entra) INTO vdt_ult_entrada FROM gestao.entradet A 
                LEFT OUTER JOIN gestao.entradas B ON (a.id_entrada=b.id_entrada) 
                WHERE B.id_empresa=vid_empresa AND A.num_oc=NEW.num_oc;

    	      -- conversão unidade medida (ENTRADA) - por jcs em 03/03/2016 às 10:30
              vfatorconv = (SELECT fator
                              FROM gestao.fatconversao A
                              LEFT OUTER JOIN gestao.produto B ON (a.id_produto=b.id_produto)
                              WHERE b.id_empresa=(CASE WHEN vid_empresa>9000 THEN vid_empresa-9000 ELSE vid_empresa END) AND b.id_erp=NEW.produ AND unid_conv=NEW.und);
             IF NOT vund_oc=NEW.und AND vfatorconv IS NOT NULL AND vfatorconv>0 THEN
                vqtd_rec = vqtd_rec + (NEW.qtd * vfatorconv);              
             ELSE
                vqtd_rec = vqtd_rec + NEW.qtd;
             END IF;
             RAISE NOTICE 'ENTRADA - vfatorconv % - vqtd_rec %',vfatorconv,vqtd_rec;

	      -- conversão unidade medida (OC) - por jcs em 03/03/2016 às 10:30
              IF NOT vund_oc=NEW.und THEN 
                vfatorconv = (SELECT fator
                                FROM gestao.fatconversao A
                                LEFT OUTER JOIN gestao.produto B ON (a.id_produto=b.id_produto)
                                WHERE b.id_empresa=(CASE WHEN vid_empresa>9000 THEN vid_empresa-9000 ELSE vid_empresa END) AND b.id_erp=NEW.produ AND unid_conv=vund_oc);
               IF vfatorconv IS NOT NULL AND vfatorconv>0 THEN
                  vqtd_rec = vqtd_rec / vfatorconv;
               END IF;
             END IF;
             RAISE NOTICE 'OC - vfatorconv % - vqtd_rec %',vfatorconv,vqtd_rec;

              -- atualiza gestao.ocd
              UPDATE gestao.ocd SET qtd_recebida=vqtd_rec WHERE id_ocd=vid_ocd;               
              -- atualiza gestao.oc - data da situação
              IF vdt_ult_entrada IS NOT NULL THEN
                UPDATE gestao.oc SET data_situacao=vdt_ult_entrada WHERE id_oc=vid_oc;
              END IF;
            END IF;
          END IF;

          IF NEW.id_pcpmaq=0 THEN
            NEW.id_pcpmaq=null;
          END IF;

        END IF;

        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER atual_qtd_recebida_ocd ON gestao.entradet;
--RUN--IGNORE ERRO

CREATE TRIGGER atual_qtd_recebida_ocd BEFORE INSERT OR UPDATE OR DELETE
   ON gestao.entradet FOR EACH ROW
   EXECUTE PROCEDURE gestao.atual_qtdade_recebida_ocd();
--RUN--

-------------------------------------
-- TABELA: ENTRADET              --
-------------------------------------
CREATE OR REPLACE FUNCTION gestao.bloqmovto_entradet()
  RETURNS trigger AS
$BODY$
    DECLARE
      v_data1        DATE;
      v_data2        DATE;
      v_empresa      INT4;
      v_modulo       VARCHAR(30);
      v_bloq         CHAR(1);
      v_periodo      DATE;

    BEGIN
      -- parametros para consulta
      v_modulo = 'COMPRAS';
      IF TG_OP='INSERT' THEN
        SELECT entra, id_empresa INTO v_data1, v_empresa FROM gestao.entradas WHERE id_entrada=NEW.id_entrada;
      ELSIF  TG_OP='UPDATE' THEN
        SELECT entra, id_empresa INTO v_data1, v_empresa FROM gestao.entradas WHERE id_entrada=NEW.id_entrada;
      ELSE
        SELECT entra, id_empresa INTO v_data1, v_empresa FROM gestao.entradas WHERE id_entrada=OLD.id_entrada;
      END IF;
      -- fim parametros

      v_data1 = to_char(v_data1,'YYYY-MM')||'-01';
      v_data2 = to_char(v_data2,'YYYY-MM')||'-01';
      SELECT bloqueado,periodo INTO v_bloq,v_periodo FROM gestao.bloqmovto WHERE id_empresa=v_empresa AND modulo=v_modulo AND periodo IN (v_data1,v_data2) AND bloqueado='S' LIMIT 1;
      IF v_bloq='S' THEN
        RAISE EXCEPTION 'Movimento bloqueado para a tabela "%" do módulo "%" no período de %.', TG_RELNAME, v_modulo, to_char(v_periodo,'MM/YYYY');
      END IF;
      IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
        RETURN NEW; 
      ELSE
        RETURN OLD; 
      END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER bloqmovto_entradet ON gestao.entradet;
--RUN--IGNORE ERRO

CREATE TRIGGER bloqmovto_entradet
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.entradet
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.bloqmovto_entradet();
--RUN--

CREATE OR REPLACE FUNCTION gestao.entradet_controle_estterceiro()
  RETURNS "trigger" AS
$BODY$
    DECLARE
      ventrada       RECORD;
      vpoder_terc    CHAR(1);
      vorigem        CHAR(20);
      vnum_remessa   INTEGER;
      vid_empmatriz  INTEGER;
      vqtddisp       NUMERIC(15,3);

    BEGIN
      IF TG_OP='DELETE' THEN
        vorigem = 'ENTRADET'||OLD.id_entradet;
        DELETE FROM gestao.estterceiro WHERE origem=vorigem;
        RETURN OLD;
      END IF;

      vorigem = 'ENTRADET'||NEW.id_entradet;

      -- busca dados da empresa
      SELECT id_matriz INTO vid_empmatriz FROM gestao.empresa WHERE id_empresa in(select id_empresa from gestao.entradas where id_entrada=NEW.id_entrada limit 1);

      IF (SELECT schemaname FROM pg_tables WHERE schemaname='gerente' AND tablename='tes')='gerente' THEN
        SELECT poder_terc INTO vpoder_terc FROM gestao.tes WHERE codigo=NEW.cod_tes and id_empresa=vid_empmatriz;
      ELSE
        SELECT poder_terc INTO vpoder_terc FROM gestao.tes  WHERE codigo=NEW.cod_tes and id_empresa=vid_empmatriz;
      END IF; 

      IF vpoder_terc NOT IN ('R','D','O') THEN
        DELETE FROM gestao.estterceiro WHERE origem=vorigem;
        RETURN NEW;
      END IF;

      RETURN NEW;
    END;
$BODY$
  LANGUAGE 'plpgsql';
--RUN--

DROP TRIGGER entradet_controle_estterceiro ON gestao.entradet;
--RUN--IGNORE ERRO

CREATE TRIGGER entradet_controle_estterceiro
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.entradet
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.entradet_controle_estterceiro()
--RUN--

CREATE OR REPLACE FUNCTION gestao.ajusta_valor_detnatureza()
  RETURNS "trigger" AS
$BODY$
    DECLARE vtotal       DECIMAL(15,2);
            vvalor       DECIMAL(15,2);
            vsoma        DECIMAL(15,2); 
            vqtd         INTEGER;
            rec          RECORD;

    BEGIN
      SELECT SUM(valor),count(*) INTO vtotal,vqtd FROM gestao.detnatureza WHERE id_empresa=NEW.id_empresa AND origem='CTP' AND id_origem=NEW.id_ctp::text;
      IF NOT vtotal=NEW.valor THEN
        vsoma = 0;
        FOR rec IN SELECT id_detnatureza,valor FROM gestao.detnatureza WHERE id_empresa=NEW.id_empresa AND origem='CTP' AND id_origem=NEW.id_ctp::text
        LOOP
          vqtd   = vqtd - 1;
          IF vqtd=0 THEN
            vvalor = NEW.valor-vsoma;
          ELSE
            vvalor = rec.valor/vtotal*NEW.valor;
          END IF;
          UPDATE gestao.detnatureza SET valor=vvalor WHERE id_detnatureza=rec.id_detnatureza;
          vsoma  = vsoma + vvalor;
        END LOOP;        
      END IF;  
      RETURN NEW;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER ajusta_valor_detnatureza ON gestao.ctp;
--RUN--IGNORE ERRO

CREATE TRIGGER ajusta_valor_detnatureza
  BEFORE UPDATE
  ON gestao.ctp
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.ajusta_valor_detnatureza();
--RUN--

-- FUNÇÃO PARA ATUALIZAR O SALDO DO CTP ANTES DE CONFIRMAR INCLUSÃO/ALTERAÇÃO NO CTP
CREATE OR REPLACE FUNCTION gestao.atual_saldo_ctp() RETURNS trigger AS 
$BODY$
    DECLARE vid_ctp       int4;
            vid_lancto    int4;
            vorigem       char(20);
            vcomplemento  char(30);
            vcod_ccusto   int4;
            vid_natureza  int4;
            vcredor       int4;
            vid_empresa   int4;
    BEGIN

      -- EXCLUIR LANÇAMENTO CAIXA/BANCOS
      IF TG_OP='DELETE' THEN
        vorigem       = 'LQCX' || OLD.id_ctp;
        DELETE FROM gestao.lanctos WHERE origem = vorigem;        
	RAISE NOTICE 'DELETE CTP: ID % / NUMERO %',old.id_ctp,old.numero;
        RETURN OLD;  
      END IF;

      IF TG_OP='UPDATE' THEN
        IF NOT old.id_ctp=new.id_ctp THEN
          RAISE EXCEPTION 'Tentativa de alteração da Id do contas a pagar. Operação cancelada!';
        END IF;
	RAISE NOTICE 'UPDATE CTP: ID % / NUMERO %',NEW.id_ctp,NEW.numero;
      ELSE
	RAISE NOTICE 'INSERT CTP: ID % / NUMERO %',NEW.id_ctp,NEW.numero;
      END IF;

      IF NEW.id_ent=0 THEN
        NEW.id_ent = NULL;
      END IF;	

      -- EXCLUIR LANÇAMENTO CAIXA/BANCOS
      IF NOT new.sit_contabil=52 THEN
        vorigem       = 'LQCX' || NEW.id_ctp;
        DELETE FROM gestao.lanctos WHERE origem = vorigem;        
      END IF;

      -- DATA DE LANÇAMENTO
      IF NEW.id_ent IS NULL THEN 
        NEW.data = (SELECT min(entra) FROM gestao.entradas WHERE id_entrada IN (SELECT id_entrada FROM gestao.ctpagrupado WHERE id_ctp=NEW.id_ctp));
      ELSE
        NEW.data = (SELECT entra FROM gestao.entradas WHERE id_entrada=NEW.id_ent);
      END IF;
      IF NEW.data IS NULL THEN
        NEW.data = NEW.emiss;
      END IF;

      IF new.pago IS NULL THEN
        new.pago := 0;
      END IF;
      IF new.situacao='C' THEN
        new.saldo := 0;
      ELSIF new.sit_contabil=51 THEN --LIQUIDADO POR OUTRA OPERAÇÃO 
        new.saldo    := 0;
        new.situacao := 'Q';
      ELSIF new.sit_contabil=52 THEN --LIQUIDADO COM LANÇAMENTO CAIXA/BANCO
        new.saldo    := 0;
        new.situacao := 'Q';
         
        -- LANÇAMENTO CAIXA/BANCO
        vorigem       = 'LQCX' || NEW.id_ctp;
        IF NEW.id_ent IS NULL THEN
          SELECT id_forne INTO vcredor 
            FROM gestao.entradas 
           WHERE id_entrada IN (SELECT id_entrada FROM gestao.ctpagrupado WHERE id_ctp=NEW.id_ctp) LIMIT 1;
        ELSE
          SELECT id_forne INTO vcredor 
            FROM gestao.entradas 
           WHERE id_entrada=NEW.id_ent;
        END IF;
        IF vcredor IS NULL THEN
          vcredor = NEW.credor;
        END IF;
        SELECT substring(nome,1,30) INTO vcomplemento FROM sig.forne WHERE id_forne=vcredor;
        SELECT cod_ccusto, id_natureza INTO vcod_ccusto,vid_natureza FROM gestao.detnatureza WHERE origem='CTP' AND id_origem=new.id_ctp::text ORDER BY ordem LIMIT 1;
        IF vid_natureza IS NULL THEN
          vid_natureza = 0 ;
        END IF;
        SELECT id INTO vid_lancto FROM gestao.lanctos WHERE origem=vorigem LIMIT 1;
        SELECT id_empresa_tabcomp INTO vid_empresa FROM gestao.tabcomp WHERE id_empresa=new.id_empresa AND nome_tabcomp='lanctos';
        IF vid_lancto IS NULL THEN
          INSERT INTO gestao.lanctos(
                      id_empresa, banco, dt_lancto, dt_movto, numero, valor, tipo, 
                      saldo, id_natureza, complemento, compensado, origem, cod_ccusto,
                      ap_res_considerar)
              VALUES (COALESCE(vid_empresa,new.id_empresa), new.porta, now(), new.emiss, new.numero, new.valor, 'S', 
                      0, vid_natureza, vcomplemento, 0, vorigem, vcod_ccusto,
                      0);
        ELSE
          UPDATE gestao.lanctos
             SET banco=new.porta, dt_movto=new.emiss, numero=new.numero, 
                 valor=new.valor, tipo='S',  id_natureza=vid_natureza, complemento=vcomplemento,
                  cod_ccusto=vcod_ccusto ,id_empresa=COALESCE(vid_empresa,new.id_empresa)
           WHERE id=vid_lancto;
        END IF;
      ELSE        
        new.saldo := new.valor + new.juros + new.vl_despesas - new.desco - new.pago;
        IF new.saldo=0 THEN
          new.situacao := 'Q';
        ELSIF new.situacao = 'Q' OR new.situacao=' ' THEN
          new.situacao := 'A';
        END IF; 
      END IF;
      -- ATUALIZA JUROS, DESCONTO, DESPESAS  NO SISTEMA FISCAL --
      IF NEW.id_empresa>9000 AND NOT NEW.status=3 AND NOT NEW.origem_lancto IN ('OU','AD') THEN
        SELECT id_ctp INTO vid_ctp FROM ONLY gestao.ctp WHERE id_empresa=NEW.id_empresa-9000 AND credo=NEW.credo AND numero=NEW.numero;
        IF vid_ctp IS NULL THEN
          -- DEIXAR LINHA ABAIXO COMO NOTICE - JCS EM 05/11/2013 - 10:30
          RAISE NOTICE 'Contas a pagar do Credor (%)  com o Número (%) não existe no sistema fiscal!. Operação cancelada!', new.credo, new.numero;
        ELSE
          UPDATE ONLY gestao.ctp SET valor=new.valor, juros=new.juros, desco=new.desco, vl_despesas=NEW.vl_despesas WHERE id_ctp=vid_ctp;
        END IF;
      END IF;
      -- FIM --
      RETURN NEW;  
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER atual_saldo_ctp ON gestao.ctp;
--RUN--IGNORE ERRO

CREATE TRIGGER atual_saldo_ctp
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.ctp
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.atual_saldo_ctp();
--RUN--

-------------------------------------
-- TABELA: CTP                     --
-------------------------------------
CREATE OR REPLACE FUNCTION gestao.bloqmovto_ctp()
  RETURNS trigger AS
$BODY$
    DECLARE
      v_data1        DATE;
      v_data2        DATE;
      v_empresa      INT4;
      v_modulo       VARCHAR(30);
      v_bloq         CHAR(1);
      v_periodo      DATE;

    BEGIN
      -- parametros para consulta
      v_modulo = 'CTP';
      IF TG_OP='INSERT' THEN
        v_data1      = NEW.data;
        v_empresa    = NEW.id_empresa;
      ELSIF  TG_OP='UPDATE' THEN
        -- SE FOR PROVISORIO " NÃO BLOQUEIA "
        IF NEW.situacao='P' THEN
           RETURN NEW;
        END IF;
        -- CONFERENCIA CAMPOS PRINCIPAIS
        IF NEW.numero =OLD.numero AND
           NEW.data   =OLD.data   AND
           NEW.credo  =OLD.credo  AND
           NEW.valor  =OLD.valor  AND
           NEW.id_conta  =OLD.id_conta AND
           NOT OLD.situacao = 'P' THEN
          RETURN NEW;
        END IF;        
        v_data1      = NEW.data;
        v_data2      = OLD.data;
        v_empresa = NEW.id_empresa;
      ELSE
        -- SE FOR PROVISORIO " NÃO BLOQUEIA "
        IF OLD.situacao='P' THEN
           RETURN OLD;
        END IF;
        
        v_data1      = OLD.data;
        v_empresa    = OLD.id_empresa;
      END IF;
      -- fim parametros

      v_data1 = to_char(v_data1,'YYYY-MM')||'-01';
      v_data2 = to_char(v_data2,'YYYY-MM')||'-01';
      SELECT bloqueado,periodo INTO v_bloq,v_periodo FROM gestao.bloqmovto WHERE id_empresa=v_empresa AND modulo=v_modulo AND periodo IN (v_data1,v_data2) AND bloqueado='S' LIMIT 1;
      IF v_bloq='S' THEN
        RAISE EXCEPTION 'Movimento bloqueado para a tabela "%" do módulo "%" no período de %. Empresa: %', TG_RELNAME, v_modulo, to_char(v_periodo,'MM/YYYY'),v_empresa ;
      END IF;
      IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
        RETURN NEW; 
      ELSE
        RETURN OLD; 
      END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER bloqmovto_ctp ON gestao.ctp;
--RUN--IGNORE ERRO

CREATE TRIGGER bloqmovto_ctp
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.ctp
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.bloqmovto_ctp();
--RUN--

-- FUNÇÃO PARA ATUALIZAR O VALOR PAGO DO CTP APOS INC/ALT/EXC DE PAGAMENTO
CREATE OR REPLACE FUNCTION gestao.atual_vlpago_ctp()
  RETURNS trigger AS
$BODY$
    DECLARE vid_ctp       int4;
            vvlpag        numeric(15,2);
            vvldesc       numeric(15,2);
            vvljuros      numeric(15,2);
            vforma        SMALLINT; 
    BEGIN
        IF TG_OP='INSERT' THEN
           vid_ctp    := new.id_ctp;
           vforma     := new.forma;
        ELSIF TG_OP='UPDATE' THEN
           IF NOT old.id_ctp=new.id_ctp THEN
              RAISE EXCEPTION 'Tentativa de alteração da Id do contas a pagar. Operação cancelada!';
           END IF;
           vid_ctp    := new.id_ctp;
           vforma     := new.forma;           
        ELSIF TG_OP='DELETE' THEN
           vid_ctp    := old.id_ctp;
           vforma     := old.forma;
        END IF;

        --IF vid_ctp IS NOT NULL THEN
        IF vid_ctp IS NOT NULL and vforma<>14 THEN        
           SELECT SUM(valor),SUM(vl_desconto),sum(vl_juros) INTO vvlpag,vvldesc,vvljuros FROM ONLY gestao.pagtos WHERE id_ctp=vid_ctp;
           IF vvlpag IS NULL THEN
             vvlpag   := 0 ;
             vvldesc  := 0 ;
             vvljuros :=0;
           END IF;
           UPDATE ONLY gestao.ctp SET pago=vvlpag,desco=vvldesc,juros=vvljuros WHERE id_ctp=vid_ctp;
        END IF;
        IF TG_OP='DELETE' THEN
            RETURN OLD;
        ELSE
            RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.atual_vlpago_ctp()
  OWNER TO postgres;
--RUN--

DROP TRIGGER atual_vlpago_ctp ON gestao.pagtos;
--RUN--IGNORE ERRO

CREATE TRIGGER atual_vlpago_ctp
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.pagtos
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.atual_vlpago_ctp();
--RUN--

-------------------------------------
-- TABELA: PAGTOS                  --
-------------------------------------
CREATE OR REPLACE FUNCTION gestao.bloqmovto_pagtos()
  RETURNS trigger AS
$BODY$
    DECLARE
      v_data1        DATE;
      v_data2        DATE;
      v_empresa      INT4;
      v_modulo       VARCHAR(30);
      v_bloq         CHAR(1);
      v_periodo      DATE;

    BEGIN
      -- parametros para consulta

      IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
	    IF NEW.id_recbto=0 THEN
		  NEW.id_recbto = NULL;
		END IF;
      END IF;


      v_modulo = 'CTP';
      IF TG_OP='INSERT' THEN
        -- SER FOR ATUALIZAÇÃO DO GERENCIAL, NÃO BLOQUEAR
        IF NEW.id_pagto>90000000 THEN 
          RETURN NEW;
        END IF;
        v_data1 = NEW.data;
        SELECT id_empresa INTO v_empresa FROM gestao.ctp WHERE id_ctp=NEW.id_ctp;
      ELSIF  TG_OP='UPDATE' THEN
        -- SER FOR ATUALIZAÇÃO DO GERENCIAL, NÃO BLOQUEAR
        IF NEW.id_pagto>90000000 THEN 
          RETURN NEW;
        END IF;

        -- CONFERENCIA CAMPOS PRINCIPAIS
        IF NEW.id_ctp   =OLD.id_ctp AND
           NEW.data     =OLD.data   AND
           NEW.valor    =OLD.valor  AND
           NEW.vl_juros =OLD.vl_juros AND
           NEW.vl_desconto =OLD.vl_desconto AND
           NEW.id_banco    =OLD.id_banco THEN
          RETURN NEW;
        END IF;

        v_data1 = NEW.data;
        SELECT id_empresa INTO v_empresa FROM gestao.ctp WHERE id_ctp=NEW.id_ctp;
      ELSE
        -- SER FOR ATUALIZAÇÃO DO GERENCIAL, NÃO BLOQUEAR
        IF OLD.id_pagto>90000000 THEN 
          RETURN OLD;
        END IF;
        v_data1 = OLD.data;
        SELECT id_empresa INTO v_empresa FROM gestao.ctp WHERE id_ctp=OLD.id_ctp;
      END IF;
      -- fim parametros

      v_data1 = to_char(v_data1,'YYYY-MM')||'-01';
      v_data2 = to_char(v_data2,'YYYY-MM')||'-01';
      SELECT bloqueado,periodo INTO v_bloq,v_periodo FROM gestao.bloqmovto WHERE id_empresa=v_empresa AND modulo=v_modulo AND periodo IN (v_data1,v_data2) AND bloqueado='S' LIMIT 1;
      IF v_bloq='S' THEN
        RAISE EXCEPTION 'Movimento bloqueado para a tabela "%" do módulo "%" no período de %.', TG_RELNAME, v_modulo, to_char(v_periodo,'MM/YYYY');
      END IF;
      IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
        RETURN NEW; 
      ELSE
        RETURN OLD; 
      END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER bloqmovto_pagtos ON gestao.pagtos;
--RUN--IGNORE ERRO

CREATE TRIGGER bloqmovto_pagtos
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.pagtos
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.bloqmovto_pagtos();
--RUN--

-- FUNÇÃO PARA LANÇAR PAGAMENTO SISTEMA FISCAL APOS INC/ALT/EXC DE FISCAL GERENCIAL
CREATE OR REPLACE FUNCTION gestao.lanca_pagtos_fiscal() RETURNS trigger AS 
$BODY$
    DECLARE vid_ctp       int4;
            rger          RECORD;
            rfis          RECORD;
            rpag          RECORD;
    BEGIN
	IF TG_OP='INSERT' THEN
           vid_ctp    := new.id_ctp; 
        ELSIF TG_OP='UPDATE' THEN
           vid_ctp    := new.id_ctp; 
	ELSIF TG_OP='DELETE' THEN
           vid_ctp    := old.id_ctp; 
        END IF;
        SELECT id_ctp,id_empresa,credo,numero,status,juros,desco,valor,vl_despesas,origem_lancto INTO rger FROM gestao.ctp WHERE id_ctp=vid_ctp;
--	IF rger.id_empresa>9000 AND NOT rger.status=3 AND NOT COALESCE(rger.origem_lancto,' ') IN ('OU','AD') THEN
	IF rger.id_empresa>9000 AND NOT rger.status=3 THEN
          -- BUSCA TITULO NO SISTEMA FISCAL
          SELECT id_ctp INTO rfis FROM gestao.ctp WHERE id_empresa=rger.id_empresa-9000 AND credo=rger.credo AND numero=rger.numero;
          IF rfis.id_ctp IS NULL THEN
            RAISE NOTICE 'Contas a pagar do Credor (%)  com o Número (%) não existe no sistema fiscal!. Operação cancelada!', rger.credo, rger.numero;
	  ELSE
            -- ATUALIZA VALOR E DESPESAS NO FISCAL
            UPDATE gestao.ctp SET vl_despesas=rger.vl_despesas WHERE id_ctp=rfis.id_ctp;         
            -- ATUALIZA PAGAMENTO FISCAL
            DELETE FROM gestao.pagtos WHERE id_ctp=rfis.id_ctp;
            FOR rpag IN SELECT * FROM ONLY gestao.pagtos WHERE id_ctp=rger.id_ctp
            LOOP
              DELETE FROM gestao.pagtos WHERE id_pagto=(rpag.id_pagto+90000000);
              INSERT INTO gestao.pagtos (id_pagto, id_credor, id_ctp, pagto_eventual, numero, data, valor, vl_juros, vl_desconto, obs, forma, id_banco, id_banco_cred, data_movto, vl_despesas,contabilizado,num_cheque,dt_para)
                              VALUES (rpag.id_pagto+90000000, rpag.id_credor, rfis.id_ctp, rpag.pagto_eventual, rpag.numero, rpag.data, rpag.valor, rpag.vl_juros, rpag.vl_desconto, rpag.obs, rpag.forma, rpag.id_banco, rpag.id_banco_cred, rpag.data_movto,rpag.vl_despesas,rpag.contabilizado,rpag.num_cheque,rpag.dt_para);
            END LOOP;
          END IF; 
        END IF;
        IF TG_OP='DELETE' THEN
            RETURN OLD;
        ELSE       
            RETURN NEW;  
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER lanca_pagtos_fiscal ON gestao.pagtos;
--RUN--IGNORE ERRO

CREATE TRIGGER lanca_pagtos_fiscal
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.pagtos
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.lanca_pagtos_fiscal();
--RUN--

-- FUNÇÃO PARA ATUALIZAR O VALOR DO CTP APOS INC/ALT/EXC DE CTPAGRUPADO
CREATE OR REPLACE FUNCTION gestao.ctpagrupado_atual_valor() RETURNS trigger AS 
$BODY$
    DECLARE vvlagr        numeric(15,2);
            vidctp        integer;
    BEGIN
        IF TG_OP='DELETE' THEN
          vidctp = OLD.id_ctp;
        ELSE
          vidctp = NEW.id_ctp;
        END IF;	
        vvlagr = (SELECT SUM(valor) FROM ONLY gestao.ctpagrupado WHERE id_ctp=vidctp);
        IF vvlagr IS NULL THEN
          -- GRAVA ZERO NO VALOR CASO O CTP TENHA BAIXAS VINCULADAS
          UPDATE ONLY gestao.ctp SET valor = 0 WHERE id_ctp=vidctp AND pago>0; 
          -- EXCLUI O CTP SE O MESMO NÃO TIVER NENHUMA BAIXAS VINCULADAS
          DELETE FROM gestao.ctp WHERE id_ctp=vidctp AND pago=0;
        ELSE
          UPDATE ONLY gestao.ctp SET valor = vvlagr WHERE id_ctp=vidctp;
        END IF;
        IF TG_OP='
        DELETE' THEN
            RETURN OLD;
        ELSE       
            RETURN NEW;  
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER ctpagrupado_atual_valor ON gestao.ctpagrupado;
--RUN--IGNORE ERRO

CREATE TRIGGER ctpagrupado_atual_valor
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.ctpagrupado
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.ctpagrupado_atual_valor();
--RUN--

-------------------------------------------------------------
-- REVISADO POR JCS EM 05/09/2012 AS 12:45
-- VALIAÇÃO PAUTA
-- ALTERADO POR HENRIQUE EM 28/11/2013 AS 17:10
-- ALTERAR ID_EMPRESA PARA NULL
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.valida_pauta()
  RETURNS "trigger" AS
$BODY$

    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
	  NEW.dt_atual=now();
          IF NEW.id_empresa = 0 THEN
            NEW.id_empresa = null;
          END IF;
          IF NEW.id_pauta_vinculada = 0 THEN
            NEW.id_pauta_vinculada = null;
          END IF;
        END IF;	
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_pauta ON gestao.pauta;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_pauta
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.pauta
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_pauta();
--RUN--

-------------------------------------------------------------
-- REVISADO POR JCS EM 05/09/2012 AS 12:50
-- VALIAÇÃO PAUXPRO
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.valida_pauxpro()
  RETURNS "trigger" AS
$BODY$

    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
	  NEW.dt_atual=now();
	  NEW.hora_atual=NOW();
        END IF;	
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_pauxpro ON gestao.pauxpro;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_pauxpro
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.pauxpro
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_pauxpro();
--RUN--

CREATE OR REPLACE FUNCTION gestao.calc_qtd_dev_estterceiro()
  RETURNS "trigger" AS
$BODY$
    DECLARE
      vmov           RECORD;
      vqtd_dev       NUMERIC(15,3);
      vqtd           NUMERIC(15,3);
      vsit           CHAR(1);
      vretorno       text;
      
    BEGIN
      IF NOT (NEW.tipo='R' AND NEW.indic_prop=2) THEN
        RETURN NEW;
      END IF;

      vretorno = (SELECT SET_CONFIG('jcs.semaforo', '1', FALSE));            

      vqtd_dev = NEW.qtdade-NEW.qtd_saldo; 
      FOR vmov IN SELECT a.id_req,a.id_reqd,a.qtdade,b.situacao FROM gestao.reqd A
                    LEFT OUTER JOIN gestao.req B ON (a.id_req=b.id_req)
                    WHERE num_rem_estterceiro=NEW.num_remessa
                    ORDER BY b.data,a.id_reqd
      LOOP
        IF vmov.qtdade>vqtd_dev THEN 
          vqtd = vqtd_dev;
          vsit = 'S';
        ELSE
          vqtd = vmov.qtdade;
          vsit = 'D';
        END IF;
        --RAISE NOTICE 'id_req: % vqtd_dev: % vmov.qtdade: % vqtd: % vsit: %',vmov.id_req,vqtd_dev,vmov.qtdade,vqtd,vsit;
	IF vmov.situacao='C' THEN
          UPDATE gestao.reqd SET qtd_dev_estterceiro=0,sit_estterceiro='N',num_rem_estterceiro=0 WHERE id_reqd=vmov.id_reqd;
	ELSE
          UPDATE gestao.reqd SET qtd_dev_estterceiro=vqtd,sit_estterceiro=vsit WHERE id_reqd=vmov.id_reqd;
          vqtd_dev = vqtd_dev - vqtd;      
	END IF;
      END LOOP;                 
      
      vretorno = (SELECT SET_CONFIG('jcs.semaforo', '0', FALSE));            
    
      RETURN NEW;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE;
ALTER FUNCTION gestao.calc_qtd_dev_estterceiro()
  OWNER TO postgres;
--RUN--

DROP TRIGGER calc_qtd_dev_estterceiro ON gestao.estterceiro;
--RUN--IGNORE ERRO

CREATE TRIGGER calc_qtd_dev_estterceiro
  AFTER UPDATE
  ON gestao.estterceiro
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.calc_qtd_dev_estterceiro();
--RUN--

CREATE OR REPLACE FUNCTION gestao.at_qtdade_produzida_op_gestao()
  RETURNS "trigger" AS
$BODY$
    DECLARE
      vid_empresa     int4;
      vnum_op         int4;
      vqtd            numeric(15,3);
      vqtd_plan       numeric(15,3);
      vqtd_canc       numeric(15,3);
      vsituacao       int4;
      vfluxo_continuo smallint;

    BEGIN
      IF TG_OP='INSERT' THEN
        IF new.num_op=0 THEN
           new.num_op = NULL;
        END IF;
        vid_empresa   = new.id_empresa;
        vnum_op       = new.num_op;
      ELSIF TG_OP='UPDATE' THEN
        IF new.num_op=0 THEN
           new.num_op = NULL;
        END IF;
        vid_empresa   = new.id_empresa;
        vnum_op       = new.num_op;
        IF NOT new.id_empresa=old.id_empresa THEN
          RAISE EXCEPTION 'Impossivel alterar empresa. Operação cancelada!';
        END IF;
        IF old.num_op>0 AND NOT new.num_op=old.num_op THEN
          RAISE EXCEPTION 'Impossivel alterar número da ordem de produção. Operação cancelada!';
        END IF;
      ELSIF TG_OP='DELETE' THEN
        vid_empresa   = old.id_empresa;
        vnum_op       = old.num_op;
      END IF;

      IF vnum_op IS NOT NULL THEN
        -- LE CONFIGURAÇÃO NA OP
        SELECT INTO vqtd_plan,vqtd_canc,vfluxo_continuo qtd_planejada,qtd_cancelada,COALESCE(fluxo_continuo,0) FROM gestao.op WHERE numero=vnum_op AND id_empresa=vid_empresa;
        IF NOT FOUND THEN
          RAISE NOTICE 'Ordem de produção inválida: % Operação cancelada!',vnum_op;
        ELSE
          -- EFETUA CALCULO DA QTDADE PRODUZIDA
          SELECT INTO vqtd SUM(qtd) FROM gestao.producao WHERE num_op=vnum_op AND id_empresa=vid_empresa;
          IF vqtd IS NULL THEN
            vqtd = 0;
          END IF;

          -- VERIFICA NOVA SITUACAO OP
		  --Pendente|#0|Liberada|#1|Em Produção|#2|Concluída Parcial|#3|Concluída Total|#4|Cancelada|#5
          IF vqtd>=(vqtd_plan) AND vfluxo_continuo=0 THEN
            vsituacao = 4;
	      ELSIF vqtd>=(vqtd_plan-vqtd_canc) AND vfluxo_continuo=0 THEN
            vsituacao = 3;
          ELSIF vqtd>0 THEN
            vsituacao = 2;
	      ELSE
		    vsituacao = 1;
          END IF;

          -- GRAVA DADOS NA OP
          UPDATE gestao.op SET qtd_produzida=vqtd,situacao=vsituacao WHERE numero=vnum_op AND id_empresa=vid_empresa;
        END IF;
      END IF;

      IF TG_OP='DELETE' THEN
        RETURN OLD;
      ELSE
        RETURN NEW;
      END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER at_qtdade_produzida_op_gestao ON gestao.producao;
--RUN--IGNORE ERRO

CREATE TRIGGER at_qtdade_produzida_op_gestao
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.producao
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.at_qtdade_produzida_op_gestao();
--RUN--


CREATE OR REPLACE FUNCTION upper(integer) RETURNS text AS
$BODY$
DECLARE
    pnumero  ALIAS FOR $1;

BEGIN
  RETURN pnumero::text;
END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_estlocal()
  RETURNS trigger AS
$BODY$
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          --REMOVE ACENTOS E OUTROS CARACTERES FORA DO ASCII
          IF NEW.id_empmovto=0 THEN
            NEW.id_empmovto=NULL;
          END IF;
        END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER valida_estlocal ON gestao.estlocal;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_estlocal
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.estlocal
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_estlocal();
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_ccusto()
  RETURNS trigger AS
$BODY$
    DECLARE
      --vid_empresa    int4;
      vid_ccusto     int4;
      vsemaforo      text;
      vretorno       text;
      emp            record;
      
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
		-- REMOVIDO POR JCS EM 14/07/2020 - FOI CRIADO COMPARTILHAMENTO PARA A TABELA CENTRO DE CUSTOS
/*
          SELECT INTO vsemaforo CURRENT_SETTING('jcs.semaforo');
          IF NOT vsemaforo='1' THEN 
           vretorno = (SELECT SET_CONFIG('jcs.semaforo', '1', FALSE));            
            FOR emp IN
  	      SELECT id_empresa FROM gestao.empresa WHERE id_empresa IN (NEW.id_empresa+9000,NEW.id_empresa-9000) OR (id_matriz IN (SELECT id_matriz FROM gestao.empresa WHERE id_empresa=NEW.id_empresa) AND NOT id_empresa=NEW.id_empresa)
            LOOP  	      
	      SELECT id_ccusto INTO vid_ccusto FROM gestao.ccusto WHERE id_empresa=emp.id_empresa AND codigo=NEW.codigo;
	      IF vid_ccusto IS NULL THEN
			INSERT INTO gestao.ccusto(
	  	     	     id_empresa, codigo, mascara, descricao, tipo, classificacao, 
			    nivel, cod_nivel_ant, tipo_custo)
		      VALUES ( emp.id_empresa, NEW.codigo, NEW.mascara, NEW.descricao, NEW.tipo, NEW.classificacao, 
			     NEW.nivel, (SELECT codigo FROM gestao.ccusto WHERE id_empresa=emp.id_empresa AND nivel=(NEW.nivel-1) AND mascara<=NEW.mascara ORDER BY mascara DESC LIMIT 1), NEW.tipo_custo);
	      ELSE
	         UPDATE gestao.ccusto
	  	    SET mascara=NEW.mascara, descricao=NEW.descricao, 
		       tipo=NEW.tipo, classificacao=NEW.classificacao, nivel=NEW.nivel, cod_nivel_ant=(SELECT codigo FROM gestao.ccusto WHERE id_empresa=emp.id_empresa AND nivel=(NEW.nivel-1) AND mascara<=NEW.mascara ORDER BY mascara DESC LIMIT 1), tipo_custo=NEW.tipo_custo
		    WHERE id_ccusto=vid_ccusto;
	      END IF;
	    END LOOP;
            vretorno = (SELECT SET_CONFIG('jcs.semaforo', '0', FALSE));            
	  END IF;
	  */
          RETURN NEW;
        ELSIF TG_OP='DELETE' THEN
		/*
          FOR emp IN
  	    SELECT id_empresa FROM gestao.empresa WHERE id_empresa IN (OLD.id_empresa+9000,OLD.id_empresa-9000) OR (id_matriz IN (SELECT id_matriz FROM gestao.empresa WHERE id_empresa=OLD.id_empresa) AND NOT id_empresa=OLD.id_empresa)
          LOOP  	      
	      SELECT id_ccusto INTO vid_ccusto FROM gestao.ccusto WHERE id_empresa=emp.id_empresa AND codigo=OLD.codigo;
              DELETE FROM gestao.ccusto WHERE id_ccusto=vid_ccusto;
          END LOOP;
		  */
          RETURN OLD;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

-- se ocorrer erro no SET_CONFIG a linha abaixo deve ser inserida no final do arquivo "postgresql.conf" e o serviço reiniciado (retirar --) - JCS
-- custom_variable_classes = 'jcs'      # list of custom variable class names

SELECT SET_CONFIG('jcs.semaforo', '0', FALSE);
--RUN--

DROP TRIGGER valida_ccusto ON gestao.ccusto;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_ccusto
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.ccusto
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_ccusto();
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_ccustoxctb()
  RETURNS trigger AS
$BODY$
    DECLARE
      vid_empresa    int4;
      vid_ccustoxctb int4;
      vsemaforo      text;
      vretorno       text;
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          SELECT INTO vsemaforo CURRENT_SETTING('jcs.semaforo');
          IF NOT vsemaforo='1' THEN 
            vretorno = (SELECT SET_CONFIG('jcs.semaforo', '1', FALSE));            
	    SELECT id_empresa INTO vid_empresa FROM gestao.empresa WHERE id_empresa IN (NEW.id_empresa+9000,NEW.id_empresa-9000);
	    IF vid_empresa IS NOT NULL THEN 
	      DELETE FROM gestao.ccustoxctb WHERE id_empresa=vid_empresa AND origem=NEW.origem;
	      INSERT INTO gestao.ccustoxctb(id_empresa, origem, cod_ccusto, cod_ctbconta, cod_ctbcusto) 
                SELECT vid_empresa, origem, cod_ccusto, cod_ctbconta, cod_ctbcusto FROM gestao.ccustoxctb WHERE id_empresa=NEW.id_empresa AND origem=NEW.origem;
	    END IF;
            vretorno = (SELECT SET_CONFIG('jcs.semaforo', '0', FALSE));            
	  END IF;
          RETURN NEW;
        ELSIF TG_OP='DELETE' THEN
          SELECT INTO vsemaforo CURRENT_SETTING('jcs.semaforo');
          IF NOT vsemaforo='1' THEN 
            SELECT id_empresa INTO vid_empresa FROM gestao.empresa WHERE id_empresa IN (OLD.id_empresa+9000,OLD.id_empresa-9000);
            DELETE FROM gestao.ccustoxctb WHERE id_empresa=vid_empresa AND origem=OLD.origem AND cod_ccusto=OLD.cod_ccusto;
          END IF;
          RETURN OLD;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--


DROP TRIGGER valida_ccustoxctb ON gestao.ccustoxctb;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_ccustoxctb
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.ccustoxctb
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_ccustoxctb();
--RUN--

CREATE OR REPLACE FUNCTION gestao.dv_gtin(text)
  RETURNS text AS    
  $BODY$
     DECLARE 
       vpar1 ALIAS  FOR $1;
       vcod_gtin    char(13);        
       cc           INT;
       vletra       CHAR(1);
       vsoma        BIGINT;
       vdv          INT;
       vtam         INT;
       
     BEGIN
       vtam = length(vpar1);
       IF vtam NOT IN (7,11,12,13) THEN
         RAISE NOTICE 'DV GTIN = TAMANHO INVÁLIDO % ',vtam;       
         RETURN '';
       END IF;
       vcod_gtin = to_char(vpar1::bigint,'0000000000000FM');
       vsoma = 0;
       FOR cc IN 1..13 LOOP
         vletra = substring(vcod_gtin,cc,1);
         IF CC%2=1 THEN
           vsoma  = vsoma + (vletra::int * 3);
         ELSE
           vsoma  = vsoma + vletra::int;
         END IF;
       END LOOP;
       vdv = vsoma % 10;
       IF NOT vdv=0 then
         vdv = 10 - vdv;
       END IF;
       RETURN vdv;
     END;
  $BODY$
LANGUAGE plpgsql;
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_gtin(text)
  RETURNS boolean AS    
  $BODY$
     DECLARE 
       vpar1 ALIAS  FOR $1;
       vcod_gtin    char(14);        
       vdv          TEXT;
       vtam         INT;
       
     BEGIN
       vtam = length(vpar1);
       vcod_gtin = to_char(vpar1::bigint,'00000000000000FM');
       vdv = gestao.dv_gtin(substring(vcod_gtin,1,13));
       IF vpar1::bigint=0 THEN
         RAISE NOTICE 'VALIDA GTIN = CÓDIGO ZERADO';
         RETURN false;
       ELSIF vtam NOT IN (8,12,13,14) THEN
         RAISE NOTICE 'VALIDA GTIN = TAMANHO INVÁLIDO % ',vtam;       
         RETURN false;
       ELSIF NOT vdv=substring(vcod_gtin,14,1) THEN
         RAISE NOTICE 'VALIDA GTIN = DV INVÁLIDO % - CORRETO %',substring(vcod_gtin,14,1),vdv;       
         RETURN false;
       ELSE
         RETURN true;
       END IF;
     END;
  $BODY$
LANGUAGE plpgsql;
--RUN--

CREATE OR REPLACE FUNCTION gestao.lanca_detnatureza_fiscal()
  RETURNS "trigger" AS
$BODY$
    DECLARE vid_ctp          int4;
            rger          RECORD;
            rfis          RECORD;
            rdet          RECORD;
    BEGIN
        IF TG_OP='INSERT' THEN
          vid_ctp    := new.id_origem;
        ELSIF TG_OP='UPDATE' THEN
          vid_ctp    := new.id_origem;
        ELSIF TG_OP='DELETE' THEN
          vid_ctp    := old.id_origem;
        END IF;
        
        --RAISE EXCEPTION 'teste % ',rdet.id_empresa;
        
        SELECT id_ctp,id_empresa,credo,numero,status INTO rger FROM gestao.ctp WHERE id_ctp=vid_ctp;
               
        IF rger.id_empresa>9000 AND NOT rger.status=3 THEN
        
          -- BUSCA TITULO NO SISTEMA FISCAL
          SELECT id_ctp INTO rfis FROM gestao.ctp WHERE id_empresa=rger.id_empresa-9000 AND credo=rger.credo AND numero=rger.numero;
          IF rfis.id_ctp IS NULL THEN
             RAISE NOTICE 'Contas a pagar do Credor (%)  com o Número (%) não existe no sistema fiscal!. Operação cancelada!', rger.credo, rger.numero;
          ELSE
            -- ATUALIZA DETNATUREZA FISCAL
            DELETE FROM gestao.detnatureza WHERE id_empresa=rger.id_empresa-9000 and origem='CTP' and id_origem=rfis.id_ctp::TEXT;
            FOR rdet IN SELECT * FROM ONLY gestao.detnatureza WHERE id_empresa=rger.id_empresa and origem='CTP' and id_origem=rger.id_ctp::TEXT
            LOOP
              DELETE FROM gestao.detnatureza WHERE id_detnatureza=(rdet.id_detnatureza+90000000);
              INSERT INTO gestao.detnatureza (id_detnatureza, id_empresa, origem, id_origem, ordem, cod_ccusto, id_natureza, valor,id_lote)
                         VALUES(rdet.id_detnatureza+90000000, rdet.id_empresa-9000, 'CTP' , rfis.id_ctp, rdet.ordem, rdet.cod_ccusto, rdet.id_natureza, rdet.valor,rdet.id_lote);
            END LOOP;
          END IF;
          
        END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER lanca_detnatureza_fiscal ON gestao.detnatureza;
--RUN--IGNORE ERRO

CREATE TRIGGER lanca_detnatureza_fiscal
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.detnatureza
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.lanca_detnatureza_fiscal();
--RUN--

CREATE OR REPLACE FUNCTION gestao.lanca_detnatureza_fiscal_ctp()
  RETURNS "trigger" AS
$BODY$
    DECLARE vid_ctp       int4;
            rec           RECORD;
    BEGIN

      IF TG_OP='DELETE' THEN
        DELETE FROM gestao.detnatureza WHERE id_empresa=OLD.id_empresa and origem='CTP' and id_origem=OLD.id_ctp::TEXT;
        RETURN OLD;
      ELSIF TG_OP='INSERT' THEN
        IF NEW.id_empresa<9001 and NOT NEW.status=3 THEN
          SELECT id_ctp INTO vid_ctp FROM ONLY gestao.ctp WHERE id_empresa=NEW.id_empresa+9000 AND credo=NEW.credo AND numero=NEW.numero;
          IF vid_ctp IS NULL THEN
            -- DEIXAR LINHA ABAIXO COMO NOTICE - JCS EM 05/11/2013 - 10:30
            RAISE NOTICE 'Contas a pagar do Credor (%)  com o Número (%) não existe no sistema gerencial!. Operação cancelada!', new.credo, new.numero;
          ELSE
            FOR rec IN SELECT id_detnatureza,valor FROM gestao.detnatureza WHERE id_empresa=NEW.id_empresa+9000 AND origem='CTP' AND id_origem=vid_ctp::text
            LOOP
              UPDATE gestao.detnatureza SET valor=rec.valor WHERE id_detnatureza=rec.id_detnatureza;
            END LOOP;
          END IF;
        END IF;
        
        RETURN NEW;              
      END IF;
      -- FIM --
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER lanca_detnatureza_fiscal_ctp ON gestao.ctp;
--RUN--IGNORE ERRO

  CREATE TRIGGER lanca_detnatureza_fiscal_ctp
  AFTER INSERT OR DELETE
  ON gestao.ctp
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.lanca_detnatureza_fiscal_ctp();
--RUN--

CREATE OR REPLACE FUNCTION gestao.lanca_estinventario_fiscal()
  RETURNS trigger AS
$BODY$
    
    BEGIN

        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN

	  -- ATUALIZA INVENTÁRIO FISCAL
	  IF new.id_empresa>9000 THEN
            DELETE FROM gestao.estinventario WHERE id_estinventario=(new.id_estinventario+90000000);
            IF new.status=1 THEN
              INSERT INTO gestao.estinventario(id_estinventario, id_empresa, data, id_estlocal, id_produto, variante, validade, qtdade, valor, operador, unidade, inf_usuario, status, id_lote)
                     VALUES (new.id_estinventario+90000000, new.id_empresa-9000, new.data, new.id_estlocal, new.id_produto, new.variante, new.validade, new.qtdade, new.valor, new.operador, new.unidade, new.inf_usuario, new.status,new.id_lote);
            END IF;
          END IF;
          
        ELSIF TG_OP='DELETE' THEN
          DELETE FROM gestao.estinventario WHERE id_estinventario=(old.id_estinventario+90000000);
        END IF;	
        
        IF TG_OP='DELETE' THEN
            RETURN OLD;
        ELSE
            RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER lanca_estinventario_fiscal ON gestao.estinventario;
--RUN--IGNORE ERRO

CREATE TRIGGER lanca_estinventario_fiscal
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.estinventario
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.lanca_estinventario_fiscal();
--RUN--

DROP TRIGGER valida_dfe ON gestao.dfe;
--RUN--IGNORE ERRO

CREATE OR REPLACE FUNCTION gestao.valida_dfe()
  RETURNS trigger AS
$BODY$

    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
          NEW.desc_justificativa  = trim(to_ascii(NEW.desc_justificativa));
          IF NEW.xml='' THEN
            NEW.xml='N';
          END IF;
        END IF;
        IF TG_OP='UPDATE' THEN          
          IF NEW.cod_manifesto>0 AND NOT NEW.cod_manifesto = coalesce(OLD.cod_manifesto,0) THEN
            NEW.dt_manifestacao = null;
            NEW.hr_manifestacao = null;
          END IF;
        END IF;        		
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE;
--RUN--

CREATE TRIGGER valida_dfe
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.dfe
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_dfe();
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_entradas()
  RETURNS trigger AS
$BODY$
    DECLARE
      v_cad_cor_for_emp INT4;
      v_id_empresa      INT4;

    BEGIN
      v_cad_cor_for_emp = COALESCE((SELECT valor::int4 FROM gestao.registro WHERE chave='Configuração' AND nome='Cadastro Correntista e Fornecedor por Empresa'),0);
      IF v_cad_cor_for_emp=1 THEN
        v_id_empresa = COALESCE((SELECT id_empresa FROM sig.forne WHERE id_forne=NEW.id_forne),0);
        IF NOT v_id_empresa=NEW.id_empresa THEN
          RAISE EXCEPTION 'Fornecedor vinculado a outra empresa (%)!',v_id_empresa;
        END IF;
      END IF;
	  IF NEW.id_mun_orig=0 THEN
	    NEW.id_mun_orig = NULL;
      END IF;
	  IF NEW.id_mun_dest=0 THEN
	    NEW.id_mun_dest = NULL;
      END IF;
	  IF NEW.data_inc IS NULL THEN
	    NEW.data_inc = now();
	  END IF;
		
      RETURN NEW;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE;
--RUN--

DROP TRIGGER valida_entradas ON gestao.entradas;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_entradas
  BEFORE INSERT OR UPDATE
  ON gestao.entradas
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_entradas();
--RUN--

CREATE OR REPLACE FUNCTION gestao.valida_ctp()
  RETURNS trigger AS
$BODY$
    DECLARE
      v_cad_cor_for_emp INT4;
      v_id_empresa      INT4;

    BEGIN
      v_cad_cor_for_emp = COALESCE((SELECT valor::int4 FROM gestao.registro WHERE chave='Configuração' AND nome='Cadastro Correntista e Fornecedor por Empresa'),0);
      IF v_cad_cor_for_emp=1 THEN
        v_id_empresa = COALESCE((SELECT id_empresa FROM sig.forne WHERE id_forne=NEW.credo),0);
        IF NOT v_id_empresa=NEW.id_empresa THEN
	  RAISE EXCEPTION 'Credor vinculado a outra empresa (%)!',v_id_empresa;
	END IF;
      END IF;	      
      RETURN NEW;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE;
--RUN--

DROP TRIGGER valida_ctp ON gestao.ctp;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_ctp
  BEFORE INSERT OR UPDATE
  ON gestao.ctp
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_ctp();
--RUN--

CREATE OR REPLACE FUNCTION secwin.delete_user_dssw22()
  RETURNS trigger AS
$BODY$
    DECLARE
      emp            record;

    BEGIN
        IF TG_OP='DELETE' THEN
          DELETE FROM secwin.dssw22 WHERE acc_operator=OLD.ope_number;
          RETURN OLD;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE;
--RUN--

DROP TRIGGER delete_user_dssw22 ON secwin.dssw21;
--RUN--IGNORE ERRO

CREATE TRIGGER delete_user_dssw22
  AFTER DELETE
  ON secwin.dssw21
  FOR EACH ROW
  EXECUTE PROCEDURE secwin.delete_user_dssw22();
--RUN--

DROP TRIGGER gera_estoque_entradet ON gestao.entradet;
--RUN--IGNORE ERRO

CREATE OR REPLACE FUNCTION gestao.gera_estoque_entradet()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$

    DECLARE rENT               RECORD;
            v_idestoque        CHAR(22);
            vfator             NUMERIC(15,6);
            vqtd               NUMERIC(15,3);
            vid_entradet       INTEGER;

    BEGIN

      IF TG_OP<>'INSERT' THEN
        SELECT id_empresa,situacao,entra,sistema,status
        INTO rENT
        FROM gestao.entradas WHERE id_entrada=OLD.id_entrada;
      ELSE
        SELECT id_empresa,situacao,entra,sistema,status
        INTO rENT
        FROM gestao.entradas WHERE id_entrada=NEW.id_entrada;
      END IF;

      IF rENT.sistema='AUTOCOM' THEN
        IF TG_OP='DELETE' THEN
          DELETE FROM gerente.estoqued WHERE id_entradet=old.id_entradet;
          RETURN OLD;
        ELSIF TG_OP='UPDATE' THEN
          --DELETE FROM gerente.estoqued WHERE id_entradet=old.id_entradet;
          IF not (rENT.situacao<>'P' AND NEW.gerar_estoque in('S') and NEW.tipo in(1,2)) THEN
		    --RAISE EXCEPTION 'AAA  %',rENT.sistema;
            DELETE FROM gerente.estoqued WHERE id_entradet=old.id_entradet;
            RETURN NEW;
          END IF;
        END IF;

        --RAISE EXCEPTION 'Movimento  %',rENT.sistema;
        IF rENT.situacao<>'P' AND NEW.gerar_estoque IN ('S') and NEW.tipo in(1,2) THEN

          -- FATOR CONVERSÃO POR JCS EM 03/05/2023 AS 11:40
          vfator = (SELECT fator FROM gestao.fatconversao
          WHERE unid_conv=NEW.und AND id_produto=(SELECT id_produto FROM gestao.produto WHERE id_erp=NEW.produ AND id_empresa=COALESCE((SELECT id_empresa_tabcomp from gestao.tabcomp WHERE nome_tabcomp='produtos' AND id_empresa=rENT.id_empresa),rENT.id_empresa)));
          IF vfator=0 OR vfator IS NULL THEN
            vqtd = (NEW.qtd + NEW.qtd_ajuste);
          ELSE
            vqtd = (NEW.qtd + NEW.qtd_ajuste) * vfator;
          END IF;

          --RAISE EXCEPTION 'Movimento3  %',old.id_entradet;		  		  
          -- NÃO DEIXA VARIANTE FICAR NULO
          IF NEW.variante IS NULL THEN
            NEW.variante = '';
          END IF;

          IF NEW.validade IS NULL THEN
            NEW.validade='3000-01-01';
          END IF;
		  
          -- busca dados do estoque
          SELECT id_estoque INTO v_idestoque FROM gerente.estoque
          WHERE id_empresa=rENT.id_empresa AND id_produto=NEW.produ AND validade=NEW.validade AND lote_serie_etc=NEW.variante;
		  
          -- grava novo estoque caso não exista
          IF v_idestoque IS NULL THEN
            INSERT INTO gerente.estoque (id_empresa,id_produto,validade,lote_serie_etc,qtdade,valor,qtd_empenhada,qtdade_fis)
            VALUES (rENT.id_empresa,NEW.produ,NEW.validade,NEW.variante,0,0,0,0);
            SELECT currval('gerente.id_estoque_seq') INTO v_idestoque;
          END IF;

          vid_entradet=(SELECT id_entradet FROM gerente.estoqued WHERE id_estoque=v_idestoque and id_entradet=old.id_entradet);
          IF TG_OP='UPDATE' and vid_entradet>0 THEN
            --grava movimento de estoque
            UPDATE gerente.estoqued
               SET data=rENT.entra, qtdade=vqtd, valor=NEW.custo_estoque, vl_tot_aquisicao=NEW.total, vl_tot_icmsdebforne=NEW.valor_icms, vl_bc_calcicmsst=NEW.base_icms_st,
               vl_tot_icmsst=NEW.valor_icms_st, status=rENT.status
            WHERE id_entradet=old.id_entradet;
            --RAISE EXCEPTION 'Movimento1  %',old.id_entradet;		  
          ELSE
	    IF TG_OP='UPDATE' THEN
  	       DELETE FROM gerente.estoqued WHERE id_entradet=old.id_entradet;
	    END IF;
            --grava movimento de estoque
            INSERT INTO gerente.estoqued (id_estoque,data,tipo,qtdade,valor,origem,id_entradet,status,vl_tot_aquisicao,vl_tot_icmsdebforne,vl_bc_calcicmsst,vl_tot_icmsst)
            VALUES (v_idestoque,rENT.entra,'E', vqtd ,NEW.custo_estoque,'ENT',new.id_entradet,rENT.status,NEW.total,NEW.valor_icms,NEW.base_icms_st,
            NEW.valor_icms_st);
          END IF;

        END IF;
      END IF;

      IF TG_OP='DELETE' THEN
        RETURN OLD;
      ELSE
        RETURN NEW;
      END IF;
    END;
$BODY$;

ALTER FUNCTION gestao.gera_estoque_entradet()
    OWNER TO postgres;
--RUN--

CREATE TRIGGER gera_estoque_entradet
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.entradet
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.gera_estoque_entradet();
--RUN--
  
-- FUNÇÃO PARA CONTROLE DO BLOQUEIO DA DATA INFORMADA NO PORTADOR
CREATE OR REPLACE FUNCTION gestao.bloquear_lanctos()
  RETURNS "trigger" AS
$BODY$
    DECLARE vdata          DATE;
    BEGIN
      IF TG_OP='INSERT' THEN
        SELECT data_bloq_lancto INTO vdata FROM gestao.portador WHERE id_portador=NEW.banco;
        IF vdata>=NEW.dt_movto THEN
          RAISE EXCEPTION 'Caixa/Banco % com movimento bloqueado. Data bloqueio: %!', NEW.banco,to_char(vdata,'DD/MM/YYYY');
        END IF;
      END IF;
      IF TG_OP='DELETE' THEN
        SELECT data_bloq_lancto INTO vdata FROM gestao.portador WHERE id_portador=OLD.banco;
        IF vdata>=OLD.dt_movto THEN
          RAISE EXCEPTION 'Caixa/Banco % com movimento bloqueado. Data bloqueio: %!', OLD.banco,to_char(vdata,'DD/MM/YYYY');
        END IF;
      END IF;

      IF TG_OP='UPDATE' THEN
        IF NOT (NEW.dt_movto=OLD.dt_movto AND
                NEW.banco   =OLD.banco    AND
                NEW.valor   =OLD.valor    AND
                NEW.tipo    =OLD.tipo     AND
                NEW.saldo   =OLD.saldo    AND
                NEW.id_empresa=OLD.id_empresa) THEN
           -- CONFERE DADOS ANTIGOS
           SELECT data_bloq_lancto INTO vdata FROM gestao.portador WHERE id_portador=OLD.banco;
           IF vdata>=OLD.dt_movto THEN
              RAISE EXCEPTION 'Caixa/Banco % com movimento bloqueado. Data bloqueio: %!',OLD.banco,to_char(vdata,'DD/MM/YYYY');
           END IF;
           -- CONFERE DADOS NOVOS 
           SELECT data_bloq_lancto INTO vdata FROM gestao.portador WHERE id_portador=NEW.banco;
           IF vdata>=NEW.dt_movto THEN
              RAISE EXCEPTION 'Caixa/Banco % com movimento bloqueado. Data bloqueio: %!',NEW.banco,to_char(vdata,'DD/MM/YYYY');
           END IF;
         END IF;
      END IF;

      IF TG_OP='DELETE' THEN
        RETURN OLD;
      ELSE
        RETURN NEW;
      END IF;

    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER bloquear_lanctos ON gestao.lanctos;
--RUN--IGNORE ERRO

CREATE TRIGGER bloquear_lanctos
   BEFORE INSERT OR UPDATE OR DELETE
   ON gestao.lanctos FOR EACH ROW
   EXECUTE PROCEDURE gestao.bloquear_lanctos();
--RUN--

CREATE OR REPLACE FUNCTION gestao.atual_qtd_recebida_oc()
  RETURNS trigger AS
$BODY$
    BEGIN
      -- UPDATE NO ETRADET PARA DISPARAR TRIGGER PARA ATUALIZAR QUANTIDADE RECEBIDA DA OC
      IF TG_OP='UPDATE' THEN
        IF (OLD.situacao='I') THEN
          UPDATE gestao.entradet SET produ=produ where id_entrada=NEW.id_entrada;
        END IF;
      END IF;
      RETURN NEW;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.atual_qtd_recebida_oc()
  OWNER TO postgres;
--RUN--

DROP TRIGGER atual_qtd_recebida_oc ON gestao.entradas;
--RUN--IGNORE ERRO

CREATE TRIGGER atual_qtd_recebida_oc
  AFTER UPDATE
  ON gestao.entradas
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.atual_qtd_recebida_oc();
--RUN--


-- FUNÇÃO PARA ATUALIZAR A SITUACAO DO LOTE APOS INC/ALT/EXC CQANALISELOTE 
CREATE OR REPLACE FUNCTION gestao.atual_situacao_lote() RETURNS trigger AS 
$BODY$
    DECLARE vid_lote      int4;
            vcount        int4;
    BEGIN
    
	IF TG_OP='INSERT' THEN
           vid_lote    := new.id_lote; 
        ELSIF TG_OP='UPDATE' THEN
           vid_lote    := new.id_lote; 
	ELSIF TG_OP='DELETE' THEN
           vid_lote    := old.id_lote; 
        END IF;
        
	IF vid_lote IS NOT NULL THEN

           select count(id_cqanaliselote) INTO vcount from only gestao.cqanaliselote
           where id_lote=vid_lote and situacao in(1,2)
           having count(id_cqanaliselote)=(select count(id_cqanaliselote) from gestao.cqanaliselote where id_lote=vid_lote) and count(id_cqanaliselote)>0           
           and (select count(id_cqteste) from gestao.cqteste where tipo=1 and id_cqesptec in(select id_cqesptec from gestao.cqesptec as a
                left outer join gestao.lote as b on(b.id_lote=vid_lote) 
                where a.id_empresa=b.id_empresa and a.id_produto=b.id_produto and a.ativa=1))=
               (select count(a.id_cqanaliselote) from gestao.cqanaliselote as a 
                left outer join gestao.cqteste as b on(a.id_cqesptec=b.id_cqesptec and a.ordem=b.ordem) where b.tipo=1 and a.id_lote=vid_lote);
  

           
           --RAISE EXCEPTION 'Total (%)!',vid_lote;
          
           IF vcount>0 THEN
             UPDATE ONLY gestao.lote SET situacao='L' WHERE id_lote=vid_lote;            
           ELSE
             select count(id_cqanaliselote) INTO vcount from only gestao.cqanaliselote where id_lote=vid_lote and situacao=3;
             IF vcount>0 THEN             
               UPDATE ONLY gestao.lote SET situacao='B' WHERE id_lote=vid_lote;                                   
             ELSE
               UPDATE ONLY gestao.lote SET situacao='P' WHERE id_lote=vid_lote;                                   
             END IF;
           END IF;

	END IF;
	
        IF TG_OP='DELETE' THEN
           RETURN OLD;
        ELSE       
           RETURN NEW;  
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER atual_situacao_lote ON gestao.cqanaliselote;
--RUN--IGNORE ERRO

CREATE TRIGGER atual_situacao_lote
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.cqanaliselote
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.atual_situacao_lote();
--RUN--

--VALIDA LOTE
CREATE OR REPLACE FUNCTION gestao.valida_lote()
  RETURNS trigger AS
$BODY$

    DECLARE vid_emp_prod     int;
            vtp_mov_lote     int;

    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN        
        
          IF NEW.situacao='' OR NEW.situacao IS NULL THEN
          
            -- BUSCA ID EMPRESA DO PRODUTO
            vid_emp_prod = 0;
            SELECT id_empresa_tabcomp INTO vid_emp_prod FROM gestao.tabcomp WHERE nome_tabcomp='produtos' AND id_empresa=NEW.id_empresa;
            IF vid_emp_prod IS NULL OR vid_emp_prod=0 THEN
              vid_emp_prod = NEW.id_empresa;
            END IF;
            -- VERIFICA TIPO MOVIMENTO DO LOTE
            SELECT lote INTO vtp_mov_lote FROM gestao.produto WHERE id_erp=NEW.id_produto and id_empresa=vid_emp_prod;
            IF vtp_mov_lote IS NULL THEN
              vtp_mov_lote=0;
            END IF;

            IF vtp_mov_lote = 2 THEN
              NEW.situacao='P';
            ELSE
              NEW.situacao='L';
            END IF;
          END IF;
        END IF;
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.valida_lote()
  OWNER TO postgres;
--RUN--

DROP TRIGGER valida_lote ON gestao.lote;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_lote
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.lote
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_lote();
--RUN--


------------------------------------------------------------
-- atual_qtd_op_estsaldo
-- CRIADO POR JCS EM 26/01/2023 AS 16:56
------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.atual_qtd_op_estsaldo()
  RETURNS trigger AS
$BODY$
    DECLARE vqtd_op       numeric(15,3);

    BEGIN
        -- bloqueio exclusao
        IF TG_OP='DELETE' THEN
          IF (select id_req from gestao.req where origem='OP#'||OLD.id_op LIMIT 1) IS NOT NULL THEN 
            RAISE EXCEPTION 'Requisição vinculada, não é possivel excluir OP!';
          END IF;
          IF (select id_producao from gestao.producao where id_empresa=OLD.id_empresa AND num_op=OLD.numero LIMIT 1) IS NOT NULL THEN 
            RAISE EXCEPTION 'Produção vinculada, não é possivel excluir OP!';
          END IF;
        END IF;

        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
           vqtd_op = (SELECT SUM(qtd_planejada-(qtd_produzida+qtd_cancelada)) FROM gestao.op WHERE id_empresa=NEW.id_empresa AND id_estlocal=NEW.id_estlocal AND id_produto=NEW.id_produto AND situacao IN (1,2) AND qtd_planejada>(qtd_produzida+qtd_cancelada));
           IF vqtd_op IS NULL THEN
             vqtd_op = 0 ;
           END IF;
           UPDATE gestao.estsaldo SET qtd_op=vqtd_op WHERE NOT qtd_op=vqtd_op AND id_empresa=NEW.id_empresa AND id_estlocal=NEW.id_estlocal AND id_produto=NEW.id_produto;
        END IF;

        IF TG_OP='DELETE' OR TG_OP='UPDATE' THEN
           vqtd_op = (SELECT SUM(qtd_planejada-(qtd_produzida+qtd_cancelada)) FROM gestao.op WHERE id_empresa=OLD.id_empresa AND id_estlocal=OLD.id_estlocal AND id_produto=OLD.id_produto AND situacao IN (1,2) AND qtd_planejada>(qtd_produzida+qtd_cancelada));
           IF vqtd_op IS NULL THEN
             vqtd_op = 0 ;
           END IF;
           UPDATE gestao.estsaldo SET qtd_op=vqtd_op WHERE NOT qtd_op=vqtd_op AND id_empresa=OLD.id_empresa AND id_estlocal=OLD.id_estlocal AND id_produto=OLD.id_produto;
        END IF;

      IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
        RETURN NEW;
      ELSE
        RETURN OLD;
      END IF ;
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER atual_qtd_op_estsaldo ON gestao.op;
--RUN--IGNORE ERRO

CREATE TRIGGER atual_qtd_op_estsaldo
  AFTER INSERT OR UPDATE OR DELETE
  ON gestao.op
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.atual_qtd_op_estsaldo();
--RUN--


CREATE OR REPLACE FUNCTION gestao.valida_req()
  RETURNS trigger AS
$BODY$


    BEGIN
      IF TG_OP='INSERT' OR TG_OP='UPDATE'  THEN
        IF NOT NEW.origem>' ' THEN
          NEW.origem = NULL;
        END IF;
        RETURN NEW;
      ELSE
        RETURN OLD;
      END IF;
    END;
$BODY$
  LANGUAGE plpgsql;
--RUN--

DROP TRIGGER valida_req ON gestao.req;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_req
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.req
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_req();
--RUN--

DROP FUNCTION gestao.validar_email(character);
--RUN--IGNORE ERRO

CREATE OR REPLACE FUNCTION gestao.validar_email(character)
  RETURNS boolean AS
$BODY$
DECLARE
    pemail      ALIAS FOR $1;
BEGIN
  IF pemail ~* '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$' THEN
    RETURN true;
  ELSE
    RETURN false;
  END IF;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.validar_email(character)
  OWNER TO postgres;
--RUN--

DROP FUNCTION gestao.validar_telefone(character);
--RUN--IGNORE ERRO

CREATE OR REPLACE FUNCTION gestao.validar_telefone(character)
  RETURNS boolean AS
$BODY$
DECLARE
    ptelefone      ALIAS FOR $1;
BEGIN

  --IF ptelefone ~* '^(\\+\\d{1,3})?\\s?(\\()?\\d{3}(?(2)\\))[-.\\s]?\\d{3}[-.\\s]?\\d{4}$' THEN
  --IF ptelefone ~* '^\\([1-9]{1}[0-9]{1}\\)-[2-9]{1}[0-9]{3}-[0-9]{4}$' THEN
  IF ptelefone ~*'^\(\d{2}\) \d{4,5}-\d{4}$' THEN
    RETURN true;
  ELSE
    RETURN false;
  END IF;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION gestao.validar_telefone(character)
  OWNER TO postgres;
--RUN--

DROP TRIGGER atual_valor_transf_req_estmovto ON gestao.estmovto;
--RUN--IGNORE ERRO

DROP FUNCTION gestao.atual_valor_transf_req_estmovto();
--RUN--IGNORE ERRO

CREATE OR REPLACE FUNCTION gestao.disconnect_users_low_connections()
RETURNS INTEGER AS $$
DECLARE
    max_conn INT;
    current_conn INT;
    available_conn INT;
    r RECORD;
    disconnect_count INT := 0;
BEGIN
    -- Obtem o numero maximo de conexoes permitidas
    SELECT setting::int INTO max_conn FROM pg_settings WHERE name = 'max_connections';

    -- Conta conexoes ativas no momento
    SELECT count(*) INTO current_conn FROM pg_stat_activity;

    -- Calcula conexoes disponiveis
    available_conn := max_conn - current_conn;

    -- Se ha 5 ou menos disponiveis, mata os 5 ociosos mais antigos
    IF available_conn <= 5 THEN
        RAISE NOTICE 'Conexoes disponiveis: % - desconectando os 5 usuarios ociosos mais antigos...', available_conn;

        FOR r IN
            SELECT pid, usename, client_addr
            FROM pg_stat_activity
            WHERE state = 'idle'
              AND pid <> pg_backend_pid()
            ORDER BY state_change ASC
            LIMIT 5
        LOOP
            RAISE NOTICE 'Desconectando PID: %, usuario: %, IP: %', r.pid, r.usename, COALESCE(r.client_addr::text, 'localhost');

            PERFORM pg_terminate_backend(r.pid);
            
            disconnect_count := disconnect_count + 1;
        END LOOP;
    ELSE
        RAISE NOTICE 'Conexoes disponiveis: % - nenhuma acao necessaria.', available_conn;
    END IF;
    RETURN disconnect_count;
END;
$$ LANGUAGE plpgsql;
--RUN--

-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.valida_estsaldo()
  RETURNS "trigger" AS
$BODY$
    BEGIN
        IF TG_OP='INSERT' OR TG_OP='UPDATE' THEN
	  NEW.dthr_atual=now();
        END IF;	
        IF TG_OP='DELETE' THEN
          RETURN OLD;
        ELSE
          RETURN NEW;
        END IF;
    END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
--RUN--

DROP TRIGGER valida_estsaldo ON gestao.estsaldo;
--RUN--IGNORE ERRO

CREATE TRIGGER valida_estsaldo
  BEFORE INSERT OR UPDATE OR DELETE
  ON gestao.estsaldo
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.valida_estsaldo();
--RUN--

-------------------------------------------------------------
CREATE OR REPLACE FUNCTION gestao.gera_k220()
  RETURNS trigger AS
$BODY$

    DECLARE vgera_k220      int;
            vid_emp_prod    int;
            vid_erp_estoque int;
            vprod_orig      int;
            vprod_dest      int;
            vqtdade         decimal(17,3);
            
    BEGIN
    
      IF TG_OP='DELETE' THEN
        DELETE FROM gestao.spedk220 WHERE id_estmovto=OLD.id_estmovto;
        RETURN OLD;
      ELSIF TG_OP='INSERT' THEN

        -- BUSCA CONFIGURAÇÃO
        SELECT valor::int INTO vgera_k220 FROM gestao.registro WHERE chave=NEW.id_empresa||'/ConfigSIS' AND nome='Gera k220';
        IF vgera_k220 IS NULL THEN
          vgera_k220 = 0;
        END IF;
        
        IF vgera_k220=1 AND (NEW.tipo='E' OR NEW.tipo='S') THEN
      
          IF NEW.origem_prefixo='PRO' OR NEW.origem_prefixo='NF' OR NEW.origem_prefixo='EN' OR NEW.origem_prefixo='RQ' OR NEW.origem_prefixo='FT' THEN

           -- BUSCA ID EMPRESA DO PRODUTO
            vid_emp_prod = 0;
            SELECT id_empresa_tabcomp INTO vid_emp_prod FROM gestao.tabcomp WHERE nome_tabcomp='produtos' AND id_empresa=NEW.id_empresa;
            IF vid_emp_prod IS NULL OR vid_emp_prod=0 THEN
              vid_emp_prod = NEW.id_empresa;
            END IF;

            -- VERIFICA ID ERP ESTOQUE
            SELECT id_erp_estoque INTO vid_erp_estoque FROM gestao.produto WHERE id_erp=NEW.id_produto and id_empresa=vid_emp_prod;
            IF vid_erp_estoque IS NULL THEN
              vid_erp_estoque=0;
            END IF;

            IF vid_erp_estoque > 0 THEN

              IF NEW.tipo='E' OR (NEW.tipo='S' AND NEW.qtdade<0) THEN
                IF NEW.qtdade<0 THEN
                  vqtdade = NEW.qtdade*-1;
                ELSE
                  vqtdade = NEW.qtdade;
                END IF;
                
                INSERT INTO gestao.spedk220(id_empresa, data, id_produto_orig, id_produto_dest, id_estlocal, qtdade, id_estmovto, historico)
                    VALUES (NEW.id_empresa, NEW.data, NEW.id_produto, vid_erp_estoque, NEW.id_estlocal, vqtdade, NEW.id_estmovto,'SPED K220 - '||NEW.origem_prefixo||' : '||NEW.origem_id);
                    
              ELSIF NEW.tipo='S' OR (NEW.tipo='E' AND NEW.qtdade<0) THEN
                IF NEW.qtdade<0 THEN
                  vqtdade = NEW.qtdade*-1;
                ELSE
                  vqtdade = NEW.qtdade;
                END IF;
                                
                INSERT INTO gestao.spedk220(id_empresa, data, id_produto_orig, id_produto_dest, id_estlocal, qtdade, id_estmovto, historico)
                    VALUES (NEW.id_empresa, NEW.data, vid_erp_estoque, NEW.id_produto, NEW.id_estlocal, vqtdade, NEW.id_estmovto,'SPED K220 - '||NEW.origem_prefixo||' : '||NEW.origem_id);

              END IF;
            END IF;
          END IF;
        END IF;  
      END IF;
      RETURN NEW;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
--RUN--
 
DROP TRIGGER gera_k220 ON gestao.estmovto;
--RUN--IGNORE ERRO

CREATE TRIGGER gera_k220
  AFTER INSERT OR DELETE
  ON gestao.estmovto
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.gera_k220();
--RUN--
 
 -------------------------------------------------------------
 CREATE OR REPLACE FUNCTION gestao.gera_estmovto_k220()
  RETURNS trigger AS
$BODY$

    DECLARE vgera_k220      int;
            vid_emp_prod    int;
            vid_erp_estoque int;
            vprod_orig      int;
            vprod_dest      int;
            vqtdade         decimal(17,3);
            vvalor         decimal(15,2);
            
    BEGIN
    
      IF TG_OP='DELETE' THEN
        DELETE FROM gestao.estmovto WHERE origem_prefixo='SPD' and origem_id=OLD.id_estmovto;
        RETURN OLD;
      ELSIF TG_OP='INSERT' THEN

        -- VALOR
        SELECT valor INTO vvalor FROM gestao.estmovto WHERE id_estmovto=NEW.id_estmovto;
        IF vvalor IS NULL THEN
          vvalor = 0;
        END IF;
        IF vvalor<0 THEN
          vvalor = vvalor*-1;
        END IF;
                
        -- ORIGEM
        INSERT INTO gestao.estmovto(
                    id_empresa, id_estlocal, id_produto, variante, validade,
                    docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                    historico, tipo, qtdade, valor, vl_ajuste,
                    status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador)
            VALUES (NEW.id_empresa, NEW.id_estlocal, NEW.id_produto_orig, ' ', ' ',
                    'I', 'SPD', ' ', ' ', NEW.data,
                    NEW.historico, 'S', NEW.qtdade, vvalor, 0,
                    1, 'SPD', NEW.id_estmovto, 1, 1,'SPED K220');


        -- DESTINO
        INSERT INTO gestao.estmovto(
                    id_empresa, id_estlocal, id_produto, variante, validade,
                    docto_natureza, docto_tipo, docto_serie, docto_numero, data,
                    historico, tipo, qtdade, valor, vl_ajuste,
                    status, origem_prefixo, origem_id, origem_ordem, origem_seq, operador)
            VALUES (NEW.id_empresa, NEW.id_estlocal, NEW.id_produto_dest, ' ', ' ',
                    'I', 'SPD', ' ', ' ', NEW.data,
                    NEW.historico, 'E', NEW.qtdade, vvalor, 0,
                    1, 'SPD', NEW.id_estmovto, 2, 1,'SPED K220');
                    
        
      END IF;
      RETURN NEW;
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
--RUN--

DROP TRIGGER gera_estmovto_k220 ON gestao.spedk220;
--RUN--IGNORE ERRO

CREATE TRIGGER gera_estmovto_k220
  AFTER INSERT OR DELETE
  ON gestao.spedk220
  FOR EACH ROW
  EXECUTE PROCEDURE gestao.gera_estmovto_k220();
--RUN--
