diff --git a/extensions/sync_ehr_to_ad/README.md b/extensions/sync_ehr_to_ad/README.md index f9c60a4..1c7451f 100644 --- a/extensions/sync_ehr_to_ad/README.md +++ b/extensions/sync_ehr_to_ad/README.md @@ -15,6 +15,9 @@ - 默认写入后立即回读校验;如果 LDAP 返回成功但字段未落地,Job 会报失败并记录未生效字段。 - EHR 目标值为空时不会清空 AD 字段。 - 如果配置了 `target_sam_accounts`,只对列表中的 AD 账号执行同步。 +- `displayName` 取 `employeeInfo.customProperties.extDDNIC_606508_303466862`。 +- `department` 写入“EHR 部门编码 + EHR 部门名称”,例如 `V000076 IT`。 +- `streetAddress` 默认取 `translateProperties.extgzddxx1_606508_892394263Text`。 ## public_cfg 示例 @@ -65,7 +68,7 @@ - `ldap_verify_tls`: 是否校验证书,默认 `true`。 - `proxy_alias_domain`: 生成 `smtp:@domain` 别名时使用的域名。 - `department_code_ad_attribute`: 部门编码写入的 AD 属性,默认 `departmentNumber`。 -- `street_address_key`: 具体地址字段编码,默认 `WorkSpacevalue`,写入 AD 的 `streetAddress`;取不到时会兜底尝试 `extgzddxx_606508_618643707`。 +- `street_address_key`: 具体地址字段编码,默认 `extgzddxx1_606508_892394263Text`,写入 AD 的 `streetAddress`;取不到时会兜底尝试 `WorkSpacevalue` 和 `extgzddxx_606508_618643707`。 - `default_company`: 固定公司名;不传时尝试取 EHR 根组织名称。 - `location_mappings`: 工作地点到 AD 国家、省、市字段的映射。 diff --git a/extensions/sync_ehr_to_ad/job.py b/extensions/sync_ehr_to_ad/job.py index b51d709..66fbba2 100644 --- a/extensions/sync_ehr_to_ad/job.py +++ b/extensions/sync_ehr_to_ad/job.py @@ -13,8 +13,9 @@ logger = logging.getLogger("connecthub.extensions.sync_ehr_to_ad") _EHR_AD_ACCOUNT_KEY = "extADAccountName_606508_511687157" _EHR_WORK_LOCATION_TEXT_KEY = "extgzddxx1_606508_892394263Text" -_EHR_STREET_ADDRESS_KEY = "WorkSpacevalue" -_EHR_STREET_ADDRESS_FALLBACK_KEYS = ("extgzddxx_606508_618643707",) +_EHR_STREET_ADDRESS_KEY = _EHR_WORK_LOCATION_TEXT_KEY +_EHR_STREET_ADDRESS_FALLBACK_KEYS = ("WorkSpacevalue", "extgzddxx_606508_618643707") +_EHR_DISPLAY_NAME_KEY = "extDDNIC_606508_303466862" def _to_bool_or_none(v: Any) -> bool | None: @@ -166,6 +167,14 @@ def _display_name(given_name: str, sn: str, name: str) -> str: return english or raw_name +def _department_value(code: str, name: str) -> str: + clean_code = str(code or "").strip() + clean_name = str(name or "").strip() + if clean_code and clean_name: + return f"{clean_code} {clean_name}" + return clean_code or clean_name + + def _proxy_addresses(email: str, sam: str, alias_domain: str | None) -> list[str]: clean_email = str(email or "").strip() clean_sam = str(sam or "").strip() @@ -546,8 +555,12 @@ class SyncEhrToAdUserJob(BaseJob): surname = _field_value(item, "PhoneticOfXing") name = str(emp.get("name") or emp.get("Name") or "").strip() title = _field_translate_or_value(item, "OIdJobPost") or _job_post_name(job_post) - department = _field_translate_or_value(item, "OIdDepartment") or _org_name(org) department_code = _org_code(org) + department_name = _field_translate_or_value(item, "OIdDepartment") or _org_name(org) + department = _department_value(department_code, department_name) + display_name = _custom_prop_value(emp.get("customProperties"), _EHR_DISPLAY_NAME_KEY) or _display_name( + given_name, surname, name + ) employee_status = _field_translate_or_value(item, "EmployeeStatus") email = _field_value(item, "Email") or _field_value(item, "email") job_number = str(rec.get("jobNumber") or rec.get("JobNumber") or "").strip() @@ -595,7 +608,7 @@ class SyncEhrToAdUserJob(BaseJob): "c": location_attrs.get("c"), "countryCode": location_attrs.get("countryCode"), "company": company, - "displayName": _display_name(given_name, surname, name), + "displayName": display_name, "mail": email, "employeeID": job_number, "employeeType": employee_status,