CASH-256 prettier config change and prevent email and phone getting cleared when navigating back from payment to service-zip.
836 lines
35 KiB
Vue
836 lines
35 KiB
Vue
<template>
|
|
<Form>
|
|
<loadingModal notFullScreen ref="loadingModal" />
|
|
<div class="container-fluid">
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-6">
|
|
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-6 col-xl-4 p-0">
|
|
<div>
|
|
<alert
|
|
ref="piaCCErrorAlert"
|
|
class="my-4"
|
|
v-if="shouldDisplayPiaCCAlert"
|
|
cmsWidgetName="PIACCErrorAlertWidget"
|
|
alertClass="alert-danger"
|
|
@textLinkClicked="paymentFailedPayLater"
|
|
v-bind:isDismissible="false" />
|
|
</div>
|
|
|
|
<div>
|
|
<alert
|
|
ref="piaAPErrorAlert"
|
|
class="my-4"
|
|
v-if="shouldDisplayPiaAPAlert"
|
|
cmsWidgetName="PIAAPErrorAlertWidget"
|
|
alertClass="alert-danger"
|
|
@textLinkClicked="paymentFailedPayLater"
|
|
v-bind:isDismissible="false" />
|
|
</div>
|
|
|
|
<div id="card-container">
|
|
<iframe
|
|
v-resize
|
|
ref="paymentFrame"
|
|
class="hop-iframe payment-iframe"
|
|
name="card-frame"
|
|
id="card-frame"
|
|
seamless
|
|
scrolling="no"
|
|
allow="payment *; microphone *; geolocation *;"></iframe>
|
|
</div>
|
|
|
|
<hr />
|
|
|
|
<cart
|
|
ref="cart"
|
|
:damage="damageInfo"
|
|
:availableVaps="availableVaps"
|
|
:allowItemRemoval="false"
|
|
v-model="lineItems"
|
|
servicePackageOptionsCmsName="ServicePackageTitle"
|
|
recyclingModalCmsWidgetName="RecycleModal"
|
|
:isInsurance="isInsurance"
|
|
:insuranceDeductible="currentDeductible"
|
|
:insuranceCompanyName="insuranceCompanyName"
|
|
:showInsuranceCoverageAs="showInsuranceCoverageAs"
|
|
:isItac="isItac"
|
|
:isNoComp="isNoComp"
|
|
:isExpandedOnLoad="true" />
|
|
|
|
<hr class="mb-5" />
|
|
|
|
<navbar
|
|
cmsWidgetName="FunnelFooterWidget"
|
|
isForwardActionDisabled="true"
|
|
:isBackButtonHidden="shouldHideBackButton"
|
|
isSubmitHidden="true"
|
|
@back-clicked="backButtonAction" />
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="shouldBlockInteraction" class="ui-block" @click="supressClick"></div>
|
|
</div>
|
|
</Form>
|
|
|
|
<form
|
|
ref="hopForm"
|
|
id="card-data"
|
|
:target="isPaypal ? '_top' : 'card-frame'"
|
|
method="POST"
|
|
:action="checkoutUrl">
|
|
<input type="hidden" name="paymentType" :value="paymentType" />
|
|
<input type="hidden" name="sgSessionId" :value="authToken" />
|
|
<input type="hidden" name="sgAuthToken" :value="authToken" />
|
|
<input type="hidden" name="sgSignaturePublic" :value="authSignature" />
|
|
<input type="hidden" name="sgSignatureStartDate" :value="authSignatureStart" />
|
|
<input type="hidden" name="referralSeqNum" :value="referralSequenceNumber" />
|
|
|
|
<input type="hidden" name="sge_commerce_indicator_isinternet" value="true" />
|
|
<input type="hidden" name="sghopsource" value="Safelite.com" />
|
|
<input type="hidden" name="sgHtmlStyle" value="ResourceSafeliteHtml" />
|
|
<input type="hidden" name="sgErrorMessagesEmbedded" value="true" />
|
|
|
|
<input type="hidden" name="sgNoKeystrokeProcessing" value="false" />
|
|
|
|
<input type="hidden" name="maskCharacter" value="*" />
|
|
<input type="hidden" name="styleSheetCode" :value="dynamicCSSUrl" />
|
|
<input type="hidden" name="styleSheetCode2" :value="dynamicHopCSSUrl" />
|
|
|
|
<input type="hidden" name="sgReceiptResponseURL" :value="piaResponseUrl" />
|
|
<input type="hidden" name="sgDeclineResponseURL" :value="piaResponseUrl" />
|
|
<input type="hidden" name="sgErrorResponseURL" :value="piaResponseUrl" />
|
|
|
|
<input type="hidden" name="sgheaderline1" :value="getHeaderLine1" />
|
|
<input type="hidden" name="sgHeader1subtitle" value="" />
|
|
<input type="hidden" name="sgheaderline2" :value="getHeaderLine2" />
|
|
<input type="hidden" name="sgheaderline3" value="" />
|
|
<input type="hidden" name="sgheaderline4" value="" />
|
|
<input type="hidden" name="sgheaderline5" value="*Required information" />
|
|
|
|
<input type="hidden" name="billTo_firstName" :value="firstName" />
|
|
<input type="hidden" name="billTo_firstNameShow" value="true" />
|
|
<input type="hidden" name="sghopmiddleInitialShow" value="false" />
|
|
<input type="hidden" name="billTo_lastName" :value="lastName" />
|
|
<input type="hidden" name="billTo_lastNameShow" value="true" />
|
|
|
|
<input type="hidden" name="billTo_street1" value="" />
|
|
<input type="hidden" name="billTo_street2" value="" />
|
|
<input type="hidden" name="billTo_city" value="" />
|
|
<input type="hidden" name="billTo_state" value="" />
|
|
|
|
<input type="hidden" name="billTo_postalCode" value="" />
|
|
<input type="hidden" name="billTo_postalCodeShow" value="true" />
|
|
<input type="hidden" name="billTo_postalCodeEnable" value="true" />
|
|
<input type="hidden" name="sgLabelPostalCode" value="Billing ZIP" />
|
|
|
|
<input type="hidden" name="sgtotalamount" :value="displayAmount" />
|
|
<input type="hidden" name="totalAmountDecimal" :value="totalAmount" />
|
|
<input type="hidden" name="lineItems" :value="piaLineItems" />
|
|
|
|
<input type="hidden" name="sgdiscountstrikethruamount" value="" />
|
|
|
|
<input type="hidden" name="callerDisplayText" value="" />
|
|
|
|
<input
|
|
type="hidden"
|
|
name="sgtermsofusedisplaytext"
|
|
value="By selecting submit, I agree to Safelite's" />
|
|
<input
|
|
type="hidden"
|
|
name="sgtermsofuseurl"
|
|
value="http://www.safelite.com/terms-of-service/" />
|
|
<input type="hidden" name="sgtermsofuselinkdisplaytext" value="Terms of service" />
|
|
<input type="hidden" name="sgtermsofcancelrefunddisplaytext" value="and" />
|
|
<input
|
|
type="hidden"
|
|
name="sgtermsofcancelrefundlinkdisplaytext"
|
|
value="cancellation and refund policy" />
|
|
<input
|
|
type="hidden"
|
|
name="sgtermsofcancelrefundurl"
|
|
value="http://www.safelite.com/cancellation-refund-policy" />
|
|
|
|
<input
|
|
type="hidden"
|
|
name="sgErrorMessageCardVerification"
|
|
value="Credit card could not be processed" />
|
|
<input
|
|
type="hidden"
|
|
name="sgErrorMessageTimeOut"
|
|
value="For your security, this transaction has been timed out." />
|
|
|
|
<input type="hidden" name="sgLabelCardNumber" value="" />
|
|
<input type="hidden" name="sgLabelAddressLine1" :value="address1" />
|
|
<input type="hidden" name="sgLabelAddressLine2" :value="address2" />
|
|
<input type="hidden" name="sgLabelCity" :value="city" />
|
|
<input type="hidden" name="sgLabelState" :value="state" />
|
|
|
|
<input type="hidden" name="sgCtu" :value="ctu" />
|
|
<input type="hidden" name="sgWorkOrder" :value="workOrderNumber" />
|
|
<input type="hidden" name="sgEmailAddress" :value="emailAddress" />
|
|
<input type="hidden" name="paypalInvoiceNumber" :value="invoiceNumber" />
|
|
<input type="hidden" name="paypalSuccessUrl" :value="piaResponseUrl" />
|
|
<input type="hidden" name="paypalCancelUrl" :value="piaCancelUrl" />
|
|
|
|
<input type="hidden" name="sgCCDeclineURL" :value="piaErrorUrl" />
|
|
<input type="hidden" name="sgCCTimeoutURL" :value="piaCancelUrl" />
|
|
|
|
<input type="hidden" name="sgTransactionType" value="authorization" />
|
|
<input type="hidden" name="amount" :value="totalAmount" />
|
|
<input type="hidden" name="ctu" :value="ctu" />
|
|
<input type="hidden" name="orderNumber" :value="workOrderNumber" />
|
|
|
|
<input type="hidden" name="billTo_email" :value="emailAddress" />
|
|
<input type="hidden" name="useDecisionManager" value="True" />
|
|
<input type="hidden" name="correlationId" :value="referralCorrelationId" />
|
|
<input type="hidden" name="sgErrorMessageCard_CVN" value="Please enter a valid CVV" />
|
|
|
|
<input type="hidden" name="ship_to_address_line1" :value="address1" />
|
|
<input type="hidden" name="ship_to_address_line2" :value="address2" />
|
|
<input type="hidden" name="ship_to_address_city" :value="city" />
|
|
<input type="hidden" name="ship_to_address_state" :value="state" />
|
|
<input type="hidden" name="ship_to_address_country" value="US" />
|
|
<input type="hidden" name="ship_to_address_postal_code" :value="zipCode" />
|
|
<input type="hidden" name="ship_to_phone" :value="phoneNumber" />
|
|
|
|
<input type="hidden" name="calling_application" value="NextGen" />
|
|
<input type="hidden" name="parentdomainname" :value="parentNomainName" />
|
|
</form>
|
|
</template>
|
|
|
|
<script>
|
|
// Components
|
|
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
|
import navbar from "@/fmg-components/nav-bar/nav-bar";
|
|
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
|
|
import cart from "@/fmg-components/cart/cart";
|
|
import alert from "@/ux-components/alert/alert";
|
|
|
|
import { storeActions } from "@/constants/store-actions";
|
|
import store from "@/store";
|
|
import { externalUrls } from "@/router/router-constants/externalUrl-values";
|
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
|
import { applicationConfig } from "@/constants/application-config";
|
|
import { paymentMethods } from "@/constants/payment-method-constants";
|
|
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
|
import baseMixin from "@/mixins/base-mixin.js";
|
|
import { mapTaxedLineItemsToStoreFormat } from "../../store";
|
|
import {
|
|
revalidatePromosAndValidateQueryStringPromo,
|
|
getAddableVapsFromAvailableLineItems,
|
|
getVapsThatNeedToBeAddedToSatisfyPromos,
|
|
} from "@/helpers/promotions-helper";
|
|
import { queryStrings } from "@/constants/query-strings";
|
|
import { getQuerystringParameter } from "@/helpers/querystring-helper";
|
|
import { deepClone } from "@/helpers/object-helper";
|
|
import { submitWorkOrder } from "@/helpers/heritage-integration/order-helper.js";
|
|
import iframeResize from "../../../node_modules/iframe-resizer/js/iframeResizer.js";
|
|
import { routerParams } from "@/router/router-constants/router-params";
|
|
import { coverageStatus } from "@/constants/insurance";
|
|
import { getBoolFromString } from "@/helpers/boolean-helper.js";
|
|
|
|
export default {
|
|
name: "payment",
|
|
data() {
|
|
return {
|
|
checkoutUrl: externalUrls.SAFELITE_HOP,
|
|
piaResponseUrl: applicationConfig.PIA_RESPONSE_URL,
|
|
piaCancelUrl: applicationConfig.PIA_CANCEL_URL,
|
|
piaErrorUrl: applicationConfig.PIA_ERROR_URL,
|
|
paymentType: this.getPaymentType(),
|
|
authToken: "",
|
|
authSignature: "",
|
|
authSignatureStart: "",
|
|
referralSequenceNumber: store.getters.order.referralSequenceNumber,
|
|
emailAddress: store.getters.order.customer.emailAddress,
|
|
address1: this.getAddress1(),
|
|
address2: this.getAddress2(),
|
|
city: this.getCity(),
|
|
state: this.getState(),
|
|
zipCode: this.getZipCode(),
|
|
firstName: store.getters.order.customer.firstName,
|
|
lastName: store.getters.order.customer.lastName,
|
|
phoneNumber: store.getters.order.customer.phoneNumber,
|
|
ctu: store.getters.order.serviceLocation.zipCodeCtu,
|
|
referralCorrelationId: store.getters.order.referralCorrelationId,
|
|
workOrderNumber: this.getWOrkOrderNumber(),
|
|
invoiceNumber: this.getInvoiceNumber(),
|
|
totalAmount: this.getAmountDue(),
|
|
displayAmount: this.getDisplayAmountDue(),
|
|
piaLineItems: "",
|
|
lineItems: [],
|
|
availableVaps: [],
|
|
shouldBlockInteraction: false,
|
|
};
|
|
},
|
|
directives: {
|
|
resize: {
|
|
mounted: function (el) {
|
|
el.addEventListener("load", () => {
|
|
iframeResize({ checkOrigin: false }, el);
|
|
});
|
|
},
|
|
unmounted: function (el) {
|
|
el.iFrameResizer.removeListeners();
|
|
},
|
|
},
|
|
},
|
|
async beforeRouteEnter(to, from, next) {
|
|
// Call APIs
|
|
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
|
|
|
const signaturePromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
|
storeActions.GET_SIGNATURE,
|
|
null,
|
|
"payment"
|
|
);
|
|
|
|
const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
|
storeActions.GET_WIPERS,
|
|
{
|
|
serviceZipCode: store.getters.order.serviceLocation.zipCode,
|
|
carId: store.getters.vehicle.carId,
|
|
},
|
|
"payment"
|
|
);
|
|
|
|
const rainDefensePromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
|
storeActions.GET_RAIN_DEFENSE,
|
|
null,
|
|
"payment"
|
|
);
|
|
|
|
const promiseResultMap = [
|
|
{
|
|
resultKey: "cmsContent",
|
|
promise: cmsContentPromise,
|
|
},
|
|
{
|
|
resultKey: "signature",
|
|
promise: signaturePromise,
|
|
},
|
|
{
|
|
resultKey: "wipers",
|
|
promise: wipersPromise,
|
|
},
|
|
{
|
|
resultKey: "rainDefense",
|
|
promise: rainDefensePromise,
|
|
},
|
|
];
|
|
|
|
const resultMap = await settleAllPromises(promiseResultMap);
|
|
const lineItemsFromStore = deepClone(store.getters.order.lineItems);
|
|
const glassParts = lineItemsFromStore.glassParts ?? [];
|
|
const supportingItems = lineItemsFromStore.supportingItems ?? [];
|
|
|
|
const lineItemsToTax = [
|
|
resultMap.rainDefense,
|
|
...supportingItems,
|
|
...resultMap.wipers,
|
|
...glassParts,
|
|
];
|
|
const availableVaps = [resultMap.rainDefense, ...resultMap.wipers];
|
|
|
|
const pricedLineItemsToTax = await baseMixin.methods.dispatchStoreActionWithLogging(
|
|
storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
|
{
|
|
availableLineItems: lineItemsToTax,
|
|
},
|
|
"payment",
|
|
false
|
|
);
|
|
|
|
// Promo logic
|
|
const promoCodeFromQueryString = getQuerystringParameter(queryStrings.PROMO);
|
|
|
|
const { validatePromoResponse, revalidatePromoResponse } =
|
|
await revalidatePromosAndValidateQueryStringPromo(
|
|
promoCodeFromQueryString,
|
|
pricedLineItemsToTax,
|
|
"payment"
|
|
);
|
|
|
|
const newValidatedPromos = validatePromoResponse?.orderPromos ?? [];
|
|
newValidatedPromos.push(
|
|
...(revalidatePromoResponse ? revalidatePromoResponse.promoLineItems : [])
|
|
);
|
|
|
|
pricedLineItemsToTax.push(...newValidatedPromos);
|
|
// End of promo logic
|
|
|
|
const taxedLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
|
|
storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
|
{
|
|
billToAccountNumber: store.getters.payment.billToAccountNumber,
|
|
providerNumber: store.getters.order.serviceLocation.provider.providerNumber,
|
|
appointmentType: store.getters.order.serviceLocation.appointmentType,
|
|
serviceLocationCity: store.getters.order.serviceLocation.city,
|
|
serviceLocationState: store.getters.order.serviceLocation.state,
|
|
serviceLocationZipCode: store.getters.order.serviceLocation.zipCode,
|
|
pricedLineItems: pricedLineItemsToTax,
|
|
},
|
|
"payment",
|
|
false
|
|
);
|
|
|
|
// Match all line items to the line items as they are in the store
|
|
// and rebuild the original structure.
|
|
const lineItems = mapTaxedLineItemsToStoreFormat(taxedLineItems, lineItemsFromStore);
|
|
const taxedVaps = mapTaxedLineItemsToStoreFormat(taxedLineItems, availableVaps);
|
|
|
|
// Add items that were not in the store yet but added via query string promo validation
|
|
//newValidatedPromos contains both validated and revalidated promos.
|
|
lineItems.promos = Array.from(newValidatedPromos);
|
|
const vapsToAddToCart = getVapsThatNeedToBeAddedToSatisfyPromos(
|
|
newValidatedPromos,
|
|
taxedVaps,
|
|
lineItems
|
|
);
|
|
lineItems.vaps = lineItems.vaps ?? [];
|
|
lineItems.vaps.push(...vapsToAddToCart);
|
|
|
|
// Call the "next" function to complete the transition to this page.
|
|
next(async (vm) => {
|
|
vm.setCmsContent(resultMap.cmsContent);
|
|
vm.availableVaps = taxedVaps;
|
|
vm.lineItems = lineItems;
|
|
|
|
vm.$nextTick(() => {
|
|
if (vm.$refs.cart) {
|
|
const cartItems = vm.$refs.cart.cartItems;
|
|
vm.getPiaLineItems(cartItems);
|
|
}
|
|
|
|
vm.fetchSignatureInfo(resultMap.signature);
|
|
vm.setIFrameListener();
|
|
});
|
|
});
|
|
},
|
|
computed: {
|
|
parentNomainName() {
|
|
return window.location.hostname;
|
|
},
|
|
dynamicCSSUrl() {
|
|
const { protocol, hostname, port } = window.location;
|
|
return `${protocol}//${hostname}:${port}/fmg/css/site-2020Styling.css`;
|
|
},
|
|
dynamicHopCSSUrl() {
|
|
const { protocol, hostname, port } = window.location;
|
|
return `${protocol}//${hostname}:${port}/fmg/css/hop-styling.css`;
|
|
},
|
|
getHeaderLine1() {
|
|
if (!this.isPaypal) {
|
|
return this.getCmsContent("PIAHeaderLine1", "Text");
|
|
}
|
|
return "";
|
|
},
|
|
getHeaderLine2() {
|
|
if (!this.isPaypal) {
|
|
return this.getCmsContent("PIAHeaderLine2", "Text");
|
|
}
|
|
return "";
|
|
},
|
|
damageInfo() {
|
|
return this.$store.getters.damage;
|
|
},
|
|
isInsurance() {
|
|
return this.$store.getters.payment.isInsurance;
|
|
},
|
|
isNoComp() {
|
|
return this.$store.getters.policy.isNoComp;
|
|
},
|
|
isItac() {
|
|
return this.$store.getters.policy.isItac;
|
|
},
|
|
hasVapsInCart() {
|
|
if (this.lineItems?.vaps?.length > 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
showInsuranceCoverageAs() {
|
|
if (!this.isInsurance) return null;
|
|
if (this.isNoComp || this.isItac) {
|
|
return coverageStatus.NOCOMP;
|
|
} else {
|
|
return this.$store.getters.payment.insuranceCoverage.coverageStatus;
|
|
}
|
|
},
|
|
currentDeductible() {
|
|
return this.$store.getters.policy.currentDeductible;
|
|
},
|
|
insuranceCompanyName() {
|
|
return this.$store.getters.policy.insuranceCompanyName;
|
|
},
|
|
isPaypal() {
|
|
if (this.paymentType == "pp") {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
shouldDisplayPiaCCAlert() {
|
|
return this.shouldDisplayPiaAlert(paymentMethods.CREDIT_CARD);
|
|
},
|
|
shouldDisplayPiaAPAlert() {
|
|
return this.shouldDisplayPiaAlert(paymentMethods.AFTERPAY);
|
|
},
|
|
},
|
|
methods: {
|
|
arePagePrerequisitesValid() {
|
|
// Service Location
|
|
const serviceLocation = store.getters.order.serviceLocation;
|
|
const mobileReqs = !!(
|
|
serviceLocation.address &&
|
|
serviceLocation.city &&
|
|
serviceLocation.state &&
|
|
serviceLocation.zipCode
|
|
);
|
|
|
|
const providerLocation = serviceLocation.provider.address;
|
|
const dropOffInshopReqs = !!(
|
|
providerLocation.streetAddress &&
|
|
providerLocation.city &&
|
|
providerLocation.state &&
|
|
providerLocation.zipCode
|
|
);
|
|
|
|
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
|
|
|
|
const serviceLocationReqs =
|
|
(isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);
|
|
|
|
// Insurance
|
|
const isInsuranceSet = store.getters.order.payment.isInsurance !== null;
|
|
|
|
// Schedule
|
|
const schedule = store.getters.order.schedule;
|
|
const scheduleReqs = !!(
|
|
schedule.date &&
|
|
schedule.startTime &&
|
|
schedule.endTime &&
|
|
schedule.jobMaxMinutes &&
|
|
schedule.jobMinMinutes
|
|
);
|
|
|
|
// Customer
|
|
const customer = store.getters.order.customer;
|
|
const customerReqs = !!(
|
|
customer.firstName &&
|
|
customer.lastName &&
|
|
customer.phoneNumber &&
|
|
customer.emailAddress
|
|
);
|
|
|
|
const paymentMethodReqs =
|
|
store.getters.order.payment.isPia !== null &&
|
|
(store.getters.order.payment.isPia || !!store.getters.order.payment.piaType);
|
|
|
|
const preReqResult =
|
|
serviceLocationReqs &&
|
|
isInsuranceSet &&
|
|
scheduleReqs &&
|
|
customerReqs &&
|
|
paymentMethodReqs;
|
|
|
|
// prettier-ignore
|
|
{
|
|
if (store.getters.applicationUser.loggingOption || !preReqResult) {
|
|
console.log("------------- payment.vue pagePrereqs start -----------------");
|
|
console.log(new Date() + "mobileReqs:" + mobileReqs);
|
|
console.log(new Date() + "serviceLocation.address:" + serviceLocation.address);
|
|
console.log(new Date() + "serviceLocation.city:" + serviceLocation.city);
|
|
console.log(new Date() + "serviceLocation.state:" + serviceLocation.state);
|
|
console.log(new Date() + "serviceLocation.zipCode:" + serviceLocation.zipCode);
|
|
console.log("");
|
|
console.log(new Date() + "dropOffInshopReqs:" + dropOffInshopReqs);
|
|
console.log(new Date() + "serviceLocationReqs:" + serviceLocationReqs);
|
|
console.log(new Date() + "providerLocation.streetAddress:" + providerLocation.streetAddress);
|
|
console.log(new Date() + "providerLocation.city:" + providerLocation.city);
|
|
console.log(new Date() + "providerLocation.state:" + providerLocation.state);
|
|
console.log(new Date() + "providerLocation.zipCode:" + providerLocation.zipCode);
|
|
console.log("");
|
|
console.log(new Date() + "isInsuranceSet:" + isInsuranceSet);
|
|
console.log("");
|
|
console.log(new Date() + "scheduleReqs:" + scheduleReqs);
|
|
console.log(new Date() + "schedule.date:" + schedule.date);
|
|
console.log(new Date() + "schedule.startTime:" + schedule.startTime);
|
|
console.log(new Date() + "schedule.endTime:" + schedule.endTime);
|
|
console.log(new Date() + "schedule.jobMaxMinutes:" + schedule.jobMaxMinutes);
|
|
console.log(new Date() + "schedule.jobMinMinutes:" + schedule.jobMinMinutes);
|
|
console.log("");
|
|
console.log(new Date() + "customerReqs:" + customerReqs);
|
|
console.log(new Date() + "customer.firstName:" + customer.firstName);
|
|
console.log(new Date() + "customer.lastName:" + customer.lastName);
|
|
console.log(new Date() + "customer.phoneNumber:" + customer.phoneNumber);
|
|
console.log(new Date() + "customer.emailAddress:" + customer.emailAddress);
|
|
console.log("");
|
|
console.log(new Date() + "paymentMethodReqs:" + paymentMethodReqs);
|
|
console.log(new Date() + "store.getters.order.payment.isPia:" + store.getters.order.payment.isPia);
|
|
console.log(new Date() + "store.getters.order.payment.piaType:" + store.getters.order.payment.piaType);
|
|
console.log("------------- payment.vue pagePrereqs end -------------------");
|
|
}
|
|
}
|
|
|
|
return preReqResult;
|
|
},
|
|
getWOrkOrderNumber() {
|
|
if (store.getters.order.workOrderNumber) {
|
|
const items = store.getters.order.workOrderNumber.split("-");
|
|
return items[1];
|
|
}
|
|
|
|
this.backButtonAction();
|
|
},
|
|
getInvoiceNumber() {
|
|
if (store.getters.order.workOrderNumber) {
|
|
return store.getters.order.workOrderNumber.replace("-", "");
|
|
}
|
|
|
|
this.backButtonAction();
|
|
},
|
|
getAddress1() {
|
|
return store.getters.order.serviceLocation.address
|
|
? store.getters.order.serviceLocation.address
|
|
: store.getters.order.serviceLocation.provider.address.streetAddress;
|
|
},
|
|
getAddress2() {
|
|
return store.getters.order.serviceLocation.address2
|
|
? store.getters.order.serviceLocation.address2
|
|
: null;
|
|
},
|
|
getCity() {
|
|
return store.getters.order.serviceLocation.city
|
|
? store.getters.order.serviceLocation.city
|
|
: store.getters.order.serviceLocation.provider.address.city;
|
|
},
|
|
getState() {
|
|
return store.getters.order.serviceLocation.state
|
|
? store.getters.order.serviceLocation.state
|
|
: store.getters.order.serviceLocation.provider.address.state;
|
|
},
|
|
getZipCode() {
|
|
return store.getters.order.serviceLocation.zipCode
|
|
? store.getters.order.serviceLocation.zipCode
|
|
: store.getters.order.serviceLocation.provider.address.zipCode;
|
|
},
|
|
getPaymentType() {
|
|
switch (store.getters.order.payment.piaType) {
|
|
case paymentMethods.AFTERPAY:
|
|
return "ap";
|
|
case paymentMethods.CREDIT_CARD:
|
|
return "cc";
|
|
case paymentMethods.PAYPAL:
|
|
return "pp";
|
|
default:
|
|
return store.getters.payment.piaType;
|
|
}
|
|
},
|
|
getPiaLineItems(cartItems) {
|
|
const glassParts = store.getters.order.lineItems.glassParts;
|
|
let lineItems = [];
|
|
|
|
if (glassParts === null) {
|
|
lineItems = ["Labor|0|1", "Repair supplies|0|1"];
|
|
} else {
|
|
lineItems = ["Parts and labor|0|1"];
|
|
}
|
|
|
|
cartItems.forEach((item) => {
|
|
if (item.name !== null && item.category != "promos") {
|
|
const total = (item.salesTax + item.subTotal).toFixed(2);
|
|
if (total > 0) {
|
|
lineItems.push(
|
|
`${item.name}|${(item.salesTax + item.subTotal).toFixed(2)}|1`
|
|
);
|
|
}
|
|
}
|
|
});
|
|
|
|
this.piaLineItems = lineItems.join("||");
|
|
},
|
|
getAmountDue() {
|
|
return baseMixin.methods.getAmountDue(store.getters.order.lineItems);
|
|
},
|
|
getDisplayAmountDue() {
|
|
return baseMixin.methods.getDisplayAmountDue(store.getters.order.lineItems);
|
|
},
|
|
async paymentFailedPayLater() {
|
|
this.$refs.loadingModal.isModalVisible = true;
|
|
|
|
await this.dispatchStoreAction(
|
|
storeActions.SAVE_PAYMENT_METHOD_CHOICE,
|
|
paymentMethods.LATER,
|
|
false
|
|
);
|
|
|
|
await this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
|
|
try {
|
|
await submitWorkOrder({
|
|
pageNameToLog: "payment",
|
|
submitAfterSave: true,
|
|
});
|
|
|
|
await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER);
|
|
window.location = applicationConfig.CONFIRMATION_URL;
|
|
} catch (error) {
|
|
console.log("error: response from submit work order(payment pg):" + error.message);
|
|
this.$router.navigateWithoutSaving(
|
|
this.navigationScenarios.PIA_ERROR,
|
|
this.$route,
|
|
{},
|
|
{ [routerParams.DISPLAY_PIA_ALERT]: true }
|
|
);
|
|
this.$refs.loadingModal.isModalVisible = false;
|
|
return;
|
|
}
|
|
},
|
|
backButtonAction() {
|
|
// The only way I could figure out how to get navigation to work on a page with the iframe.
|
|
// This is also how a cancel from Paypal would work. Just a redirect to the payment-method page.
|
|
// The normal navigation sort of works but the page does not render. The "next" callback function does not get
|
|
// invoked in payment-method's beforeroute enter. I also spotted an error in vue-router.esm-bundler.js when this
|
|
// happens but was unable to ignore it with a try catch. The navigation guard error is:
|
|
// Error: Redirected from "/?fmgPage=payment-method" to "{ params: {isSavingNation: "false"}, query: "fmgPage: "payment-method"}"
|
|
// I don't know if the navigation guard thinks the to and from are the same page.
|
|
// Also tried overriding with a $router.push
|
|
window.location = applicationConfig.PIA_CANCEL_URL;
|
|
//this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
|
|
},
|
|
submitHopForm() {
|
|
this.$nextTick(() => {
|
|
this.$refs.hopForm.submit();
|
|
|
|
const iframe = this.$refs.paymentFrame;
|
|
if (iframe) {
|
|
iframe.onload = () => {
|
|
if (iframe.contentWindow) {
|
|
if (baseMixin.methods.showApplePay()) {
|
|
iframe.contentWindow.postMessage("hybrid-with-applepay", "*");
|
|
console.log(new Date() + ": Sent applepay: new hop with applepay");
|
|
} else {
|
|
iframe.contentWindow.postMessage("hybrid", "*");
|
|
console.log(new Date() + ": Sent hybrid: new hop no applepay");
|
|
}
|
|
|
|
if (this.paymentType == "cc" || this.paymentType == "PayNow") {
|
|
iframe.contentWindow.postMessage("CreditCardChosen", "*");
|
|
console.log(new Date() + ": Sent creditcard");
|
|
} else if (this.paymentType == "ap") {
|
|
iframe.contentWindow.postMessage("afterpay", "*");
|
|
console.log(new Date() + ": Sent afterpay");
|
|
}
|
|
}
|
|
};
|
|
}
|
|
});
|
|
},
|
|
async fetchSignatureInfo(signatureInfo) {
|
|
if (this.isPaypal) {
|
|
this.$refs.loadingModal.showModal();
|
|
}
|
|
|
|
this.authToken = signatureInfo.token;
|
|
this.authSignature = signatureInfo.signature;
|
|
this.authSignatureStart = signatureInfo.startDate;
|
|
|
|
this.submitHopForm();
|
|
},
|
|
handleIFrameContentWindowMessage(event) {
|
|
if (typeof event.data === "string") {
|
|
if (event.data.indexOf("afterpayClosed") > -1) {
|
|
this.backButtonAction();
|
|
}
|
|
|
|
if (event.data.indexOf("creditCardSubmit") > -1) {
|
|
console.log(new Date() + ": Payment method credit card selected");
|
|
this.updatePaymentMethod(paymentMethods.CREDIT_CARD);
|
|
this.setUIBlock(true);
|
|
}
|
|
|
|
if (event.data.indexOf("afterpayPaymentReceived") > -1) {
|
|
console.log(new Date() + ": Payment method afterpay selected");
|
|
this.updatePaymentMethod(paymentMethods.AFTERPAY);
|
|
}
|
|
|
|
if (event.data.indexOf("applepayOpened") > -1) {
|
|
console.log(new Date() + ": Payment method applepay selected");
|
|
this.updatePaymentMethod(paymentMethods.APPLE_PAY);
|
|
}
|
|
|
|
if (event.data.indexOf("showLoaderForPaypal") > -1) {
|
|
console.log(new Date() + ": Payment method paypal selected");
|
|
this.updatePaymentMethod(paymentMethods.PAYPAL);
|
|
}
|
|
}
|
|
},
|
|
updatePaymentMethod(paymentMethod) {
|
|
// if the payment method is not set yet, then set it based on what HOP sends us
|
|
if (
|
|
store.getters.order.payment.piaType == paymentMethods.PAY_NOW ||
|
|
store.getters.order.payment.piaType == paymentMethods.NONE
|
|
) {
|
|
console.log(new Date() + " UPDATE PaymentMethod from HOP:" + paymentMethod);
|
|
this.dispatchStoreAction(
|
|
storeActions.SAVE_PAYMENT_METHOD_CHOICE,
|
|
paymentMethod,
|
|
false
|
|
);
|
|
}
|
|
},
|
|
setIFrameListener() {
|
|
window.addEventListener("message", (event) =>
|
|
this.handleIFrameContentWindowMessage(event)
|
|
);
|
|
},
|
|
setUIBlock(val) {
|
|
this.shouldBlockInteraction = val;
|
|
},
|
|
supressClick(event) {
|
|
if (this.shouldBlockInteraction) {
|
|
event.stopPropagation();
|
|
}
|
|
},
|
|
shouldDisplayPiaAlert(payMethod) {
|
|
return (
|
|
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] === payMethod ||
|
|
getBoolFromString(window.history.state.displayPiaAlert)
|
|
);
|
|
},
|
|
},
|
|
components: {
|
|
funnelHeader,
|
|
navbar,
|
|
loadingModal,
|
|
cart,
|
|
alert,
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.hop-iframe {
|
|
position: relative;
|
|
min-height: 650px;
|
|
width: 100%;
|
|
border: 0 none;
|
|
}
|
|
#pageLoadingModal {
|
|
background-color: red;
|
|
}
|
|
|
|
.ui-block {
|
|
position: fixed;
|
|
top: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 9999;
|
|
}
|
|
</style>
|