diff --git a/src/constants/query-strings.js b/src/constants/query-strings.js index 9b486517..576d1e5b 100644 --- a/src/constants/query-strings.js +++ b/src/constants/query-strings.js @@ -1,5 +1,21 @@ const queryStrings = Object.freeze({ - ISS_PAGE: 'issPage' + ISS_PAGE: 'issPage', + AUTH_CODE: 'auth_code', + BILL_TO_FIRST_NAME: 'billto_firstname', + BILL_TO_LAST_NAME: 'billto_lastname', + BILL_TO_POSTAL_CODE: 'billto_postalcode', + CARD_EXPIRATION_MONTH: 'card_expirationmonth', + CARD_EXPIRATION_YEAR: 'card_expirationyear', + CARD_TYPE: 'sgcardtype', + DISPLAY_PAY_IN_ADVANCE_ALERT: 'displayPayInAdvanceAlert', + ERROR: 'error', + LAST_FOUR: 'last_four', + REFERENCE_NUMBER: 'req_reference_number', + REFERRAL_SEQ_NUM: 'referralseqnum', + SUBSCRIPTIONID: 'subscriptionid', + TRANS_REFERENCE_NUMBER: 'auth_trans_ref_no', + TRANSACTION_ID: 'transaction_id' + }); export default queryStrings; diff --git a/src/constants/web-storage-constants.js b/src/constants/web-storage-constants.js new file mode 100644 index 00000000..29c814cf --- /dev/null +++ b/src/constants/web-storage-constants.js @@ -0,0 +1,5 @@ +const webStorageConstants = Object.freeze({ + SUBMITTED_ORDER: 'submittedOrder' +}); + +export default webStorageConstants; diff --git a/src/helpers/order-helper.js b/src/helpers/order-helper.js index 85d0bec2..33e7d3c4 100644 --- a/src/helpers/order-helper.js +++ b/src/helpers/order-helper.js @@ -1,6 +1,17 @@ import { useMainStore } from '@/store'; import { updateOrCreateISSCookie } from '@/helpers/cookie-helper'; +/* + Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing +*/ +async function saveSessionHelper(store) { + const savedSessionInfo = await store.saveSession(); + if (savedSessionInfo) { + store.setSaveSessionInfo(savedSessionInfo.data); + } + updateOrCreateISSCookie(); +} + /* Will call API to save existing order, or create new one depending where it's called from. This will also set Referral information in the store after saving, and then @@ -8,8 +19,8 @@ import { updateOrCreateISSCookie } from '@/helpers/cookie-helper'; */ export async function saveSession({ shouldAwaitSaveSessionQueue = false }) { const store = useMainStore(); - var saveSessionPromise = store.applicationUser.saveSessionPromise - ? store.applicationUser.saveSessionPromise.then(() => { return saveSessionHelper(store); }) + const saveSessionPromise = store.applicationUser.saveSessionPromise + ? store.applicationUser.saveSessionPromise.then(() => saveSessionHelper(store)) : saveSessionHelper(store); store.setSaveSessionPromise(saveSessionPromise); @@ -20,12 +31,18 @@ export async function saveSession({ shouldAwaitSaveSessionQueue = false }) { } /* - Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing + Will determine if to submitWorkOrder. + TODO: Add more description to this */ -async function saveSessionHelper(store) { - const savedSessionInfo = await store.saveSession(); - if (savedSessionInfo) { - store.setSaveSessionInfo(savedSessionInfo.data); - } - updateOrCreateISSCookie(); -} \ No newline at end of file +export async function submitWorkOrder({ + pageNameToLog, + submitAfterSave = false, + createDeleteStatusWorkOrderForPia = false +}) { + await saveSession({ + pageNameToLog, + shouldAwaitSaveSessionQueue: true, + submitAfterSave, + createDeleteStatusWorkOrderForPia + }); +} diff --git a/src/helpers/querystring-helper.js b/src/helpers/querystring-helper.js new file mode 100644 index 00000000..f4df1ed7 --- /dev/null +++ b/src/helpers/querystring-helper.js @@ -0,0 +1,11 @@ +export default function getQueryStringParameter(key) { + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const lowerCaseParams = new URLSearchParams(); + + urlParams.forEach((value, name) => { + lowerCaseParams.append(name.toLowerCase(), value); + }); + + return lowerCaseParams.get(key.toLowerCase()); +} diff --git a/src/layouts/payment-page/payment-page.vue b/src/layouts/payment-page/payment-page.vue index 7612e842..1f77de74 100644 --- a/src/layouts/payment-page/payment-page.vue +++ b/src/layouts/payment-page/payment-page.vue @@ -460,15 +460,11 @@ export default { computed: { payInAdvanceResponseUrl() { const { protocol, host } = window.location; - return `${protocol}//${host}/?issPage=${ - issPageValues.PAYMENT_RETURN - }&src=iss-nextgen`; + return `${protocol}//${host}/?issPage=${issPageValues.PAYMENT_RETURN}&src=iss-nextgen`; }, payInAdvanceCancelUrl() { const { protocol, host } = window.location; - return `${protocol}//${host}/?issPage=${ - issPageValues.PAYMENT_METHOD - }&src=iss-nextgen`; + return `${protocol}//${host}/?issPage=${issPageValues.PAYMENT_METHOD}&src=iss-nextgen`; }, dynamicCSSUrl() { const { protocol, hostname, port } = window.location; diff --git a/src/layouts/payment-return/payment-return.vue b/src/layouts/payment-return/payment-return.vue new file mode 100644 index 00000000..8e5d3de6 --- /dev/null +++ b/src/layouts/payment-return/payment-return.vue @@ -0,0 +1,143 @@ + + + diff --git a/src/router/index.js b/src/router/index.js index 4cd2dc45..fda08794 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -2,7 +2,7 @@ import { createWebHistory, createRouter } from 'vue-router'; import lazyLoadComponent from '@/router/dynamic-routing/component-loader'; import issPageValues from '@/router/router-constants/issPage-values'; -import { routingTable } from '@/router/router-constants/routing-table'; +import routingTable from '@/router/router-constants/routing-table'; import { useMainStore } from '@/store'; import eventBus from '@/helpers/event-bus/event-bus'; import { globalEvents, globalEventTypes } from '@/constants/events'; @@ -16,11 +16,9 @@ import showIssLoadingModal from '@/helpers/loading-modal-helper'; import analyticsMixin from '@/mixins/analytics-mixin'; import { saveSession } from '@/helpers/order-helper.js'; import routerParams from '@/router/router-constants/router-params'; -import bailoutCode from '@/constants/bailoutCode'; -import IssPageValues from '@/router/router-constants/issPage-values'; +import canBailoutNavigateBack from '@/helpers/bailout-helper'; +import bailoutMessage from '@/constants/bailoutMessage'; import navigationScenarios from './router-constants/navigation-scenarios'; -import canBailoutNavigateBack from "@/helpers/bailout-helper"; -import bailoutMessage from "@/constants/bailoutMessage"; const routes = [ { @@ -129,7 +127,7 @@ router.beforeEach(async (to, from) => { showIssLoadingModal(true); } - const isInIframe = fromQueryPage === IssPageValues.PAYMENT_PAGE; + const isInIframe = fromQueryPage === issPageValues.PAYMENT_PAGE; if (isInIframe) { // need to set window.top.location.href directly when navigating out of an iframe // especially when navigating with browser buttons @@ -139,7 +137,7 @@ router.beforeEach(async (to, from) => { const store = useMainStore(); // Prevent navigating backwards if we enter a bailout that we are not allowed to go back on - if (store.isBailout && from.name === IssPageValues.BAILOUT_PAGE && to.name !== 'root' && to.name !== IssPageValues.CONTACT_CONFIRMATION + if (store.isBailout && from.name === issPageValues.BAILOUT_PAGE && to.name !== 'root' && to.name !== issPageValues.CONTACT_CONFIRMATION && !canBailoutNavigateBack()) { return false; } diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 967b99d4..bd079640 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -96,6 +96,9 @@ const navigationScenarios = Object.freeze({ // Payment CLICKED_PAY_NOW: 'CLICKED_PAY_NOW', + PAY_IN_ADVANCE_ERROR: 'PAY_IN_ADVANCE_ERROR', + PAY_IN_ADVANCE_CREDIT_CARD_ERROR: 'PAY_IN_ADVANCE_CREDIT_CARD_ERROR', + PAY_IN_ADVANCE_SUCCESS: 'PAY_IN_ADVANCE_SUCCESS', // Bailout CLICKED_FORWARD_WITH_BAILOUT: 'CLICKED_FORWARD_WITH_BAILOUT' diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index d20f59cd..99582af8 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -641,6 +641,23 @@ const routingTable = () => [ } ] }, + { + issPageValue: issPageValues.PAYMENT_RETURN, + maps: [ + { + scenario: navigationScenarios.PAY_IN_ADVANCE_ERROR, + destinationIssPageValue: issPageValues.PAYMENT_METHOD + }, + { + scenario: navigationScenarios.PAY_IN_ADVANCE_CREDIT_CARD_ERROR, + destinationIssPageValue: issPageValues.PAYMENT_PAGE + }, + { + scenario: navigationScenarios.PAY_IN_ADVANCE_SUCCESS, + destinationIssPageValue: issPageValues.CONFIRMATION + } + ] + }, { issPageValue: issPageValues.TPA_CONFIRMATION, maps: [ @@ -746,4 +763,4 @@ const routingTable = () => [ ]; -export { routingTable }; +export default routingTable; diff --git a/src/store/index.js b/src/store/index.js index 5017c884..3c0dc489 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -14,6 +14,7 @@ import coverageStatuses from '@/constants/coverage-statuses'; import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from '@/constants/schedule-constants'; import { convertDateStringToDate, getDateDifferenceInDays, militaryToTwelveHourTime } from '@/helpers/date-helper'; import { paymentMethods } from '@/constants/payment-method-constants'; +import webStorageConstants from '@/constants/web-storage-constants'; import { deductibleForSelectedVehicle, endorsementsForSelectedVehicle, noCoverageForSelectedVehicle, @@ -155,7 +156,22 @@ const getDefaultState = () => ({ }, parentAccountNumber: 0, isPayInAdvance: null, - payInAdvanceType: null + payInAdvanceType: null, + paypalToken: null, + creditCardToken: { + subscriptionId: null, + expMonth: null, + expYear: null, + cardType: null, + billToPostalCode: null, + billToFirstName: null, + billToLastName: null, + referenceNumber: null, + authCode: null, + transactionId: null, + transReferenceNumber: null, + lastFour: null + } }, contactInfo: { firstName: null, @@ -933,7 +949,6 @@ export const useMainStore = defineStore({ }).then((response) => resolve(response), (error) => reject(error)); }); }, - getCarrierAccountInfo() { return new Promise((resolve, reject) => { globalMethods.callHttpClient({ @@ -945,7 +960,6 @@ export const useMainStore = defineStore({ }).catch((error) => reject(error)); }); }, - async getSupportingItems() { const { glassParts } = this.lineItems; const { carId } = this.vehicle; @@ -1198,7 +1212,7 @@ export const useMainStore = defineStore({ submitToMainframe: !!this.order.referralNumber, loadedFromDupeCheck }, - additionalSuccessEventDataHandler: (response) => + additionalSuccessEventDataHandler: () => `Email provided: ${customer.emailAddress ? 'true' : 'false'}` }).then((response) => { if (loadedFromDupeCheck) { @@ -1300,7 +1314,23 @@ export const useMainStore = defineStore({ throw ex; } }, - + updateCreditCardToken(token) { + this.order.payment.creditCardToken.subscriptionId = token.subscriptionId; + this.order.payment.creditCardToken.expMonth = token.expMonth; + this.order.payment.creditCardToken.expYear = token.expYear; + this.order.payment.creditCardToken.cardType = token.cardType; + this.order.payment.creditCardToken.billToPostalCode = token.billToPostalCode; + this.order.payment.creditCardToken.billToFirstName = token.billToFirstName; + this.order.payment.creditCardToken.billToLastName = token.billToLastName; + this.order.payment.creditCardToken.referenceNumber = token.referenceNumber; + this.order.payment.creditCardToken.authCode = token.authCode; + this.order.payment.creditCardToken.transactionId = token.transactionId; + this.order.payment.creditCardToken.transReferenceNumber = token.transReferenceNumber; + this.order.payment.creditCardToken.lastFour = token.lastFour; + }, + updatePaypalToken(token) { + this.order.payment.paypalToken = token; + }, setSaveSessionPromise(promise) { this.applicationUser.saveSessionPromise = promise; }, @@ -1382,6 +1412,10 @@ export const useMainStore = defineStore({ this.order.serviceLocation.searchFilter = serviceLocationInfo.searchFilter; }, + resetState() { + Object.assign(this, getDefaultState()); + }, + resetRegistrationState() { this.order.vehicle.registration.licensePlate = null; this.order.vehicle.registration.address = null; @@ -1391,7 +1425,7 @@ export const useMainStore = defineStore({ this.order.vehicle.registration.firstName = null; this.order.vehicle.registration.lastName = null; }, - resetServiceLocationAndDependencies(context) { + resetServiceLocationAndDependencies() { this.resetServiceLocationAppointmentType(); this.resetServiceLocationProvider(); this.resetSchedule(); @@ -2122,7 +2156,6 @@ export const useMainStore = defineStore({ this.resetInsurance(); this.resetBailout(); }, - savePaymentMethodChoice(paymentMethod) { const isPayInAdvance = paymentMethod !== paymentMethods.PAY_AT_TIME_OF_SERVICE; this.order.payment.isPayInAdvance = isPayInAdvance; @@ -2134,8 +2167,33 @@ export const useMainStore = defineStore({ method: endpoints.GetPaymentSignature.method, endpoint: endpoints.GetPaymentSignature.url }); - } + }, + hasSubmittedOrder() { + return window.sessionStorage.getItem(webStorageConstants.SUBMITTED_ORDER) !== null; + }, + + createSubmittedOrder() { + if (this.hasSubmittedOrder()) { + return; + } + const submittedOrder = this.order; + const { experiments } = this.applicationUser; + + // set to local storage + window.sessionStorage.setItem(webStorageConstants.SUBMITTED_ORDER, JSON.stringify(submittedOrder)); + + // clear vuex + this.resetState(); + + // restore user's experiments + this.applicationUser.experiments = experiments; + }, + + resetSubmittedOrder() { + // clear from local storage + window.sessionStorage.removeItem(webStorageConstants.SUBMITTED_ORDER); + } }, persist: true });