[FIX] ATTENDANCE: Fixed attendance request detail view issues

This commit is contained in:
Horilla
2025-07-17 19:44:22 +05:30
parent 4a6af2bd75
commit 9b8e6723bb
6 changed files with 137 additions and 22 deletions

View File

@@ -34,10 +34,9 @@ from django import forms
from django.apps import apps
from django.core.exceptions import ValidationError
from django.db.models.query import QuerySet
from django.forms import DateTimeInput
from django.forms import DateInput, DateTimeInput, TimeInput
from django.template.loader import render_to_string
from django.utils.html import format_html
from django.utils.text import capfirst
from django.utils.translation import gettext_lazy as _
from attendance.filters import AttendanceFilters
@@ -79,6 +78,8 @@ class AttendanceUpdateForm(BaseModelForm):
from AttendanceUpdateForm. This form can be used to update existing attendance.
"""
container_id = "attendanceUpdateFormFields"
class Meta:
"""
Meta class to add the additional info
@@ -205,6 +206,7 @@ class AttendanceForm(BaseModelForm):
Model form for Attendance model
"""
container_id = "attendanceFormFields"
employee_id = HorillaMultiSelectField(
queryset=Employee.objects.filter(employee_work_info__isnull=False),
widget=HorillaMultiSelectWidget(
@@ -661,6 +663,14 @@ class AttendanceRequestForm(BaseModelForm):
"batch_attendance_id",
]
widgets = {
"attendance_clock_in": TimeInput(attrs={"type": "time"}),
"attendance_clock_out": TimeInput(attrs={"type": "time"}),
"attendance_clock_out_date": DateInput(attrs={"type": "date"}),
"attendance_date": DateInput(attrs={"type": "date"}),
"attendance_clock_in_date": DateInput(attrs={"type": "date"}),
}
def as_p(self, *args, **kwargs):
"""
Render the form fields as HTML table rows with Bootstrap styling.
@@ -1076,12 +1086,16 @@ class BulkAttendanceRequestForm(BaseModelForm):
from_date = forms.DateField(
required=False,
label=_("From Date"),
widget=forms.DateInput(attrs={"type": "date", "class": "form-control"}),
widget=forms.DateInput(
attrs={"type": "date", "class": "form-control oh-input w-100"}
),
)
to_date = forms.DateField(
required=False,
label=_("To Date"),
widget=forms.DateInput(attrs={"type": "date", "class": "form-control"}),
widget=forms.DateInput(
attrs={"type": "date", "class": "form-control oh-input w-100"}
),
)
batch_attendance_id = forms.ModelChoiceField(
queryset=BatchAttendance.objects.all(),
@@ -1110,6 +1124,11 @@ class BulkAttendanceRequestForm(BaseModelForm):
"request_description",
)
widgets = {
"attendance_clock_in": TimeInput(attrs={"type": "time"}),
"attendance_clock_out": TimeInput(attrs={"type": "time"}),
}
def update_worked_hour_hx_fields(self, field_name):
"""Update the widget attributes for worked hour fields."""
self.fields[field_name].widget.attrs.update(

View File

@@ -103,7 +103,7 @@
role="dialog"
aria-labelledby="validateAttendanceRequest"
aria-hidden="true"
style="z-index: 35;"
style="z-index: 1025;"
>
<div class="oh-modal__dialog">
<div class="oh-modal__dialog-header">
@@ -127,7 +127,7 @@
role="dialog"
aria-labelledby="genericModalEdit"
aria-hidden="true"
style="z-index: 45;"
style="z-index: 1025;"
>
<div class="oh-modal__dialog" id="genericModalEditBody"></div>
</div>

View File

@@ -433,11 +433,11 @@ def validate_attendance_request(request, attendance_id):
first_dict = empty_data
else:
other_dict = json.loads(attendance.requested_data)
requests_ids_json = request.GET.get("requests_ids")
requests_ids_json = request.session.get("ordered_ids_attendance", [])
previous_instance_id = next_instance_id = attendance.pk
if requests_ids_json:
previous_instance_id, next_instance_id = closest_numbers(
json.loads(requests_ids_json), attendance_id
requests_ids_json, attendance_id
)
return render(
request,

View File

@@ -28,9 +28,9 @@
hx-swap="outerHTML"
hx-on:click="htmxLoadIndicator(this);"
></button>
{% if show_filter_tags %} {% include "generic/filter_tags.html" %} {% endif %}
{% if queryset|length %}
{% if show_filter_tags %} {% include "generic/filter_tags.html" %} {% endif %}
{% if queryset|length %}
{% if bulk_select_option %} {% include "generic/quick_actions.html" %} {% endif %}
<div class="bg-white p-5 pe-2 pt-3 rounded-md shadow-card relative">
@@ -86,12 +86,12 @@
{% for cell in columns %}
{% with cell_attr=header_attrs|get_item:cell.1 %}
<th
<th
class="text-sm font-medium text-left p-3"
id="{{view_id}}-{{ forloop.counter }}-{{cell.1}}-header"
>
<div class="flex gap-3 min-w-[150px] {% for sort_map in sortby_mapping %} {% if sort_map.0 == cell.0 %}cursor-pointer {% endif %}{% endfor %}"
<div class="flex gap-3 min-w-[150px] {% for sort_map in sortby_mapping %} {% if sort_map.0 == cell.0 %}cursor-pointer {% endif %}{% endfor %}"
{{cell_attr|safe}}
{% for sort_map in sortby_mapping %}
{% if sort_map.0 == cell.0 %}
@@ -166,7 +166,7 @@
</td>
{% endif %}
{% for cell in columns %}
{% with attribute=cell.1 index=forloop.counter %}
{% with attribute=cell.1 index=forloop.counter %}
<td class="text-sm text-left p-3 text-[#666]
{% if cell.1 == "attendance_date" %}
{% if 'attendance_date' in instance.requested_fields or instance.request_type == 'create_request' %}
@@ -265,7 +265,7 @@
<i class="fa-solid fa-xmark"></i>
</button> {% endcomment %}
</div>
{% else %}
{% else %}
{{instance|getattribute:option_method|safe}}
{% endif %}
@@ -297,7 +297,7 @@
<i class="fa-solid fa-xmark"></i>
</button> {% endcomment %}
</div>
{% else %}
{% else %}
{{instance|getattribute:action_method|safe}}
{% endif %}
@@ -340,7 +340,7 @@
{% else %}
{% if not custom_empty_template %}
<div class="oh-wrapper h-full" align="center" >
<div class="xl:col-span-4 md:col-span-6 col-span-12 bg-white p-6 rounded-md shadow-card h-[70%]">
<div class="flex flex-col items-center justify-center h-full">
<img src="/static/horilla_theme/assets/img/no-records.svg" alt="" width="300" class="mb-4">
@@ -365,14 +365,14 @@
badge.html(count);
badge.attr("title", title);
{% endif %}
</script>
</script>
{% if bulk_select_option %}
<script>
selectSelected("#{{view_id|safe}}",'{{selected_instances_key_id}}')
</script>
{% endif %}
{% endif %}
<script>
$("ul[data-search-url] a").click(function (e) {
$("ul[data-search-url] a").click(function (e) {
e.preventDefault();
const url = $(this).attr("hx-get")
const $urlObj = $('<a>', { href: url });
@@ -429,5 +429,5 @@
}, 200);
</script>
</div>

View File

@@ -92,4 +92,4 @@
{% endif %}
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,96 @@
{% load i18n widget_tweaks attendancefilters %}
<div id="attendanceRequestDiv">
<div class="oh-modal__dialog-header">
<h2 class="text-md font-semibold mb-3" id="addEmployeeModalLabel">
{% trans "New Attendances Request" %}
</h2>
<button class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
<div class="oh-modal__dialog-body">
<div class="oh-general__tab-target oh-profile-section" id="personal">
<form
hx-post="{% url 'request-new-attendance' %}"
id="attendanceRequestForm"
hx-encoding="multipart/form-data"
>
{% csrf_token %}
<div class="oh-profile-section__card">
<div class="row">
<div class="col-12">{{form.errors}}</div>
{% for field in form.visible_fields %}
{% if field.field.widget|is_select_multiple or field.field.widget|is_text_area %}
<div class="flex oh-label" for="id_{{ field.name }}">
<label
class="{% if field.field.required %} required-star{% endif %}"
for="id_{{ field.name }}"
>{{ field.label }}</label
>
{% if field.help_text != '' %}
<span
class="oh-info mr-2"
title="{{ field.help_text|safe }}"
></span>
{% endif %}
</div>
<div style="width: 100%; padding: 12px">
{{ field|add_class:"form-control" }}
</div>
{% else %}
<div
class="col-12 col-md-6"
id="id_{{field.name}}_parent_div"
>
<div
class="flex oh-label"
for="id_{{ field.name }}"
>
<label
class="{% if field.field.required %} required-star{% endif %}"
for="id_{{ field.name }}"
>{{ field.label }}</label
>
{% if field.help_text != '' %}
<span
class="oh-info mr-2"
title="{{ field.help_text|safe }}"
></span>
{% endif %}
</div>
{% if field.field.widget.input_type == "checkbox" %}
<div class="oh-switch" style="width: 30px">
{{ field|add_class:"oh-switch__checkbox" }}
</div>
{% else %}
{{ field|add_class:"form-control" }}
{% endif %}
{{field.errors}}
</div>
{% endif %}
{% endfor %}
</div>
<div class="d-flex flex-row-reverse">
<button
type="submit"
class="oh-btn oh-btn--secondary mt-2 mr-0 pl-4 pr-5 oh-btn--w-100-resp"
>
{% trans "Save" %}
</button>
</div>
</div>
</form>
</div>
</div>
<script>
$(document).ready(function () {
$("select").on("select2:select", function (e) {
$(".leave-message").hide();
$(this).closest("select")[0].dispatchEvent(new Event("change"));
});
});
</script>
</div>