Beispiel #1
0
		public void AddOffer() {
			GetLastOffer lastOfferstrategy = new GetLastOffer(374);
			lastOfferstrategy.Execute();
			NL_Offers lastOffer = lastOfferstrategy.Offer;
			long crID = 337;
			long decisionID = 23;

			ICashRequestRepository crRep = ObjectFactory.GetInstance<CashRequestRepository>();
			CashRequest	oldCashRequest = crRep.Get(crID);

			lastOffer.DecisionID = decisionID;
			lastOffer.LoanSourceID = oldCashRequest.LoanSource.ID;
			lastOffer.LoanTypeID = oldCashRequest.LoanType.Id;
			lastOffer.RepaymentIntervalTypeID = (int)RepaymentIntervalTypes.Month;
			lastOffer.StartTime = (DateTime)oldCashRequest.OfferStart;
			lastOffer.EndTime = (DateTime)oldCashRequest.OfferValidUntil;
			lastOffer.RepaymentCount = oldCashRequest.ApprovedRepaymentPeriod ?? 0;
			lastOffer.Amount = (decimal)oldCashRequest.ManagerApprovedSum;
			lastOffer.MonthlyInterestRate = oldCashRequest.InterestRate;
			lastOffer.CreatedTime = DateTime.UtcNow;
			lastOffer.BrokerSetupFeePercent = oldCashRequest.BrokerSetupFeePercent;
			lastOffer.Notes = "bbb";
			lastOffer.DiscountPlanID = oldCashRequest.DiscountPlan.Id;
			lastOffer.IsLoanTypeSelectionAllowed = oldCashRequest.IsLoanTypeSelectionAllowed == 1;
			lastOffer.SendEmailNotification = !oldCashRequest.EmailSendingBanned;
			lastOffer.IsRepaymentPeriodSelectionAllowed = oldCashRequest.IsCustomerRepaymentPeriodSelectionAllowed;
			lastOffer.IsAmountSelectionAllowed = true;

			// offer-fees
			NL_OfferFees setupFee = new NL_OfferFees() {
				LoanFeeTypeID = (int)NLFeeTypes.SetupFee,
				Percent = oldCashRequest.ManualSetupFeePercent,
				//OneTimePartPercent = 1, DistributedPartPercent = 0 // default
			};
			if (oldCashRequest.SpreadSetupFee != null && oldCashRequest.SpreadSetupFee == true) {
				setupFee.LoanFeeTypeID = (int)NLFeeTypes.ServicingFee;
				setupFee.OneTimePartPercent = 0;
				setupFee.DistributedPartPercent = 1;
			}
			List<NL_OfferFees> offerFees = new List<NL_OfferFees>() { setupFee };
			//this.m_oLog.Debug("NL: offer: {0}, offerFees: {1}" + "", lastOffer, offerFees);
			AddOffer offerStrategy = new AddOffer(lastOffer, offerFees);
			offerStrategy.Execute();
			Console.WriteLine(offerStrategy.OfferID);
			Console.WriteLine(offerStrategy.Error);
		}
        }         // constructor

        public CashRequest CreateQuickOfferCashRequest(Customer customer, int userID)
        {
            var          loanType     = _loanTypes.GetDefault();
            var          loanSource   = _loanSources.GetDefault(customer.Id);
            var          now          = DateTime.UtcNow;
            var          discountPlan = _discounts.GetDefault();
            const string sReason      = "Quick offer taken.";

            // TODO: do something really-really-really better than this.
            var user = _users.GetAll().FirstOrDefault(x => x.Id == 1);

            var cashRequest = new CashRequest {
                CreationDate               = now,
                Customer                   = customer,
                InterestRate               = customer.QuickOffer.ImmediateInterestRate,
                LoanType                   = loanType,
                RepaymentPeriod            = customer.QuickOffer.ImmediateTerm,
                ApprovedRepaymentPeriod    = customer.QuickOffer.ImmediateTerm,
                UseSetupFee                = customer.QuickOffer.ImmediateSetupFee > 0,
                UseBrokerSetupFee          = false,
                DiscountPlan               = discountPlan,
                IsLoanTypeSelectionAllowed = 0,
                OfferValidUntil            = now.AddDays(1),
                OfferStart                 = now,
                LoanSource                 = loanSource, // TODO: can it be EU loan?
                IsCustomerRepaymentPeriodSelectionAllowed = false,
                ManualSetupFeePercent   = customer.QuickOffer.ImmediateSetupFee,
                SystemCalculatedSum     = (double)customer.QuickOffer.Amount,
                ManagerApprovedSum      = (double)customer.QuickOffer.Amount,
                QuickOffer              = customer.QuickOffer,
                SystemDecision          = SystemDecision.Approve,
                SystemDecisionDate      = DateTime.UtcNow,
                UnderwriterDecision     = CreditResultStatus.Approved,
                UnderwriterDecisionDate = DateTime.UtcNow,
                UnderwriterComment      = sReason,
                IdUnderwriter           = user.Id,
                Originator              = EZBob.DatabaseLib.Model.Database.CashRequestOriginator.QuickOffer,
                ExpirianRating          = customer.ExperianConsumerScore,
                UwUpdatedFees           = false,
            };

            customer.CashRequests.Add(cashRequest);

            customer.DateApproved               = DateTime.UtcNow;
            customer.ApprovedReason             = sReason;
            customer.UnderwriterName            = user.Name;
            customer.Status                     = Status.Approved;
            customer.CreditResult               = CreditResultStatus.Approved;
            customer.CreditSum                  = customer.QuickOffer.Amount;
            customer.ManagerApprovedSum         = customer.QuickOffer.Amount;
            customer.OfferStart                 = cashRequest.OfferStart;
            customer.OfferValidUntil            = cashRequest.OfferValidUntil;
            customer.IsLoanTypeSelectionAllowed = 0;
            int validForHours = (int)(cashRequest.OfferValidUntil - cashRequest.OfferStart).Value.TotalHours;

            this.m_oServiceClient.Instance.ApprovedUser(
                user.Id,
                customer.Id,
                customer.QuickOffer.Amount,
                validForHours,
                customer.NumApproves == 1
                );

            this._historyRepository.LogAction(DecisionActions.Approve, sReason, user, customer);

            new Transactional(() => {
                customer.CashRequests.Add(cashRequest);
                this._customerRepository.SaveOrUpdate(customer);
            }).Execute();

            var nlCashRequest = this.m_oServiceClient.Instance.AddCashRequest(userID, new NL_CashRequests {
                CashRequestOriginID = (int)CashRequestOriginator.QuickOffer,
                CustomerID          = customer.Id,
                OldCashRequestID    = cashRequest.Id,
                RequestTime         = now,
                UserID = userID
            });

            Log.DebugFormat("Added NL CashRequestID: {0}, Error: {1}", nlCashRequest.Value, nlCashRequest.Error);

            var nlDecision = this.m_oServiceClient.Instance.AddDecision(userID, customer.Id, new NL_Decisions {
                CashRequestID  = nlCashRequest.Value,
                DecisionTime   = now,
                Notes          = CashRequestOriginator.QuickOffer.DescriptionAttr(),
                DecisionNameID = (int)DecisionActions.Approve,
                UserID         = user.Id
            }, cashRequest.Id, null);

            Log.DebugFormat("Added NL DecisionID: {0}, Error: {1}", nlDecision.Value, nlDecision.Error);

            NL_OfferFees setupFee = new NL_OfferFees()
            {
                LoanFeeTypeID = (int)NLFeeTypes.SetupFee, Percent = customer.QuickOffer.ImmediateSetupFee, OneTimePartPercent = 1, DistributedPartPercent = 0
            };

            if (cashRequest.SpreadSetupFee != null && cashRequest.SpreadSetupFee == true)
            {
                setupFee.LoanFeeTypeID          = (int)NLFeeTypes.ServicingFee;
                setupFee.OneTimePartPercent     = 0;
                setupFee.DistributedPartPercent = 1;
            }
            NL_OfferFees[] ofeerFees = { setupFee };

            var nlOffer = this.m_oServiceClient.Instance.AddOffer(userID, customer.Id, new NL_Offers {
                DecisionID              = nlDecision.Value,
                Amount                  = customer.QuickOffer.Amount,
                CreatedTime             = now,
                StartTime               = now,
                EndTime                 = now.AddDays(1),
                RepaymentIntervalTypeID = (int)RepaymentIntervalTypes.Month,
                LoanSourceID            = loanSource.ID,
                LoanTypeID              = loanType.Id,
                DiscountPlanID          = discountPlan.Id,
                Notes = CashRequestOriginator.QuickOffer.DescriptionAttr(),
                InterestOnlyRepaymentCount        = 0,
                BrokerSetupFeePercent             = 0,
                MonthlyInterestRate               = customer.QuickOffer.ImmediateInterestRate,
                RepaymentCount                    = customer.QuickOffer.ImmediateTerm,
                IsAmountSelectionAllowed          = false,
                IsRepaymentPeriodSelectionAllowed = false,
                IsLoanTypeSelectionAllowed        = false
                                                    // ### defaults, can be ommited
            }, ofeerFees);

            Log.DebugFormat("Added NL OfferID: {0}, Error: {1}", nlOffer.Value, nlOffer.Error);

            //TODO add new cash request / offer / decision
            Log.DebugFormat("add new cash request for customer {0}", customer.Id);

            return(cashRequest);
        }         // CreateQuickOfferCashRequest
        }         // constructor

        /// <exception cref="OverflowException">Condition. </exception>
        public virtual void Execute()
        {
            // not accepted rollover
            if (Calculator.acceptedRollover.Rollover == null)
            {
                Log.Alert("RolloverRescheduling: no accepted rollover");
                return;
            }

            // not accepted rollover
            if (!Calculator.acceptedRollover.Rollover.IsAccepted || !Calculator.acceptedRollover.Rollover.CustomerActionTime.HasValue)
            {
                Log.Alert("RolloverRescheduling: rollover not accepted (paid). {0}", Calculator.acceptedRollover.Rollover);
                return;
            }

            // rollover proceeseed
            if (Calculator.acceptedRollover.Rollover.CustomerActionTime.Value.Date == Calculator.currentHistory.EventTime.Date || Calculator.acceptedRolloverProcessed)
            {
                Log.Debug("RolloverRescheduling: History ({0}) for rollover {1:d}, rolloverID {2} already exists", Calculator.currentHistory.LoanHistoryID, Calculator.acceptedRollover.Rollover.CustomerActionTime.Value, Calculator.acceptedRollover.Rollover.LoanRolloverID);
                return;
            }

            var rolloverPayment = Calculator.events.FirstOrDefault(p => p.Payment != null && p.Payment.PaymentTime.Date.Equals(Calculator.acceptedRollover.Rollover.CustomerActionTime.Value.Date) && p.Payment.PaymentDestination.Equals(NLPaymentDestinations.Rollover.ToString()));

            // rollover not paid
            if (rolloverPayment == null)
            {
                Log.Alert("RolloverRescheduling: rollover payment not found. {0}", Calculator.acceptedRollover.Rollover);
                return;
            }

            DateTime acceptionTime = Calculator.acceptedRollover.Rollover.CustomerActionTime.Value.Date;

            NL_LoanHistory lastHistory = WorkingModel.Loan.LastHistory();

            // 1. create new history
            NL_LoanHistory newHistory = new NL_LoanHistory {
                LoanID                  = lastHistory.LoanID,
                LoanLegalID             = lastHistory.LoanLegalID,
                AgreementModel          = lastHistory.AgreementModel,
                Agreements              = lastHistory.Agreements,
                InterestRate            = lastHistory.InterestRate,
                RepaymentIntervalTypeID = lastHistory.RepaymentIntervalTypeID,
                UserID                  = WorkingModel.CustomerID,
                Description             = "accept rollover",
                Amount                  = Calculator.currentOpenPrincipal,
                EventTime               = acceptionTime
            };

            RepaymentIntervalTypes intervalType = (RepaymentIntervalTypes)lastHistory.RepaymentIntervalTypeID;

            int removedItems = 0;

            newHistory.RepaymentDate = DateTime.MinValue;

            // 2. mark removed schedules + add new schedules
            foreach (NL_LoanSchedules s in Calculator.schedule.Where(s => s.PlannedDate >= acceptionTime))
            {
                s.SetStatusOnRescheduling();
                s.ClosedTime = acceptionTime;

                removedItems++;

                DateTime plannedDate = Calculator.AddRepaymentIntervals(1, s.PlannedDate, intervalType);

                if (newHistory.RepaymentDate.Equals(DateTime.MinValue))
                {
                    newHistory.RepaymentDate = plannedDate;
                }

                // add new schedule instead of removed
                NL_LoanSchedules newSchedule = new NL_LoanSchedules()
                {
                    LoanScheduleID       = 0,
                    LoanScheduleStatusID = (int)NLScheduleStatuses.StillToPay,
                    Position             = s.Position,
                    PlannedDate          = plannedDate,
                    Principal            = s.Principal,          // (s.Principal - s.PrincipalPaid),
                    InterestRate         = s.InterestRate,
                    TwoDaysDueMailSent   = false,                //s.TwoDaysDueMailSent,
                    FiveDaysDueMailSent  = false,                //s.FiveDaysDueMailSent
                };

                Log.Debug("schedule {0} replaced by {1}", s, newSchedule);

                newHistory.Schedule.Add(newSchedule);
            }

            newHistory.RepaymentCount = removedItems;

            WorkingModel.Loan.Histories.Add(newHistory);

            //List<NL_LoanFees> replacedDistributedFees = new List<NL_LoanFees>();

            bool distributedFees = false;

            // 3. mark removed distributed fees + add new distributed fees
            foreach (NL_LoanFees fee in Calculator.distributedFeesList.Where(f => f.AssignTime.Date >= acceptionTime))
            {
                fee.DisabledTime    = acceptionTime;
                fee.Notes           = "disabled on rollover";
                fee.DeletedByUserID = WorkingModel.UserID ?? 1;

                distributedFees = true;

                //NL_LoanFees newFee = new NL_LoanFees() {
                //	LoanFeeID = 0,
                //	Amount = fee.Amount,
                //	AssignTime = Calculator.AddRepaymentIntervals(1, fee.AssignTime, intervalType),
                //	LoanID = WorkingModel.Loan.LoanID,
                //	LoanFeeTypeID = fee.LoanFeeTypeID,
                //	AssignedByUserID = fee.AssignedByUserID,
                //	CreatedTime = acceptionTime,
                //	Notes = fee.Notes
                //};

                //Log.Debug("fee {0} replaced by {1}", fee, newFee);

                //replacedDistributedFees.Add(newFee);
            }

            //Calculator.distributedFeesList.AddRange(replacedDistributedFees);
            //WorkingModel.Loan.Fees.AddRange(replacedDistributedFees);

            if (distributedFees)
            {
                // offer-fees
                NL_OfferFees offerFees = WorkingModel.Offer.OfferFees.FirstOrDefault();

                if (offerFees != null && offerFees.DistributedPartPercent != null && (decimal)offerFees.DistributedPartPercent == 1)
                {
                    var     feeCalculator          = new SetupFeeCalculator(offerFees.Percent, null);
                    decimal servicingFeeAmount     = feeCalculator.Calculate(newHistory.Amount).Total;
                    decimal servicingFeePaidAmount = WorkingModel.Loan.Fees.Where(f => f.LoanFeeTypeID == (int)NLFeeTypes.ServicingFee).Sum(f => f.PaidAmount);

                    Log.Debug("servicingFeeAmount: {0}, servicingFeePaidAmount: {1}", servicingFeeAmount, servicingFeePaidAmount);                     // new "spreaded" amount

                    Calculator.AttachDistributedFeesToLoanBySchedule(WorkingModel, (servicingFeeAmount - servicingFeePaidAmount), acceptionTime);
                }
            }

            // TODO could be reseted at all??????????????
            // reset paid amount for deleted/closed schedules and disabled distributed fees
            foreach (NL_Payments p in WorkingModel.Loan.Payments)
            {
                foreach (NL_LoanSchedulePayments sp in p.SchedulePayments)
                {
                    foreach (NL_LoanSchedules s in Calculator.schedule.Where(s => s.IsDeleted()))
                    {
                        if (s.LoanScheduleID == sp.LoanScheduleID)
                        {
                            sp.ResetInterestPaid  = sp.PrincipalPaid;
                            sp.ResetPrincipalPaid = sp.PrincipalPaid;

                            sp.PrincipalPaid = 0;
                            sp.InterestPaid  = 0;
                        }
                    }
                }

                foreach (NL_LoanFeePayments fp in p.FeePayments)
                {
                    foreach (NL_LoanFees f in Calculator.distributedFeesList.Where(f => f.DisabledTime.Equals(acceptionTime)))
                    {
                        if (f.LoanFeeID == fp.LoanFeeID)
                        {
                            fp.ResetAmount = fp.Amount;
                            fp.Amount      = 0;

                            f.PaidAmount -= (decimal)fp.ResetAmount;
                        }
                    }
                }
            }

            Calculator.acceptedRolloverProcessed = true;
        }
Beispiel #4
0
        }         // RejectCustomer

        private bool ApproveCustomer(NL_Decisions newDecision)
        {
            LinkOfferToInvestor linkOfferToInvestor = new LinkOfferToInvestor(this.decisionToApply.Customer.ID, this.decisionToApply.CashRequest.ID, this.decisionModel.ForceInvestor, this.decisionModel.InvestorID, this.decisionModel.underwriterID);

            linkOfferToInvestor.Execute();

            Log.Info("ApproveCustomer Decision {0} for Customer {1} cr {2} OP {3} FoundInvestor {4}",
                     this.decisionToApply.CashRequest.UnderwriterDecision,
                     this.decisionToApply.Customer.ID,
                     this.decisionToApply.CashRequest.ID,
                     linkOfferToInvestor.IsForOpenPlatform,
                     linkOfferToInvestor.FoundInvestor);

            if (linkOfferToInvestor.IsForOpenPlatform && !linkOfferToInvestor.FoundInvestor)
            {
                PendingInvestor(newDecision);
                return(false);
            }

            this.decisionToApply.Customer.DateApproved   = this.now;
            this.decisionToApply.Customer.ApprovedReason = this.decisionModel.reason;

            this.decisionToApply.Customer.CreditSum                  = this.currentState.OfferedCreditLine;
            this.decisionToApply.Customer.ManagerApprovedSum         = this.currentState.OfferedCreditLine;
            this.decisionToApply.Customer.NumApproves                = 1 + this.currentState.NumOfPrevApprovals;
            this.decisionToApply.Customer.IsLoanTypeSelectionAllowed = this.currentState.IsLoanTypeSelectionAllowed;

            this.decisionToApply.CashRequest.ManagerApprovedSum = (int)this.currentState.OfferedCreditLine;

            if (!SaveDecision <ManuallyApprove>())
            {
                return(false);
            }

            bool bSendBrokerForceResetCustomerPassword =
                this.currentState.FilledByBroker &&
                (this.currentState.NumOfPrevApprovals == 0);

            bool bSendApprovedUser = !this.currentState.EmailSendingBanned;

            int validForHours = (int)(this.currentState.OfferValidUntil - this.currentState.OfferStart).TotalHours;

            if (bSendBrokerForceResetCustomerPassword && bSendApprovedUser)
            {
                FireToBackground(
                    new ApprovedUser(
                        this.decisionModel.customerID,
                        this.currentState.OfferedCreditLine,
                        validForHours,
                        this.currentState.NumOfPrevApprovals == 0
                        )
                {
                    SendToCustomer = false,
                },
                    e => Warning = "Failed to force reset customer password and send 'approved user' email: " + e.Message
                    );
            }
            else if (bSendApprovedUser)
            {
                FireToBackground(
                    new ApprovedUser(
                        this.decisionModel.customerID,
                        this.currentState.OfferedCreditLine,
                        validForHours,
                        this.currentState.NumOfPrevApprovals == 0
                        ),
                    e => Warning = "Failed to send 'approved user' email: " + e.Message
                    );
            }
            else if (bSendBrokerForceResetCustomerPassword)
            {
                FireToBackground(new BrokerForceResetCustomerPassword(this.decisionModel.customerID));
            }

            newDecision.DecisionNameID = (int)DecisionActions.Approve;

            AddDecision nlAddDecision = new AddDecision(newDecision, this.decisionToApply.CashRequest.ID, null);

            nlAddDecision.Context.CustomerID = this.decisionModel.customerID;
            nlAddDecision.Context.UserID     = this.decisionModel.underwriterID;

            try {
                try {
                    nlAddDecision.Execute();
                    Log.Debug("nl AddDecision {0}, Error: {1}", nlAddDecision.DecisionID, nlAddDecision.Error);

                    // ReSharper disable once CatchAllClause
                } catch (Exception ex) {
                    Log.Error("Failed to add NL_decision. Err: {0}", ex.Message);
                }

                NL_Offers nlOffer = new NL_Offers()
                {
                    DecisionID            = nlAddDecision.DecisionID,
                    CreatedTime           = this.currentState.CreationDate,
                    Amount                = this.currentState.OfferedCreditLine,
                    BrokerSetupFeePercent = this.currentState.BrokerSetupFeePercent,
                    //IsAmountSelectionAllowed = this.currentState.
                    SendEmailNotification = !this.currentState.EmailSendingBanned,
                    StartTime             = this.currentState.OfferStart,
                    EndTime = this.currentState.OfferValidUntil,
                    IsLoanTypeSelectionAllowed = this.currentState.IsLoanTypeSelectionAllowed == 1,
                    Notes = this.decisionToApply.CashRequest.UnderwriterComment + " old cr " + this.decisionToApply.CashRequest.ID,
                    MonthlyInterestRate               = this.currentState.InterestRate,
                    LoanSourceID                      = this.currentState.LoanSourceID,
                    DiscountPlanID                    = this.currentState.DiscountPlanID,
                    LoanTypeID                        = this.currentState.LoanTypeID,
                    RepaymentIntervalTypeID           = (int)RepaymentIntervalTypes.Month,
                    RepaymentCount                    = this.currentState.RepaymentPeriod,  // ApprovedRepaymentPeriod???
                    IsRepaymentPeriodSelectionAllowed = this.currentState.IsCustomerRepaymentPeriodSelectionAllowed
                };

                Log.Debug("Adding nl offer: {0}", nlOffer);

                NL_OfferFees setupFee = new NL_OfferFees()
                {
                    LoanFeeTypeID          = (int)NLFeeTypes.SetupFee,
                    Percent                = this.currentState.ManualSetupFeePercent,
                    OneTimePartPercent     = 1,
                    DistributedPartPercent = 0
                };

                if (this.currentState.SpreadSetupFee)
                {
                    setupFee.LoanFeeTypeID          = (int)NLFeeTypes.ServicingFee;
                    setupFee.OneTimePartPercent     = 0;
                    setupFee.DistributedPartPercent = 1;
                }
                NL_OfferFees[] ofeerFees = { setupFee };

                AddOffer sAddOffer = new AddOffer(nlOffer, ofeerFees);
                sAddOffer.Context.CustomerID = this.decisionToApply.Customer.ID;
                sAddOffer.Context.UserID     = this.decisionModel.underwriterID;

                try {
                    sAddOffer.Execute();
                    Log.Debug("nl offer added: {0}, Error: {1}", sAddOffer.OfferID, sAddOffer.Error);
                    // ReSharper disable once CatchAllClause
                } catch (Exception ex) {
                    Log.Error("Failed to AddOffer. Err: {0}", ex.Message);
                }

                // ReSharper disable once CatchAllClause
            } catch (Exception nlException) {
                Log.Error("Failed to run NL offer/decision Err: {0}", nlException.Message);
            }

            UpdateSalesForceOpportunity(OpportunityStage.s90, model => {
                model.ApprovedAmount  = (int)this.currentState.OfferedCreditLine;
                model.ExpectedEndDate = this.currentState.OfferValidUntil;
            });

            return(true);
        }        // ApproveCustomer
Beispiel #5
0
        public JsonResult ChangeCreditLine(
            long id,
            int productID,
            int productTypeID,
            int productSubTypeID,
            int loanType,
            int loanSource,
            double amount,
            decimal interestRate,
            int repaymentPeriod,
            string offerStart,
            string offerValidUntil,
            bool allowSendingEmail,
            int discountPlan,
            decimal?brokerSetupFeePercent,
            decimal?manualSetupFeePercent,
            bool isCustomerRepaymentPeriodSelectionAllowed,
            int isLoanTypeSelectionAllowed,
            bool spreadSetupFee,
            bool feesManuallyUpdated
            )
        {
            CashRequest cr = this.cashRequestsRepository.Get(id);

            if (cr.Id <= 0)
            {
                log.Error("No cash request found");
                return(Json(true));
            }             // if

            new Transactional(() => {
                LoanType loanT    = this.loanTypes.Get(loanType);
                LoanSource source = this.loanSources.Get(loanSource);

                cr.LoanType = loanT;

                int step = CurrentValues.Instance.GetCashSliderStep;
                int sum  = (int)Math.Round(amount / step, MidpointRounding.AwayFromZero) * step;
                cr.ManagerApprovedSum      = sum;
                cr.LoanSource              = source;
                cr.InterestRate            = interestRate;
                cr.RepaymentPeriod         = repaymentPeriod;
                cr.ApprovedRepaymentPeriod = cr.RepaymentPeriod;
                cr.OfferStart              = FormattingUtils.ParseDateWithCurrentTime(offerStart);
                cr.OfferValidUntil         = FormattingUtils.ParseDateWithCurrentTime(offerValidUntil);

                cr.BrokerSetupFeePercent = brokerSetupFeePercent;
                cr.ManualSetupFeePercent = manualSetupFeePercent;
                cr.UwUpdatedFees         = feesManuallyUpdated;

                cr.EmailSendingBanned = !allowSendingEmail;
                cr.LoanTemplate       = null;

                cr.IsLoanTypeSelectionAllowed = isLoanTypeSelectionAllowed;
                cr.IsCustomerRepaymentPeriodSelectionAllowed = isCustomerRepaymentPeriodSelectionAllowed;

                cr.DiscountPlan      = this.discounts.Get(discountPlan);
                cr.SpreadSetupFee    = spreadSetupFee;
                cr.ProductSubTypeID  = productSubTypeID;
                Customer c           = cr.Customer;
                c.OfferStart         = cr.OfferStart;
                c.OfferValidUntil    = cr.OfferValidUntil;
                c.ManagerApprovedSum = sum;

                this.cashRequestsRepository.SaveOrUpdate(cr);
                this.customerRepository.SaveOrUpdate(c);
            }).Execute();

            var decision = this.serviceClient.Instance.AddDecision(this.context.UserId, cr.Customer.Id, new NL_Decisions {
                UserID         = this.context.UserId,
                DecisionTime   = DateTime.UtcNow,
                DecisionNameID = (int)DecisionActions.Waiting,
                Notes          = "Waiting; oldCashRequest: " + cr.Id
            }, cr.Id, null);

            // TODO: save feesManuallyUpdated in new loan structure (EZ-4829)

            log.Info("NL decisionID: {0}, oldCashRequestID: {1}, Error: {2}", decision.Value, cr.Id, decision.Error);

            NL_OfferFees offerFee = new NL_OfferFees()
            {
                LoanFeeTypeID          = (int)NLFeeTypes.SetupFee,
                Percent                = manualSetupFeePercent ?? 0,
                OneTimePartPercent     = 1,
                DistributedPartPercent = 0
            };

            if (cr.SpreadSetupFee != null && cr.SpreadSetupFee == true)
            {
                offerFee.LoanFeeTypeID          = (int)NLFeeTypes.ServicingFee;
                offerFee.OneTimePartPercent     = 0;
                offerFee.DistributedPartPercent = 1;
            }
            NL_OfferFees[] ofeerFees = { offerFee };

            var offer = this.serviceClient.Instance.AddOffer(this.context.UserId, cr.Customer.Id, new NL_Offers {
                DecisionID = decision.Value,
                LoanTypeID = loanType,
                RepaymentIntervalTypeID = (int)DbConstants.RepaymentIntervalTypes.Month,
                LoanSourceID            = loanSource,
                StartTime             = FormattingUtils.ParseDateWithCurrentTime(offerStart),
                EndTime               = FormattingUtils.ParseDateWithCurrentTime(offerValidUntil),
                RepaymentCount        = repaymentPeriod,
                Amount                = (decimal)amount,
                MonthlyInterestRate   = interestRate,
                CreatedTime           = DateTime.UtcNow,
                BrokerSetupFeePercent = brokerSetupFeePercent ?? 0,
                Notes                             = "offer from ChangeCreditLine, ApplicationInfoController",
                DiscountPlanID                    = discountPlan,
                IsLoanTypeSelectionAllowed        = isLoanTypeSelectionAllowed == 1,
                IsRepaymentPeriodSelectionAllowed = isCustomerRepaymentPeriodSelectionAllowed,
                SendEmailNotification             = allowSendingEmail,
                ProductSubTypeID                  = productSubTypeID
                                                    // SetupFeeAddedToLoan = 0 // default 0 TODO EZ-3515
                                                    // InterestOnlyRepaymentCount =
                                                    //IsAmountSelectionAllowed = 1 default 1 always allowed
            }, ofeerFees);

            log.Info("NL--- offerID: {0}, decisionID: {1} oldCashRequestID: {2}, Error: {3}", offer.Value, decision.Value, cr.Id, offer.Error);


            log.Debug("update offer for customer {0} all the offer is changed", cr.Customer.Id);

            return(Json(true));
        }         // ChangeCreditLine
		public override void Execute() {

			string query = "select top 20 Id from Loan l left join NL_Loans nl on nl.OldLoanID=l.Id and l.Id=null and l.Modified=0";

			NL_AddLog(LogType.Info, "Strategy start", query, null, null, null);

			List<MigrateLoanTransaction.LoanId> loansList = DB.Fill<MigrateLoanTransaction.LoanId>(query, CommandSpecies.Text);

			if (loansList.Count == 0) {
				Error = "Loans to migrate to NL not found";
				Log.Debug(Error);
				NL_AddLog(LogType.Info, "Strategy end", query, null, Error, null);
				return;
			}

			NL_AddLog(LogType.Info, "Loans to migrate", null, loansList.Count, null, null);

			foreach (MigrateLoanTransaction.LoanId l in loansList) {

				Loan loan = loanRep.Get(l.Id);

				if (loan == null) {
					Error = string.Format("Failed to load old loan {0}", l.Id);
					Log.Info(Error);
					NL_AddLog(LogType.Info, Error, l.Id, null, Error, null);
					continue;
				}

				Context.CustomerID = loan.Customer.Id;
				Context.UserID = loan.CashRequest.IdUnderwriter;
	
				try {

					// [ELINAR-PC].[ezbob].[dbo].[NL_CashRequestGetByOldID]

					query = "select CashRequestID from NL_CashRequests where [OldCashRequestID]=" + loan.CashRequest.Id;

					Log.Debug("Processing loan {0}, cr {1}, {2}", loan.Id, loan.CashRequest.Id, query);

					MigrateLoanTransaction.CashReqModel crModel = DB.FillFirst<MigrateLoanTransaction.CashReqModel>(query, CommandSpecies.Text, new QueryParameter("@crID", loan.CashRequest.Id));

					NL_AddLog(LogType.Info, "crModel", new object[] { query, loan.CashRequest.Id, l.Id }, crModel, null, null);

					// copy to NL_CashRequests
					if (crModel.CashRequestID == 0L) {
						AddCashRequest sCashRequest = new AddCashRequest(new NL_CashRequests {
							CustomerID = loan.Customer.Id,
							RequestTime = (DateTime)loan.CashRequest.CreationDate,
							CashRequestOriginID = loan.CashRequest.Originator.HasValue ? (int)loan.CashRequest.Originator.Value : 5, // NL_CashRequestOrigins "Other"
							UserID = loan.CashRequest.IdUnderwriter ?? 1,
							OldCashRequestID = loan.CashRequest.Id
						});
						
						sCashRequest.Context.CustomerID = Context.CustomerID;
						sCashRequest.Context.UserID = Context.UserID;

						sCashRequest.Execute();
						crModel.CashRequestID = sCashRequest.CashRequestID;
					}

					if (crModel.CashRequestID == 0L) {
						Error = string.Format("Failed to add/find nl CR, oldID {0}, crID {1}", loan.Id, loan.CashRequest.Id);
						Log.Info(Error);
						NL_AddLog(LogType.Info, "NL CR failed", loan.CashRequest.Id, null, Error, null);
						continue;
					}

					// copy decisions
					foreach (DecisionHistory dh in loan.CashRequest.DecisionHistories) {

						query = string.Format("select DecisionID from [dbo].[NL_Decisions] d join [dbo].[NL_CashRequests] c on d.CashRequestID=c.CashRequestID and c.OldCashRequestID={0} and d.UserID={1} " +
							"and d.DecisionNameID={2} and d.DecisionTime='{3}'",
								dh.CashRequest.Id, dh.Underwriter.Id, (int)dh.Action, dh.Date.ToString("yyyy-MM-dd HH:mm:ss"));

						//query = "select DecisionID from [dbo].[NL_Decisions] d join [dbo].[NL_CashRequests] c on d.CashRequestID=c.CashRequestID and c.OldCashRequestID=@crID " +
						//	"and d.UserID=@uID and d.DecisionNameID=@dID and d.DecisionTime='@dDate'";
							//"datediff(DAY, d.DecisionTime, '@dDate')=0";

						MigrateLoanTransaction.CashReqModel dModel = DB.FillFirst<MigrateLoanTransaction.CashReqModel>(query, CommandSpecies.Text/*, 
							new QueryParameter("@crID", dh.CashRequest.Id),
							new QueryParameter("@uID", dh.Underwriter.Id),
							new QueryParameter("@dID", (int)dh.Action),
							new QueryParameter("@dDate", dh.Date.ToString("yyyy-MM-dd HH:mm:ss"))*/); 

						NL_AddLog(LogType.Info, "dModel", new object[] { query, dh.CashRequest.Id, dh.Underwriter.Id, (int)dh.Action, dh.Date }, dModel, null, null);

						if (dModel.DecisionID == 0L) {

							List<NL_DecisionRejectReasons> rejectReasons = new List<NL_DecisionRejectReasons>();
							if (dh.RejectReasons.Count > 0) {
								dh.RejectReasons.ForEach(x => rejectReasons.Add(new NL_DecisionRejectReasons() {
									RejectReasonID = x.RejectReason.Id
								}));
							}

							AddDecision sDesicion = new AddDecision(new NL_Decisions {
								CashRequestID = dh.CashRequest.Id,
								UserID = dh.Underwriter.Id,
								DecisionNameID = (int)dh.Action,
								DecisionTime = dh.Date,
								Notes = string.Format("{0}. (migrated: old crID {1}, loan {2})", dh.Comment, loan.CashRequest.Id, l.Id)
							}, loan.CashRequest.Id, rejectReasons);

							sDesicion.Context.CustomerID = dh.Customer.Id;
							sDesicion.Context.UserID = dh.Underwriter.Id;

							sDesicion.Execute();
							dModel.DecisionID = sDesicion.DecisionID;
							crModel.DecisionID = dModel.DecisionID;
						}

						// NL_Offers for approve decision
						if (dh.Action.Equals(DecisionActions.Approve)) {
							NL_OfferFees offerFee = new NL_OfferFees {
								LoanFeeTypeID = (int)NLFeeTypes.SetupFee,
								Percent = loan.CashRequest.ManualSetupFeePercent ?? 0,
								OneTimePartPercent = 1,
								DistributedPartPercent = 0
							};

							if (loan.CashRequest.SpreadSetupFee != null && loan.CashRequest.SpreadSetupFee == true) {
								offerFee.LoanFeeTypeID = (int)NLFeeTypes.ServicingFee;
								offerFee.OneTimePartPercent = 0;
								offerFee.DistributedPartPercent = 1;
							}

							NL_OfferFees[] fees = { offerFee };

							AddOffer sOffer = new AddOffer(new NL_Offers {
								DecisionID = dModel.DecisionID,
								LoanTypeID = (int)NL_Model.LoanTypeNameToNLLoanType(loan.CashRequest.LoanType.Name),
								LoanSourceID = loan.CashRequest.LoanSource.ID,
								RepaymentIntervalTypeID = (int)RepaymentIntervalTypes.Month,
								Amount = loan.CashRequest.ApprovedSum(),
								StartTime = (DateTime)loan.CashRequest.OfferStart,
								EndTime = (DateTime)loan.CashRequest.OfferValidUntil,
								CreatedTime = (DateTime)loan.CashRequest.UnderwriterDecisionDate, // TODO ????
								DiscountPlanID = loan.CashRequest.DiscountPlan.Id, // supposed discounts transformed right 
								MonthlyInterestRate = loan.CashRequest.InterestRate,
								RepaymentCount = loan.CashRequest.ApprovedRepaymentPeriod ?? loan.CashRequest.RepaymentPeriod,
								BrokerSetupFeePercent = loan.CashRequest.BrokerSetupFeePercent,
								IsLoanTypeSelectionAllowed = loan.CashRequest.IsCustomerRepaymentPeriodSelectionAllowed,
								IsRepaymentPeriodSelectionAllowed = loan.CashRequest.IsCustomerRepaymentPeriodSelectionAllowed,
								SendEmailNotification = !loan.CashRequest.EmailSendingBanned,
								Notes = string.Format("{0}. (migrated: old crID {1}, loan {2})", loan.CashRequest.UnderwriterComment, loan.CashRequest.Id, l.Id),
								ProductSubTypeID = loan.CashRequest.ProductSubTypeID ?? null
							}, fees);

							sOffer.Context.CustomerID = dh.Customer.Id;
							sOffer.Context.UserID = dh.Underwriter.Id;

							sOffer.Execute();
							crModel.OfferID = sOffer.OfferID;
						}
					}

					// do in backfill -  after migration end
					// update .[dbo].[MedalCalculations], .[dbo].[MedalCalculationsAV]
				//	query =
				//		"IF (SELECT [NLCashRequestID] FROM [dbo].[MedalCalculations] WHERE [CashRequestID]=@crID) is null begin update [dbo].[MedalCalculations] set [NLCashRequestID]=@nlcrID where [CashRequestID]=@crID end " +
				//			"IF (SELECT [NLCashRequestID] FROM [dbo].[MedalCalculationsAV] WHERE [CashRequestID]=@crID) is null begin update [dbo].[MedalCalculationsAV] set [NLCashRequestID]=@nlcrID where [CashRequestID]=@crID end";
				//	+	"IF (SELECT [NLOfferID] FROM [dbo].[I_InvestorSystemBalance] WHERE [CashRequestID]=@crID) is null begin update [dbo].[I_InvestorSystemBalance] set [NLOfferID]=@nlcrID where [CashRequestID]=@crID end ";				
					
				//	DB.ExecuteNonQuery(query, CommandSpecies.Text, new QueryParameter("@crID", loan.CashRequest.Id), new QueryParameter("@nlcrID", crModel.CashRequestID));

					NL_AddLog(LogType.Info, "Strategy end", loansList, Error, null, null);

					// ReSharper disable once CatchAllClause
				} catch (Exception exc) {
					Error = exc.Message;
					Log.Alert(exc);
					NL_AddLog(LogType.Error, "Strategy failed", null, Error, exc.ToString(), exc.StackTrace);
					return;
				}
			}
		}
Beispiel #7
0
        }         // constructor

        protected void AddNLDecisionOffer(DateTime now)
        {
            AddDecision addDecisionStra = new AddDecision(new NL_Decisions {
                DecisionNameID = this.autoDecisionResponse.DecisionCode ?? (int)DecisionActions.Waiting,
                DecisionTime   = now,
                Notes          = this.autoDecisionResponse.CreditResult.HasValue
                                        ? this.autoDecisionResponse.CreditResult.Value.DescriptionAttr()
                                        : string.Empty,
                CashRequestID = this.nlCashRequestID,
                UserID        = this.underwriterID,
            }, this.cashRequestID, null);

            addDecisionStra.Execute();
            long decisionID = addDecisionStra.DecisionID;

            Log.Debug("Added NL decision: {0}", decisionID);

            if (!this.autoDecisionResponse.DecidedToApprove)
            {
                return;
            }

            NL_OfferFees setupFee = new NL_OfferFees {
                LoanFeeTypeID          = (int)NLFeeTypes.SetupFee,
                Percent                = this.autoDecisionResponse.SetupFee,
                OneTimePartPercent     = 1,
                DistributedPartPercent = 0
            };

            if (this.autoDecisionResponse.SpreadSetupFee)
            {
                setupFee.LoanFeeTypeID          = (int)NLFeeTypes.ServicingFee;
                setupFee.OneTimePartPercent     = 0;
                setupFee.DistributedPartPercent = 1;
            }             // if

            NL_OfferFees[] ofeerFees = { setupFee };

            AddOffer addOfferStrategy = new AddOffer(new NL_Offers {
                DecisionID                        = decisionID,
                Amount                            = this.autoDecisionResponse.ApprovedAmount,
                StartTime                         = now,
                EndTime                           = now.AddHours(this.offerValidForHours),
                CreatedTime                       = now,
                DiscountPlanID                    = this.autoDecisionResponse.DiscountPlanIDToUse,
                LoanSourceID                      = this.autoDecisionResponse.LoanSource.ID,
                LoanTypeID                        = this.autoDecisionResponse.LoanTypeID,
                RepaymentIntervalTypeID           = (int)RepaymentIntervalTypes.Month,
                MonthlyInterestRate               = this.autoDecisionResponse.InterestRate,
                RepaymentCount                    = this.autoDecisionResponse.RepaymentPeriod,
                BrokerSetupFeePercent             = this.autoDecisionResponse.BrokerSetupFeePercent,
                IsLoanTypeSelectionAllowed        = this.autoDecisionResponse.IsCustomerRepaymentPeriodSelectionAllowed,
                IsRepaymentPeriodSelectionAllowed = this.autoDecisionResponse.IsCustomerRepaymentPeriodSelectionAllowed,
                SendEmailNotification             = !this.autoDecisionResponse.LoanOfferEmailSendingBannedNew,
                // ReSharper disable once PossibleInvalidOperationException
                Notes = "Auto decision: " + this.autoDecisionResponse.Decision.Value,
            }, ofeerFees);

            addOfferStrategy.Execute();

            Log.Debug("Added NL offer: {0}", addOfferStrategy.OfferID);
        }         // AddNLDecisionOffer