Merge branches 'feature/digital/SSR-1081' and 'feature/digital/SSR-1081' of https://github.com/Safelite/DigitalConsumer.ISS into feature/digital/SSR-1081

This commit is contained in:
Matt Caimi 2024-03-05 11:12:43 -05:00
commit 7fdc9afe16
7 changed files with 140 additions and 60 deletions

View file

@ -1,20 +1,21 @@
const queryStrings = Object.freeze({ const queryStrings = Object.freeze({
ISS_PAGE: 'issPage', ISS_PAGE: 'issPage',
ERROR: 'error', AUTH_CODE: 'auth_code',
SUBSCRIPTIONID: 'subscriptionid', BILL_TO_FIRST_NAME: 'billto_firstname',
REFERRAL_SEQ_NUM: 'referralseqnum', BILL_TO_LAST_NAME: 'billto_lastname',
BILL_TO_POSTAL_CODE: 'billto_postalcode',
CARD_EXPIRATION_MONTH: 'card_expirationmonth', CARD_EXPIRATION_MONTH: 'card_expirationmonth',
CARD_EXPIRATION_YEAR: 'card_expirationyear', CARD_EXPIRATION_YEAR: 'card_expirationyear',
CARD_TYPE: 'sgcardtype', CARD_TYPE: 'sgcardtype',
BILL_TO_POSTAL_CODE: 'billto_postalcode', DISPLAY_PAY_IN_ADVANCE_ALERT: 'displayPayInAdvanceAlert',
BILL_TO_FIRST_NAME: 'billto_firstname', ERROR: 'error',
BILL_TO_LAST_NAME: 'billto_lastname',
REFERENCE_NUMBER: 'req_reference_number',
AUTH_CODE: 'auth_code',
TRANSACTION_ID: 'transaction_id',
TRANS_REFERENCE_NUMBER: 'auth_trans_ref_no',
LAST_FOUR: 'last_four', LAST_FOUR: 'last_four',
DISPLAY_PAY_IN_ADVANCE_ALERT: 'displayPayInAdvanceAlert' 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; export default queryStrings;

View file

@ -1,24 +1,6 @@
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import { updateOrCreateISSCookie } from '@/helpers/cookie-helper'; import { updateOrCreateISSCookie } from '@/helpers/cookie-helper';
/*
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
update the cookie. To force synchronous behavior pass in 'true' for shouldAwaitSaveSessionQueue
*/
export async function saveSession({ shouldAwaitSaveSessionQueue = false }) {
const store = useMainStore();
var saveSessionPromise = store.applicationUser.saveSessionPromise
? store.applicationUser.saveSessionPromise.then(() => { return saveSessionHelper(store); })
: saveSessionHelper(store);
store.setSaveSessionPromise(saveSessionPromise);
if (!store.applicationUser.savedSessionId || shouldAwaitSaveSessionQueue) {
await saveSessionPromise;
}
}
/* /*
Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing
*/ */
@ -29,3 +11,38 @@ async function saveSessionHelper(store) {
} }
updateOrCreateISSCookie(); 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
update the cookie. To force synchronous behavior pass in 'true' for shouldAwaitSaveSessionQueue
*/
export async function saveSession({ shouldAwaitSaveSessionQueue = false }) {
const store = useMainStore();
const saveSessionPromise = store.applicationUser.saveSessionPromise
? store.applicationUser.saveSessionPromise.then(() => saveSessionHelper(store))
: saveSessionHelper(store);
store.setSaveSessionPromise(saveSessionPromise);
if (!store.applicationUser.savedSessionId || shouldAwaitSaveSessionQueue) {
await saveSessionPromise;
}
}
/*
Will determine if to submitWorkOrder.
TODO: Add more description to this
*/
export async function submitWorkOrder({
pageNameToLog,
submitAfterSave = false,
createDeleteStatusWorkOrderForPia = false
}) {
await saveSession({
pageNameToLog,
shouldAwaitSaveSessionQueue: true,
submitAfterSave,
createDeleteStatusWorkOrderForPia
});
}

View file

@ -1,4 +1,4 @@
export default function getQuerystringParameter(key) { export default function getQueryStringParameter(key) {
const queryString = window.location.search; const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString); const urlParams = new URLSearchParams(queryString);
const lowerCaseParams = new URLSearchParams(); const lowerCaseParams = new URLSearchParams();

View file

@ -11,8 +11,10 @@ import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js'; import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store/index.js'; import { useMainStore } from '@/store/index.js';
import queryStrings from '@/constants/query-strings'; import queryStrings from '@/constants/query-strings';
import getQuerystringParameter from '@/helpers/querystring-helper.js'; import getQueryStringParameter from '@/helpers/querystring-helper.js';
import { paymentMethods } from '@/constants/payment-method-constants.js'; import { paymentMethods } from '@/constants/payment-method-constants.js';
import { submitWorkOrder } from '@/helpers/order-helper.js';
import showIssLoadingModal from '@/helpers/loading-modal-helper';
export default { export default {
name: 'payment-return', name: 'payment-return',
@ -22,14 +24,14 @@ export default {
}, },
mixins: [BaseFormMixin], mixins: [BaseFormMixin],
async mounted() { async mounted() {
const payInAdvanceError = getQuerystringParameter(queryStrings.ERROR); showIssLoadingModal(true);
const payInAdvanceError = getQueryStringParameter(queryStrings.ERROR);
const { payInAdvanceType } = useMainStore().order.payment; const { payInAdvanceType } = useMainStore().order.payment;
if (payInAdvanceError) { if (payInAdvanceError) {
console.error(`Error during payment: ${payInAdvanceError}`); console.error(`Error during payment: ${payInAdvanceError}`);
const paymentPageNavScenario = const paymentPageNavScenario =
payInAdvanceType === paymentMethods.CREDIT_CARD payInAdvanceType === paymentMethods.CREDIT_CARD || payInAdvanceType === paymentMethods.AFTERPAY;
|| payInAdvanceType === paymentMethods.AFTERPAY;
if (paymentPageNavScenario) { if (paymentPageNavScenario) {
this.$router.navigate( this.$router.navigate(
this.navigationScenarios.PAY_IN_ADVANCE_CREDIT_CARD_ERROR, this.navigationScenarios.PAY_IN_ADVANCE_CREDIT_CARD_ERROR,
@ -71,10 +73,16 @@ export default {
arePagePrerequisitesValid() { arePagePrerequisitesValid() {
return true; return true;
}, },
async processCreditCardResponse() { async processPaypalResponse() {
const subscriptionId = getQuerystringParameter(queryStrings.SUBSCRIPTIONID); const token = getQueryStringParameter(queryStrings.TOKEN);
this.mainStore.updatePaypalToken(token);
const referralSeqNum = getQuerystringParameter(queryStrings.REFERRAL_SEQ_NUM); await this.saveAndSubmitWorkOrder();
},
async processCreditCardResponse() {
const subscriptionId = getQueryStringParameter(queryStrings.SUBSCRIPTIONID);
const referralSeqNum = getQueryStringParameter(queryStrings.REFERRAL_SEQ_NUM);
if (referralSeqNum !== useMainStore().order.referralSequenceNumber) { if (referralSeqNum !== useMainStore().order.referralSequenceNumber) {
console.error(`error: unknown ref:${referralSeqNum} ${useMainStore().order.referralSequenceNumber}`); console.error(`error: unknown ref:${referralSeqNum} ${useMainStore().order.referralSequenceNumber}`);
this.$router.navigate( this.$router.navigate(
@ -85,19 +93,19 @@ export default {
} }
); );
} else { } else {
const expMonth = getQuerystringParameter(queryStrings.CARD_EXPIRATION_MONTH); const expMonth = getQueryStringParameter(queryStrings.CARD_EXPIRATION_MONTH);
const expYear = getQuerystringParameter(queryStrings.CARD_EXPIRATION_YEAR); const expYear = getQueryStringParameter(queryStrings.CARD_EXPIRATION_YEAR);
const cardType = getQuerystringParameter(queryStrings.CARD_TYPE); const cardType = getQueryStringParameter(queryStrings.CARD_TYPE);
const billToPostalCode = getQuerystringParameter(queryStrings.BILL_TO_POSTAL_CODE); const billToPostalCode = getQueryStringParameter(queryStrings.BILL_TO_POSTAL_CODE);
const billToFirstName = getQuerystringParameter(queryStrings.BILL_TO_FIRST_NAME); const billToFirstName = getQueryStringParameter(queryStrings.BILL_TO_FIRST_NAME);
const billToLastName = getQuerystringParameter(queryStrings.BILL_TO_LAST_NAME); const billToLastName = getQueryStringParameter(queryStrings.BILL_TO_LAST_NAME);
const referenceNumber = getQuerystringParameter(queryStrings.REFERENCE_NUMBER); const referenceNumber = getQueryStringParameter(queryStrings.REFERENCE_NUMBER);
const authCode = getQuerystringParameter(queryStrings.AUTH_CODE); const authCode = getQueryStringParameter(queryStrings.AUTH_CODE);
const transactionId = getQuerystringParameter(queryStrings.TRANSACTION_ID); const transactionId = getQueryStringParameter(queryStrings.TRANSACTION_ID);
const transReferenceNumber = getQuerystringParameter(queryStrings.TRANS_REFERENCE_NUMBER); const transReferenceNumber = getQueryStringParameter(queryStrings.TRANS_REFERENCE_NUMBER);
const lastFour = getQuerystringParameter(queryStrings.LAST_FOUR); const lastFour = getQueryStringParameter(queryStrings.LAST_FOUR);
const ccToken = { const creditCardToken = {
subscriptionId, subscriptionId,
expMonth, expMonth,
expYear, expYear,
@ -111,7 +119,7 @@ export default {
transReferenceNumber, transReferenceNumber,
lastFour lastFour
}; };
useMainStore().updateCCToken(ccToken); useMainStore().updateCreditCardToken(creditCardToken);
await this.saveAndSubmitWorkOrder(); await this.saveAndSubmitWorkOrder();
} }
}, },
@ -119,9 +127,10 @@ export default {
// Final work order submit after returning from pay in advance. // Final work order submit after returning from pay in advance.
useMainStore().resetSubmittedOrder(); useMainStore().resetSubmittedOrder();
try { try {
// do we have a function to submit a work order, await submitWorkOrder({
// perhaps built into saveSession? pageNameToLog: 'payment-return',
// we need to submit the work order here submitAfterSave: true
});
} catch (error) { } catch (error) {
console.error(`error: response from submit work order:${error.message}`); console.error(`error: response from submit work order:${error.message}`);
this.$router.navigate( this.$router.navigate(
@ -131,9 +140,11 @@ export default {
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true [queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
} }
); );
showIssLoadingModal(false);
return; return;
} }
showIssLoadingModal(false);
useMainStore().createSubmittedOrder(); useMainStore().createSubmittedOrder();
this.$router.navigate( this.$router.navigate(
this.navigationScenarios.PAY_IN_ADVANCE_SUCCESS, this.navigationScenarios.PAY_IN_ADVANCE_SUCCESS,

View file

@ -2,7 +2,7 @@
import { createWebHistory, createRouter } from 'vue-router'; import { createWebHistory, createRouter } from 'vue-router';
import lazyLoadComponent from '@/router/dynamic-routing/component-loader'; import lazyLoadComponent from '@/router/dynamic-routing/component-loader';
import issPageValues from '@/router/router-constants/issPage-values'; 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 { useMainStore } from '@/store';
import eventBus from '@/helpers/event-bus/event-bus'; import eventBus from '@/helpers/event-bus/event-bus';
import { globalEvents, globalEventTypes } from '@/constants/events'; import { globalEvents, globalEventTypes } from '@/constants/events';
@ -16,11 +16,9 @@ import showIssLoadingModal from '@/helpers/loading-modal-helper';
import analyticsMixin from '@/mixins/analytics-mixin'; import analyticsMixin from '@/mixins/analytics-mixin';
import { saveSession } from '@/helpers/order-helper.js'; import { saveSession } from '@/helpers/order-helper.js';
import routerParams from '@/router/router-constants/router-params'; import routerParams from '@/router/router-constants/router-params';
import bailoutCode from '@/constants/bailoutCode'; import canBailoutNavigateBack from '@/helpers/bailout-helper';
import IssPageValues from '@/router/router-constants/issPage-values'; import bailoutMessage from '@/constants/bailoutMessage';
import navigationScenarios from './router-constants/navigation-scenarios'; import navigationScenarios from './router-constants/navigation-scenarios';
import canBailoutNavigateBack from "@/helpers/bailout-helper";
import bailoutMessage from "@/constants/bailoutMessage";
const routes = [ const routes = [
{ {
@ -129,7 +127,7 @@ router.beforeEach(async (to, from) => {
showIssLoadingModal(true); showIssLoadingModal(true);
} }
const isInIframe = fromQueryPage === IssPageValues.PAYMENT_PAGE; const isInIframe = fromQueryPage === issPageValues.PAYMENT_PAGE;
if (isInIframe) { if (isInIframe) {
// need to set window.top.location.href directly when navigating out of an iframe // need to set window.top.location.href directly when navigating out of an iframe
// especially when navigating with browser buttons // especially when navigating with browser buttons
@ -139,7 +137,7 @@ router.beforeEach(async (to, from) => {
const store = useMainStore(); const store = useMainStore();
// Prevent navigating backwards if we enter a bailout that we are not allowed to go back on // 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()) { && !canBailoutNavigateBack()) {
return false; return false;
} }

View file

@ -655,7 +655,7 @@ const routingTable = () => [
{ {
scenario: navigationScenarios.PAY_IN_ADVANCE_SUCCESS, scenario: navigationScenarios.PAY_IN_ADVANCE_SUCCESS,
destinationIssPageValue: issPageValues.CONFIRMATION destinationIssPageValue: issPageValues.CONFIRMATION
}, }
] ]
}, },
{ {
@ -763,4 +763,4 @@ const routingTable = () => [
]; ];
export { routingTable }; export default routingTable;

View file

@ -20,6 +20,7 @@ import {
noCoverageForSelectedVehicle, noCoverageForSelectedVehicle,
repairWaivedForSelectedVehicle repairWaivedForSelectedVehicle
} from '@/helpers/policy-vehicle-helper'; } from '@/helpers/policy-vehicle-helper';
import webStorageConstants from '@/constants/web-storage-constants';
const storeId = 'main'; const storeId = 'main';
@ -157,7 +158,8 @@ const getDefaultState = () => ({
parentAccountNumber: 0, parentAccountNumber: 0,
isPayInAdvance: null, isPayInAdvance: null,
payInAdvanceType: null, payInAdvanceType: null,
ccToken: { paypalToken: null,
creditCardToken: {
subscriptionId: null, subscriptionId: null,
expMonth: null, expMonth: null,
expYear: null, expYear: null,
@ -948,7 +950,17 @@ export const useMainStore = defineStore({
}).then((response) => resolve(response), (error) => reject(error)); }).then((response) => resolve(response), (error) => reject(error));
}); });
}, },
getCarrierAccountInfo() {
return new Promise((resolve, reject) => {
globalMethods.callHttpClient({
method: endpoints.GetAccountInfo.method,
endpoint: endpoints.GetAccountInfo.url + this.issConfig.parentAccountNumber
}).then((response) => {
this.order.carrierPhoneNumber = response.data.phoneNumber;
return resolve(response.data);
}).catch((error) => reject(error));
});
},
async getSupportingItems() { async getSupportingItems() {
const { glassParts } = this.lineItems; const { glassParts } = this.lineItems;
const { carId } = this.vehicle; const { carId } = this.vehicle;
@ -1202,7 +1214,7 @@ export const useMainStore = defineStore({
submitToMainframe: !!this.order.referralNumber, submitToMainframe: !!this.order.referralNumber,
loadedFromDupeCheck loadedFromDupeCheck
}, },
additionalSuccessEventDataHandler: (response) => additionalSuccessEventDataHandler: () =>
`Email provided: ${customer.emailAddress ? 'true' : 'false'}` `Email provided: ${customer.emailAddress ? 'true' : 'false'}`
}).then((response) => { }).then((response) => {
if (loadedFromDupeCheck) { if (loadedFromDupeCheck) {
@ -1304,7 +1316,23 @@ export const useMainStore = defineStore({
throw ex; 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) { setSaveSessionPromise(promise) {
this.applicationUser.saveSessionPromise = promise; this.applicationUser.saveSessionPromise = promise;
}, },
@ -1399,7 +1427,7 @@ export const useMainStore = defineStore({
this.order.vehicle.registration.firstName = null; this.order.vehicle.registration.firstName = null;
this.order.vehicle.registration.lastName = null; this.order.vehicle.registration.lastName = null;
}, },
resetServiceLocationAndDependencies(context) { resetServiceLocationAndDependencies() {
this.resetServiceLocationAppointmentType(); this.resetServiceLocationAppointmentType();
this.resetServiceLocationProvider(); this.resetServiceLocationProvider();
this.resetSchedule(); this.resetSchedule();
@ -2130,7 +2158,6 @@ export const useMainStore = defineStore({
this.resetInsurance(); this.resetInsurance();
this.resetBailout(); this.resetBailout();
}, },
savePaymentMethodChoice(paymentMethod) { savePaymentMethodChoice(paymentMethod) {
const isPayInAdvance = paymentMethod !== paymentMethods.PAY_AT_TIME_OF_SERVICE; const isPayInAdvance = paymentMethod !== paymentMethods.PAY_AT_TIME_OF_SERVICE;
this.order.payment.isPayInAdvance = isPayInAdvance; this.order.payment.isPayInAdvance = isPayInAdvance;
@ -2144,6 +2171,32 @@ export const useMainStore = defineStore({
}); });
}, },
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);
}
updateCCToken(ccToken) { updateCCToken(ccToken) {
this.order.payment.ccToken.subscriptionId = ccToken.subscriptionId; this.order.payment.ccToken.subscriptionId = ccToken.subscriptionId;
this.order.payment.ccToken.expMonth = ccToken.expMonth; this.order.payment.ccToken.expMonth = ccToken.expMonth;