[UPDT] ATTENDANCE: Add additional fields and values to attendance detailed view
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user