feat: receive dropship inbound by source pallet
This commit is contained in:
+8
@@ -134,6 +134,14 @@ public class ReceivingContainerController {
|
||||
return ApiResponse.success(service.receiveCarton(identity.operatorKey(), identity.operatorName(), request));
|
||||
}
|
||||
|
||||
@PostMapping("/current/receipts/pallet")
|
||||
public ApiResponse<ReceivingContainerResponses.Receipt> receiveWholePallet(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Valid @RequestBody ReceivingContainerRequests.WholePalletReceive request) {
|
||||
PdaWarehouseIdentity identity = currentIdentity(user);
|
||||
return ApiResponse.success(service.receiveWholePallet(identity.operatorKey(), identity.operatorName(), request));
|
||||
}
|
||||
|
||||
@PostMapping("/current/complete")
|
||||
public ApiResponse<ReceivingContainerResponses.Session> complete(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Valid @RequestBody ReceivingContainerRequests.Action request) {
|
||||
|
||||
+2
@@ -23,4 +23,6 @@ public final class ReceivingContainerRequests {
|
||||
@Positive int packageCount, @NotBlank @Size(max = 255) String idempotencyKey) { }
|
||||
public record CartonReceive(@NotBlank String cartonMark, @NotBlank String palletCode,
|
||||
@NotBlank @Size(max = 255) String idempotencyKey) { }
|
||||
public record WholePalletReceive(@NotBlank String sourcePalletNo,
|
||||
@NotBlank @Size(max = 255) String idempotencyKey) { }
|
||||
}
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ public final class ReceivingContainerResponses {
|
||||
String fbaWarehouseCode, int plannedPalletCount, int totalPackages,
|
||||
int receivedPackages, int pendingPackages,
|
||||
boolean assigned, boolean mergeAllowed, boolean urgent,
|
||||
String mergeHint) { }
|
||||
String mergeHint, String orderType, boolean wholePalletInbound) { }
|
||||
|
||||
public record CartonResolved(String cartonMark, String inboundCode,
|
||||
String destinationType, String overseasWarehouseId,
|
||||
|
||||
+45
-1
@@ -361,6 +361,46 @@ public class ReceivingContainerService {
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public ReceivingContainerResponses.Receipt receiveWholePallet(String operatorKey, String operatorName,
|
||||
ReceivingContainerRequests.WholePalletReceive request) {
|
||||
ReceivingContainerOperation replay = replay(operatorKey, "PALLET_RECEIVE", request.idempotencyKey(), request);
|
||||
if (replay != null) return read(replay, ReceivingContainerResponses.Receipt.class);
|
||||
ReceivingContainerSession session = requireSigned(operatorKey);
|
||||
String customerId = session.getCustomerId();
|
||||
List<DropshipPalletRef> matches = new ArrayList<>();
|
||||
for (InboundRef ref : refs(customerId, session.getContainerNo())) {
|
||||
if (!"ONE_CLICK_DROPSHIP".equals(ref.order().getOrderType())) continue;
|
||||
List<InboundPlanPallet> sourcePallets = pallets.selectList(new LambdaQueryWrapper<InboundPlanPallet>()
|
||||
.eq(InboundPlanPallet::getCustomerId, customerId)
|
||||
.eq(InboundPlanPallet::getPlanId, ref.plan().getId())
|
||||
.eq(InboundPlanPallet::getSourcePalletNo, request.sourcePalletNo()));
|
||||
for (InboundPlanPallet pallet : sourcePallets) {
|
||||
List<InboundPlanPalletAllocation> palletAllocations = allocations.selectList(
|
||||
new LambdaQueryWrapper<InboundPlanPalletAllocation>()
|
||||
.eq(InboundPlanPalletAllocation::getCustomerId, customerId)
|
||||
.eq(InboundPlanPalletAllocation::getPlanId, ref.plan().getId())
|
||||
.eq(InboundPlanPalletAllocation::getLineId, ref.line().getId())
|
||||
.eq(InboundPlanPalletAllocation::getPalletId, pallet.getId()));
|
||||
palletAllocations.forEach(allocation -> matches.add(new DropshipPalletRef(ref, pallet, allocation)));
|
||||
}
|
||||
}
|
||||
if (matches.isEmpty()) throw notFound("Source pallet is not part of the current container");
|
||||
if (matches.size() != 1) throw conflict("Source pallet is duplicated inside the current container");
|
||||
DropshipPalletRef match = matches.get(0);
|
||||
int accepted = value(match.allocation().getPlannedPackageCount());
|
||||
workflow.pickWholePallet(customerId, match.ref().plan().getPlanNo(), match.allocation().getId(),
|
||||
new PdaRequests.WholePalletOperation(request.idempotencyKey() + ":PICK", operatorKey, operatorName));
|
||||
markReceiving(session);
|
||||
ReceivingContainerResponses.Inbound inbound = inbound(match.ref());
|
||||
ReceivingContainerResponses.Receipt result = new ReceivingContainerResponses.Receipt("RECEIVED",
|
||||
session.getContainerNo(), inbound.inboundCode(), inbound.destinationType(), match.pallet().getPalletNo(),
|
||||
accepted, inbound.receivedPackages(), inbound.pendingPackages(), session.getStatus(),
|
||||
inbound.assigned(), inbound.mergeAllowed(), inbound.urgent(), inbound.mergeHint());
|
||||
save(session, "PALLET_RECEIVE", request.idempotencyKey(), request, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Transactional(isolation = Isolation.READ_COMMITTED)
|
||||
public ReceivingContainerResponses.Session complete(String operatorKey,
|
||||
ReceivingContainerRequests.Action request) {
|
||||
@@ -705,6 +745,9 @@ public class ReceivingContainerService {
|
||||
private record PalletSelection(InboundPlanPallet pallet,
|
||||
WarehouseResourceGateway.WarehousePalletReference resource) { }
|
||||
|
||||
private record DropshipPalletRef(InboundRef ref, InboundPlanPallet pallet,
|
||||
InboundPlanPalletAllocation allocation) { }
|
||||
|
||||
private ReceivingContainerResponses.Session snapshot(ReceivingContainerSession session, List<InboundPlan> containerPlans) {
|
||||
List<ReceivingContainerResponses.Inbound> inbounds = refs(session.getCustomerId(), session.getContainerNo()).stream()
|
||||
.map(this::inbound).toList();
|
||||
@@ -729,7 +772,8 @@ public class ReceivingContainerService {
|
||||
ref.line().getDestinationWarehouseId(), ref.line().getDestinationWarehouseCode(),
|
||||
ref.line().getDestinationWarehouseName(), ref.line().getFbaWarehouseCode(),
|
||||
value(ref.line().getPlannedPalletCount()), total, received, Math.max(0, total - received),
|
||||
assigned(ref.plan()), mergeAllowed(ref.plan()), urgent(ref.plan()), mergeHint(ref.plan()));
|
||||
assigned(ref.plan()), mergeAllowed(ref.plan()), urgent(ref.plan()), mergeHint(ref.plan()),
|
||||
ref.order().getOrderType(), "ONE_CLICK_DROPSHIP".equals(ref.order().getOrderType()));
|
||||
}
|
||||
|
||||
private boolean assigned(InboundPlan plan) {
|
||||
|
||||
Reference in New Issue
Block a user