Skip to content

[ADD] sale_timesheet_costs_revenues: costs and revenues pivot report#936

Open
innovara wants to merge 1 commit into
OCA:18.0from
innovara:18.0-add-sale_timesheet_costs_revenues
Open

[ADD] sale_timesheet_costs_revenues: costs and revenues pivot report#936
innovara wants to merge 1 commit into
OCA:18.0from
innovara:18.0-add-sale_timesheet_costs_revenues

Conversation

@innovara

Copy link
Copy Markdown
Contributor

Description

A pivot report under Project > Reporting of billed and unbilled timesheet value for time-and-material projects, alongside the cost of the time logged.

Per project and period it shows the hours logged, their cost, and the billable value of that time split into Untaxed Amount to Invoice and Untaxed Amount Invoiced. The timesheet date drives the period grouping, and the usual
dimensions (project, customer, analytic account, product, sale order, sale order line, project manager/company/currency, and sales order confirmation date) are available as pivot rows/columns.

It is inspired by the Project Costs and Revenues report that was available under Project > Reporting in Odoo 14.0 and earlier, and removed in later versions.

How it works

Data is exposed through a SQL view over the timesheet (analytic) lines, enriched with the linked sale order line, so figures update live as time is logged and invoiced. Hours and cost come straight from the analytic line. The billable value is the timesheet duration — converted into the sale order line's unit of measure — times its unit price, less the line discount; it counts as to invoice while the timesheet is uninvoiced and as invoiced once it is linked to an invoice.

Notes for reviewers

  • This is a time-and-material report: revenue is only counted for sale order lines whose delivered quantity comes from timesheets
    (qty_delivered_method in ('timesheet', 'manual')). Fixed-price and milestone lines still contribute cost and hours, but no revenue.
  • The billable value is derived (duration × price), not read back from the posted invoice line, so it can differ if a price changed or an invoice was edited after the fact.
  • A single currency is assumed; the cost amount and the sale price are treated as the same currency.
  • The analytic-account column on account.analytic.line is referenced defensively: init() checks the column exists before building the view, so the report degrades gracefully rather than failing if an install has reworked analytic plans.

Tested on

  • 18.0

@OCA-git-bot OCA-git-bot added series:18.0 mod:sale_timesheet_costs_revenues Module sale_timesheet_costs_revenues labels Jun 10, 2026
@innovara innovara force-pushed the 18.0-add-sale_timesheet_costs_revenues branch 2 times, most recently from fe8c7e2 to a507ca3 Compare June 10, 2026 13:21
Add a read-only pivot under Project > Reporting that shows, per project
and period, the hours logged on time-and-material work, their cost, and
the billable value of that time split into untaxed amount to invoice and
untaxed amount invoiced.

Data is exposed through a SQL view over the timesheet (analytic) lines,
enriched with the linked sale order line. The billable value is the
timesheet duration, converted into the sale order line's unit of measure,
times its price less discount; it counts as to invoice until the
timesheet is linked to an invoice, then as invoiced, so the figures
update live as time is logged and billed.

Inspired by the "Project Costs and Revenues" report available under
Project > Reporting in Odoo 14.0 and earlier.

Signed-off-by: Manuel Fombuena <mfombuena@innovara.tech>
@innovara innovara force-pushed the 18.0-add-sale_timesheet_costs_revenues branch from a507ca3 to f881740 Compare June 10, 2026 13:49
@innovara innovara marked this pull request as ready for review June 10, 2026 13:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:sale_timesheet_costs_revenues Module sale_timesheet_costs_revenues series:18.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants