diff --git a/furniture-3d-system/src/app/intake/non-integrated/NonIntegratedDetailClient.tsx b/furniture-3d-system/src/app/intake/non-integrated/NonIntegratedDetailClient.tsx index bd6e1527..91ea89ed 100644 --- a/furniture-3d-system/src/app/intake/non-integrated/NonIntegratedDetailClient.tsx +++ b/furniture-3d-system/src/app/intake/non-integrated/NonIntegratedDetailClient.tsx @@ -594,6 +594,14 @@ import { getSkuFactoryModelKey, getSkuPackageGroupKey, } from "./productFactoryKeyHelpers"; +import { + getProductFactoryMissingFieldLabels, + hasPackageSharedFactoryRowContent, + isProductFactoryRowComplete, + mergePackageSharedFactoryRow, + normalizeFactorySupplier, + normalizeModelSharedProductFactoryRows, +} from "./productFactoryHelpers"; import { getSkuAssemblyPreviewNodes, hasSkuAssemblyPreviewNodes, @@ -3316,22 +3324,6 @@ function buildSkuItemFromImportedRow( }; } -function normalizeFactorySupplier( - value: string, - supplierCodeByName: ReadonlyMap = SUPPLIER_CODE_BY_NAME, -) { - const normalizedName = value.trim(); - const matchedSupplier = resolveSupplierEntryByName( - normalizedName, - supplierCodeByName, - ); - - return { - name: matchedSupplier ? matchedSupplier.name : normalizedName, - code: matchedSupplier ? matchedSupplier.code : "", - }; -} - function resolveAutoAwareBarcode( currentBarcode: string | undefined, fallbackBarcode: string, @@ -3356,29 +3348,6 @@ function resolveAutoAwareBarcode( return fallbackBarcode; } -function hasPackageSharedFactoryRowContent(row: NonIntegratedFactoryRow) { - return Array.from(PACKAGE_SHARED_PRODUCT_FACTORY_PURCHASING_KEYS).some((key) => - row[key].trim(), - ); -} - -function mergePackageSharedFactoryRow( - exactRow: NonIntegratedFactoryRow | undefined, - sharedRow: NonIntegratedFactoryRow | undefined, -) { - if (!sharedRow) return exactRow; - if (!exactRow) return sharedRow; - - return { - ...exactRow, - confirmed: exactRow.confirmed || sharedRow.confirmed, - supplierName: sharedRow.supplierName, - supplierCode: sharedRow.supplierCode, - leadTime: sharedRow.leadTime, - assemblyMode: sharedRow.assemblyMode, - }; -} - function createProductFactoryRowFromSku( sku: NonIntegratedSkuItem, existingRow?: NonIntegratedFactoryRow, @@ -3469,47 +3438,6 @@ function buildProductFactoryRows( return normalizeModelSharedProductFactoryRows(rows); } -function normalizeModelSharedProductFactoryRows( - rows: NonIntegratedFactoryRow[], -) { - const rowsByModelKey = new Map(); - - rows.forEach((row) => { - const modelKey = getSkuFactoryModelKey(row); - if (!modelKey) return; - - const modelRows = rowsByModelKey.get(modelKey) ?? []; - modelRows.push(row); - rowsByModelKey.set(modelKey, modelRows); - }); - - const sharedValueByModelAndKey = new Map(); - rowsByModelKey.forEach((modelRows, modelKey) => { - MODEL_SHARED_PRODUCT_FACTORY_KEYS.forEach((key) => { - const sharedValue = - modelRows.find((row) => row[key].trim())?.[key].trim() ?? ""; - sharedValueByModelAndKey.set(`${modelKey}:${key}`, sharedValue); - }); - }); - - return rows.map((row) => { - const modelKey = getSkuFactoryModelKey(row); - if (!modelKey) return row; - - let nextRow = row; - MODEL_SHARED_PRODUCT_FACTORY_KEYS.forEach((key) => { - const sharedValue = sharedValueByModelAndKey.get(`${modelKey}:${key}`); - if (sharedValue === undefined || nextRow[key] === sharedValue) return; - nextRow = { - ...nextRow, - [key]: sharedValue, - }; - }); - - return nextRow; - }); -} - function normalizeFactoryRowsForPayload( rows: NonIntegratedFactoryRow[], supplierCodeByName: ReadonlyMap = SUPPLIER_CODE_BY_NAME, @@ -3555,16 +3483,6 @@ function normalizeFactoryRowsForPayload( return normalizeModelSharedProductFactoryRows(normalizedRows); } -function getProductFactoryMissingFieldLabels(row: NonIntegratedFactoryRow) { - return PRODUCT_FACTORY_REQUIRED_FIELDS.filter( - ({ key }) => !row[key].trim(), - ).map(({ label }) => label); -} - -function isProductFactoryRowComplete(row: NonIntegratedFactoryRow) { - return getProductFactoryMissingFieldLabels(row).length === 0; -} - type PlanningLayoutTextFieldKey = | "priceBand" | "shop"; diff --git a/furniture-3d-system/src/app/intake/non-integrated/productFactoryHelpers.ts b/furniture-3d-system/src/app/intake/non-integrated/productFactoryHelpers.ts new file mode 100644 index 00000000..45f268e1 --- /dev/null +++ b/furniture-3d-system/src/app/intake/non-integrated/productFactoryHelpers.ts @@ -0,0 +1,103 @@ +import type { NonIntegratedFactoryRow } from "./nonIntegratedStorage"; +import { resolveSupplierEntryByName } from "./detailValueHelpers"; +import { getSkuFactoryModelKey } from "./productFactoryKeyHelpers"; +import { + MODEL_SHARED_PRODUCT_FACTORY_KEYS, + PACKAGE_SHARED_PRODUCT_FACTORY_PURCHASING_KEYS, + PRODUCT_FACTORY_REQUIRED_FIELDS, +} from "./skuFieldConfig"; +import { SUPPLIER_CODE_BY_NAME } from "./supplierDirectory"; + +export function normalizeFactorySupplier( + value: string, + supplierCodeByName: ReadonlyMap = SUPPLIER_CODE_BY_NAME, +) { + const normalizedName = value.trim(); + const matchedSupplier = resolveSupplierEntryByName( + normalizedName, + supplierCodeByName, + ); + + return { + name: matchedSupplier ? matchedSupplier.name : normalizedName, + code: matchedSupplier ? matchedSupplier.code : "", + }; +} + +export function hasPackageSharedFactoryRowContent( + row: NonIntegratedFactoryRow, +) { + return Array.from(PACKAGE_SHARED_PRODUCT_FACTORY_PURCHASING_KEYS).some((key) => + row[key].trim(), + ); +} + +export function mergePackageSharedFactoryRow( + exactRow: NonIntegratedFactoryRow | undefined, + sharedRow: NonIntegratedFactoryRow | undefined, +) { + if (!sharedRow) return exactRow; + if (!exactRow) return sharedRow; + + return { + ...exactRow, + confirmed: exactRow.confirmed || sharedRow.confirmed, + supplierName: sharedRow.supplierName, + supplierCode: sharedRow.supplierCode, + leadTime: sharedRow.leadTime, + assemblyMode: sharedRow.assemblyMode, + }; +} + +export function normalizeModelSharedProductFactoryRows( + rows: NonIntegratedFactoryRow[], +) { + const rowsByModelKey = new Map(); + + rows.forEach((row) => { + const modelKey = getSkuFactoryModelKey(row); + if (!modelKey) return; + + const modelRows = rowsByModelKey.get(modelKey) ?? []; + modelRows.push(row); + rowsByModelKey.set(modelKey, modelRows); + }); + + const sharedValueByModelAndKey = new Map(); + rowsByModelKey.forEach((modelRows, modelKey) => { + MODEL_SHARED_PRODUCT_FACTORY_KEYS.forEach((key) => { + const sharedValue = + modelRows.find((row) => row[key].trim())?.[key].trim() ?? ""; + sharedValueByModelAndKey.set(`${modelKey}:${key}`, sharedValue); + }); + }); + + return rows.map((row) => { + const modelKey = getSkuFactoryModelKey(row); + if (!modelKey) return row; + + let nextRow = row; + MODEL_SHARED_PRODUCT_FACTORY_KEYS.forEach((key) => { + const sharedValue = sharedValueByModelAndKey.get(`${modelKey}:${key}`); + if (sharedValue === undefined || nextRow[key] === sharedValue) return; + nextRow = { + ...nextRow, + [key]: sharedValue, + }; + }); + + return nextRow; + }); +} + +export function getProductFactoryMissingFieldLabels( + row: NonIntegratedFactoryRow, +) { + return PRODUCT_FACTORY_REQUIRED_FIELDS.filter( + ({ key }) => !row[key].trim(), + ).map(({ label }) => label); +} + +export function isProductFactoryRowComplete(row: NonIntegratedFactoryRow) { + return getProductFactoryMissingFieldLabels(row).length === 0; +}