Adding deductible and base price line items to cart

This commit is contained in:
Michaela Brydon 2024-02-29 14:39:35 -05:00
parent 89ee40f4d1
commit a8b75d8c1c
5 changed files with 116 additions and 38 deletions

View file

@ -81,7 +81,7 @@ describe('cart-dropdown component', () => {
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.isVerified;
const result = wrapper.vm.isVerifiedCoverageStatus;
// Assert
expect(result).toBe(expected);

View file

@ -10,13 +10,34 @@
href="javascript:void(0)"
class="col d-flex justify-content-between py-0">
<span class="label color-black">{{ amountDueLabel }}</span>
<span class="label amount-due">{{ amountDueDisplayed }}</span>
<span class="label amount-due">{{ getDisplayed(amountDue) }}</span>
</a>
</div>
<div
id="cart-table"
class="cart-table px-4">
<span>Cart Table Placeholder</span>
class="cart-table">
<div class="mt-4 line-item color-gray-100 px-5 py-1">
<div id="cart-deductible-or-base-price">
<div
v-if="showDeductibleLineItem"
id="cart-deductible"
class="d-flex justify-content-between align-items-center">
<span
id="deductible-label"
class="label">{{ deductibleOrBasePriceLabel }}</span>
<span id="deductible-value">{{ getDisplayed(deductible) }}</span>
</div>
<div
v-else
id="cart-base-price"
class="d-flex justify-content-between align-items-center">
<span
id="base-price-label"
class="label">{{ deductibleOrBasePriceLabel }}</span>
<span id="base-price-value">{{ getDisplayed(baseServicePrice) }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
@ -31,39 +52,56 @@ export default {
components: {},
props: {
showAsPaid: Boolean,
amountDueLabel: String
amountDueLabel: String,
deductibleOrBasePriceLabel: String
},
data() {
return {
isExpanded: false,
isExpanded: true,
currencyFormatter: new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}),
widget: {
amountDue: 'AmountDueTextWidget'
}
})
};
},
computed: {
isVerified() {
return useMainStore().payment?.insuranceCoverage?.isVerified ?? false;
deductible() {
return useMainStore().order.currentDeductible;
},
amountDueDisplayed() {
return this.isVerified
? this.getFormattedAmount(this.amountDue)
: VERIFYING_COVERAGE;
availableLineItems() {
// TODO make real
return [
{
kitPrice: 1,
laborAmount: 2,
sellingPrice: 3
}
];
},
baseServicePrice() {
return this.availableLineItems
.reduce(
(accumulator, lineItem) => accumulator + this.getTotalLineItemPrice(lineItem),
0
);
},
showDeductibleLineItem() {
return !useMainStore().isNoComp && !useMainStore().policy.isITAC;
},
isUnverified() {
return this.showDeductibleLineItem
&& (this.deductible == null || !useMainStore().isVerifiedCoverageStatus);
},
subTotal() {
return this.showDeductibleLineItem ? this.deductible : this.baseServicePrice;
},
salesTax() {
return 0; // TODO
},
amountDue() {
return this.showAsPaid
? 0
: this.subTotal + this.salesTax;
},
subTotal() {
return 0;
},
salesTax() {
return 0;
}
},
methods: {
@ -72,6 +110,14 @@ export default {
},
getFormattedAmount(amount) {
return this.currencyFormatter.format(amount);
},
getTotalLineItemPrice(lineItem) {
return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice;
},
getDisplayed(amount) {
return this.isUnverified
? VERIFYING_COVERAGE
: this.getFormattedAmount(amount);
}
}
};
@ -84,6 +130,13 @@ export default {
.color-black {
color: $black;
}
.color-gray-100 {
background-color: $gray-100;
}
.line-item {
color: $darker-gray;
}
.cart-table {
max-height: 0;

View file

@ -130,6 +130,7 @@ 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';
import coverageStatuses from '@/constants/coverage-statuses';
export default {
name: 'coverage-statement',
@ -265,8 +266,7 @@ export default {
return damageString === 'match' ? '' : damageString;
},
vehicleDeductible() {
const deductible = useMainStore().order.currentDeductible;
return deductible;
return useMainStore().order.currentDeductible;
},
formattedDeductible() {
return this.getDeductibleString(this.vehicleDeductible);
@ -355,6 +355,10 @@ export default {
},
async initializeComponent() {
useMainStore().updatePolicyITACFlag(this.verifiedITAC);
const coverageStatus = this.verifiedITAC || this.verifiedNoComp
? coverageStatuses.VERIFIED
: coverageStatuses.PENDING;
useMainStore().updateCoverageStatus(coverageStatus);
if (this.policyLookupSuccessful
&& useMainStore().order.vehicle.policyVehicleId >= 0
&& useMainStore().isClaimRegistrationRequired

View file

@ -21,7 +21,8 @@
<hr class="my-0" />
<cartDropdown
:showAsPaid="false"
:amountDueLabel="amountDueText" />
:amountDueLabel="amountDueText"
:deductibleOrBasePriceLabel="deductibleOrBasePriceLabel" />
<hr class="mt-0 mb-5" />
<div>Pia Alert Placeholder</div>
<paymentMethodQuestion
@ -55,11 +56,12 @@ import paymentMethodQuestion from '@/layouts/payment-method/payment-method-quest
// Supporting Items
import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { fetchCmsContentForPage, processIfStatements } from '@/helpers/cms-content-helper';
import { paymentMethods } from '@/constants/payment-method-constants';
import globalRules from '@/constants/global-rules';
import { Form } from 'vee-validate';
import widgetFields from '@/constants/cms-widget-fields.js';
import coverageStatuses from '@/constants/coverage-statuses';
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
@ -109,7 +111,8 @@ export default {
optionRequired: globalRules.OPTION_REQUIRED
},
widget: {
amountDue: 'AmountDueTextWidget'
amountDue: 'AmountDueTextWidget',
deductibleOrBasePrice: 'DeductibleOrBasePriceWidget'
}
};
},
@ -134,6 +137,13 @@ export default {
},
amountDueText() {
return this.getCmsContent(this.widget.amountDue, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
},
deductibleOrBasePriceLabel() {
const deductibleOrBasePriceLabel = this.getCmsContent(
this.widget.deductibleOrBasePrice,
widgetFields.TEXT_BLOCK_WIDGET.TEXT
);
return processIfStatements(deductibleOrBasePriceLabel, 'custom', this.getCustomValueFromString);
}
},
watch: {
@ -233,6 +243,16 @@ export default {
this.$route
);
}
},
getCustomValueFromString(str) {
switch (str) {
case 'itacOrNoComp':
return useMainStore().isNoComp || useMainStore().policy.isITAC;
case 'deductibleOrUnverified':
return !useMainStore().isNoComp && !useMainStore().policy.isITAC;
default:
return null;
}
}
}
};

View file

@ -232,6 +232,8 @@ export const useMainStore = defineStore({
isDropOffAppointment: (state) => state.order.serviceLocation.appointmentType === AppointmentTypeStrings.DROP_OFF,
isClaimRegistrationRequired: (state) => state.issConfig.isClaimRegistrationRequired,
isBailout: (state) => state.applicationUser.pageData[issPageValues.BAILOUT_PAGE] != null,
isNoComp: (state) => state.order.policy.coverageStatus === coverageStatuses.NO_COMP,
isVerifiedCoverageStatus: (state) => state.order.policy.coverageStatus === coverageStatuses.VERIFIED,
eventBusItem: (state) => (eventCategory, eventSubCategory) => {
const matchedEvent = state.applicationUser.eventBus.find(({ category, subCategory }) => category === eventCategory && subCategory === eventSubCategory);
return matchedEvent?.eventValue;
@ -489,6 +491,9 @@ export const useMainStore = defineStore({
});
});
},
updateCoverageStatus(newStatus) {
this.order.payment.insuranceCoverage.coverageStatus = newStatus;
},
registerClaim() {
const nonNumberCharRegex = /[^0-9]/g;
const { order } = this;
@ -553,18 +558,15 @@ export const useMainStore = defineStore({
const registerClaimFailed = response.data.isError;
order.payment.insuranceCoverage.isVerified = !registerClaimFailed;
order.payment.insuranceCoverage.claimNumber = null;
if (registerClaimFailed) {
this.order.payment.insuranceCoverage.coverageStatus = coverageStatuses.PENDING;
} else if (this.policy.noCoverage) {
this.order.payment.insuranceCoverage.coverageStatus = coverageStatuses.NO_COMP;
} else {
this.order.payment.insuranceCoverage.coverageStatus = coverageStatuses.VERIFIED;
if (this.policy?.noCoverage ?? false) {
this.updateCoverageStatus(coverageStatuses.NO_COMP);
} else if (!registerClaimFailed) {
this.updateCoverageStatus(coverageStatuses.VERIFIED);
this.order.payment.insuranceCoverage.claimNumber = response.data.claimNumber;
}
return resolve(response);
}, (error) => {
this.order.payment.insuranceCoverage.isVerified = false;
this.order.payment.insuranceCoverage.coverageStatus = coverageStatuses.PENDING;
this.order.payment.insuranceCoverage.claimNumber = null;
return reject(error);
});
@ -1264,7 +1266,7 @@ export const useMainStore = defineStore({
order.lineItems.vaps = data.order?.lineItems?.vaps;
order.payment.insuranceCoverage.isVerified = data.order?.payment?.insuranceCoverage?.isVerified;
order.payment.insuranceCoverage.coverageStatus = data.order?.payment?.insuranceCoverage?.coverageStatus;
this.updateCoverageStatus(data.order?.payment?.insuranceCoverage?.coverageStatus ?? coverageStatuses.PENDING);
const parentAccountNumber = Number.isNaN(data.order?.payment?.parentAccountNumber)
? 0
: data.order?.payment?.parentAccountNumber;
@ -1466,9 +1468,8 @@ export const useMainStore = defineStore({
// These could be undefined
this.order.policy.noCoverage = vehicle.noCoverage;
this.order.payment.insuranceCoverage.coverageStatus = vehicle.noCoverage
? coverageStatuses.NO_COMP
: coverageStatuses.PENDING;
const currentCoverageStatus = vehicle.noCoverage ? coverageStatuses.NO_COMP : coverageStatuses.PENDING;
this.updateCoverageStatus(currentCoverageStatus);
this.order.policy.deductible.replace = vehicle.deductible;
this.order.policy.deductible.repair = vehicle?.repairWaived ?? false ? 0 : vehicle.deductible;
this.order.policy.endorsements = vehicle?.endorsements;