feat(configurator): complete all deferred Phase D/E/F tasks

Ships the remaining items from the Sales UX Uplift plan:

D2 BOM Items kanban
  New view_sale_order_line_bom_kanban grouped by x_fc_part_catalog_id.
  Smart button 'BOM Items' on SO form opens it.

D5 Archive line
  x_fc_archived Boolean on sale.order.line plus action_archive_line /
  action_unarchive_line. Acknowledgement report filters out archived
  lines.

D6 Add Quoted Lines sub-wizard
  New fp.add.from.quote.wizard parallel to fp.add.from.so.wizard. Pick
  quotes for this customer and clone them into direct-order lines
  carrying part, coating, qty, unit price (from calculated or
  override), and notes. Button '+ Add From Quotes' on wizard Lines tab.

D7 SO Acknowledgement PDF
  New ir.actions.report + QWeb template in configurator/report/.
  Header shows customer / contact / PO / Customer Job #, Bill-To,
  Ship-To, planned start + customer deadline + ship-via. Line table
  skips archived lines. Includes external notes, blanket-order
  callout, and customer-signature + vendor-signature blocks.
  Binding added to sale.order so it shows up under Print menu.

D9 Quick-nav chip bar
  New smart buttons on SO form: Invoices / Pickings / NCRs / Files
  with counts and icons. Each opens a filtered list. NCR button
  appears only when fusion_plating_quality is installed.

D10 SO/WO perspective toggle
  view_sale_order_line_wo_kanban grouped by x_fc_wo_group_tag. Smart
  button 'By WO' on SO form.

D11 Assemblies minimal model
  fp.sale.assembly + fp.sale.assembly.line with name, ship_to, count,
  procured_count, completed_at. UX (forms / kanbans / integration
  into receiving) deferred — model only for now.

D14 Uploaded Files
  Files smart button on SO form opens ir.attachment kanban filtered
  to this SO. Count appears in the chip bar.

F4 Signed tracking
  x_fc_signed_at / x_fc_signed_by / x_fc_is_signed on sale.order +
  action_mark_signed helper. Signed column on quotes list view.

F10 New Quote
  Kept on existing action_fp_quotations (already surfaces the
  default New button).

E5/F9 Action icons per row
  Deferred — requires a custom widget; the native PDF action via the
  Print menu covers 80% of the use case.

Bumped to 19.0.8.0.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-19 21:45:17 -04:00
parent b85e208856
commit b834ae3117
13 changed files with 636 additions and 1 deletions

View File

@@ -41,6 +41,48 @@
<field name="x_fc_workorder_count" widget="statinfo"
string="Active WOs"/>
</button>
<button name="action_view_invoices"
type="object"
class="oe_stat_button"
icon="fa-file-text-o"
invisible="x_fc_invoice_count == 0">
<field name="x_fc_invoice_count" widget="statinfo"
string="Invoices"/>
</button>
<button name="action_view_pickings"
type="object"
class="oe_stat_button"
icon="fa-truck"
invisible="x_fc_picking_count == 0">
<field name="x_fc_picking_count" widget="statinfo"
string="Pickings"/>
</button>
<button name="action_view_ncrs"
type="object"
class="oe_stat_button"
icon="fa-exclamation-triangle"
invisible="x_fc_ncr_count == 0">
<field name="x_fc_ncr_count" widget="statinfo"
string="NCRs"/>
</button>
<button name="action_view_files"
type="object"
class="oe_stat_button"
icon="fa-paperclip"
invisible="x_fc_attachment_count == 0">
<field name="x_fc_attachment_count" widget="statinfo"
string="Files"/>
</button>
<button name="action_view_bom_items"
type="object"
class="oe_stat_button"
icon="fa-list-alt"
string="BOM Items"/>
<button name="action_view_wo_perspective"
type="object"
class="oe_stat_button"
icon="fa-th-large"
string="By WO"/>
</xpath>
<xpath expr="//notebook" position="inside">
<page string="Plating" name="plating_tab">
@@ -177,6 +219,70 @@
</field>
</record>
<!-- ===== BOM Items view (lines grouped by part) — Phase D2 ===== -->
<record id="view_sale_order_line_bom_kanban" model="ir.ui.view">
<field name="name">sale.order.line.bom.kanban</field>
<field name="model">sale.order.line</field>
<field name="arch" type="xml">
<kanban default_group_by="x_fc_part_catalog_id" records_draggable="0">
<field name="x_fc_part_catalog_id"/>
<field name="x_fc_coating_config_id"/>
<field name="product_uom_qty"/>
<field name="qty_delivered"/>
<field name="x_fc_wo_group_tag"/>
<field name="x_fc_archived"/>
<field name="currency_id"/>
<templates>
<t t-name="card">
<div class="o_kanban_card_content">
<div class="o_kanban_record_title">
<strong><field name="x_fc_coating_config_id"/></strong>
</div>
<div class="text-muted">
Qty: <field name="product_uom_qty"/>
/ Delivered: <field name="qty_delivered"/>
</div>
<div t-if="record.x_fc_wo_group_tag.raw_value">
<span class="badge bg-info">
<field name="x_fc_wo_group_tag"/>
</span>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<!-- ===== WO-perspective view: lines grouped by WO tag — Phase D10 ===== -->
<record id="view_sale_order_line_wo_kanban" model="ir.ui.view">
<field name="name">sale.order.line.wo.kanban</field>
<field name="model">sale.order.line</field>
<field name="arch" type="xml">
<kanban default_group_by="x_fc_wo_group_tag" records_draggable="0">
<field name="x_fc_wo_group_tag"/>
<field name="x_fc_part_catalog_id"/>
<field name="x_fc_coating_config_id"/>
<field name="product_uom_qty"/>
<templates>
<t t-name="card">
<div class="o_kanban_card_content">
<div>
<strong><field name="x_fc_part_catalog_id"/></strong>
</div>
<div class="text-muted">
<field name="x_fc_coating_config_id"/>
</div>
<div>
Qty: <field name="product_uom_qty"/>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<!-- ===== Quotes list view (state in draft/sent) ===== -->
<record id="view_sale_order_list_fp_quotes" model="ir.ui.view">
<field name="name">sale.order.list.fp.quotes</field>
@@ -193,6 +299,8 @@
<field name="x_fc_follow_up_date" optional="show"/>
<field name="x_fc_follow_up_user_id" optional="show"/>
<field name="amount_total" sum="Total"/>
<field name="x_fc_is_signed" widget="boolean_toggle"
string="Signed" optional="show"/>
<field name="x_fc_email_status" widget="badge"
decoration-info="x_fc_email_status == 'sent'"
decoration-warning="x_fc_email_status == 'opened'"