fix: 多件档口入库码逐件回写 (#250)
This commit is contained in:
@@ -13,14 +13,17 @@ import (
|
||||
)
|
||||
|
||||
type fakeInnerCodeWriter struct {
|
||||
stock syb.StockDetail
|
||||
readErr error
|
||||
deleteErr error
|
||||
updateErr error
|
||||
readCount int
|
||||
deleteCount int
|
||||
updateCount int
|
||||
updatedCode string
|
||||
stock syb.StockDetail
|
||||
readErr error
|
||||
deleteErr error
|
||||
createErr error
|
||||
updateErr error
|
||||
readCount int
|
||||
deleteCount int
|
||||
createCount int
|
||||
updateCount int
|
||||
updatedCode string
|
||||
nextDetailID int64
|
||||
}
|
||||
|
||||
func TestQueueInnerCodeApplyBatch_超过20条可一次排队(t *testing.T) {
|
||||
@@ -81,6 +84,20 @@ func (f *fakeInnerCodeWriter) DeleteInnerCode(_ context.Context, detailID int64)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeInnerCodeWriter) CreateInnerCodeDetail(_ context.Context, stockID int64, title string) (int64, error) {
|
||||
f.createCount++
|
||||
if f.createErr != nil {
|
||||
return 0, f.createErr
|
||||
}
|
||||
if f.nextDetailID == 0 {
|
||||
f.nextDetailID = 100
|
||||
}
|
||||
f.nextDetailID++
|
||||
f.stock.Details = append(f.stock.Details, syb.DetailItem{ID: f.nextDetailID, ProductTitle: title,
|
||||
ProductQty: 1, ProductPrice: 0, Raw: map[string]any{"innerExpCode": ""}})
|
||||
return f.nextDetailID, nil
|
||||
}
|
||||
|
||||
func (f *fakeInnerCodeWriter) UpdateDetailCode(_ context.Context, _, detailID int64, code string) error {
|
||||
f.updateCount++
|
||||
f.updatedCode = code
|
||||
@@ -95,21 +112,93 @@ func (f *fakeInnerCodeWriter) UpdateDetailCode(_ context.Context, _, detailID in
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestApplyClaimedInnerCode_聚合码只写一次并按完整值复读(t *testing.T) {
|
||||
func TestApplyClaimedInnerCode_两个单件码写入两个明细(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("")
|
||||
record.InnerCode = "DK260815A160101,DK260815A160102"
|
||||
record.SourceDuplicateCount = 2
|
||||
writer := innerCodeApplyTestWriter(record, "")
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record)
|
||||
if outcome.Status != model.InnerCodeUpdated || writer.updateCount != 1 || writer.updatedCode != record.InnerCode ||
|
||||
outcome.RemoteCode != record.InnerCode || writer.readCount != 2 {
|
||||
t.Fatalf("outcome=%+v update=%d code=%q read=%d", outcome, writer.updateCount, writer.updatedCode, writer.readCount)
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeUpdated || writer.updateCount != 2 || writer.createCount != 1 ||
|
||||
outcome.RemoteCode != record.InnerCode || writer.readCount != 3 {
|
||||
t.Fatalf("outcome=%+v update=%d create=%d read=%d", outcome, writer.updateCount, writer.createCount, writer.readCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyClaimedInnerCode_三个单件码创建两条零价明细(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("")
|
||||
record.InnerCode = "DK-001,DK-002,DK-003"
|
||||
record.SourceDuplicateCount = 3
|
||||
writer := innerCodeApplyTestWriter(record, "")
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeUpdated || writer.updateCount != 3 || writer.createCount != 2 {
|
||||
t.Fatalf("outcome=%+v update=%d create=%d", outcome, writer.updateCount, writer.createCount)
|
||||
}
|
||||
for _, detail := range writer.stock.Details[1:] {
|
||||
if detail.ProductQty != 1 || detail.ProductPrice != 0 {
|
||||
t.Fatalf("占位明细必须数量 1、价格 0: %+v", detail)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyClaimedInnerCode_复用人工明细已有目标码(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("")
|
||||
record.InnerCode = "DK-001,DK-002"
|
||||
record.SourceDuplicateCount = 2
|
||||
writer := innerCodeApplyTestWriter(record, "")
|
||||
writer.stock.Details = append(writer.stock.Details, syb.DetailItem{ID: 21, ProductTitle: "人工明细", ProductQty: 1,
|
||||
Raw: map[string]any{"innerExpCode": "DK-002"}})
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeUpdated || writer.updateCount != 1 || writer.createCount != 0 || writer.deleteCount != 0 {
|
||||
t.Fatalf("outcome=%+v update=%d create=%d delete=%d", outcome, writer.updateCount, writer.createCount, writer.deleteCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyClaimedInnerCode_数量不一致零写入(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("")
|
||||
record.InnerCode = "DK-001,DK-002"
|
||||
record.SourceDuplicateCount = 2
|
||||
writer := innerCodeApplyTestWriter(record, "")
|
||||
writer.stock.Details[0].ProductQty = 1
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeFailed || writer.updateCount != 0 || writer.createCount != 0 || writer.deleteCount != 0 {
|
||||
t.Fatalf("outcome=%+v update=%d create=%d delete=%d", outcome, writer.updateCount, writer.createCount, writer.deleteCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyClaimedInnerCode_创建结果未知立即停止(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("")
|
||||
record.InnerCode = "DK-001,DK-002"
|
||||
record.SourceDuplicateCount = 2
|
||||
writer := innerCodeApplyTestWriter(record, "")
|
||||
writer.createErr = fmtUnknownInnerCodeWriteError()
|
||||
checkpoints := 0
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, func([]innerCodeRemoteItem, string) error {
|
||||
checkpoints++
|
||||
return nil
|
||||
})
|
||||
if outcome.Status != model.InnerCodeNeedsCheck || writer.createCount != 1 || writer.updateCount != 1 || checkpoints < 3 {
|
||||
t.Fatalf("outcome=%+v create=%d update=%d checkpoints=%d", outcome, writer.createCount, writer.updateCount, checkpoints)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyClaimedInnerCode_崩溃遗留占位明细会复用而不重复创建(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("")
|
||||
record.InnerCode = "DK-001,DK-002"
|
||||
record.SourceDuplicateCount = 2
|
||||
writer := innerCodeApplyTestWriter(record, "")
|
||||
writer.stock.Details = append(writer.stock.Details, syb.DetailItem{ID: 99,
|
||||
ProductTitle: innerCodePlaceholderTitle(record.ID, 2), ProductQty: 1, ProductPrice: 0,
|
||||
Raw: map[string]any{"innerExpCode": ""}})
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeUpdated || writer.createCount != 0 || writer.updateCount != 2 {
|
||||
t.Fatalf("outcome=%+v create=%d update=%d", outcome, writer.createCount, writer.updateCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyClaimedInnerCode_空旧值直接写并复读确认(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("")
|
||||
writer := innerCodeApplyTestWriter(record, "")
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record)
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeUpdated || writer.deleteCount != 0 || writer.updateCount != 1 || writer.readCount != 2 {
|
||||
t.Fatalf("outcome=%+v counts read=%d delete=%d update=%d", outcome, writer.readCount, writer.deleteCount, writer.updateCount)
|
||||
}
|
||||
@@ -118,7 +207,7 @@ func TestApplyClaimedInnerCode_空旧值直接写并复读确认(t *testing.T) {
|
||||
func TestApplyClaimedInnerCode_有旧值先删后写(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("OLD")
|
||||
writer := innerCodeApplyTestWriter(record, "OLD")
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record)
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeUpdated || writer.deleteCount != 1 || writer.updateCount != 1 {
|
||||
t.Fatalf("outcome=%+v delete=%d update=%d", outcome, writer.deleteCount, writer.updateCount)
|
||||
}
|
||||
@@ -127,7 +216,7 @@ func TestApplyClaimedInnerCode_有旧值先删后写(t *testing.T) {
|
||||
func TestApplyClaimedInnerCode_规划后远端值变化不写入(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("OLD")
|
||||
writer := innerCodeApplyTestWriter(record, "OTHER")
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record)
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeNeedsCheck || writer.deleteCount != 0 || writer.updateCount != 0 {
|
||||
t.Fatalf("outcome=%+v delete=%d update=%d", outcome, writer.deleteCount, writer.updateCount)
|
||||
}
|
||||
@@ -137,7 +226,7 @@ func TestApplyClaimedInnerCode_删除明确失败不继续写(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("OLD")
|
||||
writer := innerCodeApplyTestWriter(record, "OLD")
|
||||
writer.deleteErr = errors.New("已打单数据不能清除")
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record)
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeFailed || writer.deleteCount != 1 || writer.updateCount != 0 {
|
||||
t.Fatalf("outcome=%+v delete=%d update=%d", outcome, writer.deleteCount, writer.updateCount)
|
||||
}
|
||||
@@ -147,7 +236,7 @@ func TestApplyClaimedInnerCode_写入未知结果不复读也不重试(t *testin
|
||||
record := innerCodeApplyTestRecord("")
|
||||
writer := innerCodeApplyTestWriter(record, "")
|
||||
writer.updateErr = fmtUnknownInnerCodeWriteError()
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record)
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeNeedsCheck || writer.updateCount != 1 || writer.readCount != 1 {
|
||||
t.Fatalf("outcome=%+v update=%d read=%d", outcome, writer.updateCount, writer.readCount)
|
||||
}
|
||||
@@ -157,7 +246,7 @@ func TestApplyClaimedInnerCode_采购字段出现后停止(t *testing.T) {
|
||||
record := innerCodeApplyTestRecord("")
|
||||
writer := innerCodeApplyTestWriter(record, "")
|
||||
writer.stock.Details[0].Raw["purchaseCode"] = "CG-1"
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record)
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeSkipped || writer.updateCount != 0 {
|
||||
t.Fatalf("outcome=%+v update=%d", outcome, writer.updateCount)
|
||||
}
|
||||
@@ -168,7 +257,7 @@ func TestApplyClaimedInnerCode_档口身份变化后停止(t *testing.T) {
|
||||
record.SybSKU = "A#1"
|
||||
writer := innerCodeApplyTestWriter(record, "")
|
||||
writer.stock.Details[0].Raw["sku"] = "B#2"
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record)
|
||||
outcome := applyClaimedInnerCode(context.Background(), writer, record, nil)
|
||||
if outcome.Status != model.InnerCodeSkipped || writer.updateCount != 0 {
|
||||
t.Fatalf("outcome=%+v update=%d", outcome, writer.updateCount)
|
||||
}
|
||||
@@ -176,11 +265,11 @@ func TestApplyClaimedInnerCode_档口身份变化后停止(t *testing.T) {
|
||||
|
||||
func innerCodeApplyTestRecord(oldCode string) model.InnerCodeRecord {
|
||||
return model.InnerCodeRecord{ID: 1, StockID: 10, DetailID: 20, SybSpec: "黑色,M",
|
||||
InnerCode: "DK-001", RemoteInnerCode: oldCode, Status: model.InnerCodeApplying}
|
||||
InnerCode: "DK-001", SourceDuplicateCount: 1, RemoteInnerCode: oldCode, Status: model.InnerCodeApplying}
|
||||
}
|
||||
|
||||
func innerCodeApplyTestWriter(record model.InnerCodeRecord, currentCode string) *fakeInnerCodeWriter {
|
||||
item := syb.DetailItem{ID: record.DetailID, ProductSpec: record.SybSpec, Raw: map[string]any{
|
||||
item := syb.DetailItem{ID: record.DetailID, ProductSpec: record.SybSpec, ProductQty: record.SourceDuplicateCount, Raw: map[string]any{
|
||||
"id": record.DetailID, "productSpec": record.SybSpec, "innerExpCode": currentCode,
|
||||
"purchasePlatform": "", "purchaseCode": "",
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user