1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/hr_attendance_gantt/models/hr_attendance.py
2024-12-10 09:04:09 +07:00

85 lines
4.0 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, fields, api
from odoo.addons.resource.models.utils import string_to_datetime
from odoo.osv import expression
from odoo.tools import float_is_zero
from dateutil.relativedelta import relativedelta
class HrAttendance(models.Model):
_inherit = "hr.attendance"
color = fields.Integer("Color", compute='_compute_color')
overtime_progress = fields.Float(compute="_compute_overtime_progress")
def _compute_overtime_progress(self):
for attendance in self:
if not float_is_zero(attendance.worked_hours, precision_digits=2):
attendance.overtime_progress = 100 - ((attendance.overtime_hours / attendance.worked_hours) * 100)
else:
attendance.overtime_progress = 100
@api.model
def gantt_progress_bar(self, fields, res_ids, date_start_str, date_stop_str):
if not self.user_has_groups("base.group_user"):
return {field: {} for field in fields}
start_utc, stop_utc = string_to_datetime(date_start_str), string_to_datetime(date_stop_str)
progress_bars = {field: self._gantt_progress_bar(field, res_ids[field], start_utc, stop_utc) for field in fields}
return progress_bars
def _gantt_progress_bar(self, field, res_ids, start, stop):
if field == 'employee_id':
return self._gantt_progress_bar_employee_ids(res_ids, start, stop)
raise NotImplementedError
def _gantt_progress_bar_employee_ids(self, res_ids, start, stop):
"""
Resulting display is worked hours / expected worked hours
"""
values = {}
worked_hours_group = self._read_group([('employee_id', 'in', res_ids),
('check_in', '>=', start),
('check_out', '<=', stop)],
groupby=['employee_id'],
aggregates=['worked_hours:sum'])
employee_data = {emp.id: worked_hours for emp, worked_hours in worked_hours_group}
employees = self.env['hr.employee'].browse(res_ids)
for employee in employees:
# Retrieve expected attendance for that employee
values[employee.id] = {
'value': employee_data.get(employee.id, 0),
'max_value': self.env['resource.calendar']._get_attendance_intervals_days_data(employee._get_expected_attendances(start, stop))['hours'],
}
return values
@api.model
def get_gantt_data(self, domain, groupby, read_specification, limit=None, offset=0):
"""
We override get_gantt_data to allow the display of open-ended records,
We also want to add in the gantt rows, the active emloyees that have a check in in the previous 7 days
"""
user_domain = self.env.context.get('user_domain')
start_date = self.env.context.get('gantt_start_date')
open_ended_gantt_data = super().get_gantt_data(domain, groupby, read_specification, limit=limit, offset=offset)
if start_date and groupby and groupby[0] == 'employee_id':
active_employees_domain = expression.AND([
user_domain,
[
'&',
('check_out', '<', start_date),
('check_in', '>', fields.Datetime.from_string(start_date) - relativedelta(days=7)),
('employee_id', 'not in', [group['employee_id'][0] for group in open_ended_gantt_data['groups']])
]])
previously_active_employees = super().get_gantt_data(active_employees_domain, groupby, read_specification, limit=None, offset=0)
for group in previously_active_employees['groups']:
del group['__record_ids'] # Records are not needed here
open_ended_gantt_data['groups'].append(group)
open_ended_gantt_data['length'] += 1
return open_ended_gantt_data