Merge pull request #1124 from Safelite/bugfix/humphries/order-confirmation

Fixes a few defects on order-confirmation:
This commit is contained in:
AHumphriesSL 2026-03-02 09:22:40 -05:00 committed by GitHub
commit 7a9aa23814
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 97 additions and 18 deletions

View file

@ -20,6 +20,7 @@ Object {
"salesTax": "SalesTaxWidget",
"servicePackage": "ServicePackageTitle",
"subtotal": "SubtotalWidget",
"total": "TotalWidget",
"vapsItemDescriptions": "VapsItemDescriptions",
"warrantyText": "WarrantyCartItemTextWidget",
},

View file

@ -12,6 +12,7 @@ import { getHighestFullySatisfiedTier, getPackageContents } from '@/helpers/serv
import { getPriceOfLineItems } from '@/helpers/price-calculator.js';
import coverageStatuses from '@/constants/coverage-statuses';
import coverageType from '@/constants/coverage-type';
import * as cartHelper from '@/helpers/cart-helper';
const VERIFYING_COVERAGE = 'Verifying coverage';
@ -341,21 +342,76 @@ describe('cart-dropdown component', () => {
});
describe('computed', () => {
describe('amountDue', () => {
test('returns 0 when showAsPaid is true', () => {
test('returns total when showAsPaid is false', () => {
// Arrange
const expectedAmount = 123.45;
const propsData = {
showAsPaid: true
showAsPaid: false
};
const { wrapper } = getMountedComponent({}, {}, propsData);
const totalSpy = jest.spyOn(cartHelper, 'getCartTotal').mockReturnValue(expectedAmount);
// Act
const result = wrapper.vm.amountDue;
// Assert
expect(result).toBe(expectedAmount);
});
test('returns total minus amount paid when showAsPaid is true', () => {
// Arrange
const total = 123.45;
const amountPaid = 23.45;
const expectedAmount = total - amountPaid;
const propsData = {
showAsPaid: true
};
const storeData = {
order: {
settledTenderAmount: amountPaid
}
};
const { wrapper } = getMountedComponent(storeData, {}, propsData);
const totalSpy = jest.spyOn(cartHelper, 'getCartTotal').mockReturnValue(total);
// Act
const result = wrapper.vm.amountDue;
// Assert
expect(result).toBe(expectedAmount);
});
});
describe('amountPaid', () => {
test('returns 0 when showAsPaid is false', () => {
// Arrange
const propsData = {
showAsPaid: false
};
const { wrapper } = getMountedComponent({}, {}, propsData);
// Act
const result = wrapper.vm.amountPaid;
// Assert
expect(result).toBe(0);
});
test('returns sum of subTotal and salesTax when showAsPaid is false', () => {
// TODO when subTotal and salesTax are finished
test('returns settled tender amount when showAsPaid is true', () => {
// Arrange
const expectedAmount = 123.45;
const propsData = {
showAsPaid: true
};
const storeData = {
order: {
settledTenderAmount: expectedAmount
}
};
const { wrapper } = getMountedComponent(storeData, {}, propsData);
// Act
const result = wrapper.vm.amountPaid;
// Assert
expect(result).toBe(expectedAmount);
});
});
describe('availableLineItems', () => {

View file

@ -1,6 +1,6 @@
<template>
<div
v-if="!isDeductibleOnly"
v-if="!isDeductibleOnly || showAsPaid"
class="cart-table">
<div class="cart-item-list">
<div
@ -53,7 +53,7 @@
id="cart-footer"
class="cart-footer">
<div
v-if="!isUnverified"
v-if="!isUnverified && !isDeductibleOnly"
id="cart-subtotal-and-tax"
class="subtotal-and-tax">
<div
@ -68,12 +68,23 @@
<span id="sales-tax-label">{{ salesTaxLabel }}</span>
<span id="sales-tax-value">{{ formatAmountInDollars(salesTax) }}</span>
</div>
<div
v-if="showAsPaid"
id="cart-amount-paid"
class="py-2 col d-flex justify-content-between">
</div>
<div
v-if="showAsPaid"
id="cart-total"
class="cart-item">
<div class="price-row">
<span id="total-label">{{ totalLabel }}</span>
<span id="total-value">{{ getDisplayed(total) }}</span>
</div>
</div>
<div
v-if="showAsPaid"
id="cart-amount-paid"
class="cart-item">
<div class="price-row">
<span id="amount-paid-label">{{ amountPaidLabel }}</span>
<span if="amount-paid-value">{{ getDisplayed(amountPaid) }}</span>
<span id="amount-paid-value">{{ getDisplayed(amountPaid) }}</span>
</div>
</div>
<div
@ -111,7 +122,7 @@ import {
getServiceLineItems, getSubtotal, isOrderITAC, isOrderNoComp,
isOrderUnverified
} from '@/helpers/cart-helper';
import { getPriceOfLineItems, getTaxOfLineItems } from '@/helpers/price-calculator';
import { getPriceOfLineItem, getPriceOfLineItems, getTaxOfLineItems } from '@/helpers/price-calculator';
import { processIfStatements } from '@/helpers/cms-content-helper';
const VERIFYING_COVERAGE = 'Verifying coverage';
@ -141,7 +152,8 @@ export default {
servicePackage: 'ServicePackageTitle',
vapsItemDescriptions: 'VapsItemDescriptions',
warrantyText: 'WarrantyCartItemTextWidget',
guaranteeText: 'GuaranteeCartItemTextWidget'
guaranteeText: 'GuaranteeCartItemTextWidget',
total: 'TotalWidget'
},
cartItemType
};
@ -176,7 +188,8 @@ export default {
},
servicePrice() {
const price = getPriceOfLineItems(getServiceLineItems(this.cartOrder)) ?? 0;
return price - this.recalibrationPrice;
const recycleFee = this.recycleFeeLineItem ? getPriceOfLineItem(this.recycleFeeLineItem) : 0;
return price - this.recalibrationPrice - recycleFee;
},
isUnverified() {
return isOrderUnverified(this.cartOrder);
@ -198,10 +211,10 @@ export default {
return getCartTotal(this.cartOrder);
},
amountDue() {
return this.showAsPaid ? 0 : this.total;
return this.total - this.amountPaid;
},
amountPaid() {
return !this.showAsPaid ? 0 : this.total;
return !this.showAsPaid ? 0 : this.cartOrder.settledTenderAmount;
},
availableLineItems() {
const { supportingItems, glassParts, otherParts, feeItems } = this.lineItems;
@ -278,6 +291,9 @@ export default {
salesTaxLabel() {
return this.getCmsContent(this.widget.salesTax, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
},
totalLabel() {
return this.getCmsContent(this.widget.total, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
},
recycleFeeCartItem() {
return this.recycleFeeLineItem
? this.getCartItem(
@ -414,6 +430,10 @@ export default {
a:hover {
color: $heritage-blue-secondary;
}
#amount-paid-label {
font-weight: 600;
}
}
.cart-footer {

View file

@ -281,11 +281,13 @@ export default {
},
serviceTypeText() {
const glassPieces = this.submittedOrder.lineItems.glassParts?.map((part) => part.partType.toLowerCase()) ?? [];
let glassList = getGlassList(glassPieces);
let glassList = '';
let workType = '';
if (this.isRepair) {
glassList = 'windshield';
workType = 'repair';
} else {
glassList = getGlassList(glassPieces);
workType = 'replacement';
if (this.hasRecalibrationPart) {
if (glassList === 'windshield') {
@ -622,7 +624,7 @@ export default {
}
.cart-container {
padding: 0 .9375rem;
padding: 0 .9375rem 2.1875rem;
}
.header {