""" One-off bulk update: set Current Owner for a list of phone numbers, without touching any other field (Plan, Venue, Contract Expiration, Eligibility, Comment are left exactly as they are). Usage: python apply_owner_mapping.py /path/to/telco.db mapping.csv mapping.csv has two columns: phone_number,current_owner (phone_number in the same raw format as the source Excel - digits only, with or without the leading 0; it is normalized the same way the original import did). """ import argparse import csv import sqlite3 def normalize_phone(value): s = str(value).strip() if s.isdigit() and not s.startswith("0"): s = "0" + s return s or None def main(): parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument("db_path") parser.add_argument("mapping_csv") args = parser.parse_args() con = sqlite3.connect(args.db_path) cur = con.cursor() updated, missing = [], [] with open(args.mapping_csv, newline="", encoding="utf-8-sig") as f: reader = csv.DictReader(f) for row in reader: phone_number = normalize_phone(row["phone_number"]) owner = row["current_owner"] cur.execute("UPDATE phones SET current_owner = ? WHERE phone_number = ?", (owner, phone_number)) if cur.rowcount == 0: missing.append(phone_number) else: updated.append(phone_number) con.commit() con.close() print(f"Updated {len(updated)} rows.") if missing: print(f"No matching phone found for {len(missing)} entries: {missing}") if __name__ == "__main__": main()