Ejemplo n.º 1
0
		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());
		}
Ejemplo n.º 2
0
		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);
		}
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        }         // 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
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
		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);
			}
		}
Ejemplo n.º 7
0
        }         //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);
        }
Ejemplo n.º 8
0
		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);
			}
		}
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
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
Ejemplo n.º 11
0
        }        //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
Ejemplo n.º 12
0
		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);
			}*/
		}
Ejemplo n.º 13
0
		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);
		}
Ejemplo n.º 14
0
		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()));
		}