[IMP] hr_work_entry: improve work entries error management
`display_warning` is now replaced with the `conflict` state. closes odoo/odoo#34653 Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
committed by
Yannick Tivisse
parent
8dcc4f9d94
commit
544476f945
@@ -10,7 +10,7 @@ from odoo import api, fields, models
|
||||
class HrWorkEntry(models.Model):
|
||||
_name = 'hr.work.entry'
|
||||
_description = 'HR Work Entry'
|
||||
_order = 'display_warning desc,state,date_start'
|
||||
_order = 'conflict desc,state,date_start'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
active = fields.Boolean(default=True)
|
||||
@@ -24,17 +24,23 @@ class HrWorkEntry(models.Model):
|
||||
('draft', 'Draft'),
|
||||
('confirmed', 'Confirmed'),
|
||||
('validated', 'Validated'),
|
||||
('conflict', 'Conflict'),
|
||||
('cancelled', 'Cancelled')
|
||||
], default='draft')
|
||||
display_warning = fields.Boolean(string="Error")
|
||||
company_id = fields.Many2one('res.company', string='Company', readonly=True, required=True,
|
||||
default=lambda self: self.env.company)
|
||||
conflict = fields.Boolean('Conflicts', compute='_compute_conflict', store=True) # Used to show conflicting work entries first
|
||||
|
||||
_sql_constraints = [
|
||||
('_work_entry_has_end', 'check (date_stop IS NOT NULL)', 'Work entry must end. Please define an end date or a duration.'),
|
||||
('_work_entry_start_before_end', 'check (date_stop > date_start)', 'Starting time should be before end time.')
|
||||
]
|
||||
|
||||
@api.onchange('state')
|
||||
def _compute_conflict(self):
|
||||
for rec in self:
|
||||
rec.conflict = rec.state == 'conflict'
|
||||
|
||||
@api.onchange('duration')
|
||||
def _onchange_duration(self):
|
||||
self._inverse_duration()
|
||||
@@ -59,7 +65,7 @@ class HrWorkEntry(models.Model):
|
||||
def action_validate(self):
|
||||
"""
|
||||
Try to validate work entries.
|
||||
If some errors are found, set `display_warning` to True for conflicting work entries
|
||||
If some errors are found, set `state` to conflict for conflicting work entries
|
||||
and validation fails.
|
||||
:return: True if validation succeded
|
||||
"""
|
||||
@@ -74,14 +80,14 @@ class HrWorkEntry(models.Model):
|
||||
if not self:
|
||||
return False
|
||||
undefined_type = self.filtered(lambda b: not b.work_entry_type_id)
|
||||
undefined_type.write({'display_warning': True})
|
||||
undefined_type.write({'state': 'conflict'})
|
||||
conflict = self._mark_conflicting_work_entries(min(self.mapped('date_start')), max(self.mapped('date_stop')))
|
||||
return undefined_type or conflict
|
||||
|
||||
@api.model
|
||||
def _mark_conflicting_work_entries(self, start, stop):
|
||||
"""
|
||||
Set `display_warning` to True for overlapping work entries
|
||||
Set `state` to `conflict` for overlapping work entries
|
||||
between two dates.
|
||||
Return True if overlapping work entries were detected.
|
||||
"""
|
||||
@@ -112,7 +118,7 @@ class HrWorkEntry(models.Model):
|
||||
self.env.cr.execute(query, (stop, start, stop, start))
|
||||
conflicts = [res.get('id') for res in self.env.cr.dictfetchall()]
|
||||
self.browse(conflicts).write({
|
||||
'display_warning': True,
|
||||
'state': 'conflict',
|
||||
})
|
||||
return bool(conflicts)
|
||||
|
||||
@@ -129,10 +135,7 @@ class HrWorkEntry(models.Model):
|
||||
vals['active'] = True
|
||||
elif vals['state'] == 'cancelled':
|
||||
vals['active'] = False
|
||||
skip_check &= not any(self.mapped('display_warning'))
|
||||
elif vals['state'] == 'validated':
|
||||
# A validated work entry is never conflicting
|
||||
vals['display_warning'] = False
|
||||
skip_check &= all(self.mapped(lambda w: w.state != 'conflict'))
|
||||
|
||||
if 'active' in vals:
|
||||
vals['state'] = 'confirmed' if vals['active'] else 'cancelled'
|
||||
@@ -146,7 +149,7 @@ class HrWorkEntry(models.Model):
|
||||
return super().unlink()
|
||||
|
||||
def _reset_conflicting_state(self):
|
||||
self.write({'display_warning': False})
|
||||
self.filtered(lambda w: w.state == 'conflict').write({'state': 'confirmed'})
|
||||
|
||||
@contextmanager
|
||||
def _error_checking(self, start=None, stop=None, skip=False):
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
color="color"
|
||||
event_limit="5">
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="display_warning" invisible="1"/>
|
||||
<!-- Sidebar favorites filters -->
|
||||
<field name="employee_id" write_model="hr.user.work.entry.employee" write_field="employee_id" avatar_field="image_small"/>
|
||||
<templates>
|
||||
@@ -37,7 +36,7 @@
|
||||
<div t-att-style="typeof color === 'string' ? ('background-color:'+color)+';' : ''" t-attf-class="#{record.is_highlighted && record.is_highlighted.value ? 'o_event_hightlight' : ''} #{typeof color === 'number' ? 'o_calendar_color_'+color : ''}">
|
||||
<div class="fc-time"/>
|
||||
<div class="o_fields">
|
||||
<t t-if="record.display_warning">
|
||||
<t t-if="record.state == 'conflict'">
|
||||
<span class="fa fa-exclamation-triangle mr-2" aria-label="Conflict" title="error"/>
|
||||
</t>
|
||||
<t t-if="record.state == 'validated'">
|
||||
@@ -60,7 +59,6 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Work Entry" >
|
||||
<header>
|
||||
<field name="display_warning" invisible="1"/>
|
||||
<field name="state" widget="statusbar" options="{'clickable': '1'}"/>
|
||||
</header>
|
||||
<sheet>
|
||||
@@ -98,7 +96,6 @@
|
||||
<field name="duration"/>
|
||||
<field name="state"/>
|
||||
<field name="date_start" string="Beginning"/>
|
||||
<field name="display_warning"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -111,7 +108,7 @@
|
||||
<field name="employee_id"/>
|
||||
<field name="name"/>
|
||||
<filter string="My Work Entries" domain="[('employee_id.user_id','=',uid)]" name="my_work_entries"/>
|
||||
<filter string="With error" domain="[('display_warning','=', True)]" name="work_entries_error"/>
|
||||
<filter string="With error" domain="[('state','=', 'conflict')]" name="work_entries_error"/>
|
||||
<filter name="date_filter" string="Date" date="date_start"/>
|
||||
<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'}"/>
|
||||
|
||||
Reference in New Issue
Block a user