diff --git a/src/helpers/line-items-helper.js b/src/helpers/line-items-helper.js new file mode 100644 index 00000000..b31d6f53 --- /dev/null +++ b/src/helpers/line-items-helper.js @@ -0,0 +1,4 @@ +// eslint-disable-next-line import/prefer-default-export +export function getLineItemsFlattened(lineItems) { + return lineItems?.flatMap((li) => [li, ...(getLineItemsFlattened(li.childParts))]) ?? []; +} diff --git a/src/helpers/line-items-helper.spec.js b/src/helpers/line-items-helper.spec.js new file mode 100644 index 00000000..af8337a7 --- /dev/null +++ b/src/helpers/line-items-helper.spec.js @@ -0,0 +1,55 @@ +import { getLineItemsFlattened } from '@/helpers/line-items-helper'; + +describe('getLineItemsFlattened', () => { + describe('getLineItemsFlattened', () => { + it('Returns empty array when null is passed', () => { + // Arrange + const lineItems = null; + // Act + const result = getLineItemsFlattened(lineItems); + + // Assert + expect(result).not.null; + expect(result).toStrictEqual([]); + }); + + it('Returns empty array when empty array is passed', () => { + // Arrange + const lineItems = []; + // Act + const result = getLineItemsFlattened(lineItems); + + // Assert + expect(result).not.null; + expect(result).toStrictEqual([]); + }); + + it('Returns line items as flat array without child parts', () => { + // Arrange + const lineItems = [{ partType: 'a' }, { partType: 'b' }, { partType: 'c' }]; + // Act + const result = getLineItemsFlattened(lineItems); + + // Assert + expect(result).not.null; + expect(result).toStrictEqual(lineItems); + }); + + it('Returns line items as flat array with child parts', () => { + // Arrange + const a = { partType: 'a' }; + const c = { partType: 'c' }; + const d = { partType: 'd' }; + const b = { partType: 'b', childParts: [c, d] }; + const e = { partType: 'e', childParts: null }; + + const lineItems = [a, b, e]; + // Act + const result = getLineItemsFlattened(lineItems); + + // Assert + expect(result).not.null; + expect(result).toStrictEqual([a, b, c, d, e]); + }); + }); +}); diff --git a/src/helpers/querystring-helper.js b/src/helpers/querystring-helper.js index f4df1ed7..59c1579c 100644 --- a/src/helpers/querystring-helper.js +++ b/src/helpers/querystring-helper.js @@ -1,3 +1,5 @@ +import { getLineItemsFlattened } from '@/helpers/line-items-helper'; + export default function getQueryStringParameter(key) { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); @@ -9,3 +11,20 @@ export default function getQueryStringParameter(key) { return lowerCaseParams.get(key.toLowerCase()); } + +export function buildQueryStringParameterFromArrayOfComplexObjects(arrayOfObjects, parameterName) { + let queryStringParameter = ''; + for (let i = 0; i < arrayOfObjects.length; i++) { + for (const [key, value] of Object.entries(arrayOfObjects[i])) { + queryStringParameter += `${parameterName}[${i}].${key}=${value}&`; + } + } + // Remove trailing & + return queryStringParameter.slice(0, -1); +} + +export function getLineItemQueryString(lineItems, parameterName) { + const queryString = getLineItemsFlattened(lineItems).map((lineItem, index) => + `${parameterName}[${index}].partNumber=${lineItem.partNumber}`).join('&'); + return queryString.length !== 0 ? `&${queryString}` : ''; +} diff --git a/src/helpers/querystring-helper.spec.js b/src/helpers/querystring-helper.spec.js new file mode 100644 index 00000000..1c7378be --- /dev/null +++ b/src/helpers/querystring-helper.spec.js @@ -0,0 +1,47 @@ +import { buildQueryStringParameterFromArrayOfComplexObjects, getLineItemQueryString } from '@/helpers/querystring-helper'; + +describe('querystring-helper', () => { + describe('buildQueryStringParameterFromArrayOfComplexObjects', () => { + it('returns a query string from a complex object', () => { + // Arrange + const object = [{ a: 'a', val: 24 }, { a: 'b', val: '52' }]; + + // Act + const result = buildQueryStringParameterFromArrayOfComplexObjects(object, 'param'); + + // Assert + expect(result).toBe('param[0].a=a¶m[0].val=24¶m[1].a=b¶m[1].val=52'); + }); + }); + + describe('getLineItemQueryString', () => { + it('returns empty query string from empty line items', () => { + // Arrange + const lineItems = []; + + // Act + const result = getLineItemQueryString(lineItems, 'param'); + + // Assert + expect(result).toBe(''); + }); + + it('returns a query string from line items', () => { + // Arrange + const a = { partNumber: 'a' }; + const c = { partNumber: 'c' }; + const d = { partNumber: 'd' }; + const b = { partNumber: 'b', childParts: [c, d] }; + const e = { partNumber: 'e' }; + + const lineItems = [a, b, e]; + + // Act + const result = getLineItemQueryString(lineItems, 'param'); + + // Assert + // eslint-disable-next-line max-len + expect(result).toBe('¶m[0].partNumber=a¶m[1].partNumber=b¶m[2].partNumber=c¶m[3].partNumber=d¶m[4].partNumber=e'); + }); + }); +}); diff --git a/src/store/index.js b/src/store/index.js index 8c6c5c7b..1b83b8a2 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -25,6 +25,8 @@ import partTypeStrings from '@/constants/part-type-strings'; import bailoutMessage from '@/constants/bailoutMessage'; import bailoutCode from '@/constants/bailoutCode'; import partNumberStrings from '@/constants/part-number-strings'; +import { getLineItemsFlattened } from '@/helpers/line-items-helper'; +import { buildQueryStringParameterFromArrayOfComplexObjects, getLineItemQueryString } from '@/helpers/querystring-helper'; const storeId = 'main'; @@ -1063,7 +1065,7 @@ export const useMainStore = defineStore({ + `&CTU=${ctuToUse}` + `&Deductible=${deductibleToUse}` + `&ZipCode=${zipCodeToUse}` - + `&${lineItemsQueryString}`; + + `${lineItemsQueryString}`; const lineItemServerData = this.order.lineItems?.serverData; if (lineItemServerData) { @@ -1112,7 +1114,7 @@ export const useMainStore = defineStore({ return globalMethods.callHttpClient({ method: endpoints.GetServiceabilityDetails.method, - endpoint: `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}&${lineItems}&${glassPieces}` + endpoint: `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}${lineItems}&${glassPieces}` }); }, mapTaxedLineItemsToStoreFormat(availableLineItems, storeLineItems) { @@ -2028,14 +2030,14 @@ export const useMainStore = defineStore({ + `&ServiceLocation.City=${serviceLocationCity}` + `&ServiceLocation.State=${serviceLocationState}` + `&ServiceLocation.ZipCode=${serviceLocationZipCode}` - + `&${lineItemsQueryString}`; + + `${lineItemsQueryString}`; } else { queryString = `ParentAccountNumber=${this.order.accountNumber}` + `&BillToAccountNumber=${this.billToNumberToUse}` + `&ProviderNumber=${providerNumber}` + `&AppointmentType=${appointmentType}` - + `&${lineItemsQueryString}`; + + `${lineItemsQueryString}`; } const lineItemServerData = this.order.lineItems.serverData; @@ -2576,26 +2578,6 @@ function addTaxesToPricedLineItems(pricedLineItems, taxingLineItems = []) { return pricedLineItems; } -function getLineItemQueryString(lineItems, parameterName) { - return getLineItemsFlattened(lineItems).map((lineItem, index) => - `${parameterName}[${index}].partNumber=${lineItem.partNumber}`).join('&'); -} - -function getLineItemsFlattened(lineItems) { - return lineItems?.flatMap((li) => [li, ...(getLineItemsFlattened(li.childParts) ?? [])]) ?? []; -} - -function buildQueryStringParameterFromArrayOfComplexObjects(arrayOfObjects, parameterName) { - let queryStringParameter = ''; - for (let i = 0; i < arrayOfObjects.length; i++) { - for (const [key, value] of Object.entries(arrayOfObjects[i])) { - queryStringParameter += `${parameterName}[${i}].${key}=${value}&`; - } - } - // Remove trailing & - return queryStringParameter.slice(0, -1); -} - function convertGlassPieceToBackEndCompatibleFormat(glassPieces) { return glassPieces.map((glassPiece) => ({ location: glassPiece.glassLocation,