Skip to content

Commit 7d72be3

Browse files
authored
Development add user balance year filter (#548)
* feat: Add year selection for vacation balances - Add year selection component and logic - Update balance API to accept year parameter - Refactor balance fetching and updating to support selected year - Add watcher for year changes to refetch balances - Update UI to display selected year in title and alert * feat: Add year parameter for vacation balance - Add IntegerField for year in serializer - Allow filtering vacation balance by year - Update docstring with year parameter * feat: Improve vacation balance calculation logic - Filter vacations affecting current year balance - Add balance source description to report - Indicate if vacation affects year balance
1 parent 7c10629 commit 7d72be3

2 files changed

Lines changed: 28 additions & 6 deletions

File tree

client/src/components/dashboard/AuditUserBalance.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
<div class="d-flex justify-space-between align-end mb-4">
4646
<div>
4747
<h3 class="text-h6 font-weight-bold">Audit Results for {{ reportData.user_full_name
48-
}}</h3>
48+
}}</h3>
4949
<div class="text-body-2 text-medium-emphasis">Period: {{ reportData.year }} |
5050
Reason: <span class="text-capitalize">{{ reportData.reason }}</span></div>
5151
</div>
@@ -124,9 +124,9 @@
124124
<span v-else>{{ vac.recalc }}</span>
125125
</td>
126126
<td>
127-
<v-chip size="x-small" :color="vac.is_old_balance ? 'secondary' : 'primary'"
128-
variant="tonal">
129-
{{ vac.is_old_balance ? 'Transferred' : 'Main' }}
127+
<v-chip size="x-small"
128+
:color="vac.affects_year_balance ? 'primary' : 'secondary'" variant="tonal">
129+
{{ vac.balance_source || (vac.is_old_balance ? 'Transferred' : 'Main') }}
130130
</v-chip>
131131
</td>
132132
</tr>

server/cshr/services/balance.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from datetime import datetime
22
from typing import Any, Dict, List, Optional
3+
from django.db.models import Q
34
from cshr.models.users import User, USER_TYPE
45
from cshr.models.vacations import UserVacationBalance, Vacation
56
from 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

Comments
 (0)