feat(recruitment,separation): Job Offer + Employee Separation custom fields (TETRA-1352) #4

Merged
tant merged 1 commit from feat/TETRA-1352-job-offer-separation-custom-fields into develop 2026-04-22 11:39:59 +07:00
Owner

Tóm tắt

Fix TETRA-1352: 3 endpoint trong Tetra eOffice API trả HTTP 403 "Field not permitted in query" vì Frappe Job Offer / Employee Separation thiếu custom fields mà NestJS services query.

  • GET /api/v1/recruitment/offers
  • GET /api/v1/hrms/separations
  • GET /api/v1/hrms/separations/compliance-alerts

Thay đổi

Thêm định nghĩa custom fields vào vhrms/vhrms/setup/custom_fields.py — vhrms là owner của schema Frappe, Tetra chỉ là consumer.

  • Job Offer (+27 fields): job_opening Link (stock Frappe không có), offer lifecycle (custom_offer_status, custom_offer_number), lương / hợp đồng / department / report_to, approval workflow (Flowable process ID, approval comments, decline reason), PDF attach + URL, revision tracking (custom_revision_of, custom_revision_number).
  • Job Opening (+3 fields): custom_hiring_manager_email, custom_salary_band_max, custom_job_grade_level — đọc bởi offers.service.ts khi submit offer for approval.
  • Employee Separation (+15 fields): workflow huỷ quyết định nghỉ việc theo Điều 38 BLLĐ 2019 (custom_cancellation_reason, custom_other_party_consent, requested/approved/rejected_by/at + notes) và hoàn tất (custom_completed_by/at). Block 16 field hiện tại giữ nguyên.

Verify

Trước fix:

Job Offer: 0 custom fields
Employee Separation: 0 custom fields
GET /api/v1/recruitment/offers → 403 "Field not permitted in query: custom_offer_number"
GET /api/v1/hrms/separations → 403 "Field not permitted in query: custom_status"
GET /api/v1/hrms/separations/compliance-alerts → 403 "Field not permitted in query: custom_last_working_day"

Sau fix (bench --site hrms.localhost migrate + restart backend):

Job Offer: 27 custom fields
Employee Separation: 31 custom fields
Job Opening: 7 custom fields (+3 mới)
GET /api/v1/recruitment/offers → 200 OK (trả 8 offers có sẵn)
GET /api/v1/hrms/separations → 200 OK ([] vì chưa seed)
GET /api/v1/hrms/separations/compliance-alerts → 200 OK

Ngoài scope

Brief ticket liệt kê một số field nằm ngoài Job Offer / Employee Separation:

  • custom_gross_salary, custom_is_pregnant, custom_pregnancy_status → thuộc Employee DocType
  • custom_returned, custom_returned_date, custom_return_condition, custom_return_notes → thuộc Asset Assignment DocType
  • custom_skip_reason, custom_interviewer_id, custom_location, custom_notes, custom_nps_score, custom_suggestions → thuộc Exit Interview DocType

Những field này không gây 403 cho 3 endpoint của ticket, để lại cho TETRA-1354 (dọn dẹp Layer 2 fixtures toàn diện) hoặc ticket riêng.

Refs

  • Closes: TETRA-1352
  • Duplicate: TETRA-1332
  • Related: TETRA-1354 (Layer 2 cleanup broader)

🤖 Generated with Claude Code

## Tóm tắt Fix [TETRA-1352](https://tetravn.atlassian.net/browse/TETRA-1352): 3 endpoint trong Tetra eOffice API trả `HTTP 403 "Field not permitted in query"` vì Frappe `Job Offer` / `Employee Separation` thiếu custom fields mà NestJS services query. - `GET /api/v1/recruitment/offers` - `GET /api/v1/hrms/separations` - `GET /api/v1/hrms/separations/compliance-alerts` ## Thay đổi Thêm định nghĩa custom fields vào `vhrms/vhrms/setup/custom_fields.py` — vhrms là owner của schema Frappe, Tetra chỉ là consumer. - **Job Offer** (+27 fields): `job_opening` Link (stock Frappe không có), offer lifecycle (`custom_offer_status`, `custom_offer_number`), lương / hợp đồng / department / report_to, approval workflow (Flowable process ID, approval comments, decline reason), PDF attach + URL, revision tracking (`custom_revision_of`, `custom_revision_number`). - **Job Opening** (+3 fields): `custom_hiring_manager_email`, `custom_salary_band_max`, `custom_job_grade_level` — đọc bởi `offers.service.ts` khi submit offer for approval. - **Employee Separation** (+15 fields): workflow huỷ quyết định nghỉ việc theo Điều 38 BLLĐ 2019 (`custom_cancellation_reason`, `custom_other_party_consent`, requested/approved/rejected_by/at + notes) và hoàn tất (`custom_completed_by/at`). Block 16 field hiện tại giữ nguyên. ## Verify **Trước fix:** ``` Job Offer: 0 custom fields Employee Separation: 0 custom fields GET /api/v1/recruitment/offers → 403 "Field not permitted in query: custom_offer_number" GET /api/v1/hrms/separations → 403 "Field not permitted in query: custom_status" GET /api/v1/hrms/separations/compliance-alerts → 403 "Field not permitted in query: custom_last_working_day" ``` **Sau fix** (`bench --site hrms.localhost migrate` + restart backend): ``` Job Offer: 27 custom fields Employee Separation: 31 custom fields Job Opening: 7 custom fields (+3 mới) GET /api/v1/recruitment/offers → 200 OK (trả 8 offers có sẵn) GET /api/v1/hrms/separations → 200 OK ([] vì chưa seed) GET /api/v1/hrms/separations/compliance-alerts → 200 OK ``` ## Ngoài scope Brief ticket liệt kê một số field nằm ngoài Job Offer / Employee Separation: - `custom_gross_salary`, `custom_is_pregnant`, `custom_pregnancy_status` → thuộc **Employee** DocType - `custom_returned`, `custom_returned_date`, `custom_return_condition`, `custom_return_notes` → thuộc **Asset Assignment** DocType - `custom_skip_reason`, `custom_interviewer_id`, `custom_location`, `custom_notes`, `custom_nps_score`, `custom_suggestions` → thuộc **Exit Interview** DocType Những field này không gây 403 cho 3 endpoint của ticket, để lại cho TETRA-1354 (dọn dẹp Layer 2 fixtures toàn diện) hoặc ticket riêng. ## Refs - Closes: TETRA-1352 - Duplicate: TETRA-1332 - Related: TETRA-1354 (Layer 2 cleanup broader) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Job Offer: thêm 27 custom fields bao gồm
  - job_opening link (stock Job Offer thiếu ref tới Job Opening)
  - custom_offer_number, custom_offer_status (state machine)
  - custom_response_deadline, custom_start_date, custom_probation_days
  - custom_contract_type, custom_department, custom_report_to
  - custom_gross_salary, custom_probation_salary
  - custom_special_conditions, custom_approval_comments, custom_decline_reason
  - custom_process_instance_id (Flowable BPM)
  - custom_offer_pdf (Attach), custom_pdf_url
  - custom_revision_of, custom_revision_number (revision tracking)

Job Opening: thêm 3 custom fields cho offer approval workflow
  - custom_hiring_manager_email
  - custom_salary_band_max
  - custom_job_grade_level

Employee Separation: mở rộng block hiện tại với 15 field workflow huỷ + hoàn tất
  - custom_cancellation_section + custom_cancellation_reason + custom_other_party_consent
  - custom_cancellation_requested_by/at, approved_by/at + approval_notes
  - custom_cancellation_rejected_by/at + rejection_notes
  - custom_completed_by/at (hoàn tất nghỉ việc)

Fix 3 endpoint Tetra eOffice trả 403 "Field not permitted in query":
  GET /api/v1/recruitment/offers
  GET /api/v1/hrms/separations?status=pending_cancellation
  GET /api/v1/hrms/separations/compliance-alerts

Sau khi bench migrate áp custom fields → cả 3 endpoint trả HTTP 200.

Fields Exit Interview / Asset Assignment / Employee (custom_gross_salary,
custom_is_pregnant, custom_skip_reason, custom_nps_score, custom_returned,
v.v.) được liệt kê trong brief thực ra thuộc DocType khác — nằm ngoài scope
TETRA-1352, để lại cho ticket dọn dẹp Layer 2 sau (TETRA-1354).

Refs: TETRA-1352, TETRA-1332

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tant merged commit 9bb922c591 into develop 2026-04-22 11:39:59 +07:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
tant/vhrms!4
No description provided.