Skip to content

Commit e650ae2

Browse files
fatmaebrahimCopilot
andauthored
Update Excuse Leave (#550)
* feat: restricted excuse to be of 2 hours only Co-authored-by: Copilot <copilot@github.com> * feat: changed excuses default balance to 12 * feat: added migration to update old users balance * feat: restricted excuse to be 1 per day Co-authored-by: Copilot <copilot@github.com> * test: added unit tests to server Co-authored-by: Copilot <copilot@github.com> * fix: fixed ci build error * fix: changed migration to update only the current year balance * feat: restricted non excuse leaves not to be 0.25 day Co-authored-by: Copilot <copilot@github.com> --------- Co-authored-by: Copilot <copilot@github.com>
1 parent a6b8365 commit e650ae2

8 files changed

Lines changed: 383 additions & 100 deletions

File tree

client/src/components/cards/vacationCard.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
</v-autocomplete>
8989
</v-col>
9090
<v-col cols="6">
91-
<v-text-field color="info" item-color="info" base-color="info" variant="outlined" hide-details="auto"
91+
<v-text-field v-if ="leaveReason.reason !== 'excuse'" color="info" item-color="info" base-color="info" variant="outlined" hide-details="auto"
9292
label="Requested Days" v-model="actualDays" readonly>
9393
</v-text-field>
9494
</v-col>

client/src/components/requests/leaveRequest.vue

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
The actual number of vacation days requested is zero. Please note that the selected days may include weekends or
66
public holidays.
77
</p>
8+
<p v-else-if="leaveReason?.reason == 'excuse'">
9+
The vacation request submitted is for a total of 1 excuse. </p>
810
<p v-else>
911
The vacation request submitted is for a total of {{ vacationDays.state.value }}
1012
{{ vacationDays.state.value <= 1 ? 'day' : 'days' }}. </p>
@@ -47,15 +49,15 @@
4749

4850
<div class="mt-3">
4951
<v-text-field ref="excuseStartField" item-color="info" base-color="info" color="info" variant="outlined"
50-
label="Vacation Start Time" v-model="excuseStart" hide-details="auto" type="time" :rules="[validateTimes]"
51-
:readonly="startDate !== endDate">
52+
label="Vacation Start Time" v-model="excuseStart" hide-details="auto" type="time"
53+
:rules="[validateTimes, validateLeave,]" :readonly="startDate !== endDate">
5254
</v-text-field>
5355
</div>
5456

5557
<div class="mt-3">
5658
<v-text-field ref="excuseEndField" item-color="info" base-color="info" color="info" variant="outlined"
57-
label="Vacation End Time" v-model="excuseEnd" hide-details="auto" type="time" :rules="[validateTimes]"
58-
:readonly="startDate !== endDate">
59+
label="Vacation End Time" v-model="excuseEnd" hide-details="auto" type="time"
60+
:rules="[validateTimes, validateLeave,]" :readonly="startDate !== endDate">
5961
</v-text-field>
6062
</div>
6163
<v-row class="mt-3 pa-4 d-flex justify-end">
@@ -222,6 +224,27 @@ export default {
222224
return true
223225
}
224226
227+
watch(leaveReason, () => {
228+
excuseStartField.value?.validate()
229+
excuseEndField.value?.validate()
230+
})
231+
const validateLeave = (): string | boolean => {
232+
let endHour = Number(excuseEnd.value.split(':')[0])
233+
let startHour = Number(excuseStart.value.split(':')[0])
234+
235+
let endMinute = Number(excuseEnd.value.split(':')[1])
236+
let startMinute = Number(excuseStart.value.split(':')[1])
237+
238+
let diff = (endHour - startHour) * 60 + (endMinute - startMinute)
239+
240+
if (leaveReason.value && leaveReason.value.reason === 'excuse') {
241+
if (diff > 120) return 'Excuse time cannot exceed 2 hours in a day.'
242+
} else {
243+
if (diff < 180) return 'Vacation duration cannot be less than 0.5 days.'
244+
}
245+
return true
246+
}
247+
225248
226249
onMounted(async () => {
227250
startDateField.value.validate()
@@ -301,6 +324,7 @@ export default {
301324
createLeave,
302325
validateDates,
303326
validateTimes,
327+
validateLeave,
304328
useOldBalance,
305329
balance,
306330
couldApplyUsingOldBalance,

client/src/views/RequestsView.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
Reason: <v-chip size="x-small" variant="tonal" class="text-capitalize">{{
8787
formatVacationReason(request.reason) }}</v-chip>
8888
</p>
89-
<p>
89+
<p v-if="request.reason!='excuse'" >
9090
Actual Days: <strong>{{ request.actual_days || 'N/A' }}</strong>
9191
</p>
9292
<p v-if="request.status === 'approved' || request.status === 'cancel_rejected'">
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from django.db import migrations, models
2+
from django.utils import timezone
3+
4+
5+
def update_excuse_balance(apps, schema_editor):
6+
UserVacationBalance = apps.get_model("cshr", "UserVacationBalance")
7+
current_year = timezone.now().year
8+
9+
for user_balance in UserVacationBalance.objects.filter(year=current_year).select_related("total_days", "remaining_days"):
10+
if user_balance.total_days:
11+
user_balance.total_days.excuse = 12
12+
user_balance.total_days.save(update_fields=["excuse"])
13+
if user_balance.remaining_days:
14+
user_balance.remaining_days.excuse = min(user_balance.remaining_days.excuse * 4, 12)
15+
user_balance.remaining_days.save(update_fields=["excuse"])
16+
17+
18+
def reverse_excuse_balance(apps, schema_editor):
19+
UserVacationBalance = apps.get_model("cshr", "UserVacationBalance")
20+
current_year = timezone.now().year
21+
22+
for user_balance in UserVacationBalance.objects.filter(year=current_year).select_related("total_days", "remaining_days"):
23+
if user_balance.total_days:
24+
user_balance.total_days.excuse = 6
25+
user_balance.total_days.save(update_fields=["excuse"])
26+
if user_balance.remaining_days:
27+
user_balance.remaining_days.excuse = user_balance.remaining_days.excuse / 4
28+
user_balance.remaining_days.save(update_fields=["excuse"])
29+
30+
31+
class Migration(migrations.Migration):
32+
33+
dependencies = [
34+
("cshr", "0035_alter_uservacationbalance_year"),
35+
]
36+
37+
operations = [
38+
migrations.AlterField(
39+
model_name="vacationbalancemodel",
40+
name="excuse",
41+
field=models.FloatField(default=12),
42+
),
43+
migrations.RunPython(update_excuse_balance, reverse_excuse_balance),
44+
]

server/cshr/models/vacations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class VacationBalanceModel(TimeStamp):
7171
unpaid = models.FloatField(default=365)
7272
annual = models.FloatField(default=15)
7373
emergency = models.FloatField(default=6)
74-
excuse = models.FloatField(default=6)
74+
excuse = models.FloatField(default=12)
7575
is_locked = models.BooleanField(default=False)
7676

7777
def __str__(self):

0 commit comments

Comments
 (0)