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

@@ -7,7 +7,7 @@ from odoo import api, fields, models
class FpChainOfCustody(models.Model):
"""A single custody event the audit trail for parts in transit.
"""A single custody event - the audit trail for parts in transit.
A chain of custody record is created every time parts change hands:
received from the customer, loaded on a vehicle, entered a facility,
@@ -19,7 +19,7 @@ class FpChainOfCustody(models.Model):
round-trip).
"""
_name = 'fusion.plating.chain.of.custody'
_description = 'Fusion Plating Chain of Custody Event'
_description = 'Fusion Plating - Chain of Custody Event'
_order = 'event_datetime desc, id desc'
_rec_name = 'display_name'

View File

@@ -30,7 +30,7 @@ class FpDelivery(models.Model):
migration.
"""
_name = 'fusion.plating.delivery'
_description = 'Fusion Plating Delivery'
_description = 'Fusion Plating - Delivery'
_inherit = ['mail.thread', 'mail.activity.mixin', 'fp.parent.numbered.mixin']
_order = 'scheduled_date desc, id desc'
@@ -64,7 +64,7 @@ class FpDelivery(models.Model):
'Will become a Many2one once the job module ships.',
tracking=True,
)
# ---- Sub 5 traceability fields from the source MO --------------------
# ---- Sub 5 - traceability fields from the source MO --------------------
x_fc_serial_id = fields.Many2one(
'fp.serial', string='Serial Number',
ondelete='set null', index=True,
@@ -76,13 +76,13 @@ class FpDelivery(models.Model):
)
x_fc_thickness_range = fields.Char(
string='Thickness',
help='Carried from the SO line prints on packing slip / BoL.',
help='Carried from the SO line - prints on packing slip / BoL.',
)
x_fc_revision_snapshot = fields.Char(
string='Revision (snapshot)',
)
# ---- Sub 8 box parity ------------------------------------------------
# ---- Sub 8 - box parity ------------------------------------------------
# Shipping crew packs returns into the SAME boxes the parts arrived in
# (client requirement). Receiving captures box_count_in; we capture
# box_count_out here. action_mark_delivered posts a non-blocking
@@ -131,7 +131,7 @@ class FpDelivery(models.Model):
string='Packing List',
)
# ---- Phase A outbound carrier + shipment link ----------------------
# ---- Phase A - outbound carrier + shipment link ----------------------
# Mirrors the fields on fp.receiving. Populated by
# fp.job._fp_create_delivery from the linked receiving when this
# delivery is auto-created on job-done; shipping crew can override
@@ -250,7 +250,7 @@ class FpDelivery(models.Model):
# Parent-numbered mixin hooks (2026-05-12 numbering hierarchy)
# ------------------------------------------------------------------
def _fp_parent_sale_order(self):
"""No direct sale_order_id on this model resolve via
"""No direct sale_order_id on this model - resolve via
job_ref → fp.job.name → job.sale_order_id."""
if not self.job_ref or 'fp.job' not in self.env:
return self.env['sale.order']
@@ -268,7 +268,7 @@ class FpDelivery(models.Model):
def action_view_coc(self):
"""Open the certificate record this delivery's CoC PDF came
from. The attachment carries res_model + res_id, so we
navigate to that record (operator gets all cert info issue
navigate to that record (operator gets all cert info - issue
date, void wizard, reset, etc.) rather than just opening the
raw PDF. Falls back to opening the attachment directly if
someone manually attached a PDF that isn't a cert.
@@ -286,7 +286,7 @@ class FpDelivery(models.Model):
'view_mode': 'form',
'target': 'current',
}
# Plain attachment open via PDF preview helper if available.
# Plain attachment - open via PDF preview helper if available.
if hasattr(att, 'action_fusion_preview'):
return att.action_fusion_preview(title=att.name or 'CoC')
return {
@@ -298,8 +298,8 @@ class FpDelivery(models.Model):
def action_view_packing_list(self):
"""Open the packing-list PDF via fusion_pdf_preview (or fall
back to a new tab when the preview helper isn't installed).
Packing lists don't have a backing model they're attachments
only so we don't navigate to a record.
Packing lists don't have a backing model - they're attachments
only - so we don't navigate to a record.
"""
self.ensure_one()
att = self.packing_list_attachment_id
@@ -320,7 +320,7 @@ class FpDelivery(models.Model):
def action_refresh_from_source(self):
"""Re-pull delivery address / contact / scheduled date / source
facility / carrier / CoC from the linked job → SO → receiving →
cert chain. Only fills BLANK fields never overwrites operator
cert chain. Only fills BLANK fields - never overwrites operator
edits. Use when an upstream value changed after the delivery
was auto-created, or to backfill an old delivery that was
created before the auto-populate hook existed.
@@ -336,12 +336,12 @@ class FpDelivery(models.Model):
)
if not job:
raise UserError(_(
'Delivery %s has no linked job nothing to '
'Delivery %s has no linked job - nothing to '
'refresh from.'
) % rec.name)
Delivery = rec.env['fusion.plating.delivery']
defaults = job._fp_resolve_delivery_defaults(Delivery)
# Drop fields the operator already filled never clobber
# Drop fields the operator already filled - never clobber
# manual edits. Includes the partner/job links since those
# are non-overridable.
fill = {
@@ -350,7 +350,7 @@ class FpDelivery(models.Model):
}
if not fill:
rec.message_post(body=_(
'Refresh from source: nothing to update every '
'Refresh from source: nothing to update - every '
'field already populated.'
))
continue
@@ -382,7 +382,7 @@ class FpDelivery(models.Model):
@api.model
def _default_name(self):
"""Retained for any legacy caller. New code should rely on
create() the parent-numbered mixin sets the name there."""
create() - the parent-numbered mixin sets the name there."""
seq = self.env['ir.sequence'].next_by_code('fusion.plating.delivery')
return seq or '/'
@@ -417,7 +417,7 @@ class FpDelivery(models.Model):
the pattern used in fp_direct_order_wizard and the SO action_confirm
manager-override). Non-managers can't bypass.
``getattr`` is defensive the hold field lives in
``getattr`` is defensive - the hold field lives in
``fusion_plating_invoicing``; this module doesn't dep on it.
"""
for rec in self:
@@ -438,7 +438,7 @@ class FpDelivery(models.Model):
is_manager = self.env['res.partner']._fp_user_can_override_account_hold()
if not is_manager:
raise UserError(_(
'Cannot %(action)s delivery "%(name)s" customer "%(partner)s" '
'Cannot %(action)s delivery "%(name)s" - customer "%(partner)s" '
'is on account hold.\n'
'Reason: %(reason)s\n\n'
'Contact a manager to override.'
@@ -466,14 +466,14 @@ class FpDelivery(models.Model):
Vehicle is encouraged but not strictly required (some shops
let drivers grab whatever vehicle is open at the dock). Driver
is non-negotiable without it the chain-of-custody hand-off
is non-negotiable - without it the chain-of-custody hand-off
has no signed party and the POD can't be linked to a person.
"""
self._fp_check_account_hold(_('dispatch'))
for rec in self:
if not rec.assigned_driver_id:
raise UserError(_(
'Cannot mark delivery "%(name)s" en route no driver '
'Cannot mark delivery "%(name)s" en route - no driver '
'assigned.\n\nPick a driver on the delivery (or wait for '
'the auto-prefill to find one) before tapping Start Route.'
) % {'name': rec.name or rec.display_name})
@@ -485,7 +485,7 @@ class FpDelivery(models.Model):
or rec.vehicle_id.display_name
or 'Driver'),
)
# Packing slip travels with the shipment render + attach it on
# Packing slip travels with the shipment - render + attach it on
# dispatch so the driver/customer get it and it's on the record.
self._fp_generate_packing_slip()
@@ -495,7 +495,7 @@ class FpDelivery(models.Model):
Fired on dispatch (action_start_route) and as a catch-all on
action_mark_delivered. Idempotent + best-effort: skips deliveries
that already carry a slip (unless force=True) and never raises
that already carry a slip (unless force=True) and never raises -
a report glitch must not block shipping. The report action is
resolved at runtime so this module needs no hard dependency on
fusion_plating_reports.
@@ -542,7 +542,7 @@ class FpDelivery(models.Model):
for rec in self:
if not rec.pod_id:
raise UserError(_(
'Cannot mark delivery "%(name)s" delivered no Proof '
'Cannot mark delivery "%(name)s" delivered - no Proof '
'of Delivery (POD) has been captured.\n\n'
'On the iPad: Capture POD → enter recipient name + '
'signature → save. Then mark delivered.'
@@ -558,18 +558,18 @@ class FpDelivery(models.Model):
or 'Driver'),
to_party=rec.partner_id.display_name,
)
# Sub 8 box-parity warning. Non-blocking; just posts to
# Sub 8 - box-parity warning. Non-blocking; just posts to
# chatter so the shipping supervisor sees it on the record.
rec._fp_check_box_parity()
# Catch-all: ensure a slip exists even if dispatch was skipped
# (generate-if-missing won't overwrite the dispatch-time one).
# (generate-if-missing - won't overwrite the dispatch-time one).
self._fp_generate_packing_slip()
def _fp_check_box_parity(self):
"""Compare this delivery's boxes-out count to the boxes-in count
captured at receiving. Post a chatter warning if they differ.
Never blocks shipping has already happened by the time this
Never blocks - shipping has already happened by the time this
fires. The warning is for audit + shipping-supervisor review.
"""
self.ensure_one()
@@ -577,7 +577,7 @@ class FpDelivery(models.Model):
return
if 'fp.receiving' not in self.env:
return
# Sub 11 resolve SO via job_ref → fp.job.origin → SO.name.
# Sub 11 - resolve SO via job_ref → fp.job.origin → SO.name.
so_name = False
if self.job_ref and 'fp.job' in self.env:
job = self.env['fp.job'].sudo().search(

View File

@@ -20,7 +20,7 @@ class FpPickupRequest(models.Model):
automatically as the state transitions.
"""
_name = 'fusion.plating.pickup.request'
_description = 'Fusion Plating Pickup Request'
_description = 'Fusion Plating - Pickup Request'
_inherit = ['mail.thread', 'mail.activity.mixin', 'fp.parent.numbered.mixin']
_order = 'requested_date desc, id desc'

View File

@@ -7,7 +7,7 @@ from odoo import api, fields, models
class FpProofOfDelivery(models.Model):
"""Proof of delivery record captured at the delivery point.
"""Proof of delivery record - captured at the delivery point.
Captures:
* recipient name
@@ -20,7 +20,7 @@ class FpProofOfDelivery(models.Model):
which pre-fills the delivery_id and timestamps the record.
"""
_name = 'fusion.plating.proof.of.delivery'
_description = 'Fusion Plating Proof of Delivery'
_description = 'Fusion Plating - Proof of Delivery'
_order = 'delivered_at desc, id desc'
name = fields.Char(

View File

@@ -19,7 +19,7 @@ class FpRoute(models.Model):
captures total distance (km) and elapsed time for costing.
"""
_name = 'fusion.plating.route'
_description = 'Fusion Plating Route'
_description = 'Fusion Plating - Route'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'route_date desc, id desc'

View File

@@ -15,7 +15,7 @@ class FpRouteStop(models.Model):
stops (fuel, break) just carry an address and a planned time.
"""
_name = 'fusion.plating.route.stop'
_description = 'Fusion Plating Route Stop'
_description = 'Fusion Plating - Route Stop'
_order = 'route_id, sequence, id'
route_id = fields.Many2one(

View File

@@ -3,7 +3,7 @@
# License OPL-1 (Odoo Proprietary License v1.0)
# Part of the Fusion Plating product family.
#
# Sub 5 attach delivery reverse link to fp.serial. Lives here rather
# Sub 5 - attach delivery reverse link to fp.serial. Lives here rather
# than in fusion_plating_configurator because fusion.plating.delivery
# is defined in this module, which loads after configurator.

View File

@@ -12,7 +12,7 @@ class FpVehicle(models.Model):
A vehicle belongs to a facility (its home base), carries insurance,
registration and service dates, and tracks its current driver and
state. Vehicles flagged `tdg_certified` are approved to carry TDG
(Transportation of Dangerous Goods) loads e.g. stripped parts with
(Transportation of Dangerous Goods) loads - e.g. stripped parts with
residue, waste drums, spent chemistry.
The module works without Odoo's Enterprise Fleet module: all
@@ -20,7 +20,7 @@ class FpVehicle(models.Model):
are fully supported.
"""
_name = 'fusion.plating.vehicle'
_description = 'Fusion Plating Vehicle'
_description = 'Fusion Plating - Vehicle'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'name'
@@ -28,7 +28,7 @@ class FpVehicle(models.Model):
string='Vehicle',
required=True,
tracking=True,
help='Internal name e.g. "Van 1" or "Box Truck 07".',
help='Internal name - e.g. "Van 1" or "Box Truck 07".',
)
license_plate = fields.Char(
string='License Plate',

View File

@@ -25,7 +25,7 @@ class HrEmployee(models.Model):
)
x_fc_driver_licence_class = fields.Char(
string='Licence Class',
help='Driver licence class e.g. G, G2, AZ, DZ.',
help='Driver licence class - e.g. G, G2, AZ, DZ.',
)
x_fc_licence_expiry = fields.Date(
string='Licence Expiry',