Hide Product Cost & Margins from Salespersons for Odoo 19 documentation
A guide to hiding product cost and margins from salespersons: what disappears, who still sees it, how the API is protected, and what the module does not cover.
Documents version 1.0.1Updated Oct 23, 2026
Start here
In plain words: Odoo shows the product Cost and the order Margin to every internal user. That is fine for a manager, but a salesperson who sees that you buy a chair for 55 and sell it for 70 negotiates differently, and may tell a customer. This module takes cost and margin away from the people you choose, everywhere: in the screens, in the reports, and in the API.
| Salesperson | Sales manager, accountant, administrator | |
|---|---|---|
| Product form and lists | No Cost | Cost shown |
| Order lines | No Cost, Margin, Margin % columns | Optional columns available |
| Order totals | No margin line | Margin and percentage |
| Sales and invoice analysis | No Margin measure | Margin available |
| JSON-RPC / XML-RPC / exports | Access denied | Allowed |
Tip: Salespersons keep working exactly as before: they quote, confirm, deliver and invoice. Odoo still computes the margin in the background for the people who may see it.
What is hidden
| Model | Field | Where you see it normally |
|---|---|---|
| Product / Product template | Cost (standard_price) | Product form, product list, variants list |
| Sales order line | Cost (purchase_price), Margin, Margin % | Order lines (form and list), pivot and graph |
| Sales order | Margin, Margin % | Totals of the order, orders list, pivot and graph |
| Sales analysis report | Margin | Sales → Reporting → Sales |
| Invoice analysis report | Margin, Inventory value | Invoicing → Reporting → Invoices |
In plain words: These are the fields Odoo itself uses to show or compute cost and margin. The module does not hide anything else: prices, discounts, taxes and totals stay visible.
Requirements
| Item | Details |
|---|---|
| Odoo | 19.0 (Community or Enterprise) |
| Apps needed | Sales with the Margins in Sales Orders module (sale_margin), Invoicing and Inventory. They are installed for you. |
| License | OPL-1 (Odoo Proprietary License v1.0) |
Install
- Unzip the package. Inside is
taqnix_hide_cost_margin.zip; unzip it to get the foldertaqnix_hide_cost_margin. - Copy the folder into one of the
addons_pathfolders of your Odoo server and restart Odoo. - Log in as an administrator, activate Developer mode, open Apps and press Update Apps List.
- Remove the “Apps” filter, search Hide Product Cost and press Install.
# or from the command line ./odoo-bin -c odoo.conf -d YOUR_DATABASE -i taqnix_hide_cost_margin --stop-after-init
Important: Installing the module hides cost and margin from everybody who is not in the group below. Check chapter 5 before you install on a live system, so nobody who needs cost loses it.
Who still sees cost and margin
In plain words: One group decides: See Product Cost & Margins. It is given automatically, through the roles Odoo already has, to the people who normally work with costs.
| Role in Odoo | Sees cost and margin? |
|---|---|
| Sales → Administrator (sales manager) | Yes |
| Accounting → Accountant and Adviser | Yes |
| Inventory → Administrator | Yes |
| Purchase → User and Administrator | Yes |
| Settings → Administrator | Yes |
| Sales → User: Own Documents Only | No |
| Sales → User: All Documents | No |
| Accounting → Billing only | No |
- Open Settings → Users & Companies → Users and open the user.
- To give cost visibility, add the group See Product Cost & Margins in the user's access rights, or give the user one of the roles above.
- To take it away, remove the role that grants it. Whoever has no such role simply stops seeing the figures.
Tip: Because the group comes from roles, nobody has to be edited one by one: existing managers and accountants keep seeing everything the moment you install, salespersons lose it.
On the product
In plain words: The product form is the first place people look. The same product, seen by a salesperson and by a manager:
In plain words: The product list and the variants list lose their Cost column too.
On sales orders
In plain words: On an order the module removes the Cost, Margin and Margin % columns, the margin line under the totals and the optional-column choices.
In plain words: Salespersons can still change quantities, prices and discounts. If a price is changed, the margin is updated in the background; only people in the group can see it.
In the reports
In plain words: Reports are where margin usually leaks. The module removes the Margin measure from the sales analysis, and the Margin and Inventory value measures from the invoice analysis, for people outside the group.
In plain words: The same applies to filters, grouping and exports: a field that cannot be read cannot be put in a filter, a group-by or an Excel export either.
Not only the screen: the API
In plain words: Hiding a field in a view is not enough. Odoo has an open API, and a curious employee with a few lines of Python can ask the server directly for the cost of every product. This module works on the model itself, so the server refuses.
import xmlrpc.client
common = xmlrpc.client.ServerProxy('https://erp.example.com/xmlrpc/2/common')
uid = common.authenticate('db', 'sally', 'her-password', {})
m = xmlrpc.client.ServerProxy('https://erp.example.com/xmlrpc/2/object')
m.execute_kw('db', uid, 'her-password', 'product.template', 'read', [[3], ['name']])
# [{'id': 3, 'name': 'Virtual Interior Design'}]
m.execute_kw('db', uid, 'her-password', 'product.template', 'read', [[3], ['standard_price']])
# xmlrpc.client.Fault: AccessError: You do not have enough rights to access the field "standard_price"| Call by a salesperson | Result |
|---|---|
read with the hidden field | Access error |
read without a field list | Works, but the hidden fields are not in the answer |
search / search_read with a domain on a hidden field | Access error (no guessing the cost by filtering) |
read_group on a hidden field | Access error |
write of the cost | Access error |
fields_get | Hidden fields are not announced |
What it does not hide
In plain words: Be clear about the limits so there are no surprises.
| Not covered | What to do |
|---|---|
| Vendor prices on the product's Purchase tab, purchase orders | These need the Purchase app. Do not give it to salespersons. |
| Stock valuation, inventory value reports | These need Inventory rights. Do not give them to salespersons. |
| Manufacturing cost (bills of materials, work centres) | Needs Manufacturing rights. |
| Point of Sale margin reports | Point of Sale has its own reports. Keep them to managers. |
| Custom modules that read the cost for a salesperson | They will get an access error. See chapter 12 for the fix. |
| The selling price and the discounts | These are not secrets: salespersons need them to sell. |
Important: If a salesperson also has Purchase, Inventory or Point of Sale manager rights, those apps show costs through their own screens. Review the roles of your sales team.
Try it yourself
- Create a test user with only Sales → User: All Documents (plus Invoicing if they should invoice).
- Open a private browser window and log in as that user.
- Open a product, an order and Sales → Reporting. There should be no Cost, no Margin.
- Create a quotation, confirm it and create an invoice. Everything works as before.
- Log in as a manager and check the margin of that order: it is there and correct.
In plain words: The module comes with automated tests that do exactly this, including the API calls shown in chapter 9.
For developers
In plain words: Skip this chapter if you only use the module.
| Item | Details |
|---|---|
| Group | taqnix_hide_cost_margin.group_see_cost |
| How fields are protected | The fields are re-declared with groups. Odoo then refuses to read, search, group, write and export them for others, and removes them from every view. |
| Your own code | Read protected fields with .sudo() when your code must use them for any user. |
| Order lines | _add_precomputed_values runs as superuser so the cost can be precomputed when a salesperson creates a line. |
# protect another field the same way
from odoo import fields, models
class ProductTemplate(models.Model):
_inherit = 'product.template'
my_secret_price = fields.Float(groups='taqnix_hide_cost_margin.group_see_cost')
# your own code that needs the cost for any user
cost = line.product_id.sudo().standard_priceTroubleshooting
| Problem | What to do |
|---|---|
| A salesperson still sees the cost | They have a role that grants the group (for example Sales Administrator or Purchase User). Check the user's roles and remove the one that is too much. |
| A manager no longer sees the margin | The manager is missing the group. Give the user the Sales Administrator role or add the group directly. |
| A custom report or module fails with an access error for salespersons | It reads the cost as that user. Make it use .sudo() for the cost, or give the user the group. |
| The Cost column is still in my list after installing | Reload the page with Ctrl+Shift+R. |
| Margins are missing on old orders | Nothing was lost: they are stored. Only users in the group can read them. |
Updating and removing
Replace the folder with the new version, restart Odoo and run -u taqnix_hide_cost_margin. To remove it, uninstall it from Apps: cost and margin become visible to all internal users again, as in standard Odoo. No data is changed or lost.
Support
Installation help and bug fixes are included for 6 months, with lifetime updates. Contact us through the marketplace page where you bought the module or write to support@taqnix.com with your Odoo version and a screenshot.