fix(intake): prevent single sku master data gaps
This commit is contained in:
parent
1892a5d579
commit
f3c2b9bbee
@ -927,6 +927,72 @@ describe('intakeNonIntegratedProductService', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('分配正式 SPU 时用产品名和 SPU 补齐单 SKU 主数据', async () => {
|
||||
const payload = createPayload({
|
||||
id: 'draft-single-sku-master-data-autofill',
|
||||
spu: '',
|
||||
productCategory: '角几/边几',
|
||||
productDevelopmentKind: 'product',
|
||||
openingReference: {
|
||||
productName: '禾沐边几(A款)',
|
||||
productCategory: '角几/边几',
|
||||
},
|
||||
skuItems: [
|
||||
createSkuItem({
|
||||
skuSequence: 1,
|
||||
specName: '',
|
||||
model: '',
|
||||
skuCode: '',
|
||||
barcode: '',
|
||||
}),
|
||||
],
|
||||
})
|
||||
mockedSpuNumberReservationService.reserveInTransaction.mockResolvedValue({
|
||||
productCategory: '角几/边几',
|
||||
prefix: 'BJ',
|
||||
index: 214,
|
||||
spu: 'BJ0214',
|
||||
})
|
||||
mockedRepository.findDeletedBySpuInTransaction.mockResolvedValue(null as never)
|
||||
mockedRepository.findBySpuInTransaction.mockResolvedValue(null as never)
|
||||
mockedRepository.createInTransaction.mockResolvedValue(
|
||||
createRecord({ id: 'BJ0214-1770000000000' }) as never,
|
||||
)
|
||||
mockedRepository.findActiveById.mockResolvedValue(
|
||||
createRecord({
|
||||
id: 'BJ0214-1770000000000',
|
||||
spu: 'BJ0214',
|
||||
spuBase: 'BJ0214',
|
||||
payload: createPayload({ id: 'BJ0214-1770000000000', spu: 'BJ0214' }),
|
||||
}) as never,
|
||||
)
|
||||
|
||||
await intakeNonIntegratedProductService.save(payload, baseUser, {
|
||||
formalSpuAssignmentProductCategory: '角几/边几',
|
||||
})
|
||||
|
||||
const createArg = mockedRepository.createInTransaction.mock.calls[0]?.[1] as {
|
||||
payload?: { skuItems?: Array<Record<string, unknown>> }
|
||||
skuItems?: { createMany?: { data?: Array<Record<string, unknown>> } }
|
||||
}
|
||||
expect(createArg.payload?.skuItems?.[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
specName: '禾沐边几(A款)',
|
||||
model: 'BJ0214',
|
||||
skuCode: 'BJ021401',
|
||||
barcode: 'BJ021401N01V01',
|
||||
}),
|
||||
)
|
||||
expect(createArg.skuItems?.createMany?.data?.[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
specName: '禾沐边几(A款)',
|
||||
model: 'BJ0214',
|
||||
dataQualityStatus: 'READY',
|
||||
missingRequiredFields: [],
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('分配正式 SPU 时阻断未补齐的 SKU 主数据,避免生成新的地基阻塞', async () => {
|
||||
const payload = createPayload({
|
||||
id: 'draft-incomplete-before-formal-spu',
|
||||
|
||||
@ -345,7 +345,13 @@ function shouldPreserveFormalSkuCode(skuCode: string, formalSpu: string) {
|
||||
return Boolean(normalizedSkuCode && normalizedFormalSpu && normalizedSkuCode.startsWith(normalizedFormalSpu))
|
||||
}
|
||||
|
||||
function assignFormalSpuToSkuItems(value: unknown, formalSpu: string) {
|
||||
function assignFormalSpuToSkuItems(
|
||||
value: unknown,
|
||||
formalSpu: string,
|
||||
options: {
|
||||
fallbackSingleSkuSpecName?: string
|
||||
} = {},
|
||||
) {
|
||||
if (!Array.isArray(value)) return value
|
||||
|
||||
return value.map((item, index) => {
|
||||
@ -360,9 +366,19 @@ function assignFormalSpuToSkuItems(value: unknown, formalSpu: string) {
|
||||
const barcode = existingBarcode && existingBarcode.startsWith(skuCode)
|
||||
? existingBarcode
|
||||
: buildAutoBarcode(skuCode, item.manufacturerCode, versionNo)
|
||||
const shouldAutofillSingleSkuMasterData =
|
||||
value.length === 1 && Boolean(readText(options.fallbackSingleSkuSpecName))
|
||||
|
||||
return {
|
||||
...item,
|
||||
specName:
|
||||
readText(item.specName) ||
|
||||
(shouldAutofillSingleSkuMasterData
|
||||
? readText(options.fallbackSingleSkuSpecName)
|
||||
: item.specName),
|
||||
model:
|
||||
readText(item.model) ||
|
||||
(shouldAutofillSingleSkuMasterData ? formalSpu.trim().toUpperCase() : item.model),
|
||||
skuCode,
|
||||
barcode,
|
||||
versionNo,
|
||||
@ -4094,7 +4110,9 @@ class IntakeNonIntegratedProductService {
|
||||
: assignedSpu,
|
||||
brand: normalizedBrand,
|
||||
formalSpuAssigned: true,
|
||||
skuItems: assignFormalSpuToSkuItems(productInput.skuItems, assignedSpu),
|
||||
skuItems: assignFormalSpuToSkuItems(productInput.skuItems, assignedSpu, {
|
||||
fallbackSingleSkuSpecName: readText(openingReference.productName),
|
||||
}),
|
||||
openingReference: {
|
||||
...openingReference,
|
||||
brand: readText(openingReference.brand) || normalizedBrand,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user