chore(plating): de-dash shipped code + intake-neutral customer emails

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>
This commit is contained in:
gsinghpal
2026-06-05 00:16:19 -04:00
parent c9eb61ee0c
commit 8c76a16366
789 changed files with 4692 additions and 4692 deletions

View File

@@ -4,7 +4,7 @@
# Part of the Fusion Plating product family.
{
'name': 'Fusion Plating Controlled Goods Program',
'name': 'Fusion Plating - Controlled Goods Program',
'version': '19.0.1.2.3',
'category': 'Manufacturing/Plating',
'summary': 'Canadian Controlled Goods Program (CGP) compliance for plating '
@@ -12,7 +12,7 @@
'personnel security assessments, visitor control, controlled goods '
'log, security incidents.',
'description': """
Fusion Plating Controlled Goods Program (CGP)
Fusion Plating - Controlled Goods Program (CGP)
===============================================
Part of the Fusion Plating product family by Nexa Systems Inc.
@@ -27,21 +27,21 @@ manager's view.
Records included
----------------
* CGP Registration company registration with PSPC, 5-year renewal cycle
* Authorized Individuals AI appointment, training, PSA linkage
* Personnel Security Assessments (PSA) restricted to CGP Officer+
* Visitor Control PSA-on-file check, escort, approval
* Controlled Goods Inventory what the shop actually handles
* Receipts & Shipments movement log with AI authorization
* Security Incidents breach reporting, PSPC notification (restricted)
* Physical Access Log entry / exit of controlled areas
* Security Plan seeded as a doc.control template
* CGP Registration - company registration with PSPC, 5-year renewal cycle
* Authorized Individuals - AI appointment, training, PSA linkage
* Personnel Security Assessments (PSA) - restricted to CGP Officer+
* Visitor Control - PSA-on-file check, escort, approval
* Controlled Goods Inventory - what the shop actually handles
* Receipts & Shipments - movement log with AI authorization
* Security Incidents - breach reporting, PSPC notification (restricted)
* Physical Access Log - entry / exit of controlled areas
* Security Plan - seeded as a doc.control template
Security model
--------------
A new restricted group ``CGP Officer`` is introduced on top of the core
Fusion Plating privilege. PSA and Security Incident records are visible
ONLY to the CGP Officer and the CGP Designated Official not to the
ONLY to the CGP Officer and the CGP Designated Official - not to the
generic manager role, because not every manager should see personnel
assessments. Admin must grant the new group manually; no user is
assigned by default.

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2026 Nexa Systems Inc. DEMO DATA (temporary)
Copyright 2026 Nexa Systems Inc. - DEMO DATA (temporary)
Remove this file and its manifest entry before production release.
-->
<odoo noupdate="1">
<!-- ========== CGP REGISTRATION ========== -->
<record id="demo_cgp_registration" model="fusion.plating.cgp.registration">
<field name="name">Fusion Plating Main CGP Registration</field>
<field name="name">Fusion Plating Main - CGP Registration</field>
<field name="registration_number">CGP-2024-0012</field>
<field name="state">registered</field>
<field name="registration_date" eval="(DateTime.today() - timedelta(days=730)).strftime('%Y-%m-%d')"/>
@@ -20,21 +20,21 @@
<!-- ========== CONTROLLED GOODS ========== -->
<record id="demo_controlled_good_001" model="fusion.plating.cgp.controlled.good">
<field name="name">CF-188 Hornet Main Landing Gear Strut (Group 2)</field>
<field name="name">CF-188 Hornet - Main Landing Gear Strut (Group 2)</field>
<field name="schedule_category">Group 2: Munitions</field>
<field name="customer_id" ref="fusion_plating.demo_partner_aeroparts"/>
<field name="current_quantity">6</field>
<field name="location">Controlled Area A Rack 3</field>
<field name="location">Controlled Area A - Rack 3</field>
<field name="state">in_process</field>
<field name="description" type="html"><p>Hard chrome plating on main landing gear strut per DND spec. Parts received under controlled goods receipt CGR-2026-041.</p></field>
</record>
<record id="demo_controlled_good_002" model="fusion.plating.cgp.controlled.good">
<field name="name">LAV III Hull Component Mounting Bracket</field>
<field name="name">LAV III Hull Component - Mounting Bracket</field>
<field name="schedule_category">Group 2: Munitions</field>
<field name="customer_id" ref="fusion_plating.demo_partner_precision"/>
<field name="current_quantity">24</field>
<field name="location">Controlled Area B Shelf 7</field>
<field name="location">Controlled Area B - Shelf 7</field>
<field name="state">in_storage</field>
<field name="description" type="html"><p>EN plated mounting brackets awaiting final inspection and shipment. Stored under controlled conditions per Security Plan.</p></field>
</record>
@@ -54,7 +54,7 @@
<record id="demo_cgp_visitor_002" model="fusion.plating.cgp.visitor">
<field name="name">Patricia Nguyen</field>
<field name="company_represented">General Dynamics Land Systems Canada</field>
<field name="company_represented">General Dynamics Land Systems - Canada</field>
<field name="visit_date" eval="(DateTime.now() - timedelta(days=3)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="visit_end" eval="(DateTime.now() - timedelta(days=3) + timedelta(hours=4)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="purpose">Source inspection of LAV III mounting bracket lot prior to shipment.</field>
@@ -73,7 +73,7 @@
<field name="severity">minor</field>
<field name="state">investigating</field>
<field name="description" type="html"><p>Maintenance contractor entered Controlled Area B without signing the visitor log or obtaining AI authorization. Contractor was performing scheduled HVAC filter replacement and was unaware of the controlled-area boundary. No controlled goods were accessed or moved.</p></field>
<field name="containment" type="html"><p>Contractor escorted out of controlled area immediately. Badge access log reviewed to confirm no other unauthorized entries. Controlled goods inventory verified no discrepancies.</p></field>
<field name="containment" type="html"><p>Contractor escorted out of controlled area immediately. Badge access log reviewed to confirm no other unauthorized entries. Controlled goods inventory verified - no discrepancies.</p></field>
</record>
</odoo>

View File

@@ -15,7 +15,7 @@ class FpCgpAccessLog(models.Model):
control system; this model is the lightweight hand-entry fallback.
"""
_name = 'fusion.plating.cgp.access.log'
_description = 'Fusion Plating CGP Access Log Entry'
_description = 'Fusion Plating - CGP Access Log Entry'
_order = 'access_datetime desc, id desc'
employee_id = fields.Many2one(

View File

@@ -16,7 +16,7 @@ class FpCgpAuthorizedIndividual(models.Model):
before granting access.
"""
_name = 'fusion.plating.cgp.authorized.individual'
_description = 'Fusion Plating CGP Authorized Individual'
_description = 'Fusion Plating - CGP Authorized Individual'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'appointment_date desc, id desc'
_rec_name = 'name'

View File

@@ -10,13 +10,13 @@ class FpCgpControlledGood(models.Model):
"""Inventory of controlled goods currently handled by the shop.
This is intentionally a lightweight, hand-maintained register of what
the shop actually processes parts, assemblies, or materials that
the shop actually processes - parts, assemblies, or materials that
fall under the Schedule to the Defence Production Act. It is not a
replacement for the Odoo stock module; it is the CGP-specific audit
trail that an AI can show a PSPC inspector.
"""
_name = 'fusion.plating.cgp.controlled.good'
_description = 'Fusion Plating Controlled Good'
_description = 'Fusion Plating - Controlled Good'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'name'

View File

@@ -11,7 +11,7 @@ from odoo import api, fields, models
class FpCgpPsa(models.Model):
"""Personnel Security Assessment.
Every person employee, contractor, or long-term visitor who has
Every person - employee, contractor, or long-term visitor - who has
access to controlled goods must have a current Personnel Security
Assessment on file. PSAs are valid for up to five years and include
a review of citizenship, criminal record, and loyalty considerations.
@@ -21,7 +21,7 @@ class FpCgpPsa(models.Model):
manager cannot see personnel assessments.
"""
_name = 'fusion.plating.cgp.psa'
_description = 'Fusion Plating Personnel Security Assessment'
_description = 'Fusion Plating - Personnel Security Assessment'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'assessment_date desc, id desc'
@@ -65,7 +65,7 @@ class FpCgpPsa(models.Model):
)
notes = fields.Html(
string='Internal Notes',
help='Internal notes restricted to CGP Officer and above.',
help='Internal notes - restricted to CGP Officer and above.',
)
document_ids = fields.Many2many(
'ir.attachment',

View File

@@ -14,7 +14,7 @@ class FpCgpReceiptShipment(models.Model):
border shipments additionally require an export permit reference.
"""
_name = 'fusion.plating.cgp.receipt.shipment'
_description = 'Fusion Plating CGP Receipt / Shipment'
_description = 'Fusion Plating - CGP Receipt / Shipment'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'date desc, id desc'

View File

@@ -19,7 +19,7 @@ class FpCgpRegistration(models.Model):
so this record lives on ``res.company``.
"""
_name = 'fusion.plating.cgp.registration'
_description = 'Fusion Plating CGP Registration'
_description = 'Fusion Plating - CGP Registration'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'registration_date desc, id desc'
@@ -27,7 +27,7 @@ class FpCgpRegistration(models.Model):
string='Reference',
required=True,
tracking=True,
help='Label for this registration, e.g. "Acme Plating CGP Reg."',
help='Label for this registration, e.g. "Acme Plating - CGP Reg."',
)
company_id = fields.Many2one(
'res.company',

View File

@@ -10,13 +10,13 @@ class FpCgpSecurityIncident(models.Model):
"""Security incident or breach under the Controlled Goods Program.
Any event that could have compromised the security of controlled
goods unauthorized access, a missing item, a visitor violation,
a cyber intrusion must be investigated and, depending on
goods - unauthorized access, a missing item, a visitor violation,
a cyber intrusion - must be investigated and, depending on
severity, reported to PSPC. Incident records are restricted via
``ir.rule`` to the CGP Officer and above.
"""
_name = 'fusion.plating.cgp.security.incident'
_description = 'Fusion Plating CGP Security Incident'
_description = 'Fusion Plating - CGP Security Incident'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'incident_date desc, id desc'

View File

@@ -15,7 +15,7 @@ class FpCgpVisitor(models.Model):
controlled goods under very specific conditions.
"""
_name = 'fusion.plating.cgp.visitor'
_description = 'Fusion Plating CGP Visitor'
_description = 'Fusion Plating - CGP Visitor'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'visit_date desc, id desc'

View File

@@ -57,7 +57,7 @@
<!-- PSA: only visible to CGP Officer (and implied groups above) -->
<record id="fp_cgp_psa_officer_rule" model="ir.rule">
<field name="name">Fusion Plating: CGP PSA CGP Officer full access</field>
<field name="name">Fusion Plating: CGP PSA - CGP Officer full access</field>
<field name="model_id" ref="model_fusion_plating_cgp_psa"/>
<field name="groups"
eval="[(4, ref('group_fusion_plating_cgp_officer'))]"/>
@@ -70,7 +70,7 @@
<!-- Security Incident: only visible to CGP Officer -->
<record id="fp_cgp_incident_officer_rule" model="ir.rule">
<field name="name">Fusion Plating: CGP Security Incident CGP Officer full access</field>
<field name="name">Fusion Plating: CGP Security Incident - CGP Officer full access</field>
<field name="model_id" ref="model_fusion_plating_cgp_security_incident"/>
<field name="groups"
eval="[(4, ref('group_fusion_plating_cgp_officer'))]"/>
@@ -85,7 +85,7 @@
<!-- Multi-company isolation on CGP Registration -->
<!-- ================================================================== -->
<record id="fp_cgp_registration_company_rule" model="ir.rule">
<field name="name">Fusion Plating: CGP Registration multi-company</field>
<field name="name">Fusion Plating: CGP Registration - multi-company</field>
<field name="model_id" ref="model_fusion_plating_cgp_registration"/>
<field name="global" eval="True"/>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>

View File

@@ -1,5 +1,5 @@
// =============================================================================
// Fusion Plating Controlled Goods Program
// Fusion Plating - Controlled Goods Program
// Copyright 2026 Nexa Systems Inc.
// License OPL-1 (Odoo Proprietary License v1.0)
//
@@ -18,7 +18,7 @@
// warning: var(--bs-warning) // used for "classified" tint
// danger: var(--bs-danger) // used for restricted badge
//
// The CGP pack deals with sensitive records we tint classified forms with
// The CGP pack deals with sensitive records - we tint classified forms with
// a soft warning wash so they are visually distinct from routine records
// without being loud enough to interfere with reading the form.
// =============================================================================
@@ -47,7 +47,7 @@
// -----------------------------------------------------------------------------
// Restricted badge "CGP", "Restricted PSA", etc.
// Restricted badge - "CGP", "Restricted - PSA", etc.
// -----------------------------------------------------------------------------
// Uses the danger token tinted to the current surface so it reads the same on
// light and dark without any media queries.

View File

@@ -36,7 +36,7 @@
<field name="arch" type="xml">
<form string="Authorized Individual">
<header>
<!-- Phase D5 all CGP form buttons are QM-only per spec
<!-- Phase D5 - all CGP form buttons are QM-only per spec
section 2.C (CGP fold-in lands entirely under
Quality Manager). -->
<button name="action_activate" string="Activate" type="object"

View File

@@ -35,7 +35,7 @@
<field name="arch" type="xml">
<form string="Controlled Good" class="o_fp_cgp_classified">
<header>
<!-- Phase D5 all CGP form buttons are QM-only per spec
<!-- Phase D5 - all CGP form buttons are QM-only per spec
section 2.C. -->
<button name="action_mark_in_process" string="In Process"
type="object"

View File

@@ -35,7 +35,7 @@
<field name="arch" type="xml">
<form string="Personnel Security Assessment" class="o_fp_cgp_classified">
<header>
<!-- Phase D5 all CGP form buttons are QM-only per spec
<!-- Phase D5 - all CGP form buttons are QM-only per spec
section 2.C. -->
<button name="action_start" string="Start" type="object"
class="oe_highlight"
@@ -59,7 +59,7 @@
<label for="name"/>
<h1><field name="name"/></h1>
</div>
<span class="o_fp_cgp_restricted_badge">Restricted PSA</span>
<span class="o_fp_cgp_restricted_badge">Restricted - PSA</span>
<group>
<group string="Assessment">
<field name="employee_id"/>

View File

@@ -37,7 +37,7 @@
<field name="arch" type="xml">
<form string="CGP Receipt / Shipment" class="o_fp_cgp_classified">
<header>
<!-- Phase D5 all CGP form buttons are QM-only per spec
<!-- Phase D5 - all CGP form buttons are QM-only per spec
section 2.C. -->
<button name="action_authorize" string="Authorize" type="object"
class="oe_highlight"

View File

@@ -36,7 +36,7 @@
<field name="arch" type="xml">
<form string="CGP Registration" class="o_fp_cgp_classified">
<header>
<!-- Phase D5 all CGP form buttons are QM-only per spec
<!-- Phase D5 - all CGP form buttons are QM-only per spec
section 2.C. -->
<button name="action_mark_registered" string="Mark Registered"
type="object" class="oe_highlight"
@@ -62,7 +62,7 @@
<label for="name"/>
<h1><field name="name"/></h1>
</div>
<span class="o_fp_cgp_restricted_badge">Restricted CGP</span>
<span class="o_fp_cgp_restricted_badge">Restricted - CGP</span>
<group>
<group string="Registration">
<field name="company_id"/>

View File

@@ -39,7 +39,7 @@
<field name="arch" type="xml">
<form string="Security Incident" class="o_fp_cgp_classified">
<header>
<!-- Phase D5 all CGP form buttons are QM-only per spec
<!-- Phase D5 - all CGP form buttons are QM-only per spec
section 2.C. -->
<button name="action_investigate" string="Investigate"
type="object" class="oe_highlight"
@@ -63,7 +63,7 @@
<label for="name"/>
<h1><field name="name"/></h1>
</div>
<span class="o_fp_cgp_restricted_badge">Restricted Security Incident</span>
<span class="o_fp_cgp_restricted_badge">Restricted - Security Incident</span>
<group>
<group string="Incident">
<field name="incident_date"/>

View File

@@ -39,7 +39,7 @@
<field name="arch" type="xml">
<form string="CGP Visitor">
<header>
<!-- Phase D5 all CGP form buttons are QM-only per spec
<!-- Phase D5 - all CGP form buttons are QM-only per spec
section 2.C. -->
<button name="action_check_in" string="Check In" type="object"
class="oe_highlight"

View File

@@ -6,8 +6,8 @@
-->
<odoo>
<!-- Phase 1 re-parented under Plating → Compliance hub. -->
<!-- Phase D (perms v2) QM-only under compliance hub. -->
<!-- Phase 1 - re-parented under Plating → Compliance hub. -->
<!-- Phase D (perms v2) - QM-only under compliance hub. -->
<menuitem id="menu_fp_cgp"
name="Controlled Goods (CGP)"
parent="fusion_plating.menu_fp_compliance_hub"

View File

@@ -8,7 +8,7 @@
<!--
Extend the HR employee form with a "Security (CGP)" notebook page.
Visible only to the CGP Officer group a regular HR manager will
Visible only to the CGP Officer group - a regular HR manager will
not see this tab or any of the PSA linkage.
-->
<record id="view_fp_cgp_hr_employee_form" model="ir.ui.view">