package com.fitbank.installment;

import java.math.BigDecimal;
import java.sql.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import com.fitbank.common.CategoryGroupTypes;
import com.fitbank.common.QuotaBean;
import com.fitbank.common.QuotaCategoryBean;
import com.fitbank.common.helper.CalculationBase;
import com.fitbank.common.helper.Constant;
import com.fitbank.common.helper.Dates;
import com.fitbank.common.properties.PropertiesHandler;
import com.fitbank.fin.helper.FinancialHelper;
import com.fitbank.fin.helper.Transaction;
import com.fitbank.fin.tariff.Rate;
import com.fitbank.hb.persistence.gene.Tcurrencyid;
import com.fitbank.hb.persistence.gene.Tsubsystemcategorygroup;
import com.fitbank.hb.persistence.trans.Titemdefinition;
import com.fitbank.helper.HoldChecks;
import com.fitbank.helper.InstallmentDates;

/**
 * Clase que contiene rutinas generales para el calculo de una tabla de pagos.
 * 
 * @author Soft Warehouse S.A.
 */
public abstract class AbstractQuota extends InstallmentDates {

    /** Interes global de una cuota incluye intereses y comisiones. */
    protected BigDecimal globalIntrest = BigDecimal.ZERO;
    /** Numero de cuota que se genera */
    protected int quotanumber = 0;
    /**
     * Map de categorias de interes, comision, seguros a calcular. El key es la
     * categoria de interes, comision, seguro a calcular. El objeto CategoryRate
     * tiene la tasa asociada a la categoria para calcular el valor del interes,
     * comion, impuesto, seguro ..etc ...
     */
    protected Map<String, List<CategoryRate>> mCategoryRates;
    /**
     * Referencia al objeto que almacena datos utiles para la generacion de una
     * tabla de pagos.
     */
    protected InstallmentTable quotaTable;
    /** Capital reducido de una cuota. */
    protected BigDecimal reducedcapital = Constant.BD_ZERO;
    /** Codigo de categoria de capital. */
    protected String capitalcategory;
    /** Codigo de grupo de balance aosociado a la categoria de capital */
    protected String capitalbalancegroup;
    /** Numero de dias de la frecuencia de interes. */
    protected Integer interestFrquencyDays;
    /** Indica si la tabla se genera con intereses anticipado. */
    protected boolean isAdvancedInterest = false;
    /**
     * Indica si se calcula intyeres remanete por redondedo de decimales de una
     * cuota, el remanente se calcula con 6 decimales.
     */
    protected boolean calcularemanete = false;
    /** Interes remanente de la cuota anterior. */
    private BigDecimal interesremanente = Constant.BD_ZERO;

    /**
     * Metodo a travez del cual se invoca a la clase especifca para calculo de
     * tabla.
     * 
     * @param pQuotaTable
     *            Datos generles de la tabla de pagos.
     * @throws Exception
     */
    public abstract void calculate(InstallmentTable pQuotaTable)
            throws Exception;

    /**
     * Metodo que obtiene una lista de tasas, impuestos, comiiones, seguros a
     * calcular en la cuota las categorias a calcular se obtienen: en la
     * solicitud de tsolicitudcategoriatasas, cuando se tiene la cuenta se
     * obtiene de tcuentacategoriatasas.
     * 
     * @throws Exception
     */
    protected void processByCategory(boolean advancedInterest) throws Exception {
        this.processByCategory(null, advancedInterest);
    }

    /**
     * Metodo que se encarga del calculo de valores que se provisionan, por
     * categoria de capital, ejemplo capital propio y capital externo.
     * 
     * @param pDebtorInterest
     *            Interes deudor acumualdo de las cuotas anteriores.
     * @throws Exception
     */
    protected void processByCategory(BigDecimal pDebtorInterest,
            boolean advancedInterest) throws Exception {
        Map<String, Map<String, List<CategoryRate>>> mRates = this.quotaTable
                .getMRates();
        // Obtiene las categorias de capital ejemplo Capital propio y capital
        // externo.
        Iterator<String> itr = mRates.keySet().iterator();
        while (itr.hasNext()) {
            String key = itr.next();
            StringTokenizer stk = new StringTokenizer(key, "^");
            this.capitalcategory = (String) stk.nextElement();
            this.capitalbalancegroup = (String) stk.nextElement();
            Map<String, List<CategoryRate>> mCategoryRates = mRates.get(key);
            BigDecimal amount = this.reducedcapital;
            if (!PropertiesHandler.getConfig("financial").getBoolean(
                    "nominalrate")
                    && pDebtorInterest != null) {
                amount = amount.add(pDebtorInterest);
            }
            BigDecimal interest = this.calculateIntrestCommission(
                    mCategoryRates, amount, advancedInterest);
            this.globalIntrest = this.globalIntrest.add(interest);
        }
    }

    /**
     * Calcula inteses y comisiones.
     * 
     * @throws Exception
     */
    protected BigDecimal calculateIntrestCommission(
            Map<String, List<CategoryRate>> p_mCategoryRates,
            BigDecimal pCapital, boolean advancedInterest) throws Exception {
        this.mCategoryRates = p_mCategoryRates;
        BigDecimal categoryIntrest;
        BigDecimal accumulatedIntrest = BigDecimal.ZERO;
        Iterator<String> itr_key = this.mCategoryRates.keySet().iterator();
        while (itr_key.hasNext()) {
            String key = itr_key.next();
            List<CategoryRate> categoryRateList = this.mCategoryRates.get(key);
            categoryIntrest = BigDecimal.ZERO;
            for (CategoryRate categoryRate : categoryRateList) {
                if (categoryRate.getRate() != null
                        && categoryRate.getRate().compareTo(BigDecimal.ZERO) > 0) {
                    categoryIntrest = this.calculateValueRate(categoryRate,
                            pCapital, categoryRate.getRate(),
                            this.getDaysperquota(), advancedInterest);
                }
                categoryRate.setIntrest(categoryIntrest);
                accumulatedIntrest = accumulatedIntrest.add(categoryRate
                        .getIntrest());
            }
        }
        return accumulatedIntrest;
    }

    /**
     * Calcula intereses, comisiones, seguros de una cuota, cuyo calculo sea
     * similar al calculo de interes de una cuota.
     * 
     * @param pAmount
     *            Capital reducido.
     * @param pRate
     *            Tasa a aplicar.
     * @param pDays
     *            Numero de dias de la cuota.
     * @param advancedInterest
     *            Indica si se calcula el valor de la cuota con interes
     *            anticipafo..
     * @return BigDecimal
     * @throws Exception
     */
    protected BigDecimal calculateValueRate(CategoryRate pCategoryRate,
            BigDecimal pAmount, BigDecimal pRate, int pDays,
            boolean advancedInterest) throws Exception {
        BigDecimal interest = BigDecimal.ZERO;
        Rate rate = new Rate(this.quotaTable.getCalculationBase());
        List<Map<String, Object>> ldata = null;
        if (quotaTable.getAccountnumber() != null
                && quotaTable.subsystem.compareTo("05") == 0) {
            HoldChecks h = new HoldChecks();
            ldata = h.getChecksToConfirm(quotaTable.getAccountnumber(),
                    quotaTable.getCompany(), this.previouspaydate);
        }
        if (ldata == null || ldata.isEmpty()) {
            // manejo de saldos en cheques por confirmar se resta del capital
            // original.
            if (!advancedInterest) {
                interest = rate.calculateDividendinterest(pAmount, pRate,
                        pDays, this.quotaTable.getCurrency());
            } else {
                interest = rate.calculateDividendinterestIA(pAmount, pRate,
                        this.interestFrquencyDays, pDays,
                        this.quotaTable.getCurrency());
            }
        } else {
            interest = this.calculeWithHold(rate, pAmount, pRate, pDays, ldata);
        }
        // Calculo del interes remanente.
        if (this.calcularemanete) {
            BigDecimal dif = rate.getInterescuota().subtract(interest);
            interesremanente = interesremanente.add(dif);
            Tcurrencyid tcurrencyid = FinancialHelper.getInstance()
                    .getTcurrencyid(quotaTable.getCurrency());
            BigDecimal remanente = interesremanente.divide(BigDecimal.ONE,
                    tcurrencyid.getNumerodecimales(), BigDecimal.ROUND_HALF_UP);
            if (remanente.abs().compareTo(Constant.BD_ONE_HUNDREDTH) >= 0) {
                interesremanente = interesremanente.subtract(remanente);
                pCategoryRate.setInteresremanente(remanente);
            }
        }
        return interest;
    }

    /**
     * Metodo que calcula el interes considerando valores depositados en cheque.
     * 
     * @param pRate
     *            Referencia al objeto Rate.
     * @param pAmount
     *            Capital reducido.
     * @param rate
     *            tasa con la que se calcula los intereses.
     * @param pDays
     *            Numero de dias de la cuota.
     * @param pLdata
     *            Lista de valores en cheque con fecha de liberacion futura.
     * @return BigDecimal.
     * @throws Exception
     */
    private BigDecimal calculeWithHold(Rate pRate, BigDecimal pAmount,
            BigDecimal rate, int pDays, List<Map<String, Object>> pLdata)
            throws Exception {
        BigDecimal interest = BigDecimal.ZERO;
        int originaldays = pDays;
        Date inidate = this.previouspaydate;
        for (Map<String, Object> m : pLdata) {
            Date d = (Date) m.get("date");
            int days = 1;
            if (originaldays != 1) {
                days = this.getHoldDays(d, inidate);
            }
            if (days > originaldays) {
                days = originaldays;
            }
            originaldays = originaldays - days;
            if (originaldays < 0) {
                originaldays = 0;
            }
            BigDecimal hold = this.getHoldAmount(pLdata, this.previouspaydate);
            BigDecimal prov = pRate.calculateDividendinterest(
                    pAmount.subtract(hold), rate, days,
                    this.quotaTable.getCurrency());
            interest = interest.add(prov);
        }
        if (originaldays > 0) {
            BigDecimal prov = pRate.calculateDividendinterest(pAmount, rate,
                    originaldays, this.quotaTable.getCurrency());
            interest = interest.add(prov);
        }
        return interest;
    }

    /**
     * Entrega el valor de retenciones, cuaya fecha de liberacion es mayor o
     * igual a una fecha dada.
     * 
     * @param pLdata
     *            Monto de cheques con fecha de liberacion futura.
     * @param pDate
     *            Fecha a obtener valores uturos.
     * @return {@link BigDecimal}
     * @throws Exception
     */
    private BigDecimal getHoldAmount(List<Map<String, Object>> pLdata,
            Date pDate) throws Exception {
        BigDecimal hold = BigDecimal.ZERO;
        for (Map<String, Object> m : pLdata) {
            Date d = (Date) m.get("date");
            BigDecimal value = (BigDecimal) m.get("value");
            if (d.compareTo(pDate) > 0) {
                hold = hold.add(value);
            }
        }
        return hold;
    }

    /**
     * Metodo que entrega el numero de dias entre la fecha de liberacion de
     * cheques y la fecha de inicio de la cuota.
     * 
     * @param pHolddate
     *            Fecha de liberacion de cheques.
     * @return int
     * @throws Exception
     */
    private int getHoldDays(Date pHolddate, Date pIniDate) throws Exception {
        int days = 0;
        Dates to = new Dates(pHolddate, CalculationBase.B365365);
        Dates from = new Dates(pIniDate);
        days = to.substract(from);
        return days;
    }

    /**
     * Metodo que crea una cuota de un dia utilizada en la generacion de tablas
     * de interes anticipado, adicionalmente obtiene la categoria y grupo de
     * balance de capital.
     * 
     * @param pQuotaTable
     *            Datos generles de la tabla de pagos.
     * @throws Exception
     */
    protected void addOnePayMetDay(InstallmentTable pQuotaTable)
            throws Exception {
        this.setNextpaydate(pQuotaTable.getAccountingdate());
        this.setPreviouspaydate(pQuotaTable.getAccountingdate());
        this.daysperquota = 1;
        // Obtiene la categoria de capial
        Map<String, Map<String, List<CategoryRate>>> mRates = this.quotaTable
                .getMRates();
        Iterator<String> itr = mRates.keySet().iterator();
        while (itr.hasNext()) {
            String key = itr.next();
            StringTokenizer stk = new StringTokenizer(key, "^");
            this.capitalcategory = (String) stk.nextElement();
            this.capitalbalancegroup = (String) stk.nextElement();
        }
    }

    /**
     * Encera la fecha de primer pago en cuotas con interes anticipado, con el
     * fin de respetar las condiciones de pago de la primera cuota, como fecha
     * de inicio de pagos.
     * 
     * @param pQuotaTable
     *            Datos generles de la tabla de pagos.
     * @throws Exception
     */
    protected void removeOnePayMetDay(InstallmentTable pQuotaTable)
            throws Exception {
        this.setNextpaydate(null);
        this.setPreviouspaydate(null);
        this.daysperquota = 0;
    }

    /**
     * Metodo que recalcula el numero de cuotas, cuando se conoce el plazo de
     * una operacion.
     * 
     * @param pQuotaTable
     * @throws Exception
     */
    protected void calculateTotalperiod(InstallmentTable pQuotaTable)
            throws Exception {
        int size = quotaTable.getTotalperiod();
        size = size + quotaTable.getBegincalculationperiod() - 1;
        stop = false;
        for (int i = quotaTable.getBegincalculationperiod(); i <= size; i++) {
            this.calculatePayDate(quotaTable);
            if (stop) {
                break;
            }
            quotanumber++;
        }// end for
         // Ajuste de valor de cuota fija
         // pQuotaTable.setTotalperiod(quotanumber);
        this.totaldays = 0;
        this.daysperquota = 0;
        this.previouspaydate = null;
        this.nextpaydate = null;
        this.stop = false;
        // encera nuevamente la cuota inicio.
        quotanumber = pQuotaTable.getBegincalculationperiod();
        /*
         * if(pQuotaTable.getGraceperiod() > 0){ quotanumber = quotanumber +
         * pQuotaTable.getGraceperiod(); }
         */
    }

    /**
     * Adiciona una cuota al calendario de pagos.
     * 
     * @param pQuotaTable
     *            Datos de tabla de pagos.
     * @param pQuotanumber
     *            Numero de cuota.
     * @param pReducedcapita
     *            Capital reducido.
     * @param pCapital
     *            Capital de la cuota.
     * @param pIntrest
     *            Interes de la cuota.
     * @param pCommision
     *            Comision de la cuota.
     * @throws Exception
     */
    public void addQuota(Integer pQuotanumber, BigDecimal pReducedcapita,
            BigDecimal pCapital, boolean isAddChrarges) throws Exception {
        // Genera la cuota de la solicitud
        QuotaBean quotabean = this.quotaTable.getAccountOrSolicitudeTypes()
                .getQuotaClass(this.quotaTable, pQuotanumber);
        quotabean.setCmoneda(this.quotaTable.getCurrency());
        quotabean.setFvencimiento(this.getNextpaydate());
        Dates previouspaydate = new Dates(this.previouspaydate,
                CalculationBase.B365365);
        Dates fvencimiento = new Dates(quotabean.getFvencimiento(),
                CalculationBase.B365365);
        quotabean.setNumerodiascalendario(fvencimiento
                .substract(previouspaydate));
        quotabean.setNumerodiasprovision(this.getDaysperquota());
        quotabean.setCapital(pCapital);
        quotabean.setCapitalreducido(pReducedcapita);
        this.addQuotaCategoryBean(quotabean, pQuotanumber, pReducedcapita,
                pCapital, false, isAddChrarges);
        this.quotaTable.addQuotaBean(quotabean);
    }

    /**
     * Adiciona registros por categoria a la tabla de pagos. si es Plazo
     * isAdvancedInterest=false se registra todas las cuotas
     * 
     * @param pQuotaBean
     *            Datos de la cabecera de la tabla de pagos.
     * @param pQuotanumber
     *            Numero de cuota a generar.
     * @param pReducedcapita
     *            Capital reducido de la operacion.
     * @param pCapital
     *            Valor de capital de la cuota.
     * @throws Exception
     */
    private void addQuotaCategoryBean(QuotaBean pQuotaBean,
            Integer pQuotanumber, BigDecimal pReducedcapita,
            BigDecimal pCapital, boolean isUpdate, boolean isAddChrarges)
            throws Exception {
        // Genera la categoria de Capital de la cuota de la solicitud
        QuotaCategoryBean quotaCategoryBean = this.quotaTable
                .getAccountOrSolicitudeTypes().getQuotaCategoryClass(
                        this.quotaTable, pQuotanumber, this.capitalcategory,
                        this.capitalbalancegroup);
        quotaCategoryBean.setValorcategoria(pCapital);
        quotaCategoryBean.setValordeudorcategoria(pReducedcapita);
        if (this.capitalcategory != null
                && pCapital.compareTo(Constant.BD_ZERO) > 0
                && this.isAdvancedInterest) {
            this.quotaTable.addQuotaCategoryBean(quotaCategoryBean);
        }
        if (this.capitalcategory != null && !this.isAdvancedInterest) {
            this.quotaTable.addQuotaCategoryBean(quotaCategoryBean);
        }
        // Intereses
        this.addCalculesRates(pQuotaBean, pQuotanumber);
        // cargos fijos
        if (!isUpdate && isAddChrarges) {
            this.addCharges(pQuotaBean, pQuotanumber);
        }
    }

    /**
     * Metodo que adiciona categorias calculadas aplicando una tasa a la cuota.
     * 
     * @param pQuotaBean
     *            Cabecera de una tabla de amortizacion.
     * @param pQuotaCategoryBean
     *            Detalle por categoria de la tabla de amortizacion.
     * @param pQuotanumber
     *            Numero de cuota.
     * @throws Exception
     */
    private void addCalculesRates(QuotaBean pQuotaBean, Integer pQuotanumber)
            throws Exception {
        if (this.mCategoryRates == null) {
            return;
        }
        // Genera las categorias de Intereses y Comisiones de la cuota de la
        // solicitud
        Iterator<List<CategoryRate>> itr_CategoryRate = this.mCategoryRates
                .values().iterator();
        while (itr_CategoryRate.hasNext()) {
            for (CategoryRate categoryRates : itr_CategoryRate.next()) {

                QuotaCategoryBean pQuotaCategoryBean = this.quotaTable
                        .getAccountOrSolicitudeTypes().getQuotaCategoryClass(
                                this.quotaTable, pQuotanumber,
                                categoryRates.getCategory(),
                                categoryRates.getCbalanceGroup());
                if (this.calcularemanete) {
                    pQuotaCategoryBean.setValorcategoria(categoryRates
                            .getIntrest().add(
                                    categoryRates.getInteresremanente()));
                } else {
                    pQuotaCategoryBean.setValorcategoria(categoryRates
                            .getIntrest());
                }
                /*
                 * Modificacion para copiar en valordeudorcategoria el mismo
                 * valor del cargo para las categorias que son seguros
                 */
                if (categoryRates.getRateType().compareTo(
                        CategoryGroupTypes.INSURANCE.name()) == 0) {
                    pQuotaCategoryBean.setValordeudorcategoria(categoryRates
                            .getIntrest());
                } else {
                    pQuotaCategoryBean.setValordeudorcategoria(categoryRates
                            .getDebtorinterest());
                }
                this.quotaTable.addQuotaCategoryBean(pQuotaCategoryBean);
                this.updateTquotasolicitude(pQuotaBean,
                        categoryRates.getIntrest(), categoryRates.getRateType());
            }
        }
    }

    /**
     * Metodo que adiciona cargos fijos a las cuotas.<br>
     * 
     * @param pQuotaBean
     *            Cabecera de una tabla de amortizacion.
     * @param pQuotaCategoryBean
     *            Detalle por categoria de la tabla de amortizacion.
     * @param pQuotanumber
     *            Numero de cuota.
     * @throws Exception
     */
    private void addCharges(QuotaBean pQuotaBean, Integer pQuotanumber)
            throws Exception {
        Integer quotanumber = pQuotanumber;
        if (this.isAdvancedInterest) {
            ++quotanumber;
        }
        for (ChargeValues chargeAccount : this.quotaTable.getOtherCharges()) {
            this.addChargesByRegister(chargeAccount, pQuotanumber, pQuotaBean);
        }
    }

    private void addChargesByRegister(ChargeValues chargeAccount,
            Integer pQuotanumber, QuotaBean pQuotaBean) throws Exception {
        BigDecimal value = Constant.BD_ZERO;
        if (chargeAccount.getInCuota().compareTo("1") == 0
                || chargeAccount.isDistribuyeencuotas()) {
            if (chargeAccount.isDistribuyeencuotas()) {
                // El valor que llega en el cargo se distribuye en las
                // cuotas del prestamo.
                value = this.getValue(chargeAccount);
                // chargeAccount.setValue(value);
                // para que solo haga una vez el calculo.
                // chargeAccount.setDistribuyeencuotas(false);
            }
            if (isContinue(chargeAccount, pQuotanumber)) {
                return;
            }
            // CategoryRate categoryRates = itr_CategoryRate.next();
            Transaction transaccion = new Transaction(
                    chargeAccount.getSubsistema(),
                    chargeAccount.getTranasccion(),
                    chargeAccount.getVersionTranasccion());
            Titemdefinition item = transaccion.getTitemdefinition(chargeAccount
                    .getRubro());
            this.addQuotaCategoryBeanByCharges(pQuotanumber, value,
                    chargeAccount, item);
            Tsubsystemcategorygroup tsubsystemcategorygroup = FinancialHelper
                    .getInstance().getTsubsystemcategorygroup(
                            item.getCategoria(), item.getCgrupobalance(),
                            chargeAccount.getSubsistema(),
                            chargeAccount.getCompania());
            this.updateTquotasolicitude(
                    pQuotaBean,
                    value.compareTo(Constant.BD_ZERO) == 0 ? chargeAccount
                            .getValue() : value, tsubsystemcategorygroup
                            .getGrupocategoria());
        }
    }

    private void addQuotaCategoryBeanByCharges(Integer pQuotanumber,
            BigDecimal value, ChargeValues chargeAccount, Titemdefinition item)
            throws Exception {
        QuotaCategoryBean pQuotaCategoryBean = this.quotaTable
                .getAccountOrSolicitudeTypes().getQuotaCategoryClass(
                        this.quotaTable, pQuotanumber, item.getCategoria(),
                        item.getCgrupobalance());
        pQuotaCategoryBean
                .setValorcategoria(value.compareTo(Constant.BD_ZERO) == 0
                        ? chargeAccount.getValue()
                        : value);
        pQuotaCategoryBean.setValordeudorcategoria(value
                .compareTo(Constant.BD_ZERO) == 0
                ? chargeAccount.getValue()
                : value);
        this.quotaTable.addQuotaCategoryBean(pQuotaCategoryBean);
    }

    private BigDecimal getValue(ChargeValues chargeAccount) {
        BigDecimal value = Constant.BD_ZERO;
        int size = quotaTable.getTotalperiod() - quotaTable.getGraceperiod();
        if (chargeAccount.getBeginQuota() != null
                && chargeAccount.getEndQuota() != null) {
            size = chargeAccount.getEndQuota() - chargeAccount.getBeginQuota()
                    + 1;
        }
        value = chargeAccount.getValue().divide(new BigDecimal(size), 2,
                BigDecimal.ROUND_HALF_UP);
        if (size == this.quotanumber) {
            BigDecimal amount = value.multiply(new BigDecimal(size - 1));
            value = chargeAccount.getValue().subtract(amount);
        }
        return value;
    }

    /**
     * Metodo que valida si se adiciona o no un cargo a la tabla, cuando esta
     * tiene una cuota de inicio y de finalizacion.
     * 
     * @param pChargeValues
     *            Registro de cargos a asociar a la tabla de amortizacion.
     * @param pQuotanumber
     *            Numero de cuota.
     * @return boolean.
     * @throws Exception
     */
    private boolean isContinue(ChargeValues pChargeValues, Integer pQuotanumber)
            throws Exception {
        if (pChargeValues.getBeginQuota() != null
                && pQuotanumber < pChargeValues.getBeginQuota()) {
            return true;
        }
        if (pChargeValues.getEndQuota() != null
                && pQuotanumber > pChargeValues.getEndQuota()) {
            return true;
        }
        return pChargeValues.getValue().compareTo(Constant.BD_ZERO) <= 0;
    }

    /**
     * Metodo que actualiza valores en la cuotas cuando se genera tablas con
     * interes anticipado.
     * 
     * @param pQuotaNumber
     *            Numero de cuota.
     * @param pReducedcapita
     *            Capital reducido.
     * @param pCapital
     *            Capital de la cuota.
     * @throws Exception
     */
    public void updateQuota(Integer pQuotaNumber, BigDecimal pReducedcapita,
            BigDecimal pCapital) throws Exception {
        QuotaBean quotaBean = this.quotaTable.getQuotaBean(pQuotaNumber);
        this.daysperquota = quotaBean.getNumerodiasprovision();
        quotaBean.setCapitalreducido(pReducedcapita);
        quotaBean.setCapital(pCapital);
        this.addQuotaCategoryBean(quotaBean, pQuotaNumber, pReducedcapita,
                pCapital, true, false);
    }

    /**
     * Completa valores de interes, comision, seguro, cargos en la tabla
     * tsolicitudcuotas.
     * 
     * @param pTquotasolicitude
     * @param pCategoryRate
     */
    private void updateTquotasolicitude(QuotaBean pQuotaBean,
            BigDecimal pValue, String pGroupType) {
        CategoryGroupTypes categoryGroupTypes = CategoryGroupTypes
                .valueOf(pGroupType);
        BigDecimal value = pValue; // pCategoryRate.getIntrest();
        switch (categoryGroupTypes) {
            case INTEREST :
                BigDecimal interest = pQuotaBean.getInteres();
                pQuotaBean.setInteres(interest.add(value));
                break;
            case CHARGE :
                BigDecimal charge = pQuotaBean.getCargo();
                pQuotaBean.setCargo(charge.add(value));
                break;
            case INSURANCE :
                BigDecimal insurance = pQuotaBean.getSeguro();
                pQuotaBean.setSeguro(insurance.add(value));
                break;
            case COMMISSION :
                BigDecimal comission = pQuotaBean.getComision();
                pQuotaBean.setComision(comission.add(value));
                break;
            case SHARES :
                BigDecimal shares = pQuotaBean.getAcciones();
                pQuotaBean.setAcciones(shares.add(value));
                break;
            default :
                break;
        }
    }

}
