This commit is contained in:
2026-10-14 12:13:26 +08:00
parent 166280da5a
commit 287edcf32b
3 changed files with 30 additions and 2 deletions
@@ -22,6 +22,9 @@ public interface ReturnPackingTraceMapper {
@Select("SELECT return_no, SUM(CASE WHEN target_carton_mark=#{mark} THEN quantity ELSE -quantity END) AS quantity FROM ll_return_packing_trace WHERE customer_id=#{customerId} AND sku_code=#{sku} AND (source_carton_mark=#{mark} OR target_carton_mark=#{mark}) GROUP BY return_no HAVING quantity>0 ORDER BY return_no")
List<Ownership> ownership(@Param("customerId") String customerId, @Param("mark") String mark, @Param("sku") String sku);
@Select("SELECT COALESCE(SUM(CASE WHEN target_carton_mark=#{mark} THEN quantity ELSE -quantity END),0) FROM ll_return_packing_trace WHERE customer_id=#{customerId} AND sku_code=#{sku} AND (source_carton_mark=#{mark} OR target_carton_mark=#{mark})")
long netTrackedQuantity(@Param("customerId") String customerId, @Param("mark") String mark, @Param("sku") String sku);
@Select("SELECT id,source_carton_mark,target_carton_mark,return_no,sku_code,quantity,created_at FROM ll_return_packing_trace WHERE customer_id=#{customerId} AND return_no=#{returnNo} ORDER BY created_at,id")
List<Trace> listReturn(@Param("customerId") String customerId, @Param("returnNo") String returnNo);
@@ -1014,8 +1014,7 @@ public class ReturnInventoryService {
throw conflict("目标箱已有合箱预占,不能并入");
if (existingTarget != null) ReturnCartonCountGuard.requireConfirmed(existingTarget);
if (existingTarget != null) for (var item : cartonItems.lockCarton(existingTarget.getId())) {
long tracked = packingTrace.ownership(customerId, targetMark, item.getSkuCode()).stream()
.mapToLong(com.baiyue.lastleg.returnreceipt.mapper.ReturnPackingTraceMapper.Ownership::quantity).sum();
long tracked = packingTrace.netTrackedQuantity(customerId, targetMark, item.getSkuCode());
if (tracked < value(item.getQuantity())) {
String[] origins = required(existingTarget.getSourceReturnNo(), "目标箱来源退货单缺失").split(",");
if (origins.length != 1) throw conflict("历史目标混箱缺少 SKU 来源明细");
@@ -623,6 +623,32 @@ class ReturnInventoryServiceTest {
assertThrows(ResponseStatusException.class, () -> service.confirmLabel(new PdaWarehouseIdentity("operator-2", "其他仓", 43L), "RC-SOURCE"));
}
@Test
void existingTargetSeedsOriginalOwnershipIncludingPreviouslyRemovedQuantity() {
var source = prepareConcurrentSource();
source.setCountStatus("CONFIRMED");
var target = new ReturnInventoryCarton(); target.setId(32L); target.setCartonMark("TARGET");
target.setCustomerId("10001"); target.setOverseasWarehouseId("42"); target.setSourceReturnNo("RT-1");
target.setSourceBatchNo("RB-1"); target.setStatus("AVAILABLE"); target.setCountStatus("CONFIRMED");
target.setTotalQuantity(15L); target.setSkuTypes(1);
var sourceLine = item(41L, "SKU-A", 5); var targetLine = item(42L, "SKU-A", 15);
when(cartons.lockMark("TARGET")).thenReturn(target);
when(cartonItems.lockCarton(31L)).thenReturn(List.of(sourceLine));
when(cartonItems.lockCarton(32L)).thenReturn(List.of(targetLine));
when(cartonItems.lockSku(32L, "SKU-A")).thenReturn(targetLine);
when(cartonItems.listCarton(32L)).thenReturn(List.of(targetLine));
when(cartonItems.totalQuantity(32L)).thenAnswer(ignored -> targetLine.getQuantity());
when(cartonItems.skuTypes(32L)).thenReturn(1);
when(packingTrace.netTrackedQuantity("10001", "TARGET", "SKU-A")).thenReturn(-5L);
when(balances.adjustCartonQuantity(anyString(), anyString(), anyString(), anyLong())).thenReturn(1);
ReflectionTestUtils.invokeMethod(service, "mergeScoped", new PdaWarehouseIdentity("worker", "worker", 42L),
new ReturnInventoryRequests.Merge(List.of("RT-1"), List.of(new ReturnInventoryRequests.ValidItem("SKU-A", 5)),
null, null, null, null, "target-reuse"),
java.util.Map.of("RC-SOURCE", new java.util.HashMap<>(java.util.Map.of("SKU-A", 5L))), "TARGET", null);
verify(packingTrace).insert(anyLong(), eq("10001"), anyLong(), eq(""), eq("TARGET"), eq("RT-1"), eq("SKU-A"), eq(20L), any());
assertThat(target.getTotalQuantity()).isEqualTo(20L);
}
private ReturnInventoryCarton prepareConcurrentSource() {
ReturnReceipt receipt = new ReturnReceipt(); receipt.setId(21L);
ReturnInventoryCarton snapshot = new ReturnInventoryCarton();