/// <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;
            }
        }
Exemple #2
0
        /// <summary>
        /// Generates a report with estimated payment amounts on a Target Date. Only
        /// Loans that have payments on the Target Date are contemplated. Balances are
        /// calculated using todays date.
        /// </summary>
        /// <param name="financialInstitution">Financial Institution</param>
        /// <param name="targetDate">Target Date to be used for calculation</param>
        /// <param name="startIndex">startIndex</param>
        /// <param name="maxResults">maxResults</param>
        /// <param name="totalRecords">totalRecords</param>
        /// <returns>LoanRecoveryEstimatedRecoveryReport</returns>
        public IList<LoanRecoveryEstimatedRecoveryReport> GetLoanRecoveryEstimatedRecoveryReport(
            string financialInstitution,
            DateTime targetDate,
            int startIndex,
            int maxResults,
            out int totalRecords)
        {
            try
            {
                ILoanRequestDAO loanRequestDAO = _daoFactory.GetLoanRequestDAO ();
                ILoanDAO loanDAO = _daoFactory.GetLoanDAO ();
                IInterestRateDAO interestRateDAO = _daoFactory.GetInterestRateDAO ();
                IInterestRateValueDAO interestRateValueDAO = _daoFactory.GetInterestRateValueDAO ();
                IVatDAO vatDAO = _daoFactory.GetVatDAO ();

                IList<LoanRecoveryEstimatedRecoveryReport> reports
                = loanRequestDAO.GetLoanRecoveryEstimatedRecoveryReport (financialInstitution,
                                                                         targetDate,
                                                                         startIndex,
                                                                         maxResults,
                                                                         out totalRecords);

                /* Make sure we got at least one */
                if (reports.Count <= 0)
                {
                    throw new ZiblerBusinessComponentsException (
                        Resources.ReportOperationsLoanRequestNotExist);
                }

                /* Hash table to store Loan Ids along with their respective InterestRate Ids */
                Hashtable hashLoanIds = new Hashtable ();

                /* Hash table to store unique Interest Rate Ids and the earliest date from
                * where their values are needed. This is to avoid getting the same
                * Interest Rates more than onces if they are repeated. */
                Hashtable hashIntRtDates = new Hashtable ();

                /* List of Interest Rate values for a given Interest Rate Id */
                Hashtable hashIntRtValues = new Hashtable ();

                /* Earliest date from where the VAT values are needed */
                DateTime? vatStart = null;

                /* Loop through the returned report objects and get the
                * Loan Ids, Interest Rates and VAT dates */
                foreach (LoanRecoveryEstimatedRecoveryReport rep in reports)
                {
                    /* Add the loan Id and its Interest Rate Id to the list of
                    * hashLoanIds */
                    if (!hashLoanIds.Contains (rep.LoanId))
                        hashLoanIds.Add (rep.LoanId, rep.InterestRateId);

                    /* Add the Interest Rate Id and the Loan authorization date
                    * to the hashIntRtDates list. This list is used to minimize the number
                    * of queries made to the database if the Interest Rate Id is the
                    * same for multiple loans */
                    if (!hashIntRtDates.Contains (rep.InterestRateId))
                    {
                        hashIntRtDates.Add (rep.InterestRateId, rep.AuthorizationDate);
                    }

                    /*Add the start date only if it is previous to the current one */
                    if (hashIntRtDates[rep.InterestRateId] == null)
                        hashIntRtDates[rep.InterestRateId] = rep.AuthorizationDate;
                    else
                    {
                        /* Get the date associated to the Interest Rate */
                        DateTime currDate = Convert.ToDateTime (hashIntRtDates[rep.InterestRateId]);

                        /* Determine if there is another loan (rep.AuthorizationDate) whose
                        * date is earlier than the previously assigned to the Interest Rate Id.
                        * If so (replace) then use this date as the new data so later we get
                        * all the interest rate values from there */
                        bool replace = DateUtilities.IsFirstDateGreaterThanSecondDate (currDate,
                                                                                       rep.AuthorizationDate);

                        if (replace)
                            hashIntRtDates[rep.InterestRateId] = rep.AuthorizationDate;
                    }

                    /* If we don't have a VAT date yet, use the current AuthorizationDate */
                    if (vatStart == null)
                        vatStart = Convert.ToDateTime (rep.AuthorizationDate);
                    else
                    {
                        /* Determine if the loan has an earlier date than the currently selected for
                        * the VAT. If so, then this date should be used to search for the VAT */
                        bool replace = DateUtilities.IsFirstDateGreaterThanSecondDate (
                            vatStart.Value,
                            rep.AuthorizationDate);

                        if (replace)
                            vatStart = Convert.ToDateTime (rep.AuthorizationDate);
                    }
                }

                /* Verify we have at least one loan Id */
                if (hashLoanIds.Count <= 0)
                    throw new ZiblerBusinessComponentsException (
                        Resources.ReportOperationsLoanRequestWithOutLoans);

                /* Get all the loan Ids from our hash table.  */
                IDictionaryEnumerator enLoanIds = hashLoanIds.GetEnumerator ();

                IList<int> processLoanIds = new List<int> ();
                while (enLoanIds.MoveNext ())
                {
                    /* Add the loan Id to a list of loan Ids which will be used
                    * to retrieved them from the Database */
                    processLoanIds.Add (Convert.ToInt32 (enLoanIds.Key));
                }

                /* Retrieve the Loans from the Database */
                IList<Loan> loans = loanDAO.GetLoan (processLoanIds);

                /* Get all the Interests and their values to be used to calculate
                * the statements for all the loans */
                IDictionaryEnumerator en = hashIntRtDates.GetEnumerator ();
                while (en.MoveNext ())
                {
                    /* Interest Rate needed */
                    int intRateId = Convert.ToInt32 (en.Key);

                    /* Values needed from this date */
                    DateTime dt = Convert.ToDateTime (en.Value);

                    IList<InterestRateValue> list = interestRateValueDAO.GetInterestRateValuesForStatement (
                        intRateId,
                        dt,
                        DateTime.Today);

                    /* If no interest rate value was returned, it means that a value does not exists
                    * for a given Interest Rate Id */
                    if (list == null)
                    {
                        /* Get the interest rate for informational purposes */
                        InterestRate intRate = interestRateDAO.FindById (intRateId);
                        if (intRate != null)
                        {
                            string intRateName = intRate.Name;
                            throw new ZiblerBusinessComponentsException (
                                String.Format (
                                    Resources.ReportOperationsInterestRateDateNotAvailable,
                                    intRateName,
                                    dt.ToShortDateString ()));
                        }
                    }

                    /* Add the values to a hash list and move on */
                    hashIntRtValues.Add (intRateId, list);
                }

                /* Get all the VATs */
                IList<VAT> vats = vatDAO.GetVATsForStatement (financialInstitution,
                                                              vatStart.Value,
                                                              DateTime.Today);

                if (vats.Count <= 0)
                    throw new ZiblerBusinessComponentsException (
                        Resources.ReportOperationsNoVatsAvailable);

                /* Now that we have all the required data, loop through the list of reports one more time
                * and calculate the Statement for each one of them */
                foreach (LoanRecoveryEstimatedRecoveryReport report in reports)
                {
                    /* Calculated the statement on each loan of the report */
                    foreach (Loan loan in loans)
                    {
                        if (report.LoanId == loan.Id)
                        {
                            int loanId = loan.Id;
                            int intValueId = Convert.ToInt32 (hashLoanIds[loanId]);
                            IList<InterestRateValue> intValues = (IList<InterestRateValue>)hashIntRtValues[intValueId];

                            /* Calculate the statement to today's day */
                            LoanStatement stmnt = new LoanStatement (loan,
                                                                     DateTime.Today,
                                                                     vats,
                                                                     intValues);
                            stmnt.GenerateStatement ();

                            report.DelayedDays = stmnt.DelayedDays;
                            report.DelinquentInterests = stmnt.DelinquentInterests;
                            report.DelinquentPrincipal = stmnt.DelinquentPrincipal;
                            report.DelinquentVAT = stmnt.DelinquentVAT;
                            report.DelinquentBalance = stmnt.DelinquentBalance;

                            report.LoanedAmount = stmnt.LoanedAmount;
                            report.LoanType = stmnt.LoanType;
                            report.MoratoryInterests = stmnt.MoratoryInterests;

                            /* Get the payment number on the target date, so we can
                            * determine what the estimated payment will be */
                            report.EstmtdNxtPymnt = stmnt.GetEstimatedPayment (report.PaymentNumber);

                            break;
                        }
                    }
                }

                return reports;
            }
            /* 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;
            }
        }
Exemple #3
0
        /// <summary>
        /// Gets a loan recovery main report
        /// </summary>
        /// <param name="financialInstitution"></param>
        /// <param name="startDate">Start Authorization DAte</param>
        /// <param name="endDate">End Authorization date</param>
        /// <param name="startIndex"></param>
        /// <param name="maxResults"></param>
        /// <param name="totalRecords"></param>
        /// <returns></returns>
        public IList<LoanRecoveryMainReport> GetLoanRecoveryMainReport(string financialInstitution,
            DateTime startDate,
            DateTime endDate,
            int startIndex,
            int maxResults,
            out int totalRecords)
        {
            try
            {
                ILoanRequestDAO loanRequestDAO = _daoFactory.GetLoanRequestDAO ();
                ILoanDAO loanDAO = _daoFactory.GetLoanDAO ();
                IInterestRateDAO interestRateDAO = _daoFactory.GetInterestRateDAO ();
                IInterestRateValueDAO interestRateValueDAO = _daoFactory.GetInterestRateValueDAO ();
                IVatDAO vatDAO = _daoFactory.GetVatDAO ();

                IList<LoanRecoveryMainReport> reports = loanRequestDAO.GetLoanRecoveryMainReport (
                    financialInstitution,
                    startDate,
                    endDate,
                    startIndex,
                    maxResults,
                    out totalRecords);

                if (reports.Count <= 0)
                {
                    throw new ZiblerBusinessComponentsException (
                        Resources.ReportOperationsLoanRequestNotExist);
                }

                Hashtable loanIds = new Hashtable ();
                Hashtable hashTable = new Hashtable ();
                Hashtable hashIntRtValues = new Hashtable ();
                DateTime? vatStart = null;

                /* Now that we have the Loan Recovery Main Report we need to calculate the statements
                * for the loans involved */
                foreach (LoanRecoveryMainReport rep in reports)
                {
                    /* Add the loan Id and its Interest Rate Id to the list of
                    * loanIds */
                    if (!loanIds.Contains (rep.LoanId))
                        loanIds.Add (rep.LoanId, rep.InterestRateId);

                    /* Add the Interest Rate Id and the Loan authorization date
                    * to the local list. This list is used to minimize the number
                    * of queries made to the database if the Interest Rate Id is the
                    * same for multiple loans */
                    if (!hashTable.Contains (rep.InterestRateId))
                    {
                        hashTable.Add (rep.InterestRateId, rep.AuthorizationDate);
                    }

                    /*Add the start date only if it is previous to the current one */
                    if (hashTable[rep.InterestRateId] == null)
                        hashTable[rep.InterestRateId] = rep.AuthorizationDate;
                    else
                    {
                        /* Get the date associated to the Interest Rate */
                        DateTime currDate = Convert.ToDateTime (hashTable[rep.InterestRateId]);

                        /* Determine if there is another loan (rep.AuthorizationDate) whose
                        * date is earlier than the previously assigned to the Interest Rate Id.
                        * If so (replace) then use this date as the new data so later we get
                        * all the interest rate values from there */
                        bool replace = DateUtilities.IsFirstDateGreaterThanSecondDate (currDate,
                                                                                       rep.AuthorizationDate);

                        if (replace)
                            hashTable[rep.InterestRateId] = rep.AuthorizationDate;
                    }

                    if (vatStart == null)
                        vatStart = Convert.ToDateTime (rep.AuthorizationDate);
                    else
                    {
                        /* Determine if the loan has an earlier date than the currently selected for
                        * the VAT. If so, then this date should be used to search for the VAT */
                        bool replace = DateUtilities.IsFirstDateGreaterThanSecondDate (
                            vatStart.Value,
                            rep.AuthorizationDate);

                        if (replace)
                            vatStart = Convert.ToDateTime (rep.AuthorizationDate);
                    }
                }

                if (loanIds.Count <= 0)
                {
                    throw new ZiblerBusinessComponentsException (
                        Resources.ReportOperationsLoanRequestWithOutLoans);
                }

                /* Get all the loan Ids */
                IDictionaryEnumerator enLoanIds = loanIds.GetEnumerator ();

                IList<int> temp = new List<int> ();
                while (enLoanIds.MoveNext ())
                {
                    temp.Add (Convert.ToInt32 (enLoanIds.Key));
                }

                IList<Loan> loans = loanDAO.GetLoan (temp);

                /* Get all the Interests and their values to be used to calculate
                * the statements for all the loans */
                IDictionaryEnumerator en = hashTable.GetEnumerator ();
                while (en.MoveNext ())
                {
                    /* Interest Rate needed */
                    int intRateId = Convert.ToInt32 (en.Key);

                    /* Values needed from this date */
                    DateTime dt = Convert.ToDateTime (en.Value);

                    IList<InterestRateValue> list = interestRateValueDAO.GetInterestRateValuesForStatement (
                        intRateId,
                        dt,
                        DateTime.Today);

                    /* If no interest rate value was returned, it means that a value does not exists
                    * for a given Interest Rate Id */
                    if (list == null)
                    {
                        /* Get the interest rate for informational purposes */
                        InterestRate intRate = interestRateDAO.FindById (intRateId);
                        if (intRate != null)
                        {
                            string intRateName = intRate.Name;
                            throw new ZiblerBusinessComponentsException (
                                String.Format (
                                    Resources.ReportOperationsInterestRateDateNotAvailable,
                                    intRateName,
                                    dt.ToShortDateString ()));
                        }
                    }
                    hashIntRtValues.Add (intRateId, list);
                }

                /* Get all the VATs */
                IList<VAT> vats = vatDAO.GetVATsForStatement (financialInstitution,
                                                              vatStart.Value,
                                                              DateTime.Today);

                if (vats.Count <= 0)
                    throw new ZiblerBusinessComponentsException (
                        Resources.ReportOperationsNoVatsAvailable);

                foreach (LoanRecoveryMainReport report in reports)
                {
                    /* Now that we have all the values, calculate the statements and update the report
                    * object */
                    foreach (Loan loan in loans)
                    {
                        if (report.LoanId == loan.Id)
                        {
                            int loanId = loan.Id;
                            int intValueId = Convert.ToInt32 (loanIds[loanId]);
                            IList<InterestRateValue> intValues = (IList<InterestRateValue>)hashIntRtValues[intValueId];
                            LoanStatement stmnt = new LoanStatement (loan,
                                                                     DateTime.Today,
                                                                     vats,
                                                                     intValues);
                            stmnt.GenerateStatement ();

                            report.CommissionsTotal = stmnt.CommissionsTotal;

                            report.CurrentCommissions = stmnt.CurrentCommissions;
                            report.CurrentInterests = stmnt.CurrentInterests;
                            report.CurrentPrincipal = stmnt.CurrentPrincipal;
                            report.CurrentVAT = stmnt.CurrentVAT;
                            report.CurrentBalance = stmnt.CurrentBalance;

                            report.DelayedDays = stmnt.DelayedDays;
                            report.DelinquentInterests = stmnt.DelinquentInterests;
                            report.DelinquentPrincipal = stmnt.DelinquentPrincipal;
                            report.DelinquentVAT = stmnt.DelinquentVAT;
                            report.DelinquentBalance = stmnt.DelinquentBalance;

                            report.LoanedAmount = stmnt.LoanedAmount;
                            report.LoanType = stmnt.LoanType;
                            report.MoratoryInterests = stmnt.MoratoryInterests;
                            report.TotalAmountPaid = stmnt.TotalAmountPaid;

                            report.PaymentBalance = stmnt.PaymentBalance;

                            break;
                        }
                    }
                }

                return reports;
            }
            /* 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;
            }
        }
Exemple #4
0
        /// <summary>
        /// Gets the loan statement.
        /// </summary>
        /// <param name="financialInstitution">The financial institution.</param>
        /// <param name="loan">The loan.</param>
        /// <param name="statementDate">The statement date.</param>
        /// <returns>Loan Statement</returns>
        public LoanStatement GetLoanStatement(string financialInstitution,
            Loan loan,
            DateTime statementDate)
        {
            try
            {
                IFinancialInstitutionDAO financialInstitutionDAO
                = _daoFactory.GetFinancialInstitutionDAO ();
                IInterestRateValueDAO interestRateValueDAO = _daoFactory.GetInterestRateValueDAO ();
                IVatDAO vatDAO = _daoFactory.GetVatDAO ();

                if (loan == null)
                    throw new ZiblerBusinessComponentsException (Resources.RecordNotFound);

                FinancialInstitution finInst =
                financialInstitutionDAO.GetFinancialInstitutionByName (financialInstitution);

                if (finInst == null)
                    throw new ZiblerBusinessComponentsUnknownException ();

                /* Check the statement date is not before the start */
                if (!DateUtilities.IsFirstDateGreaterOrEqualThanSecondDate (
                    Convert.ToDateTime (statementDate),
                    Convert.ToDateTime (loan.StartDate)))
                {
                    throw new ZiblerBusinessComponentsException (
                        Resources.LoanOperationsMsgStatementDateIsBeforeLoan);
                }

                if (loan.EndDate == null)
                    throw new ZiblerBusinessComponentsUnknownException ();

                /* Get all the VATS within the range */
                IList<VAT> vats = vatDAO.GetVATsForStatement (financialInstitution,
                                                              Convert.ToDateTime (loan.StartDate),
                                                              statementDate);

                /* Make sure there is at least one from the beginning of the loan */
                bool vatFound = false;
                if (vats != null)
                {
                    foreach (VAT vat in vats)
                    {
                        if (!DateUtilities.IsFirstDateGreaterThanSecondDate (
                            Convert.ToDateTime (vat.ValidFrom),
                            Convert.ToDateTime (loan.StartDate)))
                        {
                            vatFound = true;
                            break;
                        }
                    }
                }

                if (!vatFound)
                {
                    throw new ZiblerBusinessComponentsException (
                        Resources.LoanOperationsMsgNoVATsInSystem);
                }

                /* Get the interest Rate Values */
                IList<InterestRateValue> interestValues
                = interestRateValueDAO.GetInterestRateValuesForStatement (loan.InterestRate.Id,
                                                                          Convert.ToDateTime (
                                                                              loan.StartDate),
                                                                          statementDate);

                /* Make sure there is at least one from the beginning of the loan */
                bool intFound = false;
                if (interestValues != null)
                {
                    foreach (InterestRateValue val in interestValues)
                    {
                        if (!DateUtilities.IsFirstDateGreaterThanSecondDate (
                            Convert.ToDateTime (val.ValidFrom),
                            Convert.ToDateTime (loan.StartDate)))
                        {
                            intFound = true;
                            break;
                        }
                    }
                }

                if (!intFound)
                {
                    throw new ZiblerBusinessComponentsException (
                        Resources.LoanOperationsMsgNoInterestRateValu);
                }

                /* Generate the statement */
                LoanStatement loanStatement = new LoanStatement (loan,
                                                                 statementDate,
                                                                 vats,
                                                                 interestValues);
                loanStatement.GenerateStatement ();

                return loanStatement;
            }
            /* 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;
            }
        }