diff --git a/fusion_plating/fusion_plating_reports/__manifest__.py b/fusion_plating/fusion_plating_reports/__manifest__.py
index 5cd85d9b..b6522b47 100644
--- a/fusion_plating/fusion_plating_reports/__manifest__.py
+++ b/fusion_plating/fusion_plating_reports/__manifest__.py
@@ -3,7 +3,7 @@
# License OPL-1 (Odoo Proprietary License v1.0)
{
'name': 'Fusion Plating — Reports',
- 'version': '19.0.4.8.0',
+ 'version': '19.0.4.9.0',
'category': 'Manufacturing/Plating',
'summary': 'PDF reports for Fusion Plating: quote, SO, WO, packing, BoL, CoC, invoice, receipt, quality + compliance.',
'depends': [
diff --git a/fusion_plating/fusion_plating_reports/data/fp_hide_default_reports.xml b/fusion_plating/fusion_plating_reports/data/fp_hide_default_reports.xml
index 80425cb6..454af898 100644
--- a/fusion_plating/fusion_plating_reports/data/fp_hide_default_reports.xml
+++ b/fusion_plating/fusion_plating_reports/data/fp_hide_default_reports.xml
@@ -82,4 +82,86 @@
action
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fusion_plating/fusion_plating_reports/models/__init__.py b/fusion_plating/fusion_plating_reports/models/__init__.py
index ce5ec001..58b57c14 100644
--- a/fusion_plating/fusion_plating_reports/models/__init__.py
+++ b/fusion_plating/fusion_plating_reports/models/__init__.py
@@ -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
diff --git a/fusion_plating/fusion_plating_reports/models/ir_actions_report.py b/fusion_plating/fusion_plating_reports/models/ir_actions_report.py
new file mode 100644
index 00000000..bfff5644
--- /dev/null
+++ b/fusion_plating/fusion_plating_reports/models/ir_actions_report.py
@@ -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)
diff --git a/fusion_plating/scripts/fp_print_order.py b/fusion_plating/scripts/fp_print_order.py
new file mode 100644
index 00000000..fd4d2233
--- /dev/null
+++ b/fusion_plating/scripts/fp_print_order.py
@@ -0,0 +1,24 @@
+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"]}')