feat: complete overseas pda warehouse operations
This commit is contained in:
+1
-1
@@ -29,7 +29,7 @@ class SchemaChineseCommentContractTest {
|
||||
Path.of("..", "scripts", "db", "incremental.sql"), StandardCharsets.UTF_8);
|
||||
|
||||
List<TableDefinition> tables = parseAndAssert(baseline, "仓储基线 SQL");
|
||||
assertEquals(7, tables.size(), "仓储表数量变化时必须同步表索引和备注迁移");
|
||||
assertEquals(8, tables.size(), "仓储表数量变化时必须同步表索引和备注迁移");
|
||||
parseAndAssert(incremental, "统一增量 SQL");
|
||||
|
||||
int marker = incremental.indexOf("2026-08-18 / 025 Chinese table and column comments");
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
package com.baiyue.warehouse.service;
|
||||
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.warehouse.dto.PalletTransitionRequests;
|
||||
import com.baiyue.warehouse.entity.WarehousePalletEntity;
|
||||
import com.baiyue.warehouse.entity.WarehousePalletOperationEntity;
|
||||
import com.baiyue.warehouse.mapper.WarehousePalletTransitionMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class WarehousePalletTransitionServiceTest {
|
||||
@Mock private WarehousePalletTransitionMapper mapper;
|
||||
private WarehousePalletTransitionService service;
|
||||
|
||||
@BeforeEach void setUp() {
|
||||
service = new WarehousePalletTransitionService();
|
||||
ReflectionTestUtils.setField(service, "mapper", mapper);
|
||||
}
|
||||
|
||||
@Test void appliesVersionedPublicPalletTransitionAndPersistsCompensationReceipt() {
|
||||
WarehousePalletEntity pallet = pallet("P-1", "IDLE", 4);
|
||||
when(mapper.lockPublicPallet(88L, 10L)).thenReturn(pallet);
|
||||
when(mapper.countActiveLocation(88L, 20L)).thenReturn(1L);
|
||||
when(mapper.transition(88L, 10L, "OCCUPIED", 20L, 4)).thenReturn(1);
|
||||
|
||||
var response = service.apply(10L, new PalletTransitionRequests.Apply(
|
||||
88L, 4, "OCCUPIED", 20L, "operation-1", "assemble"));
|
||||
|
||||
assertEquals("APPLIED", response.operationStatus());
|
||||
assertEquals(5, response.afterVersion());
|
||||
ArgumentCaptor<WarehousePalletOperationEntity> captor = ArgumentCaptor.forClass(WarehousePalletOperationEntity.class);
|
||||
verify(mapper).insert(captor.capture());
|
||||
assertEquals("IDLE", captor.getValue().getBeforeStatus());
|
||||
assertEquals("OCCUPIED", captor.getValue().getAfterStatus());
|
||||
assertEquals(4, captor.getValue().getBeforeVersion());
|
||||
}
|
||||
|
||||
@Test void exactReplayDoesNotMutatePhysicalPalletAgain() {
|
||||
WarehousePalletOperationEntity existing = operation();
|
||||
when(mapper.findOperation("operation-1")).thenReturn(existing);
|
||||
|
||||
var response = service.apply(10L, new PalletTransitionRequests.Apply(
|
||||
88L, 4, "OCCUPIED", 20L, "operation-1", "any changed reason"));
|
||||
|
||||
assertTrue(response.replayed());
|
||||
verify(mapper, never()).transition(anyLong(), anyLong(), anyString(), anyLong(), anyInt());
|
||||
}
|
||||
|
||||
@Test void compensationRequiresExactAppliedVersionAndRestoresBeforeState() {
|
||||
WarehousePalletOperationEntity existing = operation();
|
||||
when(mapper.lockOperation("operation-1")).thenReturn(existing);
|
||||
when(mapper.transition(88L, 10L, "IDLE", 11L, 5)).thenReturn(1);
|
||||
|
||||
var response = service.compensate(10L, "operation-1", new PalletTransitionRequests.Compensate(88L));
|
||||
|
||||
assertEquals("COMPENSATED", response.operationStatus());
|
||||
verify(mapper).updateById(existing);
|
||||
}
|
||||
|
||||
@Test void staleVersionIsRejectedWithoutPhysicalMutation() {
|
||||
when(mapper.lockPublicPallet(88L, 10L)).thenReturn(pallet("P-1", "IDLE", 5));
|
||||
assertThrows(BizException.class, () -> service.apply(10L, new PalletTransitionRequests.Apply(
|
||||
88L, 4, "OCCUPIED", 20L, "operation-1", null)));
|
||||
verify(mapper, never()).transition(anyLong(), anyLong(), anyString(), anyLong(), anyInt());
|
||||
}
|
||||
|
||||
private static WarehousePalletEntity pallet(String code, String status, int version) {
|
||||
WarehousePalletEntity value = new WarehousePalletEntity(); value.setId(10L); value.setCustomerId(0L);
|
||||
value.setWarehouseId(88L); value.setLocationId(11L); value.setPalletCode(code);
|
||||
value.setStatus(status); value.setVersion(version); return value;
|
||||
}
|
||||
private static WarehousePalletOperationEntity operation() {
|
||||
WarehousePalletOperationEntity value = new WarehousePalletOperationEntity(); value.setId(1L);
|
||||
value.setOperationKey("operation-1");
|
||||
value.setRequestHash("f17b4386e6fdecbaab1d066ae4fefa47dba0687ff27361b8f92ef097d4e8072e");
|
||||
value.setWarehouseId(88L); value.setPalletId(10L); value.setPalletCode("P-1");
|
||||
value.setBeforeStatus("IDLE"); value.setAfterStatus("OCCUPIED"); value.setBeforeLocationId(11L);
|
||||
value.setAfterLocationId(20L); value.setBeforeVersion(4); value.setAfterVersion(5);
|
||||
value.setOperationStatus("APPLIED"); return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user