Skip to content

[19.0][ADD] multi_company_field_visible (+ partner/product bridges)#1018

Draft
mikecolangelo wants to merge 6 commits into
OCA:19.0from
CanariasConectada:19.0-add-multi_company_field_visible
Draft

[19.0][ADD] multi_company_field_visible (+ partner/product bridges)#1018
mikecolangelo wants to merge 6 commits into
OCA:19.0from
CanariasConectada:19.0-add-multi_company_field_visible

Conversation

@mikecolangelo

Copy link
Copy Markdown

What

Adds a small module stack that lets users without the multi-company group see and
manage the company membership of their own records, without ever exposing the other
companies a shared/global record may belong to.

  • multi_company_field_visible (base): adds an Own Company proxy field on every model
    based on multi.company.abstract.
  • partner_multi_company_field_visible / product_multi_company_field_visible:
    auto_install bridges that expose the field on the contact / product form, each with a
    per-model toggle in Settings > Companies.

Why

partner_multi_company / product_multi_company add company_ids but gate it behind
groups="base.group_multi_company", so a single-company merchant can't see or set the
company of their own records. Removing the group would leak information: company_ids can
contain other companies (shared/global records). No OCA module currently filters which
companies are shown, so this builds it.

How

  • The proxy field is computed as company_ids ∩ self.env.user.company_ids — the real
    company_ids never reaches the client, so other companies can't be enumerated.
  • The inverse does a safe merge: companies the user can't see are preserved, only the
    user's own companies are accepted, and the field is never left blank (falls back to
    env.company). It fails closed against escalation.
  • Admins / multi-company users keep the existing company_ids field untouched (including
    the empty = "all companies" / global semantics).

Security-first: record rules are not touched — the real isolation is still enforced by the
existing OCA rules. Only the UI and a safe inverse change.

Note on dependencies

This stack depends on partner_multi_company / product_multi_company, whose 19.0 ports
are still in flight (e.g. #1014). Opening as draft until those land on 19.0. Feedback on
naming and approach is very welcome in the meantime.

@OCA/multi-company-maintainers

@OCA-git-bot OCA-git-bot added series:19.0 mod:product_multi_company_field_visible Module product_multi_company_field_visible mod:partner_multi_company_field_visible Module partner_multi_company_field_visible mod:multi_company_field_visible Module multi_company_field_visible labels Jun 24, 2026
mikecolangelo and others added 3 commits June 24, 2026 10:49
Expose an Own Company proxy field on models based on multi.company.abstract
so users without the multi-company group can see and manage only their own
company, never other companies of a shared/global record. Editable with a
safe merge that preserves hidden companies, never left blank, and fails
closed against escalation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auto-installed bridge exposing the Own Company field on the contact form
when partner_multi_company is present, with a per-model toggle in Settings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auto-installed bridge exposing the Own Company field on the product form
when product_multi_company is present, with a per-model toggle in Settings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mikecolangelo mikecolangelo force-pushed the 19.0-add-multi_company_field_visible branch from 3bb586e to 4e0bd16 Compare June 24, 2026 10:49
mikecolangelo added a commit to CanariasConectada/multi-company that referenced this pull request Jul 1, 2026
…(README.rst, pyproject.toml, static/description)

Bring in the pre-commit-generated boilerplate from the sibling incubation
branch 19.0-add-multi_company_field_visible (base of upstream OCA PR OCA#1018),
which had it but this branch's copy (taken from /tmp) did not.
…write, not via constrains

@api.constrains reads company_ids while it is still protected mid-write
(it feeds the computed company_id), seeing the pre-write value -- so a
non-admin could clear it via a direct write() bypassing the safe
own_company_ids proxy and it silently passed. Move the check to run
after write()/create() return, once the field is consistent again.
…any selection

own_company_ids' compute intersects the record's companies with
self.env.user.company_ids (every company the user belongs to), not
self.env.companies (only the ones currently active in the company
switcher). Assigning a Many2many field -- even just to fill a compute's
cache -- goes through the same write path as a real edit, checking
'read' access on any newly-referenced res.company; that rule scopes by
the ACTIVE selection, so a company the user owns but didn't select
fails the check and crashes the whole read.

Fix: skip the proxy field's compute entirely when it isn't needed
(multi-company users never see it -- show_own_company_field is already
False for them). New regression test reproduces the scenario (2
companies, 1 active) and confirms it no longer crashes.
…ny is created

res.company.create() creates the company's own contact through a nested
res.partner.create() call, marked with the context key
default_parent_id=False. As part of that nested create, base_multi_company's
company_id inverse fires and briefly writes a blank company_ids on that very
partner (it has nothing to compute company_id from yet: the company doesn't
point partner_id back to it until a moment later). _check_own_company_not_blank
rejected that transient, purely internal state as if it were a real user edit,
so creating any company crashed the instant this module was installed.

Found via an exhaustive cross-module health check installing and testing the
whole multi-company stack together from scratch, something no single module's
own test suite exercises on its own.

Skip the check specifically for that context marker; a genuine attempt to
blank out company_ids by a real user is still rejected (verified with a
regression test and manually against a non-admin user).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:multi_company_field_visible Module multi_company_field_visible mod:partner_multi_company_field_visible Module partner_multi_company_field_visible mod:product_multi_company_field_visible Module product_multi_company_field_visible series:19.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants