changes
This commit is contained in:
@@ -182,6 +182,84 @@ class FusionClockReport(models.Model):
|
||||
else:
|
||||
_logger.warning("Fusion Clock: Mail template not found for report %s", self.id)
|
||||
|
||||
def action_export_csv(self):
|
||||
"""Export the report data as a CSV file for payroll."""
|
||||
import csv
|
||||
import io
|
||||
|
||||
self.ensure_one()
|
||||
if not self.attendance_ids:
|
||||
self._collect_attendance_records()
|
||||
|
||||
ICP = self.env['ir.config_parameter'].sudo()
|
||||
mapping_raw = ICP.get_param('fusion_clock.csv_column_mapping', '')
|
||||
import json as json_mod
|
||||
try:
|
||||
col_map = json_mod.loads(mapping_raw) if mapping_raw else {}
|
||||
except Exception:
|
||||
col_map = {}
|
||||
|
||||
default_cols = {
|
||||
'employee': 'Employee',
|
||||
'date': 'Date',
|
||||
'clock_in': 'Clock In',
|
||||
'clock_out': 'Clock Out',
|
||||
'worked_hours': 'Worked Hours',
|
||||
'net_hours': 'Net Hours',
|
||||
'break_min': 'Break (min)',
|
||||
'overtime': 'Overtime (h)',
|
||||
'penalties': 'Penalties',
|
||||
'location': 'Location',
|
||||
}
|
||||
for k in default_cols:
|
||||
if k in col_map:
|
||||
default_cols[k] = col_map[k]
|
||||
|
||||
output = io.StringIO()
|
||||
writer = csv.writer(output)
|
||||
writer.writerow(list(default_cols.values()))
|
||||
|
||||
for att in self.attendance_ids.sorted(key=lambda a: a.check_in):
|
||||
date_str = att.check_in.strftime('%Y-%m-%d') if att.check_in else ''
|
||||
in_str = att.check_in.strftime('%H:%M') if att.check_in else ''
|
||||
out_str = att.check_out.strftime('%H:%M') if att.check_out else ''
|
||||
penalties = self.env['fusion.clock.penalty'].search_count([
|
||||
('attendance_id', '=', att.id),
|
||||
])
|
||||
writer.writerow([
|
||||
att.employee_id.name or '',
|
||||
date_str,
|
||||
in_str,
|
||||
out_str,
|
||||
round(att.worked_hours or 0, 2),
|
||||
round(att.x_fclk_net_hours or 0, 2),
|
||||
round(att.x_fclk_break_minutes or 0, 0),
|
||||
round(att.x_fclk_overtime_hours or 0, 2),
|
||||
penalties,
|
||||
att.x_fclk_location_id.name or '',
|
||||
])
|
||||
|
||||
csv_data = output.getvalue().encode('utf-8')
|
||||
output.close()
|
||||
|
||||
filename = f"clock_export_{self.date_start}_{self.date_end}"
|
||||
if self.employee_id:
|
||||
filename += f"_{self.employee_id.name.replace(' ', '_')}"
|
||||
filename += ".csv"
|
||||
|
||||
attachment = self.env['ir.attachment'].create({
|
||||
'name': filename,
|
||||
'type': 'binary',
|
||||
'datas': base64.b64encode(csv_data),
|
||||
'mimetype': 'text/csv',
|
||||
})
|
||||
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': f'/web/content/{attachment.id}/{filename}?download=true',
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
@api.model
|
||||
def _cron_generate_period_reports(self):
|
||||
"""Cron: Generate reports when a pay period ends."""
|
||||
|
||||
Reference in New Issue
Block a user