Way4Tech
๐Ÿฉบ

Odoo for Clinic Management

Appointments, prescriptions, billing for clinics.

Single or multi-branch clinic management: appointments, prescriptions, billing, SMS reminders, and patient portal.

Odoo ships no patient record. There is no clinical note, no prescription and no consultation model in Community or in Enterprise. What Odoo does ship is a calendar, a booking page, invoicing, stock with expiry dates, a customer portal and a point of sale. A clinic system is those parts plus a patient and visit layer built on top of them, and that layer is where the cost and the risk sit.

The edition line matters more here than on most projects. Calendar is Community. Appointments, the public booking page that reads availability from staff calendars, is Enterprise. So are WhatsApp messaging, Sign, Documents, Studio and Planning. Community covers invoicing, lot and expiry tracking, the portal, POS and SMS through Odoo credits. A single site with reception-entered bookings can run Community. Online booking with WhatsApp confirmations cannot.

The rest of the work is unglamorous and it decides whether the build survives its first month. One patient has to exist once, not four times. A service needs a different price for each insurer without four product catalogues. Reception must take payment without reading clinical history. Money billed to a third party has to age separately from money owed by the person in the chair.

Who this fits

  • → Single site general practice, physiotherapy, dermatology and aesthetics clinics where the diary and the counter are the whole business.
  • → Clinic groups of three to twenty branches that want one patient record and one set of numbers across all of them.
  • → Practices with an insurer or TPA mix, where part of every consultation is billed to somebody other than the patient.
  • → Polyclinics with a dispensing counter and a small lab that want stock, dispensing and billing in one place.
  • → Not for hospitals with wards, theatres and bed management, which is a wider scope than this page covers.
  • → Not for a practice that must submit a coded clinical record to a national health system, because Odoo is not a certified electronic health record.

Core features

  • ✓ Appointment scheduling
  • ✓ Prescription templates
  • ✓ SMS / WhatsApp reminders
  • ✓ Patient portal
  • ✓ Insurance & TPA billing
  • ✓ Doctor commission
  • ✓ Walk-in queue management
  • ✓ Waiting room display

How Odoo covers Clinic Management

Diary, walk-ins and the queue on the screen

Appointments builds bookable slots from the working schedule of each doctor and removes anything already in the calendar. Rooms, chairs and machines can be booked as resources instead of named users, which avoids a paid licence for every bookable unit. Walk-ins are added to the same day view. The waiting room display and the ticket queue are not shipped by Odoo. They are a stage on the visit record plus a public page that refreshes.

What the patient record is actually made of

A patient is either a contact or a dedicated model pointing at one. Contacts give you the portal, invoicing, merge tools and messaging with no extra work. A dedicated model gives you file numbers, next of kin, allergies and a history that reception can be locked out of. Most builds use both: the contact holds identity and money, a second model holds the visit and the clinical text.

Prescriptions and the drug list

Medicines are product records carrying pack size, form and strength, tracked by lot with an expiration date where the clinic dispenses. A prescription is a header and lines against a visit, printed from a QWeb template on clinic letterhead with the prescriber name and licence number. Templates are preset line sets a doctor loads and edits, which is what makes a repeat prescription fast enough that people actually use it.

Insurance, TPA and the split bill

The visit has to become a sales order or a POS order before the money behaves. That is where the payer price list is applied and where the patient can stay the customer while the insurer sits in the invoice address, so the receivable ages against whoever actually owes it. An invoice keyed directly ignores price lists altogether, which is the usual reason payer rates end up duplicated as separate products. Co-pay and insurer share are two invoices from one visit, tied by an analytic account. Pre-authorisation and rejection are stages on the claim, with the reason recorded against the visit.

Reminders, recalls and consent to be messaged

Calendar alarms send an email or an SMS at a set offset before the appointment, with SMS drawing on Odoo credits. WhatsApp template messages need Enterprise and an approved template on a Meta business account. Recalls, the six month check or the second dose, run as a scheduled action over visits with a due date rather than a marketing blast. Consent to be contacted belongs on the patient record and has to be honoured.

The counter, deposits and what the doctor is paid

Reception takes cash and card through Point of Sale, or the invoice is paid from the portal through a payment provider already live on the website. An appointment type can require payment before it confirms, which is the practical answer to no-shows. Doctor pay is the part that gets underestimated. Odoo 18 added a Commissions app on Enterprise, but it is built around sales users and plans over invoiced amounts, so it will not split one visit between the practitioner, the service code and the payer. Clinic commission stays a build.

How the rollout runs

Settle the patient model in the first week

Contact only, or contact plus a clinical model, changes the portal, the access rules, the import and every report built after it. Two questions decide it: does reception have to be blocked from clinical history, and does the patient need to log in. If both answers are yes, both objects are needed from day one. Deciding this late means rebuilding the security and the imports together.

Build the catalogue as services with a price per payer

Every consultation, procedure and package is a product of type service with an income account and a tax. Branch and practitioner analytics come from analytic distribution models, not from a field typed on each line, because nobody keys a distribution two hundred times a day. Payer pricing is price lists rather than duplicate products, and that only holds if the visit is confirmed as an order. Have finance sign the list before anything is imported. A catalogue rebuilt after go-live invalidates every report and every commission line already posted against the old codes.

Working schedules, leave and timezones

Slots come from working schedules, so each branch and each part time contract needs its own rather than one company default. Link doctors to employee records so approved time off clears their slots, then put one real leave request through end to end before trusting it. Every bookable user needs a timezone on the user record, the appointment type carries its own, and the public page renders in the visitor timezone. One wrong value gives a page that looks correct and books an hour out.

Access rights and the export button before go-live

Reception, nurse, doctor, cashier and manager are groups with record rules, not job titles on a slide. Odoo treats export as its own capability, so a receptionist who holds it can take the whole patient list to a spreadsheet in two clicks. Switch it off for everyone who does not need it. The audit trail Odoo ships is an accounting feature, it keeps posted entries from being edited silently and says nothing about who opened a patient file, so field tracking on the clinical model and a logging module are a separate decision made before go-live, not after an incident.

Bring the old patient list across once

Export the old system to a spreadsheet, clean it there, import once. Agree the rule that makes two rows the same person before starting, usually national identity number, then sanitised mobile number, then name with date of birth. Keep the legacy file number as a searchable field so staff can still find people by the number written on the paper folder. Attachments and scans move after identity is stable.

Go live on the diary before the money

Put reception and the calendar live first and leave invoicing on the old system for a fortnight. The diary breaks loudly and gets fixed the same day. Billing breaks quietly and is only found at month end. Switch invoicing on the first day of an accounting period so the old and the new never cover the same month. Insurer claims move last, after a full cycle of clean patient invoices has proved the catalogue and the price lists.

Where these projects go wrong

The phone number is the key and it is dirty

Clinics identify patients by mobile number, and that number is stored four ways: with a country code, without one, with spaces, and with the leading zero the network stopped using years ago. Odoo matches on the sanitised value only when the country is set on the record. Clean the numbers before import. Merging contacts once appointments, invoices and messages point at both records costs far more.

Slots nobody can honour

The slot engine sees only what is in Odoo or in a connected Google or Microsoft calendar. A theatre list kept in a chat group, a doctor teaching every second Thursday and an unrecorded half day are all invisible, so the page sells them anyway. Every no-show caused this way gets blamed on the software. Decide at the start that the Odoo calendar is the only calendar, then enforce it.

Insurance revenue counted twice

The common failure is invoicing the full amount to the patient and then invoicing the insurer for its share as well, so revenue is overstated until somebody reconciles it months later. Remittances arrive as one batch covering two hundred visits with deductions on thirty of them. Without a claim reference carried on the invoice, matching that payment is a week of work every month.

Clinical notes in the chatter

Free text typed into the message thread is convenient and it is a data protection problem. Chatter follows record access, not field level rules, so anyone who can open the visit reads it, and the text is pushed into the notification email of every follower. Put clinical content in fields on a model with its own record rules and keep the chatter for administrative history.

Scans and images pushed into the database

Referral letters, consent forms, photographs of an insurance card and phone pictures of a skin condition arrive by the hundred, and every one becomes an attachment. Odoo can keep attachments in the filestore on disk or inside the database itself, and a database holding them grows until the nightly dump takes hours and the restore is never tested. Keep the filestore on disk, back it up with the dump, and cap the upload size.

Commission paid on money that never arrived

Commission computed from posted invoices pays practitioners for revenue the insurer later rejects. A rejected claim, a credit note and a counter discount all move the figure after payroll has already used it. Decide at design time whether the rule follows the invoice or the settled payment, keep it in one place that can be recomputed for a closed period, and agree in writing how a clawback is handled.

What it works with

  • + Odoo Inventory for the dispensing counter, with lot numbers and expiration dates
  • + Point of Sale at reception for cash and card, one session per till closed and posted daily, which is what makes the drawer reconcile
  • + Odoo Accounting for patient and insurer receivables, though the aged receivable and partner ledger reports are Enterprise only
  • + Employees and Attendance for duty hours, with Planning on Enterprise for rosters and Payroll on Enterprise localised country by country
  • + Sign and Documents on Enterprise for consent forms and scanned referrals
  • + WhatsApp Business and SMS gateways for confirmations, results and recalls
  • + Website payment providers for deposits taken at the moment of booking
  • + Lab and imaging systems over HL7 or a vendor API, scoped one vendor at a time

Country considerations

Saudi Arabia (KSA)

ZATCA Phase 2 decides the invoice format. Patient bills are simplified invoices reported to Fatoora within twenty four hours, while insurer invoices are standard invoices cleared before they are handed over, both as signed XML carrying a QR code. Claims themselves ride on NPHIES, which sits outside Odoo entirely, so plan the reconciliation between the two from the start.

United Arab Emirates

Dubai and Abu Dhabi run separate claim platforms, eClaimLink and Shafafiya, so a group across both emirates has two coded submission paths sitting outside one Odoo database. Tax splits by intent rather than by department: preventive and curative treatment is zero rated, elective cosmetic work is standard rated, and the same practitioner produces both in an afternoon. Corporate tax makes the analytic split by branch worth building before the first return rather than after it.

India

A clinical establishment charges no GST on healthcare services, but the dispensing counter, cosmetic procedures and room rent above the notified limit are taxable. That mix blocks full input credit, so equipment and rent carry GST nobody reclaims. E-invoicing with an IRN applies to the taxable side above the turnover threshold, not to exempt consultations, so one database runs both paths.

Pakistan

Sales tax on services is provincial, so a Karachi clinic answers to the SRB and a Lahore clinic to the PRA, with different rates and different returns, while FBR digital invoicing covers the federal side and goods. The dispensing counter and the consultation room can therefore sit under two authorities in one building.

Egypt

Most clinic income is a walk-in patient paying at the counter, which falls under the ETA e-receipt track rather than the e-invoice track used for corporate and insurer billing. Both require every service and medicine mapped to an EGS or GS1 code, and the printed slip has to carry the reference the ETA returns. Two document flows, one reception desk.

United Kingdom

Medical care by a registered health professional is VAT exempt, so a consultation-only practice may sit below registration entirely, while cosmetic work with no therapeutic purpose is standard rated and can push the practice over the threshold. Once registered, returns go to HMRC under Making Tax Digital, so the figures come from Odoo rather than a spreadsheet.

Germany

The Steuerberater will ask for a DATEV export rather than a trial balance PDF, and that expectation shapes the chart of accounts from the first week. Treatment is VAT exempt under the medical exemption, so input VAT on equipment is not recoverable and the tax mapping cannot be copied from a retail build. Records must meet GoBD retention, and any till taking cash needs a certified TSE.

Australia

Medicare is billed against MBS item numbers and health fund payments arrive through HICAPS terminals. Odoo speaks to neither, so both stay outside and are reconciled against the invoice, which is the largest scoping question on an Australian build. Most medical services are GST free while cosmetic work is taxable, and the item billed decides which. Payroll reports under Single Touch Payroll Phase 2.

Questions we get asked

Does Odoo have a built-in clinic or EMR module?

No. Neither Community nor Enterprise ships a patient record, a prescription or a clinical note, and no Odoo release has. That layer comes from a third-party app on the Odoo store or is built for the practice. Store apps are worth reviewing, but check which Odoo version the app is genuinely maintained on, whether it stores clinical text in its own fields or in the chatter, and how far it goes into billing.

Community or Enterprise for a clinic?

Enterprise if patients book themselves, because the booking page has no Community equivalent and rebuilding it is not a small module. The second deciding factor is money owed by insurers. Community gives you invoices and manual payment matching, while the aged receivable report, the partner ledger, bank feed synchronisation and automated follow-up are Enterprise, and a practice carrying ninety days of payer debt feels that gap within a quarter. Community to Enterprise later is a supported move. The reverse is not, so keep custom work in modules that survive it.

Can patients book online and pay a deposit?

Yes, with Appointments on Enterprise. The deposit is an ordinary product carrying its own price and tax, so it posts to a real account instead of sitting as an unexplained credit. Two things catch clinics out. The money arrives as a payment against the booking and still has to be matched to the invoice raised after the visit, and refunds are not automatic, so a cancelled paid booking needs a credit note raised by a person against a written cancellation policy. Agree who is allowed to raise one before the page goes live.

Does Odoo submit claims to insurers or to a national platform?

No. There is no claim submission in any edition, and no country localisation adds one. Each payer platform carries its own schema, its own credentials and usually its own sandbox, so an integration is scoped and priced per payer rather than once for the clinic. The realistic default is that staff key the claim into the payer portal while Odoo holds the amount claimed, the stage and the reference that comes back. Build a file export only for a payer whose volume pays for the mapping and for the schema changes that follow it.

Do portal patients need a paid licence?

No. Portal users are free in both editions, so patients viewing appointments, invoices and documents cost nothing. Only staff logging into the back office count as internal users. That is also why booking against rooms and chairs rather than named practitioners changes the licence bill on a large clinic.

Can two branches share one database?

Yes. Either one company with an analytic plan per branch, which is simpler and keeps reporting in one place, or multi-company with record rules where the branches are separate legal entities. Contact records are normally left with no company set, so the patient stays a single record either way while stock, journals and sequences stay separate. The cost of multi-company is that every user needs the right companies enabled, and a booking taken under the wrong active company invoices from the wrong entity.

Can a patient see their own record and their invoices?

Invoices, quotations and appointments, yes, through the free portal, and for most clinics that is as far as it should go. Nothing Odoo ships exposes clinical fields to the portal, so publishing a history or a result is a deliberate build with access rules and consent wording of its own. Watch the chatter as well. On a document the patient can open, an internal log note stays hidden, but a message and anything attached to it are visible on that portal page.

Is Odoo compliant with patient data rules?

No software is compliant on its own, and Odoo carries no health data certification. The answer is decided by where the database is hosted, who holds the backups and the keys, which groups can read clinical fields, and how long records are kept. Odoo supplies the access rules, field tracking and portal consent. Retention, the processing agreement and the hosting region stay decisions the practice has to make.