first push message
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<menuitem id="menu_saas_root" name="SaaS Portal" sequence="5"/>
|
||||
|
||||
<menuitem id="menu_saas_trial_request" name="Trial Requests"
|
||||
parent="menu_saas_root" action="action_saas_trial_request" sequence="10"/>
|
||||
|
||||
<menuitem id="menu_saas_database" name="Tenant Databases"
|
||||
parent="menu_saas_root" action="action_saas_database" sequence="20"/>
|
||||
|
||||
<menuitem id="menu_saas_subscription" name="Subscriptions"
|
||||
parent="menu_saas_root" action="action_saas_subscription" sequence="30"/>
|
||||
|
||||
<menuitem id="menu_saas_config" name="Configuration"
|
||||
parent="menu_saas_root" sequence="90"/>
|
||||
<menuitem id="menu_saas_plan" name="Plans"
|
||||
parent="menu_saas_config" action="action_saas_plan" sequence="10"/>
|
||||
<menuitem id="menu_saas_app" name="Sellable Apps"
|
||||
parent="menu_saas_config" action="action_saas_app" sequence="20"/>
|
||||
</odoo>
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_saas_database_list" model="ir.ui.view">
|
||||
<field name="name">saas.database.list</field>
|
||||
<field name="model">saas.database</field>
|
||||
<field name="arch" type="xml">
|
||||
<list>
|
||||
<field name="db_name"/>
|
||||
<field name="subdomain"/>
|
||||
<field name="worker_node"/>
|
||||
<field name="state" widget="badge" decoration-success="state=='ready'" decoration-danger="state=='error'"/>
|
||||
<field name="provisioning_seconds"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_saas_database_form" model="ir.ui.view">
|
||||
<field name="name">saas.database.form</field>
|
||||
<field name="model">saas.database</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<header>
|
||||
<button name="action_provision" type="object" string="Re-run Provisioning" class="btn-primary"
|
||||
invisible="state == 'ready'"/>
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="draft,name_generated,db_created,modules_installed,configured,credentials_sent,ready"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<group string="Identity">
|
||||
<field name="company_name"/>
|
||||
<field name="db_name"/>
|
||||
<field name="subdomain"/>
|
||||
</group>
|
||||
<group string="Instance Config">
|
||||
<field name="worker_node"/>
|
||||
<field name="worker_count"/>
|
||||
<field name="timeout_seconds"/>
|
||||
<field name="memory_limit_mb"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Admin Credentials">
|
||||
<field name="admin_login"/>
|
||||
<field name="admin_password" password="True"/>
|
||||
</group>
|
||||
<group string="Apps">
|
||||
<field name="app_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
<field name="error_message" invisible="state != 'error'"/>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_saas_database" model="ir.actions.act_window">
|
||||
<field name="name">Tenant Databases</field>
|
||||
<field name="res_model">saas.database</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_saas_plan_list" model="ir.ui.view">
|
||||
<field name="name">saas.plan.list</field>
|
||||
<field name="model">saas.plan</field>
|
||||
<field name="arch" type="xml">
|
||||
<list editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="duration_months"/>
|
||||
<field name="price"/>
|
||||
<field name="currency_id"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_saas_plan" model="ir.actions.act_window">
|
||||
<field name="name">Plans</field>
|
||||
<field name="res_model">saas.plan</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
</record>
|
||||
|
||||
<record id="view_saas_app_list" model="ir.ui.view">
|
||||
<field name="name">saas.app.list</field>
|
||||
<field name="model">saas.app</field>
|
||||
<field name="arch" type="xml">
|
||||
<list editable="bottom">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="technical_module_name"/>
|
||||
<field name="category_id"/>
|
||||
<field name="active"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_saas_app_resync" model="ir.actions.server">
|
||||
<field name="name">Resync from Installed Apps</field>
|
||||
<field name="model_id" ref="model_saas_app"/>
|
||||
<field name="binding_model_id" ref="model_saas_app"/>
|
||||
<field name="binding_view_types">list</field>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model._sync_from_installed_modules()</field>
|
||||
</record>
|
||||
|
||||
<record id="action_saas_app" model="ir.actions.act_window">
|
||||
<field name="name">Sellable Apps</field>
|
||||
<field name="res_model">saas.app</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_saas_subscription_list" model="ir.ui.view">
|
||||
<field name="name">saas.subscription.list</field>
|
||||
<field name="model">saas.subscription</field>
|
||||
<field name="arch" type="xml">
|
||||
<list>
|
||||
<field name="trial_request_id"/>
|
||||
<field name="plan_id"/>
|
||||
<field name="is_trial"/>
|
||||
<field name="is_premium"/>
|
||||
<field name="expiry_date"/>
|
||||
<field name="state" widget="badge" decoration-success="state=='active'" decoration-danger="state=='payment_failed'"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_saas_subscription_form" model="ir.ui.view">
|
||||
<field name="name">saas.subscription.form</field>
|
||||
<field name="model">saas.subscription</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<header>
|
||||
<field name="state" widget="statusbar" statusbar_visible="trial,plan_selected,payment_pending,active"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<group string="Account">
|
||||
<field name="trial_request_id"/>
|
||||
<field name="is_trial"/>
|
||||
<field name="is_premium"/>
|
||||
<field name="expiry_date"/>
|
||||
</group>
|
||||
<group string="Billing">
|
||||
<field name="plan_id"/>
|
||||
<field name="payment_provider_code"/>
|
||||
<field name="payment_transaction_id"/>
|
||||
<field name="last_payment_status"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_saas_subscription" model="ir.actions.act_window">
|
||||
<field name="name">Subscriptions</field>
|
||||
<field name="res_model">saas.subscription</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_saas_trial_request_list" model="ir.ui.view">
|
||||
<field name="name">saas.trial.request.list</field>
|
||||
<field name="model">saas.trial.request</field>
|
||||
<field name="arch" type="xml">
|
||||
<list>
|
||||
<field name="name"/>
|
||||
<field name="company_name"/>
|
||||
<field name="email"/>
|
||||
<field name="state" decoration-success="state=='ready'" decoration-danger="state=='failed'" widget="badge"/>
|
||||
<field name="trial_end_date"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_saas_trial_request_form" model="ir.ui.view">
|
||||
<field name="name">saas.trial.request.form</field>
|
||||
<field name="model">saas.trial.request</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<header>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,pending_verification,verified,trial_active,provisioning,ready"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<group string="Contact">
|
||||
<field name="name"/>
|
||||
<field name="company_name"/>
|
||||
<field name="email"/>
|
||||
<field name="phone"/>
|
||||
</group>
|
||||
<group string="Trial">
|
||||
<field name="app_ids" widget="many2many_tags"/>
|
||||
<field name="trial_start_date" readonly="1"/>
|
||||
<field name="trial_end_date" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Provisioning">
|
||||
<field name="database_id" readonly="1"/>
|
||||
<field name="subscription_id" readonly="1"/>
|
||||
</group>
|
||||
</sheet>
|
||||
<chatter/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_saas_trial_request" model="ir.actions.act_window">
|
||||
<field name="name">Trial Requests</field>
|
||||
<field name="res_model">saas.trial.request</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,201 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Step: domain-name.com/trial -> "Choose your Apps" (Step 1: card grid +
|
||||
live sidebar showing count/selection/Continue) -> "Your Information"
|
||||
(Step 2: registration form) - mirrors the odoo.com/trial reference flow -->
|
||||
<template id="trial_signup_template" name="Trial Signup">
|
||||
<t t-call="website.layout">
|
||||
<div class="container-fluid py-5" id="trial_wizard">
|
||||
|
||||
<!-- ================= STEP 1: Choose your Apps ================= -->
|
||||
<div id="trial_step_apps">
|
||||
<div class="text-center mb-5">
|
||||
<h1 class="display-4">Choose your <span class="text-success" style="border-bottom:3px solid #2ECC71;">Apps</span></h1>
|
||||
<p class="lead">Free instant access. No credit card required.</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-9" style="padding-left:20%;">
|
||||
<t t-foreach="app_groups" t-as="group">
|
||||
<h4 class="mb-3 mt-4" t-out="group[0]"/>
|
||||
<div class="row g-3 mb-5">
|
||||
<t t-foreach="group[1]" t-as="app">
|
||||
<div class="col-md-4 pt-2">
|
||||
<label class="app-card d-flex align-items-center p-3 border rounded shadow-sm w-100 position-relative"
|
||||
t-att-for="'app_%s' % app.id"
|
||||
t-att-data-app-id="app.id"
|
||||
t-att-data-app-name="app.name">
|
||||
<input type="checkbox" class="app-card-checkbox d-none"
|
||||
t-att-value="app.id" t-att-id="'app_%s' % app.id"/>
|
||||
<span class="app-card-check d-none">✓</span>
|
||||
<img t-if="app.icon" t-att-src="'/web/image/saas.app/%s/icon' % app.id"
|
||||
class="app-card-icon me-3" alt=""/>
|
||||
<img t-elif="app.icon_url" t-att-src="app.icon_url"
|
||||
class="app-card-icon me-3" alt=""/>
|
||||
<span class="fw-bold" t-out="app.name"/>
|
||||
</label>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- Live sidebar - hidden until the user selects at least 1 app -->
|
||||
<div class="col-lg-3">
|
||||
<div class="sticky-top d-none" id="trial_sidebar" style="top: 20px;">
|
||||
<div class="border rounded shadow-sm p-4 mb-3">
|
||||
<h5><span id="selected_count">0</span> Apps selected</h5>
|
||||
<ul id="selected_apps_list" class="list-unstyled mt-3 mb-0"></ul>
|
||||
</div>
|
||||
<div class="border rounded p-3 mb-3 text-center" style="background:#e6f9ec; color:#1e7e42;">
|
||||
<strong>Free, with unlimited users, forever.</strong>
|
||||
</div>
|
||||
<button type="button" id="btn_continue" class="btn btn-primary btn-lg w-100">
|
||||
Continue
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ================= STEP 2: Your Information ================= -->
|
||||
<div id="trial_step_form" class="d-none">
|
||||
<div class="row mb-4">
|
||||
<div class="col-6">
|
||||
<strong><span id="selected_count_2">0</span> apps selected</strong>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<button type="button" id="btn_change_selection" class="btn btn-light">Change apps selection</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="/trial/submit" method="post" id="trial_form" class="mx-auto" style="max-width:700px;">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="app_ids_json" id="app_ids_json"/>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>First and Last Name</label>
|
||||
<input type="text" class="form-control" name="name" required="1"/>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label>Company Name</label>
|
||||
<input type="text" class="form-control" name="company_name"/>
|
||||
</div>
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-md-6">
|
||||
<label>Email</label>
|
||||
<input type="email" class="form-control" name="email" required="1"/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label>Phone Number</label>
|
||||
<input type="text" class="form-control" name="phone"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-md-6">
|
||||
<label>Country</label>
|
||||
<select class="form-select" name="country_id">
|
||||
<option value="">-</option>
|
||||
<t t-foreach="countries" t-as="country">
|
||||
<option t-att-value="country.id" t-out="country.name"/>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label>Language</label>
|
||||
<select class="form-select" name="lang">
|
||||
<t t-foreach="languages" t-as="lang_item">
|
||||
<option t-att-value="lang_item[0]" t-out="lang_item[1]"/>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-md-6">
|
||||
<label>Company size</label>
|
||||
<select class="form-select" name="company_size">
|
||||
<option value="1-5">1 - 5 employees</option>
|
||||
<option value="6-20">6 - 20 employees</option>
|
||||
<option value="21-50">21 - 50 employees</option>
|
||||
<option value="51-200">51 - 200 employees</option>
|
||||
<option value="200+">200+ employees</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label>Primary Interest</label>
|
||||
<select class="form-select" name="primary_interest">
|
||||
<option value="my_company">Use it in my company</option>
|
||||
<option value="client">Use it for a client</option>
|
||||
<option value="explore">Just exploring</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-center text-muted small">
|
||||
By clicking on <strong>Start Now</strong>, you accept our
|
||||
Subscription Agreement and Privacy Policy.
|
||||
</p>
|
||||
<div class="text-center">
|
||||
<button type="submit" class="btn btn-primary btn-lg px-5">Start Now</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Step: Create Account & Verify Email -->
|
||||
<template id="trial_check_email_template" name="Check Your Email">
|
||||
<t t-call="website.layout">
|
||||
<div class="container py-5 text-center">
|
||||
<h2>Check your inbox 📩</h2>
|
||||
<p>We sent a verification link to <strong t-out="email"/>.</p>
|
||||
<p>Click the link in that email to activate your 15-day free trial.</p>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Step: 15-Day Free Trial Activated -->
|
||||
<template id="trial_activated_template" name="Trial Activated">
|
||||
<t t-call="website.layout">
|
||||
<div class="container py-5 text-center">
|
||||
<h2>🎉 Your 15-day free trial is now active!</h2>
|
||||
<p>Trial ends on <t t-out="trial.trial_end_date"/>.</p>
|
||||
<form action="/trial/continue" method="post">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="id" t-att-value="trial.id"/>
|
||||
<button type="submit" class="btn btn-primary btn-lg">Continue</button>
|
||||
</form>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Step: System Generates DB / Provisioning in progress -->
|
||||
<template id="trial_provisioning_template" name="Provisioning">
|
||||
<t t-call="website.layout">
|
||||
<div class="container py-5 text-center">
|
||||
<h2>Setting up your instance...</h2>
|
||||
<p>This usually takes 30-60 seconds.</p>
|
||||
<div class="spinner-border text-primary" role="status"/>
|
||||
<p class="mt-4">
|
||||
Your instance URL will be:
|
||||
<strong t-out="database.subdomain"/>
|
||||
</p>
|
||||
<p t-if="database.state == 'ready'">
|
||||
✅ Ready! Admin credentials have been sent to your email.
|
||||
</p>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="trial_error_template" name="Trial Error">
|
||||
<t t-call="website.layout">
|
||||
<div class="container py-5 text-center">
|
||||
<h2>Something went wrong</h2>
|
||||
<p t-out="message"/>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user