feat(fleet): bind quote versions and reconcile actual return quantities
This commit is contained in:
+32
@@ -0,0 +1,32 @@
|
||||
package com.baiyue.lastleg.delivery.model;
|
||||
|
||||
import com.baiyue.lastleg.delivery.entity.DeliveryOrder;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/** Quantity accounting for the original journey; later post-signature returns belong to another movement. */
|
||||
public record DeliveryCargoQuantities(int shipped, int signed, int returned, int remaining) {
|
||||
public static DeliveryCargoQuantities from(DeliveryOrder order, List<DeliveryReturnReceiptFact> receipts) {
|
||||
if (order.getPackageCount() == null || order.getPackageCount() <= 0) throw invalid("派送缺少实发数量");
|
||||
var ids = new HashSet<Long>();
|
||||
long received = 0;
|
||||
for (var receipt : receipts) {
|
||||
if (receipt.ledgerId() == null || !ids.add(receipt.ledgerId()) || receipt.packages() <= 0 || receipt.receivedAt() == null)
|
||||
throw invalid("退回实际入账流水缺失或来源映射重复");
|
||||
received = Math.addExact(received, receipt.packages());
|
||||
}
|
||||
int shipped = order.getPackageCount();
|
||||
if (received > shipped) throw invalid("退回实收超过原实发数量");
|
||||
if (order.getSignedAt() != null) {
|
||||
Integer signed = order.getSignedPackages();
|
||||
long beforeSignature = receipts.stream().filter(receipt -> !receipt.receivedAt().isAfter(order.getSignedAt())).mapToLong(DeliveryReturnReceiptFact::packages).sum();
|
||||
if (signed == null || signed <= 0 || signed > shipped || beforeSignature < shipped - signed)
|
||||
throw invalid("签收数量快照缺失或与实际退回不守恒");
|
||||
// Do not re-open or reclassify signed cargo when another return is later received.
|
||||
return new DeliveryCargoQuantities(shipped, signed, shipped - signed, 0);
|
||||
}
|
||||
if (order.getSignedPackages() != null) throw invalid("签收数量缺少签收时间");
|
||||
return new DeliveryCargoQuantities(shipped, 0, Math.toIntExact(received), shipped - Math.toIntExact(received));
|
||||
}
|
||||
private static IllegalArgumentException invalid(String message) { return new IllegalArgumentException(message); }
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package com.baiyue.lastleg.delivery.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/** Immutable actual receipt, attributed to the original dispatch item and physical pallet. */
|
||||
public record DeliveryReturnReceiptFact(Long ledgerId, Long dispatchItemId, Long palletId, long packages, LocalDateTime receivedAt) { }
|
||||
+1
-1
@@ -31,7 +31,7 @@ public final class DeliveryStatusPolicy {
|
||||
case "WAIT_DELIVERY" -> List.of(
|
||||
"START_DELIVERY", "REJECT_DELIVERY", "CANCEL_DELIVERY");
|
||||
case "DELIVERING" -> List.of("REJECT_DELIVERY", "MARK_RETURN");
|
||||
case "DELIVERED", "REJECTED" -> List.of("MARK_RETURN");
|
||||
case "DELIVERED", "REJECTED", "RETURN_PENDING" -> List.of("MARK_RETURN");
|
||||
default -> List.of();
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user