Architecture

AirDoo is an Odoo 18 module that extends the Odoo core with short-term rental management features.

Overview

graph TD A[Airbnb Email] -->|Gmail API| B[GmailService] B --> C[AirDooParser] C --> D[airdoo.accommodation._upsert_reservation] D --> E[sale.order] E --> F[Communication Engine] F --> G[airdoo.comm.rule] G --> H[airdoo.communication.log] H -->|cron 10min| I[Guest Email Send] E -->|Confirmation| J[Cleaning Email + .ics] K[Website / App] -->|Bearer Token| L[API v1 Controllers] L --> M[airdoo.accommodation] L --> E

Main Models

airdoo.accommodation

The accommodation is the central pivot. Each accommodation contains: - Its metadata (name, address, times, color) - Its specific communication rules - Its pricelist for direct bookings - Cleaning provider information - Social media and branding

File: models/airdoo_accommodation.py

sale.order (extended)

Bookings are Odoo sales orders enriched with: - PMS fields: checkin_date, checkout_date, nights, guest_count - Guest composition: adults_count, children_count, babies_count - Airbnb fields: airbnb_confirmation_code, airbnb_payout_amount, airbnb_status - Direct Booking fields: booking_source, booking_reference, stripe_payment_intent_id - Occupancy: occupancy_state (upcoming / in_stay / completed)

File: models/sale_order.py

airdoo.comm.rule

Communication rules define send timing: - event_type: confirmation / welcome / checkin_reminder / thank_you / loyalty - delay + delay_unit + delay_reference: send datetime calculation - accommodation_id: optional (empty = default rule) - Priority: specific rule > default rule

File: models/communication_rule.py

airdoo.communication.log

Communication logs are scheduled instances: - Idempotency key: {order_id}_{event_type}_{rule_id} (UNIQUE constraint) - Statuses: scheduledsent / failed / cancelled

File: models/airdoo_communication_log.py

airdoo.communication.template

Wrapper around Odoo mail.template, adding: - channel: email / whatsapp - language: fr / en / es / de / it / pt

File: models/airdoo_communication_template.py


Email Parser (airdoo_parser.py)

The parser extracts data from Airbnb HTML emails:

HTML Email → AirDooParser.parse_email() → dict {
    confirmation_code, guest_name, arrival_date, departure_date,
    payout_amount, cleaning_fee, nights, guest_count,
    adults_count, children_count, babies_count,
    property_name, booking_status
}

Accommodation → email matching is done via airbnb_listing_name (exact match, case-insensitive).


REST API (controllers/)

File Contents
airdoo_v1_api.py All /api/v1/airdoo/* endpoints (Bearer auth)
webhook_api.py /airdoo/webhook/* endpoints (HMAC auth)
booking_api_deprecated.py Old endpoints (return 410 Gone)
oauth_callback.py Google OAuth2 callback
tracking.py Email open/click tracking (in development)

API v1 Authentication

Routes use auth='bearer' — Odoo verifies the Bearer token against the airdoo_api_user system user and its native API key.


Crons

Cron Frequency Method
Gmail Sync 30 min airdoo.accommodation._cron_gmail_sync()
Generate Communications 4h sale.order._cron_generate_communications()
Send Due Communications 10 min airdoo.communication.log._cron_send_due_communications()

Direct Booking Pricing Engine

For direct bookings, sale_order._compute_direct_booking_price(): 1. Retrieves the accommodation's pricelist 2. For each night of the stay, calls pricelist._get_product_price(product, quantity=total_nights, date=night) 3. Returns {total, detail: [{date, price}], avg_price}

The quantity passed is the total number of nights (not 1) so that minimum night rules are respected.


Direct Booking Flow (API + Stripe)

1. Next.js → POST /api/v1/airdoo/availability   (check availability + price)
2. Next.js → Stripe API (create PaymentIntent)
3. Guest → Stripe Elements (pay)
4. Next.js → POST /api/v1/airdoo/bookings       (create booking)
   └─ Odoo creates sale.order (status=confirmed)
      └─ Trigger: cleaning email + comm scheduling
5. Next.js → GET /api/v1/airdoo/bookings/<id>   (confirm on UI side)

Technical Stack

Component Version
Odoo 18.0
Python 3.12
PostgreSQL 16
Google API (Gmail) OAuth2 / REST
iCalendar RFC 5545 format

← Back: Templates | Next: Tests →