diff --git a/addons/hr_contract/models/hr_contract.py b/addons/hr_contract/models/hr_contract.py index 03d629ef99c..22b07189de3 100644 --- a/addons/hr_contract/models/hr_contract.py +++ b/addons/hr_contract/models/hr_contract.py @@ -33,6 +33,7 @@ class Contract(models.Model): default=lambda self: self.env.company.resource_calendar_id.id, copy=False, index=True, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") wage = fields.Monetary('Wage', required=True, tracking=True, help="Employee's monthly gross wage.") + contract_wage = fields.Monetary('Contract Wage', compute='_compute_contract_wage') notes = fields.Html('Notes') state = fields.Selection([ ('draft', 'New'), @@ -193,6 +194,11 @@ class Contract(models.Model): for contract in self: contract.employee_id.sudo().write({'contract_id': contract.id}) + @api.depends('wage') + def _compute_contract_wage(self): + for contract in self: + contract.contract_wage = contract._get_contract_wage() + def _get_contract_wage(self): self.ensure_one() return self[self._get_contract_wage_field()] diff --git a/addons/hr_contract/report/hr_contract_history.py b/addons/hr_contract/report/hr_contract_history.py index 0e8cb44ed39..52ec7ee7b83 100644 --- a/addons/hr_contract/report/hr_contract_history.py +++ b/addons/hr_contract/report/hr_contract_history.py @@ -9,6 +9,7 @@ class ContractHistory(models.Model): _name = 'hr.contract.history' _description = 'Contract history' _auto = False + _order = 'is_under_contract' # Even though it would have been obvious to use the reference contract's id as the id of the # hr.contract.history model, it turned out it was a bad idea as this id could change (for instance if a @@ -22,6 +23,7 @@ class ContractHistory(models.Model): date_start = fields.Date('Start Date', readonly=True) date_end = fields.Date('End Date', readonly=True) employee_id = fields.Many2one('hr.employee', string='Employee', readonly=True) + active_employee = fields.Boolean('Active Employee', readonly=True) is_under_contract = fields.Boolean('Is Currently Under Contract', readonly=True) department_id = fields.Many2one('hr.department', string='Department', readonly=True) structure_type_id = fields.Many2one('hr.payroll.structure.type', string='Salary Structure Type', readonly=True) @@ -33,35 +35,42 @@ class ContractHistory(models.Model): ('close', 'Expired'), ('cancel', 'Cancelled') ], string='Status', readonly=True) - resource_calendar_id = fields.Many2one('resource.calendar', readonly=True) - wage = fields.Monetary('Wage', help="Employee's monthly gross wage.", readonly=True) + resource_calendar_id = fields.Many2one('resource.calendar', string="Working Schedule", readonly=True) + wage = fields.Monetary('Wage', help="Employee's monthly gross wage.", readonly=True, group_operator="avg") company_id = fields.Many2one('res.company', string='Company', readonly=True) company_country_id = fields.Many2one('res.country', string="Company country", related='company_id.country_id', readonly=True) country_code = fields.Char(related='company_country_id.code', readonly=True) currency_id = fields.Many2one(string='Currency', related='company_id.currency_id', readonly=True) contract_type_id = fields.Many2one('hr.contract.type', 'Contract Type', readonly=True) contract_ids = fields.One2many('hr.contract', string='Contracts', compute='_compute_contract_ids', readonly=True) + contract_count = fields.Integer(compute='_compute_contract_count', string="# Contracts") under_contract_state = fields.Selection([ ('done', 'Under Contract'), ('blocked', 'Not Under Contract') ], string='Contractual Status', compute='_compute_under_contract_state') + activity_state = fields.Selection(related='contract_id.activity_state') + + @api.depends('contract_ids') + def _compute_contract_count(self): + for history in self: + history.contract_count = len(history.contract_ids) @api.depends('is_under_contract') def _compute_under_contract_state(self): - for contract in self: - contract.under_contract_state = 'done' if contract.is_under_contract else 'blocked' + for history in self: + history.under_contract_state = 'done' if history.is_under_contract else 'blocked' @api.depends('employee_id.name') def _compute_display_name(self): - for contract in self: - contract.display_name = _("%s's Contracts History", contract.employee_id.name) + for history in self: + history.display_name = _("%s's Contracts History", history.employee_id.name) @api.model def _get_fields(self): return ','.join('contract.%s' % name for name, field in self._fields.items() if field.store and field.type not in ['many2many', 'one2many', 'related'] - and field.name not in ['id', 'contract_id', 'employee_id', 'date_hired', 'is_under_contract']) + and field.name not in ['id', 'contract_id', 'employee_id', 'date_hired', 'is_under_contract', 'active_employee']) def init(self): tools.drop_view_if_exists(self.env.cr, self._table) @@ -92,6 +101,7 @@ class ContractHistory(models.Model): ) SELECT employee.id AS id, employee.id AS employee_id, + employee.active AS active_employee, contract.id AS contract_id, contract_information.is_under_contract::bool AS is_under_contract, employee.first_contract_date AS date_hired, @@ -102,7 +112,6 @@ class ContractHistory(models.Model): ON contract_information.employee_id = employee.id AND contract.company_id = employee.company_id WHERE employee.employee_type IN ('employee', 'student') - AND (employee.active = true OR contract.state='draft') )""" % (self._table, self._get_fields())) @api.depends('employee_id.contract_ids') diff --git a/addons/hr_contract/report/hr_contract_history_report_views.xml b/addons/hr_contract/report/hr_contract_history_report_views.xml index 75d8aed98d7..cfd33d46f7d 100644 --- a/addons/hr_contract/report/hr_contract_history_report_views.xml +++ b/addons/hr_contract/report/hr_contract_history_report_views.xml @@ -12,11 +12,16 @@ + + + - + + + @@ -25,6 +30,7 @@ Contracts hr.contract.history form + {'search_default_active_employees': 1} hr.contract.history.form @@ -37,7 +43,7 @@ duplicate="false" import="false">
-
@@ -59,11 +65,10 @@ - - + - + @@ -87,13 +92,14 @@ - + - + + @@ -104,10 +110,11 @@ - Contracts + Employees hr.contract.history - tree,form + tree,kanban,form + {'search_default_active_employees': 1} Contracts to Review @@ -117,6 +124,7 @@ { 'search_default_to_review': 1, + 'search_default_active_employees': 1 } @@ -125,28 +133,65 @@ hr.contract.history - + - + + + - + + + + hr.contract.history.view.kanban + hr.contract.history + + + + + + + + +
+
+
+ + + +
+
+ +
+
+ + + +
+
+
+
+
+
+
+
+
- + @@ -117,9 +117,12 @@ - - - + + + + + + @@ -149,8 +152,8 @@ - - + + @@ -169,11 +172,12 @@ - + + @@ -205,18 +209,18 @@ hr.contract.tree hr.contract - + - + + - - + @@ -248,7 +252,7 @@
-
+
diff --git a/addons/hr_work_entry/models/hr_work_entry.py b/addons/hr_work_entry/models/hr_work_entry.py index cf229a51680..403b2db4da5 100644 --- a/addons/hr_work_entry/models/hr_work_entry.py +++ b/addons/hr_work_entry/models/hr_work_entry.py @@ -5,7 +5,7 @@ from contextlib import contextmanager from dateutil.relativedelta import relativedelta from psycopg2 import OperationalError -from odoo import api, fields, models +from odoo import api, fields, models, _ class HrWorkEntry(models.Model): @@ -61,7 +61,10 @@ class HrWorkEntry(models.Model): @api.depends('work_entry_type_id', 'employee_id') def _compute_name(self): for work_entry in self: - work_entry.name = "%s: %s" % (work_entry.work_entry_type_id.name, work_entry.employee_id.name) + if not work_entry.employee_id: + work_entry.name = _('Undefined') + else: + work_entry.name = "%s: %s" % (work_entry.work_entry_type_id.name or _('Undefined Type'), work_entry.employee_id.name) @api.depends('state') def _compute_conflict(self): @@ -213,7 +216,7 @@ class HrWorkEntryType(models.Model): _description = 'HR Work Entry Type' name = fields.Char(required=True, translate=True) - code = fields.Char(required=True) + code = fields.Char(required=True, help="Carefull, the Code is used in many references, changing it could lead to unwanted changes.") color = fields.Integer(default=0) sequence = fields.Integer(default=25) active = fields.Boolean( diff --git a/addons/hr_work_entry/views/hr_work_entry_views.xml b/addons/hr_work_entry/views/hr_work_entry_views.xml index 2374815915c..ed5d14ad1a4 100644 --- a/addons/hr_work_entry/views/hr_work_entry_views.xml +++ b/addons/hr_work_entry/views/hr_work_entry_views.xml @@ -81,6 +81,7 @@ + @@ -137,7 +138,6 @@ hr.work.entry.type - @@ -161,10 +161,13 @@ - + + + + diff --git a/addons/hr_work_entry_contract/models/hr_work_entry.py b/addons/hr_work_entry_contract/models/hr_work_entry.py index 1e6c70b50ba..ac5a63cde6c 100644 --- a/addons/hr_work_entry_contract/models/hr_work_entry.py +++ b/addons/hr_work_entry_contract/models/hr_work_entry.py @@ -152,4 +152,5 @@ class HrWorkEntryType(models.Model): _inherit = 'hr.work.entry.type' _description = 'HR Work Entry Type' - is_leave = fields.Boolean(default=False, string="Time Off") + is_leave = fields.Boolean( + default=False, string="Time Off", help="Allow the work entry type to be linked with time off types.") diff --git a/addons/hr_work_entry_contract/views/hr_work_entry_views.xml b/addons/hr_work_entry_contract/views/hr_work_entry_views.xml index 1972add686e..84c29f8f188 100644 --- a/addons/hr_work_entry_contract/views/hr_work_entry_views.xml +++ b/addons/hr_work_entry_contract/views/hr_work_entry_views.xml @@ -31,11 +31,9 @@ hr.work.entry.type - - - - - + + + diff --git a/addons/hr_work_entry_holidays/models/hr_work_entry.py b/addons/hr_work_entry_holidays/models/hr_work_entry.py index 87add98f8ae..032ca1a187f 100644 --- a/addons/hr_work_entry_holidays/models/hr_work_entry.py +++ b/addons/hr_work_entry_holidays/models/hr_work_entry.py @@ -89,4 +89,6 @@ class HrWorkEntryType(models.Model): _inherit = 'hr.work.entry.type' _description = 'HR Work Entry Type' - leave_type_ids = fields.One2many('hr.leave.type', 'work_entry_type_id', string='Time Off Type') + leave_type_ids = fields.One2many( + 'hr.leave.type', 'work_entry_type_id', string='Time Off Type', + help="Every new time off type in this list will be reported as select work entry in payslip.")