[FIX] hr_timesheet: avoid setting an archived employee to a timesheet in the form view

Steps to reproduce:
- Install timesheet
- Archive an employee
- Create a timesheet

Current behavior:
You can select the archived employee

Expected behavior:
You can not select the archived employee

Explanation:
In commit 17b2b07 the employee_id
field of the timesheet was set to have context active_test to false.
To fix this issue we reset the context for this field in every
timesheet form and we add user errors if the employee is not active
while the timesheet is created or edited.

opw-2887727
opw-2870739

X-original-commit: f034ca05b9602592a5ed140849e20738470ee292
Part-of: odoo/odoo#95644
This commit is contained in:
mafo-odoo
2022-07-08 14:34:26 +02:00
committed by Xavier BOL (xbo)
parent 8f2673708a
commit c0cbcb330e
5 changed files with 46 additions and 6 deletions
+12
View File
@@ -1206,6 +1206,12 @@ msgstr ""
msgid "Timesheets can be logged on this task."
msgstr ""
#. module: hr_timesheet
#: code:addons/hr_timesheet/models/hr_timesheet.py:0
#, python-format
msgid "Timesheets must be created with an active employee."
msgstr ""
#. module: hr_timesheet
#: model:digest.tip,name:hr_timesheet.digest_tip_hr_timesheet_0
msgid "Tip: Record your Timesheets faster"
@@ -1344,6 +1350,12 @@ msgid ""
"to timesheet on the project."
msgstr ""
#. module: hr_timesheet
#: code:addons/hr_timesheet/models/hr_timesheet.py:0
#, python-format
msgid "You cannot set an archived employee to the existing timesheets."
msgstr ""
#. module: hr_timesheet
#: code:addons/hr_timesheet/models/project.py:0
#, python-format
+10 -2
View File
@@ -124,11 +124,12 @@ class AccountAnalyticLine(models.Model):
# Although this make a second loop on the vals, we need to wait the preprocess as it could change the company_id in the vals
# TODO To be refactored in master
employees = self.env['hr.employee'].sudo().with_context(active_test=False).search([('user_id', 'in', user_ids)])
employees = self.env['hr.employee'].sudo().search([('user_id', 'in', user_ids)])
employee_for_user_company = defaultdict(dict)
for employee in employees:
employee_for_user_company[employee.user_id.id][employee.company_id.id] = employee.id
employee_ids = set()
for vals in vals_list:
# compute employee only for timesheet lines, makes no sense for other lines
if not vals.get('employee_id') and vals.get('project_id'):
@@ -137,7 +138,10 @@ class AccountAnalyticLine(models.Model):
continue
company_id = list(employee_for_company)[0] if len(employee_for_company) == 1 else vals.get('company_id', self.env.company.id)
vals['employee_id'] = employee_for_company.get(company_id, False)
elif vals.get('employee_id'):
employee_ids.add(vals['employee_id'])
if any(not emp.active for emp in self.env['hr.employee'].browse(list(employee_ids))):
raise UserError(_('Timesheets must be created with an active employee.'))
lines = super(AccountAnalyticLine, self).create(vals_list)
for line, values in zip(lines, vals_list):
if line.project_id: # applied only for timesheet
@@ -150,6 +154,10 @@ class AccountAnalyticLine(models.Model):
raise AccessError(_("You cannot access timesheets that are not yours."))
values = self._timesheet_preprocess(values)
if values.get('employee_id'):
employee = self.env['hr.employee'].browse(values['employee_id'])
if not employee.active:
raise UserError(_('You cannot set an archived employee to the existing timesheets.'))
if 'name' in values and not values.get('name'):
values['name'] = '/'
result = super(AccountAnalyticLine, self).write(values)
@@ -498,3 +498,22 @@ class TestTimesheet(TestCommonTimesheet):
timesheet1.unit_amount + timesheet2.unit_amount,
'The total timesheet time of this project should be equal to 4.'
)
def test_create_timesheet_with_archived_employee(self):
''' the timesheet can be created or edited only with an active employee
'''
self.empl_employee2.active = False
batch_vals = {
'project_id': self.project_customer.id,
'task_id': self.task1.id,
'name': 'archived employee timesheet',
'unit_amount': 3,
'employee_id': self.empl_employee2.id
}
self.assertRaises(UserError, self.env['account.analytic.line'].create, batch_vals)
batch_vals["employee_id"] = self.empl_employee.id
timesheet = self.env['account.analytic.line'].create(batch_vals)
with self.assertRaises(UserError):
timesheet.employee_id = self.empl_employee2
@@ -47,6 +47,7 @@
<attribute name="invisible">0</attribute>
<attribute name="required">1</attribute>
<attribute name="widget">many2one_avatar_employee</attribute>
<attribute name="context">{'active_test': True}</attribute>
</xpath>
</field>
</record>
@@ -163,7 +164,7 @@
<field name="priority">10</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='date']" position="before">
<field name="employee_id" required="1"/>
<field name="employee_id" required="1" context="{'active_test': True}"/>
<field name="user_id" invisible="1"/>
</xpath>
</field>
+3 -3
View File
@@ -151,7 +151,7 @@
<tree editable="bottom" string="Timesheet Activities" default_order="date">
<field name="date"/>
<field name="user_id" invisible="1"/>
<field name="employee_id" required="1" widget="many2one_avatar_employee"/>
<field name="employee_id" required="1" widget="many2one_avatar_employee" context="{'active_test': True}"/>
<field name="name" required="0"/>
<field name="tag_ids" groups="analytic.group_analytic_tags" widget="many2many_tags" optional="hide"/>
<field name="unit_amount" widget="timesheet_uom" decoration-danger="unit_amount &gt; 24 or unit_amount &lt; 0"/>
@@ -171,7 +171,7 @@
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
<div class="row">
<div class="col-6">
<field name="employee_id" widget="many2one_avatar_employee"/>
<field name="employee_id" widget="many2one_avatar_employee" context="{'active_test': True}"/>
<strong><span><t t-esc="record.employee_id.value"/></span></strong>
</div>
<div class="col-6 float-end text-end">
@@ -197,7 +197,7 @@
<group>
<field name="date"/>
<field name="user_id" invisible="1"/>
<field name="employee_id" required="1" widget="many2one_avatar_employee"/>
<field name="employee_id" required="1" widget="many2one_avatar_employee" context="{'active_test': True}"/>
<field name="name" required="0"/>
<field name="unit_amount" string="Duration" widget="float_time" decoration-danger="unit_amount &gt; 24"/>
<field name="project_id" invisible="1"/>