From ec85a33693f822a19782f8c2884dfba2e28a5fd1 Mon Sep 17 00:00:00 2001 From: Michaela Brydon Date: Fri, 1 Mar 2024 17:57:59 -0500 Subject: [PATCH 01/22] Removing unnecessary --- src/layouts/coverage-statement/coverage-statement.vue | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index f5ab548d..02848781 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -128,7 +128,6 @@ import baseFormMixin from '@/mixins/base-form-mixin.js'; import navigationScenarios from '@/router/router-constants/navigation-scenarios.js'; import routerParams from '@/router/router-constants/router-params'; import issPageValues from '@/router/router-constants/issPage-values'; -import bailoutCode from '@/constants/bailoutCode'; import bailoutMessage from '@/constants/bailoutMessage'; export default { @@ -405,7 +404,6 @@ export default { ); } }, - processIfStatements, getHeaderTextFromCms(cmsWidgetName) { const header = this.getCmsContent(cmsWidgetName, 'HeaderText'); return this.processIfStatements(header, 'custom', this.getCustomValueFromString); From 5ac9970d655bc661c2858ac18538591c0b8f6ae4 Mon Sep 17 00:00:00 2001 From: Michaela Brydon Date: Fri, 1 Mar 2024 18:01:23 -0500 Subject: [PATCH 02/22] Getting rid of mainStore data property --- .../coverage-statement/coverage-statement.vue | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index 02848781..51ad2a5d 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -177,7 +177,14 @@ export default { await useMainStore().getFinalDeductible(); pricingResults = await useMainStore().getPriceOrderItems(availableLineItems) .catch((err) => { - useMainStore().setBailout(to, bailoutMessage.pricingResponseError(availableLineItems.map((li) => li.partNumber), { code: err.code, message: err.message, data: err.data })); + useMainStore() + .setBailout( + to, + bailoutMessage.pricingResponseError( + availableLineItems.map((li) => li.partNumber), + { code: err.code, message: err.message, data: err.data } + ) + ); hasBailedOut = true; next(`/?issPage=${issPageValues.BAILOUT_PAGE}`); }); @@ -198,10 +205,6 @@ export default { }); } }, - setup() { - const mainStore = useMainStore(); - return { mainStore }; - }, data() { return { availableLineItems: [], @@ -368,7 +371,7 @@ export default { }, async navigateForward() { if (this.unverified || this.verifiedDeductible) { - this.mainStore.saveSupportingItems(this.supportingItems); + useMainStore().saveSupportingItems(this.supportingItems); this.$router.navigate( navigationScenarios.CLICKED_FORWARD, this.$route, @@ -378,7 +381,7 @@ export default { } else if (this.verifiedITAC || this.verifiedNoComp) { useMainStore().updateIsSafeliteProvider(this.selectedProvider === 'Safelite'); if (this.selectedProvider === 'Safelite') { - this.mainStore.saveSupportingItems(this.supportingItems); + useMainStore().saveSupportingItems(this.supportingItems); this.$router.navigate( navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, this.$route, @@ -386,7 +389,7 @@ export default { { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } ); } else { - this.mainStore.setBailout(this.$router.currentRoute, bailoutMessage.RequestCallback()); + useMainStore().setBailout(this.$router.currentRoute, bailoutMessage.RequestCallback()); this.$router.navigate( navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, this.$route, @@ -395,7 +398,7 @@ export default { ); } } else { - this.mainStore.setBailout(this.$router.currentRoute, bailoutMessage.coverageStatementInvalidState()); + useMainStore().setBailout(this.$router.currentRoute, bailoutMessage.coverageStatementInvalidState()); this.$router.navigate( navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE, this.$route, @@ -406,23 +409,23 @@ export default { }, getHeaderTextFromCms(cmsWidgetName) { const header = this.getCmsContent(cmsWidgetName, 'HeaderText'); - return this.processIfStatements(header, 'custom', this.getCustomValueFromString); + return processIfStatements(header, 'custom', this.getCustomValueFromString); }, getSubheaderTextFromCms(cmsWidgetName) { const subHeader = this.getCmsContent(cmsWidgetName, 'SubHeaderText'); - return this.processIfStatements(subHeader, 'custom', this.getCustomValueFromString); + return processIfStatements(subHeader, 'custom', this.getCustomValueFromString); }, getBodyTextFromCms(cmsWidgetName) { const bodyText = this.getCmsContent(cmsWidgetName, 'BodyText'); - return this.processIfStatements(bodyText, 'custom', this.getCustomValueFromString); + return processIfStatements(bodyText, 'custom', this.getCustomValueFromString); }, getSecondaryTextFromCms(cmsWidgetName) { const secondaryText = this.getCmsContent(cmsWidgetName, 'SecondaryText'); - return this.processIfStatements(secondaryText, 'custom', this.getCustomValueFromString); + return processIfStatements(secondaryText, 'custom', this.getCustomValueFromString); }, getExplantoryTextFromCms(cmsWidgetName) { const explanatoryText = this.getCmsContent(cmsWidgetName, 'BodyText'); - return this.processIfStatements(explanatoryText, 'custom', this.getCustomValueFromString); + return processIfStatements(explanatoryText, 'custom', this.getCustomValueFromString); }, getCustomValueFromString(str) { switch (str) { From 090188ed64ec6b66fa6cc53874b1e09f1ce6c70f Mon Sep 17 00:00:00 2001 From: Michaela Brydon Date: Mon, 4 Mar 2024 13:28:39 -0500 Subject: [PATCH 03/22] Partial --- .../coverage-statement/coverage-statement.vue | 191 +++++++++--------- src/store/index.js | 7 +- 2 files changed, 98 insertions(+), 100 deletions(-) diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index 51ad2a5d..80e1665f 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -38,7 +38,7 @@ {{ formattedDeductible }}
{{ formattedServicePrice }}
@@ -53,8 +53,8 @@ ref="verifiedITACAlert" class="mb-5" cmsWidgetName="VerifiedITACAlert" - :manualHeadline="verifiedITACAlertHeader" - :manualCopy="verifiedITACAlertBody" + :manualHeadline="verifiedItacAlertHeader" + :manualCopy="verifiedItacAlertBody" alertClass="alert-success" :isDismissible="false"> @@ -67,18 +67,18 @@ v-html="nextStepsBody"> @@ -88,7 +88,7 @@ cmsWidgetName="SiteFooterWidget" :isForwardActionDisabled="!meta.valid" @backClicked="navigateBackByVehicleQuestions" - @forwardClicked="forwardButtonAction" /> + @forwardClicked="navigateForward" /> @@ -129,6 +129,9 @@ import navigationScenarios from '@/router/router-constants/navigation-scenarios. import routerParams from '@/router/router-constants/router-params'; import issPageValues from '@/router/router-constants/issPage-values'; import bailoutMessage from '@/constants/bailoutMessage'; +import widgetFields from '@/constants/cms-widget-fields.js'; + +const SAFELITE_PROVIDER = 'Safelite'; export default { name: 'coverage-statement', @@ -163,8 +166,8 @@ export default { ]; const resultMap = await settleAllPromises(promiseResultMap); - const clonedGlassParts = useMainStore().order.lineItems.glassParts - ? JSON.parse(JSON.stringify(useMainStore().order.lineItems.glassParts)) + const clonedGlassParts = useMainStore().lineItems.glassParts + ? JSON.parse(JSON.stringify(useMainStore().lineItems.glassParts)) : []; const availableLineItems = [ ...(resultMap.supportingItems ?? []), @@ -173,7 +176,7 @@ export default { let hasBailedOut = false; let pricingResults = []; - if (useMainStore().order.policy.policyLookupSuccessful && useMainStore().order.vehicle.policyVehicleId >= 0) { + if (useMainStore().policy.policyLookupSuccessful && useMainStore().vehicle.policyVehicleId >= 0) { await useMainStore().getFinalDeductible(); pricingResults = await useMainStore().getPriceOrderItems(availableLineItems) .catch((err) => { @@ -196,9 +199,9 @@ export default { vm.setCmsContent(resultMap.cmsContent); vm.setSupportingItems(resultMap.supportingItems); // eslint-disable-next-line no-param-reassign - vm.availableLineItems = pricingResults; + vm.setAvailableLineItems(pricingResults); vm.$refs.loadingModal.showModal(); - vm.initializeComponent(availableLineItems); + vm.initializeComponent(); if (!vm.unverified) { useMainStore().disableKeyFields(); } @@ -206,7 +209,14 @@ export default { } }, data() { + const { isRepair } = useMainStore().damage; + const { policyLookupSuccessful, noCoverage } = useMainStore().policy; + const { currentDeductible } = useMainStore().order.currentDeductible; return { + isRepair, + policyLookupSuccessful, + deductibleValue: currentDeductible, + isNoComp: noCoverage ?? false, availableLineItems: [], selectedProvider: '', deductibleText: 'Your deductible is', @@ -219,83 +229,84 @@ export default { rules: { selectionRequired: globalRules.OPTION_REQUIRED }, - supportingItems: null + supportingItems: null, + widget: { + subheader: 'SiteSubHeaderWidget', + verifiedItacAlert: 'VerifiedITACAlert', + explanatoryText: 'ExplanatoryTextWidget', + nextStep: 'NextStepsWidget', + serviceProviderQuestion: 'ServiceProviderQuestion' + } }; }, computed: { - verifiedITACAlertHeader() { - return this.getCmsContent( - 'VerifiedITACAlert', - 'HeadlineText' + coverageStatementSubHeader() { + return this.getTextFromCmsWithCustomIfStatements( + this.widget.subheader, + widgetFields.SUB_HEADER_WIDGET.SUB_HEADER_TEXT ); }, - verifiedITACAlertBody() { + verifiedItacAlertHeader() { return this.getCmsContent( - 'VerifiedITACAlert', - 'BodyText' + this.widget.verifiedItacAlert, + widgetFields.ALERT_WIDGET.HEADLINE_TEXT + ); + }, + verifiedItacAlertBody() { + return this.getCmsContent( + this.widget.verifiedItacAlert, + widgetFields.ALERT_WIDGET.BODY_TEXT )?.replaceAll('{custom:costSavings}', this.costSavings); }, - coverageStatementSubHeader() { - return this.getSubheaderTextFromCms('SiteSubHeaderWidget'); - }, secondaryText() { - return this.getSecondaryTextFromCms('SiteSubHeaderWidget'); + return this.getTextFromCmsWithCustomIfStatements( + this.widget.subheader, + widgetFields.CONTENT_GROUP_WIDGET.SECONDARY_TEXT + ); }, explanatoryText() { - return this.getExplantoryTextFromCms('ExplanatoryTextWidget'); + return this.getTextFromCmsWithCustomIfStatements( + this.widget.explanatoryText, + widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT + ); }, nextStepsHeader() { - return this.getHeaderTextFromCms('NextStepsWidget'); + return this.getTextFromCmsWithCustomIfStatements( + this.widget.nextStep, + widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT + ); }, nextStepsBody() { - return this.getBodyTextFromCms('NextStepsWidget')?.replaceAll('{custom:damage}', this.damageText); - }, - continueWithSchedulingBodyText() { - return this.getCmsContent('continueWithSchedulingCopy', 'BodyText'); - }, - unverifiedADASNextStepsBodyText() { - return this.getCmsContent('UnverifiedADASNextStepsWidget', 'BodyText')?.replaceAll('{custom:damage}', this.damageText); - }, - unverifiedNonADASNextStepsBodyText() { - return this.getCmsContent('UnverifiedNonADASNextStepsWidget', 'BodyText')?.replaceAll('{custom:damage}', this.damageText); - }, - unverifiedNonADASRepairBodyText() { - return this.getCmsContent('UnverifiedNonADASRepairWidget', 'BodyText'); + return this.getTextFromCmsWithCustomIfStatements( + this.widget.nextStep, + widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT + )?.replaceAll('{custom:damage}', this.damageText); }, damageText() { const damageString = getDamageString(); return damageString === 'match' ? '' : damageString; }, - vehicleDeductible() { - const deductible = useMainStore().order.currentDeductible; - return deductible; - }, formattedDeductible() { - return this.getDeductibleString(this.vehicleDeductible); - }, - isDeductibleZero() { - return this.vehicleDeductible === 0; - }, - policyLookupSuccessful() { - return useMainStore().order.policy.policyLookupSuccessful; + return this.getDeductibleString(this.deductibleValue); }, registerClaimSuccessful() { return useMainStore().payment.insuranceCoverage.isVerified; }, verifiedNoComp() { - return this.policyLookupSuccessful ? useMainStore().order.policy.noCoverage : false; + return this.policyLookupSuccessful && this.isNoComp; }, verifiedITAC() { return this.policyLookupSuccessful - && !this.verifiedNoComp - && this.vehicleDeductible > this.totalServicePrice; + && !this.isNoComp + && this.deductibleValue > this.totalServicePrice; }, + // TODO maybe tweak coveredAndServicePriceAboveOrEqualDeductible() { - return !this.verifiedNoComp && this.totalServicePrice >= this.vehicleDeductible; + return !this.verifiedNoComp && this.totalServicePrice >= this.deductibleValue; }, verifiedDeductible() { return useMainStore().isClaimRegistrationRequired - ? this.registerClaimSuccessful && this.coveredAndServicePriceAboveOrEqualDeductible && this.vehicleDeductible !== null + ? this.registerClaimSuccessful && this.coveredAndServicePriceAboveOrEqualDeductible && this.deductibleValue !== null : this.policyLookupSuccessful && this.coveredAndServicePriceAboveOrEqualDeductible; }, unverified() { @@ -305,9 +316,7 @@ export default { const parts = useMainStore().order.lineItems.glassParts; return parts !== null && !!parts.find((part) => part.requiresRecalibration); }, - isRepair() { - return useMainStore().order.damage.isRepair; - }, + // TODO replace with better method totalServicePrice() { let total = 0; this.availableLineItems.forEach((lineItem) => { @@ -319,27 +328,30 @@ export default { return this.getServicePriceString(this.totalServicePrice); }, costSavings() { - const savings = this.getITACCostSavings(this.vehicleDeductible, this.totalServicePrice); + const savings = this.getITACCostSavings(this.deductibleValue, this.totalServicePrice); const formattedSavings = parseFloat(savings).toFixed(2); return `$${formattedSavings}`; }, - questionText() { - return this.getCmsContent('ServiceProviderQuestion', 'QuestionText'); + serviceProviderQuestionText() { + return this.getCmsContent( + this.widget.serviceProviderQuestion, + widgetFields.INPUT_QUESTION_WIDGET.QUESTION_TEXT + ); }, - answersFromCms() { - return this.getCmsContent('ServiceProviderQuestion', 'Answers'); + serviceProviderQuestionAnswers() { + return this.getCmsContent( + this.widget.serviceProviderQuestion, + widgetFields.INPUT_QUESTION_WIDGET.ANSWERS + ); }, - displayQuote() { + isQuoteDisplayed() { return this.verifiedITAC || this.verifiedNoComp; } }, watch: { selectedProvider() { - if (this.selectedProvider === 'Safelite') { - this.$refs.siteFooter.updateButtonText('Continue with Safelite'); - } else { - this.$refs.siteFooter.updateButtonText('Continue'); - } + const buttonText = this.selectedProvider === SAFELITE_PROVIDER ? 'Continue with Safelite' : 'Safelite'; + this.$refs.siteFooter.updateButtonText(buttonText); }, nextStepsBody(newValue, oldValue) { if (newValue !== oldValue) { @@ -366,9 +378,6 @@ export default { } this.$refs.loadingModal.hideModal(); }, - async forwardButtonAction() { - return this.navigateForward(); - }, async navigateForward() { if (this.unverified || this.verifiedDeductible) { useMainStore().saveSupportingItems(this.supportingItems); @@ -379,8 +388,8 @@ export default { { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } ); } else if (this.verifiedITAC || this.verifiedNoComp) { - useMainStore().updateIsSafeliteProvider(this.selectedProvider === 'Safelite'); - if (this.selectedProvider === 'Safelite') { + useMainStore().updateIsSafeliteProvider(this.selectedProvider === SAFELITE_PROVIDER); + if (this.selectedProvider === SAFELITE_PROVIDER) { useMainStore().saveSupportingItems(this.supportingItems); this.$router.navigate( navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, @@ -407,25 +416,9 @@ export default { ); } }, - getHeaderTextFromCms(cmsWidgetName) { - const header = this.getCmsContent(cmsWidgetName, 'HeaderText'); - return processIfStatements(header, 'custom', this.getCustomValueFromString); - }, - getSubheaderTextFromCms(cmsWidgetName) { - const subHeader = this.getCmsContent(cmsWidgetName, 'SubHeaderText'); - return processIfStatements(subHeader, 'custom', this.getCustomValueFromString); - }, - getBodyTextFromCms(cmsWidgetName) { - const bodyText = this.getCmsContent(cmsWidgetName, 'BodyText'); - return processIfStatements(bodyText, 'custom', this.getCustomValueFromString); - }, - getSecondaryTextFromCms(cmsWidgetName) { - const secondaryText = this.getCmsContent(cmsWidgetName, 'SecondaryText'); - return processIfStatements(secondaryText, 'custom', this.getCustomValueFromString); - }, - getExplantoryTextFromCms(cmsWidgetName) { - const explanatoryText = this.getCmsContent(cmsWidgetName, 'BodyText'); - return processIfStatements(explanatoryText, 'custom', this.getCustomValueFromString); + getTextFromCmsWithCustomIfStatements(widgetName, widgetField) { + const rawText = this.getCmsContent(widgetName, widgetField); + return processIfStatements(rawText, 'custom', this.getCustomValueFromString); }, getCustomValueFromString(str) { switch (str) { @@ -444,20 +437,23 @@ export default { case 'nonADASRepair': return this.isRepair; case 'deductibleOverZero': - return this.verifiedDeductible && !this.isDeductibleZero; // TODO what if deductible is negative? + return this.verifiedDeductible && this.deductibleValue !== 0; // TODO what if deductible is negative? case 'isDeductibleZero': - return this.verifiedDeductible && this.isDeductibleZero; + return this.verifiedDeductible && this.deductibleValue === 0; default: return null; } }, + // TODO move to common location getTotalLineItemPrice(lineItem) { return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice; }, + // TODO use price formatter getDeductibleString(deductible) { const formattedDeductibleFloat = parseFloat(deductible).toFixed(2); return `$${formattedDeductibleFloat}`; }, + // TODO use price formatter getServicePriceString(price) { const formattedPriceFloat = parseFloat(price).toFixed(2); return `$${formattedPriceFloat}`; @@ -467,6 +463,9 @@ export default { }, setSupportingItems(newSupportingItems) { this.supportingItems = newSupportingItems; + }, + setAvailableLineItems(newAvailableLineItems) { + this.availableLineItems = newAvailableLineItems; } } }; diff --git a/src/store/index.js b/src/store/index.js index 114b9989..c2517558 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -947,10 +947,9 @@ export const useMainStore = defineStore({ }, async getSupportingItems() { - const glassPartsArray = this.order.lineItems.glassParts ?? []; - const { carId } = this.order.vehicle; - const { isRepair } = this.order.damage; - const { numberOfChips } = this.order.damage; + const glassPartsArray = this.lineItems.glassParts ?? []; + const { carId } = this.vehicle; + const { isRepair, numberOfChips } = this.damage; return globalMethods .callHttpClient({ From 715490f12f4d0033e508e348a4197031fc8f8053 Mon Sep 17 00:00:00 2001 From: Michaela Brydon Date: Mon, 4 Mar 2024 13:39:43 -0500 Subject: [PATCH 04/22] Modifying supporting items --- src/store/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index c2517558..3ae011f1 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -950,6 +950,7 @@ export const useMainStore = defineStore({ const glassPartsArray = this.lineItems.glassParts ?? []; const { carId } = this.vehicle; const { isRepair, numberOfChips } = this.damage; + const { parentAccountNumber } = this.issConfig; return globalMethods .callHttpClient({ @@ -958,7 +959,7 @@ export const useMainStore = defineStore({ payload: { carId, damageType: isRepair ? 'Repair' : 'Replace', - parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER, + parentAccountNumber, parts: glassPartsArray, numberOfRepairChips: isRepair ? numberOfChips : 0 } From 4e4f99f7c90d4e583cd47fb107e44225ebbca8b5 Mon Sep 17 00:00:00 2001 From: Michaela Brydon Date: Tue, 5 Mar 2024 10:05:55 -0500 Subject: [PATCH 05/22] Moving line item pricing to price calculator --- src/helpers/price-calculator.js | 10 ++ src/helpers/price-calculator.spec.js | 56 +++++++++++ .../coverage-statement/coverage-statement.vue | 92 +++++++------------ 3 files changed, 99 insertions(+), 59 deletions(-) create mode 100644 src/helpers/price-calculator.js create mode 100644 src/helpers/price-calculator.spec.js diff --git a/src/helpers/price-calculator.js b/src/helpers/price-calculator.js new file mode 100644 index 00000000..9e69259b --- /dev/null +++ b/src/helpers/price-calculator.js @@ -0,0 +1,10 @@ +function getPriceOfLineItem(lineItem) { + return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice; +} + +export default function getPriceOfLineItems(lineItems) { + return lineItems.reduce( + (accumulator, lineItem) => accumulator + getPriceOfLineItem(lineItem), + 0 + ); +} diff --git a/src/helpers/price-calculator.spec.js b/src/helpers/price-calculator.spec.js new file mode 100644 index 00000000..4d09128b --- /dev/null +++ b/src/helpers/price-calculator.spec.js @@ -0,0 +1,56 @@ +import getPriceOfLineItems from "@/helpers/price-calculator.js"; + +describe('getPriceOfLineItems', () => { + test('Returns zero when no line items', () => { + // Arrange + const lineItems = []; + + // Act + const result = getPriceOfLineItems(lineItems); + + // Assert + expect(result).toBe(0); + }); + test('Returns expected when one line item', () => { + // Arrange + const lineItems = [ + { + kitPrice: 1, + laborAmount: 2, + sellingPrice: 3 + } + ]; + const expected = 6; + + // Act + const result = getPriceOfLineItems(lineItems); + + // Assert + expect(result).toBe(expected); + }); + test('Returns expected when multiple line items', () => { + // Arrange + const lineItems = [ + { + kitPrice: 1, + laborAmount: 2, + sellingPrice: 3 + }, + { + kitPrice: 1 + }, + { + kitPrice: 10, + laborAmount: 100, + sellingPrice: 1000 + } + ]; + const expected = 1117; + + // Act + const result = getPriceOfLineItems(lineItems); + + // Assert + expect(result).toBe(expected); + }); +}); diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index b6ed7771..5ac78138 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -40,7 +40,7 @@
- {{ formattedServicePrice }} + {{ servicePriceForDisplay }}
this.totalServicePrice; }, - // TODO maybe tweak coveredAndServicePriceAboveOrEqualDeductible() { return !this.verifiedNoComp && this.totalServicePrice >= this.deductibleValue; }, @@ -316,21 +321,17 @@ export default { const parts = useMainStore().order.lineItems.glassParts; return parts !== null && !!parts.find((part) => part.requiresRecalibration); }, - // TODO replace with better method totalServicePrice() { - let total = 0; - this.availableLineItems.forEach((lineItem) => { - total += this.getTotalLineItemPrice(lineItem); - }); - return total; + return getPriceOfLineItems(this.baseServiceLineItems); }, - formattedServicePrice() { - return this.getServicePriceString(this.totalServicePrice); + servicePriceForDisplay() { + return this.getFormattedAmount(this.totalServicePrice); }, - costSavings() { - const savings = this.getITACCostSavings(this.deductibleValue, this.totalServicePrice); - const formattedSavings = parseFloat(savings).toFixed(2); - return `$${formattedSavings}`; + itacCostSavings() { + return this.deductibleValue - this.totalServicePrice; + }, + itacCostSavingsForDisplay() { + return this.getFormattedAmount(this.itacCostSavings); }, serviceProviderQuestionText() { return this.getCmsContent( @@ -367,10 +368,13 @@ export default { arePagePrerequisitesValid() { return !!useMainStore().vehicle.carId; }, + getFormattedAmount(amount) { + return this.currencyFormatter.format(amount); + }, async initializeComponent() { useMainStore().updatePolicyITACFlag(this.verifiedITAC); if (this.policyLookupSuccessful - && useMainStore().order.vehicle.policyVehicleId >= 0 + && useMainStore().vehicle.policyVehicleId >= 0 && useMainStore().isClaimRegistrationRequired && !useMainStore().isClaimAlreadyRegistered && (this.coveredAndServicePriceAboveOrEqualDeductible || this.verifiedITAC)) { @@ -380,11 +384,7 @@ export default { }, async navigateForward() { if (this.unverified || this.verifiedDeductible) { -<<<<<<< HEAD - useMainStore().saveSupportingItems(this.supportingItems); -======= useMainStore().updateSupportingItems(this.supportingItems); ->>>>>>> 24103335eec282fad8ded09087cf8502b0150ad6 this.$router.navigate( navigationScenarios.CLICKED_FORWARD, this.$route, @@ -392,37 +392,28 @@ export default { { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } ); } else if (this.verifiedITAC || this.verifiedNoComp) { -<<<<<<< HEAD useMainStore().updateIsSafeliteProvider(this.selectedProvider === SAFELITE_PROVIDER); if (this.selectedProvider === SAFELITE_PROVIDER) { - useMainStore().saveSupportingItems(this.supportingItems); -======= - useMainStore().updateIsSafeliteProvider(this.selectedProvider === 'Safelite'); - if (this.selectedProvider === 'Safelite') { useMainStore().updateSupportingItems(this.supportingItems); ->>>>>>> 24103335eec282fad8ded09087cf8502b0150ad6 this.$router.navigate( navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, - this.$route, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + this.$route ); } else { useMainStore().setBailout(this.$router.currentRoute, bailoutMessage.RequestCallback()); this.$router.navigate( navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, - this.$route, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + this.$route ); } } else { - useMainStore().setBailout(this.$router.currentRoute, bailoutMessage.coverageStatementInvalidState()); + useMainStore().setBailout( + this.$router.currentRoute, + bailoutMessage.coverageStatementInvalidState() + ); this.$router.navigate( navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE, - this.$route, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + this.$route ); } }, @@ -454,28 +445,11 @@ export default { return null; } }, - // TODO move to common location - getTotalLineItemPrice(lineItem) { - return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice; - }, - // TODO use price formatter - getDeductibleString(deductible) { - const formattedDeductibleFloat = parseFloat(deductible).toFixed(2); - return `$${formattedDeductibleFloat}`; - }, - // TODO use price formatter - getServicePriceString(price) { - const formattedPriceFloat = parseFloat(price).toFixed(2); - return `$${formattedPriceFloat}`; - }, - getITACCostSavings(vehicleDeductible, totalServicePrice) { - return vehicleDeductible - totalServicePrice; - }, setSupportingItems(newSupportingItems) { this.supportingItems = newSupportingItems; }, - setAvailableLineItems(newAvailableLineItems) { - this.availableLineItems = newAvailableLineItems; + setBaseServiceLineItems(lineItems) { + this.baseServiceLineItems = lineItems; } } }; @@ -485,7 +459,7 @@ export default { .cost { color: $green; font-size: 2rem; - font-weight: 300; + font-weight: $font-weight-light; line-height: 2.75rem; } From d5bf56418ac6a9fc8cc31d466c8ef03dff66d6e2 Mon Sep 17 00:00:00 2001 From: Michaela Brydon Date: Tue, 5 Mar 2024 10:40:12 -0500 Subject: [PATCH 06/22] Starting outline of tests --- src/helpers/price-calculator.js | 4 +- .../coverage-statement.spec.js | 54 +++++++++++++++++++ .../coverage-statement/coverage-statement.vue | 2 +- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/helpers/price-calculator.js b/src/helpers/price-calculator.js index 9e69259b..b44abc5a 100644 --- a/src/helpers/price-calculator.js +++ b/src/helpers/price-calculator.js @@ -1,5 +1,7 @@ function getPriceOfLineItem(lineItem) { - return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice; + return (lineItem?.kitPrice ?? 0) + + (lineItem?.laborAmount ?? 0) + + (lineItem?.sellingPrice ?? 0); } export default function getPriceOfLineItems(lineItems) { diff --git a/src/layouts/coverage-statement/coverage-statement.spec.js b/src/layouts/coverage-statement/coverage-statement.spec.js index a597b7f9..79765a88 100644 --- a/src/layouts/coverage-statement/coverage-statement.spec.js +++ b/src/layouts/coverage-statement/coverage-statement.spec.js @@ -828,6 +828,60 @@ describe.skip('coverageStatement.vue', () => { }); describe('coverageStatement.vue-working', () => { + // test('initial data is as expected', () => {}); + describe('Rendering', () => { + test('Should render site header', () => { + // Arrange + const { wrapper } = getMountedComponent({}); + + // Act + const siteHeader = wrapper.findComponent({ ref: 'siteHeader' }); + + // Assert + expect(siteHeader.exists()).toBe(true); + }); + test('Should render site subheader', () => { + // Arrange + const { wrapper } = getMountedComponent({}); + + // Act + const subheader = wrapper.find({ ref: 'siteSubHeader' }); + + // Assert + expect(subheader.exists()).toBe(true); + }); + + test('Should render explanatory text', () => { + // Arrange + const { wrapper } = getMountedComponent({}); + + // Act + const explanatoryText = wrapper.find({ ref: 'explanatoryText' }); + + // Assert + expect(explanatoryText.exists()).toBe(true); + }); + test('Should render secondary text', () => { + // Arrange + const { wrapper } = getMountedComponent({}); + + // Act + const secondaryText = wrapper.find({ ref: 'secondaryText' }); + + // Assert + expect(secondaryText.exists()).toBe(true); + }); + test('Should render site footer', () => { + // Arrange + const { wrapper } = getMountedComponent({}); + + // Act + const footer = wrapper.findComponent({ ref: 'siteFooter' }); + + // Assert + expect(footer.exists()).toBe(true); + }); + }); describe('ITAC flag', () => { test('ITAC flag updated once component is initialized', async () => { // Arrange diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index 5ac78138..8776ebe1 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -200,7 +200,7 @@ export default { vm.setCmsContent(resultMap.cmsContent); vm.setSupportingItems(resultMap.supportingItems); // eslint-disable-next-line no-param-reassign - vm.setAvailableLineItems(pricingResults); + vm.setBaseServiceLineItems(pricingResults); vm.$refs.loadingModal.showModal(); vm.initializeComponent(); if (!vm.unverified) { From 76c35865e4fcf4141b78f6a050e1910983b44714 Mon Sep 17 00:00:00 2001 From: Michaela Brydon Date: Tue, 5 Mar 2024 10:41:47 -0500 Subject: [PATCH 07/22] Starting outline of tests --- .../coverage-statement.spec.js | 68 ++++--------------- 1 file changed, 15 insertions(+), 53 deletions(-) diff --git a/src/layouts/coverage-statement/coverage-statement.spec.js b/src/layouts/coverage-statement/coverage-statement.spec.js index 79765a88..12f0b49a 100644 --- a/src/layouts/coverage-statement/coverage-statement.spec.js +++ b/src/layouts/coverage-statement/coverage-statement.spec.js @@ -118,59 +118,6 @@ describe.skip('coverageStatement.vue', () => { expect(arePagePrerequisitesValid).not.toBeTruthy(); }); }); - describe('Rendering', () => { - test('Should render site header', () => { - // Arrange - const { wrapper } = getMountedComponent({}); - - // Act - const siteHeader = wrapper.findComponent({ ref: 'siteHeader' }); - - // Assert - expect(siteHeader.exists()).toBe(true); - }); - test('Should render site subheader', () => { - // Arrange - const { wrapper } = getMountedComponent({}); - - // Act - const subheader = wrapper.find({ ref: 'siteSubHeader' }); - - // Assert - expect(subheader.exists()).toBe(true); - }); - - test('Should render explanatory text', () => { - // Arrange - const { wrapper } = getMountedComponent({}); - - // Act - const explanatoryText = wrapper.find({ ref: 'explanatoryText' }); - - // Assert - expect(explanatoryText.exists()).toBe(true); - }); - test('Should render secondary text', () => { - // Arrange - const { wrapper } = getMountedComponent({}); - - // Act - const secondaryText = wrapper.find({ ref: 'secondaryText' }); - - // Assert - expect(secondaryText.exists()).toBe(true); - }); - test('Should render site footer', () => { - // Arrange - const { wrapper } = getMountedComponent({}); - - // Act - const footer = wrapper.findComponent({ ref: 'siteFooter' }); - - // Assert - expect(footer.exists()).toBe(true); - }); - }); describe('Verified ITAC scenario', () => { test('If policy lookup successful, not No Comp, and deductible > service price, verifiedITAC returns true', () => { // Arrange @@ -881,6 +828,21 @@ describe('coverageStatement.vue-working', () => { // Assert expect(footer.exists()).toBe(true); }); + }); + describe('Computed', () => { + describe('formattedDeductible', () => {}); + describe('verifiedNoComp', () => {}); + describe('verifiedITAC', () => {}); + describe('verifiedDeductible', () => {}); + describe('unverified', () => {}); + describe('isADAS', () => {}); + describe('servicePriceForDisplay', () => {}); + describe('itacCostSavings', () => {}); + describe('itacCostSavingsForDisplay', () => {}); + describe('isQuoteDisplayed', () => {}); + }); + describe('watchers', () => { + }); describe('ITAC flag', () => { test('ITAC flag updated once component is initialized', async () => { From d839c21244886ee96888f38ef2ecc354b07a4720 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Tue, 5 Mar 2024 09:46:36 -0600 Subject: [PATCH 08/22] SSR-600 Cannot continue existing claim --- .../duplicate-check/duplicate-check.vue | 14 +++-- src/store/index.js | 13 ++--- src/store/store.spec.js | 55 ++++++++++++++----- 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/src/layouts/duplicate-check/duplicate-check.vue b/src/layouts/duplicate-check/duplicate-check.vue index 7245adef..8f00a3ff 100644 --- a/src/layouts/duplicate-check/duplicate-check.vue +++ b/src/layouts/duplicate-check/duplicate-check.vue @@ -126,13 +126,17 @@ export default { * @summary Steps to perform when forward button clicked. */ async forwardButtonAction() { - if (this.selectedAnswer !== this.getNewOrderSelectionName) { - await useMainStore().loadSession() - .then(() => {}, () => {}) - .finally(() => { this.navigateForward(); }); - } else { + if (this.selectedAnswer === this.getNewOrderSelectionName) { this.navigateForward(); + return; } + + const duplicate = useMainStore().applicationUser.duplicateOrders.find((d) => d.referralNumber === this.selectedAnswer); + await useMainStore().loadSession(duplicate) + .catch(() => {}) + .finally(() => { + this.navigateForward(); + }); }, navigateForward() { if (!this.mainStore.order.policy.policyLookupSuccessful) { diff --git a/src/store/index.js b/src/store/index.js index 3ba028ec..befd4fd9 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1210,20 +1210,17 @@ export const useMainStore = defineStore({ }); }, - async loadSession() { + async loadSession(duplicate) { const { applicationUser, order, issConfig } = this; - // TODO how to get savedSessionId for a duplicate referral? - try { const response = await globalMethods.callHttpClient({ method: endpoints.LoadSession.method, endpoint: endpoints.LoadSession.url, payload: { - savedSessionId: applicationUser.savedSessionId?.toString(), - referralNumber: order.referralNumber?.toString(), - referralDate: order.referralDate?.toString(), + referralNumber: duplicate.referralNumber, + referralDate: duplicate.referralDate, parentAccountNumber: issConfig.parentAccountNumber, - referralCorrelationId: order.referralCorrelationId + referralCorrelationId: duplicate.referralCorrelationId } }); const { data } = response; @@ -1232,9 +1229,7 @@ export const useMainStore = defineStore({ return response; } - applicationUser.crmCustomerId = data.applicationUser?.crmCustomerId; applicationUser.experiments = data.applicationUser?.experiments ?? []; - applicationUser.savedSessionId = data.applicationUser?.savedSessionId; if (order.policy.policyLookupSuccessful) { order.customer.emailAddress = data.customer?.emailAddress; diff --git a/src/store/store.spec.js b/src/store/store.spec.js index c15352b7..2c4525bf 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -961,10 +961,7 @@ describe('Store', () => { describe('loadSession method', () => { describe('successful method call', () => { const applicationUser = { - crmCustomerId: getRandomString(6, 6), - experiments: getRandomString(6, 6), - pageData: getRandomString(6, 6), - savedSessionId: getRandomString(6, 6) + experiments: getRandomString(6, 6) }; const vehicle = { year: getRandomString(6, 6), @@ -1006,9 +1003,13 @@ describe('Store', () => { it('calls load session api endpoint', async () => { // Arrange globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve({ data: {} })); + const duplicate = { + referralNumber: getRandomString(6, 6), + referralCorrelationId: getRandomGuid() + }; // Act - store.loadSession(); + store.loadSession(duplicate); // Asserts expect(globalMethods.callHttpClient).toHaveBeenCalledWith(expect.objectContaining({ @@ -1020,9 +1021,13 @@ describe('Store', () => { // Arrange const response = { data: { ReferralNumber: getRandomString(6, 6) } }; globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve(response)); + const duplicate = { + referralNumber: getRandomString(6, 6), + referralCorrelationId: getRandomGuid() + }; // Act - const result = store.loadSession(); + const result = store.loadSession(duplicate); // Asserts await expect(result).resolves.toBe(response.data); @@ -1030,24 +1035,31 @@ describe('Store', () => { it('sets expected application user data', async () => { // Arrange globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve(fullApiResponse)); + const duplicate = { + referralNumber: getRandomString(6, 6), + referralCorrelationId: getRandomGuid() + }; // Act - await store.loadSession(); + await store.loadSession(duplicate); // Asserts expect(store.applicationUser.experiments).toEqual(applicationUser.experiments); - expect(store.applicationUser.savedSessionId).toBe(applicationUser.savedSessionId); - expect(store.applicationUser.crmCustomerId).toBe(applicationUser.crmCustomerId); }); it('sets expected vehicle data', async () => { // Arrange globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve(fullApiResponse)); + const duplicate = { + referralNumber: getRandomString(6, 6), + referralCorrelationId: getRandomGuid() + }; + store.order.policy.policyLookupSuccessful = true; store.policy.vehicles = [{ vin: vehicle.vin }]; // Act - await store.loadSession(); + await store.loadSession(duplicate); // Asserts expect(store.vehicle.year).toBe(vehicle.year); @@ -1061,11 +1073,16 @@ describe('Store', () => { // Arrange globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve(fullApiResponse)); + const duplicate = { + referralNumber: getRandomString(6, 6), + referralCorrelationId: getRandomGuid() + }; + store.order.policy.policyLookupSuccessful = true; store.policy.vehicles = [{ vin: vehicle.vin }]; // Act - await store.loadSession(); + await store.loadSession(duplicate); // Asserts expect(store.order.customer.address.streetAddress).toBe(customer.address.streetAddress); @@ -1081,10 +1098,14 @@ describe('Store', () => { it('sets expected remaining order data', async () => { // Arrange globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve(fullApiResponse)); - const originalWorkOrderNumber = store.order.workOrderNumber; + + const duplicate = { + referralNumber: getRandomString(6, 6), + referralCorrelationId: getRandomGuid() + }; // Act - await store.loadSession(); + await store.loadSession(duplicate); // Asserts expect(store.order.referralNumber).toBe(fullApiResponse.data.referralNumber); @@ -1092,7 +1113,6 @@ describe('Store', () => { expect(store.order.referralCorrelationId).toBe(fullApiResponse.data.referralCorrelationId); expect(store.order.referralSequenceNumber).toBe(fullApiResponse.data.referralSequenceNumber); expect(store.order.eon).toBe(fullApiResponse.data.eon); - expect(store.order.workOrderNumber).toBe(originalWorkOrderNumber); }); }); it('api call throws exception', async () => { @@ -1100,8 +1120,13 @@ describe('Store', () => { const error = 'load session error'; globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.reject(error)); + const duplicate = { + referralNumber: getRandomString(6, 6), + referralCorrelationId: getRandomGuid() + }; + // Act - await store.loadSession().catch((e) => { + await store.loadSession(duplicate).catch((e) => { expect(e).toEqual(error); }); From 7757bc6cfd78f02a0aee58623c4726de50f72f17 Mon Sep 17 00:00:00 2001 From: Michaela Brydon Date: Wed, 6 Mar 2024 10:15:08 -0500 Subject: [PATCH 09/22] Adding test cases --- .../coverage-statement.spec.js | 57 +++++++++++++-- .../coverage-statement/coverage-statement.vue | 70 ++++++++----------- 2 files changed, 81 insertions(+), 46 deletions(-) diff --git a/src/layouts/coverage-statement/coverage-statement.spec.js b/src/layouts/coverage-statement/coverage-statement.spec.js index 12f0b49a..186c1799 100644 --- a/src/layouts/coverage-statement/coverage-statement.spec.js +++ b/src/layouts/coverage-statement/coverage-statement.spec.js @@ -830,19 +830,62 @@ describe('coverageStatement.vue-working', () => { }); }); describe('Computed', () => { - describe('formattedDeductible', () => {}); - describe('verifiedNoComp', () => {}); - describe('verifiedITAC', () => {}); - describe('verifiedDeductible', () => {}); + describe.only('verifiedNoComp', () => { + test.each([true, false])('returns false when policyLookupSuccessful false', (isNoComp) => { + + }); + test.each([true, false])('returns false when isNoComp false', (policyLookupSuccessful) => {}); + test('returns true when policyLookupSuccessful true and policyLookupSuccessful true', () => { + + }); + }); + describe('verifiedITAC', () => { + test('returns false when policyLookupSuccessful false', () => {}); + test('returns false when isNoComp true', () => {}); + test('returns false when deductibleValue equals totalServicePrice', () => {}); + test('returns false when deductibleValue less than totalServicePrice', () => {}); + }); + describe('verifiedDeductible', () => { + test('', () => { }); + test('', () => { }); + test('', () => { }); + test('', () => { }); + test('', () => { }); + test('', () => { }); + test('', () => { }); + }); describe('unverified', () => {}); describe('isADAS', () => {}); - describe('servicePriceForDisplay', () => {}); describe('itacCostSavings', () => {}); - describe('itacCostSavingsForDisplay', () => {}); describe('isQuoteDisplayed', () => {}); + describe('shouldRegisterClaim', () => {}); }); - describe('watchers', () => { + describe('methods', () => { + describe('arePagePrerequisitesValid', () => { + }); + test.each([ + [0, '$0.00'], + [1, '$1.00'], + [12, '$12.00'], + [1.2, '$1.20'], + [1.25, '$1.25'], + [1.254, '$1.25'], + [1.255, '$1.26'], + [-1, '-$1.00'] + ])('getFormattedAmount', (value, expected) => { + // Arrange + const { wrapper } = getMountedComponent(); + + // Act + const result = wrapper.vm.getFormattedAmount(value); + + // Assert + expect(result).toBe(expected); + }); + describe('navigateForward', () => { + + }); }); describe('ITAC flag', () => { test('ITAC flag updated once component is initialized', async () => { diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index 8776ebe1..ad578df1 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -35,7 +35,7 @@
- {{ formattedDeductible }} + {{ deductibleForDisplay }}
{{ deductibleText }}  - {{ formattedDeductible }} + {{ deductibleForDisplay }}
{ - useMainStore() - .setBailout( - to, - bailoutMessage.pricingResponseError( - availableLineItems.map((li) => li.partNumber), - { code: err.code, message: err.message, data: err.data } - ) - ); + setBailout(to, bailoutMessage.pricingResponseError( + availableLineItems.map((li) => li.partNumber), + { code: err.code, message: err.message, data: err.data } + )); hasBailedOut = true; next(`/?issPage=${issPageValues.BAILOUT_PAGE}`); }); @@ -292,7 +292,7 @@ export default { deductibleValue() { return useMainStore().order.currentDeductible; }, - formattedDeductible() { + deductibleForDisplay() { return this.getFormattedAmount(this.deductibleValue); }, registerClaimSuccessful() { @@ -347,6 +347,13 @@ export default { }, isQuoteDisplayed() { return this.verifiedITAC || this.verifiedNoComp; + }, + shouldRegisterClaim() { + return this.policyLookupSuccessful + && useMainStore().vehicle.policyVehicleId >= 0 + && useMainStore().isClaimRegistrationRequired + && !useMainStore().isClaimAlreadyRegistered + && (this.coveredAndServicePriceAboveOrEqualDeductible || this.verifiedITAC); } }, watch: { @@ -373,11 +380,7 @@ export default { }, async initializeComponent() { useMainStore().updatePolicyITACFlag(this.verifiedITAC); - if (this.policyLookupSuccessful - && useMainStore().vehicle.policyVehicleId >= 0 - && useMainStore().isClaimRegistrationRequired - && !useMainStore().isClaimAlreadyRegistered - && (this.coveredAndServicePriceAboveOrEqualDeductible || this.verifiedITAC)) { + if (this.shouldRegisterClaim) { await useMainStore().registerClaim()?.catch(() => {}); } this.$refs.loadingModal.hideModal(); @@ -385,38 +388,27 @@ export default { async navigateForward() { if (this.unverified || this.verifiedDeductible) { useMainStore().updateSupportingItems(this.supportingItems); - this.$router.navigate( - navigationScenarios.CLICKED_FORWARD, - this.$route, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); + this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD); } else if (this.verifiedITAC || this.verifiedNoComp) { useMainStore().updateIsSafeliteProvider(this.selectedProvider === SAFELITE_PROVIDER); if (this.selectedProvider === SAFELITE_PROVIDER) { useMainStore().updateSupportingItems(this.supportingItems); - this.$router.navigate( - navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, - this.$route - ); + this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE); } else { - useMainStore().setBailout(this.$router.currentRoute, bailoutMessage.RequestCallback()); - this.$router.navigate( - navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, - this.$route - ); + this.setBailoutWithMessage(bailoutMessage.RequestCallback()); + this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP); } } else { - useMainStore().setBailout( - this.$router.currentRoute, - bailoutMessage.coverageStatementInvalidState() - ); - this.$router.navigate( - navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE, - this.$route - ); + this.setBailoutWithMessage(bailoutMessage.coverageStatementInvalidState()); + this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE); } }, + setBailoutWithMessage(message) { + setBailout(this.$router.currentRoute, message); + }, + navigateWithScenario(scenario) { + this.$router.navigate(scenario, this.$route); + }, getTextFromCmsWithCustomIfStatements(widgetName, widgetField) { const rawText = this.getCmsContent(widgetName, widgetField); return processIfStatements(rawText, 'custom', this.getCustomValueFromString); From 6c013bc0adeac055a88519190762599a992c8caa Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 6 Mar 2024 15:58:33 -0500 Subject: [PATCH 10/22] AfterPay Updates --- src/constants/endpoints.js | 4 + .../vehicle-banner/vehicle-banner.vue | 8 +- .../order-confirmation/order-confirmation.vue | 56 ++++--- src/layouts/payment-method/payment-method.vue | 1 - src/layouts/payment-page/payment-page.vue | 97 ++++++++++-- src/mixins/base-mixin.js | 52 ++++++ src/router/index.js | 31 +++- src/router/router-constants/routing-table.js | 2 +- src/store/index.js | 148 +++++++++++++++++- 9 files changed, 352 insertions(+), 47 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 8bd893e9..3e6a617e 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -116,6 +116,10 @@ const endpoints = Object.freeze({ url: `${ACCOUNT_BASE_URL}/`, method: 'GET' }, + TaxOrderItems: { + url: '/price/api/v1/price/taxed-order-items', + method: 'GET' + }, LogExperimentExposureIfAssigned: { url: `${EXPERIMENTS_BASE_URL}/log-exposure`, method: 'POST' diff --git a/src/iss-components/vehicle-banner/vehicle-banner.vue b/src/iss-components/vehicle-banner/vehicle-banner.vue index d86e7bfc..387118c1 100644 --- a/src/iss-components/vehicle-banner/vehicle-banner.vue +++ b/src/iss-components/vehicle-banner/vehicle-banner.vue @@ -23,7 +23,13 @@ export default { return this.genericVehicleImage; } - const { imageUrl } = this.mainStore.order.vehicle; + let imageUrl = ''; + if (this.mainStore.hasSubmittedOrder()) { + imageUrl = this.mainStore.submittedOrder.vehicle.imageUrl; + } else { + imageUrl = this.mainStore.order.vehicle.imageUrl; + } + if (!imageUrl || imageUrl === 'NULL') { return this.getUnmatchedVehicleIcon(); } diff --git a/src/layouts/order-confirmation/order-confirmation.vue b/src/layouts/order-confirmation/order-confirmation.vue index f1bddf9e..6d94001d 100644 --- a/src/layouts/order-confirmation/order-confirmation.vue +++ b/src/layouts/order-confirmation/order-confirmation.vue @@ -58,7 +58,9 @@ import settleAllPromises from '@/helpers/layout-helper'; import { Form } from 'vee-validate'; import BaseFormMixin from '@/mixins/base-form-mixin.js'; import { useMainStore } from '@/store'; -import { get12HourTimeFormat, get12HourTimeMobileFormat, convertDateStringToDate, +import { get12HourTimeFormat, + get12HourTimeMobileFormat, + convertDateStringToDate, getDisplayTextForDurationLength } from '@/helpers/date-helper.js'; import { toTitleCase } from '@/helpers/text-helper.js'; import { AppointmentTypeStrings } from '@/constants/schedule-constants'; @@ -66,14 +68,15 @@ import { AppointmentTypeStrings } from '@/constants/schedule-constants'; export default { name: 'order-confirmation', components: { + // eslint-disable-next-line vue/no-reserved-component-names + Form, siteHeader, vehicleBanner, - siteFooter, - // eslint-disable-next-line vue/no-reserved-component-names - Form + siteFooter }, mixins: [BaseFormMixin], async beforeRouteEnter(to, from, next) { + useMainStore().createSubmittedOrder(); // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); // Settle promises and get results @@ -90,7 +93,8 @@ export default { }, setup() { const mainStore = useMainStore(); - return { mainStore }; + const { submittedOrder } = mainStore; + return { mainStore, submittedOrder }; }, computed: { carrierName() { @@ -106,16 +110,16 @@ export default { return this.getCmsContent('OrderConfirmationContent', 'Image'); }, appointmentType() { - return this.mainStore.order.serviceLocation.appointmentType; + return this.submittedOrder.serviceLocation.appointmentType; }, appointmentDate() { - return this.mainStore.order.schedule.date; + return this.submittedOrder.schedule.date; }, appointmentStartTime() { - return this.mainStore.order.schedule.startTime; + return this.submittedOrder.schedule.startTime; }, appointmentEndTime() { - return this.mainStore.order.schedule.endTime; + return this.submittedOrder.schedule.endTime; }, appointmentDateFormatted() { // This conversion ensures we don't get get GMT induced date changes @@ -144,35 +148,35 @@ export default { return this.getBodyText2FromCms('DropOffAndInShopWordingWidget'); }, serviceLocationAddress() { - return this.mainStore.order.serviceLocation.address; + return this.submittedOrder.serviceLocation.address; }, serviceLocationAddress2() { - return this.mainStore.order.serviceLocation.address2; + return this.submittedOrder.serviceLocation.address2; }, serviceLocationCity() { - return this.mainStore.order.serviceLocation.city; + return this.submittedOrder.serviceLocation.city; }, serviceLocationState() { - return this.mainStore.order.serviceLocation.state; + return this.submittedOrder.serviceLocation.state; }, serviceLocationZipCode() { - return this.mainStore.order.serviceLocation.zipCode; + return this.submittedOrder.serviceLocation.zipCode; }, serviceLocationFullAddress() { // eslint-disable-next-line max-len - return `
${this.serviceLocationAddress}, ${this.serviceLocationAddress2 ? `${this.serviceLocationAddress2},` : ''}
${this.serviceLocationCity}, ${this.serviceLocationState} ${this.serviceLocationZipCode}
`; + return `${this.serviceLocationAddress}, ${this.serviceLocationAddress2 ? `${this.serviceLocationAddress2},` : ''}
${this.serviceLocationCity}, ${this.serviceLocationState} ${this.serviceLocationZipCode}`; }, providerAddress() { - return toTitleCase(this.mainStore.order.serviceLocation.provider.address.streetAddress); + return toTitleCase(this.submittedOrder.serviceLocation.provider.address.streetAddress); }, providerCity() { - return toTitleCase(this.mainStore.order.serviceLocation.provider.address.city); + return toTitleCase(this.submittedOrder.serviceLocation.provider.address.city); }, providerState() { - return this.mainStore.order.serviceLocation.provider.address.state; + return this.submittedOrder.serviceLocation.provider.address.state; }, providerZipCode() { - return this.mainStore.order.serviceLocation.provider.address.zipCode; + return this.submittedOrder.serviceLocation.provider.address.zipCode; }, providerFullAddress() { // eslint-disable-next-line max-len @@ -217,18 +221,19 @@ export default { } }, mobileAppointment() { - return this.mainStore.isMobileAppointment; + return this.submittedOrder.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE + || this.submittedOrder.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP; }, inShopAppointment() { - return this.mainStore.isInShopAppointment; + return this.submittedOrder.serviceLocation.appointmentType === AppointmentTypeStrings.IN_SHOP; }, dropOffAppointment() { - return this.mainStore.isDropOffAppointment; + return this.submittedOrder.serviceLocation.appointmentType === AppointmentTypeStrings.DROP_OFF; }, inShopAppointmentDuration() { const inshopDurationTime = getDisplayTextForDurationLength( - this.mainStore.order.schedule.jobMinMinutes, - this.mainStore.order.schedule.jobMaxMinutes + this.submittedOrder.schedule.jobMinMinutes, + this.submittedOrder.schedule.jobMaxMinutes ); return inshopDurationTime; } @@ -310,6 +315,9 @@ $page-side-padding: 1.5rem; } .appointment-text { + :deep(p) { + margin: 0; + } :deep(strong) { font-weight: $font-weight-bold; color: $black; diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index ab362f4c..c7440bf6 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -33,7 +33,6 @@ ref="siteFooter" cmsWidgetName="SiteFooterWidget" :isForwardActionDisabled="!meta.valid" - :isBackButtonHidden="shouldHideBackButton" :isStackedVertically="true" @backClicked="navigateBack" @ForwardClicked="forwardButtonAction" /> diff --git a/src/layouts/payment-page/payment-page.vue b/src/layouts/payment-page/payment-page.vue index 1f77de74..85c7f707 100644 --- a/src/layouts/payment-page/payment-page.vue +++ b/src/layouts/payment-page/payment-page.vue @@ -1,9 +1,5 @@