""" Add custom fields to Sales Invoice for analysis tracking. Run inside ERPNext container: docker exec -it didi-erpnext bench --site didi.localhost execute add-invoice-fields.add_fields Or via API (this script uses API approach). """ import requests import sys ERPNEXT_URL = "http://localhost:8080" # Login as Administrator (has permission for Custom Field) session = requests.Session() login_res = session.post(f"{ERPNEXT_URL}/api/method/login", data={"usr": "Administrator", "pwd": "admin"}) if login_res.status_code != 200: print(f"Login failed: {login_res.status_code}") sys.exit(1) print("Logged in as Administrator") HEADERS = {"Content-Type": "application/json"} FIELDS = [ { "dt": "Sales Invoice", "fieldname": "analysis_consumed", "fieldtype": "Check", "label": "Analysis Consumed", "insert_after": "amended_from", "default": "0", "allow_on_submit": 1, "description": "Checked when the purchased analysis has been used", }, { "dt": "Sales Invoice", "fieldname": "analysis_session_id", "fieldtype": "Data", "label": "Analysis Session ID", "insert_after": "analysis_consumed", "read_only": 1, "allow_on_submit": 1, "description": "Session ID from DiDi API after analysis was submitted", }, ] def add_fields(): for field in FIELDS: # Check if field already exists check = session.get( f"{ERPNEXT_URL}/api/resource/Custom Field", params={ "filters": f'[["dt","=","{field["dt"]}"],["fieldname","=","{field["fieldname"]}"]]', "fields": '["name"]', }, headers=HEADERS, ) data = check.json() if data.get("data") and len(data["data"]) > 0: print(f" Field '{field['fieldname']}' already exists, skipping.") continue res = session.post( f"{ERPNEXT_URL}/api/resource/Custom Field", json=field, headers=HEADERS, ) if res.status_code in (200, 201): print(f" Created field '{field['fieldname']}' on {field['dt']}") else: print(f" ERROR creating '{field['fieldname']}': {res.status_code} {res.text}") if __name__ == "__main__": print("Adding custom fields to Sales Invoice...") add_fields() print("Done.")