"""Rename all ERPNext accounts to Romanian.""" import requests, json, sys, io, urllib.parse sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') URL = "http://localhost:8080" s = requests.Session() s.post(f"{URL}/api/method/login", data={"usr": "Administrator", "pwd": "admin"}) print("Logged in") RENAMES = { # Root groups (Level 1) "Application of Funds (Assets)": "Active", "Source of Funds (Liabilities)": "Pasive (Datorii)", "Equity": "Capitaluri Proprii", "Income": "Venituri", "Expenses": "Cheltuieli", # Asset sub-groups "Current Assets": "Active Curente", "Cash In Hand": "Numerar", "Cash": "Casa", "Bank Accounts": "Conturi Bancare", "Accounts Receivable": "Creante Clienti", "Debtors": "Debitori", "Stock Assets": "Active Stocuri", "Stock In Hand": "Stoc", "Tax Assets": "Active Fiscale", "Loans and Advances (Assets)": "Imprumuturi si Avansuri (Active)", "Employee Advances": "Avansuri Angajati", "Securities and Deposits": "Garantii si Depozite", "Earnest Money": "Garantii", "Fixed Assets": "Imobilizari Corporale", "Capital Equipments": "Echipamente de Capital", "Electronic Equipments": "Echipamente Electronice", "Furnitures and Fixtures": "Mobilier si Dotari", "Office Equipments": "Echipamente Birou", "Plants and Machineries": "Utilaje si Masini", "Buildings": "Cladiri", "Softwares": "Software", "Accumulated Depreciation": "Amortizare Cumulata", "CWIP Account": "Lucrari in Curs", "Investments": "Investitii", "Temporary Accounts": "Conturi Temporare", "Temporary Opening": "Sold Initial Temporar", # Liability sub-groups "Current Liabilities": "Datorii Curente", "Accounts Payable": "Datorii Furnizori", "Creditors": "Creditori", "Payroll Payable": "Salarii de Plata", "Stock Liabilities": "Datorii Stocuri", "Stock Received But Not Billed": "Stoc Receptionat Nefacturat", "Asset Received But Not Billed": "Active Receptionate Nefacturate", "Duties and Taxes": "Taxe si Impozite", "TDS Payable": "Taxe de Plata", "Loans (Liabilities)": "Imprumuturi (Datorii)", "Secured Loans": "Imprumuturi Garantate", "Unsecured Loans": "Imprumuturi Negarantate", "Bank Overdraft Account": "Descoperit de Cont", # Equity "Capital Stock": "Capital Social", "Dividends Paid": "Dividende Platite", "Opening Balance Equity": "Sold Initial Capital", "Retained Earnings": "Rezultat Reportat", # Income "Direct Income": "Venituri Directe", "Sales": "Vanzari", "Service": "Servicii", "Indirect Income": "Venituri Indirecte", # Expenses "Direct Expenses": "Cheltuieli Directe", "Stock Expenses": "Cheltuieli Stocuri", "Cost of Goods Sold": "Costul Bunurilor Vandute", "Expenses Included In Asset Valuation": "Cheltuieli Incluse in Evaluarea Activelor", "Expenses Included In Valuation": "Cheltuieli Incluse in Evaluare", "Stock Adjustment": "Ajustare Stoc", "Indirect Expenses": "Cheltuieli Indirecte", "Administrative Expenses": "Cheltuieli Administrative", "Commission on Sales": "Comisioane Vanzari", "Depreciation": "Amortizare", "Entertainment Expenses": "Cheltuieli Reprezentare", "Freight and Forwarding Charges": "Cheltuieli Transport", "Legal Expenses": "Cheltuieli Juridice", "Marketing Expenses": "Cheltuieli Marketing", "Office Maintenance Expenses": "Cheltuieli Intretinere Birou", "Office Rent": "Chirie Birou", "Postal Expenses": "Cheltuieli Postale", "Print and Stationery": "Tiparituri si Papetarie", "Round Off": "Rotunjiri", "Salary": "Salarii", "Sales Expenses": "Cheltuieli Vanzari", "Telephone Expenses": "Cheltuieli Telefon", "Travel Expenses": "Cheltuieli Deplasare", "Utility Expenses": "Cheltuieli Utilitati", "Write Off": "Pierderi din Creante", "Exchange Gain/Loss": "Diferente de Curs Valutar", "Gain/Loss on Asset Disposal": "Castiguri/Pierderi din Casare Active", "Miscellaneous Expenses": "Cheltuieli Diverse", } # Get all accounts r = s.get(f"{URL}/api/resource/Account", params={ "filters": json.dumps([["company", "=", "TOP CLOSSERS SRL"]]), "fields": json.dumps(["name", "account_name"]), "limit_page_length": 200, }) accounts = r.json().get("data", []) renamed = 0 skipped = 0 errors = 0 for acc in accounts: old_name = acc["account_name"] if old_name not in RENAMES: continue new_name = RENAMES[old_name] full_old = acc["name"] # e.g. "1000 - Application of Funds (Assets) - TC" # Build new full name parts = full_old.split(" - ") if len(parts) >= 3: parts[1] = new_name full_new = " - ".join(parts) else: skipped += 1 continue # Rename via frappe.client.rename_doc r = s.post(f"{URL}/api/method/frappe.client.rename_doc", json={ "doctype": "Account", "old": full_old, "new": full_new, "merge": 0, }) if r.status_code == 200: renamed += 1 print(f" OK: {old_name} -> {new_name}") else: errors += 1 err_msg = r.text[:150] if r.text else str(r.status_code) print(f" ERR: {old_name}: {err_msg}") print(f"\nRenamed: {renamed}, Skipped: {skipped}, Errors: {errors}") # Clear cache s.post(f"{URL}/api/method/frappe.client.clear_cache") print("Cache cleared. Refresh browser.")