feat(fleet): bind quote versions and reconcile actual return quantities
This commit is contained in:
+2
-1
@@ -28,7 +28,7 @@ public class FleetHandoverPdaQuery {
|
||||
FleetDispatchGateway dispatches, FleetHandoverRepository handovers, ObjectMapper json) {
|
||||
this.bindings = bindings; this.trips = trips; this.history = history; this.dispatches = dispatches; this.handovers = handovers; this.json = json;
|
||||
}
|
||||
public record Delivery(String deliveryNo, String status, int packages, Instant terminalAt, FleetTransitEvidence.Transport transport) { }
|
||||
public record Delivery(String deliveryNo, String status, int packages, int remainingPackages, Instant terminalAt, FleetTransitEvidence.Transport transport) { }
|
||||
public record Handover(String handoverNo, Instant handedOverAt, String location,
|
||||
FleetTransitEvidence.Transport previous, FleetTransitEvidence.Transport replacement) { }
|
||||
public record Status(String dispatchNo, String tripNo, String tripStatus, String tripRecordVersion,
|
||||
@@ -53,6 +53,7 @@ public class FleetHandoverPdaQuery {
|
||||
if (departed == null || !trip.getTripNo().equals(departed.tripNo()) || !Long.toString(warehouseId).equals(departed.warehouseId())) throw notFound();
|
||||
var originalTransport = new FleetTransitEvidence.Transport(departed.vehiclePlate(), departed.driverName(), departed.driverPhone());
|
||||
var rows = evidence.deliveries().stream().map(row -> new Delivery(row.cargo().deliveryNo(), row.status(), row.cargo().packages(),
|
||||
row.cargo().terminalAt() != null ? 0 : row.cargo().packages() - row.cargo().returnedCargo().stream().mapToInt(FleetHandoverPolicy.ReturnedCargo::packages).sum(),
|
||||
row.cargo().terminalAt(), row.transport())).toList();
|
||||
var latest = handovers.latestForCargo(trip.getId(), json.writeValueAsString(Map.of("customerId", binding.getCustomerId(), "dispatchNo", dispatchNo)));
|
||||
Handover handover = null;
|
||||
|
||||
+17
-2
@@ -12,7 +12,8 @@ public final class FleetHandoverPolicy {
|
||||
String destinationKey, int packages) { }
|
||||
/** terminalAt is a signed or RETURN_COMPLETED fact, not a mutable updatedAt. */
|
||||
public record Delivery(String customerId, String dispatchNo, String deliveryNo,
|
||||
String destinationKey, int packages, Instant terminalAt) { }
|
||||
String destinationKey, int packages, Instant terminalAt, List<ReturnedCargo> returnedCargo) { }
|
||||
public record ReturnedCargo(String itemId, String palletId, int packages, Instant receivedAt) { }
|
||||
public record Pallet(String palletId, Load measuredLoad) { }
|
||||
public record Inspection(List<Cargo> remainingCargo, List<Delivery> completedDeliveries,
|
||||
Set<String> remainingPalletIds, Load occupied) { }
|
||||
@@ -48,6 +49,7 @@ public final class FleetHandoverPolicy {
|
||||
throw invalid("同一实托包含不同卸货目的地,请先核对原始装载");
|
||||
}
|
||||
Map<Destination, Delivery> byDestination = new HashMap<>();
|
||||
Map<Item, Integer> returned = new HashMap<>();
|
||||
Set<DeliveryKey> deliveryKeys = new HashSet<>();
|
||||
List<Delivery> completed = new ArrayList<>();
|
||||
for (Delivery delivery : deliveries) {
|
||||
@@ -60,6 +62,16 @@ public final class FleetHandoverPolicy {
|
||||
throw invalid("派送事实重复或目的地拆分尚未核平");
|
||||
if (!Objects.equals(shipped.get(key), delivery.packages()))
|
||||
throw invalid("派送客户、排车、目的地或箱数与原始发运不一致");
|
||||
if (delivery.returnedCargo() == null) throw invalid("缺少实际退回数量依据");
|
||||
for (ReturnedCargo receipt : delivery.returnedCargo()) {
|
||||
Item item = new Item(delivery.customerId(), delivery.dispatchNo(), receipt.itemId());
|
||||
Cargo source = departureCargo.stream().filter(cargo -> item.equals(new Item(cargo.customerId(), cargo.dispatchNo(), cargo.itemId())))
|
||||
.findFirst().orElseThrow(() -> invalid("退回来源不属于原始发运明细"));
|
||||
if (!destination(source).equals(key) || !Objects.equals(source.palletId(), receipt.palletId()) || receipt.packages() <= 0
|
||||
|| receipt.receivedAt() == null || receipt.receivedAt().isBefore(departedAt) || receipt.receivedAt().isAfter(handedOverAt))
|
||||
throw invalid("退回来源、数量或实际时间与交接不一致");
|
||||
if (returned.merge(item, receipt.packages(), Math::addExact) > source.packages()) throw invalid("累计退回超过原发运明细数量");
|
||||
}
|
||||
if (delivery.terminalAt() != null) {
|
||||
if (delivery.terminalAt().isBefore(departedAt) || delivery.terminalAt().isAfter(handedOverAt))
|
||||
throw invalid("交接时间与已发生的签收或退回事实冲突,请刷新核对");
|
||||
@@ -76,7 +88,10 @@ public final class FleetHandoverPolicy {
|
||||
}
|
||||
if (!measurements.keySet().equals(palletDestinations.keySet())) throw invalid("实测托盘与原始货物不一致");
|
||||
List<Cargo> remaining = departureCargo.stream()
|
||||
.filter(cargo -> byDestination.get(destination(cargo)).terminalAt() == null).toList();
|
||||
.filter(cargo -> byDestination.get(destination(cargo)).terminalAt() == null)
|
||||
.map(cargo -> new Cargo(cargo.customerId(), cargo.dispatchNo(), cargo.itemId(), cargo.palletId(), cargo.destinationKey(),
|
||||
cargo.packages() - returned.getOrDefault(new Item(cargo.customerId(), cargo.dispatchNo(), cargo.itemId()), 0)))
|
||||
.filter(cargo -> cargo.packages() > 0).toList();
|
||||
if (remaining.isEmpty()) throw invalid("全部货物已完成,请按结案和资源结束流程处理");
|
||||
Set<String> palletIds = new TreeSet<>();
|
||||
remaining.forEach(cargo -> palletIds.add(cargo.palletId()));
|
||||
|
||||
Reference in New Issue
Block a user