Merge branch 'develop' into CASH-132-dontation-widget-foster-love
This commit is contained in:
commit
6ef5a30c5c
31 changed files with 859 additions and 236 deletions
|
|
@ -27,7 +27,6 @@ module.exports = {
|
||||||
"!src/layouts/insurance/*.vue", // Temp test exclusion while in development
|
"!src/layouts/insurance/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/insurance-company/*.vue", // Temp test exclusion while in development
|
"!src/layouts/insurance-company/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/insurance-company/insurance-company-question/*.vue", // Temp test exclusion while in development
|
"!src/layouts/insurance-company/insurance-company-question/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/return-user/*.vue", // Temp test exclusion while in development
|
|
||||||
// END
|
// END
|
||||||
], // ! means exclude from coverage.
|
], // ! means exclude from coverage.
|
||||||
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ const endpoints = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
},
|
},
|
||||||
SaveQuote: {
|
SaveQuote: {
|
||||||
url: "/order/api/v1/order/initiate-saved-progress-email",
|
url: "/order/api/v1/order/save-progress",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
},
|
},
|
||||||
GetSignature: {
|
GetSignature: {
|
||||||
|
|
@ -168,6 +168,10 @@ const endpoints = {
|
||||||
url: "/analytics/api/v1/analytics/initialize",
|
url: "/analytics/api/v1/analytics/initialize",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
},
|
},
|
||||||
|
LogPartQuestions: {
|
||||||
|
url: "/analytics/api/v1/analytics/log-part-questions",
|
||||||
|
method: "POST",
|
||||||
|
},
|
||||||
GetExperimentsByUser: {
|
GetExperimentsByUser: {
|
||||||
url: "/analytics/api/v1/analytics/get-experiments",
|
url: "/analytics/api/v1/analytics/get-experiments",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const experimentUniverses = {
|
const experimentUniverses = {
|
||||||
CONCEPT_FUNNEL: "ConceptFunnel",
|
CONCEPT_FUNNEL: "ConceptFunnel",
|
||||||
RECAL_PRICE_REMOVAL: "NextGen_RecalPriceRemoval",
|
RECAL_PRICE_REMOVAL: "NextGen_RecalPriceRemoval",
|
||||||
|
MSR: "MSR",
|
||||||
};
|
};
|
||||||
|
|
||||||
const experimentSettings = {
|
const experimentSettings = {
|
||||||
|
|
@ -16,6 +17,7 @@ const experimentSettings = {
|
||||||
RECAL_PRICE_REMOVE: "RecalPriceRemove",
|
RECAL_PRICE_REMOVE: "RecalPriceRemove",
|
||||||
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL: "NextGen_InternalInsuranceTabDisplayThreshold",
|
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL: "NextGen_InternalInsuranceTabDisplayThreshold",
|
||||||
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL: "NextGen_ExternalInsuranceTabDisplayThreshold",
|
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL: "NextGen_ExternalInsuranceTabDisplayThreshold",
|
||||||
|
DISPLAY_MSR: "DisplayMSR",
|
||||||
};
|
};
|
||||||
|
|
||||||
const experimentTriggers = {
|
const experimentTriggers = {
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,5 @@ export const headerKeys = {
|
||||||
SESSION_SEQUENCE_NUMBER: "X-Session-Sequence-Number",
|
SESSION_SEQUENCE_NUMBER: "X-Session-Sequence-Number",
|
||||||
TRANSACTION_ID: "X-Transaction-Id",
|
TRANSACTION_ID: "X-Transaction-Id",
|
||||||
EON: "X-Enterprise-Order-Number",
|
EON: "X-Enterprise-Order-Number",
|
||||||
|
LOG_ENABLED: "log-enabled"
|
||||||
};
|
};
|
||||||
|
|
|
||||||
7
src/constants/part-number-strings.js
Normal file
7
src/constants/part-number-strings.js
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
const partNumberStrings = {
|
||||||
|
// Recalibration
|
||||||
|
MOBILE_STATIC_RECAL_FEE: "RECAL MOBILE",
|
||||||
|
MOBILE_DUAL_RECAL_FEE: "RECAL MOBILEDUAL",
|
||||||
|
};
|
||||||
|
|
||||||
|
export { partNumberStrings };
|
||||||
|
|
@ -42,10 +42,6 @@ const storeActions = {
|
||||||
VALIDATE_ZIP: "validateZip",
|
VALIDATE_ZIP: "validateZip",
|
||||||
PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA: "priceOrderItemsAndSaveServerData",
|
PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA: "priceOrderItemsAndSaveServerData",
|
||||||
TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA: "taxOrderItemsAndSaveServerData",
|
TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA: "taxOrderItemsAndSaveServerData",
|
||||||
LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure",
|
|
||||||
LOG_PAGE_VIEW: "logPageView",
|
|
||||||
LOG_CUSTOM_EVENT: "logCustomEvent",
|
|
||||||
INITIALIZE_SESSION: "initializeSession",
|
|
||||||
GET_EXPERIMENTS_BY_USER: "GetExperimentsByUser",
|
GET_EXPERIMENTS_BY_USER: "GetExperimentsByUser",
|
||||||
RUN_EXPERIMENTS_FOR_TRIGGER: "runExperimentsForTrigger",
|
RUN_EXPERIMENTS_FOR_TRIGGER: "runExperimentsForTrigger",
|
||||||
CLEAR_VIN: "clearVin",
|
CLEAR_VIN: "clearVin",
|
||||||
|
|
@ -57,6 +53,13 @@ const storeActions = {
|
||||||
GET_BILL_TO_ACCOUNT_NUMBER: "getBillToAccountNumber",
|
GET_BILL_TO_ACCOUNT_NUMBER: "getBillToAccountNumber",
|
||||||
GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS: "getRecalPartsAndSaveToLineItems",
|
GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS: "getRecalPartsAndSaveToLineItems",
|
||||||
|
|
||||||
|
// Analytics
|
||||||
|
LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure",
|
||||||
|
LOG_PAGE_VIEW: "logPageView",
|
||||||
|
LOG_CUSTOM_EVENT: "logCustomEvent",
|
||||||
|
INITIALIZE_SESSION: "initializeSession",
|
||||||
|
LOG_PART_QUESTIONS: "logPartQuestions",
|
||||||
|
|
||||||
// DEPENDENCY MUTATIONS
|
// DEPENDENCY MUTATIONS
|
||||||
RESET_VEHICLE_STATE_AND_DEPENDENCIES: "resetVehicleStateAndDependencies",
|
RESET_VEHICLE_STATE_AND_DEPENDENCIES: "resetVehicleStateAndDependencies",
|
||||||
RESET_DAMAGE_STATE_AND_DEPENDENCIES: "resetDamageAndDependencies",
|
RESET_DAMAGE_STATE_AND_DEPENDENCIES: "resetDamageAndDependencies",
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,10 @@
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
<slot name="modal-footer-slot"></slot>
|
||||||
<modalButtonMain
|
<modalButtonMain
|
||||||
isPrimary
|
isPrimary
|
||||||
class="w-100"
|
class="w-100 modal-footer-button"
|
||||||
:id="modalId + '-modalbtn'"
|
:id="modalId + '-modalbtn'"
|
||||||
ref="modalButtonMain"
|
ref="modalButtonMain"
|
||||||
loaderColor="white"
|
loaderColor="white"
|
||||||
|
|
@ -45,6 +46,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
||||||
|
import analyticsMixin from "@/mixins/analytics-mixin";
|
||||||
|
import router from "@/router/index.js";
|
||||||
import modalButtonMain from "@/digital-components/modal/ux-components/modal-button-main/modal-button-main";
|
import modalButtonMain from "@/digital-components/modal/ux-components/modal-button-main/modal-button-main";
|
||||||
import { Modal } from "bootstrap";
|
import { Modal } from "bootstrap";
|
||||||
import { useForm } from "vee-validate";
|
import { useForm } from "vee-validate";
|
||||||
|
|
@ -86,7 +90,15 @@ export default {
|
||||||
async validateAndEmit() {
|
async validateAndEmit() {
|
||||||
const validationResult = await this.validate();
|
const validationResult = await this.validate();
|
||||||
if (validationResult.valid) {
|
if (validationResult.valid) {
|
||||||
this.$emit("footer-button-event");
|
if (analyticsMixin.methods.sessionExpired()) {
|
||||||
|
analyticsMixin.methods.initSession();
|
||||||
|
router.push({
|
||||||
|
path: "/",
|
||||||
|
query: { fmgPage: fmgPageValues.RETURN_USER },
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$emit("footer-button-event");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.resetButtonStyle();
|
this.resetButtonStyle();
|
||||||
}
|
}
|
||||||
|
|
@ -247,56 +259,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.save-progress-modal-question {
|
|
||||||
p.modal-body {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.modal-body {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.textbox-question {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
margin: 0 0 1.5rem 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.save-progress-modal-question,
|
|
||||||
.save-progress-popup-question {
|
|
||||||
p.modal-body {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.modal-body {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.textbox-question {
|
|
||||||
label {
|
|
||||||
text-align: left;
|
|
||||||
font-weight: 900;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.modal-body-inner {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
.modal-disclaimer {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
order: 2;
|
|
||||||
text-align: left;
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.modal-footer {
|
|
||||||
margin: 0 0 1.5rem 0;
|
|
||||||
padding-top: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
body {
|
body {
|
||||||
.modal-backdrop {
|
.modal-backdrop {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,9 @@
|
||||||
<script>
|
<script>
|
||||||
import textLink from "@/ux-components/text-link/text-link";
|
import textLink from "@/ux-components/text-link/text-link";
|
||||||
import buttonMain from "@/ux-components/button-main/button-main";
|
import buttonMain from "@/ux-components/button-main/button-main";
|
||||||
|
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
||||||
|
import analyticsMixin from "@/mixins/analytics-mixin";
|
||||||
|
import router from "@/router/index.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "navbar",
|
name: "navbar",
|
||||||
|
|
@ -94,10 +97,28 @@ export default {
|
||||||
document.onkeydown = function (e) {
|
document.onkeydown = function (e) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
this.$emit("ForwardClicked");
|
// check session expired and initSession to recreate cookies
|
||||||
|
if (analyticsMixin.methods.sessionExpired()) {
|
||||||
|
this.routeReturnUser();
|
||||||
|
} else {
|
||||||
|
this.$emit("ForwardClicked");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
linkClick() {
|
linkClick() {
|
||||||
this.$emit("BackClicked");
|
// check session expired and initSession to recreate cookies
|
||||||
|
if (analyticsMixin.methods.sessionExpired()) {
|
||||||
|
this.routeReturnUser();
|
||||||
|
} else {
|
||||||
|
this.$emit("BackClicked");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
routeReturnUser() {
|
||||||
|
analyticsMixin.methods.initSession();
|
||||||
|
|
||||||
|
router.push({
|
||||||
|
path: "/",
|
||||||
|
query: { fmgPage: fmgPageValues.RETURN_USER },
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="save-progress-modal-question" :class="isProgressSaved ? 'progress-saved' : ''">
|
<div class="save-progress-modal-question" :class="isProgressSaved ? 'progress-saved' : ''">
|
||||||
<buttonMain
|
<buttonMain
|
||||||
ref="buttonMain"
|
|
||||||
type="button"
|
type="button"
|
||||||
v-if="!isProgressSaved"
|
v-if="!isProgressSaved"
|
||||||
:buttonText="buttonText"
|
:buttonText="buttonText"
|
||||||
loaderColor="white"
|
loaderColor="white"
|
||||||
:suppressLoader="true"
|
:suppressLoader="true"
|
||||||
class="save-progress-button"
|
class="open-save-progress-button"
|
||||||
@click-event="openModal" />
|
@click-event="openModal" />
|
||||||
<alert
|
<alert
|
||||||
class="my-4"
|
class="my-4"
|
||||||
|
|
@ -21,12 +20,14 @@
|
||||||
:onModalClosedCallback="onModalClosed"
|
:onModalClosedCallback="onModalClosed"
|
||||||
:footerButtonText="modalButtonText"
|
:footerButtonText="modalButtonText"
|
||||||
@footer-button-event="saveProgress">
|
@footer-button-event="saveProgress">
|
||||||
<p class="modal-body-inner">{{ modalBodyText }}</p>
|
<p class="modal-body-inner" v-html="modalBodyText"></p>
|
||||||
<saveProgressQuestion
|
<saveProgressQuestion
|
||||||
ref="saveProgressQuestion"
|
ref="saveProgressQuestion"
|
||||||
v-model="userInput"
|
v-model="userInput"
|
||||||
cmsWidgetName="SaveProgressQuestionWidget" />
|
cmsWidgetName="SaveProgressQuestionWidget" />
|
||||||
<p class="modal-disclaimer" v-html="modalDisclaimerText"></p>
|
<template v-slot:modal-footer-slot>
|
||||||
|
<p class="modal-disclaimer" v-html="modalDisclaimerText"></p>
|
||||||
|
</template>
|
||||||
</modal>
|
</modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -112,7 +113,7 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss">
|
||||||
.save-progress-modal-question {
|
.save-progress-modal-question {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
order: 2;
|
order: 2;
|
||||||
|
|
@ -128,7 +129,7 @@ export default {
|
||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.save-progress-button {
|
.open-save-progress-button {
|
||||||
order: 4;
|
order: 4;
|
||||||
position: relative;
|
position: relative;
|
||||||
color: $blue;
|
color: $blue;
|
||||||
|
|
@ -160,12 +161,57 @@ export default {
|
||||||
transition: background 0s 0s ease-in-out;
|
transition: background 0s 0s ease-in-out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:deep(.alert) {
|
.modal.modal-component .modal-dialog .modal-content {
|
||||||
|
.modal-header {
|
||||||
|
padding-top: 0;
|
||||||
|
margin-top: 1.875rem;
|
||||||
|
}
|
||||||
|
.modal-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
|
||||||
|
.textbox-question {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0 1.5rem 0;
|
||||||
|
|
||||||
|
label {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.modal-body-inner {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
.modal-disclaimer {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
order: 2;
|
||||||
|
text-align: left;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.modal-footer {
|
||||||
|
margin: 0 0 1.5rem 0;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
|
||||||
|
button.btn {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
border-radius: $border-radius-lg;
|
border-radius: $border-radius-lg;
|
||||||
border: 1px solid $green;
|
border: 1px solid $green;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
:deep(.alert-heading) {
|
.alert-heading {
|
||||||
position: relative;
|
position: relative;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
|
|
@ -183,20 +229,4 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.applied-promo {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 24px;
|
|
||||||
color: $green;
|
|
||||||
|
|
||||||
.promo-code {
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.alert {
|
|
||||||
color: $red;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 24px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -14,20 +14,22 @@
|
||||||
v-model="userInput"
|
v-model="userInput"
|
||||||
cmsWidgetName="SaveProgressPopupQuestionWidget"
|
cmsWidgetName="SaveProgressPopupQuestionWidget"
|
||||||
class="save-progress-popup-question" />
|
class="save-progress-popup-question" />
|
||||||
<buttonMain
|
<template v-slot:modal-footer-slot>
|
||||||
ref="skipButton"
|
<buttonMain
|
||||||
type="button"
|
ref="skipButton"
|
||||||
:buttonText="buttonText"
|
type="button"
|
||||||
loaderColor="white"
|
:buttonText="buttonText"
|
||||||
:suppressLoader="true"
|
loaderColor="white"
|
||||||
class="skip-button"
|
:suppressLoader="true"
|
||||||
@click-event="closeModal" />
|
class="skip-button"
|
||||||
|
@click-event="closeModal" />
|
||||||
|
<p class="modal-disclaimer" v-html="modalDisclaimerText"></p>
|
||||||
|
</template>
|
||||||
<alert
|
<alert
|
||||||
class="my-4"
|
class="my-4"
|
||||||
v-if="isProgressSaved"
|
v-if="isProgressSaved"
|
||||||
cmsWidgetName="SaveProgressModalAlertWidget"
|
cmsWidgetName="SaveProgressModalAlertWidget"
|
||||||
alertClass="alert-success" />
|
alertClass="alert-success" />
|
||||||
<p class="modal-disclaimer" v-html="modalDisclaimerText"></p>
|
|
||||||
</modal>
|
</modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -205,35 +207,63 @@ export default {
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.modal-footer {
|
.modal.modal-component .modal-dialog .modal-content {
|
||||||
order: 3;
|
p.modal-body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.modal-disclaimer {
|
.modal-body {
|
||||||
order: 4;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
|
||||||
|
.textbox-question {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0 1.5rem 0;
|
||||||
|
|
||||||
|
label {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.modal-body-inner {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
.modal-footer {
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
margin: 0 0 1.5rem 0;
|
||||||
|
|
||||||
|
button.btn {
|
||||||
|
order: 1;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
button.btn.skip-button {
|
||||||
|
padding: 0;
|
||||||
|
order: 2;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
.modal-disclaimer {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
text-align: left;
|
||||||
|
order: 3;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.progress-saved {
|
&.progress-saved {
|
||||||
.modal-footer,
|
.modal-footer-button,
|
||||||
.save-progress-popup-question {
|
.modal-disclaimer {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.skip-button {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.applied-promo {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 24px;
|
|
||||||
color: $green;
|
|
||||||
|
|
||||||
.promo-code {
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.alert {
|
|
||||||
color: $red;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 24px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ export default {
|
||||||
[headerKeys.REFERRAL_SEQUENCE_NUMBER]: order?.referralSequenceNumber,
|
[headerKeys.REFERRAL_SEQUENCE_NUMBER]: order?.referralSequenceNumber,
|
||||||
[headerKeys.TRANSACTION_ID]: crypto.randomUUID(),
|
[headerKeys.TRANSACTION_ID]: crypto.randomUUID(),
|
||||||
[headerKeys.EON]: order?.eon,
|
[headerKeys.EON]: order?.eon,
|
||||||
|
[headerKeys.LOG_ENABLED]: store.getters.applicationUser?.loggingOption ?? false,
|
||||||
};
|
};
|
||||||
|
|
||||||
axios({
|
axios({
|
||||||
|
|
|
||||||
19
src/helpers/boolean-helper.js
Normal file
19
src/helpers/boolean-helper.js
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
export function getBoolFromString(str) {
|
||||||
|
// Catch edge cases
|
||||||
|
if (str === null || str === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof str === "boolean") {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof str !== "string") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// string logic
|
||||||
|
const toLower = str?.toLowerCase();
|
||||||
|
|
||||||
|
return toLower === "true";
|
||||||
|
}
|
||||||
146
src/helpers/boolean-helper.spec.js
Normal file
146
src/helpers/boolean-helper.spec.js
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
import { getBoolFromString } from "./boolean-helper";
|
||||||
|
|
||||||
|
describe("getBoolFromString", () => {
|
||||||
|
describe("Happy paths", () => {
|
||||||
|
test('"true" -> true', () => {
|
||||||
|
const input = "true";
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('"false" -> false', () => {
|
||||||
|
const input = "false";
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('"other string" -> false', () => {
|
||||||
|
const input = "some random value";
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Capitalization", () => {
|
||||||
|
test('"TRUE" -> true', () => {
|
||||||
|
const input = "TRUE";
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('"True" -> true', () => {
|
||||||
|
const input = "True";
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('"FALSE" -> false', () => {
|
||||||
|
const input = "FALSE";
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('"False" -> false', () => {
|
||||||
|
const input = "False";
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Graceful type errors", () => {
|
||||||
|
describe("Boolean", () => {
|
||||||
|
test("true -> true", () => {
|
||||||
|
const input = true;
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("false -> false", () => {
|
||||||
|
const input = false;
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Empty", () => {
|
||||||
|
test("undefined -> false", () => {
|
||||||
|
const input = undefined;
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("null -> false", () => {
|
||||||
|
const input = null;
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("{} -> false", () => {
|
||||||
|
const input = {};
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Other types", () => {
|
||||||
|
test("1 -> false", () => {
|
||||||
|
const input = 1;
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Object -> false", () => {
|
||||||
|
const input = {
|
||||||
|
test: true,
|
||||||
|
true: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("function -> false", () => {
|
||||||
|
const input = () => true;
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("array -> false", () => {
|
||||||
|
const input = [true];
|
||||||
|
|
||||||
|
const output = getBoolFromString(input);
|
||||||
|
|
||||||
|
expect(output).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -8,3 +8,17 @@ export function getQuerystringParameter(key) {
|
||||||
|
|
||||||
return lowerCaseParams.get(key) ? lowerCaseParams.get(key) : null;
|
return lowerCaseParams.get(key) ? lowerCaseParams.get(key) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if you add the fmgPage to the querystringobject before calling, then pass true for skipFmgPageName
|
||||||
|
export function buildQuerystringObject(qso, skipFmgPageName = false) {
|
||||||
|
const queryString = window.location.search;
|
||||||
|
const urlParams = new URLSearchParams(queryString);
|
||||||
|
|
||||||
|
for (const [name, value] of urlParams) {
|
||||||
|
if (name.toLowerCase() === "fmgpage" && skipFmgPageName) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
qso[name] = value;
|
||||||
|
}
|
||||||
|
return qso;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,7 @@ export default {
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next(async (vm) => {
|
next(async (vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
// turned off Save Your Progress for 1/23/25 release
|
vm.showSaveProgressModal = !(emailFromStore?.length > 0);
|
||||||
// to restore, uncomment line below
|
|
||||||
// vm.showSaveProgressModal = !(emailFromStore?.length > 0);
|
|
||||||
if (store.getters.externalParameterState?.isExternalParameter) {
|
if (store.getters.externalParameterState?.isExternalParameter) {
|
||||||
if (store.getters.externalParameterServiceZip.zipCode) {
|
if (store.getters.externalParameterServiceZip.zipCode) {
|
||||||
await baseMixin.methods.dispatchStoreAction(
|
await baseMixin.methods.dispatchStoreAction(
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,43 @@ export default {
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
const hasRecalPriceRemoveExperiment = await store.getters.shouldHideRecalibration;
|
const hasRecalPriceRemoveExperiment = await store.getters.shouldHideRecalibration;
|
||||||
|
|
||||||
|
// send part question data to SPS API for logging
|
||||||
|
const orderFromStore = await deepClone(store.getters.order);
|
||||||
|
const ctu = orderFromStore.serviceLocation?.zipCodeCtu
|
||||||
|
|
||||||
|
const partsOrQuestions = orderFromStore.damage?.partQuestionAnswers;
|
||||||
|
|
||||||
|
partsOrQuestions.forEach(pqa => {
|
||||||
|
const payloadPartQuestions = [];
|
||||||
|
pqa.answeredQuestions.forEach(answer => {
|
||||||
|
payloadPartQuestions.push({
|
||||||
|
questionSeq: answer?.questionNum,
|
||||||
|
questionText: answer?.questionText,
|
||||||
|
answerText: answer?.selectedAnswerText,
|
||||||
|
basePart: pqa?.result,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
eon: orderFromStore.eon,
|
||||||
|
ctu: ctu,
|
||||||
|
workOrderId: orderFromStore.workOrderId,
|
||||||
|
workOrderNumber: orderFromStore.workOrderNumber,
|
||||||
|
carId: orderFromStore.vehicle.carId,
|
||||||
|
glassLocation: pqa?.glassLocation,
|
||||||
|
partQuestions: payloadPartQuestions,
|
||||||
|
};
|
||||||
|
|
||||||
|
baseMixin.methods.dispatchStoreAction(
|
||||||
|
storeActions.LOG_PART_QUESTIONS,
|
||||||
|
payload,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Create order
|
||||||
await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER); // This nulls the Store order
|
await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER); // This nulls the Store order
|
||||||
|
|
||||||
// Call APIs
|
// Call APIs
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,7 @@ export default {
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next(async (vm) => {
|
next(async (vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
// turned off Save Your Progress for 1/23/25 release
|
vm.showSaveProgressModal = !(emailFromStore?.length > 0);
|
||||||
// to restore, uncomment line below
|
|
||||||
// vm.showSaveProgressModal = !(emailFromStore?.length > 0);
|
|
||||||
if (store.getters.externalParameterState?.isExternalParameter) {
|
if (store.getters.externalParameterState?.isExternalParameter) {
|
||||||
if (store.getters.externalParameterServiceZip.zipCode) {
|
if (store.getters.externalParameterServiceZip.zipCode) {
|
||||||
await baseMixin.methods.dispatchStoreAction(
|
await baseMixin.methods.dispatchStoreAction(
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,7 @@ export default {
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next(async (vm) => {
|
next(async (vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
// turned off Save Your Progress for 1/23/25 release
|
vm.showSaveProgressModal = !(emailFromStore?.length > 0);
|
||||||
// to restore, uncomment line below
|
|
||||||
// vm.showSaveProgressModal = !(emailFromStore?.length > 0);
|
|
||||||
if (store.getters.externalParameterState?.isExternalParameter) {
|
if (store.getters.externalParameterState?.isExternalParameter) {
|
||||||
if (store.getters.externalParameterServiceZip.zipCode) {
|
if (store.getters.externalParameterServiceZip.zipCode) {
|
||||||
const serviceState = store.getters.order.serviceLocation.state;
|
const serviceState = store.getters.order.serviceLocation.state;
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,7 @@ import { mapTaxedLineItemsToStoreFormat } from "../../store";
|
||||||
import { coverageStatus } from "@/constants/insurance";
|
import { coverageStatus } from "@/constants/insurance";
|
||||||
import { containsLineItemWithPartType } from "@/helpers/service-package-helper";
|
import { containsLineItemWithPartType } from "@/helpers/service-package-helper";
|
||||||
import { containsRecalParts } from "@/helpers/recal-helper";
|
import { containsRecalParts } from "@/helpers/recal-helper";
|
||||||
|
import { getBoolFromString } from "@/helpers/boolean-helper";
|
||||||
|
|
||||||
defineRule("payment-method-required", required(errorMessages.OPTION_REQUIRED));
|
defineRule("payment-method-required", required(errorMessages.OPTION_REQUIRED));
|
||||||
defineRule("recal-ack-required", required(errorMessages.RECAL_ACK_REQUIRED));
|
defineRule("recal-ack-required", required(errorMessages.RECAL_ACK_REQUIRED));
|
||||||
|
|
@ -429,7 +430,7 @@ export default {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
{
|
{
|
||||||
const log = getQuerystringParameter(queryStrings.LOG);
|
const log = getQuerystringParameter(queryStrings.LOG);
|
||||||
const logAsBool = (log?.toLowerCase() === "true");
|
const logAsBool = getBoolFromString(log);
|
||||||
if (logAsBool || !preReqResult) {
|
if (logAsBool || !preReqResult) {
|
||||||
console.log("------------- payment-method.vue pagePrereqs start -----------------");
|
console.log("------------- payment-method.vue pagePrereqs start -----------------");
|
||||||
console.log(new Date() + " serviceLocationReqs::isMobile: " + isMobile);
|
console.log(new Date() + " serviceLocationReqs::isMobile: " + isMobile);
|
||||||
|
|
@ -786,7 +787,7 @@ export default {
|
||||||
shouldDisplayPiaAlert() {
|
shouldDisplayPiaAlert() {
|
||||||
return (
|
return (
|
||||||
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] ||
|
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] ||
|
||||||
eval(window.history.state.displayPiaAlert)
|
getBoolFromString(window.history.state.displayPiaAlert)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
// Necessary to make the watcher of lineItems work
|
// Necessary to make the watcher of lineItems work
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,7 @@ import { submitWorkOrder } from "@/helpers/heritage-integration/order-helper.js"
|
||||||
import iframeResize from "../../../node_modules/iframe-resizer/js/iframeResizer.js";
|
import iframeResize from "../../../node_modules/iframe-resizer/js/iframeResizer.js";
|
||||||
import { routerParams } from "@/router/router-constants/router-params";
|
import { routerParams } from "@/router/router-constants/router-params";
|
||||||
import { coverageStatus } from "@/constants/insurance";
|
import { coverageStatus } from "@/constants/insurance";
|
||||||
|
import { getBoolFromString } from "@/helpers/boolean-helper.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "payment",
|
name: "payment",
|
||||||
|
|
@ -800,7 +801,7 @@ export default {
|
||||||
shouldDisplayPiaAlert(payMethod) {
|
shouldDisplayPiaAlert(payMethod) {
|
||||||
return (
|
return (
|
||||||
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] === payMethod ||
|
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] === payMethod ||
|
||||||
eval(window.history.state.displayPiaAlert)
|
getBoolFromString(window.history.state.displayPiaAlert)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,7 @@ import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigat
|
||||||
import { containsRecalParts } from "@/helpers/recal-helper";
|
import { containsRecalParts } from "@/helpers/recal-helper";
|
||||||
import { externalParameterStatus } from "@/constants/external-parameters";
|
import { externalParameterStatus } from "@/constants/external-parameters";
|
||||||
import { saveQuote } from "@/helpers/heritage-integration/order-helper.js";
|
import { saveQuote } from "@/helpers/heritage-integration/order-helper.js";
|
||||||
|
import { getBoolFromString } from "@/helpers/boolean-helper";
|
||||||
|
|
||||||
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
||||||
|
|
||||||
|
|
@ -293,12 +294,8 @@ export default {
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next(async (vm) => {
|
next(async (vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
vm.showSaveProgressPopup = showSaveProgressPopup;
|
||||||
// turned off Save Your Progress for 1/23/25 release
|
vm.showSaveProgressModal = showSaveProgressModal;
|
||||||
// to restore, uncomment the 2 lines below
|
|
||||||
// vm.showSaveProgressPopup = showSaveProgressPopup;
|
|
||||||
// vm.showSaveProgressModal = showSaveProgressModal;
|
|
||||||
|
|
||||||
vm.addableVaps = addableVaps;
|
vm.addableVaps = addableVaps;
|
||||||
vm.lineItems = lineItems;
|
vm.lineItems = lineItems;
|
||||||
vm.availableLineItems = pricingResults;
|
vm.availableLineItems = pricingResults;
|
||||||
|
|
@ -407,7 +404,7 @@ export default {
|
||||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||||
} else {
|
} else {
|
||||||
// user came from an external source, however, the externalParms may have been reset on service-zip, property-questions, etc...
|
// user came from an external source, however, the externalParms may have been reset on service-zip, property-questions, etc...
|
||||||
if (eval(store.getters.externalParameterQuote?.isInsurance)) {
|
if (getBoolFromString(store.getters.externalParameterQuote?.isInsurance)) {
|
||||||
// did user intentionally select insurance?
|
// did user intentionally select insurance?
|
||||||
vm.isInsuranceSelected = true;
|
vm.isInsuranceSelected = true;
|
||||||
vm.servicePackage = store.getters.externalParameterQuote.servicePackage;
|
vm.servicePackage = store.getters.externalParameterQuote.servicePackage;
|
||||||
|
|
|
||||||
312
src/layouts/return-user/return-user.spec.js
Normal file
312
src/layouts/return-user/return-user.spec.js
Normal file
|
|
@ -0,0 +1,312 @@
|
||||||
|
// Components
|
||||||
|
import returnUser from "@/layouts/return-user/return-user.vue";
|
||||||
|
|
||||||
|
// Supporting Files
|
||||||
|
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
||||||
|
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper";
|
||||||
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
|
import { dispatchStoreAction } from "@/mixins/base-mixin.js";
|
||||||
|
import store from "@/store";
|
||||||
|
import router from "@/router";
|
||||||
|
import navbar from "@/fmg-components/nav-bar/nav-bar";
|
||||||
|
import { Form } from "vee-validate";
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||||
|
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||||
|
import { saveSession } from "@/helpers/heritage-integration/order-helper.js";
|
||||||
|
|
||||||
|
import { experimentSettings } from "../../constants/experiments";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
import buttonMain from "@/ux-components/button-main/button-main";
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
|
||||||
|
// Setup global mocks
|
||||||
|
let mockStoreActionData = {};
|
||||||
|
|
||||||
|
let mockStoreData = {};
|
||||||
|
let mockExperimentSettings = {
|
||||||
|
experiments: [
|
||||||
|
{
|
||||||
|
universeName: "ConceptFunnel",
|
||||||
|
settings: {
|
||||||
|
SuppressVinCapture: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
function resetMockStoreData() {
|
||||||
|
mockStoreData = {
|
||||||
|
vehicle: {
|
||||||
|
year: "2000",
|
||||||
|
make: "TestMake",
|
||||||
|
model: "TestModel",
|
||||||
|
style: "TestStyle",
|
||||||
|
carId: "TestID",
|
||||||
|
vin: null,
|
||||||
|
registration: {
|
||||||
|
licensePlate: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
address: null,
|
||||||
|
address2: null,
|
||||||
|
city: null,
|
||||||
|
state: null,
|
||||||
|
zipCode: null,
|
||||||
|
zipCodeCtu: null,
|
||||||
|
appointmentType: null,
|
||||||
|
isVehicleProtected: null,
|
||||||
|
provider: {
|
||||||
|
providerNumber: null,
|
||||||
|
address: {
|
||||||
|
streetAddress: null,
|
||||||
|
city: null,
|
||||||
|
state: null,
|
||||||
|
zipCode: null,
|
||||||
|
zipCodeCtu: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
techNotes: null,
|
||||||
|
},
|
||||||
|
customer: {
|
||||||
|
firstName: null,
|
||||||
|
lastName: null,
|
||||||
|
emailAddress: null,
|
||||||
|
phoneNumber: null,
|
||||||
|
isSmsOptIn: null,
|
||||||
|
},
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
numberOfChips: null,
|
||||||
|
glassToReplace: [{ glassLocation: "Windshield", glassName: "windshield" }],
|
||||||
|
partQuestionAnswers: null,
|
||||||
|
moldingQuestionAnswers: null,
|
||||||
|
capabilityQuestionAnswers: null,
|
||||||
|
dateOfLoss: null,
|
||||||
|
damageCause: null,
|
||||||
|
},
|
||||||
|
lineItems: {
|
||||||
|
glassParts: [
|
||||||
|
{
|
||||||
|
canSafeliteRecalibrate: true,
|
||||||
|
childParts: [
|
||||||
|
{
|
||||||
|
kitPrice: 0,
|
||||||
|
laborAmount: 23.55,
|
||||||
|
partNumber: "GGG FW4896",
|
||||||
|
salesTax: 1.77,
|
||||||
|
sellingPrice: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
color: "Green Tint",
|
||||||
|
description:
|
||||||
|
"solar, soundproofing, lane keep assist, lane departure warning system, w/adaptive cruise control",
|
||||||
|
id: "db22fd44-10dd-456f-979b-ff88cf68cca6",
|
||||||
|
kitPrice: 0,
|
||||||
|
laborAmount: 60,
|
||||||
|
partNumber: "FW04896GTYN",
|
||||||
|
partType: "WINDSHIELD",
|
||||||
|
recalibrationType: "STATIC",
|
||||||
|
requiresCapabilityQuestions: false,
|
||||||
|
requiresRecalibration: true,
|
||||||
|
salesTax: 63.86,
|
||||||
|
sellingPrice: 791.46,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
supportingItems: null,
|
||||||
|
vaps: null,
|
||||||
|
serverData: null,
|
||||||
|
promos: null,
|
||||||
|
},
|
||||||
|
payment: {
|
||||||
|
isInsurance: null,
|
||||||
|
insuranceCoverage: {
|
||||||
|
isVerified: null,
|
||||||
|
coverageStatus: null,
|
||||||
|
coverageType: null,
|
||||||
|
coverageVerificationType: null,
|
||||||
|
},
|
||||||
|
parentAccountNumber: 0,
|
||||||
|
billToAccountNumber: null,
|
||||||
|
isPia: null,
|
||||||
|
piaType: null,
|
||||||
|
inactivePromos: null,
|
||||||
|
paypalToken: null,
|
||||||
|
nextGenSettledAmount: 0,
|
||||||
|
ccToken: {
|
||||||
|
subscriptionId: null,
|
||||||
|
expMonth: null,
|
||||||
|
expYear: null,
|
||||||
|
cardType: null,
|
||||||
|
billToPostalCode: null,
|
||||||
|
billToFirstName: null,
|
||||||
|
billToLastName: null,
|
||||||
|
referenceNumber: null,
|
||||||
|
authCode: null,
|
||||||
|
transactionId: null,
|
||||||
|
transReferenceNumber: null,
|
||||||
|
lastFour: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
policy: {
|
||||||
|
currentDeductible: 0,
|
||||||
|
policyNumber: null,
|
||||||
|
isItac: false,
|
||||||
|
additionalAuthFlag: null,
|
||||||
|
isNoComp: false,
|
||||||
|
insuranceCompanyName: null,
|
||||||
|
},
|
||||||
|
schedule: {
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
routeCode: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
externalParameterServiceZip: {
|
||||||
|
zipCode: null,
|
||||||
|
emailAddress: null,
|
||||||
|
},
|
||||||
|
externalParameterState: { isExternalParameter: false },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyMockStoreDataToGetters() {
|
||||||
|
store.getters = {
|
||||||
|
vehicle: mockStoreData.vehicle,
|
||||||
|
};
|
||||||
|
store.state.order = mockStoreData;
|
||||||
|
store.state.applicationUser.experiments = mockExperimentSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function mockDispatchStoreAction(actionName) {
|
||||||
|
return mockStoreActionData[actionName];
|
||||||
|
}
|
||||||
|
|
||||||
|
jest.mock("@/mixins/base-mixin.js", () => ({
|
||||||
|
methods: {
|
||||||
|
dispatchStoreAction: jest.fn(),
|
||||||
|
dispatchStoreActionWithLogging: jest.fn().mockImplementation(mockDispatchStoreAction),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||||
|
fetchCmsContentForPage: () => Promise.resolve("content"),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/helpers/heritage-integration/order-helper.js", () => ({
|
||||||
|
saveSession: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/helpers/heritage-integration/cookie-helper", () => ({
|
||||||
|
deleteFunnelCookie: jest.fn(),
|
||||||
|
getFunnelCookie: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
router.navigateWithoutSaving = jest.fn();
|
||||||
|
router.navigateWithSaving = jest.fn();
|
||||||
|
|
||||||
|
// Tests
|
||||||
|
describe("return-user.vue", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
resetMockStoreData();
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Test prerequisites are valid and child components are rendered", () => {
|
||||||
|
test("expect pagePrerequisites are valid to be called", () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = setupMocks({});
|
||||||
|
|
||||||
|
applyMockStoreDataToGetters();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const pagePrerequisitesSpy = jest.spyOn(wrapper.vm, "arePagePrerequisitesValid");
|
||||||
|
|
||||||
|
wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(pagePrerequisitesSpy).toBeCalled();
|
||||||
|
expect(getFunnelCookie).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders child components", () => {
|
||||||
|
const wrapper = setupMocks({});
|
||||||
|
|
||||||
|
expect(wrapper.findComponent(funnelHeader).exists()).toBe(true);
|
||||||
|
expect(wrapper.findComponent(funnelSubHeader).exists()).toBe(true);
|
||||||
|
expect(wrapper.findComponent(navbar).exists()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Navigation", () => {
|
||||||
|
test("Check forwardButtonAction is working", async () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = setupMocks({});
|
||||||
|
// Act
|
||||||
|
|
||||||
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.$router.navigateWithoutSaving).toBeCalledWith(
|
||||||
|
navigationScenarios.CLICKED_FORWARD,
|
||||||
|
wrapper.vm.$route
|
||||||
|
);
|
||||||
|
});
|
||||||
|
test("expect functions in startOver to be called", async () => {
|
||||||
|
//Arrange
|
||||||
|
const wrapper = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const dispatchStoreActionSpy = jest.spyOn(wrapper.vm, "dispatchStoreAction");
|
||||||
|
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
await wrapper.vm.startOver();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.$router.navigateWithoutSaving).toBeCalledWith(
|
||||||
|
navigationScenarios.CLICKED_FORWARD,
|
||||||
|
wrapper.vm.$route
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(dispatchStoreActionSpy).toHaveBeenCalledWith(storeActions.RESET_STATE);
|
||||||
|
expect(deleteFunnelCookie).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupMocks({ customMountOptions }) {
|
||||||
|
const route = { query: { fmgPage: "return-user" }, params: {} };
|
||||||
|
|
||||||
|
baseMixin.methods.ResetExternalParamsAndHideModal = jest.fn();
|
||||||
|
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
...customMountOptions,
|
||||||
|
route: route,
|
||||||
|
});
|
||||||
|
|
||||||
|
mountOptions.global.mocks["$store"] = store;
|
||||||
|
mountOptions.global.mocks["$router"] = router;
|
||||||
|
baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true);
|
||||||
|
mountOptions["attachTo"] = document.body;
|
||||||
|
|
||||||
|
const wrapper = shallowMount(returnUser, mountOptions, {
|
||||||
|
stubs: {
|
||||||
|
Form,
|
||||||
|
funnelHeader,
|
||||||
|
funnelSubHeader,
|
||||||
|
navbar,
|
||||||
|
loadingModal: true,
|
||||||
|
buttonMain,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
@ -241,57 +241,46 @@ export default {
|
||||||
this.displayMismatchStateAndZipAlert = false;
|
this.displayMismatchStateAndZipAlert = false;
|
||||||
},
|
},
|
||||||
async setMobileLocation() {
|
async setMobileLocation() {
|
||||||
if (
|
this.resetAlerts();
|
||||||
this.internalModel.addressQuestions.zipCode !==
|
// Validate the Zip Code
|
||||||
this.modelValue.addressQuestions.zipCode
|
const zipCodeData = await this.getZipCodeData(
|
||||||
) {
|
this.internalModel.addressQuestions.zipCode,
|
||||||
this.resetAlerts();
|
"service-location"
|
||||||
// Validate the Zip Code
|
);
|
||||||
const zipCodeData = await this.getZipCodeData(
|
|
||||||
this.internalModel.addressQuestions.zipCode,
|
if (!zipCodeData.isValid) {
|
||||||
|
this.displayInvalidZipAlert = true;
|
||||||
|
this.resetModalButtonStyle();
|
||||||
|
} else if (zipCodeData.state != this.internalModel.addressQuestions.state) {
|
||||||
|
this.displayMismatchStateAndZipAlert = true;
|
||||||
|
this.resetModalButtonStyle();
|
||||||
|
} else {
|
||||||
|
// retrieve mobile fee part
|
||||||
|
const serviceZipCode = this.internalModel.addressQuestions.zipCode;
|
||||||
|
const mobileFeePart = await getPricedMobileFeePart(
|
||||||
|
serviceZipCode,
|
||||||
"service-location"
|
"service-location"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!zipCodeData.isValid) {
|
// retrieve serviceability details
|
||||||
this.displayInvalidZipAlert = true;
|
const serviceabilityDetails = await getServiceabilityDetails(
|
||||||
this.resetModalButtonStyle();
|
serviceZipCode,
|
||||||
} else if (zipCodeData.state != this.internalModel.addressQuestions.state) {
|
null,
|
||||||
this.displayMismatchStateAndZipAlert = true;
|
"service-location"
|
||||||
this.resetModalButtonStyle();
|
);
|
||||||
} else {
|
|
||||||
// retrieve mobile fee part
|
|
||||||
const serviceZipCode = this.internalModel.addressQuestions.zipCode;
|
|
||||||
const mobileFeePart = await getPricedMobileFeePart(
|
|
||||||
serviceZipCode,
|
|
||||||
"service-location"
|
|
||||||
);
|
|
||||||
|
|
||||||
// retrieve serviceability details
|
const billToAccountNumber = await getBillToAccountNumber(
|
||||||
const serviceabilityDetails = await getServiceabilityDetails(
|
this.internalModel.zipCodeCtu
|
||||||
serviceZipCode,
|
);
|
||||||
null,
|
|
||||||
"service-location"
|
|
||||||
);
|
|
||||||
|
|
||||||
const billToAccountNumber = await getBillToAccountNumber(
|
// update content related to service zip code
|
||||||
this.internalModel.zipCodeCtu
|
this.$emit("updated-mobile-fee-part", mobileFeePart);
|
||||||
);
|
this.$emit("updated-serviceability", serviceabilityDetails.data);
|
||||||
|
this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase);
|
||||||
|
this.$emit("updated-mobile-ctu", zipCodeData.zipCodeCtu);
|
||||||
|
this.$emit("updated-bill-to-account-number", billToAccountNumber);
|
||||||
|
|
||||||
// update content related to service zip code
|
// update the page level model
|
||||||
this.$emit("updated-mobile-fee-part", mobileFeePart);
|
|
||||||
this.$emit("updated-serviceability", serviceabilityDetails.data);
|
|
||||||
this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase);
|
|
||||||
this.$emit("updated-mobile-ctu", zipCodeData.zipCodeCtu);
|
|
||||||
this.$emit("updated-bill-to-account-number", billToAccountNumber);
|
|
||||||
|
|
||||||
// update the page level model
|
|
||||||
this.$emit("update:modelValue", this.internalModel);
|
|
||||||
|
|
||||||
//Page advance to Schedule page
|
|
||||||
this.$emit("mobileLocationSelected");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Update the page level model
|
|
||||||
this.$emit("update:modelValue", this.internalModel);
|
this.$emit("update:modelValue", this.internalModel);
|
||||||
|
|
||||||
//Page advance to Schedule page
|
//Page advance to Schedule page
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { getMountOptions } from "@/helpers/unit-test-helper";
|
||||||
|
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import baseMixin from "@/mixins/base-mixin";
|
import baseMixin from "@/mixins/base-mixin";
|
||||||
|
import { experimentSettings } from "@/constants/experiments";
|
||||||
|
|
||||||
// Define Mocks
|
// Define Mocks
|
||||||
jest.mock("@/helpers/cms-content-helper", () => ({
|
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||||
|
|
@ -199,6 +200,9 @@ beforeEach(() => {
|
||||||
zipCode: "43054",
|
zipCode: "43054",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
experimentSettings: {
|
||||||
|
settingName: experimentSettings.DISPLAY_MSR,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,8 @@ import contentGroupModal from "@/fmg-components/content-group-modal/content-grou
|
||||||
|
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
|
import experimentMixin from "@/mixins/experiment-mixin.js";
|
||||||
|
import { experimentSettings } from "@/constants/experiments";
|
||||||
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
||||||
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
|
@ -151,6 +153,7 @@ import {
|
||||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||||
import { applicationConfig } from "@/constants/application-config";
|
import { applicationConfig } from "@/constants/application-config";
|
||||||
import { Provider } from "@/layouts/service-location/classes/provider";
|
import { Provider } from "@/layouts/service-location/classes/provider";
|
||||||
|
import { partNumberStrings } from "@/constants/part-number-strings";
|
||||||
|
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
|
||||||
|
|
@ -159,7 +162,6 @@ import { defineRule } from "vee-validate";
|
||||||
import { errorMessages } from "@/constants/error-messages";
|
import { errorMessages } from "@/constants/error-messages";
|
||||||
|
|
||||||
const MOBILE_FEE_PART_TYPE = "MOBILE FEE";
|
const MOBILE_FEE_PART_TYPE = "MOBILE FEE";
|
||||||
const MOBILE_STATIC_RECAL_FEE_PART_NUMBER = "RECAL MOBILE";
|
|
||||||
|
|
||||||
// DEFINE VALIDATION RULES
|
// DEFINE VALIDATION RULES
|
||||||
defineRule("mobile-location-required", (value) => {
|
defineRule("mobile-location-required", (value) => {
|
||||||
|
|
@ -319,11 +321,19 @@ export default {
|
||||||
},
|
},
|
||||||
isMobileStaticRecalibrationApplicable() {
|
isMobileStaticRecalibrationApplicable() {
|
||||||
return (
|
return (
|
||||||
|
this.displayMSR &&
|
||||||
this.isVehicleMobileStaticRecalibrationApplicable &&
|
this.isVehicleMobileStaticRecalibrationApplicable &&
|
||||||
this.mobileFeePart?.partNumber == MOBILE_STATIC_RECAL_FEE_PART_NUMBER &&
|
this.mobileFeePart?.partNumber == partNumberStrings.MOBILE_STATIC_RECAL_FEE &&
|
||||||
(this.isInsurance ? this.mobileFeePart?.isInsurable : true)
|
(this.isInsurance ? this.mobileFeePart?.isInsurable : true)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
displayMSR() {
|
||||||
|
return (
|
||||||
|
experimentMixin.methods
|
||||||
|
.getSettingValue(experimentSettings.DISPLAY_MSR)
|
||||||
|
?.toLowerCase() === "true"
|
||||||
|
);
|
||||||
|
},
|
||||||
mobileFeeApplies() {
|
mobileFeeApplies() {
|
||||||
if (
|
if (
|
||||||
this.mobileFeePart?.laborAmount > 0 ||
|
this.mobileFeePart?.laborAmount > 0 ||
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,7 @@ import { routerParams } from "@/router/router-constants/router-params";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import baseMixin from "@/mixins/base-mixin";
|
import baseMixin from "@/mixins/base-mixin";
|
||||||
import { nextTick } from "vue";
|
import { nextTick } from "vue";
|
||||||
|
import { getBoolFromString } from "@/helpers/boolean-helper";
|
||||||
// DEFINE VALIDATION RULES
|
// DEFINE VALIDATION RULES
|
||||||
defineRule("replace-options-required", required(errorMessages.REPLACE_OPTIONS_REQUIRED));
|
defineRule("replace-options-required", required(errorMessages.REPLACE_OPTIONS_REQUIRED));
|
||||||
|
|
||||||
|
|
@ -622,7 +623,7 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
shouldDisplayVehicleChangeAlert() {
|
shouldDisplayVehicleChangeAlert() {
|
||||||
return eval(window.history.state.displayVehicleChangeAlert);
|
return getBoolFromString(window.history.state.displayVehicleChangeAlert);
|
||||||
},
|
},
|
||||||
shouldHideBackButton() {
|
shouldHideBackButton() {
|
||||||
return this.$store.getters.requiresVerifiedRedirecting;
|
return this.$store.getters.requiresVerifiedRedirecting;
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,7 @@ export default {
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
// turned off Save Your Progress for 1/23/25 release
|
vm.showSaveProgressModal = !(emailFromStore?.length > 0);
|
||||||
// to restore, uncomment line below
|
|
||||||
// vm.showSaveProgressModal = !(emailFromStore?.length > 0);
|
|
||||||
|
|
||||||
// Glass Part Question dynamic component
|
// Glass Part Question dynamic component
|
||||||
Object.keys(vm.$refs)
|
Object.keys(vm.$refs)
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,11 @@ import vehicleQuestion from "@/layouts/vehicle/vehicle-question/vehicle-question
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
import { experimentUniverses } from "@/constants/experiments";
|
import { experimentUniverses } from "@/constants/experiments";
|
||||||
import { getSessionKeyValue, getUserIdValue } from "@/helpers/heritage-integration/cookie-helper";
|
import {
|
||||||
|
getSessionKeyValue,
|
||||||
|
getUserIdValue,
|
||||||
|
getDeviceIdValue,
|
||||||
|
} from "@/helpers/heritage-integration/cookie-helper";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
import { Form, defineRule } from "vee-validate";
|
import { Form, defineRule } from "vee-validate";
|
||||||
import { required } from "@/helpers/validation-rules";
|
import { required } from "@/helpers/validation-rules";
|
||||||
|
|
@ -186,11 +190,12 @@ export default {
|
||||||
storeActions.LOG_EXPERIMENT_EXPOSURE,
|
storeActions.LOG_EXPERIMENT_EXPOSURE,
|
||||||
{
|
{
|
||||||
userId: getUserIdValue(),
|
userId: getUserIdValue(),
|
||||||
|
deviceId: getDeviceIdValue(),
|
||||||
sessionKey: getSessionKeyValue(),
|
sessionKey: getSessionKeyValue(),
|
||||||
pageName: to.query.fmgPage,
|
pageName: "vehicle-logExposure", //to.query.fmgPage,
|
||||||
experiment: experimentForLogging,
|
experiment: experimentForLogging,
|
||||||
},
|
},
|
||||||
"vehicle",
|
"vehicle-logExposure",
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -712,24 +712,19 @@ export default {
|
||||||
return !areAllSessionCookiesSet();
|
return !areAllSessionCookiesSet();
|
||||||
},
|
},
|
||||||
|
|
||||||
async validateSession() {
|
// sessionExpired is true when one of the analytics cookies(sid, dxdev) has expired but we still have the vehicle year in vuex
|
||||||
// The noSession function checks the cookies related to analytics logging(sid). it is not the funnel info cookie.
|
sessionExpired() {
|
||||||
// The sid cookie for analytics will expire every 30 minutes and get recreated in initSession. If this happens
|
|
||||||
// and we also have the funnel cookie present, that indicates they have an existing session that is now expired
|
|
||||||
// so route them to the return user page.
|
|
||||||
const fromHeritage = getQuerystringParameter(queryStrings.FROM_HERITAGE) === "true";
|
const fromHeritage = getQuerystringParameter(queryStrings.FROM_HERITAGE) === "true";
|
||||||
const funnelCookieLastTouched = getFunnelCookie()?.LastTouched;
|
if (this.noSession() && !fromHeritage && store.getters.order.vehicle?.year > 0) {
|
||||||
if (
|
return true;
|
||||||
this.noSession() &&
|
} else {
|
||||||
!fromHeritage &&
|
return false;
|
||||||
funnelCookieLastTouched !== null &&
|
}
|
||||||
funnelCookieLastTouched !== undefined
|
},
|
||||||
) {
|
|
||||||
await this.initSession();
|
async validateSession() {
|
||||||
router.push({
|
// do not init session if it is expired. let the click event on nav-bar handle session expired logic
|
||||||
path: "/",
|
if (this.sessionExpired()) {
|
||||||
query: { fmgPage: fmgPageValues.RETURN_USER },
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"
|
||||||
import { routingTable } from "@/router/router-constants/routing-table.js";
|
import { routingTable } from "@/router/router-constants/routing-table.js";
|
||||||
import { globalEvents, globalEventTypes } from "@/constants/events";
|
import { globalEvents, globalEventTypes } from "@/constants/events";
|
||||||
import { queryStrings } from "@/constants/query-strings";
|
import { queryStrings } from "@/constants/query-strings";
|
||||||
import { getQuerystringParameter } from "@/helpers/querystring-helper";
|
import { getQuerystringParameter, buildQuerystringObject } from "@/helpers/querystring-helper";
|
||||||
import { getDeviceIdValue } from "@/helpers/heritage-integration/cookie-helper";
|
import { getDeviceIdValue } from "@/helpers/heritage-integration/cookie-helper";
|
||||||
import { showFmgLoadingModal } from "@/helpers/loading-modal-helper";
|
import { showFmgLoadingModal } from "@/helpers/loading-modal-helper";
|
||||||
import { fmgPageValues, funnelStartPageName } from "@/router/router-constants/fmgPage-values";
|
import { fmgPageValues, funnelStartPageName } from "@/router/router-constants/fmgPage-values";
|
||||||
|
|
@ -38,6 +38,7 @@ import { applicationConfig } from "../constants/application-config";
|
||||||
import { shouldStripPromoQueryString } from "@/helpers/promotions-helper";
|
import { shouldStripPromoQueryString } from "@/helpers/promotions-helper";
|
||||||
import bailout from "@/layouts/bailout/bailout";
|
import bailout from "@/layouts/bailout/bailout";
|
||||||
import { nextTick } from "vue";
|
import { nextTick } from "vue";
|
||||||
|
import { getBoolFromString } from "@/helpers/boolean-helper";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
|
|
@ -58,6 +59,11 @@ const routes = [
|
||||||
|
|
||||||
await analyticsMixin.methods.validateSession();
|
await analyticsMixin.methods.validateSession();
|
||||||
|
|
||||||
|
// after session is validated, remove the fromHeritage querystring if it exists so session expiration works
|
||||||
|
if (to.query) {
|
||||||
|
delete to.query[queryStrings.FROM_HERITAGE];
|
||||||
|
}
|
||||||
|
|
||||||
if (getFunnelCookie()?.SuppressConceptFunnel) {
|
if (getFunnelCookie()?.SuppressConceptFunnel) {
|
||||||
log(" --go to heritage suppressConceptFunnel: ");
|
log(" --go to heritage suppressConceptFunnel: ");
|
||||||
await navigateToHeritageFunnel({ shouldSaveSession: false });
|
await navigateToHeritageFunnel({ shouldSaveSession: false });
|
||||||
|
|
@ -95,27 +101,24 @@ const routes = [
|
||||||
}
|
}
|
||||||
// On entering the funnel "fresh", read cookie information, decide what to do next.
|
// On entering the funnel "fresh", read cookie information, decide what to do next.
|
||||||
else if (from.redirectedFrom === undefined || fromReturnUser) {
|
else if (from.redirectedFrom === undefined || fromReturnUser) {
|
||||||
// if entering the funnel from the content site, check and see if there is already a funnel cookie.
|
// if entering the funnel from the content site, check and see if there is already a vehicle year in vuex.
|
||||||
// if so, send them to return-user page.
|
// if so, send them to return-user page.
|
||||||
const funnelCookieLastTouched = getFunnelCookie()?.LastTouched;
|
|
||||||
if (
|
if (
|
||||||
fromContentSite &&
|
fromContentSite &&
|
||||||
funnelCookieLastTouched !== null &&
|
!toReturnUserPage &&
|
||||||
funnelCookieLastTouched !== undefined &&
|
store.getters.order.vehicle?.year > 0
|
||||||
!toReturnUserPage
|
|
||||||
) {
|
) {
|
||||||
log(" --from content site navigate to return user");
|
log(" --from content site navigate to return user");
|
||||||
var qso = {
|
var qso = {
|
||||||
fmgPage: fmgPageValues.RETURN_USER,
|
fmgPage: fmgPageValues.RETURN_USER,
|
||||||
};
|
};
|
||||||
const lg = getQuerystringParameter(queryStrings.LOG);
|
|
||||||
if (lg) {
|
const newQueryString = buildQuerystringObject(qso, true);
|
||||||
qso[queryStrings.LOG] = true;
|
log(" -- returnUser add querystring: " + JSON.stringify(newQueryString));
|
||||||
}
|
|
||||||
|
|
||||||
router.push({
|
router.push({
|
||||||
path: "/",
|
path: "/",
|
||||||
query: Object.assign({}, qso),
|
query: Object.assign({}, newQueryString),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -173,8 +176,8 @@ const routes = [
|
||||||
// clear part related state because heritage selected a new vehicle
|
// clear part related state because heritage selected a new vehicle
|
||||||
if (
|
if (
|
||||||
to.query.fmgPage === fmgPageValues.VEHICLE &&
|
to.query.fmgPage === fmgPageValues.VEHICLE &&
|
||||||
eval(getFunnelCookie()?.HasDelayedClaimRegistration &&
|
getBoolFromString(getFunnelCookie()?.HasDelayedClaimRegistration) &&
|
||||||
!fromReturnUser)
|
!fromReturnUser
|
||||||
) {
|
) {
|
||||||
store.commit(storeMutations.RESET_GLASS_PARTS_STATE);
|
store.commit(storeMutations.RESET_GLASS_PARTS_STATE);
|
||||||
}
|
}
|
||||||
|
|
@ -182,7 +185,7 @@ const routes = [
|
||||||
// if coming from the return user page, clear the destination page so implicit navigation runs
|
// if coming from the return user page, clear the destination page so implicit navigation runs
|
||||||
log(" --to.query ", JSON.stringify(to.query));
|
log(" --to.query ", JSON.stringify(to.query));
|
||||||
if (fromReturnUser && to.query) {
|
if (fromReturnUser && to.query) {
|
||||||
log( " --clear to.query");
|
log(" --clear to.query");
|
||||||
delete to.query[queryStrings.FMG_PAGE];
|
delete to.query[queryStrings.FMG_PAGE];
|
||||||
|
|
||||||
//to.query[queryStrings.FMG_PAGE] = "";
|
//to.query[queryStrings.FMG_PAGE] = "";
|
||||||
|
|
@ -422,7 +425,7 @@ router.afterEach(async (to, from) => {
|
||||||
store.commit(storeMutations.UPDATE_LAST_PAGE_VISITED, to.name);
|
store.commit(storeMutations.UPDATE_LAST_PAGE_VISITED, to.name);
|
||||||
|
|
||||||
// If saving on navigation is requested, check for saved SessionId or EmailAddress to determine if saving is appropriate
|
// If saving on navigation is requested, check for saved SessionId or EmailAddress to determine if saving is appropriate
|
||||||
if (eval(window.history.state.isSavingNavigation)) {
|
if (getBoolFromString(window.history.state.isSavingNavigation)) {
|
||||||
if (
|
if (
|
||||||
store.getters.applicationUser.savedSessionId ||
|
store.getters.applicationUser.savedSessionId ||
|
||||||
store.getters.order.customer?.emailAddress
|
store.getters.order.customer?.emailAddress
|
||||||
|
|
@ -794,7 +797,7 @@ async function runExperiments(nextPage) {
|
||||||
await baseMixin.methods.dispatchStoreActionWithLogging(
|
await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.RUN_EXPERIMENTS_FOR_TRIGGER,
|
storeActions.RUN_EXPERIMENTS_FOR_TRIGGER,
|
||||||
{
|
{
|
||||||
userId: getDeviceIdValue(),
|
deviceId: getDeviceIdValue(),
|
||||||
triggerEvent: experimentTriggers.SITE_ENTRY,
|
triggerEvent: experimentTriggers.SITE_ENTRY,
|
||||||
triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE,
|
triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE,
|
||||||
},
|
},
|
||||||
|
|
@ -805,9 +808,9 @@ async function runExperiments(nextPage) {
|
||||||
await baseMixin.methods.dispatchStoreActionWithLogging(
|
await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.RUN_EXPERIMENTS_FOR_TRIGGER,
|
storeActions.RUN_EXPERIMENTS_FOR_TRIGGER,
|
||||||
{
|
{
|
||||||
userId: getDeviceIdValue(),
|
deviceId: getDeviceIdValue(),
|
||||||
triggerEvent: experimentTriggers.PAGE_ENTRY,
|
triggerEvent: experimentTriggers.PAGE_ENTRY,
|
||||||
triggerValue: nextPage,
|
triggerValue: nextPage == "vehicle" ? "vehicle-pageEntry" : nextPage,
|
||||||
},
|
},
|
||||||
nextPage
|
nextPage
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1252,7 +1252,7 @@ export const actions = {
|
||||||
// Analytics Actions
|
// Analytics Actions
|
||||||
logExperimentExposure(
|
logExperimentExposure(
|
||||||
context,
|
context,
|
||||||
{ payload: { userId, sessionKey, pageName, experiment }, pageNameToLog }
|
{ payload: { userId, deviceId, sessionKey, pageName, experiment }, pageNameToLog }
|
||||||
) {
|
) {
|
||||||
return globalMethods.callHttpClient({
|
return globalMethods.callHttpClient({
|
||||||
method: endpoints.LogExperimentExposureIfAssigned.method,
|
method: endpoints.LogExperimentExposureIfAssigned.method,
|
||||||
|
|
@ -1260,6 +1260,7 @@ export const actions = {
|
||||||
payload: {
|
payload: {
|
||||||
experimentForLogging: {
|
experimentForLogging: {
|
||||||
userId: userId,
|
userId: userId,
|
||||||
|
deviceId: deviceId,
|
||||||
experimentUniverseId: experiment.universeId,
|
experimentUniverseId: experiment.universeId,
|
||||||
experimentUniverseName: experiment.universeName,
|
experimentUniverseName: experiment.universeName,
|
||||||
experimentTestId: experiment.testId,
|
experimentTestId: experiment.testId,
|
||||||
|
|
@ -1445,6 +1446,39 @@ export const actions = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
logPartQuestions(
|
||||||
|
context,
|
||||||
|
{
|
||||||
|
eon,
|
||||||
|
ctu,
|
||||||
|
workOrderId,
|
||||||
|
workOrderNumber,
|
||||||
|
carId,
|
||||||
|
glassLocation,
|
||||||
|
partQuestions,
|
||||||
|
userAgent,
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
var payload = {
|
||||||
|
applicationName: applicationConfig.APPLICATION_NAME,
|
||||||
|
eon: eon,
|
||||||
|
ctu: ctu,
|
||||||
|
workOrderId: workOrderId,
|
||||||
|
workOrderNumber: workOrderNumber,
|
||||||
|
carId: carId,
|
||||||
|
glassLocation: glassLocation,
|
||||||
|
partQuestions: partQuestions,
|
||||||
|
userAgent: navigator.userAgent
|
||||||
|
};
|
||||||
|
|
||||||
|
return globalMethods
|
||||||
|
.callHttpClient({
|
||||||
|
method: endpoints.LogPartQuestions.method,
|
||||||
|
endpoint: endpoints.LogPartQuestions.url,
|
||||||
|
payload: payload,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// Misc Actions
|
// Misc Actions
|
||||||
setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId, eon }) {
|
setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId, eon }) {
|
||||||
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
|
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
|
||||||
|
|
@ -1463,7 +1497,7 @@ export const actions = {
|
||||||
|
|
||||||
async runExperimentsForTrigger(
|
async runExperimentsForTrigger(
|
||||||
context,
|
context,
|
||||||
{ payload: { userId, triggerEvent, triggerValue }, pageNameToLog }
|
{ payload: { deviceId, triggerEvent, triggerValue }, pageNameToLog }
|
||||||
) {
|
) {
|
||||||
if (triggerEvent == experimentTriggers.SITE_ENTRY) {
|
if (triggerEvent == experimentTriggers.SITE_ENTRY) {
|
||||||
context.commit(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true);
|
context.commit(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true);
|
||||||
|
|
@ -1471,7 +1505,7 @@ export const actions = {
|
||||||
|
|
||||||
var payload = {
|
var payload = {
|
||||||
applicationName: applicationConfig.APPLICATION_NAME,
|
applicationName: applicationConfig.APPLICATION_NAME,
|
||||||
userId: userId,
|
deviceId: deviceId,
|
||||||
triggerEvent: triggerEvent,
|
triggerEvent: triggerEvent,
|
||||||
triggerValue: triggerValue,
|
triggerValue: triggerValue,
|
||||||
experimentOrder: context.getters.experimentOrder,
|
experimentOrder: context.getters.experimentOrder,
|
||||||
|
|
@ -1638,10 +1672,10 @@ export const actions = {
|
||||||
var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`;
|
var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`;
|
||||||
|
|
||||||
if (isMobileStaticRecalibrationApplicable) {
|
if (isMobileStaticRecalibrationApplicable) {
|
||||||
const staticRecalPartNumber = getStaticRecalPartNumber(order.lineItems?.glassParts[0]);
|
const recalPartNumber = getRecalPartNumber(order.lineItems?.glassParts[0]);
|
||||||
const carId = order.vehicle?.carId;
|
const carId = order.vehicle?.carId;
|
||||||
if (staticRecalPartNumber && carId) {
|
if (recalPartNumber && carId) {
|
||||||
endPoint = `${endPoint}&partNumbers=${staticRecalPartNumber}&carId=${carId}`;
|
endPoint = `${endPoint}&partNumbers=${recalPartNumber}&carId=${carId}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3685,9 +3719,11 @@ function saveExternalParameterState(externalParameterState) {
|
||||||
window.sessionStorage.setItem("externalParameterState", JSON.stringify(externalParameterState));
|
window.sessionStorage.setItem("externalParameterState", JSON.stringify(externalParameterState));
|
||||||
}
|
}
|
||||||
|
|
||||||
//This function checks if static recalibration is available for the vehicle and returns the part number for it.
|
//This function finds the recalibration part and returns the part number for it.
|
||||||
function getStaticRecalPartNumber(glassPartsArray) {
|
function getRecalPartNumber(glassPartsArray) {
|
||||||
const recalPart = glassPartsArray.childParts.find((item) => item.partNumber === "RECAL STATIC");
|
const recalPart = glassPartsArray.childParts.find(
|
||||||
|
(item) => item.partType === partTypeStrings.ADAS_RECALIBRATION
|
||||||
|
);
|
||||||
if (recalPart) {
|
if (recalPart) {
|
||||||
return recalPart.partNumber;
|
return recalPart.partNumber;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue