From d2476619c9a09297df2511a24441764d03632937 Mon Sep 17 00:00:00 2001 From: Horilla Date: Wed, 4 Dec 2024 14:46:55 +0530 Subject: [PATCH] [UPDT] ATTENDANCE: Updated attendance app by adding htmx function in attendance dashboard cards --- .../attendance/batch_attendance_form.html | 10 +- .../attendance/attendance/batches_list.html | 8 +- .../attendance/dashboard/dashboard.html | 58 +++--- .../dashboard/on_break_employees.html | 27 +++ .../attendance/dashboard/overtime_table.html | 172 ++++++++-------- .../dashboard/to_validate_table.html | 190 ++++++++--------- attendance/urls.py | 30 +-- attendance/views/dashboard.py | 191 ++++++++---------- .../attendance_validate.html | 79 -------- .../request_and_approve/overtime_approve.html | 74 ------- templates/birthdays_container.html | 6 +- templates/dashboard_tile_container.html | 6 +- 12 files changed, 340 insertions(+), 511 deletions(-) create mode 100644 attendance/templates/attendance/dashboard/on_break_employees.html delete mode 100644 base/templates/request_and_approve/attendance_validate.html delete mode 100644 base/templates/request_and_approve/overtime_approve.html diff --git a/attendance/templates/attendance/attendance/batch_attendance_form.html b/attendance/templates/attendance/attendance/batch_attendance_form.html index eb181bdc0..0593f5ffe 100644 --- a/attendance/templates/attendance/attendance/batch_attendance_form.html +++ b/attendance/templates/attendance/attendance/batch_attendance_form.html @@ -5,18 +5,18 @@ reloadMessage() {% if previous_url %} - {% endif %} - + {% endif %}
-
{{form.as_p}}
-
\ No newline at end of file + diff --git a/attendance/templates/attendance/attendance/batches_list.html b/attendance/templates/attendance/attendance/batches_list.html index d4954b3be..799128cfa 100644 --- a/attendance/templates/attendance/attendance/batches_list.html +++ b/attendance/templates/attendance/attendance/batches_list.html @@ -48,7 +48,7 @@ >
{% if batch.created_by == request.user %} -
- {% if perms.attendance.delete_batchattendance %} -
@@ -105,4 +105,4 @@
{% endif %} - \ No newline at end of file + diff --git a/attendance/templates/attendance/dashboard/dashboard.html b/attendance/templates/attendance/dashboard/dashboard.html index a34370e99..f92d97e34 100644 --- a/attendance/templates/attendance/dashboard/dashboard.html +++ b/attendance/templates/attendance/dashboard/dashboard.html @@ -60,8 +60,7 @@
+ style="min-height: 423px;">
@@ -143,48 +142,38 @@ {% trans "On Break" %}
-
- {% if on_break %} -
    - {% for emp in on_break %} -
  • -
    -
    - Amy Winehouse -
    - {{emp.employee_id}} -
    -
  • - {% endfor %} -
- {% else %} -
-
- -

{% trans "No employees are currently taking a break." %}

-
-
- {% endif %} +
+
- {% trans "Overtime To Validate" %} + {% trans "Overtime To Approve" %}
-
- {% include "attendance/dashboard/overtime_table.html" %} +
+
-
-
- {% include "attendance/dashboard/to_validate_table.html" %} +
+
+
+
+ {% trans "Attendance To Validate" %} +
+
+
+
+
@@ -241,7 +230,6 @@
- - - {% endblock content %} +
+{% endblock content %} diff --git a/attendance/templates/attendance/dashboard/on_break_employees.html b/attendance/templates/attendance/dashboard/on_break_employees.html new file mode 100644 index 000000000..eff84d30b --- /dev/null +++ b/attendance/templates/attendance/dashboard/on_break_employees.html @@ -0,0 +1,27 @@ +{% load static %} +{% load i18n %} +{% if on_break %} +
    + {% for emp in on_break %} +
  • +
    +
    + Amy Winehouse +
    + {{emp.employee_id}} +
    +
  • + {% endfor %} +
+{% else %} +
+
+ +

+ {% trans "No employees are currently taking a break." %}

+
+
+{% endif %} \ No newline at end of file diff --git a/attendance/templates/attendance/dashboard/overtime_table.html b/attendance/templates/attendance/dashboard/overtime_table.html index bc164d32e..41f6aee49 100644 --- a/attendance/templates/attendance/dashboard/overtime_table.html +++ b/attendance/templates/attendance/dashboard/overtime_table.html @@ -1,92 +1,104 @@ {% load i18n static %} {% if overtime_attendances %} -
-
-
-
-
- {% trans "Employee" %} +
+
+
+
+
+ {% trans "Employee" %} +
+ {% if not main_dashboard %} +
{% trans "Check-In" %}
+
+ {% trans "In Date" %} +
+
{% trans "Check-Out" %}
+
+ {% trans "Out Date" %} +
+ {% endif %} +
+ {% trans "Overtime" %} +
+
{% trans "Actions" %}
-
{% trans "Check-In" %}
-
- {% trans "In Date" %} -
-
{% trans "Check-Out" %}
-
- {% trans "Out Date" %} -
-
- {% trans "Overtime" %} -
-
{% trans "Actions" %}
-
- {% for attendance in overtime_attendances %} -
-
-
-
-
- + {% for attendance in overtime_attendances %} +
+
+
+
+
+ +
+ {{attendance.employee_id}}
- {{attendance.employee_id}} +
+ {% if not main_dashboard %} +
+ {{attendance.attendance_clock_in}} +
+
+ {{attendance.attendance_clock_in_date}} +
+
+ {{attendance.attendance_clock_out}} +
+
+ {{attendance.attendance_clock_out_date}} +
+ {% endif %} + +
+ {{attendance.attendance_overtime}} +
+
-
- {{attendance.attendance_clock_in}} -
-
- {{attendance.attendance_clock_in_date}} -
-
- {{attendance.attendance_clock_out}} -
-
- {{attendance.attendance_clock_out_date}} -
-
- {{attendance.attendance_overtime}} -
-
-
- {% endfor %} + {% endfor %} +
{% else %} -
-
- -

{% trans "No Overtime to Validate...." %}

-
-
+
+
+ +

{% trans "No Overtime to Validate...." %}

+
+
+{% endif %} +{% if overtime_attendances.has_previous or overtime_attendances.has_next %} +
+ {% if overtime_attendances.has_previous %} + + + + {% endif %} + {% if overtime_attendances.has_next %} + + + + {% endif %} + {% if overtime_attendances.has_previous or overtime_attendances.has_next %} + + {% trans "Page" %} {{ overtime_attendances.number }} {%trans "of" %} + {{overtime_attendances.paginator.num_pages }} + + {% endif %} +
{% endif %} diff --git a/attendance/templates/attendance/dashboard/to_validate_table.html b/attendance/templates/attendance/dashboard/to_validate_table.html index 3caaf7a0b..1d86eb272 100644 --- a/attendance/templates/attendance/dashboard/to_validate_table.html +++ b/attendance/templates/attendance/dashboard/to_validate_table.html @@ -1,142 +1,122 @@ {% load i18n static basefilters %} -
-
- {% if validate_attendances.has_previous %} - - - - {% endif %} - - {% trans 'Attendance To Validate' %} - - {% if validate_attendances.has_next %} - - - - {% endif %} -
-
- {% if validate_attendances %} -
-
-
-
-
+{% if validate_attendances %} +
+
+
+
+
{% trans "Employee" %} -
-
- {% trans "Date" %} +
+ {% if not main_dashboard %} +
+ {% trans "Date" %}
{% trans "Check-In" %}
-
- {% trans "In Date" %} +
+ {% trans "In Date" %}
{% trans "Check-Out" %}
-
- {% trans "Out Date" %} +
+ {% trans "Out Date" %}
{% trans "Shift" %}
{% trans "Work Type" %}
{% trans "Min Hour" %}
-
+
+ {% trans "Pending Hour" %} +
+ {% endif %} +
{% trans "At Work" %} -
-
- {% trans "Pending Hour" %} -
-
{% trans "Actions" %}
+
{% trans "Actions" %}
- {% for attendance in validate_attendances %} -
-
+
+ {% for attendance in validate_attendances %} +
+
-
-
-
- Mary Magdalene -
- {{attendance.employee_id}} +
+
+
+ Mary Magdalene
+ {{attendance.employee_id}}
+
+ {% if not main_dashboard %}
{{attendance.attendance_date}}
- {{attendance.attendance_clock_in}} + {{attendance.attendance_clock_in}}
- {{attendance.attendance_clock_in_date}} + {{attendance.attendance_clock_in_date}}
- {{attendance.attendance_clock_out}} + {{attendance.attendance_clock_out}}
- {{attendance.attendance_clock_out_date}} + {{attendance.attendance_clock_out_date}}
{{attendance.shift_id}}
{{attendance.work_type_id}}
{{attendance.minimum_hour}}
-
- {{attendance.attendance_worked_hour}} -
{{attendance.hours_pending}}
-
- {% if perms.attendance.change_attendance or request.user|is_reportingmanager %} - + {{attendance.attendance_worked_hour}} +
+ - + + {% endif %}
-
- {% endfor %} -
-
- {% else %} -
-
- +
+
+ {% endfor %} +
+
+{% else %} +
+
+

{% trans "All Attendance Validated." %}

-
-
+
+
+{% endif %} +{% if validate_attendances.has_previous or validate_attendances.has_next %} +
+ {% if validate_attendances.has_previous %} + + + + {% endif %} + {% if validate_attendances.has_next %} + + + + {% endif %} + {% if validate_attendances.has_previous or validate_attendances.has_next %} + + {% trans "Page" %} {{ validate_attendances.number }} {%trans "of" %} + {{validate_attendances.paginator.num_pages }} + {% endif %}
-
+{% endif %} diff --git a/attendance/urls.py b/attendance/urls.py index a27943e1f..4307c8fd4 100644 --- a/attendance/urls.py +++ b/attendance/urls.py @@ -225,16 +225,26 @@ urlpatterns = [ path( "dashboard", attendance.views.dashboard.dashboard, name="attendance-dashboard" ), + path( + "on-break-employees", + attendance.views.dashboard.on_break_employees, + name="on-break-employees", + ), + path( + "dashboard-approve-overtimes", + attendance.views.dashboard.dashboard_approve_overtimes, + name="dashboard-approve-overtimes", + ), + path( + "dashboard-validate-attendances", + attendance.views.dashboard.dashboard_validate_attendances, + name="dashboard-validate-attendances", + ), path( "department-overtime-chart", attendance.views.dashboard.department_overtime_chart, name="department-overtime-chart", ), - path( - "attendance-validate-table/", - attendance.views.dashboard.validated_attendances_table, - name="attendance-validate-table", - ), path( "dashboard-attendance/", attendance.views.dashboard.dashboard_attendance, @@ -440,16 +450,6 @@ urlpatterns = [ attendance.views.penalty.cut_available_leave, name="cut-penalty", ), - path( - "dashboard-overtime-approve", - attendance.views.dashboard.dashboard_overtime_approve, - name="dashboard-overtime-approve", - ), - path( - "dashboard-attendance-validate", - attendance.views.dashboard.dashboard_attendance_validate, - name="dashboard-attendance-validate", - ), path( "attendance-settings-view/", views.validation_condition_view, diff --git a/attendance/views/dashboard.py b/attendance/views/dashboard.py index f3ce07774..05a56ef48 100644 --- a/attendance/views/dashboard.py +++ b/attendance/views/dashboard.py @@ -8,7 +8,6 @@ import json from datetime import date, datetime from django.apps import apps -from django.db.models import Q from django.http import JsonResponse from django.shortcuts import render from django.utils.translation import gettext_lazy as _ @@ -75,12 +74,6 @@ def dashboard(request): """ This method is used to render individual dashboard for attendance module """ - page_number = request.GET.get("page") - previous_data = request.GET.urlencode() - employees = Employee.objects.filter( - is_active=True, - ).filter(~Q(employee_work_info__shift_id=None)) - total_employees = len(employees) today = datetime.today() week_day = today.strftime("%A").lower() @@ -101,10 +94,61 @@ def dashboard(request): marked_attendances_ratio = ( f"{(marked_attendances / expected_attendances) * 100:.2f}" ) + + return render( + request, + "attendance/dashboard/dashboard.html", + { + "on_time": on_time, + "on_time_ratio": on_time_ratio, + "late_come": late_come_obj, + "late_come_ratio": late_come_ratio, + "expected_attendances": expected_attendances, + "marked_attendances": marked_attendances, + "marked_attendances_ratio": marked_attendances_ratio, + }, + ) + + +@login_required +@hx_request_required +def on_break_employees(request): + """ + Fetches and displays employees who left early (early outs) for the current day. + + This view retrieves all records from the `AttendanceLateComeEarlyOut` model + where the type is "early_out" and the associated attendance date matches the current date. + The results are passed to the template `on_break_employees.html` for rendering + """ + today = datetime.today() early_outs = AttendanceLateComeEarlyOut.objects.filter( type="early_out", attendance_id__attendance_date=today ) + context = { + "on_break": early_outs, + } + return render(request, "attendance/dashboard/on_break_employees.html", context) + +@login_required +@hx_request_required +def dashboard_approve_overtimes(request): + """ + Displays and validates employee overtime records for the dashboard. + + This view retrieves a paginated list of employee attendance records with + overtime that meets or exceeds a specified minimum threshold, which is defined + in the `AttendanceValidationCondition` model. Only records that are validated + but not yet approved are included, and the results are filtered based on the + user's subordinate permissions. + """ + main_dashboard = None + referer = request.META.get("HTTP_REFERER", "/") + referer = "/" + "/".join(referer.split("/")[3:]) + if referer == "/": + main_dashboard = True + + page_number = request.GET.get("page") condition = AttendanceValidationCondition.objects.first() min_ot = strtime_seconds("00:00") if condition is not None and condition.minimum_overtime_to_approve is not None: @@ -121,6 +165,33 @@ def dashboard(request): queryset=ot_attendances, ) + id_list = [ot.id for ot in ot_attendances] + ot_attendances_ids = json.dumps(list(id_list)) + ot_attendances = paginator_qry(ot_attendances, page_number) + context = { + "overtime_attendances": ot_attendances, + "ot_attendances_ids": ot_attendances_ids, + "main_dashboard": main_dashboard, + } + return render(request, "attendance/dashboard/overtime_table.html", context) + + +@login_required +@hx_request_required +def dashboard_validate_attendances(request): + """ + Displays and validates employee attendance records for the dashboard. + + This view retrieves a paginated list of attendance records that have not yet + been validated. Only records belonging to active employees and accessible + subordinates, as determined by the user's permissions, are included in the results. + """ + main_dashboard = None + referer = request.META.get("HTTP_REFERER", "/") + referer = "/" + "/".join(referer.split("/")[3:]) + if referer == "/": + main_dashboard = True + page_number = request.GET.get("page") validate_attendances = Attendance.objects.filter( attendance_validated=False, employee_id__is_active=True ) @@ -130,52 +201,16 @@ def dashboard(request): perm="attendance.change_overtime", queryset=validate_attendances, ) - validate_attendances = paginator_qry(validate_attendances, page_number) - id_list = [ot.id for ot in ot_attendances] + validate_id_list = [val.id for val in validate_attendances] - ot_attendances_ids = json.dumps(list(id_list)) validate_attendances_ids = json.dumps(list(validate_id_list)) - return render( - request, - "attendance/dashboard/dashboard.html", - { - "total_employees": total_employees, - "on_time": on_time, - "on_time_ratio": on_time_ratio, - "late_come": late_come_obj, - "late_come_ratio": late_come_ratio, - "expected_attendances": expected_attendances, - "marked_attendances": marked_attendances, - "marked_attendances_ratio": marked_attendances_ratio, - "on_break": early_outs, - "overtime_attendances": ot_attendances, - "validate_attendances": validate_attendances, - "pd": previous_data, - "ot_attendances_ids": ot_attendances_ids, - "validate_attendances_ids": validate_attendances_ids, - }, - ) - - -@login_required -@hx_request_required -def validated_attendances_table(request): - page_number = request.GET.get("page") - previous_data = request.GET.urlencode() - validate_attendances = Attendance.objects.filter( - attendance_validated=False, employee_id__is_active=True - ) - validate_attendances = filtersubordinates( - request=request, - perm="attendance.change_attendance", - queryset=validate_attendances, - ) + validate_attendances = paginator_qry(validate_attendances, page_number) context = { - "validate_attendances": paginator_qry(validate_attendances, page_number), - "pd": previous_data, + "validate_attendances": validate_attendances, + "validate_attendances_ids": validate_attendances_ids, + "main_dashboard": main_dashboard, } - return render(request, "attendance/dashboard/to_validate_table.html", context) @@ -417,63 +452,3 @@ def department_overtime_chart(request): } return JsonResponse(response) - - -@login_required -def dashboard_overtime_approve(request): - previous_data = request.GET.urlencode() - page_number = request.GET.get("page") - min_ot = strtime_seconds("00:00") - if apps.is_installed("attendance"): - from attendance.models import Attendance, AttendanceValidationCondition - - condition = AttendanceValidationCondition.objects.first() - if condition is not None and condition.minimum_overtime_to_approve is not None: - min_ot = strtime_seconds(condition.minimum_overtime_to_approve) - ot_attendances = Attendance.objects.filter( - overtime_second__gte=min_ot, - attendance_validated=True, - employee_id__is_active=True, - attendance_overtime_approve=False, - ) - else: - ot_attendances = None - ot_attendances = filtersubordinates( - request, ot_attendances, "attendance.change_attendance" - ) - ot_attendances = paginator_qry(ot_attendances, page_number) - ot_attendances_ids = json.dumps([instance.id for instance in ot_attendances]) - return render( - request, - "request_and_approve/overtime_approve.html", - { - "overtime_attendances": ot_attendances, - "ot_attendances_ids": ot_attendances_ids, - "pd": previous_data, - }, - ) - - -@login_required -def dashboard_attendance_validate(request): - previous_data = request.GET.urlencode() - page_number = request.GET.get("page") - validate_attendances = Attendance.objects.filter( - attendance_validated=False, employee_id__is_active=True - ) - validate_attendances = filtersubordinates( - request, validate_attendances, "attendance.change_attendance" - ) - validate_attendances = paginator_qry(validate_attendances, page_number) - validate_attendances_ids = json.dumps( - [instance.id for instance in validate_attendances] - ) - return render( - request, - "request_and_approve/attendance_validate.html", - { - "validate_attendances": validate_attendances, - "validate_attendances_ids": validate_attendances_ids, - "pd": previous_data, - }, - ) diff --git a/base/templates/request_and_approve/attendance_validate.html b/base/templates/request_and_approve/attendance_validate.html deleted file mode 100644 index b3e6dbc44..000000000 --- a/base/templates/request_and_approve/attendance_validate.html +++ /dev/null @@ -1,79 +0,0 @@ -{% load i18n static %} -{% if validate_attendances %} -
-
-
-
-
- {% trans "Employee" %} -
-
- {% trans "Worked Hours" %} -
-
{% trans "Actions" %}
-
-
- {% for attendance in validate_attendances %} -
-
-
-
-
- -
- {{attendance.employee_id}} -
-
-
- {{attendance.attendance_worked_hour}} -
- -
-
- {% endfor %} -
-
-{% else %} -
-

- - {% trans "No records available at the moment." %} -

-
-{% endif %} -{% if validate_attendances.has_next or validate_attendances.has_previous %} -
- {% if validate_attendances.has_previous %} - - - - {% endif %} - - {% if validate_attendances.has_next %} - - - - {% endif %} - - - {% trans "Page" %} {{ validate_attendances.number }} {%trans "of" %} - {{validate_attendances.paginator.num_pages }} - -
-{% endif %} diff --git a/base/templates/request_and_approve/overtime_approve.html b/base/templates/request_and_approve/overtime_approve.html deleted file mode 100644 index 87de8cae8..000000000 --- a/base/templates/request_and_approve/overtime_approve.html +++ /dev/null @@ -1,74 +0,0 @@ -{% load i18n static %} -{% if overtime_attendances %} -
-
-
-
-
- {% trans "Employee" %} -
-
- {% trans "Overtime" %} -
-
{% trans "Actions" %}
-
-
- {% for attendance in overtime_attendances %} -
-
-
-
-
- -
- {{attendance.employee_id}} -
-
-
- {{attendance.attendance_overtime}} -
- -
-
- {% endfor %} -
-
-{% else %} -
-

- - {% trans "No records available at the moment." %} -

-
-{% endif %} -{% if overtime_attendances.has_next or overtime_attendances.has_previous %} -
- {% if overtime_attendances.has_previous %} - - - - {% endif %} - {% if overtime_attendances.has_next %} - - - - {% endif %} - {% if overtime_attendances.has_next or overtime_attendances.has_previous %} - - {% trans "Page" %} {{ overtime_attendances.number }} {%trans "of" %} - {{overtime_attendances.paginator.num_pages }} - - {% endif %} -
-{% endif %} diff --git a/templates/birthdays_container.html b/templates/birthdays_container.html index 15d7d098d..19d3e76c7 100644 --- a/templates/birthdays_container.html +++ b/templates/birthdays_container.html @@ -20,11 +20,11 @@
    {% for birthday in birthdays %} -
  • {% endfor %}
-{% endif %} \ No newline at end of file +{% endif %} diff --git a/templates/dashboard_tile_container.html b/templates/dashboard_tile_container.html index 584deaadd..3d6aa88ea 100644 --- a/templates/dashboard_tile_container.html +++ b/templates/dashboard_tile_container.html @@ -354,7 +354,7 @@
+ hx-get="{% url 'dashboard-approve-overtimes' %}" hx-trigger="load">
@@ -377,7 +377,7 @@
+ hx-get="{% url 'dashboard-validate-attendances' %}" hx-trigger="load">
@@ -445,7 +445,7 @@
{% endif %} {% if "asset"|app_installed and not 'asset_request_approve' in charts %} - {% if perms.asset.change_assetrequest or request.user|is_reportingmanager %} + {% if perms.asset.view_assetrequest %}