-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MIG] sale_order_rename: Migration to 16.0
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
- Loading branch information
1 parent
51137ef
commit 7031632
Showing
5 changed files
with
155 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"] | ||
for so in self: | ||
domain = [ | ||
("name", "=", so.name), | ||
("company_id", "=", so.company_id.id), | ||
("id", "!=", so.id), | ||
] | ||
if so_obj.search_count(domain): | ||
_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!")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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", | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters