update
This commit is contained in:
parent
92a3a1bed7
commit
c291a02a89
|
|
@ -1,6 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from urllib.parse import quote
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
@ -164,3 +165,32 @@ class SeeyonClient(BaseClient):
|
||||||
json=body,
|
json=body,
|
||||||
headers={"Content-Type": "application/json"},
|
headers={"Content-Type": "application/json"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_org_members_by_code(self, *, code: str, pageNo: int = 0, pageSize: int = 20) -> list[dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
按人员编码查询 OA 人员信息:
|
||||||
|
GET /seeyon/rest/orgMembers/code/{code}?pageNo={pageNo}&pageSize={pageSize}
|
||||||
|
"""
|
||||||
|
c = str(code or "").strip()
|
||||||
|
if not c:
|
||||||
|
raise ValueError("code is required")
|
||||||
|
if pageNo < 0:
|
||||||
|
pageNo = 0
|
||||||
|
if pageSize <= 0:
|
||||||
|
pageSize = 20
|
||||||
|
path = f"/seeyon/rest/orgMembers/code/{quote(c, safe='')}"
|
||||||
|
resp = self.request("GET", path, params={"pageNo": pageNo, "pageSize": pageSize})
|
||||||
|
payload = resp.json() if resp.content else {}
|
||||||
|
if isinstance(payload, list):
|
||||||
|
return [x for x in payload if isinstance(x, dict)]
|
||||||
|
if isinstance(payload, dict):
|
||||||
|
data = payload.get("data")
|
||||||
|
if isinstance(data, list):
|
||||||
|
return [x for x in data if isinstance(x, dict)]
|
||||||
|
if isinstance(data, dict):
|
||||||
|
items = data.get("content")
|
||||||
|
if isinstance(items, list):
|
||||||
|
return [x for x in items if isinstance(x, dict)]
|
||||||
|
return [data]
|
||||||
|
return [payload]
|
||||||
|
return []
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,12 @@ def _cell_value(cell: Any) -> str:
|
||||||
return str(cell or "").strip()
|
return str(cell or "").strip()
|
||||||
|
|
||||||
|
|
||||||
|
def _cell_show_value(cell: Any) -> str:
|
||||||
|
if isinstance(cell, dict):
|
||||||
|
return str(cell.get("showValue") or "").strip()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def _date_only(s: Any) -> str:
|
def _date_only(s: Any) -> str:
|
||||||
v = str(s or "").strip()
|
v = str(s or "").strip()
|
||||||
if not v:
|
if not v:
|
||||||
|
|
@ -148,6 +154,20 @@ def _extract_staff_code(staff_profile: dict[str, Any]) -> str:
|
||||||
).strip()
|
).strip()
|
||||||
|
|
||||||
|
|
||||||
|
def _pick_best_member_by_code(members: list[dict[str, Any]]) -> dict[str, Any] | None:
|
||||||
|
if not members:
|
||||||
|
return None
|
||||||
|
# 优先:可用且在职
|
||||||
|
for m in members:
|
||||||
|
if bool(m.get("isValid", True)) and int(m.get("state", 1) or 1) == 1:
|
||||||
|
return m
|
||||||
|
# 次优:enabled
|
||||||
|
for m in members:
|
||||||
|
if bool(m.get("enabled", True)):
|
||||||
|
return m
|
||||||
|
return members[0]
|
||||||
|
|
||||||
|
|
||||||
def _extract_oa_row_id_and_fields(row: dict[str, Any]) -> tuple[int | None, dict[str, Any]]:
|
def _extract_oa_row_id_and_fields(row: dict[str, Any]) -> tuple[int | None, dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
兼容不同 OA export 返回结构,提取:
|
兼容不同 OA export 返回结构,提取:
|
||||||
|
|
@ -391,12 +411,28 @@ class SyncEhrToOaFormJob(BaseJob):
|
||||||
code = _extract_staff_code(profile)
|
code = _extract_staff_code(profile)
|
||||||
if code:
|
if code:
|
||||||
user_id_to_staff_code[int(uid)] = code
|
user_id_to_staff_code[int(uid)] = code
|
||||||
|
# 3.4) 将 HRBP/汇报人工号转换为 OA 人员ID(member 字段要求)
|
||||||
|
need_member_codes = list({c for c in user_id_to_staff_code.values() if str(c or "").strip()})
|
||||||
|
code_to_member: dict[str, dict[str, str]] = {}
|
||||||
|
for code in need_member_codes:
|
||||||
|
try:
|
||||||
|
members = seeyon.get_org_members_by_code(code=code, pageNo=0, pageSize=20)
|
||||||
|
best = _pick_best_member_by_code(members)
|
||||||
|
if not best:
|
||||||
|
continue
|
||||||
|
member_id = str(best.get("id") or "").strip()
|
||||||
|
member_name = str(best.get("name") or best.get("loginName") or "").strip()
|
||||||
|
if member_id:
|
||||||
|
code_to_member[code] = {"id": member_id, "name": member_name}
|
||||||
|
except Exception as e: # noqa: BLE001
|
||||||
|
logger.warning("OA 人员查询失败:code=%s err=%r", code, e)
|
||||||
logger.info(
|
logger.info(
|
||||||
"人员工号反查完成:staff_profiles=%s reportings=%s hrbp_ids=%s resolved_staff_codes=%s",
|
"人员工号反查完成:staff_profiles=%s reportings=%s hrbp_ids=%s resolved_staff_codes=%s resolved_member_ids=%s",
|
||||||
len(staff_profile_by_user_id),
|
len(staff_profile_by_user_id),
|
||||||
len(reporting_user_ids),
|
len(reporting_user_ids),
|
||||||
len(hrbp_user_ids),
|
len(hrbp_user_ids),
|
||||||
len(user_id_to_staff_code),
|
len(user_id_to_staff_code),
|
||||||
|
len(code_to_member),
|
||||||
)
|
)
|
||||||
if verbose_trace:
|
if verbose_trace:
|
||||||
for job_no in list(ehr_by_job_no.keys()):
|
for job_no in list(ehr_by_job_no.keys()):
|
||||||
|
|
@ -427,13 +463,19 @@ class SyncEhrToOaFormJob(BaseJob):
|
||||||
leave_date = _date_only(rec.get("lastWorkDate"))
|
leave_date = _date_only(rec.get("lastWorkDate"))
|
||||||
id_number = str(emp.get("iDNumber") or "")
|
id_number = str(emp.get("iDNumber") or "")
|
||||||
hrbp_uid = _to_int_safe(rec.get(_EHR_HRBP_ID_KEY) or _custom_prop_value(rec.get("customProperties"), _EHR_HRBP_ID_KEY))
|
hrbp_uid = _to_int_safe(rec.get(_EHR_HRBP_ID_KEY) or _custom_prop_value(rec.get("customProperties"), _EHR_HRBP_ID_KEY))
|
||||||
hrbp = str(user_id_to_staff_code.get(hrbp_uid) or "")
|
hrbp_code = str(user_id_to_staff_code.get(hrbp_uid) or "")
|
||||||
|
hrbp_member = code_to_member.get(hrbp_code, {})
|
||||||
|
hrbp = str(hrbp_member.get("id") or "")
|
||||||
|
hrbp_show = str(hrbp_member.get("name") or hrbp_code)
|
||||||
manager_uid = _extract_reporting_user_id(staff_profile_by_user_id.get(user_id, {}))
|
manager_uid = _extract_reporting_user_id(staff_profile_by_user_id.get(user_id, {}))
|
||||||
manager = str(user_id_to_staff_code.get(manager_uid) or "")
|
manager_code = str(user_id_to_staff_code.get(manager_uid) or "")
|
||||||
|
manager_member = code_to_member.get(manager_code, {})
|
||||||
|
manager = str(manager_member.get("id") or "")
|
||||||
|
manager_show = str(manager_member.get("name") or manager_code)
|
||||||
is_leaving = "是" if _date_only(rec.get("lastWorkDate")) else "否"
|
is_leaving = "是" if _date_only(rec.get("lastWorkDate")) else "否"
|
||||||
domain_account = _custom_prop_value(emp.get("customProperties"), domain_custom_key) or str(emp.get("_Name") or "")
|
domain_account = _custom_prop_value(emp.get("customProperties"), domain_custom_key) or str(emp.get("_Name") or "")
|
||||||
logger.info(
|
logger.info(
|
||||||
"EHR 字段预览:job_no=%s company=%s name=%s rd_attr=%s place=%s entry_date=%s leave_date=%s id_number=%s hrbp=%s manager=%s is_leaving=%s domain_account=%s",
|
"EHR 字段预览:job_no=%s company=%s name=%s rd_attr=%s place=%s entry_date=%s leave_date=%s id_number=%s hrbp_id=%s hrbp_show=%s manager_id=%s manager_show=%s is_leaving=%s domain_account=%s",
|
||||||
job_no,
|
job_no,
|
||||||
company,
|
company,
|
||||||
name,
|
name,
|
||||||
|
|
@ -443,7 +485,9 @@ class SyncEhrToOaFormJob(BaseJob):
|
||||||
leave_date,
|
leave_date,
|
||||||
id_number,
|
id_number,
|
||||||
hrbp,
|
hrbp,
|
||||||
|
hrbp_show,
|
||||||
manager,
|
manager,
|
||||||
|
manager_show,
|
||||||
is_leaving,
|
is_leaving,
|
||||||
domain_account,
|
domain_account,
|
||||||
)
|
)
|
||||||
|
|
@ -652,9 +696,15 @@ class SyncEhrToOaFormJob(BaseJob):
|
||||||
leave_date = _date_only(rec.get("lastWorkDate"))
|
leave_date = _date_only(rec.get("lastWorkDate"))
|
||||||
id_number = str(emp.get("iDNumber") or "")
|
id_number = str(emp.get("iDNumber") or "")
|
||||||
hrbp_uid = _to_int_safe(rec.get(_EHR_HRBP_ID_KEY) or _custom_prop_value(rec.get("customProperties"), _EHR_HRBP_ID_KEY))
|
hrbp_uid = _to_int_safe(rec.get(_EHR_HRBP_ID_KEY) or _custom_prop_value(rec.get("customProperties"), _EHR_HRBP_ID_KEY))
|
||||||
hrbp = str(user_id_to_staff_code.get(hrbp_uid) or "")
|
hrbp_code = str(user_id_to_staff_code.get(hrbp_uid) or "")
|
||||||
|
hrbp_member = code_to_member.get(hrbp_code, {})
|
||||||
|
hrbp = str(hrbp_member.get("id") or "")
|
||||||
|
hrbp_show = str(hrbp_member.get("name") or hrbp_code)
|
||||||
manager_uid = _extract_reporting_user_id(staff_profile_by_user_id.get(user_id, {}))
|
manager_uid = _extract_reporting_user_id(staff_profile_by_user_id.get(user_id, {}))
|
||||||
manager = str(user_id_to_staff_code.get(manager_uid) or "")
|
manager_code = str(user_id_to_staff_code.get(manager_uid) or "")
|
||||||
|
manager_member = code_to_member.get(manager_code, {})
|
||||||
|
manager = str(manager_member.get("id") or "")
|
||||||
|
manager_show = str(manager_member.get("name") or manager_code)
|
||||||
is_leaving = "是" if _date_only(rec.get("lastWorkDate")) else "否"
|
is_leaving = "是" if _date_only(rec.get("lastWorkDate")) else "否"
|
||||||
domain_account = _custom_prop_value(emp.get("customProperties"), domain_custom_key) or str(emp.get("_Name") or "")
|
domain_account = _custom_prop_value(emp.get("customProperties"), domain_custom_key) or str(emp.get("_Name") or "")
|
||||||
|
|
||||||
|
|
@ -668,6 +718,8 @@ class SyncEhrToOaFormJob(BaseJob):
|
||||||
id_number = _prefer_non_empty(id_number, _cell_value(existing_field_map.get(display_to_code["身份证号"])))
|
id_number = _prefer_non_empty(id_number, _cell_value(existing_field_map.get(display_to_code["身份证号"])))
|
||||||
hrbp = _prefer_non_empty(hrbp, _cell_value(existing_field_map.get(display_to_code["HRBP"])))
|
hrbp = _prefer_non_empty(hrbp, _cell_value(existing_field_map.get(display_to_code["HRBP"])))
|
||||||
manager = _prefer_non_empty(manager, _cell_value(existing_field_map.get(display_to_code["汇报人"])))
|
manager = _prefer_non_empty(manager, _cell_value(existing_field_map.get(display_to_code["汇报人"])))
|
||||||
|
hrbp_show = _prefer_non_empty(hrbp_show, _cell_show_value(existing_field_map.get(display_to_code["HRBP"])))
|
||||||
|
manager_show = _prefer_non_empty(manager_show, _cell_show_value(existing_field_map.get(display_to_code["汇报人"])))
|
||||||
is_leaving = _prefer_non_empty(is_leaving, _cell_value(existing_field_map.get(display_to_code["在离职"])))
|
is_leaving = _prefer_non_empty(is_leaving, _cell_value(existing_field_map.get(display_to_code["在离职"])))
|
||||||
domain_account = _prefer_non_empty(domain_account, _cell_value(existing_field_map.get(display_to_code["域账号"])))
|
domain_account = _prefer_non_empty(domain_account, _cell_value(existing_field_map.get(display_to_code["域账号"])))
|
||||||
|
|
||||||
|
|
@ -679,8 +731,8 @@ class SyncEhrToOaFormJob(BaseJob):
|
||||||
{"name": display_to_code["入职日期"], "value": entry_date, "showValue": entry_date},
|
{"name": display_to_code["入职日期"], "value": entry_date, "showValue": entry_date},
|
||||||
{"name": display_to_code["离职日期"], "value": leave_date, "showValue": leave_date},
|
{"name": display_to_code["离职日期"], "value": leave_date, "showValue": leave_date},
|
||||||
{"name": display_to_code["身份证号"], "value": id_number, "showValue": id_number},
|
{"name": display_to_code["身份证号"], "value": id_number, "showValue": id_number},
|
||||||
{"name": display_to_code["HRBP"], "value": hrbp, "showValue": hrbp},
|
{"name": display_to_code["HRBP"], "value": hrbp, "showValue": hrbp_show},
|
||||||
{"name": display_to_code["汇报人"], "value": manager, "showValue": manager},
|
{"name": display_to_code["汇报人"], "value": manager, "showValue": manager_show},
|
||||||
{"name": display_to_code["在离职"], "value": is_leaving, "showValue": is_leaving},
|
{"name": display_to_code["在离职"], "value": is_leaving, "showValue": is_leaving},
|
||||||
{"name": display_to_code["域账号"], "value": domain_account, "showValue": domain_account},
|
{"name": display_to_code["域账号"], "value": domain_account, "showValue": domain_account},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue