Skip to content

Commit abe4856

Browse files
uso-odoomba-odoo
authored andcommitted
[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#70796 Taskid: 2513067 Related: odoo/enterprise#18386 Signed-off-by: LTU-Odoo <[email protected]>
1 parent 9c6c77b commit abe4856

File tree

8 files changed

+14
-14
lines changed

8 files changed

+14
-14
lines changed

addons/hr_timesheet/models/hr_timesheet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def _timesheet_preprocess(self, vals):
155155
vals['account_id'] = project.analytic_account_id.id
156156
vals['company_id'] = project.analytic_account_id.company_id.id or project.company_id.id
157157
if not project.analytic_account_id.active:
158-
raise UserError(_('The project you are timesheeting on is not linked to an active analytic account. Set one on the project configuration.'))
158+
raise UserError(_('You cannot add timesheets to a project linked to an inactive analytic account.'))
159159
# employee implies user
160160
if vals.get('employee_id') and not vals.get('user_id'):
161161
employee = self.env['hr.employee'].browse(vals['employee_id'])

addons/hr_timesheet/models/project.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def _compute_allow_timesheets(self):
4040
def _check_allow_timesheet(self):
4141
for project in self:
4242
if project.allow_timesheets and not project.analytic_account_id:
43-
raise ValidationError(_('To allow timesheet, your project %s should have an analytic account set.', project.name))
43+
raise ValidationError(_('You cannot use timesheets without an analytic account.'))
4444

4545
@api.depends('timesheet_ids')
4646
def _compute_total_timesheet_time(self):

addons/project_timesheet_holidays/models/account_analytic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ class AccountAnalyticLine(models.Model):
1313
@api.ondelete(at_uninstall=False)
1414
def _unlink_except_linked_leave(self):
1515
if any(line.holiday_id for line in self):
16-
raise UserError(_('You cannot delete timesheet lines attached to a leaves. Please cancel the leaves instead.'))
16+
raise UserError(_('You cannot delete timesheets linked to time off. Please, cancel the time off instead.'))

addons/project_timesheet_holidays/models/hr_holidays.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def _default_task_id(self):
2121
help="If checked, when validating a time off, timesheet will be generated in the Vacation Project of the company.")
2222
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.")
2323
timesheet_task_id = fields.Many2one(
24-
'project.task', string="Task for timesheet", compute='_compute_timesheet_task_id',
24+
'project.task', string="Task", compute='_compute_timesheet_task_id',
2525
store=True, readonly=False, default=_default_task_id,
2626
domain="[('project_id', '=', timesheet_project_id),"
2727
"('company_id', '=', company_id)]")

addons/project_timesheet_holidays/views/hr_holidays_views.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
<field name="inherit_id" ref="hr_holidays.edit_holiday_status_form"/>
88
<field name="arch" type="xml">
99
<xpath expr="//group[@name='calendar']" position="after">
10-
<group name="timesheet" string="Timesheet" groups="base.group_no_one">
10+
<group name="timesheet" string="Timesheets" groups="base.group_no_one">
1111
<field name="timesheet_project_id" context="{'active_test': False}"/>
12-
<field name="timesheet_task_id" context="{'active_test': False}"/>
12+
<field name="timesheet_task_id" context="{'active_test': False}" attrs="{'required': [('timesheet_project_id', '!=', False)]}"/>
1313
<field name="timesheet_generate" invisible="1"/>
1414
</group>
1515

addons/sale_timesheet/models/account.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def write(self, values):
6464
def _check_can_write(self, values):
6565
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'):
6666
if any(field_name in values for field_name in ['unit_amount', 'employee_id', 'project_id', 'task_id', 'so_line', 'amount', 'date']):
67-
raise UserError(_('You can not modify already invoiced timesheets (linked to a Sales order items invoiced on Time and material).'))
67+
raise UserError(_('You cannot modify timesheets that are already invoiced.'))
6868

6969
@api.model
7070
def _timesheet_preprocess(self, values):

addons/sale_timesheet/models/product.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,15 @@ def _onchange_service_policy(self):
9393
def _unlink_except_master_data(self):
9494
time_product = self.env.ref('sale_timesheet.time_product')
9595
if time_product.product_tmpl_id in self:
96-
raise ValidationError(_('The %s product is required by the Timesheet app and cannot be archived/deleted.') % time_product.name)
96+
raise ValidationError(_('The %s product is required by the Timesheets app and cannot be archived nor deleted.') % time_product.name)
9797

9898
def write(self, vals):
9999
# timesheet product can't be archived
100100
test_mode = getattr(threading.currentThread(), 'testing', False) or self.env.registry.in_test_mode()
101101
if not test_mode and 'active' in vals and not vals['active']:
102102
time_product = self.env.ref('sale_timesheet.time_product')
103103
if time_product.product_tmpl_id in self:
104-
raise ValidationError(_('The %s product is required by the Timesheet app and cannot be archived/deleted.') % time_product.name)
104+
raise ValidationError(_('The %s product is required by the Timesheets app and cannot be archived nor deleted.') % time_product.name)
105105
return super(ProductTemplate, self).write(vals)
106106

107107

@@ -126,13 +126,13 @@ def _onchange_service_policy(self):
126126
def _unlink_except_master_data(self):
127127
time_product = self.env.ref('sale_timesheet.time_product')
128128
if time_product in self:
129-
raise ValidationError(_('The %s product is required by the Timesheet app and cannot be archived/deleted.') % time_product.name)
129+
raise ValidationError(_('The %s product is required by the Timesheets app and cannot be archived nor deleted.') % time_product.name)
130130

131131
def write(self, vals):
132132
# timesheet product can't be archived
133133
test_mode = getattr(threading.currentThread(), 'testing', False) or self.env.registry.in_test_mode()
134134
if not test_mode and 'active' in vals and not vals['active']:
135135
time_product = self.env.ref('sale_timesheet.time_product')
136136
if time_product in self:
137-
raise ValidationError(_('The %s product is required by the Timesheet app and cannot be archived/deleted.') % time_product.name)
137+
raise ValidationError(_('The %s product is required by the Timesheets app and cannot be archived nor deleted.') % time_product.name)
138138
return super(ProductProduct, self).write(vals)

addons/sale_timesheet/models/project.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def _search_pricing_type(self, operator, value):
8888
if operator not in ('=', '!='):
8989
raise UserError(_('Operation not supported'))
9090
if not ((isinstance(value, bool) and value is False) or (isinstance(value, str) and value in ('task_rate', 'fixed_rate', 'employee_rate'))):
91-
return UserError(_('Value does not exist in the pricing type'))
91+
raise UserError(_('Value does not exist in the pricing type'))
9292
if value is False:
9393
return [('allow_billable', operator, value)]
9494

@@ -167,9 +167,9 @@ def _compute_sale_line_id(self):
167167
def _check_sale_line_type(self):
168168
for project in self.filtered(lambda project: project.sale_line_id):
169169
if not project.sale_line_id.is_service:
170-
raise ValidationError(_("A billable project should be linked to a Sales Order Item having a Service product."))
170+
raise ValidationError(_("You cannot link a billable project to a sales order item that is not a service."))
171171
if project.sale_line_id.is_expense:
172-
raise ValidationError(_("A billable project should be linked to a Sales Order Item that does not come from an expense or a vendor bill."))
172+
raise ValidationError(_("You cannot link a billable project to a sales order item that comes from an expense or a vendor bill."))
173173

174174
def write(self, values):
175175
res = super(Project, self).write(values)

0 commit comments

Comments
 (0)