public CreditContractRepayment(Loan pContract, CreditContractOptions pCCo, DateTime pDate,int pInstallmentNumber, User pUser, ApplicationSettings pGeneralSettings,NonWorkingDateSingleton pNonWorkingDate) { _generalSettings = pGeneralSettings; _nWds = pNonWorkingDate; _date = pDate; _installmentNumber = pInstallmentNumber; PaidIstallments = new List<Installment>(); _amountToRepayTottalyLoan = new CalculateMaximumAmountToRepayStrategy(pCCo, pContract.Copy(), pUser, _generalSettings,_nWds); _amountToRegradingLoan = new CalculateMaximumAmountToRegradingLoanStrategy(pCCo, pContract.Copy(), pUser, _generalSettings, _nWds); _amountToRepayInstallment = new CalculateAmountToRepaySpecifiedInstallmentStrategy(pCCo, pContract.Copy(), pUser, _generalSettings, _nWds); _calculateInstallments = new Repayment.RepayLateInstallments.CalculateInstallments(pCCo, pContract, pUser, _generalSettings, _nWds); _feesForAnticipatedRepayment = new CalculateAnticipatedFeesStrategy(pCCo, pContract, _generalSettings); _repayNextInstallments = new RepayNextInstallmentsStrategy(pContract, pCCo, pUser, _generalSettings); _repaymentMethod = new RepaymentMethod(pContract,pCCo); CalculateMaximumAmountAuthorizedToRepay(); CalculateAmountToRegradingLoan(); CalculateMaximumAmountForEscapedMember(); LoanOptions = pCCo; }
public OCurrency CalculateAmountToRepaySpecifiedInstallment(int pNumber, DateTime pDate, bool pCancelFees, OCurrency pManualFeesAmount, OCurrency pManualCommissionAmount, bool pDisableInterests, OCurrency pManualInterests, bool pKeepExpectedInstallment) { CreditContractOptions cCo = new CreditContractOptions(Product.LoanType, pKeepExpectedInstallment, pCancelFees, pManualFeesAmount, pManualCommissionAmount, pDisableInterests, pManualInterests, Product.AnticipatedTotalRepaymentPenaltiesBase); CreditContractRepayment cCr = new CreditContractRepayment(this, cCo, pDate, pNumber, _user, _generalSettings, _nwdS); return cCr.AmountToRepayInstallment; }
public OCurrency CalculateMaximumAmountForEscapedMember(int pNumber, DateTime pDate, bool pCancelFees, OCurrency pManualFeesAmount, OCurrency pManualCommissionAmount, bool pDisableInterests, OCurrency pManualInterests, bool pKeepExpectedInstallment, OCurrency pLoanShareAmount) { var cCo = new CreditContractOptions(Product.LoanType, pKeepExpectedInstallment, pCancelFees, pManualFeesAmount, pManualCommissionAmount, pDisableInterests, pManualInterests, Product.AnticipatedTotalRepaymentPenaltiesBase, Product.IsExotic); var cCr = new CreditContractRepayment(this, cCo, pDate, pNumber, _user, _generalSettings, _nwdS); return cCr.MaximumAmountForEscapedMember; }
/// <summary> /// This method manages all the repayment cases implemented in OCTOPUS /// </summary> /// <param name="pNumber">pNumber of the installment paid</param> /// <param name="pDate">pDate of the payment</param> /// <param name="pAmountPaid">amount paid by the client which can be lower, equal or greater than the expected amount for an installment</param> /// <param name="cancelFees">when true, cancel anticipated payment Commission</param> /// <param name="manualFeesAmount">manual amount of commission (when anticipated payment commission are cancelled)</param> /// <returns>A RepaymentEvent or null if : /// - repayment amount lower than 0 /// - repayment amount greater than olb + interestsToPay + commission /// - installment already repaid /// - bad loan and past due days greater than 180 /// </returns> /// <param name="manualCommissionAmount"></param> /// <param name="disableInterests"></param> /// <param name="manualInterests"></param> /// <param name="keepExpectedInstallment"></param> /// <param name="paymentMethod"></param> /// <param name="comment"></param> /// <param name="pending"></param> public RepaymentEvent Repay(int pNumber, DateTime pDate, OCurrency pAmountPaid, bool cancelFees, OCurrency manualFeesAmount, OCurrency manualCommissionAmount, bool disableInterests, OCurrency manualInterests, bool keepExpectedInstallment, OPaymentMethods paymentMethod, string comment, bool pending) { OCurrency anticipatePayment = CalculateAnticipateInteresAmountForClosure(pDate, OPaymentType.PartialPayment) + CalculateTotalNonRepaymentPenalties(pDate); if (anticipatePayment >= pAmountPaid || (anticipatePayment == 0 && GetInstallment(pNumber - 1).ExpectedDate <= pDate)) { keepExpectedInstallment = true; } var cCo = new CreditContractOptions(Product.LoanType, keepExpectedInstallment, cancelFees, manualFeesAmount, manualCommissionAmount, disableInterests, manualInterests, Product.AnticipatedTotalRepaymentPenaltiesBase, Product.IsExotic); var cCr = new CreditContractRepayment(this, cCo, pDate, pNumber, _user, _generalSettings, _nwdS); if (AmountComparer.Compare(pAmountPaid, cCr.MaximumAmountAuthorizeToRepay, pNumber) > 0) { return null; } OCurrency principalEvent = 0; OCurrency interestEvent = 0; OCurrency interestPrepayment = 0; OCurrency penaltiesEvent = 0; OCurrency commissionsEvent = 0; OCurrency manualInterestEvent = cCo.ManualInterestsAmount; int pastDueDays = CalculatePastDueSinceLastRepayment(pDate); OPaymentType paymentType = OPaymentType.StandardPayment; foreach (Installment installment in InstallmentList) { if (!installment.IsRepaid && installment.Number == pNumber && !keepExpectedInstallment) { paymentType = OPaymentType.PartialPayment; } } //we have total repayment for a person if(EscapedMember != null) { paymentType = OPaymentType.PartialPayment; keepExpectedInstallment = false; cCo.KeepExpectedInstallments = false; } if (AmountComparer.Compare(pAmountPaid, cCr.MaximumAmountAuthorizeToRepay, pNumber) == 0 && !keepExpectedInstallment) { paymentType = OPaymentType.TotalPayment; } cCr.Repay(pAmountPaid, ref penaltiesEvent, ref commissionsEvent, ref interestEvent, ref interestPrepayment, ref principalEvent, ref manualInterestEvent, paymentType); //this part of code to correct calculation of principal OCurrency principalAmount = principalEvent; foreach (RepaymentEvent rPayment in Events.GetRepaymentEvents()) { if (!rPayment.Deleted) principalAmount += rPayment.Principal; if (principalAmount > Amount) { principalEvent -= Math.Round(principalAmount.Value, 2) - Amount; } } // when we keep initial schedule and total payment if (AmountComparer.Compare(pAmountPaid, cCr.MaximumAmountAuthorizeToRepay, pNumber) == 0 && (pNumber != InstallmentList.Count) && AllInstallmentsRepaid) { paymentType = OPaymentType.TotalPayment; } ////////////////////////////////////////////////////////////// RepaymentEvent rPe = CreateRepaymentEvent(pNumber, pDate, penaltiesEvent, commissionsEvent, interestEvent, interestPrepayment, principalEvent, pastDueDays, _clientType == OClientTypes.Group, paymentType, pending); if (AllInstallmentsRepaid && !pending) { if (ContractStatus != OContractStatus.WrittenOff) { _closed = true; ContractStatus = OContractStatus.Closed; CloseDate = pDate; } // check if Client has other 'active' loans if so, mark him as active client if (Project != null) foreach (var loan in Project.Credits) Project.Client.Active = loan.ContractStatus == OContractStatus.Active; } //Event identification Events.Add(GenerateRepaymentEvents(cCr, pDate, penaltiesEvent, commissionsEvent, interestEvent, interestPrepayment, principalEvent, pastDueDays, paymentType, pending, pNumber, paymentMethod)); //principal amount correction in case of shit which is taken place when we do big prepayment //please remove it when all shity contracts will be closed OCurrency paidPrincipal = 0; foreach (RepaymentEvent repaymentEvent in Events.GetLoanRepaymentEvents()) { if(repaymentEvent.Deleted == false) { paidPrincipal += repaymentEvent.Principal; } if(paidPrincipal > Amount) { repaymentEvent.Principal += Amount - paidPrincipal; } } ////////////////////////////////////////////////////////////////////////////////////////////// _installmentList.Sort((x, y) => x.ExpectedDate.CompareTo(y.ExpectedDate)); foreach (Installment installment in InstallmentList) { //setup paid date for installments if (installment.IsRepaid && installment.Number > pNumber) { installment.PaidDate = pDate; installment.PaymentMethod = paymentMethod; installment.Comment = comment; installment.IsPending = pending; } else if (installment.Number == pNumber) { installment.PaidDate = pDate; installment.PaymentMethod = paymentMethod; installment.Comment = comment; installment.IsPending = pending; } installment.OLB = CalculateExpectedOlb(installment.Number, keepExpectedInstallment); } EscapedMember = null; return rPe; }
public OCurrency CalculateMaximumAmountAuthorizedToRepay(int pNumber, DateTime pDate, bool pCancelFees, OCurrency pManualFeesAmount, OCurrency pManualCommissionAmount, bool pDisableInterests, OCurrency pManualInterests, bool pKeepExpectedInstallment, bool pIsForExoticProduct) { Loan fakeLoan = Copy(); if (_generalSettings.AccountingProcesses == OAccountingProcesses.Accrual && !pKeepExpectedInstallment) { fakeLoan.CreateLoanInterestAccruingEvent(pDate); } CreditContractOptions cCo = new CreditContractOptions(Product.LoanType, pKeepExpectedInstallment, pCancelFees, pManualFeesAmount, pManualCommissionAmount, pDisableInterests, pManualInterests, Product.AnticipatedTotalRepaymentPenaltiesBase, pIsForExoticProduct); CreditContractRepayment cCr = new CreditContractRepayment(fakeLoan, cCo, pDate, pNumber, _user, _generalSettings, _nwdS); return cCr.MaximumAmountAuthorizeToRepay; }