Merge branch 'develop' into feature/SSR-1464

This commit is contained in:
Katie Kroell 2024-10-18 12:21:28 -04:00
commit 0cf68c2c8a
8 changed files with 151 additions and 57 deletions

View file

@ -4,8 +4,8 @@ import submitType from '@/constants/submit-type';
/* /*
Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing
*/ */
async function saveSessionHelper(store, { submitAfterSave }) { async function saveSessionHelper(store, { submitAfterSave, createWorkOrderNumberForPIA }) {
const savedSessionInfo = await store.saveSession({ submitAfterSave }); const savedSessionInfo = await store.saveSession({ submitAfterSave, createWorkOrderNumberForPIA });
if (savedSessionInfo) { if (savedSessionInfo) {
store.setSaveSessionInfo(savedSessionInfo.data); store.setSaveSessionInfo(savedSessionInfo.data);
} }
@ -16,11 +16,11 @@ async function saveSessionHelper(store, { submitAfterSave }) {
This will also set Referral information in the store after saving, and then This will also set Referral information in the store after saving, and then
update the cookie. To force synchronous behavior pass in 'true' for shouldAwaitSaveSessionQueue update the cookie. To force synchronous behavior pass in 'true' for shouldAwaitSaveSessionQueue
*/ */
export async function saveSession({ shouldAwaitSaveSessionQueue = false, submitAfterSave = false }) { export async function saveSession({ shouldAwaitSaveSessionQueue = false, submitAfterSave = false, createWorkOrderNumberForPIA = false }) {
const store = useMainStore(); const store = useMainStore();
const saveSessionPromise = store.applicationUser.saveSessionPromise const saveSessionPromise = store.applicationUser.saveSessionPromise
? store.applicationUser.saveSessionPromise.then(() => saveSessionHelper(store, { submitAfterSave })) ? store.applicationUser.saveSessionPromise.then(() => saveSessionHelper(store, { submitAfterSave, createWorkOrderNumberForPIA }))
: saveSessionHelper(store, { submitAfterSave }); : saveSessionHelper(store, { submitAfterSave, createWorkOrderNumberForPIA });
store.setSaveSessionPromise(saveSessionPromise); store.setSaveSessionPromise(saveSessionPromise);

View file

@ -43,3 +43,29 @@ export function getTaxLineItemQueryString(lineItems, parameterName) {
+ `&${parameterName}[${index}].kitPrice=${lineItem.kitPrice}`).join('&'); + `&${parameterName}[${index}].kitPrice=${lineItem.kitPrice}`).join('&');
return queryString.length !== 0 ? `&${queryString}` : ''; return queryString.length !== 0 ? `&${queryString}` : '';
} }
export function buildURLSearchParams(data) {
const params = new URLSearchParams();
Object.entries(data).forEach(([key, value]) => {
if (value == null) {
return;
}
if (Array.isArray(value)) {
value.forEach((arrayValue, index) => {
if (typeof value === 'object') {
Object.entries(arrayValue).forEach(([objectKey, objectValue]) => {
if (objectValue != null) {
params.append(`${key}[${index}].${objectKey}`, `${objectValue}`);
}
});
} else {
params.append(`${key}[${index}]`, `${value}`);
}
});
} else {
params.append(key, `${value}`);
}
});
return params;
}

View file

@ -395,9 +395,10 @@ export default {
showIssLoadingModal(false); showIssLoadingModal(false);
}, },
async getPricedParts() { async getPricedParts() {
const { glassParts } = this.mainStore.order.lineItems; const { glassParts, supportingItems } = this.mainStore.order.lineItems;
const availableLineItems = [ const availableLineItems = [
...(glassParts ?? []) ...(glassParts ?? []),
...(supportingItems ?? [])
]; ];
// We only call the ITAC pricing endpoint if we are not repair or we are NoComp // We only call the ITAC pricing endpoint if we are not repair or we are NoComp

View file

@ -920,6 +920,29 @@ describe('OrderConfirmation.vue', () => {
// Act // Act
const testValue = wrapper.vm.isDropOffAppointment; const testValue = wrapper.vm.isDropOffAppointment;
// Assert
expect(testValue).toBe(expected);
});
});
describe('showCart', () => {
test.each([
[true, true, 100],
[true, false, 100],
[false, true, 0],
[false, true, null]
])('showCart is %p when is PIA is %p and settledTenderAmount is %p', (expected, isPia, settledTenderAmount) => {
// Arrange
const order = deepClone(sessionStorage);
order.payment.isPayInAdvance = isPia;
order.settledTenderAmount = settledTenderAmount;
const mockStoreActions = () => {
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
};
const { wrapper } = getMountedComponent({}, {}, mockStoreActions);
// Act
const testValue = wrapper.vm.showCart;
// Assert // Assert
expect(testValue).toBe(expected); expect(testValue).toBe(expected);
}); });

View file

@ -56,6 +56,7 @@
<hr class="mb-0" /> <hr class="mb-0" />
<div> <div>
<cartDropdown <cartDropdown
v-if="showCart"
:showAsPaid="payment.isPayInAdvance" :showAsPaid="payment.isPayInAdvance"
:readOnly="true" :readOnly="true"
:isInitiallyExpanded="false" :isInitiallyExpanded="false"
@ -305,6 +306,19 @@ export default {
this.schedule.jobMinMinutes, this.schedule.jobMinMinutes,
this.schedule.jobMaxMinutes this.schedule.jobMaxMinutes
); );
},
showCart() {
if (!this.payment.isPayInAdvance) {
return true;
}
if (this.submittedOrder.settledTenderAmount > 0) {
return true;
}
// settleTenderAmount always shows 0 via localhost or dev.
// Temporarily set return true to see cart in localhost or dev environment
return false;
} }
}, },
mounted() { mounted() {

View file

@ -89,9 +89,10 @@ import issPageValues from '@/router/router-constants/issPage-values';
import bailoutMessage from '@/constants/bailoutMessage'; import bailoutMessage from '@/constants/bailoutMessage';
import { AppointmentTypeStrings } from '@/constants/schedule-constants'; import { AppointmentTypeStrings } from '@/constants/schedule-constants';
import VehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue'; import VehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
import { submitWorkOrder } from '@/helpers/order-helper.js'; import { saveSession, submitWorkOrder } from '@/helpers/order-helper.js';
import { experimentSettings } from '@/constants/experiments'; import { experimentSettings } from '@/constants/experiments';
import submitType from '@/constants/submit-type'; import submitType from '@/constants/submit-type';
import routerParams from '@/router/router-constants/router-params';
export default { export default {
name: 'payment-method', name: 'payment-method',
@ -284,9 +285,16 @@ export default {
console.error(`error: response from submit work order:${error.message}`); console.error(`error: response from submit work order:${error.message}`);
} }
} else { } else {
await saveSession({
createWorkOrderNumberForPIA: true,
shouldAwaitSaveSessionQueue: true
});
this.$router.navigate( this.$router.navigate(
this.navigationScenarios.CLICKED_PAY_NOW, this.navigationScenarios.CLICKED_PAY_NOW,
this.$route this.$route,
{},
{ [routerParams.SKIP_SAVE_SESSION]: true }
); );
} }
} }

View file

@ -415,8 +415,10 @@ export default {
if (this.isWindshieldRepair) { if (this.isWindshieldRepair) {
const results = await Promise.allSettled([useMainStore().getSupportingItems(), useMainStore().getRecalParts()]); const results = await Promise.allSettled([useMainStore().getSupportingItems(), useMainStore().getRecalParts()]);
const supportingItems = results[0]; const supportingItems = results[0].value;
useMainStore().updateSupportingItems(supportingItems.data); useMainStore().updateSupportingItems(supportingItems.data);
} else {
useMainStore().updateSupportingItems([]);
} }
if (this.mainStore.damage.isRepair) { if (this.mainStore.damage.isRepair) {

View file

@ -26,7 +26,7 @@ import bailoutCode from '@/constants/bailoutCode';
import partNumberStrings from '@/constants/part-number-strings'; import partNumberStrings from '@/constants/part-number-strings';
import { findLineItemIndex, getLineItemsFlattened } from '@/helpers/line-items-helper'; import { findLineItemIndex, getLineItemsFlattened } from '@/helpers/line-items-helper';
import { import {
buildQueryStringParameterFromArrayOfComplexObjects, buildQueryStringParameterFromArrayOfComplexObjects, buildURLSearchParams,
getLineItemQueryString, getLineItemQueryString,
getPartNumbersListForQueryString, getPartNumbersListForQueryString,
getTaxLineItemQueryString getTaxLineItemQueryString
@ -214,6 +214,8 @@ export const getDefaultState = () => ({
eon: null, eon: null,
workOrderId: null, workOrderId: null,
workOrderNumber: null, workOrderNumber: null,
settledTenderAmount: null,
lockToken: null,
customerPortalLoginToken: null, customerPortalLoginToken: null,
originalDeductible: null, originalDeductible: null,
currentDeductible: null, currentDeductible: null,
@ -1205,49 +1207,53 @@ export const useMainStore = defineStore({
}, },
async getCombinedQuote(availableLineItems) { async getCombinedQuote(availableLineItems) {
const { vehicle, serviceLocation, policy, eon, referralNumber, referralDate, referralSequenceNumber, lineItems } = this.order; if (availableLineItems && availableLineItems.length > 0) {
const { vehicle, serviceLocation, policy, eon, referralNumber, referralDate, referralSequenceNumber, lineItems } = this.order;
const payload = { const payload = {
ParentAccountNumber: this.order.parentAccountNumber, ParentAccountNumber: this.order.parentAccountNumber,
BillToAccountNumber: this.billToAccountNumber, BillToAccountNumber: this.billToAccountNumber,
ProviderNumber: this.providerNumber, ProviderNumber: this.providerNumber,
CarId: vehicle.carId, CarId: vehicle.carId,
Make: vehicle.make, Make: vehicle.make,
Model: vehicle.model, Model: vehicle.model,
Year: vehicle.year, Year: vehicle.year,
EON: eon, EON: eon,
ZipCode: policy.policyZipCode, ZipCode: policy.policyZipCode,
State: policy.damageState, State: policy.damageState,
ReferralNumber: referralNumber, ReferralNumber: referralNumber,
ReferralDate: referralDate, ReferralDate: referralDate,
ReferralSequenceNumber: referralSequenceNumber, ReferralSequenceNumber: referralSequenceNumber,
ServiceZipCode: serviceLocation.zipCode, ServiceZipCode: serviceLocation.zipCode,
IsReplacement: !this.isRepair, IsReplacement: !this.isRepair,
ServerData: lineItems.serverData, ServerData: lineItems.serverData,
LineItems: getLineItemsFlattened(availableLineItems) LineItems: getLineItemsFlattened(availableLineItems)
}; };
const response = await globalMethods const response = await globalMethods
.callHttpClient({ .callHttpClient({
method: endpoints.GetCombinedQuote.method, method: endpoints.GetCombinedQuote.method,
endpoint: endpoints.GetCombinedQuote.url, endpoint: endpoints.GetCombinedQuote.url,
payload payload
}) })
.catch((error) => { .catch((error) => {
console.error(error); console.error(error);
return []; return [];
}); });
const { lineItems: pricedLinedItems, serverData } = response.data; const { lineItems: pricedLinedItems, serverData } = response.data;
if (serverData) { if (serverData) {
this.order.lineItems.serverData = serverData; this.order.lineItems.serverData = serverData;
}
if (pricedLinedItems) {
return addPricesToLineItems(availableLineItems, pricedLinedItems);
}
return availableLineItems;
} }
if (pricedLinedItems) { return [];
return addPricesToLineItems(availableLineItems, pricedLinedItems);
}
return availableLineItems;
}, },
getMobileFeePart() { getMobileFeePart() {
@ -1272,18 +1278,26 @@ export const useMainStore = defineStore({
}, },
getServiceabilityDetails({ serviceZipCode }) { getServiceabilityDetails({ serviceZipCode }) {
const lineItems = getLineItemQueryString(this.order.lineItems.supportingItems, 'lineItems'); const { vehicle, damage, parentAccountNumber, referralSequenceNumber, lineItems } = this.order;
const { vehicle } = this.order;
const { carId } = vehicle; const { carId } = vehicle;
const { damage } = this.order;
const glassArray = convertGlassPieceNamingForApi(damage.glassToReplace); const glassArray = convertGlassPieceNamingForApi(damage.glassToReplace);
const lineItemParts = [...(lineItems.glassParts || []), ...(lineItems.supportingItems || [])].map((part) => ({
partNumber: part.partNumber,
recalibrationType: part.recalibrationType
}));
const glassPieces = buildQueryStringParameterFromArrayOfComplexObjects(glassArray, 'glassPieces'); const params = buildURLSearchParams({
parentAccountNumber,
referralSequenceNumber,
zip: serviceZipCode,
carId,
glassPieces: glassArray,
lineItems: lineItemParts
});
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetServiceabilityDetails.method, method: endpoints.GetServiceabilityDetails.method,
endpoint: `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}${lineItems}&${glassPieces}` endpoint: `${endpoints.GetServiceabilityDetails.url}?${params.toString()}`
}); });
}, },
lookupVehicleByVin(vin) { lookupVehicleByVin(vin) {
@ -1318,12 +1332,14 @@ export const useMainStore = defineStore({
this.order.referralCorrelationId = response.referralCorrelationId; this.order.referralCorrelationId = response.referralCorrelationId;
this.order.eon = response.eon; this.order.eon = response.eon;
this.order.workOrderNumber = response.workOrderNumber; this.order.workOrderNumber = response.workOrderNumber;
this.order.settledTenderAmount = response.settledTenderAmount;
this.order.lockToken = response.lockToken;
this.order.customerPortalLoginToken = response.customerPortalLoginToken; this.order.customerPortalLoginToken = response.customerPortalLoginToken;
this.applicationUser.savedSessionId = response.savedSessionId; this.applicationUser.savedSessionId = response.savedSessionId;
this.applicationUser.crmCustomerId = response.crmCustomerId.toString(); this.applicationUser.crmCustomerId = response.crmCustomerId.toString();
}, },
saveSession({ submitAfterSave }) { saveSession({ submitAfterSave, createWorkOrderNumberForPIA }) {
const { vehicle, damage, policy, customer, contactInfo, payment, const { vehicle, damage, policy, customer, contactInfo, payment,
lineItems, serviceLocation, schedule, insuranceCoverage } = this.order; lineItems, serviceLocation, schedule, insuranceCoverage } = this.order;
@ -1463,6 +1479,8 @@ export const useMainStore = defineStore({
referralSequenceNumber: this.order.referralSequenceNumber, referralSequenceNumber: this.order.referralSequenceNumber,
eon: this.order.eon, eon: this.order.eon,
submitToMainframe: !!this.order.referralNumber, submitToMainframe: !!this.order.referralNumber,
createWorkOrderNumberForPIA: createWorkOrderNumberForPIA,
lockToken: this.order.lockToken,
loadedFromDupeCheck, loadedFromDupeCheck,
submitAfterSave: !!submitAfterSave submitAfterSave: !!submitAfterSave
}; };
@ -1841,7 +1859,7 @@ export const useMainStore = defineStore({
}, },
updateSupportingItems(partsData) { updateSupportingItems(partsData) {
if (partsData == null) { if (partsData == null) {
this.order.lineItems.supportingItems = null; this.order.lineItems.supportingItems = [];
return; return;
} }
@ -1977,6 +1995,8 @@ export const useMainStore = defineStore({
this.order.referralSequenceNumber = null; this.order.referralSequenceNumber = null;
this.order.workOrderId = null; this.order.workOrderId = null;
this.order.workOrderNumber = null; this.order.workOrderNumber = null;
this.order.settledTenderAmount = null;
this.order.lockToken = null;
this.order.eon = null; this.order.eon = null;
this.order.originalDeductible = null; this.order.originalDeductible = null;
this.order.currentDeductible = null; this.order.currentDeductible = null;
@ -2051,7 +2071,7 @@ export const useMainStore = defineStore({
resetGlassPartsState() { resetGlassPartsState() {
this.order.lineItems.glassParts = null; this.order.lineItems.glassParts = null;
this.order.lineItems.supportingItems = null; this.order.lineItems.supportingItems = [];
this.order.lineItems.vaps = null; this.order.lineItems.vaps = null;
this.order.lineItems.feeItems = []; this.order.lineItems.feeItems = [];
this.order.lineItems.serverData = null; this.order.lineItems.serverData = null;