new report for employee attendance
This commit is contained in:
parent
44f17a8f52
commit
0b0de1f3d9
File diff suppressed because it is too large
Load Diff
|
|
@ -323,6 +323,67 @@
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</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">
|
<template id="general_attendances_report_temp">
|
||||||
<t t-call="web.html_container">
|
<t t-call="web.html_container">
|
||||||
<t t-call="web.external_layout">
|
<t t-call="web.external_layout">
|
||||||
|
|
@ -336,14 +397,19 @@
|
||||||
font-family: ae_AlMohanad;
|
font-family: ae_AlMohanad;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<t t-if="type == 'late'">
|
<t t-if="totals_only">
|
||||||
<t t-call="attendances.late_attendance_report_template"/>
|
<t t-call="attendances.totals_only_attendance_report_template"/>
|
||||||
</t>
|
</t>
|
||||||
<t t-if="type == 'absent'">
|
<t t-else="">
|
||||||
<t t-call="attendances.absent_attendance_report_template"/>
|
<t t-if="type == 'late'">
|
||||||
</t>
|
<t t-call="attendances.late_attendance_report_template"/>
|
||||||
<t t-if="type == 'employee'">
|
</t>
|
||||||
<t t-call="attendances.employee_attendance_report_template"/>
|
<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>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,11 @@
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="to_date"/>
|
<field name="to_date"/>
|
||||||
<!-- <field name="employee_ids" widget="many2many_tags"/>-->
|
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="print_totals_only"/>
|
||||||
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="Employees" >
|
<page string="Employees" >
|
||||||
<field name="employee_ids" nolabel="1" required="1">
|
<field name="employee_ids" nolabel="1" required="1">
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,71 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import collections
|
|
||||||
import datetime
|
|
||||||
from odoo import api, fields, models, _
|
|
||||||
from odoo.exceptions import ValidationError
|
|
||||||
import pytz
|
import pytz
|
||||||
from pytz import timezone
|
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):
|
class AttendancesReport(models.TransientModel):
|
||||||
_name = "employee.attendance.report"
|
_name = "employee.attendance.report"
|
||||||
_description = "Employee Attendance Report"
|
_description = "Employee Attendance Report"
|
||||||
|
|
||||||
from_date = fields.Date(string='From Date', required=True)
|
from_date = fields.Date(required=True)
|
||||||
to_date = fields.Date(string='To Date', required=True)
|
to_date = fields.Date(required=True)
|
||||||
employee_ids = fields.Many2many(comodel_name='hr.employee', string='Employees' ,required=True)
|
employee_ids = fields.Many2many("hr.employee", string="Employees", required=True)
|
||||||
resource_calender_id = fields.Many2one(comodel_name='resource.calendar', string='Employee work record')
|
resource_calender_id = fields.Many2one("resource.calendar", string="Employee work record")
|
||||||
type = fields.Selection(selection=[('late', 'Late and Early exit'), ('absent', 'Absent'), ('employee', 'Employee')],
|
type = fields.Selection([
|
||||||
required=True,
|
("late", "Late and Early exit"),
|
||||||
default='late', string='Type')
|
("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):
|
def print_report(self):
|
||||||
if not self.employee_ids:
|
if not self.employee_ids:
|
||||||
raise ValidationError(_("Please select Employees Name"))
|
raise ValidationError(_("Please select Employees Name"))
|
||||||
data = {
|
return self.env.ref("attendances.general_attendance_action_report").report_action(self, data=self._payload())
|
||||||
'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)
|
|
||||||
|
|
||||||
def print_excel_report(self):
|
def print_excel_report(self):
|
||||||
data = {
|
return self.env.ref("attendances.general_attendance_action_xls").report_action(self, data=self._payload(), config=False)
|
||||||
'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)
|
|
||||||
|
|
||||||
|
|
||||||
class ReportAttendancePublic(models.AbstractModel):
|
class ReportAttendancePublic(models.AbstractModel):
|
||||||
_name = 'report.attendances.general_attendances_report_temp'
|
_name = "report.attendances.general_attendances_report_temp"
|
||||||
_description = "General Attendances Report"
|
_description = "General Attendances Report"
|
||||||
|
|
||||||
def get_value(self, data):
|
def get_value(self, data):
|
||||||
type = data['form']['type']
|
type = data['form']['type']
|
||||||
|
totals_only = data["form"].get("print_totals_only", False)
|
||||||
employee_ids = data['form']['employee_ids']
|
employee_ids = data['form']['employee_ids']
|
||||||
resource_calender_id = data['form']['resource_calender_id']
|
resource_calender_id = data['form']['resource_calender_id']
|
||||||
from_date = data['form']['from_date']
|
from_date = data['form']['from_date']
|
||||||
|
|
@ -68,7 +77,7 @@ class ReportAttendancePublic(models.AbstractModel):
|
||||||
total_dic = {}
|
total_dic = {}
|
||||||
mykey = []
|
mykey = []
|
||||||
resource = self.env['resource.calendar'].browse(resource_calender_id)
|
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:
|
if resource.employee_ids:
|
||||||
for emp in resource.employee_ids:
|
for emp in resource.employee_ids:
|
||||||
employee_ids.append(emp.id)
|
employee_ids.append(emp.id)
|
||||||
|
|
@ -83,23 +92,23 @@ class ReportAttendancePublic(models.AbstractModel):
|
||||||
attendance_transaction_ids = self.env['hr.attendance.transaction'].search(domain)
|
attendance_transaction_ids = self.env['hr.attendance.transaction'].search(domain)
|
||||||
employees = attendance_transaction_ids.mapped('employee_id.name')
|
employees = attendance_transaction_ids.mapped('employee_id.name')
|
||||||
employee_ids = attendance_transaction_ids.mapped('employee_id')
|
employee_ids = attendance_transaction_ids.mapped('employee_id')
|
||||||
emp_data=[]
|
emp_data = []
|
||||||
for emp in employee_ids:
|
for emp in employee_ids:
|
||||||
emp_data.append({'job': emp.sudo().job_id.name, 'department': emp.department_id.name,
|
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)
|
grouped_data = collections.defaultdict(list)
|
||||||
emp_data_dict={}
|
emp_data_dict = {}
|
||||||
for item in emp_data:
|
for item in emp_data:
|
||||||
grouped_data[item['emp_namw']].append(item)
|
grouped_data[item['emp_namw']].append(item)
|
||||||
for key,value in grouped_data.items():
|
for key, value in grouped_data.items():
|
||||||
emp_data_dict[key]=list(value)
|
emp_data_dict[key] = list(value)
|
||||||
if type == 'late':
|
if type == 'late':
|
||||||
for resource in attendance_transaction_ids:
|
for resource in attendance_transaction_ids:
|
||||||
note=''
|
note = ''
|
||||||
if resource.is_absent:
|
if resource.is_absent:
|
||||||
note='غياب'
|
note = 'غياب'
|
||||||
elif resource.public_holiday:
|
elif resource.public_holiday:
|
||||||
note="عطلة رسمية"
|
note = "عطلة رسمية"
|
||||||
elif resource.official_id:
|
elif resource.official_id:
|
||||||
note = resource.official_id.mission_type.name
|
note = resource.official_id.mission_type.name
|
||||||
elif resource.normal_leave:
|
elif resource.normal_leave:
|
||||||
|
|
@ -109,27 +118,27 @@ class ReportAttendancePublic(models.AbstractModel):
|
||||||
|
|
||||||
data.append({
|
data.append({
|
||||||
'date': resource.date,
|
'date': resource.date,
|
||||||
'day': week_dayS_arabic[resource.date.weekday()],
|
'day': WEEK_DAYS_AR[resource.date.weekday()],
|
||||||
'sig_in': resource.sign_in,
|
'sig_in': resource.sign_in,
|
||||||
'sig_out': resource.sign_out,
|
'sig_out': resource.sign_out,
|
||||||
'lateness': resource.lateness,
|
'lateness': resource.lateness,
|
||||||
'early_exit': resource.early_exit,
|
'early_exit': resource.early_exit,
|
||||||
'extra_hours': resource.additional_hours,
|
'extra_hours': resource.additional_hours,
|
||||||
'office_hours':resource.office_hours,
|
'office_hours': resource.office_hours,
|
||||||
'note':note,
|
'note': note,
|
||||||
'department':resource.employee_id.department_id.name,
|
'department': resource.employee_id.department_id.name,
|
||||||
'employee_number':resource.employee_number,
|
'employee_number': resource.employee_number,
|
||||||
'calendar_id':resource.calendar_id.name,
|
'calendar_id': resource.calendar_id.name,
|
||||||
'employee_id': resource.employee_id,
|
'employee_id': resource.employee_id,
|
||||||
'employee_name': resource.employee_id.name,
|
'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:
|
for emp in employees:
|
||||||
list_cat = attendance_transaction_ids.filtered(lambda r: r.employee_id.name == emp)
|
list_cat = attendance_transaction_ids.filtered(lambda r: r.employee_id.name == emp)
|
||||||
total_lateness = sum(list_cat.mapped('lateness'))
|
total_lateness = sum(list_cat.mapped('lateness'))
|
||||||
total_early_exit = sum(list_cat.mapped('early_exit'))
|
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 = sum(list_cat.mapped('additional_hours'))
|
||||||
total_extra_hours = str(datetime.timedelta(minutes=total_extra_hours))
|
total_extra_hours = str(datetime.timedelta(minutes=total_extra_hours))
|
||||||
list_absent = attendance_transaction_ids.filtered(
|
list_absent = attendance_transaction_ids.filtered(
|
||||||
|
|
@ -141,11 +150,13 @@ class ReportAttendancePublic(models.AbstractModel):
|
||||||
list_not_log_out = attendance_transaction_ids.filtered(
|
list_not_log_out = attendance_transaction_ids.filtered(
|
||||||
lambda r: r.employee_id.name == emp and r.sign_out == 0.0)
|
lambda r: r.employee_id.name == emp and r.sign_out == 0.0)
|
||||||
list_leave = attendance_transaction_ids.filtered(
|
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_not_sig_out = len(list_not_log_out)
|
||||||
total_leave = len(list_leave)
|
total_leave = len(list_leave)
|
||||||
total_dic[emp] = {'total_lateness': total_lateness, 'total_early_exit': total_early_exit,
|
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}
|
'total_not_sig_out': total_not_sig_out}
|
||||||
grouped = collections.defaultdict(list)
|
grouped = collections.defaultdict(list)
|
||||||
for item in data:
|
for item in data:
|
||||||
|
|
@ -154,7 +165,7 @@ class ReportAttendancePublic(models.AbstractModel):
|
||||||
final_dic[key] = list(value)
|
final_dic[key] = list(value)
|
||||||
key_list.append(key)
|
key_list.append(key)
|
||||||
mykey = list(dict.fromkeys(key_list))
|
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':
|
elif type == 'absent':
|
||||||
for resource in attendance_transaction_ids.filtered(lambda r: r.is_absent == True):
|
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)
|
final_dic[key] = list(value)
|
||||||
key_list.append(key)
|
key_list.append(key)
|
||||||
mykey = list(dict.fromkeys(key_list))
|
mykey = list(dict.fromkeys(key_list))
|
||||||
return final_dic, mykey, '',emp_data_dict
|
return final_dic, mykey, '', emp_data_dict
|
||||||
elif type == 'employee':
|
elif type == 'employee':
|
||||||
for emp in employees:
|
for emp in employees:
|
||||||
list_cat = attendance_transaction_ids.filtered(lambda r: r.employee_id.name == emp)
|
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}
|
total_dic[emp] = {'total_lateness': total_lateness, 'total_early_exit': total_early_exit}
|
||||||
key_list.append(emp)
|
key_list.append(emp)
|
||||||
mykey = list(dict.fromkeys(key_list))
|
mykey = list(dict.fromkeys(key_list))
|
||||||
print("mk",mykey,total_dic)
|
print("mk", mykey, total_dic)
|
||||||
return '', mykey, total_dic,emp_data_dict
|
return '', mykey, total_dic, emp_data_dict
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _get_report_values(self, docids, data=None):
|
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']
|
start_date = data['form']['from_date']
|
||||||
end_date = data['form']['to_date']
|
end_date = data['form']['to_date']
|
||||||
type = data['form']['type']
|
type = data['form']['type']
|
||||||
print("dataa",mykey,final_dic)
|
print("dataa", mykey, final_dic)
|
||||||
local_tz = pytz.timezone(
|
local_tz = pytz.timezone(
|
||||||
self.env.user.tz or 'GMT')
|
self.env.user.tz or 'GMT')
|
||||||
print_date=datetime.datetime.now(timezone('UTC'))
|
print_date = datetime.datetime.now(timezone('UTC'))
|
||||||
print_date=print_date.astimezone(local_tz)
|
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 {
|
return {
|
||||||
'doc_ids': data['ids'],
|
'doc_ids': data['ids'],
|
||||||
'doc_model': data['model'],
|
'doc_model': data['model'],
|
||||||
|
|
@ -204,14 +250,15 @@ class ReportAttendancePublic(models.AbstractModel):
|
||||||
'type': type,
|
'type': type,
|
||||||
'data': final_dic,
|
'data': final_dic,
|
||||||
'mykey': mykey,
|
'mykey': mykey,
|
||||||
'emp_data':emp_data,
|
'emp_data': emp_data,
|
||||||
'total': total,
|
'total': total,
|
||||||
'print_date':print_date.strftime("%H:%m %m/%d/%Y" ),
|
'summary': summary_rows,
|
||||||
'print_user':self.env.user.name
|
'totals_only': totals_only,
|
||||||
|
'print_date': print_date.strftime("%H:%m %m/%d/%Y"),
|
||||||
|
'print_user': self.env.user.name
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AttendancesReportXls(models.AbstractModel):
|
class AttendancesReportXls(models.AbstractModel):
|
||||||
_name = 'report.attendances.general_attendance_xls'
|
_name = 'report.attendances.general_attendance_xls'
|
||||||
_inherit = 'report.report_xlsx.abstract'
|
_inherit = 'report.report_xlsx.abstract'
|
||||||
|
|
@ -219,19 +266,85 @@ class AttendancesReportXls(models.AbstractModel):
|
||||||
def generate_xlsx_report(self, workbook, data, datas):
|
def generate_xlsx_report(self, workbook, data, datas):
|
||||||
self = self.with_context(lang=self.env.user.lang)
|
self = self.with_context(lang=self.env.user.lang)
|
||||||
x = self.env['report.attendances.general_attendances_report_temp']
|
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']
|
start_date = data['form']['from_date']
|
||||||
end_date = data['form']['to_date']
|
end_date = data['form']['to_date']
|
||||||
type = data['form']['type']
|
type = data['form']['type']
|
||||||
|
totals_only = data['form'].get('print_totals_only', False)
|
||||||
sheet = workbook.add_worksheet(U'Holiday Report')
|
sheet = workbook.add_worksheet(U'Holiday Report')
|
||||||
|
calendar_id = data['form']['resource_calender_id']
|
||||||
sheet.right_to_left()
|
sheet.right_to_left()
|
||||||
sheet.set_column(1, 10, 15)
|
sheet.set_column(1, 10, 15)
|
||||||
# sheet.set_column(6, 100, 25)
|
employee_ids = data['form']['employee_ids']
|
||||||
format2 = workbook.add_format(
|
format2 = workbook.add_format(
|
||||||
{'font_size': 10, 'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center',
|
{'font_size': 10, 'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center',
|
||||||
'bold': True})
|
'bold': True})
|
||||||
format2.set_align('center')
|
format2.set_align('center')
|
||||||
format2.set_align('vcenter')
|
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':
|
if type == 'late':
|
||||||
sheet.merge_range('D3:I3', _("Attendance Reports"), format2)
|
sheet.merge_range('D3:I3', _("Attendance Reports"), format2)
|
||||||
sheet.write('E4:E4', _("From date"), format2)
|
sheet.write('E4:E4', _("From date"), format2)
|
||||||
|
|
@ -241,16 +354,16 @@ class AttendancesReportXls(models.AbstractModel):
|
||||||
row = 8
|
row = 8
|
||||||
for key in mykey:
|
for key in mykey:
|
||||||
n = 1
|
n = 1
|
||||||
h_col=4
|
h_col = 4
|
||||||
size = len(final_dic[key])
|
size = len(final_dic[key])
|
||||||
tot_size = len(total[key])
|
tot_size = len(total[key])
|
||||||
sheet.write(row - 3, h_col, _('Employee Number'), format2)
|
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, _('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, _('date'), format2)
|
||||||
sheet.write(row, n+1, _('day'), format2)
|
sheet.write(row, n + 1, _('day'), format2)
|
||||||
sheet.write(row, n +2 , _('Sign in'), format2)
|
sheet.write(row, n + 2, _('Sign in'), format2)
|
||||||
sheet.write(row, n + 3, _('Sign out'), format2)
|
sheet.write(row, n + 3, _('Sign out'), format2)
|
||||||
sheet.write(row, n + 4, _('lateness'), format2)
|
sheet.write(row, n + 4, _('lateness'), format2)
|
||||||
sheet.write(row, n + 5, _('Early Exit'), 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
|
total_lateness = total_early_exit = total_extra_hours = total_office_hours = 0.0
|
||||||
|
|
||||||
for line in final_dic[key]:
|
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.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(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, 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)),
|
sheet.write(data_row, n + 2, '{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['sig_in']) * 60, 60)),
|
||||||
format2)
|
format2)
|
||||||
|
|
@ -283,7 +395,7 @@ class AttendancesReportXls(models.AbstractModel):
|
||||||
sheet.write(data_row, n + 7,
|
sheet.write(data_row, n + 7,
|
||||||
'{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['office_hours']) * 60, 60)), format2)
|
'{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)
|
sheet.write(data_row, n + 9, line['calendar_id'], format2)
|
||||||
total_lateness += float(line['lateness'])
|
total_lateness += float(line['lateness'])
|
||||||
total_early_exit += float(line['early_exit'])
|
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)),
|
sheet.write(data_row + 1, n + 7, '{0:02.0f}:{1:02.0f}'.format(*divmod(total_office_hours * 60, 60)),
|
||||||
format2)
|
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.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 + 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 + 6, _('Total Absent'), format2)
|
||||||
sheet.write(data_row+3, n + 7, str(total[key]['total_absent']), format2)
|
sheet.write(data_row + 3, n + 7, str(total[key]['total_absent']), format2)
|
||||||
size -= 2
|
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 + 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 + 6, _('Total Leave'), format2)
|
||||||
sheet.write(data_row + 4, n + 7, total[key]['total_leave'], format2)
|
sheet.write(data_row + 4, n + 7, total[key]['total_leave'], format2)
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue