fix(aihr): adapt updated organization snapshot

This commit is contained in:
2026-07-16 14:27:00 +08:00
parent f2f13987b7
commit 1fe91cc0f3
2 changed files with 49 additions and 4 deletions
@@ -375,7 +375,7 @@ public class AihrOrgSyncService {
project_code = values(project_code),
project_name = values(project_name),
dept_name = values(dept_name),
person_phone = values(person_phone),
person_phone = coalesce(nullif(values(person_phone), ''), person_phone),
person_name = values(person_name),
position_name = values(position_name),
position_level = values(position_level),
@@ -389,7 +389,7 @@ public class AihrOrgSyncService {
private OrgRow orgRow(JsonNode employee, Map<String, CompanyInfo> companies, Map<String, DepartmentInfo> departments,
Map<String, PositionMapping> positionMappings) {
String extPartyId = firstNonBlank(text(employee, "employee_number", "employeeNo", "employee_id", "employeeId", "id", "user_id"));
String extPartyId = firstNonBlank(text(employee, "id", "employee_id", "employeeId", "employee_number", "employeeNo", "user_id"));
if (extPartyId.isBlank()) {
return null;
}
@@ -617,10 +617,13 @@ public class AihrOrgSyncService {
private static String positionLevel(String rawLevel, String positionName) {
String inferred = level(positionName);
String level = clean(rawLevel);
if (level.isBlank() || (("一线".equals(level) || "员工".equals(level)) && !"一线".equals(inferred))) {
if (!POSITION_LEVELS.contains(level) && !"员工".equals(level)) {
return inferred;
}
return level;
if (("一线".equals(level) || "员工".equals(level)) && !"一线".equals(inferred)) {
return inferred;
}
return "员工".equals(level) ? "一线" : level;
}
private Map<String, PositionMapping> positionMappings() {
@@ -16,13 +16,19 @@ import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.argThat;
@Tag("dev")
public class AihrOrgSyncServiceTest {
@@ -135,6 +141,42 @@ public class AihrOrgSyncServiceTest {
assertEquals("一线", ReflectionTestUtils.getField(noImplicitPromotion, "positionLevel"));
}
@Test
public void updatedEmployeeSchemaKeepsResourceIdAndInfersNumericPositionLevel() throws Exception {
ObjectMapper mapper = new ObjectMapper();
AihrOrgSyncService service = new AihrOrgSyncService(mapper, mock(JdbcTemplate.class), mock(TransactionTemplate.class));
Object row = ReflectionTestUtils.invokeMethod(service, "orgRow",
mapper.readTree("{\"id\":\"employee-1\",\"employee_number\":\"NO-1001\","
+ "\"position_name\":\"客服主管\",\"position_level\":3}"),
Map.of(), Map.of(), Map.of());
assertEquals("employee-1", ReflectionTestUtils.getField(row, "extPartyId"));
assertEquals("主管", ReflectionTestUtils.getField(row, "positionLevel"));
}
@Test
public void incrementalSyncDoesNotEraseExistingPhoneWhenUpstreamPhoneIsMasked() throws Exception {
ObjectMapper mapper = new ObjectMapper();
JdbcTemplate jdbcTemplate = mock(JdbcTemplate.class);
TransactionTemplate transactionTemplate = mock(TransactionTemplate.class);
doAnswer(invocation -> {
@SuppressWarnings("unchecked")
Consumer<Object> callback = invocation.getArgument(0);
callback.accept(mock(org.springframework.transaction.TransactionStatus.class));
return null;
}).when(transactionTemplate).executeWithoutResult(any());
AihrOrgSyncService service = new AihrOrgSyncService(mapper, jdbcTemplate, transactionTemplate);
Object row = ReflectionTestUtils.invokeMethod(service, "orgRow",
mapper.readTree("{\"id\":\"employee-1\",\"phone\":\"139****1111\"}"),
Map.of(), Map.of(), Map.of());
ReflectionTestUtils.invokeMethod(service, "saveRows", List.of(row), false);
verify(jdbcTemplate).batchUpdate(argThat(sql ->
sql.contains("person_phone = coalesce(nullif(values(person_phone), ''), person_phone)")), anyList());
}
@Test
public void positionMapRejectsPrivilegeLevelsOutsideTheContract() {
AihrOrgSyncService service = new AihrOrgSyncService(new ObjectMapper(), mock(JdbcTemplate.class), mock(TransactionTemplate.class));