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,
};
}