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>
<!-- 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 -->
<!-- This will be a loop when this is implemented -->
<div class="non-packaged-cart-item">
<div
v-if="mobileFeeCartItem"
id="mobile-fee"
class="cart-item">
<div
v-if="mobileFeeCartItem"
id="mobile-fee-item"
class="d-flex justify-content-between align-items-center">
<span id="mobile-fee-label">{{ mobileFeeCartItem.name }}</span>
@ -56,18 +92,18 @@
</div>
<div
v-if="recycleFeeCartItem"
id="recycle-fee"
class="cart-item cart-gray">
<div
v-if="recycleFeeCartItem"
id="recycle-fee-item"
class="d-flex justify-content-between align-items-center">
<span id="recycle-fee-label">
<textLink
linkType="text"
:text="recycleFeeCartItem.name"
href="javascript:void(0)"
@clickEvent="openModal(recyclingModalCmsWidgetName)" />
linkType="text"
:text="recycleFeeCartItem.name"
href="javascript:void(0)"
@clickEvent="openModal(recyclingModalCmsWidgetName)" />
</span>
<span id="recycle-fee-value">{{ getDisplayed(recycleFeeCartItem.subTotal) }}</span>
</div>
@ -100,30 +136,6 @@
</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
ref="RecycleModal"
: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 getPriceOfLineItems from '@/helpers/price-calculator.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
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';
const VERIFYING_COVERAGE = 'Verifying coverage';
@ -159,24 +169,26 @@ export default {
},
props: {
showAsPaid: Boolean,
// servicePackageLabel: String,
readOnly: Boolean,
// TODO add allowRemoveItems
recyclingModalCmsWidgetName: String
recyclingModalCmsWidgetName: String,
availableVaps: Array
},
data() {
const { currentDeductible } = useMainStore().order;
const { glassToReplace, isRepair } = useMainStore().damage;
const { supportingItems, glassParts, otherParts, vaps } = useMainStore().lineItems;
const baseServiceLineItems = [
...(supportingItems ?? []),
...(glassParts ?? []),
...(otherParts ?? [])
];
return {
vaps: vaps ?? [],
isRepair,
glassToReplace: glassToReplace ?? [],
vapsInOrder: vaps ?? [],
baseServiceLineItems: [
...(supportingItems ?? []),
...(glassParts ?? []),
...(otherParts ?? [])
],
deductible: currentDeductible,
baseServiceLineItems,
isExpanded: false,
isExpanded: true, // false,
widget: {
amountDue: 'AmountDueTextWidget',
deductible: 'DeductibleWidget',
@ -184,7 +196,8 @@ export default {
subtotal: 'SubtotalWidget',
salesTax: 'SalesTaxWidget',
recycleFee: 'RecycleFeeWidget',
mobileFee: 'MobileServiceWidget'
mobileFee: 'MobileServiceWidget',
servicePackage: 'ServicePackageTitle'
}
};
},
@ -209,141 +222,64 @@ export default {
amountDue() {
return this.showAsPaid
? 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() {
// return this.getCmsContentForVapsType(partTypeStrings.FRONT_WIPER);
// },
// frontWipersCartItem() {
// let cartItem = null;
// const frontWiperLineItems = this.vaps.filter((vapsLineItem) => vapsLineItem.partType == partTypeStrings.FRONT_WIPER);
// if (frontWiperLineItems.length > 0) {
// cartItem = {
// name: this.frontWiperCartItemName,
// 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);
frontWipersCartItem() {
const frontWipersLabel = this.getCmsContentForVapsType(partTypeStrings.FRONT_WIPER);
const frontWipersLineItems = this.vapsInOrder
.filter((vapsLineItem) => vapsLineItem.partType === partTypeStrings.FRONT_WIPER);
return this.getCartItem(frontWipersLabel, frontWipersLineItems);
},
rearWipersCartItem() {
const rearWipersLabel = this.getCmsContentForVapsType(partTypeStrings.REAR_WIPER);
const rearWipersLineItems = this.vapsInOrder
.filter((vapsLineItem) => vapsLineItem.partType === partTypeStrings.REAR_WIPER);
return this.getCartItem(rearWipersLabel, rearWipersLineItems);
},
rainDefenseCartItem() {
let cartItem = null;
const rainDefenseLineItem = this.vaps.find((vapsLineItem) => vapsLineItem.partType === partTypeStrings.RAIN_DEFENSE);
rainDefenseLineItem.cartItemType = cartItemTypes.RAIN_DEFENSE;
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;
const rainDefenseLabel = this.getCmsContentForVapsType(partTypeStrings.RAIN_DEFENSE);
const rainDefenseLineItem = this.vapsInOrder
.find((vapsLineItem) => vapsLineItem.partType === partTypeStrings.RAIN_DEFENSE);
return this.getCartItem(rainDefenseLabel, [rainDefenseLineItem]);
},
packagePrice() {
return getPriceOfLineItems(this.packageLineItems);
},
// 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;
return getPriceOfLineItems(this.vapsInOrder);
},
amountDueLabel() {
return this.getCmsContent(this.widget.amountDue, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
@ -360,16 +296,33 @@ export default {
salesTaxLabel() {
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() {
return this.getCartItem(
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() {
return this.getCartItem(
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,
getCartItem(label, lineItem) {
getCartItem(label, lineItems) {
let cartItem = null;
if (lineItem) {
if (lineItems) {
cartItem = {
name: label,
subTotal: this.getTotalLineItemPrice(lineItem, false),
salesTax: lineItem.salesTax ?? 0
subTotal: getPriceOfLineItems(lineItems),
salesTax: lineItems.salesTax ?? 0
};
}
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>
@import "@/styles/ux-variables-svg-strings.scss";
.force-no-top-margin {
margin-top: 0 !important;
}
.color-black {
color: $black;
}
@ -415,6 +387,10 @@ export default {
color: $green;
}
.color-darker-gray {
color: $darker-gray;
}
.cart-line-item {
padding: 0.25rem 1.5rem;
color: $darker-gray;
@ -427,6 +403,12 @@ export default {
visibility: hidden;
margin-top: 1rem;
:deep(a) {
padding-bottom: 0 !important;
line-height: 1.625 !important;
text-underline-offset: auto !important;
}
.cart-item {
padding: 0.25rem 1.5rem;
}

View file

@ -21,15 +21,10 @@
<hr class="my-0" />
<cartDropdown
:showAsPaid="false"
<<<<<<< HEAD
:amountDueLabel="amountDueText"
:deductibleLabel="deductibleLabel"
:basePriceLabel="basePriceLabel"
:servicePackageLabel="serviceLabel"
:readOnly="false" />
=======
recyclingModalCmsWidgetName="RecycleModal" />
>>>>>>> feafc2e3accf2c6901ff1b6739e44c60c44fd8aa
:readOnly="false"
recyclingModalCmsWidgetName="RecycleModal"
servicePackageTitleWidgetName="ServicePackageTitle"
:availableVaps="availableVaps" />
<hr class="mt-0 mb-5" />
<div>Pia Alert Placeholder</div>
<paymentMethodQuestion
@ -66,6 +61,7 @@ import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { paymentMethods } from '@/constants/payment-method-constants';
import globalRules from '@/constants/global-rules';
import { Form } from 'vee-validate';
import issPageValues from '@/router/router-constants/issPage-values';
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
@ -86,6 +82,8 @@ export default {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
const reviewDropdownPromise = reviewDropdown.methods.loadInitialData();
const wipersPromise = useMainStore().getWipers();
const rainDefensePromise = useMainStore().getRainDefense();
const promiseResultMap = [
{
@ -95,21 +93,49 @@ export default {
{
resultKey: 'reviewDropdownData',
promise: reviewDropdownPromise
},
{
resultKey: 'wipers',
promise: wipersPromise
},
{
resultKey: 'rainDefense',
promise: rainDefensePromise
}
];
const resultMap = await settleAllPromises(promiseResultMap);
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
const unpricedVaps = [...resultMap.wipers, resultMap.rainDefense];
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() {
return {
availableVaps: [],
paymentMethodInternalModel: this.getPaymentMethodFromStore(),
rules: {
optionRequired: globalRules.OPTION_REQUIRED
@ -131,22 +157,6 @@ export default {
},
paymentMethod() {
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: {
@ -247,6 +257,9 @@ export default {
this.$route
);
}
},
setAvailableVaps(vaps) {
this.availableVaps = vaps;
}
}
};

View file

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