[ADD] ATTENDANCE: Work record date filter

This commit is contained in:
Horilla
2025-10-14 14:20:41 +05:30
parent b703e7e32f
commit 3d653b0e7e
3 changed files with 183 additions and 25 deletions

View File

@@ -1,6 +1,61 @@
{% extends 'index.html' %} {% block content %} {% load i18n %}
<style>
.date-filter-form {
display: flex;
flex-wrap: wrap;
gap: 1rem 2rem;
align-items: flex-end;
background-color: #f9f9f9;
padding: 1rem 1.5rem;
border-radius: 8px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
max-width: 700px;
margin-bottom: 1.5rem;
}
/* Stack label and input vertically */
.input-group {
display: flex;
flex-direction: column;
gap: 0.3rem;
}
/* Button aligns right */
.button-group {
margin-left: auto;
}
/* Input style */
.oh-input {
padding: 0.5rem 0.75rem;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 0.95rem;
width: 180px;
}
/* Button style */
.oh-btn-filter {
padding: 0.5rem 1.25rem;
background-color: hsl(8, 77%, 56%);
color: white;
border: none;
border-radius: 5px;
font-size: 0.95rem;
cursor: pointer;
transition: background-color 0.3s ease;
}
.oh-btn-filter:hover {
background-color: hsl(8, 77%, 56%);
}
/* Label style */
.date-filter-form label {
font-weight: 500;
}
table {
width: 100%;
}
@@ -48,12 +103,12 @@
<div class="col-12 mt-4 mb-4">
<div class="oh-card d-flex justify-content-between align-items-center">
<div>
<h4>{% trans "Work Records" %}</h4>
<h4>{% trans "Work Record Status" %}</h4>
</div>
<div class="me-3" >
<h6 class="mb-2 fw-bold">{% trans "Date:" %} {{ current_date }}</h6>
<h6>
<div style = "cursor: pointer;display:flex;align-items:center">
{% comment %} <div style = "cursor: pointer;display:flex;align-items:center">
<label for="monthYearField" class="text-danger fw-bold" style = "cursor: pointer;">{% trans "Month" %}</label>
<input class="oh-select p-2 w-75 m-1"
type="month"
@@ -64,7 +119,27 @@
hx-target="#workRecordTable"
hx-trigger="change"
>
</div>
</div> {% endcomment %}
<form
id="dateFilterForm"
hx-get="{% url 'work-records-change-month' %}"
hx-target="#workRecordTable"
class="date-filter-form"
>
<div class="input-group">
<label for="startDate">Start Date:</label>
<input type="date" name="start_date" id="startDate" class="oh-input">
</div>
<div class="input-group">
<label for="endDate">End Date:</label>
<input type="date" name="end_date" id="endDate" class="oh-input" max="{{ today|date:'Y-m-d' }}">
</div>
<div class="button-group">
<button type="submit" class="oh-btn-filter">Filter</button>
</div>
</form>
</h6>
</div>
</div>

View File

@@ -1,19 +1,25 @@
{% load i18n %}
{% if perms.attendance.delete_attendanceactivity %}
<div class="detail-view" style="width: 100%;" onclick="event.stopPropagation()">
<button class="oh-btn oh-btn-group oh-btn--secondary"
hx-confirm="{% trans 'Are you sure you want to delete ?' %}"
hx-post="{% url 'attendance-activity-delete' instance.id %}?instances_ids={{request.GET.instance_ids}}"
hx-target="#genericModalBody" style="width:100%;"
title="{% trans 'Delete' %}"
data-toggle="oh-modal-toggle">
<ion-icon class="me-1" name="trash-outline"></ion-icon>
</button>
</div>
<div class="detail-view" style="width: 100%" onclick="event.stopPropagation()">
<button
class="oh-btn oh-btn-group oh-btn--secondary"
hx-confirm="{% trans 'Are you sure you want to delete ?' %}"
hx-post="{% url 'attendance-activity-delete' instance.id %}?instances_ids={{request.GET.instance_ids}}"
hx-target="#genericModalBody"
style="width: 100%"
title="{% trans 'Delete' %}"
data-toggle="oh-modal-toggle"
>
<ion-icon class="me-1" name="trash-outline"></ion-icon>
{% trans 'Delete' %}
</button>
</div>
{% endif %}
{% if request.GET.deleted %}
<script>
$("#reloadMessagesButton").click()
$('.reload-record').click();
</script>
<script>
$("#reloadMessagesButton").click();
$(".reload-record").click();
</script>
{% endif %}

View File

@@ -2471,12 +2471,48 @@ def work_records_change_month(request):
employees = [request.user.employee_get] + list(page_emp.object_list)
month_dates = [
datetime(year, month, day).date()
for week in calendar.monthcalendar(year, month)
for day in week
if day
]
start_date_str = request.GET.get("start_date")
end_date_str = request.GET.get("end_date")
# Initialize as None
start_date = None
end_date = None
# Try parsing the start date
if start_date_str:
try:
start_date = datetime.strptime(start_date_str, "%Y-%m-%d").date()
except ValueError:
start_date = None
# Try parsing the end date
if end_date_str:
try:
end_date = datetime.strptime(end_date_str, "%Y-%m-%d").date()
except ValueError:
end_date = None
# Default end_date to today if missing or invalid
if not end_date:
today = date.today()
last_day = calendar.monthrange(today.year, today.month)[1]
end_date = date(today.year, today.month, last_day)
# Default start_date to first day of end_date's month if missing or invalid
if not start_date:
start_date = date(year=end_date.year, month=end_date.month, day=1)
# Ensure start_date is not after end_date
if start_date > end_date:
# Optional: raise error or swap, depending on your use case
start_date = date(year=end_date.year, month=end_date.month, day=1)
# Generate list of dates between start_date and end_date (inclusive)
month_dates = []
current_date = start_date
while current_date <= end_date:
month_dates.append(current_date)
current_date += timedelta(days=1)
work_records = WorkRecords.objects.filter(
date__in=month_dates, employee_id__in=page_emp.object_list
@@ -2512,6 +2548,7 @@ def work_records_change_month(request):
@login_required
@permission_required("attendance.view_workrecords")
def work_record_export(request):
try:
month_str = request.GET.get("month")
if month_str:
@@ -2524,8 +2561,48 @@ def work_record_export(request):
employees = EmployeeFilter(request.GET).qs
records = WorkRecords.objects.filter(date__month=month, date__year=year)
num_days = calendar.monthrange(year, month)[1]
all_date_objects = [date(year, month, day) for day in range(1, num_days + 1)]
# all_date_objects = [date(year, month, day) for day in range(1, num_days + 1)]
start_date_str = request.GET.get("start_date")
end_date_str = request.GET.get("end_date")
# Initialize as None
start_date = None
end_date = None
# Try parsing the start date
if start_date_str:
try:
start_date = datetime.strptime(start_date_str, "%Y-%m-%d").date()
except ValueError:
start_date = None
# Try parsing the end date
if end_date_str:
try:
end_date = datetime.strptime(end_date_str, "%Y-%m-%d").date()
except ValueError:
end_date = None
# Default end_date to today if missing or invalid
if not end_date:
end_date = date.today()
# Default start_date to first day of end_date's month if missing or invalid
if not start_date:
start_date = date(year=end_date.year, month=end_date.month, day=1)
# Ensure start_date is not after end_date
if start_date > end_date:
# Optional: raise error or swap, depending on your use case
start_date = date(year=end_date.year, month=end_date.month, day=1)
# Generate list of dates between start_date and end_date (inclusive)
all_date_objects = []
current_date = start_date
while current_date <= end_date:
all_date_objects.append(current_date)
current_date += timedelta(days=1)
leave_dates = set(monthly_leave_days(month, year))
record_lookup = defaultdict(lambda: "ABS")