diff --git a/src/constants/error-messages.js b/src/constants/error-messages.js
index 58f22ebe2..262979ed4 100644
--- a/src/constants/error-messages.js
+++ b/src/constants/error-messages.js
@@ -32,6 +32,7 @@ const errorMessages = {
DATE_REQUIRED: "Please select a date",
PHONE_REQUIRED: "Please enter your phone number",
PHONE_FORMAT: "Phone number must be 10 digits",
+ PHONE_EXTENSION_FORMAT: "The specified extension is invalid",
SMS_CONSENT_REQUIRED_1: "Please select checkbox to receive text messages",
SMS_CONSENT_REQUIRED_2: "Please select at least one consent option",
YEAR_REQUIRED: "Please select your vehicle year",
diff --git a/src/constants/experiments.js b/src/constants/experiments.js
index 4fab998af..81444f1e1 100644
--- a/src/constants/experiments.js
+++ b/src/constants/experiments.js
@@ -58,12 +58,17 @@ const experimentSettings = {
TIER_ONE: "TierOne",
TIER_TWO: "TierTwo",
TIER_THREE: "TierThree",
+ TIER_TWO_DESCRIPTION: "TierTwo_Description",
+ TIER_THREE_DESCRIPTION: "TierThree_Description",
// Consent Management
SHOW_CONSENT_MANAGEMENT: "ShowConsentManagement",
// YMM
BAILOUT_VIN_REQUIRED_VEHICLES: "BailoutVINRequiredVehicles",
+
+ // Promo Banner
+ SHOW_PROMO_BANNER: "ShowQuotePageRegionalPromoBanner",
};
const experimentTriggers = {
diff --git a/src/constants/query-strings.js b/src/constants/query-strings.js
index 1857643be..034e0a6ef 100644
--- a/src/constants/query-strings.js
+++ b/src/constants/query-strings.js
@@ -48,6 +48,7 @@ const queryStrings = {
FROM_HERITAGE: "fromheritage",
PHONE_NUMBER: "phonenumber",
OFFER_QUOTE: "offerquote",
+ PIA_AUTH_AMOUNT_ADJUST: "piaauthamountadjust",
};
export { queryStrings };
diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js
index 742e1c461..00875bb6f 100644
--- a/src/constants/store-actions.js
+++ b/src/constants/store-actions.js
@@ -118,6 +118,7 @@ const storeActions = {
SAVE_CCTOKEN: "saveCCToken",
SAVE_PAYPAL_TOKEN: "savePaypalToken",
SAVE_NEXTGEN_SETTLED_AMOUNT: "saveNextGenSettledAmount",
+ SAVE_AUTHORIZATION_AMOUNT: "saveAuthorizationAmount",
SAVE_IS_RECAL_ACK_OPT_IN: "saveIsRecalAckOptIn",
SAVE_IS_RECAL_ACKNOWLEDGED_FOR_SCHEDULING: "saveIsRecalAcknowledgedForScheduling",
SAVE_IS_OEM_GLASS_SELECTED: "saveIsOemGlassSelected",
diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js
index 8437a395e..d60bca6ea 100644
--- a/src/constants/store-mutations.js
+++ b/src/constants/store-mutations.js
@@ -3,6 +3,7 @@ const storeMutations = {
UPDATE_CCTOKEN: "updateCCToken",
UPDATE_PAYPAL_TOKEN: "updatePaypalToken",
UPDATE_NEXTGEN_SETTLED_AMOUNT: "updateNextGenSettledAmount",
+ UPDATE_AUTHORIZATION_AMOUNT: "updateAuthorizationAmount",
// VEHICLE MUTATIONS
UPDATE_YEAR: "updateYear",
diff --git a/src/digital-components/date-picker/date-picker.vue b/src/digital-components/date-picker/date-picker.vue
index ae6ca6229..a94a4e079 100644
--- a/src/digital-components/date-picker/date-picker.vue
+++ b/src/digital-components/date-picker/date-picker.vue
@@ -114,11 +114,9 @@
-
+
+
+
@@ -742,15 +740,6 @@ export default {
diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue
index 50512bcbf..c21b9164c 100644
--- a/src/layouts/quote/quote.vue
+++ b/src/layouts/quote/quote.vue
@@ -5,6 +5,14 @@
+
@@ -47,8 +55,7 @@
+ cmsWidgetName="AfterpayBannerWidget" />
+ class="quote-disclaimer text-left text-md-center" />
+
@@ -134,6 +146,7 @@ import textBlock from "@/digital-components/text-block/text-block";
import contentGroupModal from "@/fmg-components/content-group-modal/content-group-modal";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
import afterpayModalBanner from "@/layouts/quote/afterpay-modal-banner/afterpay-modal-banner";
+import promoBanner from "@/layouts/quote/promo-banner/promo-banner";
import recalDisclaimer from "@/layouts/quote/recal-disclaimer/recal-disclaimer.vue";
import saveProgressModalQuestion from "@/fmg-components/save-progress-modal-question/save-progress-modal-question";
import saveProgressPopupQuestion from "@/fmg-components/save-progress-popup-question/save-progress-popup-question";
@@ -684,6 +697,12 @@ export default {
showAfterpayBanner() {
return !this.isRecalibrationOnOrder || !this.shouldHideRecalibration;
},
+ showPromoBanner() {
+ return experimentMixin.methods.hasSettingEqualTo(
+ experimentSettings.SHOW_PROMO_BANNER,
+ "true"
+ );
+ },
isRecalPriceRemove() {
return (
experimentMixin.methods
@@ -1041,6 +1060,7 @@ export default {
contentGroupModal,
loadingModal,
afterpayModalBanner,
+ promoBanner,
promoModalQuestion,
recalDisclaimer,
saveProgressModalQuestion,
@@ -1166,4 +1186,7 @@ export default {
:deep(.promo-modal-question a) {
@include responsive-font-size-md(0.875rem, 1rem);
}
+.quote-disclaimer:last-child {
+ margin-bottom: 1.5rem;
+}
diff --git a/src/layouts/quote/service-package-question/service-package-question.spec.js b/src/layouts/quote/service-package-question/service-package-question.spec.js
index 1d0f78c1a..46b084d02 100644
--- a/src/layouts/quote/service-package-question/service-package-question.spec.js
+++ b/src/layouts/quote/service-package-question/service-package-question.spec.js
@@ -856,6 +856,52 @@ describe("service-package-question.vue, matching business rules for package disp
getExperimentPackageLabelSpy.mockRestore();
});
+ it("should use experiment package descriptions when ServicePackageNameTest is active", () => {
+ const getExperimentPackageDescriptionSpy = jest
+ .spyOn(servicePackageQuestion.methods, "getExperimentPackageDescription")
+ .mockImplementation((tierName) => {
+ const experimentPackageDescriptions = {
+ [packageNames.TIER_TWO]: "Most popular choice",
+ [packageNames.TIER_THREE]: "Best value",
+ };
+
+ return experimentPackageDescriptions[tierName] ?? null;
+ });
+
+ const packageNameKey = "05_01_CSR_Quote_Standard_Repair";
+ Object.assign(processedCmsContent, mockProcessedCmsContent[packageNameKey]);
+ mockProps.availableLineItems.push(driverFrontWiperLineItem);
+ mockProps.availableLineItems.push(passengerFrontWiperLineItem);
+ const wrapper = setupMocks({
+ mountOptionsMockData: {
+ store: {
+ getters: {
+ order: {
+ damage: {
+ isRepair: true,
+ glassToReplace: [],
+ },
+ },
+ hasAnyNonWindshieldGlassParts: false,
+ },
+ },
+ },
+ });
+
+ expect(
+ wrapper.vm.servicePackageAnswers[0].additionalButtonData.packageDescription
+ ).toBeNull();
+ expect(wrapper.vm.servicePackageAnswers[1].additionalButtonData.packageDescription).toBe(
+ "Most popular choice"
+ );
+ expect(wrapper.vm.servicePackageAnswers[2].additionalButtonData.packageDescription).toBe(
+ "Best value"
+ );
+ expect(wrapper.vm.servicePackageAnswers[1].buttonLabelSubCopy).toBe("MOST POPULAR");
+ expect(wrapper.vm.servicePackageAnswers[2].buttonLabelSubCopy).toBe("");
+
+ getExperimentPackageDescriptionSpy.mockRestore();
+ });
it("should use CMS package names when ServicePackageNameTest is not active", () => {
const packageNameKey = "05_01_CSR_Quote_Standard_Repair";
Object.assign(processedCmsContent, mockProcessedCmsContent[packageNameKey]);
diff --git a/src/layouts/quote/service-package-question/service-package-question.vue b/src/layouts/quote/service-package-question/service-package-question.vue
index 4a54ee3f5..905898481 100644
--- a/src/layouts/quote/service-package-question/service-package-question.vue
+++ b/src/layouts/quote/service-package-question/service-package-question.vue
@@ -159,6 +159,7 @@ export default {
? false
: "Special: Save $" + this.getDiscountPrice(answer.Name),
isInsuranceSelected: this.isInsuranceSelected,
+ packageDescription: this.getExperimentPackageDescription(answer.Name),
},
}));
@@ -265,6 +266,19 @@ export default {
);
},
getExperimentPackageLabel(tierName) {
+ return this.getExperimentPackageSetting(tierName, {
+ [packageNames.TIER_ONE]: experimentSettings.TIER_ONE,
+ [packageNames.TIER_TWO]: experimentSettings.TIER_TWO,
+ [packageNames.TIER_THREE]: experimentSettings.TIER_THREE,
+ });
+ },
+ getExperimentPackageDescription(tierName) {
+ return this.getExperimentPackageSetting(tierName, {
+ [packageNames.TIER_TWO]: experimentSettings.TIER_TWO_DESCRIPTION,
+ [packageNames.TIER_THREE]: experimentSettings.TIER_THREE_DESCRIPTION,
+ });
+ },
+ getExperimentPackageSetting(tierName, tierSettingKeys) {
if (
!experimentMixin.methods.hasSettingEqualTo(
experimentSettings.SHOW_SERVICE_PACKAGE_NAME_TEST,
@@ -274,13 +288,8 @@ export default {
return null;
}
- const tierSettingKey = {
- [packageNames.TIER_ONE]: experimentSettings.TIER_ONE,
- [packageNames.TIER_TWO]: experimentSettings.TIER_TWO,
- [packageNames.TIER_THREE]: experimentSettings.TIER_THREE,
- }[tierName];
-
- return tierSettingKey ? experimentMixin.methods.getSettingValue(tierSettingKey) : null;
+ const settingKey = tierSettingKeys[tierName];
+ return settingKey ? experimentMixin.methods.getSettingValue(settingKey) : null;
},
getHeaderTextFromCms(cmsWidgetName) {
return this.getCmsContent(cmsWidgetName, "HeaderText");
diff --git a/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue b/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue
index 959c7345e..bae95af8f 100644
--- a/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue
+++ b/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue
@@ -2,7 +2,10 @@
diff --git a/src/layouts/service-location/shop-question/shop-question-popup.vue b/src/layouts/service-location/shop-question/shop-question-popup.vue
index c66f4c79a..385fc27a3 100644
--- a/src/layouts/service-location/shop-question/shop-question-popup.vue
+++ b/src/layouts/service-location/shop-question/shop-question-popup.vue
@@ -32,10 +32,10 @@
:isRequired="false"
:validationRules="''" />
-
+
-
+
{
+ if (glass.answerData) {
+ glass.answerData = {};
+ }
+ });
+ },
hasPartQuestions(partsOrQuestions) {
return partsOrQuestions?.some((pq) => pq.partQuestions?.length > 0);
},
@@ -114,11 +122,12 @@ export default {
);
});
// set the answerString to use for answerSelected
- if (chosenAns.nextQuestionSequence) {
- answerString = `${answeredQuestion.questionNum}|nextQuestion|${chosenAns.nextQuestionSequence}|${chosenAns.answerText}`;
- } else {
- answerString = `${answeredQuestion.questionNum}|answer|${chosenAns.answerResult}|${chosenAns.answerText}`;
- }
+ answerString = buildQuestionChainAnswerValue({
+ questionSequence: answeredQuestion.questionNum,
+ nextQuestionSequence: chosenAns.nextQuestionSequence,
+ answerResult: chosenAns.answerResult,
+ answerText: chosenAns.answerText,
+ });
// mark this question as answered (question-chain will read this)
glass.questions[answeredQuestion.questionNum - 1].answerSelected =
@@ -177,6 +186,8 @@ export default {
*/
const self = vm ?? this;
+ const isIncomplete = !!answer.incomplete;
+ const hadSavedAnswer = !!self.questionsData[answer.index]?.answerData?.answerResult;
// clear out any preloaded answers
self.selectedAnswers = {};
@@ -193,7 +204,6 @@ export default {
*/
const answeredQuestionText = answeredQuestion.questionText.toUpperCase();
- const answeredQuestionAnswer = answeredQuestion.selectedAnswer.toUpperCase();
const answeredQuestionAnswerText =
answeredQuestion.selectedAnswerText.toUpperCase();
const answeredQuestionNum = answeredQuestion.questionNum;
@@ -208,8 +218,7 @@ export default {
if (answeredQuestionIndex === 0) question.answerSelected = null;
if (answeredQuestionNum - 1 === questionIndex) {
- // on the right question
- question.answerSelected = answeredQuestionAnswer;
+ question.answerSelected = answeredQuestion.selectedAnswer;
}
});
}
@@ -346,6 +355,27 @@ export default {
});
});
+ if (isIncomplete) {
+ // User changed an earlier answer; downstream questions were cleared in the chain
+ self.questionsData[answer.index].answerData = null;
+ self.currentGlassIndex = answer.index;
+
+ if (hadSavedAnswer) {
+ self.questionsData[answer.index].key =
+ (self.questionsData[answer.index].key ??
+ self.questionsData[answer.index].answerKey ??
+ answer.index) + Date.now().toString();
+ }
+
+ return;
+ }
+
+ // Force re-render so the updated selection displays when changing a prior answer
+ self.questionsData[answer.index].key =
+ (self.questionsData[answer.index].key ??
+ self.questionsData[answer.index].answerKey ??
+ answer.index) + Date.now().toString();
+
// set final answer data for the current answered glass part
self.questionsData[answer.index].answerData = {
answerResult: answer.answerResult,
diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js
index 0fd027258..a557adefa 100644
--- a/src/mixins/vehicle-questions-mixin.spec.js
+++ b/src/mixins/vehicle-questions-mixin.spec.js
@@ -499,6 +499,88 @@ describe("vehicle-questions-mixin", () => {
// Assert
expect(wrapper.vm.selectedAnswers).toMatchObject({});
});
+
+ test("should clear answerData and keep currentGlassIndex when answer is incomplete", () => {
+ const answer = {
+ incomplete: true,
+ answeredQuestions: [
+ {
+ questionText: "Is this the Overland edition?",
+ selectedAnswer: "1|nextQuestion|5|No",
+ selectedAnswerText: "No",
+ questionNum: 1,
+ },
+ ],
+ index: 0,
+ };
+ const { wrapper } = setupMocks({});
+
+ wrapper.vm.currentGlassIndex = 1;
+ wrapper.vm.questionsData = [
+ {
+ glassLocation: "Windshield",
+ glassName: "Single",
+ questions: [
+ {
+ questionSequence: 1,
+ questionText: "Is this the Overland edition?",
+ answers: [],
+ },
+ ],
+ answerData: { answerResult: "OLD-PART" },
+ answerKey: "Windshield-Single",
+ },
+ {
+ glassLocation: "Driver",
+ glassName: "Front",
+ questions: [],
+ answerData: { answerResult: "OTHER-PART" },
+ },
+ ];
+
+ wrapper.vm.handleCompletedQuestionChainAnswers(answer, "", wrapper.vm);
+
+ expect(wrapper.vm.questionsData[0].answerData).toBeNull();
+ expect(wrapper.vm.questionsData[1].answerData).toBeNull();
+ expect(wrapper.vm.currentGlassIndex).toBe(0);
+ });
+
+ test("should not bump key when incomplete answer had no saved answer", () => {
+ const answer = {
+ incomplete: true,
+ answeredQuestions: [
+ {
+ questionText: "Is this the Overland edition?",
+ selectedAnswer: "1|nextQuestion|2|Yes",
+ selectedAnswerText: "Yes",
+ questionNum: 1,
+ },
+ ],
+ index: 0,
+ };
+ const { wrapper } = setupMocks({});
+
+ wrapper.vm.questionsData = [
+ {
+ glassLocation: "Windshield",
+ glassName: "Single",
+ questions: [
+ {
+ questionSequence: 1,
+ questionText: "Is this the Overland edition?",
+ answers: [],
+ },
+ ],
+ answerData: null,
+ answerKey: "Windshield-Single",
+ key: "stable-key",
+ },
+ ];
+
+ wrapper.vm.handleCompletedQuestionChainAnswers(answer, "", wrapper.vm);
+
+ expect(wrapper.vm.questionsData[0].key).toBe("stable-key");
+ });
});
describe("questions in glass parts that are after the answered glass", () => {
diff --git a/src/router/methods/route-logic/adyen-return.js b/src/router/methods/route-logic/adyen-return.js
index f15168861..9a287b243 100644
--- a/src/router/methods/route-logic/adyen-return.js
+++ b/src/router/methods/route-logic/adyen-return.js
@@ -2,7 +2,7 @@ import { routeData } from "@/router/constants/routes";
import { createAdyenCheckout, getSessionInfo } from "@/helpers/adyen-helper";
import { mapAdyenToFmgPaymentMethod, generateCcToken } from "@/helpers/adyen-helper";
import baseMixin from "@/mixins/base-mixin.js";
-import { getAmountDue } from "@/helpers/pricing-helper";
+import { getPiaAuthorizationAmount } from "@/helpers/pricing-helper";
import store from "@/store";
import { storeActions } from "@/constants/store-actions";
import { submitWorkOrder } from "@/helpers/heritage-integration/order-helper.js";
@@ -49,7 +49,7 @@ export async function adyenReturnBeforeEnter(to, from) {
// TODO once afterpay info is returned, create cc token and submit order.
const paymentMethod = mapAdyenToFmgPaymentMethod(sessionInfo?.paymentMethod);
- const amountDue = getAmountDue(store.getters.order.lineItems);
+ const authorizationAmount = getPiaAuthorizationAmount(store.getters.order.lineItems);
const ccToken = generateCcToken(sessionInfo);
ccToken.authCode = "831001";
@@ -68,7 +68,13 @@ export async function adyenReturnBeforeEnter(to, from) {
await baseMixin.methods.dispatchStoreAction(
storeActions.SAVE_NEXTGEN_SETTLED_AMOUNT,
- amountDue,
+ authorizationAmount,
+ false
+ );
+
+ await baseMixin.methods.dispatchStoreAction(
+ storeActions.SAVE_AUTHORIZATION_AMOUNT,
+ authorizationAmount,
false
);
diff --git a/src/store/index.js b/src/store/index.js
index d9ca5c6fe..d6410b196 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -133,6 +133,8 @@ const getDefaultState = () => {
dateOfLoss: null,
damageCause: null,
installOemGlass: null,
+ damageCity: null,
+ damageState: null,
},
lineItems: {
glassParts: null,
@@ -162,6 +164,7 @@ const getDefaultState = () => {
inactivePromos: null,
paypalToken: null,
nextGenSettledAmount: 0,
+ authorizationAmount: null,
ccToken: {
subscriptionId: null,
expMonth: null,
@@ -488,6 +491,9 @@ export const mutations = {
updateNextGenSettledAmount(state, nextGenSettledAmount) {
state.order.payment.nextGenSettledAmount = nextGenSettledAmount;
},
+ updateAuthorizationAmount(state, authorizationAmount) {
+ state.order.payment.authorizationAmount = authorizationAmount;
+ },
updateInsuranceVerifiedStatus(state, isVerified) {
state.order.payment.insuranceCoverage.isVerified = isVerified;
},
@@ -614,6 +620,8 @@ export const mutations = {
if (damageDetails) {
state.order.damage.dateOfLoss = damageDetails.dateOfLoss;
state.order.damage.damageCause = damageDetails.damageCause;
+ state.order.damage.damageState = damageDetails.damageState;
+ state.order.damage.damageCity = damageDetails.damageCity;
}
},
@@ -887,7 +895,8 @@ export const mutations = {
sessionInformation.order.damage?.dateOfLoss
);
state.order.damage.damageCause = sessionInformation.order.damage?.damageCause;
-
+ state.order.damage.damageState = sessionInformation.order.damage?.damageState;
+ state.order.damage.damageCity = sessionInformation.order.damage?.damageCity;
state.order.damage.partQuestionAnswers =
sessionInformation.order.damage.partQuestionAnswers;
state.order.damage.moldingQuestionAnswers =
@@ -2008,35 +2017,30 @@ export const actions = {
const vehicle = context.getters.vehicle;
const damage = context.getters.damage;
const order = context.state.order;
+ const payment = context.getters.payment;
- const carId = vehicle.carId;
- const glassArray = damage.glassToReplace;
- const zipCode = order.serviceLocation.zipCode;
- const vin = vehicle.vin;
- const serviceType = damage.isRepair ? "Repair" : "Install";
- const parentAccountNumber = context.getters.payment.parentAccountNumber;
- const referralSeqNumber = order.referralSequenceNumber;
-
- // create a new array to avoid mutating state
- const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray);
+ const glassArrayForPayload = convertGlassPieceNamingForApi(damage.glassToReplace);
const partsOrQuestionsEndpoint = vehicle.vinRequired
? endpoints.GetPartsOrQuestionsV2
: endpoints.GetPartsOrQuestions;
+ const requestPayload = {
+ carId: vehicle.carId,
+ glassPieces: glassArrayForPayload,
+ zip: order.serviceLocation.zipCode,
+ vin: vehicle.vin,
+ serviceType: damage.isRepair ? "Repair" : "Install",
+ referralSeqNumber: order.referralSequenceNumber,
+ parentAccountNumber: payment.parentAccountNumber,
+ billToAccountNumber: payment.billToAccountNumber,
+ };
+
const response = await globalMethods
.callHttpClient({
method: partsOrQuestionsEndpoint.method,
endpoint: partsOrQuestionsEndpoint.url,
- payload: {
- carId: carId,
- glassPieces: glassArrayForPayload,
- zip: zipCode,
- vin: vin,
- serviceType: serviceType,
- referralSeqNumber: referralSeqNumber,
- parentAccountNumber: parentAccountNumber,
- },
+ payload: requestPayload,
logApiCall: true,
pageNameToLog: pageNameToLog,
})
@@ -2072,32 +2076,25 @@ export const actions = {
const order = context.state.order;
const payment = context.getters.payment;
- const carId = vehicle.carId;
- const glassArray = damage.glassToReplace;
- const resultsArray = damage.partQuestionAnswers;
- const zipCode = order.serviceLocation.zipCode;
- const vin = vehicle.vin;
- const serviceType = order.serviceLocation?.appointmentType;
- const referralSeqNumber = order.referralSequenceNumber;
- const parentAccountNumber = payment.parentAccountNumber;
+ const glassArrayForPayload = convertGlassPieceNamingForApi(damage.glassToReplace);
+ const resultsArrayForPayload = convertResultsForApi(damage.partQuestionAnswers);
- // create a new array to avoid mutating state
- const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray);
- const resultsArrayForPayload = convertResultsForApi(resultsArray);
+ const requestPayload = {
+ carId: vehicle.carId,
+ glassPieces: glassArrayForPayload,
+ answerResults: resultsArrayForPayload,
+ zip: order.serviceLocation.zipCode,
+ vin: vehicle.vin,
+ serviceType: order.serviceLocation?.appointmentType,
+ referralSeqNumber: order.referralSequenceNumber,
+ parentAccountNumber: payment.parentAccountNumber,
+ billToAccountNumber: payment.billToAccountNumber,
+ };
const response = await globalMethods.callHttpClient({
method: endpoints.GetParts.method,
endpoint: endpoints.GetParts.url,
- payload: {
- carId: carId,
- glassPieces: glassArrayForPayload,
- answerResults: resultsArrayForPayload,
- zip: zipCode,
- vin: vin,
- serviceType: serviceType,
- referralSeqNumber: referralSeqNumber,
- parentAccountNumber: parentAccountNumber,
- },
+ payload: requestPayload,
logApiCall: true,
pageNameToLog: pageNameToLog,
});
@@ -2860,6 +2857,8 @@ export const actions = {
installOemGlass: order.damage.installOemGlass,
dateOfLoss: order.damage.dateOfLoss,
damageCause: order.damage.damageCause,
+ damageState: order.damage.damageState,
+ damageCity: order.damage.damageCity,
},
lineItems: {
glassParts: lineItems.glassParts,
@@ -2893,6 +2892,9 @@ export const actions = {
order.payment.piaType == paymentMethods.APPLE_PAY ? true : false,
paypalToken: order.payment.paypalToken,
nextGenSettledAmount: order.payment.nextGenSettledAmount,
+ ...(order.payment.authorizationAmount > 0
+ ? { authorizationAmount: order.payment.authorizationAmount }
+ : {}),
ccToken: {
subscriptionId: order.payment.ccToken.subscriptionId,
expMonth: order.payment.ccToken.expMonth,
@@ -3047,6 +3049,10 @@ export const actions = {
context.commit(storeMutations.UPDATE_NEXTGEN_SETTLED_AMOUNT, nextGenSettledAmount);
},
+ saveAuthorizationAmount(context, authorizationAmount) {
+ context.commit(storeMutations.UPDATE_AUTHORIZATION_AMOUNT, authorizationAmount);
+ },
+
savePaypalToken(context, ppToken) {
context.commit(storeMutations.UPDATE_PAYPAL_TOKEN, ppToken);
},
diff --git a/src/store/store.spec.js b/src/store/store.spec.js
index 74cda6c9f..72eaac142 100644
--- a/src/store/store.spec.js
+++ b/src/store/store.spec.js
@@ -920,6 +920,105 @@ describe("Actions", () => {
);
});
+ it("saveSession action, includes authorizationAmount when PIA was authorized", async () => {
+ const context = createAuthorizationAmountSaveSessionContext(312.45);
+
+ globalMethods.callHttpClient.mockImplementation(() => {
+ return Promise.resolve({ data: { referralNumber: 123 } });
+ });
+
+ await actions.saveSession(context, { pageNameToLog: "test" });
+
+ expect(globalMethods.callHttpClient).toHaveBeenCalledWith(
+ expect.objectContaining({
+ payload: expect.objectContaining({
+ order: expect.objectContaining({
+ payment: expect.objectContaining({
+ authorizationAmount: 312.45,
+ }),
+ }),
+ }),
+ })
+ );
+ });
+
+ it("saveSession action, omits authorizationAmount when PIA was not authorized", async () => {
+ const context = createAuthorizationAmountSaveSessionContext(null);
+
+ globalMethods.callHttpClient.mockImplementation(() => {
+ return Promise.resolve({ data: { referralNumber: 123 } });
+ });
+ globalMethods.callHttpClient.mockClear();
+
+ await actions.saveSession(context, { pageNameToLog: "test" });
+
+ const callPayload = globalMethods.callHttpClient.mock.calls[0][0].payload;
+ expect(callPayload.order.payment.authorizationAmount).toBeUndefined();
+ });
+
+ function createAuthorizationAmountSaveSessionContext(authorizationAmount) {
+ const context = state;
+ const damage = {
+ numberOfChips: "2",
+ partQuestionAnswers: {},
+ moldingQuestionAnswers: {},
+ capabilityQuestionAnswers: {},
+ };
+
+ context.getters = {
+ vehicle: { registration: {} },
+ order: { damage },
+ damage: {},
+ applicationUser: {
+ lastPageVisited: "test-page",
+ crmCustomerId: "xxx-xxx-xxx",
+ savedSessionId: "xxx-xxx-xxx",
+ },
+ };
+ context.state = {
+ order: {
+ damage,
+ payment: {
+ insuranceCoverage: { isVerified: false },
+ isInsurance: false,
+ authorizationAmount,
+ ccToken: {
+ subscriptionId: authorizationAmount ? "sub-123" : null,
+ expMonth: null,
+ expYear: null,
+ cardType: null,
+ billToPostalCode: null,
+ billToFirstName: null,
+ billToLastName: null,
+ referenceNumber: null,
+ authCode: authorizationAmount ? "831001" : null,
+ transactionId: null,
+ transReferenceNumber: null,
+ lastFour: null,
+ },
+ },
+ serviceLocation: {},
+ customer: {
+ emailAddress: "test@safelite.com",
+ firstName: "John",
+ lastName: "Doe",
+ isSmsOptIn: true,
+ phoneNumber: "1234567890",
+ address: {
+ streetAddress: "123 Main St",
+ streetAddress2: "Apt 1",
+ city: "Anytown",
+ state: "OH",
+ zipCode: "12345",
+ },
+ },
+ lineItems: {},
+ },
+ };
+
+ return context;
+ }
+
it("loadSession action, returns order information, calls mutation", async () => {
// Arrange
const context = state;
diff --git a/src/ux-components/button-main/button-main.spec.js b/src/ux-components/button-main/button-main.spec.js
index 76e9afe28..9324726a0 100644
--- a/src/ux-components/button-main/button-main.spec.js
+++ b/src/ux-components/button-main/button-main.spec.js
@@ -36,48 +36,6 @@ describe("buttonMain.vue", () => {
expect(button.attributes()["aria-disabled"]).toEqual("true");
});
- it("Should return loader color", async () => {
- // Arrange
- const wrapper = shallowMount(
- buttonMain,
- setupMocks({
- propsData: {
- loaderColor: "blue",
- loaderEnabled: true,
- },
- })
- );
-
- // Act
- wrapper.vm.clicked();
- await nextTick();
-
- // Assert
- const loader = wrapper.find("loader-stub");
- expect(loader.attributes("class")).toContain("blue");
- });
-
- it("Should return loader position", async () => {
- // Arrange
- const wrapper = shallowMount(
- buttonMain,
- setupMocks({
- propsData: {
- loaderPosition: "right",
- loaderEnabled: true,
- },
- })
- );
-
- // Act
- wrapper.vm.clicked();
- await nextTick();
-
- // Assert
- const loader = wrapper.find("loader-stub");
- expect(loader.attributes("class")).toContain("right");
- });
-
it("Should set 'isLoaderDisplayed' to false when calling 'removeLoader'", async () => {
// Arrange
const wrapper = shallowMount(
diff --git a/src/ux-components/button-main/button-main.vue b/src/ux-components/button-main/button-main.vue
index 87eb28841..d91ebf7cd 100644
--- a/src/ux-components/button-main/button-main.vue
+++ b/src/ux-components/button-main/button-main.vue
@@ -12,7 +12,8 @@
+ :loaderColor="loaderColor"
+ :loaderPosition="loaderPosition" />
@@ -64,6 +65,7 @@ export default {