Odoo Project Implementation
Tasks, milestones, gantt, kanban.
Manage projects with kanban, gantt, milestones, subtasks, client portals, and analytic accounting integration.
Odoo Project holds work as tasks inside a project, and the project is an analytic container. Hours logged against it, vendor bills coded to it and invoices raised from it all land on the same analytic account, which is why a project reports a margin without anybody writing a report. That single design decision explains most of what the app does well, and most of what buyers expect it to do and then find missing.
The app itself is Community, and so is almost everything a delivery team touches daily: the board, the subtask, the link that says one task waits on another, the view the customer logs into, and the posting that turns an hour into a cost. What Enterprise buys is a set of views, timesheet validation, and a set of neighbouring apps. A Community project can plan, deliver and bill work. It cannot draw a timeline with dependency lines, and that single view is often the whole reason the licence gets signed.
What decides whether the implementation holds is not the kanban board. It is whether the project structure matches how the business sells and reports, whether cost reaches the analytic account from purchases and subcontractors as well as timesheets, and whether the customer sees in the portal what you intended them to see. Those three decisions are made in the first fortnight and they are expensive to reverse once a year of history sits on top of them.
Who Odoo Project is for
- → Professional services firms, agencies and engineering consultancies that deliver against a quoted scope and need delivered cost measured against it.
- → Contracting, fit-out and installation businesses billing in progress stages, where subcontractor cost, materials and labour have to meet on one record.
- → Internal IT, product and facilities teams running work that never reaches an invoice but still carries a budget somebody defends.
- → Companies already running Odoo Sales or Accounting that can see what was sold and what was spent, but cannot join the two per engagement.
- → Not for planning-heavy programmes run on float, baselines and earned value, none of which Odoo produces, and not for shift rostering, which is Planning.
- → Not for ticket queues with response deadlines, which belong in Helpdesk where the SLA rules live.
Key features
- ✓ Kanban & gantt views
- ✓ Tasks, subtasks, milestones
- ✓ Customer portal access
- ✓ Time & material billing
- ✓ Analytic accounting
- ✓ Burn-down charts
What Odoo Project actually does
Tasks, stages, and a status that is not the stage
Tasks carry an assignee, a deadline, allocated hours, tags, subtasks and a stage per project. Odoo 17 added a separate status on the task, with values such as In Progress, Changes Requested, Approved, Done and Cancelled. Stage is where the card sits on the board. Status is what the work is. Teams that encoded Done as a stage now hold two answers to the same question, and reporting has to pick one.
The project as an analytic container
Each project points at an analytic account. Timesheet lines post labour cost there automatically. Purchase order lines, vendor bills and expenses reach it only through analytic distribution set on the line, in percentages across analytic plans. Revenue arrives from the invoices linked to the same project. The profitability panel reads all of it, which makes it accurate exactly to the degree that the coding discipline behind it is.
Milestones and the billing model
A service product with service tracking creates the project or the task when the order is confirmed, so delivery starts from the sale rather than beside it. Invoicing then follows the product policy: milestones release an invoice when the milestone is reached, timesheet-based billing invoices delivered hours, prepaid sells a block and reports what is left, and down payments take a fixed amount or a percentage up front.
Scheduling, dependencies and the gantt
Task dependencies switch on in project settings, in Community, and a task then records what blocks it and what it blocks. There is exactly one relation type. No lag, no lead, no start to start, so a two week curing period between two activities has to become a task of its own. The other split worth knowing is the date fields. A Community task carries a deadline; the planned start date that a bar gets dragged along comes with the Enterprise module, which is why dependencies are free and the timeline is not.
Properties, for the fields this business needs and Odoo does not ship
A project defines its own set of task properties and every task inside it carries them: text, number, date, checkbox, selection, tags, or a link to another record such as a contact or a product. A fit-out project holds a unit number, a retainer holds the client's PO reference, and neither needs a module written. The constraint is storage. Properties are held as JSON on the task rather than as database columns, so they filter and group well and they are poor ground for pivot analysis. Once two or three of them start driving real reporting, that is the signal to promote those into proper fields.
Portal access and project sharing
Project visibility has three settings: invited internal users, all internal users, or invited portal users. On the last one, sharing the project with a customer contact sends an invitation and gives them a browser view of the task list, either read only or with the right to edit and create tasks. They stay portal users rather than internal ones, so they reach the projects they were invited to and nothing else in the database. Access is granted and withdrawn per project per contact, which is worth auditing whenever a client-side manager moves on.
Reporting on what happened, not just what is open
Tasks pivot by project, assignee, stage, deadline and customer, and project updates give a dated status snapshot with the profitability figures attached. The burndown chart is built from the record of stage changes, so it needs stages used consistently and a real history behind each task. Anything imported straight into a late stage has no history, and the chart quietly starts flat for those records.
How we configure Odoo Project
Decide what one project represents
The analytic account sits on the project, so the project is the smallest unit you can report cost against without going down to task level. One project per client cannot answer profitability per engagement. One project per engagement, with tasks per deliverable, answers both. Long-running retainers usually want a project per year, otherwise the margin figure blends four years of rates into one number nobody trusts.
Design the stage set once
Task stages can be shared across projects or kept per project. Shared stages make cross-project reporting possible and force every team into one vocabulary. Per-project stages fit each team and make the portfolio view meaningless. Pick deliberately, keep the count under about seven, and set the folded stages properly, because a stage that is not folded keeps closed work on the board forever.
Wire cost in from purchases, not only from hours
Timesheets post to the project on their own. Nothing else does. A subcontractor bill, a hired plant item or a materials purchase reaches the project only when analytic distribution is filled in on the line, and asking a buyer to remember that on every line does not survive a busy month. Use the analytic distribution models in Accounting so a partner, a product or a product category carries its own default onto the purchase order and the bill inherits it. Skip this and profitability shows full revenue against labour cost alone, which reads as a spectacular margin and gets quoted in a pricing meeting.
Set portal visibility before the first customer is invited
Decide per project what a customer sees, then check it through an actual portal login rather than as an administrator, because the two views differ and only one of them is the one your client gets. The setting is not neutral later either: moving a project off invited portal users takes the collaborators with it, so a visibility change made for an internal reason ends client access without anybody announcing it. Agree with the delivery team where internal discussion goes. Notes stay inside, messages go out, and that rule has to land before go live rather than after.
Import tasks knowing what does not come with them
Task import needs project, name, stage, assignee, deadline and allocated hours, with stages created first because the import matches them by name. What does not come across is the discussion history, the stage change trail behind the burndown, and attachments unless they are loaded separately. Import one project, have its manager confirm it reads correctly, then load the rest. Closed work is usually better summarised than migrated.
Where Odoo Project projects go wrong
Buying it as a replacement for Microsoft Project
Odoo schedules tasks and shows dependencies. It does not calculate a critical path, store a baseline to measure slippage against, level an over-allocated resource, or produce earned value, in either edition. A planner who works in float and variance will find none of it. Say that at the demo rather than after the deposit, because the buyer who was sold a gantt is measuring the wrong thing on day one and blames the implementation for it.
Profitability built on half the cost
The panel is only as complete as the analytic coding upstream. Missing employee cost rates, purchases with no analytic distribution, subcontractor bills posted to a general expense account and overheads that were never allocated all produce a margin that looks precise and is wrong. Reconcile one finished project line by line against the general ledger before anybody uses the figure in a pricing decision.
The portal showing more than intended
Sharing is granted at project level, and there is no per-task switch inside a shared project. Every task in it is visible to the invited contact, including the one somebody raised to chase an unpaid invoice. The chatter goes the same way: a message about a delay reaches the client the second it is posted, while an internal note does not, and the two boxes sit next to each other. Keep client-facing work in its own project and give the team one rule about which box is safe.
Treating the project as the contract
There is no variation order object in Odoo. A scope change is another sale order line, a new order, or an untracked argument later. Retention has no native field either, so a ten percent holdback becomes a deliberate invoice line and a manual release months afterwards. Percentage of completion revenue recognition is not standard behaviour. Decide how each of these is handled before the first contract is loaded.
Stage sprawl and renamed history
Stages multiply quickly once each team adds its own, and renaming or deleting one rewrites how past work reads. Reporting grouped by stage stops comparing like with like, and the burndown depends on that same history. Freeze the stage set after go live, put changes through whoever owns reporting, and archive stages instead of deleting them so the record behind old tasks survives.
What it works with
- + Timesheets, which post labour hours and cost to the project analytic account as they are entered
- + Sales, where the order line opens the delivery record on confirmation and fixes how that work will be billed
- + Purchase and Invoicing, where analytic distribution on a bill line brings subcontractor and material cost onto the project
- + Expenses, for reimbursable cost that can be re-invoiced to the customer at cost or at sales price
- + Employees, which holds the hourly cost that turns recorded time into a money figure
- + Planning, Helpdesk and Field Service, all Enterprise, for shifts, tickets and site visits that generate project work
- + Documents and Sign, both Enterprise, for drawings, method statements and signed approvals held against the job
- + Accounting, where the same analytic account carries the ledger side of the job and analytic budgets sit above what the profitability panel shows
Odoo Project by country
Saudi Arabia (KSA)
Contracting is the sector that buys this, and a progress invoice raised from a milestone is a standard tax invoice, so it clears through the ZATCA Fatoora platform before it can be handed to the customer. Clearance is per document and each registered issuing unit runs an unbroken counter, so a numbering scheme per site is a registration exercise, not a sequence you add in Odoo. Arabic is mandatory on the invoice itself, which makes the progress billing layout a bilingual template job rather than the English default that gets demonstrated.
United Arab Emirates
Corporate tax at nine percent turned per project cost into a documentation question, particularly for free zone entities testing qualifying income against mainland work. Progress payments on construction contracts also fix the VAT date of supply. On the published timetable, businesses above AED 50 million in revenue appoint an Accredited Service Provider and go live on the e-invoicing system from January 2027, which puts a clearance step between the milestone and the customer.
Qatar
There is no VAT, so a project invoice carries no tax line and the compliance work sits elsewhere. Five percent withholding applies to payments to non-residents, which catches the overseas design consultant and the specialist subcontractor on a build. Contracts above the reporting thresholds are notified through Dhareeba, and the return and the accounts filed with it are prepared in Arabic. E-invoicing has no published format or scope yet, so there is nothing to build against.
India
Services connected to immovable property take their place of supply from the site, so a project executed in another state decides whether the invoice carries IGST or CGST plus SGST, and the site address becomes a data quality problem rather than a note in the file. Above the turnover threshold each progress invoice needs an IRN and a signed QR code, and for the larger turnover bands the portal refuses documents reported more than thirty days after their date, which rules out catching up a quarter of billing in one evening.
Pakistan
Project services are taxed by the province where they are rendered, through the Punjab or Sindh revenue authority rather than federal sales tax, so one firm bills two projects at two different rates. FBR digital invoicing returns its number before the invoice is issued, which turns a month end batch of progress invoices into a queue of API calls that has to be watched.
Turkey
Construction runs on hakedis progress payments, and the channel depends on the counterparty: e-Fatura where the client is registered in the system, e-Arsiv where it is not. Both leave as signed UBL-TR through a private integrator rather than as a PDF from the project. Archiving outside Turkiye is not permitted, which constrains where the database and its task attachments are hosted.
United Kingdom
There is no B2B e-invoicing mandate, but public sector buyers must already be able to receive EN 16931 invoices over Peppol, so a project billed to an NHS trust needs that route rather than email. Making Tax Digital expects digital links from the invoice through to the VAT return. Construction Industry Scheme deductions on subcontractor payments are not calculated by standard Odoo.
Germany
Every German business has had to be able to receive structured e-invoices since January 2025, and an invoice to a federal contracting authority needs XRechnung with the Leitweg-ID carried as the buyer reference. Construction services between builders fall under the reverse charge in section 13b UStG, so tax on a subcontractor bill sits with the recipient. GoBD expects records that cannot be quietly altered.
Odoo Project FAQs
Do we need Enterprise to run Project properly?
Only for the views, timesheet validation and the neighbouring apps. Tasks, subtasks, stages, dependencies, recurring tasks, properties, project sharing and analytic posting are Community. The gantt, map and cohort views and the timesheet grid are Enterprise, as are Planning, Helpdesk, Field Service, Documents and Sign. The pricing detail matters more than the list: Enterprise is licensed per user for the whole database rather than per app, so if those people are already licensed for Sales or Accounting, switching Project on adds nothing to the bill.
Can one project hold fixed price and time and materials work at once?
Yes, because the billing policy lives on the service product and not on the project. A single order can carry a milestone billed line for the fixed scope and a timesheet billed line for the variable part, both delivering into the same project. The profitability panel reports them separately, so the fixed portion does not disguise an overrun on the hourly portion. It does mean product setup is the real configuration work, not project setup.
Does Odoo calculate a critical path or hold a baseline?
No, in either edition. Where a contract demands that discipline the schedule stays in the planning tool and Odoo carries execution, cost and billing. Make the join explicit rather than cultural: carry the planning tool's activity code on the Odoo task, decide that dates flow in one direction only, and name the person who updates the other system. Two tools both believing they own the finish date is the usual failure.
If we raise an employee's cost rate, does the project margin change?
No. The cost that values a timesheet line is taken from the employee when the line is created and stays on it. Time already recorded is not restated, which is correct, and it means a project running across a pay review holds two rates inside one margin figure. If a client engagement needs one blended rate for its whole life, solve that in reporting. Editing historic lines to force it will not reconcile to the ledger afterwards.
Can timesheets be approved before they turn into an invoice?
On Enterprise, yes. The validation step, the lock it puts on a validated line and the reminder emails come with the timesheet grid, which is Enterprise. Run validation before the billing run rather than after, because an invoice raised from delivered hours takes whatever is sitting there at that moment. Community has the access groups, so a user sees only their own lines while an approver sees everyone's, but nothing freezes a line once it is entered. The workable substitute is to treat invoicing as the cut-off and reconcile the period before it goes out.
Can a customer see our costs in the portal?
No, and there is no setting that would expose them. Timesheet values, vendor bills, employee cost rates and the profitability panel are internal records a portal user has no access rule for. The exposure runs the other way. That same contact also sees their own quotations and invoices in the portal, so a re-invoiced expense appears at whatever the re-invoicing policy set, described exactly as somebody typed it on the vendor bill. The thing to review is the wording on billable lines, not the portal permissions.
How much project history should we migrate?
Open work, anything still to be invoiced, and enough closed work to compare against. The part teams forget is the money rather than the tasks: a job half delivered before go live needs its cost to date posted to the analytic account, or its first month in Odoo shows revenue against almost no cost and reads as pure profit. Agree that opening position with whoever signs off the margin before the first invoice goes out.
Can one project span two companies?
A project belongs to one company. Cost booked in another company's ledger reaches it only if it posts to the same analytic account, which is possible because an analytic account can be left without a company of its own. Currency is the other trap: cost lands in each company's currency while the project reports in its own, so the conversion basis has to be agreed before anyone quotes a margin from it.