from candidate_forms.plugins import to_percent def _sections_as_percent(sections): if not sections: return list(sections) if sections else None out = [] for section in sections: item = dict(section) if "average" in item: item["average"] = to_percent(item.get("average")) criteria = item.get("criteria") if criteria: item["criteria"] = [ {**c, "rating": to_percent(c.get("rating"))} if isinstance(c, dict) else c for c in criteria ] out.append(item) return out def serialize_form( row, *, candidate_name=None, job_title=None, interviewer_name=None, created_by_name=None, ) -> dict: """`candidate_name` / `job_title` / user names come from one batched lookup in views — never a lazy per-row load.""" return { "id": str(row.id) if row.id else None, "inbox_id": row.inbox_id, "manual_upload_candidate_id": ( str(row.manual_upload_candidate_id) if row.manual_upload_candidate_id else None ), "job_post_id": str(row.job_post_id) if row.job_post_id else None, "candidate_name": candidate_name, "job_title": job_title, "form_type": row.form_type, "interviewer_id": str(row.interviewer_id) if row.interviewer_id else None, "interviewer_name": interviewer_name, "form_date": row.form_date.isoformat() if row.form_date else None, "sections": _sections_as_percent(row.sections), "fields": dict(row.fields) if row.fields else {}, "overall_score": to_percent(row.overall_score), "recommendation": row.recommendation, "created_by": str(row.created_by) if row.created_by else None, "created_by_name": created_by_name, "created_at": row.created_at.isoformat() if row.created_at else None, "updated_at": row.updated_at.isoformat() if row.updated_at else None, } def _date(value): return value.isoformat() if value else None def _enum(value): if value is None: return None return getattr(value, "value", value) def serialize_requisition_option(row) -> dict: """Compact row for a searchable picker: `{job title} - {department}`.""" title = (row.position_title or "").strip() department = (row.department or "").strip() return { "id": str(row.id) if row.id else None, "title": row.position_title, "department": row.department, "department_id": str(row.department_id) if row.department_id else None, "label": f"{title or 'Untitled'} - {department or '—'}", } def serialize_requisition(row) -> dict: return { "id": str(row.id) if row.id else None, "position": { "department": row.department, "department_id": str(row.department_id) if row.department_id else None, "title": row.position_title, "date": _date(row.date), "date_needed": _date(row.date_needed), "type": _enum(row.employment_type), "job_description": row.job_description, "period_from": _date(row.period_from), "period_to": _date(row.period_to), "jd_available": row.jd_available, }, "replacement_for": { "to_replace": row.to_replace, "grade": row.grade, "title": row.recruitment_title, "date_separated": _date(row.date_separated), "justification": row.justification, "budget": row.budget, "recommended_grade": row.recommended_grade, }, "refferal_by": { "employee_name": row.employee_name, "employee_department": row.employee_department, "entity": row.entity, }, "initiated_by": row.initiated_by, "initiated_date": _date(row.initiated_date), "recommended_by": row.recommended_by, "recommended_date": _date(row.recommended_date), "approved_by_hr": row.approved_by_hr, "approved_by_date_hr": _date(row.approved_by_date_hr), "approved_by_vp": row.approved_by_vp, "approved_by_date_vp": _date(row.approved_by_date_vp), "approved_by_svp": row.approved_by_svp, "approved_by_date_svp": _date(row.approved_by_date_svp), "created_by": str(row.created_by) if row.created_by else None, "created_at": row.created_at.isoformat() if row.created_at else None, "updated_at": row.updated_at.isoformat() if row.updated_at else None, }