废弃 ,换标文件上传 ,排车托盘锁粒度
This commit is contained in:
+16
-4
@@ -222,11 +222,12 @@ public class CargoDiscardService {
|
||||
application.setUpdatedAt(reviewedAt); applications.updateById(application);
|
||||
LastlegOrder linked = orders.findSource(customerId, "LASTLEG_DISCARD", "CARGO_DISCARD:" + application.getId());
|
||||
if (linked != null) {
|
||||
linked.setCurrentStatus(next); linked.setVersion((linked.getVersion() == null ? 0 : linked.getVersion()) + 1); linked.setUpdatedAt(reviewedAt);
|
||||
String linkedStatus = mainOrderStatus(next);
|
||||
linked.setCurrentStatus(linkedStatus); linked.setVersion((linked.getVersion() == null ? 0 : linked.getVersion()) + 1); linked.setUpdatedAt(reviewedAt);
|
||||
orders.updateById(linked);
|
||||
LastlegOrderStatusHistory orderHistory = new LastlegOrderStatusHistory(); orderHistory.setId(IdWorker.getId());
|
||||
orderHistory.setCustomerId(customerId); orderHistory.setOrderId(linked.getId()); orderHistory.setFromStatus(PENDING_REVIEW);
|
||||
orderHistory.setToStatus(next); orderHistory.setEventId("CARGO_DISCARD_REVIEW:" + application.getId()); orderHistory.setRemark(historyRemark); orderHistory.setCreatedAt(reviewedAt);
|
||||
orderHistory.setToStatus(linkedStatus); orderHistory.setEventId("CARGO_DISCARD_REVIEW:" + application.getId()); orderHistory.setRemark(historyRemark); orderHistory.setCreatedAt(reviewedAt);
|
||||
orderHistories.insert(orderHistory);
|
||||
}
|
||||
history(customerId, application.getId(), PENDING_REVIEW, next, operatorId, historyRemark, reviewedAt);
|
||||
@@ -248,10 +249,12 @@ public class CargoDiscardService {
|
||||
LocalDateTime at = now(); application.setStatus(to); application.setUpdatedAt(at); applications.updateById(application);
|
||||
LastlegOrder linked = orders.findSource(customerId, "LASTLEG_DISCARD", "CARGO_DISCARD:" + application.getId());
|
||||
if (linked != null) {
|
||||
linked.setCurrentStatus(to); linked.setPackageCount(application.getTotalPackages());
|
||||
String linkedFrom = mainOrderStatus(from);
|
||||
String linkedTo = mainOrderStatus(to);
|
||||
linked.setCurrentStatus(linkedTo); linked.setPackageCount(application.getTotalPackages());
|
||||
linked.setVersion((linked.getVersion() == null ? 0 : linked.getVersion()) + 1); linked.setUpdatedAt(at); orders.updateById(linked);
|
||||
LastlegOrderStatusHistory h = new LastlegOrderStatusHistory(); h.setId(IdWorker.getId()); h.setCustomerId(customerId); h.setOrderId(linked.getId());
|
||||
h.setFromStatus(from); h.setToStatus(to); h.setEventId("CARGO_DISCARD_STATUS:" + application.getId() + ":" + to); h.setRemark(remark); h.setCreatedAt(at); orderHistories.insert(h);
|
||||
h.setFromStatus(linkedFrom); h.setToStatus(linkedTo); h.setEventId("CARGO_DISCARD_STATUS:" + application.getId() + ":" + linkedTo); h.setRemark(remark); h.setCreatedAt(at); orderHistories.insert(h);
|
||||
}
|
||||
history(customerId, application.getId(), from, to, operatorId, remark, at);
|
||||
}
|
||||
@@ -360,6 +363,15 @@ public class CargoDiscardService {
|
||||
}
|
||||
}
|
||||
|
||||
/** Maps application/PDA-only states to the five states exposed by the tail-leg main order. */
|
||||
private static String mainOrderStatus(String status) {
|
||||
return switch (status) {
|
||||
case REJECTED -> CANCELLED;
|
||||
case PDA_COMPLETED -> "PROCESSING";
|
||||
default -> status;
|
||||
};
|
||||
}
|
||||
|
||||
private String hash(Object value) {
|
||||
try {
|
||||
byte[] json = objectMapper.writeValueAsBytes(value);
|
||||
|
||||
+18
-3
@@ -26,6 +26,9 @@ import com.baiyue.lastleg.dispatch.pda.mapper.DispatchPdaTaskMapper;
|
||||
import com.baiyue.lastleg.entity.LastlegOrder;
|
||||
import com.baiyue.lastleg.mapper.LastlegOrderMapper;
|
||||
import com.baiyue.lastleg.delivery.mapper.OutboundOrderMapper;
|
||||
import com.baiyue.lastleg.relabel.entity.RelabelApplication;
|
||||
import com.baiyue.lastleg.relabel.mapper.RelabelApplicationMapper;
|
||||
import com.baiyue.lastleg.relabel.service.RelabelApplicationService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -62,6 +65,7 @@ public class DispatchService {
|
||||
@Resource private LastlegOrderNoGenerator orderNoGenerator;
|
||||
@Resource private LastlegOrderMapper tailOrders;
|
||||
@Resource private OutboundOrderMapper outboundOrders;
|
||||
@Resource private RelabelApplicationMapper relabelApplications;
|
||||
|
||||
public String resolveCustomerScopeForPlans(List<Long> planIds) {
|
||||
return requireSingleCustomerScope(candidates.findCustomerScopesByPlanIds(normalizeIds(planIds, "Plan IDs")),
|
||||
@@ -75,9 +79,16 @@ public class DispatchService {
|
||||
}
|
||||
|
||||
public String resolveCustomerScopeForRelabel(String relabelNo) {
|
||||
List<DispatchPalletCandidate> values = candidates.relabelAvailable(null, null, trimToNull(relabelNo));
|
||||
return requireSingleCustomerScope(values.stream().map(DispatchPalletCandidate::customerId)
|
||||
.filter(StringUtils::hasText).distinct().toList(), "Selected relabel order");
|
||||
String normalized = trimToNull(relabelNo);
|
||||
RelabelApplication application = normalized == null ? null : relabelApplications.findAnyByRelabelNo(normalized);
|
||||
if (application == null) throw new ResponseStatusException(HttpStatus.NOT_FOUND, "换标单不存在,请检查换标单号");
|
||||
if (!RelabelApplicationService.READY_FOR_OUTBOUND.equals(application.getStatus())) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "换标尚未完成或客户尚未确认,无法进行排车");
|
||||
}
|
||||
if (!"TRUCK".equals(application.getDeliveryMethod())) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "该换标单不是卡车派送,无需进行排车");
|
||||
}
|
||||
return application.getCustomerId();
|
||||
}
|
||||
|
||||
public List<DispatchPalletCandidate> candidates(String customerId, List<Long> planIds, String orderNo,
|
||||
@@ -415,6 +426,10 @@ public class DispatchService {
|
||||
|
||||
@Transactional
|
||||
private DispatchResponse preArrangeRelabel(String customerId, String operatorId, DispatchRequests.PreArrange request) {
|
||||
RelabelApplication application = relabelApplications.findNo(customerId, request.relabelNo());
|
||||
if (application == null || !RelabelApplicationService.READY_FOR_OUTBOUND.equals(application.getStatus())) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "换标尚未完成或客户尚未确认,无法进行排车");
|
||||
}
|
||||
List<DispatchPalletCandidate> selected = candidates.relabelAvailable(customerId, null, request.relabelNo());
|
||||
Set<Long> requested = request.planPalletIds().stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
selected = selected.stream().filter(c -> requested.contains(c.warehousePalletId())).toList();
|
||||
|
||||
@@ -13,7 +13,9 @@ public enum LastlegOrderType {
|
||||
/** Return shipment that also requires relabeling. */
|
||||
RETURN_RELABEL("退货换标"),
|
||||
/** One-click dropship order, retained for existing data and workflows. */
|
||||
ONE_CLICK_DROPSHIP("一件代发");
|
||||
ONE_CLICK_DROPSHIP("一件代发"),
|
||||
/** Cargo discard order created from an approved cargo discard application. */
|
||||
CARGO_DISCARD("货物废弃订单");
|
||||
|
||||
private final String label;
|
||||
|
||||
|
||||
+18
-5
@@ -381,11 +381,11 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
if (query.createdFrom() != null && query.createdTo() != null && query.createdFrom().isAfter(query.createdTo())) {
|
||||
throw badRequest("createdFrom must not be after createdTo");
|
||||
}
|
||||
String requestedStatus = trim(query.status());
|
||||
LambdaQueryWrapper<RelabelApplication> wrapper = new LambdaQueryWrapper<RelabelApplication>()
|
||||
.eq(StringUtils.hasText(customerId), RelabelApplication::getCustomerId, customerId)
|
||||
.like(StringUtils.hasText(query.relabelNo()), RelabelApplication::getRelabelNo, query.relabelNo())
|
||||
.like(StringUtils.hasText(query.customerOrderNo()), RelabelApplication::getCustomerOrderNo, query.customerOrderNo())
|
||||
.eq(StringUtils.hasText(query.status()), RelabelApplication::getStatus, query.status())
|
||||
.eq(StringUtils.hasText(query.overseasWarehouseId()), RelabelApplication::getOverseasWarehouseId,
|
||||
trim(query.overseasWarehouseId()))
|
||||
.ge(query.createdFrom() != null, RelabelApplication::getCreatedAt, query.createdFrom())
|
||||
@@ -394,6 +394,14 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
"EXISTS (SELECT 1 FROM ll_relabel_item ri WHERE ri.application_id=ll_relabel_application.id AND ri.customer_id=ll_relabel_application.customer_id AND ri.sku_code LIKE CONCAT('%',{0},'%'))",
|
||||
query.skuCode())
|
||||
.orderByDesc(RelabelApplication::getCreatedAt);
|
||||
if (PENDING_PROCESSING.equals(requestedStatus)) {
|
||||
wrapper.in(RelabelApplication::getStatus, PENDING_PROCESSING, "PROCESSING", CUSTOMER_CONFIRM_PENDING,
|
||||
"REJECTED", "CANCELLED");
|
||||
} else if ("COMPLETED".equals(requestedStatus)) {
|
||||
wrapper.in(RelabelApplication::getStatus, READY_FOR_OUTBOUND, "COMPLETED");
|
||||
} else if (StringUtils.hasText(requestedStatus)) {
|
||||
wrapper.eq(RelabelApplication::getStatus, requestedStatus);
|
||||
}
|
||||
Page<RelabelApplication> page = applications.selectPage(new Page<>(query.page(), query.size()), wrapper);
|
||||
List<RelabelResponses.Summary> records = page.getRecords().stream().map(value -> summary(value, itemList(value.getId()))).toList();
|
||||
return new PageResult<>(records, page.getCurrent(), page.getSize(), page.getTotal(), page.getPages());
|
||||
@@ -488,7 +496,7 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
};
|
||||
order.setCurrentStatus(orderStatus);
|
||||
order.setSubOrderStatus("RELABEL:" + next);
|
||||
order.setRelabelStatus(next);
|
||||
order.setRelabelStatus(businessRelabelStatus(next));
|
||||
order.setUpdatedAt(now);
|
||||
orders.updateById(order);
|
||||
if (!Objects.equals(orderBefore, orderStatus)) {
|
||||
@@ -586,7 +594,7 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
String orderBefore = order.getCurrentStatus();
|
||||
order.setCurrentStatus("PENDING_ASSIGNMENT");
|
||||
order.setSubOrderStatus("RELABEL:" + application.getFulfillmentStatus());
|
||||
order.setRelabelStatus(READY_FOR_OUTBOUND);
|
||||
order.setRelabelStatus("COMPLETED");
|
||||
order.setUpdatedAt(now);
|
||||
orders.updateById(order);
|
||||
if (!Objects.equals(orderBefore, order.getCurrentStatus())) {
|
||||
@@ -609,9 +617,9 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
if (transferOrder != null && customerId.equals(transferOrder.getCustomerId())) {
|
||||
String transferOrderBefore = transferOrder.getCurrentStatus();
|
||||
transferOrder.setCurrentStatus("READY_FOR_DISPATCH");
|
||||
transferOrder.setRelabelStatus(READY_FOR_OUTBOUND);
|
||||
transferOrder.setRelabelStatus("COMPLETED");
|
||||
transferOrder.setSubOrderStatus("WAREHOUSE_TRANSFER:READY_FOR_DISPATCH;RELABEL:"
|
||||
+ READY_FOR_OUTBOUND);
|
||||
+ "COMPLETED");
|
||||
transferOrder.setUpdatedAt(now);
|
||||
orders.updateById(transferOrder);
|
||||
if (!Objects.equals(transferOrderBefore, transferOrder.getCurrentStatus())) {
|
||||
@@ -889,6 +897,11 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
|| READY_FOR_OUTBOUND.equals(from) && Set.of("COMPLETED", "CANCELLED").contains(to);
|
||||
if (!allowed) throw conflict("Relabel status cannot change from " + from + " to " + to);
|
||||
}
|
||||
|
||||
private static String businessRelabelStatus(String workflowStatus) {
|
||||
return Set.of(READY_FOR_OUTBOUND, "COMPLETED").contains(workflowStatus)
|
||||
? "COMPLETED" : PENDING_PROCESSING;
|
||||
}
|
||||
private String hash(Object value) {
|
||||
try { return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256")
|
||||
.digest(objectMapper.copy().findAndRegisterModules().writeValueAsString(value).getBytes(StandardCharsets.UTF_8))); }
|
||||
|
||||
@@ -52,6 +52,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@@ -511,7 +512,7 @@ public class LastlegOrderService {
|
||||
? containerNodes.get(order.getSourceContainerBookingId()) : null), csv(order.getAbnormal()), csv(order.getDetained()),
|
||||
csv(order.getPalletCount()), csv(order.getPackageCount()), csv(order.getVolumeCbm()), csv(order.getProductQuantity()),
|
||||
csv(order.getVolumeWeightKg()), csv(order.getEstimatedArrivalAt()), csv(order.getActualArrivalAt()),
|
||||
csv(order.getEstimatedWarehouseAt()), csv(order.getInboundOrderNo()), csv(order.getRelabelOrderNo()), csv(order.getRelabelStatus()),
|
||||
csv(order.getEstimatedWarehouseAt()), csv(order.getInboundOrderNo()), csv(order.getRelabelOrderNo()), csv(relabelBusinessStatus(order.getRelabelStatus())),
|
||||
csv(order.getPalletMergeFlag()), csv(order.getCurrentStatus()), csv(order.getSubOrderStatus()), csv(order.getPrivateRemark()),
|
||||
csv(order.getCustomerRemark()), csv(order.getWarehouseRemark()))) + "\r\n";
|
||||
output.write(line.getBytes(StandardCharsets.UTF_8));
|
||||
@@ -602,7 +603,7 @@ public class LastlegOrderService {
|
||||
Boolean.TRUE.equals(o.getManualNodeOverride()), Boolean.TRUE.equals(o.getManualNodeOverride()) ? "MANUAL" : "CONTAINER",
|
||||
o.getVersion() == null ? 0 : o.getVersion(), o.getPalletCount(), o.getPackageCount(), o.getVolumeCbm(),
|
||||
o.getProductQuantity(), o.getVolumeWeightKg(), o.getEstimatedArrivalAt(), o.getActualArrivalAt(),
|
||||
o.getEstimatedWarehouseAt(), o.getInboundOrderNo(), dispatchStatus, o.getRelabelOrderNo(), o.getRelabelStatus(),
|
||||
o.getEstimatedWarehouseAt(), o.getInboundOrderNo(), dispatchStatus, o.getRelabelOrderNo(), relabelBusinessStatus(o.getRelabelStatus()),
|
||||
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(),
|
||||
@@ -639,6 +640,12 @@ public class LastlegOrderService {
|
||||
? null : order.getInboundCode();
|
||||
}
|
||||
|
||||
private static String relabelBusinessStatus(String workflowStatus) {
|
||||
if (!StringUtils.hasText(workflowStatus) || "NOT_REQUIRED".equals(workflowStatus)) return workflowStatus;
|
||||
return Set.of("READY_FOR_OUTBOUND", "COMPLETED").contains(workflowStatus)
|
||||
? "COMPLETED" : "PENDING_PROCESSING";
|
||||
}
|
||||
|
||||
private static Long parseLong(String value) {
|
||||
try { return StringUtils.hasText(value) ? Long.parseLong(value.trim()) : null; }
|
||||
catch (NumberFormatException ignored) { return null; }
|
||||
|
||||
Reference in New Issue
Block a user