package com.fitbank.installment; import java.math.BigDecimal; import java.sql.Date; import com.fitbank.common.ApplicationDates; import com.fitbank.common.Helper; import com.fitbank.common.exception.FitbankException; import com.fitbank.common.helper.CalculationBase; import com.fitbank.common.helper.Constant; import com.fitbank.common.helper.Dates; import com.fitbank.fin.helper.FinancialHelper; import com.fitbank.hb.persistence.acco.Taccount; import com.fitbank.hb.persistence.acco.TaccountKey; import com.fitbank.hb.persistence.gene.Tcurrencyid; import com.fitbank.hb.persistence.gene.Tfrecuencyid; /** * Genera tabla de amortización con frecuencia de capital diferente a la * frecuencia de interés. * * @author Soft WareHouse S.A. */ public class SpecialGradualInstallment extends AbstractQuota { /** * Número de cuotas de capital. */ protected int totalCapitalPeriod = 0; /** * Périodos con capital. */ protected int capitalPeriod = 0; /** * Número de cuotas de interés. */ protected int totalInterestPeriod = 0; protected Date originalInicialDate; protected BigDecimal quotaCapital; /* * (non-Javadoc) * * @see * com.fitbank.installment.AbstractQuota#calculate(com.fitbank.installment * .InstallmentTable) */ public void calculate(InstallmentTable pQuotaTable) throws Exception { this.quotaTable = pQuotaTable; this.quotanumber = pQuotaTable.getBegincalculationperiod(); this.reducedcapital = pQuotaTable.getAmount(); this.generateTable(); } /** * Método que genera la tabla de amortización. * * @throws Exception */ private void generateTable() throws Exception { // Genera las cuotas de capital e interes boolean end = false; this.fillCapitalQuotas(); int capitalQuotaCounter = 0; BigDecimal capitalZero = Constant.BD_ZERO; originalInicialDate = quotaTable.getFirstpaymetdate(); this.calculateFistpaymentdate(quotaTable); for (int i = this.quotaTable.getBegincalculationperiod(); i <= totalInterestPeriod; i++) { capitalQuotaCounter = capitalQuotaCounter + 1; super.calculatePayDate(this.quotaTable); if (i == totalInterestPeriod) { end = true; } super.processByCategory(false); if (this.capitalPeriod == capitalQuotaCounter || (originalInicialDate != null && originalInicialDate .compareTo(super.getNextpaydate()) == 0)) { if (originalInicialDate == null) { this.calculateCuota(quotaCapital, end); capitalQuotaCounter = 0; } else if (originalInicialDate .compareTo(super.getNextpaydate()) == 0) { this.calculateCuota(quotaCapital, end); capitalQuotaCounter = 0; originalInicialDate = null; } else { this.calculateCuota(capitalZero, end); } } else { this.calculateCuota(capitalZero, end); } this.quotanumber++; }// end for } /** * Método que valida que la frecuencia de capital sea un múltiplo de la * frecuencia de interés, obtiene el valor de capital a cobrar en cada cuota * que coincida con la frecuencia de capital. * * @throws Exception */ protected void fillCapitalQuotas() throws Exception { // Obtiene la moneda de la tabla de pagos Tcurrencyid tcurrencyid = FinancialHelper.getInstance().getTcurrencyid( this.quotaTable.getCurrency()); // Define el total de cuotas de capital de la tabla de pagos Tfrecuencyid capitalFrequencyId = FinancialHelper.getInstance() .getTfrecuencyid(quotaTable.getCapitalFrequency()); if (this.quotaTable.getAccountnumber() != null) { TaccountKey key = new TaccountKey( this.quotaTable.getAccountnumber(), ApplicationDates.DEFAULT_EXPIRY_TIMESTAMP, this.quotaTable.getCompany()); Taccount taccount = (Taccount) Helper.getBean(Taccount.class, key); if (taccount != null) { Dates openingDate = new Dates(taccount.getFapertura(), CalculationBase.B365365); Dates accountingDate = new Dates( this.quotaTable.getAccountingdate(), CalculationBase.B365365); if (capitalFrequencyId != null && capitalFrequencyId.getNumerodias() != null) { int aux = this.quotaTable.getTerm() - (accountingDate.substract(openingDate)); if (aux <= capitalFrequencyId.getNumerodias()) { this.totalCapitalPeriod = 1; } else { this.totalCapitalPeriod = (this.quotaTable.getTerm() - (accountingDate .substract(openingDate))) / capitalFrequencyId.getNumerodias(); } } else { this.totalCapitalPeriod = this.quotaTable.getTotalperiod(); } } } else { if (capitalFrequencyId != null && capitalFrequencyId.getNumerodias() != null) { this.totalCapitalPeriod = this.quotaTable.getTerm() / capitalFrequencyId.getNumerodias(); } else { this.totalCapitalPeriod = this.quotaTable.getTotalperiod(); } } // Define el total de cuotas de interes de la tabla de pagos Tfrecuencyid interestFrequencyId = FinancialHelper.getInstance() .getTfrecuencyid(quotaTable.getIntrestFrequency()); if (interestFrequencyId.getNumerodias().compareTo( capitalFrequencyId.getNumerodias()) > 0) { throw new FitbankException("QUO010", "FRECUENCIA DE INTERES TIENE QUE SER MENOR O IGUAL A LA FRECUENCIA DE CAPITAL."); } if (capitalFrequencyId.getNumerodias() % interestFrequencyId.getNumerodias() != 0) { throw new FitbankException("QUO011", "FRECUENCIA DE CAPITAL TIENE QUE SER MULTIPLO DE LA FRECUENCIA DE INTERES."); } super.interestFrquencyDays = interestFrequencyId.getNumerodias(); if (interestFrequencyId != null && interestFrequencyId.getNumerodias() != null) { this.totalInterestPeriod = this.quotaTable.getTerm() / interestFrequencyId.getNumerodias(); } else { this.totalInterestPeriod = this.quotaTable.getTotalperiod(); } if (capitalFrequencyId.getNumerodias().compareTo( interestFrequencyId.getNumerodias()) > 0) { this.capitalPeriod = capitalFrequencyId.getNumerodias() / interestFrequencyId.getNumerodias(); } else { this.capitalPeriod = 1; } // Obtiene el valor fijo de capital de cada cuota quotaCapital = this.quotaTable.getAmount().divide( new BigDecimal(this.totalCapitalPeriod), tcurrencyid.getNumerodecimales(), BigDecimal.ROUND_HALF_UP); } /** * Calcula tabla de pago dado una cuota fija. * * @throws Exception */ private void calculateCuota(BigDecimal pCapital, boolean pEnd) throws Exception { // Obtiene los valores de interes y comision para cada categoria // Obtiene el valor de interes y comision de la cuota // Si se trata de la ultima cuota BigDecimal capital = pCapital; if (pEnd) { // Carga todo el capital reducido al capital de la cuota capital = this.reducedcapital; this.reducedcapital = this.reducedcapital.subtract(capital); } super.addQuota(this.quotanumber, this.reducedcapital, capital, true); if (!pEnd) { if (capital.compareTo(this.reducedcapital) > 0) { capital = this.reducedcapital; } this.reducedcapital = this.reducedcapital.subtract(capital); } } /** * Calcua la fecha de inicio de pagos. * * @param pQuotaTable * @throws Exception */ protected void calculateFistpaymentdate(InstallmentTable pQuotaTable) throws Exception { if (pQuotaTable.getFirstpaymetdate() == null) { return; } Dates dates = null; Date date = null; int substractQuotas = capitalPeriod * -1; if (pQuotaTable.isFixday()) { dates = new Dates(pQuotaTable.getFirstpaymetdate(), CalculationBase.B360360); } else { dates = new Dates(pQuotaTable.getFirstpaymetdate(), pQuotaTable.getCalculationBase()); } while (dates.getDate().compareTo(pQuotaTable.getAccountingdate()) > 0) { date = dates.getDate(); dates.addDaysBased(pQuotaTable.getDaysperperiod() * -1, pQuotaTable.getPayday()); substractQuotas++; } if (date != null) { pQuotaTable.setFirstpaymetdate(date); quotaTable.setTotalperiod(quotaTable.getTotalperiod() + substractQuotas); } } }