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

@@ -9,7 +9,7 @@ from odoo import _, api, fields, models
class FpPortalJob(models.Model):
"""Lightweight portal-facing view of a production job.
This is intentionally a simple, decoupled model it does NOT replace any
This is intentionally a simple, decoupled model - it does NOT replace any
real job/MO model from process packs (e.g. fusion_plating_process_en).
Instead, the shop populates this once per job (manually or via a small
sync rule from the real job) so the customer sees a clean, sanitised
@@ -19,7 +19,7 @@ class FpPortalJob(models.Model):
optional CoC + packing list attachments, and a tracking reference.
"""
_name = 'fusion.plating.portal.job'
_description = 'Fusion Plating Portal Job'
_description = 'Fusion Plating - Portal Job'
_inherit = ['portal.mixin', 'mail.thread']
_order = 'received_date desc, id desc'
@@ -249,7 +249,7 @@ class FpPortalJob(models.Model):
def walk(node, depth):
for child in node.child_ids.sorted('sequence'):
if not child.customer_visible:
# Hidden node and its sub-tree is also hidden,
# Hidden node - and its sub-tree is also hidden,
# because if you're skipping the parent the kids
# never make sense in isolation.
continue
@@ -264,14 +264,14 @@ class FpPortalJob(models.Model):
return result
# ==========================================================================
# State recompute single source of truth derived from upstream models
# State recompute - single source of truth derived from upstream models
# ==========================================================================
# The portal state should ALWAYS reflect the real shop-floor state of the
# linked fp.job(s), the outbound shipment(s), and the customer invoice.
# Earlier paths wrote state directly from each event hook (tracking number
# arrived → 'shipped'; invoice posted → 'complete') which drifted out of
# sync the moment any of those events fired before the job was actually
# done e.g. a FedEx label booked early would promote portal state to
# done - e.g. a FedEx label booked early would promote portal state to
# 'shipped' even though the WO was still in 'confirmed'. The helper below
# is the new single source of truth; the hooks now delegate to it.
def _fp_recompute_portal_state(self):
@@ -284,7 +284,7 @@ class FpPortalJob(models.Model):
for portal in self:
jobs = Job.sudo().search([('portal_job_id', '=', portal.id)])
if not jobs:
# No linked job leave manual edits alone.
# No linked job - leave manual edits alone.
continue
all_done = all(j.state == 'done' for j in jobs)
@@ -312,7 +312,7 @@ class FpPortalJob(models.Model):
elif ship.status == 'shipped':
ship_in_transit = True
# Invoice signal any posted customer invoice on the SO.
# Invoice signal - any posted customer invoice on the SO.
invoiced = False
for j in jobs:
so = j.sale_order_id

View File

@@ -13,14 +13,14 @@ class FpQuoteRequest(models.Model):
The RFQ is the entry point for new business through the customer portal.
A customer fills out the public form (logged in), uploads any drawings,
and submits the record lands in the shop's backend in state ``new``.
and submits - the record lands in the shop's backend in state ``new``.
The shop reviews, prices, and either quotes (``quoted``), declines, or
lets the request expire. The portal mixin gives each request a stable
access token URL so quote PDFs can be linked from chatter.
"""
_name = 'fusion.plating.quote.request'
_description = 'Fusion Plating Quote Request'
_description = 'Fusion Plating - Quote Request'
_inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']
_order = 'create_date desc, id desc'
@@ -139,7 +139,7 @@ class FpQuoteRequest(models.Model):
)
notes_internal = fields.Html(
string='Internal Notes',
help='Visible to shop users only never shown on the customer portal.',
help='Visible to shop users only - never shown on the customer portal.',
)
company_id = fields.Many2one(

View File

@@ -13,7 +13,7 @@ class FpQuoteRequestLine(models.Model):
part number, quantity, description, and file attachments.
"""
_name = 'fusion.plating.quote.request.line'
_description = 'Fusion Plating Quote Request Line'
_description = 'Fusion Plating - Quote Request Line'
_order = 'sequence, id'
request_id = fields.Many2one(