Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion edi_core_oca/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Define backends, exchange types, exchange records,
basic automation and views for handling EDI exchanges.
""",
"version": "18.0.1.6.3",
"version": "18.0.1.6.4",
"website": "https://github.com/OCA/edi-framework",
"development_status": "Beta",
"license": "LGPL-3",
Expand Down
24 changes: 24 additions & 0 deletions edi_core_oca/migrations/18.0.1.6.4/post-mig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2026 Camptocamp SA (http://www.camptocamp.com)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from logging import getLogger

from openupgradelib import openupgrade

_logger = getLogger(__name__)


@openupgrade.migrate()
def migrate(env, version):
xmlid = "edi_core_oca.rule_edi_exchange_record_user"
if rule := env.ref(xmlid, False):
old_domain = (rule.domain_force or "").strip()
new_domain = ["|", ("model", "!=", False), ("res_id", "=", 0)]
_logger.info(
f"Updating {rule} ({xmlid=}) domain:\n"
f" - old: {old_domain}\n"
f" - new: {new_domain}"
)
rule.domain_force = new_domain
else:
_logger.warning(f"No rule found with XMLID '{xmlid}', skipping...")
2 changes: 1 addition & 1 deletion edi_core_oca/security/ir_model_access.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
<field name="model_id" ref="edi_core_oca.model_edi_exchange_record" />
<field
name="domain_force"
>['|', ('model','!=', False), ('res_id', '=', False)]</field>
>['|', ('model', '!=', False), ('res_id', '=', 0)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]" />
</record>
<record id="rule_edi_exchange_record_manager" model="ir.rule">
Expand Down
32 changes: 32 additions & 0 deletions edi_core_oca/tests/test_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,35 @@ def test_search_pagination_with_inaccessible_middle_records(self):

# The records fetched from the second page must be present in the final result
self.assertIn(visible_id_2, records.ids)

def test_search_no_res_id(self):
"""Test Exc Rec visibility for internal users when ``res_id`` is False-ish

Exchange Record's ``res_id`` is a ``Many2onReference`` field, which internally
converts False-ish values to 0 before storing them to the cache and the DB.
The rule's domain old leaf ``('res_id', '=', False)`` was instead converted to a
SQL query clause ``WHERE "edi_exchange_record.res_id" IS NULL``.
Since all ``edi_exchange_record`` rows contain a non-negative integer in the
``res_id`` column, the rule old domain leaf always failed to fetch any record.

Changing the leaf to ``('res_id', '=', 0)`` fixes the issue, making such
Exchange Records visible again for internal users.
"""
# Add the test user to the internal users group
self.user.write({"groups_id": [(4, self.env.ref("base.group_user").id)]})

# Create Exchange Records with no model (condition ``('model', '!=', False)``
# will fail) and False-ish record ID (to test condition ``('res_id', '=', 0)``):
# such False-ish values are all converted to 0 by ``fields.Many2oneReference``
# methods (and methods of its superclasses) when updating the cache values and
# preparing SQL queries to flush to the DB
exc_recs = self.env["edi.exchange.record"]
type_code = "test_csv_output"
vals = {"model": False}
for res_id in (0, 0.00, False, None, "", self.env["base"]):
exc_recs += self.backend.create_record(type_code, vals | {"res_id": res_id})
self.assertEqual(exc_recs.mapped("res_id"), [0] * len(exc_recs))

# Check that the test user can actually fetch such records
exc_recs_model = self.env["edi.exchange.record"].with_user(self.user)
self.assertEqual(exc_recs_model.search([("id", "in", exc_recs.ids)]), exc_recs)
Loading