[16.0] [MIG] sale_order_rename: Migration to 16.0#3556
[16.0] [MIG] sale_order_rename: Migration to 16.0#3556patrickt-oforce wants to merge 11 commits intoOCA:16.0from
Conversation
4458c3c to
fc5e07c
Compare
|
Code LGTM |
fc5e07c to
1290592
Compare
Rewrite check for unique sale.order name, using api.constraint and ensure that name is unique on same company. Update test according to new name uniqueness check logic Remove xpath for sale order name label because the form is always in edit mode
1290592 to
7031632
Compare
|
/ocabot migration sale_order_rename |
| @api.constrains("name") | ||
| def _check_unique_name_in_company(self): | ||
| so_obj = self.env["sale.order"] | ||
| for so in self: |
There was a problem hiding this comment.
@patrickt-oforce Have you tried something like this ?
result = self._read_group(
domain=[('name', 'in', self.mapped('name')],
fields=['company_id', 'ids:array_agg(id)'],
groupby=['company_id'],
)
for res in result:
if res.get('company_id_count', 0) >= 2:
duplicate_orders = self.browse(res['ids'])
raise (...)
In order to not do as much queries as recordset amount.
There was a problem hiding this comment.
Hi @rousseldenis, sorry i've seen the comment only now; i try and write here if ok
alexey-pelykh
left a comment
There was a problem hiding this comment.
Review: sale_order_rename migration to 16.0
Thank you for the migration work. The module structure, tests, manifest, and i18n are all in good shape. A few issues need to be addressed before merge.
Issues requiring changes
1. Use ValidationError instead of UserError in @api.constrains (correctness)
Odoo convention is to raise odoo.exceptions.ValidationError from @api.constrains methods, not UserError. UserError is intended for business logic checks in button actions / write methods, while ValidationError is the standard for constraint violations. See Odoo ORM docs on @api.constrains.
2. N+1 query in _check_unique_name_in_company (performance)
As already noted by @rousseldenis, the current implementation executes one search_count per record in the recordset. For batch writes this becomes O(n) queries. A single read_group or a raw SQL query checking for duplicates across all records in self would be more efficient. Please address the suggestion from the earlier review comment.
3. _logger.error() before raising exception (best practice)
Logging at ERROR level right before raising a UserError/ValidationError is redundant -- Odoo already logs unhandled exceptions. If the intent is audit/debug tracing, _logger.debug() or _logger.warning() would be more appropriate. Logging at ERROR level for a normal validation failure creates noise in production logs.
Suggestions (non-blocking)
- Copyright year in
__manifest__.py: The header saysCopyright 2020-2022 CorporateHubbut the migration was done in 2025. Consider updating to2020-2025. - Missing
readme/USAGE.rst: The description mentions renaming in Draft state, but there is no usage documentation. A brief explanation of how to use the feature would help users.
Overall the module is well-structured with good test coverage. Once the ValidationError and N+1 issues are resolved, this should be ready.
Review posted via CorporateHub OCA review campaign
|
|
||
| import logging | ||
|
|
||
| from odoo import _, api, models |
There was a problem hiding this comment.
For @api.constrains methods, the Odoo convention is to raise ValidationError instead of UserError.
from odoo.exceptions import ValidationErrorAnd correspondingly change the raise UserError(...) to raise ValidationError(...) on line 32.
|
|
||
| @api.constrains("name") | ||
| def _check_unique_name_in_company(self): | ||
| so_obj = self.env["sale.order"] |
There was a problem hiding this comment.
This loop executes one search_count per record, which is an N+1 query pattern. For batch operations (e.g., importing multiple sale orders), this becomes costly.
Consider using read_group or a single SQL query to detect duplicates across all records in self at once, as suggested by @rousseldenis in an earlier comment.
| ("company_id", "=", so.company_id.id), | ||
| ("id", "!=", so.id), | ||
| ] | ||
| if so_obj.search_count(domain): |
There was a problem hiding this comment.
_logger.error() is too noisy here -- this is a normal validation failure, not an unexpected system error. Odoo will log the exception anyway. Consider _logger.debug() or remove the logging entirely.
No description provided.