Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions client/src/views/RequestsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
requests from a different year; only the last three years are available for filtering.
</v-alert>
<v-row>
<v-col cols="9">
<v-col cols="6">
<v-autocomplete :rules="requiredRules" hide-details="auto" v-model="selectedUser" :items="users"
item-title="full_name" item-value="id" label="User" return-object
:disabled="isLoadingUsers || isLoadingVacations" :loading="isLoadingUsers || isLoadingVacations">
Expand All @@ -18,6 +18,10 @@
<v-select :loading="isLoadingUsers || isLoadingVacations" :disabled="isLoadingUsers || isLoadingVacations"
:items="supportedYears" label="Select a year" v-model="selectedYear" />
</v-col>
<v-col cols="3">
<v-select :loading="isLoadingUsers || isLoadingVacations" :disabled="isLoadingUsers || isLoadingVacations"
:items="supportedRequestTypes" label="Request type" v-model="selectedType" />
</v-col>
</v-row>
<v-divider></v-divider>
</div>
Expand Down Expand Up @@ -104,7 +108,9 @@ export default defineComponent({
const isLoadingUsers = ref(false);
const isLoadingVacations = ref(false);
const selectedYear = ref(new Date().getFullYear());
const selectedType = ref('All');
const supportedYears = ref<number[]>([]);
const supportedRequestTypes = ref(['All', 'Annual', 'Emergency', 'Excuse', 'Sick', 'Unpaid', 'Compensation', 'Paternity', 'Maternity']);

const userRequests = ref<Api.Vacation[]>([]);
const vacationsCount = ref(0);
Expand Down Expand Up @@ -134,7 +140,7 @@ export default defineComponent({
if (selectedUser.value == null) return
let userId = selectedUser.value?.id ? selectedUser.value?.id : selectedUser.value
isLoadingVacations.value = true;
const result = await $api.vacations.listUserRequests({ user_id: userId, page: vacationsPage.value, year: selectedYear.value });
const result = await $api.vacations.listUserRequests({ user_id: userId, page: vacationsPage.value, year: selectedYear.value, type: selectedType.value.toLocaleLowerCase() });
userRequests.value = result!.results;
vacationsCount.value = Math.ceil(result!.count / 10);
isLoadingVacations.value = false;
Expand Down Expand Up @@ -167,10 +173,11 @@ export default defineComponent({
});

watch(
[selectedUser, selectedYear],
[selectedUser, selectedYear, selectedType],
async () => {
if (!selectedYear.value) return
if (!selectedUser.value) return
if (!selectedType.value) return
vacationsPage.value = 1
await userVacationsState.execute();
},
Expand Down Expand Up @@ -201,6 +208,8 @@ export default defineComponent({
getStatusColor,
convertToTimeOnly,
requiredRules,
supportedRequestTypes,
selectedType,
};
},
});
Expand Down
26 changes: 25 additions & 1 deletion server/cshr/services/vacations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.db.models.query import QuerySet
from typing import List

from cshr.models.vacations import UserVacationBalance, Vacation
from cshr.models.vacations import ReasonChoices, UserVacationBalance, Vacation


def filter_vacations_by_month_and_year(month: str, year: str) -> Vacation:
Expand Down Expand Up @@ -94,3 +94,27 @@ def get_user_balance(user: User) -> UserVacationBalance:
return UserVacationBalance.objects.get(user=user)
except UserVacationBalance.DoesNotExist:
return None

def normalize_request_type(request_type: str) -> str:
"""
Normalize request type to be used in the query
"""
request_type = request_type.lower()
if request_type == "annual":
return ReasonChoices.Annual.value
elif request_type == "emergency":
return ReasonChoices.Emergency.value
elif request_type == "excuse":
return ReasonChoices.Excuse.value
elif request_type == "sick":
return ReasonChoices.Sick.value
elif request_type == "unpaid":
return ReasonChoices.Unpaid.value
elif request_type == "compensation":
return ReasonChoices.Compensation.value
elif request_type == "maternity":
return ReasonChoices.Maternity.value
elif request_type == "paternity":
return ReasonChoices.Paternity.value
else:
return None
30 changes: 25 additions & 5 deletions server/cshr/views/vacations.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from cshr.services.vacations import (
get_vacation_by_id,
get_all_vacations,
normalize_request_type,
)
from rest_framework.generics import GenericAPIView, ListAPIView
from rest_framework.request import Request
Expand Down Expand Up @@ -147,17 +148,36 @@ def get_queryset(self) -> Response:
if not year:
year = datetime.now().year

request_type = self.request.query_params.get("type")
if not request_type:
request_type = "all"

if request_type != "all":
request_type = normalize_request_type(request_type)
if request_type is None:
return CustomResponse.bad_request(message="Invalid request type")

current_user: User = get_user_by_id(user_id)
if current_user is None:
return CustomResponse.not_found(
message="user is not found", status_code=404
)

queryset = (
filter_vacations_by_user_id(current_user.id)
.filter(from_date__year=year)
.order_by("-created_at")
)
queryset = None

if request_type != "all":
queryset = (
filter_vacations_by_user_id(current_user.id)
.filter(from_date__year=year)
.filter(reason=request_type)
.order_by("-created_at")
)
else:
queryset = (
filter_vacations_by_user_id(current_user.id)
.filter(from_date__year=year)
.order_by("-created_at")
)

return queryset

Expand Down