Exemple #1
0
		public void AddSpreadedFeeTest() {
			const long loanID = 4;
			DateTime now = DateTime.UtcNow;
			List<NL_LoanFees> fees = new List<NL_LoanFees>();
			NL_LoanFees f1 = new NL_LoanFees() {
				LoanFeeTypeID = (int)NLFeeTypes.ServicingFee,
				Amount = 20,
				AssignedByUserID = 1,
				AssignTime = now,
				CreatedTime = now,
				Notes = "test servicing",
				LoanID = loanID
			};
			fees.Add(f1);
			NL_LoanFees f2 = new NL_LoanFees() {
				LoanFeeTypeID = (int)NLFeeTypes.ServicingFee,
				Amount = 20,
				AssignedByUserID = 1,
				AssignTime = now.AddMonths(1),
				CreatedTime = now,
				Notes = "test servicing",
				LoanID = loanID
			};
			fees.Add(f2);
			fees.ForEach(f => m_oLog.Debug(f));
			int result = this.m_oDB.ExecuteNonQuery("NL_LoanFeesSave", CommandSpecies.StoredProcedure, this.m_oDB.CreateTableParameter<NL_LoanFees>("Tbl", fees));
			m_oLog.Debug(result);
		}
Exemple #2
0
        //[Transactional]
        public void NL_SyncFees(int id)
        {
            Log.DebugFormat("sync NL fees for old loan {0}", id);

            var loan = this._loans.Get(id);

            try {
                long nlLoanId = this.serviceClient.Instance.GetLoanByOldID(id, loan.Customer.Id, this._context.UserId).Value;

                if (nlLoanId > 0)
                {
                    NL_Model nlModel = this.serviceClient.Instance.GetLoanState(loan.Customer.Id, nlLoanId, DateTime.UtcNow, this._context.UserId, false).Value;
                    Log.InfoFormat("nlModel : {0} loan: {1}  >>>", nlModel, loan);

                    // new/edit fee
                    foreach (LoanCharge ch in loan.Charges.OrderBy(ff => ff.Date))
                    {
                        NL_LoanFees f = nlModel.Loan.Fees.FirstOrDefault(ff => ff.OldFeeID == ch.Id);
                        if (f == null)
                        {
                            f = new NL_LoanFees()
                            {
                                AssignedByUserID = this._context.UserId,
                                LoanFeeTypeID    = (int)NL_Model.ConfVarToNLFeeType(ch.ChargesType),
                                LoanID           = nlLoanId,
                                OldFeeID         = ch.Id,                         // update in strategy after this [Transactional]
                                Amount           = ch.Amount,
                                AssignTime       = ch.Date.Date,
                                Notes            = !string.IsNullOrEmpty(ch.Description) ? ch.Description : "add fee from edit loan"
                            };
                            this.serviceClient.Instance.SaveFee(this._context.UserId, loan.Customer.Id, f);

                            // fee type is editable + modified (amount/assign date/notes)
                        }
                        else if (Array.Exists <NLFeeTypes>(NL_Model.NLFeeTypesEditable, element => element == (NLFeeTypes)f.LoanFeeTypeID) && (f.Amount != ch.Amount || f.AssignTime.Date != ch.Date.Date || f.Notes != ch.Description))
                        {
                            f.UpdatedByUserID = this._context.UserId;
                            f.Amount          = ch.Amount;
                            f.AssignTime      = ch.Date.Date;
                            f.Notes           = !string.IsNullOrEmpty(ch.Description) ? ch.Description : "add fee from edit loan";
                            this.serviceClient.Instance.SaveFee(this._context.UserId, loan.Customer.Id, f);
                        }
                    }

                    //	removed fee
                    foreach (NL_LoanFees f in nlModel.Loan.Fees.OrderBy(ff => ff.AssignTime))
                    {
                        var charge = loan.Charges.FirstOrDefault(c => c.Id == f.LoanFeeID);
                        if (charge == null)
                        {
                            f.DeletedByUserID = this._context.UserId;
                            this.serviceClient.Instance.CancelFee(this._context.UserId, loan.Customer.Id, f);
                        }
                    }
                }
                // ReSharper disable once CatchAllClause
            } catch (Exception ex) {
                Log.InfoFormat("Fail to sync NL loan fees. {0}, err: {1}", Environment.StackTrace, ex.Message);
            }
        }
Exemple #3
0
        }         // SaveFee

        public StringActionResult CancelFee(int userID, int customerID, NL_LoanFees fee)
        {
            CancelFee s = new CancelFee(fee);

            s.Context.UserID     = userID;
            s.Context.CustomerID = customerID;
            var amd = ExecuteSync(out s, customerID, userID, fee);

            return(new StringActionResult {
                Value = s.Error
            });
        } // CancelFee
Exemple #4
0
		public void CancelFeeTest() {
			NL_LoanFees f = m_oDB.FillFirst<NL_LoanFees>("NL_LoanFeesGet",
				CommandSpecies.StoredProcedure,
				new QueryParameter("LoanID", 3),
				new QueryParameter("LoanFeeID", 20011));

			f.DeletedByUserID = 357;
			CancelFee s = new CancelFee(f);
			try {
				s.Execute();
			} catch (Exception e) {
				m_oLog.Debug(e);
			}
		}
Exemple #5
0
		public void AddLateFeeTest() {
			const long loanID = 17;
			DateTime now = new DateTime(2015, 12, 28);

			NL_LoanFees fee = new NL_LoanFees() {
				LoanFeeTypeID = (int)NLFeeTypes.AdminFee,
				Amount = decimal.Parse(CurrentValues.Instance.AdministrationCharge.Value),    //NL_Model.GetLateFeesAmount(NLFeeTypes.AdminFee),
				AssignedByUserID = 1,
				AssignTime = now,
				CreatedTime = now,
				Notes = "test late fee3",
				LoanID = loanID
			};
			int result = this.m_oDB.ExecuteNonQuery("NL_LoanFeesSave", CommandSpecies.StoredProcedure, this.m_oDB.CreateTableParameter<NL_LoanFees>("Tbl", fee));
			m_oLog.Debug(result);
		}
Exemple #6
0
		public void SaveFeeUpdateTest() {
			NL_LoanFees f = m_oDB.FillFirst<NL_LoanFees>("NL_LoanFeesGet",
				CommandSpecies.StoredProcedure,
				new QueryParameter("LoanID", 3),
				new QueryParameter("LoanFeeID", 20011));

			f.UpdatedByUserID = 357;
			f.UpdateTime = DateTime.UtcNow;
			f.Amount = 29;
			f.AssignTime = DateTime.Now.Date.AddDays(-30);

			SaveFee s = new SaveFee(f);
			try {
				s.Execute();
			} catch (Exception e) {
				m_oLog.Debug(e);
			}
		}
Exemple #7
0
		public void SaveFeeNewTest() {
			NL_LoanFees f = new NL_LoanFees() {
				LoanID = 3,
				Amount = 54,
				AssignedByUserID = 357,
				AssignTime = DateTime.UtcNow,
				CreatedTime = DateTime.UtcNow,
				LoanFeeTypeID = (int)NLFeeTypes.OtherCharge,
				Notes = "other fee",
				UpdatedByUserID = 357
			};
			SaveFee s = new SaveFee(f);
			try {
				s.Execute();
			} catch (Exception e) {
				m_oLog.Debug(e);
			}
		}
Exemple #8
0
		/// <exception cref="ArgumentNullException"><paramref /> is null. </exception>
		/// <exception cref="FormatException"><paramref /> is not in the correct format. </exception>
		public override void Execute() {

			if (!CurrentValues.Instance.NewLoanRun) {
				NL_AddLog(LogType.Info, "NL disabled by configuration", null, null, null, null);
				return;
			}

			this.strategyArgs = new object[] { CustomerID, LoanID };

			if (CustomerID == 0) {
				Error = NL_ExceptionCustomerNotFound.DefaultMessage;
				NL_AddLog(LogType.DataExsistense, "Strategy failed", this.strategyArgs, null, Error, null);
				return;
			}

			if (LoanID == 0) {
				Error = NL_ExceptionLoanNotFound.DefaultMessage;
				NL_AddLog(LogType.DataExsistense, "Strategy failed", this.strategyArgs, null, Error, null);
				return;
			}

			// TODO EZ-4330
			/* RolloverPayment = open interest till accept day included + rollover fees assigned
			1. records NL_Payments (+NL_PaypointTransactions) for rollover () - via AddPayment strategy from outside - via customer dashboard before this strategy
			2. record rollover fee for into NL_LoanFees
			3. update existing rollover record: [CustomerActionTime], [IsAccepted] in [dbo].[NL_LoanRollovers] table
			5. make rollover using calculator - add to NL model new history, rearrange schedules, statuses
			 *  - run calc.GetState to get outstanding balance
			 *  - create new history
			 *  - mark non relevant schedules as CancelledOnRollover
			 *  - create schedule for new history
			6. update DB: records new history, new schedule items; update previous schedule with appropriate statuses
			*/

			DateTime nowTime = DateTime.Now;
			bool rolloverAccepted = false;

			NL_AddLog(LogType.Info, "Strategy Start", this.strategyArgs, null, Error, null);

			// fetch loan's rollovers and check rollover exists, valid and not accepted yet
			NL_LoanRollovers rollover=DB.Fill<NL_LoanRollovers>("NL_RolloversGet", CommandSpecies.StoredProcedure, new QueryParameter("LoanID", LoanID))
				.FirstOrDefault(r => r.DeletedByUserID == null && r.DeletionTime == null && r.IsAccepted == false && (r.CreationTime <= nowTime && nowTime <= r.ExpirationTime));

			if (rollover == null) {
				Error = string.Format("Rollover opportunity for loan {0} not found, or expired, or accepted", LoanID);
				Log.Info(Error);
				NL_AddLog(LogType.DataExsistense, "Strategy end", this.strategyArgs, null, Error, null);
				rolloverAccepted = true;
			}

			if (!rolloverAccepted) {
				// set rollover data for future update
				rollover.IsAccepted = true;
				rollover.CustomerActionTime = nowTime;

				ConnectionWrapper pconn = DB.GetPersistent();

				try {

					// insert rollover fee
					NL_LoanFees rolloverFee = new NL_LoanFees() {
						LoanID = LoanID,
						Amount = Decimal.Parse(CurrentValues.Instance.RolloverCharge.Value),
						AssignedByUserID = rollover.CreatedByUserID,
						AssignTime = rollover.CustomerActionTime.Value,
						CreatedTime = rollover.CustomerActionTime.Value, //DateTime.UtcNow,
						LoanFeeTypeID = (int)NLFeeTypes.RolloverFee,
						Notes = string.Format("rolloverID {2} {0:d}-{1:d}", rollover.CreationTime, rollover.ExpirationTime, rollover.LoanRolloverID)
					};

					rollover.LoanFeeID = DB.ExecuteScalar<long>("NL_LoanFeesSave", CommandSpecies.StoredProcedure, DB.CreateTableParameter<NL_LoanFees>("Tbl", rolloverFee));

					Log.Info("NL rollover fee {0} added", rollover.LoanFeeID);
					NL_AddLog(LogType.Info, "Rollover fee added", this.strategyArgs, rollover.LoanFeeID, Error, null);

					// set newly created history ID for rollover row
					//rollover.LoanHistoryID = loanState.Result.Loan.LastHistory().LoanHistoryID;

					// update rollover
					DB.ExecuteNonQuery("NL_LoanRolloverUpdate", CommandSpecies.StoredProcedure, DB.CreateTableParameter<NL_LoanRollovers>("Tbl", rollover), new QueryParameter("RolloverID", rollover.LoanRolloverID));

					pconn.Commit();

					//ReSharper disable once CatchAllClause
				} catch (Exception ex) {

					pconn.Rollback();

					Error = ex.Message;
					Log.Error("Failed to 'accept rollover': {0}", Error);
					NL_AddLog(LogType.Error, "Strategy failed", this.strategyArgs, Error, ex.ToString(), ex.StackTrace);

					return;
				}
			}

			// update "old" schedules, add new history + new schedules + new distributed fees to DB
			UpdateLoanDBState updateState = new UpdateLoanDBState(CustomerID, LoanID, 1);
			try {
				updateState.Execute();
				// ReSharper disable once CatchAllClause
			} catch (Exception ex) {
				Error = ex.Message;
				Log.Alert(Error);
				NL_AddLog(LogType.Error, "Strategy failed", this.strategyArgs, null, Error, null);
			}

			// reassign payments and save
			try {
				updateState.Execute();
				// ReSharper disable once CatchAllClause
			} catch (Exception ex) {
				Error = ex.Message;
				Log.Alert(Error);
				NL_AddLog(LogType.Error, "Strategy failed", this.strategyArgs, null, Error, null);
			}

		}
Exemple #9
0
		public CancelFee(NL_LoanFees fee) {
			Fee = fee;
			this.strategyArgs = new object[] { Fee };
		}
Exemple #10
0
 // fee
 public LoanEvent(DateTime date, NL_LoanFees fee) : this(new DateTime(date.Year, date.Month, date.Day, 23, 59, 57))
 {
     Fee = fee;
 }
Exemple #11
0
		public void IsInTest() {
			NL_LoanFees f = new NL_LoanFees() { LoanFeeTypeID = 8 };
			Console.WriteLine(Array.Exists<NLFeeTypes>(NL_Model.NLFeeTypesEditable, element => element == (NLFeeTypes)f.LoanFeeTypeID));
		}
        }        //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