/// <summary> /// Cancels last event from given contract, restores associated installment status. /// and restores Client(individual, corporate) status /// </summary> /// <param name="contract">Contract</param> /// <param name="pClient"></param> /// <param name="comment"> </param> /// <returns>Cancelled event</returns> public Event CancelLastEvent(Loan contract, IClient pClient, string comment) { using (SqlConnection conn = _loanManager.GetConnection()) using (SqlTransaction sqlTransaction = conn.BeginTransaction()) { Event cancelledEvent; try { Event evnt = contract.GetLastNonDeletedEvent(); if (null == evnt) throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.EventIsNull); if (!evnt.Cancelable) throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.EventNotCancelable); if (string.IsNullOrEmpty(comment)) throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.EventCommentIsEmpty); if (pClient is Person) evnt.ClientType = OClientTypes.Person; else if (pClient is Group) evnt.ClientType = OClientTypes.Group; else if (pClient is Corporate) evnt.ClientType = OClientTypes.Corporate; else if (pClient is Village) evnt.ClientType = OClientTypes.Village; var evntCopy = evnt.Copy(); evntCopy.Id = evnt.ParentId ?? evnt.Id; CallInterceptor(new Dictionary<string, object> { {"Loan", contract}, {"Event", evntCopy}, {"Deleted", true}, {"SqlTransaction", sqlTransaction} }); if (ApplicationSettings.GetInstance(User.CurrentUser.Md5).UseMandatorySavingAccount) { var id = 0; if (int.TryParse(evnt.Comment, out id)) ServicesProvider.GetInstance() .GetSavingServices() .DeleteEvent(new SavingWithdrawEvent() { Id = id, CancelDate = TimeProvider.Today }); } evnt.Comment = comment; evnt.CancelDate = TimeProvider.Now; // if event is loan close event, we delete it first if (evnt is LoanCloseEvent) { _ePs.CancelFireEvent(evnt, sqlTransaction, contract, contract.Product.Currency.Id); evnt.Deleted = true; evnt = contract.GetLastNonDeletedEvent(); if (pClient is Person) evnt.ClientType = OClientTypes.Person; else if (pClient is Group) evnt.ClientType = OClientTypes.Group; else if (pClient is Corporate) evnt.ClientType = OClientTypes.Corporate; else if (pClient is Village) evnt.ClientType = OClientTypes.Village; evnt.Comment = comment; evnt.CancelDate = TimeProvider.Now; } _ePs.CancelFireEvent(evnt, sqlTransaction, contract, contract.Product.Currency.Id); _ePs.UpdateCommentForLoanEvent(evnt, sqlTransaction); evnt.Deleted = true; //in case total repayment there could be several rep events foreach (RepaymentEvent evt in contract.Events.GetRepaymentEvents()) { if ((evt.ParentId == evnt.ParentId && evnt.ParentId != null) || (evt.Id == evnt.ParentId)) { evt.Deleted = true; evt.Comment = evnt.Comment; _ePs.UpdateCommentForLoanEvent(evt, sqlTransaction); } } if (evnt.Code == "ATR" || evnt.Code == "RBLE") { foreach (Event cie in contract.Events) { if (cie is CreditInsuranceEvent) if (cie.Deleted == false && cie.Code == "LCIP") { _ePs.CancelFireEvent(cie, sqlTransaction, contract, contract.Product.Currency.Id); cie.Deleted = true; } } } cancelledEvent = evnt; // Restore the installment status. UnarchiveInstallments(contract, cancelledEvent, sqlTransaction); contract.InstallmentList = _instalmentManager.SelectInstallments(contract.Id, sqlTransaction); contract.GivenTranches = _loanManager.SelectTranches(contract.Id, sqlTransaction); contract.NbOfInstallments = contract.InstallmentList.Count; //return interest rate after delete event contract.InterestRate = GetPreviousRate(contract); if (evnt is LoanDisbursmentEvent) { contract.Disbursed = false; } else if (evnt is RescheduleLoanEvent) { contract.Rescheduled = false; } else if (cancelledEvent is TrancheEvent) { contract.Amount = contract.Amount - (cancelledEvent as TrancheEvent).Amount; TrancheEvent trancheEventToDelete = new TrancheEvent(); foreach (var trancheEvent in contract.GivenTranches) { if (trancheEvent.Id == cancelledEvent.Id) { trancheEventToDelete = trancheEvent; } } contract.GivenTranches.Remove(trancheEventToDelete); if (contract.AllInstallmentsRepaid) { contract.ContractStatus = OContractStatus.Closed; contract.Closed = true; //Restore interest rate contract.InterestRate = contract.GivenTranches[contract.GivenTranches.Count - 1].InterestRate.Value; } } else if (cancelledEvent is RepaymentEvent) { //restor a person of the corporate _clientManager.RestorMemberOfGroupByEventId(cancelledEvent.Id, contract, sqlTransaction); contract.EscapedMember = null; if (cancelledEvent.RepaymentType == OPaymentType.TotalPayment) { if (contract.HasCompulsoryAmount()) { SavingEvent savingUnblockEvent = contract.CompulsorySavings.Events.FirstOrDefault( e => e.LoanEventId == cancelledEvent.Id); if (savingUnblockEvent != null) { _savingEventManager.DeleteSavingsEventByLoanEventId( cancelledEvent.ParentId ?? cancelledEvent.Id, sqlTransaction); savingUnblockEvent.Deleted = true; } } } } if (!contract.WrittenOff && !contract.AllInstallmentsRepaid) { contract.Closed = false; if (evnt is LoanDisbursmentEvent) contract.ContractStatus = OContractStatus.Validated; else { contract.ContractStatus = evnt is LoanValidationEvent ? OContractStatus.Pending : OContractStatus.Active; } } //come back after write off if (evnt is WriteOffEvent) { contract.WrittenOff = false; contract.ContractStatus = OContractStatus.Active; CreditInsuranceEvent lciw = contract.GetNotDeletedInsuranceWriteOff(); if (lciw != null) { _ePs.CancelFireEvent(lciw, sqlTransaction, contract, contract.Product.Currency.Id); lciw.Deleted = true; } } _loanManager.UpdateLoan(contract, sqlTransaction); FundingLineEvent flFundingLineEvent; if (cancelledEvent is LoanDisbursmentEvent) { if (contract.HasCompulsoryAmount()) { _savingEventManager.DeleteSavingsEventByLoanEventId( cancelledEvent.ParentId ?? cancelledEvent.Id, sqlTransaction); SavingBlockCompulsarySavingsEvent savingBlockEvent = contract.CompulsorySavings.GetBlockCompulsorySavingEvent(); savingBlockEvent.Deleted = true; } LoanDisbursmentEvent temp = (LoanDisbursmentEvent) cancelledEvent; flFundingLineEvent = new FundingLineEvent { Code = String.Concat("DE_", contract.Code), Type = OFundingLineEventTypes.Disbursment, Amount = temp.Amount, Movement = OBookingDirections.Debit, CreationDate = TimeProvider.Now, FundingLine = contract.FundingLine }; DeleteFundingLineEvent(ref contract, flFundingLineEvent, sqlTransaction); _clientManager.DecrementLoanCycleByContractId(contract.Id, sqlTransaction); // delete entry fee events foreach (Event contractEvent in contract.Events) { if (contractEvent.Deleted) continue; if (contractEvent is LoanEntryFeeEvent) { _ePs.CancelFireEvent(contractEvent, sqlTransaction, contract, contract.Product.Currency.Id); contractEvent.Deleted = true; CallInterceptor(new Dictionary<string, object> { {"Loan", contract}, {"Event", contractEvent}, {"Deleted", true}, {"SqlTransaction", sqlTransaction} }); } if (contractEvent is CreditInsuranceEvent) { _ePs.CancelFireEvent(contractEvent, sqlTransaction, contract, contract.Product.Currency.Id); contractEvent.Deleted = true; } } if (evnt.ClientType == OClientTypes.Person) { if (_econimcActivityServices.EconomicActivityLoanHistoryExists(contract.Id, pClient.Id, sqlTransaction)) _econimcActivityServices.UpdateDeletedEconomicActivityLoanHistory(contract.Id, pClient.Id, ((Person) pClient) .Activity.Id, sqlTransaction, true); } else if (evnt.ClientType == OClientTypes.Group) { foreach (Member member in ((Group) pClient).Members) { if (_econimcActivityServices.EconomicActivityLoanHistoryExists(contract.Id, member.Tiers.Id, sqlTransaction)) _econimcActivityServices.UpdateDeletedEconomicActivityLoanHistory(contract.Id, member.Tiers.Id, ((Person) member.Tiers) .Activity.Id, sqlTransaction, true); } } else if (evnt.ClientType == OClientTypes.Corporate) { if (_econimcActivityServices.EconomicActivityLoanHistoryExists(contract.Id, pClient.Id, sqlTransaction)) _econimcActivityServices.UpdateDeletedEconomicActivityLoanHistory(contract.Id, pClient.Id, ((Corporate) pClient) .Activity.Id, sqlTransaction, true); } } else if (cancelledEvent is RepaymentEvent) { RepaymentEvent temp = (RepaymentEvent) cancelledEvent; decimal amountCalc = (temp.Principal.HasValue ? temp.Principal.Value : 0) + (ApplicationSettings.GetInstance(_user != null ? _user.Md5 : ""). InterestsCreditedInFL ? ((temp.Interests.HasValue ? temp.Interests.Value : 0) + (temp.Penalties.HasValue ? temp.Penalties.Value : 0)) : 0); if (amountCalc > 0 || ApplicationSettings.GetInstance(_user != null ? _user.Md5 : "").InterestsCreditedInFL) { flFundingLineEvent = new FundingLineEvent { Code = String.Concat("RE_", contract.Code, "_INS_", temp.InstallmentNumber), Type = OFundingLineEventTypes.Repay, Amount = amountCalc, CreationDate = TimeProvider.Now, FundingLine = _fundingLineServices.SelectFundingLineById(contract.FundingLine.Id, sqlTransaction) }; //temporary line to check whether funding line has enough amount to debit repayment event flFundingLineEvent.Movement = OBookingDirections.Debit; _fundingLineServices.ApplyRulesAmountEventFundingLine(flFundingLineEvent); flFundingLineEvent.Movement = OBookingDirections.Credit; DeleteFundingLineEvent(ref contract, flFundingLineEvent, sqlTransaction); } } CancelSavingsEvent(cancelledEvent, sqlTransaction); sqlTransaction.Commit(); sqlTransaction.Dispose(); SetClientStatus(contract, pClient); } catch (Exception) { sqlTransaction.Rollback(); throw; } return cancelledEvent; } }
public void UpdateLoan(Loan pLoan, SqlTransaction pSqlTransac) { string q = @"UPDATE Credit SET loanofficer_id = @loanOfficerId, fundingLine_id = @fundingLine_id, disbursed = @disbursed, rescheduled = @rescheduled, nb_of_installment = @NbOfInstallment, amount = @Amount, interest_rate = @InterestRate, grace_period = @GracePeriode, anticipated_total_repayment_penalties = @AnticipatedTotalRepayment, anticipated_partial_repayment_penalties = @AnticipatedPartialRepayment, non_repayment_penalties_based_on_overdue_principal = @NRPBOOP, non_repayment_penalties_based_on_initial_amount = @NRPBOIA, non_repayment_penalties_based_on_olb = @NRPBOOLB, non_repayment_penalties_based_on_overdue_interest = @NRPBOOI, synchronize = @synchronize, grace_period_of_latefees = @grace_period_of_latefees, [number_of_drawings_loc] = @DrawingsNumber, [amount_under_loc] = @AmountUnderLoc, [maturity_loc] = @MaturityLoc, [anticipated_partial_repayment_base] = @AnticipatedPartialRepaymentPenaltiesBase, [anticipated_total_repayment_base] = @AnticipatedTotalRepaymentPenaltiesBase, [schedule_changed] = @schedule_changed, [written_off] = @written_off, [insurance]=@insurance WHERE id = @id"; using(OpenCbsCommand c = new OpenCbsCommand(q, pSqlTransac.Connection, pSqlTransac)) { SetLoanForUpdate(c, pLoan); c.ExecuteNonQuery(); } q = @"UPDATE Contracts SET start_date = @startDate, align_disbursed_date = @align_disbursed_date, close_date = @closeDate, closed = @closed, status = @status, loan_purpose = @loanPurpose, comments = @comments, activity_id = @activityId, preferred_first_installment_date = @preferredFirstInstallmentDate WHERE id = @id"; using(OpenCbsCommand c = new OpenCbsCommand(q, pSqlTransac.Connection, pSqlTransac)) { c.AddParam("@startDate", pLoan.StartDate); c.AddParam("@align_disbursed_date", pLoan.AlignDisbursementDate); c.AddParam("@closeDate", pLoan.CloseDate); c.AddParam("@closed", pLoan.Closed); c.AddParam("@status", Convert.ToInt32(pLoan.ContractStatus)); c.AddParam("@id", pLoan.Id); c.AddParam("@loanPurpose", pLoan.LoanPurpose); c.AddParam("@comments", pLoan.Comments); c.AddParam("@activityId", pLoan.EconomicActivityId); c.AddParam("@preferredFirstInstallmentDate", pLoan.FirstInstallmentDate); c.ExecuteNonQuery(); } // Updating Tiers status to 'active' if (pLoan.Project != null && pLoan.Project.Client != null) { q = @"UPDATE Tiers SET active = @active WHERE id = @id"; using (OpenCbsCommand c = new OpenCbsCommand(q, pSqlTransac.Connection, pSqlTransac)) { c.AddParam("@active", pLoan.Project.Client.Active); c.AddParam("@id", pLoan.Project.Client.Id); c.ExecuteNonQuery(); } } if (pLoan.EscapedMember != null && pLoan.Project != null && pLoan.Project.Client != null) { //delete member from the group _clientManager.UpdatePersonFromGroup(pLoan.EscapedMember.Tiers.Id, pLoan.Project.Client.Id, pSqlTransac); q = @"UPDATE LoanShareAmounts SET payment_date = @payment_date, event_id = @event_id WHERE person_id = @person_id AND group_id = @group_id AND contract_id = @contract_id"; using (OpenCbsCommand c = new OpenCbsCommand(q, pSqlTransac.Connection, pSqlTransac)) { c.AddParam("@payment_date", pLoan.GetLastNonDeletedEvent().Date); c.AddParam("@event_id", pLoan.GetLastNonDeletedEvent().Id); c.AddParam("@person_id", pLoan.EscapedMember.Tiers.Id); c.AddParam("@group_id", pLoan.Project.Client.Id); c.AddParam("@contract_id", pLoan.Id); c.ExecuteNonQuery(); } pLoan.EscapedMember = null; } _DeleteGuarantorsFromLoan(pLoan.Id, pSqlTransac); foreach (Guarantor guarantor in pLoan.Guarantors) { _AddGuarantor(guarantor, pLoan.Id, pSqlTransac); } _DeleteCollateralsFromLoan(pLoan.Id, pSqlTransac); foreach (ContractCollateral collateral in pLoan.Collaterals) { AddCollateral(collateral, pLoan.Id, pSqlTransac); } // Compulsory savings handling if (pLoan.CompulsorySavings != null) { int loanSavingsId = 0; string sqlCompulsory = @"SELECT id FROM LoansLinkSavingsBook WHERE loan_id = @loan_id"; using (OpenCbsCommand c = new OpenCbsCommand(sqlCompulsory, pSqlTransac.Connection, pSqlTransac)) { c.AddParam("@loan_id", pLoan.Id); using (OpenCbsReader r = c.ExecuteReader()) { if (r == null || r.Empty) { loanSavingsId = 0; } else { r.Read(); loanSavingsId = r.GetInt("id"); } } } if (loanSavingsId == 0) { sqlCompulsory = @"INSERT INTO LoansLinkSavingsBook ([loan_id], [savings_id], [loan_percentage]) VALUES (@loanId, @savingsId, @loanPercentage)"; using (OpenCbsCommand c = new OpenCbsCommand(sqlCompulsory, pSqlTransac.Connection, pSqlTransac)) { if (pLoan.CompulsorySavings != null) c.AddParam("@savingsId", pLoan.CompulsorySavings.Id); else c.AddParam("@savingsId", null); c.AddParam("@loanId", pLoan.Id); c.AddParam("@loanPercentage", pLoan.CompulsorySavingsPercentage); c.ExecuteNonQuery(); } } else { sqlCompulsory = @"UPDATE [LoansLinkSavingsBook] SET savings_id = @savingsId, loan_percentage = @loanPercentage WHERE loan_id = @loanId"; using (OpenCbsCommand c = new OpenCbsCommand(sqlCompulsory, pSqlTransac.Connection, pSqlTransac)) { c.AddParam("@savingsId", pLoan.CompulsorySavings.Id); c.AddParam("@loanId", pLoan.Id); c.AddParam("@loanPercentage", pLoan.CompulsorySavingsPercentage); c.ExecuteNonQuery(); } } } }
public void WaiveFee(ref Loan credit, ref IClient client) { Event foundEvent = credit.GetLastNonDeletedEvent(); if (foundEvent == null) throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.EventIsNull); if (!(foundEvent is RepaymentEvent)) throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.WrongEvent); if (!foundEvent.Cancelable) throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.EventNotCancelable); if (((RepaymentEvent) foundEvent).Fees == 0) throw new OpenCbsContractSaveException(OpenCbsContractSaveExceptionEnum.ZeroFee); string fee = ((RepaymentEvent) foundEvent).Fees.GetFormatedValue(credit.UseCents); String comment = "FEE WAIVED [" + fee.Replace("�", string.Empty) + "]"; //foundEvent.Comment = comment; ////EventProcessorServices eps = ServicesProvider.GetInstance().GetEventProcessorServices(); ////eps.UpdateCommentForLoanEvent(foundEvent, null); CancelLastEvent(credit, client, comment); //update a loan for a client foreach (Project prj in client.Projects) { foreach (Loan loan in prj.Credits) { if (loan.Code == credit.Code) { loan.Disbursed = credit.Disbursed; } } } OCurrency amount = ((RepaymentEvent) foundEvent).Principal + ((RepaymentEvent) foundEvent).Interests + ((RepaymentEvent) foundEvent).Fees; comment = "ID[" + foundEvent.Id + "] FEE WAIVED [" + fee.Replace("�", string.Empty) + "]"; Loan l = Repay(credit, client, foundEvent.InstallmentNumber, foundEvent.Date, amount, true, 0, 0, false, 0, true, false, foundEvent.PaymentMethod, comment, false); credit.Events = l.Events; }
private void ShowLoanInListView(VillageMember member, Loan loan) { Person person = (Person)member.Tiers; ApplicationSettings dataParam = ApplicationSettings.GetInstance(string.Empty); int decimalPlaces = dataParam.InterestRateDecimalPlaces; ListViewItem item = new ListViewItem(person.Name) { Tag = member }; if (loan == null || _village.EstablishmentDate==null) return; if (loan.CreationDate.Date >= _village.EstablishmentDate.Value.Date && _village.Id == loan.NsgID) { item.SubItems.Add(loan.ProductName); item.SubItems.Add(loan.Code); item.SubItems.Add(MultiLanguageStrings.GetString(Ressource.ClientForm, loan.ContractStatus + ".Text")); item.SubItems.Add(loan.Amount.GetFormatedValue(loan.UseCents)); item.SubItems.Add( loan.CalculateActualOlbBasedOnRepayments().GetFormatedValue(loan.UseCents)); item.SubItems.Add(loan.Product.Currency.Name); item.SubItems.Add(Math.Round(loan.InterestRate*100m, decimalPlaces).ToString()); item.SubItems.Add(loan.InstallmentType.Name); item.SubItems.Add(loan.NbOfInstallments.ToString()); item.SubItems.Add(loan.AlignDisbursementDate.ToShortDateString()); if (loan.GetLastNonDeletedEvent() != null) item.SubItems.Add(loan.GetLastNonDeletedEvent().Date.ToShortDateString()); else item.SubItems.Add("-"); if (loan.NextInstallment != null) { item.SubItems.Add(loan.NextInstallment.ExpectedDate.ToShortDateString()); item.SubItems.Add( ServicesHelper.ConvertDecimalToString(loan.NextInstallment.Amount.Value)); } else { item.SubItems.Add("-"); item.SubItems.Add("-"); } item.SubItems.Add(loan.CloseDate.ToShortDateString()); if (member.LeftDate != null) item.BackColor = Color.Red; listViewLoans.Items.Add(item); } }