Module Architecture
flowchart TD
SUBSMOD["sadeem_subscription\nSubscription Base"]
PLAN["sadeem.subscription.plan\npublished subscription plan\npackages · addons · billing periods"]
PKGLINE["sadeem.subscription.plan.package.line\npackage options per plan"]
PKGPRICE["sadeem.subscription.plan.package.pricing\npackage pricing by period"]
ADDON["sadeem.subscription.plan.addon\nadd-on definition\ntype · pricing"]
ADDONPRICE["sadeem.subscription.plan.addon.pricing\naddon price by period"]
PERIOD["sadeem.subscription.plan.period\navailable billing periods\nmonthly · yearly etc"]
ORDER["sadeem.subscription.plan.order\ncustomer order record\nsubdomain · package · addons"]
ORDERADDON["sadeem.subscription.plan.order.addon\nadd-on lines on an order"]
SUB["sadeem.subscription\ncreated after payment confirmed"]
WEB[/website plans page\n/saas/plans/]
SUBSMOD --> SUB
PLAN --> PKGLINE
PLAN --> ADDON
PLAN --> PERIOD
PKGLINE --> PKGPRICE
ADDON --> ADDONPRICE
ORDER --> PLAN
ORDER --> ORDERADDON
ORDERADDON --> ADDON
WEB --> PLAN
WEB --> ORDER
PLAN --> A1([action_publish\nvalidate + publish plan to website])
ORDER --> A2([action_create_subscription\ncreate subscription from order after payment])
ORDER --> A3([action_check_subdomain\ncheck domain availability])
ORDER --> A4([action_create_sale_order\ngenerate Odoo sale order + redirect to payment])
A2 --> SUB
CTRL[/website controller\n/saas/plans route/]
WEB --> CTRL
CTRL --> ORDER
Module Description
Subscription Website Plans - Public-facing SAAS subscription purchase system. Allows customers
to browse plans, configure packages and add-ons, pick a subdomain, and purchase subscriptions
through the website with integrated payment.
Dependencies
base, web, mail, website, website_sale
sadeem_subscription
Website
└─ Plans
├─ Subscription Plans
└─ Plan Orders
Purchase Flow
Browse Plans → Configure → Pick Subdomain → Checkout → Pay → Subscription Created
- Customer visits
/saas/plans to browse published plans
- Selects a plan and configures packages, add-ons, and billing period
- Picks a subdomain and checks availability
- Reviews the order summary at checkout
- Submits the order, which creates a sale order and redirects to payment
- After payment, the subscription is automatically created and deployed
Key Fields
Subscription Plan (sadeem.subscription.plan)
| Field |
Type |
Description |
| url_string |
Char |
URL slug for the plan page (required) |
| plan_url |
Char |
Computed full public URL |
| published |
Boolean |
Whether the plan is visible on the website |
| saas_subscription_type |
Selection |
Deployment type (docker or dbfilter — extended by variant modules) |
| allowed_domain |
Char |
Base domain for subscriptions created from this plan (required) |
| auto_create_subscription |
Boolean |
Auto-create subscription after payment without manual confirmation |
| product_id |
Many2one |
Odoo product used for billing/invoicing |
| currency_id |
Many2one |
Currency for pricing |
| package_line_ids |
One2many |
Available package options with their pricing |
| addon_ids |
One2many |
Add-on definitions for this plan |
| available_period_ids |
One2many |
Billing periods offered (monthly, yearly, etc.) |
| database_template |
Many2one |
Default DB template for subscriptions from this plan |
| badge_text |
Char |
Marketing badge (e.g., "Popular") |
| features_html |
Html |
HTML feature list shown on the plan page |
Subscription Plan Order (sadeem.subscription.plan.order)
| Field |
Type |
Description |
| plan_id |
Many2one |
The selected plan (required) |
| period |
Selection |
Billing period chosen by the customer |
| subdomain |
Char |
Customer-chosen subdomain |
| full_domain |
Char |
Computed full domain (subdomain + allowed_domain) |
| partner_id |
Many2one |
Authenticated customer |
| session_id |
Char |
Session identifier for unauthenticated orders |
| package_line_ids |
Many2many |
Selected package options |
| addon_line_ids |
One2many |
Selected add-on quantities |
| package_price |
Float |
Computed price of the selected packages |
| addon_total |
Float |
Computed total for add-ons |
| total_price |
Float |
Computed grand total |
| state |
Selection |
Order lifecycle: draft, confirmed, paid, done, cancelled |
| sale_order_id |
Many2one |
Generated Odoo sale order |
| subscription_id |
Many2one |
Created subscription after payment |
Plan Add-on (sadeem.subscription.plan.addon)
| Field |
Type |
Description |
| plan_id |
Many2one |
Parent plan |
| addon_type |
Selection |
Type of add-on: users, storage, stages, or custom |
| included_value |
Integer |
Default included quantity |
| step_value |
Integer |
Quantity increment per unit |
| min_value / max_value |
Integer |
Allowed range for selection |
| unit_label |
Char |
Display unit (e.g., "GB", "Users") |
| pricing_ids |
One2many |
Prices per billing period |
Plan Period (sadeem.subscription.plan.period)
| Field |
Type |
Description |
| plan_id |
Many2one |
Parent plan |
| period |
Selection |
Period type: monthly, quarterly, biannual, yearly |
| is_default |
Boolean |
Whether this is the default period shown on the plan page |
Lifecycle & States
Plan Order States
| State |
Meaning |
draft |
Order created but not yet submitted |
confirmed |
Order submitted; sale order generated; pending payment |
paid |
Payment received; subscription creation in progress |
done |
Subscription successfully created |
cancelled |
Order was cancelled |
Transitions:
- draft → confirmed: action_create_sale_order — validates order and creates Odoo sale order; redirects to payment
- confirmed → paid: action_after_payment — triggered by payment confirmation webhook/event
- paid → done: action_create_subscription — creates and (optionally) confirms the subscription
- Any → cancelled: action_cancel — blocks if state is done
Key Actions
| Action |
Model |
Description |
action_publish |
sadeem.subscription.plan |
Validates plan configuration and toggles published |
action_create_sale_order |
sadeem.subscription.plan.order |
Validates order; creates Odoo sale order; moves to confirmed |
action_after_payment |
sadeem.subscription.plan.order |
Called after payment; triggers subscription creation |
action_create_subscription |
sadeem.subscription.plan.order |
Creates sadeem.subscription from order details; moves to done |
action_check_subdomain |
sadeem.subscription.plan.order |
Checks if the chosen subdomain is available |
action_cancel |
sadeem.subscription.plan.order |
Cancels the order |
action_view_subscription |
sadeem.subscription.plan.order |
Opens the linked subscription |
action_view_sale_order |
sadeem.subscription.plan.order |
Opens the linked sale order |
Warnings & Important Notes
- Plan product required:
action_create_sale_order raises ValidationError if product_id is not set on the plan.
- Package required:
action_create_sale_order raises ValidationError if no package is selected in the order.
- Product variant required: Raises
ValidationError if the plan's product has no purchasable variant.
- Subscription already exists:
action_create_subscription raises ValidationError if subscription_id is already set on the order.
- Cannot cancel done orders:
action_cancel raises ValidationError if state is done.
- Plan publish validation:
action_publish raises ValidationError for missing required plan configuration (allowed domain, product, at least one period, etc.).
- Subdomain uniqueness:
action_check_subdomain verifies the domain is not already in use before allowing order confirmation.