Exemple #1
0
        /// <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;
            }
        }