B2B Profitability
What you bought, what you sold, and the margin the period left
It compares invoiced sales against confirmed purchases over a date range and shows the margin with its percentage, broken down month by month, week by week and year against year. One button generates it, and it stays as a dated snapshot of that period.
How you get it
Every development works in all three Odoo environments. The only thing that changes is how we deliver it.
Odoo Online (SaaS)
You do not need the ability to install modules. A Millora consultant comes in with temporary access that you authorize and implements it with Odoo Studio. When they are done, you revoke the access.
Odoo.sh or your own server
You receive the module and the installation guide by email as soon as payment clears. Install it yourself, or we install it with you.
Installation · shell
# 1 · copia el módulo a tu addons_path
cp -r millora_rentabilidad_b2b /mnt/extra-addons/
# 2 · reinicia y actualiza la lista de apps
odoo-bin -u all -d tu_base --stop-after-init
# 3 · instala desde Apps
# busca "B2B Profitability"What it solves
The problem
"How much did we make last month?" should take a minute to answer and almost never does. Somebody exports the customer invoices, somebody else exports the purchase orders, they get pasted into a spreadsheet, subtracted, and the percentage comes out. Next month it happens again, and because a different person builds it each time with slightly different criteria, two reports on the same quarter never quite compare.
And when somebody asks whether the margin is improving or getting worse, the honest answer is usually that nobody knows: the previous calculation was never kept.
How it works
You enter a date range and press Generate report. The development reads two things and nothing else:
- Sales — posted customer invoices, by invoice date, excluding tax.
- Purchases — confirmed purchase orders, by order date, excluding tax.
From that it builds three cards at the top — total purchases, total sales, and margin with its percentage — and below them three collapsible breakdowns: month by month, week by week and year against year. Every row carries its purchases, its sales, its margin and its percentage.
The percentage is colour-coded: green from 15% up, amber between 5 and 15, red below. Those are the thresholds it ships with; if your business runs on different margins, they get adjusted.
The report is stored on the record and does not recalculate on its own. That is deliberate: each record is a dated snapshot of the period you queried, so you can keep several and set them side by side later.
Built entirely with Studio
There is no module to install. The model, its fields, the view and the button are created with Odoo Studio, and the calculation lives in a server action. That is why it is implemented the same way on Odoo Online, on Odoo.sh and on-premise, with no server access and without touching base code.
What it does not do
Precision matters here, because how you read the number depends on it.
It is not cost of goods sold. It compares a period's purchases against that same period's sales, not against the cost of the goods actually sold. If you buy heavily one month to stock the next, that month will look bad and the next one excellent, and neither is your real margin. Read month by month it is a behaviour signal; read across a year it evens out. The annual breakdown is there for exactly that reason.
It does not go down to product or customer. These are period totals. Knowing which product or channel earns most takes a different tool.
It does not subtract credit notes. It takes customer invoices only, so a return does not reduce the period's sales.
It does not include costs that skip a purchase order. Payroll, rent, freight paid directly: none of it counts. This is not a profit and loss statement and does not pretend to be one.
It measures committed purchasing, not invoiced. It counts confirmed purchase orders — what you have already committed to pay — not what the supplier has already invoiced you.
What changes
The margin question stops being assembled by hand every time. And because each query is stored with its range and its calculation, you can finally set one quarter beside another and read the trend on the same basis — which is precisely what the spreadsheet never allowed, because each time it was built slightly differently.
What's included
- Compares invoiced sales against confirmed purchases over the date range you choose
- Shows total purchases, total sales and margin with its percentage in three cards
- Breaks the period down month by month, week by week and year against year, in collapsible sections
- Colour-codes every percentage against the margin thresholds you define
- Stores the report on the record: each query stays as a dated snapshot
- Generates from one button, with nothing exported to a spreadsheet
- Works on tax-excluded amounts, so VAT does not distort the margin
- Implemented with Studio, so there is no module to install
Requirements
- The Invoicing or Accounting module active, with customer invoices posted
- The Purchase module active, with purchase orders confirmed
- Purchases and sales in the period in the same currency: amounts are summed without conversion
You might also need
Payment Allocator
You decide how much goes to each invoice, not the order of the list
Accounting & tax
AutoAzur Global Invoice Reconciler
One global invoice, hundreds of orders, one run
Accounting & tax
Aspel NOI payroll import
The payroll you already filed lands in Odoo as a journal entry
Accounting & tax

