
-- StoreProcedure {atualizaSaldoCC()} Versao {24} Esquema {padrao} Descricao {Grava/atualiza saldos da Conta Corrente}
-- -----------------------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION padrao.atualizaSaldoCC(integer, date, boolean)
  RETURNS boolean AS

$BODY$

DECLARE
 p_idcc           ALIAS FOR $1;
 p_database       ALIAS FOR $2;
 p_todos          ALIAS FOR $3;
 v_resultado      RECORD;
 v_fadiv          RECORD;
 v_database       Date;
 v_dataquebra     Date;
 v_recno          BigInt;
 v_TipoSaldo      char(1);
 aCampos          character varying[];
 aDados           character varying[];

 msaldo_vcto            NUMERIC(16,4);
 msaldo_conciliado      NUMERIC(16,4);
 msaldo_emissao         NUMERIC(16,4);
 msaldo_referencia      NUMERIC(16,4);

 
 
 BEGIN
   IF p_todos = True THEN
      v_database = CAST('01/01/1500' AS DATE);
   ELSE
      v_database = p_database;
      v_database = v_database - 1;
   END IF;

   msaldo_vcto          = 0; -- data_vencimento 
   msaldo_conciliado    = 0; -- data_conciliacao
   msaldo_emissao       = 0; -- data_emissao
   msaldo_referencia    = 0; -- data_referencia 



-- acha saldo inicial - Emissao
   SELECT datasaldo, saldo
     INTO v_resultado
     FROM financ_cc_saldo
    WHERE idcc          = p_idcc
      AND naturezasaldo = 'E'
      AND datasaldo    <= v_DataBase
    ORDER BY datasaldo DESC, idcc DESC
    LIMIT 1;
    
    IF FOUND THEN
       --RAISE NOTICE '****** PEGANDO SALDO INICIAL(% - %")', v_resultado.datasaldo, p_DataBase;
       IF p_DataBase >=  v_resultado.datasaldo THEN
          msaldo_emissao   = v_resultado.saldo;
        --delete saldo da data base
          DELETE FROM financ_cc_saldo WHERE idcc = p_idcc AND datasaldo >= p_database AND naturezasaldo = 'E';
       END IF;  
    END IF;
    
-- acha saldo inicial - Vencimento
   SELECT datasaldo, saldo
     INTO v_resultado
     FROM financ_cc_saldo
    WHERE idcc          = p_idcc
      AND naturezasaldo = 'V'
      AND datasaldo    <= v_DataBase
    ORDER BY datasaldo DESC, idcc DESC
    LIMIT 1;
    
    IF FOUND THEN
       --RAISE NOTICE '****** PEGANDO SALDO INICIAL(% - %")', v_resultado.datasaldo, p_DataBase;
       IF p_DataBase >=  v_resultado.datasaldo THEN
          msaldo_vcto  = v_resultado.saldo;
        --delete saldo da data base
           DELETE FROM financ_cc_saldo WHERE idcc = p_idcc AND datasaldo >= p_database AND naturezasaldo = 'V';          
       END IF;  
    END IF;    

-- acha saldo inicial - Conciliado
   SELECT datasaldo, saldo
     INTO v_resultado
     FROM financ_cc_saldo
    WHERE idcc          = p_idcc
      AND naturezasaldo = 'C'
      AND datasaldo    <= v_DataBase
    ORDER BY datasaldo DESC, idcc DESC
    LIMIT 1;
    
    IF FOUND THEN
       --RAISE NOTICE '****** PEGANDO SALDO INICIAL(% - %")', v_resultado.datasaldo, p_DataBase;
       IF p_DataBase >=  v_resultado.datasaldo THEN
          msaldo_Conciliado        = v_resultado.saldo;
        --delete saldo da data base
          DELETE FROM financ_cc_saldo WHERE idcc = p_idcc AND datasaldo >= p_database AND naturezasaldo = 'C';          
       END IF;  
    END IF;    
    
-- acha saldo inicial - Referencia
   SELECT datasaldo, saldo
     INTO v_resultado
     FROM financ_cc_saldo
    WHERE idcc          = p_idcc
      AND naturezasaldo = 'R'
      AND datasaldo    <= v_DataBase
    ORDER BY datasaldo DESC, idcc DESC
    LIMIT 1;
    
    IF FOUND THEN
       --RAISE NOTICE '****** PEGANDO SALDO INICIAL(% - %")', v_resultado.datasaldo, p_DataBase;
       IF p_DataBase >=  v_resultado.datasaldo THEN
          msaldo_Referencia        = v_resultado.saldo;
        --delete saldo da data base
          DELETE FROM financ_cc_saldo WHERE idcc = p_idcc AND datasaldo >= p_database AND naturezasaldo = 'R';          
       END IF;  
    END IF;    
        
-- atualiza registros a partir da data base - data_vencimento
   v_dataquebra = p_database;
   v_TipoSaldo  = 'V';
   FOR v_resultado IN SELECT financ_cc_movto.controle,
                             financ_cc_movto.cad_filial_id,
                             financ_cc_movto.data_emissao,
                             financ_cc_movto.data_vencimento,
                             financ_cc_movto.data_referencia,
                             financ_cc_movto.data_conciliacao,
                             financ_cc_movto.fat_transacao_id,
                             financ_cc_movto.natureza,
                             financ_cc_movto.cancelado,
                             financ_cc_movto.valor_cancelado,
                             financ_cc_movto.valor,
                             COALESCE((SELECT substring(propriedade from 1 for 1) FROM view_transacao WHERE codigo_transacao = financ_cc_movto.fat_transacao_id AND diretiva = 410),'S') AS atualiza_saldo
                        FROM financ_cc_movto
                       WHERE financ_cc_movto.financ_cc_id       = p_idcc
                         AND financ_cc_movto.data_vencimento   >= p_database
                       ORDER BY financ_cc_movto.data_vencimento, financ_cc_movto.controle
                       LOOP
      --RAISE NOTICE 'Natureza(%")', v_resultado.natureza;
      --RAISE NOTICE 'Valor...(%")', v_resultado.valor;


      IF substring(v_resultado.natureza from 1 for 1) = 'C' THEN -- Debito
         IF v_resultado.cancelado = true THEN -- Se cancelado
           msaldo_vcto  = msaldo_vcto;  
         ELSIF v_resultado.atualiza_saldo = 'N' THEN
           msaldo_vcto  = msaldo_vcto;
         ELSE
           msaldo_vcto  = msaldo_vcto + v_resultado.Valor; 
         END IF;
      ELSEIF substring(v_resultado.natureza from 1 for 1) = 'D' THEN
         IF v_resultado.cancelado = true THEN -- Se cancelado
           msaldo_vcto  = msaldo_vcto;  
         ELSIF v_resultado.atualiza_saldo = 'N' THEN
           msaldo_vcto  = msaldo_vcto;
         ELSE
           msaldo_vcto  = msaldo_vcto - v_resultado.Valor; 
         END IF;
      END IF;
      --RAISE NOTICE 'msaldo_vcto...(%")', msaldo_vcto;
      --RAISE NOTICE 'Data_Vcto...(%") - Data quebra(%)', v_resultado.data_vencimento,v_dataquebra ;
      --Quebra por data
   	  IF  v_resultado.data_vencimento >= v_dataquebra THEN  
   	     aCampos =  '{ idcc, datasaldo, saldo }';
		 aDados  =  '{' || to_char(p_idcc,'99999')                                 ||  ','
		 			    || to_Char(v_resultado.data_vencimento::DATE,'dd/MM/yyyy') ||  ','
		 		        || to_Char(msaldo_vcto,'999999999.99')                     ||  '}';
		 		       
		 
		 --RAISE NOTICE 'aCampos: (%)',     aCampos;
		 --RAISE NOTICE 'aDados: (%)',      aDados;
		 IF aDados IS NULL THEN
			    RAISE EXCEPTION 'Nao sera possivel persistir Saldo pelo vencimento. 
		                      Dados para Saldo esta incompleto.Verifique Campos <NULL>: 
		                     (idcc:%            
		                      datasaldo:%         
		                      saldo_vcto:% )',
		                      to_char(p_idcc,'99999') ,                                               
			                  to_Char(v_resultado.data_vencimento::DATE, 'dd/MM/yyyy'),  
			                  to_Char(msaldo_vcto, '999999999.99') ;                               
		  END IF;
		  IF NOT padrao.gravasaldoCC(aCampos, aDados, v_TipoSaldo) THEN
			    RAISE EXCEPTION 'Nao foi possivel persistir saldo pelo vcto (Conta.:%  - ARRAY:%)!',p_idcc, aDados;
		  END IF;
		  v_dataquebra = v_resultado.data_vencimento;
      END IF;      
   END LOOP;

   v_dataquebra = p_database;
   v_TipoSaldo  = 'C';
   FOR v_resultado IN SELECT financ_cc_movto.controle,
                             financ_cc_movto.cad_filial_id,
                             financ_cc_movto.data_emissao,
                             financ_cc_movto.data_vencimento,
                             financ_cc_movto.data_referencia,
                             financ_cc_movto.data_conciliacao,
                             financ_cc_movto.fat_transacao_id,
                             financ_cc_movto.natureza,
                             financ_cc_movto.cancelado,
                             financ_cc_movto.valor_cancelado,
                             financ_cc_movto.valor,
                             COALESCE((SELECT substring(propriedade from 1 for 1) FROM view_transacao WHERE codigo_transacao = financ_cc_movto.fat_transacao_id AND diretiva = 410),'S') AS atualiza_saldo
                        FROM financ_cc_movto
                       WHERE financ_cc_movto.financ_cc_id        = p_idcc
                         AND financ_cc_movto.data_conciliacao   >= p_database
                       ORDER BY financ_cc_movto.data_conciliacao, financ_cc_movto.controle
                       LOOP
      --RAISE NOTICE 'Natureza(%")', v_resultado.natureza;
      --RAISE NOTICE 'Valor...(%")', v_resultado.valor;
      IF substring(v_resultado.natureza from 1 for 1) = 'C' THEN -- Debito
         IF v_resultado.cancelado = true THEN -- Se cancelado
           msaldo_conciliado  = msaldo_conciliado;  
         ELSIF v_resultado.atualiza_saldo = 'N' THEN
           msaldo_vcto  = msaldo_vcto;
         ELSE
           msaldo_conciliado  = msaldo_conciliado + v_resultado.Valor; 
         END IF;
      ELSEIF substring(v_resultado.natureza from 1 for 1) = 'D' THEN
         IF v_resultado.cancelado = true THEN -- Se cancelado
           msaldo_conciliado  = msaldo_conciliado;  
         ELSIF v_resultado.atualiza_saldo = 'N' THEN
           msaldo_vcto  = msaldo_vcto;
         ELSE
           msaldo_conciliado  = msaldo_conciliado - v_resultado.Valor; 
         END IF;
      END IF;
      --RAISE NOTICE 'msaldo_vcto...(%")', msaldo_conciliado;
      --RAISE NOTICE 'Data_Conciliacao...(%") - Data quebra(%)', v_resultado.data_conciliacao,v_dataquebra ;
      --Quebra por data
   	  
      IF  v_resultado.data_conciliacao >= v_dataquebra THEN  
		
          -- Grava
		
           aCampos =  '{ idcc, datasaldo, saldo }';
		  
		  aDados  =  '{' || to_char(p_idcc,'99999')                                  || ','
		 			    || to_Char(v_resultado.data_conciliacao::DATE,'dd/MM/yyyy') || ','
		 		        || to_Char(msaldo_conciliado,'999999999.99')                || '}';
		  
		
		  
		 IF aDados IS NULL THEN
			    RAISE EXCEPTION 'Nao sera possivel persistir Saldo pelo data de conciliacao. 
		                      Dados para Saldo esta incompleto.Verifique Campos <NULL>: 
		                     (idcc:%            
		                      datasaldo:%         
		                      saldo de vcto:% )',
		                      to_char(p_idcc,'99999') ,                                               
			                  to_Char(v_resultado.data_conciliacao::DATE, 'dd/MM/yyyy'),  
			                  to_Char(msaldo_conciliado, '999999999.99') ;                               
		  END IF;
		  
		  IF NOT padrao.gravasaldoCC(aCampos, aDados, v_TipoSaldo) THEN
			    RAISE EXCEPTION 'Nao foi possivel persistir saldo pela data de conciliacao (Conta.:%  - ARRAY:%)!',p_idcc, aDados;
		  END IF;
		  
		  v_dataquebra = v_resultado.data_conciliacao;
		  
      END IF;      
     
   END LOOP;
-- atualiza registros a partir da data base - data_emissao
   v_dataquebra = p_database;
   v_TipoSaldo  = 'E';
   FOR v_resultado IN SELECT financ_cc_movto.controle,
                             financ_cc_movto.cad_filial_id,
                             financ_cc_movto.data_emissao,
                             financ_cc_movto.data_vencimento,
                             financ_cc_movto.data_referencia,
                             financ_cc_movto.data_conciliacao,
                             financ_cc_movto.fat_transacao_id,
                             financ_cc_movto.natureza,
                             financ_cc_movto.cancelado,
                             financ_cc_movto.valor_cancelado,
                             financ_cc_movto.valor,
                             COALESCE((SELECT substring(propriedade from 1 for 1) FROM view_transacao WHERE codigo_transacao = financ_cc_movto.fat_transacao_id AND diretiva = 410),'S') AS atualiza_saldo
                        FROM financ_cc_movto
                       WHERE financ_cc_movto.financ_cc_id       = p_idcc
                         AND financ_cc_movto.data_emissao      >= p_database
                       ORDER BY financ_cc_movto.data_emissao, financ_cc_movto.controle
                       LOOP

       

  
     
                       
      IF substring(v_resultado.natureza from 1 for 1) = 'C' THEN -- Debito
      
         IF v_resultado.cancelado = true THEN -- Se cancelado
           msaldo_emissao  = msaldo_emissao;  
         ELSIF v_resultado.atualiza_saldo = 'N' THEN
           msaldo_vcto  = msaldo_vcto;
         ELSE
           msaldo_emissao  = msaldo_emissao + v_resultado.Valor; 
         END IF;
      ELSEIF substring(v_resultado.natureza from 1 for 1) = 'D' THEN
         IF v_resultado.cancelado = true THEN 
           msaldo_emissao  = msaldo_emissao;  
         ELSIF v_resultado.atualiza_saldo = 'N' THEN
           msaldo_vcto  = msaldo_vcto;
         ELSE
           msaldo_emissao  = msaldo_emissao - v_resultado.Valor; 
         END IF;
      END IF;

       --RAISE NOTICE '**************** msaldo_emissao...(%")', msaldo_emissao;
    
      --Quebra por data
   	  
      IF  v_resultado.data_emissao >= v_dataquebra THEN  
        
		
   	      aCampos =  '{ idcc, datasaldo, saldo }';
			    
		  
		 aDados  =  '{' || to_char(p_idcc,'99999')                              || ','
		 			    || to_Char(v_resultado.data_emissao::DATE,'dd/MM/yyyy') || ','
		 		        || to_Char(msaldo_emissao,'999999999.99')               || '}';
		 		          
		  
		
		  
		 IF aDados IS NULL THEN
			    RAISE EXCEPTION 'Nao sera possivel persistir Saldo pela emissao. 
		                      Dados para Saldo esta incompleto.Verifique Campos <NULL>: 
		                     (idcc:%            
		                      datasaldo:%         
		                      saldo de emissao:% )',
		                      to_char(p_idcc,'99999') ,                                               
			                  to_Char(v_resultado.data_emissao::DATE, 'dd/MM/yyyy'),  
			                  to_Char(msaldo_emissao, '999999999.99') ;                               
		  END IF;
		   
		  IF NOT padrao.gravasaldoCC(aCampos, aDados, v_TipoSaldo) THEN
			    RAISE EXCEPTION 'Nao foi possivel persistir saldo pela data de emissao (Conta.:%  - ARRAY:%)!',p_idcc, aDados;
		  END IF;
		  
		  -- Atualiza v_DataQuebra
		  
		  v_dataquebra = v_resultado.data_emissao;
		  
      END IF;   
   END LOOP;   
-- atualiza registros a partir da data base - data_referencia
   v_dataquebra = p_database;
   v_TipoSaldo  = 'R';
   FOR v_resultado IN SELECT financ_cc_movto.controle,
                             financ_cc_movto.cad_filial_id,
                             financ_cc_movto.data_emissao,
                             financ_cc_movto.data_vencimento,
                             financ_cc_movto.data_referencia,
                             financ_cc_movto.data_conciliacao,
                             financ_cc_movto.fat_transacao_id,
                             financ_cc_movto.natureza,
                             financ_cc_movto.cancelado,
                             financ_cc_movto.valor_cancelado,
                             financ_cc_movto.valor,
                             COALESCE((SELECT substring(propriedade from 1 for 1) FROM view_transacao WHERE codigo_transacao = financ_cc_movto.fat_transacao_id AND diretiva = 410),'S') AS atualiza_saldo
                        FROM financ_cc_movto
                       WHERE financ_cc_movto.financ_cc_id       = p_idcc
                         AND financ_cc_movto.data_referencia   >= p_database
                       ORDER BY financ_cc_movto.data_referencia, financ_cc_movto.controle
                       LOOP

       

  
      
                       
      IF substring(v_resultado.natureza from 1 for 1) = 'C' THEN -- Debito
      
         IF v_resultado.cancelado = true THEN -- Se cancelado
           msaldo_referencia  = msaldo_referencia;  
         ELSIF v_resultado.atualiza_saldo = 'N' THEN
           msaldo_vcto  = msaldo_vcto;
         ELSE
           msaldo_referencia  = msaldo_referencia + v_resultado.Valor; 
         END IF;
      ELSEIF substring(v_resultado.natureza from 1 for 1) = 'D' THEN
         IF v_resultado.cancelado = true THEN -- Se cancelado
           msaldo_referencia  = msaldo_referencia;  
         ELSIF v_resultado.atualiza_saldo = 'N' THEN
           msaldo_vcto  = msaldo_vcto;
         ELSE
           msaldo_referencia  = msaldo_referencia - v_resultado.Valor; 
         END IF;
      END IF;
      
     
      --Quebra por data
   	  
      IF  v_resultado.data_referencia >= v_dataquebra THEN  
         
   	      
   
		 -- Grava ProdutoMovto
		
       aCampos =  '{ idcc, datasaldo, saldo }';
			    
		  
		 aDados  =  '{' || to_char(p_idcc,'99999')                              || ','
		 			    || to_Char(v_resultado.data_emissao::DATE,'dd/MM/yyyy') || ','
		 		        || to_Char(msaldo_referencia,'999999999.99')            || '}';
		 		          
		  
		
		  
		 IF aDados IS NULL THEN
			    RAISE EXCEPTION 'Nao sera possivel persistir Saldo pela data referencia. 
		                      Dados para Saldo esta incompleto.Verifique Campos <NULL>: 
		                     (idcc:%            
		                      datasaldo de Referencia:%         
		                      saldo:% )',
		                      to_char(p_idcc,'99999') ,                                               
			                  to_Char(v_resultado.data_referencia::DATE, 'dd/MM/yyyy'),  
			                  to_Char(msaldo_referencia, '999999999.99') ;                               
		  END IF;
		  
		  IF NOT padrao.gravasaldoCC(aCampos, aDados, v_TipoSaldo) THEN
			    RAISE EXCEPTION 'Nao foi possivel persistir saldo pela data de referencia (Conta.:%  - ARRAY:%)!',p_idcc, aDados;
		  END IF;
		
		  -- Atualiza v_DataQuebra
		   
		  v_dataquebra = v_resultado.data_referencia;
      END IF; 
   END LOOP;  
   RETURN NULL;		    	      
END;

$BODY$

LANGUAGE 'plpgsql' VOLATILE;

 