2026-08-21 17:21:26 +08:00
|
|
|
package com.baiyue.lastleg.dispatch;
|
|
|
|
|
|
|
|
|
|
import com.baiyue.lastleg.dispatch.mapper.DispatchCandidateMapper;
|
|
|
|
|
import org.apache.ibatis.annotations.Select;
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
|
|
|
|
|
|
class DispatchCandidateMapperContractTest {
|
|
|
|
|
private static final List<String> CONSTRUCTOR_ALIASES = List.of(
|
|
|
|
|
"planId", "planPalletId", "warehousePalletId", "orderId", "customerId", "customerName",
|
|
|
|
|
"planNo", "orderType", "volumeWeightKg", "containerNo", "appointmentAt", "expectedLoadingAt",
|
|
|
|
|
"overseasWarehouseId", "overseasWarehouseName", "orderNo", "orderRefs", "inboundCode", "palletNo",
|
|
|
|
|
"destinationWarehouseId", "destinationWarehouseCode", "destinationWarehouseName", "fbaWarehouseCode",
|
|
|
|
|
"packageCount", "volumeCbm", "sourceStage", "cartonMarks"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void candidateQueriesKeepRecordConstructorColumnOrder() throws Exception {
|
|
|
|
|
assertConstructorColumnOrder(DispatchCandidateMapper.class.getMethod("available",
|
2026-08-22 10:20:38 +08:00
|
|
|
String.class, List.class, String.class, String.class, String.class, String.class));
|
2026-08-21 17:21:26 +08:00
|
|
|
assertConstructorColumnOrder(DispatchCandidateMapper.class.getMethod("lockSelected",
|
|
|
|
|
String.class, List.class));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void selectedReceivedPalletMustStillHaveAvailableInventory() throws Exception {
|
|
|
|
|
Method method = DispatchCandidateMapper.class.getMethod("lockSelected", String.class, List.class);
|
|
|
|
|
String sql = String.join(" ", method.getAnnotation(Select.class).value());
|
|
|
|
|
|
|
|
|
|
assertTrue(sql.contains("p.warehouse_pallet_id IS NULL OR EXISTS"));
|
|
|
|
|
assertTrue(sql.contains("pos.available_packages > 0"));
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-07 15:07:34 +08:00
|
|
|
@Test
|
|
|
|
|
void candidateWarehouseComesFromPhysicalInventoryOrFrozenInboundPlan() throws Exception {
|
|
|
|
|
for (Method method : List.of(
|
|
|
|
|
DispatchCandidateMapper.class.getMethod("available", String.class, List.class, String.class,
|
|
|
|
|
String.class, String.class, String.class),
|
|
|
|
|
DispatchCandidateMapper.class.getMethod("lockSelected", String.class, List.class))) {
|
|
|
|
|
String sql = String.join(" ", method.getAnnotation(Select.class).value());
|
|
|
|
|
assertTrue(sql.contains("CASE WHEN p.warehouse_pallet_id IS NOT NULL"));
|
|
|
|
|
assertTrue(sql.contains("pos.overseas_warehouse_id"));
|
|
|
|
|
assertTrue(sql.contains("CAST(ip.overseas_warehouse_id AS CHAR)"));
|
|
|
|
|
assertTrue(sql.contains("ll_inventory_balance"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-21 17:21:26 +08:00
|
|
|
private void assertConstructorColumnOrder(Method method) {
|
|
|
|
|
String sql = String.join(" ", method.getAnnotation(Select.class).value());
|
|
|
|
|
int previous = -1;
|
|
|
|
|
for (String alias : CONSTRUCTOR_ALIASES) {
|
|
|
|
|
int current = sql.indexOf(" AS " + alias, previous + 1);
|
|
|
|
|
assertTrue(current > previous,
|
|
|
|
|
() -> method.getName() + " must select alias " + alias + " in record constructor order");
|
|
|
|
|
previous = current;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|