// Simple check to see if model is valid // This is only used for final validation to detect account changes or tampering // therefore does not need to feed back errors to user public bool Validate(PaymentOptionsVm paymentOptionsVm) { PaymentOptionsVmValidator validator = new PaymentOptionsVmValidator(); ValidationResult result = validator.Validate(paymentOptionsVm); return(result.IsValid); }
// Used to re-instate user entries after loading fresh data from CaseFlow or from cache public void UpdateFieldsFromUserEntries(IUserIdentity loggedInUser, PaymentOptionsVm paymentOptionsToUpdate, PaymentOptionsVm paymentOptionsUserEntries) { paymentOptionsToUpdate.DiscountAccepted = paymentOptionsUserEntries.DiscountAccepted; paymentOptionsToUpdate.SelectedPaymentOption = paymentOptionsUserEntries.SelectedPaymentOption; paymentOptionsToUpdate.FullPaymentSelectedSourceOfFunds = paymentOptionsUserEntries.FullPaymentSelectedSourceOfFunds; paymentOptionsToUpdate.FullPaymentSourceOfFundsOtherText = paymentOptionsUserEntries.FullPaymentSourceOfFundsOtherText; paymentOptionsToUpdate.PartialPaymentAmount = paymentOptionsUserEntries.PartialPaymentAmount; paymentOptionsToUpdate.PartialPaymentSelectedSourceOfFunds = paymentOptionsUserEntries.PartialPaymentSelectedSourceOfFunds; paymentOptionsToUpdate.PartialPaymentSourceOfFundsOtherText = paymentOptionsUserEntries.PartialPaymentSourceOfFundsOtherText; paymentOptionsToUpdate.DirectDebitSelectedFrequency = paymentOptionsUserEntries.DirectDebitSelectedFrequency; paymentOptionsToUpdate.DirectDebitSelectedStartDate = paymentOptionsUserEntries.DirectDebitSelectedStartDate; paymentOptionsToUpdate.DirectDebitAmount = paymentOptionsUserEntries.DirectDebitAmount; paymentOptionsToUpdate.AverageMonthlyPayment = paymentOptionsUserEntries.AverageMonthlyPayment; paymentOptionsToUpdate.MonthlyDisposableIncome = paymentOptionsUserEntries.MonthlyDisposableIncome; paymentOptionsToUpdate.SelectedPlanSetupOption = paymentOptionsUserEntries.SelectedPlanSetupOption; paymentOptionsToUpdate.IandELessThanOrIs12MonthsOld = paymentOptionsUserEntries.IandELessThanOrIs12MonthsOld; // User should only have provided Direct Debit Email Address if they are anonymous (not logged in) // Email will have been pre-populated with user's email address during building of VM if they are logged in if (!loggedInUser.IsLoggedInUser) { paymentOptionsToUpdate.DirectDebitEmailAddress = paymentOptionsUserEntries.DirectDebitEmailAddress; } // User only ticks T&C box when anonymous. Will be defaulted to true by builder if logged in. if (!loggedInUser.IsLoggedInUser) { paymentOptionsToUpdate.AcceptTermsAndConditions = paymentOptionsUserEntries.AcceptTermsAndConditions; } }
public IActionResult Cancel(Guid id, PaymentOptionsVm paymentOptionsVmPostedBack) { // Restore VM from state field, so that we get lists and all other fields required to build view var paymentOptionsVm = DeserialiseModel <PaymentOptionsVm>(paymentOptionsVmPostedBack.InitialState); Debug.Assert(paymentOptionsVm.InitialState == null, "Serialisation Loop Detected - InitialState should be marked as JsonIgnore"); // Carry state through paymentOptionsVm.InitialState = paymentOptionsVmPostedBack.InitialState; // Place form field selections into restored VM _buildPaymentOptionsVmService.UpdateFieldsFromUserEntries(LoggedInUser, paymentOptionsVm, paymentOptionsVmPostedBack); // Construct model for Cancel view var cancelVm = new ReturnToFormVm { State = SerialiseModel(paymentOptionsVm), StateFieldName = nameof(PaymentOptionsStateVm.FilledInState), StateType = nameof(PaymentOptionsVm), ReturnControllerName = ControllerName, ReturnActionName = nameof(Change) }; return(View("PaymentCancel", cancelVm)); }
public void DirectDebit_SelectedPlanSetupOption_OtherPaymentOffer() { _accountVm = new PaymentOptionsVm() { AcceptTermsAndConditions = true, AverageMonthlyPayment = 48.00M, DirectDebitAmount = 48.00M, MonthlyDisposableIncome = 0.00M, DirectDebitEmailAddress = "*****@*****.**", DirectDebitSelectedFrequency = "monthly", DirectDebitSelectedStartDate = DateTime.Now.Date.ToString(), DiscountAccepted = false, DirectDebitStartDateEarliest = DateTime.Now.Date.AddDays(-1), DirectDebitStartDateLatest = DateTime.Now.AddDays(1), DiscountAmount = 0.00M, DiscountBalanceAvailable = false, DiscountPercentage = 0.00M, IandELessThanOrIs12MonthsOld = true, SelectedPaymentOption = "direct-debit", FullPaymentBalance = 123.45M, WithLowellSolicitors = false, OutstandingBalance = 123.45M, SelectedPlanSetupOption = PlanSetupOptions.OtherPaymentOffer }; var result = _validator.Validate(_accountVm); Assert.IsTrue(result.IsValid); }
public void Validate_WhenModelIsInvalid_ReturnsFalse() { PaymentOptionsVm paymentOptionsVm = new PaymentOptionsVm() { SelectedPaymentOption = PaymentOptionsSelectionsVm.Values.PleaseSelect }; Assert.IsFalse(_paymentOptionsValidatorProcess.Validate(paymentOptionsVm)); }
public void Validate_WhenModelIsValid_ReturnsTrue() { // Simplest possible valid scenario PaymentOptionsVm paymentOptionsVm = new PaymentOptionsVm() { SelectedPaymentOption = PaymentOptionsSelectionsVm.Values.FullPayment, FullPaymentSelectedSourceOfFunds = "anything" }; Assert.IsTrue(_paymentOptionsValidatorProcess.Validate(paymentOptionsVm)); }
public void ShowPayOffDiscountedDDPlanWarning_DDPlanNotInPlace_DiscountNotAccepted() { PaymentOptionsVm vm = new PaymentOptionsVm() { PlanInPlace = false, PlanIsDirectDebit = false, DiscountedBalancePreviouslyAccepted = false }; Assert.IsFalse(vm.ShowPayOffDiscountedDDPlanWarning); }
public DirectDebitDetailsVm Build(PaymentOptionsVm paymentOptionsVm) { return(new DirectDebitDetailsVm() { LowellRef = paymentOptionsVm.LowellReference, DiscountAvailable = paymentOptionsVm.DiscountedBalancePreviouslyAccepted || paymentOptionsVm.DiscountBalanceAvailable, PaymentAmount = paymentOptionsVm.DirectDebitAmount, PaymentFrequency = paymentOptionsVm.DirectDebitSelectedFrequency, DiscountSelected = paymentOptionsVm.DiscountAccepted, SelectedPlanSetupOption = paymentOptionsVm.SelectedPlanSetupOption }); }
public RequestDataModel CreateDataModel(PaymentOptionsVm accountVm) { var requestDataModel = new RequestDataModel(); decimal?amount; if (accountVm.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.FullPayment) { amount = accountVm.FullPaymentAmountDerived; } else { amount = accountVm.PartialPaymentAmount; } // Should never be null, as validated with Fluent Debug.Assert(amount != null, "amount != null"); requestDataModel.api = _verifoneSetting.ApiVersion; requestDataModel.merchantid = _verifoneSetting.Merchant.MerchantId; requestDataModel.systemid = _verifoneSetting.Merchant.SystemId; requestDataModel.systemguid = _verifoneSetting.Merchant.SystemGuid; requestDataModel.merchantreference = accountVm.VerifoneTransactionGuid.ToString(); requestDataModel.returnurlxml = $"<returnurl>{_verifoneSetting.CompletionUrlOverride}</returnurl>"; requestDataModel.merchanttemplateid = _verifoneSetting.Template.MerchantTemplateId.SetupPaymentPlan; requestDataModel.languagetemplateid = 1; requestDataModel.capturemethod = 12; requestDataModel.processingidentifier = 1; requestDataModel.accountid = _verifoneSetting.Merchant.AccountId; requestDataModel.transactionvalue = amount.Value; requestDataModel.tokenidxml = ""; requestDataModel.registertoken = "false"; requestDataModel.tokenexpirationdate = DateTime.Now.AddYears(4).ToString("ddMMyyyy"); requestDataModel.allowedpaymentschemes = _verifoneSetting.AllowedPaymentSchemes; requestDataModel.allowedpaymentmethods = "1"; requestDataModel.description = "Payment to Lowell account " + accountVm.LowellReference; requestDataModel.firstname = ""; requestDataModel.lastname = ""; requestDataModel.email = ""; requestDataModel.address1 = ""; requestDataModel.address2 = ""; requestDataModel.postcode = ""; requestDataModel.town = ""; requestDataModel.totalamount = accountVm.OutstandingBalance; requestDataModel.productname = "Payment to Lowell account " + accountVm.LowellReference; requestDataModel.productcode = accountVm.LowellReference; requestDataModel.processCPC = false; requestDataModel.payerauthxml = ""; return(requestDataModel); }
public void CreateDataModel_WhenSelectedPaymentOptionNotFull_TransactionValueIsPartialPaymentAmount() { PaymentOptionsVm paymentOptionsVm = new PaymentOptionsVm() { SelectedPaymentOption = PaymentOptionsSelectionsVm.Values.PartialPayment, VerifoneTransactionGuid = "fb3ce06f-af36-40d4-a88b-dab5f39b0893", PartialPaymentAmount = 987.65m, LowellReference = "anyoldref", OutstandingBalance = 211.12m }; RequestDataModel requestDataModel = _createVerifoneRequestProcess.CreateDataModel(paymentOptionsVm); string tokenexpirationdate = DateTime.Now.AddYears(4).ToString("ddMMyyyy"); Assert.AreEqual(null, requestDataModel.api); // ConfigurationManager.AppSettings["Verifone:PostData:Api"] Assert.AreEqual(null, requestDataModel.merchantid); // ConfigurationManager.AppSettings["Verifone:Merchant:MerchantId"] Assert.AreEqual(null, requestDataModel.systemid); // ConfigurationManager.AppSettings["Verifone:Merchant:SystemId"] Assert.AreEqual(null, requestDataModel.systemguid); // ConfigurationManager.AppSettings["Verifone:Merchant:SystemGuid"]) Assert.AreEqual("fb3ce06f-af36-40d4-a88b-dab5f39b0893", requestDataModel.merchantreference); Assert.AreEqual("<returnurl></returnurl>", requestDataModel.returnurlxml); // $"<returnurl>{ConfigurationManager.AppSettings["Verifone:Url:CompletionUrlOverride"]}</returnurl>"; Assert.AreEqual(null, requestDataModel.merchanttemplateid); // ConfigurationManager.AppSettings["Verifone:Template:MerchantTemplateId:SetupPaymentPlan"] Assert.AreEqual(1, requestDataModel.languagetemplateid); Assert.AreEqual(12, requestDataModel.capturemethod); Assert.AreEqual(1, requestDataModel.processingidentifier); Assert.AreEqual(null, requestDataModel.accountid); // ConfigurationManager.AppSettings["Verifone:Merchant:AccountId"] Assert.AreEqual(987.65m, requestDataModel.transactionvalue); Assert.AreEqual("", requestDataModel.tokenidxml); Assert.AreEqual("false", requestDataModel.registertoken); Assert.AreEqual(tokenexpirationdate, requestDataModel.tokenexpirationdate); Assert.AreEqual(null, requestDataModel.allowedpaymentschemes); // ConfigurationManager.AppSettings["Verifone:PostData:AllowedPaymentSchemes"] Assert.AreEqual("1", requestDataModel.allowedpaymentmethods); Assert.AreEqual("Payment to Lowell account anyoldref", requestDataModel.description); Assert.AreEqual("", requestDataModel.firstname); Assert.AreEqual("", requestDataModel.lastname); Assert.AreEqual("", requestDataModel.email); Assert.AreEqual("", requestDataModel.address1); Assert.AreEqual("", requestDataModel.address2); Assert.AreEqual("", requestDataModel.postcode); Assert.AreEqual("", requestDataModel.town); Assert.AreEqual(211.12m, requestDataModel.totalamount); Assert.AreEqual("Payment to Lowell account anyoldref", requestDataModel.productname); Assert.AreEqual("anyoldref", requestDataModel.productcode); Assert.AreEqual(false, requestDataModel.processCPC); Assert.AreEqual("", requestDataModel.payerauthxml); Assert.Inconclusive("Unable to unit test completely. Should be taking IApplicationSettingsReader as a method parameter, so as to be able to mock config."); Assert.Inconclusive("Make internal method that takes token expiration date, so that it can be unit tested in detail."); }
public void Initialise() { _validator = new PaymentOptionsVmValidator(); _accountVm = new PaymentOptionsVm() { OutstandingBalance = 100, AcceptTermsAndConditions = true, SelectedPaymentOption = PaymentOptionsSelectionsVm.Values.FullPayment, DirectDebitStartDateEarliest = new DateTime(2018, 8, 28), DirectDebitStartDateLatest = new DateTime(2018, 8, 29), DirectDebitSelectedStartDate = "28/08/2018" }; }
private PaymentOptionsVm ConvertToPaymentOptionsVm(string seralisedState) { try { PaymentOptionsVm paymentOptionsVm = DeserialiseModel <PaymentOptionsVm>(seralisedState); return(paymentOptionsVm); } catch (Exception e) { Logger.LogError($"Failed to convert to PaymentVm. Exception details - {e.Message}"); } return(null); }
public async Task <IBuildDirectDebitPlanOverviewVmValidationResult> ValidateAndBuild( IUserIdentity loggedInUser, IApplicationSessionState applicationSessionState, Guid lowellReferenceSurrogateKey, PaymentOptionsVm paymentOptionsVmWithUserEntries, DirectDebitDetailsVm directDebitDetailsVmWithUserEntries, string caseflowUserId) { // // Payment Options - reconstruct from CaseFlow, populate user entris and validate clean // PaymentOptionsVm paymentOptionsVm = await _buildPaymentOptionsVmService.Build(loggedInUser, applicationSessionState, lowellReferenceSurrogateKey, caseflowUserId); _buildPaymentOptionsVmService.UpdateFieldsFromUserEntries(loggedInUser, paymentOptionsVm, paymentOptionsVmWithUserEntries); if (!_paymentOptionsVmValidatorProcess.Validate(paymentOptionsVm)) { return new ValidationResult() { IsValid = false } } ; // // Direct Debit Details - reconstruct from fresh payment options, populate user entris and validate clean // DirectDebitDetailsVm directDebitDetailsVm = _buildDirectDebitDetailsVmService.Build(paymentOptionsVm); _buildDirectDebitDetailsVmService.UpdateFieldsFromUserEntries(directDebitDetailsVm, directDebitDetailsVmWithUserEntries); if (!_directDebitDetailsVmValidatorProcess.Validate(directDebitDetailsVm)) { return new ValidationResult() { IsValid = false } } ; // // Return valid result with overview built clean // return(new ValidationResult() { IsValid = true, DirectDebitPlanOverviewVm = Build(paymentOptionsVm, directDebitDetailsVm) }); } } }
public async Task <ActionResult> Index(PaymentCancelledDto dto) { if (dto.PaymentStateType == nameof(PaymentOptionsVm)) { PaymentOptionsVm vm = DeserialiseModel <PaymentOptionsVm>(dto.PaymentState); if (ApplicationSessionState.LogPaymentResult) { await _webActivityService.LogOneOffPaymentCancelled(vm.LowellReference, LoggedInUserId, vm.SelectedPaymentOption == "partial-payment", vm.DiscountAccepted); ApplicationSessionState.LogPaymentResult = false; } } if (dto.PaymentStateType == nameof(DirectDebitDetailsVm)) { var vm = DeserialiseModel <DirectDebitDetailsVm>(dto.PaymentState); if (ApplicationSessionState.LogSetUpPlanResult) { if (vm.DiscountSelected) { await LogDiscountDirectDebitCancelled(vm); } else { await LogDirectDebitCancelled(vm); } ApplicationSessionState.LogSetUpPlanResult = false; } } if (dto.PaymentStateType == nameof(AmendDirectDebitVm)) { var vm = DeserialiseModel <AmendDirectDebitVm>(dto.PaymentState); if (ApplicationSessionState.LogSetUpPlanResult) { await LogAmendDirectDebitCancelled(vm); ApplicationSessionState.LogSetUpPlanResult = false; } } return(View()); }
public void RaisePaymentEvent_PageVisited(PaymentOptionsVm vm, string userId, string planType) { string plan_status = vm.PlanInPlace ? "Payment against Plan" : "No Plan in Place"; plan_status = !String.IsNullOrEmpty(vm.ArrearsMessage) ? "Plan Arrears Payment" : plan_status; vm.GtmEvents.Add(new GtmEvent() { gtm_event = GtmEvents.PaymentEvent, step = PaymentSteps.Step1VisitMakeAPaymentPage, discount_available = vm.DiscountBalanceAvailable ? "Discount available" : "No discount available", plan_type = planType, plan_status = plan_status, guid = String.IsNullOrEmpty(userId) ? null : userId, user_status = String.IsNullOrEmpty(userId) ? "Not Logged In" : "Logged In" }); }
private async Task LogDiscountDirectDebitCompleteFailure(PaymentOptionsVm paymentOptionsVm) { if (paymentOptionsVm.SelectedPlanSetupOption.HasValue) { switch (paymentOptionsVm.SelectedPlanSetupOption.Value) { case PlanSetupOptions.AverageSetupValue: { await _webActivityService.LogDiscountDirectDebitPaymentASVOptionCompleteFailed(paymentOptionsVm.LowellReference, LoggedInUserId); break; } case PlanSetupOptions.DisposableIncome: { await _webActivityService.LogDiscountDirectDebitDIOptionCompleteFailed(paymentOptionsVm.LowellReference, LoggedInUserId); break; } case PlanSetupOptions.OtherPaymentOffer: { if (paymentOptionsVm.IandENotAvailable || !paymentOptionsVm.IandELessThanOrIs12MonthsOld) { await _webActivityService.LogDiscountDirectDebitMyOfferOptionCompleteFailedWithNoIandE(paymentOptionsVm.LowellReference, LoggedInUserId); } else if (paymentOptionsVm.MonthlyDisposableIncome > 0) { await _webActivityService.LogDiscountDirectDebitMyOfferOptionCompleteFailedWithPositiveIandE(paymentOptionsVm.LowellReference, LoggedInUserId); } else { await _webActivityService.LogDiscountDirectDebitMyOfferOptionCompleteFailedWithNegativeIandE(paymentOptionsVm.LowellReference, LoggedInUserId); } break; } } } }
public async Task <IActionResult> Index(Guid id, PaymentOptionsVm paymentOptionsVmPostedBack) { // Restore VM from state field, so that we get lists and all other fields required to build view var paymentOptionsVm = DeserialiseModel <PaymentOptionsVm>(paymentOptionsVmPostedBack.InitialState); Debug.Assert(paymentOptionsVm.InitialState == null, "Serialisation Loop Detected - InitialState should be marked as JsonIgnore"); // Carry state through paymentOptionsVm.InitialState = paymentOptionsVmPostedBack.InitialState; // Place form field selections into restored VM _buildPaymentOptionsVmService.UpdateFieldsFromUserEntries( LoggedInUser, paymentOptionsVm, paymentOptionsVmPostedBack); return(await ProcessPaymentOptionsPost(id, paymentOptionsVm)); }
public DirectDebitPlanOverviewVm Build(PaymentOptionsVm accountVm, DirectDebitDetailsVm directDebitDetailsVm) { // Should never be null, as validated with Fluent Debug.Assert(accountVm.DirectDebitAmount != null, "accountVm.DirectDebitPayment.Amount != null"); int totalMonths = _directDebitTermCalculator.CalculateTermInMonths( accountVm.FullPaymentAmountDerived, accountVm.DirectDebitAmount.Value, accountVm.DirectDebitSelectedFrequency); int years = totalMonths / 12; int months = totalMonths % 12; DirectDebitPlanOverviewVm directDebitPlanOverview = new DirectDebitPlanOverviewVm() { SortCode = directDebitDetailsVm.SortCode, AccountNumber = directDebitDetailsVm.AccountNumber, AccountHoldersName = directDebitDetailsVm.AccountHoldersName, ClientName = accountVm.ClientName, LowellReference = accountVm.LowellReference, PaymentAmount = accountVm.DirectDebitAmount.Value, PaymentType = AccountMessages.DirectDebit, StartDate = accountVm.DirectDebitSelectedStartDate, Frequency = _directDebitFrequencyTranslator.TranslateClientScriptCompatibleValueToDescription( accountVm.DirectDebitSelectedFrequency), GuaranteeRead = directDebitDetailsVm.AcceptDirectDebitGuarantee, PlanTotal = accountVm.DiscountedBalancePreviouslyAccepted ? accountVm.DiscountedBalance : accountVm.OutstandingBalance, DiscountAccepted = accountVm.DiscountAccepted, DiscountAmount = accountVm.DiscountAmount, EmailAddress = accountVm.DirectDebitEmailAddress, DiscountAvailable = directDebitDetailsVm.DiscountAvailable, PaymentFrequency = directDebitDetailsVm.PaymentFrequency, TermYears = years, TermMonths = months, SelectedPlanSetupOption = directDebitDetailsVm.SelectedPlanSetupOption }; return(directDebitPlanOverview); }
public string CreatePayload(PaymentOptionsVm accountVm) { using (var sr = new StreamReader("Verifone/PostData-template.txt")) { _postdataTemplateXml = sr.ReadToEnd(); } using (var sr = new StreamReader("Verifone/EftRequest-template.txt")) { _requestTemplateXml = sr.ReadToEnd(); } var requestDataModel = _createVerifoneRequestProcess.CreateDataModel(accountVm); var formattedRequestXml = _requestTemplateXml.FormatWith(requestDataModel); var htmlEncodedRequest = HttpUtility.HtmlEncode(formattedRequestXml); var postDataModel = _createVerifonePostProcess.CreateDataModel(htmlEncodedRequest); var formattedPostDataXml = _postdataTemplateXml.FormatWith(postDataModel); return(formattedPostDataXml); }
// // Private // private async Task <IActionResult> ProcessPaymentOptionsPost(Guid lowellReferenceSurrogateKey, PaymentOptionsVm paymentOptionsVmWithUserEntries) { if (!ModelState.IsValid) { var outstandingPayment = paymentOptionsVmWithUserEntries.FullPaymentAmountDerived; bool isDirectDebitPayment = paymentOptionsVmWithUserEntries.SelectedPlanSetupOption == PlanSetupOptions.AverageSetupValue || paymentOptionsVmWithUserEntries.SelectedPlanSetupOption == PlanSetupOptions.DisposableIncome || paymentOptionsVmWithUserEntries.SelectedPlanSetupOption == PlanSetupOptions.OtherPaymentOffer; if (isDirectDebitPayment && paymentOptionsVmWithUserEntries.DirectDebitAmount > outstandingPayment) { ModelState.Clear(); paymentOptionsVmWithUserEntries.DirectDebitAmount = null; ModelState.AddModelError(nameof(PaymentOptionsVm.SelectedPlanSetupOption), $"{ValidationMessages.AmountGreaterThenAllowed}{outstandingPayment}"); } else if (!isDirectDebitPayment && paymentOptionsVmWithUserEntries.PartialPaymentAmount.HasValue && paymentOptionsVmWithUserEntries.PartialPaymentAmount.Value > outstandingPayment) { ModelState.Clear(); paymentOptionsVmWithUserEntries.PartialPaymentAmount = null; ModelState.AddModelError(nameof(PaymentOptionsVm.PartialPaymentAmount), $"{ValidationMessages.AmountGreaterThenAllowed}{outstandingPayment}"); } else if (!isDirectDebitPayment && paymentOptionsVmWithUserEntries.PartialPaymentAmount.HasValue && paymentOptionsVmWithUserEntries.PartialPaymentAmount.Value < 1.0m ) { ModelState.Clear(); paymentOptionsVmWithUserEntries.PartialPaymentAmount = null; ModelState.AddModelError(nameof(PaymentOptionsVm.PartialPaymentAmount), $"{ValidationMessages.AmountLessThanOneGbp}"); } Debug.Assert(paymentOptionsVmWithUserEntries.InitialState != null, "Initial state must be stashed to re-create view on round-trip"); return(View(paymentOptionsVmWithUserEntries)); } if (paymentOptionsVmWithUserEntries.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.PartialPayment || paymentOptionsVmWithUserEntries.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.FullPayment) { OneOffPaymentReviewVm oneOffPaymentReviewVm; { // // IMPORTANT: Validates models again versus CaseFlow, to ensure no tamper or state changes since // started process of entering payment information // var result = await _buildOneOffPaymentReviewVmService.ValidateAndBuild( LoggedInUser, ApplicationSessionState, lowellReferenceSurrogateKey, paymentOptionsVmWithUserEntries, GetCaseflowUserId()); if (result.IsValid == false) { return(View("ValidationFailed")); } oneOffPaymentReviewVm = result.OneOffPaymentReviewVm; } // Stash state of payment options form, so that 'change' feature can return oneOffPaymentReviewVm.FilledInPaymentOptionsState = SerialiseModel(paymentOptionsVmWithUserEntries); var oneOffPaymentDto = _mapper.Map <OneOffPaymentReviewVm, OneOffPaymentDto>(oneOffPaymentReviewVm); _logger.LogDebug("Before AddVerifoneTransactionAsync"); await _verifonePaymentProviderService.AddVerifoneTransactionAsync( new VerifoneTransactionDto { CompanyCode = 1, //LFL TransactionGuid = oneOffPaymentReviewVm.VerifoneTransactionGuid, TransactionData = JsonConvert.SerializeObject(oneOffPaymentDto) }); _gtmService.RaiseOneOffPaymentEvent_OptionsSelected(oneOffPaymentReviewVm, LoggedInUserId, "Regular Account"); await _webActivityService.LogOneOffPaymentSelected(oneOffPaymentReviewVm.LowellReference, LoggedInUserId, !oneOffPaymentReviewVm.PaidInFull, oneOffPaymentReviewVm.DiscountSelected); // Ensure no model state is used in view render ModelState.Clear(); ApplicationSessionState.LogPaymentResult = true; return(View("OneOff", oneOffPaymentReviewVm)); } if (paymentOptionsVmWithUserEntries.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.DirectDebit) { // Not validated here - occurs on the final step (DirectDebitComplete) var directDebitDetailsVm = _buildDirectDebitDetailsVmService.Build(paymentOptionsVmWithUserEntries); // Stash model in state, to allow view to be rebuilt on postback directDebitDetailsVm.InitialState = SerialiseModel(directDebitDetailsVm); // Stash payment options VM in Direct Debit VM to allow it to be passed back // (e.g. if user clicks 'change' and goes back to Payment Options) directDebitDetailsVm.PaymentOptionsFilledInState = SerialiseModel(paymentOptionsVmWithUserEntries); if (directDebitDetailsVm.DiscountSelected) { await LogDiscountDirectDebitOptionsSelected(paymentOptionsVmWithUserEntries); } else { await LogDirectDebitOptionsSelected(paymentOptionsVmWithUserEntries); } // TODO: change over to building and returning view directly _gtmService.RaiseDirectDebitEvent_OptionsSelected(directDebitDetailsVm, LoggedInUserId, "Regular Account"); ApplicationSessionState.LogSetUpPlanResult = true; return(View("DirectDebit", directDebitDetailsVm)); } throw new ApplicationException("Invalid SelectedPaymentOption"); }
public async Task <PaymentOptionsVm> Build(IUserIdentity loggedInUser, IApplicationSessionState applicationSessionState, Guid lowellReferenceSurrogateKey, string caseflowUserId) { string lowellReference = applicationSessionState.GetLowellReferenceFromSurrogate(lowellReferenceSurrogateKey); AccountReferenceDto accountReferenceDto = new AccountReferenceDto() { LowellReference = lowellReference }; PaymentOptionsDto paymentOptionsDto = await _apiGatewayProxy.GetPaymentOptions(accountReferenceDto); IncomeAndExpenditureApiModel incomeAndExpenditureDto = await _apiGatewayProxy.GetIncomeAndExpenditure(lowellReference); List <AccountSummary> accounts; if (caseflowUserId != null) { accounts = await _accountsService.GetAccounts(caseflowUserId); } else { accounts = await _accountsService.GetMyAccountsSummary(lowellReference); } var workingAccounts = accounts.Count(a => !a.AccountStatusIsClosed); if (workingAccounts == 0) { workingAccounts = 1; } var accountDetails = await _accountsService.GetAccount(caseflowUserId, lowellReference); string[] planMessages = accountDetails.PlanMessages; var paymentOptionsVm = new PaymentOptionsVm() { OutstandingBalance = paymentOptionsDto.OutstandingBalance, LowellReference = paymentOptionsDto.LowellReference, ClientName = paymentOptionsDto.ClientName, ExcludedAccountMessage = paymentOptionsDto.ExcludedAccountMessage, PlanInPlace = paymentOptionsDto.PlanInPlace, PlanIsDirectDebit = paymentOptionsDto.PaymentPlanIsDirectDebit, WithLowellSolicitors = paymentOptionsDto.WithLowellSolicitors, PaymentOptions = new List <PaymentOptionsSelectionsVm>(), DiscountPercentage = paymentOptionsDto.DiscountPercentage, DiscountAmount = paymentOptionsDto.DiscountAmount, DiscountExpiryDate = paymentOptionsDto.DiscountExpiryDate, DiscountedBalance = paymentOptionsDto.DiscountedBalance, DiscountBalanceAvailable = paymentOptionsDto.DiscountBalanceAvailable, ProposedDiscountedBalanceIfAccepted = paymentOptionsDto.ProposedDiscountedBalanceIfAccepted, DiscountedBalancePreviouslyAccepted = paymentOptionsDto.DiscountedBalancePreviouslyAccepted, ArrearsMessage = _arrearsDescriptionProcess.DeriveArrearsDetail(paymentOptionsDto.PaymentPlanArrearsAmount, paymentOptionsDto.PaymentPlanIsAutomated), StandingOrder = paymentOptionsDto.StandingOrder, StandingOrderMessage = paymentOptionsDto.StandingOrderMessage, VerifoneTransactionGuid = $"{paymentOptionsDto.LowellReference}_{Guid.NewGuid()}", DiscountAccepted = paymentOptionsDto.DiscountedBalancePreviouslyAccepted, PlanMessage = planMessages != null && planMessages.Length > 0? planMessages[0]:string.Empty }; if (loggedInUser.IsLoggedInUser) { paymentOptionsVm.DirectDebitEmailAddress = loggedInUser.EmailAddress; } else { paymentOptionsVm.DirectDebitIsEmailAddressFieldVisible = true; } // Logged in user has accept T&C defaulted and will be hidden. // Anon user has tick box displayed. Must be ticked. if (loggedInUser.IsLoggedInUser) { paymentOptionsVm.AcceptTermsAndConditions = true; } else { paymentOptionsVm.IsAcceptTermsAndConditionsFieldVisible = true; } // Work out amount that needs to be paid to clear balance if (paymentOptionsVm.DiscountedBalancePreviouslyAccepted) { paymentOptionsVm.FullPaymentBalance = paymentOptionsVm.DiscountedBalance; } else { paymentOptionsVm.FullPaymentBalance = paymentOptionsVm.OutstandingBalance; } // Customer has a plan but it isn't direct debit. // Used to display a message informing customer that they can change to a DD online. if (paymentOptionsDto.PlanInPlace && !paymentOptionsDto.PaymentPlanIsDirectDebit) { paymentOptionsVm.HasNonDirectDebitPlanInPlace = true; } if (paymentOptionsDto.WithLowellSolicitors) { paymentOptionsVm.LowellSolicitorsRedirectLink = _portalSetting.SolicitorsRedirectDataProtectionUrl; } // Shared list of options for partial / full paymentOptionsVm.SourceOfFunds = BuildSourceOfFundsSelections(paymentOptionsDto); // Direct Debit paymentOptionsVm.DirectDebitFrequency = BuildFrequencyList(paymentOptionsDto.DirectDebitFrequencies); paymentOptionsVm.DirectDebitStartDateEarliest = paymentOptionsDto.DirectDebitStartDateEarliest; paymentOptionsVm.DirectDebitStartDateLatest = paymentOptionsDto.DirectDebitStartDateLatest; // TODO: Wrap the code below in a strategy pattern if (paymentOptionsDto.CanMakeFullPayment) { paymentOptionsVm.PaymentOptions.Add(new PaymentOptionsSelectionsVm() { DisplayedText = "Card payment (Pay in Full)", Value = PaymentOptionsSelectionsVm.Values.FullPayment, DataFormValue = PaymentOptionsSelectionsVm.Values.FullPayment }); } if (paymentOptionsDto.CanMakePartialPayment) { paymentOptionsVm.PaymentOptions.Add(new PaymentOptionsSelectionsVm() { DisplayedText = "Card payment (Partial amount)", Value = PaymentOptionsSelectionsVm.Values.PartialPayment, DataFormValue = PaymentOptionsSelectionsVm.Values.PartialPayment, ClassValue = "js-hide-option" // script hides this }); } if (paymentOptionsDto.CanSetupDirectDebit) { paymentOptionsVm.PaymentOptions.Add(new PaymentOptionsSelectionsVm() { DisplayedText = "Direct Debit plan", Value = PaymentOptionsSelectionsVm.Values.DirectDebit, DataFormValue = PaymentOptionsSelectionsVm.Values.DirectDebit }); } // Only add 'please select' if there are options // Required because view checks for availability of payment options if (paymentOptionsVm.PaymentOptions.Count > 0) { paymentOptionsVm.PaymentOptions.Insert(0, new PaymentOptionsSelectionsVm() { DisplayedText = "Please Select", Value = PaymentOptionsSelectionsVm.Values.PleaseSelect, DataFormValue = PaymentOptionsSelectionsVm.Values.PleaseSelect }); } paymentOptionsVm.LowellReferenceSurrogate = lowellReferenceSurrogateKey; paymentOptionsVm.IandENotAvailable = incomeAndExpenditureDto == null; paymentOptionsVm.IandELessThanOrIs12MonthsOld = (incomeAndExpenditureDto != null && incomeAndExpenditureDto.Created.AddMonths(12).Date >= DateTime.Now.Date); paymentOptionsVm.AverageMonthlyPayment = _portalSetting.AverageMonthlyPaymentAmount; paymentOptionsVm.MonthlyDisposableIncome = (incomeAndExpenditureDto == null ? 0 : (incomeAndExpenditureDto.DisposableIncome * (_portalSetting.MonthlyDisposableIncomePlanSetupPercentage / 100))); paymentOptionsVm.AccountCount = workingAccounts; paymentOptionsVm.MonthlyDisposableIncomePerAccount = paymentOptionsVm.MonthlyDisposableIncome / workingAccounts; return(paymentOptionsVm); }
// Checks the information entered by the user against CaseFlow afresh // If validation fails, returns false and OneOffPaymentReviewVm will be output as NULL // If successful, returns true and OneOffPaymentReviewVm will be output populated public async Task <IBuildOneOffPaymentReviewVmValidationResult> ValidateAndBuild( IUserIdentity loggedInUser, IApplicationSessionState applicationSessionState, Guid lowellReferenceSurrogateKey, PaymentOptionsVm paymentOptionsVmWithUserEntries, string caseflowUserId) { // Reload from CaseFlow PaymentOptionsVm paymentOptionsVm = await _buildPaymentOptionsVmService.Build(loggedInUser, applicationSessionState, lowellReferenceSurrogateKey, caseflowUserId); // Populate user entries, giving a clean model to validate _buildPaymentOptionsVmService.UpdateFieldsFromUserEntries(loggedInUser, paymentOptionsVm, paymentOptionsVmWithUserEntries); if (!_paymentOptionsVmValidatorProcess.Validate(paymentOptionsVm)) { return new ValidationResult() { IsValid = false } } ; // Ensure we are not using this - must use clean, validated model (defensive coding) // ReSharper disable once RedundantAssignment paymentOptionsVmWithUserEntries = null; var postDataXml = _verifonePaymentProviderService.CreatePayload(paymentOptionsVm); OneOffPaymentReviewVm vm = new OneOffPaymentReviewVm() { LowellReference = paymentOptionsVm.LowellReference, ClientName = paymentOptionsVm.ClientName, VerifoneUrl = _verifoneSetting.ApiEndpoint, VerifonePostDataXml = postDataXml, VerifoneTransactionGuid = paymentOptionsVm.VerifoneTransactionGuid.ToString(), UserID = loggedInUser.UserId, PaidInFull = paymentOptionsVm.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.FullPayment, DiscountAvailable = paymentOptionsVm.DiscountBalanceAvailable, DiscountSelected = paymentOptionsVm.DiscountAccepted, PlanInPlace = paymentOptionsVm.PlanInPlace, InArrears = !String.IsNullOrEmpty(paymentOptionsVm.ArrearsMessage) }; // Source payment information from appropriate nested object if (paymentOptionsVm.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.FullPayment) { vm.PaymentAmount = paymentOptionsVm.FullPaymentAmountDerived; vm.SourceOfFunds = paymentOptionsVm.FullPaymentSelectedSourceOfFunds; vm.SourceOfFundsOther = paymentOptionsVm.FullPaymentSourceOfFundsOtherText; vm.PaidInFull = true; } else if (paymentOptionsVm.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.PartialPayment) { Debug.Assert(paymentOptionsVm.PartialPaymentAmount != null, "paymentOptionsVmWithUserEntries.PartialPaymentAmount != null"); vm.PaymentAmount = paymentOptionsVm.PartialPaymentAmount.Value; vm.SourceOfFunds = paymentOptionsVm.PartialPaymentSelectedSourceOfFunds; vm.SourceOfFundsOther = paymentOptionsVm.PartialPaymentSourceOfFundsOtherText; } else { throw new ApplicationException("Invalid SelectedPaymentOption"); } return(new ValidationResult() { IsValid = true, OneOffPaymentReviewVm = vm }); } }
private async Task <IActionResult> ProcessDirectDebitDetailsPost(Guid lowellReferenceSurrogateKey, DirectDebitDetailsVm directDebitDetailsVmWithUserEntries) { if (!ModelState.IsValid) { Debug.Assert(directDebitDetailsVmWithUserEntries.InitialState != null, "Initial state must be stashed to re-create view on round-trip"); return(View(directDebitDetailsVmWithUserEntries)); } //TODO: Change to async var result = await _directDebitPlanSetupService.CheckDirectDebitDetails(directDebitDetailsVmWithUserEntries); // Restore Payment Options from state embedded in Direct Debit VM PaymentOptionsVm paymentOptionsVm = DeserialiseModel <PaymentOptionsVm>(directDebitDetailsVmWithUserEntries.PaymentOptionsFilledInState); Debug.Assert(paymentOptionsVm.InitialState == null, "Serialisation Loop Detected - a previous step must have serialised a model that already contains InitialState"); if (!result.IsSuccessful) { directDebitDetailsVmWithUserEntries.MessageForUser = result.MessageForUser; if (ApplicationSessionState.LogSetUpPlanResult) { if (directDebitDetailsVmWithUserEntries.DiscountSelected) { await LogDiscountDirectDebitCompleteFailure(paymentOptionsVm); } else { await LogDirectDebitCompleteFailure(paymentOptionsVm); } ApplicationSessionState.LogSetUpPlanResult = false; } return(View(directDebitDetailsVmWithUserEntries)); } DirectDebitPlanOverviewVm directDebitPlanOverview = _buildDirectDebitPlanOverviewVmService.Build(paymentOptionsVm, directDebitDetailsVmWithUserEntries); // Need to stash direct debit model, so that we can round-trip when 'change' options are selected on confirmation screen. Debug.Assert(!string.IsNullOrEmpty(directDebitDetailsVmWithUserEntries.PaymentOptionsFilledInState), "Stashed model MUST contain stashed payment options model, so that it can be round-tripped back to Payment Options if choose to change that"); directDebitPlanOverview.DirectDebitDetailsFilledInState = SerialiseModel(directDebitDetailsVmWithUserEntries); _gtmService.RaiseDirectDebitEvent_BankDetails(directDebitPlanOverview, LoggedInUserId, "Direct Debit Plan"); if (directDebitDetailsVmWithUserEntries.DiscountSelected) { await LogDiscountDirectDebitDetailsEntered(paymentOptionsVm); } else { await LogDirectDebitDetailsEntered(paymentOptionsVm); } return(View("DirectDebitConfirm", directDebitPlanOverview)); }