贴标申请,仓储转运
This commit is contained in:
+1
@@ -30,6 +30,7 @@ public final class WarehouseTransferResponses {
|
||||
String lastlegOrderNo, String operatingWarehouseId, String fbaWarehouseCode,
|
||||
String destinationType, String destinationWarehouseCode, String destinationWarehouseName,
|
||||
int packageCount, String deliveryMethod, boolean needRelabel, String relabelNo,
|
||||
String relabelApplicationStatus, String relabelFulfillmentStatus,
|
||||
String status, LocalDateTime estimatedArrivalAt, LocalDateTime createdAt) {}
|
||||
public record Detail(Long id, String transferNo, Long inboundOrderId, String inboundCode,
|
||||
Long lastlegOrderId, String lastlegOrderNo, String orderType, String orderStatus,
|
||||
|
||||
+5
-1
@@ -23,7 +23,11 @@ import org.apache.ibatis.annotations.Update;
|
||||
@Update("UPDATE ll_warehouse_transfer_order SET status='OUTBOUNDED',outbound_at=#{outboundAt},updated_at=#{outboundAt} WHERE customer_id=#{customerId} AND lastleg_order_id=#{orderId} AND outbound_at IS NULL")
|
||||
int markOutboundByOrder(@Param("customerId") String customerId, @Param("orderId") Long orderId,
|
||||
@Param("outboundAt") java.time.LocalDateTime outboundAt);
|
||||
@Update("UPDATE ll_warehouse_transfer_order SET status='OUTBOUNDED',outbound_at=#{outboundAt},updated_at=#{outboundAt} WHERE customer_id=#{customerId} AND relabel_no=#{relabelNo} AND outbound_at IS NULL")
|
||||
@Update("UPDATE ll_warehouse_transfer_order wto SET wto.status='OUTBOUNDED',wto.outbound_at=#{outboundAt},wto.updated_at=#{outboundAt} " +
|
||||
"WHERE wto.customer_id=#{customerId} AND wto.relabel_no=#{relabelNo} AND wto.outbound_at IS NULL " +
|
||||
"AND NOT EXISTS (SELECT 1 FROM ll_warehouse_transfer_pallet wtp " +
|
||||
"JOIN ll_inventory_position ip ON ip.customer_id=wtp.customer_id AND ip.pallet_id=wtp.warehouse_pallet_id " +
|
||||
"WHERE wtp.customer_id=wto.customer_id AND wtp.transfer_order_id=wto.id AND ip.available_packages>0)")
|
||||
int markOutboundByRelabel(@Param("customerId") String customerId, @Param("relabelNo") String relabelNo,
|
||||
@Param("outboundAt") java.time.LocalDateTime outboundAt);
|
||||
}
|
||||
|
||||
+33
-19
@@ -147,8 +147,10 @@ public class WarehouseTransferService {
|
||||
validateDestination(request.destinationType(), request.destinationWarehouseCode(), request.fbaWarehouseCode(),
|
||||
request.privateDestinationAddress(), request.privateDestinationPostalCode(),
|
||||
request.privateDestinationContactName(), request.privateDestinationContactPhone());
|
||||
validateTransferDestinationRelabel(request.destinationType(), request.fbaWarehouseCode(), request.destinationWarehouseCode(),
|
||||
request.needRelabel());
|
||||
// A split relabel transfer may intentionally defer the whole-order
|
||||
// destination: relabeled cartons go through relabel dispatch while the
|
||||
// remaining cartons are bound later from warehouse-transfer outbound.
|
||||
// All other transfer types must still select FBA or PRIVATE up front.
|
||||
String key = request.idempotencyKey().trim();
|
||||
String requestHash = hash(request);
|
||||
WarehouseTransferOrder replay = transfers.findKey(customerId, key);
|
||||
@@ -279,8 +281,6 @@ public class WarehouseTransferService {
|
||||
validateDestination(request.destinationType(), request.destinationWarehouseCode(), request.fbaWarehouseCode(),
|
||||
request.privateDestinationAddress(), request.privateDestinationPostalCode(),
|
||||
request.privateDestinationContactName(), request.privateDestinationContactPhone());
|
||||
validateTransferDestinationRelabel(request.destinationType(), request.fbaWarehouseCode(), request.destinationWarehouseCode(),
|
||||
request.needRelabel());
|
||||
|
||||
LastlegOrder order = requireTailOrder(customerId, transfer);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
@@ -422,12 +422,16 @@ public class WarehouseTransferService {
|
||||
.le(query.createdTo() != null, WarehouseTransferOrder::getCreatedAt, query.createdTo())
|
||||
.orderByDesc(WarehouseTransferOrder::getCreatedAt).orderByDesc(WarehouseTransferOrder::getId);
|
||||
Page<WarehouseTransferOrder> result = transfers.selectPage(Page.of(query.page(), query.size()), wrapper);
|
||||
Map<String, RelabelApplication> relabelApplicationsByNo = relabelApplications(result.getRecords());
|
||||
List<WarehouseTransferResponses.Summary> records = result.getRecords().stream().map(value ->
|
||||
new WarehouseTransferResponses.Summary(value.getId(), value.getTransferNo(), value.getInboundCode(),
|
||||
value.getLastlegOrderId(), value.getLastlegOrderNo(), value.getOperatingWarehouseId(),
|
||||
value.getFbaWarehouseCode(), value.getDestinationType(), value.getDestinationWarehouseCode(),
|
||||
value.getDestinationWarehouseName(), value.getPackageCount(), value.getDeliveryMethod(),
|
||||
Boolean.TRUE.equals(value.getNeedRelabel()), value.getRelabelNo(), value.getStatus(),
|
||||
Boolean.TRUE.equals(value.getNeedRelabel()), value.getRelabelNo(),
|
||||
relabelApplicationsByNo.get(value.getRelabelNo()) == null ? null : relabelApplicationsByNo.get(value.getRelabelNo()).getStatus(),
|
||||
relabelApplicationsByNo.get(value.getRelabelNo()) == null ? null : relabelApplicationsByNo.get(value.getRelabelNo()).getFulfillmentStatus(),
|
||||
value.getStatus(),
|
||||
value.getEstimatedArrivalAt(), value.getCreatedAt())).toList();
|
||||
return new PageResult<>(records, result.getCurrent(), result.getSize(), result.getTotal(), result.getPages());
|
||||
}
|
||||
@@ -911,7 +915,7 @@ public class WarehouseTransferService {
|
||||
transfers.updateById(transfer);
|
||||
LastlegOrder order = requireTailOrder(customerId, transfer); String before = order.getCurrentStatus();
|
||||
order.setCurrentStatus(INBOUND_COMPLETED);
|
||||
order.setRelabelStatus(Boolean.TRUE.equals(transfer.getNeedRelabel()) ? "PENDING_PROCESSING" : "NOT_REQUIRED");
|
||||
order.setRelabelStatus(Boolean.TRUE.equals(transfer.getNeedRelabel()) ? "PENDING_REVIEW" : "NOT_REQUIRED");
|
||||
order.setSubOrderStatus("WAREHOUSE_TRANSFER:" + transfer.getStatus() + ";RELABEL:" + order.getRelabelStatus());
|
||||
order.setUpdatedAt(now); orders.updateById(order);
|
||||
if (!java.util.Objects.equals(before, order.getCurrentStatus())) {
|
||||
@@ -1214,18 +1218,34 @@ public class WarehouseTransferService {
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<WarehouseTransferResponses.Summary> pdaCandidates(long overseasWarehouseId) {
|
||||
return transfers.selectList(new LambdaQueryWrapper<WarehouseTransferOrder>()
|
||||
List<WarehouseTransferOrder> candidates = transfers.selectList(new LambdaQueryWrapper<WarehouseTransferOrder>()
|
||||
.eq(WarehouseTransferOrder::getOperatingWarehouseId, String.valueOf(overseasWarehouseId))
|
||||
.in(WarehouseTransferOrder::getStatus, List.of(WAIT_PDA_RECEIVING, APPROVED, ALLOCATED, WAIT_RELABEL, READY_FOR_DISPATCH))
|
||||
.orderByDesc(WarehouseTransferOrder::getUpdatedAt)).stream().map(value ->
|
||||
.orderByDesc(WarehouseTransferOrder::getUpdatedAt));
|
||||
Map<String, RelabelApplication> relabelApplicationsByNo = relabelApplications(candidates);
|
||||
return candidates.stream().map(value ->
|
||||
new WarehouseTransferResponses.Summary(value.getId(), value.getTransferNo(), value.getInboundCode(),
|
||||
value.getLastlegOrderId(), value.getLastlegOrderNo(), value.getOperatingWarehouseId(),
|
||||
value.getFbaWarehouseCode(), value.getDestinationType(), value.getDestinationWarehouseCode(),
|
||||
value.getDestinationWarehouseName(), value.getPackageCount(), value.getDeliveryMethod(),
|
||||
Boolean.TRUE.equals(value.getNeedRelabel()), value.getRelabelNo(), value.getStatus(),
|
||||
Boolean.TRUE.equals(value.getNeedRelabel()), value.getRelabelNo(),
|
||||
relabelApplicationsByNo.get(value.getRelabelNo()) == null ? null : relabelApplicationsByNo.get(value.getRelabelNo()).getStatus(),
|
||||
relabelApplicationsByNo.get(value.getRelabelNo()) == null ? null : relabelApplicationsByNo.get(value.getRelabelNo()).getFulfillmentStatus(),
|
||||
value.getStatus(),
|
||||
value.getEstimatedArrivalAt(), value.getCreatedAt())).toList();
|
||||
}
|
||||
|
||||
private Map<String, RelabelApplication> relabelApplications(List<WarehouseTransferOrder> transferOrders) {
|
||||
Set<String> relabelNos = transferOrders.stream().map(WarehouseTransferOrder::getRelabelNo)
|
||||
.filter(StringUtils::hasText).collect(Collectors.toSet());
|
||||
if (relabelNos.isEmpty()) return Map.of();
|
||||
List<RelabelApplication> applications = relabelApplications.selectList(
|
||||
new LambdaQueryWrapper<RelabelApplication>().in(RelabelApplication::getRelabelNo, relabelNos));
|
||||
if (applications == null || applications.isEmpty()) return Map.of();
|
||||
return applications.stream().collect(Collectors.toMap(RelabelApplication::getRelabelNo,
|
||||
Function.identity(), (left, right) -> right));
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public WarehouseTransferResponses.Detail pdaDetail(long overseasWarehouseId, String transferNo) {
|
||||
WarehouseTransferOrder transfer = transfers.findNoByWarehouse(transferNo, String.valueOf(overseasWarehouseId));
|
||||
@@ -1391,19 +1411,13 @@ public class WarehouseTransferService {
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateTransferDestinationRelabel(String destinationType, String fbaWarehouseCode,
|
||||
String destinationWarehouseCode, boolean needRelabel) {
|
||||
private static void validateTransferDestinationRequired(String destinationType, String fbaWarehouseCode,
|
||||
boolean allowDeferredForRelabel) {
|
||||
String type = trim(destinationType);
|
||||
if (type == null && StringUtils.hasText(fbaWarehouseCode)) type = "FBA";
|
||||
if (type == null || "NONE".equalsIgnoreCase(type)) {
|
||||
if ((type == null || "NONE".equalsIgnoreCase(type)) && !allowDeferredForRelabel) {
|
||||
throw badRequest("仓储转运必须选择 FBA 仓或私人仓");
|
||||
}
|
||||
if ("FBA".equalsIgnoreCase(type) && !needRelabel) {
|
||||
throw badRequest("转运到 FBA 仓必须同时创建贴标单");
|
||||
}
|
||||
if ("PRIVATE".equalsIgnoreCase(type) && needRelabel) {
|
||||
throw badRequest("不需要贴标时请选择私人仓作为目的地");
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyDestination(WarehouseTransferOrder transfer, WarehouseTransferRequests.Create request) {
|
||||
@@ -1598,7 +1612,7 @@ public class WarehouseTransferService {
|
||||
transfer.getOperatingWarehouseId(), transfer.getLabelDeadline(), transfer.getRelabelContactName(),
|
||||
transfer.getRelabelContactPhone(), transfer.getRelabelChargeAmount(), "仓储转运确认后自动创建换标单",
|
||||
"WAREHOUSE_TRANSFER:" + transfer.getTransferNo() + ":RELABEL", items,
|
||||
trim(transfer.getRelabelDeliveryMethod()), false);
|
||||
firstText(transfer.getRelabelDeliveryMethod(), "TRUCK"), false);
|
||||
return relabelService.createForExistingTailOrder(customerId, operatorId,
|
||||
transfer.getLastlegOrderId(), request);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user