From cf86fcae23cea37884ac9d14d0baef7991619c31 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Mon, 13 Feb 2023 15:30:36 -0500 Subject: [PATCH 1/2] CSR-1168 | Change how we determine if a package has been selected --- src/layouts/quote/quote.vue | 13 +++++++-- .../service-package-question.vue | 27 +++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 21f5753bb..ecc5d5d32 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -103,12 +103,12 @@ export default { ]; const resultMap = await settleAllPromises(promiseResultMap); - const glassParts = store.getters.order.lineItems.glassParts ?? []; + const clonedGlassParts = store.getters.order.lineItems.glassParts ? JSON.parse(JSON.stringify(store.getters.order.lineItems.glassParts)) : []; const availableLineItems = [ resultMap.rainDefense, ...resultMap.supportingItems, ...resultMap.wipers, - ...glassParts, + ...clonedGlassParts, ]; const pricingResults = await baseMixin.methods.dispatchStoreAction( @@ -120,6 +120,7 @@ export default { // Call the "next" function to complete the transition to this page. next((vm) => { vm.setCmsContent(resultMap.cmsContent); + vm.pricedGlassParts = clonedGlassParts; vm.supportingItems = resultMap.supportingItems; vm.availableLineItems = pricingResults; vm.isInsuranceSelected = vm.getDefaultIsInsuranceSelectedValue(vm.availableLineItems); @@ -131,6 +132,7 @@ export default { selectedVaps: null, availableLineItems: null, supportingItems: null, + pricedGlassParts: null }; }, methods: { @@ -183,6 +185,13 @@ export default { if (this.$store.getters.order.accountNumber != applicationConfig.CASH_ACCOUNT_NUMBER) { this.supportingItems = this.filterOutFees(this.supportingItems); } + if(this.pricedGlassParts.length > 0) { + this.dispatchStoreAction( + this.storeActions.SAVE_GLASS_PARTS, + this.pricedGlassParts, + false + ); + } this.dispatchStoreAction( this.storeActions.SAVE_SUPPORTING_ITEMS, this.supportingItems, 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 796da19e9..820c988ee 100644 --- a/src/layouts/quote/service-package-question/service-package-question.vue +++ b/src/layouts/quote/service-package-question/service-package-question.vue @@ -42,9 +42,10 @@ export default { }, watch: { availableLineItems() { - if (this.$store.getters.lineItems.vaps) { + if (this.allGlassPartsAndSupportingItemsHavePrices(this.$store.getters.lineItems)) { this.selectDefaultPackage(); } + }, selectedPackageName(newValue) { const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue); @@ -212,7 +213,7 @@ export default { selectDefaultPackage() { const vapsFromStore = this.$store.getters.lineItems.vaps; let lowestTierForPackage = packageNames.TIER_ONE; - if (vapsFromStore.length > 0) { + if (vapsFromStore?.length > 0) { vapsFromStore.every((vapsItem) => { let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem); if (lowestTierForThisItem === packageNames.TIER_THREE) { @@ -228,6 +229,28 @@ export default { } this.selectedPackageName = lowestTierForPackage; }, + allGlassPartsAndSupportingItemsHavePrices(lineItems) { + if (lineItems?.glassParts) { + for (let i = 0; i < lineItems.glassParts.length; i++) { + if (this.priceIsNullOrZero(lineItems.glassParts[i])) { + return false; + } + } + } + if (lineItems?.supportingItems) { + for (let i = 0; i < lineItems.supportingItems.length; i++) { + if (this.priceIsNullOrZero(lineItems.supportingItems[i])) { + return false; + } + } + } + return true; + }, + priceIsNullOrZero(lineItem) { + return (lineItem.kitPrice == null || lineItem.kitPrice == 0) && + (lineItem.laborAmount == null || lineItem.laborAmount == 0) && + (lineItem.sellingPrice == null || lineItem.sellingPrice == 0); + }, getLowestTierForThisItem(vapsItem) { let lowestTierForThisItem = null; switch (vapsItem.partType) { From 91df8c52c25d0b09229ea0691f3dde7918725385 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 14 Feb 2023 15:17:18 -0500 Subject: [PATCH 2/2] CSR-1168 | Added default service package unit tests --- src/layouts/quote/quote.spec.js | 4 + src/layouts/quote/quote.vue | 8 +- .../service-package-question.spec.js | 207 ++++++++++++++++++ .../service-package-question.vue | 9 +- 4 files changed, 221 insertions(+), 7 deletions(-) diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index e5d4d54fb..dccc73346 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -78,6 +78,8 @@ describe("quote.vue", () => { }; }); + wrapper.vm.pricedGlassParts = []; + //Act await wrapper.vm.forwardButtonAction(); @@ -107,6 +109,8 @@ describe("quote.vue", () => { }; }); + wrapper.vm.pricedGlassParts = []; + //Act await wrapper.vm.forwardButtonAction(); diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 2d5f95e05..786b046b9 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -102,7 +102,9 @@ export default { ]; const resultMap = await settleAllPromises(promiseResultMap); - const clonedGlassParts = store.getters.order.lineItems.glassParts ? JSON.parse(JSON.stringify(store.getters.order.lineItems.glassParts)) : []; + const clonedGlassParts = store.getters.order.lineItems.glassParts + ? JSON.parse(JSON.stringify(store.getters.order.lineItems.glassParts)) + : []; const availableLineItems = [ resultMap.rainDefense, ...resultMap.supportingItems, @@ -131,7 +133,7 @@ export default { selectedVaps: null, availableLineItems: null, supportingItems: null, - pricedGlassParts: null + pricedGlassParts: null, }; }, methods: { @@ -185,7 +187,7 @@ export default { if (this.$store.getters.order.accountNumber != applicationConfig.CASH_ACCOUNT_NUMBER) { this.supportingItems = this.filterOutFees(this.supportingItems); } - if(this.pricedGlassParts.length > 0) { + if (this.pricedGlassParts.length > 0) { this.dispatchStoreAction( this.storeActions.SAVE_GLASS_PARTS, this.pricedGlassParts, 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 cd10b893f..af04ff36a 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 @@ -135,6 +135,213 @@ describe("service-package-question.vue", () => { expectedModifiedAnswers[packageNameKey].tierThree ); }); + it("should not select a default package if ANY glass part or supporting item has no prices", async () => { + // Note, only the first WSREPAIR item has a 0 for laborAmount, this is enough to not try and select a default package + const wrapper = setupMocks({ + mountOptionsMockData: { + store: { + getters: { + lineItems: { + glassParts: [ + { + partNumber: "FW02627GBYNOEE", + description: "solar, 3rd visor band", + color: "Green Tint, Blue Shade", + partType: "WINDSHIELD", + canSafeliteRecalibrate: false, + requiresRecalibration: false, + requiresCapabilityQuestions: false, + recalibrationType: null, + childParts: null, + laborAmount: 5.0, + }, + ], + supportingItems: [ + { + partNumber: "SUPPLIES-REPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + { + partNumber: "WSREPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 0, + }, + { + partNumber: "WSREPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + { + partNumber: "WSREPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + ], + }, + order: { + damage: { + isRepair: false, + glassToReplace: [{ glassLocation: "Windshield" }], + }, + }, + }, + }, + }, + }); + + // Act + wrapper.setProps({ availableLineItems: null }); + + await nextTick(); + + // Assert + expect(wrapper.vm.selectedPackageName).toBe(null); + }); + it("should select a default package if ALL glass parts and supporting items have prices", async () => { + const wrapper = setupMocks({ + mountOptionsMockData: { + store: { + getters: { + lineItems: { + glassParts: [ + { + partNumber: "FW02627GBYNOEE", + description: "solar, 3rd visor band", + color: "Green Tint, Blue Shade", + partType: "WINDSHIELD", + canSafeliteRecalibrate: false, + requiresRecalibration: false, + requiresCapabilityQuestions: false, + recalibrationType: null, + childParts: null, + laborAmount: 5.0, + }, + ], + supportingItems: [ + { + partNumber: "SUPPLIES-REPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + { + partNumber: "WSREPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + { + partNumber: "WSREPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + { + partNumber: "WSREPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + ], + }, + order: { + damage: { + isRepair: false, + glassToReplace: [{ glassLocation: "Windshield" }], + }, + }, + }, + }, + }, + }); + + // Act + wrapper.setProps({ availableLineItems: null }); + + await nextTick(); + + // Assert + expect(wrapper.vm.selectedPackageName).toBe("TierOne"); + }); + it("should select TierThree default package if Rain Defense is on order", async () => { + // This tests the business intent that when returning to the page, the selected package is the lowest package that contains all VAPs on the order. + // In this case Rain Defense is only in Premium so Tier Three should be defaulted to + const wrapper = setupMocks({ + mountOptionsMockData: { + store: { + getters: { + lineItems: { + glassParts: [ + { + partNumber: "FW02627GBYNOEE", + description: "solar, 3rd visor band", + color: "Green Tint, Blue Shade", + partType: "WINDSHIELD", + canSafeliteRecalibrate: false, + requiresRecalibration: false, + requiresCapabilityQuestions: false, + recalibrationType: null, + childParts: null, + laborAmount: 5.0, + }, + ], + vaps: [ + { + partNumber: "RAIN DEFENSE", + partType: "RAIN DEFENSE", + }, + ], + supportingItems: [ + { + partNumber: "SUPPLIES-REPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + { + partNumber: "WSREPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + { + partNumber: "WSREPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + { + partNumber: "WSREPAIR", + description: null, + partType: "REPAIR FEE", + laborAmount: 5.0, + }, + ], + }, + order: { + damage: { + isRepair: false, + glassToReplace: [{ glassLocation: "Windshield" }], + }, + }, + }, + }, + }, + }); + + // Act + wrapper.setProps({ availableLineItems: null }); + + await nextTick(); + + // Assert + expect(wrapper.vm.selectedPackageName).toBe("TierThree"); + }); }); describe("service-package-question.vue, matching business rules for package display", () => { // mock scenarios in figma: 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 820c988ee..cca37bb45 100644 --- a/src/layouts/quote/service-package-question/service-package-question.vue +++ b/src/layouts/quote/service-package-question/service-package-question.vue @@ -45,7 +45,6 @@ export default { if (this.allGlassPartsAndSupportingItemsHavePrices(this.$store.getters.lineItems)) { this.selectDefaultPackage(); } - }, selectedPackageName(newValue) { const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue); @@ -247,9 +246,11 @@ export default { return true; }, priceIsNullOrZero(lineItem) { - return (lineItem.kitPrice == null || lineItem.kitPrice == 0) && - (lineItem.laborAmount == null || lineItem.laborAmount == 0) && - (lineItem.sellingPrice == null || lineItem.sellingPrice == 0); + return ( + (lineItem.kitPrice == null || lineItem.kitPrice == 0) && + (lineItem.laborAmount == null || lineItem.laborAmount == 0) && + (lineItem.sellingPrice == null || lineItem.sellingPrice == 0) + ); }, getLowestTierForThisItem(vapsItem) { let lowestTierForThisItem = null;