weekly attendance auto mail
This commit is contained in:
parent
0e99df97ad
commit
2be841e823
|
|
@ -0,0 +1 @@
|
||||||
|
from . import models
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
'name': 'Weekly Attendance Email Report',
|
||||||
|
'version': '1.0',
|
||||||
|
'category': 'Human Resources',
|
||||||
|
'depends': ['hr_attendance', 'mail'],
|
||||||
|
'data': [
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
'application': False,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
from . import attendance_report
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
from odoo import models, fields, api
|
||||||
|
from datetime import timedelta
|
||||||
|
import json
|
||||||
|
from collections import defaultdict
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class AttendanceWeeklyReport(models.Model):
|
||||||
|
_name = 'attendance.weekly.report'
|
||||||
|
_description = 'Weekly Attendance Report'
|
||||||
|
|
||||||
|
def send_weekly_attendance_email(self):
|
||||||
|
management_emails = self.env['hr.employee'].search([
|
||||||
|
('department_id.name', '=', 'Administration'),
|
||||||
|
('work_email', '!=', False)
|
||||||
|
]).mapped('work_email')
|
||||||
|
|
||||||
|
if not management_emails:
|
||||||
|
return
|
||||||
|
|
||||||
|
today = fields.Date.context_today(self)
|
||||||
|
last_monday = today - timedelta(days=today.weekday() + 7)
|
||||||
|
last_sunday = last_monday + timedelta(days=6)
|
||||||
|
|
||||||
|
attendances = self.env['hr.attendance'].search([
|
||||||
|
('check_in', '>=', str(last_monday)),
|
||||||
|
('check_out', '<=', str(last_sunday + timedelta(days=1)))
|
||||||
|
])
|
||||||
|
|
||||||
|
employee_data = {}
|
||||||
|
|
||||||
|
employee_data = defaultdict(list)
|
||||||
|
grouped_attendance = defaultdict(lambda: defaultdict(list)) # {emp: {date: [attendances]}}
|
||||||
|
|
||||||
|
for att in attendances:
|
||||||
|
emp = att.employee_id.name
|
||||||
|
date = att.check_in.date()
|
||||||
|
grouped_attendance[emp][date].append(att)
|
||||||
|
|
||||||
|
for emp_name, dates in grouped_attendance.items():
|
||||||
|
for date, records in dates.items():
|
||||||
|
records = sorted(records, key=lambda a: a.check_in)
|
||||||
|
total_seconds = 0
|
||||||
|
first_in = records[0].check_in.time().strftime('%H:%M')
|
||||||
|
last_out = 'N/A'
|
||||||
|
|
||||||
|
for rec in records:
|
||||||
|
if rec.check_in and rec.check_out:
|
||||||
|
total_seconds += (rec.check_out - rec.check_in).total_seconds()
|
||||||
|
last_out = rec.check_out.time().strftime('%H:%M')
|
||||||
|
|
||||||
|
employee_data[emp_name].append({
|
||||||
|
'date': date.strftime('%Y-%m-%d'),
|
||||||
|
'in': first_in,
|
||||||
|
'out': last_out,
|
||||||
|
'hours': f'{total_seconds / 3600:.2f}',
|
||||||
|
})
|
||||||
|
|
||||||
|
# Inline QWeb-compatible HTML template (must be in a real view in production)
|
||||||
|
html_template = """
|
||||||
|
<div style="max-width:800px;margin:auto;background-color:#fff;padding:20px;border:1px solid #ddd;border-radius:8px;">
|
||||||
|
<p>Dear Management,</p>
|
||||||
|
<p>
|
||||||
|
Please find below the attendance summary for the period
|
||||||
|
<strong>%(from_date)s</strong> to <strong>%(to_date)s</strong>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
%(employee_tables)s
|
||||||
|
|
||||||
|
<p style="margin-top: 24px;">Regards,<br/><strong>Odoo HR System</strong></p>
|
||||||
|
<a href="https://ftprotech.in/odoo/attendances" target="_blank" style="color:#1e88e5;text-decoration:none;">For more details, visit ftprotech.in</a>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
|
||||||
|
employee_tables_html = ""
|
||||||
|
if employee_data:
|
||||||
|
for emp_name, records in employee_data.items():
|
||||||
|
rows = ""
|
||||||
|
total = 0
|
||||||
|
for line in records:
|
||||||
|
total += float(line['hours']) if line['hours'] != False else 0
|
||||||
|
rows += f"""
|
||||||
|
<tr style="background-color:#fafafa;">
|
||||||
|
<td style="border:1px solid #ddd;padding:8px;">{line['date']}</td>
|
||||||
|
<td style="border:1px solid #ddd;padding:8px;">{line['in']}</td>
|
||||||
|
<td style="border:1px solid #ddd;padding:8px;">{line['out']}</td>
|
||||||
|
<td style="border:1px solid #ddd;padding:8px;">{line['hours']}</td>
|
||||||
|
</tr>
|
||||||
|
"""
|
||||||
|
t =f"""
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:left;font-size: 14px;">
|
||||||
|
<strong>Total worked Hours {total:.2f}</strong>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
"""
|
||||||
|
table = f"""
|
||||||
|
<div style="margin-bottom: 30px;">
|
||||||
|
<h3 style="margin-bottom:10px;color:#2c3e50;font-size:16px;">{emp_name}</h3>
|
||||||
|
<table style="width:100%;border-collapse:collapse;font-size:13px;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="border:1px solid #ccc;padding:8px;background-color:#e0e0e0;text-align:left;">Date</th>
|
||||||
|
<th style="border:1px solid #ccc;padding:8px;background-color:#e0e0e0;text-align:left;">Check In</th>
|
||||||
|
<th style="border:1px solid #ccc;padding:8px;background-color:#e0e0e0;text-align:left;">Check Out</th>
|
||||||
|
<th style="border:1px solid #ccc;padding:8px;background-color:#e0e0e0;text-align:left;">Hours Worked</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>{rows}{t}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
employee_tables_html += table
|
||||||
|
else:
|
||||||
|
employee_tables_html = "<p>No attendance data available for this period.</p>"
|
||||||
|
|
||||||
|
# Final HTML body
|
||||||
|
body_html = html_template % {
|
||||||
|
'from_date': last_monday.strftime('%Y-%m-%d'),
|
||||||
|
'to_date': last_sunday.strftime('%Y-%m-%d'),
|
||||||
|
'employee_tables': employee_tables_html
|
||||||
|
}
|
||||||
|
|
||||||
|
# Send email to all management emails
|
||||||
|
for email in management_emails:
|
||||||
|
self.env['mail.mail'].create({
|
||||||
|
'email_to': email,
|
||||||
|
'subject': f"Weekly Attendance Report: {last_monday} to {last_sunday}",
|
||||||
|
'body_html': body_html,
|
||||||
|
}).send()
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
id,name,model_id:id,group_id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_attendance_weekly_report,access_attendance_weekly_report,model_attendance_weekly_report,,1,1,1,1
|
||||||
|
Loading…
Reference in New Issue