gigafibre-fsm/scripts/migration/fix_issue_owners.py
louispaulb 22377bb381 feat: fix all data relationships + PPA reference numbers
- fix_issue_owners.py: 53K Issues linked to creator (owner) + 55K to assignee (_assign)
- fix_issue_cust2.py: 47K Issues linked to Customer via legacy_account_id
- fix_sub_address.py: 21K Subscriptions linked to service Address
- customer_pos_id set to legacy PPA reference (15-digit bank number) on all 6,667 Customers
- Subscription custom fields: service_address (Link→Address), service_location (Link→Service Location)
- Fiscal Year 2025-2026 created (Jul 1 2025 → Jun 30 2026)

Relationships now complete:
  Customer → Address (N) → Subscription (N) → Item (plan + speeds)
  Customer → Contact (N) → email/phone
  Customer → Issue (N) → parent_incident → child Issues
  Issue → owner (User who created) + _assign (User responsible)
  Subscription → service_address → specific installation address
  Customer.customer_pos_id = PPA bank reference number

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:45:51 -04:00

90 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""
Fix Issue owner + _assign from legacy ticket.open_by / assign_to → ERPNext User email.
Direct PG. Detached.
"""
import pymysql
import psycopg2
import json
LEGACY = {"host": "10.100.80.100", "user": "facturation", "password": "VD67owoj",
"database": "gestionclient", "connect_timeout": 30, "read_timeout": 300}
PG = {"host": "db", "port": 5432, "user": "postgres", "password": "123",
"dbname": "_eb65bdc0c4b1b2d6"}
def log(msg):
print(msg, flush=True)
def main():
log("=== Fix Issue Owners + Assignees ===")
# Staff ID → email
mc = pymysql.connect(**LEGACY)
cur = mc.cursor(pymysql.cursors.DictCursor)
cur.execute("SELECT id, email FROM staff WHERE email IS NOT NULL AND email != ''")
staff_email = {r["id"]: r["email"] for r in cur.fetchall()}
# ticket → open_by, assign_to
cur.execute("SELECT id, open_by, assign_to FROM ticket ORDER BY id")
tickets = cur.fetchall()
mc.close()
log(" {} tickets, {} staff with email".format(len(tickets), len(staff_email)))
pg = psycopg2.connect(**PG)
pgc = pg.cursor()
# ERPNext users (verify they exist)
pgc.execute('SELECT name FROM "tabUser" WHERE enabled = 1')
valid_users = set(r[0] for r in pgc.fetchall())
# Issue legacy_ticket_id → name
pgc.execute('SELECT legacy_ticket_id, name FROM "tabIssue" WHERE legacy_ticket_id > 0')
issue_map = {r[0]: r[1] for r in pgc.fetchall()}
log(" {} issues mapped".format(len(issue_map)))
updated_owner = 0
updated_assign = 0
for i, t in enumerate(tickets):
issue_name = issue_map.get(t["id"])
if not issue_name:
continue
sets = []
vals = []
# Owner (who created)
open_email = staff_email.get(t.get("open_by"))
if open_email and open_email in valid_users:
sets.append('owner = %s')
vals.append(open_email)
updated_owner += 1
# Assign (who's responsible)
assign_email = staff_email.get(t.get("assign_to"))
if assign_email and assign_email in valid_users:
assign_json = json.dumps([assign_email])
sets.append('"_assign" = %s')
vals.append(assign_json)
updated_assign += 1
if sets:
vals.append(issue_name)
pgc.execute('UPDATE "tabIssue" SET {} WHERE name = %s'.format(", ".join(sets)), vals)
if (i + 1) % 5000 == 0:
pg.commit()
log(" [{}/{}] owner={} assign={}".format(i+1, len(tickets), updated_owner, updated_assign))
pg.commit()
pg.close()
log("")
log("=" * 50)
log("Owner updated: {}".format(updated_owner))
log("Assign updated: {}".format(updated_assign))
log("=" * 50)
if __name__ == "__main__":
main()