Champions Club
Champions Club – Sports Club Management on Odoo
One member record sets the price everywhere.
A sports club operating system on Odoo 17 for court bookings, memberships, a pro shop and a bar POS, where a member’s tier sets the price everywhere and website enquiries flow into a CRM pipeline.
- Type
- Hackathon build
- Built at
- Odoo Hackathon 2026
- Team
- Hackathon team
- Core stack
- Odoo 17 · Python · PostgreSQL 15
Problem and solution
The problem
Racket clubs run on spreadsheets, WhatsApp groups and paper. Courts get double-booked, member discounts are applied from memory, and enquiries from the website get lost.
The solution
Champions Club runs the whole club on Odoo. Bookings, shop and bar orders, invoices and the public website share one database, prices always come from the member’s tier pricelist on the server, and enquiries move through a CRM pipeline from lead to quote to member.
How it’s built
- 01club_websitePublic pages, availability and online booking
- 02OWL screensBooking grid, plans, pro shop and bar POS
- 03club_managementRules, pricing, CRM and reports in Python
- 04Odoo 17 + PostgreSQLCRM, Sales, Inventory, Accounting and POS
What it does
Courts and members
- Booking gridLive availability in 30-minute slots, one-hour sessions and two bookings a day.
- MembershipsGold, Silver and Junior plans with member IDs, QR cards and automatic lapse.
- Reschedule and cancelEvery change re-runs the booking rules.
- Friday social playShared courts with a player capacity per slot.
Shop and bar
- Pro shopCatalogue, cart and checkout against live stock.
- Bar POSTables, open tabs and cash, card or UPI payment.
- Tier pricingThe shop, the bar and Odoo’s own POS read the same pricelist.
Running the club
- CRM pipelineWebsite enquiry to lead, quote and member.
- Owner dashboardRevenue by source, GST, payroll and leave in one place.
- Public websitePlans, live availability, online booking and the shop.
Under the hood
No double bookings under load
The overlap check locks the court row with SELECT … FOR UPDATE, so two simultaneous requests can’t both take the same slot.
One source of truth for price
Each plan generates an Odoo pricelist, every screen asks the server for prices, and a test checks that the screen price matches the real POS.
Club-time rules
Daily limits and Friday social play are worked out in Asia/Kolkata time, not the server’s timezone.
Tested in a real browser
Python tests cover the booking, pricing and CRM rules, and headless Chrome scripts drive the real screens and then check the database.
Hardened public forms
CSRF tokens, a honeypot field and random status tokens stop enquiries from being spammed or guessed.
Built with
- Odoo 17
- Python
- PostgreSQL 15
- OWL
- JavaScript
- QWeb
- SCSS
- Docker Compose
- Puppeteer
- Mailpit
My part
I built the club_management backend (booking rules, tier pricing, invoicing, the CRM pipeline and scheduled jobs), the public website and the owner dashboard and reports, and connected the team’s OWL screens to the backend.