Skip to content

fix: resolve HRMS issues from Frappe Errors 2026#5

Open
mprinceb wants to merge 3 commits intocustom-patches2from
fix/frappe-errors-2026-hrms
Open

fix: resolve HRMS issues from Frappe Errors 2026#5
mprinceb wants to merge 3 commits intocustom-patches2from
fix/frappe-errors-2026-hrms

Conversation

@mprinceb
Copy link
Member

Summary

This PR fixes the hrms app side of the issues from Frappe Errors 2026.pdf for tcr.localhost, focused on approver visibility, salary slip robustness, and requested list filters.

Changes and Reasoning

  • Fix Team Leaves loading in Leave History (including direct ?tab=Team+Leaves route)

    • frontend/src/components/ListView.vue
    • Added route-query tab resolution, Team Leave mode data source (hrms.api.get_leave_applications_for_approval), local filter handling, safer infinite-scroll pagination source, and workflow-field dedupe.
    • Reason: approvers were seeing empty Team Leaves on the Leave History page despite having pending team leave records.
  • Unify managed-employee resolution for approver flows

    • hrms/api/__init__.py
    • Introduced _get_managed_employees_for_approver() using all relevant mappings:
      • Employee custom approvers (custom_leave_approvers)
      • Department leave approvers
      • Direct leave_approver
      • custom_reporting_manager_l1
    • Reused this logic in:
      • get_managed_employees
      • get_leave_applications_for_approval
      • get_today_holidays_for_employee
      • get_attendance_regularization_requests
      • get_sunday_holiday_working_requests_for_approver
    • Reason: previous join logic under-fetched managed employees, causing missing approver data in multiple endpoints.
  • Salary slip download fallback for print-format errors

    • hrms/api/__init__.py
    • Added fallback to Standard format if default print format fails.
    • Reason: avoids API failure when custom print format rendering is broken on live data.
  • Leave approval conflict handling for half-day attendance edge case

    • hrms/hr/doctype/leave_application/leave_application.py
    • Excludes attendance conflicts on half_day_date for half-day leave applications.
    • Reason: allows legitimate approval when attendance exists for the non-leave half/session.
  • Add requested L1/status/date filters across HR list views

    • hrms/hr/doctype/attendance/attendance_list.js
    • hrms/hr/doctype/employee_checkin/employee_checkin_list.js
    • hrms/hr/doctype/leave_allocation/leave_allocation_list.js
    • hrms/hr/doctype/leave_policy_assignment/leave_policy_assignment_list.js
    • hrms/hr/doctype/shift_assignment/shift_assignment_list.js
    • hrms/payroll/doctype/payroll_entry/payroll_entry_list.js
    • hrms/payroll/doctype/salary_slip/salary_slip_list.js
    • hrms/payroll/doctype/salary_structure_assignment/salary_structure_assignment_list.js (new)
    • Reason: implements the requested operational filters (L1, status, posting date/payroll month, etc.) in affected list screens.

Validation

  • npm run build (HRMS frontend)
  • python3 -m py_compile on changed Python modules
  • node --check on changed JS modules
  • bench --site tcr.localhost migrate
  • bench --site tcr.localhost clear-cache && clear-website-cache
  • Playwright verification: approver Leave History Team Leaves path now loads records via direct route and tab view.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6f7d202075

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +336 to +337
if (isTeamRequest.value && managedEmployees.length) {
docs = docs.filter((item) => managedEmployees.includes(item.employee))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Enforce team scope even when no managed employees are found

The new team-request scoping only runs when managedEmployees.length is non-zero, so users with no managed employees now skip scoping entirely and still keep the employee != current_user default filter. In Team tabs this returns other employees’ records instead of an empty result, which exposes non-team data (e.g., attendance/shift/expense/advance team views) to users who should see none.

Useful? React with 👍 / 👎.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 3083c32: team request scoping now always applies, including when managed employee list is empty, so no non-team data leaks into team views.

Comment on lines +302 to +306
if (condition === "Like" || condition === "like") {
return `${docValue ?? ""}`.toLowerCase().includes(`${value ?? ""}`.toLowerCase())
}

return true

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Support date comparison operators in Team Leaves local filter

Team Leaves now relies on applyLocalFilters, but this logic only handles =, !=, and Like; all other operators fall through to true. The filter UI allows date comparisons (>, <, >=, <=), so those selections are silently ignored on Team Leaves and users receive unfiltered results despite applying filters.

Useful? React with 👍 / 👎.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 3083c32: local filter logic now handles >, <, >=, <= operators used by date filters in Team Leaves.

@mprinceb
Copy link
Member Author

Addressed review feedback in commit 3083c32.\n\n- Team scoping now always applies in team requests, even when managed employees resolves to an empty list (returns empty, no data leakage).\n- Local filter handling now supports comparison operators (, , , ) used by date filters.\n- Added refresh watcher so team data is re-fetched after managed employees loading completes.

@mprinceb
Copy link
Member Author

Correction to previous comment formatting: review feedback is addressed in commit 3083c32.

  • Team scoping now always applies in team requests, even when managed employees resolves to an empty list (returns empty, no data leakage).
  • Local filter handling now supports comparison operators >, <, >=, <= used by date filters.
  • Added refresh watcher so team data is re-fetched after managed employees loading completes.

@mprinceb
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3083c32139

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

},
transform(data) {
const start = teamLeaveDocuments.params?.start || 0
const filtered = applyLocalFilters(Array.isArray(data) ? [...data] : [])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep Team Leaves filters server-compatible

In Team Leaves mode this code applies all filters client-side, but hrms.api.get_leave_applications_for_approval only returns a limited field set (it does not include fields like department in hrms/api/__init__.py), so selecting Department in Leave History makes doc.department undefined for every row and the equality check filters out all records. This causes false empty results specifically when users apply filters that are present in the UI but missing from the Team Leaves payload.

Useful? React with 👍 / 👎.

employee: employee.data.name,
approver_id: employee.data.user_id,
for_approval: 1,
limit: 500,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove hard 500-row cap from Team Leaves pagination

Team Leaves fetches are hard-limited to 500 records, and subsequent scroll loads only page through that same capped result, so approvers with more than 500 eligible leave applications can never reach older entries. This is a data-visibility regression that appears in larger datasets where Team Leaves exceeds the fixed cap.

Useful? React with 👍 / 👎.

@mprinceb
Copy link
Member Author

Added follow-up fixes for remaining mobile issues from the PDF in commit fece1fb:

  • hrms.api.get_all_employees now returns only active employees and excludes records linked to disabled users (unless user_id is empty), which prevents left/disabled employees from appearing in Raven user lists.
  • frontend/src/data/employees.js now imports router explicitly for auth-error redirects and clears cached employee maps before repopulating, so stale left-employee entries do not linger in memory.

This targets issue #5 (user-list auth failure path) and issue frappe#8 (left employees still shown in mobile).

@mprinceb
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fece1fbe18

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +315 to +316
if (normalizedCondition === "=") {
return `${docValue ?? ""}` === `${value ?? ""}`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Guard local Team Leaves filters against missing fields

Team Leaves filtering is now done client-side, but this equality check treats absent fields as empty strings, so any filter on a field not present in the fetched payload (for example department) rejects every row and shows a false empty state. Since get_leave_applications_for_approval does not return all filterable fields, this path regresses valid filters into “no data” for approvers.

Useful? React with 👍 / 👎.

employee: employee.data.name,
approver_id: employee.data.user_id,
for_approval: 1,
limit: 500,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove fixed 500-row cap from Team Leaves pagination

The Team Leaves request hard-codes limit: 500 and then paginates by slicing client-side, so records beyond the first 500 can never be reached even when infinite scroll continues. In environments with large teams or long histories, approvers will silently miss older applications.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant