[UPDT] ATTENDANCE: On time date filteration in main dashboard
This commit is contained in:
@@ -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 = {
|
||||
|
||||
@@ -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>
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user