-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[16.0] [MIG] sale_order_rename: Migration to 16.0 #3556
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 16.0
Are you sure you want to change the base?
Changes from 1 commit
d70b140
31d8f37
5b5367c
13df29c
6671123
de60c57
d1638d3
980845e
ec68dfa
51137ef
7031632
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,31 +1,28 @@ | ||
| # Translation of Odoo Server. | ||
| # This file contains the translation of the following modules: | ||
| # * sale_order_rename | ||
| # * sale_order_rename | ||
| # | ||
| msgid "" | ||
| msgstr "" | ||
| "Project-Id-Version: Odoo Server 12.0\n" | ||
| "Project-Id-Version: Odoo Server 16.0+e-20250113\n" | ||
| "Report-Msgid-Bugs-To: \n" | ||
| "Last-Translator: <>\n" | ||
| "POT-Creation-Date: 2025-01-30 11:19+0000\n" | ||
| "PO-Revision-Date: 2025-01-30 11:19+0000\n" | ||
| "Last-Translator: \n" | ||
| "Language-Team: \n" | ||
| "MIME-Version: 1.0\n" | ||
| "Content-Type: text/plain; charset=UTF-8\n" | ||
| "Content-Transfer-Encoding: \n" | ||
| "Plural-Forms: \n" | ||
|
|
||
| #. module: sale_order_rename | ||
| #: code:addons/sale_order_rename/models/sale_order.py:26 | ||
| #. odoo-python | ||
| #: code:addons/sale_order_rename/models/sale_order.py:0 | ||
| #, python-format | ||
| msgid "New" | ||
| msgid "Sale Order name must be unique within a company!" | ||
| msgstr "" | ||
|
|
||
| #. module: sale_order_rename | ||
| #: model:ir.model,name:sale_order_rename.model_sale_order | ||
| msgid "Sale Order" | ||
| msgstr "" | ||
|
|
||
| #. module: sale_order_rename | ||
| #: sql_constraint:sale.order:0 | ||
| msgid "Sale Order name must be unique within a company!" | ||
| msgid "Sales Order" | ||
| msgstr "" | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,37 +1,33 @@ | ||
| # Copyright 2018 Brainbean Apps (https://brainbeanapps.com) | ||
| # Copyright 2025 Openforce Srls Unipersonale (www.openforce.it) | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
|
||
| import logging | ||
| from psycopg2 import IntegrityError | ||
|
|
||
| from odoo import models, api, _, tools | ||
| from odoo import _, api, models | ||
| from odoo.exceptions import UserError | ||
|
|
||
| _logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| class SaleOrder(models.Model): | ||
| _inherit = 'sale.order' | ||
| _inherit = "sale.order" | ||
|
|
||
| _name_company_uniq_constraint = 'name_company_uniq' | ||
| _sql_constraints = [ | ||
| ( | ||
| _name_company_uniq_constraint, | ||
| 'unique(name, company_id)', | ||
| 'Sale Order name must be unique within a company!' | ||
| ), | ||
| ] | ||
|
|
||
| @api.model | ||
| def create(self, vals): | ||
| is_name_generated = vals.get('name', _('New')) != _('New') | ||
| duplicate_key_msg = 'duplicate key value violates unique constraint' | ||
| while True: | ||
| try: | ||
| with self._cr.savepoint(), tools.mute_logger('odoo.sql_db'): | ||
| return super().create(vals.copy()) | ||
| except IntegrityError as e: | ||
| e_msg = str(e) | ||
| if is_name_generated or duplicate_key_msg not in e_msg or \ | ||
| self._name_company_uniq_constraint not in e_msg: | ||
| raise e | ||
| _logger.debug('Duplicate sale.order name, retrying creation') | ||
| @api.constrains("name") | ||
| def _check_unique_name_in_company(self): | ||
| so_obj = self.env["sale.order"] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This loop executes one Consider using |
||
| for so in self: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @patrickt-oforce Have you tried something like this ? In order to not do as much queries as recordset amount.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @rousseldenis, sorry i've seen the comment only now; i try and write here if ok |
||
| domain = [ | ||
| ("name", "=", so.name), | ||
| ("company_id", "=", so.company_id.id), | ||
| ("id", "!=", so.id), | ||
| ] | ||
| if so_obj.search_count(domain): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| _logger.error( | ||
| "Sale Order name %(so_name)s exists for company:" " %(company)s", | ||
| { | ||
| "so_name": so.name, | ||
| "company": so.company_id.name, | ||
| }, | ||
| ) | ||
| raise UserError(_("Sale Order name must be unique within a company!")) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,56 +1,129 @@ | ||
| # Copyright 2018 Brainbean Apps (https://brainbeanapps.com) | ||
| # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). | ||
|
|
||
| from psycopg2 import IntegrityError | ||
| from unittest import mock | ||
|
|
||
| from odoo.exceptions import UserError | ||
| from odoo.tests import common | ||
| from odoo.tools.misc import mute_logger | ||
|
|
||
| _ir_sequence_class = 'odoo.addons.base.models.ir_sequence.IrSequence' | ||
|
|
||
|
|
||
| class TestSaleOrderRename(common.TransactionCase): | ||
|
|
||
| def setUp(self): | ||
| super().setUp() | ||
|
|
||
| self.SaleOrder = self.env['sale.order'] | ||
| self.SudoSaleOrder = self.SaleOrder.sudo() | ||
|
|
||
| def test_1(self): | ||
| self.SudoSaleOrder.create({ | ||
| 'name': 'Test #1', | ||
| 'partner_id': self.env.ref('base.res_partner_1').id, | ||
| }) | ||
|
|
||
| with self.assertRaises(IntegrityError), mute_logger('odoo.sql_db'): | ||
| self.SudoSaleOrder.create({ | ||
| 'name': 'Test #1', | ||
| 'partner_id': self.env.ref('base.res_partner_1').id, | ||
| }) | ||
|
|
||
| def test_2(self): | ||
| sale_order_1 = self.SudoSaleOrder.create({ | ||
| 'partner_id': self.env.ref('base.res_partner_1').id, | ||
| }) | ||
| sale_order_2 = self.SudoSaleOrder.create({ | ||
| 'partner_id': self.env.ref('base.res_partner_1').id, | ||
| }) | ||
|
|
||
| self.assertNotEqual(sale_order_1.name, sale_order_2.name) | ||
|
|
||
| def test_3(self): | ||
| sale_order_1 = self.SudoSaleOrder.create({ | ||
| 'name': 'Test #3-1', | ||
| 'partner_id': self.env.ref('base.res_partner_1').id, | ||
| }) | ||
|
|
||
| with mock.patch( | ||
| _ir_sequence_class + '.next_by_code', | ||
| side_effect=['Test #3-1', 'Test #3-2']): | ||
| sale_order_2 = self.SudoSaleOrder.create({ | ||
| 'partner_id': self.env.ref('base.res_partner_1').id, | ||
| }) | ||
|
|
||
| self.assertNotEqual(sale_order_1.name, sale_order_2.name) | ||
| self.sale_order = self.env["sale.order"] | ||
| self.sale_order_sudo = self.sale_order.sudo() | ||
| self.base_company = self.env.ref("base.main_company") | ||
| self.other_company = self._create_company() | ||
|
|
||
| def _create_company(self): | ||
| return self.env["res.company"].create( | ||
| { | ||
| "name": "Test Company", | ||
| } | ||
| ) | ||
|
|
||
| def test_01_two_sale_order_with_same_name_in_different_companies(self): | ||
| so_vals = { | ||
| "name": "Test #1", | ||
| "partner_id": self.env.ref("base.res_partner_1").id, | ||
| } | ||
| self.sale_order.create( | ||
| [ | ||
| { | ||
| **so_vals, | ||
| "company_id": self.base_company.id, | ||
| } | ||
| ] | ||
| ) | ||
| self.sale_order.create( | ||
| [ | ||
| { | ||
| **so_vals, | ||
| "company_id": self.other_company.id, | ||
| } | ||
| ] | ||
| ) | ||
|
|
||
| def test_02_raise_exception_two_sale_order_with_same_name_in_same_company(self): | ||
| so_vals = { | ||
| "name": "Test #1", | ||
| "partner_id": self.env.ref("base.res_partner_1").id, | ||
| } | ||
| self.sale_order.create( | ||
| [ | ||
| { | ||
| **so_vals, | ||
| "company_id": self.base_company.id, | ||
| } | ||
| ] | ||
| ) | ||
| with self.assertRaises(UserError): | ||
| self.sale_order.create( | ||
| [ | ||
| { | ||
| **so_vals, | ||
| "company_id": self.base_company.id, | ||
| } | ||
| ] | ||
| ) | ||
|
|
||
| def test_03_raise_exception_renaming_two_so_in_same_company_with_same_name(self): | ||
| so_vals = { | ||
| "company_id": self.base_company.id, | ||
| "partner_id": self.env.ref("base.res_partner_1").id, | ||
| } | ||
| so1 = self.sale_order.create( | ||
| [ | ||
| { | ||
| **so_vals, | ||
| } | ||
| ] | ||
| ) | ||
| so2 = self.sale_order.create( | ||
| [ | ||
| { | ||
| **so_vals, | ||
| } | ||
| ] | ||
| ) | ||
| so1.write( | ||
| { | ||
| "name": "Test #1", | ||
| } | ||
| ) | ||
| with self.assertRaises(UserError): | ||
| so2.write( | ||
| { | ||
| "name": "Test #1", | ||
| } | ||
| ) | ||
|
|
||
| def test_04_allowed_renaming_two_so_in_different_company_with_same_name(self): | ||
| so_vals = { | ||
| "partner_id": self.env.ref("base.res_partner_1").id, | ||
| } | ||
| so1 = self.sale_order.create( | ||
| [ | ||
| { | ||
| **so_vals, | ||
| "company_id": self.base_company.id, | ||
| } | ||
| ] | ||
| ) | ||
| so2 = self.sale_order.create( | ||
| [ | ||
| { | ||
| **so_vals, | ||
| "company_id": self.other_company.id, | ||
| } | ||
| ] | ||
| ) | ||
| so1.write( | ||
| { | ||
| "name": "Test #1", | ||
| } | ||
| ) | ||
| so2.write( | ||
| { | ||
| "name": "Test #1", | ||
| } | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For
@api.constrainsmethods, the Odoo convention is to raiseValidationErrorinstead ofUserError.And correspondingly change the
raise UserError(...)toraise ValidationError(...)on line 32.