diff --git a/app/src/components/InventoryTable.vue b/app/src/components/InventoryTable.vue index ca6dce3..779e325 100644 --- a/app/src/components/InventoryTable.vue +++ b/app/src/components/InventoryTable.vue @@ -126,7 +126,7 @@ variant="light" @click=" openUrlInNewWindow( - vinDetail[row.item.vin]['DI']['DealerVDPURL'], + vinDetail[row.item.vin]['DI']['DealerVDPURL'] ) " class="mr-2 align-middle" @@ -149,7 +149,7 @@ variant="light" @click=" openUrlInNewWindow( - generateGenesisWindowStickerUrl(row.item.vin, form.model), + generateGenesisWindowStickerUrl(row.item.vin, form.model) ) " class="mr-2 align-middle" @@ -344,7 +344,7 @@ sortable: true, sortDirection: "desc", showFor: ["all"], - hideFor: [], + hideFor: ["Chevrolet"], }, { key: "drivetrainDesc", @@ -446,7 +446,7 @@ // A lot of additional detail is included in the inventory data, so // passing the inventory API response into getVinDetail to display in the // VIN detail section - this.item, + this.item ); }, async hyundai() { @@ -454,7 +454,7 @@ this.item.vin, this.manufacturer, this.model, - this.year, + this.year ); }, async kia() { @@ -470,7 +470,7 @@ return await getVolkswagenVinDetail( this.zipcode, this.item.vin, - this.manufacturer, + this.manufacturer ); }, async ford() { @@ -481,7 +481,7 @@ this.item.modelYear, this.item.dealerPaCode, this.zipcode, - this.manufacturer, + this.manufacturer ); }, async audi() { @@ -568,7 +568,7 @@ filterFunction(rowRecord, filterSelections) { // selectedCategories looks like ['trimDesc', ['LIMITED', 'SEL']] var selectedCategories = Object.entries(filterSelections).filter( - (f) => f[1].length > 0, + (f) => f[1].length > 0 ); var selectedCategoriesCount = selectedCategories.length; var isMatch = []; @@ -583,7 +583,7 @@ return this.filterByPrice(rowRecord, selectedPrice); } else { return selectedCategories[0][1].some((val) => - Object.values(rowRecord).includes(val), + Object.values(rowRecord).includes(val) ); } } else if (selectedCategoriesCount > 1) { @@ -598,7 +598,7 @@ // Each loop is a category. Do we have an OR match for the selected filter items? // e.g. Blue OR Black OR White isMatch.push( - selectedItems.some((s) => Object.values(rowRecord).includes(s)), + selectedItems.some((s) => Object.values(rowRecord).includes(s)) ); } } @@ -639,7 +639,7 @@ (field) => (field.showFor.includes("all") || field.showFor.includes(this.form.manufacturer)) && - !field.hideFor.includes(this.form.manufacturer), + !field.hideFor.includes(this.form.manufacturer) ); return f; diff --git a/app/src/manufacturers/chevrolet.js b/app/src/manufacturers/chevrolet.js index 4d15f27..682bb1e 100644 --- a/app/src/manufacturers/chevrolet.js +++ b/app/src/manufacturers/chevrolet.js @@ -1,5 +1,5 @@ /** - * Copyright 2023 Joel Gomez, Ben Chapman + * Copyright 2023 Joel Gomez, 2023 - 2024 Ben Chapman * * This file is part of The EV Finder. * @@ -17,7 +17,7 @@ import { convertToCurrency, generateErrorMessage, titleCase } from "../helpers/libs"; import { apiRequest } from "../helpers/request"; -import { chevroletInventoryMapping, chevroletVinMapping } from "./chevroletMappings"; +import { chevroletVinMapping } from "./chevroletMappings"; const manufacturer = "chevrolet"; @@ -46,69 +46,19 @@ export async function getChevroletInventory(zip, year, model, radius, manufactur * @returns a "normalized" inventory object */ function formatChevroletInventoryResults(input) { - // find exterior and interior color mappings from filter values - const extColors = input.data?.filters - .find((item) => item.key == "extColor") - .values.reduce( - (colors, color) => ({ ...colors, [color.value]: color.displayValue }), - {}, - ); - - // for interior colors, also include a hint for the material type - const intColors = input.data?.filters - .find((item) => item.key == "intColor") - .values.reduce( - (colors, color) => ({ - ...colors, - [color.value]: `${color.displayValue.split(",")[0]}, ${ - color.displayValue.split(",")[1].split(" ")[1] - }`, - }), - {}, - ); - const results = []; - - input.data?.listResponse.forEach((vehicle) => { - const _vehicle = {}; - - // bring some nested values up to the top level and create entries that don't exist - const enhancedResult = { - ...vehicle, - dealerName: titleCase(vehicle?.dealer?.name), - dealerDistance: vehicle.dealer?.distance, - trimName: vehicle.trim?.name, - totalPrice: vehicle.pricing?.cash?.summary?.items - .find((item) => item.type == "total_vehicle_price") - .value.toString(), - vehicleAvailabilityDisplayStatus: titleCase( - vehicle.vehicleAvailabilityStatus?.displayStatus, - ), - extColor: extColors[colorCodeFromUrl(vehicle.extImages[0])], - intColor: intColors[colorCodeFromUrl(vehicle.intImages[0])], - drivetrainDesc: "FWD", // hard coded for Bolt EV, Bolt EUV; future models may require better strategy for deriving this. - }; - - Object.keys(enhancedResult).forEach((key) => { - // Remap the Chevrolet-specific key into the EV Finder specific key - if (Object.keys(chevroletInventoryMapping).includes(key)) { - _vehicle[chevroletInventoryMapping[key]] = enhancedResult[key]; - } else { - // If there's no EV Finder-specific key, just append the Chevrolet key - _vehicle[key] = enhancedResult[key]; - } + input?.data?.hits.forEach((vehicle) => { + results.push({ + dealerName: titleCase(vehicle.dealer.name), + deliveryDate: vehicle.stockDetails.estimatedDeliveryDate, + drivetrainDesc: vehicle.driveType, + distance: vehicle.dealer.distance.value, + price: vehicle.pricing.cash.msrp.value, + exteriorColor: vehicle.baseExteriorColor, + interiorColor: vehicle.baseInteriorColor, + vin: vehicle.id, + trimDesc: vehicle.variant.name, }); - - // Some inventory is marked as "Temporarily Unavailable", which is exposed through - // a recall key, and not vehicleAvailabilityStatus. Dealing with that here - if (vehicle.recall) { - _vehicle["deliveryDate"] = vehicle.recall?.displayStatus; - } - - // Populate inventoryStatus which is exposed as the Availability filter - _vehicle["inventoryStatus"] = _vehicle["deliveryDate"]; - - results.push(_vehicle); }); return results; } @@ -135,7 +85,7 @@ export async function getChevroletVinDetail(vin) { totalVehiclePrice: convertToCurrency( vinData.data.prices?.summary .find((item) => item.type == "total_vehicle_price") - .value.toString() ?? "0", + .value.toString() ?? "0" ), trimName: vinData.data.trim?.name, extColorOptionCode: vinData.data.extColor?.optionCode, @@ -157,16 +107,3 @@ export async function getChevroletVinDetail(vin) { return vinFormattedData; } - -/** - * Utility function to extract the color code from image urls. - * An image url has the color code as the first substring of a substring - * in a long query param. - * - * @param {String} url the image url to extract the color code from - * @returns the color code as a string, e.g. GAZ - */ -function colorCodeFromUrl(url) { - const color = new URL(url); - return color.search.split("/")[3].split("_")[0]; -}