# -*- coding: utf-8 -*- # Copyright 2026 Nexa Systems Inc. # 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. # # Run from `odoo shell` where `env` is in scope. See ./README.md. import logging _logger = logging.getLogger('fp_jobs_migration') def run(env): """Print a snapshot of what migrate_to_fp_jobs.py would touch. All queries are SELECT-only. Safe to run on production at any time. """ cr = env.cr print('=== Pre-migration audit ===') # Core MRP counts cr.execute("SELECT COUNT(*) FROM mrp_production") mo_total = cr.fetchone()[0] print('mrp.production total:', mo_total) cr.execute("SELECT state, COUNT(*) FROM mrp_production GROUP BY state ORDER BY 1") print('mrp.production by state:', cr.fetchall()) cr.execute("SELECT COUNT(*) FROM mrp_workorder") wo_total = cr.fetchone()[0] print('mrp.workorder total:', wo_total) cr.execute("SELECT state, COUNT(*) FROM mrp_workorder GROUP BY state ORDER BY 1") print('mrp.workorder by state:', cr.fetchall()) # Already migrated? cr.execute("SELECT COUNT(*) FROM fp_job") job_total = cr.fetchone()[0] print('fp.job already exists:', job_total) cr.execute("SELECT COUNT(*) FROM fp_job_step") step_total = cr.fetchone()[0] print('fp.job.step already exists:', step_total) # Data quality if 'x_fc_recipe_id' in env['mrp.production']._fields: cr.execute( "SELECT COUNT(*) FROM mrp_production WHERE x_fc_recipe_id IS NULL" ) no_recipe = cr.fetchone()[0] print('MOs without x_fc_recipe_id:', no_recipe) cr.execute( "SELECT COUNT(*) FROM mrp_workorder WHERE workcenter_id IS NULL" ) no_wc = cr.fetchone()[0] print('WOs without workcenter_id:', no_wc) # Dependent records — check by model registry (truthful even when # the schema names differ from defaults). if 'fp.quality.hold' in env: cr.execute( "SELECT COUNT(*) FROM fp_quality_hold WHERE production_id IS NOT NULL" ) print('fp.quality.hold rows with production_id:', cr.fetchone()[0]) if 'fp.certificate' in env: cr.execute( "SELECT COUNT(*) FROM fp_certificate WHERE production_id IS NOT NULL" ) print('fp.certificate rows with production_id:', cr.fetchone()[0]) if 'fp.thickness.reading' in env: cr.execute( "SELECT COUNT(*) FROM fp_thickness_reading WHERE production_id IS NOT NULL" ) print( 'fp.thickness.reading rows with production_id:', cr.fetchone()[0], ) if 'fusion.plating.batch' in env: cr.execute( "SELECT COUNT(*) FROM fusion_plating_batch WHERE workorder_id IS NOT NULL" ) print( 'fusion.plating.batch rows with workorder_id:', cr.fetchone()[0], ) if 'fusion.plating.portal.job' in env: cr.execute("SELECT COUNT(*) FROM fusion_plating_portal_job") print('fusion.plating.portal.job total:', cr.fetchone()[0]) if 'fp.racking.inspection' in env: cr.execute( "SELECT COUNT(*) FROM fp_racking_inspection WHERE production_id IS NOT NULL" ) print( 'fp.racking.inspection rows with production_id:', cr.fetchone()[0], ) if 'fusion.plating.delivery' in env: cr.execute( "SELECT COUNT(*) FROM fusion_plating_delivery WHERE job_ref IS NOT NULL" ) print( 'fusion.plating.delivery rows with job_ref:', cr.fetchone()[0], ) print('=== End pre-migration audit ===') # 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 except NameError: print('This script expects to run inside `odoo shell` where `env` is defined.')