""" Data Migration: Populate new Serial No fields from Device Condition Report data. Run this IMMEDIATELY after `bench migrate` on production. Requires: all new fields already exist (grade, cpu_test, ram_test, etc.) Maps cosmetic_grade C# values from latest Device Condition Report → new grade field: C5-C9 → High C4 → Med C3 → Low C0-C2, blank, anything else → Flagged """ import frappe from frappe.utils import now def run(): print(f"[{now()}] Starting Serial No grade migration...") # Get all Serial Nos with their latest Device Condition Report serials = frappe.get_all("Serial No", fields=["name"], limit_page_length=0 ) stats = {"high": 0, "med": 0, "low": 0, "flagged": 0, "skipped": 0, "errors": 0, "no_report": 0} for i, s in enumerate(serials): try: # Find latest Device Condition Report for this serial reports = frappe.get_all("Device Condition Report", filters={"serial_no": s.name}, fields=["cosmetic_grade"], order_by="creation DESC", limit=1 ) if not reports: # No report found - flag it new_grade = "Flagged" stats["no_report"] += 1 else: cosmetic = (reports[0].cosmetic_grade or "").strip().upper() # Map cosmetic_grade → new grade if cosmetic in ("C5", "C6", "C7", "C8", "C9"): new_grade = "High" stats["high"] += 1 elif cosmetic == "C4": new_grade = "Med" stats["med"] += 1 elif cosmetic == "C3": new_grade = "Low" stats["low"] += 1 else: new_grade = "Flagged" stats["flagged"] += 1 # Only update if grade is blank current_grade = frappe.db.get_value("Serial No", s.name, "grade") if current_grade and current_grade in ("High", "Med", "Low", "Flagged"): stats["skipped"] += 1 continue # Determine pricing_status if new_grade == "Flagged": pricing_status = "Flagged" else: pricing_status = "Needs Pricing" frappe.db.set_value("Serial No", s.name, { "grade": new_grade, "pricing_status": pricing_status }) if (i + 1) % 1000 == 0: frappe.db.commit() print(f" Processed {i + 1}/{len(serials)}...") except Exception as e: stats["errors"] += 1 frappe.log_error(f"Migration error for {s.name}: {e}", "Serial Grade Migration") frappe.db.commit() print(f"\n[{now()}] Migration complete!") print(f" Total Serial Nos: {len(serials)}") print(f" High: {stats['high']}") print(f" Med: {stats['med']}") print(f" Low: {stats['low']}") print(f" Flagged (from missing/bad grade): {stats['flagged']}") print(f" Flagged (no report found): {stats['no_report']}") print(f" Skipped (already migrated): {stats['skipped']}") print(f" Errors: {stats['errors']}") if __name__ == "__main__": run()