forked from Mapan/odoo17e
85 lines
4.0 KiB
Python
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
|