Backend services: - targo-hub: extract deepGetValue to helpers.js, DRY disconnect reasons lookup map, compact CAPABILITIES, consolidate vision.js prompts/schemas, extract dispatch scoring weights, trim section dividers across 9 files - modem-bridge: extract getSession() helper (6 occurrences), resetIdleTimer(), consolidate DM query factory, fix duplicate username fill bug, trim headers (server.js -36%, tplink-session.js -47%, docker-compose.yml -57%) Frontend: - useWifiDiagnostic: extract THRESHOLDS const, split processDiagnostic into 6 focused helpers (processOnlineStatus, processWanIPs, processRadios, processMeshNodes, processClients, checkRadioIssues) - EquipmentDetail: merge duplicate ROLE_LABELS, remove verbose comments Documentation (17 → 13 files, -1,400 lines): - New consolidated README.md (architecture, services, dependencies, auth) - Merge ECOSYSTEM-OVERVIEW into ARCHITECTURE.md - Merge MIGRATION-PLAN + ARCHITECTURE-COMPARE + FIELD-GAP + CHANGELOG → MIGRATION.md - Merge COMPETITIVE-ANALYSIS into PLATFORM-STRATEGY.md - Update ROADMAP.md with current phase status - Delete CONTEXT.md (absorbed into README) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
84 lines
3.1 KiB
Python
84 lines
3.1 KiB
Python
"""Debug: check a specific unupdated invoice and test the exact match logic."""
|
|
import frappe, pymysql, os, sys
|
|
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)
|
|
os.chdir("/home/frappe/frappe-bench/sites")
|
|
frappe.init(site="erp.gigafibre.ca", sites_path=".")
|
|
frappe.connect()
|
|
|
|
DEFAULT_INCOME = "Autres produits d'exploitation - T"
|
|
|
|
# Find an invoice that STILL has default income (was never updated)
|
|
r = frappe.db.sql("""
|
|
SELECT si.name, si.legacy_invoice_id, sii.idx, sii.item_name, sii.income_account
|
|
FROM "tabSales Invoice" si
|
|
JOIN "tabSales Invoice Item" sii ON sii.parent = si.name
|
|
WHERE sii.income_account = %s AND si.legacy_invoice_id > 0
|
|
ORDER BY si.legacy_invoice_id DESC
|
|
LIMIT 5
|
|
""", (DEFAULT_INCOME,))
|
|
|
|
for row in r:
|
|
print(f" inv={row[0]} legacy_id={row[1]} idx={row[2]} acct={row[4]} name={row[3][:40]}")
|
|
|
|
if not r:
|
|
print("All items already updated!")
|
|
frappe.destroy()
|
|
exit()
|
|
|
|
# Take one and test the mapping
|
|
test_inv = r[0][0]
|
|
test_lid = int(r[0][1])
|
|
print(f"\nTesting invoice {test_inv}, legacy_id={test_lid}")
|
|
|
|
# Get all items for this invoice
|
|
items_erp = frappe.db.sql("""
|
|
SELECT name, idx, item_name, income_account FROM "tabSales Invoice Item"
|
|
WHERE parent = %s ORDER BY idx
|
|
""", (test_inv,))
|
|
print(f" ERPNext items: {len(items_erp)}")
|
|
for item in items_erp:
|
|
print(f" idx={item[1]} acct={item[3]} {item[2][:50]}")
|
|
|
|
# Check legacy items
|
|
legacy = pymysql.connect(
|
|
host="legacy-db", user="facturation", password="VD67owoj",
|
|
database="gestionclient", cursorclass=pymysql.cursors.DictCursor
|
|
)
|
|
with legacy.cursor() as cur:
|
|
cur.execute("""SELECT id, sku, product_name FROM invoice_item WHERE invoice_id = %s ORDER BY id""", (test_lid,))
|
|
litems = cur.fetchall()
|
|
legacy.close()
|
|
print(f"\n Legacy items: {len(litems)}")
|
|
for i, li in enumerate(litems, 1):
|
|
print(f" pos={i} sku={li['sku']} {li['product_name'][:50]}")
|
|
|
|
# Now build the map and check
|
|
legacy2 = pymysql.connect(
|
|
host="legacy-db", user="facturation", password="VD67owoj",
|
|
database="gestionclient", cursorclass=pymysql.cursors.DictCursor
|
|
)
|
|
with legacy2.cursor() as cur:
|
|
cur.execute("""SELECT p.sku, pc.num_compte FROM product p JOIN product_cat pc ON p.category = pc.id
|
|
WHERE p.sku IS NOT NULL AND p.sku != '' AND pc.num_compte IS NOT NULL""")
|
|
sku_to_gl_num = {r['sku']: str(int(r['num_compte'])) for r in cur.fetchall() if r['num_compte']}
|
|
legacy2.close()
|
|
|
|
accts = frappe.db.sql("""SELECT account_number, name FROM "tabAccount"
|
|
WHERE root_type IN ('Income','Expense') AND company='TARGO' AND is_group=0
|
|
AND account_number IS NOT NULL AND account_number != ''""")
|
|
gl_by_number = {r[0]: r[1] for r in accts}
|
|
sku_to_income = {sku: gl_by_number[num] for sku, num in sku_to_gl_num.items() if num in gl_by_number}
|
|
|
|
# Build what the script builds
|
|
inv_item_map = {}
|
|
for i, li in enumerate(litems, 1):
|
|
sku = li['sku'] or ''
|
|
acct = sku_to_income.get(sku)
|
|
if acct:
|
|
inv_item_map[i] = acct
|
|
print(f" Mapped: idx={i} sku={sku} → {acct}")
|
|
|
|
print(f"\n Would update {len(inv_item_map)} of {len(items_erp)} items")
|
|
|
|
frappe.destroy()
|