[FIX] hr_work_entry: Closed contract

When a contract is closed, set the date of the day.
In the contract cron, ensure that all closed contracts have
an end date if it is followed by a new contract.
Add multi-edit on work_entry list

closes odoo/odoo#44118

Taskid: 2180263
X-original-commit: 0b5d8ce756eac904a040ca700f44ea860daefcb4
Related: odoo/enterprise#7991
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
jbm-odoo
2020-01-28 14:16:21 +00:00
committed by Yannick Tivisse
parent 9d98c43581
commit 41a465bc86
3 changed files with 42 additions and 15 deletions
+25 -2
View File
@@ -19,9 +19,9 @@ class Contract(models.Model):
employee_id = fields.Many2one('hr.employee', string='Employee', tracking=True, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]")
department_id = fields.Many2one('hr.department', domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", string="Department")
job_id = fields.Many2one('hr.job', domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", string='Job Position')
date_start = fields.Date('Start Date', required=True, default=fields.Date.today,
date_start = fields.Date('Start Date', required=True, default=fields.Date.today, tracking=True,
help="Start date of the contract.")
date_end = fields.Date('End Date',
date_end = fields.Date('End Date', tracking=True,
help="End date of the contract (if it's a fixed-term contract).")
trial_date_end = fields.Date('End of Trial Period',
help="End date of the trial period (if there is one).")
@@ -133,6 +133,26 @@ class Contract(models.Model):
self.search([('state', '=', 'draft'), ('kanban_state', '=', 'done'), ('date_start', '<=', fields.Date.to_string(date.today())),]).write({
'state': 'open'
})
contract_ids = self.search([('date_end', '=', False), ('state', '=', 'close'), ('employee_id', '!=', False)])
# Ensure all closed contract followed by a new contract have a end date.
# If closed contract has no closed date, the work entries will be generated for an unlimited period.
for contract in contract_ids:
next_contract = self.search([
('employee_id', '=', contract.employee_id.id),
('state', 'not in', ['cancel', 'new']),
('date_start', '>', contract.date_start)
], order="date_start asc", limit=1)
if next_contract:
contract.date_end = next_contract.date_start - relativedelta(days=1)
continue
next_contract = self.search([
('employee_id', '=', contract.employee_id.id),
('date_start', '>', contract.date_start)
], order="date_start asc", limit=1)
if next_contract:
contract.date_end = next_contract.date_start - relativedelta(days=1)
return True
def _assign_open_contract(self):
@@ -143,6 +163,9 @@ class Contract(models.Model):
res = super(Contract, self).write(vals)
if vals.get('state') == 'open':
self._assign_open_contract()
if vals.get('state') == 'close':
for contract in self.filtered(lambda c: not c.date_end):
contract.date_end = max(date.today(), contract.date_start)
calendar = vals.get('resource_calendar_id')
if calendar:
@@ -40,7 +40,7 @@
<field name="arch" type="xml">
<form string="Work Entry" >
<header>
<field name="state" widget="statusbar" options="{'clickable': '1'}"/>
<field name="state" widget="statusbar" options="{'clickable': '1'}" statusbar_visible="draft,validated,conflict"/>
</header>
<sheet>
<div class="oe_title">
@@ -73,8 +73,8 @@
<field name="model">hr.work.entry</field>
<field name="arch" type="xml">
<tree multi_edit="1">
<field name="name" readonly="1"/>
<field name="work_entry_type_id" attrs="{'readonly': [('state', '=', 'validated')]}" options="{'no_create': True, 'no_open': True}"/>
<field name="name"/>
<field name="work_entry_type_id" options="{'no_create': True, 'no_open': True}"/>
<field name="duration" readonly="1"/>
<field name="state"/>
<field name="date_start" string="Beginning" readonly="1"/>
@@ -93,9 +93,13 @@
<filter name="work_entries_error" string="Conflicting" domain="[('state', '=', 'conflict')]"/>
<separator/>
<filter name="date_filter" string="Date" date="date_start"/>
<filter name="current_month" string="Current Month" domain="[
('date_stop', '&gt;=', (context_today()).strftime('%Y-%m-01')),
('date_start', '&lt;', (context_today() + relativedelta(months=1)).strftime('%Y-%m-01'))]"/>
<separator/>
<filter name="group_employee" string="Employee" context="{'group_by': 'employee_id'}"/>
<filter name="group_work_entry_type" string="Type" context="{'group_by': 'work_entry_type_id'}"/>
<filter name="group_start_date" string="Start Date" context="{'group_by': 'date_start'}"/>
<separator/>
<filter name="archived" string="Archived" domain="[('active', '=', False)]"/>
</search>
+10 -10
View File
@@ -316,9 +316,9 @@ class ResourceCalendar(models.Model):
# --------------------------------------------------
# Computation API
# --------------------------------------------------
def _attendance_intervals(self, start_dt, end_dt, resource=None, domain=None):
def _attendance_intervals(self, start_dt, end_dt, resource=None, domain=None, tz=None):
""" Return the attendance intervals in the given datetime range.
The returned intervals are expressed in the resource's timezone.
The returned intervals are expressed in specified tz or in the resource's timezone.
"""
assert start_dt.tzinfo and end_dt.tzinfo
combine = datetime.combine
@@ -331,8 +331,8 @@ class ResourceCalendar(models.Model):
('display_type', '=', False),
]])
# express all dates and times in the resource's timezone
tz = timezone((resource or self).tz)
# express all dates and times in specified tz or in the resource's timezone
tz = tz if tz else timezone((resource or self).tz)
start_dt = start_dt.astimezone(tz)
end_dt = end_dt.astimezone(tz)
@@ -366,9 +366,9 @@ class ResourceCalendar(models.Model):
return Intervals(result)
def _leave_intervals(self, start_dt, end_dt, resource=None, domain=None):
def _leave_intervals(self, start_dt, end_dt, resource=None, domain=None, tz=None):
""" Return the leave intervals in the given datetime range.
The returned intervals are expressed in the calendar's timezone.
The returned intervals are expressed in specified tz or in the calendar's timezone.
"""
assert start_dt.tzinfo and end_dt.tzinfo
self.ensure_one()
@@ -385,7 +385,7 @@ class ResourceCalendar(models.Model):
]
# retrieve leave intervals in (start_dt, end_dt)
tz = timezone((resource or self).tz)
tz = tz if tz else timezone((resource or self).tz)
start_dt = start_dt.astimezone(tz)
end_dt = end_dt.astimezone(tz)
result = []
@@ -396,10 +396,10 @@ class ResourceCalendar(models.Model):
return Intervals(result)
def _work_intervals(self, start_dt, end_dt, resource=None, domain=None):
def _work_intervals(self, start_dt, end_dt, resource=None, domain=None, tz=None):
""" Return the effective work intervals between the given datetimes. """
return (self._attendance_intervals(start_dt, end_dt, resource) -
self._leave_intervals(start_dt, end_dt, resource, domain))
return (self._attendance_intervals(start_dt, end_dt, resource, tz=tz) -
self._leave_intervals(start_dt, end_dt, resource, domain, tz=tz))
# --------------------------------------------------
# Private Methods / Helpers