贴标申请,仓储转运
This commit is contained in:
@@ -72,6 +72,8 @@ public record LastlegOrderSummary(
|
||||
String customerRemark,
|
||||
String warehouseRemark,
|
||||
LocalDateTime createdAt,
|
||||
LocalDateTime updatedAt
|
||||
LocalDateTime updatedAt,
|
||||
@Schema(description = "同一主单关联的全部换标子单及各自状态,按创建时间排序")
|
||||
List<RelabelSubOrder> relabelApplications
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.baiyue.lastleg.dto;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/** A relabel application keeps its own status within the received parent order. */
|
||||
public record RelabelSubOrder(Long lastlegOrderId, String relabelNo, String status,
|
||||
Integer quantity, LocalDateTime createdAt) { }
|
||||
@@ -16,6 +16,11 @@ import java.math.BigDecimal;
|
||||
|
||||
@Mapper
|
||||
public interface LastlegOrderMapper extends BaseMapper<LastlegOrder> {
|
||||
@Select("<script>SELECT r.lastleg_order_id,r.relabel_no,r.status,r.notified_package_count AS quantity,r.created_at " +
|
||||
"FROM ll_relabel_application r JOIN ll_order o ON o.id=r.lastleg_order_id AND o.customer_id=r.customer_id " +
|
||||
"WHERE r.lastleg_order_id IN <foreach collection='orderIds' item='id' open='(' separator=',' close=')'>#{id}</foreach> " +
|
||||
"ORDER BY r.created_at,r.id</script>")
|
||||
List<com.baiyue.lastleg.dto.RelabelSubOrder> findRelabelSubOrders(@Param("orderIds") List<Long> orderIds);
|
||||
String WAREHOUSE_FILTER_SQL = "(LOWER(TRIM(overseas_warehouse_code)) LIKE CONCAT('%',LOWER({0}),'%') " +
|
||||
"OR LOWER(TRIM(overseas_warehouse_name)) LIKE CONCAT('%',LOWER({0}),'%'))";
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public final class RelabelResponses {
|
||||
String destinationFbaWarehouseName, String skuCode, String productNameZh,
|
||||
long availablePackages, long version, List<InventoryPosition> positions,
|
||||
String sourceType, Long returnCartonId, String cartonMark,
|
||||
List<SkuItem> skuItems) {}
|
||||
List<SkuItem> skuItems, long relabelledPackages) {}
|
||||
public record HistoricalOrder(Long id, String orderNo, String sourceOrderNo, String outboundOrderNo,
|
||||
String relabelOrderNo, String orderType, String status, Integer packageCount,
|
||||
LocalDateTime createdAt) {}
|
||||
|
||||
+35
-17
@@ -260,7 +260,7 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
balance.getOverseasWarehouseCode(), balance.getOverseasWarehouseName(),
|
||||
balance.getDestinationWarehouseCode(), balance.getDestinationWarehouseName(), balance.getSkuCode(),
|
||||
balance.getProductNameZh(), available, value(balance.getVersion()), positions,
|
||||
"INBOUND", null, null, List.of());
|
||||
"INBOUND", null, null, List.of(), 0);
|
||||
}).filter(candidate -> candidate.availablePackages() > 0).toList());
|
||||
for (ReturnInventoryCarton carton : returnCartons.findAvailable(customerId, operationWarehouseId.trim())) {
|
||||
String keyword = trim(inboundCode);
|
||||
@@ -269,19 +269,23 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
&& !containsIgnoreCase(carton.getSourceReturnNo(), keyword)) continue;
|
||||
List<RelabelResponses.SkuItem> cartonSkus = returnCartonItems.listCarton(carton.getId()).stream()
|
||||
.filter(item -> value(item.getQuantity()) > 0)
|
||||
.map(item -> new RelabelResponses.SkuItem(item.getSkuCode(), null,
|
||||
Math.toIntExact(item.getQuantity()), null)).toList();
|
||||
.map(item -> {
|
||||
long used = returnCartons.relabelledQuantity(carton.getId(), item.getSkuCode());
|
||||
long remaining = value(item.getQuantity()) - used;
|
||||
return new RelabelResponses.SkuItem(item.getSkuCode(), null,
|
||||
Math.toIntExact(Math.max(remaining, 0)), null);
|
||||
}).filter(item -> item.quantity() > 0).toList();
|
||||
if (cartonSkus.isEmpty()) continue;
|
||||
String skuCodes = cartonSkus.stream().map(RelabelResponses.SkuItem::skuCode)
|
||||
.collect(Collectors.joining(","));
|
||||
long availablePackages = value(carton.getTotalQuantity());
|
||||
if (availablePackages <= 0) {
|
||||
availablePackages = cartonSkus.stream().mapToLong(RelabelResponses.SkuItem::quantity).sum();
|
||||
}
|
||||
long availablePackages = cartonSkus.stream().mapToLong(RelabelResponses.SkuItem::quantity).sum();
|
||||
if (availablePackages <= 0) continue;
|
||||
long relabelledPackages = carton.getTotalQuantity() == null ? 0
|
||||
: Math.max(0, carton.getTotalQuantity() - availablePackages);
|
||||
result.add(new RelabelResponses.InventoryCandidate(null, null, carton.getSourceReturnNo(),
|
||||
null, carton.getOverseasWarehouseId(), null, null, carton.getDestinationWarehouseCode(),
|
||||
carton.getDestinationWarehouseName(), skuCodes, "退货入库库存", availablePackages, 0, List.of(),
|
||||
"RETURN_CARTON", carton.getId(), carton.getCartonMark(), cartonSkus));
|
||||
"RETURN_CARTON", carton.getId(), carton.getCartonMark(), cartonSkus, relabelledPackages));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -380,9 +384,10 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
if (!"AVAILABLE".equals(carton.getStatus()) || carton.getRelabelApplicationId() != null) {
|
||||
throw conflict("仓库唛头 " + carton.getCartonMark() + " 已不可用于换标");
|
||||
}
|
||||
long previouslyRelabelled = returnCartons.relabelledQuantity(carton.getId(), item.skuCode());
|
||||
long requestedPackages = selectedReturnPackages.merge(carton.getId(),
|
||||
(long) item.notifiedPackageCount(), Math::addExact);
|
||||
if (requestedPackages > value(carton.getTotalQuantity())) {
|
||||
if (requestedPackages + previouslyRelabelled > value(carton.getTotalQuantity())) {
|
||||
throw conflict("退货托盘 " + carton.getCartonMark() + " 可用箱数不足");
|
||||
}
|
||||
sources.add(new SourceInventory(item, null, carton));
|
||||
@@ -455,9 +460,9 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
applications.insert(application);
|
||||
|
||||
for (ReturnInventoryCarton carton : selectedReturnCartons.values()) {
|
||||
carton.setRelabelApplicationId(applicationId); carton.setRelabelNo(relabelNo);
|
||||
carton.setRelabelStatus("PENDING"); carton.setStatus("RELABEL_PENDING"); carton.setUpdatedAt(now);
|
||||
returnCartons.updateById(carton);
|
||||
if (returnCartons.markRelabelPending(carton.getId(), applicationId, relabelNo, now) != 1) {
|
||||
throw conflict("退货箱状态已变化,请刷新后重试");
|
||||
}
|
||||
}
|
||||
|
||||
if (requiresWallet) {
|
||||
@@ -600,6 +605,7 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
}
|
||||
}
|
||||
for (LastlegOrder order : linkedOrders) {
|
||||
if ("RETURN_RELABEL".equals(order.getOrderType()) && !Objects.equals(order.getRelabelOrderNo(), application.getRelabelNo())) continue;
|
||||
String orderBefore = order.getCurrentStatus();
|
||||
String mainStatus = "RELABEL_APPLICATION".equals(order.getOrderType())
|
||||
? "WAIT_RELABEL" : orderBefore;
|
||||
@@ -612,8 +618,7 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
};
|
||||
// Reviewing/processing a return relabel must not move the already
|
||||
// completed inbound order back to assignment or relabel waiting.
|
||||
if ("RETURN_RELABEL".equals(order.getOrderType())
|
||||
&& !Set.of("COMPLETED", "REJECTED", "CANCELLED").contains(next)) {
|
||||
if ("RETURN_RELABEL".equals(order.getOrderType())) {
|
||||
orderStatus = "INBOUND_COMPLETED";
|
||||
}
|
||||
order.setCurrentStatus(orderStatus);
|
||||
@@ -703,6 +708,7 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
application.setStatus("PROCESSING"); application.setFulfillmentStatus("WAIT_RELABEL");
|
||||
application.setUpdatedAt(LocalDateTime.now()); applications.updateById(application);
|
||||
for (LastlegOrder order : tailOrders(application)) {
|
||||
if ("RETURN_RELABEL".equals(order.getOrderType()) && !Objects.equals(order.getRelabelOrderNo(), application.getRelabelNo())) continue;
|
||||
order.setRelabelStatus("PROCESSING"); order.setSubOrderStatus("RELABEL:PROCESSING");
|
||||
order.setUpdatedAt(LocalDateTime.now()); orders.updateById(order);
|
||||
}
|
||||
@@ -748,9 +754,18 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
}
|
||||
application.setUpdatedAt(now);
|
||||
applications.updateById(application);
|
||||
WarehouseTransferOrder linkedTransfer = warehouseTransfers == null ? null
|
||||
: warehouseTransfers.lockByRelabelNo(customerId, relabelNo);
|
||||
for (LastlegOrder order : tailOrders(application)) {
|
||||
if ("RETURN_RELABEL".equals(order.getOrderType()) && !Objects.equals(order.getRelabelOrderNo(), application.getRelabelNo())) continue;
|
||||
// 仓储转运尾程单由下方按转运目的仓一次性写入精确状态,避免先落入通用状态。
|
||||
if (linkedTransfer != null && "WAIT_RELABEL".equals(linkedTransfer.getStatus())
|
||||
&& Objects.equals(order.getId(), linkedTransfer.getLastlegOrderId())) continue;
|
||||
String orderBefore = order.getCurrentStatus();
|
||||
order.setCurrentStatus(requiresOutbound ? "PENDING_ASSIGNMENT" : "COMPLETED");
|
||||
// 换标确认时货物已经完成入库,不得退回最初建单的“待分配”。
|
||||
// 独立换标先进入待出库;仓储转运会在下方按目的仓进一步收敛为待排车或待确认目的仓。
|
||||
order.setCurrentStatus("RETURN_RELABEL".equals(order.getOrderType()) ? "INBOUND_COMPLETED"
|
||||
: requiresOutbound ? "WAIT_OUTBOUND" : "COMPLETED");
|
||||
order.setSubOrderStatus("RELABEL:" + application.getFulfillmentStatus());
|
||||
order.setRelabelStatus("COMPLETED");
|
||||
order.setUpdatedAt(now);
|
||||
@@ -774,13 +789,16 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
ReturnInventoryCarton carton = returnCartons.lockId(item.getReturnCartonId());
|
||||
if (carton == null || !Objects.equals(carton.getRelabelApplicationId(), application.getId())) continue;
|
||||
carton.setRelabelStatus("COMPLETED"); carton.setRelabelCompletedAt(now);
|
||||
// 换标已完成后释放“当前申请占用”关系,但保留 COMPLETED 作为历史状态。
|
||||
// 否则退货箱虽显示 AVAILABLE,下一次贴标申请仍会被旧 relabel_application_id 拦截。
|
||||
carton.setRelabelApplicationId(null); carton.setRelabelNo(null);
|
||||
carton.setStatus("AVAILABLE"); carton.setUpdatedAt(now); returnCartons.updateById(carton);
|
||||
}
|
||||
insertHistory(customerId, application.getId(), before, application.getStatus(), operatorId,
|
||||
request.remark(), now);
|
||||
// 仓储转运换标在客户确认后立即恢复为可排车,发车时再转为 OUTBOUNDED。
|
||||
if (warehouseTransfers != null) {
|
||||
WarehouseTransferOrder transfer = warehouseTransfers.lockByRelabelNo(customerId, relabelNo);
|
||||
if (linkedTransfer != null) {
|
||||
WarehouseTransferOrder transfer = linkedTransfer;
|
||||
if (transfer != null && "WAIT_RELABEL".equals(transfer.getStatus())) {
|
||||
Set<String> destinations = relabelItems.stream()
|
||||
.map(RelabelItem::getDestinationFbaWarehouseCode)
|
||||
|
||||
+2
-1
@@ -8,7 +8,8 @@ public final class ReturnOrderResponses {
|
||||
public record Summary(String returnNo, String lastlegOrderNo, String overseasWarehouseId,
|
||||
String warehouseContactName, String warehouseContactPhone, String customerReferenceNo, String status,
|
||||
int skuTypes, long expectedQuantity, long receivedQuantity, boolean needRelabel,
|
||||
String relabelNo, String relabelStatus, String discrepancyReason, LocalDateTime createdAt) { }
|
||||
String relabelNo, String relabelStatus, String discrepancyReason, LocalDateTime createdAt,
|
||||
List<com.baiyue.lastleg.dto.RelabelSubOrder> relabelApplications) { }
|
||||
public record Item(String skuCode, String productNameZh, long expectedQuantity,
|
||||
long receivedQuantity) { }
|
||||
public record Detail(Summary order, String remark, List<Item> items, List<Receipt> receipts, List<PalletDetail> pallets, List<Photo> photos) { }
|
||||
|
||||
+12
@@ -36,6 +36,12 @@ public interface ReturnInventoryCartonMapper extends BaseMapper<ReturnInventoryC
|
||||
@Select("SELECT * FROM ll_return_inventory_carton WHERE id=#{id} FOR UPDATE")
|
||||
ReturnInventoryCarton lockId(@Param("id") long id);
|
||||
|
||||
@Select("SELECT COALESCE(SUM(ri.notified_package_count),0) FROM ll_relabel_item ri " +
|
||||
"JOIN ll_relabel_application ra ON ra.id=ri.application_id " +
|
||||
"WHERE ri.return_carton_id=#{cartonId} AND ri.sku_code=#{skuCode} " +
|
||||
"AND ra.status NOT IN ('CANCELLED','REJECTED')")
|
||||
long relabelledQuantity(@Param("cartonId") long cartonId, @Param("skuCode") String skuCode);
|
||||
|
||||
@Update("UPDATE ll_return_inventory_carton SET total_quantity=#{remaining},sku_types=#{skuTypes},status='AVAILABLE'," +
|
||||
"relabel_application_id=NULL,relabel_no=NULL,relabel_status=NULL,updated_at=NOW(3) " +
|
||||
"WHERE id=#{id} AND customer_id=#{customerId} AND relabel_application_id=#{applicationId} " +
|
||||
@@ -44,6 +50,12 @@ public interface ReturnInventoryCartonMapper extends BaseMapper<ReturnInventoryC
|
||||
@Param("applicationId") long applicationId, @Param("remaining") long remaining,
|
||||
@Param("skuTypes") int skuTypes);
|
||||
|
||||
@Update("UPDATE ll_return_inventory_carton SET relabel_application_id=#{applicationId},relabel_no=#{relabelNo}," +
|
||||
"relabel_status='PENDING',status='RELABEL_PENDING',updated_at=#{updatedAt} " +
|
||||
"WHERE id=#{id} AND status='AVAILABLE' AND sku_types>0 AND total_quantity>0 AND relabel_application_id IS NULL")
|
||||
int markRelabelPending(@Param("id") long id, @Param("applicationId") long applicationId,
|
||||
@Param("relabelNo") String relabelNo, @Param("updatedAt") java.time.LocalDateTime updatedAt);
|
||||
|
||||
@Select("SELECT * FROM ll_return_inventory_carton WHERE source_receipt_id=#{receiptId} LIMIT 1")
|
||||
ReturnInventoryCarton findReceipt(@Param("receiptId") long receiptId);
|
||||
|
||||
|
||||
+2
@@ -13,6 +13,8 @@ public interface ReturnOrderMapper extends BaseMapper<ReturnOrder> {
|
||||
ReturnOrder findKey(@Param("customerId") String customerId, @Param("key") String key);
|
||||
@Select("SELECT * FROM ll_return_order WHERE customer_id=#{customerId} AND return_no=#{returnNo} LIMIT 1")
|
||||
ReturnOrder findNo(@Param("customerId") String customerId, @Param("returnNo") String returnNo);
|
||||
@Select("SELECT * FROM ll_return_order WHERE customer_id=#{customerId} AND return_no=#{returnNo} LIMIT 1 FOR UPDATE")
|
||||
ReturnOrder lockCustomerNo(@Param("customerId") String customerId, @Param("returnNo") String returnNo);
|
||||
@Select("SELECT * FROM ll_return_order WHERE return_no=#{returnNo} LIMIT 1 FOR UPDATE")
|
||||
ReturnOrder lockNo(@Param("returnNo") String returnNo);
|
||||
@Select("SELECT * FROM ll_return_order WHERE return_no=#{returnNo} AND overseas_warehouse_id=#{warehouseId} " +
|
||||
|
||||
+26
-10
@@ -186,7 +186,9 @@ public class ReturnReceiptService {
|
||||
w.in(ReturnOrder::getId, ids);
|
||||
}
|
||||
Page<ReturnOrder> result = orders.selectPage(Page.of(query.page(), query.size()), w);
|
||||
return new PageResult<>(result.getRecords().stream().map(this::summary).toList(), result.getCurrent(),
|
||||
var relabels = relabelSubOrders(result.getRecords());
|
||||
return new PageResult<>(result.getRecords().stream().map(order -> summary(order,
|
||||
relabels.getOrDefault(order.getLastlegOrderId(), List.of()))).toList(), result.getCurrent(),
|
||||
result.getSize(), result.getTotal(), result.getPages());
|
||||
}
|
||||
|
||||
@@ -216,7 +218,7 @@ public class ReturnReceiptService {
|
||||
}).toList();
|
||||
List<ReturnOrderResponses.Photo> photos = photoList(order).stream()
|
||||
.map(file -> new ReturnOrderResponses.Photo(file.fileId(), file.fileName(), file.contentType(), file.sizeBytes())).toList();
|
||||
return new ReturnOrderResponses.Detail(summary(order), order.getRemark(), items, receiptViews, palletViews, photos);
|
||||
return new ReturnOrderResponses.Detail(summary(order, relabelSubOrders(List.of(order)).getOrDefault(order.getLastlegOrderId(), List.of())), order.getRemark(), items, receiptViews, palletViews, photos);
|
||||
}
|
||||
|
||||
public com.baiyue.lastleg.relabel.pda.gateway.RelabelPhotoFileGateway.DownloadedFile downloadPhoto(String customerId, String returnNo, long fileId) {
|
||||
@@ -265,7 +267,7 @@ public class ReturnReceiptService {
|
||||
@Transactional
|
||||
public ReturnOrderResponses.RelabelCreated createRelabel(String customerId, String operatorId, String returnNo,
|
||||
ReturnOrderRequests.RelabelCreate request) {
|
||||
ReturnOrder order = orders.findNo(customerId, text(returnNo));
|
||||
ReturnOrder order = orders.lockCustomerNo(customerId, text(returnNo));
|
||||
if (order == null) throw notFound("退货单不存在");
|
||||
if (!COMPLETED.equals(order.getStatus())) throw conflict("退货单尚未完成签收");
|
||||
String fileScope = norm(request.fileScope());
|
||||
@@ -273,9 +275,14 @@ public class ReturnReceiptService {
|
||||
String key = text(request.idempotencyKey());
|
||||
String requestHash = hash(request);
|
||||
RelabelApplication replay = relabelApplications.findKey(customerId, key);
|
||||
if (replay != null) return new ReturnOrderResponses.RelabelCreated(replay.getRelabelNo(), replay.getId(),
|
||||
order.getReturnNo(), request.items().stream().map(ReturnOrderRequests.RelabelItem::skuCode).toList(), replay.getStatus());
|
||||
if (text(order.getRelabelNo()) != null) throw conflict("当前退货单已经生成贴标申请");
|
||||
if (replay != null) {
|
||||
if (!order.getReturnNo().equals(replay.getCustomerOrderNo()) || !requestHash.equals(replay.getRequestHash()))
|
||||
throw conflict("相同幂等键的贴标申请内容不一致");
|
||||
return new ReturnOrderResponses.RelabelCreated(replay.getRelabelNo(), replay.getId(),
|
||||
order.getReturnNo(), request.items().stream().map(ReturnOrderRequests.RelabelItem::skuCode).toList(), replay.getStatus());
|
||||
}
|
||||
// The order keeps the latest application reference, not an order-wide inventory lock.
|
||||
// Each new application must still allocate only unlabelled, available carton quantities below.
|
||||
var destination = fbaWarehouseValidator.required(request.destinationFbaWarehouseId(), request.destinationFbaWarehouseCode(), null);
|
||||
Map<String, ReturnOrderItem> receivedBySku = orderItems.lockOrder(order.getId()).stream()
|
||||
.collect(java.util.stream.Collectors.toMap(item -> norm(item.getSkuCode()), item -> item));
|
||||
@@ -311,8 +318,10 @@ public class ReturnReceiptService {
|
||||
tail.setRelabelStatus("PENDING_REVIEW");
|
||||
tail.setSubOrderStatus("RETURN_RELABEL:PENDING_REVIEW");
|
||||
tail.setCurrentStatus("RETURN_RELABEL".equals(tail.getOrderType()) ? "INBOUND_COMPLETED" : tail.getCurrentStatus());
|
||||
tail.setPackageCount(Math.toIntExact(totalQuantity));
|
||||
tail.setProductQuantity(Math.toIntExact(totalQuantity));
|
||||
if (!"RETURN_RELABEL".equals(tail.getOrderType())) {
|
||||
tail.setPackageCount(Math.toIntExact(totalQuantity));
|
||||
tail.setProductQuantity(Math.toIntExact(totalQuantity));
|
||||
}
|
||||
tail.setUpdatedAt(now);
|
||||
lastlegOrders.updateById(tail);
|
||||
RelabelApplication app = new RelabelApplication(); app.setId(appId); app.setCustomerId(customerId); app.setRelabelNo(relabelNo); app.setLastlegOrderId(tail.getId());
|
||||
@@ -331,6 +340,7 @@ public class ReturnReceiptService {
|
||||
long skuQuantity = cartonItems.listCarton(candidate.getId()).stream()
|
||||
.filter(line -> norm(requested.skuCode()).equals(norm(line.getSkuCode())))
|
||||
.mapToLong(line -> value(line.getQuantity())).sum();
|
||||
skuQuantity -= cartons.relabelledQuantity(candidate.getId(), norm(requested.skuCode()));
|
||||
if (skuQuantity <= 0) continue;
|
||||
ReturnInventoryCarton carton = selectedCartons.computeIfAbsent(candidate.getId(), ignored -> cartons.lockId(candidate.getId()));
|
||||
if (carton == null || !"AVAILABLE".equals(carton.getStatus()) || carton.getRelabelApplicationId() != null)
|
||||
@@ -551,10 +561,16 @@ public class ReturnReceiptService {
|
||||
return new PdaReturnReceiptResponses.Confirmed(order.getReturnNo(), receipt.getReceiptNo(), receipt.getReceiptBatchNo(), receipt.getPalletCode(),
|
||||
order.getStatus(), completed, value(order.getExpectedQuantity()), value(order.getReceivedQuantity()), receipt.getSignedAt());
|
||||
}
|
||||
private ReturnOrderResponses.Summary summary(ReturnOrder order) { return new ReturnOrderResponses.Summary(order.getReturnNo(), order.getLastlegOrderNo(),
|
||||
private Map<Long, List<com.baiyue.lastleg.dto.RelabelSubOrder>> relabelSubOrders(List<ReturnOrder> values) {
|
||||
var ids = values.stream().map(ReturnOrder::getLastlegOrderId).filter(java.util.Objects::nonNull).distinct().toList();
|
||||
if (ids.isEmpty()) return java.util.Collections.emptyMap();
|
||||
var rows = lastlegOrders.findRelabelSubOrders(ids);
|
||||
return rows == null ? java.util.Collections.emptyMap() : rows.stream().collect(java.util.stream.Collectors.groupingBy(com.baiyue.lastleg.dto.RelabelSubOrder::lastlegOrderId));
|
||||
}
|
||||
private ReturnOrderResponses.Summary summary(ReturnOrder order, List<com.baiyue.lastleg.dto.RelabelSubOrder> relabelApplications) { return new ReturnOrderResponses.Summary(order.getReturnNo(), order.getLastlegOrderNo(),
|
||||
order.getOverseasWarehouseId(), order.getWarehouseContactName(), order.getWarehouseContactPhone(), order.getCustomerReferenceNo(), order.getStatus(),
|
||||
order.getExpectedSkuTypes() == null ? 0 : order.getExpectedSkuTypes(), value(order.getExpectedQuantity()),
|
||||
value(order.getReceivedQuantity()), Boolean.TRUE.equals(order.getNeedRelabel()), order.getRelabelNo(), order.getRelabelStatus(), order.getDiscrepancyReason(), order.getCreatedAt()); }
|
||||
value(order.getReceivedQuantity()), Boolean.TRUE.equals(order.getNeedRelabel()), order.getRelabelNo(), order.getRelabelStatus(), order.getDiscrepancyReason(), order.getCreatedAt(), relabelApplications); }
|
||||
private ReturnOrderResponses.Item item(ReturnOrderItem item) { return new ReturnOrderResponses.Item(item.getSkuCode(),
|
||||
item.getProductNameZh(), value(item.getExpectedQuantity()), value(item.getReceivedQuantity())); }
|
||||
private PdaReturnReceiptResponses.Item pdaItem(ReturnOrderItem item) { return new PdaReturnReceiptResponses.Item(item.getSkuCode(),
|
||||
|
||||
@@ -96,10 +96,12 @@ public class LastlegOrderService {
|
||||
Map<String, String> containerNodes = containerNodes(page.getRecords());
|
||||
Map<Long, String> dispatchStatuses = dispatchStatuses(page.getRecords());
|
||||
Map<Long, LastlegOrderMapper.OrderWeightRow> weights = orderWeights(page.getRecords());
|
||||
Map<Long, List<com.baiyue.lastleg.dto.RelabelSubOrder>> relabels = relabelSubOrders(page.getRecords());
|
||||
return new PageResult<>(page.getRecords().stream().map(order -> summary(order, mergeRelations.get(order.getId()),
|
||||
StringUtils.hasText(order.getSourceContainerBookingId())
|
||||
? containerNodes.get(order.getSourceContainerBookingId()) : null,
|
||||
dispatchStatuses.getOrDefault(order.getId(), "UNSCHEDULED"), weights.get(order.getId()))).toList(),
|
||||
dispatchStatuses.getOrDefault(order.getId(), "UNSCHEDULED"), weights.get(order.getId()),
|
||||
relabels.getOrDefault(order.getId(), List.of()))).toList(),
|
||||
page.getCurrent(), page.getSize(), page.getTotal(), page.getPages());
|
||||
}
|
||||
|
||||
@@ -353,7 +355,7 @@ public class LastlegOrderService {
|
||||
.sorted(java.util.Comparator.comparingInt(value -> MANUAL_NODE_CODES.indexOf(value.nodeCode()))).toList();
|
||||
return new LastlegOrderDetailResponse(summary(order, palletMergeRelations(List.of(order)).get(order.getId()),
|
||||
containerNode(order), dispatchStatuses(List.of(order)).getOrDefault(order.getId(), "UNSCHEDULED"),
|
||||
orderWeights(List.of(order)).get(order.getId())), manualNodes, cargo, history.stream()
|
||||
orderWeights(List.of(order)).get(order.getId()), relabelSubOrders(List.of(order)).getOrDefault(order.getId(), List.of())), manualNodes, cargo, history.stream()
|
||||
.map(value -> new LastlegOrderDetailResponse.History(value.getId(), value.getFromStatus(),
|
||||
value.getToStatus(), value.getRemark(), value.getCreatedAt())).toList(), fees, operations.stream()
|
||||
.map(value -> new LastlegOrderDetailResponse.Operation(value.getId(), value.getOperationNode(),
|
||||
@@ -577,7 +579,10 @@ public class LastlegOrderService {
|
||||
.like(LastlegOrder::getOrderNo, query.orderNo())
|
||||
.or()
|
||||
.like(LastlegOrder::getSourceOrderNo, query.orderNo()))
|
||||
.like(StringUtils.hasText(relabelNo), LastlegOrder::getRelabelOrderNo, relabelNo)
|
||||
.and(StringUtils.hasText(relabelNo), nested -> nested
|
||||
.like(LastlegOrder::getRelabelOrderNo, relabelNo)
|
||||
.or().apply("EXISTS (SELECT 1 FROM ll_relabel_application r WHERE r.lastleg_order_id=ll_order.id " +
|
||||
"AND r.customer_id=ll_order.customer_id AND r.relabel_no LIKE CONCAT('%',{0},'%'))", relabelNo))
|
||||
.eq(StringUtils.hasText(query.orderType()), LastlegOrder::getOrderType, query.orderType())
|
||||
.like(StringUtils.hasText(query.inboundCode()), LastlegOrder::getInboundCode, query.inboundCode())
|
||||
.like(StringUtils.hasText(query.lxCode()), LastlegOrder::getLxCode, query.lxCode())
|
||||
@@ -637,9 +642,16 @@ public class LastlegOrderService {
|
||||
return rows.stream().collect(Collectors.toMap(LastlegOrderMapper.OrderWeightRow::orderId, row -> row));
|
||||
}
|
||||
|
||||
private Map<Long, List<com.baiyue.lastleg.dto.RelabelSubOrder>> relabelSubOrders(List<LastlegOrder> orders) {
|
||||
if (orders.isEmpty()) return Map.of();
|
||||
var rows = orderMapper.findRelabelSubOrders(orders.stream().map(LastlegOrder::getId).toList());
|
||||
return rows == null ? Map.of() : rows.stream().collect(Collectors.groupingBy(com.baiyue.lastleg.dto.RelabelSubOrder::lastlegOrderId));
|
||||
}
|
||||
|
||||
private LastlegOrderSummary summary(LastlegOrder o, List<LastlegOrderMapper.PalletMergeRelationRow> relations,
|
||||
String containerNode, String dispatchStatus,
|
||||
LastlegOrderMapper.OrderWeightRow weight) {
|
||||
LastlegOrderMapper.OrderWeightRow weight,
|
||||
List<com.baiyue.lastleg.dto.RelabelSubOrder> relabelApplications) {
|
||||
List<LastlegOrderMapper.PalletMergeRelationRow> related = relations == null ? List.of() : relations;
|
||||
return new LastlegOrderSummary(o.getId(), displayOrderNo(o), o.getOrderType(),
|
||||
LastlegOrderType.labelOf(o.getOrderType()), o.getDestinationType(), o.getSourceInboundId(),
|
||||
@@ -657,7 +669,7 @@ public class LastlegOrderService {
|
||||
o.getPalletMergeFlag(), related.stream().map(LastlegOrderMapper.PalletMergeRelationRow::mergeGroupNo).distinct().findFirst().orElse(null),
|
||||
related.stream().map(LastlegOrderMapper.PalletMergeRelationRow::relatedInboundNo).filter(Objects::nonNull).distinct().toList(),
|
||||
o.getCurrentStatus(), o.getSubOrderStatus(), o.getPrivateRemark(),
|
||||
o.getCustomerRemark(), o.getWarehouseRemark(), o.getCreatedAt(), o.getUpdatedAt());
|
||||
o.getCustomerRemark(), o.getWarehouseRemark(), o.getCreatedAt(), o.getUpdatedAt(), relabelApplications);
|
||||
}
|
||||
|
||||
private static Integer packageDifference(LastlegOrder order) {
|
||||
|
||||
Reference in New Issue
Block a user