[UPDT] ATTENDANCE: Add additional fields and values to attendance detailed view

This commit is contained in:
Horilla
2024-10-14 16:10:31 +05:30
parent 477adf932d
commit 053eba0b86
6 changed files with 180 additions and 124 deletions

View File

@@ -217,6 +217,15 @@ class Attendance(HorillaModel):
return f"{self.employee_id.employee_first_name} \
{self.employee_id.employee_last_name} - {self.attendance_date}"
def activities(self):
"""
This method is used to return the activites and count of activites comes for an attendance
"""
activities = AttendanceActivity.objects.filter(
attendance_date=self.attendance_date, employee_id=self.employee_id
)
return {"query": activities, "count": activities.count()}
def requested_fields(self):
"""
This method will returns the value difference fields

View File

@@ -0,0 +1,48 @@
{% load i18n %}
<div class="oh-modal__dialog-header pb-0">
<span class="oh-modal__dialog-title">
{% trans "Activities" %}
</span>
<button class="oh-modal__close--custom" aria-label="Close"
onclick="$(this).parents().closest('.oh-modal--show').toggleClass('oh-modal--show');">
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
<div class="oh-modal__dialog-body">
<div class="oh-multiple-table-sort">
<div class="oh-sticky-table oh-sticky-table--no-overflow">
<div class="oh-sticky-table__table">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th">{% trans "Employee" %}</div>
<div class="oh-sticky-table__th">{% trans "Attendance Date" %}</div>
<div class="oh-sticky-table__th">{% trans "In Date" %}</div>
<div class="oh-sticky-table__th">{% trans "Clock In" %}</div>
<div class="oh-sticky-table__th">{% trans "Clock Out" %}</div>
<div class="oh-sticky-table__th">{% trans "Out Date" %}</div>
</div>
</div>
<div class="oh-sticky-table__tbody">
{% for activity in attendance.activities.query %}
<div class="oh-sticky-table__tr oh-multiple-table-sort__movable" draggable="true">
<div class="oh-sticky-table__sd">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img src="https://ui-avatars.com/api/?name={{activity.employee_id}}&background=random"
class="oh-profile__image" alt="Mary Magdalene" />
</div>
<span class="oh-profile__name oh-text--dark">{{activity.employee_id}}</span>
</div>
</div>
<div class="oh-sticky-table__td">{{activity.attendance_date}}</div>
<div class="oh-sticky-table__td">{{activity.clock_in_date}}</div>
<div class="oh-sticky-table__td">{{activity.clock_in}}</div>
<div class="oh-sticky-table__td">{{activity.clock_out}}</div>
<div class="oh-sticky-table__td">{{activity.clock_out_date}}</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>

View File

@@ -10,15 +10,18 @@
<div class="oh-modal__dialog-body oh-modal__dialog-relative">
<div class="oh-modal__dialog oh-modal__dialog--navigation m-0 p-0">
<button hx-get="{% url 'user-request-one-view' previous_instance %}?instances_ids={{instance_ids_json}}&validate={{request.GET.validate}}&ot={{request.GET.ot}}&all_attendance={{request.GET.all_attendance}}&my_attendance={{request.GET.my_attendance}}&dashboard={{dashboard}}"
<button
hx-get="{% url 'user-request-one-view' previous_instance %}?instances_ids={{instance_ids_json}}&validate={{request.GET.validate}}&ot={{request.GET.ot}}&all_attendance={{request.GET.all_attendance}}&my_attendance={{request.GET.my_attendance}}&dashboard={{dashboard}}"
hx-target="#objectDetailsModalW25Target" class="oh-modal__diaglog-nav oh-modal__nav-prev"
data-action="previous">
<ion-icon name="chevron-back-outline" class="md hydrated" role="img"
aria-label="chevron back outline"></ion-icon>
</button>
<button hx-get="{% url 'user-request-one-view' next_instance %}?instances_ids={{instance_ids_json}}&validate={{request.GET.validate}}&ot={{request.GET.ot}}&all_attendance={{request.GET.all_attendance}}&my_attendance={{request.GET.my_attendance}}&dashboard={{dashboard}}"
hx-target="#objectDetailsModalW25Target" class="oh-modal__diaglog-nav oh-modal__nav-next" data-action="next">
<button
hx-get="{% url 'user-request-one-view' next_instance %}?instances_ids={{instance_ids_json}}&validate={{request.GET.validate}}&ot={{request.GET.ot}}&all_attendance={{request.GET.all_attendance}}&my_attendance={{request.GET.my_attendance}}&dashboard={{dashboard}}"
hx-target="#objectDetailsModalW25Target" class="oh-modal__diaglog-nav oh-modal__nav-next"
data-action="next">
<ion-icon name="chevron-forward-outline" class="md hydrated" role="img"
aria-label="chevron forward outline"></ion-icon>
</button>
@@ -34,7 +37,8 @@
<div class="oh-timeoff-modal__profile-info">
<span class="oh-timeoff-modal__user fw-bold">{{attendance_request.employee_id}}</span>
<span class="oh-timeoff-modal__user m-0" style="font-size: 18px; color: #4d4a4a">
{{attendance_request.employee_id.employee_work_info.department_id}} / {{attendance_request.employee_id.employee_work_info.job_position_id}}
{{attendance_request.employee_id.employee_work_info.department_id}} /
{{attendance_request.employee_id.employee_work_info.job_position_id}}
</span>
</div>
@@ -107,9 +111,13 @@
<span class="oh-timeoff-modal__stat-title">{% trans "Overtime" %}</span>
<span class="oh-timeoff-modal__stat-count">{{over_time}}</span>
</div>
<div class="oh-timeoff-modal__stat" style="margin-left: 20px;">
<span class="oh-timeoff-modal__stat-title"></span>
<span class="oh-timeoff-modal__stat-count"></span>
<div class="oh-timeoff-modal__stat" style="margin-left: 20px; cursor: pointer;">
<span class="oh-timeoff-modal__stat-title">{% trans "Activities" %}</span>
<span data-target="#objectCreateModal" data-toggle="oh-modal-toggle" hx-get="{% url 'get-attendance-activities' attendance_request.id %}"
hx-target="#objectCreateModalTarget" class="oh-timeoff-modal__stat-count" style="display: flex;" title="{% trans 'View Activities' %}">
<p class="m-0">{{attendance_request.activities.count}} {% trans "Activity" %}</p>
<ion-icon name="eye-outline" class="md hydrated ml-1 mt-1" role="img" aria-label="chevron back outline"></ion-icon>
</span>
</div>
</div>
{% if request.GET.my_attendance %}
@@ -121,73 +129,69 @@
<ion-icon name="lock-open-outline" role="img" class="md hydrated" aria-label="create outline">
</ion-icon>
</a>
{% elif request.GET.ot %}
<div class="oh-modal__button-container text-center">
{% if perms.attendance.change_attendance and perms.attendance.delete_attendance or request.user|is_reportingmanager%}
<div class="oh-btn-group">
<a class="oh-btn oh-btn--info"
hx-get="{% url 'attendance-update' attendance_request.id %}?dashboard={{dashboard}}"
hx-target="{% if dashboard == 'true' %}#editModalForm {% else %}#updateAttendanceModalBody{% endif %}"
hx-swap='innerHTML' data-toggle='oh-modal-toggle'
data-target="{% if dashboard == 'true' %}#editModal {% else %}#updateAttendanceModal {% endif %}"
style="width: 50%;" title='{% trans "Edit" %}'>
<ion-icon name="create-outline" role="img" class="md hydrated" aria-label="create outline">
</ion-icon>
<div class="oh-modal__button-container text-center">
{% if perms.attendance.change_attendance and perms.attendance.delete_attendance or request.user|is_reportingmanager%}
<div class="oh-btn-group">
<a class="oh-btn oh-btn--info"
hx-get="{% url 'attendance-update' attendance_request.id %}?dashboard={{dashboard}}"
hx-target="{% if dashboard == 'true' %}#editModalForm {% else %}#updateAttendanceModalBody{% endif %}"
hx-swap='innerHTML' data-toggle='oh-modal-toggle'
data-target="{% if dashboard == 'true' %}#editModal {% else %}#updateAttendanceModal {% endif %}"
style="width: 50%;" title='{% trans "Edit" %}'>
<ion-icon name="create-outline" role="img" class="md hydrated" aria-label="create outline">
</ion-icon>
</a>
{% if attendance_request.attendance_overtime_approve %}
<a href="#" class="oh-btn oh-btn--success disabled w-50" title='{% trans "Approve" %}'>
<ion-icon name="ban-outline"></ion-icon>
</a>
{% elif minot <= attendance_request.overtime_second %}
<a href="{% url 'approve-overtime' attendance_request.id %}" class="oh-btn oh-btn--success w-50"
title='{% trans "Approve" %}'>
<ion-icon name="checkmark-done-outline"></ion-icon>
</a>
{% if attendance_request.attendance_overtime_approve %}
<a href="#" class="oh-btn oh-btn--success disabled w-50" title='{% trans "Approve" %}'>
<ion-icon name="ban-outline"></ion-icon>
</a>
{% elif minot <= attendance_request.overtime_second %}
<a href="{% url 'approve-overtime' attendance_request.id %}" class="oh-btn oh-btn--success w-50" title='{% trans "Approve" %}'>
<ion-icon name="checkmark-done-outline"></ion-icon>
</a>
{% elif attendance_request.overtime_second >= 60 %}
<a type="submit" href="#" title="{% trans 'Approve' %}"
class="oh-btn oh-btn--warning w-100"
onclick="event.stopPropagation();
Swal.fire({
title: '{% trans 'Are you sure?' %}',
text: '{% trans 'This does not satisfy the minimum OT requirement!' %}',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Approve',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
Swal.fire(
'{% trans 'Approved!' %}',
'{% trans 'Your action has been approved.' %}',
'success'
);
$('[data-ot-approve-id={{attendance_request.id}}]').click();
}
}); "
>
<ion-icon class="me-1" name="checkmark-outline"></ion-icon>
</a>
<button type="submit" data-ot-approve-id={{attendance_request.id}} hidden href=""
onclick="window.location.href='{% url 'approve-overtime' attendance_request.id %}'"
title="{% trans 'Approve Overtime' %}"
class="oh-btn oh-btn--success w-100"
>
<ion-icon class="me-1" name="checkmark-outline"></ion-icon>
</button>
<a type="submit" href="#" title="{% trans 'Approve' %}" class="oh-btn oh-btn--warning w-50"
onclick="event.stopPropagation();
Swal.fire({
title: '{% trans 'Are you sure?' %}',
text: '{% trans 'This does not satisfy the minimum OT requirement!' %}',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Approve',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
Swal.fire(
'{% trans 'Approved!' %}',
'{% trans 'Your action has been approved.' %}',
'success'
);
$('[data-ot-approve-id={{attendance_request.id}}]').click();
}
}); ">
<ion-icon class="me-1" name="checkmark-outline"></ion-icon>
</a>
<button type="submit" data-ot-approve-id={{attendance_request.id}} hidden href=""
onclick="window.location.href='{% url 'approve-overtime' attendance_request.id %}'"
title="{% trans 'Approve Overtime' %}" class="oh-btn oh-btn--success w-100">
<ion-icon class="me-1" name="checkmark-outline"></ion-icon>
</button>
{% endif %}
<form action="{% url 'attendance-delete' attendance_request.id %}"
onsubmit="return confirm('{% trans "Are you sure want to delete this attendance?" %}')"
hx-target="#tab_contents" method='post'
style="width: 50%;">
onsubmit="return confirm('{% trans " Are you sure want to delete this attendance?" %}')"
hx-target="#tab_contents" method='post' style="width: 50%;">
{% csrf_token %}
<button type='submit' class="oh-btn oh-btn--danger w-100" data-action="delete" title='{% trans "Delete" %}'><ion-icon name="trash-outline" role="img"
class="md hydrated" aria-label="create outline"></ion-icon></button>
<button type='submit' class="oh-btn oh-btn--danger w-100" data-action="delete" title='{% trans "Delete" %}'>
<ion-icon name="trash-outline" role="img" class="md hydrated" aria-label="create outline"></ion-icon>
</button>
</form>
</div>
{% endif %}
</div>
</div>
{% endif %}
</div>
{% elif request.GET.validate %}
<div class="oh-modal__button-container text-center">
{% if perms.attendance.change_attendance and perms.attendance.delete_attendance or request.user|is_reportingmanager %}
@@ -201,19 +205,18 @@
</ion-icon>
</a>
<a href='{% url "validate-this-attendance" attendance_request.id %}' hx-target='#updateAttendanceBody'
class="oh-btn oh-btn--success w-50"
title='{% trans "Validate" %}'
class="oh-btn oh-btn--success w-50" title='{% trans "Validate" %}'
data-req="/attendance/request-attendance-view/?id={{attendance_request.id}}"
onclick="{% if attendance_request.is_validate_request %} event.preventDefault(); showSweetAlert($(this).data('req')); {% endif %}">
<ion-icon name="checkmark-done-outline"></ion-icon>
</a>
<form action="{% url 'attendance-delete' attendance_request.id %}"
onsubmit="return confirm('{% trans "Are you sure want to delete this attendance?" %}')"
hx-target="#tab_contents" method='post'
style="width: 50%;">
<form action="{% url 'attendance-delete' attendance_request.id %}" method='post' style="width: 50%;"
onsubmit="return confirm('{% trans " Are you sure want to delete this attendance?" %}')"
>
{% csrf_token %}
<button type='submit' class="oh-btn oh-btn--danger w-100" data-action="delete" title='{% trans "Delete" %}'><ion-icon name="trash-outline" role="img"
class="md hydrated" aria-label="create outline"></ion-icon></button>
<button type='submit' class="oh-btn oh-btn--danger w-100" data-action="delete" title='{% trans "Delete" %}'>
<ion-icon name="trash-outline" role="img" class="md hydrated" aria-label="create outline"></ion-icon>
</button>
</form>
</div>
{% endif %}
@@ -228,13 +231,13 @@
<ion-icon name="create-outline" role="img" class="md hydrated" aria-label="create outline">
</ion-icon>
</a>
<form action="{% url 'attendance-delete' attendance_request.id %}"
onsubmit="return confirm('{% trans " Are you sure want to delete this attendance?" %}')"
hx-target="#tab_contents" method='post'
<form action="{% url 'attendance-delete' attendance_request.id %}" onsubmit="return confirm('{% trans "
Are you sure want to delete this attendance?" %}')" hx-target="#tab_contents" method='post'
style="width: 50%;">
{% csrf_token %}
<button type='submit' class="oh-btn oh-btn--danger w-100" data-action="delete" title='{% trans "Delete" %}'><ion-icon name="trash-outline" role="img"
class="md hydrated" aria-label="create outline"></ion-icon></button>
<button type='submit' class="oh-btn oh-btn--danger w-100" data-action="delete" title='{% trans "Delete" %}'>
<ion-icon name="trash-outline" role="img" class="md hydrated" aria-label="create outline"></ion-icon>
</button>
</form>
</div>
{% endif %}

View File

@@ -320,6 +320,11 @@ urlpatterns = [
views.user_request_one_view,
name="user-request-one-view",
),
path(
"get-attendance-activities/<int:obj_id>",
views.get_attendance_activities,
name="get-attendance-activities",
),
path(
"hour-attendance-select/",
views.hour_attendance_select,

View File

@@ -1672,6 +1672,17 @@ def user_request_one_view(request, id):
)
@login_required
@hx_request_required
def get_attendance_activities(request, obj_id):
attendance = Attendance.find(obj_id)
return render(
request,
"attendance/attendance/attendance_activites_view.html",
context={"attendance": attendance},
)
@login_required
def hour_attendance_select(request):
page_number = request.GET.get("page")