优化
This commit is contained in:
+8
-10
@@ -20,7 +20,7 @@ import static org.mockito.Mockito.*;
|
||||
import static com.baiyue.lastleg.inboundplan.receiving.FbaReceivingContracts.*;
|
||||
|
||||
class AppointmentWorkPreArrangementPersistenceTest {
|
||||
@Test void siblingPlanChangeCannotGrantOrRemovePhysicalPreArrangementAndNeverAuthorizesDeparture() {
|
||||
@Test void siblingPlanChangeNeverAuthorizesUnconfirmedFbaCargoToEnterDispatch() {
|
||||
try(var context=new AnnotationConfigApplicationContext(FbaAppointmentPersistenceTest.Config.class)) {
|
||||
var sources=context.getBean(AppointmentSourceService.class);
|
||||
var cargo=List.of(source("B",1,60),source("D",2,40));
|
||||
@@ -40,17 +40,17 @@ class AppointmentWorkPreArrangementPersistenceTest {
|
||||
doReturn(List.of(new AppointmentWorkDispatchMapper.Physical(2L,"D","FBA:ONT8",40,40))).when(mapper).physical(102L,"D");
|
||||
var jdbc=new JdbcTemplate(context.getBean(DataSource.class));jdbc.update("INSERT INTO ll_dispatch_order(id,dispatch_no,record_version,status) VALUES(20,'DP-B',0,'ACTIVE')");
|
||||
jdbc.update("INSERT INTO ll_dispatch_item(id,customer_id,dispatch_order_id,plan_pallet_id,source_stage,package_count) VALUES(201,'B',20,101,'RECEIVED',60)");
|
||||
var candidates=new AppointmentWorkDispatchCandidates(mapper,batches,sources);
|
||||
var candidates=new AppointmentWorkDispatchCandidates(mapper,batches,sources,new AppointmentDispatchAvailability(store));
|
||||
var binding=new AppointmentWorkDispatchBinding(mapper,batches,sources,mock(AppointmentWorkChanges.class),store,candidates);
|
||||
var tx=new TransactionTemplate(context.getBean(PlatformTransactionManager.class));
|
||||
var before=candidates.read(batch.batchKey()).candidates().stream().filter(c->c.customerId().equals("B")).findFirst().orElseThrow();
|
||||
assertTrue(before.blockReasons().isEmpty());assertEquals(60,before.packageCount());
|
||||
assertBindable(tx,binding,mapper,before);
|
||||
assertFalse(before.blockReasons().isEmpty());assertEquals(60,before.packageCount());
|
||||
assertNotBindable(tx,binding,mapper,before);
|
||||
batch=receiving.plan("operator",new Plan("pending-d",new Selection(batch.batchKey(),batch.version(),"D"),plan("PENDING"),"transport-v1")).batches().get(0);
|
||||
assertEquals("PENDING",batch.appointmentStatus());assertEquals(originalB,store.plan(batch.batchKey(),"B"));
|
||||
var after=candidates.read(batch.batchKey()).candidates().stream().filter(c->c.customerId().equals("B")).findFirst().orElseThrow();
|
||||
assertEquals(before.packageCount(),after.packageCount());assertEquals(before.blockReasons(),after.blockReasons());
|
||||
assertNotEquals(before.allocations().get(0).recordVersion(),after.allocations().get(0).recordVersion());assertBindable(tx,binding,mapper,after);
|
||||
assertNotEquals(before.allocations().get(0).recordVersion(),after.allocations().get(0).recordVersion());assertNotBindable(tx,binding,mapper,after);
|
||||
var bound=new AppointmentWorkDispatchMapper.Bound(20L,201L,101L,batch.batchKey(),"B","ORDER:1","FBA:ONT8",60);
|
||||
doReturn(List.of(bound)).when(mapper).bindings("DP-B");
|
||||
assertTrue(assertThrows(ResponseStatusException.class,()->binding.requireDeparture("DP-B")).getReason().contains("尚无有效收货确认"));
|
||||
@@ -65,13 +65,11 @@ class AppointmentWorkPreArrangementPersistenceTest {
|
||||
assertTrue(mapper.byDispatch(20).isEmpty());
|
||||
}
|
||||
}
|
||||
private static void assertBindable(TransactionTemplate tx,AppointmentWorkDispatchBinding binding,AppointmentWorkDispatchMapper mapper,AppointmentWorkDispatchCandidates.Candidate candidate) {
|
||||
tx.executeWithoutResult(status->{
|
||||
private static void assertNotBindable(TransactionTemplate tx,AppointmentWorkDispatchBinding binding,AppointmentWorkDispatchMapper mapper,AppointmentWorkDispatchCandidates.Candidate candidate) {
|
||||
assertThrows(ResponseStatusException.class,()->tx.executeWithoutResult(status->{
|
||||
binding.lockBatches(Map.of(candidate.allocations().get(0).batchKey(),candidate.allocations().get(0).recordVersion()));
|
||||
binding.bindItems(20,List.of(new AppointmentWorkDispatchPort.PhysicalItem(201L,"B",101L,"RECEIVED",60)),candidate.allocations());
|
||||
assertEquals(60,mapper.byDispatch(20).stream().mapToInt(AppointmentWorkDispatchMapper.Bound::packages).sum());
|
||||
status.setRollbackOnly(); // Compare identical physical availability before and after the independent customer's plan command.
|
||||
});
|
||||
}));
|
||||
assertTrue(mapper.byDispatch(20).isEmpty());
|
||||
}
|
||||
private static FbaAppointmentDetails plan(String status) {return new FbaAppointmentDetails(LocalDate.of(2026,10,25),null,null,null,null,null,status,"仓库暂无确认",null,null);}
|
||||
|
||||
+16
-2
@@ -51,6 +51,7 @@ class AppointmentWorkDispatchPersistenceTest {
|
||||
private AppointmentWorkDispatchCandidates candidates;
|
||||
private InboundFbaAppointmentService appointments;
|
||||
private AppointmentSourceService sources;
|
||||
private FbaReceivingStore receiving;
|
||||
private final String batch="FBA_APPOINTMENT:1";
|
||||
|
||||
/** 无客户主单,多个客户可在同车同批;真实计划逐票数量来自各自明细。 */
|
||||
@@ -78,8 +79,21 @@ class AppointmentWorkDispatchPersistenceTest {
|
||||
when(appointments.batchContext(batch)).thenAnswer(c->new FbaAppointmentBatchContext(snapshot(),List.of(),List.of(),List.of(),List.of(),List.of()));
|
||||
when(sources.canonicalOrders(anyList())).thenAnswer(c->{List<AppointmentExternalSourceGateway.OrderRef> orders=c.getArgument(0);return orders.stream().map(o->new AppointmentCoverageService.SourceRef(o.customerId(),o.orderId()==2?"BOOKING:real-2":"ORDER:"+o.orderId(),null)).toList();});
|
||||
doAnswer(c->{jdbc.update("UPDATE change_guard SET version=version+1 WHERE id=1");return null;}).when(changes).requirementsChanged();
|
||||
candidates=new AppointmentWorkDispatchCandidates(mapper,appointments,sources);
|
||||
var proxy=new ProxyFactory(new AppointmentWorkDispatchBinding(mapper,appointments,sources,changes,mock(FbaReceivingStore.class),candidates));proxy.setProxyTargetClass(true);proxy.addAdvice(new TransactionInterceptor(manager,new AnnotationTransactionAttributeSource()));binding=(AppointmentWorkDispatchPort)proxy.getProxy();
|
||||
receiving=mock(FbaReceivingStore.class);
|
||||
when(receiving.currentAgreement(eq(batch),anyString())).thenAnswer(call->confirmed(call.getArgument(1)));
|
||||
when(receiving.snapshots(anyList())).thenAnswer(call->List.of(new com.baiyue.lastleg.inboundplan.receiving.FbaReceivingContracts.BatchReceiving(batch,List.of(confirmed("101"),confirmed("202")),List.of(),List.of())));
|
||||
var availability=new AppointmentDispatchAvailability(receiving);
|
||||
candidates=new AppointmentWorkDispatchCandidates(mapper,appointments,sources,availability);
|
||||
var target=new AppointmentWorkDispatchBinding(mapper,appointments,sources,changes,receiving,candidates);
|
||||
org.springframework.test.util.ReflectionTestUtils.setField(target,"allocationReader",new AppointmentDispatchAllocationReader(new AppointmentDispatchAllocationRepository(mapper),sources,availability));
|
||||
var proxy=new ProxyFactory(target);proxy.setProxyTargetClass(true);proxy.addAdvice(new TransactionInterceptor(manager,new AnnotationTransactionAttributeSource()));binding=(AppointmentWorkDispatchPort)proxy.getProxy();
|
||||
}
|
||||
/** 成功场景明确提供本客户原来源的正式收货时间,不借其他客户确认通过。 */
|
||||
private com.baiyue.lastleg.inboundplan.receiving.FbaReceivingContracts.Agreement confirmed(String customer) {
|
||||
var details=new FbaAppointmentDetails(null,null,null,"CONF-"+customer,java.time.LocalDateTime.of(2026,10,26,10,0),null,"SUCCESS",null,null,null);
|
||||
var source=new com.baiyue.lastleg.inboundplan.receiving.FbaReceivingContracts.Source("101".equals(customer)?"ORDER:1":"BOOKING:real-2","FBA:ONT8","101".equals(customer)?80:160,"v1",1,"IN-"+customer);
|
||||
var member=new com.baiyue.lastleg.inboundplan.receiving.FbaReceivingContracts.Member(batch,"AP-1",0,customer,List.of(source),null);
|
||||
return new com.baiyue.lastleg.inboundplan.receiving.FbaReceivingContracts.Agreement("RA-"+customer,0,"ACTIVE","FBA:ONT8",details,"America/Los_Angeles",List.of(member),"仓库明确确认");
|
||||
}
|
||||
/** 插入真实客户、托盘和逐票数量,不从请求猜测。 */
|
||||
private void seed(long item,String customer,long order,int count,String destination) {
|
||||
|
||||
Reference in New Issue
Block a user