[UPDT] ATTENDANCE: On time date filteration in main dashboard

This commit is contained in:
Horilla
2023-10-17 10:22:39 +05:30
parent 2be26d42c7
commit 3a2ffc0f57
5 changed files with 208 additions and 21 deletions

View File

@@ -16,6 +16,8 @@ from attendance.models import (
AttendanceLateComeEarlyOut,
AttendanceActivity,
)
from django.utils.translation import gettext_lazy as _
from django.db.models import Subquery, OuterRef
class FilterSet(django_filters.FilterSet):
@@ -155,12 +157,10 @@ class AttendanceOverTimeFilter(FilterSet):
def __init__(self, data=None, queryset=None, *, request=None, prefix=None):
super().__init__(data=data, queryset=queryset, request=request, prefix=prefix)
class LateComeEarlyOutFilter(FilterSet):
"""
LateComeEarlyOutFilter class
"""
search = django_filters.CharFilter(method=filter_by_name)
attendance_date__gte = django_filters.DateFilter(
field_name="attendance_id__attendance_date",
@@ -225,8 +225,6 @@ class LateComeEarlyOutFilter(FilterSet):
month = django_filters.CharFilter(
field_name="attendance_id__attendance_date",lookup_expr="month"
)
week = django_filters.CharFilter(field_name="attendance_id__attendance_date",lookup_expr="week")
class Meta:
@@ -413,6 +411,13 @@ class AttendanceFilters(FilterSet):
overtime_second__gte = DurationInSecondsFilter(
field_name="overtime_second", lookup_expr="gte"
)
year = django_filters.CharFilter(field_name="attendance_date",lookup_expr="year")
month = django_filters.CharFilter(
field_name="attendance_date",lookup_expr="month"
)
week = django_filters.CharFilter(field_name="attendance_date",lookup_expr="week")
department = django_filters.CharFilter(field_name="employee_id__employee_work_info__department_id__department",lookup_expr="icontains")
class Meta:
"""
@@ -446,6 +451,7 @@ class AttendanceFilters(FilterSet):
"overtime_second__lte",
"overtime_second__gte",
"overtime_second",
"department",
]
widgets = {

View File

@@ -0,0 +1,134 @@
{% load i18n %}
{% load attendancefilters %}
{% load basefilters %}
{% include 'filter_tags.html' %}
<style>
.disabled {
opacity: 0.5;
cursor: not-allowed;
}
</style>
<div class="oh-sticky-table">
<div class="oh-sticky-table__table oh-table--sortable">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th" >
<div class="d-flex">
<div class="">
<input type="checkbox" title='{% trans "Select All" %}' class="oh-input oh-input__checkbox mt-1 mr-2 all-attendances" />
</div>
<div hx-get="{% url 'attendance-search' %}?{{pd}}&sortby=employee_id__employee_first_name" hx-target="#tab_contents">
{% trans "Employee" %}
</div>
</div>
</div>
<div class="oh-sticky-table__th" hx-get="{% url 'attendance-search' %}?{{pd}}&sortby=attendance_date" hx-target="#tab_contents">{% trans "Date" %}</div>
<div class="oh-sticky-table__th">{% trans "Day" %}</div>
<div class="oh-sticky-table__th" >{% trans "Check-In" %}</div>
<div class="oh-sticky-table__th" hx-get="{% url 'attendance-search' %}?{{pd}}&sortby=attendance_clock_in_date" hx-target="#tab_contents">{% trans "In Date" %}</div>
<div class="oh-sticky-table__th">{% trans "Check-Out" %}</div>
<div class="oh-sticky-table__th" hx-get="{% url 'attendance-search' %}?{{pd}}&sortby=attendance_clock_out_date" hx-target="#tab_contents">{% trans "Out Date" %}</div>
<div class="oh-sticky-table__th">{% trans "Shift" %}</div>
<div class="oh-sticky-table__th">{% trans "Work Type" %}</div>
<div class="oh-sticky-table__th" >{% trans "Min Hour" %}</div>
<div class="oh-sticky-table__th" hx-get="{% url 'attendance-search' %}?{{pd}}&sortby=at_work_second" hx-target="#tab_contents">{% trans "At Work" %}</div>
<div class="oh-sticky-table__th" hx-get="{% url 'attendance-search' %}?{{pd}}&sortby=overtime_second" hx-target="#tab_contents">{% trans "Overtime" %}</div>
<div class="oh-sticky-table__th"></div>
</div>
</div>
<div class="oh-sticky-table__tbody">
{% for attendance in attendances %}
<div class="oh-sticky-table__tr"
draggable="false">
<div class="oh-sticky-table__sd">
<div class="d-flex">
<div class="">
<input type="checkbox" id="{{attendance.id}}" class="oh-input attendance-checkbox oh-input__checkbox mt-2 mr-2 all-attendance-row" />
</div>
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img
src="https://ui-avatars.com/api/?name={{attendance.employee_id.employee_first_name}}+{{attendance.employee_id.employee_last_name}}&background=random"
class="oh-profile__image"
alt="Mary Magdalene"
/>
</div>
<span class="oh-profile__name oh-text--dark"
>{{attendance.employee_id}}</span
>
</div>
</div>
</div>
<div class="oh-sticky-table__td">
{{attendance.attendance_date}}
</div>
<div class="oh-sticky-table__td">
{{attendance.attendance_day.get_day_display }}
</div>
<div class="oh-sticky-table__td">
{{attendance.attendance_clock_in}}
</div>
<div class="oh-sticky-table__td">
{{attendance.attendance_clock_in_date}}
</div>
<div class="oh-sticky-table__td">
{{attendance.attendance_clock_out}}
</div>
<div class="oh-sticky-table__td">
{{attendance.attendance_clock_out_date}}
</div>
<div class="oh-sticky-table__td">{{attendance.shift_id}}</div>
<div class="oh-sticky-table__td">
{{attendance.work_type_id}}
</div>
<div class="oh-sticky-table__td">
{{attendance.minimum_hour}}
</div>
<div class="oh-sticky-table__td">
{{attendance.attendance_worked_hour}}
</div>
<div class="oh-sticky-table__td">
{{attendance.attendance_overtime}}
</div>
<div class="oh-sticky-table__td">
<div class="oh-btn-group">
{% if perms.attendance.change_attendance or request.user|is_reportingmanager %}
<a hx-get="{% url 'attendance-update' attendance.id %}" hx-target='#updateAttendanceModalBody' hx-swap='innerHTML' data-toggle='oh-modal-toggle' data-target='#updateAttendanceModal' class="oh-btn oh-btn--light-bkg w-50" title="{% trans 'Edit' %}"><ion-icon name="create-outline"></ion-icon></a>
{% endif %}
{% if perms.attendance.delete_attendance %}
<form action="{% url 'attendance-delete' attendance.id %}" onsubmit="return confirm('{% trans "Are you sure want to delete this attendance?" %}')" hx-target="#tab_contents" method='post' class='w-50'>
{% csrf_token %}
<button type='submit' class="oh-btn oh-btn--danger-outline oh-btn--light-bkg w-100" title="{% trans 'Remove' %}"><ion-icon name="trash-outline"></ion-icon></button>
</form>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<script>
$(document).ready(function () {
var activeTab = localStorage.getItem('activeTabAttendance')
if (activeTab != null) {
var tab = $(`[data-target="${activeTab}"]`)
var tabContent = $(activeTab)
$(tab).attr('class', 'oh-tabs__tab oh-tabs__tab--active');
$(tabContent).attr('class', 'oh-tabs__content oh-tabs__content--active');
}
else{
$('[data-target="#tab_1"]').attr('class', 'oh-tabs__tab oh-tabs__tab--active');
$('#tab_1').attr('class', 'oh-tabs__content oh-tabs__content--active');
}
$('.oh-tabs__tab').click(function (e) {
var activeTab = $(this).attr('data-target');
localStorage.setItem('activeTabAttendance',activeTab)
});
});
</script>

View File

@@ -95,6 +95,11 @@ urlpatterns = [
),
path("clock-in", attendance.views.clock_in_out.clock_in, name="clock-in"),
path("clock-out", attendance.views.clock_in_out.clock_out, name="clock-out"),
path(
"on-time-view",
views.on_time_view,
name="on-time-view",
),
path(
"late-come-early-out-view",
views.late_come_early_out_view,

View File

@@ -11,11 +11,11 @@ from django.shortcuts import render
from django.http import JsonResponse
from django.utils.translation import gettext_lazy as _
from attendance.filters import AttendanceFilters, LateComeEarlyOutFilter
from attendance.models import Attendance, AttendanceLateComeEarlyOut
from base.methods import filtersubordinates
from base.models import Department, EmployeeShiftSchedule
from employee.models import Employee
from horilla.decorators import login_required
from attendance.models import Attendance, AttendanceLateComeEarlyOut
def find_on_time(request, today, week_day, department=None):
@@ -108,11 +108,14 @@ def dashboard(request):
def total_attendance(start_date, department, end_date=None):
"""
This method is used to find total attandance
"""
attandance = AttendanceFilters(
{
"attendance_date__gte": start_date,
"attendance_date__lte": end_date,
"employee_id__employee_work_info__department_id": department,
"department": department,
}
).qs
return attandance
@@ -120,7 +123,7 @@ def total_attendance(start_date, department, end_date=None):
def find_late_come(start_date, department=None, end_date=None):
"""
This method is used to find count of late comers
This method is used to find late comers
"""
if department is not None:
late_come_obj = LateComeEarlyOutFilter(
@@ -159,6 +162,9 @@ def find_early_out(start_date, end_date=None, department=None):
def get_week_start_end_dates(week):
"""
This method is use to return the start and end date of the week
"""
# Parse the ISO week date
year, week_number = map(int, week.split("-W"))
@@ -172,6 +178,9 @@ def get_week_start_end_dates(week):
def get_month_start_end_dates(year_month):
"""
This method is use to return the start and end date of the month
"""
# split year and month separately
year, month = map(int, year_month.split("-"))
# Get the first day of the month

View File

@@ -697,6 +697,25 @@ def activity_datetime(attendance_activity):
)
@login_required
def on_time_view(request):
"""
This method render template to view all on come early out entries
"""
total_attendances = AttendanceFilters(request.GET).qs
ids_to_exclude = AttendanceLateComeEarlyOut.objects.filter(
attendance_id__id__in=[attendance.id for attendance in total_attendances],type="late_come"
).values_list('attendance_id__id', flat=True)
# Exclude attendances with related objects in AttendanceLateComeEarlyOut
total_attendances = total_attendances.exclude(id__in=ids_to_exclude)
context ={
'attendances':total_attendances,
}
return render(request,"attendance/attendance/attendance_on_time.html",
context=context)
@login_required
@manager_can_enter("attendance.view_attendancelatecomeearlyout")
def late_come_early_out_view(request):
@@ -888,10 +907,14 @@ def revalidate_this_attendance(request, obj_id):
),
verb=f"{attendance.employee_id} requested revalidation for \
{attendance.attendance_date} attendance",
verb_ar=f"{attendance.employee_id} طلب إعادة التحقق من حضور تاريخ {attendance.attendance_date}",
verb_de=f"{attendance.employee_id} beantragte eine Neubewertung der Teilnahme am {attendance.attendance_date}",
verb_es=f"{attendance.employee_id} solicitó la validación nuevamente para la asistencia del {attendance.attendance_date}",
verb_fr=f"{attendance.employee_id} a demandé une revalidation pour la présence du {attendance.attendance_date}",
verb_ar=f"{attendance.employee_id} طلب إعادة\
التحقق من حضور تاريخ {attendance.attendance_date}",
verb_de=f"{attendance.employee_id} beantragte eine Neubewertung der \
Teilnahme am {attendance.attendance_date}",
verb_es=f"{attendance.employee_id} solicitó la validación nuevamente \
para la asistencia del {attendance.attendance_date}",
verb_fr=f"{attendance.employee_id} a demandé une revalidation pour la \
présence du {attendance.attendance_date}",
redirect="/attendance/view-my-attendance",
icon="refresh",
)
@@ -914,11 +937,16 @@ def approve_overtime(request, obj_id):
notify.send(
request.user.employee_get,
recipient=attendance.employee_id.employee_user_id,
verb=f"Your {attendance.attendance_date}'s attendance overtime approved.",
verb_ar=f"تمت الموافقة على إضافة ساعات العمل الإضافية لتاريخ {attendance.attendance_date}.",
verb_de=f"Die Überstunden für den {attendance.attendance_date} wurden genehmigt.",
verb_es=f"Se ha aprobado el tiempo extra de asistencia para el {attendance.attendance_date}.",
verb_fr=f"Les heures supplémentaires pour la date {attendance.attendance_date} ont été approuvées.",
verb=f"Your {attendance.attendance_date}'s attendance \
overtime approved.",
verb_ar=f"تمت الموافقة على إضافة ساعات العمل الإضافية لتاريخ \
{attendance.attendance_date}.",
verb_de=f"Die Überstunden für den {attendance.attendance_date}\
wurden genehmigt.",
verb_es=f"Se ha aprobado el tiempo extra de asistencia para el \
{attendance.attendance_date}.",
verb_fr=f"Les heures supplémentaires pour la date\
{attendance.attendance_date} ont été approuvées.",
redirect="/attendance/attendance-overtime-view",
icon="checkmark",
)
@@ -941,11 +969,16 @@ def approve_bulk_overtime(request):
notify.send(
request.user.employee_get,
recipient=attendance.employee_id.employee_user_id,
verb=f"Overtime approved for {attendance.attendance_date}'s attendance",
verb_ar=f"تمت الموافقة على العمل الإضافي لحضور تاريخ {attendance.attendance_date}",
verb_de=f"Überstunden für die Anwesenheit am {attendance.attendance_date} genehmigt",
verb_es=f"Horas extra aprobadas para la asistencia del {attendance.attendance_date}",
verb_fr=f"Heures supplémentaires approuvées pour la présence du {attendance.attendance_date}",
verb=f"Overtime approved for\
{attendance.attendance_date}'s attendance",
verb_ar=f"تمت الموافقة على العمل الإضافي لحضور تاريخ \
{attendance.attendance_date}",
verb_de=f"Überstunden für die Anwesenheit am \
{attendance.attendance_date} genehmigt",
verb_es=f"Horas extra aprobadas para la asistencia del \
{attendance.attendance_date}",
verb_fr=f"Heures supplémentaires approuvées pour la présence du \
{attendance.attendance_date}",
redirect="/attendance/attendance-overtime-view",
icon="checkmark",
)