[UPDT] ATTENDANCE: Work record colored view and export option

This commit is contained in:
Horilla
2024-05-09 14:25:34 +05:30
parent d8e3dd8b58
commit f6bacfbe1f
4 changed files with 159 additions and 48 deletions

View File

@@ -1,4 +1,31 @@
{% load i18n %} {% load attendancefilters %}
<div class="d-flex justify-content-between m-2 ms-0">
<button class="oh-btn oh-btn--secondary" data-toggle="oh-modal-toggle" data-target="#exportRecords" onclick="window.location.href = `{% url 'work-record-export' %}?month={{leave_dates.0.month}}&year={{leave_dates.0.year}}`">
<ion-icon name="download-outline" class="mr-1 md hydrated" role="img" aria-label="download"></ion-icon>{% trans "Export" %}
</button>
<div class="d-flex flex-row-reverse m-2">
<span class="" style="margin-left: 10px;">
<span class="oh-dot oh-dot--small me-1" style="background-color:#ed4c4c"></span>
{% trans "Conflict" %}
</span>
<span class="me-3" style="margin-left: 10px;">
<span class="oh-dot oh-dot--small me-1" style="background-color:#a8b1ff"></span>
{% trans "Expected Working" %}
</span>
<span class="me-3" style="margin-left: 10px;">
<span class="oh-dot oh-dot--small me-1" style="background-color:#808080"></span>
{% trans "Absent" %}
</span>
<span class="me-3" style="margin-left: 10px;">
<span class="oh-dot oh-dot--small me-1" style="background-color:#dfdf52"></span>
{% trans "Half Day Present" %}
</span>
<span class="me-3" style="margin-left: 10px;">
<span class="oh-dot oh-dot--small me-1" style="background-color:#38c338"></span>
{% trans "Present" %}
</span>
</div>
</div>
<div class="oh-sticky-table">
<table>
<thead>

View File

@@ -50,53 +50,25 @@
<div>
<h4>{% trans "Work Records" %}</h4>
</div>
<div class="me-3 d-flex flex-row-reverse align-items-center" >
<div>
<h6 class="mb-2 fw-bold">{% trans "Date:" %} {{ current_date }}</h6>
<h6>
<div style = "cursor: pointer;">
<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"
id="monthYearField"
value="{{ current_date|date:"Y-m" }}"
name="month"
hx-get="{% url 'work-records-change-month' %}"
hx-target="#workRecordTable"
hx-trigger="input">
</div>
</h6>
</div>
<div style="width:250px">
<div class="d-flex oh-wrapper" style="align-items: center">
<div>
<div class="draft me-3" style="margin-left: 5px; margin-bottom:5px">
<div class="oh-dot oh-dot--small me-1" style="background-color: #a8b1ff;"></div>
{% trans "Expected Working" %}
</div>
<div class="review_ongoing me-3" onclick="$('[name=status]').val('review_ongoing'); $('[name=status]').first().change(); $('.filterButton').click()" style=" margin-left: 5px; margin-bottom:5px">
<div class="oh-dot oh-dot--small me-1" style="background-color: #dfdf52;"></div>
{% trans "Half Day Present" %}
</div>
</div>
<div>
<div class="confirmed me-3" onclick="$('[name=status]').val('confirmed'); $('[name=status]').first().change(); $('.filterButton').click()" style=" margin-left: 5px; margin-bottom:5px">
<div class="oh-dot oh-dot--small me-1" style="background-color: #38c338;"></div>
{% trans "Present" %}
</div>
<div class="paid me-3" onclick="$('[name=status]').val('paid'); $('[name=status]').first().change(); $('.filterButton').click()" style=" margin-left: 5px; margin-bottom:5px">
<div class="oh-dot oh-dot--small me-1" style="background-color: #808080;"></div>
{% trans "Absent" %}
</div>
</div>
<div class="me-3" >
<h6 class="mb-2 fw-bold">{% trans "Date:" %} {{ current_date }}</h6>
<h6>
<div style = "cursor: pointer;">
<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"
id="monthYearField"
value="{{ current_date|date:"Y-m" }}"
name="month"
hx-get="{% url 'work-records-change-month' %}"
hx-target="#workRecordTable"
hx-trigger="input">
</div>
</div>
</h6>
</div>
</div>
<div id="workRecordTable">
{% include "attendance/work_record/work_record_list.html" %}
<div id="workRecordTable" hx-get="{% url 'work-records-change-month' %}?month={{ current_date|date:"Y-m" }}" hx-trigger="load">
<div class="animated-background"></div>
</div>
</div>
</div>

View File

@@ -364,6 +364,7 @@ urlpatterns = [
name="delete-comment-file",
),
path("work-records/", views.work_records, name="work-records"),
path("work-record-export/", views.work_record_export, name="work-record-export"),
path(
"work-records-change-month",
views.work_records_change_month,

View File

@@ -13,6 +13,7 @@ provide the main entry points for interacting with the application's functionali
import calendar
import contextlib
import io
import json
from datetime import date, datetime, timedelta
from urllib.parse import parse_qs
@@ -1954,8 +1955,6 @@ def monthly_leave_days(month, year):
based_on_week = company_leave.based_on_week
based_on_week_day = company_leave.based_on_week_day
if based_on_week != None:
# Set Sunday as the first day of the week
calendar.setfirstweekday(6)
month_calendar = calendar.monthcalendar(year, month)
weeks = month_calendar[int(based_on_week)]
@@ -1968,9 +1967,8 @@ def monthly_leave_days(month, year):
date_name.weekday() == int(based_on_week_day)
and date_name not in leave_dates
):
leave_dates.append(date_name.day)
leave_dates.append(date_name)
else:
# Set Monday as the first day of the week
calendar.setfirstweekday(0)
month_calendar = calendar.monthcalendar(year, month)
for week in month_calendar:
@@ -2087,6 +2085,119 @@ def work_records_change_month(request):
)
@login_required
@permission_required("leave.add_leaverequest")
def work_record_export(request):
month = int(request.GET.get("month", date.today().month))
year = int(request.GET.get("year", date.today().year))
records = WorkRecord.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)]
leave_dates = monthly_leave_days(month, year)
data_rows = []
data = ["Employee"]
if info := request.user.employee_get.employee_work_info:
try:
employee_company = info.company_id
date_format = (
employee_company.date_format
if employee_company and employee_company.date_format
else "DD-MM-YYYY"
)
except:
date_format = "DD-MM-YYYY"
else:
date_format = "DD-MM-YYYY"
# Define date formats
date_formats = {
"DD-MM-YYYY": "%d-%m-%Y",
"DD.MM.YYYY": "%d.%m.%Y",
"DD/MM/YYYY": "%d/%m/%Y",
"MM/DD/YYYY": "%m/%d/%Y",
"YYYY-MM-DD": "%Y-%m-%d",
"YYYY/MM/DD": "%Y/%m/%d",
"MMMM D, YYYY": "%B %d, %Y",
"DD MMMM, YYYY": "%d %B, %Y",
"MMM. D, YYYY": "%b. %d, %Y",
"D MMM. YYYY": "%d %b. %Y",
"dddd, MMMM D, YYYY": "%A, %B %d, %Y",
}
format_string = date_formats[date_format]
for employee in Employee.objects.all():
row_data = {"Employee": employee}
for date_item in all_date_objects:
for record in records:
if date_item <= date.today() and date_item not in leave_dates:
date_item_string = date_item.strftime(format_string)
if employee == record.employee_id:
row_data[str(record.date.strftime(format_string))] = (
record.work_record_type
)
else:
row_data[str(date_item_string)] = "EW"
data_rows.append(row_data)
for date_item in all_date_objects:
data.append(str(date_item.strftime(format_string)))
data_frame = pd.DataFrame(data_rows, columns=data)
output = io.BytesIO()
with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
data_frame.to_excel(writer, index=False, sheet_name="Sheet1")
workbook = writer.book
worksheet = writer.sheets["Sheet1"]
format_abs = workbook.add_format(
{"bg_color": "#808080", "font_color": "#ffffff"}
)
format_fdp = workbook.add_format(
{"bg_color": "#38c338", "font_color": "#ffffff"}
)
format_hdp = workbook.add_format(
{"bg_color": "#dfdf52", "font_color": "#000000"}
)
format_conf = workbook.add_format(
{"bg_color": "#ed4c4c", "font_color": "#ffffff"}
)
format_ew = workbook.add_format(
{"bg_color": "#a8b1ff", "font_color": "#ffffff"}
)
for row_num in range(1, len(data_frame) + 1):
for col_num in range(1, len(data_frame.columns)):
cell_value = data_frame.iloc[row_num - 1, col_num]
if cell_value == "ABS":
worksheet.write(row_num, col_num, cell_value, format_abs)
elif cell_value == "FDP":
worksheet.write(row_num, col_num, cell_value, format_fdp)
elif cell_value == "HDP":
worksheet.write(row_num, col_num, cell_value, format_hdp)
elif cell_value == "CONF":
worksheet.write(row_num, col_num, cell_value, format_conf)
elif cell_value == "EW":
worksheet.write(row_num, col_num, cell_value, format_ew)
for i, col in enumerate(data_frame.columns):
column_len = max(data_frame[col].astype(str).map(len).max(), len(col))
worksheet.set_column(i, i, column_len)
output.seek(0)
response = HttpResponse(
output.read(),
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
)
response["Content-Disposition"] = 'attachment; filename="work_record_export.xlsx"'
return response
@login_required
@permission_required("attendance.add_attendancegeneralsetting")
def enable_timerunner(request):