修改提交

This commit is contained in:
2026-08-21 17:21:26 +08:00
parent af97217184
commit bbd303cd65
36 changed files with 1045 additions and 100 deletions
@@ -1,5 +1,7 @@
package com.baiyue.lastleg.dispatch.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baiyue.lastleg.dispatch.dto.DispatchRequests;
import com.baiyue.lastleg.dispatch.entity.DispatchItem;
import com.baiyue.lastleg.dispatch.entity.DispatchOrder;
@@ -69,6 +71,74 @@ class DispatchServiceTest {
verify(items).insert(any(DispatchItem.class));
}
@Test
void movingPalletIntoDraftImmediatelyCreatesExpiringExclusiveLock() {
when(candidates.lockSelected("100", List.of(10L))).thenReturn(List.of(candidate(10L, null, "ONT8")));
service.lockDraftPallet("100", "7", new DispatchRequests.DraftPallet(10L, "draft-1"));
ArgumentCaptor<DispatchPalletLock> lock = ArgumentCaptor.forClass(DispatchPalletLock.class);
verify(locks).insert(lock.capture());
assertEquals("draft-1", lock.getValue().getDraftToken());
assertEquals("7", lock.getValue().getOperatorId());
assertNotNull(lock.getValue().getExpiresAt());
assertEquals(null, lock.getValue().getDispatchOrderId());
verify(locks).clearInactiveActiveKey("100", "PLAN:10");
}
@Test
void movingVolumeOnlyPlanPalletIntoDraftCreatesLock() {
when(candidates.lockSelected("100", List.of(10L)))
.thenReturn(List.of(candidate(10L, null, "ONT8", 0)));
service.lockDraftPallet("100", "7", new DispatchRequests.DraftPallet(10L, "draft-1"));
verify(locks).insert(any(DispatchPalletLock.class));
}
@Test
void preArrangeAcceptsVolumeOnlyPlanPallet() {
when(candidates.lockSelected("100", List.of(10L)))
.thenReturn(List.of(candidate(10L, null, "ONT8", 0)));
service.preArrange("100", "7", new DispatchRequests.PreArrange(List.of(10L), null,
null, null, null));
ArgumentCaptor<DispatchOrder> dispatch = ArgumentCaptor.forClass(DispatchOrder.class);
verify(orders).insert(dispatch.capture());
assertEquals(0, dispatch.getValue().getPackageCount());
verify(items).insert(any(DispatchItem.class));
}
@Test
void removingPalletFromOwnedDraftImmediatelyReleasesLock() {
when(candidates.lockSelected("100", List.of(10L))).thenReturn(List.of(candidate(10L, null, "ONT8")));
DispatchPalletLock lock = new DispatchPalletLock();
lock.setDraftToken("draft-1"); lock.setOperatorId("7"); lock.setStatus("ACTIVE"); lock.setActiveKey("PLAN:10");
when(locks.lockActive("100", "PLAN:10")).thenReturn(lock);
service.unlockDraftPallet("100", "7", new DispatchRequests.DraftPallet(10L, "draft-1"));
assertEquals("RELEASED", lock.getStatus());
assertEquals(null, lock.getActiveKey());
verify(locks).updateById(lock);
}
@Test
void preArrangeConvertsOwnedDraftLockInsteadOfInsertingAnotherLock() {
when(candidates.lockSelected("100", List.of(10L))).thenReturn(List.of(candidate(10L, null, "ONT8")));
DispatchPalletLock lock = new DispatchPalletLock();
lock.setDraftToken("draft-1"); lock.setOperatorId("7"); lock.setStatus("ACTIVE"); lock.setActiveKey("PLAN:10");
when(locks.lockActive("100", "PLAN:10")).thenReturn(lock);
service.preArrange("100", "7", new DispatchRequests.PreArrange(List.of(10L), null, null, null, null, "draft-1"));
assertNotNull(lock.getDispatchOrderId());
assertEquals(null, lock.getDraftToken());
verify(locks).updateById(lock);
verify(locks, never()).insert(any(DispatchPalletLock.class));
}
@Test
void rejectsPalletAlreadyLockedByAnotherDispatch() {
when(candidates.lockSelected("100", List.of(10L))).thenReturn(List.of(candidate(10L, null, "ONT8")));
@@ -87,6 +157,15 @@ class DispatchServiceTest {
verify(candidates, never()).available(any(), any(), any(), any(), any());
}
@Test
void platformCandidatesQueryAcrossCustomersWithoutPlanScope() {
when(candidates.available(null, null, null, null, "RECEIVED")).thenReturn(List.of());
service.platformCandidates(null, null, "RECEIVED");
verify(candidates).available(null, null, null, null, "RECEIVED");
}
@Test
void resolvesCustomerFromSelectedPlansAndPalletsInMultiCustomerDeployment() {
when(candidates.findCustomerScopesByPlanIds(List.of(1L, 2L))).thenReturn(List.of("100"));
@@ -106,17 +185,6 @@ class DispatchServiceTest {
assertEquals(409, exception.getStatusCode().value());
}
@Test
void resolvesOnlyCustomerScopeAndRejectsMultipleCustomers() {
when(candidates.findCustomerScopes()).thenReturn(List.of("100"));
assertEquals("100", service.resolveSingleCustomerScope());
when(candidates.findCustomerScopes()).thenReturn(List.of("100", "200"));
ResponseStatusException exception = assertThrows(ResponseStatusException.class,
() -> service.resolveSingleCustomerScope());
assertEquals(409, exception.getStatusCode().value());
}
@Test
void emptyCustomerScopeProducesEmptyCandidatesAndRejectsPreArrange() {
assertEquals(List.of(), service.candidates(null, null, null, null, null));
@@ -159,9 +227,42 @@ class DispatchServiceTest {
verify(items).findByDispatchOrder("200", 1L);
}
@Test
void platformPageQueriesAllCustomersAndLoadsItemsInEachCustomerScope() {
DispatchOrder first = new DispatchOrder();
first.setId(1L); first.setCustomerId("100"); first.setDispatchNo("PC1");
DispatchOrder second = new DispatchOrder();
second.setId(2L); second.setCustomerId("200"); second.setDispatchNo("PC2");
Page<DispatchOrder> resultPage = new Page<>(1, 20, 2);
resultPage.setRecords(List.of(first, second));
when(orders.selectPage(any(Page.class), any(LambdaQueryWrapper.class))).thenReturn(resultPage);
var result = service.platformPage(new DispatchRequests.Query(1, 20, null, null, null, null));
assertEquals(2, result.total());
verify(items).findByDispatchOrder("100", 1L);
verify(items).findByDispatchOrder("200", 2L);
}
@Test
void platformDetailUsesCustomerFromMatchedDispatch() {
DispatchOrder dispatch = new DispatchOrder();
dispatch.setId(1L); dispatch.setCustomerId("200"); dispatch.setDispatchNo("PC1");
when(orders.findAcrossCustomersByDispatchNo("PC1")).thenReturn(List.of(dispatch));
service.platformDetail("PC1");
verify(items).findByDispatchOrder("200", 1L);
}
private DispatchPalletCandidate candidate(long planPalletId, Long warehousePalletId, String destination) {
return candidate(planPalletId, warehousePalletId, destination, 12);
}
private DispatchPalletCandidate candidate(long planPalletId, Long warehousePalletId, String destination,
int packageCount) {
return new DispatchPalletCandidate(1L, planPalletId, warehousePalletId, 2L, "WH-1", "Overseas warehouse", "LMO1", "LMO1", "RK1",
"LIP1-P001", destination, destination, destination, destination, 12,
"LIP1-P001", destination, destination, destination, destination, packageCount,
new BigDecimal("1.2000"), warehousePalletId == null ? "PLAN" : "RECEIVED");
}
}