Ejemplo n.º 1
0
        /// <summary>
        /// Updates an existing loan in a loan request.
        /// </summary>
        /// <param name="financialInstitutionName">financialInstitution</param>
        /// <param name="workingCapitalLoan">workingCapitalLoan</param>
        /// <param name="interestRateId">interestRateId</param>
        /// <remarks>This function will update the Credit Line amounts only if the
        /// loan request has been completed.</remarks>
        public void UpdateLoanRequestLoanInformation(string financialInstitutionName,
            Loan loan,
            int interestRateId,
            int loanId,
            int loanVersion)
        {
            try
            {
                IFinancialInstitutionDAO financialInstitutionDAO = _daoFactory.GetFinancialInstitutionDAO ();
                IInterestRateDAO interestRateDAO = _daoFactory.GetInterestRateDAO ();
                ILoanDAO loanDAO = _daoFactory.GetLoanDAO ();

                //Before anything happens, lets verify the Id's match the given loan Id.
                if ((loan.Id != loanId) || (loan.Version != loanVersion))
                {
                    throw new ZiblerBusinessComponentsException (Resources.RecordNotFound);
                }

                /* Check that the loan has a valid amount */
                if (loan.LoanedAmount <= 0)
                {
                    throw new ZiblerBusinessComponentsException (
                        Resources.LoanRequestOperationsMsgInvalidLoanAmount);
                }

                //If it is an Administrator, they may choose to leave the Start Date Blank
                //so the system will determine the Start Date automatically, however, they
                //may still want to override the default parameters, that is why I check for
                //the Interest Rate Id. Interest Rate Id won't be reported if they have not
                //selected one.
                if (loan.StartDate == null && interestRateId == 0)
                {
                    FinancialInstitution financialInstitution
                    = financialInstitutionDAO.GetFinancialInstitutionByName (
                        financialInstitutionName);

                    //Look for the Loan Bracket.
                    if (!financialInstitution.LoanBrackets.IsEmpty)
                    {
                        //We need to know what was the last request from the client
                        //to whom the Loan Request belongs to.
                        //TODO: It may be a better idea to calculate the max amount
                        //		using the database, rather than retrieven the records and
                        //		performing the operation here.
                        Client client = loan.LoanRequest.Client;

                        decimal maxTotalAmount = 0m;

                        foreach (LoanRequest existingLoanRequest in client.LoanRequests)
                        {
                            /* Any loan request that has been approved is ok. The system allows
                            * them to register loan requests even if they have not fully
                            * paid the previous ones */
                            if (existingLoanRequest.LoanRequestStatus == LoanRequestStatus.Aprobada
                                || existingLoanRequest.LoanRequestStatus == LoanRequestStatus.Corriente
                                || existingLoanRequest.LoanRequestStatus == LoanRequestStatus.Vencida
                                || existingLoanRequest.LoanRequestStatus == LoanRequestStatus.ExtraJudicial
                                || existingLoanRequest.LoanRequestStatus == LoanRequestStatus.JudicialAltoRiesgo
                                || existingLoanRequest.LoanRequestStatus == LoanRequestStatus.Pagada)
                            {
                                decimal loanReqTotalAmount = 0.0m;
                                foreach (Loan existingLoan in existingLoanRequest.Loans)
                                {
                                    loanReqTotalAmount = loanReqTotalAmount +
                                                         existingLoan.LoanedAmount;
                                }

                                //If this is higher, then use it.
                                if (loanReqTotalAmount > maxTotalAmount)
                                    maxTotalAmount = loanReqTotalAmount;
                            }
                        }

                        //Order the loan brackets
                        IList<LoanBracket> orderLoanBrackets = new List<LoanBracket> ();

                        //Copy the list to a structure that will make it easier to work with.
                        foreach (LoanBracket existingLoanBracket in
                            financialInstitution.LoanBrackets)
                        {
                            orderLoanBrackets.Add (existingLoanBracket);
                        }

                        // TODO: Improve sorting algorithm
                        // Sorting: Bubble Sort
                        for (int i = orderLoanBrackets.Count - 1; i >= 0; i--)
                        {
                            for (int j = 1; j <= i; j++)
                            {
                                if (orderLoanBrackets[j - 1].MinimumAmount >
                                    orderLoanBrackets[j].MinimumAmount)
                                {
                                    LoanBracket temp = orderLoanBrackets[j - 1];
                                    orderLoanBrackets[j - 1] = orderLoanBrackets[j];
                                    orderLoanBrackets[j] = temp;
                                }
                            }
                        }

                        decimal maxAmountAllowed = 0;
                        decimal minAmountAllowed = 0;
                        LoanParameter loanParameterToUse = null;

                        //It is a new loan request, then use the lowest bracket
                        if (maxTotalAmount <= 0)
                        {
                            //Take the first loan bracket. I would not be here
                            //if there was not at least one bracket.
                            maxAmountAllowed = orderLoanBrackets[0].MaximumAmount;
                            minAmountAllowed = orderLoanBrackets[0].MinimumAmount;

                            foreach (LoanParameter loanParamInBracket in
                                orderLoanBrackets[0].LoanParameters)
                            {
                                if (loanParamInBracket.LoanType == loan.LoanType)
                                {
                                    loanParameterToUse = loanParamInBracket;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            bool bracketFound = false;

                            //Search for the appropriate bracket.
                            for (int i = 0; i < orderLoanBrackets.Count; i++)
                            {
                                decimal currentMaxAmnt = orderLoanBrackets[i].MaximumAmount;
                                decimal currentMinAmnt = orderLoanBrackets[i].MinimumAmount;

                                //If we have found the bracket for the maximum amount
                                //the user has ever borrowed, then we step up to the next
                                //bracket.
                                if (maxTotalAmount <= currentMaxAmnt &&
                                    maxTotalAmount >= currentMinAmnt)
                                {
                                    //indicate we have found a bracket for the max amount
                                    //ever borrowd
                                    bracketFound = true;

                                    //If there is another Loan Bracket
                                    if (i + 1 <= orderLoanBrackets.Count)
                                    {
                                        maxAmountAllowed = orderLoanBrackets[i + 1].MaximumAmount;
                                        minAmountAllowed = orderLoanBrackets[i + 1].MinimumAmount;

                                        foreach (LoanParameter loanParamInBracket in
                                            orderLoanBrackets[i + 1].LoanParameters)
                                        {
                                            if (loanParamInBracket.LoanType == loan.LoanType)
                                            {
                                                loanParameterToUse = loanParamInBracket;
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //If there are no more brackets
                                        //use this one.
                                        maxAmountAllowed = orderLoanBrackets[i].MaximumAmount;
                                        minAmountAllowed = orderLoanBrackets[i].MinimumAmount;
                                        foreach (LoanParameter loanParamInBracket in
                                            orderLoanBrackets[i].LoanParameters)
                                        {
                                            if (loanParamInBracket.LoanType == loan.LoanType)
                                            {
                                                loanParameterToUse = loanParamInBracket;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                            //If there are brackets registered in the system
                            //but we could not find one which would fit the maximum
                            //amount the client have ever requested then, we will simply
                            //use the first one. We will then leave it up to an
                            //administrator to change the loan amounts.
                            if (!bracketFound)
                            {
                                //Take the first loan bracket.
                                maxAmountAllowed = orderLoanBrackets[0].MaximumAmount;
                                minAmountAllowed = orderLoanBrackets[0].MinimumAmount;
                                foreach (LoanParameter loanParamInBracket in
                                    orderLoanBrackets[0].LoanParameters)
                                {
                                    if (loanParamInBracket.LoanType == loan.LoanType)
                                    {
                                        loanParameterToUse = loanParamInBracket;
                                        break;
                                    }
                                }
                            }
                        }

                        //Now that we have the data we will use for max/min amounts
                        //and parameters we have to run a check to make sure the user
                        //is within the min and max parameters.

                        decimal amntAlrdyRqsted = 0m;
                        foreach (Loan requestLoan in loan.LoanRequest.Loans)
                        {
                            //Only account for the loans that are not the same.
                            //other wise I will end up counting twice.
                            if (requestLoan.Id != loan.Id)
                                amntAlrdyRqsted = amntAlrdyRqsted + requestLoan.LoanedAmount;
                        }

                        decimal amntCheck = loan.LoanedAmount + amntAlrdyRqsted;

                        //if we are within boundaries
                        if (amntCheck <= maxAmountAllowed && amntCheck >= minAmountAllowed)
                        {
                            if (loanParameterToUse == null) //There no loan parameters setup for the loan bracket
                                throw new ZiblerBusinessComponentsException (
                                    Resources.LoanRequestOperationsMsgNoParameterExistsForLoanBracket);

                            //Setup the parameters for the loan.
                            loan.AmortizationTableType = loanParameterToUse.AmortizationTableType;
                            loan.GracePeriod = loanParameterToUse.GracePeriod;
                            loan.GrossEarningsMargin = loanParameterToUse.GrossEarningsMargin;
                            loan.NumberOfAmortizations = loanParameterToUse.NumberOfAmortizations;
                            loan.OverdueRateFactor = loanParameterToUse.OverdueRateFactor;
                            loan.OverdueRateAmount = loanParameterToUse.OverdueRateAmount;
                            loan.PaymentFrequency = loanParameterToUse.PaymentFrequency;

                            //Now get the interest rate
                            loan.InterestRate = loanParameterToUse.InterestRate;

                            /* Clear any previous commissions */
                            loan.ClearAllApplicableCommissions ();

                            //Get the applicable commissions
                            foreach (LoanCommission commissionToApply in
                                loanParameterToUse.LoanCommissions)
                            {
                                LoanApplicableCommission newCommission = new LoanApplicableCommission ();
                                newCommission.Amount = commissionToApply.Amount;
                                newCommission.Concept = commissionToApply.Concept;
                                newCommission.RateOverAmount = commissionToApply.RateOverAmount;
                                loan.AddLoanApplicableCommission (newCommission);
                            }
                        }
                        else
                        {
                            throw new ZiblerBusinessComponentsException (
                                String.Format (
                                    Resources.LoanRequestOperationsMsgAmountOutOfBoundariesForBracket,
                                    minAmountAllowed.ToString ("C"),
                                    maxAmountAllowed.ToString ("C")));
                        }
                    }
                    /* There are no brackets */
                    else
                    {
                        bool defaultParamFound = false;
                        //If the loan bracket was not found, look for the default parameters
                        foreach (LoanParameter existingParam in financialInstitution.LoanParameters)
                        {
                            //Look for the default parameter for this type of loan.
                            if (existingParam.IsDefault && existingParam.LoanType == loan.LoanType)
                            {
                                defaultParamFound = true;

                                loan.AmortizationTableType = existingParam.AmortizationTableType;
                                loan.GracePeriod = existingParam.GracePeriod;
                                loan.GrossEarningsMargin = existingParam.GrossEarningsMargin;
                                loan.NumberOfAmortizations = existingParam.NumberOfAmortizations;
                                loan.OverdueRateFactor = existingParam.OverdueRateFactor;
                                loan.OverdueRateAmount = existingParam.OverdueRateAmount;
                                loan.PaymentFrequency = existingParam.PaymentFrequency;

                                //Now get the interest rate
                                loan.InterestRate = existingParam.InterestRate;

                                /* Clear any applicable commissions */
                                loan.ClearAllApplicableCommissions ();

                                //Get the applicable commissions
                                foreach (LoanCommission commissionToApply in
                                    existingParam.LoanCommissions)
                                {
                                    LoanApplicableCommission newCommission = new LoanApplicableCommission ();
                                    newCommission.Amount = commissionToApply.Amount;
                                    newCommission.Concept = commissionToApply.Concept;
                                    newCommission.RateOverAmount = commissionToApply.RateOverAmount;
                                    loan.AddLoanApplicableCommission (newCommission);
                                }
                                break;
                            }
                        }

                        //There are no Default parameters
                        if (!defaultParamFound)
                        {
                            throw new ZiblerBusinessComponentsException (
                                Resources.LoanRequestOperationsMsgNoDefaultParameterExists);
                        }
                    }
                }
                /* Use the parameters entered by the user. */
                else
                {
                    InterestRate interestRate = interestRateDAO.FindById (interestRateId);

                    //No interest rate is available
                    if (interestRate == null)
                    {
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgNoInterestRateExists);
                    }

                    loan.InterestRate = interestRate;
                }

                //After we have updated the loan information we need to update
                //the Credit Line amounts.

                //To do that we need to get the loan old amount first, to verify
                //if there is a new amount that we need to update.
                decimal oldAmount = loanDAO.GetOldLoanAmount (loan.Id);

                //If the amounts are different, then we will go ahead
                //and update the Credit Line.
                if (oldAmount != loan.LoanedAmount)
                {
                    /* Update the loan request no matter what state it is. */
                    if (loan.LoanRequest.CreditLine != null)
                    {
                        CreditLine loanRequestCreditLine = loan.LoanRequest.CreditLine;

                        //First we verify the status of the credit line. Only
                        //active credit lines can be associated with LoanRequests
                        if (loanRequestCreditLine.CreditLineStatus ==
                            CreditLineStatus.Suspendida)
                        {
                            throw new ZiblerBusinessComponentsException (
                                Resources.CreditLineOperationsMsgCreditLineMustBeActiveForAssociation);
                        }

                        /* Determine what values in the credit line to update based on the
                        * status of the loan request */

                        if (loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.Capturada ||
                            loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.Condicionada ||
                            loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.EnCaptura ||
                            loan.LoanRequest.LoanRequestStatus ==
                            LoanRequestStatus.ExpedienteIntegrado)
                        {
                            //Restore credit line balance
                            loanRequestCreditLine.AmountInRequestedLoans = loanRequestCreditLine.AmountInRequestedLoans -
                                                                           oldAmount;
                            loanRequestCreditLine.AvailableAmount = loanRequestCreditLine.AvailableAmount +
                                                                    oldAmount;

                            //If there is not enough money in the credit line to associate
                            // we raise an exception indicating the problem.
                            if (loanRequestCreditLine.AvailableAmount < loan.LoanedAmount)
                            {
                                throw new ZiblerBusinessComponentsException (
                                    Resources.CreditLineOperationsMsgNotEnoughMoneyInCreditLine);
                            }

                            //Update credit line with new numbers.
                            loanRequestCreditLine.AmountInRequestedLoans = loanRequestCreditLine.AmountInRequestedLoans +
                                                                           loan.LoanedAmount;
                            loanRequestCreditLine.AvailableAmount = loanRequestCreditLine.AvailableAmount -
                                                                    loan.LoanedAmount;
                        }
                        else if (loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.Aprobada ||
                                 loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.Corriente ||
                                 loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.ExtraJudicial ||
                                 loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.JudicialAltoRiesgo ||
                                 loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.Vencida)
                        {
                            loanRequestCreditLine.AmountInAuthorizedLoans = loanRequestCreditLine.AmountInAuthorizedLoans -
                                                                            oldAmount;
                            loanRequestCreditLine.AvailableAmount = loanRequestCreditLine.AvailableAmount +
                                                                    oldAmount;

                            //If there is not enough money in the credit line to associate
                            // we raise an exception indicating the problem.
                            if (loanRequestCreditLine.AvailableAmount < loan.LoanedAmount)
                            {
                                throw new ZiblerBusinessComponentsException (
                                    Resources.CreditLineOperationsMsgNotEnoughMoneyInCreditLine);
                            }

                            loanRequestCreditLine.AmountInAuthorizedLoans = loanRequestCreditLine.AmountInAuthorizedLoans +
                                                                            loan.LoanedAmount;
                            loanRequestCreditLine.AvailableAmount = loanRequestCreditLine.AvailableAmount -
                                                                    loan.LoanedAmount;
                        }
                    }
                }
                /* Now lets update the payment schedule for the loan for those loans
                * that have been approved already */

                if (loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.Aprobada ||
                    loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.Corriente ||
                    loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.ExtraJudicial ||
                    loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.JudicialAltoRiesgo ||
                    loan.LoanRequest.LoanRequestStatus == LoanRequestStatus.Vencida)
                {
                    //TODO: Should I do this here, or when they print the pagare.
                    ZiblerFinanceUtilities util = new ZiblerFinanceUtilities ();
                    AmortizationFactory amrtztnFctry = new AmortizationFactory ();

                    if (loan.StartDate == null)
                        loan.StartDate = loan.LoanRequest.LoanAuthorizationDate;
                    else if (loan.StartDate != loan.LoanRequest.LoanAuthorizationDate)
                    {
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgLoanStartDateAndAuthorizationDateAreNotEqual);
                    }

                    /* After setting the checks and setting the start date, then calculate the end
                    * date */

                    /* Calculate the Last payment date for this loan */
                    DateTime endDate = util.GetPaymentNumberDate (
                        Convert.ToDateTime (loan.StartDate),
                        loan.NumberOfAmortizations,
                        loan.PaymentFrequency,
                        Country.Mexico);
                    loan.EndDate = endDate;

                    /* Calculate the payments for this loan, and save them to the database.
                    * This is to ease the report operations later */
                    Amortization amortization = amrtztnFctry.CreateAmortization (
                        loan.AmortizationTableType,
                        loan.LoanedAmount,
                        loan.NumberOfAmortizations,
                        loan.PaymentFrequency,
                        0,
                        loan.GracePeriod,
                        loan.StartDate.Value,
                        0);

                    //Calculate the amortization.
                    amortization.CalculateAmortizationTable ();

                    /* Add the payment dates */
                    util.AddAmortizationPaymentDates (amortization.AmortizationTable,
                                                      amortization.StartDate,
                                                      amortization.PaymentFrequency,
                                                      Country.Mexico);

                    /* Remove all payment schedules. This will guarantee that only
                    * the correct information will be stored in the database */
                    loan.RemoveAllPaymentSchedules ();

                    /* Add the Payment Schedule */
                    foreach (AmortizationEntry entry in amortization.AmortizationTable)
                    {
                        PaymentSchedule newSchedule = new PaymentSchedule ();
                        newSchedule.PaymentDate = entry.Date;
                        newSchedule.PaymentNumber = entry.Number;

                        loan.AddPaymentSchedule (newSchedule);
                    }
                }
            }
            /* If the exception was thrown here, just pass it up */
            catch (ZiblerBusinessComponentsException ex)
            {
                throw;
            }
            /* Catch any Data Layer or other exception and throw an unkown exception */
            catch (Exception ex)
            {
                ZiblerBusinessComponentsUnknownException exc
                = new ZiblerBusinessComponentsUnknownException (ex);

                /* Throw the new exception */
                throw exc;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Adds a new Loan to a loan request
        /// </summary>
        /// <param name="financialInstitutionName">financialInstitution</param>
        /// <param name="loanRequest">loanRequest</param>
        /// <param name="workingCapitalLoan">workingCapitalLoan</param>
        /// <param name="interestRateId">interestRateId</param>
        /// <remarks>This function won't change the balances in the Credit lines. This is because
        /// when a new loan is created, the Loan Request has not been completed. I will only update
        /// the amounts once the Loan Request has been completed or when they update a Loan Amount and the
        /// loan request is completed.</remarks>
        public void CreateNewLoanInLoanRequest(string financialInstitutionName, 
            LoanRequest loanRequest,
            Loan loan,
            int interestRateId)
        {
            try
            {
                IFinancialInstitutionDAO financialInstitutionDAO
                = _daoFactory.GetFinancialInstitutionDAO ();
                IInterestRateDAO interestRateDAO = _daoFactory.GetInterestRateDAO ();

                /* Check that the loan has a valid amount */
                if (loan.LoanedAmount <= 0)
                {
                    throw new ZiblerBusinessComponentsException (
                        Resources.LoanRequestOperationsMsgInvalidLoanAmount);
                }

                //First we determine if we need to use default values for the loan,
                //of if this values were provided. This values will only be provided
                //if the user has the authority to do so.

                //If it is an Administrator, they may choose to leave the Start Date Blank
                //so the system will determine the Start Date automatically, however, they
                //may still want to override the default parameters, that is why I check for
                //the Interest Rate Id. Interest Rate Id won't be reported if they have not
                //selected one.
                if (loan.StartDate == null && interestRateId == 0)
                {
                    FinancialInstitution financialInstitution
                    = financialInstitutionDAO.
                    GetFinancialInstitutionByName (financialInstitutionName);

                    //TODO: If enforce
                    //Look for the Loan Bracket.
                    if (!financialInstitution.LoanBrackets.IsEmpty)
                    {
                        //We need to know what was the last request from the client
                        //to whom the Loan Request belongs to.
                        //TODO: It may be a better idea to calculate the max amount
                        //		using the database, rather than retrieven the records and
                        //		performing the operation here.
                        Client client = loanRequest.Client;

                        decimal maxTotalAmount = 0m;

                        foreach (LoanRequest existingLoanRequest in client.LoanRequests)
                        {
                            //In theory all loan requests must be paid before they allow
                            //the client to get another loan. The system checks for this before
                            //allow them to register a new loan request, so technically I should
                            //only be looking for Pagada.
                            if ((existingLoanRequest.LoanRequestStatus == LoanRequestStatus.Aprobada)
                                || (existingLoanRequest.LoanRequestStatus
                                    == LoanRequestStatus.Corriente)
                                || (existingLoanRequest.LoanRequestStatus
                                    == LoanRequestStatus.Vencida)
                                || existingLoanRequest.LoanRequestStatus
                                   == LoanRequestStatus.ExtraJudicial
                                || existingLoanRequest.LoanRequestStatus
                                   == LoanRequestStatus.JudicialAltoRiesgo
                                || existingLoanRequest.LoanRequestStatus
                                   == LoanRequestStatus.Pagada)
                            {
                                decimal loanReqTotalAmount = 0.0m;
                                foreach (Loan existingLoan in existingLoanRequest.Loans)
                                {
                                    loanReqTotalAmount = loanReqTotalAmount +
                                                         existingLoan.LoanedAmount;
                                }

                                //If this is higher, then use it.
                                if (loanReqTotalAmount > maxTotalAmount)
                                    maxTotalAmount = loanReqTotalAmount;
                            }
                        }

                        //Order the loan brackets
                        IList<LoanBracket> orderLoanBrackets = new List<LoanBracket> ();

                        //Copy the list to a structure that will make it easier to work with.
                        foreach (LoanBracket existingLoanBracket in
                            financialInstitution.LoanBrackets)
                        {
                            orderLoanBrackets.Add (existingLoanBracket);
                        }

                        // Sorting: Bubble Sort
                        for (int i = orderLoanBrackets.Count - 1; i >= 0; i--)
                        {
                            for (int j = 1; j <= i; j++)
                            {
                                if (orderLoanBrackets[j - 1].MinimumAmount
                                    > orderLoanBrackets[j].MinimumAmount)
                                {
                                    LoanBracket temp = orderLoanBrackets[j - 1];
                                    orderLoanBrackets[j - 1] = orderLoanBrackets[j];
                                    orderLoanBrackets[j] = temp;
                                }
                            }
                        }

                        decimal maxAmountAllowed = 0;
                        decimal minAmountAllowed = 0;
                        LoanParameter loanParameterToUse = null;

                        //It is a new loan request, then use the lowest bracket
                        if (maxTotalAmount <= 0)
                        {
                            //Take the first loan bracket. I would not be here
                            //if there was not at least one bracket.
                            maxAmountAllowed = orderLoanBrackets[0].MaximumAmount;
                            minAmountAllowed = orderLoanBrackets[0].MinimumAmount;

                            foreach (LoanParameter loanParamInBracket
                                in orderLoanBrackets[0].LoanParameters)
                            {
                                if (loanParamInBracket.LoanType == loan.LoanType)
                                {
                                    loanParameterToUse = loanParamInBracket;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            bool bracketFound = false;

                            //Search for the appropriate bracket.
                            for (int i = 0; i < orderLoanBrackets.Count; i++)
                            {
                                decimal currentMaxAmnt = orderLoanBrackets[i].MaximumAmount;
                                decimal currentMinAmnt = orderLoanBrackets[i].MinimumAmount;

                                //If we have found the bracket for the maximum amount
                                //the user has ever borrowed, then we step up to the next
                                //bracket.
                                if (maxTotalAmount <= currentMaxAmnt
                                    && maxTotalAmount >= currentMinAmnt)
                                {
                                    //indicate we have found a bracket for the max amount
                                    //ever borrowd
                                    bracketFound = true;

                                    //If there is another Loan Bracket
                                    if (i + 1 <= orderLoanBrackets.Count)
                                    {
                                        maxAmountAllowed = orderLoanBrackets[i + 1].MaximumAmount;
                                        minAmountAllowed = orderLoanBrackets[i + 1].MinimumAmount;

                                        foreach (LoanParameter loanParamInBracket
                                            in orderLoanBrackets[i + 1].LoanParameters)
                                        {
                                            if (loanParamInBracket.LoanType == loan.LoanType)
                                            {
                                                loanParameterToUse = loanParamInBracket;
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //If there are no more brackets
                                        //use this one.
                                        maxAmountAllowed = orderLoanBrackets[i].MaximumAmount;
                                        minAmountAllowed = orderLoanBrackets[i].MinimumAmount;
                                        foreach (LoanParameter loanParamInBracket
                                            in orderLoanBrackets[i].LoanParameters)
                                        {
                                            if (loanParamInBracket.LoanType == loan.LoanType)
                                            {
                                                loanParameterToUse = loanParamInBracket;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                            //If there are brackets registered in the system
                            //but we could not find one which would fit the maximum
                            //amount the client have ever requested then, we will simply
                            //use the first one. We will then leave it up to an
                            //administrator to change the loan amounts.
                            if (!bracketFound)
                            {
                                //Take the first loan bracket.
                                maxAmountAllowed = orderLoanBrackets[0].MaximumAmount;
                                minAmountAllowed = orderLoanBrackets[0].MinimumAmount;
                                foreach (LoanParameter loanParamInBracket
                                    in orderLoanBrackets[0].LoanParameters)
                                {
                                    if (loanParamInBracket.LoanType == loan.LoanType)
                                    {
                                        loanParameterToUse = loanParamInBracket;
                                        break;
                                    }
                                }
                            }
                        }

                        //Now that we have the data we will use for max/min amounts
                        //and parameters we have to run a check to make sure the user
                        //is within the min and max parameters.

                        decimal amntAlrdyRqsted = 0m;
                        foreach (Loan requestLoan in loanRequest.Loans)
                        {
                            //Only account for the loans that are not the same.
                            //other wise I will end up counting twice.
                            if (requestLoan.Id != loan.Id)
                                amntAlrdyRqsted = amntAlrdyRqsted + requestLoan.LoanedAmount;
                        }

                        decimal amntCheck = loan.LoanedAmount + amntAlrdyRqsted;

                        //if we are within boundaries
                        if (amntCheck <= maxAmountAllowed && amntCheck >= minAmountAllowed)
                        {
                            //There no loan parameters setup for
                            //the loan bracket
                            if (loanParameterToUse == null)
                            {
                                throw new
                                ZiblerBusinessComponentsException (
                                    Resources.LoanRequestOperationsMsgNoParameterExistsForLoanBracket);
                            }

                            //Setup the parameters for the loan.
                            loan.AmortizationTableType = loanParameterToUse.AmortizationTableType;
                            loan.GracePeriod = loanParameterToUse.GracePeriod;
                            loan.GrossEarningsMargin = loanParameterToUse.GrossEarningsMargin;
                            loan.NumberOfAmortizations = loanParameterToUse.NumberOfAmortizations;
                            loan.OverdueRateFactor = loanParameterToUse.OverdueRateFactor;
                            loan.OverdueRateAmount = loanParameterToUse.OverdueRateAmount;
                            loan.PaymentFrequency = loanParameterToUse.PaymentFrequency;
                            loan.DelayedDays = 0;

                            //Now get the interest rate
                            loan.InterestRate = loanParameterToUse.InterestRate;

                            //Get the applicable commissions
                            foreach (LoanCommission commissionToApply
                                in loanParameterToUse.LoanCommissions)
                            {
                                LoanApplicableCommission newCommission = new LoanApplicableCommission ();
                                newCommission.Amount = commissionToApply.Amount;
                                newCommission.Concept = commissionToApply.Concept;
                                newCommission.RateOverAmount = commissionToApply.RateOverAmount;
                                loan.AddLoanApplicableCommission (newCommission);
                            }

                            //Now that we have set the loan properties, we will add it to the
                            //loan request.
                            loanRequest.AddLoan (loan);
                        }
                        else
                        {
                            throw new
                            ZiblerBusinessComponentsException (
                                String.Format (
                                    Resources.LoanRequestOperationsMsgAmountOutOfBoundariesForBracket,
                                    minAmountAllowed.ToString ("C"),
                                    maxAmountAllowed.ToString ("C")));
                        }
                    }
                    else
                    {
                        bool defaultParamFound = false;
                        //If the loan bracket was not found, look for the default parameters
                        foreach (LoanParameter existingParam in financialInstitution.LoanParameters)
                        {
                            //Look for the default parameter
                            if (existingParam.IsDefault && existingParam.LoanType == loan.LoanType)
                            {
                                defaultParamFound = true;

                                loan.AmortizationTableType = existingParam.AmortizationTableType;
                                loan.GracePeriod = existingParam.GracePeriod;
                                loan.GrossEarningsMargin = existingParam.GrossEarningsMargin;
                                loan.NumberOfAmortizations = existingParam.NumberOfAmortizations;
                                loan.OverdueRateFactor = existingParam.OverdueRateFactor;
                                loan.OverdueRateAmount = existingParam.OverdueRateAmount;
                                loan.PaymentFrequency = existingParam.PaymentFrequency;
                                loan.DelayedDays = 0;

                                //Now get the interest rate
                                loan.InterestRate = existingParam.InterestRate;

                                //Get the applicable commissions
                                foreach (LoanCommission commissionToApply
                                    in existingParam.LoanCommissions)
                                {
                                    LoanApplicableCommission newCommission
                                    = new LoanApplicableCommission ();
                                    newCommission.Amount = commissionToApply.Amount;
                                    newCommission.Concept = commissionToApply.Concept;
                                    newCommission.RateOverAmount = commissionToApply.RateOverAmount;
                                    loan.AddLoanApplicableCommission (newCommission);
                                }
                                break;
                            }
                        }

                        if (defaultParamFound)
                        {
                            loanRequest.AddLoan (loan);
                        }
                        //There are no Default parameters
                        else
                        {
                            throw new ZiblerBusinessComponentsException (
                                Resources.LoanRequestOperationsMsgNoDefaultParameterExists);
                        }
                    }
                }
                else
                {
                    //TODO: Add the loan applicable commissions
                    //If values have been provided then we simply take the loan
                    //and add it to the loan request.
                    InterestRate interestRate = interestRateDAO.FindById (interestRateId);
                    if (interestRate == null)
                    {
                        //No interest rate is available
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgNoInterestRateExists);
                    }

                    loan.InterestRate = interestRate;
                    loanRequest.AddLoan (loan);
                }
            }
            /* If the exception was thrown here, just pass it up */
            catch (ZiblerBusinessComponentsException ex)
            {
                throw;
            }
            /* Catch any Data Layer or other exception and throw an unkown exception */
            catch (Exception ex)
            {
                ZiblerBusinessComponentsUnknownException exc
                = new ZiblerBusinessComponentsUnknownException (ex);

                /* Throw the new exception */
                throw exc;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Adds a list of Loan commissions to a loan
        /// </summary>
        /// <param name="loanToUpdate">loanToUpdate</param>
        /// <param name="loanCommissions">loanCommissions</param>
        public void AddLoanApplicableCommissions(Loan loanToUpdate, IList<int> loanCommissions)
        {
            try
            {
                ILoanCommissionDAO loanCommissionDAO = _daoFactory.GetLoanCommissionDAO ();

                foreach (int loanCommissionId in loanCommissions)
                {
                    LoanCommission loanCommission = loanCommissionDAO.FindById (loanCommissionId);

                    if (loanCommission == null)
                    {
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanOperationsMsgLoanCommissionNotFound);
                    }
                    else
                    {
                        LoanApplicableCommission newCommission = new LoanApplicableCommission ();
                        newCommission.Amount = loanCommission.Amount;
                        newCommission.Concept = loanCommission.Concept;
                        newCommission.RateOverAmount = loanCommission.RateOverAmount;

                        //Make sure it does not have an existing commission
                        foreach (LoanApplicableCommission loanAppComm in
                            loanToUpdate.LoanApplicableCommissions)
                        {
                            if (loanAppComm.Concept == newCommission.Concept)
                            {
                                throw new ZiblerBusinessComponentsException (
                                    Resources.LoanOperationsMsgLoanCommissionExistsInLoan);
                            }
                        }

                        loanToUpdate.AddLoanApplicableCommission (newCommission);
                    }
                }
            }
            /* If the exception was thrown here, just pass it up */
            catch (ZiblerBusinessComponentsException ex)
            {
                throw;
            }
            /* Catch any Data Layer or other exception and throw an unkown exception */
            catch (Exception ex)
            {
                ZiblerBusinessComponentsUnknownException exc
                = new ZiblerBusinessComponentsUnknownException (ex);

                /* Throw the new exception */
                throw exc;
            }
        }