This commit is contained in:
2026-09-01 11:09:14 +08:00
191 changed files with 6486 additions and 403 deletions
@@ -70,7 +70,7 @@ class InboundPlanPaginationTest {
.getMethod("rows", String.class, InboundPlanRequests.Query.class, long.class, long.class)
.getAnnotation(org.apache.ibatis.annotations.Select.class).value()) + InboundPlanQueryMapper.FROM_AND_FILTER;
assertThat(sql).contains("a2.customer_id=#{customerId}", "ORDER BY a2.created_at DESC,ai2.id DESC LIMIT 1");
assertThat(sql).contains("di.customer_id=#{customerId} AND di.order_id=l.order_id");
assertThat(sql).contains("di.customer_id=#{customerId} AND </if>di.order_id=l.order_id");
assertThat(sql).contains("q.planNo", "q.inboundCode", "q.status", "q.overseasWarehouseId",
"q.destinationWarehouseCode", "q.warehouse",
"q.fbaWarehouseCode", "q.appointmentStatus", "q.dispatchStatus", "q.createdFrom", "q.createdTo");
@@ -2,6 +2,7 @@ package com.baiyue.lastleg.inboundplan.service;
import com.baiyue.lastleg.inboundplan.entity.InboundPlan;
import com.baiyue.lastleg.inboundplan.dto.InboundPlanRequests;
import com.baiyue.lastleg.inboundplan.dto.UpdateInboundPlanRequest;
import com.baiyue.lastleg.inboundplan.entity.InboundPlanLine;
import com.baiyue.lastleg.inboundplan.entity.InboundPlanPallet;
import com.baiyue.lastleg.inboundplan.entity.InboundPlanPalletAllocation;
@@ -55,6 +56,7 @@ class InboundPlanServiceTest {
ReflectionTestUtils.setField(service, "allocationMapper", allocationMapper);
ReflectionTestUtils.setField(service, "orderMapper", orderMapper);
ReflectionTestUtils.setField(service, "inventoryBalanceMapper", inventoryBalanceMapper);
ReflectionTestUtils.setField(service, "orderNoGenerator", new com.baiyue.lastleg.service.LastlegOrderNoGenerator());
org.mockito.Mockito.lenient().when(lineMapper.selectList(any())).thenReturn(List.of());
org.mockito.Mockito.lenient().when(palletMapper.selectList(any())).thenReturn(List.of());
org.mockito.Mockito.lenient().when(allocationMapper.selectList(any())).thenReturn(List.of());
@@ -182,13 +184,93 @@ class InboundPlanServiceTest {
}
@Test
void rejectsTransferWarehouseThatDiffersFromCargoSnapshots() {
SourceOrderSnapshot invalid = new SourceOrderSnapshot(1L, "100", "MSCU6639870", "RK-1",
void transferWarehouseOverridesOriginalCargoDestination() {
SourceOrderSnapshot transferred = new SourceOrderSnapshot(1L, "100", "MSCU6639870", "RK-1",
"DESTINATION_ASSIGNED", null, BigDecimal.ONE, 1, "WH-B", "WH-B", "Warehouse B", 1, 1);
when(orderMapper.lockOrder("100", 1L)).thenReturn(List.of(invalid));
when(orderMapper.lockOrder("100", 1L)).thenReturn(List.of(transferred));
when(orderMapper.markPlanned(any(), any(), any(), org.mockito.ArgumentMatchers.anyInt(), any()))
.thenReturn(1);
assertThrows(ResponseStatusException.class, () -> service.convert("100", 1L));
verify(planMapper, never()).insert(any(InboundPlan.class));
service.convert("100", 1L);
ArgumentCaptor<InboundPlanPallet> pallet = ArgumentCaptor.forClass(InboundPlanPallet.class);
verify(palletMapper).insert(pallet.capture());
assertEquals("WH-B", pallet.getValue().getDestinationWarehouseId());
assertEquals("WH-B", pallet.getValue().getDestinationWarehouseCode());
}
@Test
void convertsDropshipSourcePalletsWithoutRedistributingTheirPackages() {
when(orderMapper.lockOrder("100", 2L)).thenReturn(List.of(order(2L, "RK-2", "1.0000", "WH-A")));
when(orderMapper.markPlanned(any(), any(), any(), org.mockito.ArgumentMatchers.anyInt(), any()))
.thenReturn(1);
service.convertDropship("100", 2L, List.of(
new InboundPlanService.WholePalletInput("SOURCE-P-1", 3),
new InboundPlanService.WholePalletInput("SOURCE-P-2", 7)));
ArgumentCaptor<InboundPlanPallet> pallets = ArgumentCaptor.forClass(InboundPlanPallet.class);
verify(palletMapper, times(2)).insert(pallets.capture());
assertEquals(List.of("SOURCE-P-1", "SOURCE-P-2"),
pallets.getAllValues().stream().map(InboundPlanPallet::getPalletNo).toList());
ArgumentCaptor<InboundPlanPalletAllocation> allocations =
ArgumentCaptor.forClass(InboundPlanPalletAllocation.class);
verify(allocationMapper, times(2)).insert(allocations.capture());
assertEquals(List.of(3, 7), allocations.getAllValues().stream()
.map(InboundPlanPalletAllocation::getPlannedPackageCount).toList());
}
@Test
void updateSynchronizesDestinationSnapshotToLinesAndPallets() {
InboundPlan plan = new InboundPlan();
plan.setId(20L);
plan.setPlanNo("IP-20");
plan.setCustomerId("100");
plan.setStatus("PENDING_ASSIGNMENT");
plan.setLineCount(1);
plan.setPalletCount(1);
plan.setVersion(3);
InboundPlanLine line = new InboundPlanLine();
line.setId(21L);
line.setCustomerId("100");
line.setPlanId(20L);
line.setRequiredPackageCount(1);
line.setPlannedPalletCount(1);
line.setDestinationWarehouseId("OLD-WH");
line.setDestinationWarehouseCode("OLD-CODE");
line.setDestinationWarehouseName("Old warehouse");
InboundPlanPallet pallet = new InboundPlanPallet();
pallet.setId(22L);
pallet.setCustomerId("100");
pallet.setPlanId(20L);
pallet.setSequenceNo(1);
pallet.setActualPackageCount(0);
pallet.setDestinationWarehouseId("OLD-WH");
pallet.setDestinationWarehouseCode("OLD-CODE");
pallet.setDestinationWarehouseName("Old warehouse");
when(planMapper.selectOne(any())).thenReturn(plan);
when(lineMapper.selectList(any())).thenReturn(List.of(line), List.of(line));
when(palletMapper.selectList(any())).thenReturn(List.of(pallet), List.of(pallet));
when(allocationMapper.selectList(any())).thenReturn(List.of());
service.update("100", "IP-20",
new UpdateInboundPlanRequest("100", 193000000000200003L,
" US-LAX-01 ", " Los Angeles Warehouse ", 3));
ArgumentCaptor<InboundPlanLine> updatedLine = ArgumentCaptor.forClass(InboundPlanLine.class);
verify(lineMapper).updateById(updatedLine.capture());
assertEquals("193000000000200003", updatedLine.getValue().getDestinationWarehouseId());
assertEquals("US-LAX-01", updatedLine.getValue().getDestinationWarehouseCode());
assertEquals("Los Angeles Warehouse", updatedLine.getValue().getDestinationWarehouseName());
ArgumentCaptor<InboundPlanPallet> updatedPallet = ArgumentCaptor.forClass(InboundPlanPallet.class);
verify(palletMapper).updateById(updatedPallet.capture());
assertEquals("193000000000200003", updatedPallet.getValue().getDestinationWarehouseId());
assertEquals("US-LAX-01", updatedPallet.getValue().getDestinationWarehouseCode());
assertEquals("Los Angeles Warehouse", updatedPallet.getValue().getDestinationWarehouseName());
}
@Test
@@ -49,6 +49,16 @@ class PalletAllocatorTest {
.map(PalletAllocator.AllocationDraft::plannedPackageCount).toList());
}
@Test
void keepsAtLeastTheFirstLegRecommendedPalletCount() {
PalletAllocator.Result result = PalletAllocator.allocate(List.of(
new PalletAllocator.LineInput(1L, "WH-A", new BigDecimal("1.5000"), 6, 3)));
assertEquals(3, result.pallets().size());
assertEquals(6, result.allocations().stream()
.mapToInt(PalletAllocator.AllocationDraft::plannedPackageCount).sum());
}
private PalletAllocator.Result allocate(String volume) {
return PalletAllocator.allocate(List.of(
new PalletAllocator.LineInput(1L, "WH-A", new BigDecimal(volume),