feat(appointments): add four-type calendar sources and align release contracts
This commit is contained in:
+39
@@ -0,0 +1,39 @@
|
||||
package com.baiyue.lastleg.calendar;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
|
||||
import org.apache.ibatis.mapping.Environment;
|
||||
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
|
||||
import org.h2.jdbcx.JdbcDataSource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class WarehouseCalendarMapperTest {
|
||||
/** 同柜跨客户不重复,人工改期与已建计划日期分别保留。 */
|
||||
@Test void deduplicatesCustomersPreservesManualAndFrozenDatesAndFindsCrossMonthRescheduling() throws Exception {
|
||||
var ds = new JdbcDataSource(); ds.setURL("jdbc:h2:mem:warehouse-calendar;MODE=MySQL;DB_CLOSE_DELAY=-1");
|
||||
try (var connection=ds.getConnection(); var sql=connection.createStatement()) {
|
||||
sql.execute("CREATE TABLE ll_order(id BIGINT,customer_id VARCHAR,source_container_booking_id VARCHAR,container_no VARCHAR," +
|
||||
"overseas_warehouse_id VARCHAR,overseas_warehouse_name VARCHAR,overseas_warehouse_code VARCHAR," +
|
||||
"estimated_warehouse_at TIMESTAMP,arrival_time_version INT)");
|
||||
sql.execute("CREATE TABLE ll_inbound_plan(source_order_id BIGINT,customer_id VARCHAR)");
|
||||
sql.execute("CREATE TABLE ll_receiving_container_session(source_container_booking_id VARCHAR,receiving_at TIMESTAMP)");
|
||||
sql.execute("INSERT INTO ll_order VALUES(1,'A','1','CONT1','W','Warehouse','W','2026-10-01 09:00:00',0)," +
|
||||
"(2,'B','1','CONT1','W','Warehouse','W','2026-10-01 09:00:00',0)," +
|
||||
"(3,'A','2','CONT2','W','Warehouse','W','2026-11-10 09:00:00',2)," +
|
||||
"(4,'A','3','CONT3','W','Warehouse','W','2026-11-12 09:00:00',0)");
|
||||
sql.execute("INSERT INTO ll_inbound_plan VALUES(4,'A')");
|
||||
}
|
||||
var config=new MybatisConfiguration(); config.setEnvironment(new Environment("test",new JdbcTransactionFactory(),ds));
|
||||
config.addMapper(WarehouseCalendarMapper.class);
|
||||
try(var session=new MybatisSqlSessionFactoryBuilder().build(config).openSession()) {
|
||||
var rows=session.getMapper(WarehouseCalendarMapper.class).calendar(LocalDateTime.parse("2026-11-01T00:00:00"),LocalDateTime.parse("2026-12-01T00:00:00"),List.of("1"));
|
||||
assertEquals(3,rows.size());
|
||||
assertEquals("1",rows.get(0).sourceContainerBookingId()); assertNull(rows.get(0).plannedAt());
|
||||
assertEquals(2,rows.get(1).version()); assertEquals("2026-11-10T09:00",rows.get(1).plannedAt().toString());
|
||||
assertEquals(1,rows.get(2).planCount()); assertNotNull(rows.get(2).plannedAt());
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.baiyue.lastleg.calendar;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class WarehouseCalendarServiceTest {
|
||||
/** 读取资格不代替写权限,已有入库计划仍冻结时间。 */
|
||||
@Test void keepsReadAccessSeparateFromWriteAndFreezesExistingPlans() {
|
||||
var repository=mock(WarehouseCalendarRepository.class); var service=new WarehouseCalendarService(repository);
|
||||
var query=new WarehouseCalendarModels.Query(LocalDate.of(2026,11,1),LocalDate.of(2026,12,1),List.of("1"));
|
||||
var open=new WarehouseCalendarModels.Entry("1","CONT","Warehouse","W",null,null,0,0,false);
|
||||
var frozen=new WarehouseCalendarModels.Entry("2","CONT2","Warehouse","W",null,null,1,1,false);
|
||||
when(repository.calendar(query)).thenReturn(List.of(open,frozen));
|
||||
assertTrue(service.calendar(query,true).get(0).canEdit()); assertFalse(service.calendar(query,true).get(1).canEdit());
|
||||
assertTrue(service.calendar(query,false).stream().noneMatch(WarehouseCalendarModels.Entry::canEdit));
|
||||
assertThrows(ResponseStatusException.class,()->service.calendar(new WarehouseCalendarModels.Query(query.from(),query.to(),List.of("1","1")),true));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -46,7 +46,7 @@ class FleetTripApiContractTest {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
assertThat(count).isEqualTo(53);
|
||||
assertThat(count).isEqualTo(54);
|
||||
verifyRefs(document, document);
|
||||
verifyRefs(preparation, preparation);
|
||||
verifyRefs(pool, pool);
|
||||
|
||||
+2
@@ -87,6 +87,8 @@ class FleetTripAuthorizationTest {
|
||||
}
|
||||
@Configuration @EnableMethodSecurity
|
||||
static class Config {
|
||||
/** 既有取货能力依赖原仓储引用;权限测试使用只读替身,不连接数据库。 */
|
||||
@Bean com.baiyue.lastleg.fleet.pickup.FleetPickupRepository pickups() { return mock(com.baiyue.lastleg.fleet.pickup.FleetPickupRepository.class); }
|
||||
@Bean com.baiyue.lastleg.fleet.trip.work.AppointmentWorkTripChanges workTripChanges() { return mock(com.baiyue.lastleg.fleet.trip.work.AppointmentWorkTripChanges.class); }
|
||||
@Bean com.baiyue.lastleg.appointmentwork.AppointmentWorkDispatchPort workDispatches() { return mock(com.baiyue.lastleg.appointmentwork.AppointmentWorkDispatchPort.class); }
|
||||
@Bean FleetTripCalendarService calendar() { return mock(FleetTripCalendarService.class); }
|
||||
|
||||
Reference in New Issue
Block a user