update
This commit is contained in:
parent
96b3439c5b
commit
6c804b7b84
|
|
@ -80,6 +80,66 @@ def _to_int_safe(v: Any) -> int:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def _cell_value(cell: Any) -> str:
|
||||||
|
if isinstance(cell, dict):
|
||||||
|
v = cell.get("value")
|
||||||
|
if v is None or str(v).strip() == "":
|
||||||
|
v = cell.get("showValue")
|
||||||
|
return str(v 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 _extract_oa_row_id_and_fields(row: dict[str, Any]) -> tuple[int | None, dict[str, Any]]:
|
||||||
|
field_map: dict[str, Any] = {}
|
||||||
|
row_id: int | None = None
|
||||||
|
|
||||||
|
master = row.get("masterData")
|
||||||
|
if isinstance(master, dict):
|
||||||
|
for k, v in master.items():
|
||||||
|
if isinstance(k, str) and k.startswith("field"):
|
||||||
|
field_map[k] = v
|
||||||
|
for candidate in (row.get("id"), row.get("masterDataId"), master.get("id")):
|
||||||
|
if candidate is None:
|
||||||
|
continue
|
||||||
|
rid = _to_int_safe(candidate)
|
||||||
|
if rid > 0:
|
||||||
|
row_id = rid
|
||||||
|
break
|
||||||
|
|
||||||
|
master_table = row.get("masterTable")
|
||||||
|
if isinstance(master_table, dict):
|
||||||
|
record = master_table.get("record")
|
||||||
|
if isinstance(record, dict):
|
||||||
|
fields = record.get("fields")
|
||||||
|
if isinstance(fields, list):
|
||||||
|
for fld in fields:
|
||||||
|
if not isinstance(fld, dict):
|
||||||
|
continue
|
||||||
|
name = str(fld.get("name") or "").strip()
|
||||||
|
if name:
|
||||||
|
field_map[name] = fld
|
||||||
|
if row_id is None:
|
||||||
|
rid = _to_int_safe(record.get("id"))
|
||||||
|
if rid > 0:
|
||||||
|
row_id = rid
|
||||||
|
|
||||||
|
row_fields = row.get("fields")
|
||||||
|
if isinstance(row_fields, list):
|
||||||
|
for fld in row_fields:
|
||||||
|
if not isinstance(fld, dict):
|
||||||
|
continue
|
||||||
|
name = str(fld.get("name") or "").strip()
|
||||||
|
if name:
|
||||||
|
field_map[name] = fld
|
||||||
|
return row_id, field_map
|
||||||
|
|
||||||
|
|
||||||
def _normalize_decimal_1(v: Any) -> str:
|
def _normalize_decimal_1(v: Any) -> str:
|
||||||
return _decimal_to_str(_to_decimal(v))
|
return _decimal_to_str(_to_decimal(v))
|
||||||
|
|
||||||
|
|
@ -207,6 +267,9 @@ class SyncEhrLeavesToOaMonthJob(BaseJob):
|
||||||
field_leave_days = display_to_code[display_leave_days]
|
field_leave_days = display_to_code[display_leave_days]
|
||||||
field_name = display_to_code.get(display_name)
|
field_name = display_to_code.get(display_name)
|
||||||
master_table_name = _OA_SQLSERVER_TABLE
|
master_table_name = _OA_SQLSERVER_TABLE
|
||||||
|
rows = form.get("data") or []
|
||||||
|
if not isinstance(rows, list):
|
||||||
|
rows = []
|
||||||
|
|
||||||
vacations = ehr.get_vacations_in_date_range(
|
vacations = ehr.get_vacations_in_date_range(
|
||||||
start_date=month_start,
|
start_date=month_start,
|
||||||
|
|
@ -270,7 +333,32 @@ class SyncEhrLeavesToOaMonthJob(BaseJob):
|
||||||
if staff_name and key not in name_map:
|
if staff_name and key not in name_map:
|
||||||
name_map[key] = staff_name
|
name_map[key] = staff_name
|
||||||
|
|
||||||
existing_row_map = ehr.get_oa_rows_by_job_and_date(
|
existing_row_map_by_export: dict[tuple[str, str], dict[str, str]] = {}
|
||||||
|
for row in rows:
|
||||||
|
if not isinstance(row, dict):
|
||||||
|
continue
|
||||||
|
rid, field_map = _extract_oa_row_id_and_fields(row)
|
||||||
|
job_no = _cell_value(field_map.get(field_job_no))
|
||||||
|
leave_date = _cell_show_value(field_map.get(field_leave_date)) or _date_only(_cell_value(field_map.get(field_leave_date)))
|
||||||
|
if not job_no or not leave_date:
|
||||||
|
continue
|
||||||
|
leave_days_val = _cell_value(field_map.get(field_leave_days))
|
||||||
|
name_val = _cell_value(field_map.get(field_name)) if field_name else ""
|
||||||
|
existing_row_map_by_export[(job_no, leave_date)] = {
|
||||||
|
"id": str(rid or ""),
|
||||||
|
"job_no": job_no,
|
||||||
|
"leave_date": leave_date,
|
||||||
|
"leave_days": leave_days_val,
|
||||||
|
"name": name_val,
|
||||||
|
}
|
||||||
|
logger.info(
|
||||||
|
"OA export 现有记录索引完成:month=%s~%s indexed=%s",
|
||||||
|
month_start.isoformat(),
|
||||||
|
month_end.isoformat(),
|
||||||
|
len(existing_row_map_by_export),
|
||||||
|
)
|
||||||
|
|
||||||
|
existing_row_map_by_sql = ehr.get_oa_rows_by_job_and_date(
|
||||||
table_name=_OA_SQLSERVER_TABLE,
|
table_name=_OA_SQLSERVER_TABLE,
|
||||||
schema=_OA_SQLSERVER_SCHEMA,
|
schema=_OA_SQLSERVER_SCHEMA,
|
||||||
job_no_column=field_job_no,
|
job_no_column=field_job_no,
|
||||||
|
|
@ -280,6 +368,9 @@ class SyncEhrLeavesToOaMonthJob(BaseJob):
|
||||||
start_date=month_start,
|
start_date=month_start,
|
||||||
end_date=month_end,
|
end_date=month_end,
|
||||||
)
|
)
|
||||||
|
# 以 export 为主(日期 showValue 更稳定),SQL 兜底补齐
|
||||||
|
existing_row_map = dict(existing_row_map_by_sql)
|
||||||
|
existing_row_map.update(existing_row_map_by_export)
|
||||||
|
|
||||||
data_list: list[dict[str, Any]] = []
|
data_list: list[dict[str, Any]] = []
|
||||||
to_update = 0
|
to_update = 0
|
||||||
|
|
@ -382,13 +473,14 @@ class SyncEhrLeavesToOaMonthJob(BaseJob):
|
||||||
failed_data[str(k)] = str(v)
|
failed_data[str(k)] = str(v)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
"EHR 请假月度同步完成:month=%s~%s vacations=%s aggregated=%s to_update=%s to_insert=%s success=%s failed=%s",
|
"EHR 请假月度同步完成:month=%s~%s vacations=%s aggregated=%s to_update=%s to_insert=%s skipped_unchanged=%s success=%s failed=%s",
|
||||||
month_start.isoformat(),
|
month_start.isoformat(),
|
||||||
month_end.isoformat(),
|
month_end.isoformat(),
|
||||||
len(vacations),
|
len(vacations),
|
||||||
len(agg),
|
len(agg),
|
||||||
to_update,
|
to_update,
|
||||||
to_insert,
|
to_insert,
|
||||||
|
skipped_unchanged,
|
||||||
success_count,
|
success_count,
|
||||||
failed_count,
|
failed_count,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue