metatroncubeswdev d05d80c4df feat(tncsc_deployment): TNCSC client configuration (Phase 7)
Data-only deployment layer seeding TNCSC's branding (navy/orange/electric-
blue from the plan), 5 membership tiers in CAD (Individual $50, Family $80,
Student $20, Senior $30, Life $500 - the plan's own example figures;
update via Settings once TNCSC confirms real pricing), the
'TNCSC-{year}-{seq}' member-ID format, a Canadian (Ontario/HST) chart of
accounts via l10n_ca plus non-profit-specific accounts (Membership Dues/
Event/Sponsorship/School Fees/Donations Revenue, Deferred Event Revenue
liability, a Stripe clearing account) and a Donations journal, bilingual
EN/Tamil overrides of two membership email templates (Tamil text is a
best-effort draft only, explicitly flagged as needing native-speaker
review before go-live), five placeholder website pages (Home/About/Tamil
School/Sponsors/Contact), and TNCSC-named role groups (Board Admin,
Treasurer, Events Officer, School Coordinator, Teacher, Classifieds
Moderator) that imply the existing generic product-layer groups rather
than defining new permission logic.

Chasing the chart-of-accounts setup down to a genuinely working state
took real digging: setting company.country_id on a brand-new company
auto-schedules this Odoo build's own chart-template installer via a
precommit hook (res.company.install_l10n_modules), which races an
explicit try_loading('ca_2023', ...) call made in the same install
transaction and silently replaces its result afterwards (reverting
currency to USD, chart_template to 'generic_coa', and deleting the custom
accounts) - confirmed via raw SQL checks that the correct state exists
right up until the post_init_hook transaction commits, and is gone by the
time the install process exits. Since the precommit auto-trigger only
ever fires once per company (guarded by chart_template being unset), a
second call from a separate transaction is immune to the race. The fix:
the actual setup logic lives in an idempotent res.company._tncsc_setup_
accounting() method (models/res_company.py - a narrow, documented
exception to "no models" in the deployment layer, since cramming this
into a sandboxed ir.cron code string wasn't practical), called as a
best-effort from post_init_hook and guaranteed by a daily safety-net cron
que runs in its own transaction. Also hit two smaller, separate bugs on
the way: ir.cron code execution forbids direct attribute assignment
(STORE_ATTR) in its sandbox, and Html config_parameter fields must not be
wrapped in CDATA in data XML.

Verified end-to-end on a genuinely fresh database (not the long-lived dev
DB, which already has posted entries and correctly refuses a currency
change): installed tncsc_deployment alone, pulling in all 8 product
modules plus l10n_ca as dependencies, confirmed the post-install state via
raw SQL, manually triggered the safety-net cron and confirmed it reached
the fully-correct state (CAD, ca_2023, 355 accounts including all 7
custom ones, the Donations journal, tier products linked to the dues
account), confirmed the cron is idempotent on a second run, and ran the
full test suite (9/9 passing) with the same deterministic setup called
from the test transaction directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 00:53:17 -04:00

161 lines
6.8 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<!-- Home -->
<record id="view_page_home" model="ir.ui.view">
<field name="name">TNCSC Home</field>
<field name="type">qweb</field>
<field name="key">tncsc_deployment.page_home</field>
<field name="arch" type="xml">
<t t-name="tncsc_deployment.page_home">
<t t-call="website.layout">
<div class="container" style="margin-top: 40px; margin-bottom: 60px;">
<h1>Tamil Nadu Cultural Society of Canada</h1>
<p class="lead">Celebrating Tamil language, arts, and culture in Canada.</p>
<p>Content to be finalized by TNCSC - this is a placeholder home page
generated by the deployment layer.</p>
<a href="/school/register" class="btn btn-primary me-2">Register for Tamil School</a>
<a href="/classifieds" class="btn btn-outline-secondary">Browse Classifieds</a>
</div>
</t>
</t>
</field>
</record>
<record id="page_home" model="website.page">
<field name="url">/</field>
<field name="view_id" ref="view_page_home"/>
<field name="is_published">True</field>
</record>
<!-- About -->
<record id="view_page_about" model="ir.ui.view">
<field name="name">TNCSC About</field>
<field name="type">qweb</field>
<field name="key">tncsc_deployment.page_about</field>
<field name="arch" type="xml">
<t t-name="tncsc_deployment.page_about">
<t t-call="website.layout">
<div class="container" style="margin-top: 40px; margin-bottom: 60px;">
<h1>About Us</h1>
<p>Placeholder content - to be filled in with TNCSC's real history, mission,
and board information.</p>
</div>
</t>
</t>
</field>
</record>
<record id="page_about" model="website.page">
<field name="url">/about</field>
<field name="view_id" ref="view_page_about"/>
<field name="is_published">True</field>
</record>
<!-- Tamil School -->
<record id="view_page_tamil_school" model="ir.ui.view">
<field name="name">TNCSC Tamil School</field>
<field name="type">qweb</field>
<field name="key">tncsc_deployment.page_tamil_school</field>
<field name="arch" type="xml">
<t t-name="tncsc_deployment.page_tamil_school">
<t t-call="website.layout">
<div class="container" style="margin-top: 40px; margin-bottom: 60px;">
<h1>Tamil School</h1>
<p>Weekend Tamil language classes for children and youth. See current terms,
levels, and class schedules below.</p>
<a href="/school/register" class="btn btn-primary">Register</a>
</div>
</t>
</t>
</field>
</record>
<record id="page_tamil_school" model="website.page">
<field name="url">/tamil-school</field>
<field name="view_id" ref="view_page_tamil_school"/>
<field name="is_published">True</field>
</record>
<!-- Sponsors -->
<record id="view_page_sponsors" model="ir.ui.view">
<field name="name">TNCSC Sponsors</field>
<field name="type">qweb</field>
<field name="key">tncsc_deployment.page_sponsors</field>
<field name="arch" type="xml">
<t t-name="tncsc_deployment.page_sponsors">
<t t-call="website.layout">
<div class="container" style="margin-top: 40px; margin-bottom: 60px;">
<h1>Our Sponsors</h1>
<p>Placeholder content - sponsor logos and tiers to be added.</p>
<a href="/benefits" class="btn btn-outline-secondary">See Member Benefits</a>
</div>
</t>
</t>
</field>
</record>
<record id="page_sponsors" model="website.page">
<field name="url">/sponsors</field>
<field name="view_id" ref="view_page_sponsors"/>
<field name="is_published">True</field>
</record>
<!-- Contact -->
<record id="view_page_contact" model="ir.ui.view">
<field name="name">TNCSC Contact</field>
<field name="type">qweb</field>
<field name="key">tncsc_deployment.page_contact</field>
<field name="arch" type="xml">
<t t-name="tncsc_deployment.page_contact">
<t t-call="website.layout">
<div class="container" style="margin-top: 40px; margin-bottom: 60px;">
<h1>Contact Us</h1>
<p>Email: <t t-out="env.company.email or ''"/></p>
<p>Placeholder content - add a real address, phone number, and contact form.</p>
</div>
</t>
</t>
</field>
</record>
<record id="page_contact" model="website.page">
<field name="url">/contact</field>
<field name="view_id" ref="view_page_contact"/>
<field name="is_published">True</field>
</record>
<!-- Main nav menu entries -->
<record id="menu_about" model="website.menu">
<field name="name">About</field>
<field name="url">/about</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence">10</field>
</record>
<record id="menu_tamil_school" model="website.menu">
<field name="name">Tamil School</field>
<field name="url">/tamil-school</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence">20</field>
</record>
<record id="menu_classifieds" model="website.menu">
<field name="name">Classifieds</field>
<field name="url">/classifieds</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence">30</field>
</record>
<record id="menu_benefits" model="website.menu">
<field name="name">Benefits</field>
<field name="url">/benefits</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence">40</field>
</record>
<record id="menu_sponsors" model="website.menu">
<field name="name">Sponsors</field>
<field name="url">/sponsors</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence">50</field>
</record>
<record id="menu_contact" model="website.menu">
<field name="name">Contact</field>
<field name="url">/contact</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence">60</field>
</record>
</odoo>