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

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
"""Per-step compliance audit walks every WO of the most recent MO
"""Per-step compliance audit - walks every WO of the most recent MO
and reports which compliance data points are captured vs missing,
broken down by WO kind.
@@ -32,7 +32,7 @@ KIND_RULES = {
('x_fc_oven_id', 'CRITICAL', 'Which oven'),
('x_fc_bake_temp', 'CRITICAL', 'Setpoint temp (Nadcap req)'),
('x_fc_bake_duration_hours','CRITICAL','Actual bake duration'),
('chart_recorder_ref', 'CRITICAL', 'Chart-recorder ref on the OVEN auditor demands the chart for the run'),
('chart_recorder_ref', 'CRITICAL', 'Chart-recorder ref on the OVEN - auditor demands the chart for the run'),
('duration', 'CRITICAL', 'WO timer duration'),
('x_fc_started_by_user_id','IMPORTANT','Who started'),
('x_fc_finished_by_user_id','IMPORTANT','Who finished'),
@@ -40,7 +40,7 @@ KIND_RULES = {
'mask': [
('x_fc_assigned_user_id', 'CRITICAL', 'Operator'),
('duration', 'CRITICAL', 'Run time'),
('masking_material', 'IMPORTANT','Which material needed for stripping later'),
('masking_material', 'IMPORTANT','Which material - needed for stripping later'),
('x_fc_started_by_user_id','IMPORTANT','Who started'),
('x_fc_finished_by_user_id','IMPORTANT','Who finished'),
],
@@ -72,7 +72,7 @@ def check_field(wo, field):
if field == 'bath_log_during_window':
# Look for any bath log on this WO's bath, between start+finish
if not wo.x_fc_bath_id or not wo.x_fc_started_at or not wo.x_fc_finished_at:
return ('', False, 'no log searchable')
return ('-', False, 'no log searchable')
Log = env['fusion.plating.bath.log']
n = Log.search_count([
('bath_id', '=', wo.x_fc_bath_id.id),
@@ -82,11 +82,11 @@ def check_field(wo, field):
return (f'{n} log(s)', n > 0, '')
if field == 'chart_recorder_ref':
ref = wo.x_fc_oven_id.chart_recorder_ref if wo.x_fc_oven_id else False
return (ref or '', bool(ref), 'on oven')
return (ref or '-', bool(ref), 'on oven')
if field == 'masking_material':
val = wo.x_fc_masking_material if 'x_fc_masking_material' in wo._fields else False
if not val:
return ('', False, '')
return ('-', False, '')
label = dict(wo._fields['x_fc_masking_material'].selection).get(val, val)
return (label, True, '')
if field == 'thickness_readings':
@@ -99,7 +99,7 @@ def check_field(wo, field):
('production_id', '=', wo.production_id.id),
])
if not rs:
return ('', False, 'no readings')
return ('-', False, 'no readings')
n_with = sum(1 for r in rs if r.calibration_std_ref)
return (f'{n_with}/{len(rs)} have cal std', n_with == len(rs), '')
if field == 'gauge_serial':
@@ -107,14 +107,14 @@ def check_field(wo, field):
r = env['fp.thickness.reading'].search(
[('production_id', '=', wo.production_id.id)], limit=1)
if not r:
return ('', False, 'no readings')
return (r.equipment_model or '', bool(r.equipment_model), 'from reading.equipment_model')
return ('-', False, 'no readings')
return (r.equipment_model or '-', bool(r.equipment_model), 'from reading.equipment_model')
# Direct field on WO
val = getattr(wo, field, False) if field in wo._fields else None
if val is None:
return ('(field n/a)', False, '')
if hasattr(val, '_name'):
label = val.display_name if val else ''
label = val.display_name if val else '-'
return (label, bool(val.ids), '')
if isinstance(val, (int, float)):
return (str(val), val > 0, '')
@@ -158,7 +158,7 @@ for wo in mo.workorder_ids.sorted('sequence'):
print(ln)
# =====================================================================
banner('SUMMARY gaps per WO kind across this MO')
banner('SUMMARY - gaps per WO kind across this MO')
# =====================================================================
for kind, gaps in PER_KIND.items():
@@ -169,7 +169,7 @@ for kind, gaps in PER_KIND.items():
print(f' × {field:<30} missing in {n} WO(s)')
print(f'\n Totals: {GAP_TOTALS["CRITICAL"]} CRITICAL gaps, {GAP_TOTALS["IMPORTANT"]} IMPORTANT gaps')
print('\n Note: "missing" doesn\'t always mean "broken" some fields')
print('\n Note: "missing" doesn\'t always mean "broken" - some fields')
print(' are optional today but should be required for stricter')
print(' AS9100 / Nadcap compliance. See the per-kind list to')
print(' decide which are real bugs vs roadmap items.')