gigafibre-fsm/scripts/fix_ple_groupby.py
louispaulb 101faa21f1 feat: inline editing, search, notifications + full repo cleanup
- InlineField component + useInlineEdit composable for Odoo-style dblclick editing
- Client search by name, account ID, and legacy_customer_id (or_filters)
- SMS/Email notification panel on ContactCard via n8n webhooks
- Ticket reply thread via Communication docs
- All migration scripts (51 files) now tracked
- Client portal and field tech app added to monorepo
- README rewritten with full feature list, migration summary, architecture
- CHANGELOG updated with all recent work
- ROADMAP updated with current completion status
- Removed hardcoded tokens from docs (use $ERP_SERVICE_TOKEN)
- .gitignore updated (docker/, .claude/, exports/, .quasar/)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 07:34:41 -04:00

67 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""
Fix the PostgreSQL GROUP BY bug in ERPNext's payment_ledger_entry.py
on the server via SSH.
The bug: update_voucher_outstanding() selects 'account', 'party_type', 'party'
but doesn't include them in GROUP BY — PostgreSQL requires this, MariaDB doesn't.
This script SSH into the server and patches the file in-place.
"""
import subprocess
import sys
SERVER = "root@96.125.196.67"
# Path inside the erpnext docker container
CONTAINER = "erpnext-backend-1"
FILE_PATH = "apps/erpnext/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py"
# First, let's read the current file to find the exact code to patch
print("Step 1: Reading current file from server...")
result = subprocess.run(
["ssh", SERVER, f"docker exec {CONTAINER} cat /home/frappe/frappe-bench/{FILE_PATH}"],
capture_output=True, text=True
)
if result.returncode != 0:
print(f"ERROR reading file: {result.stderr}")
sys.exit(1)
content = result.stdout
print(f" File size: {len(content)} bytes")
# Find the problematic groupby
# Look for the pattern where groupby has voucher_type and voucher_no but NOT account
import re
# Find the update_voucher_outstanding function and its groupby
lines = content.split('\n')
found = False
for i, line in enumerate(lines):
if 'def update_voucher_outstanding' in line:
print(f" Found function at line {i+1}")
if '.groupby(' in line and 'voucher_type' in line and 'voucher_no' in line:
# Check surrounding lines for account in groupby
context = '\n'.join(lines[max(0,i-3):i+5])
if 'ple.account' not in context or '.groupby' in line:
print(f" Found groupby at line {i+1}: {line.strip()}")
found = True
if not found:
print(" Could not find the problematic groupby pattern")
print(" Dumping function for manual inspection...")
in_func = False
for i, line in enumerate(lines):
if 'def update_voucher_outstanding' in line:
in_func = True
if in_func:
print(f" {i+1}: {line}")
if in_func and line.strip() and not line.startswith('\t') and not line.startswith(' ') and i > 0:
if 'def ' in line and 'update_voucher_outstanding' not in line:
break
if in_func and i > 250: # safety limit
break
print("\n--- Full file dumped for inspection ---")
print("Use this output to craft the sed command manually")