[UPDT] ATTENDANCE: Replace jquery function for shift field to htmx method in Attendance form

This commit is contained in:
Horilla
2024-08-26 12:00:37 +05:30
parent 35fe7cfe93
commit 649866a92c
12 changed files with 286 additions and 339 deletions

View File

@@ -204,7 +204,10 @@ class AttendanceUpdateForm(ModelForm):
self.fields["shift_id"].widget.attrs.update(
{
"id": str(uuid.uuid4()),
"onchange": "shiftChange($(this))",
"hx-include": "#attendanceUpdateForm",
"hx-target": "#attendanceUpdateForm",
"hx-trigger": "change",
"hx-get": "/attendance/update-fields-based-shift",
}
)
self.fields["attendance_date"].widget.attrs.update(
@@ -278,22 +281,30 @@ class AttendanceForm(ModelForm):
}
def __init__(self, *args, **kwargs):
# Get the initial data passed from the view
view_initial = kwargs.pop("initial", {})
# Default initial values
initial = {
"attendance_clock_out_date": datetime.datetime.today()
.date()
.strftime("%Y-%m-%d"),
"attendance_clock_out": datetime.datetime.today().time().strftime("%H:%M"),
}
# If an instance is provided, override the default initial values
if instance := kwargs.get("instance"):
# django forms not showing value inside the date, time html element.
# so here overriding default forms instance method to set initial value
initial = {
"attendance_date": instance.attendance_date.strftime("%Y-%m-%d"),
"attendance_clock_in": instance.attendance_clock_in.strftime("%H:%M"),
"attendance_clock_in_date": instance.attendance_clock_in_date.strftime(
"%Y-%m-%d"
),
}
initial.update(
{
"attendance_date": instance.attendance_date.strftime("%Y-%m-%d"),
"attendance_clock_in": instance.attendance_clock_in.strftime(
"%H:%M"
),
"attendance_clock_in_date": instance.attendance_clock_in_date.strftime(
"%Y-%m-%d"
),
}
)
if instance.attendance_clock_out_date is not None:
initial["attendance_clock_out"] = (
instance.attendance_clock_out.strftime("%H:%M")
@@ -301,14 +312,21 @@ class AttendanceForm(ModelForm):
initial["attendance_clock_out_date"] = (
instance.attendance_clock_out_date.strftime("%Y-%m-%d")
)
# Merge with initial values passed from the view
initial.update(view_initial)
kwargs["initial"] = initial
super().__init__(*args, **kwargs)
reload_queryset(self.fields)
self.fields["employee_id"].widget.attrs.update({"id": str(uuid.uuid4())})
self.fields["shift_id"].widget.attrs.update(
{
"id": str(uuid.uuid4()),
"onchange": "shiftChange($(this))",
"hx-include": "#attendanceCreateForm",
"hx-target": "#attendanceCreateForm",
"hx-trigger": "change",
"hx-get": "/attendance/update-fields-based-shift",
}
)
self.fields["attendance_date"].widget.attrs.update(
@@ -560,7 +578,11 @@ class AttendanceRequestForm(ModelForm):
self.fields["shift_id"].widget.attrs.update(
{
"id": str(uuid.uuid4()),
"onchange": "shiftChange($(this))",
"hx-include": "#attendanceRequestForm",
"hx-target": "#attendanceRequestDiv",
"hx-trigger": "change",
"hx-swap": "outerHTML",
"hx-get": "/attendance/update-fields-based-shift",
}
)
self.fields["attendance_date"].widget.attrs.update(
@@ -609,7 +631,8 @@ class NewRequestForm(AttendanceRequestForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Get the initial data passes from views.py file
view_initial = kwargs.pop("initial", {})
# Add the new model choice field to the form at the beginning
old_dict = self.fields
new_dict = {
@@ -624,6 +647,7 @@ class NewRequestForm(AttendanceRequestForm):
"hx-trigger": "change",
}
),
initial=view_initial.get("employee_id"),
),
"create_bulk": forms.BooleanField(
required=False,
@@ -642,6 +666,8 @@ class NewRequestForm(AttendanceRequestForm):
new_dict.update(old_dict)
self.fields = new_dict
kwargs["initial"] = view_initial
def as_p(self, *args, **kwargs):
"""
Render the form fields as HTML table rows with Bootstrap styling.

View File

@@ -1,132 +1,77 @@
{% extends 'index.html' %} {% block content %} {% load static %} {% load i18n %}
{% load basefilters %} {% include 'attendance/attendance/attendance_nav.html' %}
{% extends 'index.html' %}
{% block content %}
{% load i18n %}
{% load static %}
{% load basefilters %}
{% include 'attendance/attendance/attendance_nav.html' %}
<div class="oh-wrapper" id="attendance-container">
<div class="oh-tabs">
<ul class="oh-tabs__tablist">
<li class="oh-tabs__tab" data-target="#tab_1">
{% trans "Validate Attendances" %}
<div class="oh-dropdown float-end" x-data="{open: false}">
<button
class="oh-btn oh-stop-prop oh-btn--transparent oh-accordion-meta__btn"
@click="open = !open"
@click.outside="open = false"
title='{% trans "Actions" %}'
>
<ion-icon name="ellipsis-vertical"></ion-icon>
</button>
<div
class="oh-dropdown__menu oh-dropdown__menu--right"
x-show="open"
style="display: none"
>
<ul class="oh-dropdown__items">
{% if perms.attendance.change_attendance or request.user|is_reportingmanager %}
<li class="oh-dropdown__item">
<a href="#" id="validateAttendances" class="oh-dropdown__link"
>{% trans "Validate" %}</a
>
</li>
{% endif %}
</ul>
</div>
<div class="oh-tabs">
<ul class="oh-tabs__tablist">
<li class="oh-tabs__tab" data-target="#tab_1">
{% trans "Validate Attendances" %}
<div class="oh-dropdown float-end" x-data="{open: false}">
<button class="oh-btn oh-stop-prop oh-btn--transparent oh-accordion-meta__btn" @click="open = !open"
@click.outside="open = false" title='{% trans "Actions" %}'>
<ion-icon name="ellipsis-vertical"></ion-icon>
</button>
<div class="oh-dropdown__menu oh-dropdown__menu--right" x-show="open" style="display: none">
<ul class="oh-dropdown__items">
{% if perms.attendance.change_attendance or request.user|is_reportingmanager %}
<li class="oh-dropdown__item">
<a href="#" id="validateAttendances" class="oh-dropdown__link">{% trans "Validate" %}</a>
</li>
{% endif %}
</ul>
</div>
</div>
</li>
<li class="oh-tabs__tab oh-tabs__tab" data-target="#tab_3">
{% trans "OT Attendances" %}
<div class="oh-dropdown float-end" x-data="{open: false}">
<button class="oh-btn oh-stop-prop oh-btn--transparent oh-accordion-meta__btn" @click="open = !open"
@click.outside="open = false" title='{% trans "Actions" %}'>
<ion-icon name="ellipsis-vertical"></ion-icon>
</button>
<div class="oh-dropdown__menu oh-dropdown__menu--right" x-show="open" style="display: none">
<ul class="oh-dropdown__items">
{% if perms.attendance.change_attendance or request.user|is_reportingmanager %}
<li class="oh-dropdown__item">
<a href="#" id="approveOt" class="oh-dropdown__link">{% trans "Approve OT" %}</a>
</li>
{% endif %}
</ul>
</div>
</div>
</li>
<li class="oh-tabs__tab" data-target="#tab_2">
{% trans "Validated Attendances" %}
</li>
</ul>
<div class="oh-tabs__contents" id="tab_contents">
{% include 'attendance/attendance/tab_content.html' %}
</div>
</li>
<li class="oh-tabs__tab oh-tabs__tab" data-target="#tab_3">
{% trans "OT Attendances" %}
<div class="oh-dropdown float-end" x-data="{open: false}">
<button
class="oh-btn oh-stop-prop oh-btn--transparent oh-accordion-meta__btn"
@click="open = !open"
@click.outside="open = false"
title='{% trans "Actions" %}'
>
<ion-icon name="ellipsis-vertical"></ion-icon>
</button>
<div
class="oh-dropdown__menu oh-dropdown__menu--right"
x-show="open"
style="display: none"
>
<ul class="oh-dropdown__items">
{% if perms.attendance.change_attendance or request.user|is_reportingmanager %}
<li class="oh-dropdown__item">
<a href="#" id="approveOt" class="oh-dropdown__link"
>{% trans "Approve OT" %}</a
>
</li>
{% endif %}
</ul>
</div>
</div>
</li>
<li class="oh-tabs__tab" data-target="#tab_2">
{% trans "Validated Attendances" %}
</li>
</ul>
<div class="oh-tabs__contents" id="tab_contents">
{% include 'attendance/attendance/tab_content.html' %}
</div>
</div>
</div>
<script>
function shiftChange(selectElement) {
var shiftId = selectElement.val();
let parentForm = selectElement.parents().closest("form");
var attendanceDate = parentForm
.find("[name=attendance_date]")
.first()
.val();
$.ajax({
type: "post",
url: "{% url 'update-shift-details' %}",
data: {
csrfmiddlewaretoken: getCookie("csrftoken"),
shift_id: shiftId,
attendance_date: attendanceDate,
},
success: function (response) {
parentForm
.find("[name=attendance_clock_in]")
.val(response.shift_start_time);
parentForm
.find("[name=attendance_clock_out]")
.val(response.shift_end_time);
parentForm
.find("[name=attendance_worked_hour]")
.val(response.worked_hour);
parentForm.find("[name=minimum_hour]").val(response.minimum_hour);
parentForm
.find("[name=attendance_clock_out_date]")
.val(response.checkout_date);
parentForm
.find("[name=attendance_clock_in_date]")
.val(response.checkin_date);
if (parentForm.find("[name=attendance_date]").val().length == 0) {
parentForm.find("[name=attendance_date]").val(response.checkin_date);
}
},
});
}
function dateChange(selectElement) {
var selectedDate = selectElement.val();
let parentForm = selectElement.parents().closest("form");
var shiftId = parentForm.find("[name=shift_id]").val();
function dateChange(selectElement) {
var selectedDate = selectElement.val();
let parentForm = selectElement.parents().closest("form");
var shiftId = parentForm.find("[name=shift_id]").val();
$.ajax({
type: "post",
url: "{% url 'update-date-details' %}",
data: {
csrfmiddlewaretoken: getCookie("csrftoken"),
attendance_date: selectedDate,
shift_id: shiftId,
},
success: function (response) {
parentForm.find("[name=minimum_hour]").val(response.minimum_hour);
},
});
}
$.ajax({
type: "post",
url: "{% url 'update-date-details' %}",
data: {
csrfmiddlewaretoken: getCookie("csrftoken"),
attendance_date: selectedDate,
shift_id: shiftId,
},
success: function (response) {
parentForm.find("[name=minimum_hour]").val(response.minimum_hour);
},
});
}
</script>
{% endblock content %}

View File

@@ -1,8 +1,11 @@
{% load i18n %}
<form
hx-post="{% url 'attendance-create' %}"
hx-target="#addAttendanceModalBody"
id="addForm"
>
{{form.as_p}}
<form hx-post="{% url 'attendance-create' %}" hx-target="#addAttendanceModalBody" id="attendanceCreateForm">
{{form.as_p}}
</form>
<script>
$(document).ready(function () {
$("select").on("select2:select", function (e) {
$(this).closest("select")[0].dispatchEvent(new Event("change"));
});
});
</script>

View File

@@ -1,11 +1,11 @@
{% load i18n %}
<form
hx-post="{% url 'attendance-update' form.instance.id %}?{{urlencode}}"
hx-swap="#updateAttendanceModalBody"
method="post"
id="updateForm"
>
{{form.as_p}}
<script></script>
<form hx-post="{% url 'attendance-update' form.instance.id %}?{{urlencode}}" hx-swap="#updateAttendanceModalBody" id="attendanceUpdateForm">
{{form.as_p}}
<script>
$(document).ready(function () {
$("select").on("select2:select", function (e) {
$(this).closest("select")[0].dispatchEvent(new Event("change"));
});
});
</script>
</form>

View File

@@ -0,0 +1,8 @@
{{form.as_p}}
<script>
$(document).ready(function () {
$("select").on("select2:select", function (e) {
$(this).closest("select")[0].dispatchEvent(new Event("change"));
});
});
</script>

View File

@@ -1,12 +1,12 @@
{% load i18n %}
<label
class="oh-label"
for="id_{{field.name }}"
title="{{field.help_text|safe }}"
>{{field.label}}</label
>
<label class="oh-label" for="id_{{field.name }}" title="{{field.help_text|safe }}">{{field.label}}</label>
{{field}}
<script>
$("[name={{field.name}}]").change()
$("[name={{field.name}}]").change()
$(document).ready(function () {
$("select").on("select2:select", function (e) {
$(".leave-message").hide()
$(this).closest("select")[0].dispatchEvent(new Event("change"));
});
});
</script>

View File

@@ -1,72 +1,61 @@
{% load i18n %}{% load widget_tweaks %} {% load attendancefilters %}
<div class="oh-modal__dialog-header">
<h2 class="oh-modal__dialog-title" 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' %}?bulk={{bulk}}" hx-target="#objectCreateModalTarget">
{% csrf_token %}
<div class="oh-profile-section__card">
<div class="row">
<div class="col-12">{{form.non_field_errors}}</div>
{% for field in form.visible_fields %}
{% if field.field.widget|is_select_multiple or field.field.widget|is_text_area %}
<label
class="oh-label {% if field.field.required %} required-star{% endif %}"
for="id_{{ field.name }}"
title="{{ field.help_text|safe }}"
>{{ field.label }}</label
>
<div style="width: 100%; padding: 12px;">
{{ field|add_class:"form-control" }}
</div>
{% else %}
<div class="col-12 col-md-6" id="id_{{field.name}}_div">
<label
class="oh-label {% if field.field.required %} required-star{% endif %}"
for="id_{{ field.name }}"
title="{{ field.help_text|safe }}"
>{{ field.label }}</label
>
{% 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 "Request" %}
<div id="attendanceRequestDiv">
{% load i18n widget_tweaks attendancefilters %}
<div class="oh-modal__dialog-header">
<h2 class="oh-modal__dialog-title" id="addEmployeeModalLabel">
{% trans "New Attendances Request" %}
</h2>
<button class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
</button>
</form>
</div>
</div>
</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' %}?bulk={{bulk}}" hx-target="#objectCreateModalTarget" id="attendanceRequestForm">
{% csrf_token %}
<div class="oh-profile-section__card">
<div class="row">
<div class="col-12">{{form.non_field_errors}}</div>
{% for field in form.visible_fields %}
{% if field.field.widget|is_select_multiple or field.field.widget|is_text_area %}
<label class="oh-label {% if field.field.required %} required-star{% endif %}"
for="id_{{ field.name }}" title="{{ field.help_text|safe }}">{{ field.label }}</label>
<div style="width: 100%; padding: 12px;">
{{ field|add_class:"form-control" }}
</div>
{% else %}
<div class="col-12 col-md-6" id="id_{{field.name}}_div">
<label class="oh-label {% if field.field.required %} required-star{% endif %}"
for="id_{{ field.name }}" title="{{ field.help_text|safe }}">{{ field.label }}</label>
{% 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 "Request" %}
</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>
<script>
$(document).ready(function () {
$("select").on("select2:select", function (e) {
$(".leave-message").hide()
$(this).closest("select")[0].dispatchEvent(new Event("change"));
});
});
</script>

View File

@@ -302,9 +302,9 @@ urlpatterns = [
name="attendance-widget-filter",
),
path(
"update-shift-details",
views.form_shift_dynamic_data,
name="update-shift-details",
"update-fields-based-shift",
views.update_fields_based_shift,
name="update-fields-based-shift",
),
path(
"update-date-details",

View File

@@ -60,6 +60,7 @@ from attendance.forms import (
AttendanceValidationConditionForm,
GraceTimeForm,
LateComeEarlyOutExportForm,
NewRequestForm,
)
from attendance.methods.utils import (
Request,
@@ -103,6 +104,7 @@ from base.models import (
AttendanceAllowedIP,
EmployeeShiftSchedule,
TrackLateComeEarlyOut,
WorkType,
)
from employee.filters import EmployeeFilter
from employee.models import Employee, EmployeeWorkInformation
@@ -1407,62 +1409,90 @@ def approve_bulk_overtime(request):
return JsonResponse({"message": "Success"})
def form_shift_dynamic_data(request):
"""
This method is used to update the shift details to the form
"""
work_type = None
if "employee_id" in request.POST and request.POST["employee_id"]:
shift_id = request.POST["shift_id"]
# Check if 'employee_id' is present in POST request and not empty
if "employee_id" in request.POST and request.POST["employee_id"]:
employee_id = request.POST["employee_id"]
try:
employee = Employee.objects.get(id=employee_id)
# Use getattr to get the work type
work_type = employee.get_work_type()
if work_type:
work_type = work_type.id
except Employee.DoesNotExist:
pass
attendance_date_str = request.POST.get("attendance_date")
today = datetime.now()
attendance_date = date(day=today.day, month=today.month, year=today.year)
if attendance_date_str is not None and attendance_date_str != "":
attendance_date = datetime.strptime(attendance_date_str, "%Y-%m-%d").date()
@login_required
@hx_request_required
def update_fields_based_shift(request):
shift_id = request.GET.get("shift_id")
hx_target = request.META.get("HTTP_HX_TARGET")
employee_ids = (
request.GET.get("employee_id")
if hx_target == "attendanceUpdateForm" or hx_target == "attendanceRequestDiv"
else request.GET.getlist("employee_id")
)
employee_queryset = (
(
Employee.objects.get(id=employee_ids)
if hx_target == "attendanceUpdateForm"
or hx_target == "attendanceRequestDiv"
else Employee.objects.filter(id__in=employee_ids)
)
if employee_ids
else None
)
attendance_date_str = request.GET.get("attendance_date")
attendance_date = (
datetime.strptime(attendance_date_str, "%Y-%m-%d").date()
if attendance_date_str
else datetime.today().date()
)
day = attendance_date.strftime("%A").lower()
schedule_today = None
if shift_id:
schedule_today = EmployeeShiftSchedule.objects.filter(
shift_id__id=shift_id, day__day=day
).first()
shift_start_time = ""
shift_end_time = ""
minimum_hour = "00:00"
attendance_clock_out_date = attendance_date
if schedule_today is not None:
shift_start_time = schedule_today.start_time
shift_end_time = schedule_today.end_time
minimum_hour = schedule_today.minimum_working_hour
if shift_end_time < shift_start_time:
attendance_clock_out_date = attendance_date + timedelta(days=1)
worked_hour = minimum_hour
if attendance_date == date(day=today.day, month=today.month, year=today.year):
shift_end_time = datetime.now().strftime("%H:%M")
schedule_today = (
EmployeeShiftSchedule.objects.filter(shift_id=shift_id, day__day=day).first()
if shift_id
else None
)
shift_start_time = schedule_today.start_time if schedule_today else ""
shift_end_time = schedule_today.end_time if schedule_today else ""
minimum_hour = schedule_today.minimum_working_hour if schedule_today else "00:00"
if schedule_today and shift_end_time < shift_start_time:
attendance_clock_out_date = (attendance_date + timedelta(days=1)).strftime(
"%Y-%m-%d"
)
else:
attendance_clock_out_date = attendance_date.strftime("%Y-%m-%d")
if attendance_date == datetime.today().date():
shift_end_time = datetime.now().time()
worked_hour = "00:00"
else:
worked_hour = minimum_hour
minimum_hour = attendance_day_checking(str(attendance_date), minimum_hour)
return JsonResponse(
{
"shift_start_time": shift_start_time,
"shift_end_time": shift_end_time,
"checkin_date": attendance_date.strftime("%Y-%m-%d"),
"minimum_hour": minimum_hour,
"worked_hour": worked_hour,
"checkout_date": attendance_clock_out_date.strftime("%Y-%m-%d"),
"work_type": str(work_type),
}
initial_data = {
"work_type_id": WorkType.find(request.GET.get("work_type_id")),
"shift_id": shift_id,
"employee_id": employee_queryset,
"minimum_hour": minimum_hour,
"attendance_date": attendance_date.strftime("%Y-%m-%d"),
"attendance_clock_in": (
shift_start_time.strftime("%H:%M") if shift_start_time else ""
),
"attendance_clock_out": (
shift_end_time.strftime("%H:%M") if shift_end_time else ""
),
"attendance_worked_hour": worked_hour,
"attendance_clock_in_date": attendance_date.strftime("%Y-%m-%d"),
"attendance_clock_out_date": attendance_clock_out_date,
}
form = (
AttendanceUpdateForm(initial=initial_data)
if hx_target == "attendanceUpdateForm"
else (
NewRequestForm(initial=initial_data)
if hx_target == "attendanceRequestDiv"
else AttendanceForm(initial=initial_data)
)
)
return render(
request,
"attendance/attendance/update_hx_form.html",
{"request": request, "form": form},
)

View File

@@ -139,7 +139,10 @@ def csrf_token(context):
"""
to access csrf token inside the render_template method
"""
request = context["request"]
try:
request = context["request"]
except:
request = getattr(_thread_locals, "request")
csrf_input_lazy = lazy(csrf_input, SafeString, str)
return csrf_input_lazy(request)

View File

@@ -106,36 +106,6 @@ nav.after(
)
);
function shiftChange(selectElement) {
var shiftId =selectElement.val()
let parentForm = selectElement.parents().closest("form")
var attendanceDate = parentForm.find("[name=attendance_date]").first().val()
var employeeId = parentForm.find("[name=employee_id]").first().val()
$.ajax({
type: "post",
url: "/attendance/update-shift-details",
data: {
csrfmiddlewaretoken: getCookie("csrftoken"),
"shift_id":shiftId,
"attendance_date":attendanceDate,
'employee_id':employeeId
},
success: function (response) {
parentForm.find("[name=attendance_clock_in]").val(response.shift_start_time)
parentForm.find("[name=attendance_clock_out]").val(response.shift_end_time)
parentForm.find("[name=attendance_worked_hour]").val(response.worked_hour)
parentForm.find("[name=minimum_hour]").val(response.minimum_hour)
parentForm.find("[name=attendance_clock_out_date]").val(response.checkout_date)
parentForm.find("[name=attendance_clock_in_date]").val(response.checkin_date)
parentForm.find("[name=work_type_id]").val(response.work_type).change()
if (parentForm.find("[name=attendance_date]").val().length == 0) {
parentForm.find("[name=attendance_date]").val(response.checkin_date)
}
}
});
}
function attendanceDateChange(selectElement) {
var selectedDate =selectElement.val()
let parentForm = selectElement.parents().closest("form")

View File

@@ -105,33 +105,6 @@
// ==================== Attendance request ====================
function shiftChange(selectElement) {
var shiftId =selectElement.val()
let parentForm = selectElement.parents().closest("form")
var attendanceDate = parentForm.find("[name=attendance_date]").first().val()
$.ajax({
type: "post",
url: "{% url 'update-shift-details' %}",
data: {
csrfmiddlewaretoken: getCookie("csrftoken"),
"shift_id":shiftId,
"attendance_date":attendanceDate
},
success: function (response) {
parentForm.find("[name=attendance_clock_in]").val(response.shift_start_time)
parentForm.find("[name=attendance_clock_out]").val(response.shift_end_time)
parentForm.find("[name=attendance_worked_hour]").val(response.worked_hour)
parentForm.find("[name=minimum_hour]").val(response.minimum_hour)
parentForm.find("[name=attendance_clock_out_date]").val(response.checkout_date)
parentForm.find("[name=attendance_clock_in_date]").val(response.checkin_date)
if (parentForm.find("[name=attendance_date]").val().length == 0) {
parentForm.find("[name=attendance_date]").val(response.checkin_date)
}
}
});
}
function dateChange(selectElement) {
var selectedDate =selectElement.val()
let parentForm = selectElement.parents().closest("form")