From d98c5480ee38fa52a1c496b316a83562b0bf9690 Mon Sep 17 00:00:00 2001 From: Horilla Date: Wed, 8 May 2024 15:57:41 +0530 Subject: [PATCH] [UPDT] LEAVE: Leave compensatory request section --- attendance/templates/attendance_form.html | 2 +- employee/views.py | 9 +- leave/admin.py | 4 + leave/filters.py | 76 ++++ leave/forms.py | 132 +++++- leave/methods.py | 62 +++ leave/models.py | 107 ++++- .../compensatory_leave/attendance_id.html | 1 + .../compensatory_leave/comp_leave_form.html | 43 ++ .../compensatory_leave_comment.html | 177 ++++++++ .../compensatory_leave_reject_form..html | 38 ++ .../compensatory_leave_req_list.html | 426 ++++++++++++++++++ .../compensatory_leave_view.html | 421 +++++++++++++++++ .../leave_allocation_request_list.html | 4 +- .../leave/leave_type/leave_types.html | 2 +- leave/templatetags/__init__.py | 0 leave/templatetags/leavefilters.py | 13 + leave/urls.py | 60 +++ recruitment/models.py | 12 +- static/css/style.css | 1 + templates/settings.html | 26 ++ templates/sidebar.html | 11 +- 22 files changed, 1607 insertions(+), 20 deletions(-) create mode 100644 leave/templates/leave/compensatory_leave/attendance_id.html create mode 100644 leave/templates/leave/compensatory_leave/comp_leave_form.html create mode 100644 leave/templates/leave/compensatory_leave/compensatory_leave_comment.html create mode 100644 leave/templates/leave/compensatory_leave/compensatory_leave_reject_form..html create mode 100644 leave/templates/leave/compensatory_leave/compensatory_leave_req_list.html create mode 100644 leave/templates/leave/compensatory_leave/compensatory_leave_view.html create mode 100644 leave/templatetags/__init__.py create mode 100644 leave/templatetags/leavefilters.py diff --git a/attendance/templates/attendance_form.html b/attendance/templates/attendance_form.html index 1a6413d2d..bd73a34f3 100644 --- a/attendance/templates/attendance_form.html +++ b/attendance/templates/attendance_form.html @@ -16,7 +16,7 @@ title="{{ field.help_text|safe }}" >{% trans field.label %} -
+
{{ field|add_class:"form-control" }}
diff --git a/employee/views.py b/employee/views.py index b0917c52d..f671bf357 100755 --- a/employee/views.py +++ b/employee/views.py @@ -106,7 +106,8 @@ from horilla_documents.forms import ( DocumentUpdateForm, ) from horilla_documents.models import Document, DocumentRequest -from leave.models import LeaveRequest +from leave.methods import get_leave_day_attendance +from leave.models import LeaveGeneralSetting, LeaveRequest from notifications.signals import notify from onboarding.models import OnboardingStage, OnboardingTask from payroll.methods.payslip_calc import dynamic_attr @@ -174,7 +175,11 @@ def employee_profile(request): """ user = request.user employee = request.user.employee_get - user_leaves = employee.available_leave.all() + user_leaves = employee.available_leave.all().exclude( + leave_type_id__is_compensatory_leave=True + ) + if LeaveGeneralSetting.objects.first().compensatory_leave: + user_leaves = employee.available_leave.all() instances = LeaveRequest.objects.filter(employee_id=employee) leave_request_ids = json.dumps([instance.id for instance in instances]) employee = Employee.objects.filter(employee_user_id=user).first() diff --git a/leave/admin.py b/leave/admin.py index 50ee69a8e..2db666447 100644 --- a/leave/admin.py +++ b/leave/admin.py @@ -9,9 +9,11 @@ from simple_history.admin import SimpleHistoryAdmin from .models import ( AvailableLeave, CompanyLeave, + CompensatoryLeaveRequest, Holiday, LeaveAllocationRequest, LeaveallocationrequestComment, + LeaveGeneralSetting, LeaveRequest, LeaverequestComment, LeaveRequestConditionApproval, @@ -30,3 +32,5 @@ admin.site.register(LeaveRequestConditionApproval) admin.site.register(LeaverequestComment) admin.site.register(LeaveallocationrequestComment) admin.site.register(RestrictLeave) +admin.site.register(CompensatoryLeaveRequest) +admin.site.register(LeaveGeneralSetting) diff --git a/leave/filters.py b/leave/filters.py index ccc595473..adcd4ba5f 100644 --- a/leave/filters.py +++ b/leave/filters.py @@ -22,6 +22,7 @@ from employee.models import Employee from .models import ( AvailableLeave, CompanyLeave, + CompensatoryLeaveRequest, Holiday, LeaveAllocationRequest, LeaveRequest, @@ -575,3 +576,78 @@ class RestrictLeaveFilter(FilterSet): super().__init__(data=data, queryset=queryset, request=request, prefix=prefix) for field in self.form.fields.keys(): self.form.fields[field].widget.attrs["id"] = f"{uuid.uuid4()}" + + +class CompensatoryLeaveRequestFilter(FilterSet): + """ + Filter class for CompensatoryLeaveRequest model specific to user leave requests. + This filter allows searching user-specific LeaveRequest objects + based on leave type, date range, and status. + """ + + id = django_filters.NumberFilter(field_name="id") + + leave_type = filters.CharFilter( + field_name="leave_type_id__name", lookup_expr="icontains" + ) + search = filters.CharFilter(method="filter_by_name") + created_by__employee_get = django_filters.CharFilter( + field_name="created_by__employee_get", + lookup_expr="exact", + widget=forms.SelectMultiple(attrs={"class": "form-control"}), + ) + number_of_days_up_to = filters.NumberFilter( + field_name="requested_days", lookup_expr="lte" + ) + number_of_days_more_than = filters.NumberFilter( + field_name="requested_days", lookup_expr="gte" + ) + + class Meta: + """ + Meta class defines the model and fields to filter + """ + + model = CompensatoryLeaveRequest + fields = { + "id": ["exact"], + "created_by__employee_get": ["exact"], + "status": ["exact"], + "leave_type_id": ["exact"], + "employee_id": ["exact"], + } + + def filter_by_name(self, queryset, name, value): + # Call the imported function + filter_method = { + "leave_type": "leave_type_id__name__icontains", + "status": "status__icontains", + "department": "employee_id__employee_work_info__department_id__department__icontains", + "job_position": "employee_id__employee_work_info__job_position_id__job_position__icontains", + "company": "employee_id__employee_work_info__company_id__company__icontains", + } + search_field = self.data.get("search_field") + if not search_field: + parts = value.split() + first_name = parts[0] + last_name = " ".join(parts[1:]) if len(parts) > 1 else "" + + # Filter the queryset by first name and last name + if first_name and last_name: + queryset = queryset.filter( + employee_id__employee_first_name__icontains=first_name, + employee_id__employee_last_name__icontains=last_name, + ) + elif first_name: + queryset = queryset.filter( + employee_id__employee_first_name__icontains=first_name + ) + elif last_name: + queryset = queryset.filter( + employee_id__employee_last_name__icontains=last_name + ) + else: + filter = filter_method.get(search_field) + queryset = queryset.filter(**{filter: value}) + + return queryset diff --git a/leave/forms.py b/leave/forms.py index c5c1297ee..8d1a70505 100644 --- a/leave/forms.py +++ b/leave/forms.py @@ -10,13 +10,14 @@ from typing import Any from django import forms from django.core.exceptions import ValidationError +from django.db.models import Q from django.forms import ModelForm from django.forms.widgets import TextInput from django.template.loader import render_to_string from django.utils.translation import gettext_lazy as _ from base import thread_local_middleware -from base.methods import reload_queryset +from base.methods import filtersubordinates, reload_queryset from base.models import Department from employee.filters import EmployeeFilter from employee.forms import MultipleFileField @@ -28,12 +29,15 @@ from horilla_widgets.widgets.select_widgets import HorillaMultiSelectWidget from .methods import ( calculate_requested_days, company_leave_dates_list, + get_leave_day_attendance, holiday_dates_list, leave_requested_dates, ) from .models import ( AvailableLeave, CompanyLeave, + CompensatoryLeaveRequest, + CompensatoryLeaverequestComment, Holiday, LeaveAllocationRequest, LeaveallocationrequestComment, @@ -1250,3 +1254,129 @@ class RestrictLeaveForm(ModelForm): def __init__(self, *args, **kwargs): super(RestrictLeaveForm, self).__init__(*args, **kwargs) self.fields["title"].widget.attrs["autocomplete"] = "title" + + +class CompensatoryLeaveForm(ModelForm): + """ + Form for creating a leave allocation request. + + This form allows users to create a leave allocation request by specifying + details such as leave type, employee, requested days, description, and attachment. + + Methods: + - as_p: Render the form fields as HTML table rows with Bootstrap styling. + """ + + class Meta: + """ + Meta class for additional options + """ + + attendance_id = forms.MultipleChoiceField(required=True) + model = CompensatoryLeaveRequest + fields = [ + # "leave_type_id", + "employee_id", + "attendance_id", + # "requested_days", + "description", + ] + + def __init__(self, *args, **kwargs): + from attendance.models import Attendance + + super(CompensatoryLeaveForm, self).__init__(*args, **kwargs) + + request = getattr(thread_local_middleware._thread_locals, "request", None) + instance_id = None + if self.instance: + instance_id = self.instance.id + if ( + request + and hasattr(request, "user") + and hasattr(request.user, "employee_get") + ): + employee = request.user.employee_get + holiday_attendance = get_leave_day_attendance(employee, comp_id=instance_id) + # Get a list of tuples containing (id, attendance_date) + attendance_dates = list( + holiday_attendance.values_list("id", "attendance_date") + ) + # Set the queryset of attendance_id to the attendance_dates + self.fields["attendance_id"].choices = attendance_dates + self.fields["employee_id"].widget.attrs.update( + { + "hx-target": "#id_attendance_id_parent_div", + "hx-trigger": "change", + "hx-get": "/leave/get-leave-attendance-dates", + } + ) + + def as_p(self, *args, **kwargs): + """ + Render the form fields as HTML table rows with Bootstrap styling. + """ + context = {"form": self} + table_html = render_to_string("attendance_form.html", context) + return table_html + + def clean(self): + cleaned_data = super().clean() + attendance_id = cleaned_data.get("attendance_id") + employee = cleaned_data.get("employee_id") + attendance_repeat = False + instance_id = None + if self.instance: + instance_id = self.instance.id + for attendance in attendance_id: + if ( + CompensatoryLeaveRequest.objects.filter( + employee_id=employee, attendance_id=attendance + ) + .exclude(Q(id=instance_id) | Q(status="rejected")) + .exists() + ): + attendance_repeat = True + break + if attendance_repeat: + raise forms.ValidationError( + { + "attendance_id": "This attendance is already converted to complimentory leave" + } + ) + return cleaned_data + + +class CompensatoryLeaveRequestRejectForm(forms.Form): + """ + Form for rejecting a compensatory leave request. + + This form allows administrators to provide a rejection reason when rejecting + a compensatory leave request. + + Attributes: + - reason: A CharField representing the reason for rejecting the compensatory leave request. + """ + + reason = forms.CharField( + label=_("Rejection Reason"), + widget=forms.Textarea(attrs={"rows": 4, "class": "p-4 oh-input w-100"}), + ) + + class Meta: + model = CompensatoryLeaveRequest + fields = ["reject_reason"] + + +class CompensatoryLeaveRequestcommentForm(ModelForm): + """ + LeaverequestComment form + """ + + class Meta: + """ + Meta class for additional options + """ + + model = CompensatoryLeaverequestComment + fields = ("comment",) diff --git a/leave/methods.py b/leave/methods.py index 87803e0d6..588ce2ba9 100644 --- a/leave/methods.py +++ b/leave/methods.py @@ -1,6 +1,8 @@ import calendar from datetime import datetime, timedelta +from django.db.models import Q + def calculate_requested_days( start_date, end_date, start_date_breakdown, end_date_breakdown @@ -102,3 +104,63 @@ def company_leave_dates_list(company_leaves, start_date): if date not in company_leave_dates: company_leave_dates.append(date) return company_leave_dates + + +def get_leave_day_attendance(employee, comp_id=None): + """ + This function returns a queryset of attendance on leave dates + """ + from attendance.filters import AttendanceFilters + from attendance.models import Attendance + from leave.models import CompensatoryLeaveRequest, LeaveRequest + + holiday_dates = LeaveRequest.holiday_dates(None) + company_leave_dates = LeaveRequest.company_leave_dates(None) + leave_day_attendance = Attendance.objects.none() + converted_dates = [] + if ( + CompensatoryLeaveRequest.objects.filter(employee_id=employee) + .exclude(Q(id=comp_id) | Q(status="rejected")) + .exists() + ): + comp_leave_reqs = CompensatoryLeaveRequest.objects.filter( + employee_id=employee + ).exclude(Q(id=comp_id) | Q(status="rejected")) + attendances = Attendance.objects.none() # Empty queryset to start with + for req in comp_leave_reqs: + attendances |= req.attendance_id.all() + converted_dates = [attendance.attendance_date for attendance in attendances] + leave_dates = set(company_leave_dates + holiday_dates) - set(converted_dates) + for leave_day in leave_dates: + attendance_qs = AttendanceFilters( + {"employee": employee.id, "attendance_date": leave_day} + ).qs + if attendance_qs.exists(): + leave_day_attendance |= attendance_qs + + return leave_day_attendance + + +def attendance_days(employee, attendances): + """ + This function returns count of workrecord from the attendance + """ + from payroll.models.models import WorkRecord + + attendance_days = 0 + for attendance in attendances: + if WorkRecord.objects.filter( + employee_id=employee, date=attendance.attendance_date + ).exists(): + work_record_type = ( + WorkRecord.objects.filter( + employee_id=employee, date=attendance.attendance_date + ) + .first() + .work_record_type + ) + if work_record_type == "HDP": + attendance_days += 0.5 + elif work_record_type == "FDP": + attendance_days += 1 + return attendance_days diff --git a/leave/models.py b/leave/models.py index 3f499b3ae..ed0702601 100644 --- a/leave/models.py +++ b/leave/models.py @@ -30,7 +30,7 @@ from horilla_audit.methods import get_diff from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog from leave.threading import LeaveClashThread -from .methods import calculate_requested_days +from .methods import attendance_days, calculate_requested_days operator_mapping = { "equal": operator.eq, @@ -195,6 +195,7 @@ class LeaveType(HorillaModel): max_length=30, choices=CHOICES, default="no" ) exclude_holiday = models.CharField(max_length=30, choices=CHOICES, default="no") + is_compensatory_leave = models.BooleanField(default=False) company_id = models.ForeignKey( Company, null=True, editable=False, on_delete=models.PROTECT ) @@ -215,13 +216,17 @@ class LeaveType(HorillaModel): url = self.icon.url return url + def clean(self, *args, **kwargs): + if self.is_compensatory_leave: + if LeaveType.objects.filter(is_compensatory_leave=True).count() >= 1: + raise ValidationError(_("Compensatory Leave Request already exists.")) + def save(self, *args, **kwargs): if ( self.carryforward_type != "no carryforward" and self.carryforward_max is None ): self.carryforward_max = math.inf - super().save(*args, **kwargs) def __str__(self): return self.name @@ -557,10 +562,15 @@ class LeaveRequest(HorillaModel): def company_leave_dates(self): """ :return: This function returns a list of all company leave dates""" + from datetime import date + company_leaves = CompanyLeave.objects.all() company_leave_dates = [] for company_leave in company_leaves: - year = self.start_date.year + if self: + year = self.start_date.year + else: + year = date.today().year based_on_week = company_leave.based_on_week based_on_week_day = company_leave.based_on_week_day for month in range(1, 13): @@ -945,3 +955,94 @@ class RestrictLeave(HorillaModel): def __str__(self) -> str: return f"{self.title}" + + +class CompensatoryLeaveRequest(HorillaModel): + from attendance.models import Attendance + + leave_type_id = models.ForeignKey( + LeaveType, on_delete=models.PROTECT, verbose_name="Leave type" + ) + employee_id = models.ForeignKey( + Employee, on_delete=models.CASCADE, verbose_name="Employee" + ) + attendance_id = models.ManyToManyField(Attendance, verbose_name="Attendance") + requested_days = models.FloatField(blank=True, null=True) + requested_date = models.DateField(default=timezone.now) + description = models.TextField(max_length=255) + status = models.CharField( + max_length=30, choices=LEAVE_ALLOCATION_STATUS, default="requested" + ) + reject_reason = models.TextField(blank=True, max_length=255) + history = HorillaAuditLog( + related_name="history_set", + bases=[ + HorillaAuditInfo, + ], + ) + objects = HorillaCompanyManager( + related_company_field="employee_id__employee_work_info__company_id" + ) + + class Meta: + ordering = ["-id"] + + def __str__(self): + return f"{self.employee_id}| {self.leave_type_id}| {self.id}" + + def assign_compensatory_leave_type(self): + available_leave, created = AvailableLeave.objects.get_or_create( + employee_id=self.employee_id, + leave_type_id=self.leave_type_id, + ) + available_leave.available_days += self.requested_days + available_leave.save() + + def exclude_compensatory_leave(self): + if AvailableLeave.objects.filter( + employee_id=self.employee_id, + leave_type_id=self.leave_type_id, + ).exists(): + available_leave = AvailableLeave.objects.filter( + employee_id=self.employee_id, + leave_type_id=self.leave_type_id, + ).first() + if available_leave.available_days < self.requested_days: + available_leave.available_days = 0 + available_leave.carryforward_days = max( + 0, + available_leave.carryforward_days + - (self.requested_days - available_leave.available_days), + ) + else: + available_leave.available_days -= self.requested_days + available_leave.save() + + def save(self, *args, **kwargs): + self.leave_type_id = LeaveType.objects.filter( + is_compensatory_leave=True + ).first() + super().save(*args, **kwargs) + + +class LeaveGeneralSetting(HorillaModel): + """ + AttendanceGeneralSettings + """ + + compensatory_leave = models.BooleanField(default=True) + company_id = models.ForeignKey(Company, on_delete=models.CASCADE, null=True) + + +class CompensatoryLeaverequestComment(HorillaModel): + """ + LeaveallocationrequestComment Model + """ + + request_id = models.ForeignKey(CompensatoryLeaveRequest, on_delete=models.CASCADE) + employee_id = models.ForeignKey(Employee, on_delete=models.CASCADE) + files = models.ManyToManyField(LeaverequestFile, blank=True) + comment = models.TextField(null=True, verbose_name=_("Comment"), max_length=255) + + def __str__(self) -> str: + return f"{self.comment}" diff --git a/leave/templates/leave/compensatory_leave/attendance_id.html b/leave/templates/leave/compensatory_leave/attendance_id.html new file mode 100644 index 000000000..ad8938412 --- /dev/null +++ b/leave/templates/leave/compensatory_leave/attendance_id.html @@ -0,0 +1 @@ +{{form.attendance_id}} \ No newline at end of file diff --git a/leave/templates/leave/compensatory_leave/comp_leave_form.html b/leave/templates/leave/compensatory_leave/comp_leave_form.html new file mode 100644 index 000000000..e100043a6 --- /dev/null +++ b/leave/templates/leave/compensatory_leave/comp_leave_form.html @@ -0,0 +1,43 @@ +{% load i18n %} +{% if form.errors %} +
+
+ {% for error in form.non_field_errors %} +
{{ error }}
+ {% endfor %} +
+
+{% endif %} +
+ + {% if form.instance.id %} + {% trans "Update Compensetory Leave Request" %} + {% else %} + {% trans "Create Compensetory Leave Request" %} + {% endif %} + + +
+
+
+ {% csrf_token %} {{form.as_p}} +
+
+ \ No newline at end of file diff --git a/leave/templates/leave/compensatory_leave/compensatory_leave_comment.html b/leave/templates/leave/compensatory_leave/compensatory_leave_comment.html new file mode 100644 index 000000000..3e69b84b1 --- /dev/null +++ b/leave/templates/leave/compensatory_leave/compensatory_leave_comment.html @@ -0,0 +1,177 @@ +{% load i18n static %} + + +{% if messages %} +
+ {% for message in messages %} +
{{ message }}
+ {% endfor %} +
+ +{% endif %} + +
+ + + + {% trans "Comments" %} +
+ +
+ {% csrf_token %} + +
+ + +
+ + +
+ + +{% if comments %} +
    + {% for comment in comments %} +
  1. + {{ comment.comment }} + + + + + +
    + {% for file in comment.files.all %} + + {% endfor %} + +
    + {% csrf_token %} + + + +
    +
    + + {% trans 'by' %} + + {{ comment.employee_id.get_full_name }} @ {{comment.request_id.employee_id.get_full_name }} + {% trans "'s leave request" %} + +
    +
    +
    +
  2. + + {% endfor %} +
+{% else %} +
+
+
+ {% trans "There are no comments to show." %} + +
+
+
+{% endif %} + + + + + + + diff --git a/leave/templates/leave/compensatory_leave/compensatory_leave_reject_form..html b/leave/templates/leave/compensatory_leave/compensatory_leave_reject_form..html new file mode 100644 index 000000000..1064a985d --- /dev/null +++ b/leave/templates/leave/compensatory_leave/compensatory_leave_reject_form..html @@ -0,0 +1,38 @@ +{% load i18n %} {% if form.errors %} + +
+
+ {% for error in form.non_field_errors %} +
{{ error }}
+ {% endfor %} +
+
+{% endif %} +
+

+ {% trans "Reject Compensatory Leave Request" %} +

+ +
+
+
+
+ + {{form.reason}} {{form.errors}} +
+
+ +
+
+
diff --git a/leave/templates/leave/compensatory_leave/compensatory_leave_req_list.html b/leave/templates/leave/compensatory_leave/compensatory_leave_req_list.html new file mode 100644 index 000000000..6e5012acf --- /dev/null +++ b/leave/templates/leave/compensatory_leave/compensatory_leave_req_list.html @@ -0,0 +1,426 @@ +{% load i18n %} +{% load static %} +{% load basefilters %} +{% include 'filter_tags.html' %} +{% if messages %} +
+ {% for message in messages %} +
+
+ {{ message }} +
+
+ {% endfor %} +
+{% endif %} + +
+
+ {% if my_comp_leave_requests %} + +
+
+
+
+
{% trans "Employee" %}
+
{% trans "Leave Type" %}
+
{% trans "Attendance Dates" %}
+
{% trans "Requested Days" %}
+
{% trans "Created By" %}
+
{% trans "Status" %}
+
{% trans "Description" %}
+
{% trans "Comment" %}
+
{% trans "Actions" %}
+
+
+
+ {% for comp_leave_request in my_comp_leave_requests %} +
+
+
+
+ {% if comp_leave_request.employee_id.employee_profile %} + + {% else %} + + {% endif %} +
+ {{comp_leave_request.employee_id}} +
+
+
{{comp_leave_request.leave_type_id}}
+
+ {% for attendance in comp_leave_request.attendance_id.all %} + {{ attendance.attendance_date }}
+ {% endfor %} +
+
{{comp_leave_request.requested_days}}
+
{{comp_leave_request.created_by.employee_get}}
+
{{comp_leave_request.get_status_display}}
+
{{comp_leave_request.description|truncatechars:25}}
+ +
+ +
+ +
+
+ {% if comp_leave_request.status == 'requested' %} + + {% else %} + + {% endif %} + {% if comp_leave_request.status != 'approved' %} + + + + {% else %} + + {% endif %} +
+
+
+ {% endfor %} +
+
+
+ + +
+ + {% trans "Page" %} {{ my_comp_leave_requests.number }} {% trans "of" %} {{ my_comp_leave_requests.paginator.num_pages }}. + + +
+ + {% else %} +
+
+
+ +

{% trans "You have No leave requests for this filter." %}

+
+
+
+ {% endif %} +
+ + {% if request.user|is_reportingmanager or perms.leave.view_compensatoryleaverequest %} +
+ {% if comp_leave_requests %} + +
+
+
+
+
{% trans "Employee" %}
+
{% trans "Leave Type" %}
+
{% trans "Attendance Dates" %}
+
{% trans "Requested Days" %}
+
{% trans "Created By" %}
+
{% trans "Status" %}
+
{% trans "Description" %}
+
{% trans "Comment" %}
+
{% trans "Actions" %}
+
{% trans "Confirmation" %}
+
+
+
+ {% for comp_leave_request in comp_leave_requests %} +
+
+
+
+ +
+ {{comp_leave_request.employee_id}} +
+
+
{{comp_leave_request.leave_type_id}}
+
+ {% for attendance in comp_leave_request.attendance_id.all %} + {{ attendance.attendance_date }}
+ {% endfor %} +
+
{{comp_leave_request.requested_days}}
+
{{comp_leave_request.created_by.employee_get}}
+
{{comp_leave_request.get_status_display}}
+
{{ comp_leave_request.description|truncatechars:20}}
+ +
+ +
+ +
+
+ {% if comp_leave_request.status == 'requested' %} + + {% else %} + + {% endif %} + {% if comp_leave_request.status != 'approved' %} + + + + {% else %} + + {% endif %} +
+
+
+
+ + {% if perms.leave.change_leaveallocationrequest or request.user|is_reportingmanager %} + {% if comp_leave_request.status == 'requested' %} + + + + {% else %} + + + + {% endif %} + {% if comp_leave_request.status == 'requested' or comp_leave_request.status == 'approved' %} + + + + {% else %} + + + + {% endif %} + {% endif %} +
+
+
+ {% endfor %} +
+
+
+ + +
+ + {% trans "Page" %} {{ comp_leave_requests.number }} {% trans "of" %} {{ comp_leave_requests.paginator.num_pages }}. + + +
+ + {% else %} +
+
+ +

{% trans "You have No leave requests for this filter." %}

+
+
+
+ {% endif %} +
+ {% endif %} +
+ + + + + + + + + + \ No newline at end of file diff --git a/leave/templates/leave/compensatory_leave/compensatory_leave_view.html b/leave/templates/leave/compensatory_leave/compensatory_leave_view.html new file mode 100644 index 000000000..e3ba0aaf5 --- /dev/null +++ b/leave/templates/leave/compensatory_leave/compensatory_leave_view.html @@ -0,0 +1,421 @@ +{% extends 'index.html' %} {% block content %} {% load static %} {% load i18n %} +{% load basefilters %} + + + +
+
+

+ {% trans "Compensatory Leave Requests" %} +

+ + + +
+
+ +
+
+ + +
+
+ + +
+ + {% comment %}
+ + +
{% endcomment %} +
+ + + +
+
+ +
+
+ +
+
+ + +
+ {% if comp_leave_requests or my_comp_leave_requests %} + +
+ + + {% trans "Rejected" %} + + + + {% trans "Requested" %} + + +
+ + +
+ {% include "leave/compensatory_leave/compensatory_leave_req_list.html" %} +
+ + {% else %} +
+
+ +

+ {% trans "There are no compensatory leave requests at the moment." %} +

+
+
+ {% endif %} +
+ + + + + + +
+
+
+
+ + + + + + + +{% endblock %} diff --git a/leave/templates/leave/leave_allocation_request/leave_allocation_request_list.html b/leave/templates/leave/leave_allocation_request/leave_allocation_request_list.html index b2a75bc42..98e46dcbf 100644 --- a/leave/templates/leave/leave_allocation_request/leave_allocation_request_list.html +++ b/leave/templates/leave/leave_allocation_request/leave_allocation_request_list.html @@ -58,7 +58,7 @@
{{leave_allocation_request.leave_type_id}}
{{leave_allocation_request.requested_days}}
-
{{leave_allocation_request.created_by}}
+
{{leave_allocation_request.created_by.employee_get}}
{{leave_allocation_request.get_status_display}}
{{ leave_allocation_request.description|truncatechars:25}}
@@ -202,7 +202,7 @@
{{leave_allocation_request.leave_type_id}}
{{leave_allocation_request.requested_days}}
-
{{leave_allocation_request.created_by}}
+
{{leave_allocation_request.created_by.employee_get}}
{{leave_allocation_request.get_status_display}}
{{ leave_allocation_request.description|truncatechars:20}}
diff --git a/leave/templates/leave/leave_type/leave_types.html b/leave/templates/leave/leave_type/leave_types.html index 766329d80..7973c0dcc 100644 --- a/leave/templates/leave/leave_type/leave_types.html +++ b/leave/templates/leave/leave_type/leave_types.html @@ -52,7 +52,7 @@