fix: resolve FBA PDA carton by inbound prefix

This commit is contained in:
2026-08-26 18:03:17 +08:00
parent cbcbb9c764
commit 29c27d2fd7
2 changed files with 25 additions and 17 deletions
@@ -226,7 +226,19 @@ public class ReceivingContainerService {
ReceivingContainerRequests.CartonResolve request) {
ReceivingContainerSession session = requireSigned(operatorKey);
String customerId = session.getCustomerId();
CartonRef carton = requireCartonRef(customerId, session.getContainerNo(), request.cartonMark());
String inboundCode = cartonInboundCode(request.cartonMark());
List<InboundRef> matches = refs(customerId, session.getContainerNo()).stream()
.filter(value -> inboundCode.equals(value.line().getInboundCode())).toList();
CartonRef carton;
if (matches.size() > 1) {
throw conflict("Carton mark inbound code is ambiguous in the current container");
} else if (matches.size() == 1 && "FBA".equals(destinationType(matches.get(0).line(), matches.get(0).order()))) {
carton = new CartonRef(matches.get(0));
} else if (matches.size() == 1) {
carton = requireCartonRef(customerId, session.getContainerNo(), request.cartonMark());
} else {
carton = requireUnmatchedFbaCartonPrefix(customerId, inboundCode);
}
InboundRef ref = carton.ref();
ReceivingContainerResponses.Inbound inbound = inbound(ref);
return new ReceivingContainerResponses.CartonResolved(request.cartonMark().trim(),
@@ -423,7 +435,7 @@ public class ReceivingContainerService {
private CartonRef requireCartonRef(String customerId, String containerNo, String cartonMark) {
InboundPlanCarton carton = cartons.selectOne(new LambdaQueryWrapper<InboundPlanCarton>()
.eq(InboundPlanCarton::getCustomerId, customerId).eq(InboundPlanCarton::getCartonMark, cartonMark));
if (carton == null) return resolveFbaCartonCodeWithoutManifest(customerId, containerNo, cartonMark);
if (carton == null) throw notFound("Carton mark was not found");
List<InboundRef> matches = refs(customerId, containerNo).stream()
.filter(value -> carton.getLineId() == null || Objects.equals(value.line().getId(), carton.getLineId()))
.filter(value -> carton.getPlanId() == null || Objects.equals(value.plan().getId(), carton.getPlanId()))
@@ -432,24 +444,20 @@ public class ReceivingContainerService {
return new CartonRef(matches.get(0));
}
private CartonRef resolveFbaCartonCodeWithoutManifest(String customerId, String containerNo, String cartonMark) {
private String cartonInboundCode(String cartonMark) {
int delimiter = cartonMark == null ? -1 : cartonMark.indexOf('#');
if (delimiter < 1) throw conflict("Carton mark must contain a non-empty inbound code prefix");
String inboundCode = cartonMark.substring(0, delimiter).trim();
if (inboundCode.isEmpty()) throw conflict("Carton mark must contain a non-empty inbound code prefix");
List<InboundRef> matches = refs(customerId, containerNo).stream()
.filter(value -> inboundCode.equals(value.line().getInboundCode())).toList();
if (matches.isEmpty()) {
boolean exists = lines.selectList(new LambdaQueryWrapper<InboundPlanLine>()
.eq(InboundPlanLine::getCustomerId, customerId)
.eq(InboundPlanLine::getInboundCode, inboundCode)).stream().findAny().isPresent();
if (exists) throw conflict("Carton mark belongs to another container");
throw notFound("Carton mark was not found");
}
if (matches.size() != 1) throw conflict("Carton mark inbound code is ambiguous in the current container");
InboundRef ref = matches.get(0);
if (!"FBA".equals(destinationType(ref.line(), ref.order()))) throw notFound("Carton mark was not found");
return new CartonRef(ref);
return inboundCode;
}
private CartonRef requireUnmatchedFbaCartonPrefix(String customerId, String inboundCode) {
boolean exists = lines.selectList(new LambdaQueryWrapper<InboundPlanLine>()
.eq(InboundPlanLine::getCustomerId, customerId)
.eq(InboundPlanLine::getInboundCode, inboundCode)).stream().findAny().isPresent();
if (exists) throw conflict("Carton mark belongs to another container");
throw notFound("Carton mark was not found");
}
private List<InboundRef> requireFbaPlanRefs(String customerId, String containerNo, InboundRef selected) {
@@ -447,7 +447,7 @@ class ReceivingContainerServiceBehaviorTest {
org.mockito.Mockito.reset(lines, cartons);
when(lines.selectList(any())).thenReturn(List.of(current), List.of());
assertThatThrownBy(() -> service.resolveCarton("7",
new ReceivingContainerRequests.CartonResolve("UNKNOWN#5-1")))
new ReceivingContainerRequests.CartonResolve("NYEXX26082600001#4-1")))
.isInstanceOfSatisfying(ResponseStatusException.class,
error -> assertThat(error.getStatusCode().value()).isEqualTo(404));