Modifed Time Attendance report exported file name

This commit is contained in:
2025-10-13 10:57:55 -04:00
parent 76ab9d83d2
commit 8269751b08
+64 -116
View File
@@ -7204,23 +7204,48 @@ def export_time_attendance():
# Generate filename # Generate filename
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
# Format dates for filename (MMDDYYYY format)
date_from_formatted = ''
date_to_formatted = ''
if start_date:
try:
date_obj = datetime.strptime(start_date, '%Y-%m-%d')
date_from_formatted = date_obj.strftime('%m%d%Y')
except ValueError:
pass
if end_date:
try:
date_obj = datetime.strptime(end_date, '%Y-%m-%d')
date_to_formatted = date_obj.strftime('%m%d%Y')
except ValueError:
pass
# Build filename with date range
# Format: time_attendance_[fromdate_todate].xlsx/csv
date_range_str = ''
if date_from_formatted and date_to_formatted:
date_range_str = f"{date_from_formatted}_{date_to_formatted}"
elif date_from_formatted:
date_range_str = f"{date_from_formatted}"
elif date_to_formatted:
date_range_str = f"{date_to_formatted}"
# Keep the filter_str for backward compatibility (but not in filename anymore)
filter_desc = [] filter_desc = []
if employee_filter: if employee_filter:
filter_desc.append(f"emp_{employee_filter}") filter_desc.append(f"emp_{employee_filter}")
if location_filter: if location_filter:
filter_desc.append(f"loc_{location_filter[:10]}") filter_desc.append(f"loc_{location_filter[:10]}")
if start_date:
filter_desc.append(f"from_{start_date}")
if end_date:
filter_desc.append(f"to_{end_date}")
filter_str = "_".join(filter_desc) if filter_desc else "all" filter_str = "_".join(filter_desc) if filter_desc else "all"
# Export based on format # Export based on format
if export_format == 'excel' or export_format == 'xlsx': if export_format == 'excel' or export_format == 'xlsx':
return export_time_attendance_excel(records, timestamp, filter_str) return export_time_attendance_excel(records, timestamp, date_range_str, filter_str)
else: else:
return export_time_attendance_csv(records, timestamp, filter_str) return export_time_attendance_csv(records, timestamp, date_range_str, filter_str)
except Exception as e: except Exception as e:
logger_handler.logger.error(f"Error exporting time attendance records: {e}") logger_handler.logger.error(f"Error exporting time attendance records: {e}")
@@ -7228,7 +7253,7 @@ def export_time_attendance():
return redirect(url_for('time_attendance_records')) return redirect(url_for('time_attendance_records'))
def export_time_attendance_csv(records, timestamp, filter_str): def export_time_attendance_csv(records, timestamp, date_range_str, filter_str):
"""Generate CSV export of time attendance records""" """Generate CSV export of time attendance records"""
import csv import csv
import io import io
@@ -7264,9 +7289,9 @@ def export_time_attendance_csv(records, timestamp, filter_str):
record.recorded_address or '' record.recorded_address or ''
]) ])
# Prepare response # Prepare response with new filename format
output.seek(0) output.seek(0)
filename = f'time_attendance_{filter_str}_{timestamp}.csv' filename = f'time_attendance_{date_range_str}.csv'
return Response( return Response(
output.getvalue(), output.getvalue(),
@@ -7276,7 +7301,7 @@ def export_time_attendance_csv(records, timestamp, filter_str):
} }
) )
def export_time_attendance_excel(records, timestamp, filter_str): def export_time_attendance_excel(records, timestamp, date_range_str, filter_str):
"""Generate Excel export of time attendance records""" """Generate Excel export of time attendance records"""
import io import io
from openpyxl import Workbook from openpyxl import Workbook
@@ -7298,126 +7323,49 @@ def export_time_attendance_excel(records, timestamp, filter_str):
bottom=Side(style='thin') bottom=Side(style='thin')
) )
# Headers # Header row
headers = [ headers = ['Employee ID', 'Employee Name', 'Platform', 'Date', 'Time',
'Employee ID', 'Employee Name', 'Platform', 'Date', 'Time', 'Location Name', 'Action Description', 'Event Description', 'Recorded Address']
'Location Name', 'Action Description', 'Event Description',
'Recorded Address'
]
# Write headers
for col_num, header in enumerate(headers, 1): for col_num, header in enumerate(headers, 1):
cell = ws.cell(row=1, column=col_num) cell = ws.cell(row=1, column=col_num, value=header)
cell.value = header
cell.fill = header_fill cell.fill = header_fill
cell.font = header_font cell.font = header_font
cell.alignment = Alignment(horizontal='center', vertical='center') cell.alignment = Alignment(horizontal='center', vertical='center')
cell.border = border cell.border = border
# Write data # Data rows
for row_num, record in enumerate(records, 2): for row_num, record in enumerate(records, 2):
data = [ ws.cell(row=row_num, column=1, value=record.employee_id).border = border
record.employee_id, ws.cell(row=row_num, column=2, value=record.employee_name).border = border
record.employee_name, ws.cell(row=row_num, column=3, value=record.platform or '').border = border
record.platform or '', ws.cell(row=row_num, column=4, value=record.attendance_date.strftime('%Y-%m-%d') if record.attendance_date else '').border = border
record.attendance_date.strftime('%Y-%m-%d') if record.attendance_date else '', ws.cell(row=row_num, column=5, value=record.attendance_time.strftime('%H:%M:%S') if record.attendance_time else '').border = border
record.attendance_time.strftime('%H:%M:%S') if record.attendance_time else '', ws.cell(row=row_num, column=6, value=record.location_name).border = border
record.location_name, ws.cell(row=row_num, column=7, value=record.action_description).border = border
record.action_description, ws.cell(row=row_num, column=8, value=record.event_description or '').border = border
record.event_description or '', ws.cell(row=row_num, column=9, value=record.recorded_address or '').border = border
record.recorded_address or ''
]
for col_num, value in enumerate(data, 1): # Auto-size columns
cell = ws.cell(row=row_num, column=col_num) for col in ws.columns:
cell.value = value max_length = 0
cell.border = border column = col[0].column_letter
for cell in col:
try:
if len(str(cell.value)) > max_length:
max_length = len(str(cell.value))
except:
pass
adjusted_width = min(max_length + 2, 50)
ws.column_dimensions[column].width = adjusted_width
# Special formatting for specific columns # Save to BytesIO
if col_num in [5, 6]: # Date and Time columns
cell.alignment = Alignment(horizontal='center')
elif col_num in [1, 2]: # ID columns
cell.alignment = Alignment(horizontal='right')
# Adjust column widths
column_widths = {
'A': 8, # ID
'B': 12, # Employee ID
'C': 20, # Employee Name
'D': 15, # Platform
'E': 12, # Date
'F': 10, # Time
'G': 20, # Location Name
'H': 18, # Action Description
'I': 25, # Event Description
'J': 30, # Recorded Address
'K': 15, # Import Batch ID
'L': 18, # Import Date
'M': 25 # Import Source
}
for col, width in column_widths.items():
ws.column_dimensions[col].width = width
# Freeze header row
ws.freeze_panes = 'A2'
# Add summary sheet
ws_summary = wb.create_sheet("Summary")
# Summary statistics
total_records = len(records)
unique_employees = len(set(r.employee_id for r in records))
unique_locations = len(set(r.location_name for r in records))
date_range_start = min(r.attendance_date for r in records if r.attendance_date)
date_range_end = max(r.attendance_date for r in records if r.attendance_date)
# Action breakdown
action_counts = {}
for record in records:
action = record.action_description
action_counts[action] = action_counts.get(action, 0) + 1
# Write summary
summary_data = [
['Time Attendance Export Summary'],
[''],
['Export Date:', datetime.now().strftime('%Y-%m-%d %H:%M:%S')],
['Exported By:', session.get('username', 'Unknown')],
[''],
['Statistics'],
['Total Records:', total_records],
['Unique Employees:', unique_employees],
['Unique Locations:', unique_locations],
['Date Range:', f"{date_range_start.strftime('%Y-%m-%d')} to {date_range_end.strftime('%Y-%m-%d')}"],
[''],
['Actions Breakdown']
]
for action, count in sorted(action_counts.items()):
summary_data.append([action, count])
for row_num, row_data in enumerate(summary_data, 1):
for col_num, value in enumerate(row_data, 1):
cell = ws_summary.cell(row=row_num, column=col_num)
cell.value = value
# Style the title
if row_num == 1:
cell.font = Font(bold=True, size=14)
elif row_num in [6, 12]: # Section headers
cell.font = Font(bold=True, size=11)
# Adjust summary column widths
ws_summary.column_dimensions['A'].width = 25
ws_summary.column_dimensions['B'].width = 15
# Save to bytes
output = io.BytesIO() output = io.BytesIO()
wb.save(output) wb.save(output)
output.seek(0) output.seek(0)
filename = f'time_attendance_{filter_str}_{timestamp}.xlsx' # New filename format
filename = f'time_attendance_{date_range_str}.xlsx'
return send_file( return send_file(
output, output,