Skip to content

fix(leave_allocation): handle expired leave allocation#4559

Merged
deepeshgarg007 merged 7 commits into
frappe:version-15-hotfixfrom
iamkhanraheel:fix/leave_allocation_data_after_expire
May 25, 2026
Merged

fix(leave_allocation): handle expired leave allocation#4559
deepeshgarg007 merged 7 commits into
frappe:version-15-hotfixfrom
iamkhanraheel:fix/leave_allocation_data_after_expire

Conversation

@iamkhanraheel
Copy link
Copy Markdown
Collaborator

@iamkhanraheel iamkhanraheel commented May 19, 2026

Reason

  • Expired leave allocations are still showing new_leaves_allocated and total_leaves_allocated values even after expiry making it difficult to understand the new allocation after expiry
leaveExpiryBug.mov

Changes Done

  • Reset new_leaves_allocated and total_leaves_allocated to 0 when allocations expire. Also hide the new_leaves_allocated field for earned leave allocations as only the total_leaves_allocated field is updated
  • Reload doc after leave expiry as there is a document sync error just after the expiration
LeaveExpiryFix.mov

Summary by CodeRabbit

  • Bug Fixes

    • Expired leave allocations now hide the allocated-leaves input, reset both new and total allocated leave counts to zero, and ensure the form reloads to show updated values.
  • Tests

    • Added an automated test verifying that expiration clears allocations and that subsequent manual reallocations update totals while new-allocation stays cleared.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This pull request updates the expire_allocation function to include type hints and to mark linked Leave Allocation documents expired while resetting new_leaves_allocated and total_leaves_allocated to 0. The Leave Allocation form refresh handler now hides the new_leaves_allocated field when the document is expired. Tests were added to expire an allocation, assert cleared counters, and verify manual reallocation updates totals while new_leaves_allocated remains 0.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing how expired leave allocations are handled, which is central to all modifications across the three files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
hrms/hr/doctype/leave_ledger_entry/leave_ledger_entry.py (1)

229-253: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Apply consistent field updates to carry-forward allocations.

The expire_allocation function now updates the Leave Allocation document with zeroed fields (line 222-226), but expire_carried_forward_allocation only creates a ledger entry without updating the Leave Allocation document. This creates an inconsistency where carry-forward allocations retain their new_leaves_allocated and total_leaves_allocated values after expiry, while regular allocations have them zeroed.

🔧 Proposed fix to add field updates for carry-forward expiration
 def expire_carried_forward_allocation(allocation):
     """Expires remaining leaves in the on carried forward allocation"""
     from hrms.hr.doctype.leave_application.leave_application import get_leaves_for_period
 
     leaves_taken = get_leaves_for_period(
         allocation.employee,
         allocation.leave_type,
         allocation.from_date,
         allocation.to_date,
         skip_expired_leaves=False,
     )
     leaves = flt(allocation.leaves) + flt(leaves_taken)
 
     # allow expired leaves entry to be created
     if leaves > 0:
         args = frappe._dict(
             transaction_name=allocation.name,
             transaction_type="Leave Allocation",
             leaves=leaves * -1,
             is_carry_forward=allocation.is_carry_forward,
             is_expired=1,
             from_date=allocation.to_date,
             to_date=allocation.to_date,
         )
         create_leave_ledger_entry(allocation, args)
+    
+    frappe.db.set_value(
+        "Leave Allocation",
+        allocation.name,
+        {"expired": 1, "new_leaves_allocated": 0, "total_leaves_allocated": 0},
+    )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@hrms/hr/doctype/leave_ledger_entry/leave_ledger_entry.py` around lines 229 -
253, The carry-forward expiry function expire_carried_forward_allocation
currently only creates a ledger entry but does not update the Leave Allocation
doc fields like expire_allocation does; after creating the ledger entry with
create_leave_ledger_entry(allocation, args) update the allocation record to zero
out the same fields expire_allocation resets (e.g. new_leaves_allocated,
total_leaves_allocated, leaves or whichever allocation fields are zeroed in
expire_allocation) and persist the change (use the same persistence approach
used in expire_allocation such as allocation.db_set or allocation.save) so
carry-forward allocations are consistently updated when expired.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@hrms/hr/doctype/leave_allocation/leave_allocation.js`:
- Around line 31-33: The current code hides new_leaves_allocated for any expired
allocation (frm.doc.expired) but the backend zeroes both new_leaves_allocated
and total_leaves_allocated, causing a mismatch; update the client logic to hide
both fields when frm.doc.expired by calling
frm.set_df_property("new_leaves_allocated", "hidden", 1) and
frm.set_df_property("total_leaves_allocated", "hidden", 1) in the same
expired-check block (or, if the intended behavior is only for earned leave,
instead add the earned-leave condition around the existing frm.doc.expired check
to hide only new_leaves_allocated).

In `@hrms/hr/doctype/leave_ledger_entry/leave_ledger_entry.py`:
- Around line 222-226: The cancellation path in Leave Ledger Entry only unsets
the expired flag but does not restore fields that were zeroed
(new_leaves_allocated, total_leaves_allocated); update the on_cancel method on
the Leave Ledger Entry class to restore those original values for the related
Leave Allocation: either read and restore values saved on the expiry ledger
entry (add fields to the ledger like prev_new_leaves_allocated and
prev_total_leaves_allocated when expiring in the code that calls
frappe.db.set_value), or recompute the allocation totals from prior ledger
entries and set them back via frappe.db.set_value on the same allocation record;
ensure you reference the allocation by allocation.name and restore expired,
new_leaves_allocated and total_leaves_allocated together.

---

Outside diff comments:
In `@hrms/hr/doctype/leave_ledger_entry/leave_ledger_entry.py`:
- Around line 229-253: The carry-forward expiry function
expire_carried_forward_allocation currently only creates a ledger entry but does
not update the Leave Allocation doc fields like expire_allocation does; after
creating the ledger entry with create_leave_ledger_entry(allocation, args)
update the allocation record to zero out the same fields expire_allocation
resets (e.g. new_leaves_allocated, total_leaves_allocated, leaves or whichever
allocation fields are zeroed in expire_allocation) and persist the change (use
the same persistence approach used in expire_allocation such as
allocation.db_set or allocation.save) so carry-forward allocations are
consistently updated when expired.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7679fd3f-8a8c-4b7f-81c2-327fb7a71597

📥 Commits

Reviewing files that changed from the base of the PR and between 1e7fecd and 59ec354.

📒 Files selected for processing (2)
  • hrms/hr/doctype/leave_allocation/leave_allocation.js
  • hrms/hr/doctype/leave_ledger_entry/leave_ledger_entry.py

Comment thread hrms/hr/doctype/leave_allocation/leave_allocation.js
Comment thread hrms/hr/doctype/leave_ledger_entry/leave_ledger_entry.py
@deepeshgarg007
Copy link
Copy Markdown
Member

@iamkhanraheel Please add unit test for this scenario

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@hrms/hr/doctype/leave_allocation/test_leave_allocation.py`:
- Around line 636-644: Add assertions to ensure the earned-leave counter doesn't
change during manual allocations: after each call to
leave_allocation.allocate_leaves_manually(...) and leave_allocation.reload(),
assert that leave_allocation.new_leaves_allocated == 0 in addition to the
existing total_leaves_allocated checks so the test verifies only
total_leaves_allocated is updated while new_leaves_allocated remains unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2d11aeb5-164c-41c9-a407-49c45d18ea2d

📥 Commits

Reviewing files that changed from the base of the PR and between 59ec354 and f40b16f.

📒 Files selected for processing (1)
  • hrms/hr/doctype/leave_allocation/test_leave_allocation.py

Comment thread hrms/hr/doctype/leave_allocation/test_leave_allocation.py
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
hrms/hr/doctype/leave_allocation/leave_allocation.js (1)

134-134: ⚡ Quick win

Consider conditional reload for consistency.

The reload_doc() call executes unconditionally, while the similar callback for allocate_leaves_manually (lines 101-106) only reloads on success. For consistency with the established pattern in this file and Frappe best practices, consider moving the reload inside the success condition:

♻️ Align with the callback pattern used elsewhere in this file
 			callback: function (r) {
 				if (!r.exc) {
 					frappe.msgprint(__("Allocation Expired!"));
+					frm.reload_doc();
 				}
-				frm.reload_doc();
 			},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@hrms/hr/doctype/leave_allocation/leave_allocation.js` at line 134, The
unconditional frm.reload_doc() should be moved into the success branch of the
callback to match the pattern used by allocate_leaves_manually; locate the
callback that currently ends with frm.reload_doc() and wrap that call so it only
runs when the server response indicates success (e.g., inside the if (!r.exc) /
if (r.message) success check), mirroring how allocate_leaves_manually handles
reloads.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@hrms/hr/doctype/leave_allocation/leave_allocation.js`:
- Line 134: The unconditional frm.reload_doc() should be moved into the success
branch of the callback to match the pattern used by allocate_leaves_manually;
locate the callback that currently ends with frm.reload_doc() and wrap that call
so it only runs when the server response indicates success (e.g., inside the if
(!r.exc) / if (r.message) success check), mirroring how allocate_leaves_manually
handles reloads.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6e1c1d4b-5fa0-43ec-9278-f8b62c2539ea

📥 Commits

Reviewing files that changed from the base of the PR and between 6f17464 and bc02b6d.

📒 Files selected for processing (1)
  • hrms/hr/doctype/leave_allocation/leave_allocation.js

@iamkhanraheel iamkhanraheel force-pushed the fix/leave_allocation_data_after_expire branch from 4803da1 to 21dbdb7 Compare May 25, 2026 08:26
@deepeshgarg007 deepeshgarg007 merged commit 4bc5abb into frappe:version-15-hotfix May 25, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants