fix: bind received dispatches to current per-order inventory

This commit is contained in:
2026-10-23 02:24:49 +08:00
parent 7e1703bde9
commit 85c7cde040
5 changed files with 88 additions and 5 deletions
@@ -133,7 +133,8 @@ public class AppointmentWorkDispatchBinding implements AppointmentWorkDispatchPo
return new Allocation(row.palletId(),row.batchKey(),version,row.customerId(),row.sourceKey(),row.destinationKey(),row.packages());
}
private void validatePhysical(String customer,PhysicalItem item,List<Allocation> selected,boolean received,boolean picked) {
var physical=picked?mapper.pickedPhysical(item.itemId(),customer):mapper.physical(item.planPalletId(),customer);
var physical=picked?mapper.pickedPhysical(item.itemId(),customer)
:received?mapper.receivedPhysical(item.planPalletId(),customer):mapper.physical(item.planPalletId(),customer);
if(physical.isEmpty()) throw conflict("托盘缺少真实逐票分配,不能按整票或整托总数猜测批次");
var canonical=AppointmentWorkPhysicalSources.canonical(physical,sources);
var remaining=new HashMap<String,Long>();
@@ -259,8 +260,8 @@ public class AppointmentWorkDispatchBinding implements AppointmentWorkDispatchPo
}
}
private List<AppointmentWorkDispatchMapper.Bound> privateAllocation(String customer,long dispatch,PhysicalItem item) {
var physical=mapper.physical(item.planPalletId(),customer);
if(physical.isEmpty()) return List.of();
var physical="RECEIVED".equals(item.sourceStage())?mapper.receivedPhysical(item.planPalletId(),customer):mapper.physical(item.planPalletId(),customer);
if(physical.isEmpty()) throw conflict("托盘缺少真实逐票库存归属,不能推算分配数量");
if(physical.stream().anyMatch(p->p.destinationKey()==null)) throw conflict("实物目的地尚未核实");
var canonical=AppointmentWorkPhysicalSources.canonical(physical,sources); var rows=new ArrayList<AppointmentWorkDispatchMapper.Bound>();
for(var part:physical) {
@@ -122,6 +122,21 @@ public interface AppointmentWorkDispatchMapper {
List<Candidate> candidates(long id);
@Select("SELECT l.order_id,l.customer_id,CASE WHEN l.destination_type='PRIVATE' THEN CONCAT('CUSTOMER:',l.order_id) ELSE CONCAT('FBA:',l.fba_warehouse_code) END destination_key,CASE WHEN COUNT(a.planned_package_count)=COUNT(a.line_id) THEN SUM(a.planned_package_count) END planned_packages,CASE WHEN COUNT(a.counted_package_count)=COUNT(a.line_id) THEN SUM(a.counted_package_count) END counted_packages FROM ll_inbound_plan_pallet_allocation a JOIN ll_inbound_plan_line l ON l.id=a.line_id AND l.customer_id=a.customer_id WHERE a.pallet_id=#{pallet} AND a.customer_id=#{customer} GROUP BY l.order_id,l.customer_id,l.destination_type,l.fba_warehouse_code")
List<Physical> physical(@Param("pallet") long pallet,@Param("customer") String customer);
/** 已收货托盘按当前库位逐票归属读取;移托后的库存不能继续使用原收货分配箱数。 */
@Select("""
SELECT o.id order_id,o.customer_id,
CASE WHEN o.destination_type='PRIVATE' THEN CONCAT('CUSTOMER:',o.id) ELSE CONCAT('FBA:',o.fba_warehouse_code) END destination_key,
NULL planned_packages,
SUM(COALESCE(pos.available_packages,0)+COALESCE(pos.allocated_packages,0)+COALESCE(pos.picked_packages,0)) counted_packages
FROM ll_inbound_plan_pallet pp
JOIN ll_inventory_position pos ON pos.pallet_id=pp.warehouse_pallet_id AND pos.customer_id=pp.customer_id
JOIN ll_inventory_balance b ON b.id=pos.balance_id AND b.customer_id=pos.customer_id
JOIN ll_order o ON o.customer_id=b.customer_id AND o.inbound_code=b.inbound_code
WHERE pp.id=#{pallet} AND pp.customer_id=#{customer}
AND COALESCE(pos.available_packages,0)+COALESCE(pos.allocated_packages,0)+COALESCE(pos.picked_packages,0)>0
GROUP BY o.id,o.customer_id,o.destination_type,o.fba_warehouse_code
""")
List<Physical> receivedPhysical(@Param("pallet") long pallet,@Param("customer") String customer);
@Select("SELECT a.order_id,a.customer_id,CASE WHEN i.destination_type='PRIVATE' THEN CONCAT('CUSTOMER:',a.order_id) ELSE CONCAT('FBA:',i.fba_warehouse_code) END destination_key,NULL planned_packages,SUM(a.packages) counted_packages FROM ll_dispatch_pda_pick_order a JOIN ll_dispatch_pda_pick p ON p.id=a.pick_id AND p.customer_id=a.customer_id JOIN ll_dispatch_item i ON i.id=p.dispatch_item_id AND i.customer_id=p.customer_id WHERE i.id=#{item} AND a.customer_id=#{customer} GROUP BY a.order_id,a.customer_id,i.destination_type,i.fba_warehouse_code")
List<Physical> pickedPhysical(@Param("item") long item,@Param("customer") String customer);
@Select("SELECT * FROM ll_inbound_fba_appointment WHERE id=#{id} FOR UPDATE")