public void RaiseOneOffPaymentEvent_OptionsSelected(OneOffPaymentReviewVm vm, string userId, string planType)
        {
            string plan_status = vm.PlanInPlace ? "Payment against Plan" : "No Plan in Place";

            plan_status = vm.InArrears ? "Plan Arrears Payment" : plan_status;

            vm.GtmEvents.Add(new GtmEvent()
            {
                gtm_event          = GtmEvents.PaymentEvent,
                step               = PaymentSteps.Step2PaymentOptionsSelected,
                payment_type       = "One Off Payment",
                payment_amount     = vm.PaymentAmount,
                payment_detail     = vm.PaidInFull ? "Full Balance" : "Partial Payment",
                discount_available = vm.DiscountAvailable ? "Discount available" : "No discount available",
                plan_type          = planType,
                balance_selected   = vm.DiscountSelected ? "Discounted Balance" : "Full Balance",
                plan_status        = plan_status,
                guid               = String.IsNullOrEmpty(userId) ? null : userId,
                user_status        = String.IsNullOrEmpty(userId) ? "Not Logged In" : "Logged In",
                source_of_funds    = vm.SourceOfFunds
            });
        }
        // 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
            });
        }
    }