Skip to content

Commit 22c36ca

Browse files
committed
Merge PR #2190 into 18.0
Signed-off-by pedrobaeza
2 parents 7ca278a + 36b93fa commit 22c36ca

File tree

5 files changed

+161
-0
lines changed

5 files changed

+161
-0
lines changed

partner_property/models/res_company.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
33

44
from odoo import api, fields, models
5+
from odoo.osv.expression import FALSE_DOMAIN, TRUE_DOMAIN
56

67

78
class ResCompany(models.Model):
@@ -11,11 +12,13 @@ class ResCompany(models.Model):
1112
string="Partner Properties (company)",
1213
compute="_compute_partner_properties_definition_company",
1314
inverse="_inverse_partner_properties_definition_company",
15+
search="_search_partner_properties_definition_company",
1416
)
1517
partner_properties_definition_person = fields.PropertiesDefinition(
1618
string="Partner Properties (person)",
1719
compute="_compute_partner_properties_definition_person",
1820
inverse="_inverse_partner_properties_definition_person",
21+
search="_search_partner_properties_definition_person",
1922
)
2023

2124
@api.depends_context("company")
@@ -56,6 +59,22 @@ def _inverse_partner_properties_definition_person(self):
5659
)
5760
ICP.sudo().set_param("partner_property.properties_definition_person", value)
5861

62+
def _search_partner_properties_definition_company(self, operator, value):
63+
if operator not in ("=", "!=") or value is not False: # pragma: no cover
64+
raise NotImplementedError("Only = and != operators are supported")
65+
ICP = self.env["ir.config_parameter"]
66+
value = ICP.sudo().get_param("partner_property.properties_definition_company")
67+
condition = operator == "!=" and bool(value) or not value
68+
return condition and TRUE_DOMAIN or FALSE_DOMAIN
69+
70+
def _search_partner_properties_definition_person(self, operator, value):
71+
if operator not in ("=", "!=") or value is not False: # pragma: no cover
72+
raise NotImplementedError("Only = and != operators are supported")
73+
ICP = self.env["ir.config_parameter"]
74+
value = ICP.sudo().get_param("partner_property.properties_definition_person")
75+
condition = operator == "!=" and bool(value) or not value
76+
return condition and TRUE_DOMAIN or FALSE_DOMAIN
77+
5978
@api.model
6079
def web_search_read(
6180
self, domain, specification, offset=0, limit=None, order=None, count_limit=None

partner_property/models/res_partner.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
33

44
from odoo import api, fields, models
5+
from odoo.osv.expression import SQL_OPERATORS
6+
from odoo.tools.sql import SQL
57

68

79
class ResPartner(models.Model):
810
_inherit = "res.partner"
911

1012
properties_company_id = fields.Many2one(
1113
compute="_compute_properties_company_id",
14+
search="_search_properties_company_id",
1215
comodel_name="res.company",
1316
)
1417
properties_type_company = fields.Properties(
@@ -25,3 +28,27 @@ class ResPartner(models.Model):
2528
def _compute_properties_company_id(self):
2629
for item in self:
2730
item.properties_company_id = item.company_id or self.env.company
31+
32+
def _search_properties_company_id(self, operator, value):
33+
self.flush_model(["company_id"])
34+
query = self._where_calc([])
35+
query.add_where(
36+
SQL(
37+
"%s %s %s",
38+
self._field_to_sql(
39+
"properties_company_id", "properties_company_id", query
40+
),
41+
SQL_OPERATORS[operator],
42+
value,
43+
)
44+
)
45+
return [("id", "in", query)]
46+
47+
def _field_to_sql(self, alias, fname, query=None, flush: bool = True) -> SQL:
48+
# OVERRIDE to allow to export the properties
49+
if fname == "properties_company_id":
50+
return SQL(
51+
"""COALESCE(company_id, %(env_company)s)""",
52+
env_company=self.env.company.id,
53+
)
54+
return super()._field_to_sql(alias, fname, query, flush)

partner_property/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
from . import test_export
12
from . import test_res_partner
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright 2025 Camptocamp SA (https://www.camptocamp.com).
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
import json
5+
6+
from odoo.tests import HttpCase
7+
8+
9+
class TextPartnerExport(HttpCase):
10+
def test_export_get_fields(self):
11+
"""Text the export wizard get_fields method.
12+
13+
Due to the way `properties_company_id` is computed and used in the path of the
14+
properties definition, the export wizard fails as it expects a stored field.
15+
16+
A fix is done by implementing the `_field_to_sql` and
17+
`_search_properties_company_id` methods. This unit test would fail without it.
18+
19+
.. traceback::
20+
21+
File "/odoo/src/odoo/addons/web/controllers/export.py", line 400, in get_fields
22+
exportable_fields.update(self._get_property_fields(fields, model, domain=domain))
23+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
File "/odoo/src/odoo/addons/web/controllers/export.py", line 321, in _get_property_fields
25+
field_to_get = Model._field_to_sql(Model._table, definition_record, self_subquery)
26+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27+
File "/odoo/src/odoo/odoo/models.py", line 2976, in _field_to_sql
28+
raise ValueError(f"Cannot convert {field} to SQL because it is not stored")
29+
ValueError: Cannot convert res.partner.properties_company_id to SQL because it is not stored
30+
""" # noqa: E501
31+
self.authenticate("admin", "admin")
32+
self.url_open(
33+
"/web/export/get_fields",
34+
data=json.dumps(
35+
{
36+
"params": {
37+
"model": "res.partner",
38+
"import_compat": True,
39+
"domain": [("id", "in", self.env.user.partner_id.ids)],
40+
}
41+
}
42+
),
43+
headers={"Content-Type": "application/json"},
44+
).raise_for_status()

partner_property/tests/test_res_partner.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,73 @@ def test_properties_company_B(self):
4949
partner.properties_company_id,
5050
self.company_b,
5151
)
52+
53+
def test_properties_company_id(self):
54+
partner = self.env["res.partner"].create({"name": "Partner Test"})
55+
# The partner has no company set, so the properties_company_id should
56+
# always match the current context company.
57+
self.assertEqual(
58+
partner.with_company(self.company_a.id).properties_company_id,
59+
self.company_a,
60+
)
61+
self.assertEqual(
62+
partner.with_company(self.company_b.id).properties_company_id,
63+
self.company_b,
64+
)
65+
# Searching should also work..
66+
self.assertEqual(
67+
self.env["res.partner"]
68+
.with_company(self.company_a.id)
69+
.search(
70+
[
71+
("properties_company_id", "=", self.company_a.id),
72+
("id", "=", partner.id),
73+
]
74+
),
75+
partner,
76+
)
77+
self.assertEqual(
78+
self.env["res.partner"]
79+
.with_company(self.company_b.id)
80+
.search(
81+
[
82+
("properties_company_id", "=", self.company_b.id),
83+
("id", "=", partner.id),
84+
]
85+
),
86+
partner,
87+
)
88+
# Except if we set an explicit company.. then it should match that
89+
# company regardless of the context company.
90+
partner.company_id = self.company_a
91+
self.assertEqual(
92+
partner.with_company(self.company_a.id).properties_company_id,
93+
self.company_a,
94+
)
95+
self.assertEqual(
96+
partner.with_company(self.company_b.id).properties_company_id,
97+
self.company_a,
98+
)
99+
# Searching should also work..
100+
self.assertEqual(
101+
self.env["res.partner"]
102+
.with_company(self.company_a.id)
103+
.search(
104+
[
105+
("properties_company_id", "=", self.company_a.id),
106+
("id", "=", partner.id),
107+
]
108+
),
109+
partner,
110+
)
111+
self.assertFalse(
112+
self.env["res.partner"]
113+
.with_company(self.company_b.id)
114+
.search(
115+
[
116+
("properties_company_id", "=", self.company_b.id),
117+
("id", "=", partner.id),
118+
]
119+
),
120+
partner,
121+
)

0 commit comments

Comments
 (0)