metatroncubeswdev 24be6360e2 feat(tncsc_deployment): migrate real tncsc.com content into the website pages
Replaces the Phase 7 "content to be finalized" placeholder pages with
TNCSC's actual site content (captured 2026-08-20), verified against a
live Odoo container on a dedicated fresh database (tncsc_site):

- Home, About, About/Tamil Nadu, About/Board of Directors (12 real
  members), Membership hub, Membership Benefits, Tamil Class, and
  Contact pages, with nav restructured to match tncsc.com's real
  structure (About and Membership as dropdowns).
- Real images downloaded from tncsc.com and self-hosted under
  static/src/img/ instead of hotlinking the WordPress site.
- Home's "Upcoming Events" and the membership pricing tables are wired
  to live event.event / community.membership.tier records instead of
  being static copies; Tamil Class links to the real /school/register
  flow. One real event seeded (Summer Picnic 2026).
- Deliberately not reproduced: tncsc.com's own Sponsors page and Contact
  phone number are unmigrated WordPress theme demo placeholders on the
  live site itself (generic client-01..09 logos, a non-Canadian demo
  number) - confirmed by inspection, not assumed. Contact page uses the
  real, verified email and social links instead.
- post_init_hook now also fixes two Odoo website Copy-On-Write gotchas
  that silently prevented the new homepage and nav dropdowns from
  rendering at all (auto-forked per-website duplicates winning over
  this module's records) - see HANDOFF.md for the full explanation.
2026-08-20 12:32:59 -04:00

89 lines
3.7 KiB
Python

from . import models
def post_init_hook(env):
"""Best-effort immediate attempt at the accounting bootstrap. The daily
cron in data/ir_cron.xml (calling the same idempotent method from a
separate transaction) is what guarantees eventual correctness - see
models/res_company.py for why a single call from within this hook's own
transaction isn't reliable on this Odoo build.
"""
env.company._tncsc_setup_accounting()
_remove_stock_homepage_page(env)
_fix_website_menus(env)
def _remove_stock_homepage_page(env):
"""The website module auto-creates its own website-bound "homepage"
page/view (key 'website.homepage') for every website, independently of
this module. That page ties on priority with data/../views/website_pages.xml's
own website-bound page_home record (same url "/", same website_id) -
confirmed empirically against a live container that the url "/" route
(unlike every other page url) only resolves a website-bound page, so an
unbound generic page or an inherited view has no effect here, and on a
tie the stock page wins by insertion order (it's created before this
module installs). Removing it is what makes page_home actually serve.
"""
website = env.ref('website.default_website', raise_if_not_found=False)
if not website:
return
stock_view = env['ir.ui.view'].sudo().search([
('key', '=', 'website.homepage'),
('website_id', '=', website.id),
])
stock_page = env['website.page'].sudo().search([
('url', '=', '/'),
('website_id', '=', website.id),
('view_id', 'in', stock_view.ids),
])
# unlinking the page cascades to its underlying view - unlinking the
# (already-cascaded) view afterward would raise a MissingError.
stock_page.unlink()
# xmlid (without module prefix) of each top-level nav entry -> xmlids of its
# children, as declared in views/website_pages.xml.
_MENU_TREE = {
'menu_home': [],
'menu_about': ['menu_about_tamil_nadu', 'menu_about_board'],
'menu_events': [],
'menu_membership': ['menu_membership_benefits', 'menu_membership_registration'],
'menu_tamil_class': [],
'menu_contact': [],
}
def _fix_website_menus(env):
"""Same Copy-On-Write pattern as _remove_stock_homepage_page, applied to
website.menu: the website module auto-forks its own website-bound copy
of the top nav tree (a "Top Menu for Website <n>" record, referenced by
website.menu_id) independently of this module. website_pages.xml's menu
records attach to the generic tree (website.main_menu) instead, so they
never render, while Odoo's auto-forked copy renders as flat top-level
items with none of our children - confirmed empirically against a live
container. Fix: re-parent our records onto the actual rendered tree, and
drop every other child Odoo forked there so only ours show.
"""
website = env.ref('website.default_website', raise_if_not_found=False)
if not website:
return
root = website.menu_id
if not root:
return
mine = env['website.menu']
for top_xmlid, child_xmlids in _MENU_TREE.items():
top_menu = env.ref(f'tncsc_deployment.{top_xmlid}', raise_if_not_found=False)
if not top_menu:
continue
top_menu.write({'website_id': website.id, 'parent_id': root.id})
mine |= top_menu
for child_xmlid in child_xmlids:
child_menu = env.ref(f'tncsc_deployment.{child_xmlid}', raise_if_not_found=False)
if child_menu:
child_menu.write({'website_id': website.id, 'parent_id': top_menu.id})
mine |= child_menu
stray = env['website.menu'].sudo().search([('parent_id', '=', root.id), ('id', 'not in', mine.ids)])
stray.unlink()