Esempio n. 1
0
        public Loan EditSchedule(Loan pLoan, int roundTo)
        {
            Loan temp = pLoan.Copy();
            int sum = 0;
            if (roundTo == 0)
                return pLoan;

            foreach (Installment installment in temp.InstallmentList)
            {
                if (installment.Number != temp.InstallmentList.Count)
                {
                    int dif = Convert.ToInt32(installment.CapitalRepayment.Value + installment.InterestsRepayment.Value) % roundTo;
                    dif = dif > roundTo - dif ? roundTo - dif : -dif;
                    installment.CapitalRepayment += dif;
                    sum += dif;
                }
                else
                {
                    installment.CapitalRepayment -= sum;
                }
            }
            return temp;
        }
Esempio n. 2
0
        public Loan SimulateRescheduling(Loan loan, ScheduleConfiguration rescheduleConfiguration)
        {
            var copyOfLoan = loan.Copy();
            var scheduleConfiguration = _configurationFactory
                .Init()
                .WithLoan(copyOfLoan)
                .Finish()
                .GetConfiguration();

            var schedule = Mapper.Map<IEnumerable<Installment>, IEnumerable<IInstallment>>(copyOfLoan.InstallmentList);
            var scheduleBuilder = new ScheduleBuilder();
            var rescheduleAssembler = new RescheduleAssembler();
            var copyOfRescheduleConfiguration = (IScheduleConfiguration) rescheduleConfiguration.Clone();
            copyOfRescheduleConfiguration.InterestRate *=
                (decimal) scheduleConfiguration.PeriodPolicy.GetNumberOfPeriodsInYear(
                    copyOfRescheduleConfiguration.StartDate,
                    scheduleConfiguration.YearPolicy);

            schedule = rescheduleAssembler.AssembleRescheduling(
                schedule,
                scheduleConfiguration,
                copyOfRescheduleConfiguration,
                scheduleBuilder,
                loan.CalculateActualOlb().Value);

            var newSchedule = Mapper.Map<IEnumerable<IInstallment>, List<Installment>>(schedule);

            copyOfLoan.InstallmentList = newSchedule;
            copyOfLoan.NbOfInstallments = newSchedule.Count();
            return copyOfLoan;
        }
Esempio n. 3
0
        public KeyValuePair<Loan, RepaymentEvent> ShowNewContract(Loan pContract,
                                                                  int installmentNumber,
                                                                  DateTime date,
                                                                  OCurrency amount,
                                                                  bool disableFees,
                                                                  OCurrency manualFeesAmount,
                                                                  OCurrency manualCommissionAmount,
                                                                  bool disableInterests,
                                                                  OCurrency manualInterests,
                                                                  bool pKeepExpectedInstallment,
                                                                  bool doProportionPayment,
                                                                  PaymentMethod pPaymentMethod,
                                                                  bool pPending,
                                                                  bool isTotalRepayment)
        {
            if (!pContract.UseCents)
            {
                if (amount != Decimal.Ceiling(amount.Value))
                {
                    throw new OpenCbsRepayException(OpenCbsRepayExceptionsEnum.DecimalAmount);
                }
            }
            else if (amount < 0)
                throw new OpenCbsRepayException(OpenCbsRepayExceptionsEnum.NegativeAmount);

            Loan fakeContract = pContract.Copy();

            OCurrency expectedMaxAmount = fakeContract.CalculateMaximumAmountAuthorizedToRepay(installmentNumber, date,
                                                                                               disableFees,
                                                                                               manualFeesAmount,
                                                                                               manualCommissionAmount,
                                                                                               disableInterests,
                                                                                               manualInterests,
                                                                                               pKeepExpectedInstallment);

            expectedMaxAmount = fakeContract.UseCents
                                    ? Math.Round(expectedMaxAmount.Value, 2, MidpointRounding.AwayFromZero)
                                    : expectedMaxAmount;

            if (!disableFees && !isTotalRepayment)
            {
                if (AmountComparer.Compare(amount, expectedMaxAmount) > 0)
                    throw new OpenCbsRepayException(OpenCbsRepayExceptionsEnum.AmountGreaterThanTotalRemainingAmount);

            }
            else
            {
                if (isTotalRepayment)
                    amount = expectedMaxAmount;
            }

            RepaymentEvent e = fakeContract.Repay(installmentNumber, date, amount, disableFees, manualFeesAmount,
                                                  manualCommissionAmount, disableInterests, manualInterests,
                                                  pKeepExpectedInstallment, doProportionPayment, pPaymentMethod, null,
                                                  pPending);

            return new KeyValuePair<Loan, RepaymentEvent>(fakeContract, e);
        }
Esempio n. 4
0
        public Loan AddManualScheduleChangeEvent(Loan loan, ManualScheduleChangeEvent manualScheduleChangeEvent)
        {
            using (SqlConnection conn = _savingEventManager.GetConnection())
            using (SqlTransaction sqlTransaction = conn.BeginTransaction())
            {
                try
                {
                    Loan copyOfLoan = loan.Copy();
                    _ePs.FireEvent(manualScheduleChangeEvent, loan, sqlTransaction);
                    ArchiveInstallments(copyOfLoan, manualScheduleChangeEvent, sqlTransaction);

                    sqlTransaction.Commit();
                    return loan;
                }
                catch (Exception ex)
                {
                    sqlTransaction.Rollback();
                    throw ex;
                }
            }
        }
Esempio n. 5
0
        public Loan AddTranche(Loan pContract, IClient pClient, DateTime pDate, int pNbOfMaturity, int pTrancheAmount, bool pApplyNewInterestOnOLB, decimal pNewInterestRate)
        {
            using (SqlConnection conn = _loanManager.GetConnection())
            using (SqlTransaction sqlTransaction = conn.BeginTransaction())
            {
                try
                {
                    CheckTranche(pDate, pContract, pTrancheAmount);

                    Loan copyOfLoan = pContract.Copy();

                    TrancheOptions to = new TrancheOptions
                                            {
                                                TrancheDate = pDate,
                                                CountOfNewInstallments = pNbOfMaturity,
                                                TrancheAmount = pTrancheAmount,
                                                InterestRate = pNewInterestRate,
                                                ApplyNewInterestOnOLB = pApplyNewInterestOnOLB
                                            };

                    TrancheEvent trancheEvent = pContract.CalculateTranche(to);
                    trancheEvent.User = _user;

                    //insert into table TrancheEvent
                    _ePs.FireEvent(trancheEvent, pContract, sqlTransaction);

                    ArchiveInstallments(copyOfLoan, trancheEvent, sqlTransaction);

                    //delete all the old installments of the table Installments
                    _instalmentManager.DeleteInstallments(pContract.Id, sqlTransaction);

                    //insert all the new installments in the table Installments
                    _instalmentManager.AddInstallments(pContract.InstallmentList, pContract.Id, sqlTransaction);

                    //Activate the contract if it's closed because of new tranch
                    if (pContract.Closed)
                    {
                        pContract.ContractStatus = OContractStatus.Active;
                        pContract.Closed = false;
                        _loanManager.UpdateLoan(pContract, sqlTransaction);
                    }
                    //in the feature might be combine UpdateLoan + UpdateLoanWithinTranche
                    _loanManager.UpdateLoanWithinTranche(to.InterestRate, pContract.NbOfInstallments, pContract,
                                                         sqlTransaction);
                    pContract.Events.Add(trancheEvent);
                    pContract.GivenTranches.Add(trancheEvent);
                    sqlTransaction.Commit();

                    SetClientStatus(pContract, pClient);
                    return pContract;
                }
                catch (Exception ex)
                {
                    if (sqlTransaction != null)
                        sqlTransaction.Rollback();

                    throw ex;
                }
            }
        }
Esempio n. 6
0
        public void TestMethodeCopyCredit()
        {
            LoanProduct package = new LoanProduct
                                      {
                                          InstallmentType = new InstallmentType(1, "Monthly", 0, 1),
                                          LoanType = OLoanTypes.DecliningFixedInstallments,
                                          ChargeInterestWithinGracePeriod = true,
                                          Currency = new Currency { Id = 1 }
                                      };
            package.KeepExpectedInstallment = false;
            Loan contractSource = new Loan(package,1500,0.03m,9,1,new DateTime(2006,1,2),
                new User(), ApplicationSettings.GetInstance(""), NonWorkingDateSingleton.GetInstance(""),
                ProvisionTable.GetInstance(new User()), ChartOfAccounts.GetInstance(new User()));
            RepaymentEvent rE1 = new RepaymentEvent
                                     {
                                         Id = 1,
                                         InstallmentNumber = 1,
                                         Principal = 200,
                                         Interests = 100,
                                         Commissions = 0,
                                         Penalties = 0,
                                         ClientType = OClientTypes.Group
                                     };
            LoanDisbursmentEvent lDE = new LoanDisbursmentEvent{Id = 2,Date = DateTime.Today,Amount = 100, ClientType = OClientTypes.Group};

            contractSource.Code = "HHHHJKLLJJBNBJJ";
            contractSource.AnticipatedTotalRepaymentPenalties = 0.02;
            contractSource.Events.Add(rE1);
            contractSource.Events.Add(lDE);

            Loan contractDestination = contractSource.Copy();

            Assert.AreEqual(contractSource.Amount.Value, contractDestination.Amount.Value);
            Assert.AreEqual(contractSource.AnticipatedTotalRepaymentPenalties,contractDestination.AnticipatedTotalRepaymentPenalties);
            Assert.AreEqual(contractSource.Code,contractDestination.Code);
            Assert.AreEqual(contractSource.ClientType,contractDestination.ClientType);
            Assert.AreEqual(contractSource.InstallmentList.Count,contractDestination.InstallmentList.Count);
            Assert.AreEqual(contractSource.InstallmentList[0].Number,contractDestination.InstallmentList[0].Number);
            Assert.AreEqual(contractSource.InstallmentList[1].Number,contractDestination.InstallmentList[1].Number);

            //            ((LoanDisbursmentEvent)contractSource.Events.GetEvent(1)).Commission = 22;
            //            Assert.IsTrue(((LoanDisbursmentEvent)contractDestination.Events.GetEvent(1)).Commission == 0);
            //            Assert.IsFalse(((LoanDisbursmentEvent)contractDestination.Events.GetEvent(1)).Commission == 22);

            contractSource.InstallmentList[0].Number = 4;
            Assert.IsFalse(contractDestination.InstallmentList[0].Number == 4);
            Assert.IsTrue(contractDestination.InstallmentList[0].Number == 1);
        }
Esempio n. 7
0
        public Loan ConfirmPendingRepayment(Loan pLoan, IClient pClient)
        {
            Loan savedContract = pLoan.Copy();
            using (SqlConnection conn = _loanManager.GetConnection())
            using (SqlTransaction sqlTransaction = conn.BeginTransaction())
            {
                try
                {
                    RepaymentEvent repayEvent = savedContract.ConfirmPendingRepayment();
                    repayEvent.User = _user;
                    if (Teller.CurrentTeller != null && Teller.CurrentTeller.Id != 0)
                        repayEvent.TellerId = Teller.CurrentTeller.Id;

                    FundingLineEvent repayFlFundingLineEvent = new FundingLineEvent
                        {
                            Code =
                                String.Concat("RE_", pLoan.Code, "_INS_",
                                              repayEvent.InstallmentNumber),
                            Type = OFundingLineEventTypes.Repay,
                            Amount =
                                ApplicationSettings.GetInstance(_user != null
                                                                    ? _user.
                                                                          Md5
                                                                    : "").
                                                    InterestsCreditedInFL
                                    ? repayEvent.Principal +
                                      repayEvent.Interests
                                    : repayEvent.Principal,
                            Movement = OBookingDirections.Credit,
                            CreationDate = TimeProvider.Now,
                            FundingLine = pLoan.FundingLine
                            ,
                            AttachTo = repayEvent
                        };

                    if (Teller.CurrentTeller != null && Teller.CurrentTeller.Id != 0)
                        repayFlFundingLineEvent.TellerId = Teller.CurrentTeller.Id;

                    //this line is to prevent errors from popping up when client makes a repayment of
                    //everything but the principal
                    if (repayFlFundingLineEvent.Amount > 0 ||
                        ApplicationSettings.GetInstance(_user != null ? _user.Md5 : "").InterestsCreditedInFL)
                        pLoan.FundingLine.AddEvent(
                            new FundingLineServices(_user).AddFundingLineEvent(repayFlFundingLineEvent, sqlTransaction));

                    _ePs.FireEvent(repayEvent, savedContract, sqlTransaction);
                    // Put a copy of installments into the history
                    ArchiveInstallments(pLoan, repayEvent, sqlTransaction);

                    //Update Installments
                    foreach (Installment installment in savedContract.InstallmentList)
                    {
                        _instalmentManager.UpdateInstallment(installment, savedContract.Id, repayEvent.Id,
                                                             sqlTransaction);
                    }

                    for (int i = savedContract.Events.GetNumberOfEvents - 1; i >= 0; i--)
                    {
                        Event e = savedContract.Events.GetEvent(i);
                        if ((e is RepaymentEvent) || (e is LoanDisbursmentEvent))
                        {
                            e.Cancelable = true; //EventIsCancelable(e.Id, sqlTransaction);
                            if (!e.Cancelable)
                                break;
                        }
                        else
                        {
                            break;
                        }
                    }

                    _loanManager.UpdateLoan(savedContract, sqlTransaction);
                    if (sqlTransaction != null) sqlTransaction.Commit();

                    SetClientStatus(savedContract, pClient);

                    return savedContract;
                }
                catch (Exception)
                {
                    if (sqlTransaction != null) sqlTransaction.Rollback();
                    throw;
                }
            }
        }
Esempio n. 8
0
        private void AddLoan(ref Loan pLoan, int pProjectId, ref IClient pClient, SqlTransaction transaction)
        {
            if (pProjectId == 0)
                throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.ProjectIsNull);

            ApplicationSettings appSettings = ApplicationSettings.GetInstance(_user.Md5);

            if (!appSettings.IsAllowMultipleLoans && pClient.Active)
                throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.BeneficiaryIsActive);

            Loan clonedLoan = pLoan.Copy();
            IClient clonedClient = pClient.Copy();
            try
            {
                string branchCode = pClient.Branch.Code;
                if (String.IsNullOrEmpty(branchCode))
                    branchCode = _branchService.FindBranchCodeByClientId(pClient.Id, transaction);

                pLoan.ContractStatus = OContractStatus.Pending;
                pLoan.CreationDate = pLoan.StartDate;
                pLoan.CloseDate = (pLoan.InstallmentList[pLoan.InstallmentList.Count - 1]).ExpectedDate;
                pLoan.BranchCode = branchCode;

                pLoan.Id = AddLoanInDatabase(pLoan, pProjectId, pClient, transaction);
                pLoan.Code = GenerateContractCode(pClient, pLoan, transaction);
                _loanManager.UpdateContractCode(pLoan.Id, pLoan.Code, transaction);
            }
            catch
            {
                pLoan = clonedLoan;
                pClient = clonedClient;
                throw;
            }
        }
Esempio n. 9
0
        public Loan SimulateTranche(Loan loan, ITrancheConfiguration trancheConfiguration)
        {
            var copyOfLoan = loan.Copy();
            var scheduleConfiguration = _configurationFactory
                .Init()
                .WithLoan(copyOfLoan)
                .Finish()
                .GetConfiguration();

            var schedule = copyOfLoan.InstallmentList;
            var scheduleBuilder = new ScheduleBuilder();
            var trancheBuilder = new TrancheBuilder();
            var trancheAssembler = new TrancheAssembler();
            var copyOfTrancheConfiguration = (ITrancheConfiguration)trancheConfiguration.Clone();

            var newSchedule = new List<Installment>();
            if (loan.Product.ScriptName == null)
                newSchedule = trancheAssembler.AssembleTranche(
                    schedule,
                    scheduleConfiguration,
                    copyOfTrancheConfiguration,
                    scheduleBuilder,
                    trancheBuilder).ToList();
            else
                newSchedule = AssembleTranche(copyOfLoan, scheduleConfiguration, trancheConfiguration);

            foreach (var installment in newSchedule)
            {
                var oldInstallment = copyOfLoan.InstallmentList.Find(i => i.Number == installment.Number);
                if (oldInstallment == null) break;

                installment.Comment = oldInstallment.Comment;
                installment.PaidFees = oldInstallment.PaidFees;
                installment.PaidCommissions = oldInstallment.PaidCommissions;
                installment.FeesUnpaid = oldInstallment.FeesUnpaid;
                installment.CommissionsUnpaid = oldInstallment.CommissionsUnpaid;
                installment.IsPending = oldInstallment.IsPending;
                //installment.PaidDate = oldInstallment.PaidDate;
            }
            copyOfLoan.InstallmentList = newSchedule;
            copyOfLoan.NbOfInstallments = newSchedule.Count();
            copyOfLoan.Amount += trancheConfiguration.Amount;
            return copyOfLoan;
        }
Esempio n. 10
0
        public Loan SimulateRescheduling(Loan loan, ScheduleConfiguration rescheduleConfiguration)
        {
            var copyOfLoan = loan.Copy();
            var scheduleConfiguration = _configurationFactory
                .Init()
                .WithLoan(copyOfLoan)
                .Finish()
                .GetConfiguration();

            var schedule = copyOfLoan.InstallmentList;
            var scheduleBuilder = new ScheduleBuilder();
            var rescheduleAssembler = new RescheduleAssembler();
            var copyOfRescheduleConfiguration = (IScheduleConfiguration)rescheduleConfiguration.Clone();
            if (loan.Product.ScriptName == null)
                schedule = rescheduleAssembler.AssembleRescheduling(
                    schedule,
                    scheduleConfiguration,
                    copyOfRescheduleConfiguration,
                    scheduleBuilder,
                    loan.CalculateActualOlb().Value).ToList();
            else
                schedule = AssembleRescheduling(loan, rescheduleConfiguration, scheduleConfiguration);

            copyOfLoan.InstallmentList = schedule;
            copyOfLoan.NbOfInstallments = schedule.Count();
            return copyOfLoan;
        }
Esempio n. 11
0
 public Loan FakeReschedule(Loan contract, DateTime date, int nbOfMaturity, int dateOffset, bool pAccruedInterestDuringTheGracePeriod, decimal pNewInterestRate, int gracePeriod, bool chargeInterestDuringGracePeriod)
 {
     Loan fakeContract = contract.Copy();
     ReschedulingOptions ro = new ReschedulingOptions
                                  {
                                      ChargeInterestDuringShift = pAccruedInterestDuringTheGracePeriod,
                                      NewInstallments = nbOfMaturity,
                                      InterestRate = pNewInterestRate,
                                      RepaymentDateOffset = dateOffset,
                                      ReschedulingDate = date,
                                      GracePeriod = gracePeriod,
                                      ChargeInterestDuringGracePeriod = chargeInterestDuringGracePeriod
                                  };
     fakeContract.Reschedule(ro);
     return fakeContract;
 }
Esempio n. 12
0
        private void AddLoan(ref Loan pLoan, int pProjectId, ref IClient pClient, SqlTransaction transaction)
        {
            if (pProjectId == 0)
                throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.ProjectIsNull);

            ApplicationSettings appSettings = ApplicationSettings.GetInstance(_user.Md5);

            if (!appSettings.IsAllowMultipleLoans && pClient.Active)
                throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.BeneficiaryIsActive);

            Loan clonedLoan = pLoan.Copy();
            IClient clonedClient = pClient.Copy();
            try
            {
                var clientName = (pClient is Person) ? ((Person)pClient).LastName : pClient.Name;
                string branchCode = pClient.Branch.Code;
                if (String.IsNullOrEmpty(branchCode))
                    branchCode = _branchService.FindBranchCodeByClientId(pClient.Id, transaction);

                pLoan.ContractStatus = OContractStatus.Pending;
                pLoan.CreationDate = pLoan.StartDate;
                pLoan.CloseDate = (pLoan.InstallmentList[pLoan.InstallmentList.Count - 1]).ExpectedDate;
                pLoan.BranchCode = branchCode;

                if (string.IsNullOrEmpty(clonedLoan.Code))
                {
                    int len = 1 == pClient.District.Name.Length ? 1 : 2;
                    pLoan.Code = pLoan.GenerateLoanCode(appSettings.ContractCodeTemplate
                        , branchCode
                        , pClient.District.Name.Substring(0, len)
                        , (pClient.LoanCycle + 1).ToString(CultureInfo.InvariantCulture)
                        , pClient.Projects.Count.ToString(CultureInfo.InvariantCulture)
                        , pClient.Id.ToString(CultureInfo.InvariantCulture)
                        , clientName);
                }

                pLoan.Id = AddLoanInDatabase(pLoan, pProjectId, pClient, transaction);
                pLoan.Code = pLoan.Code + '/' + pLoan.Id;
                _loanManager.UpdateContractCode(pLoan.Id, pLoan.Code, transaction);
            }
            catch
            {
                pLoan = clonedLoan;
                pClient = clonedClient;
                throw;
            }
        }
Esempio n. 13
0
        public Loan Reschedule(Loan pContract, DateTime pDate, int pNbOfMaturity, int dateOffset,
            bool pAccruedInterestDuringTheGracePeriod, decimal pNewInterestRate, int gracePeriod, bool chargeInterestDuringGracePeriod)
        {
            using (SqlConnection conn = _loanManager.GetConnection())
            using (SqlTransaction sqlTransac = conn.BeginTransaction())
            {
                try
                {
                    Loan copyOfLoan = pContract.Copy();

                    //create the rescheduling loan event
                    ReschedulingOptions ro = new ReschedulingOptions
                                                 {
                                                     ReschedulingDate = pDate,
                                                     ChargeInterestDuringShift = pAccruedInterestDuringTheGracePeriod,
                                                     InterestRate = pNewInterestRate,
                                                     RepaymentDateOffset = dateOffset,
                                                     NewInstallments = pNbOfMaturity,
                                                     GracePeriod = gracePeriod,
                                                     ChargeInterestDuringGracePeriod = chargeInterestDuringGracePeriod
                                                 };
                    RescheduleLoanEvent rescheduleLoanEvent = pContract.Reschedule(ro);
                    rescheduleLoanEvent.User = _user;

                    //insert into table ReschedulingOfALoanEvents
                    _ePs.FireEvent(rescheduleLoanEvent, pContract, sqlTransac);
                    OverdueEvent overdueEvent = pContract.AddRecheduleTransformationEvent(pDate);
                    if (overdueEvent != null) _ePs.FireEvent(overdueEvent, pContract, sqlTransac);

                    ArchiveInstallments(copyOfLoan, rescheduleLoanEvent, sqlTransac);

                    //delete all the old installments of the table Installments
                    _instalmentManager.DeleteInstallments(pContract.Id, sqlTransac);

                    //insert all the new installments in the table Installments
                    _instalmentManager.AddInstallments(pContract.InstallmentList, pContract.Id, sqlTransac);

                    _loanManager.UpdateLoanToRescheduled(pNewInterestRate, pNbOfMaturity, pContract, sqlTransac);

                    sqlTransac.Commit();
                    return pContract;
                }
                catch (Exception ex)
                {
                    sqlTransac.Rollback();
                    throw ex;
                }
            }
        }
Esempio n. 14
0
        public Loan FakeTranche(Loan pContract, DateTime pDate, int pNbOfMaturity, int pTrancheAmount, bool pApplyNewInterestOnOLB, decimal pNewInterestRate)
        {
            Loan fakeContract = pContract.Copy();

            TrancheOptions to = new TrancheOptions
            {
                TrancheDate = pDate,
                CountOfNewInstallments = pNbOfMaturity,
                TrancheAmount = pTrancheAmount,
                InterestRate = pNewInterestRate,
                ApplyNewInterestOnOLB = pApplyNewInterestOnOLB
            };

            fakeContract.CalculateTranche(to);
            return fakeContract;
        }
Esempio n. 15
0
        public Loan SimulateTranche(Loan loan, ITrancheConfiguration trancheConfiguration)
        {
            var copyOfLoan = loan.Copy();
            var scheduleConfiguration = _configurationFactory
                .Init()
                .WithLoan(copyOfLoan)
                .Finish()
                .GetConfiguration();

            var schedule = Mapper.Map<IEnumerable<Installment>, IEnumerable<IInstallment>>(copyOfLoan.InstallmentList);
            var scheduleBuilder = new ScheduleBuilder();
            var trancheBuilder = new TrancheBuilder();
            var trancheAssembler = new TrancheAssembler();
            var copyOfTrancheConfiguration = (ITrancheConfiguration) trancheConfiguration.Clone();
            copyOfTrancheConfiguration.InterestRate *=
                (decimal) scheduleConfiguration.PeriodPolicy.GetNumberOfPeriodsInYear(
                    copyOfTrancheConfiguration.StartDate,
                    scheduleConfiguration.YearPolicy);

            schedule = trancheAssembler.AssembleTranche(
                schedule,
                scheduleConfiguration,
                copyOfTrancheConfiguration,
                scheduleBuilder,
                trancheBuilder);

            var newSchedule = Mapper.Map<IEnumerable<IInstallment>, List<Installment>>(schedule);

            foreach (var installment in newSchedule)
            {
                var oldInstallment = copyOfLoan.InstallmentList.Find(i => i.Number == installment.Number);
                if (oldInstallment == null) break;

                installment.Comment = oldInstallment.Comment;
                installment.PaidFees = oldInstallment.PaidFees;
                installment.PaidCommissions = oldInstallment.PaidCommissions;
                installment.FeesUnpaid = oldInstallment.FeesUnpaid;
                installment.CommissionsUnpaid = oldInstallment.CommissionsUnpaid;
                installment.IsPending = oldInstallment.IsPending;
                //installment.PaidDate = oldInstallment.PaidDate;
            }
            copyOfLoan.InstallmentList = newSchedule;
            copyOfLoan.NbOfInstallments = newSchedule.Count();
            copyOfLoan.Amount += trancheConfiguration.Amount;
            return copyOfLoan;
        }
Esempio n. 16
0
        public Loan UpdateContractStatus(Loan credit, Project project, IClient client, bool undoValidation)
        {
            CheckOperationDate(credit.CreditCommiteeDate.Value);
            using (SqlConnection conn = _loanManager.GetConnection())
            using (SqlTransaction sqlTransaction = conn.BeginTransaction())
            {

                try
                {
                    if (credit.StartDate.Date < ((DateTime) credit.CreditCommiteeDate).Date)
                        throw new OpenCbsContractSaveException(
                            OpenCbsContractSaveExceptionEnum.LoanWasValidatedLaterThanDisbursed);

                    Loan tempLoan = credit.Copy();

                    LoanValidationEvent lve = null;
                    if (undoValidation)
                    {
                        if (tempLoan.Events.GetLastLoanNonDeletedEvent != null &&
                            tempLoan.Events.GetLastLoanNonDeletedEvent is LoanValidationEvent)
                        {
                            ((LoanValidationEvent) tempLoan.Events.GetLastLoanNonDeletedEvent).Amount = credit.Amount;
                            _ePs.CancelFireEvent(tempLoan.Events.GetLastLoanNonDeletedEvent, sqlTransaction, tempLoan,
                                                 tempLoan.Product.Currency.Id);
                            tempLoan.Events.GetLastLoanNonDeletedEvent.Deleted = true;
                        }
                    }
                    else if (tempLoan.ContractStatus == OContractStatus.Validated)
                    {
                        lve = new LoanValidationEvent();
                        lve.Amount = tempLoan.Amount;
                        lve.Date = tempLoan.CreditCommiteeDate.Value;
                        lve.Cancelable = true;
                        lve.User = _user;
                        lve.Deleted = false;

                        if (Teller.CurrentTeller != null && Teller.CurrentTeller.Id != 0)
                            lve.TellerId = Teller.CurrentTeller.Id;

                        _ePs.FireEvent(lve, tempLoan, sqlTransaction);
                        tempLoan.Events.Add(lve);
                    }
                    _loanManager.UpdateLoanStatus(tempLoan, sqlTransaction);
                    project.SetStatus();
                    new ProjectServices(_user).UpdateProjectStatus(project, sqlTransaction);
                    client.SetStatus();
                    new ClientServices(_user).UpdateClientStatus(client, sqlTransaction);

                    FundingLineEvent pendingFundingLineEvent = new FundingLineEvent
                        {
                            Code =
                                string.Concat(
                                    OFundingLineEventTypes.Commitment.
                                                           ToString(), "/", tempLoan.Code),
                            Type = OFundingLineEventTypes.Commitment,
                            FundingLine =
                                _fundingLineServices.SelectFundingLineById(
                                    tempLoan.FundingLine.Id, sqlTransaction),
                            Movement = OBookingDirections.Debit,
                            CreationDate = TimeProvider.Now,
                            Amount = tempLoan.Amount
                            ,
                            AttachTo = lve
                        };
                    //if this is a new validate event, register it, otherwise delete previous validate event
                    if (tempLoan.ContractStatus == OContractStatus.Validated)
                        tempLoan.FundingLine.AddEvent(_fundingLineServices.AddFundingLineEvent(pendingFundingLineEvent,
                                                                                               sqlTransaction));
                    else if (undoValidation)
                    {
                        DeleteFundingLineEvent(ref tempLoan, pendingFundingLineEvent, sqlTransaction);
                    }
                    sqlTransaction.Commit();
                    return tempLoan;
                }
                catch (Exception ex)
                {
                    sqlTransaction.Rollback();
                    throw ex;
                }
            }
        }
Esempio n. 17
0
        private List<Installment> AssembleRescheduling(Loan loan, ScheduleConfiguration rescheduleConfiguration, IScheduleConfiguration scheduleConfiguration)
        {
            var copyOfLoan = loan.Copy();;
            var schedule = copyOfLoan.InstallmentList;
            // Build a new combined schedule

            // 1. To close all active installments before date of rescheduling.

            // Get the part of the schedule that comes before the rescheduling date...
            var newSchedule =
                from installment in schedule
                where installment.ExpectedDate <= rescheduleConfiguration.StartDate
                select installment;

            // Get overpaid principal = sum of paid principal after the rescheduling date...
            var overpaidPrincipal = (
                from installment in schedule
                where installment.PaidDate > rescheduleConfiguration.StartDate
                select installment
            ).Sum(installment => installment.PaidCapital.Value);

            //Add overpaid principal to paid principal of the last installment before the rescheduling
            if (newSchedule.Any())
                newSchedule.Last().PaidCapital += overpaidPrincipal;

            // Close all active installments before date of rescheduling
            var olbDifference = 0m;
            foreach (var installment in newSchedule)
            {
                installment.OLB += olbDifference;
                olbDifference += installment.CapitalRepayment.Value - installment.PaidCapital.Value;
                installment.CapitalRepayment = installment.PaidCapital;
                installment.InterestsRepayment = installment.PaidInterests;
            }

            // 2. To store amounts of interest paid, those for installments after date of rescheduling.
            var overpaidInterest = (
                from installment in schedule
                where installment.ExpectedDate > rescheduleConfiguration.StartDate
                select installment
            ).Sum(installment => installment.PaidInterests.Value);

            // 3. To get total of first calculated interest. It will be interest between last closed installment and date of rescheduling
            //    plus interest between date of rescheduling and first repayment date

            //    To calculate extra interest for used days.
            //    For the case when date of rescheduling < date of first installment
            var currentOlb = loan.CalculateActualOlb().Value;
            var usedDays = 0;
            if (newSchedule.Any())
            {
                usedDays = (rescheduleConfiguration.StartDate - newSchedule.Last().ExpectedDate).Days;
            }
            var daysInYear = scheduleConfiguration.YearPolicy.GetNumberOfDays(rescheduleConfiguration.StartDate);
            var extraInterest = currentOlb * scheduleConfiguration.InterestRate / 100 * usedDays / daysInYear;

            // To calculate interest between date of rescheduling and first repayment date.
            var daysTillRepayment =
                (rescheduleConfiguration.PreferredFirstInstallmentDate - rescheduleConfiguration.StartDate).Days;
            decimal firstInterest = 0;
            if (rescheduleConfiguration.GracePeriod == 0 || rescheduleConfiguration.ChargeInterestDuringGracePeriod)
                firstInterest = currentOlb*rescheduleConfiguration.InterestRate/100*daysTillRepayment/
                            scheduleConfiguration.PeriodPolicy.GetNumberOfDays(
                                rescheduleConfiguration.PreferredFirstInstallmentDate);

            copyOfLoan.Amount = currentOlb;
            copyOfLoan.InterestRate = rescheduleConfiguration.InterestRate/100;
            copyOfLoan.NbOfInstallments = rescheduleConfiguration.NumberOfInstallments;
            copyOfLoan.GracePeriod = rescheduleConfiguration.GracePeriod;
            copyOfLoan.StartDate = rescheduleConfiguration.StartDate;
            copyOfLoan.FirstInstallmentDate = rescheduleConfiguration.PreferredFirstInstallmentDate;
            copyOfLoan.Product.ChargeInterestWithinGracePeriod = rescheduleConfiguration.ChargeInterestDuringGracePeriod;
            rescheduleConfiguration.RoundingPolicy = scheduleConfiguration.RoundingPolicy;

            var rescheduled = SimulateScheduleCreation(copyOfLoan);
            // Adjust the new schedule's installment numbers
            var increment = newSchedule.Count();
            foreach (var installment in rescheduled)
            {
                installment.Number += increment;
            }

            // Distribute the extra and overpaid interest
            if (rescheduleConfiguration.GracePeriod > 0 && !rescheduleConfiguration.ChargeInterestDuringGracePeriod)
                rescheduled[rescheduleConfiguration.GracePeriod].InterestsRepayment +=
                    rescheduleConfiguration.RoundingPolicy.Round(extraInterest);
            else
                rescheduled.First().InterestsRepayment =
                    rescheduleConfiguration.RoundingPolicy.Round(firstInterest + extraInterest);
            foreach (var installment in rescheduled)
            {
                if (installment.InterestsRepayment < overpaidInterest)
                {
                    installment.PaidInterests = installment.InterestsRepayment;
                    overpaidInterest -= installment.InterestsRepayment.Value;
                }
                else
                {
                    installment.PaidInterests = overpaidInterest;
                    break;
                }
            }

            var result = new List<Installment>();
            result.AddRange(newSchedule);
            result.AddRange(rescheduled);

            return result;
        }
Esempio n. 18
0
        public void CancelPendingInstallments(Loan pLoan)
        {
            Loan fakeLoan = pLoan.Copy();

            foreach (var installment in pLoan.InstallmentList.FindAll(item => item.IsPending))
            {
                var fakeInstallment = fakeLoan.InstallmentList.Find(item => item.Number == installment.Number);
                _instalmentManager.UpdateInstallment(fakeInstallment, pLoan.Id, null, null);
            }
        }
Esempio n. 19
0
        private IEnumerable<Installment> BuildTranche(IEnumerable<Installment> schedule,Loan loan, IScheduleConfiguration scheduleConfiguration, ITrancheConfiguration trancheConfiguration)
        {
            var copyOfLoan = loan.Copy();
            loan.Amount = trancheConfiguration.Amount;
            loan.NbOfInstallments = trancheConfiguration.NumberOfInstallments;
            loan.GracePeriod = trancheConfiguration.GracePeriod;
            loan.InterestRate = trancheConfiguration.InterestRate/100;
            loan.StartDate = trancheConfiguration.StartDate;
            loan.FirstInstallmentDate = trancheConfiguration.PreferredFirstInstallmentDate;

            var rhs = SimulateScheduleCreation(loan);

            loan.Amount = schedule.Sum(i => i.CapitalRepayment.Value - i.PaidCapital.Value);
            if (!trancheConfiguration.ApplyNewInterestRateToOlb)
            {
                loan.InterestRate = copyOfLoan.InterestRate;
            }

            var lhs = SimulateScheduleCreation(loan);

            var result = new List<Installment>();

            // Merge the two schedules
            var max = Math.Max(lhs.Count, rhs.Count);
            for (var i = 0; i < max; i++)
            {
                var lhi = i >= lhs.Count ? null : lhs[i];
                var rhi = i >= rhs.Count ? null : rhs[i];

                Installment installment;

                if (lhi == null)
                {
                    installment = rhi;
                }
                else if (rhi == null)
                {
                    installment = lhi;
                }
                else
                {
                    installment = new Installment
                    {
                        Number = lhi.Number,
                        StartDate = lhi.StartDate,
                        ExpectedDate = lhi.ExpectedDate,
                        //RepaymentDate = lhi.RepaymentDate,
                        CapitalRepayment = lhi.CapitalRepayment + rhi.CapitalRepayment,
                        InterestsRepayment = lhi.InterestsRepayment + rhi.InterestsRepayment,
                        OLB = lhi.OLB + rhi.OLB,
                    };
                }
                result.Add(installment);
            }

            result[0].InterestsRepayment += GetExtraInterest(schedule, scheduleConfiguration, trancheConfiguration);
            return result;
        }
Esempio n. 20
0
        public Loan Disburse(Loan pLoan, DateTime pDateToDisburse, bool pAlignInstallmentsDatesOnRealDisbursmentDate,
                             bool pDisableFees, PaymentMethod method)
        {
            Loan copyLoan = pLoan.Copy();
            CheckDisbursedLoan(copyLoan, pDateToDisburse);
            CheckOperationDate(pDateToDisburse);

            using (SqlConnection connection = _loanManager.GetConnection())
            using (SqlTransaction sqlTransaction = connection.BeginTransaction())
            {
                try
                {
                    LoanDisbursmentEvent loanDisbursmentEvent = copyLoan.Disburse(pDateToDisburse,
                                                                                  pAlignInstallmentsDatesOnRealDisbursmentDate,
                                                                                  pDisableFees);
                    loanDisbursmentEvent.User = _user;
                    loanDisbursmentEvent.PaymentMethod = method;

                    if (pLoan.CompulsorySavings != null)
                        loanDisbursmentEvent.Comment = pLoan.CompulsorySavings.Code;

                    FundingLineEvent flFundingLineEvent = new FundingLineEvent
                        {
                            Code = String.Concat("DE_", copyLoan.Code),
                            Type = OFundingLineEventTypes.Disbursment,
                            Amount = loanDisbursmentEvent.Amount,
                            Movement = OBookingDirections.Debit,
                            CreationDate = TimeProvider.Now,
                            FundingLine =
                                _fundingLineServices.SelectFundingLineById(
                                    copyLoan.FundingLine.Id, sqlTransaction),
                            AttachTo = loanDisbursmentEvent
                        };

                    if (Teller.CurrentTeller != null && Teller.CurrentTeller.Id != 0)
                    {
                        loanDisbursmentEvent.TellerId = Teller.CurrentTeller.Id;
                        flFundingLineEvent.TellerId = Teller.CurrentTeller.Id;
                    }
                    loanDisbursmentEvent.Comment = copyLoan.Comments;
                    _ePs.FireEvent(loanDisbursmentEvent, copyLoan, sqlTransaction);

                    flFundingLineEvent = _fundingLineServices.AddFundingLineEvent(flFundingLineEvent, sqlTransaction);

                    foreach (Event item in copyLoan.Events)
                    {
                        if (item is CreditInsuranceEvent)
                        {
                            _ePs.FireEvent(item, copyLoan, sqlTransaction);
                            break;
                        }
                    }

                    copyLoan.ContractStatus = OContractStatus.Active;

                    if (copyLoan.Project != null)
                        copyLoan.Project.Client.Active = true;

                    _loanManager.UpdateLoan(copyLoan, sqlTransaction);

                    int loanDisbEventId = loanDisbursmentEvent.Id;
                    if (pAlignInstallmentsDatesOnRealDisbursmentDate ||
                        ApplicationSettings.GetInstance(_user != null ? _user.Md5 : string.Empty).
                                            PayFirstInterestRealValue)
                        foreach (Installment installment in copyLoan.InstallmentList)
                            _instalmentManager.UpdateInstallment(installment, copyLoan.Id, loanDisbEventId,
                                                                 sqlTransaction);

                    copyLoan.FundingLine.AddEvent(flFundingLineEvent);

                    loanDisbursmentEvent.Cancelable = true;

                    if (copyLoan.HasCompulsoryAmount())
                    {
                        SavingBookContract compulsorySaving = copyLoan.CompulsorySavings;
                        SavingBlockCompulsarySavingsEvent savingBlockEvent =
                            compulsorySaving.GetBlockCompulsorySavingEvent();
                        Debug.Assert(savingBlockEvent != null,
                                     "Saving should have block event on disbursment if it has compulsary saving");
                        savingBlockEvent.LoanEventId = loanDisbEventId;

                        _ePs.FireSavingBlockEvent(savingBlockEvent, compulsorySaving.Id, sqlTransaction);
                    }

                    _clientManager.IncrementLoanCycleByContractId(pLoan.Id, sqlTransaction);

                    SetEconomicActivity(pLoan, sqlTransaction);

                    loanDisbursmentEvent.PaymentMethodId = method.Id;
                    CallInterceptor(new Dictionary<string, object>
                    {
                        {"Loan", pLoan},
                        {"Event", loanDisbursmentEvent},
                        {"SqlTransaction", sqlTransaction}
                    });
                    if (loanDisbursmentEvent.Commissions != null && loanDisbursmentEvent.Commissions.Count != 0)
                        CallInterceptor(new Dictionary<string, object>
                        {
                            {"Loan", pLoan},
                            {
                                "Event", new LoanEntryFeeEvent
                                    {
                                        Id = loanDisbursmentEvent.Commissions.First().Id,
                                        Fee = loanDisbursmentEvent.Commissions.Sum(i => i.Fee.Value),
                                        Code = "LEE0",
                                        Date = loanDisbursmentEvent.Date
                                    }
                            },
                            {"SqlTransaction", sqlTransaction}
                        });

                    sqlTransaction.Commit();
                    return copyLoan;
                }
                catch
                {
                    if (sqlTransaction != null) sqlTransaction.Rollback();
                    throw;
                }
            }
        }
Esempio n. 21
0
        /// <summary>
        /// Simulate a disbursement
        /// </summary>
        /// <param name="pLoan"></param>
        /// <param name="pAlignInstallmentsDatesOnRealDisbursmentDate"></param>
        /// <param name="pDateToDisburse"></param>
        /// <param name="pDisableFees"></param>
        /// <returns>a Loan disbursement event</returns>
        public LoanDisbursmentEvent DisburseSimulation(Loan pLoan, bool pAlignInstallmentsDatesOnRealDisbursmentDate,
                                                       DateTime pDateToDisburse, bool pDisableFees)
        {
            Loan clonedLoan = pLoan.Copy();
            LoanDisbursmentEvent loanDisbursmentEvent = clonedLoan.Disburse(pDateToDisburse,
                                                                            pAlignInstallmentsDatesOnRealDisbursmentDate,
                                                                            pDisableFees);

            if (loanDisbursmentEvent == null)
                throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.DisburseIsNull);

            loanDisbursmentEvent.User = _user;
            return loanDisbursmentEvent;
        }
Esempio n. 22
0
        public void Copy_NoChange()
        {
            Loan loan = new Loan
                            {
                                Code = "Code",
                                Amount = 1000,
                                InterestRate = 0.3m,
                                ClientType = OClientTypes.Group,
                                InstallmentList = new List<Installment>
                                                      {
                                                          new Installment{Number = 1,CapitalRepayment = 100,InterestsRepayment = 2,ExpectedDate = new DateTime(2007, 1, 1),OLB = 10},
                                                          new Installment{Number = 2,CapitalRepayment = 222,InterestsRepayment = 24,ExpectedDate = new DateTime(2007, 2, 1),OLB = 100}
                                                      },
                                Events = new EventStock
                                             {
                                                 new RepaymentEvent{InstallmentNumber = 1,Principal = 200,Interests = 100,Commissions = 0, Penalties = 0,ClientType = OClientTypes.Group},
            //                                                 new LoanDisbursmentEvent{Date = TimeProvider.Today, Amount = 100, Commission = 0, ClientType = OClientTypes.Group }
                                             }
                            };

            Loan cloneLoan = loan.Copy();

            Assert.AreEqual("Code", cloneLoan.Code);
            Assert.AreEqual(1000, cloneLoan.Amount.Value);
            Assert.AreEqual(0.3, cloneLoan.InterestRate);
            Assert.AreEqual(OClientTypes.Group, cloneLoan.ClientType);

            _AssertSpecifiedInstallment(cloneLoan.GetInstallment(0), 1, new DateTime(2007, 1, 1), 2, 100, 10, 0, 0);
            _AssertSpecifiedInstallment(cloneLoan.GetInstallment(1), 2, new DateTime(2007, 2, 1), 24, 222, 100, 0, 0);
        }
Esempio n. 23
0
        public Loan Repay(Loan curentLoan,
                          IClient client,
                          int installmentNumber,
                          DateTime payDate,
                          OCurrency amount,
                          bool disableFees,
                          OCurrency manualFeesAmount,
                          OCurrency manualCommission,
                          bool disableInterests,
                          OCurrency manualInterestsAmount,
                          bool keepExpectedInstallment,
                          bool proportionPayment,
                          PaymentMethod paymentMethod,
                          string comment,
                          bool isPending)
        {
            if (payDate.Date < curentLoan.StartDate.Date)
            {
                throw new OpenCbsRepayException(OpenCbsRepayExceptionsEnum.RepaymentBeforeDisburse);
            }

            if (curentLoan.Events.GetRepaymentEvents().Any(r => !r.Deleted && r.Date > payDate))
            {
                throw new OpenCbsRepayException(OpenCbsRepayExceptionsEnum.RepaymentBeforeLastEventDate);
            }
            CheckOperationDate(payDate);

            Loan savedContract = curentLoan.Copy();
            using (SqlConnection conn = _loanManager.GetConnection())
            using (SqlTransaction sqlTransaction = conn.BeginTransaction())
            {
                try
                {
                    //Repay
                    // Accrued Interest Event generation
                    if (ApplicationSettings.GetInstance(_user.Md5).AccountingProcesses == OAccountingProcesses.Accrual)
                    {
                        DateTime dateTime = payDate;

                        AccruedInterestEvent e = savedContract.GetAccruedInterestEvent(dateTime);

                        if (e != null)
                        {
                            if (Teller.CurrentTeller != null && Teller.CurrentTeller.Id != 0)
                                e.TellerId = Teller.CurrentTeller.Id;

                            ServicesProvider.GetInstance().GetContractServices().AddAccruedInterestEvent(savedContract,
                                                                                                         e,
                                                                                                         sqlTransaction);
                        }
                    }

                    RepaymentEvent repayEvent = savedContract.Repay(installmentNumber, payDate, amount, disableFees,
                                                                    manualFeesAmount, manualCommission,
                                                                    disableInterests, manualInterestsAmount,
                                                                    keepExpectedInstallment, proportionPayment,
                                                                    paymentMethod, comment,
                                                                    isPending);

                    savedContract.EscapedMember = curentLoan.EscapedMember;
                    repayEvent.User = _user;
                    //the code below should be moved into event generation proccess
                    if (Teller.CurrentTeller != null && Teller.CurrentTeller.Id != 0)
                        repayEvent.TellerId = Teller.CurrentTeller.Id;

                    if (!isPending)
                    {
                        FundingLineEvent repayFlFundingLineEvent = new FundingLineEvent
                            {
                                Code =
                                    String.Concat("RE_", curentLoan.Code,
                                                  "_INS_", installmentNumber),
                                Type = OFundingLineEventTypes.Repay,
                                Amount =
                                    ApplicationSettings.GetInstance(
                                        _user != null
                                            ? _user.Md5
                                            : "")
                                                       .InterestsCreditedInFL
                                        ? amount
                                        : repayEvent.Principal,
                                Movement = OBookingDirections.Credit,
                                CreationDate = TimeProvider.Now,
                                FundingLine = curentLoan.FundingLine,
                                AttachTo = repayEvent
                            };
                        //the code below should be moved into event generation proccess
                        if (Teller.CurrentTeller != null && Teller.CurrentTeller.Id != 0)
                            repayFlFundingLineEvent.TellerId = Teller.CurrentTeller.Id;

                        //this line is to prevent errors from popping up when client makes a repayment of
                        //everything but the principal
                        if (repayFlFundingLineEvent.Amount > 0
                            || ApplicationSettings.GetInstance(_user != null ? _user.Md5 : "").InterestsCreditedInFL)
                            curentLoan.FundingLine.AddEvent(
                                new FundingLineServices(_user).AddFundingLineEvent(repayFlFundingLineEvent,
                                                                                   sqlTransaction));
                    }

                    foreach (RepaymentEvent loanEvent in savedContract.Events.GetLoanRepaymentEvents())
                    {
                        if (loanEvent.IsFired) continue;
                        loanEvent.Comment = comment;
                    }

                    _ePs.FireEvent(repayEvent, savedContract, sqlTransaction);
                    if (paymentMethod.Method == OPaymentMethods.Savings)
                        DoRepaymentFromSavings(savedContract, repayEvent, amount, sqlTransaction);

                    if (repayEvent.RepaymentType == OPaymentType.TotalPayment && savedContract.HasCompulsoryAmount())
                    {
                        SavingBookContract compulsorySaving = savedContract.CompulsorySavings;
                        SavingUnblockCompulsorySavingsEvent savingUnblockEvent =
                            compulsorySaving.GetUnblockCompulsorySavingEvent();
                        if (savingUnblockEvent != null)
                            _ePs.FireSavingUnblockEvent(savingUnblockEvent, compulsorySaving.Id, repayEvent.Id,
                                                        sqlTransaction);
                    }

                    // Put a copy of installments into the history
                    ArchiveInstallments(curentLoan, repayEvent, sqlTransaction);

                    CreditInsuranceEvent cie = savedContract.Events.GetCreditInsuranceEvents();
                    if (cie != null)
                        _ePs.FireEvent(cie, savedContract, sqlTransaction);

                    //Update Installments
                    foreach (Installment installment in savedContract.InstallmentList)
                        _instalmentManager.UpdateInstallment(installment, savedContract.Id, repayEvent.Id,
                                                             sqlTransaction);

                    for (int i = savedContract.Events.GetNumberOfEvents - 1; i >= 0; i--)
                    {
                        Event e = savedContract.Events.GetEvent(i);
                        if ((e is RepaymentEvent) || (e is LoanDisbursmentEvent))
                        {
                            e.Cancelable = true;
                            if (!e.Cancelable)
                                break;
                        }
                        else
                        {
                            break;
                        }
                    }

                    var repaymentEvents = (from item in savedContract.Events.GetRepaymentEvents()
                                           where item.ParentId == repayEvent.Id || item.Id == repayEvent.Id
                                           select item).ToList();
                    var listOfRble = (from item in repaymentEvents where item.Code == "RBLE" select item).ToList();
                    var listOfRgle = repaymentEvents.Except(listOfRble).ToList();
                    if (repayEvent.Code == "RBLE")
                        CallInterceptor(new Dictionary<string, object>
                        {
                            {"Loan", savedContract},
                            {
                                "Event", new RepaymentEvent
                                {
                                    Code = "RBLE",
                                    Principal = listOfRble.Sum(item => item.Principal.Value),
                                    Interests = listOfRble.Sum(item => item.Interests.Value),
                                    Commissions = listOfRble.Sum(item => item.Commissions.Value),
                                    Penalties = listOfRble.Sum(item => item.Fees.Value),
                                    Id = repayEvent.Id,
                                    Date = repayEvent.Date
                                }
                            },
                            {"SqlTransaction", sqlTransaction}
                        });
                    CallInterceptor(new Dictionary<string, object>
                    {
                        {"Loan", savedContract},
                        {
                            "Event", new RepaymentEvent
                            {
                                Code = "RGLE",
                                Principal = listOfRgle.Sum(item => item.Principal.Value),
                                Interests = listOfRgle.Sum(item => item.Interests.Value),
                                Commissions = listOfRgle.Sum(item => item.Commissions.Value),
                                Penalties = listOfRgle.Sum(item => item.Fees.Value),
                                Id = repayEvent.Id,
                                Date = repayEvent.Date
                            }
                        },
                        {"SqlTransaction", sqlTransaction}
                    });

                    if (savedContract.AllInstallmentsRepaid)
                    {
                        _ePs.FireEvent(savedContract.GetCloseEvent(payDate), savedContract, sqlTransaction);
                    }

                    _loanManager.UpdateLoan(savedContract, sqlTransaction);

                    if (sqlTransaction != null)
                    {
                        sqlTransaction.Commit();
                        sqlTransaction.Dispose();
                    }

                    SetClientStatus(savedContract, client);
                    savedContract.EscapedMember = null;
                    return savedContract;
                }
                catch (Exception)
                {
                    if (sqlTransaction != null) sqlTransaction.Rollback();
                    throw;
                }
            }
        }