} // GetStateAt public void Recalculate(Loan loan, DateTime dateTime) { var payEarlyCalc = new LoanRepaymentScheduleCalculator(loan, dateTime, this.amountToChargeFrom); payEarlyCalc.GetState(); try { long nlLoanId = serviceInstance.GetLoanByOldID(loan.Id, loan.Customer.Id); if (nlLoanId > 0) { var nlModel = serviceInstance.GetLoanState(loan.Customer.Id, nlLoanId, dateTime, 1); Log.InfoFormat("<<<Recalculate NL_Compare {0}\n 'old' loan: {1} >>>", nlModel, loan); } else { Log.InfoFormat("<<<Recalculate NL loan for oldid {0} not found >>>", loan.Id); } } catch (Exception) { Log.InfoFormat("<<< NL_Compare Fail at: {0}", Environment.StackTrace); } } // Recalculate
} // MakePayment public LoanScheduleItem GetStateAt(Loan loan, DateTime dateTime) { var payEarlyCalc = new LoanRepaymentScheduleCalculator(loan, dateTime, this.amountToChargeFrom); var result = payEarlyCalc.GetState(); try { long nlLoanId = serviceInstance.GetLoanByOldID(loan.Id, loan.Customer.Id); if (nlLoanId > 0) { var nlModel = serviceInstance.GetLoanState(loan.Customer.Id, nlLoanId, dateTime, 1); Log.InfoFormat("<<<GetStateAt NL_Compare at : {0} ; nlModel : {1} loan: {2} >>>", Environment.StackTrace, nlModel, loan); } else { Log.InfoFormat("<<<GetStateAt NL loan for oldid {0} not found >>>", loan.Id); } } catch (Exception) { Log.InfoFormat("<<<GetStateAt NL_Compare Fail at : {0}", Environment.StackTrace); } return(result); } // GetStateAt
} // constructor /// <summary> /// Заплатить за кредит. Платёж может быть произвольный. Early, On time, Late. /// Perform loan payment. Payment can be manual. Early, On time, Late. /// </summary> public virtual decimal PayLoan( Loan loan, string transId, decimal amount, string ip, DateTime?term = null, string description = "payment from customer", bool interestOnly = false, string sManualPaymentMethod = null, NL_Payments nlPayment = null) { int customerID = loan.Customer.Id; var paymentTime = term ?? DateTime.UtcNow; var oldLoan = loan.Clone(); const string Manual = "--- manual ---"; string otherMethod = transId == Manual ? "Manual" : "Auto"; var loanTransactionMethod = this.loanTransactionMethodRepository.FindOrDefault(sManualPaymentMethod, otherMethod); var transaction = this.session.BeginTransaction(); var transactionItem = new PaypointTransaction { Amount = amount, Description = description, PostDate = paymentTime, Status = LoanTransactionStatus.Done, PaypointId = transId, IP = ip, LoanRepayment = oldLoan.Principal - loan.Principal, Interest = loan.InterestPaid - oldLoan.InterestPaid, InterestOnly = interestOnly, LoanTransactionMethod = loanTransactionMethod }; try { loan.AddTransaction(transactionItem); List <InstallmentDelta> deltas = loan.Schedule.Select(inst => new InstallmentDelta(inst)) .ToList(); var calculator = new LoanRepaymentScheduleCalculator(loan, paymentTime, this.amountToChargeFrom); calculator.RecalculateSchedule(); if (this._historyRepository != null) { var historyRecord = new LoanHistory(loan, paymentTime); this._historyRepository.SaveOrUpdate(historyRecord); } // if loan.UpdateStatus(paymentTime); if (loan.Customer != null) { loan.Customer.UpdateCreditResultStatus(); } if (loan.Id > 0) { foreach (InstallmentDelta dlt in deltas) { dlt.SetEndValues(); if (dlt.IsZero) { continue; } loan.ScheduleTransactions.Add(new LoanScheduleTransaction { Date = DateTime.UtcNow, FeesDelta = dlt.Fees.EndValue - dlt.Fees.StartValue, InterestDelta = dlt.Interest.EndValue - dlt.Interest.StartValue, Loan = loan, PrincipalDelta = dlt.Principal.EndValue - dlt.Principal.StartValue, Schedule = dlt.Installment, StatusAfter = dlt.Status.EndValue, StatusBefore = dlt.Status.StartValue, Transaction = transactionItem }); } // for each delta } // if if (nlPayment != null) { Log.InfoFormat("PayLoan: oldLoanID: {0} customer: {1} nlpayment {2}", loan.Id, customerID, nlPayment); // override those for backword compatibility nlPayment.PaymentMethodID = loanTransactionMethod.Id; nlPayment.Notes = description; nlPayment.CreationTime = DateTime.UtcNow; nlPayment.PaymentTime = paymentTime; nlPayment.Amount = amount; nlPayment.PaymentStatusID = (int)NLPaymentStatuses.Active; Log.InfoFormat("PayLoan: overriden nlpayment {0}", nlPayment); long nlLoanId = serviceInstance.GetLoanByOldID(loan.Id, customerID); if (nlLoanId == 0) { Log.InfoFormat("Failed to find nl loan for oldLoanID {0}, customer {1}", loan.Id, customerID); } else { nlPayment.LoanID = nlLoanId; // use argument's nlPayment data: CreatedByUserID if (nlPayment.PaymentSystemType == NLPaymentSystemTypes.Paypoint) { // workaround - from MakeAutomaticPayment sent transactionid with timestamp concated var card = loan.Customer.PayPointCards.FirstOrDefault(x => transId.StartsWith(x.TransactionId)); if (card == null) { Log.InfoFormat("PayPointCard for customer {0}, transId={1}, oldLoanID={2}, nl loanID={3} not found. nl payment\n {4}{5}", customerID, transId, loan.Id, nlPayment.LoanID, AStringable.PrintHeadersLine(typeof(NL_Payments)), nlPayment.ToStringAsTable()); } else { nlPayment.PaypointTransactions.Clear(); nlPayment.PaypointTransactions.Add(new NL_PaypointTransactions() { TransactionTime = paymentTime, Amount = amount, Notes = description, PaypointTransactionStatusID = (int)NLPaypointTransactionStatuses.Done, PaypointUniqueID = transId, PaypointCardID = card.Id, IP = ip }); } } serviceInstance.AddPayment(customerID, nlPayment, nlPayment.CreatedByUserID); } } transaction.Commit(); } catch (Exception ex) { Log.ErrorFormat("Failed to pay {1} pounds for loan {0}, rollbacking \n {2}", loan.Id, amount, ex); transaction.Rollback(); } Log.InfoFormat("LinkPaymentToInvestor {0} {1} {2} {3} {4} begin", transactionItem.Id, loan.Id, loan.Customer.Id, amount, paymentTime); serviceInstance.LinkPaymentToInvestor(1, transactionItem.Id, loan.Id, loan.Customer.Id, amount, paymentTime); // modified by elinar at 9/02/2016 EZ-4678 bugfix return(amount); } // PayLoan
} // PayAllLoansForCustomer /// <exception cref="OverflowException">The sum is larger than <see cref="F:System.Decimal.MaxValue" />.</exception> /// <exception cref="ArgumentNullException"><paramref /> or <paramref /> is null.</exception> /// <exception cref="InvalidCastException"><paramref /> cannot be cast to the element type of the current <see cref="T:System.Array" />.</exception> public void PayAllLateLoansForCustomer( Customer customer, decimal amount, string transId, DateTime?term = null, string description = null, string sManualPaymentMethod = null, NL_Payments nlPaymentCommomData = null) { DateTime date = term ?? DateTime.Now; IEnumerable <Loan> loans = customer.ActiveLoans.Where(l => l.Status == LoanStatus.Late); var nlLoansList = serviceInstance.GetCustomerLoans(customer.Id).ToList(); if (nlLoansList.Count > 0) { nlLoansList.ForEach(l => Log.InfoFormat("PayAllLateLoansForCustomer NLLoanID={0}", l.LoanID)); } foreach (var loan in loans) { if (amount <= 0) { break; } LoanRepaymentScheduleCalculator c = new LoanRepaymentScheduleCalculator(loan, term, this.amountToChargeFrom); LoanScheduleItem state = c.GetState(); decimal late = loan.Schedule.Where(s => s.Status == LoanScheduleStatus.Late).Sum(s => s.LoanRepayment) + state.Interest + state.Fees + state.LateCharges; decimal money = Math.Min(amount, late); NL_Payments nlPayment = null; // customer's nl loans if (nlLoansList.Count > 0) { // current loan var nlLoan = nlLoansList.FirstOrDefault(x => x.OldLoanID == loan.Id); if (nlLoan != null) { var nlModel = serviceInstance.GetLoanState(loan.Customer.Id, nlLoan.LoanID, DateTime.UtcNow, 1); decimal nlLate = nlModel.Interest + nlModel.Fees; nlModel.Loan.Histories.ForEach(h => h.Schedule.Where(s => s.LoanScheduleStatusID == (int)NLScheduleStatuses.Late).Sum(s => nlLate += s.Principal)); decimal nlMoney = Math.Min(amount, nlLate); Log.InfoFormat("<<< NL_Compare: Loan:{0} NLModel:{1}.\n late={2}, nlLate={3}, amount={4}, money={5}, nlMoney={6} >>>", loan, nlModel, late, nlLate, amount, money, nlMoney); nlPayment = new NL_Payments() { Amount = money, CreatedByUserID = 1, CreationTime = DateTime.UtcNow, LoanID = nlLoan.LoanID, PaymentTime = DateTime.UtcNow, Notes = "PayAllLateLoansForCustomer", //PaymentMethodID = (int)NLLoanTransactionMethods.CustomerAuto, PaymentStatusID = (int)NLPaymentStatuses.Active, PaymentSystemType = nlPaymentCommomData != null ? nlPaymentCommomData.PaymentSystemType : NLPaymentSystemTypes.None, PaymentMethodID = nlPaymentCommomData != null ? nlPaymentCommomData.PaymentMethodID : (int)NLLoanTransactionMethods.Manual // put better check }; } } PayLoan(loan, transId, money, null, date, description, false, sManualPaymentMethod, nlPayment); amount = amount - money; } // for } // PayAllLateLoansForCustomer