#!/usr/bin/env python3 """ Server-side bulk submit script for ERPNext migration data. Run this INSIDE the erpnext-backend container via bench console. Usage: 1. SSH into server: ssh root@96.125.196.67 2. Enter container: docker exec -it erpnext-backend-1 bash 3. Go to bench: cd /home/frappe/frappe-bench 4. Run: bench --site all execute scripts.server_bulk_submit.run OR copy this file and run with bench console: bench --site erp.gigafibre.ca console Then paste the code below. BEFORE RUNNING: Fix the PostgreSQL GROUP BY bug first! (see fix_ple_postgres.sh) """ # === Paste this into bench console === import frappe def run(): """Main entry point for bench execute""" site = frappe.local.site print(f"Running on site: {site}") # Mute all emails and notifications frappe.flags.mute_emails = True frappe.flags.mute_notifications = True frappe.flags.in_import = True # Step 1: Enable disabled items print("\n═══ Step 1: Enable disabled Items ═══") disabled_items = frappe.get_all("Item", filters={"disabled": 1}, pluck="name") print(f" Found {len(disabled_items)} disabled items") for item_name in disabled_items: frappe.db.set_value("Item", item_name, "disabled", 0, update_modified=False) frappe.db.commit() print(f" Enabled all {len(disabled_items)} items") # Step 2: Submit Sales Invoices print("\n═══ Step 2: Submit Sales Invoices ═══") draft_invoices = frappe.get_all( "Sales Invoice", filters={"docstatus": 0}, pluck="name", order_by="posting_date asc", limit_page_length=0 ) total_inv = len(draft_invoices) print(f" Total draft invoices: {total_inv}") ok, fail = 0, 0 errors = [] for i, inv_name in enumerate(draft_invoices): try: inv = frappe.get_doc("Sales Invoice", inv_name) inv.set_posting_time = 1 # keep original posting_date inv.flags.ignore_permissions = True inv.flags.mute_emails = True inv.flags.ignore_notifications = True inv.submit() ok += 1 if ok % 100 == 0: frappe.db.commit() print(f" Progress: {ok + fail}/{total_inv} (ok={ok}, fail={fail})") except Exception as e: fail += 1 frappe.db.rollback() if len(errors) < 30: errors.append(f"{inv_name}: {str(e)[:150]}") frappe.db.commit() print(f" Done: submitted={ok}, failed={fail}") if errors: print(f" Errors (first {len(errors)}):") for e in errors: print(f" {e}") # Step 3: Submit Payment Entries print("\n═══ Step 3: Submit Payment Entries ═══") draft_payments = frappe.get_all( "Payment Entry", filters={"docstatus": 0}, pluck="name", order_by="posting_date asc", limit_page_length=0 ) total_pe = len(draft_payments) print(f" Total draft payments: {total_pe}") ok, fail = 0, 0 errors = [] for i, pe_name in enumerate(draft_payments): try: pe = frappe.get_doc("Payment Entry", pe_name) pe.flags.ignore_permissions = True pe.flags.mute_emails = True pe.flags.ignore_notifications = True pe.submit() ok += 1 if ok % 100 == 0: frappe.db.commit() print(f" Progress: {ok + fail}/{total_pe} (ok={ok}, fail={fail})") except Exception as e: fail += 1 frappe.db.rollback() if len(errors) < 30: errors.append(f"{pe_name}: {str(e)[:150]}") frappe.db.commit() print(f" Done: submitted={ok}, failed={fail}") if errors: print(f" Errors (first {len(errors)}):") for e in errors: print(f" {e}") # Unmute frappe.flags.mute_emails = False frappe.flags.mute_notifications = False frappe.flags.in_import = False print("\n✓ All done!")