feat(reports): sequence-sort the Print dropdown so FP reports are #1
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>
This commit is contained in:
@@ -3,4 +3,5 @@
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
# Part of the Fusion Plating product family.
|
||||
|
||||
from . import ir_actions_report
|
||||
from . import report_wo_margin
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
# Part of the Fusion Plating product family.
|
||||
"""Patch ir.actions.report so the Print dropdown can be ordered.
|
||||
|
||||
Odoo 19 fetches print-menu bindings via `ir.actions.actions._get_bindings`
|
||||
which returns reports in `ORDER BY a.id` (insertion order). Only the
|
||||
`action` bindings get a sequence sort applied — `report` bindings are
|
||||
returned in the raw SQL order. Result: third-party FP reports installed
|
||||
after Odoo's stock ones always appear at the BOTTOM of the dropdown,
|
||||
even when they're the customer-facing primary report.
|
||||
|
||||
Two changes:
|
||||
1. Add a `sequence` Integer field to ir.actions.report.
|
||||
2. Override `_get_bindings` to also sort report bindings by sequence
|
||||
(then by name as a tie-breaker), matching the behaviour Odoo
|
||||
already applies to action bindings.
|
||||
|
||||
Lower sequence = appears higher in the Print dropdown.
|
||||
"""
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools import frozendict
|
||||
|
||||
|
||||
class IrActionsReport(models.Model):
|
||||
_inherit = 'ir.actions.report'
|
||||
|
||||
sequence = fields.Integer(
|
||||
default=100,
|
||||
help='Order in which this report appears in the Print menu '
|
||||
'(lower = higher in the list). Default 100 leaves room '
|
||||
'for both higher and lower priorities.',
|
||||
)
|
||||
|
||||
|
||||
class IrActionsActions(models.Model):
|
||||
_inherit = 'ir.actions.actions'
|
||||
|
||||
@api.model
|
||||
def _get_bindings(self, model_name):
|
||||
# super() returns a cached frozendict via @tools.ormcache; we
|
||||
# re-sort the 'report' slice (Odoo already sorts 'action').
|
||||
result = super()._get_bindings(model_name)
|
||||
if not result.get('report'):
|
||||
return result
|
||||
sorted_reports = tuple(sorted(
|
||||
result['report'],
|
||||
key=lambda vals: (
|
||||
vals.get('sequence', 100),
|
||||
(vals.get('name') or '').lower(),
|
||||
),
|
||||
))
|
||||
# frozendict is immutable — rebuild from a plain dict.
|
||||
new_result = dict(result)
|
||||
new_result['report'] = sorted_reports
|
||||
return frozendict(new_result)
|
||||
Reference in New Issue
Block a user