Replace em-dashes and en-dashes with hyphens across 789 shipped source files (py/xml/js/scss) so the delivered module reads as human-written; em-dashes had become a recognizable AI-generated tell. Internal .md dev notes are excluded. The WO-sticker mojibake strippers keep their dash search targets (now written — / –). No logic changes: comments and display strings only; validated with py_compile + lxml parse. Rewrite the 7 customer notification emails to be intake-neutral (ship-in / drop-off / pickup) and repair-aware, and fix the Shipped email documents line (packing slip vs bill of lading; certificate only when issued). Subjects use a hyphen separator. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
146 lines
6.7 KiB
XML
146 lines
6.7 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!--
|
|
Copyright 2026 Nexa Systems Inc.
|
|
License OPL-1 (Odoo Proprietary License v1.0)
|
|
Box-level tracking - fp.box list / form / search / kanban + menu.
|
|
-->
|
|
<odoo>
|
|
|
|
<!-- ===== List ===== -->
|
|
<record id="fp_box_view_list" model="ir.ui.view">
|
|
<field name="name">fp.box.list</field>
|
|
<field name="model">fp.box</field>
|
|
<field name="arch" type="xml">
|
|
<list string="Boxes" decoration-muted="state in ('shipped','cancelled')" decoration-danger="state == 'lost'">
|
|
<field name="box_number"/>
|
|
<field name="box_count"/>
|
|
<field name="name"/>
|
|
<field name="sale_order_id"/>
|
|
<field name="partner_id"/>
|
|
<field name="job_id"/>
|
|
<field name="location_note"/>
|
|
<field name="state" widget="badge"
|
|
decoration-info="state == 'received'"
|
|
decoration-warning="state in ('racked','in_process','packed')"
|
|
decoration-success="state == 'shipped'"
|
|
decoration-danger="state == 'lost'"/>
|
|
</list>
|
|
</field>
|
|
</record>
|
|
|
|
<!-- ===== Form ===== -->
|
|
<record id="fp_box_view_form" model="ir.ui.view">
|
|
<field name="name">fp.box.form</field>
|
|
<field name="model">fp.box</field>
|
|
<field name="arch" type="xml">
|
|
<form>
|
|
<header>
|
|
<button name="action_set_racked" type="object" string="Mark Racked"
|
|
class="btn-primary" invisible="state != 'received'"/>
|
|
<button name="action_set_in_process" type="object" string="Mark In Process"
|
|
class="btn-primary" invisible="state != 'racked'"/>
|
|
<button name="action_set_packed" type="object" string="Mark Packed"
|
|
class="btn-primary" invisible="state != 'in_process'"/>
|
|
<button name="action_set_shipped" type="object" string="Mark Shipped"
|
|
class="btn-primary" invisible="state != 'packed'"/>
|
|
<button name="action_set_lost" type="object" string="Flag Lost"
|
|
invisible="state in ('shipped','lost','cancelled')"/>
|
|
<button name="action_reset_received" type="object" string="Reset to Received"
|
|
groups="fusion_plating.group_fp_shop_manager_v2"
|
|
invisible="state == 'received'"/>
|
|
<field name="state" widget="statusbar"
|
|
statusbar_visible="received,racked,in_process,packed,shipped"/>
|
|
</header>
|
|
<sheet>
|
|
<div class="oe_title">
|
|
<h1><field name="name" readonly="1"/></h1>
|
|
</div>
|
|
<group>
|
|
<group>
|
|
<label for="box_number" string="Box"/>
|
|
<div>
|
|
<field name="box_number" class="oe_inline"/> /
|
|
<field name="box_count" class="oe_inline"/>
|
|
</div>
|
|
<field name="receiving_id"/>
|
|
<field name="sale_order_id"/>
|
|
<field name="job_id"/>
|
|
</group>
|
|
<group>
|
|
<field name="partner_id"/>
|
|
<field name="location_note"/>
|
|
<field name="scan_url" widget="url" readonly="1"/>
|
|
<field name="company_id" groups="base.group_multi_company"/>
|
|
</group>
|
|
</group>
|
|
</sheet>
|
|
<chatter/>
|
|
</form>
|
|
</field>
|
|
</record>
|
|
|
|
<!-- ===== Search ===== -->
|
|
<record id="fp_box_view_search" model="ir.ui.view">
|
|
<field name="name">fp.box.search</field>
|
|
<field name="model">fp.box</field>
|
|
<field name="arch" type="xml">
|
|
<search>
|
|
<field name="name"/>
|
|
<field name="sale_order_id"/>
|
|
<field name="partner_id"/>
|
|
<field name="job_id"/>
|
|
<field name="receiving_id"/>
|
|
<filter name="open" string="Open (not shipped)" domain="[('state','not in',('shipped','cancelled'))]"/>
|
|
<filter name="received" string="Received" domain="[('state','=','received')]"/>
|
|
<filter name="in_process" string="In Process" domain="[('state','in',('racked','in_process','packed'))]"/>
|
|
<filter name="shipped" string="Shipped" domain="[('state','=','shipped')]"/>
|
|
<filter name="lost" string="Lost" domain="[('state','=','lost')]"/>
|
|
<group>
|
|
<filter name="g_state" string="Status" context="{'group_by':'state'}"/>
|
|
<filter name="g_customer" string="Customer" context="{'group_by':'partner_id'}"/>
|
|
<filter name="g_receiving" string="Receiving" context="{'group_by':'receiving_id'}"/>
|
|
</group>
|
|
</search>
|
|
</field>
|
|
</record>
|
|
|
|
<!-- ===== Kanban (by status) ===== -->
|
|
<record id="fp_box_view_kanban" model="ir.ui.view">
|
|
<field name="name">fp.box.kanban</field>
|
|
<field name="model">fp.box</field>
|
|
<field name="arch" type="xml">
|
|
<kanban default_group_by="state" class="o_kanban_small_column">
|
|
<field name="state"/>
|
|
<templates>
|
|
<t t-name="card">
|
|
<div class="oe_kanban_content">
|
|
<strong><field name="name"/></strong>
|
|
<div><field name="partner_id"/></div>
|
|
<div t-if="record.location_note.raw_value">
|
|
<span class="text-muted">@ </span><field name="location_note"/>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</templates>
|
|
</kanban>
|
|
</field>
|
|
</record>
|
|
|
|
<!-- ===== Action ===== -->
|
|
<record id="action_fp_box" model="ir.actions.act_window">
|
|
<field name="name">Boxes</field>
|
|
<field name="res_model">fp.box</field>
|
|
<field name="view_mode">list,kanban,form</field>
|
|
<field name="search_view_id" ref="fp_box_view_search"/>
|
|
<field name="context">{'search_default_open': 1}</field>
|
|
</record>
|
|
|
|
<!-- ===== Menu ===== -->
|
|
<menuitem id="menu_fp_box"
|
|
name="Boxes"
|
|
parent="menu_fp_receiving_root"
|
|
action="action_fp_box"
|
|
sequence="35"/>
|
|
|
|
</odoo>
|