diff --git a/furniture-3d-system/src/app/intake/non-integrated/NonIntegratedDetailClient.test.tsx b/furniture-3d-system/src/app/intake/non-integrated/NonIntegratedDetailClient.test.tsx index 7aa07ea0..fe505f15 100644 --- a/furniture-3d-system/src/app/intake/non-integrated/NonIntegratedDetailClient.test.tsx +++ b/furniture-3d-system/src/app/intake/non-integrated/NonIntegratedDetailClient.test.tsx @@ -1844,6 +1844,47 @@ describe("NonIntegratedDetailClient", () => { expect(await screen.findByText("已匹配 1 张SKU图片")).toBeInTheDocument(); }); + it("matches batch SKU images for workbook imported SKU rows", async () => { + const actor = userEvent.setup(); + saveNonIntegratedProduct( + createProductRecord({ + id: "DNZ0405-imported-sku-image-match", + spu: "DNZ0405", + skuItems: [ + createSkuItem({ + id: "sku-imported-image-match-1", + skuSequence: 1, + skuCode: "DNZ040501", + barcode: "DNZ040501N1440V01", + source: "sku_workbook", + sourceTable: "sku_workbook", + contentLocked: true, + }), + ], + }), + ); + + const { container } = render( + , + ); + + expect(screen.getByDisplayValue("DNZ040501")).toBeInTheDocument(); + const batchSkuImageInput = container.querySelector( + 'input[type="file"][accept="image/*"][multiple]', + ); + expect(batchSkuImageInput).toBeInTheDocument(); + + await actor.upload( + batchSkuImageInput!, + new File(["image"], "DNZ040501.jpg", { type: "image/jpeg" }), + ); + + expect(await screen.findByText(/1 .*SKU/)).toBeInTheDocument(); + }); + it("does not treat a temporary code as formal when only basic info is approved", () => { saveNonIntegratedProduct( createProductRecord({ @@ -3215,7 +3256,7 @@ describe("NonIntegratedDetailClient", () => { ).not.toBeInTheDocument(); }); - it("keeps imported SKU workbook barcode readonly instead of recalculating it", () => { + it("keeps imported SKU workbook barcode value editable instead of recalculating it", () => { saveNonIntegratedProduct( createProductRecord({ id: "ZWJ0218-imported-sku-lock", @@ -3245,7 +3286,7 @@ describe("NonIntegratedDetailClient", () => { .getAllByDisplayValue("ZWJ02180131978877V01") .find((element) => element.tagName.toLowerCase() === "textarea"); expect(importedBarcode).toBeDefined(); - expect(importedBarcode).toHaveAttribute("readonly"); + expect(importedBarcode).not.toHaveAttribute("readonly"); expect(screen.getByDisplayValue("N396")).toBeInTheDocument(); expect(screen.queryByDisplayValue("ZWJ021801N396V01")).not.toBeInTheDocument(); }); 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 6b7b2cb9..cf78e500 100644 --- a/furniture-3d-system/src/app/intake/non-integrated/NonIntegratedDetailClient.tsx +++ b/furniture-3d-system/src/app/intake/non-integrated/NonIntegratedDetailClient.tsx @@ -4893,14 +4893,23 @@ function normalizeSkuSourceMarker(value: string | undefined) { return (value ?? "").trim().toLowerCase().replace(/-/g, "_"); } +function isSkuWorkbookImportedItem(item: NonIntegratedSkuItem) { + const source = normalizeSkuSourceMarker(item.source); + const sourceTable = normalizeSkuSourceMarker(item.sourceTable); + + return source === SKU_WORKBOOK_SOURCE || sourceTable === SKU_WORKBOOK_SOURCE; +} + function isImportedSkuContentLocked(item: NonIntegratedSkuItem) { const source = normalizeSkuSourceMarker(item.source); const sourceTable = normalizeSkuSourceMarker(item.sourceTable); + if (isSkuWorkbookImportedItem(item)) { + return false; + } + return ( item.contentLocked === true || - source === SKU_WORKBOOK_SOURCE || - sourceTable === SKU_WORKBOOK_SOURCE || source === "jst_sku" || sourceTable === "jst_sku" ); @@ -6361,9 +6370,13 @@ function deriveSkuItem( const versionNo = normalizeSkuVersionNo(item.versionNo); const normalizedItem = { ...item, versionNo }; const importedContentLocked = isImportedSkuContentLocked(item); + const skuWorkbookImported = isSkuWorkbookImportedItem(item); + const shouldPreserveImportedContent = + importedContentLocked || skuWorkbookImported; const seriesComponentAssetSku = isSeriesComponentAssetSkuItem(item); const resolvedSkuCode = - (importedContentLocked || seriesComponentAssetSku) && item.skuCode.trim() + (shouldPreserveImportedContent || seriesComponentAssetSku) && + item.skuCode.trim() ? item.skuCode.trim().toUpperCase() : finalSkuCode; const autoDrawingId = buildAutoDrawingId({ @@ -6375,27 +6388,24 @@ function deriveSkuItem( item.manufacturerCode, versionNo, ); - const importedLockedBarcode = importedContentLocked - ? item.barcode.trim().toUpperCase() - : ""; const manualSpecName = item.specName.trim(); const resolvedSpecName = seriesComponentAssetSku ? manualSpecName : manualSpecName || autoSpecName; - const resolvedBarcode = seriesComponentAssetSku - ? item.barcode.trim().toUpperCase() - : importedLockedBarcode || - (shouldKeepCustomBarcode( - item.barcode, - resolvedSkuCode, - item.manufacturerCode, - versionNo, - ) + const resolvedBarcode = + seriesComponentAssetSku || shouldPreserveImportedContent + ? item.barcode.trim().toUpperCase() + : shouldKeepCustomBarcode( + item.barcode, + resolvedSkuCode, + item.manufacturerCode, + versionNo, + ) ? item.barcode.trim() - : autoBarcode); + : autoBarcode; const resolvedDrawingId = seriesComponentAssetSku ? item.drawingId.trim().toUpperCase() - : importedContentLocked && item.drawingId.trim() + : shouldPreserveImportedContent && item.drawingId.trim() ? item.drawingId.trim().toUpperCase() : shouldKeepCustomDrawingId(item.drawingId, normalizedItem) ? item.drawingId.trim() @@ -6501,7 +6511,7 @@ function buildSkuItemFromImportedRow( tagMaterial: formValues.tagMaterial.trim() || baseItem.tagMaterial, source: SKU_WORKBOOK_SOURCE, sourceTable: SKU_WORKBOOK_SOURCE, - contentLocked: true, + contentLocked: false, }; }