Odoo 19's `ir.actions.actions._get_bindings` returns the print-menu bindings via `ORDER BY a.id` (insertion order) and only sequence-sorts the `action`-type bindings — `report`-type bindings are returned in raw SQL order. Result: FP reports installed after Odoo's stock ones appear at the BOTTOM of the dropdown, even when they're the customer-facing primary report (e.g. Timesheets above Quotation on sale.order). Two changes in fusion_plating_reports/models/ir_actions_report.py: 1. **Add `sequence` (Integer, default 100) to ir.actions.report** — gives every report a sortable knob. 2. **Override `ir.actions.actions._get_bindings`** to also sort the `report` slice by `(sequence, name.lower())`. super() returns the cached frozendict; we rebuild with the sorted reports. Then set sequences in fp_hide_default_reports.xml (lower = top): | Model | seq 10 (#1) | seq 15 (#2) | seq 20+ | |-----------------|--------------------------|--------------------------|-----------------------| | sale.order | FP Quotation Portrait | FP Quotation Landscape | FP Job Traveller (20) | | account.move | FP Invoice Portrait | FP Invoice Landscape | | | stock.picking | FP Packing Slip Portrait | FP Packing Slip Landscape| | | mrp.production | FP Job Traveller Portrait| FP Job Traveller Landscape| FP WO Margin (20) | | account.payment | FP Receipt Portrait | FP Receipt Landscape | | | fp.delivery | FP BoL Portrait | FP BoL Landscape | | | portal.job | FP CoC Portrait | FP CoC Landscape | | | fp.certificate | FP CoC English | FP CoC Français | | Odoo defaults stay at sequence 100 (default) → always at bottom. Verified on entech: sale.order print menu now shows Quotation Portrait → Quotation Landscape → Job Traveller × 2 → PRO-FORMA → Timesheets. Same pattern across all touched models. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
25 lines
1.1 KiB
Python
25 lines
1.1 KiB
Python
env = env # noqa
|
|
# Use the SAME path the web client uses (the cog menu) — _get_bindings.
|
|
# This honours the new sequence-based sort we just added.
|
|
MODELS = ['sale.order', 'account.move', 'stock.picking', 'mrp.production',
|
|
'fusion.plating.delivery', 'account.payment', 'fusion.plating.portal.job',
|
|
'fp.certificate']
|
|
Actions = env['ir.actions.actions']
|
|
Actions.clear_caches() if hasattr(Actions, 'clear_caches') else env.registry.clear_cache()
|
|
for m in MODELS:
|
|
bindings = Actions._get_bindings(m)
|
|
reports = bindings.get('report', ())
|
|
if not reports:
|
|
continue
|
|
print(f'\\n=== {m} (top→bottom in Print menu) ===')
|
|
for i, r in enumerate(reports, 1):
|
|
# Get xmlid
|
|
xmlids = env['ir.model.data'].search([
|
|
('model', '=', 'ir.actions.report'), ('res_id', '=', r['id'])
|
|
])
|
|
xmlid = ', '.join(f'{x.module}.{x.name}' for x in xmlids) or '(no xmlid)'
|
|
is_fp = 'fusion_plating' in xmlid
|
|
marker = '★' if is_fp else ' '
|
|
seq = r.get('sequence', 100)
|
|
print(f' {marker} {i:>2}. seq={seq:<4} {r["name"]}')
|