[FIX]attendance bug fix

This commit is contained in:
Nikhil
2023-07-05 11:46:47 +05:30
parent f078ef62af
commit 81a38dd29a
8 changed files with 149 additions and 180 deletions

View File

@@ -20,9 +20,10 @@ class YourForm(forms.Form):
# Custom validation logic goes here
pass
"""
import uuid
import uuid, datetime
from calendar import month_name
from django import forms
from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError
from django.forms import DateTimeInput
@@ -132,6 +133,14 @@ class AttendanceUpdateForm(ModelForm):
kwargs["initial"] = initial
super().__init__(*args, **kwargs)
def as_p(self, *args, **kwargs):
"""
Render the form fields as HTML table rows with Bootstrap styling.
"""
context = {"form": self}
table_html = render_to_string("attendance_form.html", context)
return table_html
class AttendanceForm(ModelForm):
"""
@@ -166,6 +175,14 @@ class AttendanceForm(ModelForm):
}
def __init__(self, *args, **kwargs):
initial = {
"attendance_clock_out_date": datetime.datetime.today()
.date()
.strftime("%Y-%m-%d"),
"attendance_clock_out": datetime.datetime.today()
.time()
.strftime("%H:%M"),
}
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
@@ -183,7 +200,7 @@ class AttendanceForm(ModelForm):
initial[
"attendance_clock_out_date"
] = instance.attendance_clock_out_date.strftime("%Y-%m-%d")
kwargs["initial"] = initial
kwargs["initial"] = initial
super().__init__(*args, **kwargs)
self.fields["employee_id"].widget.attrs.update({"id": str(uuid.uuid4())})
self.fields["shift_id"].widget.attrs.update({"id": str(uuid.uuid4())})
@@ -201,6 +218,14 @@ class AttendanceForm(ModelForm):
instance.save()
return instance
def as_p(self, *args, **kwargs):
"""
Render the form fields as HTML table rows with Bootstrap styling.
"""
context = {"form": self}
table_html = render_to_string("attendance_form.html", context)
return table_html
def clean_employee_id(self):
"""
Used to validate employee_id field

View File

@@ -69,6 +69,7 @@ class AttendanceActivity(models.Model):
"""
AttendanceActivity model
"""
employee_id = models.ForeignKey(
Employee,
on_delete=models.CASCADE,
@@ -88,6 +89,7 @@ class AttendanceActivity(models.Model):
"""
Meta class to add some additional options
"""
ordering = ["-attendance_date", "employee_id__employee_first_name", "clock_in"]
@@ -95,6 +97,7 @@ class Attendance(models.Model):
"""
Attendance model_
"""
employee_id = models.ForeignKey(
Employee,
on_delete=models.CASCADE,
@@ -143,6 +146,7 @@ class Attendance(models.Model):
"""
Meta class to add some additional options
"""
unique_together = ("employee_id", "attendance_date")
permissions = [
("change_validateattendance", "Validate Attendance"),
@@ -253,11 +257,40 @@ class Attendance(models.Model):
employee_ot.save()
return employee_ot
def clean(self, *args, **kwargs):
super().clean(*args, **kwargs)
now = datetime.now().time()
today = datetime.today().date()
out_time = self.attendance_clock_out
if self.attendance_clock_in_date < self.attendance_date:
raise ValidationError(
{
"attendance_clock_in_date": \
"Attendance check-in date never smaller than attendance date"
}
)
if self.attendance_clock_out_date < self.attendance_clock_in_date:
raise ValidationError(
{
"attendance_clock_out_date": \
"Attendance check-out date never smaller than attendance check-in date"
}
)
if self.attendance_clock_out_date >= today:
if out_time > now:
raise ValidationError(
{"attendance_clock_out": "Check out time not allow in the future"}
)
print("----------------------")
print(now)
print("----------------------")
class AttendanceOverTime(models.Model):
"""
AttendanceOverTime model
"""
employee_id = models.ForeignKey(
Employee,
on_delete=models.CASCADE,
@@ -288,6 +321,7 @@ class AttendanceOverTime(models.Model):
"""
Meta class to add some additional options
"""
unique_together = [("employee_id"), ("month"), ("year")]
ordering = ["-year", "-month_sequence"]
@@ -317,6 +351,7 @@ class AttendanceLateComeEarlyOut(models.Model):
"""
AttendanceLateComeEarlyOut model
"""
choices = [
("late_come", _("Late Come")),
("early_out", _("Early Out")),
@@ -338,6 +373,7 @@ class AttendanceLateComeEarlyOut(models.Model):
"""
Meta class to add some additional options
"""
unique_together = [("attendance_id"), ("type")]
def __str__(self) -> str:
@@ -349,6 +385,7 @@ class AttendanceValidationCondition(models.Model):
"""
AttendanceValidationCondition model
"""
validation_at_work = models.CharField(
default="09:00", max_length=10, validators=[validate_time_format]
)

View File

@@ -1,86 +1,8 @@
{% load i18n %}
<form hx-post="{% url 'attendance-create' %}" hx-target="#addAttendanceModalBody" id="addForm">
<div class="row">
<div class="col-12">
<label class="oh-label" for="firstname">{% trans "Employee" %}</label>
{{form.employee_id}}
{{form.employee_id.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Shift" %}</label>
{{form.shift_id}}
{{form.shift_id.errors}}
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Work Type" %}</label>
{{form.work_type_id}}
{{form.work_type_id.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Attendance Date" %}</label>
{{form.attendance_date}}
{{form.attendance_date.errors}}
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Minimum Hour" %}</label>
{{form.minimum_hour}}
{{form.minimum_hour.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Check-In Date" %}</label>
{{form.attendance_clock_in_date}}
{{form.attendance_clock_in_date.errors}}
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "In Time" %}</label>
{{form.attendance_clock_in}}
{{form.attendance_clock_in.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Check-Out Date" %}</label>
{{form.attendance_clock_out_date}}
{{form.attendance_clock_out_date.errors}}
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Out Time" %}</label>
{{form.attendance_clock_out}}
{{form.attendance_clock_out.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "At Work" %}</label>
{{form.attendance_worked_hour}}
{{form.attendance_worked_hour.errors}}
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Overtime" %}</label>
{{form.attendance_overtime}}
{{form.attendance_overtime.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Validated" %}</label><br>
{{form.attendance_validated}}
{{form.attendance_validated.errors}}
</div>
</div>
</div>
</div>
<div class="oh-modal__dialog-footer">
<input type="submit" value='{% trans "Add Attendance" %}' class="oh-btn oh-btn--secondary oh-btn--shadow">
</div>
</form>
<form
hx-post="{% url 'attendance-create' %}"
hx-target="#addAttendanceModalBody"
id="addForm"
>
{{form.as_p}}
</form>

View File

@@ -478,7 +478,7 @@ aria-hidden="true"
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
<div id="updateAttendanceModalBody">
<div class="oh-modal__dialog-body" id="updateAttendanceModalBody">
</div>
</div>

View File

@@ -1,92 +1,11 @@
{% load i18n %}
<form hx-post="{% url 'attendance-update' form.instance.id %}" hx-swap="#updateAttendanceModalBody" method="post" id="updateForm">
<div class="oh-modal__dialog-body">
{% csrf_token %}
<div class="row">
<div class="col-12">
<label class="oh-label" for="firstname">{% trans "Employee" %}</label>
{{form.employee_id}}
{{form.employee_id.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Shift" %}</label>
{{form.shift_id}}
{{form.shift_id.errors}}
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Work Type" %}</label>
{{form.work_type_id}}
{{form.work_type_id.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Attendance Date" %}</label>
{{form.attendance_date}}
{{form.attendance_date.errors}}
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Minimum Hour" %}</label>
{{form.minimum_hour}}
{{form.minimum_hour.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Check-In Date" %}</label>
{{form.attendance_clock_in_date}}
{{form.attendance_clock_in_date.errors}}
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "In Time" %}</label>
{{form.attendance_clock_in}}
{{form.attendance_clock_in.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Check-Out Date" %}</label>
{{form.attendance_clock_out_date}}
{{form.attendance_clock_out_date.errors}}
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Out Time" %}</label>
{{form.attendance_clock_out}}
{{form.attendance_clock_out.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "At Work" %}</label>
{{form.attendance_worked_hour}}
{{form.attendance_worked_hour.errors}}
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Overtime" %}</label>
{{form.attendance_overtime}}
{{form.attendance_overtime.errors}}
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6">
<label class="oh-label" for="lastname">{% trans "Validated" %}</label><br>
{{form.attendance_validated}}
{{form.attendance_validated.errors}}
</div>
</div>
</div>
</div>
</div>
<div class="oh-modal__dialog-footer">
<input type="submit" value='Save' class="pl-5 pr-5 oh-btn oh-btn--secondary oh-btn--shadow">
<form
hx-post="{% url 'attendance-update' form.instance.id %}"
hx-swap="#updateAttendanceModalBody"
method="post"
id="updateForm"
>
{{form.as_p}}
<script></script>
</form>
</div>
<script>
</script>

View File

@@ -7,8 +7,8 @@
<div class="oh-sticky-table__th"hx-target='#activity-table' hx-get="{% url 'attendance-activity-search' %}?{{pd}}&orderby=employee_id__employee_first_name">{% trans "Employee" %}</div>
<div class='oh-sticky-table__th'hx-target='#activity-table' hx-get="{% url 'attendance-activity-search' %}?{{pd}}&orderby=attendance_date">{% trans "Attendnace Date" %}</div>
<div class='oh-sticky-table__th'hx-target='#activity-table' hx-get="{% url 'attendance-activity-search' %}?{{pd}}&orderby=clock_in_date">{% trans "In Date" %}</div>
<div class='oh-sticky-table__th'hx-target='#activity-table' hx-get="{% url 'attendance-activity-search' %}?{{pd}}&orderby=">{% trans "Clock In" %}</div>
<div class='oh-sticky-table__th'hx-target='#activity-table' hx-get="{% url 'attendance-activity-search' %}?{{pd}}&orderby=">{% trans "Clock Out" %}</div>
<div class='oh-sticky-table__th'hx-target='#activity-table' hx-get="{% url 'attendance-activity-search' %}?{{pd}}&orderby=">{% trans "Check In" %}</div>
<div class='oh-sticky-table__th'hx-target='#activity-table' hx-get="{% url 'attendance-activity-search' %}?{{pd}}&orderby=">{% trans "Check Out" %}</div>
<div class='oh-sticky-table__th'hx-target='#activity-table' hx-get="{% url 'attendance-activity-search' %}?{{pd}}&orderby=clock_out_date">{% trans "Out Date" %}</div>
</div>
</div>

View File

@@ -0,0 +1,50 @@
{% load widget_tweaks %} {% load attendancefilters %}
<div class="oh-general__tab-target oh-profile-section" id="personal">
<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 %}
<label
class="oh-label"
for="id_{{ field.name }}"
title="{{ field.help_text|safe }}"
>{{ field.label }}</label
>
{{ field|add_class:"form-control" }}
{{field.errors}}
{% else %}
<div class="col-12 col-md-6">
<label
class="oh-label"
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"
>
Save
</button>
</div>
</div>
</div>

View File

@@ -6,6 +6,7 @@ This module is used to write custom template filters.
"""
from itertools import groupby
from django import template
from django.forms.widgets import SelectMultiple
from django.template import TemplateSyntaxError
from django.template.defaultfilters import register
from attendance.views import strtime_seconds
@@ -172,3 +173,18 @@ def any_permission(user, app_label):
bool: True if any permission on the module
"""
return user.has_module_perms(app_label)
@register.filter
def is_select_multiple(widget):
"""
Custom template filter to check if a widget is an instance of SelectMultiple.
Usage:
{% load custom_filters %}
{% if field.field.widget|is_select_multiple %}
<!-- Your code here -->
{% endif %}
"""
return isinstance(widget, SelectMultiple)