Adds the membership foundation: community.membership.tier (admin-configurable
tiers, each auto-creating a linked invoicing product), res.partner membership
fields (member ID, tier, state, family grouping, volunteer tracking), and a
res.config.settings page (org name, member-ID format, renewal offsets, portal
toggle) - all backed by ir.config_parameter so nothing is hardcoded.
Member IDs are generated on activation via a configurable format string
({year}/{seq}) resolved against an ir.sequence. Adds the Membership Manager
group/menu and views (tier list/form, partner form tab, list columns, search
filters, settings page).
Along the way, hit two real Odoo 19 API changes vs. older tutorials/docs:
res.groups.category_id was replaced by privilege_id -> res.groups.privilege,
and module settings pages now use the <app>/<block>/<setting> pattern
inherited from base.res_config_settings_view_form rather than raw divs.
Verified by upgrading the module against a live Odoo 19 + Postgres 16
container: installs clean, all 4 tests pass (tier->product creation, member
ID generation on activation, one-time/lifetime tiers never expire,
configurable ID format), and the module still installs cleanly for its
dependents (community_benefits, tncsc_deployment).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
56 lines
2.3 KiB
XML
56 lines
2.3 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<odoo>
|
|
<record id="view_membership_tier_list" model="ir.ui.view">
|
|
<field name="name">community.membership.tier.list</field>
|
|
<field name="model">community.membership.tier</field>
|
|
<field name="arch" type="xml">
|
|
<list string="Membership Tiers">
|
|
<field name="sequence" widget="handle"/>
|
|
<field name="name"/>
|
|
<field name="code"/>
|
|
<field name="price" widget="monetary"/>
|
|
<field name="currency_id" column_invisible="1"/>
|
|
<field name="period"/>
|
|
<field name="active" column_invisible="1"/>
|
|
</list>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="view_membership_tier_form" model="ir.ui.view">
|
|
<field name="name">community.membership.tier.form</field>
|
|
<field name="model">community.membership.tier</field>
|
|
<field name="arch" type="xml">
|
|
<form string="Membership Tier">
|
|
<sheet>
|
|
<div class="oe_title">
|
|
<label for="name"/>
|
|
<h1><field name="name" placeholder="e.g. Individual"/></h1>
|
|
</div>
|
|
<group>
|
|
<group>
|
|
<field name="code"/>
|
|
<field name="price" widget="monetary"/>
|
|
<field name="currency_id" groups="base.group_multi_currency"/>
|
|
<field name="period"/>
|
|
</group>
|
|
<group>
|
|
<field name="sequence"/>
|
|
<field name="active"/>
|
|
<field name="product_id" readonly="1"/>
|
|
</group>
|
|
</group>
|
|
<group string="Notes">
|
|
<field name="member_state_logic" nolabel="1" placeholder="Optional admin notes on state handling for this tier..."/>
|
|
</group>
|
|
</sheet>
|
|
</form>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="action_membership_tier" model="ir.actions.act_window">
|
|
<field name="name">Membership Tiers</field>
|
|
<field name="res_model">community.membership.tier</field>
|
|
<field name="view_mode">list,form</field>
|
|
</record>
|
|
</odoo>
|