Merge pull request #1007 from Safelite/defect/CSR-1229
Cherry-pick | 1168 - supporting items changes
This commit is contained in:
commit
7ee0530cb0
3 changed files with 246 additions and 4 deletions
|
|
@ -107,12 +107,14 @@ export default {
|
||||||
];
|
];
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
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 = [
|
const availableLineItems = [
|
||||||
resultMap.rainDefense,
|
resultMap.rainDefense,
|
||||||
...resultMap.supportingItems,
|
...resultMap.supportingItems,
|
||||||
...resultMap.wipers,
|
...resultMap.wipers,
|
||||||
...glassParts,
|
...clonedGlassParts,
|
||||||
];
|
];
|
||||||
|
|
||||||
const pricingResults = await baseMixin.methods.dispatchStoreAction(
|
const pricingResults = await baseMixin.methods.dispatchStoreAction(
|
||||||
|
|
@ -124,6 +126,7 @@ export default {
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
vm.pricedGlassParts = clonedGlassParts;
|
||||||
vm.supportingItems = resultMap.supportingItems;
|
vm.supportingItems = resultMap.supportingItems;
|
||||||
vm.availableLineItems = pricingResults;
|
vm.availableLineItems = pricingResults;
|
||||||
vm.isInsuranceSelected = vm.getDefaultIsInsuranceSelectedValue(vm.availableLineItems);
|
vm.isInsuranceSelected = vm.getDefaultIsInsuranceSelectedValue(vm.availableLineItems);
|
||||||
|
|
@ -135,6 +138,7 @@ export default {
|
||||||
selectedVaps: null,
|
selectedVaps: null,
|
||||||
availableLineItems: null,
|
availableLineItems: null,
|
||||||
supportingItems: null,
|
supportingItems: null,
|
||||||
|
pricedGlassParts: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -187,6 +191,13 @@ export default {
|
||||||
if (this.$store.getters.order.accountNumber != applicationConfig.CASH_ACCOUNT_NUMBER) {
|
if (this.$store.getters.order.accountNumber != applicationConfig.CASH_ACCOUNT_NUMBER) {
|
||||||
this.supportingItems = this.filterOutFees(this.supportingItems);
|
this.supportingItems = this.filterOutFees(this.supportingItems);
|
||||||
}
|
}
|
||||||
|
if (this.pricedGlassParts.length > 0) {
|
||||||
|
this.dispatchStoreAction(
|
||||||
|
this.storeActions.SAVE_GLASS_PARTS,
|
||||||
|
this.pricedGlassParts,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
this.dispatchStoreAction(
|
this.dispatchStoreAction(
|
||||||
this.storeActions.SAVE_SUPPORTING_ITEMS,
|
this.storeActions.SAVE_SUPPORTING_ITEMS,
|
||||||
this.supportingItems,
|
this.supportingItems,
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,213 @@ describe("service-package-question.vue", () => {
|
||||||
expectedModifiedAnswers[packageNameKey].tierThree
|
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", () => {
|
describe("service-package-question.vue, matching business rules for package display", () => {
|
||||||
// mock scenarios in figma:
|
// mock scenarios in figma:
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ export default {
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
availableLineItems() {
|
availableLineItems() {
|
||||||
if (this.$store.getters.lineItems.vaps) {
|
if (this.allGlassPartsAndSupportingItemsHavePrices(this.$store.getters.lineItems)) {
|
||||||
this.selectDefaultPackage();
|
this.selectDefaultPackage();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -212,7 +212,7 @@ export default {
|
||||||
selectDefaultPackage() {
|
selectDefaultPackage() {
|
||||||
const vapsFromStore = this.$store.getters.lineItems.vaps;
|
const vapsFromStore = this.$store.getters.lineItems.vaps;
|
||||||
let lowestTierForPackage = packageNames.TIER_ONE;
|
let lowestTierForPackage = packageNames.TIER_ONE;
|
||||||
if (vapsFromStore.length > 0) {
|
if (vapsFromStore?.length > 0) {
|
||||||
vapsFromStore.every((vapsItem) => {
|
vapsFromStore.every((vapsItem) => {
|
||||||
let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem);
|
let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem);
|
||||||
if (lowestTierForThisItem === packageNames.TIER_THREE) {
|
if (lowestTierForThisItem === packageNames.TIER_THREE) {
|
||||||
|
|
@ -228,6 +228,30 @@ export default {
|
||||||
}
|
}
|
||||||
this.selectedPackageName = lowestTierForPackage;
|
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) {
|
getLowestTierForThisItem(vapsItem) {
|
||||||
let lowestTierForThisItem = null;
|
let lowestTierForThisItem = null;
|
||||||
switch (vapsItem.partType) {
|
switch (vapsItem.partType) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue