}         // 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
Exemple #2
0
		/// <exception cref="NL_ExceptionInputDataInvalid">Condition. </exception>
		public override void Execute() {

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

			// invalid input
			if (!string.IsNullOrEmpty(Error)) {
				throw new NL_ExceptionInputDataInvalid(Error);
			}

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

			// load loan
			NL_Loans loan = LoanDAL.GetLoan(Payment.LoanID);

			if (loan.LoanStatusID == (int)NLLoanStatuses.Pending) {
				// loan pending - can't to add payment
				Error = string.Format("Loan {0} in status 'Pending' yet, payment registering not allowed.", loan.LoanID);
				Log.Debug(Error);
				NL_AddLog(LogType.Info, "End", this.strategyArgs, null, Error, null);
				return;
			}

			if ((loan.LoanStatusID == (int)NLLoanStatuses.PaidOff || loan.LoanStatusID == (int)NLLoanStatuses.WriteOff) && loan.DateClosed!=null) {
				// loan closed - can't to add payment
				Error = string.Format("Loan {0} in status {1} since {2:d}, payment registering not allowed.", loan.LoanID, loan.LoanStatusID, loan.DateClosed);
				Log.Debug(Error);
				NL_AddLog(LogType.Info, "End", this.strategyArgs, null, Error, null);
				return;
			}
	
			ConnectionWrapper pconn = DB.GetPersistent();

			try {

				pconn.BeginTransaction();
	
				//  RESET PAID PRINCIPAL, INTEREST (SCHEDULE), FEES PAID on retroactive payment - in SP NL_ResetPaymentsPaidAmounts, called from NL_PaymentsSave.
				PaymentID = DB.ExecuteScalar<long>("NL_PaymentsSave", CommandSpecies.StoredProcedure, DB.CreateTableParameter<NL_Payments>("Tbl", Payment));
				Payment.PaymentID = PaymentID;

				if (Payment.PaypointTransactions.Count > 0) {

					NL_PaypointTransactions ppTransaction = Payment.PaypointTransactions.FirstOrDefault();

					if (ppTransaction == null) {
						Log.Info("Paypoint transaction not found. Payment \n{0}{1}", AStringable.PrintHeadersLine(typeof(NL_Payments)), Payment.ToStringAsTable());
						NL_AddLog(LogType.Info, "Paypoint transaction not found", this.strategyArgs, null, Error, null);
					} else {
						ppTransaction.PaymentID = Payment.PaymentID;
						ppTransaction.PaypointTransactionID = DB.ExecuteScalar<long>("NL_PaypointTransactionsSave", CommandSpecies.StoredProcedure, DB.CreateTableParameter<NL_PaypointTransactions>("Tbl", ppTransaction));
					}
				}

				pconn.Commit();

				NL_AddLog(LogType.Info, "End", this.strategyArgs, Payment, Error, null);

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

				pconn.Rollback();

				Error = ex.Message;
				Log.Error("Failed to add new payment: {0}", Error);
				NL_AddLog(LogType.Error, "Strategy Faild - Rollback", Payment, Error, ex.ToString(), ex.StackTrace);

				return;
			}

			// recalculate state by calculator + save new state to DB
			UpdateLoanDBState reloadLoanDBState = new UpdateLoanDBState(CustomerID, Payment.LoanID, UserID);
			try {
				reloadLoanDBState.Execute();

				// ReSharper disable once CatchAllClause
			} catch (Exception ex) {
				Error = ex.Message;
				Log.Error("Failed on UpdateLoanDBState {0}", Error);
				NL_AddLog(LogType.Error, "Failed on UpdateLoanDBState", Payment, reloadLoanDBState.Error + "\n" + Error, ex.ToString(), ex.StackTrace);
			}

		}
Exemple #3
0
		public void GetLoanFees() {
			const long loanid = 9;
			var loanFees = this.m_oDB.Fill<NL_LoanFees>("NL_LoanFeesGet", CommandSpecies.StoredProcedure, new QueryParameter("@LoanID", loanid));
			m_oLog.Debug(AStringable.PrintHeadersLine(typeof(NL_LoanFees)));
			loanFees.ForEach(f => m_oLog.Debug(f));
		}