B2B Customer Portal in Odoo: When You Need Custom Controllers

Understand how a B2B portal can expose approved quotes and order history in Odoo and when custom models, controllers and access rules are needed.
Short answer: Odoo’s standard customer portal already shows a signed-in customer their own quotations, orders, and invoices. A B2B portal project needs custom controllers when the business wants to change what “their own” means — buyer hierarchies, approval steps, negotiated catalogues — or to expose data the standard portal never shows. The dividing line is not features, it is access logic: the moment a buyer must see some records and provably not others beyond the standard partner rule, you are in custom territory, and the access rules need a developer’s audit, not optimism.The scenario below is an illustrative walkthrough. It describes a composite industrial supplier; every detail is fictional and meant to show the shape of the scoping exercise, not to describe any real company or deployment.

What does the standard Odoo portal already give a B2B customer?

More than most teams realise before they scope a build. Out of the box, a portal user linked to a customer can sign in and see that customer’s quotations, sales orders, invoices, and delivery information, download documents, and communicate through the portal. For a straightforward B2B relationship — one customer account, a handful of buyers, standard pricing — that is frequently enough, and the honest scoping answer is “turn it on and configure it.”

Our illustrative supplier sells industrial components to a few hundred trade accounts. Their portal ambitions sound simple: buyers should see approved quotes and order history, check what is outstanding, and stop phoning the sales office for copies of documents. The standard portal covers the document part on day one. The scoping work is in the two words “approved” and “buyers” — because their accounts are not simple.

Where does the standard portal stop being enough?

Three requirements push this supplier past configuration, and they are the three that push most B2B portal projects into custom development:

  • Buyer hierarchy. A trade account has a head-office buyer who may see all branches’ orders, branch buyers who may see only their branch, and a finance contact who sees invoices but not pricing discussions. The standard portal’s rule — a portal user sees their partner’s records — has no concept of branch-level subsets within one customer.
  • Approval before visibility. Internally, sales reps draft quotations that go through margin review. The customer must only ever see a quotation after it is approved; a draft that leaks into the portal is a pricing incident. The standard portal keys visibility off the quotation’s state in ways that do not map neatly onto this supplier’s internal review states.
  • Negotiated catalogue. Each account has contract pricing and, for some, a restricted product range. The portal ordering experience has to show the account’s products at the account’s prices — and must not accidentally surface another account’s contract range through search or direct links.

Each of these is an access-logic requirement. That is the signal: when the scoping conversation keeps returning to who may see what, the project is a security-sensitive custom module, and it should be planned like one.

Architecture: what a custom portal module actually contains

A custom B2B portal module in Odoo typically has four layers, and it is worth naming them because each carries a different kind of risk:

  • Models. Usually extensions rather than new tables: fields on the partner or a small link model expressing the buyer hierarchy (which portal users belong to which branch of which account), plus flags that mark a quotation as portal-approved.
  • Controllers. The HTTP routes behind the portal pages. Custom controllers replace or extend the standard ones wherever the visibility logic differs — the buyer’s order list, the quotation detail page, the catalogue view. Every controller is a door; each one must check who is knocking.
  • Access rules. Access control lists (which models a portal user may read at all) and record rules (which rows within those models). This layer is the real security boundary — the controller decides what to render, but the record rules are what stop a manipulated URL from returning another branch’s order.
  • Templates. The QWeb views. Lowest risk, highest visibility — and the layer teams over-invest in while under-investing in the two above it.

The scoping mistake to avoid is budgeting this as a “website project.” It is an access-control project with a website attached.

The audit a developer must run before go-live

Because the portal’s promise is “a buyer sees only their own company’s data,” the pre-launch audit is not optional polish. A developer should be able to produce evidence for each of these:

  • ACL review: every model the portal touches has an explicit access entry for the portal group — no model is reachable by accident, and nothing internal (costs, margins, internal notes) is readable by portal users.
  • Record-rule tests: scripted checks with two buyer accounts from different branches of the same customer, and two from different customers, attempting to read each other’s quotations and orders by direct URL and by search — all must fail.
  • Cross-company isolation: if the database runs multiple companies, portal users of company A must get nothing from company B, including via attachments and document downloads.
  • State leakage: quotations in every internal state (draft, under review, rejected) are requested through the portal to confirm only approved states render.
  • Attachment sweep: files attached to visible records are checked — a record can be correctly hidden while its attachment stays downloadable if attachment rules were not scoped with the same care.

Threat checklist for scoping conversations

Use this checklist in the scoping workshop. Any row the team cannot answer is a design task, not a detail to leave for later:

Threat Question to answer Where it is handled
Buyer opens another branch’s order by guessing its URL Do record rules scope portal reads to the buyer’s branch? Record rules + controller checks
Unapproved quotation becomes visible Which states are portal-visible, and who can set them? Model flag + workflow design
Contract pricing leaks via search results Does catalogue search filter by the account’s agreed range? Controller + catalogue rules
Attachment from a hidden record downloads directly Are attachment access rules aligned with record rules? ACL / ir.attachment rules
Deactivated buyer keeps access after leaving the customer What is the offboarding step, and who owns it? Process + user administration
Multi-company data crosses over Are portal rules company-scoped and tested? Record rules with company conditions

Standard portal vs custom module: a feature comparison

Capability Standard portal Custom portal module
Customer sees own quotes, orders, invoices Yes, out of the box Yes
Document downloads and portal messaging Yes Yes
Branch-level visibility within one account No Yes, with hierarchy modelling
Visibility gated on internal approval states Limited Yes, designed per workflow
Account-specific catalogue and contract range Pricelists only Yes, with filtered search
Buyer roles (purchasing vs finance views) Single portal view Yes, role-based controllers
Security audit surface Odoo’s tested defaults Your team’s responsibility

That last row is the honest trade-off. The standard portal inherits years of hardening. A custom module gives you the access logic your B2B relationships actually need — at the price of owning the audit yourself.

Frequently asked questions

Can we start standard and customise later?
Yes, and it is often the right sequence: launch the standard portal for document access, watch what customers actually ask for, and scope the custom module against real demand. The one caution: do not promise branch-level visibility dates until the access design exists.

Does a custom portal need its own user licences?
Portal users are external users in Odoo’s model and are generally treated differently from internal users, but licensing terms vary by edition and contract. Confirm the position for your edition during scoping rather than assuming.

How do we handle a buyer who works for two of our customers?
As two separate portal identities or one identity with carefully designed rules — a real scoping decision, because the record rules must keep both relationships’ data separated while the human experiences one login. Raise it early; it is much harder to retrofit.

What is the single most common portal security mistake?
Hiding a link in the interface and calling it security. If the record rule allows the read, the record is accessible — the missing menu item only hides it from honest users.

Next step

Scope the access logic before the screens: the buyer hierarchy, the approval states, and the audit evidence you will demand at go-live. Scope a GitHub-ready B2B portal module with Module Builder — where the controllers, models, and access rules are generated as reviewable code your team can test, rather than as promises in a slide deck.