fix(intake): keep imported sku rows editable

This commit is contained in:
WuYongJie 2026-06-05 15:33:16 +08:00
parent d650e2f562
commit 2194824e6c
2 changed files with 71 additions and 20 deletions

View File

@ -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(
<NonIntegratedDetailClient
mode="edit"
productId="DNZ0405-imported-sku-image-match"
/>,
);
expect(screen.getByDisplayValue("DNZ040501")).toBeInTheDocument();
const batchSkuImageInput = container.querySelector<HTMLInputElement>(
'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();
});

View File

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