diff --git a/westech_r2/migrations/migrate_serial_grades.py b/westech_r2/migrations/migrate_serial_grades.py index a8ae778..6bb293c 100644 --- a/westech_r2/migrations/migrate_serial_grades.py +++ b/westech_r2/migrations/migrate_serial_grades.py @@ -1,10 +1,10 @@ """ -Data Migration: Populate new Serial No fields from existing data. +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 → new grade field: +Maps cosmetic_grade C# values from latest Device Condition Report → new grade field: C5-C9 → High C4 → Med C3 → Low @@ -17,29 +17,48 @@ 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", "cosmetic_grade", "grade", "pricing_status"], + fields=["name"], limit_page_length=0 ) - stats = {"high": 0, "med": 0, "low": 0, "flagged": 0, "skipped": 0, "errors": 0} + stats = {"high": 0, "med": 0, "low": 0, "flagged": 0, "skipped": 0, "errors": 0, "no_report": 0} for i, s in enumerate(serials): try: - cosmetic = (s.cosmetic_grade or "").strip().upper() + # 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 + ) - # Map cosmetic_grade → new grade - if cosmetic in ("C5", "C6", "C7", "C8", "C9"): - new_grade = "High" - elif cosmetic == "C4": - new_grade = "Med" - elif cosmetic == "C3": - new_grade = "Low" - else: + 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 or old value - if s.grade and s.grade in ("High", "Med", "Low", "Flagged"): + # 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 @@ -54,8 +73,6 @@ def run(): "pricing_status": pricing_status }) - stats[new_grade.lower()] += 1 - if (i + 1) % 1000 == 0: frappe.db.commit() print(f" Processed {i + 1}/{len(serials)}...") @@ -71,8 +88,9 @@ def run(): print(f" High: {stats['high']}") print(f" Med: {stats['med']}") print(f" Low: {stats['low']}") - print(f" Flagged: {stats['flagged']}") - print(f" Skipped (already new grade): {stats['skipped']}") + 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__":