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:
@@ -4,5 +4,5 @@
|
||||
#
|
||||
# This package holds standalone migration / audit scripts for the native
|
||||
# job model rollout. Scripts under this directory are NOT imported at
|
||||
# module load time — they are invoked manually from `odoo shell` by the
|
||||
# module load time - they are invoked manually from `odoo shell` by the
|
||||
# cutover engineer. See README.md in this directory for usage.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
#
|
||||
# Post-migration audit. Verifies migration counts match expectations.
|
||||
# Read-only — does NOT modify data. Run from `odoo shell`.
|
||||
# Read-only - does NOT modify data. Run from `odoo shell`.
|
||||
|
||||
import logging
|
||||
|
||||
@@ -47,7 +47,7 @@ def run(env):
|
||||
if step_migrated < wo_total:
|
||||
print('WARNING: %d WOs not migrated' % (wo_total - step_migrated))
|
||||
|
||||
# Cross-references — for each dependent model, show counts of records
|
||||
# Cross-references - for each dependent model, show counts of records
|
||||
# with the LEGACY production_id set vs the NEW x_fc_job_id set. After
|
||||
# migration, the second column should match the first (we don't clear
|
||||
# production_id during shadow period).
|
||||
@@ -163,7 +163,7 @@ def run(env):
|
||||
|
||||
|
||||
try:
|
||||
run(env) # noqa: F821 — `env` is provided by odoo shell
|
||||
run(env) # noqa: F821 - `env` is provided by odoo shell
|
||||
except NameError:
|
||||
print(
|
||||
'This script expects to run inside `odoo shell` where `env` is defined.'
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
#
|
||||
# Pre-migration audit. Reports row counts and data-quality concerns
|
||||
# before running migrate_to_fp_jobs.py. Read-only — does NOT modify data.
|
||||
# before running migrate_to_fp_jobs.py. Read-only - does NOT modify data.
|
||||
#
|
||||
# Run from `odoo shell` where `env` is in scope. See ./README.md.
|
||||
|
||||
@@ -58,7 +58,7 @@ def run(env):
|
||||
no_wc = cr.fetchone()[0]
|
||||
print('WOs without workcenter_id:', no_wc)
|
||||
|
||||
# Dependent records — check by model registry (truthful even when
|
||||
# Dependent records - check by model registry (truthful even when
|
||||
# the schema names differ from defaults).
|
||||
if 'fp.quality.hold' in env:
|
||||
cr.execute(
|
||||
@@ -111,6 +111,6 @@ def run(env):
|
||||
|
||||
# Run when the script is exec'd from odoo shell (env is in scope).
|
||||
try:
|
||||
run(env) # noqa: F821 — `env` is provided by odoo shell
|
||||
run(env) # noqa: F821 - `env` is provided by odoo shell
|
||||
except NameError:
|
||||
print('This script expects to run inside `odoo shell` where `env` is defined.')
|
||||
|
||||
@@ -27,7 +27,7 @@ def run(env):
|
||||
print(' Deleted %d fp.job.node.override rows' % n)
|
||||
|
||||
# 3. Deliveries linked to jobs OR with job_ref set OR linked to a SO that
|
||||
# we will delete. Delete ALL deliveries — they're test data.
|
||||
# we will delete. Delete ALL deliveries - they're test data.
|
||||
if 'fusion.plating.delivery' in env:
|
||||
deliveries = env['fusion.plating.delivery'].sudo().search([])
|
||||
n = len(deliveries)
|
||||
@@ -62,7 +62,7 @@ def run(env):
|
||||
portals.unlink()
|
||||
print(' Deleted %d fusion.plating.portal.job rows' % n)
|
||||
|
||||
# 8. Racking inspections — required FK to mrp.production, so delete
|
||||
# 8. Racking inspections - required FK to mrp.production, so delete
|
||||
# BEFORE we kill the productions.
|
||||
if 'fp.racking.inspection' in env:
|
||||
insps = env['fp.racking.inspection'].sudo().search([])
|
||||
@@ -70,7 +70,7 @@ def run(env):
|
||||
insps.unlink()
|
||||
print(' Deleted %d fp.racking.inspection rows' % n)
|
||||
|
||||
# 9. Receiving records (required FK to sale.order — delete before SOs)
|
||||
# 9. Receiving records (required FK to sale.order - delete before SOs)
|
||||
if 'fp.receiving' in env:
|
||||
recs = env['fp.receiving'].sudo().search([])
|
||||
n = len(recs)
|
||||
@@ -92,7 +92,7 @@ def run(env):
|
||||
env['mrp.workorder'].sudo().search([]).unlink()
|
||||
print(' Deleted %d mrp.workorder rows' % n)
|
||||
|
||||
# 13. mrp.production (legacy) — force state via SQL so unlink() bypasses
|
||||
# 13. mrp.production (legacy) - force state via SQL so unlink() bypasses
|
||||
# Odoo's _unlink_except_done guard (which forbids deleting done MOs)
|
||||
# and the action_cancel guard (which forbids cancelling done MOs).
|
||||
# Demo data only.
|
||||
@@ -111,7 +111,7 @@ def run(env):
|
||||
env['mrp.production'].sudo().search([]).unlink()
|
||||
print(' Deleted %d mrp.production rows' % n)
|
||||
|
||||
# 14. Account payments (must come before invoices — payment is reconciled
|
||||
# 14. Account payments (must come before invoices - payment is reconciled
|
||||
# against move lines)
|
||||
Payment = env['account.payment'].sudo()
|
||||
payments = Payment.search([])
|
||||
@@ -230,7 +230,7 @@ def run(env):
|
||||
)
|
||||
print(' Deleted %d stock.move rows' % n)
|
||||
|
||||
# 17. Sale orders (cancel any non-cancel state first). Delete ALL —
|
||||
# 17. Sale orders (cancel any non-cancel state first). Delete ALL -
|
||||
# demo data only.
|
||||
sos = env['sale.order'].sudo().search([])
|
||||
n = len(sos)
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
# fp.job.step with same name, work centre (mapped via legacy
|
||||
# code), sequence, durations, state.
|
||||
# 4. Time logs: copy mrp.workorder.time_ids if available.
|
||||
# 5. Rebind cross-references on dependent models (defensive — only
|
||||
# 5. Rebind cross-references on dependent models (defensive - only
|
||||
# writes a value when the field exists on both sides AND the
|
||||
# target field is currently empty).
|
||||
# 6. Write audit log to /tmp/fp_jobs_migration.log.
|
||||
#
|
||||
# This is NOT an Odoo upgrade hook — it is an explicit cutover step.
|
||||
# This is NOT an Odoo upgrade hook - it is an explicit cutover step.
|
||||
# Run from `odoo shell -d <db>` so the surrounding transaction can be
|
||||
# rolled back manually if the operator spots a problem (`env.cr.rollback()`).
|
||||
# At the end of run() we env.cr.commit() — the operator can comment that
|
||||
# At the end of run() we env.cr.commit() - the operator can comment that
|
||||
# out if they want to inspect changes before persisting.
|
||||
#
|
||||
# See ./README.md for usage.
|
||||
@@ -60,7 +60,7 @@ def map_work_centre(env, mrp_wc):
|
||||
"""Find the fp.work.centre that corresponds to a mrp.workcenter.
|
||||
|
||||
Strategy: match by code. If no match, return False (the step will
|
||||
have no work centre — operator can fix manually post-cutover).
|
||||
have no work centre - operator can fix manually post-cutover).
|
||||
"""
|
||||
if not mrp_wc:
|
||||
return False
|
||||
@@ -120,7 +120,7 @@ def migrate_mo(env, mo, audit):
|
||||
'state': JOB_STATE_MAP.get(mo.state, 'draft'),
|
||||
'legacy_mrp_production_id': mo.id,
|
||||
}
|
||||
# Optional fields — only set when the source has them
|
||||
# Optional fields - only set when the source has them
|
||||
if 'x_fc_facility_id' in mo._fields and mo.x_fc_facility_id:
|
||||
if 'facility_id' in Job._fields:
|
||||
vals['facility_id'] = mo.x_fc_facility_id.id
|
||||
@@ -140,7 +140,7 @@ def migrate_mo(env, mo, audit):
|
||||
if 'coating_config_id' in Job._fields:
|
||||
vals['coating_config_id'] = mo.x_fc_coating_config_id.id
|
||||
|
||||
# Bypass any auto-create lifecycle hooks while migrating — the source
|
||||
# Bypass any auto-create lifecycle hooks while migrating - the source
|
||||
# MO already had its hooks run when it was originally created. We
|
||||
# don't want a second portal job / racking inspection / etc.
|
||||
job = Job.with_context(
|
||||
@@ -196,7 +196,7 @@ def migrate_wo(env, wo, job, audit):
|
||||
).create(vals)
|
||||
audit['wo_migrated'] += 1
|
||||
|
||||
# Migrate time logs — only if both sides have a time-log model
|
||||
# Migrate time logs - only if both sides have a time-log model
|
||||
if 'time_ids' in wo._fields and wo.time_ids \
|
||||
and 'fp.job.step.timelog' in env:
|
||||
TimeLog = env['fp.job.step.timelog']
|
||||
@@ -382,7 +382,7 @@ def run(env):
|
||||
# every run.
|
||||
if 'legacy_mrp_production_id' not in env['fp.job']._fields:
|
||||
msg = (
|
||||
'fp.job.legacy_mrp_production_id field missing — upgrade '
|
||||
'fp.job.legacy_mrp_production_id field missing - upgrade '
|
||||
'fusion_plating_jobs to v19.0.2.0.0+ before running this '
|
||||
'script.'
|
||||
)
|
||||
@@ -391,7 +391,7 @@ def run(env):
|
||||
return None
|
||||
if 'legacy_mrp_workorder_id' not in env['fp.job.step']._fields:
|
||||
msg = (
|
||||
'fp.job.step.legacy_mrp_workorder_id field missing — upgrade '
|
||||
'fp.job.step.legacy_mrp_workorder_id field missing - upgrade '
|
||||
'fusion_plating_jobs to v19.0.2.0.0+ before running this '
|
||||
'script.'
|
||||
)
|
||||
@@ -404,7 +404,7 @@ def run(env):
|
||||
# fp.job.button_mark_done to skip lifecycle side-effects (creating
|
||||
# portal jobs, QC checks, racking inspections, deliveries, certs,
|
||||
# notifications). The migration script rebinds existing records via
|
||||
# x_fc_job_id directly — so the side-effects would create duplicates.
|
||||
# x_fc_job_id directly - so the side-effects would create duplicates.
|
||||
env = env(context=dict(env.context, fp_jobs_migration=True))
|
||||
MO = env['mrp.production']
|
||||
all_mos = MO.search([])
|
||||
@@ -480,7 +480,7 @@ def run(env):
|
||||
|
||||
# Run when exec'd from odoo shell
|
||||
try:
|
||||
result = run(env) # noqa: F821 — `env` is provided by odoo shell
|
||||
result = run(env) # noqa: F821 - `env` is provided by odoo shell
|
||||
except NameError:
|
||||
print(
|
||||
'This script expects to run inside `odoo shell` where `env` is defined.'
|
||||
|
||||
@@ -133,4 +133,4 @@ print('=' * 60)
|
||||
print(f'PASS: every doc tied to parent {parent}')
|
||||
print('=' * 60)
|
||||
env.cr.rollback()
|
||||
print('(rolled back — DB unchanged)')
|
||||
print('(rolled back - DB unchanged)')
|
||||
|
||||
@@ -60,7 +60,7 @@ def _build_combos(env):
|
||||
|
||||
def _create_so(env, partner, part, coating, qty, deadline_offset_days):
|
||||
"""Create + confirm a SO with one plating line. Returns (so, job)."""
|
||||
# fp.part.catalog has no product_id field — use a generic product
|
||||
# fp.part.catalog has no product_id field - use a generic product
|
||||
# for the SO line. Plating-specific fields (x_fc_part_catalog_id,
|
||||
# x_fc_coating_config_id) carry the real linkage.
|
||||
fallback_product = env['product.product'].search(
|
||||
@@ -106,7 +106,7 @@ def _create_job_direct(env, partner, part, recipe, qty, deadline_offset_days):
|
||||
}
|
||||
if part:
|
||||
vals['part_catalog_id'] = part.id
|
||||
# fp.part.catalog has no product_id field — leave fp.job.product_id
|
||||
# fp.part.catalog has no product_id field - leave fp.job.product_id
|
||||
# null. It's an optional field used as a "Reference Product".
|
||||
return Job.create(vals)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ def run(env):
|
||||
|
||||
coatings_with_recipe = Coating.search([('recipe_id', '!=', False)])
|
||||
if not coatings_with_recipe:
|
||||
print(' No coatings with recipes available — abort')
|
||||
print(' No coatings with recipes available - abort')
|
||||
return
|
||||
print(f' Coatings with recipes: {len(coatings_with_recipe)}')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user