提交
This commit is contained in:
+22
@@ -40,6 +40,28 @@ import org.apache.ibatis.annotations.Select;
|
||||
)
|
||||
|
||||
|
||||
UNION ALL
|
||||
SELECT c.carton_mark,c.sku_code,NULL,c.product_quantity,NULL,NULL,
|
||||
(SELECT JSON_ARRAYAGG(JSON_OBJECT('skuCode',s.sku_code,'quantity',s.product_quantity))
|
||||
FROM ll_dropship_carton_sku s WHERE s.customer_id=c.customer_id AND s.carton_id=c.id)
|
||||
FROM ll_dropship_carton c
|
||||
JOIN ll_order o ON o.id=c.order_id AND o.customer_id=c.customer_id
|
||||
JOIN ll_dropship_order_profile p ON p.id=c.profile_id AND p.customer_id=c.customer_id
|
||||
JOIN ll_inventory_position pos ON pos.id=p.inventory_position_id AND pos.customer_id=c.customer_id
|
||||
JOIN ll_inventory_balance b ON b.id=pos.balance_id AND b.customer_id=c.customer_id
|
||||
WHERE c.customer_id=#{customerId} AND o.inbound_code=#{inboundCode}
|
||||
AND o.overseas_warehouse_id=#{warehouseId} AND c.status='AVAILABLE'
|
||||
AND p.status='ACTIVE' AND pos.available_packages>0 AND b.available_packages>0
|
||||
AND NOT EXISTS (SELECT 1 FROM ll_inbound_plan_carton existing
|
||||
WHERE existing.customer_id=c.customer_id AND existing.order_id=c.order_id
|
||||
AND existing.carton_mark=c.carton_mark)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM ll_relabel_item ri
|
||||
JOIN ll_relabel_application ra ON ra.id=ri.application_id AND ra.customer_id=ri.customer_id
|
||||
WHERE ri.customer_id=c.customer_id AND ri.source_inbound_code=o.inbound_code
|
||||
AND ra.overseas_warehouse_id=#{warehouseId}
|
||||
AND UPPER(TRIM(COALESCE(NULLIF(ri.source_carton_mark,''),ri.carton_mark)))=UPPER(TRIM(c.carton_mark))
|
||||
AND ra.status NOT IN ('CANCELLED','REJECTED'))
|
||||
ORDER BY cartonMark
|
||||
""")
|
||||
java.util.List<SourceCarton> sourceCartons(@Param("customerId") String customerId,
|
||||
|
||||
+19
@@ -3,11 +3,30 @@ package com.baiyue.lastleg.transfer.mapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import java.util.List;
|
||||
|
||||
/** 使用提交单据的原箱快照表达业务占用,不提前扣减实物库存。 */
|
||||
@Mapper
|
||||
public interface TransferSourceReservationMapper {
|
||||
/** 在出库事务中按原箱身份更新来源箱,保留箱内件数和清点时间。 */
|
||||
@Update("""
|
||||
UPDATE ll_warehouse_transfer_carton original
|
||||
JOIN ll_warehouse_transfer_order origin_order
|
||||
ON origin_order.id=original.transfer_order_id AND origin_order.customer_id=original.customer_id
|
||||
JOIN ll_warehouse_transfer_order outgoing
|
||||
ON outgoing.customer_id=origin_order.customer_id AND outgoing.inbound_code=origin_order.inbound_code
|
||||
AND outgoing.operating_warehouse_id=origin_order.operating_warehouse_id
|
||||
JOIN ll_warehouse_transfer_carton selected
|
||||
ON selected.customer_id=outgoing.customer_id AND selected.transfer_order_id=outgoing.id
|
||||
AND COALESCE(NULLIF(selected.customer_carton_mark,''),selected.carton_mark)=original.carton_mark
|
||||
SET original.status='SHIPPED',original.updated_at=CURRENT_TIMESTAMP
|
||||
WHERE outgoing.customer_id=#{customerId} AND outgoing.id=#{transferOrderId}
|
||||
AND outgoing.transfer_no<>outgoing.inbound_code AND origin_order.transfer_no=origin_order.inbound_code
|
||||
AND original.status='COUNTED'
|
||||
""")
|
||||
int shipSelectedCartons(@Param("customerId") String customerId, @Param("transferOrderId") Long transferOrderId);
|
||||
|
||||
/** 按同一入仓快照串行提交,防止不同草稿同时抢占原箱。 */
|
||||
@Select("SELECT id FROM ll_inbound_order WHERE customer_id=#{customerId} AND id=#{inboundOrderId} FOR UPDATE")
|
||||
Long lockInbound(@Param("customerId") String customerId, @Param("inboundOrderId") Long inboundOrderId);
|
||||
|
||||
+5
@@ -21,6 +21,11 @@ public class TransferInventorySourceRepository {
|
||||
return reservations.occupiedMarks(customerId, warehouseId, sourceCode);
|
||||
}
|
||||
|
||||
/** 按当前转运实际选择的箱唛记录来源箱出库,不按箱数截断历史箱集合。 */
|
||||
public int shipSelectedCartons(String customerId, Long transferOrderId) {
|
||||
return reservations.shipSelectedCartons(customerId, transferOrderId);
|
||||
}
|
||||
|
||||
/** 读取当前来源单未被有效换标申请使用的箱级快照。 */
|
||||
public List<InboundSnapshotMapper.SourceCarton> sourceCartons(String customerId, String warehouseId, String inboundCode) {
|
||||
return snapshots.sourceCartons(customerId, warehouseId, inboundCode);
|
||||
|
||||
+12
-3
@@ -1063,8 +1063,13 @@ public class WarehouseTransferService {
|
||||
boolean hasSkuReceiptDifference(List<WarehouseTransferCarton> cartons, List<WarehouseTransferItem> items) {
|
||||
Map<String, Long> expected = new java.util.HashMap<>();
|
||||
Map<String, Long> received = new java.util.HashMap<>();
|
||||
Set<String> unknown = new java.util.HashSet<>();
|
||||
Map<Long, WarehouseTransferItem> byId = items.stream().collect(Collectors.toMap(WarehouseTransferItem::getId, Function.identity()));
|
||||
for (var item : items) expected.merge(item.getSkuCode(), item.getDeclaredQuantity() == null ? 0L : item.getDeclaredQuantity(), Long::sum);
|
||||
// 同SKU任一申报缺失时整体不可比较,不能把未知件数视作零制造差异。
|
||||
for (var item : items) {
|
||||
if (item.getDeclaredQuantity() == null) unknown.add(item.getSkuCode());
|
||||
else expected.merge(item.getSkuCode(), item.getDeclaredQuantity(), Long::sum);
|
||||
}
|
||||
for (var carton : cartons) {
|
||||
var contents = cartonContents(carton);
|
||||
if (contents.isEmpty()) {
|
||||
@@ -1075,8 +1080,10 @@ public class WarehouseTransferService {
|
||||
for (var line : contents) received.merge(line.skuCode(), line.quantity(), Long::sum);
|
||||
}
|
||||
}
|
||||
return expected.entrySet().stream().anyMatch(entry -> !entry.getValue().equals(received.getOrDefault(entry.getKey(), 0L)))
|
||||
|| received.entrySet().stream().anyMatch(entry -> !entry.getValue().equals(expected.getOrDefault(entry.getKey(), 0L)));
|
||||
return expected.entrySet().stream().anyMatch(entry -> !unknown.contains(entry.getKey())
|
||||
&& !entry.getValue().equals(received.getOrDefault(entry.getKey(), 0L)))
|
||||
|| received.entrySet().stream().anyMatch(entry -> !unknown.contains(entry.getKey())
|
||||
&& !entry.getValue().equals(expected.getOrDefault(entry.getKey(), 0L)));
|
||||
}
|
||||
|
||||
private List<WarehouseTransferCarton> requireCountedCartons(WarehouseTransferOrder transfer) {
|
||||
@@ -1520,6 +1527,8 @@ public class WarehouseTransferService {
|
||||
allocation.setStatus("SHIPPED"); allocation.setActivePositionKey(null);
|
||||
allocation.setShippedAt(now); allocation.setUpdatedAt(now); inventoryAllocations.updateById(allocation);
|
||||
}
|
||||
// 同一事务记录所选原箱已出库,当前库存候选据此排除;签收快照仍完整保留。
|
||||
inventorySources.shipSelectedCartons(customerId, transfer.getId());
|
||||
transfer.setStatus(OUTBOUNDED); transfer.setOutboundIdempotencyKey(key);
|
||||
transfer.setOutboundRequestHash(requestHash); transfer.setOutboundAt(now); transfer.setUpdatedAt(now);
|
||||
transfers.updateById(transfer);
|
||||
|
||||
Reference in New Issue
Block a user