Merge remote-tracking branch 'origin/develop' into feature/CSR-2266
This commit is contained in:
commit
fcd5c99cf3
11 changed files with 155 additions and 62 deletions
|
|
@ -12,6 +12,7 @@ const experimentSettings = {
|
|||
SUBMIT_ORDER_ENABLE_PIA: "SubmitOrder_Enable_PIA",
|
||||
IS_EMAIL_OPTIONAL: "isEmailOptional",
|
||||
SERVICE_PACKAGE_DISCOUNT: "OfferServicePackageDiscount",
|
||||
PROMO_ON_PACKAGE: "Offer_Promo_On_Pkg",
|
||||
RECAL_PRICE_REMOVE: "RecalPriceRemove",
|
||||
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL: "NextGen_InternalInsuranceTabDisplayThreshold",
|
||||
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL: "NextGen_ExternalInsuranceTabDisplayThreshold",
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export default {
|
|||
},
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -46,10 +46,19 @@ import baseMixin from "@/mixins/base-mixin.js";
|
|||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||
import { applicationConfig } from "@/constants/application-config";
|
||||
import store from "@/store";
|
||||
import router from "@/router";
|
||||
|
||||
export default {
|
||||
name: "insurance-company",
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
//force reload if redirected from external application
|
||||
if (from.redirectedFrom === undefined && !sessionStorage.getItem("reloaded")) {
|
||||
sessionStorage.setItem("reloaded", "true");
|
||||
router.go(0);
|
||||
} else {
|
||||
sessionStorage.removeItem("reloaded");
|
||||
}
|
||||
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
||||
const insuranceCompanyListPromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export default {
|
|||
},
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -346,12 +346,24 @@ export default {
|
|||
let internalThreshold = experimentMixin.methods.getSettingValue(
|
||||
experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL
|
||||
);
|
||||
let externalThreshold = experimentMixin.methods.getSettingValue(
|
||||
experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL
|
||||
);
|
||||
const isExternalParameter = store.getters.externalParameterState?.isExternalParameter;
|
||||
|
||||
if (
|
||||
isExternalParameter === externalParameterStatus.NOT_SET ||
|
||||
isExternalParameter === externalParameterStatus.INACTIVE
|
||||
) {
|
||||
// prettier-ignore
|
||||
{
|
||||
const log = getQuerystringParameter(queryStrings.LOG);
|
||||
if (eval(log)) {
|
||||
console.log("------------- quote.vue thresholds start -----------------");
|
||||
console.log(new Date() + " isExternalParameter: " + isExternalParameter);
|
||||
console.log(new Date() + " internalThreshold: " + internalThreshold);
|
||||
console.log(new Date() + " externalThreshold: " + externalThreshold);
|
||||
console.log("------------- quote.vue thresholds end -----------------");
|
||||
}
|
||||
}
|
||||
|
||||
if (isExternalParameter === externalParameterStatus.NOT_SET) {
|
||||
// there are no active or inactive external parameters; use internal threshold
|
||||
if (internalThreshold) thresholdToUse = internalThreshold;
|
||||
|
||||
|
|
@ -361,23 +373,26 @@ export default {
|
|||
);
|
||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||
} else {
|
||||
// user came from an external source
|
||||
if (store.getters.externalParameterQuote?.isInsurance == true) {
|
||||
// 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)) {
|
||||
// did user intentionally select insurance?
|
||||
vm.isInsuranceSelected = true;
|
||||
vm.servicePackage = store.getters.externalParameterQuote.servicePackage;
|
||||
await nextTick();
|
||||
const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm);
|
||||
if (isValid) {
|
||||
vm.forwardButtonAction();
|
||||
} else {
|
||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||
|
||||
if (
|
||||
vm.servicePackage != null &&
|
||||
isExternalParameter === externalParameterStatus.ACTIVE
|
||||
) {
|
||||
const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm);
|
||||
if (isValid) {
|
||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||
vm.forwardButtonAction();
|
||||
}
|
||||
}
|
||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||
} else {
|
||||
const externalThreshold = experimentMixin.methods.getSettingValue(
|
||||
experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL
|
||||
);
|
||||
thresholdToUse = externalThreshold;
|
||||
if (externalThreshold) thresholdToUse = externalThreshold;
|
||||
|
||||
vm.isInsuranceSelected = getIsInsuranceSelectedValue(
|
||||
vm.availableLineItems,
|
||||
|
|
@ -437,7 +452,7 @@ export default {
|
|||
},
|
||||
arePagePrerequisitesValid() {
|
||||
const payment = store.getters.order.payment;
|
||||
|
||||
|
||||
// prettier-ignore
|
||||
{
|
||||
const log = getQuerystringParameter(queryStrings.LOG);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
containsLineItemWithPartType,
|
||||
findLineItemsWithPartType,
|
||||
} from "@/helpers/service-package-helper";
|
||||
import { experimentSettings } from "@/constants/experiments";
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
import { partTypeStrings } from "@/constants/part-type-strings";
|
||||
import { nextTick } from "vue";
|
||||
|
|
@ -19,6 +20,18 @@ jest.mock("@/store", () => ({
|
|||
dispatch: jest.fn(),
|
||||
}));
|
||||
|
||||
const mockExperimentSettings = experimentSettings;
|
||||
|
||||
jest.mock("@/mixins/experiment-mixin.js", () => ({
|
||||
methods: {
|
||||
getSettingValue(settingName) {
|
||||
if (settingName === mockExperimentSettings.PROMO_ON_PACKAGE) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
describe("service-package-question.vue", () => {
|
||||
beforeEach(async () => {
|
||||
processedCmsContent = inputQuestionWidgetAnswers;
|
||||
|
|
@ -162,6 +175,19 @@ describe("service-package-question.vue", () => {
|
|||
wrapper.vm.servicePackageAnswers[0].buttonAuxillaryCopy.includes("As little as")
|
||||
).toBe(true);
|
||||
});
|
||||
it("should show service package discount when insurance is not selected", () => {
|
||||
// Arrange
|
||||
mockProps.isInsuranceSelected = false;
|
||||
const wrapper = setupMocks({});
|
||||
// Act
|
||||
|
||||
// Assert
|
||||
expect(
|
||||
wrapper.vm.servicePackageAnswers[0].additionalButtonData.Text.includes(
|
||||
"Special: Save $"
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
it("should return [] from nullSafeAvailableLineItems and not error out if availableLineItems is null", () => {
|
||||
// Arrange
|
||||
mockProps.availableLineItems = null;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ import {
|
|||
getLineItemsThatMatchPromos,
|
||||
} from "@/helpers/promotions-helper";
|
||||
import { containsRecalParts, getItemsWithoutRecalParts } from "@/helpers/recal-helper";
|
||||
import experimentMixin from "@/mixins/experiment-mixin.js";
|
||||
import { experimentSettings } from "@/constants/experiments";
|
||||
|
||||
export default {
|
||||
name: "servicePackageQuestion",
|
||||
|
|
@ -129,16 +131,22 @@ export default {
|
|||
buttonLabelSubCopy: this.getSubheaderTextFromCms(answer.SubWidgetName),
|
||||
buttonBodyCopy: this.getBodyTextFromCms(answer.SubWidgetName),
|
||||
//The package supports service-package-discount if it has the text value in CMS
|
||||
buttonAuxillaryCopy: this.getDiscountedPackagePriceString(
|
||||
answer.Name,
|
||||
this.isServicePackageDiscountOnOrder && answer.Text != ""
|
||||
),
|
||||
buttonAuxillaryCopy: this.isInsuranceSelected
|
||||
? this.getDiscountedPackagePriceString(answer.Name, false)
|
||||
: this.getDiscountedPackagePriceString(
|
||||
answer.Name,
|
||||
this.isServicePackageDiscountOnOrder &&
|
||||
this.discountPackageNames == answer.Name
|
||||
),
|
||||
buttonFooterCopy: this.getFooterTextFromCms(answer.SubWidgetName),
|
||||
additionalButtonData: {
|
||||
strikeThroughPrice: this.getPackagePriceString(answer.Name),
|
||||
servicePackageDiscount:
|
||||
this.isServicePackageDiscountOnOrder && answer.Text != "",
|
||||
Text: answer.Text + this.getServicePackageDiscountPrice(),
|
||||
this.isServicePackageDiscountOnOrder &&
|
||||
this.discountPackageNames == answer.Name,
|
||||
Text: this.isInsuranceSelected
|
||||
? false
|
||||
: "Special: Save $" + this.getServicePackageDiscountPrice(),
|
||||
},
|
||||
}));
|
||||
return modifiedAnswers;
|
||||
|
|
@ -149,6 +157,21 @@ export default {
|
|||
this.nullSafeAvailableLineItems
|
||||
);
|
||||
},
|
||||
discountPackageNames() {
|
||||
const discountServicePackage = experimentMixin.methods.getSettingValue(
|
||||
experimentSettings.PROMO_ON_PACKAGE
|
||||
);
|
||||
switch (discountServicePackage) {
|
||||
case "ECON":
|
||||
return packageNames.TIER_ONE;
|
||||
case "STANDARD":
|
||||
return packageNames.TIER_TWO;
|
||||
case "PREMIUM":
|
||||
return packageNames.TIER_THREE;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
frontWipersApplicableForTierTwo() {
|
||||
return shouldFrontWipersBeAvailable(
|
||||
this.glassToReplace,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,8 @@
|
|||
<template>
|
||||
<div
|
||||
:class="[this.additionalButtonData.Text ? 'discount-text' : '']"
|
||||
v-if="this.additionalButtonData.servicePackageDiscount"
|
||||
v-html="this.additionalButtonData.Text"></div>
|
||||
<baseInputButton v-bind="$props" @buttonClicked="handleAnswerChange" v-model="selectedValue">
|
||||
<div
|
||||
class="package-label"
|
||||
:class="[
|
||||
this.buttonLabelSubCopy ? 'has-subheader' : '',
|
||||
this.additionalButtonData.servicePackageDiscount ? 'has-text' : '',
|
||||
]"
|
||||
:class="[this.buttonLabelSubCopy ? 'has-subheader' : '']"
|
||||
for="testradio">
|
||||
<div class="package-specs">
|
||||
<div v-if="this.additionalButtonData.servicePackageDiscount" class="row">
|
||||
|
|
@ -82,6 +75,15 @@
|
|||
v-if="this.buttonFooterCopy"
|
||||
v-html="this.buttonFooterCopy"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="
|
||||
this.additionalButtonData.servicePackageDiscount &&
|
||||
this.additionalButtonData.Text
|
||||
"
|
||||
class="special-save-box">
|
||||
<span v-html="this.additionalButtonData.Text"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</baseInputButton>
|
||||
|
|
@ -143,20 +145,13 @@ export default {
|
|||
margin: 1rem 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
@include media-breakpoint-up(md) {
|
||||
display: flex;
|
||||
min-height: 336px;
|
||||
}
|
||||
//Unique breakpoint for this page only to accommodate price spacing issues
|
||||
//from use of position: absolute on .service-package-discount (per Design Team request)
|
||||
@media only screen and (min-width: 860px) {
|
||||
display: flex;
|
||||
min-height: 276px;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -179,19 +174,16 @@ export default {
|
|||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
min-height: 60px;
|
||||
max-height: 100px;
|
||||
max-height: 126px;
|
||||
@include media-breakpoint-up(md) {
|
||||
max-height: 500px;
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
transition: max-height 0.25s ease-in;
|
||||
|
||||
&.has-subheader {
|
||||
min-height: 80px;
|
||||
}
|
||||
&.has-text {
|
||||
border-radius: 0 0 0.5rem 0.5rem;
|
||||
border: 1px solid $green;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
|
|
@ -245,6 +237,9 @@ export default {
|
|||
background-color: $blue-100;
|
||||
border: 1px solid $blue;
|
||||
max-height: 500px;
|
||||
.special-save-box {
|
||||
background-color: $green-200;
|
||||
}
|
||||
}
|
||||
+ .package-label {
|
||||
&:before {
|
||||
|
|
@ -294,8 +289,8 @@ export default {
|
|||
bottom: 0.75rem;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 1.125rem;
|
||||
margin-left: 1.25rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
span.strikethrough-price {
|
||||
text-decoration: line-through;
|
||||
|
|
@ -316,28 +311,32 @@ export default {
|
|||
&.service-package-discount {
|
||||
color: $green;
|
||||
text-align: end;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
div.strikethrough-discount-price {
|
||||
text-decoration: line-through;
|
||||
margin-right: 0;
|
||||
font-weight: 400;
|
||||
font-size: 0.875rem;
|
||||
margin-right: 0.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.75rem;
|
||||
line-height: 20px;
|
||||
color: $gray-500;
|
||||
padding-right: 2px;
|
||||
color: $gray-550;
|
||||
@include media-breakpoint-up(md) {
|
||||
margin-right: 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
div.discount-price {
|
||||
color: $green;
|
||||
font-weight: 600;
|
||||
font-size: 1.625rem;
|
||||
}
|
||||
@include media-breakpoint-up(md) {
|
||||
position: absolute;
|
||||
bottom: 0.75rem;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
left: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -388,6 +387,21 @@ export default {
|
|||
font-weight: 600;
|
||||
letter-spacing: 0.75px;
|
||||
}
|
||||
.special-save-box {
|
||||
background-color: $green-100;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: auto;
|
||||
margin-left: -2rem;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 0.25rem;
|
||||
margin-top: 0.5rem;
|
||||
span {
|
||||
color: $green;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -669,6 +669,12 @@ function updateExternalParameterState() {
|
|||
if (externalParameterZipCode) {
|
||||
store.commit(storeMutations.UPDATE_EXTERNAL_PARAMETER_ZIP_CODE, externalParameterZipCode);
|
||||
}
|
||||
if (externalParameterEmail) {
|
||||
store.commit(
|
||||
storeMutations.UPDATE_EXTERNAL_PARAMETER_EMAIL_ADDRESS,
|
||||
externalParameterEmail
|
||||
);
|
||||
}
|
||||
if (externalParameterIsInsurance?.toUpperCase() == "TRUE") {
|
||||
store.commit(storeMutations.UPDATE_EXTERNAL_PARAMETER_IS_INSURANCE, true);
|
||||
store.commit(
|
||||
|
|
|
|||
|
|
@ -505,7 +505,6 @@ export const mutations = {
|
|||
saveExternalParameterState(externalParameterState);
|
||||
},
|
||||
resetExternalParameterQuoteState(state) {
|
||||
externalParameterState.quote.isInsurance = null;
|
||||
externalParameterState.quote.servicePackage = null;
|
||||
saveExternalParameterState(externalParameterState);
|
||||
},
|
||||
|
|
@ -1656,7 +1655,7 @@ export const actions = {
|
|||
applicationConfig.CASH_PARENT_ACCOUNT_NUMBER;
|
||||
const referralSequenceNumber = context.getters.order.referralSequenceNumber;
|
||||
|
||||
var endPoint = `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}&parentAccountNumber=${parentAccountNumber}&referralSequenceNumber=${referralSequenceNumber}`;
|
||||
var endPoint = `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}&parentAccountNumber=${parentAccountNumber}&referralSequenceNumber=${referralSequenceNumber}&applicationName=${applicationConfig.ANALYTICS_APPLICATION_NAME}`;
|
||||
if (lineItems) {
|
||||
endPoint += `&${lineItems}`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ process.env.VUE_APP_CURRENT_ENVIRONMENT = "Localhost";
|
|||
process.env.VUE_APP_MY_ACCOUNT = "https://myaccountdev.safelite.com/";
|
||||
|
||||
//process.env.VUE_APP_SAFELITE_HOP = "http://localhost:60966/fmgCheckoutShared.aspx";
|
||||
process.env.VUE_APP_SAFELITE_HOP = "https://sv2-safelitehop-sys.safelite.com/fmgCheckoutShared.aspx";
|
||||
process.env.VUE_APP_SAFELITE_HOP = "https://sv2-safelitehop-dev.safelite.com/fmgCheckoutShared.aspx";
|
||||
|
||||
// GA & GTM
|
||||
process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY =
|
||||
|
|
|
|||
Loading…
Reference in a new issue