fix: unify receiving discrepancy confirmation

This commit is contained in:
2026-11-06 20:13:41 +08:00
parent 87bb905283
commit f4901d155c
3 changed files with 55 additions and 4 deletions
@@ -26,8 +26,8 @@ public final class InboundReceivingReconciliation {
public record Confirm(@NotBlank String customerId, @NotBlank String snapshotHash, public record Confirm(@NotBlank String customerId, @NotBlank String snapshotHash,
@NotBlank @Size(max = 200) String reason, @NotBlank @Size(max = 200) String reason,
@NotNull @Size(max = 1000) List<@NotNull @Valid Count> pallets, @NotNull List<@NotNull @Valid Count> pallets,
@NotNull @Size(max = 10000) List<@NotNull @Valid Quantity> receipts) { } @NotNull List<@NotNull @Valid Quantity> receipts) { }
public record Count(@NotNull Long palletId, public record Count(@NotNull Long palletId,
@NotNull @Min(0) Integer countedPackageCount) { } @NotNull @Min(0) Integer countedPackageCount) { }
@@ -105,8 +105,8 @@ components:
customerId: { type: string } customerId: { type: string }
snapshotHash: { type: string } snapshotHash: { type: string }
reason: { type: string, minLength: 1, maxLength: 200 } reason: { type: string, minLength: 1, maxLength: 200 }
pallets: { type: array, maxItems: 1000, items: { $ref: '#/components/schemas/Count' } } pallets: { type: array, items: { $ref: '#/components/schemas/Count' } }
receipts: { type: array, maxItems: 10000, items: { $ref: '#/components/schemas/Quantity' } } receipts: { type: array, items: { $ref: '#/components/schemas/Quantity' } }
Count: Count:
type: object type: object
required: [palletId, countedPackageCount] required: [palletId, countedPackageCount]
@@ -0,0 +1,51 @@
package com.baiyue.lastleg.inboundplan.pda.service;
import com.baiyue.lastleg.inboundplan.dto.InboundReceivingReconciliation.*;
import jakarta.validation.Validation;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import static org.assertj.core.api.Assertions.assertThat;
/** 请求层接受当前完整核对范围,数量守恒与只读事实继续由服务校验。 */
class InboundReceivingReconciliationRequestTest {
/** 多票多商品的完整矩阵不能被任意一万行上限阻塞。 */
@Test void acceptsCompleteLargeReconciliationSnapshot() {
List<Quantity> rows = IntStream.range(0, 10400).mapToObj(index ->
new Quantity("100", "IP-1", 3L, 10L + index / 400, "SKU-" + index % 400, 0)).toList();
List<Count> pallets = IntStream.range(0, 26).mapToObj(index -> new Count(10L + index, 0)).toList();
try (var factory = Validation.buildDefaultValidatorFactory()) {
assertThat(factory.getValidator().validate(new Confirm("100", "snapshot", "逐托复核", pallets, rows))).isEmpty();
}
}
/** 空行必须在进入业务事务前拒绝,不能触发空引用错误。 */
@Test void rejectsNullListElements() {
try (var factory = Validation.buildDefaultValidatorFactory()) {
var validator = factory.getValidator();
assertThat(validator.validate(new Confirm("100", "snapshot", "现场复核", Arrays.asList((Count) null), List.of())))
.isNotEmpty();
assertThat(validator.validate(new Confirm("100", "snapshot", "现场复核", List.of(), Arrays.asList((Quantity) null))))
.isNotEmpty();
}
}
/** 已完成只读整托可以超过普通FBA单托上限,服务仍禁止改写这些数量。 */
@Test void acceptsReadonlySourceQuantityAboveBulkLimit() {
try (var factory = Validation.buildDefaultValidatorFactory()) {
assertThat(factory.getValidator().validate(new Confirm("100", "snapshot", "现场复核",
List.of(new Count(10L, 80)), List.of(new Quantity("100", "IP-1", 3L, 10L, "SKU-1", 80)))))
.isEmpty();
}
}
/** 原因必填,负数清点或SKU数量均在请求层拒绝。 */
@Test void rejectsNegativeCountsAndMissingReason() {
try (var factory = Validation.buildDefaultValidatorFactory()) {
assertThat(factory.getValidator().validate(new Confirm("100", "snapshot", " ",
List.of(new Count(10L, -1)), List.of(new Quantity("100", "IP-1", 3L, 10L, "SKU-1", -1)))))
.hasSize(3);
}
}
}