""" Disable customers with no active Service Subscriptions. These are legacy accounts (moved, cancelled, etc.) that were imported as enabled. Run inside erpnext-backend-1: /home/frappe/frappe-bench/env/bin/python /home/frappe/frappe-bench/cleanup_customer_status.py """ import frappe import os import time from datetime import datetime os.chdir("/home/frappe/frappe-bench/sites") frappe.init(site="erp.gigafibre.ca", sites_path=".") frappe.connect() frappe.local.flags.ignore_permissions = True print("Connected:", frappe.local.site) T_TOTAL = time.time() # ═══════════════════════════════════════════════════════════════ # PHASE 1: Identify customers to disable # ═══════════════════════════════════════════════════════════════ print("\n" + "="*60) print("PHASE 1: IDENTIFY INACTIVE CUSTOMERS") print("="*60) # Customers that are active but have NO active subscriptions to_disable = frappe.db.sql(""" SELECT c.name FROM "tabCustomer" c WHERE c.disabled = 0 AND NOT EXISTS ( SELECT 1 FROM "tabService Subscription" ss WHERE ss.customer = c.name AND ss.status = %s ) """, ("Actif",)) to_disable_names = [r[0] for r in to_disable] print("Customers to disable (no active subscriptions): {}".format(len(to_disable_names))) # ═══════════════════════════════════════════════════════════════ # PHASE 2: Disable them # ═══════════════════════════════════════════════════════════════ print("\n" + "="*60) print("PHASE 2: DISABLE CUSTOMERS") print("="*60) if to_disable_names: # Batch update in chunks of 1000 for i in range(0, len(to_disable_names), 1000): batch = to_disable_names[i:i+1000] placeholders = ", ".join(["%s"] * len(batch)) frappe.db.sql(""" UPDATE "tabCustomer" SET disabled = 1 WHERE name IN ({}) """.format(placeholders), tuple(batch)) frappe.db.commit() print(" Disabled batch {}-{}".format(i+1, min(i+1000, len(to_disable_names)))) print("Disabled {} customers".format(len(to_disable_names))) # ═══════════════════════════════════════════════════════════════ # PHASE 3: VERIFY # ═══════════════════════════════════════════════════════════════ print("\n" + "="*60) print("PHASE 3: VERIFY") print("="*60) by_status = frappe.db.sql(""" SELECT disabled, COUNT(*) as cnt FROM "tabCustomer" GROUP BY disabled ORDER BY disabled """, as_dict=True) print("Customer status after cleanup:") for r in by_status: label = "Active (Abonné)" if r["disabled"] == 0 else "Disabled (Inactif)" print(" {}: {}".format(label, r["cnt"])) # Cross-check: all active customers should have at least one active sub active_no_sub = frappe.db.sql(""" SELECT COUNT(*) FROM "tabCustomer" c WHERE c.disabled = 0 AND NOT EXISTS ( SELECT 1 FROM "tabService Subscription" ss WHERE ss.customer = c.name AND ss.status = %s ) """, ("Actif",))[0][0] print("\nActive customers with no active subscription: {} (should be 0)".format(active_no_sub)) elapsed = time.time() - T_TOTAL print("\n" + "="*60) print("DONE in {:.1f}s".format(elapsed)) print("="*60)