public void CalculatorState() { DateTime calcTime = DateTime.UtcNow; const long loanID = 10007; const int customerID = 59; GetLoanState dbState = new GetLoanState(customerID, loanID, calcTime, 357, false); try { dbState.Execute(); } catch (NL_ExceptionInputDataInvalid nlExceptionInputDataInvalid) { Console.WriteLine(nlExceptionInputDataInvalid.Message); return; } try { ALoanCalculator calc = new LegacyLoanCalculator(dbState.Result, calcTime); calc.GetState(); m_oLog.Debug("----------------------------------{0}", calc.WorkingModel); } catch (Exception exception) { m_oLog.Error("{0}", exception.Message); } return; // old loan LoanRepository loanRep = ObjectFactory.GetInstance<LoanRepository>(); Loan oldLoan = loanRep.Get(dbState.Result.Loan.OldLoanID); // old calc LoanRepaymentScheduleCalculator oldCalc = new LoanRepaymentScheduleCalculator(oldLoan, calcTime, 0); oldCalc.GetState(); m_oLog.Debug("++++++++++++++++++++++++++++++old loan: {0}", oldLoan); m_oLog.Debug("NextEarlyPayment={0}", oldCalc.NextEarlyPayment()); }
public void UpdateRolloverTest() { const int oldID = 5116; const int customerID = 385; DateTime now = DateTime.UtcNow; PaymentRolloverRepository rep = ObjectFactory.GetInstance<PaymentRolloverRepository>(); var rollovers = rep.GetByLoanId(oldID); var paymentRollovers = rollovers as IList<PaymentRollover> ?? rollovers.ToList(); //paymentRollovers.ForEach(rr => this.m_oLog.Debug(rr)); var r = paymentRollovers.FirstOrDefault(rr => rr.ExpiryDate > now); m_oLog.Debug(r); if (r == null) { return; } var s = new GetLoanIDByOldID(oldID); s.Execute(); GetLoanState state = new GetLoanState(customerID, s.LoanID, now, 1, false); state.Execute(); NL_LoanRollovers nlr = state.Result.Loan.Rollovers.FirstOrDefault(nr => nr.CreationTime.Date == r.Created.Date && nr.ExpirationTime.Date == r.ExpiryDate); if (nlr == null) return; nlr.ExpirationTime = nlr.ExpirationTime.AddDays(4); m_oLog.Debug(nlr); SaveRollover saver = new SaveRollover(nlr, state.Result.Loan.LoanID); saver.Execute(); m_oLog.Debug(saver.Error); }
/// <exception cref="NL_ExceptionInputDataInvalid">Condition. </exception> public NL_Model GetLoanState(int customerID, long loanID, DateTime utcNow, int userID, bool getCalculatorState = true) { var stra = new GetLoanState(customerID, loanID, utcNow); stra.Context.CustomerID = customerID; stra.Context.UserID = userID; stra.Execute(); return(stra.Result); }
} // GetCustomerLoans public NLModelActionResult GetLoanState(int customerID, long loanID, DateTime calculationDate, int userID, bool getCalculatorState = true) { GetLoanState s = new GetLoanState(customerID, loanID, calculationDate, userID, getCalculatorState); s.Context.CustomerID = customerID; s.Context.UserID = userID; var amd = ExecuteSync(out s, customerID, userID, customerID, loanID, calculationDate, userID, getCalculatorState); return(new NLModelActionResult { MetaData = amd, Value = s.Result, Error = s.Error }); } // GetLoanState
private void NL_SendMailAndMarkDB(SafeReader sr) { int customerID = sr["CustomerId"]; long loanID = sr["LoanID"]; DateTime plannedDate = sr["PlannedDate"]; int Xdays = sr["Xdays"]; // 2|5 indicate which type of notification to send long loanScheduleId = sr["LoanScheduleID"]; NL_AddLog(LogType.Info, "NL_SendMailAndMarkDB", new object[] { customerID, loanID, Xdays, loanScheduleId, plannedDate, nowTime }, null, null, null); GetLoanState loanState = new GetLoanState(customerID, loanID, nowTime); loanState.Execute(); var nlModel = loanState.Result; NL_LoanSchedules theSchedule = null; nlModel.Loan.Histories.ForEach(h => theSchedule = h.Schedule.FirstOrDefault(s => s.LoanScheduleID == loanScheduleId)); if (theSchedule == null) { Log.Debug("Schedule for loan {0}, old {1} not found", loanID, sr["OldLoanID"]); NL_AddLog(LogType.Warn, "Schedule not found", new object[] { customerID, loanID, Xdays, loanScheduleId, plannedDate, nowTime }, null, null, null); return; } var variables = new Dictionary <string, string> { { "FirstName", sr["FirstName"] }, { "AmountDueScalar", theSchedule.AmountDue.ToString(CultureInfo.InvariantCulture) }, { "Date", FormattingUtils.FormatDateToString(plannedDate) }, { "DebitCard", sr["CreditCardNo"] } }; var templateName = (Xdays == 2) ? "Mandrill - 2 days notice" : "Mandrill - 5 days notice"; XDaysDueMails xDaysDueMails = new XDaysDueMails(customerID, templateName, variables); //DON"T DELETE - in the futere email will be sent from here.!!! //xDaysDueMails.Execute(); var parameterName = (Xdays == 2) ? "TwoDaysDueMailSent" : "FiveDaysDueMailSent"; // new SP var queryParameteres = new QueryParameter[] { new QueryParameter("LoanScheduleID", loanScheduleId), new QueryParameter(parameterName, true) }; NL_AddLog(LogType.Info, "Processing", new object[] { customerID, loanID, Xdays, loanScheduleId, plannedDate, nowTime }, new object[] { theSchedule, parameterName, templateName }, null, null); DB.ExecuteNonQuery("NL_LoanSchedulesUpdate", CommandSpecies.StoredProcedure, queryParameteres); Log.Info("update loanID {2} scheduleID {1} x days due for customer {0}", customerID, loanScheduleId, loanID); }
public void GetLoanStateTest() { DateTime calcTime = DateTime.UtcNow; /*const long loanID = 21; const int customerID = 351;*/ const long loanID = 4; const int customerID = 1394; GetLoanState state = new GetLoanState(customerID, loanID, calcTime, 357); try { state.Execute(); m_oLog.Debug("----------------------------------{0}", state.Result); } catch (NL_ExceptionInputDataInvalid nlExceptionInputDataInvalid) { Console.WriteLine(nlExceptionInputDataInvalid.Message); } catch (Exception ex) { m_oLog.Error("{0}", ex.Message); } }
} //Execute private void BuildCollectionDataModel(SafeReader sr) { string mobilePhone = sr["MobilePhone"]; var model = new CollectionDataModel { CustomerID = sr["CustomerID"], OriginID = sr["OriginID"], LoanRefNum = sr["LoanRefNum"], FirstName = sr["FirstName"], FullName = sr["FullName"], Email = sr["email"], PhoneNumber = string.IsNullOrEmpty(mobilePhone) ? sr["DaytimePhone"] : mobilePhone, DueDate = sr["ScheduleDate"], LoanID = sr["OldLoanID"], ScheduleID = 0, NLLoanID = sr["LoanID"], LoanHistoryID = sr["LoanHistoryID"], NLScheduleID = sr["ScheduleID"], SmsSendingAllowed = sr["SmsSendingAllowed"], EmailSendingAllowed = sr["EmailSendingAllowed"], ImailSendingAllowed = sr["MailSendingAllowed"] }; model.LateDays = (int)(now - model.DueDate).TotalDays; GetLoanState loanState = new GetLoanState(model.CustomerID, model.NLLoanID, now); loanState.Execute(); List <NL_LoanSchedules> schedules = new List <NL_LoanSchedules>(); loanState.Result.Loan.Histories.ForEach(h => schedules.AddRange(h.Schedule)); var scheduleItem = schedules.FirstOrDefault(s => s.LoanScheduleID == model.NLScheduleID); model.Interest = loanState.Result.Interest; if (scheduleItem != null) { model.FeeAmount = scheduleItem.Fees; model.AmountDue = scheduleItem.AmountDue; } nlNotificationsList.Add(model); Log.Info(model.ToString()); NL_AddLog(LogType.Info, "CollectionDataModel", now, model, null, null); }
public void TestDateInterval() { const long loanID = 17; GetLoanState strategy = new GetLoanState(56, loanID, DateTime.UtcNow, 357); strategy.Execute(); NL_Model model = strategy.Result; model.Loan.Payments.Clear(); try { DateTime calcDate = new DateTime(2015, 10, 25); ALoanCalculator calc = new LegacyLoanCalculator(model); DateTime start = calcDate; DateTime end = new DateTime(2016, 02, 25); int days = end.Subtract(start).Days; m_oLog.Debug("total days: {0}", days); var schedule = model.Loan.LastHistory().Schedule; for (int i=0; i <= days; i++) { DateTime theDate = start.AddDays(i); var scheduleItem = schedule.FirstOrDefault(s => theDate.Date >= calc.PreviousScheduleDate(s.PlannedDate.Date, RepaymentIntervalTypes.Month) && theDate.Date <= s.PlannedDate.Date); m_oLog.Debug("theDate: {0}, {1}", theDate, scheduleItem.PlannedDate); } } catch (Exception exception) { m_oLog.Error("{0}", exception.Message); } }
public decimal GetAmountToPay(int customerID, long loandID, long loanScheduleID) { NL_Model nlModel = new NL_Model(customerID) { Loan = new NL_Loans() }; GetLoanState state = new GetLoanState(customerID, loandID, DateTime.UtcNow); try { state.Execute(); nlModel = state.Result; } catch (NL_ExceptionInputDataInvalid nlExceptionInputDataInvalid) { Error = nlExceptionInputDataInvalid.Message; Log.Error(Error); NL_AddLog(LogType.Error, "Failed to GetLoanState for NL loan", new object[] { customerID, loandID, loanScheduleID }, Error, nlExceptionInputDataInvalid.ToString(), nlExceptionInputDataInvalid.StackTrace); } if (!string.IsNullOrEmpty(state.Error)) { Error = state.Error; Log.Error(Error); NL_AddLog(LogType.Error, "Failed to GetLoanState for NL loan", new object[] { customerID, loandID, loanScheduleID }, Error, Error, null); } var item = nlModel.Loan.LastHistory().Schedule.FirstOrDefault(s => s.LoanScheduleID == loanScheduleID); if (item != null) { return(item.AmountDue); } Error = string.Format("Failed to get AmountDue for nlloanID {0}, schedule={1}", loandID, loanScheduleID); Log.Error(Error); NL_AddLog(LogType.Error, "Failed to get AmountDue", new object[] { customerID, loandID, loanScheduleID }, Error, Error, null); return(0); }
} //CollectionDay90 private CollectionMailModel GetCollectionMailModel(CollectionDataModel model) { SafeReader sr = DB.GetFirst("GetDataForCollectionMail", CommandSpecies.StoredProcedure, new QueryParameter("CustomerID", model.CustomerID), new QueryParameter("LoanID", model.LoanID)); CollectionMailModel mailModel = new CollectionMailModel { CustomerName = model.FullName, CustomerAddress = new Address { Line1 = sr["CAddress1"], Line2 = sr["CAddress2"], Line3 = sr["CAddress3"], Line4 = sr["CAddress4"], Postcode = sr["CPostcode"], }, CompanyAddress = new Address { Line1 = sr["BAddress1"], Line2 = sr["BAddress2"], Line3 = sr["BAddress3"], Line4 = sr["BAddress4"], Postcode = sr["BPostcode"], }, GuarantorAddress = new Address { //TODO implement Line1 = sr["GAddress1"], Line2 = sr["GAddress2"], Line3 = sr["GAddress3"], Line4 = sr["GAddress4"], Postcode = sr["GPostcode"], }, GuarantorName = sr["GuarantorName"], //TODO implement IsLimited = sr["IsLimited"], CompanyName = sr["CompanyName"], Date = this.now, LoanAmount = sr["LoanAmount"], LoanRef = sr["LoanRef"], LoanDate = sr["LoanDate"], //OutstandingBalance = sr["OutstandingBalance"], OutstandingPrincipal = sr["OutstandingPrincipal"], CustomerId = model.CustomerID, OriginId = model.OriginID, MissedPayment = new MissedPaymentModel { AmountDue = sr["AmountDue"], DateDue = sr["SchedDate"], Fees = sr["Fees"], RepaidAmount = sr["RepaidAmount"], RepaidDate = sr["RepaidDate"] }, PreviousMissedPayment = new MissedPaymentModel { AmountDue = sr["PreviousAmountDue"], DateDue = sr["PreviousSchedDate"], Fees = sr["PreviousFees"], RepaidAmount = sr["PreviousRepaidAmount"], RepaidDate = sr["PreviousRepaidDate"] }, }; var loanRepository = ObjectFactory.GetInstance <LoanRepository>(); Loan loan = loanRepository.Get(model.LoanID); var payEarlyCalc = new LoanRepaymentScheduleCalculator(loan, this.now, CurrentValues.Instance.AmountToChargeFrom); var balance = payEarlyCalc.TotalEarlyPayment(); mailModel.OutstandingBalance = balance; if (model.NLLoanID > 0) { GetLoanState nlState = new GetLoanState(model.CustomerID, model.NLLoanID, this.now, 1); nlState.Execute(); mailModel.LoanRef = nlState.Result.Loan.Refnum; mailModel.OutstandingPrincipal = nlState.Result.Principal; mailModel.OutstandingBalance = nlState.Result.TotalEarlyPayment; var firtHistory = nlState.Result.Loan.FirstHistory(); if (firtHistory != null) { mailModel.LoanAmount = (int)firtHistory.Amount; mailModel.LoanDate = firtHistory.EventTime; } // TODO handle MissedPayment, PreviousMissedPayment } return(mailModel); } //GetCollectionMailModel
} //Execute private void NLMarkLoanAsLate(NLLateLoansJobModel model) { Log.Debug("NLMarkLoanAsLate: {0}", model.ToString()); NL_AddLog(LogType.Info, "NLMarkLoanAsLate", model, null, null, null); if (model.LoanStatus != NLLoanStatuses.Late) { // DON'T REMOVE!!!!!!!!!! SHOULD BE UNCOMMENT AFTER "old" job cancellation //DB.ExecuteNonQuery( // "UpdateCustomer", CommandSpecies.StoredProcedure, // new QueryParameter("CustomerId", customerId), // new QueryParameter("LoanStatus", "Late"), // new QueryParameter("IsWasLate", true) // ); DB.ExecuteNonQuery("NL_LoanUpdate", CommandSpecies.StoredProcedure, new QueryParameter("LoanID", model.LoanID), new QueryParameter("LoanStatusID", (int)NLLoanStatuses.Late)); Log.Debug("Updating nlloan {0} to late", model.LoanID); NL_AddLog(LogType.Info, "updating loan to late", model, model.LoanID, null, null); } if (model.ScheduleStatus != NLScheduleStatuses.Late) { DB.ExecuteNonQuery("NL_LoanSchedulesUpdate", CommandSpecies.StoredProcedure, new QueryParameter("LoanScheduleID", model.LoanScheduleID), new QueryParameter("LoanScheduleStatusID", (int)NLScheduleStatuses.Late)); Log.Debug("Updating schedule {0} to late", model.LoanScheduleID); NL_AddLog(LogType.Info, "updating schedule to late", model, model.LoanScheduleID, null, null); } GetLoanState loanState = new GetLoanState(model.CustomerID, model.LoanID, now); loanState.Execute(); decimal interest = loanState.Result.Interest; // TODO check: real unpaid interest for this date here if (!LateFeesAllowed(loanState.Result.Loan.LoanOptions, model.LoanID)) { Log.Debug("late fees for loan {0} not allowed", model.LoanID); NL_AddLog(LogType.Info, "Late fees not allowed", model, loanState.Result.Loan.LoanOptions, null, null); return; } int daysLate = (int)(now - model.PlannedDate).TotalDays; int feeAmount; NLFeeTypes feeType; NL_Model.CalculateFee(daysLate, interest, out feeAmount, out feeType); Log.Debug("calculated feeAmount={0}, FeeType={1} daysLate={2} schedule={3} loan={4}", feeAmount, (int)feeType, daysLate, model.LoanScheduleID, model.LoanID); NL_AddLog(LogType.Info, "calculated fee data", model, new object[] { daysLate, interest, feeAmount, feeType }, null, null); if (feeType != NLFeeTypes.None) { // check if this fee type for this schedule already assigned // get next schedule date NL_LoanSchedules nextSchedule = null; loanState.Result.Loan.Histories.ForEach(h => nextSchedule = h.Schedule.FirstOrDefault(s => s.PlannedDate > model.PlannedDate)); DateTime dateTo = nextSchedule == null ? model.PlannedDate : nextSchedule.PlannedDate; // between this and nect schedules same fee alread assigned if (loanState.Result.Loan.Fees.FirstOrDefault(f => f.LoanFeeTypeID == (int)feeType && f.AssignTime.Date <= dateTo.Date && f.AssignTime.Date >= model.PlannedDate) != null) { Log.Debug("NL: Tried to apply already assigned late charge for customer {0} loan {1}: feetype: {2}", model.CustomerID, model.LoanID, feeType); NL_AddLog(LogType.Info, "LatefeeExists", model, feeType, null, null); return; } NL_LoanFees lateFee = new NL_LoanFees() { AssignedByUserID = 1, LoanID = model.LoanID, Amount = feeAmount, AssignTime = now.Date, CreatedTime = now, LoanFeeTypeID = (int)feeType, Notes = daysLate + " days late;schedule " + model.LoanScheduleID, DeletedByUserID = null, DisabledTime = null }; var nlfList = new List <NL_LoanFees>(); nlfList.Add(lateFee); try { DB.ExecuteNonQuery("NL_LoanFeesSave", CommandSpecies.StoredProcedure, DB.CreateTableParameter <NL_LoanFees>("Tbl", nlfList)); Log.Debug("NL: Applied late charge for customer {0} loan {1}: data: {2}", model.CustomerID, model.LoanID, lateFee); NL_AddLog(LogType.Info, "Latefee", model, lateFee, null, null); // ReSharper disable once CatchAllClause } catch (Exception ex) { Log.Alert("NL: Failed to add late fee for customer {0} loan {1}: data: {2}", model.CustomerID, model.LoanID, lateFee); NL_AddLog(LogType.Error, "Failed to add late fee", model, lateFee, ex.ToString(), ex.StackTrace); } } } //NL_MarkLoanAsLate
public void RolloverRescheduling() { DateTime calcTime = DateTime.UtcNow; const long loanID = 17; // 21; GetLoanState dbState = new GetLoanState(56, loanID, calcTime, 357); try { dbState.Execute(); } catch (NL_ExceptionInputDataInvalid nlExceptionInputDataInvalid) { Console.WriteLine(nlExceptionInputDataInvalid.Message); } NL_Model model = dbState.Result; ILoanRepository loanRep = ObjectFactory.GetInstance<LoanRepository>(); var oldLoan = loanRep.Get(model.Loan.OldLoanID); var rolloverRep = ObjectFactory.GetInstance<PaymentRolloverRepository>(); var oldRollover = rolloverRep.GetByLoanId(oldLoan.Id).FirstOrDefault(); // copy rollover+fee+payment to NL if (oldRollover != null && oldRollover.PaidPaymentAmount > 0) { DateTime rolloverConfirmationDate = (DateTime)oldRollover.CustomerConfirmationDate; var fee = model.Loan.Fees.LastOrDefault(); model.Loan.Fees.Add(new NL_LoanFees() { Amount = CurrentValues.Instance.RolloverCharge, AssignTime = rolloverConfirmationDate, CreatedTime = rolloverConfirmationDate, LoanFeeID = (fee.LoanFeeID + 1), LoanFeeTypeID = (int)NLFeeTypes.RolloverFee, AssignedByUserID = 1, LoanID = loanID, Notes = "rollover fee" }); fee = model.Loan.Fees.LastOrDefault(); model.Loan.AcceptedRollovers.Add(new NL_LoanRollovers() { CreatedByUserID = 1, CreationTime = oldRollover.Created, CustomerActionTime = oldRollover.CustomerConfirmationDate, ExpirationTime = rolloverConfirmationDate, IsAccepted = true, LoanHistoryID = model.Loan.LastHistory().LoanHistoryID, LoanFeeID = fee.LoanFeeID }); var transaction = oldLoan.Transactions.LastOrDefault(); if (transaction != null) { model.Loan.Payments.Add(new NL_Payments() { Amount = transaction.Amount, CreatedByUserID = 1, CreationTime = transaction.PostDate, LoanID = model.Loan.LoanID, PaymentTime = transaction.PostDate, Notes = "dummy payment for rollover", PaymentStatusID = (int)NLPaymentStatuses.Active, PaymentMethodID = (int)NLLoanTransactionMethods.Manual, PaymentID = 15 }); } } /*try { ALoanCalculator calc = new LegacyLoanCalculator(model, calcTime); calc.RolloverRescheduling(); m_oLog.Debug("{0}", calc); // old calc LoanRepaymentScheduleCalculator oldCalc = new LoanRepaymentScheduleCalculator(oldLoan, calcTime, 0); oldCalc.GetState(); m_oLog.Debug("old loan State: {0}", oldLoan); m_oLog.Debug("\n\n====================OLD CALC InterestToPay={0}, FeesToPay={1}", oldCalc.InterestToPay, oldCalc.FeesToPay); } catch (Exception exception) { m_oLog.Error("{0}", exception.Message); }*/ }
public void LoanStateStrategy() { const long loanID = 9; var strategy = new GetLoanState(351, loanID, DateTime.UtcNow, 1, false); // loanID = 17, customer = 56 strategy.Execute(); m_oLog.Debug(strategy.Result); }
public void ExceptPaymentTest() { const long loanID = 13; var state = new GetLoanState(351, loanID, DateTime.UtcNow, 1, false); // loanID = 17, customer = 56 state.Execute(); NL_Model nlLoan = state.Result; // loan - from DB, actual - from UI ILoanRepository loanRep = ObjectFactory.GetInstance<LoanRepository>(); var loan = loanRep.Get(nlLoan.Loan.OldLoanID); var actual = loanRep.Get(nlLoan.Loan.OldLoanID); List<PaypointTransaction> loanList = loan.TransactionsWithPaypointSuccesefull; m_oLog.Debug("DB state:"); loanList.ForEach(xxx => m_oLog.Debug(xxx.ToString())); List<PaypointTransaction> actualList = loan.TransactionsWithPaypointSuccesefull; var toremove = actualList.Last(); actualList.Remove(toremove); m_oLog.Debug("\n\n from UI:"); actualList.ForEach(yyy => m_oLog.Debug(yyy.ToString())); var removedPayments = loanList.Except(actualList); m_oLog.Debug("\n\n Cancelled payments:"); foreach (PaypointTransaction transaction in removedPayments.ToList()) { m_oLog.Debug(transaction); transaction.Description = transaction.Description + "; removed amount = " + transaction.Amount; transaction.Interest = 0; transaction.Fees = 0; transaction.LoanRepayment = 0; transaction.Rollover = 0; transaction.Cancelled = true; transaction.CancelledAmount = transaction.Amount; transaction.Amount = 0; var transaction1 = transaction; // reset paid charges loan.Charges.Where(f => f.Date <= transaction1.PostDate).ForEach(f => f.AmountPaid = 0); loan.Charges.Where(f => f.Date <= transaction1.PostDate).ForEach(f => f.State = null); IEnumerable<LoanScheduleTransaction> schTransactions = loan.ScheduleTransactions.Where(st => st.Transaction.Id == transaction1.Id); foreach (LoanScheduleTransaction st in schTransactions) { var paidSchedule = loan.Schedule.FirstOrDefault(s => s.Id == st.Schedule.Id); if (paidSchedule != null) { // reset paid rollover foreach (PaymentRollover r in paidSchedule.Rollovers) { r.PaidPaymentAmount = 0; r.CustomerConfirmationDate = null; r.PaymentNewDate = null; r.Status = (r.ExpiryDate.HasValue && r.ExpiryDate.Value <= DateTime.UtcNow) ? RolloverStatus.Expired : RolloverStatus.New; } } } } m_oLog.Debug("\n\n final state:"); loan.TransactionsWithPaypointSuccesefull.ForEach(xx => m_oLog.Debug(xx.ToString())); }