[FIX] hr,sale,project(_timesheet)_holidays: improve the user/validation errors

Purpose of the commit is, User/validation errors are sometimes not
correct in English and/or quite obscure and don't help the user
understand/solve the issue. so some copywriting should help make
the experience better.

So in this commit, re-word the several validation and usererror message
and als make the timesheet_task_id field required when the
timesheet_project_id field is set,

closes odoo/odoo#70796

Taskid: 2513067
Related: odoo/enterprise#18386
Signed-off-by: LTU-Odoo <IT-Ideas@users.noreply.github.com>
This commit is contained in:
Urvi Soni
2021-06-03 06:52:21 +00:00
committed by Barad Mahendra
parent 9c6c77bcc0
commit abe4856f4c
8 changed files with 14 additions and 14 deletions
+1 -1
View File
@@ -155,7 +155,7 @@ class AccountAnalyticLine(models.Model):
vals['account_id'] = project.analytic_account_id.id
vals['company_id'] = project.analytic_account_id.company_id.id or project.company_id.id
if not project.analytic_account_id.active:
raise UserError(_('The project you are timesheeting on is not linked to an active analytic account. Set one on the project configuration.'))
raise UserError(_('You cannot add timesheets to a project linked to an inactive analytic account.'))
# employee implies user
if vals.get('employee_id') and not vals.get('user_id'):
employee = self.env['hr.employee'].browse(vals['employee_id'])
+1 -1
View File
@@ -40,7 +40,7 @@ class Project(models.Model):
def _check_allow_timesheet(self):
for project in self:
if project.allow_timesheets and not project.analytic_account_id:
raise ValidationError(_('To allow timesheet, your project %s should have an analytic account set.', project.name))
raise ValidationError(_('You cannot use timesheets without an analytic account.'))
@api.depends('timesheet_ids')
def _compute_total_timesheet_time(self):
@@ -13,4 +13,4 @@ class AccountAnalyticLine(models.Model):
@api.ondelete(at_uninstall=False)
def _unlink_except_linked_leave(self):
if any(line.holiday_id for line in self):
raise UserError(_('You cannot delete timesheet lines attached to a leaves. Please cancel the leaves instead.'))
raise UserError(_('You cannot delete timesheets linked to time off. Please, cancel the time off instead.'))
@@ -21,7 +21,7 @@ class HolidaysType(models.Model):
help="If checked, when validating a time off, timesheet will be generated in the Vacation Project of the company.")
timesheet_project_id = fields.Many2one('project.project', string="Project", default=_default_project_id, domain="[('company_id', '=', company_id)]", help="The project will contain the timesheet generated when a time off is validated.")
timesheet_task_id = fields.Many2one(
'project.task', string="Task for timesheet", compute='_compute_timesheet_task_id',
'project.task', string="Task", compute='_compute_timesheet_task_id',
store=True, readonly=False, default=_default_task_id,
domain="[('project_id', '=', timesheet_project_id),"
"('company_id', '=', company_id)]")
@@ -7,9 +7,9 @@
<field name="inherit_id" ref="hr_holidays.edit_holiday_status_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='calendar']" position="after">
<group name="timesheet" string="Timesheet" groups="base.group_no_one">
<group name="timesheet" string="Timesheets" groups="base.group_no_one">
<field name="timesheet_project_id" context="{'active_test': False}"/>
<field name="timesheet_task_id" context="{'active_test': False}"/>
<field name="timesheet_task_id" context="{'active_test': False}" attrs="{'required': [('timesheet_project_id', '!=', False)]}"/>
<field name="timesheet_generate" invisible="1"/>
</group>
+1 -1
View File
@@ -64,7 +64,7 @@ class AccountAnalyticLine(models.Model):
def _check_can_write(self, values):
if self.sudo().filtered(lambda aal: aal.so_line.product_id.invoice_policy == "delivery") and self.filtered(lambda t: t.timesheet_invoice_id and t.timesheet_invoice_id.state != 'cancel'):
if any(field_name in values for field_name in ['unit_amount', 'employee_id', 'project_id', 'task_id', 'so_line', 'amount', 'date']):
raise UserError(_('You can not modify already invoiced timesheets (linked to a Sales order items invoiced on Time and material).'))
raise UserError(_('You cannot modify timesheets that are already invoiced.'))
@api.model
def _timesheet_preprocess(self, values):
+4 -4
View File
@@ -93,7 +93,7 @@ class ProductTemplate(models.Model):
def _unlink_except_master_data(self):
time_product = self.env.ref('sale_timesheet.time_product')
if time_product.product_tmpl_id in self:
raise ValidationError(_('The %s product is required by the Timesheet app and cannot be archived/deleted.') % time_product.name)
raise ValidationError(_('The %s product is required by the Timesheets app and cannot be archived nor deleted.') % time_product.name)
def write(self, vals):
# timesheet product can't be archived
@@ -101,7 +101,7 @@ class ProductTemplate(models.Model):
if not test_mode and 'active' in vals and not vals['active']:
time_product = self.env.ref('sale_timesheet.time_product')
if time_product.product_tmpl_id in self:
raise ValidationError(_('The %s product is required by the Timesheet app and cannot be archived/deleted.') % time_product.name)
raise ValidationError(_('The %s product is required by the Timesheets app and cannot be archived nor deleted.') % time_product.name)
return super(ProductTemplate, self).write(vals)
@@ -126,7 +126,7 @@ class ProductProduct(models.Model):
def _unlink_except_master_data(self):
time_product = self.env.ref('sale_timesheet.time_product')
if time_product in self:
raise ValidationError(_('The %s product is required by the Timesheet app and cannot be archived/deleted.') % time_product.name)
raise ValidationError(_('The %s product is required by the Timesheets app and cannot be archived nor deleted.') % time_product.name)
def write(self, vals):
# timesheet product can't be archived
@@ -134,5 +134,5 @@ class ProductProduct(models.Model):
if not test_mode and 'active' in vals and not vals['active']:
time_product = self.env.ref('sale_timesheet.time_product')
if time_product in self:
raise ValidationError(_('The %s product is required by the Timesheet app and cannot be archived/deleted.') % time_product.name)
raise ValidationError(_('The %s product is required by the Timesheets app and cannot be archived nor deleted.') % time_product.name)
return super(ProductProduct, self).write(vals)
+3 -3
View File
@@ -88,7 +88,7 @@ class Project(models.Model):
if operator not in ('=', '!='):
raise UserError(_('Operation not supported'))
if not ((isinstance(value, bool) and value is False) or (isinstance(value, str) and value in ('task_rate', 'fixed_rate', 'employee_rate'))):
return UserError(_('Value does not exist in the pricing type'))
raise UserError(_('Value does not exist in the pricing type'))
if value is False:
return [('allow_billable', operator, value)]
@@ -167,9 +167,9 @@ class Project(models.Model):
def _check_sale_line_type(self):
for project in self.filtered(lambda project: project.sale_line_id):
if not project.sale_line_id.is_service:
raise ValidationError(_("A billable project should be linked to a Sales Order Item having a Service product."))
raise ValidationError(_("You cannot link a billable project to a sales order item that is not a service."))
if project.sale_line_id.is_expense:
raise ValidationError(_("A billable project should be linked to a Sales Order Item that does not come from an expense or a vendor bill."))
raise ValidationError(_("You cannot link a billable project to a sales order item that comes from an expense or a vendor bill."))
def write(self, values):
res = super(Project, self).write(values)