Skip to content

fix(spp_user_roles): prevent validation error when assigning groups to a new role#177

Open
anthonymarkQA wants to merge 1 commit into19.0from
fix/user-role-assignment-issue
Open

fix(spp_user_roles): prevent validation error when assigning groups to a new role#177
anthonymarkQA wants to merge 1 commit into19.0from
fix/user-role-assignment-issue

Conversation

@anthonymarkQA
Copy link
Copy Markdown
Contributor

Clicking "Add a line" in the Groups tab triggered inline creation of a
new res.groups record. Since res.groups.name is required and left blank,
Odoo threw a validation error and blocked the save entirely.

Two changes:

  • role.xml: replace implied_ids field with an inner list using create="0"
    so "Add a line" opens a search dialog to select existing groups instead
    of creating an inline row
  • role.py: override create() to extract implied_ids from vals and write it
    directly to group_id after creation, mirroring the existing write()
    workaround in base_user_role for the same Odoo _inherits cache-clearing bug

Why is this change needed?

Users unable to create a role and assign a group in one save. previously users must create an empty role first then save, then add a group into it. which is inneficient

How was the change implemented?

How was the change implemented?

1. spp_user_roles/views/role.xml
Replaced the implied_ids field override with one that includes an explicit
inner <list create="0">. Setting create="0" on the inner list tells Odoo
to replace the "Add a line" inline row with an "Add" button that opens a
search/select dialog. This ensures only existing res.groups records can be
linked to a role — no blank inline records are ever created.

2. spp_user_roles/models/role.py
Added a create() override that mirrors the existing write() workaround
already present in base_user_role. The res.users.role model uses Odoo's
_inherits delegation to res.groups, which means fields like implied_ids
belong to the parent res.groups record. On create, passing implied_ids
through the _inherits mechanism triggers an Odoo cache-clearing bug
(documented in the upstream write() override) that causes the value to be
dropped. The fix extracts implied_ids from vals before calling
super().create(), lets the role and its associated group_id be created
first, then writes implied_ids directly to group_id — bypassing the bug.

New unit tests

Unit tests executed by the author

How to test manually

Related links

https://projects.acn.fr/projects/acn-eng/work_packages/979/activity

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements a workaround for an Odoo cache-clearing bug by overriding the create method in the ResUsersRoleCustomSPP model and updates the implied_ids field display in the XML view. Feedback includes a recommendation to narrow the scope of the create override to specifically target implied_ids to prevent interference with standard mechanisms, and a correction for a likely invalid field name (full_name) in the view definition.

domain="[('role_id', '=', False)]"
>
<list create="0">
<field name="full_name" string="Group" />
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The field full_name does not exist in the standard Odoo res.groups model. Unless it is added by a custom module not shown in this context, this will cause a traceback when loading the view. You should likely use name or display_name instead.

Suggested change
<field name="full_name" string="Group" />
<field name="name" string="Group" />

Comment on lines +21 to +34
groups_vals_list = []
group_fields = set(self.env["res.groups"]._fields) - {"name"}
for vals in vals_list:
group_vals = {}
for field in group_fields:
if field in vals:
group_vals[field] = vals.pop(field)
groups_vals_list.append(group_vals)

new_records = super().create(vals_list)

for record, group_vals in zip(new_records, groups_vals_list):
if group_vals:
record.group_id.write(group_vals)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation of the create override is broader than necessary. By popping all fields belonging to res.groups (except name), you risk interfering with the standard Odoo _inherits mechanism for fields that don't suffer from the cache-clearing bug. It also makes the creation fragile if other modules add required fields to res.groups. It is recommended to target only the problematic fields, specifically implied_ids, as mentioned in the PR description and mirroring the write workaround in base_user_role.

Suggested change
groups_vals_list = []
group_fields = set(self.env["res.groups"]._fields) - {"name"}
for vals in vals_list:
group_vals = {}
for field in group_fields:
if field in vals:
group_vals[field] = vals.pop(field)
groups_vals_list.append(group_vals)
new_records = super().create(vals_list)
for record, group_vals in zip(new_records, groups_vals_list):
if group_vals:
record.group_id.write(group_vals)
implied_ids_list = [vals.pop("implied_ids", None) for vals in vals_list]
new_records = super().create(vals_list)
for record, implied_ids in zip(new_records, implied_ids_list):
if implied_ids:
record.group_id.write({"implied_ids": implied_ids})

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 71.48%. Comparing base (98a45a9) to head (6217a00).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             19.0     #177   +/-   ##
=======================================
  Coverage   71.48%   71.48%           
=======================================
  Files         932      932           
  Lines       54840    54840           
=======================================
  Hits        39201    39201           
  Misses      15639    15639           
Flag Coverage Δ
spp_analytics 93.13% <ø> (ø)
spp_api_v2 80.10% <ø> (ø)
spp_api_v2_change_request 66.85% <ø> (ø)
spp_api_v2_cycles 71.12% <ø> (ø)
spp_api_v2_data 64.41% <ø> (ø)
spp_api_v2_entitlements 70.19% <ø> (ø)
spp_api_v2_gis 71.52% <ø> (ø)
spp_api_v2_products 66.27% <ø> (ø)
spp_api_v2_service_points 70.94% <ø> (ø)
spp_api_v2_simulation 71.12% <ø> (ø)
spp_api_v2_vocabulary 57.26% <ø> (ø)
spp_approval 50.29% <ø> (ø)
spp_area 80.07% <ø> (ø)
spp_area_hdx 81.43% <ø> (ø)
spp_audit 72.60% <ø> (ø)
spp_base_common 90.26% <ø> (ø)
spp_case_cel 89.01% <ø> (ø)
spp_case_demo 94.34% <ø> (ø)
spp_programs 64.51% <ø> (ø)
spp_security 66.66% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant