Finishing initial work

This commit is contained in:
Michaela Brydon 2024-03-25 12:54:53 -04:00
parent 4e078e8327
commit afde96f0f1
3 changed files with 206 additions and 210 deletions

View file

@ -39,15 +39,51 @@
</div> </div>
<!-- Packaged Cart Items --> <!-- Packaged Cart Items -->
<div
id="cart-service-package"
class="color-darker-gray px-5">
<div
id="service-package-name"
class="py-1 d-flex justify-content-between align-items-center">
<textBlock
:cmsWidgetName="servicePackageLabelWidget"
class="force-no-top-margin" />
<span id="service-package-price">{{ formatAmountInDollars(packagePrice) }}</span>
</div>
<div
id="service-item"
class="ps-4">
<div
v-for="(item, i) in servicePackageCartItems"
:key="i"
class="packaged-cart-item">
<div class="py-1 d-flex justify-content-between align-items-center">
<span>{{ item.name }}</span>
<textLink
v-if="!readOnly || !showAsPaid"
ref="removeLink"
linkType="text"
text="Remove"
href="javascript:void(0)"
class="force-no-bottom-margin"
@clickEvent="removeItem">
<template #after-text>
<span class="sr-only">{{ item.name }}</span>
</template>
</textLink>
</div>
</div>
</div>
</div>
<!-- Nonpackaged Cart Items --> <!-- Nonpackaged Cart Items -->
<!-- This will be a loop when this is implemented --> <!-- This will be a loop when this is implemented -->
<div class="non-packaged-cart-item"> <div class="non-packaged-cart-item">
<div <div
v-if="mobileFeeCartItem"
id="mobile-fee" id="mobile-fee"
class="cart-item"> class="cart-item">
<div <div
v-if="mobileFeeCartItem"
id="mobile-fee-item" id="mobile-fee-item"
class="d-flex justify-content-between align-items-center"> class="d-flex justify-content-between align-items-center">
<span id="mobile-fee-label">{{ mobileFeeCartItem.name }}</span> <span id="mobile-fee-label">{{ mobileFeeCartItem.name }}</span>
@ -56,18 +92,18 @@
</div> </div>
<div <div
v-if="recycleFeeCartItem"
id="recycle-fee" id="recycle-fee"
class="cart-item cart-gray"> class="cart-item cart-gray">
<div <div
v-if="recycleFeeCartItem"
id="recycle-fee-item" id="recycle-fee-item"
class="d-flex justify-content-between align-items-center"> class="d-flex justify-content-between align-items-center">
<span id="recycle-fee-label"> <span id="recycle-fee-label">
<textLink <textLink
linkType="text" linkType="text"
:text="recycleFeeCartItem.name" :text="recycleFeeCartItem.name"
href="javascript:void(0)" href="javascript:void(0)"
@clickEvent="openModal(recyclingModalCmsWidgetName)" /> @clickEvent="openModal(recyclingModalCmsWidgetName)" />
</span> </span>
<span id="recycle-fee-value">{{ getDisplayed(recycleFeeCartItem.subTotal) }}</span> <span id="recycle-fee-value">{{ getDisplayed(recycleFeeCartItem.subTotal) }}</span>
</div> </div>
@ -100,30 +136,6 @@
</div> </div>
</div> </div>
</div> </div>
<div
id="cart-service-package"
class="cart-line-item">
<div
id="service-package-name"
class="d-flex justify-content-between align-items-center">
<span
id="service-package-label"
class="label">{{ servicePackageLabel }}</span>
<span id="service-package-price">{{ formatAmountInDollars(packagePrice) }}</span>
<span
v-if="servicePackageRemovable && !readOnly"
id="service-package-remove">Remove</span>
</div>
<!-- TODO make inclusion of service items a for loop -->
<div
id="service-item"
class="py-1 ps-4 d-flex justify-content-between align-items-center">
<span id="service">Wiper blades</span>
<span
v-if="!readOnly"
id="remove-service-link">Remove</span>
</div>
</div>
<contentGroupModal <contentGroupModal
ref="RecycleModal" ref="RecycleModal"
:cmsWidgetName="recyclingModalCmsWidgetName"> :cmsWidgetName="recyclingModalCmsWidgetName">
@ -140,12 +152,10 @@ import textBlock from '@/digital-components/text-block/text-block.vue';
import textLink from '@/ux-components/text-link/text-link.vue'; import textLink from '@/ux-components/text-link/text-link.vue';
import getPriceOfLineItems from '@/helpers/price-calculator.js'; import getPriceOfLineItems from '@/helpers/price-calculator.js';
import { formatAmountInDollars } from '@/helpers/text-helper.js'; import { formatAmountInDollars } from '@/helpers/text-helper.js';
import { getHighestFullySatisfiedTier, getAvailablePackages } from '@/helpers/service-package-helper.js'; import { getHighestFullySatisfiedTier, getPackageContents } from '@/helpers/service-package-helper.js';
// Constants // Constants
import partTypeStrings from '@/constants/part-type-strings.js'; import partTypeStrings from '@/constants/part-type-strings.js';
import cartItemCategories from '@/constants/cart-item-categories.js';
import cartItemTypes from '@/constants/cart-item-types.js';
import widgetFields from '@/constants/cms-widget-fields.js'; import widgetFields from '@/constants/cms-widget-fields.js';
const VERIFYING_COVERAGE = 'Verifying coverage'; const VERIFYING_COVERAGE = 'Verifying coverage';
@ -159,24 +169,26 @@ export default {
}, },
props: { props: {
showAsPaid: Boolean, showAsPaid: Boolean,
// servicePackageLabel: String,
readOnly: Boolean, readOnly: Boolean,
// TODO add allowRemoveItems recyclingModalCmsWidgetName: String,
recyclingModalCmsWidgetName: String availableVaps: Array
}, },
data() { data() {
const { currentDeductible } = useMainStore().order; const { currentDeductible } = useMainStore().order;
const { glassToReplace, isRepair } = useMainStore().damage;
const { supportingItems, glassParts, otherParts, vaps } = useMainStore().lineItems; const { supportingItems, glassParts, otherParts, vaps } = useMainStore().lineItems;
const baseServiceLineItems = [
...(supportingItems ?? []),
...(glassParts ?? []),
...(otherParts ?? [])
];
return { return {
vaps: vaps ?? [], isRepair,
glassToReplace: glassToReplace ?? [],
vapsInOrder: vaps ?? [],
baseServiceLineItems: [
...(supportingItems ?? []),
...(glassParts ?? []),
...(otherParts ?? [])
],
deductible: currentDeductible, deductible: currentDeductible,
baseServiceLineItems, isExpanded: true, // false,
isExpanded: false,
widget: { widget: {
amountDue: 'AmountDueTextWidget', amountDue: 'AmountDueTextWidget',
deductible: 'DeductibleWidget', deductible: 'DeductibleWidget',
@ -184,7 +196,8 @@ export default {
subtotal: 'SubtotalWidget', subtotal: 'SubtotalWidget',
salesTax: 'SalesTaxWidget', salesTax: 'SalesTaxWidget',
recycleFee: 'RecycleFeeWidget', recycleFee: 'RecycleFeeWidget',
mobileFee: 'MobileServiceWidget' mobileFee: 'MobileServiceWidget',
servicePackage: 'ServicePackageTitle'
} }
}; };
}, },
@ -209,141 +222,64 @@ export default {
amountDue() { amountDue() {
return this.showAsPaid return this.showAsPaid
? 0 ? 0
: this.subTotal + this.packagePrice + this.salesTax; : this.subTotal + this.salesTax;
},
availableLineItems() {
const { glassParts, supportingItems } = useMainStore().lineItems;
return [
...(glassParts ?? []),
...(supportingItems ?? []),
...this.availableVaps
];
},
servicePackageTier() {
return getHighestFullySatisfiedTier(
this.glassToReplace,
this.availableLineItems,
this.isRepair,
this.vapsInOrder
);
},
servicePackageCartItems() {
const packageContentTypes = getPackageContents(
this.glassToReplace,
this.availableLineItems,
this.isRepair,
this.servicePackageTier
) ?? [];
const items = [];
if (packageContentTypes.includes(partTypeStrings.FRONT_WIPER)) {
items.push(this.frontWipersCartItem);
}
if (packageContentTypes.includes(partTypeStrings.REAR_WIPER)) {
items.push(this.rearWipersCartItem);
}
if (packageContentTypes.includes(partTypeStrings.RAIN_DEFENSE)) {
items.push(this.rainDefenseCartItem);
}
return items;
}, },
// frontWiperCartItemName() { frontWipersCartItem() {
// return this.getCmsContentForVapsType(partTypeStrings.FRONT_WIPER); const frontWipersLabel = this.getCmsContentForVapsType(partTypeStrings.FRONT_WIPER);
// }, const frontWipersLineItems = this.vapsInOrder
// frontWipersCartItem() { .filter((vapsLineItem) => vapsLineItem.partType === partTypeStrings.FRONT_WIPER);
// let cartItem = null; return this.getCartItem(frontWipersLabel, frontWipersLineItems);
},
// const frontWiperLineItems = this.vaps.filter((vapsLineItem) => vapsLineItem.partType == partTypeStrings.FRONT_WIPER); rearWipersCartItem() {
const rearWipersLabel = this.getCmsContentForVapsType(partTypeStrings.REAR_WIPER);
// if (frontWiperLineItems.length > 0) { const rearWipersLineItems = this.vapsInOrder
// cartItem = { .filter((vapsLineItem) => vapsLineItem.partType === partTypeStrings.REAR_WIPER);
// name: this.frontWiperCartItemName, return this.getCartItem(rearWipersLabel, rearWipersLineItems);
// category: cartItemCategories.VAPS,
// cartItemType: cartItemTypes.FRONT_WIPERS,
// isDisplayed: true,
// isRemovable: true,
// subTotal: 0,
// salesTax: 0,
// lineItems: []
// };
// frontWiperLineItems.forEach((lineItem) => {
// lineItem.cartItemType = cartItem.cartItemType;
// cartItem.lineItems.push(lineItem);
// cartItem.subTotal
// += (lineItem.kitPrice ?? 0)
// + (lineItem.laborAmount ?? 0)
// + (lineItem.sellingPrice ?? 0);
// cartItem.salesTax += lineItem.salesTax ?? 0;
// });
// }
// return cartItem;
// },
// rearWiperCartItemName() {
// return this.getCmsContentForVapsType(partTypeStrings.REAR_WIPER);
// },
// rearWipersCartItem() {
// let cartItem = null;
// const rearWiperLineItems = this.vaps.filter((vapsLineItem) => vapsLineItem.partType == partTypeStrings.REAR_WIPER);
// if (rearWiperLineItems.length > 0) {
// cartItem = {
// name: this.rearWiperCartItemName,
// category: cartItemCategories.VAPS,
// cartItemType: cartItemTypes.REAR_WIPERS,
// isDisplayed: true,
// isRemovable: true,
// subTotal: 0,
// salesTax: 0,
// lineItems: []
// };
// rearWiperLineItems.forEach((lineItem) => {
// lineItem.cartItemType = cartItem.cartItemType;
// cartItem.lineItems.push(lineItem);
// cartItem.subTotal
// += (lineItem.kitPrice ?? 0)
// + (lineItem.laborAmount ?? 0)
// + (lineItem.sellingPrice ?? 0);
// cartItem.salesTax += lineItem.salesTax ?? 0;
// });
// }
// return cartItem;
// },
rainDefenseCartItemName() {
return this.getCmsContentForVapsType(partTypeStrings.RAIN_DEFENSE);
}, },
rainDefenseCartItem() { rainDefenseCartItem() {
let cartItem = null; const rainDefenseLabel = this.getCmsContentForVapsType(partTypeStrings.RAIN_DEFENSE);
const rainDefenseLineItem = this.vapsInOrder
const rainDefenseLineItem = this.vaps.find((vapsLineItem) => vapsLineItem.partType === partTypeStrings.RAIN_DEFENSE); .find((vapsLineItem) => vapsLineItem.partType === partTypeStrings.RAIN_DEFENSE);
rainDefenseLineItem.cartItemType = cartItemTypes.RAIN_DEFENSE; return this.getCartItem(rainDefenseLabel, [rainDefenseLineItem]);
if (rainDefenseLineItem) {
cartItem = {
name: this.rainDefenseCartItemName,
category: cartItemCategories.VAPS,
cartItemType: cartItemTypes.RAIN_DEFENSE,
isDisplayed: true,
isRemovable: true,
subTotal: getPriceOfLineItems([rainDefenseLineItem]),
salesTax: rainDefenseLineItem.salesTax ?? 0,
lineItems: [rainDefenseLineItem]
};
}
return cartItem;
},
servicePackageLabelCalc() {
// If just rain, "Rain"
return '';
},
packageLevel() {
const tier = getHighestFullySatisfiedTier(
this.glassToReplace,
this.baseServiceLineItems,
this.isRepair,
this.vaps
);
return tier;
}, },
packagePrice() { packagePrice() {
return getPriceOfLineItems(this.packageLineItems); return getPriceOfLineItems(this.vapsInOrder);
},
// TODO
packageLineItems() {
return this.vaps;
},
// TODO finish
servicePackageRemovable() {
// If valid package level then false
// otherwise true
return false;
},
// TODO finish
isValidPackageLevel() {
const availablePackages = getAvailablePackages(
// TODO what is glass to replace
this.glassToReplace,
// TODO what are available line items
this.availableLineItems,
this.isRepair
);
availablePackages.find((servicePackage) => servicePackage.forEach() === this.vaps);
return false;
}, },
amountDueLabel() { amountDueLabel() {
return this.getCmsContent(this.widget.amountDue, widgetFields.TEXT_BLOCK_WIDGET.TEXT); return this.getCmsContent(this.widget.amountDue, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
@ -360,16 +296,33 @@ export default {
salesTaxLabel() { salesTaxLabel() {
return this.getCmsContent(this.widget.salesTax, widgetFields.TEXT_BLOCK_WIDGET.TEXT); return this.getCmsContent(this.widget.salesTax, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
}, },
// TODO confirm what happens when servicePackageNames is null with test
servicePackageNames() {
return this.getCmsContent(
this.widget.servicePackage,
widgetFields.INPUT_QUESTION_WIDGET.ANSWERS
);
},
servicePackageLabelWidget() {
if (!this.servicePackageNames) {
console.log('no service package names');
return '';
}
const currentPackage = this.servicePackageNames
?.find((entry) => entry.Name === this.servicePackageTier);
return currentPackage.SubWidgetName ?? '';
},
recycleFeeCartItem() { recycleFeeCartItem() {
return this.getCartItem( return this.getCartItem(
this.getCmsContent(this.widget.recycleFee, widgetFields.TEXT_BLOCK_WIDGET.TEXT), this.getCmsContent(this.widget.recycleFee, widgetFields.TEXT_BLOCK_WIDGET.TEXT),
useMainStore().order.lineItems.supportingItems.find((lineItem) => lineItem.partType === partTypeStrings.REPLACE_FEE) [useMainStore().lineItems.supportingItems.find((lineItem) => lineItem.partType === partTypeStrings.REPLACE_FEE)]
); );
}, },
mobileFeeCartItem() { mobileFeeCartItem() {
return this.getCartItem( return this.getCartItem(
this.getCmsContent(this.widget.mobileFee, widgetFields.TEXT_BLOCK_WIDGET.TEXT), this.getCmsContent(this.widget.mobileFee, widgetFields.TEXT_BLOCK_WIDGET.TEXT),
useMainStore().order.lineItems.mobileFee [useMainStore().lineItems.mobileFee]
); );
} }
}, },
@ -386,18 +339,33 @@ export default {
: formatAmountInDollars(amount); : formatAmountInDollars(amount);
}, },
formatAmountInDollars, formatAmountInDollars,
getCartItem(label, lineItem) { getCartItem(label, lineItems) {
let cartItem = null; let cartItem = null;
if (lineItem) { if (lineItems) {
cartItem = { cartItem = {
name: label, name: label,
subTotal: this.getTotalLineItemPrice(lineItem, false), subTotal: getPriceOfLineItems(lineItems),
salesTax: lineItem.salesTax ?? 0 salesTax: lineItems.salesTax ?? 0
}; };
} }
return cartItem; return cartItem;
},
removeItem() {
// TODO in later ticket
},
getCmsContentForVapsType(vapsType) {
// TODO make strings constants
const vapsItemDescriptions = this.getCmsContent('VapsItemDescriptions', 'Answers');
if (!vapsItemDescriptions) {
return '';
}
const vapsTypeName = vapsItemDescriptions.find((entry) => entry.Name === vapsType);
return vapsTypeName.Text;
} }
} }
}; };
@ -407,6 +375,10 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import "@/styles/ux-variables-svg-strings.scss"; @import "@/styles/ux-variables-svg-strings.scss";
.force-no-top-margin {
margin-top: 0 !important;
}
.color-black { .color-black {
color: $black; color: $black;
} }
@ -415,6 +387,10 @@ export default {
color: $green; color: $green;
} }
.color-darker-gray {
color: $darker-gray;
}
.cart-line-item { .cart-line-item {
padding: 0.25rem 1.5rem; padding: 0.25rem 1.5rem;
color: $darker-gray; color: $darker-gray;
@ -427,6 +403,12 @@ export default {
visibility: hidden; visibility: hidden;
margin-top: 1rem; margin-top: 1rem;
:deep(a) {
padding-bottom: 0 !important;
line-height: 1.625 !important;
text-underline-offset: auto !important;
}
.cart-item { .cart-item {
padding: 0.25rem 1.5rem; padding: 0.25rem 1.5rem;
} }

View file

@ -21,15 +21,10 @@
<hr class="my-0" /> <hr class="my-0" />
<cartDropdown <cartDropdown
:showAsPaid="false" :showAsPaid="false"
<<<<<<< HEAD :readOnly="false"
:amountDueLabel="amountDueText" recyclingModalCmsWidgetName="RecycleModal"
:deductibleLabel="deductibleLabel" servicePackageTitleWidgetName="ServicePackageTitle"
:basePriceLabel="basePriceLabel" :availableVaps="availableVaps" />
:servicePackageLabel="serviceLabel"
:readOnly="false" />
=======
recyclingModalCmsWidgetName="RecycleModal" />
>>>>>>> feafc2e3accf2c6901ff1b6739e44c60c44fd8aa
<hr class="mt-0 mb-5" /> <hr class="mt-0 mb-5" />
<div>Pia Alert Placeholder</div> <div>Pia Alert Placeholder</div>
<paymentMethodQuestion <paymentMethodQuestion
@ -66,6 +61,7 @@ import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { paymentMethods } from '@/constants/payment-method-constants'; import { paymentMethods } from '@/constants/payment-method-constants';
import globalRules from '@/constants/global-rules'; import globalRules from '@/constants/global-rules';
import { Form } from 'vee-validate'; import { Form } from 'vee-validate';
import issPageValues from '@/router/router-constants/issPage-values';
import { AppointmentTypeStrings } from '@/constants/schedule-constants'; import { AppointmentTypeStrings } from '@/constants/schedule-constants';
@ -86,6 +82,8 @@ export default {
// Call APIs // Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
const reviewDropdownPromise = reviewDropdown.methods.loadInitialData(); const reviewDropdownPromise = reviewDropdown.methods.loadInitialData();
const wipersPromise = useMainStore().getWipers();
const rainDefensePromise = useMainStore().getRainDefense();
const promiseResultMap = [ const promiseResultMap = [
{ {
@ -95,21 +93,49 @@ export default {
{ {
resultKey: 'reviewDropdownData', resultKey: 'reviewDropdownData',
promise: reviewDropdownPromise promise: reviewDropdownPromise
},
{
resultKey: 'wipers',
promise: wipersPromise
},
{
resultKey: 'rainDefense',
promise: rainDefensePromise
} }
]; ];
const resultMap = await settleAllPromises(promiseResultMap); const resultMap = await settleAllPromises(promiseResultMap);
next((vm) => { const unpricedVaps = [...resultMap.wipers, resultMap.rainDefense];
vm.setCmsContent(resultMap.cmsContent);
vm.updateFooterButtonText(vm.customCallToActionButtonCopy); let hasBailedOut = false;
const pricedVaps = await useMainStore().getPriceOrderItems(unpricedVaps)
.catch((err) => {
useMainStore().setBailout(
to,
// TODO use bailout message if keeping
'bailout message'
// bailoutMessage.pricingResponseError(
// availableLineItems.map((li) => li.partNumber),
// { code: err.code, message: err.message, data: err.data }
// )
);
hasBailedOut = true;
next(`/?issPage=${issPageValues.BAILOUT_PAGE}`);
});
vm.$refs.reviewDropdown.initializeComponent(resultMap.reviewDropdownData); if (!hasBailedOut) {
}); next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
vm.$refs.reviewDropdown.initializeComponent(resultMap.reviewDropdownData);
vm.setAvailableVaps(pricedVaps);
});
}
}, },
data() { data() {
return { return {
availableVaps: [],
paymentMethodInternalModel: this.getPaymentMethodFromStore(), paymentMethodInternalModel: this.getPaymentMethodFromStore(),
rules: { rules: {
optionRequired: globalRules.OPTION_REQUIRED optionRequired: globalRules.OPTION_REQUIRED
@ -131,22 +157,6 @@ export default {
}, },
paymentMethod() { paymentMethod() {
return this.paymentMethodInternalModel; return this.paymentMethodInternalModel;
<<<<<<< HEAD
},
amountDueText() {
return this.getCmsContent(this.widget.amountDue, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
},
deductibleLabel() {
return this.getCmsContent(this.widget.deductible, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
},
basePriceLabel() {
return this.getCmsContent(this.widget.basePrice, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
},
// TODO
serviceLabel() {
return 'Standard service';
=======
>>>>>>> feafc2e3accf2c6901ff1b6739e44c60c44fd8aa
} }
}, },
watch: { watch: {
@ -247,6 +257,9 @@ export default {
this.$route this.$route
); );
} }
},
setAvailableVaps(vaps) {
this.availableVaps = vaps;
} }
} }
}; };

View file

@ -97,6 +97,7 @@ export default {
} }
}, },
methods: { methods: {
// TODO maybe move to shared location "loadAvailableVaps"
loadInitialData() { loadInitialData() {
const wipersPromise = useMainStore().getWipers(); const wipersPromise = useMainStore().getWipers();
const rainDefensePromise = useMainStore().getRainDefense(); const rainDefensePromise = useMainStore().getRainDefense();