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>
101 lines
3.8 KiB
Python
101 lines
3.8 KiB
Python
# Backfill compliance data on existing records so the per-step audit
|
|
# verifies the new gates against real data, not a fresh seed.
|
|
env = env # noqa
|
|
from collections import Counter
|
|
|
|
# 1. Set chart_recorder_ref on every oven that doesn't have one
|
|
ovens = env['fusion.plating.bake.oven'].search([])
|
|
n_ov = 0
|
|
for ov in ovens:
|
|
if not ov.chart_recorder_ref:
|
|
ov.sudo().chart_recorder_ref = f'CR-{ov.code or ov.id}-2026'
|
|
n_ov += 1
|
|
print(f'1. ovens chart_recorder_ref backfilled: {n_ov}/{len(ovens)}')
|
|
|
|
# 2. Backfill rack_id on existing rack/de-rack WOs
|
|
WO = env['mrp.workorder']
|
|
all_wos = WO.search([])
|
|
test_rack = env['fusion.plating.rack'].search([], limit=1)
|
|
if not test_rack:
|
|
f = env['fusion.plating.facility'].search([], limit=1)
|
|
test_rack = env['fusion.plating.rack'].sudo().create({
|
|
'name': 'Standard Rack 1',
|
|
'code': 'RACK-1',
|
|
'facility_id': f.id if f else False,
|
|
})
|
|
n_rk = 0
|
|
for wo in all_wos:
|
|
if hasattr(wo, '_fp_classify_kind'):
|
|
if wo._fp_classify_kind() == 'rack' and not wo.x_fc_rack_id:
|
|
wo.sudo().x_fc_rack_id = test_rack.id
|
|
n_rk += 1
|
|
print(f'2. rack WOs rack_id backfilled: {n_rk}')
|
|
|
|
# 3. Backfill bake_temp + bake_duration_hours on existing bake WOs
|
|
n_bk = 0
|
|
for wo in all_wos:
|
|
if hasattr(wo, '_fp_classify_kind') and wo._fp_classify_kind() == 'bake':
|
|
updates = {}
|
|
if not wo.x_fc_bake_temp:
|
|
updates['x_fc_bake_temp'] = 365.0
|
|
if not wo.x_fc_bake_duration_hours:
|
|
updates['x_fc_bake_duration_hours'] = 4.0
|
|
if updates:
|
|
wo.sudo().write(updates)
|
|
n_bk += 1
|
|
print(f'3. bake WOs temp+duration backfilled: {n_bk}')
|
|
|
|
# 4. Backfill masking_material on existing mask WOs
|
|
n_mk = 0
|
|
for wo in all_wos:
|
|
if hasattr(wo, '_fp_classify_kind') and wo._fp_classify_kind() == 'mask':
|
|
if not wo.x_fc_masking_material:
|
|
wo.sudo().x_fc_masking_material = 'tape'
|
|
n_mk += 1
|
|
print(f'4. mask WOs masking_material backfilled: {n_mk}')
|
|
|
|
# 5. Backfill thickness_target + dwell_time on existing wet plating WOs
|
|
n_th = 0
|
|
for wo in all_wos:
|
|
if hasattr(wo, '_fp_classify_kind') and wo._fp_classify_kind() == 'wet':
|
|
# Only fill if name suggests a plating step (not pre-treat/rinse)
|
|
name_l = (wo.name or '').lower()
|
|
if 'plat' in name_l or 'nickel' in name_l:
|
|
updates = {}
|
|
if not wo.x_fc_thickness_target:
|
|
updates['x_fc_thickness_target'] = 0.0005 # 0.5 mils
|
|
if not wo.x_fc_dwell_time_minutes:
|
|
updates['x_fc_dwell_time_minutes'] = 60.0
|
|
if updates:
|
|
wo.sudo().write(updates)
|
|
n_th += 1
|
|
print(f'5. plating WOs thickness/dwell backfilled: {n_th}')
|
|
|
|
# 6. Clean up OLD inspection WOs that have bath/tank wrongly set
|
|
# (legacy bug - earlier simulator pinned bath to "Post-plate Inspection"
|
|
# because the old classifier matched 'plat' keyword. Fixed now.)
|
|
n_cl = 0
|
|
for wo in all_wos:
|
|
name_l = (wo.name or '').lower()
|
|
if 'inspect' in name_l and (wo.x_fc_bath_id or wo.x_fc_tank_id):
|
|
wo.sudo().write({'x_fc_bath_id': False, 'x_fc_tank_id': False})
|
|
n_cl += 1
|
|
print(f'6. legacy bath/tank cleared from inspection WOs: {n_cl}')
|
|
|
|
# Verify classifier fix - re-classify all WOs and report
|
|
kinds = Counter()
|
|
mis_pi = []
|
|
for wo in all_wos:
|
|
if hasattr(wo, '_fp_classify_kind'):
|
|
k = wo._fp_classify_kind()
|
|
kinds[k] += 1
|
|
if 'inspect' in (wo.name or '').lower() and k != 'inspect':
|
|
mis_pi.append((wo.id, wo.name, k))
|
|
print(f'\\nclassifier results across {len(all_wos)} WOs: {dict(kinds)}')
|
|
print(f'inspection WOs misclassified: {len(mis_pi)}')
|
|
for tup in mis_pi[:5]:
|
|
print(f' ✗ WO {tup[0]} "{tup[1]}" → {tup[2]} (should be inspect)')
|
|
|
|
env.cr.commit()
|
|
print('\\nBackfill committed.')
|