Addressing merge conflicts
This commit is contained in:
commit
b7282f4693
22 changed files with 1708 additions and 1041 deletions
|
|
@ -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;
|
||||
|
|
|
|||
5
src/constants/web-storage-constants.js
Normal file
5
src/constants/web-storage-constants.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
const webStorageConstants = Object.freeze({
|
||||
SUBMITTED_ORDER: 'submittedOrder'
|
||||
});
|
||||
|
||||
export default webStorageConstants;
|
||||
|
|
@ -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();
|
||||
}
|
||||
export async function submitWorkOrder({
|
||||
pageNameToLog,
|
||||
submitAfterSave = false,
|
||||
createDeleteStatusWorkOrderForPia = false
|
||||
}) {
|
||||
await saveSession({
|
||||
pageNameToLog,
|
||||
shouldAwaitSaveSessionQueue: true,
|
||||
submitAfterSave,
|
||||
createDeleteStatusWorkOrderForPia
|
||||
});
|
||||
}
|
||||
|
|
|
|||
12
src/helpers/price-calculator.js
Normal file
12
src/helpers/price-calculator.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
function getPriceOfLineItem(lineItem) {
|
||||
return (lineItem?.kitPrice ?? 0)
|
||||
+ (lineItem?.laborAmount ?? 0)
|
||||
+ (lineItem?.sellingPrice ?? 0);
|
||||
}
|
||||
|
||||
export default function getPriceOfLineItems(lineItems) {
|
||||
return lineItems.reduce(
|
||||
(accumulator, lineItem) => accumulator + getPriceOfLineItem(lineItem),
|
||||
0
|
||||
);
|
||||
}
|
||||
56
src/helpers/price-calculator.spec.js
Normal file
56
src/helpers/price-calculator.spec.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import getPriceOfLineItems from "@/helpers/price-calculator.js";
|
||||
|
||||
describe('getPriceOfLineItems', () => {
|
||||
test('Returns zero when no line items', () => {
|
||||
// Arrange
|
||||
const lineItems = [];
|
||||
|
||||
// Act
|
||||
const result = getPriceOfLineItems(lineItems);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
test('Returns expected when one line item', () => {
|
||||
// Arrange
|
||||
const lineItems = [
|
||||
{
|
||||
kitPrice: 1,
|
||||
laborAmount: 2,
|
||||
sellingPrice: 3
|
||||
}
|
||||
];
|
||||
const expected = 6;
|
||||
|
||||
// Act
|
||||
const result = getPriceOfLineItems(lineItems);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
test('Returns expected when multiple line items', () => {
|
||||
// Arrange
|
||||
const lineItems = [
|
||||
{
|
||||
kitPrice: 1,
|
||||
laborAmount: 2,
|
||||
sellingPrice: 3
|
||||
},
|
||||
{
|
||||
kitPrice: 1
|
||||
},
|
||||
{
|
||||
kitPrice: 10,
|
||||
laborAmount: 100,
|
||||
sellingPrice: 1000
|
||||
}
|
||||
];
|
||||
const expected = 1117;
|
||||
|
||||
// Act
|
||||
const result = getPriceOfLineItems(lineItems);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
});
|
||||
11
src/helpers/querystring-helper.js
Normal file
11
src/helpers/querystring-helper.js
Normal file
|
|
@ -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());
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`coverageStatement.vue-working returns the initial data 1`] = `
|
||||
Object {
|
||||
"baseServiceLineItems": Array [],
|
||||
"currencyFormatter": NumberFormat {},
|
||||
"deductibleText": "Your deductible is",
|
||||
"isNoComp": false,
|
||||
"isRepair": true,
|
||||
"loadingText": Array [
|
||||
"Connecting to your insurance company",
|
||||
"Nearly there",
|
||||
"Finishing up",
|
||||
],
|
||||
"policyLookupSuccessful": true,
|
||||
"rules": Object {
|
||||
"selectionRequired": "option-required",
|
||||
},
|
||||
"selectedProvider": "",
|
||||
"supportingItems": null,
|
||||
"widget": Object {
|
||||
"explanatoryText": "ExplanatoryTextWidget",
|
||||
"nextStep": "NextStepsWidget",
|
||||
"serviceProviderQuestion": "ServiceProviderQuestion",
|
||||
"subheader": "SiteSubHeaderWidget",
|
||||
"verifiedItacAlert": "VerifiedITACAlert",
|
||||
},
|
||||
}
|
||||
`;
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -35,26 +35,26 @@
|
|||
<div
|
||||
v-if="verifiedDeductible"
|
||||
class="d-flex justify-content-center cost">
|
||||
{{ formattedDeductible }}
|
||||
{{ deductibleForDisplay }}
|
||||
</div>
|
||||
<div
|
||||
v-if="displayQuote"
|
||||
v-if="isQuoteDisplayed"
|
||||
class="d-flex justify-content-center cost mb-0">
|
||||
{{ formattedServicePrice }}
|
||||
{{ servicePriceForDisplay }}
|
||||
</div>
|
||||
<div
|
||||
v-if="verifiedITAC"
|
||||
class="d-flex justify-content-center mb-4 deductible-text">
|
||||
{{ deductibleText }}
|
||||
<span class="text-success fw-bold">{{ formattedDeductible }}</span>
|
||||
<span class="text-success fw-bold">{{ deductibleForDisplay }}</span>
|
||||
</div>
|
||||
<alert
|
||||
v-if="verifiedITAC"
|
||||
ref="verifiedITACAlert"
|
||||
class="mb-5"
|
||||
cmsWidgetName="VerifiedITACAlert"
|
||||
:manualHeadline="verifiedITACAlertHeader"
|
||||
:manualCopy="verifiedITACAlertBody"
|
||||
:manualHeadline="verifiedItacAlertHeader"
|
||||
:manualCopy="verifiedItacAlertBody"
|
||||
alertClass="alert-success"
|
||||
:isDismissible="false">
|
||||
</alert>
|
||||
|
|
@ -67,18 +67,18 @@
|
|||
v-html="nextStepsBody">
|
||||
</div>
|
||||
<buttonQuestion
|
||||
v-if="displayQuote"
|
||||
v-if="isQuoteDisplayed"
|
||||
v-model="selectedProvider"
|
||||
cmsWidgetName="ServiceProviderQuestion"
|
||||
:questionText="questionText"
|
||||
:answers="answersFromCms"
|
||||
:questionText="serviceProviderQuestionText"
|
||||
:answers="serviceProviderQuestionAnswers"
|
||||
groupName="ServiceProviderQuestionOption"
|
||||
buttonTypeString="listButton"
|
||||
isRequired
|
||||
:validationRules="rules.selectionRequired">
|
||||
</buttonQuestion>
|
||||
<text-block
|
||||
v-if="displayQuote"
|
||||
v-if="isQuoteDisplayed"
|
||||
cmsWidgetName="DisclaimerWidget"
|
||||
typeStyle="caption" />
|
||||
</div>
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@backClicked="navigateBackByVehicleQuestions"
|
||||
@forwardClicked="forwardButtonAction" />
|
||||
@forwardClicked="navigateForward" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -126,11 +126,17 @@ import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin.js';
|
|||
import globalRules from '@/constants/global-rules.js';
|
||||
import baseFormMixin from '@/mixins/base-form-mixin.js';
|
||||
import navigationScenarios from '@/router/router-constants/navigation-scenarios.js';
|
||||
import routerParams from '@/router/router-constants/router-params';
|
||||
import issPageValues from '@/router/router-constants/issPage-values';
|
||||
import bailoutCode from '@/constants/bailoutCode';
|
||||
import bailoutMessage from '@/constants/bailoutMessage';
|
||||
import coverageStatuses from '@/constants/coverage-statuses';
|
||||
import widgetFields from '@/constants/cms-widget-fields.js';
|
||||
import getPriceOfLineItems from '@/helpers/price-calculator.js';
|
||||
|
||||
const SAFELITE_PROVIDER = 'Safelite';
|
||||
|
||||
function setBailout(currentRoute, message) {
|
||||
useMainStore().setBailout(currentRoute, message);
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'coverage-statement',
|
||||
|
|
@ -165,8 +171,8 @@ export default {
|
|||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
const clonedGlassParts = useMainStore().order.lineItems.glassParts
|
||||
? JSON.parse(JSON.stringify(useMainStore().order.lineItems.glassParts))
|
||||
const clonedGlassParts = useMainStore().lineItems.glassParts
|
||||
? JSON.parse(JSON.stringify(useMainStore().lineItems.glassParts))
|
||||
: [];
|
||||
const availableLineItems = [
|
||||
...(resultMap.supportingItems ?? []),
|
||||
|
|
@ -175,17 +181,14 @@ export default {
|
|||
|
||||
let hasBailedOut = false;
|
||||
let pricingResults = [];
|
||||
if (useMainStore().order.policy.policyLookupSuccessful && useMainStore().order.vehicle.policyVehicleId >= 0) {
|
||||
if (useMainStore().policy.policyLookupSuccessful && useMainStore().vehicle.policyVehicleId >= 0) {
|
||||
await useMainStore().getFinalDeductible();
|
||||
pricingResults = await useMainStore().getPriceOrderItems(availableLineItems)
|
||||
.catch((err) => {
|
||||
useMainStore().setBailout(
|
||||
to,
|
||||
bailoutMessage.pricingResponseError(
|
||||
availableLineItems.map((li) => li.partNumber),
|
||||
{ code: err.code, message: err.message, data: err.data }
|
||||
)
|
||||
);
|
||||
setBailout(to, bailoutMessage.pricingResponseError(
|
||||
availableLineItems.map((li) => li.partNumber),
|
||||
{ code: err.code, message: err.message, data: err.data }
|
||||
));
|
||||
hasBailedOut = true;
|
||||
next(`/?issPage=${issPageValues.BAILOUT_PAGE}`);
|
||||
});
|
||||
|
|
@ -197,22 +200,27 @@ export default {
|
|||
vm.setCmsContent(resultMap.cmsContent);
|
||||
vm.setSupportingItems(resultMap.supportingItems);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
vm.availableLineItems = pricingResults;
|
||||
vm.setBaseServiceLineItems(pricingResults);
|
||||
vm.$refs.loadingModal.showModal();
|
||||
vm.initializeComponent(availableLineItems);
|
||||
vm.initializeComponent();
|
||||
if (!vm.unverified) {
|
||||
useMainStore().disableKeyFields();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
const mainStore = useMainStore();
|
||||
return { mainStore };
|
||||
},
|
||||
data() {
|
||||
const { isRepair } = useMainStore().damage;
|
||||
const { policyLookupSuccessful, noCoverage } = useMainStore().policy;
|
||||
return {
|
||||
availableLineItems: [],
|
||||
currencyFormatter: new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD'
|
||||
}),
|
||||
isRepair,
|
||||
policyLookupSuccessful,
|
||||
isNoComp: noCoverage ?? false,
|
||||
baseServiceLineItems: [],
|
||||
selectedProvider: '',
|
||||
deductibleText: 'Your deductible is',
|
||||
// TODO update when design team gives appropriate text
|
||||
|
|
@ -224,83 +232,90 @@ export default {
|
|||
rules: {
|
||||
selectionRequired: globalRules.OPTION_REQUIRED
|
||||
},
|
||||
supportingItems: null
|
||||
supportingItems: null,
|
||||
widget: {
|
||||
subheader: 'SiteSubHeaderWidget',
|
||||
verifiedItacAlert: 'VerifiedITACAlert',
|
||||
explanatoryText: 'ExplanatoryTextWidget',
|
||||
nextStep: 'NextStepsWidget',
|
||||
serviceProviderQuestion: 'ServiceProviderQuestion'
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
verifiedITACAlertHeader() {
|
||||
return this.getCmsContent(
|
||||
'VerifiedITACAlert',
|
||||
'HeadlineText'
|
||||
coverageStatementSubHeader() {
|
||||
return this.getTextFromCmsWithCustomIfStatements(
|
||||
this.widget.subheader,
|
||||
widgetFields.SUB_HEADER_WIDGET.SUB_HEADER_TEXT
|
||||
);
|
||||
},
|
||||
verifiedITACAlertBody() {
|
||||
verifiedItacAlertHeader() {
|
||||
return this.getCmsContent(
|
||||
'VerifiedITACAlert',
|
||||
'BodyText'
|
||||
this.widget.verifiedItacAlert,
|
||||
widgetFields.ALERT_WIDGET.HEADLINE_TEXT
|
||||
);
|
||||
},
|
||||
verifiedItacAlertBody() {
|
||||
return this.getCmsContent(
|
||||
this.widget.verifiedItacAlert,
|
||||
widgetFields.ALERT_WIDGET.BODY_TEXT
|
||||
)?.replaceAll('{custom:costSavings}', this.costSavings);
|
||||
},
|
||||
coverageStatementSubHeader() {
|
||||
return this.getSubheaderTextFromCms('SiteSubHeaderWidget');
|
||||
},
|
||||
secondaryText() {
|
||||
return this.getSecondaryTextFromCms('SiteSubHeaderWidget');
|
||||
return this.getTextFromCmsWithCustomIfStatements(
|
||||
this.widget.subheader,
|
||||
widgetFields.CONTENT_GROUP_WIDGET.SECONDARY_TEXT
|
||||
);
|
||||
},
|
||||
explanatoryText() {
|
||||
return this.getExplantoryTextFromCms('ExplanatoryTextWidget');
|
||||
return this.getTextFromCmsWithCustomIfStatements(
|
||||
this.widget.explanatoryText,
|
||||
widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
|
||||
);
|
||||
},
|
||||
nextStepsHeader() {
|
||||
return this.getHeaderTextFromCms('NextStepsWidget');
|
||||
return this.getTextFromCmsWithCustomIfStatements(
|
||||
this.widget.nextStep,
|
||||
widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT
|
||||
);
|
||||
},
|
||||
nextStepsBody() {
|
||||
return this.getBodyTextFromCms('NextStepsWidget')?.replaceAll('{custom:damage}', this.damageText);
|
||||
},
|
||||
continueWithSchedulingBodyText() {
|
||||
return this.getCmsContent('continueWithSchedulingCopy', 'BodyText');
|
||||
},
|
||||
unverifiedADASNextStepsBodyText() {
|
||||
return this.getCmsContent('UnverifiedADASNextStepsWidget', 'BodyText')?.replaceAll('{custom:damage}', this.damageText);
|
||||
},
|
||||
unverifiedNonADASNextStepsBodyText() {
|
||||
return this.getCmsContent('UnverifiedNonADASNextStepsWidget', 'BodyText')?.replaceAll('{custom:damage}', this.damageText);
|
||||
},
|
||||
unverifiedNonADASRepairBodyText() {
|
||||
return this.getCmsContent('UnverifiedNonADASRepairWidget', 'BodyText');
|
||||
return this.getTextFromCmsWithCustomIfStatements(
|
||||
this.widget.nextStep,
|
||||
widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
|
||||
)?.replaceAll('{custom:damage}', this.damageText);
|
||||
},
|
||||
damageText() {
|
||||
const damageString = getDamageString();
|
||||
return damageString === 'match' ? '' : damageString;
|
||||
},
|
||||
vehicleDeductible() {
|
||||
deductibleValue() {
|
||||
return useMainStore().order.currentDeductible;
|
||||
},
|
||||
formattedDeductible() {
|
||||
return this.getDeductibleString(this.vehicleDeductible);
|
||||
},
|
||||
isDeductibleZero() {
|
||||
return this.vehicleDeductible === 0;
|
||||
},
|
||||
policyLookupSuccessful() {
|
||||
return useMainStore().order.policy.policyLookupSuccessful;
|
||||
deductibleForDisplay() {
|
||||
return this.getFormattedAmount(this.deductibleValue);
|
||||
},
|
||||
registerClaimSuccessful() {
|
||||
return useMainStore().payment.insuranceCoverage.isVerified;
|
||||
},
|
||||
verifiedNoComp() {
|
||||
return this.policyLookupSuccessful ? useMainStore().order.policy.noCoverage : false;
|
||||
return this.policyLookupSuccessful && this.isNoComp;
|
||||
},
|
||||
verifiedITAC() {
|
||||
return this.policyLookupSuccessful
|
||||
&& !this.verifiedNoComp
|
||||
&& this.vehicleDeductible > this.totalServicePrice;
|
||||
&& !this.isNoComp
|
||||
&& this.deductibleValue > this.totalServicePrice;
|
||||
},
|
||||
coveredAndServicePriceAboveOrEqualDeductible() {
|
||||
return !this.verifiedNoComp && this.totalServicePrice >= this.vehicleDeductible;
|
||||
return !this.verifiedNoComp && this.totalServicePrice >= this.deductibleValue;
|
||||
},
|
||||
verifiedDeductible() {
|
||||
return useMainStore().isClaimRegistrationRequired
|
||||
? this.registerClaimSuccessful && this.coveredAndServicePriceAboveOrEqualDeductible && this.vehicleDeductible !== null
|
||||
: this.policyLookupSuccessful && this.coveredAndServicePriceAboveOrEqualDeductible;
|
||||
? this.registerClaimSuccessful
|
||||
&& this.coveredAndServicePriceAboveOrEqualDeductible
|
||||
&& this.deductibleValue !== null
|
||||
: this.policyLookupSuccessful
|
||||
&& this.coveredAndServicePriceAboveOrEqualDeductible;
|
||||
},
|
||||
unverified() {
|
||||
return !this.verifiedDeductible && !this.verifiedITAC && !this.verifiedNoComp;
|
||||
|
|
@ -309,42 +324,46 @@ export default {
|
|||
const parts = useMainStore().order.lineItems.glassParts;
|
||||
return parts !== null && !!parts.find((part) => part.requiresRecalibration);
|
||||
},
|
||||
isRepair() {
|
||||
return useMainStore().order.damage.isRepair;
|
||||
},
|
||||
// TODO share
|
||||
totalServicePrice() {
|
||||
let total = 0;
|
||||
this.availableLineItems.forEach((lineItem) => {
|
||||
total += this.getTotalLineItemPrice(lineItem);
|
||||
});
|
||||
return total;
|
||||
return getPriceOfLineItems(this.baseServiceLineItems);
|
||||
},
|
||||
formattedServicePrice() {
|
||||
return this.getServicePriceString(this.totalServicePrice);
|
||||
servicePriceForDisplay() {
|
||||
return this.getFormattedAmount(this.totalServicePrice);
|
||||
},
|
||||
costSavings() {
|
||||
const savings = this.getITACCostSavings(this.vehicleDeductible, this.totalServicePrice);
|
||||
const formattedSavings = parseFloat(savings).toFixed(2);
|
||||
return `$${formattedSavings}`;
|
||||
itacCostSavings() {
|
||||
return this.deductibleValue - this.totalServicePrice;
|
||||
},
|
||||
questionText() {
|
||||
return this.getCmsContent('ServiceProviderQuestion', 'QuestionText');
|
||||
itacCostSavingsForDisplay() {
|
||||
return this.getFormattedAmount(this.itacCostSavings);
|
||||
},
|
||||
answersFromCms() {
|
||||
return this.getCmsContent('ServiceProviderQuestion', 'Answers');
|
||||
serviceProviderQuestionText() {
|
||||
return this.getCmsContent(
|
||||
this.widget.serviceProviderQuestion,
|
||||
widgetFields.INPUT_QUESTION_WIDGET.QUESTION_TEXT
|
||||
);
|
||||
},
|
||||
displayQuote() {
|
||||
serviceProviderQuestionAnswers() {
|
||||
return this.getCmsContent(
|
||||
this.widget.serviceProviderQuestion,
|
||||
widgetFields.INPUT_QUESTION_WIDGET.ANSWERS
|
||||
);
|
||||
},
|
||||
isQuoteDisplayed() {
|
||||
return this.verifiedITAC || this.verifiedNoComp;
|
||||
},
|
||||
shouldRegisterClaim() {
|
||||
return this.policyLookupSuccessful
|
||||
&& useMainStore().vehicle.policyVehicleId != null
|
||||
&& useMainStore().vehicle.policyVehicleId >= 0
|
||||
&& useMainStore().isClaimRegistrationRequired
|
||||
&& !useMainStore().isClaimAlreadyRegistered
|
||||
&& (this.coveredAndServicePriceAboveOrEqualDeductible || this.verifiedITAC);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selectedProvider() {
|
||||
if (this.selectedProvider === 'Safelite') {
|
||||
this.$refs.siteFooter.updateButtonText('Continue with Safelite');
|
||||
} else {
|
||||
this.$refs.siteFooter.updateButtonText('Continue');
|
||||
}
|
||||
const buttonText = this.selectedProvider === SAFELITE_PROVIDER ? 'Continue with Safelite' : 'Safelite';
|
||||
this.$refs.siteFooter.updateButtonText(buttonText);
|
||||
},
|
||||
nextStepsBody(newValue, oldValue) {
|
||||
if (newValue !== oldValue) {
|
||||
|
|
@ -360,82 +379,47 @@ export default {
|
|||
arePagePrerequisitesValid() {
|
||||
return !!useMainStore().vehicle.carId;
|
||||
},
|
||||
getFormattedAmount(amount) {
|
||||
return this.currencyFormatter.format(amount);
|
||||
},
|
||||
async initializeComponent() {
|
||||
useMainStore().updatePolicyITACFlag(this.verifiedITAC);
|
||||
const coverageStatus = this.verifiedITAC || this.verifiedNoComp
|
||||
? coverageStatuses.VERIFIED
|
||||
: coverageStatuses.PENDING;
|
||||
useMainStore().updateCoverageStatus(coverageStatus);
|
||||
if (this.policyLookupSuccessful
|
||||
&& useMainStore().order.vehicle.policyVehicleId >= 0
|
||||
&& useMainStore().isClaimRegistrationRequired
|
||||
&& !useMainStore().isClaimAlreadyRegistered
|
||||
&& (this.coveredAndServicePriceAboveOrEqualDeductible || this.verifiedITAC)) {
|
||||
if (this.shouldRegisterClaim) {
|
||||
await useMainStore().registerClaim()?.catch(() => {});
|
||||
}
|
||||
this.$refs.loadingModal.hideModal();
|
||||
},
|
||||
async forwardButtonAction() {
|
||||
return this.navigateForward();
|
||||
},
|
||||
async navigateForward() {
|
||||
if (this.unverified || this.verifiedDeductible) {
|
||||
this.mainStore.saveSupportingItems(this.supportingItems);
|
||||
this.$router.navigate(
|
||||
navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route,
|
||||
{},
|
||||
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true }
|
||||
);
|
||||
useMainStore().updateSupportingItems(this.supportingItems);
|
||||
this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD);
|
||||
} else if (this.verifiedITAC || this.verifiedNoComp) {
|
||||
useMainStore().updateIsSafeliteProvider(this.selectedProvider === 'Safelite');
|
||||
if (this.selectedProvider === 'Safelite') {
|
||||
this.mainStore.saveSupportingItems(this.supportingItems);
|
||||
this.$router.navigate(
|
||||
navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE,
|
||||
this.$route,
|
||||
{},
|
||||
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true }
|
||||
);
|
||||
useMainStore().updateIsSafeliteProvider(this.selectedProvider === SAFELITE_PROVIDER);
|
||||
if (this.selectedProvider === SAFELITE_PROVIDER) {
|
||||
useMainStore().updateSupportingItems(this.supportingItems);
|
||||
this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE);
|
||||
} else {
|
||||
this.mainStore.setBailout(this.$router.currentRoute, bailoutMessage.RequestCallback());
|
||||
this.$router.navigate(
|
||||
navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP,
|
||||
this.$route,
|
||||
{},
|
||||
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true }
|
||||
);
|
||||
this.setBailoutWithMessage(bailoutMessage.RequestCallback());
|
||||
this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP);
|
||||
}
|
||||
} else {
|
||||
this.mainStore.setBailout(this.$router.currentRoute, bailoutMessage.coverageStatementInvalidState());
|
||||
this.$router.navigate(
|
||||
navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE,
|
||||
this.$route,
|
||||
{},
|
||||
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true }
|
||||
);
|
||||
this.setBailoutWithMessage(bailoutMessage.coverageStatementInvalidState());
|
||||
this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE);
|
||||
}
|
||||
},
|
||||
processIfStatements,
|
||||
getHeaderTextFromCms(cmsWidgetName) {
|
||||
const header = this.getCmsContent(cmsWidgetName, 'HeaderText');
|
||||
return this.processIfStatements(header, 'custom', this.getCustomValueFromString);
|
||||
setBailoutWithMessage(message) {
|
||||
setBailout(this.$router.currentRoute, message);
|
||||
},
|
||||
getSubheaderTextFromCms(cmsWidgetName) {
|
||||
const subHeader = this.getCmsContent(cmsWidgetName, 'SubHeaderText');
|
||||
return this.processIfStatements(subHeader, 'custom', this.getCustomValueFromString);
|
||||
navigateWithScenario(scenario) {
|
||||
this.$router.navigate(scenario, this.$route);
|
||||
},
|
||||
getBodyTextFromCms(cmsWidgetName) {
|
||||
const bodyText = this.getCmsContent(cmsWidgetName, 'BodyText');
|
||||
return this.processIfStatements(bodyText, 'custom', this.getCustomValueFromString);
|
||||
},
|
||||
getSecondaryTextFromCms(cmsWidgetName) {
|
||||
const secondaryText = this.getCmsContent(cmsWidgetName, 'SecondaryText');
|
||||
return this.processIfStatements(secondaryText, 'custom', this.getCustomValueFromString);
|
||||
},
|
||||
getExplantoryTextFromCms(cmsWidgetName) {
|
||||
const explanatoryText = this.getCmsContent(cmsWidgetName, 'BodyText');
|
||||
return this.processIfStatements(explanatoryText, 'custom', this.getCustomValueFromString);
|
||||
getTextFromCmsWithCustomIfStatements(widgetName, widgetField) {
|
||||
const rawText = this.getCmsContent(widgetName, widgetField);
|
||||
return processIfStatements(rawText, 'custom', this.getCustomValueFromString);
|
||||
},
|
||||
getCustomValueFromString(str) {
|
||||
switch (str) {
|
||||
|
|
@ -454,29 +438,18 @@ export default {
|
|||
case 'nonADASRepair':
|
||||
return this.isRepair;
|
||||
case 'deductibleOverZero':
|
||||
return this.verifiedDeductible && !this.isDeductibleZero; // TODO what if deductible is negative?
|
||||
return this.verifiedDeductible && this.deductibleValue !== 0; // TODO what if deductible is negative?
|
||||
case 'isDeductibleZero':
|
||||
return this.verifiedDeductible && this.isDeductibleZero;
|
||||
return this.verifiedDeductible && this.deductibleValue === 0;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
getTotalLineItemPrice(lineItem) {
|
||||
return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice;
|
||||
},
|
||||
getDeductibleString(deductible) {
|
||||
const formattedDeductibleFloat = parseFloat(deductible).toFixed(2);
|
||||
return `$${formattedDeductibleFloat}`;
|
||||
},
|
||||
getServicePriceString(price) {
|
||||
const formattedPriceFloat = parseFloat(price).toFixed(2);
|
||||
return `$${formattedPriceFloat}`;
|
||||
},
|
||||
getITACCostSavings(vehicleDeductible, totalServicePrice) {
|
||||
return vehicleDeductible - totalServicePrice;
|
||||
},
|
||||
setSupportingItems(newSupportingItems) {
|
||||
this.supportingItems = newSupportingItems;
|
||||
},
|
||||
setBaseServiceLineItems(lineItems) {
|
||||
this.baseServiceLineItems = lineItems;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -486,7 +459,7 @@ export default {
|
|||
.cost {
|
||||
color: $green;
|
||||
font-size: 2rem;
|
||||
font-weight: 300;
|
||||
font-weight: $font-weight-light;
|
||||
line-height: 2.75rem;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ import { createTestingPinia } from '@pinia/testing';
|
|||
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
|
||||
|
||||
jest.mock('@/helpers/cms-content-helper', () => ({
|
||||
fetchCmsContentForPage: jest.fn()
|
||||
fetchCmsContentForPage: jest.fn(),
|
||||
processIfStatements: jest.fn()
|
||||
}));
|
||||
const wordingText = 'wording Text {custom:address}';
|
||||
|
||||
|
|
@ -34,12 +35,18 @@ const headerStub = {
|
|||
render: () => {}
|
||||
};
|
||||
|
||||
const vehicleBannerStub = {
|
||||
render: () => {}
|
||||
};
|
||||
|
||||
const initialStore = {
|
||||
order: {
|
||||
schedule: {
|
||||
date: '2024-03-01',
|
||||
startTime: '09:00',
|
||||
endTime: '10:00'
|
||||
endTime: '10:00',
|
||||
jobMinMinutes: 60,
|
||||
jobMaxMinutes: 90
|
||||
},
|
||||
serviceLocation: {
|
||||
address: '123 Test Way',
|
||||
|
|
@ -70,7 +77,8 @@ function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRu
|
|||
|
||||
mountOptions.global.stubs = {
|
||||
siteFooter: footerStub,
|
||||
siteHeader: headerStub
|
||||
siteHeader: headerStub,
|
||||
vehicleBanner: vehicleBannerStub
|
||||
};
|
||||
|
||||
const testingPinia = createTestingPinia({
|
||||
|
|
@ -110,6 +118,16 @@ describe('OrderConfirmation.vue', () => {
|
|||
// Assert
|
||||
expect(siteHeader.exists()).toBe(true);
|
||||
});
|
||||
test('Should render Vehicle Banner', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getMountedComponent(initialStore);
|
||||
|
||||
// Act
|
||||
const vehicleBanner = wrapper.findComponent(vehicleBannerStub);
|
||||
|
||||
// Assert
|
||||
expect(vehicleBanner.exists()).toBe(true);
|
||||
});
|
||||
test('If Advanced flow, should display Site Footer', () => {
|
||||
// Arrange
|
||||
const testStore = {
|
||||
|
|
@ -215,7 +233,7 @@ describe('OrderConfirmation.vue', () => {
|
|||
endTime: '10:00'
|
||||
},
|
||||
serviceLocation: {
|
||||
appointmentType: 'Drop Off'
|
||||
appointmentType: 'Dropoff'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -282,7 +300,7 @@ describe('OrderConfirmation.vue', () => {
|
|||
zipCode: '12345'
|
||||
}
|
||||
},
|
||||
appointmentType: 'Drop Off'
|
||||
appointmentType: 'Dropoff'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -324,5 +342,74 @@ describe('OrderConfirmation.vue', () => {
|
|||
// Assert
|
||||
expect(testValue).toEqual('<br/>123 Safelite Street,<br/> Mesa, AZ 12345<br/>');
|
||||
});
|
||||
test('appointmentWordingText2 should return Mobile text in expected format', () => {
|
||||
// Arrange
|
||||
const testStore = {
|
||||
order: {
|
||||
schedule: {
|
||||
date: '2019-01-01',
|
||||
startTime: '09:00',
|
||||
endTime: '10:00'
|
||||
},
|
||||
serviceLocation: {
|
||||
address: '123 Test Way',
|
||||
address2: '#1',
|
||||
city: 'Mesa',
|
||||
state: 'AZ',
|
||||
zipCode: '12345',
|
||||
appointmentType: 'Mobile'
|
||||
}
|
||||
}
|
||||
};
|
||||
const { wrapper } = getMountedComponent(testStore);
|
||||
|
||||
// Act
|
||||
const testValue = wrapper.vm.appointmentWordingText2;
|
||||
|
||||
// Assert
|
||||
expect(testValue).toEqual(wordingText);
|
||||
});
|
||||
test('appointmentWordingText2 should return Drop Off and text in expected format', () => {
|
||||
// Arrange
|
||||
const testStore = {
|
||||
order: {
|
||||
schedule: {
|
||||
date: '2019-01-01',
|
||||
startTime: '09:00',
|
||||
endTime: '10:00'
|
||||
},
|
||||
serviceLocation: {
|
||||
provider: {
|
||||
address: {
|
||||
streetAddress: '123 Safelite Street',
|
||||
city: 'Mesa',
|
||||
state: 'AZ',
|
||||
zipCode: '12345'
|
||||
}
|
||||
},
|
||||
appointmentType: 'Dropoff'
|
||||
}
|
||||
}
|
||||
};
|
||||
const { wrapper } = getMountedComponent(testStore);
|
||||
|
||||
// Act
|
||||
const testValue = wrapper.vm.appointmentWordingText2;
|
||||
const expected = wrapper.vm.getBodyText2FromCms('Test Widget');
|
||||
|
||||
// Assert
|
||||
expect(testValue).toEqual(expected);
|
||||
});
|
||||
test('appointmentWordingText2 should return In Shop text in expected format', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getMountedComponent(initialStore);
|
||||
|
||||
// Act
|
||||
const testValue = wrapper.vm.appointmentWordingText2;
|
||||
const expected = wrapper.vm.getBodyText2FromCms('Test Widget');
|
||||
|
||||
// Assert
|
||||
expect(testValue).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,9 +26,13 @@
|
|||
<p>{{ appointmentTimeFormatted }}</p>
|
||||
</div>
|
||||
<div
|
||||
class="appointment-text text-center text-color--black lh-base"
|
||||
class="appointment-text text-center lh-base"
|
||||
v-html="appointmentWordingText">
|
||||
</div>
|
||||
<div
|
||||
class="appointment-text text-center lh-base mt-2"
|
||||
v-html="appointmentWordingText2">
|
||||
</div>
|
||||
</div>
|
||||
<siteFooter
|
||||
v-if="carrierUrl"
|
||||
|
|
@ -49,13 +53,15 @@ import siteHeader from '@/iss-components/site-header/site-header.vue';
|
|||
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
|
||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||
// Supporting files
|
||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||
import { fetchCmsContentForPage, processIfStatements } from '@/helpers/cms-content-helper';
|
||||
import settleAllPromises from '@/helpers/layout-helper';
|
||||
import { Form } from 'vee-validate';
|
||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||
import { useMainStore } from '@/store';
|
||||
import { get12HourTimeFormat, get12HourTimeMobileFormat, convertDateStringToDate } from '@/helpers/date-helper.js';
|
||||
import { get12HourTimeFormat, get12HourTimeMobileFormat, convertDateStringToDate,
|
||||
getDisplayTextForDurationLength } from '@/helpers/date-helper.js';
|
||||
import { toTitleCase } from '@/helpers/text-helper.js';
|
||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||
|
||||
export default {
|
||||
name: 'order-confirmation',
|
||||
|
|
@ -100,7 +106,7 @@ export default {
|
|||
return this.getCmsContent('OrderConfirmationContent', 'Image');
|
||||
},
|
||||
appointmentType() {
|
||||
return this.mainStore.order.serviceLocation.appointmentType.toUpperCase();
|
||||
return this.mainStore.order.serviceLocation.appointmentType;
|
||||
},
|
||||
appointmentDate() {
|
||||
return this.mainStore.order.schedule.date;
|
||||
|
|
@ -128,9 +134,15 @@ export default {
|
|||
mobileWordingText() {
|
||||
return this.getCmsContent('MobileWordingWidget', 'BodyText');
|
||||
},
|
||||
mobileWordingText2() {
|
||||
return this.getCmsContent('MobileWordingWidget', 'BodyText2');
|
||||
},
|
||||
dropOffAndInShopWordingText() {
|
||||
return this.getCmsContent('DropOffAndInShopWordingWidget', 'BodyText');
|
||||
},
|
||||
dropOffAndInShopWordingText2() {
|
||||
return this.getBodyText2FromCms('DropOffAndInShopWordingWidget');
|
||||
},
|
||||
serviceLocationAddress() {
|
||||
return this.mainStore.order.serviceLocation.address;
|
||||
},
|
||||
|
|
@ -167,7 +179,58 @@ export default {
|
|||
return `<br/>${this.providerAddress},<br/> ${this.providerCity}, ${this.providerState} ${this.providerZipCode}<br/>`;
|
||||
},
|
||||
appointmentWordingText() {
|
||||
return this.formatWordingText(this.appointmentType);
|
||||
switch (this.appointmentType) {
|
||||
case AppointmentTypeStrings.MOBILE:
|
||||
case AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP:
|
||||
return this.mobileWordingText?.replaceAll(
|
||||
'{custom:address}',
|
||||
this.serviceLocationFullAddress
|
||||
);
|
||||
case AppointmentTypeStrings.DROP_OFF:
|
||||
return this.dropOffAndInShopWordingText?.replaceAll(
|
||||
'{custom:address}',
|
||||
this.providerFullAddress
|
||||
);
|
||||
case AppointmentTypeStrings.IN_SHOP:
|
||||
return this.dropOffAndInShopWordingText?.replaceAll(
|
||||
'{custom:address}',
|
||||
this.providerFullAddress
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
appointmentWordingText2() {
|
||||
switch (this.appointmentType) {
|
||||
case AppointmentTypeStrings.MOBILE:
|
||||
case AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP:
|
||||
return this.mobileWordingText2;
|
||||
case AppointmentTypeStrings.DROP_OFF:
|
||||
return this.dropOffAndInShopWordingText2;
|
||||
case AppointmentTypeStrings.IN_SHOP:
|
||||
return this.dropOffAndInShopWordingText2?.replaceAll(
|
||||
'{custom:inShopDuration}',
|
||||
this.inShopAppointmentDuration
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
mobileAppointment() {
|
||||
return this.mainStore.isMobileAppointment;
|
||||
},
|
||||
inShopAppointment() {
|
||||
return this.mainStore.isInShopAppointment;
|
||||
},
|
||||
dropOffAppointment() {
|
||||
return this.mainStore.isDropOffAppointment;
|
||||
},
|
||||
inShopAppointmentDuration() {
|
||||
const inshopDurationTime = getDisplayTextForDurationLength(
|
||||
this.mainStore.order.schedule.jobMinMinutes,
|
||||
this.mainStore.order.schedule.jobMaxMinutes
|
||||
);
|
||||
return inshopDurationTime;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -181,34 +244,29 @@ export default {
|
|||
},
|
||||
formatAppointmentTime(appointmentType) {
|
||||
switch (appointmentType) {
|
||||
case 'MOBILE':
|
||||
case AppointmentTypeStrings.MOBILE:
|
||||
case AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP:
|
||||
// eslint-disable-next-line max-len
|
||||
return `Between ${get12HourTimeMobileFormat(this.appointmentStartTime)} - ${get12HourTimeMobileFormat(this.appointmentEndTime)}`;
|
||||
case 'DROP OFF':
|
||||
case AppointmentTypeStrings.DROP_OFF:
|
||||
return 'Drop off before 9:30 AM';
|
||||
case 'INSHOP':
|
||||
case AppointmentTypeStrings.IN_SHOP:
|
||||
return `at ${get12HourTimeFormat(this.appointmentStartTime)}`;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
formatWordingText(appointmentType) {
|
||||
switch (appointmentType) {
|
||||
case 'MOBILE':
|
||||
return this.mobileWordingText?.replaceAll(
|
||||
'{custom:address}',
|
||||
this.serviceLocationFullAddress
|
||||
);
|
||||
case 'DROP OFF':
|
||||
return this.dropOffAndInShopWordingText?.replaceAll(
|
||||
'{custom:address}',
|
||||
this.providerFullAddress
|
||||
);
|
||||
case 'INSHOP':
|
||||
return this.dropOffAndInShopWordingText?.replaceAll(
|
||||
'{custom:address}',
|
||||
this.providerFullAddress
|
||||
);
|
||||
processIfStatements,
|
||||
getBodyText2FromCms(cmsWidgetName) {
|
||||
const body2Text = this.getCmsContent(cmsWidgetName, 'BodyText2');
|
||||
return this.processIfStatements(body2Text, 'custom', this.getCustomValueFromString);
|
||||
},
|
||||
getCustomValueFromString(str) {
|
||||
switch (str) {
|
||||
case 'inShopAppointment':
|
||||
return this.inShopAppointment;
|
||||
case 'dropOffAppointment':
|
||||
return this.dropOffAppointment;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
@ -254,6 +312,7 @@ $page-side-padding: 1.5rem;
|
|||
.appointment-text {
|
||||
:deep(strong) {
|
||||
font-weight: $font-weight-bold;
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -197,7 +197,8 @@ export default {
|
|||
&& providerLocation.zipCode
|
||||
);
|
||||
|
||||
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
|
||||
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
||||
const serviceLocationReqs =
|
||||
(isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
143
src/layouts/payment-return/payment-return.vue
Normal file
143
src/layouts/payment-return/payment-return.vue
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<Form
|
||||
ref="theForm"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Form } from 'vee-validate';
|
||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||
import { useMainStore } from '@/store/index.js';
|
||||
import queryStrings from '@/constants/query-strings';
|
||||
import getQueryStringParameter from '@/helpers/querystring-helper.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 {
|
||||
name: 'payment-return',
|
||||
components: {
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Form
|
||||
},
|
||||
mixins: [BaseFormMixin],
|
||||
computed: {
|
||||
creditCardToken() {
|
||||
return {
|
||||
subscriptionId: getQueryStringParameter(queryStrings.SUBSCRIPTIONID),
|
||||
expMonth: getQueryStringParameter(queryStrings.CARD_EXPIRATION_MONTH),
|
||||
expYear: getQueryStringParameter(queryStrings.CARD_EXPIRATION_YEAR),
|
||||
cardType: getQueryStringParameter(queryStrings.CARD_TYPE),
|
||||
billToPostalCode: getQueryStringParameter(queryStrings.BILL_TO_POSTAL_CODE),
|
||||
billToFirstName: getQueryStringParameter(queryStrings.BILL_TO_FIRST_NAME),
|
||||
billToLastName: getQueryStringParameter(queryStrings.BILL_TO_LAST_NAME),
|
||||
referenceNumber: getQueryStringParameter(queryStrings.REFERENCE_NUMBER),
|
||||
authCode: getQueryStringParameter(queryStrings.AUTH_CODE),
|
||||
transactionId: getQueryStringParameter(queryStrings.TRANSACTION_ID),
|
||||
transReferenceNumber: getQueryStringParameter(queryStrings.TRANS_REFERENCE_NUMBER),
|
||||
lastFour: getQueryStringParameter(queryStrings.LAST_FOUR)
|
||||
};
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
showIssLoadingModal(true);
|
||||
const payInAdvanceError = getQueryStringParameter(queryStrings.ERROR);
|
||||
const { payInAdvanceType } = useMainStore().order.payment;
|
||||
|
||||
if (payInAdvanceError) {
|
||||
console.error(`Error during payment: ${payInAdvanceError}`);
|
||||
const paymentPageNavScenario =
|
||||
payInAdvanceType === paymentMethods.CREDIT_CARD || payInAdvanceType === paymentMethods.AFTERPAY;
|
||||
if (paymentPageNavScenario) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.PAY_IN_ADVANCE_CREDIT_CARD_ERROR,
|
||||
this.$route,
|
||||
{
|
||||
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: payInAdvanceType
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.PAY_IN_ADVANCE_ERROR,
|
||||
this.$route,
|
||||
{
|
||||
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
switch (payInAdvanceType) {
|
||||
case paymentMethods.CREDIT_CARD:
|
||||
case paymentMethods.AFTERPAY:
|
||||
await this.processCreditCardResponse();
|
||||
break;
|
||||
case paymentMethods.PAYPAL:
|
||||
break;
|
||||
default:
|
||||
console.log(`Unknown pay in advance type: ${payInAdvanceType}`);
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.PAY_IN_ADVANCE_ERROR,
|
||||
this.$route,
|
||||
{
|
||||
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
return true;
|
||||
},
|
||||
navigateOnPayInAdvanceError() {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.PAY_IN_ADVANCE_ERROR,
|
||||
this.$route,
|
||||
{
|
||||
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
|
||||
}
|
||||
);
|
||||
},
|
||||
async processPaypalResponse() {
|
||||
const token = getQueryStringParameter(queryStrings.TOKEN);
|
||||
this.mainStore.updatePaypalToken(token);
|
||||
|
||||
await this.saveAndSubmitWorkOrder();
|
||||
},
|
||||
async processCreditCardResponse() {
|
||||
const referralSeqNum = getQueryStringParameter(queryStrings.REFERRAL_SEQ_NUM);
|
||||
if (referralSeqNum !== useMainStore().order.referralSequenceNumber) {
|
||||
console.error(`error: unknown ref:${referralSeqNum} ${useMainStore().order.referralSequenceNumber}`);
|
||||
this.navigateOnPayInAdvanceError();
|
||||
} else {
|
||||
useMainStore().updateCreditCardToken(this.creditCardToken);
|
||||
await this.saveAndSubmitWorkOrder();
|
||||
}
|
||||
},
|
||||
async saveAndSubmitWorkOrder() {
|
||||
// Final work order submit after returning from pay in advance.
|
||||
useMainStore().resetSubmittedOrder();
|
||||
try {
|
||||
await submitWorkOrder({
|
||||
pageNameToLog: 'payment-return',
|
||||
submitAfterSave: true
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`error: response from submit work order:${error.message}`);
|
||||
this.navigateOnPayInAdvanceError();
|
||||
showIssLoadingModal(false);
|
||||
return;
|
||||
}
|
||||
|
||||
showIssLoadingModal(false);
|
||||
useMainStore().createSubmittedOrder();
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.PAY_IN_ADVANCE_SUCCESS,
|
||||
this.$route
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -75,8 +75,6 @@ function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
|||
}
|
||||
});
|
||||
|
||||
// mountOptions.global.mocks["$store"] = store;
|
||||
|
||||
mountOptions.global.stubs = {
|
||||
siteFooter: footerStub,
|
||||
loadingModal: loadingModalStub
|
||||
|
|
@ -337,81 +335,4 @@ describe('schedule-page.vue', () => {
|
|||
// Assert
|
||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
||||
});
|
||||
test('for mobile appts, updateSupportingItems should call store action to save supporting items', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE;
|
||||
wrapper.vm.mobilePremiumAppointmentFee = 14.99;
|
||||
wrapper.vm.selectedTimeSlotInfo.isPremiumAppointment = true;
|
||||
wrapper.vm.mainStore.lineItems.supportingItems = [
|
||||
{
|
||||
partNumber: 'EARLY BIRD',
|
||||
description: null,
|
||||
partType: 'EARLY BIRD',
|
||||
laborAmount: 0,
|
||||
sellingPrice: 0,
|
||||
kitPrice: 0
|
||||
}
|
||||
];
|
||||
const store = useMainStore();
|
||||
|
||||
// Act
|
||||
await wrapper.vm.updateSupportingItems();
|
||||
|
||||
// Assert
|
||||
expect(store.saveSupportingItemsSuppressingStateResetting).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.vm.mainStore.lineItems.supportingItems)
|
||||
.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
partType: 'EARLY BIRD'
|
||||
})
|
||||
]));
|
||||
});
|
||||
test(
|
||||
'for Inshop appts, updateSupportingItems should call store action to save supporting items WITHOUT the EARLY BIRD supporting item',
|
||||
async () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.serviceLocation.appointmentType = AppointmentTypeStrings.IN_SHOP;
|
||||
wrapper.vm.mobilePremiumAppointmentFee = 14.99;
|
||||
wrapper.vm.selectedTimeSlotInfo.isPremiumAppointment = true;
|
||||
wrapper.vm.mainStore.lineItems.supportingItems = [
|
||||
{
|
||||
partNumber: 'EARLY BIRD',
|
||||
description: null,
|
||||
partType: 'EARLY BIRD',
|
||||
laborAmount: 0,
|
||||
sellingPrice: 0,
|
||||
kitPrice: 0
|
||||
}
|
||||
];
|
||||
const store = useMainStore();
|
||||
|
||||
// Act
|
||||
await wrapper.vm.updateSupportingItems();
|
||||
|
||||
// Assert
|
||||
expect(store.saveSupportingItemsSuppressingStateResetting).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.vm.mainStore.lineItems.supportingItems)
|
||||
.not.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
partType: 'EARLY BIRD'
|
||||
})
|
||||
]));
|
||||
}
|
||||
);
|
||||
test('if no EARLY BIRD supporting item, then updateSupportingItems should NOT call store action', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE;
|
||||
wrapper.vm.mobilePremiumAppointmentFee = 14.99;
|
||||
wrapper.vm.selectedTimeSlotInfo.isPremiumAppointment = false;
|
||||
wrapper.vm.mainStore.lineItems.supportingItems = [];
|
||||
const store = useMainStore();
|
||||
// Act
|
||||
await wrapper.vm.updateSupportingItems();
|
||||
|
||||
// Assert
|
||||
expect(store.saveSupportingItemsSuppressingStateResetting).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -291,6 +291,9 @@ export default {
|
|||
}
|
||||
|
||||
return this.selectableDatesData.days?.find((selectableDate) => selectableDate.date === this.selectedDate);
|
||||
},
|
||||
supportingItems() {
|
||||
return useMainStore().lineItems.supportingItems;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -324,7 +327,7 @@ export default {
|
|||
&& ((serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP)
|
||||
|| serviceLocation.provider.providerNumber);
|
||||
const supportingItems = useMainStore().lineItems.supportingItems !== null;
|
||||
const supportingItems = this.supportingItems !== null;
|
||||
const damageInfo =
|
||||
useMainStore().order.damage.isRepair
|
||||
|| (useMainStore().order.lineItems?.glassParts != null
|
||||
|
|
@ -360,9 +363,8 @@ export default {
|
|||
return this.mainStore.order.schedule.date;
|
||||
},
|
||||
getSelectedTimeSlotInfo() {
|
||||
const supportingItems = this.getSupportingItems();
|
||||
const isPremiumAppointment =
|
||||
!!supportingItems.filter((lineItem) => lineItem.partType === PREMIUM_FEE_PART_TYPE)
|
||||
!!(this.supportingItems?.filter((lineItem) => lineItem.partType === PREMIUM_FEE_PART_TYPE) ?? [])
|
||||
.length > 0;
|
||||
|
||||
const selectedTimeSlotInfo = {
|
||||
|
|
@ -372,9 +374,6 @@ export default {
|
|||
|
||||
return selectedTimeSlotInfo;
|
||||
},
|
||||
getSupportingItems() {
|
||||
return this.mainStore.lineItems.supportingItems;
|
||||
},
|
||||
timeSlotModalClosed() {
|
||||
// Clear the selectedDate if no timeSlot has been selected
|
||||
if (this.selectedTimeSlotInfo.timeSlot.routeCode == null) {
|
||||
|
|
@ -424,40 +423,7 @@ export default {
|
|||
}
|
||||
return `${hours}:${minutes} ${meridianNotation}`;
|
||||
},
|
||||
updateSupportingItems() {
|
||||
const supportingItems = this.getSupportingItems();
|
||||
|
||||
// if we have a premium fee(early bird), then save/update supporting items
|
||||
if (
|
||||
this.appointmentType === AppointmentTypeStrings.MOBILE
|
||||
&& this.selectedTimeSlotInfo?.isPremiumAppointment
|
||||
) {
|
||||
const premiumFeeIndex = supportingItems.findIndex((item) => item.partType === PREMIUM_FEE_PART_TYPE);
|
||||
|
||||
if (premiumFeeIndex >= 0) {
|
||||
supportingItems[premiumFeeIndex].laborAmount =
|
||||
this.mobilePremiumAppointmentFee.laborAmount;
|
||||
supportingItems[premiumFeeIndex].sellingPrice =
|
||||
this.mobilePremiumAppointmentFee.sellingPrice;
|
||||
supportingItems[premiumFeeIndex].kitPrice =
|
||||
this.mobilePremiumAppointmentFee.kitPrice;
|
||||
} else {
|
||||
supportingItems.push(this.mobilePremiumAppointmentFee);
|
||||
}
|
||||
|
||||
this.mainStore.saveSupportingItemsSuppressingStateResetting(supportingItems);
|
||||
} else {
|
||||
// if it's not a mobile and/or premium early bird, then make sure we remove any that may have been added
|
||||
const removePremiumFeeIndex = supportingItems.findIndex((item) => item.partType === PREMIUM_FEE_PART_TYPE);
|
||||
|
||||
if (removePremiumFeeIndex >= 0) {
|
||||
supportingItems.splice(removePremiumFeeIndex, 1);
|
||||
this.mainStore.saveSupportingItemsSuppressingStateResetting(supportingItems);
|
||||
}
|
||||
}
|
||||
},
|
||||
forwardButtonAction() {
|
||||
this.updateSupportingItems();
|
||||
this.mainStore.saveSchedule(this.selectedTimeSlotInfo.timeSlot);
|
||||
|
||||
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||
|
|
|
|||
|
|
@ -124,7 +124,13 @@ export default {
|
|||
let hasBailedOut = false;
|
||||
const pricingResults = await store.getPriceOrderItems(availableLineItems)
|
||||
.catch((err) => {
|
||||
useMainStore().setBailout(to, bailoutMessage.pricingResponseError(availableLineItems.map((li) => li.partNumber), { code: err.code, message: err.message, data: err.data }));
|
||||
useMainStore().setBailout(
|
||||
to,
|
||||
bailoutMessage.pricingResponseError(
|
||||
availableLineItems.map((li) => li.partNumber),
|
||||
{ code: err.code, message: err.message, data: err.data }
|
||||
)
|
||||
);
|
||||
hasBailedOut = true;
|
||||
next(`/?issPage=${issPageValues.BAILOUT_PAGE}`);
|
||||
});
|
||||
|
|
@ -179,15 +185,19 @@ export default {
|
|||
this.selectedVaps = vapsItemsSelected;
|
||||
},
|
||||
forwardButtonAction() {
|
||||
const parts = { glassParts: this.pricedGlassParts, supportingItems: this.supportingItems, vaps: this.selectedVaps };
|
||||
const parts = {
|
||||
glassParts: this.pricedGlassParts,
|
||||
supportingItems: this.supportingItems,
|
||||
vaps: this.selectedVaps
|
||||
};
|
||||
if (!allGlassPartsAndItemsHavePrices(parts)) {
|
||||
window.console.error('One or more items have no price assigned!');
|
||||
}
|
||||
if (this.pricedGlassParts.length > 0) {
|
||||
store.saveGlassParts(this.pricedGlassParts);
|
||||
store.updateGlassParts(this.pricedGlassParts);
|
||||
}
|
||||
store.saveSupportingItems(this.supportingItems);
|
||||
store.saveVaps(this.selectedVaps);
|
||||
store.updateSupportingItems(this.supportingItems);
|
||||
store.updateVaps(this.selectedVaps);
|
||||
|
||||
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ export default {
|
|||
|
||||
if (this.isWindshieldRepair) {
|
||||
const supportingItems = await useMainStore().getSupportingItems();
|
||||
this.mainStore.saveSupportingItems(supportingItems.data);
|
||||
useMainStore().updateSupportingItems(supportingItems.data);
|
||||
}
|
||||
|
||||
if (this.mainStore.damage.isRepair) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ import applicationConfig from '@/constants/application-config';
|
|||
import issPageValues from '@/router/router-constants/issPage-values';
|
||||
import damageLocationsSelected from '@/constants/damage-locations-selected';
|
||||
import coverageStatuses from '@/constants/coverage-statuses';
|
||||
import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from '@/constants/schedule-constants';
|
||||
import { AppointmentTypeStrings } 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,
|
||||
|
|
@ -237,6 +253,7 @@ export const useMainStore = defineStore({
|
|||
isMobileAppointment: (state) => state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP,
|
||||
isDropOffAppointment: (state) => state.order.serviceLocation.appointmentType === AppointmentTypeStrings.DROP_OFF,
|
||||
isInShopAppointment: (state) => state.order.serviceLocation.appointmentType === AppointmentTypeStrings.IN_SHOP,
|
||||
isClaimRegistrationRequired: (state) => state.issConfig.isClaimRegistrationRequired,
|
||||
isClaimAlreadyRegistered: (state) => state.order.payment.insuranceCoverage.claimNumber !== null,
|
||||
isBailout: (state) => state.applicationUser.pageData[issPageValues.BAILOUT_PAGE] != null,
|
||||
|
|
@ -935,7 +952,6 @@ export const useMainStore = defineStore({
|
|||
}).then((response) => resolve(response), (error) => reject(error));
|
||||
});
|
||||
},
|
||||
|
||||
getCarrierAccountInfo() {
|
||||
return new Promise((resolve, reject) => {
|
||||
globalMethods.callHttpClient({
|
||||
|
|
@ -947,12 +963,10 @@ export const useMainStore = defineStore({
|
|||
}).catch((error) => reject(error));
|
||||
});
|
||||
},
|
||||
|
||||
async getSupportingItems() {
|
||||
const glassPartsArray = this.order.lineItems.glassParts ?? [];
|
||||
const { carId } = this.order.vehicle;
|
||||
const { isRepair } = this.order.damage;
|
||||
const { numberOfChips } = this.order.damage;
|
||||
const { glassParts } = this.lineItems;
|
||||
const { carId } = this.vehicle;
|
||||
const { isRepair, numberOfChips } = this.damage;
|
||||
|
||||
return globalMethods
|
||||
.callHttpClient({
|
||||
|
|
@ -962,7 +976,7 @@ export const useMainStore = defineStore({
|
|||
carId,
|
||||
damageType: isRepair ? 'Repair' : 'Replace',
|
||||
parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
|
||||
parts: glassPartsArray,
|
||||
parts: glassParts ?? [],
|
||||
numberOfRepairChips: isRepair ? numberOfChips : 0
|
||||
}
|
||||
});
|
||||
|
|
@ -1201,7 +1215,7 @@ export const useMainStore = defineStore({
|
|||
submitToMainframe: !!this.order.referralNumber,
|
||||
loadedFromDupeCheck
|
||||
},
|
||||
additionalSuccessEventDataHandler: (response) =>
|
||||
additionalSuccessEventDataHandler: () =>
|
||||
`Email provided: ${customer.emailAddress ? 'true' : 'false'}`
|
||||
}).then((response) => {
|
||||
if (loadedFromDupeCheck) {
|
||||
|
|
@ -1303,7 +1317,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;
|
||||
},
|
||||
|
|
@ -1385,6 +1415,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;
|
||||
|
|
@ -1394,7 +1428,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();
|
||||
|
|
@ -1470,8 +1504,8 @@ export const useMainStore = defineStore({
|
|||
this.order.originalDeductible = vehicle.deductible;
|
||||
this.order.currentDeductible = vehicle.deductible;
|
||||
|
||||
this.resetSupportingItemsState();
|
||||
this.resetVapsState();
|
||||
this.updateSupportingItems(null);
|
||||
this.updateVaps(null);
|
||||
},
|
||||
|
||||
updateVehicleVin(vin) {
|
||||
|
|
@ -1494,6 +1528,7 @@ export const useMainStore = defineStore({
|
|||
|
||||
resetGlassPartsState() {
|
||||
this.order.lineItems.glassParts = null;
|
||||
this.order.lineItems.supportingItems = null;
|
||||
this.order.damage.partQuestionAnswers = null;
|
||||
this.order.damage.moldingQuestionAnswers = null;
|
||||
this.order.damage.capabilityQuestionAnswers = null;
|
||||
|
|
@ -1509,21 +1544,6 @@ export const useMainStore = defineStore({
|
|||
this.order.schedule.routeCode = null;
|
||||
this.order.schedule.jobMaxMinutes = null;
|
||||
this.order.schedule.jobMinMinutes = null;
|
||||
|
||||
// premium appointment fee used on schedule page also needs reset when schedule is reset
|
||||
const { supportingItems } = this.order.lineItems;
|
||||
const premiumAppointmentFeeIndex = supportingItems?.findIndex((item) => item.partType === PREMIUM_FEE_PART_TYPE);
|
||||
|
||||
if (premiumAppointmentFeeIndex >= 0) {
|
||||
supportingItems.splice(premiumAppointmentFeeIndex, 1);
|
||||
state.order.lineItems.supportingItems = supportingItems;
|
||||
}
|
||||
},
|
||||
resetSupportingItemsState() {
|
||||
this.order.lineItems.supportingItems = null;
|
||||
},
|
||||
resetVapsState() {
|
||||
this.order.lineItems.vaps = null;
|
||||
},
|
||||
resetDamageState() {
|
||||
this.order.damage.isRepair = null;
|
||||
|
|
@ -1683,8 +1703,8 @@ export const useMainStore = defineStore({
|
|||
this.updateGlassParts(null);
|
||||
this.updateMoldingQuestionAnswers(null);
|
||||
this.updateCapabilityQuestionAnswers(null);
|
||||
this.resetSupportingItemsState();
|
||||
this.resetVapsState();
|
||||
this.updateSupportingItems(null);
|
||||
this.updateVaps(null);
|
||||
|
||||
this.updatePageData({ page: issPageValues.VEHICLE_PARTS, data: null });
|
||||
this.updatePageData({ page: issPageValues.MOLDING_QUESTIONS, data: null });
|
||||
|
|
@ -1728,18 +1748,6 @@ export const useMainStore = defineStore({
|
|||
// Save new values
|
||||
this.updateCapabilityQuestionAnswers(capabilityQuestionAnswersArray);
|
||||
},
|
||||
saveGlassParts(glassParts) {
|
||||
this.order.lineItems.glassParts = glassParts;
|
||||
},
|
||||
saveSupportingItems(supportingItems) {
|
||||
this.order.lineItems.supportingItems = supportingItems;
|
||||
},
|
||||
saveSupportingItemsSuppressingStateResetting(supportingItems) {
|
||||
this.order.lineItems.supportingItems = supportingItems;
|
||||
},
|
||||
saveVaps(vaps) {
|
||||
this.order.lineItems.vaps = vaps;
|
||||
},
|
||||
|
||||
// Price order actions
|
||||
async priceOrderItemsAndSaveServerData(availableLineItems, serviceZipCode, serviceZipCodeCtu) {
|
||||
|
|
@ -2108,21 +2116,18 @@ export const useMainStore = defineStore({
|
|||
resetRegistrationAndDependencies() {
|
||||
this.resetRegistrationState();
|
||||
this.resetGlassPartsState();
|
||||
this.resetSupportingItemsState();
|
||||
this.resetVapsState();
|
||||
this.updateVaps(null);
|
||||
},
|
||||
|
||||
resetDamageAndDependencies() {
|
||||
this.resetDamageState();
|
||||
this.resetGlassPartsState();
|
||||
this.resetSupportingItemsState();
|
||||
this.resetVapsState();
|
||||
this.updateVaps(null);
|
||||
},
|
||||
|
||||
resetPartsAndDependencies() {
|
||||
this.resetGlassPartsState();
|
||||
this.resetSupportingItemsState();
|
||||
this.resetVapsState();
|
||||
this.updateVaps(null);
|
||||
|
||||
this.resetServiceLocationAndDependencies();
|
||||
},
|
||||
|
|
@ -2150,7 +2155,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;
|
||||
|
|
@ -2162,8 +2166,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
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue