Identificador de Regra
TES-606APEPM01
Módulo: TES - Tesouraria
Finalidade: O objetivo desse identificador é permitir o cálculo das prestações dos contratos de empréstimos de forma alternativa a embarcada no ERP, diretamente através de regra ou através da importação de um arquivo CSV e que também pode ter o complemento de regra.
Características: Existe uma hierarquia de execução da regra, na qual o campo de regra de cálculo do contrato de empréstimo tem prioridade sobre a regra ligada ao identificador. Sendo assim, se existir regra informada no cadastro do identificador e regra ligada no cadastro do contrato, a regra do contrato será a executada pois tem prioridade sobre a ligada ao identificador.
"INCLUSAO" - ao clicar no botão Mostrar para contrato aberto, será executada a regra com esta operação.
"ATUALIZACAO" - ao clicar no botão Atualizar será executada a regra com esta operação.
"CSV" - indica para a regra que a origem das prestações é uma planilha.
"REGRA" - indica para a regra que as prestações foram geradas via cálculo realizado na regra.
Na regra constam todos os campos das tabelas Financeiro-Aplicação\Captação Recursos - Cadastro (E606CCR) e Financeiro-Cálculo Contratos Aplicação\Captação Recursos (E606CAC), porém nenhum campo retornará alteração para o sistema. A partir desses dados é possível buscar qualquer informação relacionada ao contrato, tais como lista de parcelas, itens do cálculo do contrato, etc.
Uma lista com os registros das prestações também está disponível na regra através de um ponteiro de memória. Essa lista possui campos da tabela Financeiro-Aplicação\Captação Recursos-Prestações (E606PRE), além de alguns campos que são utilizados na guia Geração e Atualização de Prestações para a apresentação das informações relacionadas a elas. A lista de campos está detalhada abaixo, na tabela de variáveis disponíveis na regra.
Para sabermos como a lista de prestações chega até a regra, precisamos levar em consideração o conteúdo das variáveis VarATipExe e VarAPlaCal, conforme a seguinte combinação:
- Se a primeira for INCLUSAO e a segunda REGRA, a lista de prestações chega na regra sem nenhum registro e deverá ser alimentada de acordo com o cálculo a ser realizado e os campos disponíveis, para retornar à rotina as prestações conforme necessidade do cliente;
- Se a primeira for INCLUSAO e a segunda CSV, a lista de prestações chega na regra com os registros carregados a partir da planilha .csv, e poderá sofrer alterações de acordo com o cálculo a ser realizado e os campos disponíveis, para retornar à rotina as prestações conforme necessidade do cliente;
- Se a primeira for ATUALIZACAO independentemente da segunda ser CSV ou REGRA, a lista de prestações chega na regra com todas as prestações salvas nas tabelas do sistema conforme foram inseridas previamente, e só permitirá a edição dos campos de valores para que a atualização das prestações possa ocorrer. A utilização da variável VarAPlaCal dentro da regra para diferenciar o conteúdo entre CSV e REGRA, pode ser feita para um tratamento diferenciado que se deseje realizar caso as prestações estejam sendo calculadas por planilha ou o cálculo esteja sendo totalmente realizado dentro da regra.
ListaRegraPrimeiro(CcrNLista, A_S_N);
ListaRegraProximo(CcrNLista, A_S_N);
ListaRegraAnterior(CcrNLista, A_S_N);
ListaRegraUltimo(CcrNLista, A_S_N);
ListaRegraInicio(CcrNLista, A_S_N);
ListaRegrafim(CcrNLista, A_S_N);
ListaRegraObterValorAlfa(CcrNLista, "TipPre", aTipPre, A_S_N);
ListaRegraObterValorNumero(CcrNLista, "SeqPre", aSeqPre, A_S_N);
ListaRegraObterValorData(CcrNLista, "DatPre", aDatPre, A_S_N);
ListaRegraProcurarAfa(CcrNLista, "TipPre", aTipPre, A_S_N);
ListaRegraProcurarNumero(CcrNLista, "SeqPre", aSeqPre, A_S_N);
ListaRegraProcurarData(CcrNLista, "DatPre", aDatPre, A_S_N);
ListaRegraProcurarRegistro(CcrNLista, A_S_N);
ListaRegraTotalLinhas(CcrNLista, VenATotalLinha);
ListaRegraAddValorLinhaAlfa(CcrNLista, 'TipPre', aTipPre, A_S_N);
ListaRegraAddValorLinhaNumero(CcrNLista, 'SeqPre', aSeqPre, A_S_N);
ListaRegraAddValorLinhaData(CcrNLista, 'DatPre', aDatPre, A_S_N);
ListaRegraInicializarProcurar(CcrNLista, A_S_N);
ListaRegraAddProcurarAlfa(CcrNLista, 'TipPre', aTipPre, A_S_N);
ListaRegraAddProcurarNumero(CcrNLista, 'SeqPre', aSeqPre, A_S_N);
ListaRegraAddProcurarData(CcrNLista, 'DatPre', aDatPre, A_S_N);
ListaRegraNovaLinha(CcrNLista);
ListaRegraSalvarLinha(CcrNLista);
ListaRegraExcluirLinha(CcrNLista);
ListaRegraSalvarLista(CcrNLista, "C:
ListaRegraEmInclusao(CcrNLista, A_S_N);
ListaRegraPosicaoAtual(CcrNLista, VenMPosicaoAtual);
ListaRegraPodeExcluir(CcrNLista, A_S_N);
ListaRegraPodeAlterar(CcrNLista, A_S_N);
ListaRegraPodeIncluir(CcrNLista, A_S_N);
ListaRegraProcurarProximo(CcrNLista, A_S_N);
ListaRegraProcurarAnterior(CcrNLista, A_S_N);
ListaRegraIrPara(CcrNLista, 3, A_S_N);
ListaRegraAlterarLinhaAlfa(CcrNLista, 'TipPre', aTipPre, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, 'SeqPre', aSeqPre, A_S_N);
ListaRegraAlterarLinhaData(CcrNLista, 'DatPre', aDatPre, A_S_N).
Tela: F606APE
Variáveis Disponibilizadas:
Nome | Tipo | Observações | Retorna Valor |
---|---|---|---|
VarATipExe | Alfa | Receberá na regra INCLUSAO ou ATUALIZACAO. | N |
VarAPlaCal | Alfa | Receberá na regra CSV ou REGRA | N |
CcrNLista | Número | Endereço da lista em memória (ver tabela abaixo). | S |
Colunas disponíveis na variável CcrNLista | ||
---|---|---|
Nome | Tipo | Observações |
DatPre | Data | Data da prestação. |
SeqPre | Número | Sequência da prestação. |
SeqVct | Número | Sequência no vencimento do contrato. |
PreCar | Alfa | Indicativo se a prestação é de carência (S ou N). |
PreJrs | Alfa | Indicativo se a prestação é de juros (S ou N). |
VctPre | Alfa | Indicativo se é uma prestação a pagar (S ou N) ou somente cálculo de atualização de conta. |
TipPre | Alfa | Indicativo do tipo de prestação (C - atualização, P - prestação ou U - último dia da competência). |
VlrAmo | Número | Valor da amortização do saldo devedor da prestação. |
AmoOri | Número | Valor da amortização original do saldo devedor da prestação. |
VlrJrs | Número | Valor dos juros da prestação. |
JrsOri | Número | Valor dos juros originais da prestação. |
VlrPre | Número | Valor da prestação. |
PreOri | Número | Valor original da prestação. |
VlrJmc | Número | Valor rateado dos juros dos meses de carência. |
SalDev | Número | Valor do saldo devedor do contrato após cálculo da prestação. |
DscNeg | Número | Valor do desconto, utilizado para atualização de contrato quando o valor da prestação já salvo diminuir. |
OutNeg | Número | Valor do acréscimo, utilizado para atualização de contrato quando o valor da prestação já salvo aumentar. |
PreRes | Alfa | Indicativo se a prestação é de residual (S ou N). |
TemBai | Alfa | Indicativo se o título associado a esta parcela já possui baixa (S ou N). |
JrsMoe | Número | Juros na moeda do título |
AmoMoe | Número | Amortização na moeda do título |
PreMoe | Número | Valor a ser pago na prestação na moeda do título |
SalMoe | Número | Valor do saldo devedor do contrato após cálculo da prestação na moeda do título |
CorMoe | Número | Valor da correção monetária para o valor da prestação |
CorMoeAnt | Número | Valor da correção monetária para o valor da prestação anteriormente calculado |
CorJur | Número | Valor da correção monetária para o juros |
CorJurAnt | Número | Valor da correção monetária para o juros anteriormente calculado |
VlrAmoAnt | Número | Valor amortização do saldo devedor da prestação anteriormente calculado |
VlrJrsAnt | Número | Valor dos juros da prestação anteriormente calculado |
DscNegAnt | Número | Valor do desconto anteriormente calculado |
OutNegAnt | Número | Valor do acréscimo anteriormente calculado |
A importação de CSV requer alguns cuidados mínimos para ocorrer. Primeiramente, os campos disponíveis são os mesmos que compõem as colunas da lista CcrNLista. Um segundo ponto importante é que os arquivos deverão conter minimamente as colunas DATPRE, SEQPRE, PREJRS, VLRAMO, VLRJRS, VLRPRE, SALDEV que são obrigatórias para todos os arquivos CSV serem considerados válidos na rotina.
A definição das colunas que serão importadas no CSV informado no contrato deve constar na primeira linha do arquivo, sem informar colunas em branco. As linhas seguintes devem conter as informações de cada prestação calculada, e cada célula deve ter uma informação compatível com a referida coluna (datas válidas, valores válidos, caracteres onde for exigido caracter, etc.)
Importante:
- Valores de data devem ser informados no formato "DD/MM/YYYY";
- Valores do tipo alfanumérico são um caracter apenas, que deve ser maiúsculo;
- Valores numéricos que trouxerem informação com valor decimal, devem ter a máscara configurada para apresentar somente o separador decimal ",", sem separador de milhares.
Exemplo de planilha CSV com informações a serem importadas:
Observação
Conforme pode ser verificado na figura, o arquivo conterá somente as informações pertinentes as prestações a serem importadas no sistema. A sugestão é que todo o cálculo seja realizado em planilhas ou abas separadas, e uma aba ou planilha receba as informações finais das prestações para que o arquivo CSV seja salvo.
Exemplos de regras com o cálculo das prestações
Lembrando que as regras abaixo são exemplos, e não fazem parte do produto padrão. Cada cliente deve adequar a regra conforme sua necessidade.
Declarações
@ Lista de prestações a serem pagas
Definir Numero CcrNLista;
@ Variável global utilizada para verificar se a execução dos métodos ocorreu com sucesso @
Definir Alfa A_S_N;
@ Valor definido na aplicação que indica se é inclusão de cálculo ou atualização @
Definir Alfa VarATipExe;
@ Variáveis globais de uso geral @
Definir Numero nCodEmp; @ Empresa do contrato @
Definir Numero nCodCac; @ Código do cálculo do contrato @
Definir Numero nVlrEmp; @ Valor do empréstimo @
Definir Numero nVlrJrs; @ Valor dos juros @
Definir Numero nSalDev; @ Saldo devedor a cada prestação @
Definir Numero nVlrAtu; @ Valor atualizado após cálculo de cada prestação @
Definir Numero nVlrAmo; @ Valor da amortização @
Definir Numero nDiaIni; @ Dia...@
Definir Numero nMesIni; @ Mês...@
Definir Numero nAnoIni; @ e Ano para início de cálculo de juros @
Definir Numero nDiaAtu; @ Dia... @
Definir Numero nMesAtu; @ Mês... @
Definir Numero nAnoAtu; @ e Ano de cada prestação gerada @
Definir Data dPreAtu; @ Data da prestação atual @
Definir Alfa aCodMoe; @ Código da moeda @
Definir Numero nCotMoe; @ Cotação do índice informado no cálculo do contrato @
Definir Numero nQtdPrestGeradas; @ Quantidade de prestações do contrato @
Definir Numero nTemCalculo; @ Variável para controlar looping de cálculos para cada prestação @
Definir Numero nTemPrestacao; @ Variável para controlar looping das prestações a serem geradas @
Definir Alfa aPreJrs; @ Indica se a prestação é somente para pagamento de juros @
@ Cursores e listas@
Definir Lista lis_ItemCalculo; @ Lista dos itens de cálculo do contrato @
Definir Lista lis_Prestacoes; @ Lista que gurada as prestações do contrato @
Definir Cursor Cur_E606ICC; @ Cursor para selecionar os itens de cálculo do contrato @
Definir Cursor Cur_E031IMO; @ Cursor para buscar as cotações do índice ligado ao cálculo do contrato @
@ Funções @
Definir Funcao Inicializar();
Definir Funcao InicializarListas();
Definir Funcao GerarPrestacoes();
Definir Funcao InserePagamentoLista();
Definir Funcao AlteraPagamentoLista();
Definir Funcao Finalizar();
@ Método principal @
Inicializar();
GerarPrestacoes();
Finalizar();
@ Inicializar lista de sequências de cálculo do contrato e lista de prestações @
Funcao InicializarListas(); {
lis_ItemCalculo.DefinirCampos();
lis_ItemCalculo.AdicionarCampo("SEQCAL", Numero); @ Sequência do cálculo @
lis_ItemCalculo.AdicionarCampo("TIPCAL", Alfa); @ Tipo do cálculo (V-Valor, D-Índice, P-Percentual (taxa fixa), H-Hora) @
lis_ItemCalculo.AdicionarCampo("CODMOE", Alfa); @ Moeda/Índice do cálculo caso seja do tipo "D" @
lis_ItemCalculo.AdicionarCampo("VALPER", Numero); @ Valor/Percentual conforme tipo @
lis_ItemCalculo.EfetivarCampos();
lis_Prestacoes.DefinirCampos();
lis_Prestacoes.AdicionarCampo("SEQPRE", Numero); @ Sequência da prestação @
lis_Prestacoes.AdicionarCampo("DATPGT", Data); @ Data de pagamento da prestação @
lis_Prestacoes.AdicionarCampo("DIAPRE", Numero); @ Dia... @
lis_Prestacoes.AdicionarCampo("MESPRE", Numero); @ Mês... @
lis_Prestacoes.AdicionarCampo("ANOPRE", Numero); @ E ano da prestação @
lis_Prestacoes.AdicionarCampo("VLRPRE", Numero); @ Valor da prestação @
lis_Prestacoes.EfetivarCampos();
}
Funcao GerarPrestacoes(); {
Definir Numero nVlrPre;
Cur_E031IMO.Sql "SELECT CODMOE, DATMOE, VLRCOT FROM E031IMO WHERE CODMOE = :ACODMOE AND DATMOE = :DPREATU AND VLRCOT > 0 ORDER BY DATMOE DESC";
nQtdPrestGeradas = 0;
@ Iniciar looping a partir da data de início do contrato. Looping enquanto ainda existir saldo devedor e/ou não atingir a data final do contrato pelo período de quebra (dia, quinzena, mês, bimestre, etc.)@
nTemPrestacao = lis_Prestacoes.Primeiro();
Enquanto ((nSalDev > 0) e (nTemPrestacao = 1)) {
@ Posicionar no primeiro item de cálculo do contrato @
nTemCalculo = lis_ItemCalculo.Primeiro();
@ Quebra na data base para cálculo da prestação @
MontaData(nDiaAtu, nMesAtu, nAnoAtu, dPreAtu);
@ Busca próximo mês a ser calculado @
SomarMesesDataRef(dPreAtu, 1 @incrementa 1 mês@ , 0 @opção 0 não altera o dia do vencimento@ , dPreAtu);
@ Atualiza variáveis com a próxima data que será gerada prestação @
DesMontaData(dPreAtu, nDiaAtu, nMesAtu, nAnoAtu);
nVlrAtu = nSalDev;
nVlrJrs = 0;
Enquanto (nTemCalculo = 1) { @ Enquanto tiver item de cálculo @
se (lis_ItemCalculo.TIPCAL = "D") { @ Buscar índice da data, aplicar índice no valor @
aCodMoe = lis_ItemCalculo.CODMOE;
Cur_E031IMO.AbrirCursor();
se (Cur_E031IMO.Achou) {
nCotMoe = Cur_E031IMO.VlrCot;
@ Caso atender, pode ser utilizado o objeto de multi moeda ao invés do cursor Cur_E031IMO @
@ MMBuscaCotacaoMoeda(aCodMoe, dPreAtu, 0, nCotMoe); @
nVlrJrs = nVlrJrs + (nVlrAtu * (nCotMoe/100));
nVlrAtu = nVlrAtu + (nVlrAtu * (nCotMoe/100));
}
Senao {
Definir Alfa aDia;
Definir Alfa aMes;
Definir Alfa aAno;
DecimalParaAlfa(nDiaAtu, aDia);
DecimalParaAlfa(nMesAtu, aMes);
DecimalParaAlfa(nAnoAtu, aAno);
/*mensagem(erro, "Não foi encontrada cotação para a moeda "+aCodMoe+" no dia "+aDia+"/"+aMes+"/"+aAno+".");*/
}
Cur_E031IMO.FecharCursor();
}
senao se (lis_ItemCalculo.TIPCAL = "P") { @ aplicar taxa fixa @
nVlrJrs = nVlrJrs + (nVlrAtu * (lis_ItemCalculo.VALPER/100));
nVlrAtu = nVlrAtu + (nVlrAtu * (lis_ItemCalculo.VALPER/100));
}
nTemCalculo = lis_ItemCalculo.Proximo();
}
@ verificar se é prestação somente de juros ou de juros e amortização. Os meses de amortização do saldo deverão estar no contrato ou na regra @
Se ((lis_Prestacoes.MESPRE = nMesAtu) e (lis_Prestacoes.ANOPRE = nAnoAtu)) { @ Amortização de saldo devedor junto com juros @
nVlrAmo = lis_Prestacoes.VLRPRE;
nTemPrestacao = lis_Prestacoes.Proximo();
ArredondarValor(nVlrAmo,2);
Se (nTemPrestacao = 0) {
nVlrAmo = nSaldev;
nVlrPre = nVlrAtu - nSalDev + nVlrAmo;
nSalDev = 0;
}
Senao {
nVlrPre = nVlrAtu - nSalDev + nVlrAmo;
nSalDev = nSaldev - nVlrAmo;
}
aPreJrs = "N";
}
Senao {
nVlrAmo = 0;
nVlrPre = nVlrAtu - nSalDev;
aPreJrs = "S";
}
@ Gravar dados da prestação na lista @
nQtdPrestGeradas = nQtdPrestGeradas + 1;
se (VarATipExe = "INCLUSAO")
InserePagamentoLista();
senao
AlteraPagamentoLista();
}
}
Funcao InserePagamentoLista(); {
ListaRegraPodeIncluir(CcrNLista, A_S_N); @ Verifica se tem permissão para incluir @
se (A_S_N = "S") {
ListaRegraNovaLinha(CcrNLista); @ Prepara lista para inclusão de uma nova linha. Deve ser chamado sempre que for usar os métodos incluir as colunas. @
ListaRegraEmInclusao(CcrNLista, A_S_N); @ Verifica situação da lista. @
se (A_S_N = "S") {
ListaRegraAddValorLinhaData(CcrNLista, "DatPre", dPreAtu, A_S_N); @ Adiciona data da prestação @
ListaRegraAddValorLinhaNumero(CcrNLista, "SeqPre", nQtdPrestGeradas, A_S_N); @ Adiciona sequência da prestação @
ListaRegraAddValorLinhaNumero(CcrNLista, "SeqVct", 1, A_S_N); @ 1 - indica prestação normal @
ListaRegraAddValorLinhaAlfa(CcrNLista, "PreCar", "N", A_S_N); @ "N" - indica que não é prestação de carência @
ListaRegraAddValorLinhaAlfa(CcrNLista, "PreJrs", aPreJrs, A_S_N); @ indica se é prestação de pagamento de juros apenas @
ListaRegraAddValorLinhaAlfa(CcrNLista, "VctPre", "S", A_S_N); @ "S" - Indica que é um registro de prestação a pagar @
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrAmo", nVlrAmo, A_S_N); @ Valor da amortização - Quando não for mês de amortização será zero @
@ Valor original da amortização - normalmente igual a VlrAmo, pode existir correção ou desconto na última com relação ao calculado, porém por regra, os valores podem ser sempre iguais @
ListaRegraAddValorLinhaNumero(CcrNLista, "AmoOri", nVlrAmo, A_S_N);
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrJrs", nVlrJrs, A_S_N); @ Valor dos juros na prestação @
@ Valor dos juros original - Quando houver algum tipo de cálculo a mais de juros sobre o valor em aberto do contrato, deverá ser somado ao ao juro da prestação e armazenado aqui @
ListaRegraAddValorLinhaNumero(CcrNLista, "JrsOri", nVlrJrs, A_S_N);
@ Valor a ser pago na prestação - Normalmente amortização mais juros - As vezes é preciso fazer algum ajuste no cálculo para fechar com o valor do contrato na liquidação por exemplo @
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrPre", nVlrPre, A_S_N);
ListaRegraAddValorLinhaNumero(CcrNLista, "PreOri", nVlrPre, A_S_N); @ Valor original a ser pago na prestação - Normalmente igual ao valor da prestação @
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrJmc", 0, A_S_N); @ Guarda o valor dos juros nos meses de carência - Quando houver carência, pode-se trabalhar com este campo @
ListaRegraAddValorLinhaNumero(CcrNLista, "SalDev", nSalDev, A_S_N); @ Saldo devedor do contrato, após pagamento da prestação @
ListaRegraAddValorLinhaAlfa(CcrNLista, "TipPre", "P", A_S_N); @ P - Tudo prestação - Em alguns contratos pode ser "U" quando for cálculo referente ao último dia do mês @
ListaRegraAddValorLinhaAlfa(CcrNLista, "PreRes", "N", A_S_N); @ N - Não é prestação residual @
ListaRegraSalvarLinha(CcrNLista); @Salva a linha na lista@
}
}
}
Funcao AlteraPagamentoLista(); {
Definir Numero nOutNeg;
Definir Numero nJrsAnt;
ListaRegraPodeAlterar(CcrNLista, A_S_N); @ Verifica se tem permissão para alterar @
se (A_S_N = "S") {
ListaRegraInicializarProcurar(CcrNLista, A_S_N); @ Inicializa procura na lista @
se (A_S_N = "S") {
ListaRegraAddProcurarData(CcrNLista, "DatPre", dPreAtu, A_S_N);
ListaRegraAddProcurarNumero(CcrNLista, "SeqPre", nQtdPrestGeradas, A_S_N);
ListaRegraProcurarRegistro(CcrNLista, A_S_N); @ Procura e posiciona na lista pela data e sequência da prestacao @
se (A_S_N = "S") {
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrAmo", nVlrAmo, A_S_N); @ Valor da amortização - Quando não for mês de amortização será zero @
@ Valor original da amortização - normalmente igual a VlrAmo, pode existir correção ou desconto na última com relação ao calculado, porém por regra, os valores podem ser sempre iguais @
ListaRegraAlterarLinhaNumero(CcrNLista, "AmoOri", nVlrAmo, A_S_N);
ListaRegraObterValorNumero(CcrNLista, "VlrJrs", nJrsAnt, A_S_N); @ Obter os juros antes da atualização @
ArredondarValor(nVlrJrs,2);
Se (nJrsAnt <> nVlrJrs) { @ Se antes não tinha algum valor de juros... @
ListaRegraAlterarLinhaNumero(CcrNLista, "OutAnt", nJrsAnt, A_S_N); @ ... deve guardar o valor de juros calculado anteriormento nos outros negociados anterior ... @
nJrsAnt = (nVlrJrs - nJrsAnt);
ListaRegraAlterarLinhaNumero(CcrNLista, "OutNeg", nJrsAnt, A_S_N); @ ... e deve ter a diferença com relação ao original acrescentado como outros valores negociados agora @
}
senao {
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrJrs", nVlrJrs, A_S_N); @ Valor dos juros na prestação @
@ Valor dos juros original - Quando houver algum tipo de cálculo a mais de juros sobre o valor em aberto do contrato, deverá ser somado ao ao juro da prestação e armazenado aqui @
ListaRegraAlterarLinhaNumero(CcrNLista, "JrsOri", nVlrJrs, A_S_N);
}
@ Valor a ser pago na prestação - Normalmente amortização mais juros - As vezes é preciso fazer algum ajuste no cálculo para fechar com o valor do contrato na liquidação por exemplo @
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrPre", nVlrPre, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "PreOri", nVlrPre, A_S_N); @ Valor original a ser pago na prestação - Normalmente igual ao valor da prestação @
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrJmc", 0, A_S_N); @ Guarda o valor dos juros nos meses de carência - Quando houver carência, pode-se trabalhar com este campo @
ListaRegraAlterarLinhaNumero(CcrNLista, "SalDev", nSalDev, A_S_N); @ Saldo devedor do contrato, após pagamento da prestação @
/* ListaRegraSalvarLinha(CcrNLista); @Salva a linha na lista@ */
}
Senao
mensagem(erro, "Prestação não localizada na lista de prestações.");
}
}
}
@ Inicialização de variáveis @
Funcao Inicializar(); {
nQtdPrestGeradas = 0;
@ Verificar dados do contrato @
Se (E606CCR.NumCcr > 0) {
nCodEmp = E606CCR.CodEmp; @ Empresa do contrato @
nVlrEmp = E606CCR.VlrCcr; @ Valor do contrato @
nSalDev = nVlrEmp;
DesmontaData(E606CCR.DatBcj, nDia, nMes, nAno); @ Data base para o cálculo de juros @
nDiaIni = nDia;
nMesIni = nMes;
nAnoIni = nAno;
DesmontaData(E606CCR.DatPre, nDia, nMes, nAno); @ Data da primeira amortização, pegar somente o dia base @
nDiaAtu = nDia;
nMesAtu = nMesIni;
nAnoAtu = nAnoIni;
@ Verificar dados do cálculo @
Se (E606CCR.CodCac > 0) {
nCodCac = E606CCR.CodCac;
InicializarListas();
@ Selecionar itens do cálculo do contrato @
Cur_E606ICC.Sql "SELECT SEQICC,TIPCAL,CODMOE,VLRCAL FROM E606ICC WHERE CODEMP = :NCODEMP AND CODCAC = :NCODCAC ORDER BY SEQICC";
Cur_E606ICC.AbrirCursor();
@ Alimenta lista dos cálculos do contrato @
Enquanto (Cur_E606ICC.Achou) {
lis_ItemCalculo.Adicionar();
lis_ItemCalculo.SEQCAL = Cur_E606ICC.SeqIcc; @ Sequência de cálculo do contrato @
lis_ItemCalculo.TIPCAL = Cur_E606ICC.TipCal; @ Tipo de cálculo da sequência do contrato @
lis_ItemCalculo.CODMOE = Cur_E606ICC.CodMoe; @ Código da moeda da seqüência de cálculo do contrato @
lis_ItemCalculo.VALPER = Cur_E606ICC.VlrCal; @ Valor/Percentual da sequência de cálculo do contrato @
lis_ItemCalculo.Gravar();
Cur_E606ICC.Proximo();
}
Cur_E606ICC.FecharCursor();
@ Verifica o período de amortização para o contrato @
Se (E606CCR.CodPri = "M") @ Mensal @
nMesOffset = 1;
Senao Se (E606CCR.CodPri = "B") @ Bimestral @
nMesOffset = 2;
Senao Se (E606CCR.CodPri = "T") @ Trimestral @
nMesOffset = 3;
Senao Se (E606CCR.CodPri = "U") @ Quadrimestral @
nMesOffset = 4;
Senao Se (E606CCR.CodPri = "R") @ Semestral @
nMesOffset = 6;
Senao
nMesOffset = 12; @ Anual @
@ Alimenta a lista de prestações de amortização conforme a quantidade informada no contrato @
Enquanto (nQtdPrestGeradas < E606CCR.QtdTit) {
nQtdPrestGeradas = nQtdPrestGeradas + 1;
lis_Prestacoes.Adicionar();
lis_Prestacoes.SEQPRE = nQtdPrestGeradas; @ Sequência da prestação @
Se (nQtdPrestGeradas = 1) {
lis_Prestacoes.DATPGT = E606CCR.DatPre; @ Data da primeira prestação @
dPreAtu = E606CCR.DatPre;
}
Senao {
SomarMesesDataRef(dPreAtu, nMesOffset, 0 @opção 0 não altera o dia do vencimento@ , dPreAtu);
lis_Prestacoes.DATPGT = dPreAtu; @ A data é sempre a mesma, alterando somente o mês conforme o offset@
}
DesmontaData(dPreAtu, nDia, nMes, nAno);
lis_Prestacoes.DIAPRE = nDia;
lis_Prestacoes.MESPRE = nMes;
lis_Prestacoes.ANOPRE = nAno;
lis_Prestacoes.VLRPRE = E606CCR.VlrCcr / E606CCR.QtdTit; @ Total dividido pela quantidade de parcelas @
lis_Prestacoes.Gravar();
}
}
Senao
mensagem(erro, "Cálculo do contrato não informado no contrato.");
MMCria();
nCotMoe = 0;
}
senao
mensagem(erro, "Contrato não carregado para a regra.");
}
@ Finalização dos objetos @
Funcao Finalizar(); {
MMLibera();
}
Para o exemplo de empréstimo considerando CDI + Taxa Fixa com uma parcela e N prestações de amortização semestrais, sem carência para pagamento de juros, o preenchimento dos campos foi realizado conforme exemplo abaixo:
Para melhor entendimento dos campos e variáveis do contrato que são utilizados, verificar a Implementação da regra.
Declarações
@ Lista de prestações a serem pagas @
Definir Numero CcrNLista;
@ Variável global utilizada para verificar se a execução dos métodos ocorreu com sucesso @
Definir Alfa A_S_N;
@ Valor definido na aplicação que indica se é inclusão de cálculo ou atualização @
Definir Alfa VarATipExe;
@ Variáveis globais de uso geral @
Definir Numero nCodEmp; @ Empresa do contrato @
Definir Numero nCodFil; @ Filial do contrato @
Definir Numero nNumCcr; @ Número do contrato @
Definir Numero nCodCac; @ Código do cálculo do contrato @
Definir Numero nVlrEmp; @ Valor do empréstimo @
Definir Numero nVlrJrs; @ Valor dos juros @
Definir Numero nSalDev; @ Saldo devedor a cada prestação @
Definir Numero nVlrAtu; @ Valor atualizado após cálculo de cada prestação @
Definir Numero nVlrAmo; @ Valor da amortização @
Definir Numero nVlrPre; @ Valor da prestação @
Definir Numero nAmoMoe; @ Valor da amortização na moeda do contrato @
Definir Numero nJrsMoe; @ Valor dos juros na moeda do contrato @
Definir Numero nPreMoe; @ Valor da prestação na moeda do contrato @
Definir Numero nSalMoe; @ Saldo devedor a cada prestação na moeda do contrato @
Definir Numero nDiaIni; @ Dia...@
Definir Numero nMesIni; @ Mês...@
Definir Numero nAnoIni; @ e Ano para início de cálculo de juros @
Definir Numero nDiaAtu; @ Dia... @
Definir Numero nMesAtu; @ Mês... @
Definir Numero nAnoAtu; @ e Ano de cada prestação gerada @
Definir Numero nDia; @ Dia... @
Definir Numero nMes; @ Mês... @
Definir Numero nAno; @ e Ano para uso global @
Definir Data dPreAtu; @ Data da prestação atual @
Definir Alfa aCodMoe; @ Código da moeda @
Definir Numero nCotMoe; @ Cotação do índice informado no cálculo do contrato @
Definir Numero nQtdPrestGeradas; @ Quantidade de prestações do contrato @
Definir Numero nTemCalculo; @ Variável para controlar looping de cálculos para cada prestação @
Definir Numero nTemPrestacao; @ Variável para controlar looping das prestações a serem geradas @
Definir Alfa aPreJrs; @ Indica se a prestação é somente para pagamento de juros @
Definir Data dDatAnt; @ Guarda o vencimento do período anterior @
Definir Numero dOutraMoeda; @ Indicativo se a moeda do contrato é diferente da moeda da empresa @
Definir Numero nCotEmi; @ Variável com cotação da moeda na emissão @
Definir Numero nVlrCor; @ Valor da correção monetária para variação a maior @
Definir Numero nVlrOde; @ Valor da correção monetária para variação a menor @
@ Cursores e listas@
Definir Lista lis_ItemCalculo; @ Lista dos itens de cálculo do contrato @
Definir Lista lis_Prestacoes; @ Lista que guarda as prestações do contrato @
Definir Lista lis_Parcelas; @ Lista que gurda as parcelas do contrato @
@ Funções @
Definir Funcao Inicializar();
Definir Funcao InicializarListas();
Definir Funcao GerarPrestacoes();
Definir Funcao InserePagamentoLista();
Definir Funcao AlteraPagamentoLista();
Definir Funcao Finalizar();
@ Método principal @
Inicializar();
GerarPrestacoes();
Finalizar();
@ Inicializar lista de sequências de cálculo do contrato e lista de prestações @
Funcao InicializarListas(); {
lis_ItemCalculo.DefinirCampos();
lis_ItemCalculo.AdicionarCampo("SEQCAL", Numero); @ Sequência do cálculo @
lis_ItemCalculo.AdicionarCampo("TIPCAL", Alfa); @ Tipo do cálculo (V-Valor, D-Índice, P-Percentual (taxa fixa), H-Hora) @
lis_ItemCalculo.AdicionarCampo("CODMOE", Alfa); @ Moeda/Índice do cálculo caso seja do tipo "D" @
lis_ItemCalculo.AdicionarCampo("VALPER", Numero); @ Valor/Percentual conforme tipo @
lis_ItemCalculo.EfetivarCampos();
lis_Prestacoes.DefinirCampos();
lis_Prestacoes.AdicionarCampo("SEQPRE", Numero); @ Sequência da prestação @
lis_Prestacoes.AdicionarCampo("DATPGT", Data); @ Data de pagamento da prestação @
lis_Prestacoes.AdicionarCampo("DIAPRE", Numero); @ Dia... @
lis_Prestacoes.AdicionarCampo("MESPRE", Numero); @ Mês... @
lis_Prestacoes.AdicionarCampo("ANOPRE", Numero); @ E ano da prestação @
lis_Prestacoes.AdicionarCampo("VLRPRE", Numero); @ Valor da prestação @
lis_Prestacoes.EfetivarCampos();
lis_Parcelas.DefinirCampos();
lis_Parcelas.AdicionarCampo("SEQPAR", Numero); @ Sequência da parcela @
lis_Parcelas.AdicionarCampo("DATPAR", Data); @ Data de entrada da parcela @
lis_Parcelas.AdicionarCampo("DIAPAR", Data); @ Dia... @
lis_Parcelas.AdicionarCampo("MESPAR", Data); @ Mês... @
lis_Parcelas.AdicionarCampo("ANOPAR", Data); @ E ano da parcela @
lis_Parcelas.AdicionarCampo("VLRPAR", Numero); @ Valor da parcela @
lis_Parcelas.EfetivarCampos();
}
Funcao GerarPrestacoes(); {
Definir Numero nJrsPre;
Definir Numero nQtdDia;
Definir Data dUltDia;
Definir Data dDatPar;
Definir Numero nVlrPar;
Definir Numero nTemParcela;
Definir Numero nDiaAno;
@ Valores locais para calculo @
Definir Numero nAmoLoc;
Definir Numero nJrsLoc;
Definir Numero nPreLoc;
Definir Numero nSalLoc;
Definir Numero nCotLoc; @ Variável local para trabalhar com cotação da moeda @
Se (E606CAC.DiaAno = "S") {
nDiaAno = 365;
}
Senao {
nDiaAno = 360;
}
nQtdPrestGeradas = 0;
@ Iniciar looping a partir da data de início do contrato. Looping enquanto ainda existir saldo devedor e/ou não atingir a data final do contrato pelo período de quebra (dia, quinzena, mês, bimestre, etc.) @
nTemPrestacao = lis_Prestacoes.Primeiro();
@ Inicializa saldo com primeira parcela @
nTemParcela = lis_Parcelas.Primeiro();
nSalLoc = lis_Parcelas.VLRPAR;
@ Se houver próxima parcela, inicializa valores da próxima parcela @
nTemParcela = lis_Parcelas.Proximo();
Se (nTemParcela = 1) {
dDatPar = lis_Parcelas.DATPAR;
nVlrPar = lis_Parcelas.VLRPAR;
}
Senao {
dDatPar = 0;
nVlrPar = 0;
}
dUltDia = 0;
@ Inicialização do juros ainda não pagos por parcela e do valor atualizado do saldo com juros @
nVlrAtu = nSalLoc;
nJrsLoc = 0;
dDatAnt = E606CCR.DatBcj; @ Inicializa a data base de cálculo de juros para posterior cálculo de dias corridos de cada prestação ou pagamento de juros @
Enquanto ((nSalLoc > 0) e (nTemPrestacao = 1)) {
@ Posicionar no primeiro item de cálculo do contrato @
nTemCalculo = lis_ItemCalculo.Primeiro();
@ Verificar qual data é menor entre, próximo vencimento, último dia mês ou data de entrada da próxima parcela @
Se (dUltDia = dDatAnt) {
dUltDia = dUltDia + 1;
}
Senao {
dUltDia = dDatAnt;
}
UltimoDia(dUltDia);
dPreAtu = lis_Prestacoes.DATPGT;
Se (dUltDia < dPreAtu) {
dPreAtu = dUltDia;
}
Se ((dDatPar > 0) e (dDatPar < dPreAtu)) {
dPreAtu = dDatPar;
}
@ Atualiza variáveis com a próxima data que será gerada prestação @
DesMontaData(dPreAtu, nDiaAtu, nMesAtu, nAnoAtu);
@ Verificar quantidade de dias entre essa maior data e a última data usada como base (dDatAnt) @
nQtdDia = dPreAtu - dDatAnt;
@ Atualizar a dDatAnt com esta data menor utilizada @
dDatAnt = dPreAtu;
@ Buscar o índice de moeda pela data a ser calculada e somar a outros itens do cálculo @
nCotMoe = 0;
Enquanto (nTemCalculo = 1) { @ Enquanto tiver item de cálculo @
se (lis_ItemCalculo.TIPCAL = "D") { @ Somar índice da data @
aCodMoe = lis_ItemCalculo.CODMOE;
MMBuscaCotacaoMoeda(aCodMoe, dPreAtu, 0, nCotLoc);
nCotMoe = nCotMoe + nCotLoc;
}
senao se (lis_ItemCalculo.TIPCAL = "P") { @ Somar taxa fixa @
nCotMoe = nCotMoe + lis_ItemCalculo.VALPER;
}
nTemCalculo = lis_ItemCalculo.Proximo();
}
@ Calcular juros do período de dias encontrado (com taxa fixa mais índice) @
nJrsPre = ((nSalLoc * (nCotMoe/100))/nDiaAno) * nQtdDia; @ Formula utilizada pelo cliente para cálculo de contrato debêntures @
@ Atualizar valores de juros @
nJrsLoc = nJrsLoc + nJrsPre; @ Soma ao juros a serem pagos @
nVlrAtu = nVlrAtu + nJrsPre; @ soma ao saldo atualizado com juros @
@ Verificar se data é de parcela e deve atualizar valor com nova parcela @
Se ((dDatPar > 0) e ((lis_Parcelas.DIAPAR = nDiaAtu) e (lis_Parcelas.MESPAR = nMesAtu) e (lis_Parcelas.ANOPAR = nAnoAtu))) {
nSalLoc = nSalLoc + lis_Parcelas.VLRPAR;
nVlrAtu = nVlrAtu + lis_Parcelas.VLRPAR;
nTemParcela = lis_Parcelas.Proximo();
Se (nTemParcela = 1) {
dDatPar = lis_Parcelas.DATPAR;
nVlrPar = lis_Parcelas.VLRPAR;
}
Senao {
dDatPar = 0;
nVlrPar = 0;
}
}
@ Verificar se deve ser gerada prestação de juros ou de amortização e gerar, senão só acumular os valores para a próxima prestação @
Se (((lis_Prestacoes.DIAPRE = nDiaAtu) e (lis_Prestacoes.MESPRE = nMesAtu) e (lis_Prestacoes.ANOPRE = nAnoAtu))) {
Se (lis_Prestacoes.VLRPRE > 0) { @ Amortização de saldo devedor junto com juros @
nAmoLoc = lis_Prestacoes.VLRPRE;
nTemPrestacao = lis_Prestacoes.Proximo();
ArredondarValor(nAmoLoc,2);
Se (nTemPrestacao = 0) {
nAmoLoc = nSalLoc;
nPreLoc = nVlrAtu - nSalLoc + nAmoLoc;
nSalLoc = 0;
}
Senao {
nPreLoc = nVlrAtu - nSalLoc + nAmoLoc;
nSalLoc = nSalLoc - nAmoLoc;
}
aPreJrs = "N";
}
Senao { @ Amortização somente de juros @
nAmoLoc = 0;
nPreLoc = nVlrAtu - nSalLoc;
nTemPrestacao = lis_Prestacoes.Proximo();
aPreJrs = "S";
}
@ Gravar dados da prestação na lista @
nQtdPrestGeradas = nQtdPrestGeradas + 1;
@ Se o contrato está em outra moeda, todos os valores devem ser atualizados para a moeda do contrato e a moeda da empresa @
Se (dOutraMoeda = 1) {
nAmoMoe = nAmoLoc;
nJrsMoe = nJrsLoc;
nPreMoe = nPreLoc;
nSalMoe = nSalLoc;
MMBuscaCotacaoMoeda(E606CCR.CodMoe, dPreAtu, 0, nCotLoc);
nVlrAmo = nAmoMoe * nCotLoc;
nVlrJrs = nJrsMoe * nCotLoc;
nVlrPre = nPreMoe * nCotLoc;
nSalDev = nSalMoe * nCotLoc;
}
Senao {
nVlrAmo = nAmoLoc;
nVlrJrs = nJrsLoc;
nVlrPre = nPreLoc;
nSalDev = nSalLoc;
}
Se (VarATipExe = "INCLUSAO")
InserePagamentoLista();
Senao
AlteraPagamentoLista();
@ Atualizar o saldo devedor @
nVlrAtu = nSalLoc;
nJrsLoc = 0;
}
}
}
Funcao InserePagamentoLista(); {
ListaRegraPodeIncluir(CcrNLista, A_S_N); @ Verifica se tem permissão para incluir @
se (A_S_N = "S") {
ListaRegraNovaLinha(CcrNLista); @ Prepara lista para inclusão de uma nova linha. Deve ser chamado sempre que for usar os métodos incluir as colunas. @
ListaRegraEmInclusao(CcrNLista, A_S_N); @ Verifica situação da lista. @
se (A_S_N = "S") {
ListaRegraAddValorLinhaData(CcrNLista, "DatPre", dPreAtu, A_S_N); @ Adiciona data da prestação @
ListaRegraAddValorLinhaNumero(CcrNLista, "SeqPre", nQtdPrestGeradas, A_S_N); @ Adiciona sequência da prestação @
ListaRegraAddValorLinhaNumero(CcrNLista, "SeqVct", 1, A_S_N); @ 1 - indica prestação normal @
ListaRegraAddValorLinhaAlfa(CcrNLista, "PreCar", "N", A_S_N); @ "N" - indica que não é prestação de carência @
ListaRegraAddValorLinhaAlfa(CcrNLista, "PreJrs", aPreJrs, A_S_N); @ indica se é prestação de pagamento de juros apenas @
ListaRegraAddValorLinhaAlfa(CcrNLista, "VctPre", "S", A_S_N); @ "S" - Indica que é um registro de prestação a pagar @
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrAmo", nVlrAmo, A_S_N); @ Valor da amortização - Quando não for mês de amortização será zero @
@ Valor original da amortização - normalmente igual a VlrAmo, pode existir correção ou desconto na última com relação ao calculado, porém por regra, os valores podem ser sempre iguais @
ListaRegraAddValorLinhaNumero(CcrNLista, "AmoOri", nVlrAmo, A_S_N);
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrJrs", nVlrJrs, A_S_N); @ Valor dos juros na prestação @
@ Valor dos juros original - Quando houver algum tipo de cálculo a mais de juros sobre o valor em aberto do contrato, deverá ser somado ao ao juro da prestação e armazenado aqui @
ListaRegraAddValorLinhaNumero(CcrNLista, "JrsOri", nVlrJrs, A_S_N);
@ Valor a ser pago na prestação - Normalmente amortização mais juros - As vezes é preciso fazer algum ajuste no cálculo para fechar com o valor do contrato na liquidação por exemplo @
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrPre", nVlrPre, A_S_N);
ListaRegraAddValorLinhaNumero(CcrNLista, "PreOri", nVlrPre, A_S_N); @ Valor original a ser pago na prestação - Normalmente igual ao valor da prestação @
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrJmc", 0, A_S_N); @ Guarda o valor dos juros nos meses de carência - Quando houver carência, pode-se trabalhar com este campo @
ListaRegraAddValorLinhaNumero(CcrNLista, "SalDev", nSalDev, A_S_N); @ Saldo devedor do contrato, após pagamento da prestação @
ListaRegraAddValorLinhaAlfa(CcrNLista, "TipPre", "P", A_S_N); @ P - Tudo prestação - Em alguns contratos pode ser "U" quando for cálculo referente ao último dia do mês @
ListaRegraAddValorLinhaAlfa(CcrNLista, "PreRes", "N", A_S_N); @ N - Não é prestação residual @
@ Informações na moeda do contrato @
Se (dOutraMoeda = 1) {
ListaRegraAddValorLinhaNumero(CcrNLista, "AmoMoe", nAmoMoe, A_S_N);
ListaRegraAddValorLinhaNumero(CcrNLista, "JrsMoe", nJrsMoe, A_S_N);
ListaRegraAddValorLinhaNumero(CcrNLista, "PreMoe", nPreMoe, A_S_N);
ListaRegraAddValorLinhaNumero(CcrNLista, "SalMoe", nSalMoe, A_S_N);
@ Correção monetária - Se houver variação para mais vem na nVlrCor, variação para menos na nVlrOde @
MMCalcularCorrecaoMonetaria(E606CCR.CodMoe, E606CCR.DatBcj, nCotEmi, dPreAtu, nVlrPre, nVlrCor, nVlrOde);
Se (nVlrCor > 0) {
ListaRegraAddValorLinhaNumero(CcrNLista, "CorMoe", nVlrCor, A_S_N);
}
Senao {
Se (nVlrOde > 0) {
ListaRegraAddValorLinhaNumero(CcrNLista, "CorMoe", (nVlrOde * -1), A_S_N);
}
}
}
ListaRegraSalvarLinha(CcrNLista); @Salva a linha na lista@
}
}
}
Funcao AlteraPagamentoLista(); {
Definir Numero nJrsAnt;
Definir Numero nCorAnt;
ListaRegraPodeAlterar(CcrNLista, A_S_N); @ Verifica se tem permissão para alterar @
se (A_S_N = "S") {
ListaRegraInicializarProcurar(CcrNLista, A_S_N); @ Inicializa procura na lista @
se (A_S_N = "S") {
ListaRegraAddProcurarData(CcrNLista, "DatPre", dPreAtu, A_S_N);
ListaRegraAddProcurarNumero(CcrNLista, "SeqPre", nQtdPrestGeradas, A_S_N);
ListaRegraProcurarRegistro(CcrNLista, A_S_N); @ Procura e posiciona na lista pela data e sequência da prestacao @
se (A_S_N = "S") {
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrAmo", nVlrAmo, A_S_N); @ Valor da amortização - Quando não for mês de amortização será zero @
@ Valor original da amortização - normalmente igual a VlrAmo, pode existir correção ou desconto na última com relação ao calculado, porém por regra, os valores podem ser sempre iguais @
ListaRegraAlterarLinhaNumero(CcrNLista, "AmoOri", nVlrAmo, A_S_N);
ListaRegraObterValorNumero(CcrNLista, "VlrJrs", nJrsAnt, A_S_N); @ Obter os juros antes da atualização @
ArredondarValor(nVlrJrs,2);
Se (nJrsAnt <> nVlrJrs) { @ Se antes não tinha algum valor de juros... @
ListaRegraAlterarLinhaNumero(CcrNLista, "OutNegAnt", nJrsAnt, A_S_N); @ ... deve guardar o valor de juros calculado anteriormento nos outros negociados anterior ... @
nJrsAnt = (nVlrJrs - nJrsAnt);
ListaRegraAlterarLinhaNumero(CcrNLista, "OutNeg", nJrsAnt, A_S_N); @ ... e deve ter a diferença com relação ao original acrescentado como outros valores negociados agora @
}
senao {
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrJrs", nVlrJrs, A_S_N); @ Valor dos juros na prestação @
@ Valor dos juros original - Quando houver algum tipo de cálculo a mais de juros sobre o valor em aberto do contrato, deverá ser somado ao ao juro da prestação e armazenado aqui @
ListaRegraAlterarLinhaNumero(CcrNLista, "JrsOri", nVlrJrs, A_S_N);
}
@ Valor a ser pago na prestação - Normalmente amortização mais juros - As vezes é preciso fazer algum ajuste no cálculo para fechar com o valor do contrato na liquidação por exemplo @
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrPre", nVlrPre, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "PreOri", nVlrPre, A_S_N); @ Valor original a ser pago na prestação - Normalmente igual ao valor da prestação @
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrJmc", 0, A_S_N); @ Guarda o valor dos juros nos meses de carência - Quando houver carência, pode-se trabalhar com este campo @
ListaRegraAlterarLinhaNumero(CcrNLista, "SalDev", nSalDev, A_S_N); @ Saldo devedor do contrato, após pagamento da prestação @
@ Dados em outra moeda e correção monetária do empréstimo @
Se (dOutraMoeda = 1) {
ListaRegraAlterarLinhaNumero(CcrNLista, "AmoMoe", nAmoMoe, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "JrsMoe", nJrsMoe, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "PreMoe", nPreMoe, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "SalMoe", nSalMoe, A_S_N);
ListaRegraObterValorNumero(CcrNLista, "CorMoe", nCorAnt, A_S_N); @ Obter a correção antes da atualização @
@ Correção monetária - Se houver variação para mais vem na nVlrCor, variação para menos na nVlrOde @
MMCalcularCorrecaoMonetaria(E606CCR.CodMoe, E606CCR.DatBcj, nCotEmi, dPreAtu, nVlrPre, nVlrCor, nVlrOde);
Se (nVlrCor > 0) {
ListaRegraAlterarLinhaNumero(CcrNLista, "CorMoe", nVlrCor, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "CorMoeAnt", nCorAnt, A_S_N);
}
Senao {
Se (nVlrOde > 0) {
ListaRegraAlterarLinhaNumero(CcrNLista, "CorMoe", (nVlrOde * -1), A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "CorMoeAnt", nCorAnt, A_S_N);
}
}
}
* ListaRegraSalvarLinha(CcrNLista); @Salva a linha na lista@ */
}
Senao
mensagem(erro, "Prestação não localizada na lista de prestações.");
}
}
}
@ Inicialização de variáveis @
Funcao Inicializar(); {
nQtdPrestGeradas = 0;
@ Verificar dados do contrato @
Se (E606CCR.NumCcr > 0) {
MMCria();
nCodEmp = E606CCR.CodEmp; @ Empresa do contrato @
nCodFil = E606CCR.CodFil; @ Filial do contrato @
nNumCcr = E606CCR.NumCcr; @ Numero do contrato @
nVlrEmp = E606CCR.VlrCcr; @ Valor do contrato @
@ Cursor para buscar a moeda da empresa @
Definir Cursor Cur_E006PAI;
Cur_E006PAI.Sql "SELECT E006PAI.CODMOE FROM E006PAI, E070EMP WHERE E006PAI.CODPAI = E070EMP.CODPAI AND E070EMP.CODEMP = :NCODEMP";
Cur_E006PAI.AbrirCursor();
dOutraMoeda = 0;
Se ((Cur_E006PAI.CodMoe <> "") e (Cur_E006PAI.CodMoe <> E606CCR.CodMoe)) {
dOutraMoeda = 1;
MMBuscaCotacaoMoeda(E606CCR.CodMoe, E606CCR.DatBcj, 0, nCotEmi);
}
DesmontaData(E606CCR.DatBcj, nDia, nMes, nAno); @ Data base para o cálculo de juros @
nDiaIni = nDia;
nMesIni = nMes;
nAnoIni = nAno;
DesmontaData(E606CCR.DatPre, nDia, nMes, nAno); @ Data da primeira amortização, pegar somente o dia base @
nDiaAtu = nDia;
nMesAtu = nMesIni;
nAnoAtu = nAnoIni;
@ Verificar dados do cálculo @
Se (E606CCR.CodCac > 0) {
nCodCac = E606CCR.CodCac;
InicializarListas();
@ Selecionar itens do cálculo do contrato @
Definir Cursor Cur_E606ICC; @ Cursor para selecionar os itens de cálculo do contrato @
Cur_E606ICC.Sql "SELECT SEQICC,TIPCAL,CODMOE,VLRCAL FROM E606ICC WHERE CODEMP = :NCODEMP AND CODCAC = :NCODCAC ORDER BY SEQICC";
Cur_E606ICC.AbrirCursor();
@ Alimenta lista dos cálculos do contrato @
Enquanto (Cur_E606ICC.Achou) {
lis_ItemCalculo.Adicionar();
lis_ItemCalculo.SEQCAL = Cur_E606ICC.SeqIcc; @ Sequência de cálculo do contrato @lis_ItemCalculo.TIPCAL = Cur_E606ICC.TipCal; @ Tipo de cálculo da sequência do contrato @
lis_ItemCalculo.CODMOE = Cur_E606ICC.CodMoe; @ Código da moeda da seqüência de cálculo do contrato @
lis_ItemCalculo.VALPER = Cur_E606ICC.VlrCal; @ Valor/Percentual da sequência de cálculo do contrato @
lis_ItemCalculo.Gravar();
Cur_E606ICC.Proximo();
}
Cur_E606ICC.FecharCursor();
@ Alimenta lista das parcelas do contrato @
Definir Cursor Cur_E606PAR; @ Cursor para carga das parcelas @
Cur_E606PAR.Sql "SELECT SEQPAR,DATPAR,VLRPAR FROM E606PAR WHERE CODEMP = :NCODEMP AND CODFIL = :NCODFIL AND NUMCCR = :NNUMCCR ORDER BY SEQPAR";
Cur_E606PAR.AbrirCursor();
Enquanto (Cur_E606PAR.Achou) {
lis_Parcelas.Adicionar();
lis_Parcelas.SEQPAR = Cur_E606PAR.SeqPar; @ Sequência da parcela @
lis_Parcelas.DATPAR = Cur_E606PAR.DatPar; @ Data em qu a parcela será recebida @
dPreAtu = Cur_E606PAR.DatPar;
DesmontaData(dPreAtu, nDia, nMes, nAno);
lis_Parcelas.DIAPAR = nDia;
lis_Parcelas.MESPAR = nMes;
lis_Parcelas.ANOPAR = nAno;
lis_Parcelas.VLRPAR = Cur_E606PAR.VlrPar; @ Valor da parcela @
lis_Parcelas.Gravar();
Cur_E606PAR.Proximo();
}
Cur_E606PAR.FecharCursor();
@ Verifica o período de amortização para o contrato @
Se (E606CCR.CodPri = "M") @ Mensal @
nMesOffset = 1
Senao Se (E606CCR.CodPri = "B") @ Bimestral @
nMesOffset = 2;
Senao Se (E606CCR.CodPri = "T") @ Trimestral @
nMesOffset = 3;
Senao Se (E606CCR.CodPri = "U") @ Quadrimestral @
nMesOffset = 4;
Senao Se (E606CCR.CodPri = "R") @ Semestral @
nMesOffset = 6;
Senao
nMesOffset = 12; @ Anual @
Definir Numero nDiaBas; @ Dia base da primeira amortização. Guardará o dia base de vencimento das prestações, para ser usado em todos os meses que houver prestação @
Definir Numero nMesBas; @ Mês base da primeira amortização @
Definir Numero nAnoBas; @ Ano base da primeira amortização @
dPreAtu = E606CCR.DatPre; @ Atribui data da primeira prestação... @
DesmontaData(dPreAtu, nDiaBas, nMesBas, nAnoBas); @ ... para pegar o dia base para nDiaBas @
dPreAtu = E606CCR.DatBcj; @ Inicializa o preenchimento das prestações a patir da data base de cálculo de juros @
@ Caso existir meses de carência, e alguns com somente juros, começa montando a lista aqui @
Definir Numero nPos; @ Posição da primeira vírgula na lista de meses @
Definir Alfa aMes; @ mes corrente em alfanumérico @
Definir Numero nQtdMeses; @ Qtde meses a serem incrementados para pagamento de juros @
Definir Alfa aMesesPgto; @ Lista alfanumérica de incrementos de carência mensal, separada por vírgula @
@ Deve ser informado aqui uma lista de quantidade de meses sequencialmente separados por vírgula, ... @
@ ... para serem adicionados a partir da data base cálculo juros para encontrar a próxima prestação de juros com carência de amortização @
@ Aqui no exemplo, está sendo usado um campo de usuário craido na tabela E606CCR que é alimentado no cadastro do contrato através do botão "PERSONALIZAÇÃO" @
aMesesPgto = E606CCR.MesCaa; @ E606CCR.USU_MESPAGJUR; @
LimpaEspacos(aMesesPgto);
Enquanto (aMesesPgto <> "") { @ Se tiver lista de quantidade de meses para pagamento somente de juros antes de começar a amortizar @
nQtdPrestGeradas = nQtdPrestGeradas + 1;
lis_Prestacoes.Adicionar();
lis_Prestacoes.SEQPRE = nQtdPrestGeradas; @ Sequência da prestação @
PosicaoStr(",", aMesesPgto, nPos);
aMes = aMesesPgto;
Se (nPos > 0){
CopiarStr(aMes, 1, (nPos - 1));
DeletarStr(aMesesPgto, 1, nPos);
}
Senao {
aMesesPgto = "";
}
StrParaInt(aMes, nQtdMeses);
SomarMesesDataRef(dPreAtu, nQtdMeses, 0 @opção 0 não altera o dia do vencimento@ , dPreAtu);
DesmontaData(dPreAtu, nDia, nMes, nAno); @ Mês para cálculo de juros @
MontaData(nDiaBas, nMes, nAno, dPreAtu); @ Data com o dia correto para pagamento @
lis_Prestacoes.DATPGT = dPreAtu; @ Data da prestação de juros @
DesmontaData(dPreAtu, nDia, nMes, nAno);
lis_Prestacoes.DIAPRE = nDia;
lis_Prestacoes.MESPRE = nMes;
lis_Prestacoes.ANOPRE = nAno;
lis_Prestacoes.VLRPRE = 0; @ Prestação de juros @
lis_Prestacoes.Gravar();
Se (dPreAtu >= E606CCR.DatPre) {
aMesesPgto = "";
}
}
Definir Numero nModificador;
nModificador = nQtdPrestGeradas;
nQtdPrestGeradas = 0;
@ Alimenta a lista de prestações de amortização conforme a quantidade informada no contrato @
Enquanto (nQtdPrestGeradas < E606CCR.QtdTit) {
nQtdPrestGeradas = nQtdPrestGeradas + 1;
lis_Prestacoes.Adicionar();
lis_Prestacoes.SEQPRE = nQtdPrestGeradas + nModificador; @ Sequência da prestação @
Se (nQtdPrestGeradas = 1) {
dPreAtu = E606CCR.DatPre;
/*DesmontaData(dPreAtu, nDiaBas, nMes, nAno); @ Atribui o dia base para nDiaBas @*/
}
Senao {
DesmontaData(dPreAtu, nDia, nMes, nAno); @ Pega o último vencimento de prestação... @
MontaData(nDiaBas, nMes, nAno, dPreAtu); @ ... e atribui o dia base para ele @
SomarMesesDataRef(dPreAtu, nMesOffset, 0 @opção 0 não altera o dia do vencimento@ , dPreAtu);
}
lis_Prestacoes.DATPGT = dPreAtu; @ A data é sempre a mesma, para dia útil, alterando somente o mês conforme o offset @
DesmontaData(dPreAtu, nDia, nMes, nAno);
lis_Prestacoes.DIAPRE = nDia;
lis_Prestacoes.MESPRE = nMes;
lis_Prestacoes.ANOPRE = nAno;
lis_Prestacoes.VLRPRE = E606CCR.VlrCcr / E606CCR.QtdTit; @ Total dividido pela quantidade de parcelas @
lis_Prestacoes.Gravar();
}
}
Senao
mensagem(erro, "Cálculo do contrato não informado no contrato.");
nCotMoe = 0;
}
senao
mensagem(erro, "Contrato não carregado para a regra.");
}
@ Finalização dos objetos @
Funcao Finalizar(); {
MMLibera();
}
Para o exemplo de empréstimo considerando debêntures com N parcelas de empréstimo (entrada de valor em mais de uma vez), o preenchimento dos campos foi realizado conforme exemplo abaixo:
Para o exemplo de multimoedas com apenas 1 parcela, a regra continua sendo a mesma, mas o preenchimento muda ligeiramente, conforme imagens abaixo:
Para melhor entendimento dos campos e variáveis do contrato que são utilizados, verificar a Implementação da regra.
Declarações
@ Lista de prestações a serem pagas @
Definir Numero CcrNLista;
@ Variável global utilizada para verificar se a execução dos métodos ocorreu com sucesso @
Definir Alfa A_S_N;
@ Valor definido na aplicação que indica se é inclusão de cálculo ou atualização @
Definir Alfa VarATipExe;
@ Variáveis globais de uso geral @
Definir Numero nCodEmp; @ Empresa do contrato @
Definir Numero nCodCac; @ Código do cálculo do contrato @
Definir Numero nVlrJrs; @ Valor dos juros @
Definir Numero nSalDev; @ Saldo devedor a cada prestação @
Definir Numero nVlrAtu; @ Valor atualizado após cálculo de cada prestação @
Definir Numero nVlrAmo; @ Valor da amortização @
Definir Numero nDiaIni; @ Dia...@
Definir Numero nMesIni; @ Mês...@
Definir Numero nAnoIni; @ e Ano para início de cálculo de juros @
Definir Numero nDiaAtu; @ Dia... @
Definir Numero nMesAtu; @ Mês... @
Definir Numero nAnoAtu; @ e Ano de cada prestação gerada @
Definir Numero nDia; @ Dia... @
Definir Numero nMes; @ Mês... @
Definir Numero nAno; @ e Ano para uso global @
Definir Data dPreAtu; @ Data da prestação atual @
Definir Alfa aCodMoe; @ Código da moeda @
Definir Numero nQtdPrestGeradas; @ Quantidade de prestações do contrato @
Definir Numero nTemCalculo; @ Variável para controlar looping de cálculos para cada prestação @
Definir Numero nTemPrestacao; @ Variável para controlar looping das prestações a serem geradas @
Definir Alfa aPreJrs; @ Indica se a prestação é somente para pagamento de juros @
Definir Data dDatAnt; @ Guarda o vencimento do período anterior @
Definir Numero nQtdDiaAno; @ Quantidade de dias no ano para uso nas fórmulas de cálculo de juros @
Definir Numero nVlrPre; @ Valor da prestação a ser gerada @
@ Cursores e listas@
Definir Lista lis_ItemCalculo; @ Lista dos itens de cálculo do contrato @
Definir Lista lis_Prestacoes; @ Lista que guarda as prestações do contrato @
@ Funções @
Definir Funcao Inicializar();
Definir Funcao InicializarListas();
Definir Funcao GerarPrestacoes();
Definir Funcao InserePagamentoLista();
Definir Funcao AlteraPagamentoLista();
Definir Funcao Finalizar();
Implementações
@ Método principal @
Inicializar();
GerarPrestacoes();
Finalizar();
@ Inicializar lista de sequências de cálculo do contrato e lista de prestações @
Funcao InicializarListas(); {
lis_ItemCalculo.DefinirCampos();
lis_ItemCalculo.AdicionarCampo("SEQCAL", Numero); @ Sequência do cálculo @
lis_ItemCalculo.AdicionarCampo("TIPCAL", Alfa); @ Tipo do cálculo (V-Valor, D-Índice, P-Percentual (taxa fixa), H-Hora) @
lis_ItemCalculo.AdicionarCampo("CODMOE", Alfa); @ Moeda/Índice do cálculo caso seja do tipo "D" @
lis_ItemCalculo.AdicionarCampo("VALPER", Numero); @ Valor/Percentual conforme tipo @
lis_ItemCalculo.EfetivarCampos();
lis_Prestacoes.DefinirCampos();
lis_Prestacoes.AdicionarCampo("SEQPRE", Numero); @ Sequência da prestação @
lis_Prestacoes.AdicionarCampo("DATPGT", Data); @ Data de pagamento da prestação @
lis_Prestacoes.AdicionarCampo("DIAPRE", Numero); @ Dia... @
lis_Prestacoes.AdicionarCampo("MESPRE", Numero); @ Mês... @
lis_Prestacoes.AdicionarCampo("ANOPRE", Numero); @ E ano da prestação @
lis_Prestacoes.AdicionarCampo("VLRPRE", Numero); @ Valor da prestação @
lis_Prestacoes.EfetivarCampos();
}
Funcao GerarPrestacoes(); {
Definir Numero nCotLoc; @ Variável local para guardar a cotação do índice @
Definir Numero nJrsLoc; @ Variável local para guardar os juros calculados em cada passagem da repetição do cálculo @
Definir Numero nQtdDia; @ Variável local para guardar a quantidade de dias úteis para o cálculo de juros @
/* @ Exemplo de uso de campos de usuário para arredondamentos @
Definir Numero nCodFil;
Definir Numero nNumCcr;
nCodFil = E606CCR.CodFil; @ Filial do contrato @
nNumCcr = E606CCR.NumCcr; @ Número do contrato @
Definir Cursor Cur_E606CCR; @ Cursor para selecionar os campos de usuário do contrato de empréstimo @
Cur_E606CCR.Sql "SELECT USU_ARRTAXFIX FROM E606CCR WHERE CODEMP = :NCODEMP AND CODFIL = :NCODFIL AND NUMCCR = :NNUMCCR";
Cur_E606CCR.AbrirCursor();
@ Verifica existência dos campos de usuário @
Se (Cur_E606CCR.NaoAchou) {
mensagem(erro, "Campo de usuário USU_ARRTAXFIX não encontrado na tabela E606CCR.");
} */
nQtdPrestGeradas = 0;
@ Iniciar looping a partir da data de início do contrato. Looping enquanto ainda existir saldo devedor e/ou não atingir a data final do contrato pelo período de quebra (dia, quinzena, mês, bimestre, etc.) @
nTemPrestacao = lis_Prestacoes.Primeiro();
@ Inicializa saldo do contrato @
nSalDev = E606CCR.VlrCcr; @ Valor do contrato @
@ Inicialização do juros ainda não pagos por parcela e do valor atualizado do saldo com juros @
nVlrAtu = nSalDev;
nVlrJrs = 0;
dDatAnt = E606CCR.DatBcj; @ Inicializa a data base de cálculo de juros para posterior cálculo de dias corridos de cada prestação ou pagamento de juros @
Enquanto ((nSalDev > 0) e (nTemPrestacao = 1)) {
dPreAtu = lis_Prestacoes.DATPGT;
@ Atualiza variáveis com a próxima data que será gerada prestação @
DesMontaData(dPreAtu, nDiaAtu, nMesAtu, nAnoAtu);
@ Verificar quantidade de dias úteis entre data da prestação e a última data usada como base (dDatAnt) @
RetornarDiasUteisPeriodo(dDatAnt, dPreAtu, nQtdDia);
@ Atualizar a dDatAnt com a última data de prestação utilizada + 1 dia, para que não tenha sempre um dia a mais na verificação de cada mês @
dDatAnt = dPreAtu + 1;
@ Posicionar no primeiro item de cálculo do contrato @
nTemCalculo = lis_ItemCalculo.Primeiro();
@ Buscar o índice de moeda pela data a ser calculada e somar a outros itens do cálculo @
@ =(ARRED(ARRED(((1+Taxa)^(nQtdDia/nQtdDiaAno)-1);6)*(nSalDev);5))+(nSalDev*((Selic/100+1)^(nQtdDia/nQtdDiaAno)-1)) @
nJrsLoc = 0;
Enquanto (nTemCalculo = 1) { @ Enquanto tiver item de cálculo @
se (lis_ItemCalculo.TIPCAL = "P") { @ Somar taxa fixa @
Potencia((1+lis_ItemCalculo.VALPER), (nQtdDia/nQtdDiaAno), nJrsLoc);
nJrsLoc = nJrsLoc - 1;
/* Arredonda(nJrsLoc, Cur_E606CCR.USU_ARRTAXFIX); */ @ Caso se queira utilizar campos de usuário ao invés de valor fixo, selecionados no cursor logo acima @
Arredonda(nJrsLoc, 6);
nJrsLoc = nJrsLoc * nSalDev;
Arredonda(nJrsLoc, 5);
nVlrJrs = nVlrJrs + nJrsLoc; @ Soma ao juros a serem pagos @
nVlrAtu = nVlrAtu + nJrsLoc; @ soma ao saldo atualizado com juros @
}
senao se (lis_ItemCalculo.TIPCAL = "D") { @ Somar índice da data @
aCodMoe = lis_ItemCalculo.CODMOE;
MMBuscaCotacaoMoeda(aCodMoe, dPreAtu, 0, nCotLoc);
Potencia((1+(nCotLoc/100)), (nQtdDia/nQtdDiaAno), nJrsLoc);
nJrsLoc = (nJrsLoc - 1) * nSalDev;
nVlrJrs = nVlrJrs + nJrsLoc; @ Soma ao juros a serem pagos @
nVlrAtu = nVlrAtu + nJrsLoc; @ soma ao saldo atualizado com juros @
}
nTemCalculo = lis_ItemCalculo.Proximo();
}
@ Verificar se deve ser gerada prestação de juros ou de amortização e gerar, senão só acumular os valores para a próxima prestação @
Se (((lis_Prestacoes.DIAPRE = nDiaAtu) e (lis_Prestacoes.MESPRE = nMesAtu) e (lis_Prestacoes.ANOPRE = nAnoAtu))) {
Se (lis_Prestacoes.VLRPRE > 0) { @ Amortização de saldo devedor junto com juros @
nVlrAmo = lis_Prestacoes.VLRPRE;
nTemPrestacao = lis_Prestacoes.Proximo();
ArredondarValor(nVlrAmo,2);
Se (nTemPrestacao = 0) {
nVlrAmo = nSaldev;
nVlrPre = nVlrAtu - nSalDev + nVlrAmo;
nSalDev = 0;
}
Senao {
nVlrPre = nVlrAtu - nSalDev + nVlrAmo;
nSalDev = nSaldev - nVlrAmo;
}
aPreJrs = "N";
}
Senao { @ Amortização somente de juros @
nVlrAmo = 0;
nVlrPre = nVlrAtu - nSalDev;
nTemPrestacao = lis_Prestacoes.Proximo();
aPreJrs = "S";
}
@ Gravar dados da prestação na lista @
nQtdPrestGeradas = nQtdPrestGeradas + 1;
se (VarATipExe = "INCLUSAO")
InserePagamentoLista();
senao
AlteraPagamentoLista();
@ Atualizar o saldo devedor @
nVlrAtu = nSalDev;
nVlrJrs = 0;
}
}
/* Cur_E606CCR.FecharCursor(); */ @ Fechar o cursor que seleciona campos de usuário @
}
Funcao InserePagamentoLista(); {
ListaRegraPodeIncluir(CcrNLista, A_S_N); @ Verifica se tem permissão para incluir @
se (A_S_N = "S") {
ListaRegraNovaLinha(CcrNLista); @ Prepara lista para inclusão de uma nova linha. Deve ser chamado sempre que for usar os métodos incluir as colunas. @
ListaRegraEmInclusao(CcrNLista, A_S_N); @ Verifica situação da lista. @
se (A_S_N = "S") {
ListaRegraAddValorLinhaData(CcrNLista, "DatPre", dPreAtu, A_S_N); @ Adiciona data da prestação @
ListaRegraAddValorLinhaNumero(CcrNLista, "SeqPre", nQtdPrestGeradas, A_S_N); @ Adiciona sequência da prestação @
ListaRegraAddValorLinhaNumero(CcrNLista, "SeqVct", 1, A_S_N); @ 1 - indica prestação normal @
ListaRegraAddValorLinhaAlfa(CcrNLista, "PreCar", "N", A_S_N); @ "N" - indica que não é prestação de carência @
ListaRegraAddValorLinhaAlfa(CcrNLista, "PreJrs", aPreJrs, A_S_N); @ indica se é prestação de pagamento de juros apenas @
ListaRegraAddValorLinhaAlfa(CcrNLista, "VctPre", "S", A_S_N); @ "S" - Indica que é um registro de prestação a pagar @
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrAmo", nVlrAmo, A_S_N); @ Valor da amortização - Quando não for mês de amortização será zero @
@ Valor original da amortização - normalmente igual a VlrAmo, pode existir correção ou desconto na última com relação ao calculado, porém por regra, os valores podem ser sempre iguais @
ListaRegraAddValorLinhaNumero(CcrNLista, "AmoOri", nVlrAmo, A_S_N);
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrJrs", nVlrJrs, A_S_N); @ Valor dos juros na prestação @
@ Valor dos juros original - Quando houver algum tipo de cálculo a mais de juros sobre o valor em aberto do contrato, deverá ser somado ao ao juro da prestação e armazenado aqui @
ListaRegraAddValorLinhaNumero(CcrNLista, "JrsOri", nVlrJrs, A_S_N);
@ Valor a ser pago na prestação - Normalmente amortização mais juros - As vezes é preciso fazer algum ajuste no cálculo para fechar com o valor do contrato na liquidação por exemplo @
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrPre", nVlrPre, A_S_N);
ListaRegraAddValorLinhaNumero(CcrNLista, "PreOri", nVlrPre, A_S_N); @ Valor original a ser pago na prestação - Normalmente igual ao valor da prestação @
ListaRegraAddValorLinhaNumero(CcrNLista, "VlrJmc", 0, A_S_N); @ Guarda o valor dos juros nos meses de carência - Quando houver carência, pode-se trabalhar com este campo @
ListaRegraAddValorLinhaNumero(CcrNLista, "SalDev", nSalDev, A_S_N); @ Saldo devedor do contrato, após pagamento da prestação @
ListaRegraAddValorLinhaAlfa(CcrNLista, "TipPre", "P", A_S_N); @ P - Tudo prestação - Em alguns contratos pode ser "U" quando for cálculo referente ao último dia do mês @
ListaRegraAddValorLinhaAlfa(CcrNLista, "PreRes", "N", A_S_N); @ N - Não é prestação residual @
ListaRegraSalvarLinha(CcrNLista); @Salva a linha na lista@
}
}
}
Funcao AlteraPagamentoLista(); {
Definir Numero nJrsAnt; @ Variável local para guardar o valor da base dos juros calculados anteriormente @
ListaRegraPodeAlterar(CcrNLista, A_S_N); @ Verifica se tem permissão para alterar @
se (A_S_N = "S") {
ListaRegraInicializarProcurar(CcrNLista, A_S_N); @ Inicializa procura na lista @
se (A_S_N = "S") {
ListaRegraAddProcurarData(CcrNLista, "DatPre", dPreAtu, A_S_N);
ListaRegraAddProcurarNumero(CcrNLista, "SeqPre", nQtdPrestGeradas, A_S_N);
ListaRegraProcurarRegistro(CcrNLista, A_S_N); @ Procura e posiciona na lista pela data e sequência da prestacao @
se (A_S_N = "S") {
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrAmo", nVlrAmo, A_S_N); @ Valor da amortização - Quando não for mês de amortização será zero @
@ Valor original da amortização - normalmente igual a VlrAmo, pode existir correção ou desconto na última com relação ao calculado, porém por regra, os valores podem ser sempre iguais @
ListaRegraAlterarLinhaNumero(CcrNLista, "AmoOri", nVlrAmo, A_S_N);
ListaRegraObterValorNumero(CcrNLista, "VlrJrs", nJrsAnt, A_S_N); @ Obter os juros antes da atualização @
ArredondarValor(nVlrJrs,2);
Se (nJrsAnt <> nVlrJrs) { @ Se antes não tinha algum valor de juros... @
ListaRegraAlterarLinhaNumero(CcrNLista, "OutNegAnt", nJrsAnt, A_S_N); @ ... deve guardar o valor de juros calculado anteriormento nos outros negociados anterior ... @
nJrsAnt = (nVlrJrs - nJrsAnt);
ListaRegraAlterarLinhaNumero(CcrNLista, "OutNeg", nJrsAnt, A_S_N); @ ... e deve ter a diferença com relação ao original acrescentado como outros valores negociados agora @
}
senao {
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrJrs", nVlrJrs, A_S_N); @ Valor dos juros na prestação @
@ Valor dos juros original - Quando houver algum tipo de cálculo a mais de juros sobre o valor em aberto do contrato, deverá ser somado ao ao juro da prestação e armazenado aqui @
ListaRegraAlterarLinhaNumero(CcrNLista, "JrsOri", nVlrJrs, A_S_N);
}
@ Valor a ser pago na prestação - Normalmente amortização mais juros - As vezes é preciso fazer algum ajuste no cálculo para fechar com o valor do contrato na liquidação por exemplo @
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrPre", nVlrPre, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "PreOri", nVlrPre, A_S_N); @ Valor original a ser pago na prestação - Normalmente igual ao valor da prestação @
ListaRegraAlterarLinhaNumero(CcrNLista, "VlrJmc", 0, A_S_N); @ Guarda o valor dos juros nos meses de carência - Quando houver carência, pode-se trabalhar com este campo @
ListaRegraAlterarLinhaNumero(CcrNLista, "SalDev", nSalDev, A_S_N); @ Saldo devedor do contrato, após pagamento da prestação @
/* ListaRegraSalvarLinha(CcrNLista); @Salva a linha na lista@ */
}
Senao
mensagem(erro, "Prestação não localizada na lista de prestações.");
}
}
}
@ Inicialização de variáveis @
Funcao Inicializar(); {
nQtdPrestGeradas = 0;
@ Verificar dados do contrato @
Se (E606CCR.NumCcr > 0) {
nCodEmp = E606CCR.CodEmp; @ Empresa do contrato @
DesmontaData(E606CCR.DatBcj, nDia, nMes, nAno); @ Data base para o cálculo de juros @
nDiaIni = nDia;
nMesIni = nMes;
nAnoIni = nAno;
DesmontaData(E606CCR.DatPre, nDia, nMes, nAno); @ Data da primeira amortização, pegar somente o dia base @
nDiaAtu = nDia;
nMesAtu = nMesIni;
nAnoAtu = nAnoIni;
@ Verificar dados do cálculo @
Se (E606CCR.CodCac > 0) {
nCodCac = E606CCR.CodCac;
InicializarListas();
@ Selecionar itens do cálculo do contrato @
Definir Cursor Cur_E606ICC; @ Cursor para selecionar os itens de cálculo do contrato @
Cur_E606ICC.Sql "SELECT SEQICC,TIPCAL,CODMOE,VLRCAL FROM E606ICC WHERE CODEMP = :NCODEMP AND CODCAC = :NCODCAC ORDER BY SEQICC";
Cur_E606ICC.AbrirCursor();
@ Alimenta lista dos cálculos do contrato @
Enquanto (Cur_E606ICC.Achou) {
lis_ItemCalculo.Adicionar();
lis_ItemCalculo.SEQCAL = Cur_E606ICC.SeqIcc; @ Sequência de cálculo do contrato @
lis_ItemCalculo.TIPCAL = Cur_E606ICC.TipCal; @ Tipo de cálculo da sequência do contrato @
lis_ItemCalculo.CODMOE = Cur_E606ICC.CodMoe; @ Código da moeda da seqüência de cálculo do contrato @
lis_ItemCalculo.VALPER = Cur_E606ICC.VlrCal; @ Valor/Percentual da sequência de cálculo do contrato @
lis_ItemCalculo.Gravar();
Cur_E606ICC.Proximo();
}
Cur_E606ICC.FecharCursor();
@ Verifica o período de amortização para o contrato @
Se (E606CCR.CodPri = "M") @ Mensal @
nMesOffset = 1;
Senao Se (E606CCR.CodPri = "B") @ Bimestral @
nMesOffset = 2;
Senao Se (E606CCR.CodPri = "T") @ Trimestral @
nMesOffset = 3;
Senao Se (E606CCR.CodPri = "U") @ Quadrimestral @
nMesOffset = 4;
Senao Se (E606CCR.CodPri = "R") @ Semestral @
nMesOffset = 6;
Senao
nMesOffset = 12; @ Anual @
RetornarQtdDiasAno(E606CCR.DatBcj, 0, nQtdDiaAno); @ Atribui a variável nQtdDiaAno o valor 252, pois a opção 0 busca quantidade de dias pra ano útil @
Definir Numero nDiaBas; @ Dia base da primeira amortização. Guardará o dia base de vencimento das prestações, para ser usado em todos os meses que houver prestação @
Definir Numero nMesBas; @ Mês base da primeira amortização @
Definir Numero nAnoBas; @ Ano base da primeira amortização @
dPreAtu = E606CCR.DatPre; @ Atribui data da primeira prestação... @
DesmontaData(dPreAtu, nDiaBas, nMesBas, nAnoBas); @ ... para pegar o dia base para nDiaBas @
dPreAtu = E606CCR.DatBcj; @ Inicializa o preenchimento das prestações a patir da data base de cálculo de juros @
@ Caso existir meses de carência, e alguns com somente juros, começa montando a lista aqui @
Definir Numero nPos; @ Posição da primeira vírgula na lista de meses @
Definir Alfa aMes; @ mes corrente em alfanumérico @
Definir Numero nQtdMeses; @ Qtde meses a serem incrementados para pagamento de juros @
Definir Alfa aMesesPgto; @ Lista alfanumérica de incrementos de carência mensal, separada por vírgula @
@ Deve ser informado aqui uma lista de quantidade de meses sequencialmente separados por vírgula, ... @
@ ... para serem adicionados a partir da data base cálculo juros para encontrar a próxima prestação de juros com carência de amortização @
@ Aqui no exemplo, está sendo usado um campo do contrato, mas poderia ser um campo de usuário criado na tabela E606CCR que é alimentado no cadastro do contrato através do botão "PERSONALIZAÇÃO" @
aMesesPgto = E606CCR.MesCaa; @ Cur_E606CCR.USU_MESPAGJUR; @
LimpaEspacos(aMesesPgto);
Enquanto (aMesesPgto <> "") { @ Se tiver lista de quantidade de meses para pagamento somente de juros antes de começar a amortizar @
nQtdPrestGeradas = nQtdPrestGeradas + 1;
lis_Prestacoes.Adicionar();
lis_Prestacoes.SEQPRE = nQtdPrestGeradas; @ Sequência da prestação @
PosicaoStr(",", aMesesPgto, nPos);
aMes = aMesesPgto;
Se (nPos > 0){
CopiarStr(aMes, 1, (nPos - 1));
DeletarStr(aMesesPgto, 1, nPos);
}
Senao {
aMesesPgto = "";
}
StrParaInt(aMes, nQtdMeses);
SomarMesesDataRef(dPreAtu, nQtdMeses, 0 @opção 0 não altera o dia do vencimento@ , dPreAtu);
DesmontaData(dPreAtu, nDia, nMes, nAno); @ Mês para cálculo de juros @
MontaData(nDiaBas, nMes, nAno, dPreAtu); @ Data com o dia correto para pagamento @
lis_Prestacoes.DATPGT = dPreAtu; @ Data da prestação de juros @
DesmontaData(dPreAtu, nDia, nMes, nAno);
lis_Prestacoes.DIAPRE = nDia;
lis_Prestacoes.MESPRE = nMes;
lis_Prestacoes.ANOPRE = nAno;
lis_Prestacoes.VLRPRE = 0; @ Prestação de juros @
lis_Prestacoes.Gravar();
Se (dPreAtu >= E606CCR.DatPre) {
aMesesPgto = "";
}
}
Definir Numero nModificador; @ Guarda a quantidade de prestações apenas de juros, para totalizar para geração de prestações @
nModificador = nQtdPrestGeradas;
nQtdPrestGeradas = 0;
@ Alimenta a lista de prestações de amortização conforme a quantidade informada no contrato @
Enquanto (nQtdPrestGeradas < E606CCR.QtdTit) {
nQtdPrestGeradas = nQtdPrestGeradas + 1;
lis_Prestacoes.Adicionar();
lis_Prestacoes.SEQPRE = nQtdPrestGeradas + nModificador; @ Sequência da prestação @
Se (nQtdPrestGeradas = 1) {
dPreAtu = E606CCR.DatPre;
/*DesmontaData(dPreAtu, nDiaBas, nMes, nAno); @ Atribui o dia base para nDiaBas @*/
}
Senao {
DesmontaData(dPreAtu, nDia, nMes, nAno); @ Pega o último vencimento de prestação... @
MontaData(nDiaBas, nMes, nAno, dPreAtu); @ ... e atribui o dia base para ele @
SomarMesesDataRef(dPreAtu, nMesOffset, 0 @opção 0 não altera o dia do vencimento@ , dPreAtu);
}
lis_Prestacoes.DATPGT = dPreAtu; @ A data é sempre a mesma, para dia útil, alterando somente o mês conforme o offset @
DesmontaData(dPreAtu, nDia, nMes, nAno);
lis_Prestacoes.DIAPRE = nDia;
lis_Prestacoes.MESPRE = nMes;
lis_Prestacoes.ANOPRE = nAno;
lis_Prestacoes.VLRPRE = E606CCR.VlrCcr / E606CCR.QtdTit; @ Total dividido pela quantidade de parcelas @
lis_Prestacoes.Gravar();
}
}
Senao
mensagem(erro, "Cálculo do contrato não informado no contrato.");
MMCria();
}
senao
mensagem(erro, "Contrato não carregado para a regra.");
}
@ Finalização dos objetos @
Funcao Finalizar(); {
MMLibera();
}
Para este exemplo de regra, o cálculo é realizado considerando taxa fixa mais índice Selic cadastrado no sistema, bem como os arredondamentos diferenciados no cálculo. O cadastramento dos campos no contrato foram realizados conforme as imagens a seguir:
Alguns campos estão sendo usados no exemplo de regra para outra utilidade que não a original, como por exemplo o campo Meses de carência antes da 1ª prestação. Esse campo foi utilizado para informar na regra a quantidade de meses entre cada prestação somente de juros. No exemplo foi definido "2,3" e essa informação foi utilizada na regra da seguinte forma:
- A partir da data base para cálculo de juros foi somado 2 meses, chegando a data "15/03/2016", data da primeira prestação de juros;
- Em seguida, foi somado mais 3 meses a essa data, chegando na segunda data de prestação de juros: "15/06/2016";
- A partir de "15/07/2016", as prestações são de amortização.
Os demais campos que são obrigatórios podem ser informados com qualquer conteúdo que não afete a geração/atualização de prestações e títulos, pois não são usados no cálculo das prestações via regra.
A solução mais indicada para o exemplo relatado acima, não é utilizar um campo existente, e sim criar um campo de usuário para este fim, que pode ser apresentado para o usuário informar o conteúdo através da tela Contrato de Aplicação e Financiamento - Personalização (F606CCP), acessada através do botão Personalização da tela Cadastro Contrato da Aplicação e Financiamento(F606CCR).
@ Lista de prestações a serem pagas @
Definir Numero CcrNLista;
@ Variável global utilizada para verificar se a execução dos métodos ocorreu com sucesso @
Definir Alfa A_S_N;
@ Valor definido na aplicação que indica se é inclusão de cálculo ou atualização @
Definir Alfa VarATipExe;
@ Valor definido na aplicação que indica se o cálculo veio de regra ou deverá ser executado na regra @
Definir Alfa VarAPlaCal;
Definir Numero nVlrJrs; @ Valor dos juros @
Definir Numero nJrsOri; @ Valor dos juros originais @
Definir Numero nVlrJrsAnt; @ Valor Juros anterior @
Definir Numero nCorJur; @ Valor correção dos juros @
Definir Numero nDscNeg; @ Valor do desconto @
Definir Numero nDscNegAnt; @ Valor do desconto anterior @
Definir Numero nOutNeg; @ Valor de outros acréscimos @
Definir Numero nOutNegAnt; @ Valor de outros acréscimos anterior @
Definir Numero nSeqPre; @ Sequência da prestação @
Definir Numero nCodEmp; @ Código da empresa @
Definir Numero nCodFil; @ Código da filial @
Definir Numero nNumCcr; @ Número do contrato @
se ((VarAPlaCal = "CSV") e (VarATipExe = "ATUALIZACAO")) {
ListaRegraPrimeiro(CcrNLista, A_S_N); @ Posiciona no primeiro registro da lista @
se (A_S_N = "S") {
A_S_N = "N";
@ Atribui as variáveis as informações do contrato @
nCodEmp = E606CCR.CODEMP;
nCodFil = E606CCR.CODFIL;
nNumCcr = E606CCR.NUMCCR;
@ Cursor para buscar a moeda da empresa @
Definir Alfa Cur_E606APT;
SQL_Criar(Cur_E606APT);
SQL_UsarSQLSenior2(Cur_E606APT,0); @ Define que o comando deverá utilizar a sintaxe nativa do banco de dados. @
/* Passa como parâmetro o Cursor que deseja manipular e
depois o numero da abrangência de usuário que deseja fazer.
Deve sempre ser chamado antes de se passar o comando SQL. */
SQL_UsarAbrangencia(Cur_E606APT, 0);
SQL_DefinirComando(Cur_E606APT,"SELECT SUM(E606APT.OUTNEG) SUMOUTNEG, SUM(E606APT.DSCNEG) SUMDSCNEG FROM E606APT WHERE \
E606APT.CODEMP = :NCODEMP AND E606APT.CODFIL = :NCODFIL AND \
E606APT.NUMCCR = :NNUMCCR AND E606APT.SEQPRE = :NSEQPRE");
enquanto (A_S_N <> "S") {@ Enquanto não estiver no final da lista entra no laço. @
ListaRegraObterValorNumero(CcrNLista, "VlrJrs", nVlrJrs, A_S_N); @ Obter os juros atuais @
ListaRegraObterValorNumero(CcrNLista, "VlrJrsAnt", nVlrJrsAnt, A_S_N); @ Obter os juros anteriores @
ListaRegraObterValorNumero(CcrNLista, "JrsOri", nJrsOri, A_S_N); @ Obter os juros originais @
ListaRegraObterValorNumero(CcrNLista, "SeqPre", nSeqPre, A_S_N); @ Obter a sequnecia da prestação @
@ Passar os parâmetros para o cursor @
SQL_DefinirInteiro(Cur_E606APT, "NCODEMP", nCodEmp);
SQL_DefinirInteiro(Cur_E606APT, "NCODFIL", nCodFil);
SQL_DefinirInteiro(Cur_E606APT, "NNUMCCR", nNumCcr);
SQL_DefinirInteiro(Cur_E606APT, "NSEQPRE", nSeqPre);
@ Abre o cursor e atribui as somas selecionadas as variáveis @
SQL_AbrirCursor(Cur_E606APT);
SQL_RetornarFlutuante(Cur_E606APT, "SUMOUTNEG", nOutNegAnt);
SQL_RetornarFlutuante(Cur_E606APT, "SUMDSCNEG", nDscNegAnt);
se (A_S_N = "S") {
@ Arredonda os valores para comparação @
ArredondarValor(nVlrJrs,2);
ArredondarValor(nVlrJrsAnt,2);
ArredondarValor(nJrsOri,2);
ArredondarValor(nDscNegAnt,2);
ArredondarValor(nOutNegAnt,2);
@ Se existir diferença entre o valor calculado atualmente e o original considerando todos os descontos e acréscimos, haverá alteração @
se (nVlrJrs <> (nJrsOri - nDscNegAnt + nOutNegAnt)) {
ListaRegraObterValorNumero(CcrNLista, "DscNeg", nDscNeg, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "DscNegAnt", nDscNeg, A_S_N);
ListaRegraObterValorNumero(CcrNLista, "OutNeg", nOutNeg, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "OutNegAnt", nOutNeg, A_S_N);
ListaRegraAlterarLinhaAlfa(CcrNLista, "TipPre", "P", A_S_N);
se (((nJrsOri - nDscNegAnt + nOutNegAnt) - nVlrJrs) > 0) {
ListaRegraAlterarLinhaNumero(CcrNLista, "OutNeg", 0, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "DscNeg", ((nJrsOri - nDscNegAnt + nOutNegAnt) - nVlrJrs), A_S_N);
}
senao {
ListaRegraAlterarLinhaNumero(CcrNLista, "DscNeg", 0, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "OutNeg", (nVlrJrs - (nJrsOri - nDscNegAnt + nOutNegAnt)), A_S_N);
}
}
senao {
ListaRegraAlterarLinhaNumero(CcrNLista, "OutNeg", 0, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "OutNegAnt", 0, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "DscNeg", 0, A_S_N);
ListaRegraAlterarLinhaNumero(CcrNLista, "DscNegAnt", 0, A_S_N);
}
}
SQL_FecharCursor(Cur_E606APT); @ Fecha o cursor para ser reutilizado no próximo registro da lista @
ListaRegraProximo(CcrNLista, A_S_N); @ Posiciona no próximo registro; @
ListaRegraFim(CcrNLista, A_S_N); @ Atualiza variável final de lista @
}
SQL_Destruir(Cur_E606APT);
}
}