コード例 #1
0
ファイル: FinancialAnalysis.cs プロジェクト: zibler/zibler
        public FinancialAnalysis(LoanRequest loanRequest, VAT vat)
        {
            //The loan Request contains all the necessary data
            //to calculate a Financial Analysis.
            _loanRequest = loanRequest;
            _financeUtil = new ZiblerFinanceUtilities ();

            //Establish what loans are present
            foreach (Loan existingLoan in _loanRequest.Loans)
            {
                if (existingLoan.LoanType == LoanType.CapitalDeTrabajo)
                {
                    _wrkngCptlAmrtztn = CreateAmortizationTable (existingLoan, vat);
                    _wrkngCptlLoan = existingLoan;
                    _financeUtil.AddAmortizationPaymentDates (_wrkngCptlAmrtztn.AmortizationTable,
                                                              _wrkngCptlAmrtztn.StartDate,
                                                              _wrkngCptlAmrtztn.PaymentFrequency,
                                                              Country.Mexico);
                }
                if (existingLoan.LoanType == LoanType.Refaccionario)
                {
                    _fxdAsstAmrtztn = CreateAmortizationTable (existingLoan, vat);
                    _fxdAsstLoan = existingLoan;
                    _financeUtil.AddAmortizationPaymentDates (_fxdAsstAmrtztn.AmortizationTable,
                                                              _fxdAsstAmrtztn.StartDate,
                                                              _fxdAsstAmrtztn.PaymentFrequency,
                                                              Country.Mexico);
                }
            }
        }
コード例 #2
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;
            }
        }
コード例 #3
0
        /// <summary>
        /// Updates the information in the Loan Request
        /// </summary>
        /// <param name="loanRequest">Loan Request to update</param>
        /// <param name="financialInstitutionName">Financial institution</param>
        /// <remarks>
        /// IT IS ABSOLUTLY NECESSARY THAT AFTER A LOAN REQUEST HAS BEEN CANCELLED,
        /// REJECTED OR PAID, THEN THE SYSTEM WON'T ALLOW THEM TO UPDATE ANY DATA ON
        /// THE REQUEST. IN FACT THIS FUNCTION SHOULD NOT BE CALLED EVER AGAIN
        /// ON THE REQUEST, OTHERWISE THE CREDIT LINE AMOUNTS WILL NOT BE ACCURATE</remarks>        
        public void UpdateLoanRequestInformation(string financialInstitutionName,
            LoanRequest loanRequest)
        {
            try
            {
                ICreditLineDAO creditLineDAO = _daoFactory.GetCreditLineDAO ();
                ILoanRequestDAO loanRequestDAO = _daoFactory.GetLoanRequestDAO ();
                IDepreciationForecastParametersDAO depreciationForecastParametersDAO = _daoFactory.GetDepreciationForecastParametersDAO ();
                IFinancialForecastParametersDAO financialForecastParametersDAO = _daoFactory.GetFinancialForecastParametersDAO ();
                IProjectFeasibilityParametersDAO projectFeasibilityParametersDAO = _daoFactory.GetProjectFeasibilityParametersDAO ();

                string oldTrackingCode = loanRequestDAO.GetOldTrackingCode (loanRequest.Id);

                //If the Request status has been changed to Aprobada
                LoanRequestStatus previousLoanRequestState = loanRequestDAO.GetLoanRequestOldStatus (
                    loanRequest.Id);

                /* Check the tracking code entered by the financial institution */
                if (loanRequest.TrackingCode != null)
                {
                    if (oldTrackingCode != loanRequest.TrackingCode)
                    {
                        //HACK: NOTE THAT I USE THE CLIENT OPERATIONS MESSAGE FOR THIS CHECK
                        if (loanRequestDAO.TrackingCodeExists (financialInstitutionName,
                                                               loanRequest.TrackingCode.Trim ()))
                        {
                            throw new ZiblerBusinessComponentsException (
                                Resources.ClientOperationsMsgLoanRequestTrackingCodeExists);
                        }
                    }
                }

                /* They have entered an authorization date, however the
                * loan request is not approved yet */
                if (loanRequest.LoanRequestStatus != LoanRequestStatus.Aprobada
                    && loanRequest.LoanRequestStatus != LoanRequestStatus.Corriente
                    && loanRequest.LoanRequestStatus != LoanRequestStatus.Vencida
                    && loanRequest.LoanRequestStatus != LoanRequestStatus.ExtraJudicial
                    && loanRequest.LoanRequestStatus != LoanRequestStatus.JudicialAltoRiesgo
                    && loanRequest.LoanRequestStatus != LoanRequestStatus.Pagada
                    && loanRequest.LoanRequestStatus != LoanRequestStatus.Cancelada)
                {
                    if (loanRequest.LoanAuthorizationDate != null)
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgLoanRequestHasAuthDateButNoApproved);
                }

                /* Indicates if the authorization date has changed */
                bool authDateChanged = false;

                /* They marked the loan request approved or a status passed approved
                * so check and make sure they have entered an authorization date.*/
                if (loanRequest.LoanRequestStatus == LoanRequestStatus.Aprobada ||
                    loanRequest.LoanRequestStatus == LoanRequestStatus.Corriente ||
                    loanRequest.LoanRequestStatus == LoanRequestStatus.ExtraJudicial ||
                    loanRequest.LoanRequestStatus == LoanRequestStatus.JudicialAltoRiesgo ||
                    loanRequest.LoanRequestStatus == LoanRequestStatus.Vencida)
                {
                    if (loanRequest.LoanAuthorizationDate == null)
                    {
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgNoAuthorizationDateProvided);
                    }
                    else
                    {
                        /* Get the old authorization date. We will use this to determine whether
                        * or not they changed it */
                        DateTime? oldAuthDate = loanRequestDAO.GetLoanRequestOldAuthorizationDate (
                            loanRequest.Id);

                        if (oldAuthDate != loanRequest.LoanAuthorizationDate)
                        {
                            authDateChanged = true;
                        }
                    }
                }

                /* Get the old amount */
                decimal oldAmount = loanRequestDAO.GetLoanRequestOldTotalAmount (
                    loanRequest.Id);

                //Get the analysis parameters regardless if the loan request had them already
                //this is because they could have changed fron when the request was initialy
                //registered
                if (loanRequest.LoanRequestStatus == LoanRequestStatus.Aprobada
                    || loanRequest.LoanRequestStatus == LoanRequestStatus.Capturada
                    || loanRequest.LoanRequestStatus == LoanRequestStatus.ExpedienteIntegrado
                    || loanRequest.LoanRequestStatus == LoanRequestStatus.Condicionada)
                {
                    /* Get all the parameters for a financial institution */
                    //TODO: I don't expect anybody to have thousands of parameters
                    //		thus we can get them all.
                    IList<DepreciationForecastParameters> depForecastParams
                    = depreciationForecastParametersDAO.GetAllDepreciationForecasetParameters (
                        financialInstitutionName);

                    /* Make sure they have registered the parameters */
                    if (depForecastParams.Count <= 0)
                    {
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgDepreciationForecastParamsMissing);
                    }

                    DepreciationForecastParameters depParamToAssociate = null;

                    //Look for the parameter that is applicable so we can associate it
                    //to our loan request.
                    foreach (DepreciationForecastParameters depForecastParam in
                        depForecastParams)
                    {
                        DateTime paramDate = Convert.ToDateTime (depForecastParam.ValidFrom);

                        //There is a posiblity that they have not assigned an Authorization date.
                        //in that case we use todays date.
                        DateTime? loanReqDate = null;
                        if (loanRequest.LoanAuthorizationDate == null)
                            loanReqDate = DateTime.Now;
                        else
                            loanReqDate = Convert.ToDateTime (loanRequest.LoanAuthorizationDate);

                        if (DateUtilities.IsFirstDateGreaterOrEqualThanSecondDate (
                            Convert.ToDateTime (loanReqDate),
                            paramDate))
                        {
                            //The Current Parameter Date could apply to this loan Request.
                            //Before we take it, we verify if we already have another date
                            //in our paramToAssociate
                            if (depParamToAssociate != null)
                            {
                                DateTime previousDate = Convert.ToDateTime (
                                    depParamToAssociate.ValidFrom);

                                if (DateUtilities.IsFirstDateGreaterOrEqualThanSecondDate (
                                    paramDate,
                                    previousDate))
                                {
                                    //Take the new param
                                    depParamToAssociate = depForecastParam;
                                }
                            }
                            else
                            {
                                depParamToAssociate = depForecastParam;
                            }
                        }
                    }

                    /* We could not find a parameter to associate */
                    if (depParamToAssociate == null)
                    {
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgDepreciationForecastParamsWrongDate);
                    }

                    loanRequest.DepreciationForecastParameters = depParamToAssociate;

                    //TODO: I don't expect anybody to have thousands of parameters
                    //		thus we can get them all.
                    IList<FinancialForecastParameters> finForecastParams
                    = financialForecastParametersDAO.GetAllFinancialForecasetParameters (
                        financialInstitutionName);

                    /* Make sure they have registered the parameters */
                    if (finForecastParams.Count <= 0)
                    {
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgFinancialForecastParamsMissing);
                    }

                    FinancialForecastParameters finForeParamToAssociate = null;

                    //Look for the parameter that is applicable so we can associate it
                    //to our loan request.
                    foreach (FinancialForecastParameters finForecastParam in finForecastParams)
                    {
                        DateTime paramDate = Convert.ToDateTime (finForecastParam.ValidFrom);

                        //There is a posiblity that they have not assigned an Authorization date.
                        //in that case we use todays date.
                        DateTime? loanReqDate = null;
                        if (loanRequest.LoanAuthorizationDate == null)
                            loanReqDate = DateTime.Now;
                        else
                            loanReqDate = Convert.ToDateTime (loanRequest.LoanAuthorizationDate);

                        if (DateUtilities.IsFirstDateGreaterOrEqualThanSecondDate (
                            Convert.ToDateTime (loanReqDate),
                            paramDate))
                        {
                            //The Current Parameter Date could apply to this loan Request.
                            //Before we take it, we verify if we already have another date
                            //in our paramToAssociate
                            if (finForeParamToAssociate != null)
                            {
                                DateTime previousDate = Convert.ToDateTime (
                                    finForeParamToAssociate.ValidFrom);

                                if (DateUtilities.IsFirstDateGreaterOrEqualThanSecondDate (
                                    paramDate,
                                    previousDate))
                                {
                                    //Take the new param
                                    finForeParamToAssociate = finForecastParam;
                                }
                            }
                            else
                            {
                                finForeParamToAssociate = finForecastParam;
                            }
                        }
                    }

                    /* We could not find a parameter to associate */
                    if (finForeParamToAssociate == null)
                    {
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgFinancialForecastParamsWrongDate);
                    }

                    loanRequest.FinancialForecastParameters = finForeParamToAssociate;

                    //TODO: I don't expect anybody to have thousands of parameters
                    //		thus we can get them all.
                    IList<ProjectFeasibilityParameters> projFeasibilityParams
                    = projectFeasibilityParametersDAO.GetAllProjectFeasibilityParameters (
                        financialInstitutionName);

                    /* Make sure they have registered the parameters */
                    if (projFeasibilityParams.Count <= 0)
                    {
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgProjectFeasibilityParamsMissing);
                    }

                    ProjectFeasibilityParameters projFeasParamToAssociate = null;

                    //Look for the parameter that is applicable so we can associate it
                    //to our loan request.
                    foreach (ProjectFeasibilityParameters projFeasParam in projFeasibilityParams)
                    {
                        DateTime paramDate = Convert.ToDateTime (projFeasParam.ValidFrom);

                        //There is a posiblity that they have not assigned an Authorization date.
                        //in that case we use todays date.
                        DateTime? loanReqDate = null;
                        if (loanRequest.LoanAuthorizationDate == null)
                            loanReqDate = DateTime.Now;
                        else
                            loanReqDate = Convert.ToDateTime (loanRequest.LoanAuthorizationDate);

                        if (DateUtilities.IsFirstDateGreaterOrEqualThanSecondDate (
                            Convert.ToDateTime (loanReqDate),
                            paramDate))
                        {
                            //The Current Parameter Date could apply to this loan Request.
                            //Before we take it, we verify if we already have another date
                            //in our paramToAssociate
                            if (projFeasParamToAssociate != null)
                            {
                                DateTime previousDate = Convert.ToDateTime (
                                    projFeasParamToAssociate.ValidFrom);

                                if (DateUtilities.IsFirstDateGreaterOrEqualThanSecondDate (
                                    paramDate,
                                    previousDate))
                                {
                                    //Take the new param
                                    projFeasParamToAssociate = projFeasParam;
                                }
                            }
                            else
                            {
                                projFeasParamToAssociate = projFeasParam;
                            }
                        }
                    }

                    /* We could not find a parameter to associate */
                    if (projFeasParamToAssociate == null)
                    {
                        throw new ZiblerBusinessComponentsException (
                            Resources.LoanRequestOperationsMsgProjectFeasibilityParamsWrongDate);
                    }

                    loanRequest.ProjectFeasibilityParameters = projFeasParamToAssociate;

                    /* Assign a credit line only if we have not done it before.
                    * This is to avoid wrong balances in the credit line.
                    * If the credit line has been assigned before, then we won't do anything
                    * it will be up to the Administrator to change it if they need to.
                    *
                    * Note also that this method is called whenever the loan request is fully
                    * captured in the system. This menas that the credit line balances
                    * will be automatically updated whenever the loan request is first
                    * captured. After this point, if the loan request status is changed
                    * the credit line will also be updated.
                    * */

                    //Get the default credit line and associate the Request
                    //to the Credit line.

                    //TODO: The following code is identical to the code contained in the
                    //		CreditLineOperations function:
                    //		public void AddLoanRequestsToCreditLine(CreditLine creditLineToUpdate,
                    //														IList<int> loanRequestIds)

                    /*
                    * The following rules are followed to determine how to calculate the amounts for the
                    * credit line.
                    *
                    * If the Loan Request status is any of the following:
                    *
                    * -Cancelada
                    * -Rechazada
                    * -Pagada
                    * -EnCaptura
                    *
                    * Then no update will be made to the balances in the Credit line. The update to the balance
                    * will be performed when the LoanRequest status is changed to any of these. So we can
                    * safely assume that if a loan request status is any of the above mention, it means that
                    * the balance to its credit line has been updated.
                    *
                    * if the loan Request status is any of the following:
                    *
                    * -Capturada
                    * -Expediente Integrado
                    * -Condicionada
                    *
                    * then the total amount in loans will be added to the AmountInRequestedLoans
                    * and substracted from the available amount.
                    *
                    * if the request status is any of the following:
                    *
                    * -Aprobada
                    * -Corriente
                    * -Vencida
                    * -ExtraJudicial
                    * -Judicial de Alto Riesgo
                    *
                    * then the total amount in loans will be added to the AmountInApprovedLoans
                    * and substracted from the available amount
                    *
                    * */

                    CreditLine defaultCreditLine = creditLineDAO.GetDefaultCreditLine (
                        financialInstitutionName);

                    //Now lets add the amounts from all the associated loans to this loanRequest
                    decimal totalLoans = 0.0m;

                    foreach (Loan loan in loanRequest.Loans)
                    {
                        totalLoans = totalLoans + loan.LoanedAmount;
                    }

                    if (loanRequest.LoanRequestStatus == LoanRequestStatus.Capturada
                        || loanRequest.LoanRequestStatus == LoanRequestStatus.ExpedienteIntegrado
                        || loanRequest.LoanRequestStatus == LoanRequestStatus.Condicionada)
                    {
                        /* If we have not previously assigned the Credit Line and the
                        * default credit line exists then we go ahead and assign the
                        * credit line and update balances.
                        * Update the credit line status */
                        if (loanRequest.CreditLine == null && defaultCreditLine != null)
                        {
                            //If there is not enough money in the credit line to associate
                            //the loan request then we raise an exception indicating the problem.
                            if (defaultCreditLine.AvailableAmount < totalLoans)
                                throw new ZiblerBusinessComponentsException (
                                    Resources.CreditLineOperationsMsgNotEnoughMoneyInCreditLine);
                            else //Otherwise
                            {
                                //Add the totalLoans amount to the Amount In Authorized Loans
                                defaultCreditLine.AmountInRequestedLoans = defaultCreditLine.AmountInRequestedLoans +
                                                                           totalLoans;
                                defaultCreditLine.AvailableAmount = defaultCreditLine.AvailableAmount -
                                                                    totalLoans;

                                //Associate the Credit Line to the LoanRequest
                                loanRequest.CreditLine = defaultCreditLine;
                            }
                        }
                        else
                        {
                            /* DO NOTHING:
                            * If either the credit line is not null or the
                            * defulat credit line is null, then there is no
                            * need to update the credit line, as it either does not exist
                            * because they have not registered it or they did not buy
                            * that part of the system, or it was assigned before
                            * which means the values have been updated.
                            */
                        }
                    }
                    /* If the loan request has been approved, then we need to update the
                    * credit line mounts in case they updated the amounts in the loans */
                    else if (loanRequest.LoanRequestStatus == LoanRequestStatus.Aprobada ||
                             loanRequest.LoanRequestStatus == LoanRequestStatus.Corriente ||
                             loanRequest.LoanRequestStatus == LoanRequestStatus.ExtraJudicial ||
                             loanRequest.LoanRequestStatus == LoanRequestStatus.JudicialAltoRiesgo ||
                             loanRequest.LoanRequestStatus == LoanRequestStatus.Vencida)
                    {
                        /* At this point a credit line should have been assigned
                        * to the loan request, so only perform the update if
                        * the credit line was assigned to it */
                        if (loanRequest.CreditLine != null)
                        {
                            decimal totalAmount = 0.00m;
                            foreach (Loan existingLoan in loanRequest.Loans)
                            {
                                totalAmount = totalAmount + existingLoan.LoanedAmount;
                            }

                            /* They have just approved the loan request */
                            if (loanRequest.LoanRequestStatus == LoanRequestStatus.Aprobada &&
                                previousLoanRequestState != loanRequest.LoanRequestStatus)
                            {
                                /* Update the credit line amounts */
                                loanRequest.CreditLine.AmountInRequestedLoans = loanRequest.CreditLine.AmountInRequestedLoans -
                                                                                oldAmount;

                                loanRequest.CreditLine.AvailableAmount = loanRequest.CreditLine.AvailableAmount +
                                                                         oldAmount;

                                /* Make sure there is enough money */
                                if (loanRequest.CreditLine.AvailableAmount < totalAmount)
                                {
                                    throw new ZiblerBusinessComponentsException (
                                        Resources.CreditLineOperationsMsgNotEnoughMoneyInCreditLine);
                                }

                                loanRequest.CreditLine.AmountInAuthorizedLoans = loanRequest.CreditLine.AmountInAuthorizedLoans +
                                                                                 totalAmount;

                                loanRequest.CreditLine.AvailableAmount = loanRequest.CreditLine.AvailableAmount -
                                                                         totalAmount;
                            }
                            /* The loan request has been approved already, we are just updating
                            * it after it has been approved */
                            else
                            {
                                /* Update the credit line amounts */
                                loanRequest.CreditLine.AmountInAuthorizedLoans = loanRequest.CreditLine.AmountInAuthorizedLoans -
                                                                                 oldAmount;

                                loanRequest.CreditLine.AvailableAmount = loanRequest.CreditLine.AvailableAmount +
                                                                         oldAmount;

                                /* Make sure there is enough money */
                                if (loanRequest.CreditLine.AvailableAmount < totalAmount)
                                {
                                    throw new ZiblerBusinessComponentsException (
                                        Resources.CreditLineOperationsMsgNotEnoughMoneyInCreditLine);
                                }

                                loanRequest.CreditLine.AmountInAuthorizedLoans = loanRequest.CreditLine.AmountInAuthorizedLoans +
                                                                                 totalAmount;

                                loanRequest.CreditLine.AvailableAmount = loanRequest.CreditLine.AvailableAmount -
                                                                         totalAmount;
                            }
                        }
                    }
                }

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

                    //Finally we need to verify if a Start Date has been provided for the Loans
                    //If it has, then we won't do anything, otherwise we will verify
                    //if the loan is approved
                    foreach (Loan existingLoan in loanRequest.Loans)
                    {
                        /* Make the loan start date, the same as the authorization date */
                        existingLoan.StartDate = loanRequest.LoanAuthorizationDate;

                        /* 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 (existingLoan.StartDate),
                            existingLoan.NumberOfAmortizations,
                            existingLoan.PaymentFrequency,
                            Country.Mexico);
                        existingLoan.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 (
                            existingLoan.AmortizationTableType,
                            existingLoan.LoanedAmount,
                            existingLoan.NumberOfAmortizations,
                            existingLoan.PaymentFrequency,
                            0,
                            existingLoan.GracePeriod,
                            existingLoan.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 */
                        existingLoan.RemoveAllPaymentSchedules ();

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

                            existingLoan.AddPaymentSchedule (newSchedule);
                        }
                    }
                }

                //If the loan request is in any of these final states, we have to make sure
                //we update the available amounts in the credit line associated to this loan request.

                /*
                * IT IS ABSOLUTLY NECESSARY THAT AFTER A LOAN REQUEST HAS BEEN CANCELLED,
                * REJECTED OR PAID, THEN THE SYSTEM WON'T ALLOW THEM TO UPDATE ANY DATA ON
                * THE REQUEST. IN FACT THIS FUNCTION SHOULD NOT BE CALLED EVER AGAIN
                * ON THE REQUEST, OTHERWISE THE CREDIT LINE AMOUNTS WILL NOT BE ACCURATE
                * */

                //TODO: Again this could cause problems if there were no Credit Lines previously
                //registered.
                if (loanRequest.LoanRequestStatus == LoanRequestStatus.Cancelada
                    || loanRequest.LoanRequestStatus == LoanRequestStatus.Rechazada
                    || loanRequest.LoanRequestStatus == LoanRequestStatus.Pagada)
                {
                    if (loanRequest.CreditLine != null)
                    {
                        decimal totalAmountInLoans = 0.0m;
                        foreach (Loan loan in loanRequest.Loans)
                        {
                            totalAmountInLoans = totalAmountInLoans + loan.LoanedAmount;
                        }

                        //Now that we know how much we have borrowed. Lets update the Creditline
                        //amounts.
                        if (loanRequest.LoanRequestStatus == LoanRequestStatus.Pagada)
                        {
                            loanRequest.CreditLine.AmountInAuthorizedLoans
                            = loanRequest.CreditLine.AmountInAuthorizedLoans - oldAmount;
                            loanRequest.CreditLine.AvailableAmount = loanRequest.CreditLine.AvailableAmount +
                                                                     oldAmount;
                        }
                        else if (loanRequest.LoanRequestStatus == LoanRequestStatus.Rechazada)
                        {
                            loanRequest.CreditLine.AmountInRequestedLoans = loanRequest.CreditLine.AmountInRequestedLoans -
                                                                            oldAmount;
                            loanRequest.CreditLine.AvailableAmount = loanRequest.CreditLine.AvailableAmount +
                                                                     oldAmount;
                        }
                        else if (loanRequest.LoanRequestStatus == LoanRequestStatus.Cancelada
                                 && (previousLoanRequestState == LoanRequestStatus.Aprobada
                                     || previousLoanRequestState == LoanRequestStatus.Corriente
                                     || previousLoanRequestState == LoanRequestStatus.Vencida
                                     || previousLoanRequestState == LoanRequestStatus.ExtraJudicial
                                     ||
                                     previousLoanRequestState ==
                                     LoanRequestStatus.JudicialAltoRiesgo))
                        {
                            loanRequest.CreditLine.AmountInAuthorizedLoans
                            = loanRequest.CreditLine.AmountInAuthorizedLoans - oldAmount;
                            loanRequest.CreditLine.AvailableAmount = loanRequest.CreditLine.AvailableAmount +
                                                                     oldAmount;
                        }
                        else if (loanRequest.LoanRequestStatus == LoanRequestStatus.Cancelada
                                 && (previousLoanRequestState == LoanRequestStatus.Capturada
                                     || previousLoanRequestState == LoanRequestStatus.Condicionada
                                     ||
                                     previousLoanRequestState ==
                                     LoanRequestStatus.ExpedienteIntegrado))
                        {
                            loanRequest.CreditLine.AmountInRequestedLoans = loanRequest.CreditLine.AmountInRequestedLoans -
                                                                            oldAmount;
                            loanRequest.CreditLine.AvailableAmount = loanRequest.CreditLine.AvailableAmount +
                                                                     oldAmount;
                        }
                    }

                    //If they just rejected the loan request, then we will go ahead
                    //and update the rejection date
                    if (loanRequest.LoanRequestStatus == LoanRequestStatus.Rechazada
                        && previousLoanRequestState != LoanRequestStatus.Rechazada)
                    {
                        //If the date has not been provided then we use todays date.
                        if (loanRequest.LoanRejectionDate == null)
                            loanRequest.LoanRejectionDate = DateTime.Today;
                    }

                    //If they just cancelled the loan request, then we will go ahead
                    //and update the cancelled date
                    if (loanRequest.LoanRequestStatus == LoanRequestStatus.Cancelada
                        && previousLoanRequestState != LoanRequestStatus.Cancelada)
                    {
                        if (loanRequest.LoanCancelledDate == null)
                            loanRequest.LoanCancelledDate = DateTime.Today;
                    }
                }
            }
            /* 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;
            }
        }