feat(portal): inject filter+search strip into Odoo /my/orders + docs

- views/fp_sale_order_portal.xml: new template inherit
  portal_my_orders_fp_search on sale.portal_my_orders. Injects the
  fp_portal_list_controls strip before the "no orders" alert. Filter
  pills + sort dropdown are disabled here (we don't own the route,
  Odoo's sortby is preserved separately). The search input is wired
  to .o_portal_my_doc_table tbody (the table class Odoo's
  portal.portal_table emits) so real-time keyword filtering works
  without needing to monkey-patch the stock route or template.

- CLAUDE.md: documents two conventions surfaced by the recent portal
  work:
    Rule 17 — test scaffolding for account.move creation must use
      with_context(fp_from_so_invoice=True) and pass
      invoice_payment_term_id, to satisfy custom gates in
      fusion_plating_jobs and fusion_plating_invoicing.
    Rule 18 — FP portal list pages don't paginate. They load up to
      500 records and rely on fp_portal_list_search.js to filter
      client-side. Hidden <td class="d-none"> cells per row carry
      extra searchable text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-18 00:06:26 -04:00
parent b27f68b8d5
commit f8fc6be370
2 changed files with 40 additions and 0 deletions

View File

@@ -14,6 +14,41 @@
-->
<odoo>
<!-- ================================================================== -->
<!-- /my/orders — inject filter strip + data-fp-filterable before the -->
<!-- Odoo portal table so real-time search works client-side. -->
<!-- Sort dropdown reuses Odoo's existing sortby param; filter pills -->
<!-- link to URL params that Odoo's stock route honours natively. -->
<!-- ================================================================== -->
<template id="portal_my_orders_fp_search"
inherit_id="sale.portal_my_orders"
priority="50">
<!-- Inject the controls strip right after the portal_searchbar call
and before the "no orders" alert / portal_table. The anchor is
the <div t-if="not orders"> alert — we inject before it. -->
<xpath expr="//div[@t-if='not orders']" position="before">
<t t-call="fusion_plating_portal.fp_portal_list_controls">
<t t-set="filters" t-value="False"/>
<t t-set="active_filter" t-value="'all'"/>
<t t-set="sorts" t-value="False"/>
<t t-set="active_sort" t-value="'date'"/>
<t t-set="search" t-value="''"/>
<t t-set="url" t-value="'/my/orders'"/>
<t t-set="extra_qs" t-value="''"/>
<!-- Odoo's portal.portal_table emits a <table class="o_portal_my_doc_table">
so we don't need to add our own id; the JS just needs a stable selector. -->
<t t-set="target" t-value="'.o_portal_my_doc_table tbody'"/>
<t t-set="result_total" t-value="orders|length if orders else 0"/>
<t t-set="clipped" t-value="False"/>
</t>
</xpath>
</template>
<!-- ================================================================== -->
<!-- Sale order portal content: add Part # column -->
<!-- ================================================================== -->
<template id="sale_order_portal_content_fp_part_column"
inherit_id="sale.sale_order_portal_content">