11from datetime import datetime
22from typing import Any , Dict , List , Optional
3+ from django .db .models import Q
34from cshr .models .users import User , USER_TYPE
45from cshr .models .vacations import UserVacationBalance , Vacation
56from cshr .models .requests import STATUS_CHOICES
@@ -31,11 +32,16 @@ def audit_user_balance(user: User, year: int, reason: str) -> Dict[str, Any]:
3132 total_quota = getattr (balance_obj .total_days , reason , 0 )
3233 current_db_remaining = getattr (balance_obj .remaining_days , reason , 0 )
3334
35+ # Query vacations that affect this year's balance:
36+ # 1. Vacations from this year that are NOT from old balance (consumed from current year's balance)
37+ # 2. Vacations from the next year that ARE from old balance (consumed from this year's transferred balance)
3438 vacations = Vacation .objects .filter (
3539 applying_user = user ,
36- from_date__year = year ,
3740 status__in = [STATUS_CHOICES .APPROVED , STATUS_CHOICES .CANCEL_REJECTED ],
3841 reason = reason ,
42+ ).filter (
43+ Q (from_date__year = year , is_old_balance = False ) | # Regular vacations from this year
44+ Q (from_date__year = year + 1 , is_old_balance = True ) # Next year vacations using this year's balance
3945 ).order_by ("from_date" )
4046
4147 reports = []
@@ -52,9 +58,23 @@ def audit_user_balance(user: User, year: int, reason: str) -> Dict[str, Any]:
5258 ):
5359 days = 1.0
5460
55- if not vac .is_old_balance :
61+ # Count days that affect this year's remaining balance:
62+ # - Current year vacations (not from old balance) → deducted from this year's remaining
63+ # - Next year vacations (from old balance) → deducted from this year's remaining (via transferred)
64+ is_current_year_main = vac .from_date .year == year and not vac .is_old_balance
65+ is_next_year_transferred = vac .from_date .year == year + 1 and vac .is_old_balance
66+
67+ if is_current_year_main or is_next_year_transferred :
5668 total_recalc_current += days
5769
70+ # Determine the balance source description
71+ if is_next_year_transferred :
72+ balance_source = f"Transferred (from { year } )"
73+ elif vac .is_old_balance :
74+ balance_source = f"Transferred (from { year - 1 } )"
75+ else :
76+ balance_source = "Main"
77+
5878 reports .append (
5979 {
6080 "id" : vac .id ,
@@ -63,6 +83,8 @@ def audit_user_balance(user: User, year: int, reason: str) -> Dict[str, Any]:
6383 "stored" : vac .actual_days ,
6484 "recalc" : days ,
6585 "is_old_balance" : vac .is_old_balance ,
86+ "balance_source" : balance_source ,
87+ "affects_year_balance" : is_current_year_main or is_next_year_transferred ,
6688 }
6789 )
6890
0 commit comments