Merge pull request #2942 from expsa/pla-451615-new-report-for-employee-totals

new report for employee attendance
This commit is contained in:
Mostafa Abdo 2025-04-29 19:12:56 -07:00 committed by GitHub
commit f98de60ef0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 890 additions and 460 deletions

File diff suppressed because it is too large Load Diff

View File

@ -323,6 +323,67 @@
</template>
<template id="totals_only_attendance_report_template">
<div class="page" style="font-size:12pt" dir="rtl">
<center>
<h2 style="font-weight:bold">تقرير الحضور والانصراف للموظفين</h2>
</center>
<br/>
<div class="row">
<div class="col-md-6">
<h4 style="font-weight:bold">من تاريخ</h4>
<t t-esc="date_start"/>
</div>
<div class="col-md-6">
<h4 style="font-weight:bold">إلى</h4>
<t t-esc="date_end"/>
</div>
</div>
<table class="table table-condensed" style="width:100%">
<thead style="width:100%;">
<tr style="width:100%;text-align:center;">
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">الرقم الوظيفي</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:10%;text-align:center;">اسم الموظف</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:10%;text-align:center;">رقم الهوية</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:10%;text-align:center;">اﻹدارة</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:10%;text-align:center;">المسمي الوظيفي</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">ايام الحضور</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">الاجازات</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">الاجازات الرسمية</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">الغياب</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">ساعات العمل الفعلية</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">ساعات العمل الاضافية</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">الاستئذان</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">مهام عمل/انتداب/تدريب</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">التأخيرات</th>
<th tyle="border: 1px solid gray; padding: 1px; font-size:0.8em;background-color: #b9d7d4;color: black;width:6%;text-align:center;">الخروج المبكر</th>
</tr>
</thead>
<tbody>
<t t-foreach="summary" t-as="row">
<tr style="text-align:center;font-weight:bold;background-color: #b9d7d4">
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['employee_number']"/>
<td style="border: 1px solid gray;padding: 1px; width:10%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['name']"/>
<td style="border: 1px solid gray;padding: 1px; width:10%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['iqama']"/>
<td style="border: 1px solid gray;padding: 1px; width:10%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['department']"/>
<td style="border: 1px solid gray;padding: 1px; width:10%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['job']"/>
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['days_present']"/>
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['leave_days']"/>
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['holiday_days']"/>
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['absent_days']"/>
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['office_hours']"/>
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['extra_hours']"/>
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['permission_hours']"/>
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['mission_hours']"/>
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['lateness_approved']"/>
<td style="border: 1px solid gray;padding: 1px; width:6%;font-size:0.8em;background-color: white;color: black; text-align:center" t-esc="row['early_exit_approved']"/>
</tr>
</t>
</tbody>
</table>
</div>
</template>
<template id="general_attendances_report_temp">
<t t-call="web.html_container">
<t t-call="web.external_layout">
@ -336,14 +397,19 @@
font-family: ae_AlMohanad;
}
</style>
<t t-if="type == 'late'">
<t t-call="attendances.late_attendance_report_template"/>
<t t-if="totals_only">
<t t-call="attendances.totals_only_attendance_report_template"/>
</t>
<t t-if="type == 'absent'">
<t t-call="attendances.absent_attendance_report_template"/>
</t>
<t t-if="type == 'employee'">
<t t-call="attendances.employee_attendance_report_template"/>
<t t-else="">
<t t-if="type == 'late'">
<t t-call="attendances.late_attendance_report_template"/>
</t>
<t t-if="type == 'absent'">
<t t-call="attendances.absent_attendance_report_template"/>
</t>
<t t-if="type == 'employee'">
<t t-call="attendances.employee_attendance_report_template"/>
</t>
</t>
</t>
</t>

View File

@ -15,9 +15,11 @@
</group>
<group>
<field name="to_date"/>
<!-- <field name="employee_ids" widget="many2many_tags"/>-->
</group>
</group>
<group>
<field name="print_totals_only"/>
</group>
<notebook>
<page string="Employees" >
<field name="employee_ids" nolabel="1" required="1">

View File

@ -1,62 +1,71 @@
# -*- coding: utf-8 -*-
import collections
import datetime
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
import pytz
from pytz import timezone
import collections
import datetime
from odoo import fields, models, _,api
from odoo.exceptions import ValidationError
WEEK_DAYS_AR = {
0: "الاثنين",
1: "الثلاثاء",
2: "الاربعاء",
3: "الخميس",
4: "الجمعة",
5: "السبت",
6: "الاحد",
}
def hhmm(val):
if not val:
return "00:00"
mins = float(val) * 60
return "{0:02.0f}:{1:02.0f}".format(*divmod(mins, 60))
week_dayS_arabic={0:"الاثنين", 1: 'الثلاثاء', 4:'الجمعة' , 2:'الاربعاء',3: 'الخميس', 6:'الاحد',5: 'السبت'}
class AttendancesReport(models.TransientModel):
_name = "employee.attendance.report"
_description = "Employee Attendance Report"
from_date = fields.Date(string='From Date', required=True)
to_date = fields.Date(string='To Date', required=True)
employee_ids = fields.Many2many(comodel_name='hr.employee', string='Employees' ,required=True)
resource_calender_id = fields.Many2one(comodel_name='resource.calendar', string='Employee work record')
type = fields.Selection(selection=[('late', 'Late and Early exit'), ('absent', 'Absent'), ('employee', 'Employee')],
required=True,
default='late', string='Type')
from_date = fields.Date(required=True)
to_date = fields.Date(required=True)
employee_ids = fields.Many2many("hr.employee", string="Employees", required=True)
resource_calender_id = fields.Many2one("resource.calendar", string="Employee work record")
type = fields.Selection([
("late", "Late and Early exit"),
("absent", "Absent"),
("employee", "Employee"),
], default="late", required=True)
print_totals_only = fields.Boolean(string="Totals only (one line per employee)", default=False)
def _payload(self):
return {
"ids": self.ids,
"model": self._name,
"form": {
"resource_calender_id": self.resource_calender_id.id,
"from_date": self.from_date,
"to_date": self.to_date,
"employee_ids": self.employee_ids.ids,
"type": self.type,
"print_totals_only": self.print_totals_only,
},
}
def print_report(self):
if not self.employee_ids:
raise ValidationError(_("Please select Employees Name"))
data = {
'ids': self.ids,
'model': self._name,
'form': {
'resource_calender_id': self.resource_calender_id.id,
'from_date': self.from_date,
'to_date': self.to_date,
'employee_ids': self.employee_ids.ids,
'type': self.type,
},
}
return self.env.ref('attendances.general_attendance_action_report').report_action(self, data=data)
return self.env.ref("attendances.general_attendance_action_report").report_action(self, data=self._payload())
def print_excel_report(self):
data = {
'ids': self.ids,
'model': self._name,
'form': {
'resource_calender_id': self.resource_calender_id.id,
'from_date': self.from_date,
'to_date': self.to_date,
'employee_ids': self.employee_ids.ids,
'type': self.type,
},
}
return self.env.ref('attendances.general_attendance_action_xls').report_action(self, data=data, config=False)
return self.env.ref("attendances.general_attendance_action_xls").report_action(self, data=self._payload(), config=False)
class ReportAttendancePublic(models.AbstractModel):
_name = 'report.attendances.general_attendances_report_temp'
_name = "report.attendances.general_attendances_report_temp"
_description = "General Attendances Report"
def get_value(self, data):
type = data['form']['type']
totals_only = data["form"].get("print_totals_only", False)
employee_ids = data['form']['employee_ids']
resource_calender_id = data['form']['resource_calender_id']
from_date = data['form']['from_date']
@ -68,7 +77,7 @@ class ReportAttendancePublic(models.AbstractModel):
total_dic = {}
mykey = []
resource = self.env['resource.calendar'].browse(resource_calender_id)
if resource and not employee_ids:
if resource and not employee_ids:
if resource.employee_ids:
for emp in resource.employee_ids:
employee_ids.append(emp.id)
@ -83,23 +92,23 @@ class ReportAttendancePublic(models.AbstractModel):
attendance_transaction_ids = self.env['hr.attendance.transaction'].search(domain)
employees = attendance_transaction_ids.mapped('employee_id.name')
employee_ids = attendance_transaction_ids.mapped('employee_id')
emp_data=[]
emp_data = []
for emp in employee_ids:
emp_data.append({'job': emp.sudo().job_id.name, 'department': emp.department_id.name,
'emp_no': emp.emp_no,'emp_namw':emp.name})
'emp_no': emp.emp_no, 'emp_namw': emp.name})
grouped_data = collections.defaultdict(list)
emp_data_dict={}
emp_data_dict = {}
for item in emp_data:
grouped_data[item['emp_namw']].append(item)
for key,value in grouped_data.items():
emp_data_dict[key]=list(value)
for key, value in grouped_data.items():
emp_data_dict[key] = list(value)
if type == 'late':
for resource in attendance_transaction_ids:
note=''
note = ''
if resource.is_absent:
note='غياب'
note = 'غياب'
elif resource.public_holiday:
note="عطلة رسمية"
note = "عطلة رسمية"
elif resource.official_id:
note = resource.official_id.mission_type.name
elif resource.normal_leave:
@ -109,27 +118,27 @@ class ReportAttendancePublic(models.AbstractModel):
data.append({
'date': resource.date,
'day': week_dayS_arabic[resource.date.weekday()],
'day': WEEK_DAYS_AR[resource.date.weekday()],
'sig_in': resource.sign_in,
'sig_out': resource.sign_out,
'lateness': resource.lateness,
'early_exit': resource.early_exit,
'extra_hours': resource.additional_hours,
'office_hours':resource.office_hours,
'note':note,
'department':resource.employee_id.department_id.name,
'employee_number':resource.employee_number,
'calendar_id':resource.calendar_id.name,
'office_hours': resource.office_hours,
'note': note,
'department': resource.employee_id.department_id.name,
'employee_number': resource.employee_number,
'calendar_id': resource.calendar_id.name,
'employee_id': resource.employee_id,
'employee_name': resource.employee_id.name,
})
data=sorted(data, key=lambda d: d['date'])
data = sorted(data, key=lambda d: d['date'])
for emp in employees:
list_cat = attendance_transaction_ids.filtered(lambda r: r.employee_id.name == emp)
total_lateness = sum(list_cat.mapped('lateness'))
total_early_exit = sum(list_cat.mapped('early_exit'))
total_late_early = str(datetime.timedelta(minutes=total_early_exit+total_lateness))
total_late_early = str(datetime.timedelta(minutes=total_early_exit + total_lateness))
total_extra_hours = sum(list_cat.mapped('additional_hours'))
total_extra_hours = str(datetime.timedelta(minutes=total_extra_hours))
list_absent = attendance_transaction_ids.filtered(
@ -141,11 +150,13 @@ class ReportAttendancePublic(models.AbstractModel):
list_not_log_out = attendance_transaction_ids.filtered(
lambda r: r.employee_id.name == emp and r.sign_out == 0.0)
list_leave = attendance_transaction_ids.filtered(
lambda r: r.employee_id.name == emp and (r.normal_leave or r.approve_personal_permission ))
lambda r: r.employee_id.name == emp and (r.normal_leave or r.approve_personal_permission))
total_not_sig_out = len(list_not_log_out)
total_leave = len(list_leave)
total_dic[emp] = {'total_lateness': total_lateness, 'total_early_exit': total_early_exit,
"total_extra_hours":total_extra_hours, "total_late_early":total_late_early,"total_leave":total_leave,'total_absent': total_absent, 'total_not_sig_in': total_not_sig_in,
"total_extra_hours": total_extra_hours, "total_late_early": total_late_early,
"total_leave": total_leave, 'total_absent': total_absent,
'total_not_sig_in': total_not_sig_in,
'total_not_sig_out': total_not_sig_out}
grouped = collections.defaultdict(list)
for item in data:
@ -154,7 +165,7 @@ class ReportAttendancePublic(models.AbstractModel):
final_dic[key] = list(value)
key_list.append(key)
mykey = list(dict.fromkeys(key_list))
return final_dic, mykey,total_dic,emp_data_dict
return final_dic, mykey, total_dic, emp_data_dict
elif type == 'absent':
for resource in attendance_transaction_ids.filtered(lambda r: r.is_absent == True):
@ -171,7 +182,7 @@ class ReportAttendancePublic(models.AbstractModel):
final_dic[key] = list(value)
key_list.append(key)
mykey = list(dict.fromkeys(key_list))
return final_dic, mykey, '',emp_data_dict
return final_dic, mykey, '', emp_data_dict
elif type == 'employee':
for emp in employees:
list_cat = attendance_transaction_ids.filtered(lambda r: r.employee_id.name == emp)
@ -182,20 +193,55 @@ class ReportAttendancePublic(models.AbstractModel):
total_dic[emp] = {'total_lateness': total_lateness, 'total_early_exit': total_early_exit}
key_list.append(emp)
mykey = list(dict.fromkeys(key_list))
print("mk",mykey,total_dic)
return '', mykey, total_dic,emp_data_dict
print("mk", mykey, total_dic)
return '', mykey, total_dic, emp_data_dict
@api.model
def _get_report_values(self, docids, data=None):
final_dic, mykey, total,emp_data = self.get_value(data)
final_dic, mykey, total, emp_data = self.get_value(data)
start_date = data['form']['from_date']
end_date = data['form']['to_date']
type = data['form']['type']
print("dataa",mykey,final_dic)
print("dataa", mykey, final_dic)
local_tz = pytz.timezone(
self.env.user.tz or 'GMT')
print_date=datetime.datetime.now(timezone('UTC'))
print_date=print_date.astimezone(local_tz)
print_date = datetime.datetime.now(timezone('UTC'))
print_date = print_date.astimezone(local_tz)
totals_only = data['form'].get('print_totals_only', False)
summary_rows = []
if totals_only:
domain = [('date', '>=', start_date), ('date', '<=', end_date)]
emp_ids = data['form']['employee_ids']
cal_id = data['form']['resource_calender_id']
if emp_ids:
domain.append(('employee_id', 'in', list(set(emp_ids))))
elif cal_id:
rc = self.env['resource.calendar'].browse(cal_id)
domain.append(('employee_id', 'in', rc.employee_ids.ids))
att = self.env['hr.attendance.transaction'].search(domain)
for emp in att.mapped('employee_id'):
lines = att.filtered(lambda l, e=emp: l.employee_id == e)
iq = getattr(emp, 'iqama_number', False) or getattr(emp, 'saudi_number', '')
summary_rows.append({
'employee_number': emp.emp_no or '',
'name': emp.name,
'iqama':iq.display_name or '',
'department': emp.department_id.name,
'job': emp.sudo().job_id.name,
'days_present': len({l.date for l in lines if not l.is_absent}),
'leave_days': len(lines.filtered(lambda l: l.normal_leave)),
'holiday_days': len(lines.filtered(lambda l: l.public_holiday)),
'absent_days': len(lines.filtered(lambda l: l.is_absent)),
'office_hours': hhmm(sum(lines.mapped('office_hours'))),
'extra_hours': hhmm(sum(lines.mapped('additional_hours'))),
'permission_hours': hhmm(sum(lines.mapped('total_permission_hours'))),
'mission_hours': hhmm(sum(lines.mapped('total_mission_hours'))),
'lateness_approved': hhmm(sum(lines.filtered(lambda l: l.approve_lateness).mapped('lateness'))),
'early_exit_approved': hhmm(sum(lines.filtered(lambda l: l.approve_exit_out).mapped('early_exit'))),
})
return {
'doc_ids': data['ids'],
'doc_model': data['model'],
@ -204,14 +250,15 @@ class ReportAttendancePublic(models.AbstractModel):
'type': type,
'data': final_dic,
'mykey': mykey,
'emp_data':emp_data,
'emp_data': emp_data,
'total': total,
'print_date':print_date.strftime("%H:%m %m/%d/%Y" ),
'print_user':self.env.user.name
'summary': summary_rows,
'totals_only': totals_only,
'print_date': print_date.strftime("%H:%m %m/%d/%Y"),
'print_user': self.env.user.name
}
class AttendancesReportXls(models.AbstractModel):
_name = 'report.attendances.general_attendance_xls'
_inherit = 'report.report_xlsx.abstract'
@ -219,19 +266,85 @@ class AttendancesReportXls(models.AbstractModel):
def generate_xlsx_report(self, workbook, data, datas):
self = self.with_context(lang=self.env.user.lang)
x = self.env['report.attendances.general_attendances_report_temp']
final_dic, mykey, total,emp_data = ReportAttendancePublic.get_value(x, data)
final_dic, mykey, total, emp_data = ReportAttendancePublic.get_value(x, data)
start_date = data['form']['from_date']
end_date = data['form']['to_date']
type = data['form']['type']
totals_only = data['form'].get('print_totals_only', False)
sheet = workbook.add_worksheet(U'Holiday Report')
calendar_id = data['form']['resource_calender_id']
sheet.right_to_left()
sheet.set_column(1, 10, 15)
# sheet.set_column(6, 100, 25)
employee_ids = data['form']['employee_ids']
format2 = workbook.add_format(
{'font_size': 10, 'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center',
'bold': True})
format2.set_align('center')
format2.set_align('vcenter')
fmt = workbook.add_format({'font_size': 10, 'border': 1, 'align': 'center', 'valign': 'vcenter', 'bold': True})
if totals_only:
sheet.merge_range('F2:P2', _('تقرير الحضور والانصراف للموظفين'), fmt)
sheet.write('G3', _('من تاريخ'), fmt)
sheet.write('J3', _('إلى تاريخ'), fmt)
sheet.write(2, 7, str(start_date)[0:10], fmt)
sheet.write(2, 10, str(end_date)[0:10], fmt)
headers = [
'الرقم الوظيفي', 'اسم الموظف', 'رقم الهوية', 'اﻹدارة', 'المسمي الوظيفي',
'ايام الحضور', 'الاجازات', 'الاجازات الرسمية', 'الغياب', 'ساعات العمل الفعلية',
'ساعات العمل الاضافية', 'الاستئذان', 'مهام عمل/انتداب/تدريب', 'التأخيرات', 'الخروج المبكر',
]
header_row = 5
for col, title in enumerate(headers, start=1):
sheet.write(header_row, col, title, fmt)
domain = [('date', '>=', start_date), ('date', '<=', end_date)]
if employee_ids:
domain.append(('employee_id', 'in', list(set(employee_ids))))
elif calendar_id:
rc = self.env['resource.calendar'].browse(calendar_id)
domain.append(('employee_id', 'in', rc.employee_ids.ids))
att = self.env['hr.attendance.transaction'].search(domain)
row = header_row + 1
for emp in att.mapped('employee_id'):
lines = att.filtered(lambda l, e=emp: l.employee_id == e)
sheet.write(row, 1, emp.emp_no or '', fmt)
sheet.write(row, 2, emp.name, fmt)
iq = getattr(emp, 'iqama_number', False) or getattr(emp, 'saudi_number', '')
sheet.write(row, 3, iq.display_name, fmt)
sheet.write(row, 4, emp.department_id.name, fmt)
sheet.write(row, 5, emp.sudo().job_id.name, fmt)
sheet.write(row, 6, len({l.date for l in lines if not l.is_absent}), fmt)
sheet.write(row, 7, len(lines.filtered(lambda l: l.normal_leave)), fmt)
sheet.write(row, 8, len(lines.filtered(lambda l: l.public_holiday)), fmt)
sheet.write(row, 9, len(lines.filtered(lambda l: l.is_absent)), fmt)
sheet.write(row, 10, hhmm(sum(lines.mapped('office_hours'))), fmt)
sheet.write(row, 11, hhmm(sum(lines.mapped('additional_hours'))), fmt)
sheet.write(row, 12, hhmm(sum(lines.mapped('total_permission_hours'))), fmt)
sheet.write(row, 13, hhmm(sum(lines.mapped('total_mission_hours'))), fmt)
sheet.write(row, 14, hhmm(sum(lines.filtered(lambda l: l.approve_lateness).mapped('lateness'))), fmt)
sheet.write(row, 15, hhmm(sum(lines.filtered(lambda l: l.approve_exit_out).mapped('early_exit'))), fmt)
row += 1
sheet.write(row, 1, _('الاجمالي'), fmt)
sheet.write(row, 2, '', fmt)
sheet.write(row, 3, '', fmt)
sheet.write(row, 4, '', fmt)
sheet.write(row, 5, '', fmt)
sheet.write(row, 6, len({l.date for l in att if not l.is_absent}), fmt)
sheet.write(row, 7, len(att.filtered(lambda l: l.normal_leave)), fmt)
sheet.write(row, 8, len(att.filtered(lambda l: l.public_holiday)), fmt)
sheet.write(row, 9, len(att.filtered(lambda l: l.is_absent)), fmt)
sheet.write(row, 10, hhmm(sum(att.mapped('office_hours'))), fmt)
sheet.write(row, 11, hhmm(sum(att.mapped('additional_hours'))), fmt)
sheet.write(row, 12, hhmm(sum(att.mapped('total_permission_hours'))), fmt)
sheet.write(row, 13, hhmm(sum(att.mapped('total_mission_hours'))), fmt)
sheet.write(row, 14, hhmm(sum(att.filtered(lambda l: l.approve_lateness).mapped('lateness'))), fmt)
sheet.write(row, 15, hhmm(sum(att.filtered(lambda l: l.approve_exit_out).mapped('early_exit'))), fmt)
return
if type == 'late':
sheet.merge_range('D3:I3', _("Attendance Reports"), format2)
sheet.write('E4:E4', _("From date"), format2)
@ -241,16 +354,16 @@ class AttendancesReportXls(models.AbstractModel):
row = 8
for key in mykey:
n = 1
h_col=4
h_col = 4
size = len(final_dic[key])
tot_size = len(total[key])
sheet.write(row - 3, h_col, _('Employee Number'), format2)
sheet.write(row - 3, h_col+3, _('job '), format2)
sheet.write(row - 3, h_col + 3, _('job '), format2)
sheet.write(row - 2, h_col, _('Name'), format2)
sheet.write(row - 2, h_col+3, _('Department'), format2)
sheet.write(row - 2, h_col + 3, _('Department'), format2)
sheet.write(row, n, _('date'), format2)
sheet.write(row, n+1, _('day'), format2)
sheet.write(row, n +2 , _('Sign in'), format2)
sheet.write(row, n + 1, _('day'), format2)
sheet.write(row, n + 2, _('Sign in'), format2)
sheet.write(row, n + 3, _('Sign out'), format2)
sheet.write(row, n + 4, _('lateness'), format2)
sheet.write(row, n + 5, _('Early Exit'), format2)
@ -262,13 +375,12 @@ class AttendancesReportXls(models.AbstractModel):
total_lateness = total_early_exit = total_extra_hours = total_office_hours = 0.0
for line in final_dic[key]:
sheet.merge_range(row - 3, h_col + 1,row - 3,h_col + 2, emp_data[key][0]['emp_no'], format2)
sheet.merge_range(row - 3, h_col + 1, row - 3, h_col + 2, emp_data[key][0]['emp_no'], format2)
sheet.write(row - 3, h_col + 4, emp_data[key][0]['job'], format2)
sheet.merge_range(row - 2, h_col + 1,row - 2,h_col + 2, emp_data[key][0]['emp_namw'], format2)
sheet.merge_range(row - 2, h_col + 1, row - 2, h_col + 2, emp_data[key][0]['emp_namw'], format2)
sheet.write(row - 2, h_col + 4, emp_data[key][0]['department'], format2)
sheet.write(data_row, n, str(line['date']), format2)
sheet.write(data_row, n+1, str(line['day']), format2)
sheet.write(data_row, n + 1, str(line['day']), format2)
sheet.write(data_row, n + 2, '{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['sig_in']) * 60, 60)),
format2)
@ -283,7 +395,7 @@ class AttendancesReportXls(models.AbstractModel):
sheet.write(data_row, n + 7,
'{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['office_hours']) * 60, 60)), format2)
sheet.write(data_row, n + 8,line['note'], format2)
sheet.write(data_row, n + 8, line['note'], format2)
sheet.write(data_row, n + 9, line['calendar_id'], format2)
total_lateness += float(line['lateness'])
total_early_exit += float(line['early_exit'])
@ -301,13 +413,13 @@ class AttendancesReportXls(models.AbstractModel):
sheet.write(data_row + 1, n + 7, '{0:02.0f}:{1:02.0f}'.format(*divmod(total_office_hours * 60, 60)),
format2)
sheet.write(data_row+3, n+4, _('Total lateness'), format2)
sheet.write(data_row + 3, n + 4, _('Total lateness'), format2)
# sheet.set_column(data_row,data_row, 15)
sheet.write(data_row+3, n + 5, str(total[key]['total_late_early'].split('.')[0]), format2)
sheet.write(data_row+3, n + 6, _('Total Absent'), format2)
sheet.write(data_row+3, n + 7, str(total[key]['total_absent']), format2)
sheet.write(data_row + 3, n + 5, str(total[key]['total_late_early'].split('.')[0]), format2)
sheet.write(data_row + 3, n + 6, _('Total Absent'), format2)
sheet.write(data_row + 3, n + 7, str(total[key]['total_absent']), format2)
size -= 2
sheet.write(data_row + 4, n+4, _('Total Extra'), format2)
sheet.write(data_row + 4, n + 4, _('Total Extra'), format2)
sheet.write(data_row + 4, n + 5, str(total[key]['total_extra_hours'].split('.')[0]), format2)
sheet.write(data_row + 4, n + 6, _('Total Leave'), format2)
sheet.write(data_row + 4, n + 7, total[key]['total_leave'], format2)

BIN
odex25_hr/to_attendance_system/.DS_Store vendored Normal file

Binary file not shown.