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); } } }
/// <summary> /// Creates a new Loan Request Transaction Log Entry /// </summary> /// <param name="loanRequest">loanRequest</param> /// <param name="transactionLog">transactionLog entry</param> public void CreateNewLoanRequestTransactionLogEntry(LoanRequest loanRequest, TransactionLogEntry transactionLog) { try { //Verify we are in a valid state 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) { throw new ZiblerBusinessComponentsException ( Resources.LoanRequestOperationsMsgCannotAddTransactionLogEntry); } /* Not that this will actually get all entries in the database for the Entry Logs */ loanRequest.AddTransactionLogEntry (transactionLog); } /* 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; } }
/// <summary> /// Creates a new Loan Request Evaluations /// </summary> /// <param name="loanRequest">loanRequest</param> /// <param name="evaluations">evaluations</param> public void CreateNewLoanRequestEvaluations(LoanRequest loanRequest, string[,] evaluations) { try { //Clear the existing evaluations loanRequest.LoanRequestEvaluations.Clear (); for (int i = 0; i < evaluations.GetLength (0); i++) { ZiblerBusinessObjects.Loans.LoanRequestEvaluation newEvaluation = new LoanRequestEvaluation (); newEvaluation.Concept = evaluations[i,0]; newEvaluation.Complies = Convert.ToBoolean (evaluations[i,1]); //Add the evaluation loanRequest.AddLoanRequestEvaluation (newEvaluation); } if (loanRequest.MiscLoanRequestInformation.CreditReportRating == "-Seleccione una opción-") { throw new ZiblerBusinessComponentsException ( Resources.LoanRequestOperationsMsgNoCreditScoreSelected); } //Since the status was updated, then we call this function to make sure //all the other data is ok. UpdateLoanRequestInformation (loanRequest.Client.FinancialInstitution.Name, loanRequest); } /* 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; } }
/// <summary> /// Adds a new Collateral to the Loan Request /// </summary> /// <param name="loanRequest">loanRequest</param> /// <param name="collateral">collateral</param> public void CreateNewLoanRequestCollateral(LoanRequest loanRequest, Collateral collateral) { try { //If the loan request is not editable, then don't give them the option //to delete any data from it. if (loanRequest.LoanRequestStatus != LoanRequestStatus.Condicionada && loanRequest.LoanRequestStatus != LoanRequestStatus.Capturada && loanRequest.LoanRequestStatus != LoanRequestStatus.ExpedienteIntegrado) { throw new ZiblerBusinessComponentsException ( Resources.LoanRequestOperationsMsgCannotAddCollateral); } //Add the collateral if no exceptions were thrown loanRequest.AddCollateral (collateral); } /* 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; } }
/// <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; } }
/// <summary> /// Creates a new Financial Information /// </summary> /// <param name="financialInstitution">financialInstitution</param> /// <param name="loanRequest">loanRequest</param> /// <param name="financialInformation">financialInformation</param> public void CreateNewFinancialInfoInLoanRequest(string financialInstitution, LoanRequest loanRequest, FinancialInformation financialInformation) { try { loanRequest.FinancialInformation = financialInformation; } /* 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; } }
/// <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; } }
/// <summary> /// Sets the Loan request status based on the number of days this /// loan is delayed. /// </summary> /// <param name="loanRequest">LoanRequest to update</param> /// <param name="loan">Loan to be used for the update</param> /// <param name="stmntDate">Date to use to calculate the statement</param> /// <param name="vats">List of applicable VATS</param> /// <param name="intValues">List of applicable Interest Rate valus</param> /// <param name="nrmlzdDate">Normalized date used to set the next status update date.</param> /// <param name="firstPass">Is this the first time this function is called for the loans of a loan request?</param> public void SetLoanRequestStatus(LoanRequest loanRequest, Loan loan, DateTime stmntDate, IList<VAT> vats, IList<InterestRateValue> intValues, DateTime nrmlzdDate, bool firstPass) { try { DateTime nextUpdtDate = nrmlzdDate; /* Calculate the statement to today's day */ LoanStatement stmnt = new LoanStatement (loan, stmntDate, vats, intValues, false); /* Calculate the statement and determine how many days * behind is the loan. */ stmnt.GenerateStatement (); int delayedDays = stmnt.DelayedDays; /* Update the loan statement values stored in the DB */ loan.DelinquentVAT = stmnt.DelinquentVAT; loan.MoratoryInterests = stmnt.MoratoryInterests; loan.DelinquentInterests = stmnt.DelinquentInterests; loan.DelinquentPrincipal = stmnt.DelinquentPrincipal; loan.DelinquentBalance = stmnt.DelinquentBalance; loan.CurrentPrincipal = stmnt.CurrentPrincipal; loan.CurrentInterests = stmnt.CurrentInterests; loan.CurrentVAT = stmnt.CurrentVAT; loan.CurrentCommissions = stmnt.CurrentCommissions; loan.PaymentBalance = stmnt.PaymentBalance; loan.CurrentBalance = stmnt.CurrentBalance; loan.DelayedDays = delayedDays; /* Set the Loan Request Status accordingly. * * Corriente - No Delays * Vencida - Delayed 1 to 3 days (including day 3) * ExtraJudicial - Delayed 4 to 89 days * JudicialAltoRiesgo - Delayed 90 or more * */ if (delayedDays == 0) /* Corriente */ { /* If this is the first loan, set the loan request status */ if (firstPass) { /* Get the next payment date from the day * we calculated this update */ nextUpdtDate = nrmlzdDate; nextUpdtDate = stmnt.GetNextPayment (nrmlzdDate); /* Check one day after the next payment */ nextUpdtDate = nextUpdtDate.AddDays (1); loanRequest.LoanRequestStatus = LoanRequestStatus.Corriente; loanRequest.ContinueStatusUpdates = true; loanRequest.NextStatusUpdate = nextUpdtDate; } else { /* Corriente status takes presedence as long as this is not the first * pass and the following condition is TRUE */ if (loanRequest.LoanRequestStatus != LoanRequestStatus.Vencida && loanRequest.LoanRequestStatus != LoanRequestStatus.ExtraJudicial && loanRequest.LoanRequestStatus != LoanRequestStatus.JudicialAltoRiesgo) { /* Get the next payment date from the day * we calculated this update */ nextUpdtDate = nrmlzdDate; nextUpdtDate = stmnt.GetNextPayment (nrmlzdDate); /* Check one day after the next payment */ nextUpdtDate = nextUpdtDate.AddDays (1); loanRequest.LoanRequestStatus = LoanRequestStatus.Corriente; loanRequest.ContinueStatusUpdates = true; loanRequest.NextStatusUpdate = nextUpdtDate; } else { /* DO NOTHING */ } } } else if (delayedDays >= 1 && delayedDays <= Globals.VENCIDA) { if (firstPass) { nextUpdtDate = nrmlzdDate; nextUpdtDate = GetNextUpdateDate (nextUpdtDate); loanRequest.LoanRequestStatus = LoanRequestStatus.Vencida; loanRequest.ContinueStatusUpdates = true; loanRequest.NextStatusUpdate = nextUpdtDate; } else { /* Vencida status takes presedence as long as this is not the first * pass and the following condition is TRUE */ if (loanRequest.LoanRequestStatus != LoanRequestStatus.ExtraJudicial && loanRequest.LoanRequestStatus != LoanRequestStatus.JudicialAltoRiesgo) { nextUpdtDate = nrmlzdDate; nextUpdtDate = GetNextUpdateDate (nextUpdtDate); loanRequest.LoanRequestStatus = LoanRequestStatus.Vencida; loanRequest.ContinueStatusUpdates = true; loanRequest.NextStatusUpdate = nextUpdtDate; } else { /* DO NOTHING */ } } } else if (delayedDays > Globals.VENCIDA && delayedDays <= Globals.EXTRA_JUDICIAL) { if (firstPass) { nextUpdtDate = nrmlzdDate; nextUpdtDate = GetNextUpdateDate (nextUpdtDate); loanRequest.LoanRequestStatus = LoanRequestStatus.ExtraJudicial; loanRequest.ContinueStatusUpdates = true; loanRequest.NextStatusUpdate = nextUpdtDate; } else { /* ExtraJudicial status takes presedence as long as this is not the first * pass and the following condition is TRUE */ if (loanRequest.LoanRequestStatus != LoanRequestStatus.JudicialAltoRiesgo) { nextUpdtDate = nrmlzdDate; nextUpdtDate = GetNextUpdateDate (nextUpdtDate); loanRequest.LoanRequestStatus = LoanRequestStatus.ExtraJudicial; loanRequest.ContinueStatusUpdates = true; loanRequest.NextStatusUpdate = nextUpdtDate; } else { /* DO NOTHING */ } } } else if (delayedDays >= Globals.JUDICIAL_ALTO_RIESGO) { nextUpdtDate = nrmlzdDate; nextUpdtDate = GetNextUpdateDate (nextUpdtDate); /* JudicialAltoRiesgo takes presedence over every other state */ loanRequest.LoanRequestStatus = LoanRequestStatus.JudicialAltoRiesgo; /* We will stop updating if the delayed days is greater than 180 days */ if (delayedDays > Globals.MAX_UPDATE_DAYS) { loanRequest.ContinueStatusUpdates = false; } else { loanRequest.ContinueStatusUpdates = true; } loanRequest.NextStatusUpdate = nextUpdtDate; } } /* 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; } }
/// <summary> /// Returns a FinancialAnalysis object for a given loan request /// </summary> /// <param name="loanRequest">loanRequest</param> /// <param name="applicableVAT">applicableVAT</param> /// <returns></returns> public FinancialAnalysis GetFinancialAnalysis(LoanRequest loanRequest, VAT applicableVAT) { FinancialAnalysis financialAnalysis = new FinancialAnalysis(loanRequest, applicableVAT); return financialAnalysis; }
/// <summary> /// Removes a loan Request from the list of Loan Requests in this Client /// </summary> /// <param name="loanRequest"></param> public virtual void RemoveLoanRequest(LoanRequest loanRequest) { LoanRequests.Remove(loanRequest); }
/// <summary> /// Adds a loan Request to the list of Loan Requests in this Client /// </summary> /// <param name="loanRequest"></param> public virtual void AddLoanRequest(LoanRequest loanRequest) { loanRequest.Client = this; LoanRequests.Add(loanRequest); }
/// <summary> /// Adds a new Loan Request to a Client /// </summary> /// <param name="financialInstitutdionName">financialInstitutdionName</param> /// <param name="clientId">clientId</param> /// <param name="clientVersion">clientVersion</param> /// <param name="newLoanRequest">newLoanRequest</param> /// <exception cref="ZiblerBusinessComponentsException" /> /// <remarks>Note that this method is called whenever a new loan request /// is added to a client. At this point, the loan request is not completed /// yet, so we don't have to worry about credit line balances, until the /// loan request is completly finished.</remarks> public void AddLoanRequestToClient(string financialInstitutdionName, int clientId, int clientVersion, LoanRequest newLoanRequest) { try { //Retrieve the client from the database. IClientDAO clientDAO = _daoFactory.GetClientDAO (); ILoanRequestDAO loanRequestDAO = _daoFactory.GetLoanRequestDAO (); int maxTries = 4; int tried = 0; int initialGuid = 9; //Used for First Try int secondGuid = 9; //Used for Second Try int thirdGuid = 10; //Used for third try int fourthGuid = 11; //Generate internal loan request tracking number. //There is a small probability that the generated GUID will be repeated, thus we may //try up to three times. After that we fail and request them to try again. long generatedGuid = 0; bool guidOk = false; bool continueTrying = true; while (continueTrying) { //TODO: Perhaps there is a better way to do this. if (tried == 0) generatedGuid = NumberUtilities.GenerateSmallGUID (initialGuid); if (tried == 1) generatedGuid = NumberUtilities.GenerateSmallGUID (secondGuid); if (tried == 2) generatedGuid = NumberUtilities.GenerateSmallGUID (thirdGuid); if (tried == 3) generatedGuid = NumberUtilities.GenerateSmallGUID (fourthGuid); //Now we verify if the number exists already in the system if (!loanRequestDAO.InternalTrackingCodeExists (financialInstitutdionName, generatedGuid)) { guidOk = true; continueTrying = false; } tried++; if (tried >= maxTries) continueTrying = false; } if (guidOk) { //Now that we have our GUID, we verify the Tracking Code provided //by the user. if (newLoanRequest.TrackingCode != null) { if (newLoanRequest.TrackingCode.Trim () != "") { if (loanRequestDAO.TrackingCodeExists (financialInstitutdionName, newLoanRequest.TrackingCode.Trim ())) throw new ZiblerBusinessComponentsException ( Resources.ClientOperationsMsgLoanRequestTrackingCodeExists); } } Client client = clientDAO.FindByIdAndVersion (clientId, clientVersion); if (client == null) throw new ZiblerBusinessComponentsException (Resources.RecordNotFound); else { /* Don't worry if the client has already an active * loan request */ //Make sure we set the Status to EnCaptura since //this is a new Loan Request. newLoanRequest.LoanRequestStatus = LoanRequestStatus.EnCaptura; newLoanRequest.InternalTrackingCode = Convert.ToUInt64 (generatedGuid); /* Also set the flag indicating that this is a loan request that must * be automatically updated. Note that it won't be updated until the * loan request is actually approved */ newLoanRequest.ContinueStatusUpdates = true; /* Add the loan request. */ client.AddLoanRequest (newLoanRequest); } } else { //We should neve get here really. However Raise an exception, and let them //know that something happended and ask them to try again. ZiblerBusinessComponentsUnknownException ex = new ZiblerBusinessComponentsUnknownException (); ex.Data.Add ("GUID", generatedGuid.ToString ()); throw ex; } } /* 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; } }