} // SuspendCustomer private void EscalateCustomer(NL_Decisions newDecision) { this.decisionToApply.Customer.DateEscalated = this.now; this.decisionToApply.Customer.EscalationReason = this.decisionModel.reason; if (!SaveDecision <ManuallyEscalate>()) { return; } FireToBackground( new Escalated(this.decisionModel.customerID), e => Warning = "Failed to send 'escalated' email: " + e.Message ); newDecision.DecisionNameID = (int)DecisionActions.Escalate; AddDecision nlAddDecision = new AddDecision(newDecision, this.decisionToApply.CashRequest.ID, null); nlAddDecision.Context.CustomerID = this.decisionModel.customerID; nlAddDecision.Context.UserID = this.decisionModel.underwriterID; try { nlAddDecision.Execute(); // ReSharper disable once CatchAllClause } catch (Exception ex) { Log.Error("Failed to add NL_decision. Err: {0}", ex.Message); } UpdateSalesForceOpportunity(OpportunityStage.s20); } // EscalateCustomer
} // EscalateCustomer private bool RejectCustomer(NL_Decisions newDecision) { this.decisionToApply.Customer.DateRejected = this.now; this.decisionToApply.Customer.RejectedReason = this.decisionModel.reason; this.decisionToApply.Customer.NumRejects = 1 + this.currentState.NumOfPrevRejections; this.decisionToApply.CashRequest.RejectionReasons.Clear(); List <NL_DecisionRejectReasons> nlRejectReasonsList = new List <NL_DecisionRejectReasons>(); if (this.decisionModel.rejectionReasons != null && this.decisionModel.rejectionReasons.Any()) { this.decisionToApply.CashRequest.RejectionReasons.AddRange(this.decisionModel.rejectionReasons); nlRejectReasonsList = this.decisionModel.rejectionReasons.Select(x => new NL_DecisionRejectReasons { RejectReasonID = x }).ToList(); } if (!SaveDecision <ManuallyReject>()) { return(false); } bool bSendToCustomer = !(this.currentState.FilledByBroker && (this.currentState.NumOfPrevApprovals == 0)); if (!this.currentState.EmailSendingBanned) { FireToBackground( new RejectUser(this.decisionModel.customerID, bSendToCustomer), e => Warning = "Failed to send 'reject user' email: " + e.Message ); } // if newDecision.DecisionNameID = (int)DecisionActions.Reject; AddDecision nlAddDecision = new AddDecision(newDecision, this.decisionToApply.CashRequest.ID, nlRejectReasonsList); nlAddDecision.Context.CustomerID = this.decisionModel.customerID; nlAddDecision.Context.UserID = this.decisionModel.underwriterID; try { nlAddDecision.Execute(); // ReSharper disable once CatchAllClause } catch (Exception ex) { Log.Error("Failed to add NL_decision. Err: {0}", ex.Message); } UpdateSalesForceOpportunity(null, model => { model.CloseDate = this.now; model.DealCloseType = OpportunityDealCloseReason.Lost.ToString(); model.DealLostReason = this.decisionModel.reason; }); return(true); } // RejectCustomer
public void TestAddDecision() { AddDecision addDecision = new AddDecision(new NL_Decisions { UserID = 357, DecisionTime = DateTime.UtcNow, Notes = " old CR 30364", DecisionNameID = (int)DecisionActions.Reject }, 30364, new List<NL_DecisionRejectReasons> { new NL_DecisionRejectReasons { RejectReasonID = 1 }, new NL_DecisionRejectReasons { RejectReasonID = 3 } } ); addDecision.Execute(); Console.WriteLine(addDecision.DecisionID); Console.WriteLine(addDecision.Error); }
} // ReturnCustomerToWaitingForDecision private bool SuspendCustomer(NL_Decisions newDecision) { this.decisionToApply.Customer.IsWaitingForSignature = this.decisionModel.signature == 1; this.decisionToApply.Customer.ManagerApprovedSum = this.currentState.OfferedCreditLine; if (!SaveDecision <ManuallySuspend>()) { return(false); } newDecision.DecisionNameID = (int)DecisionActions.Pending; AddDecision nlAddDecision = new AddDecision(newDecision, this.decisionToApply.CashRequest.ID, null); nlAddDecision.Context.CustomerID = this.decisionModel.customerID; nlAddDecision.Context.UserID = this.decisionModel.underwriterID; nlAddDecision.Execute(); UpdateSalesForceOpportunity((this.decisionModel.signature == 1) ? OpportunityStage.s75 : OpportunityStage.s50); return(true); } // SuspendCustomer
} // CanChangeDecision private void ReturnCustomerToWaitingForDecision(NL_Decisions newDecision) { if (!SaveDecision <ManuallyUnsuspend>()) { return; } newDecision.DecisionNameID = (int)DecisionActions.Waiting; AddDecision nlAddDecision = new AddDecision(newDecision, this.decisionToApply.CashRequest.ID, null); nlAddDecision.Context.CustomerID = this.decisionModel.customerID; nlAddDecision.Context.UserID = this.decisionModel.underwriterID; try { nlAddDecision.Execute(); // ReSharper disable once CatchAllClause } catch (Exception ex) { Log.Error("Failed to add NL_decision. Err: {0}", ex.Message); } UpdateSalesForceOpportunity(OpportunityStage.s40); } // ReturnCustomerToWaitingForDecision
} // 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
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; } } }
} // 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