didi-website-erp-crm/erp_crm/scripts/archive/setup-sidebar.py

291 lines
13 KiB
Python

"""
Create clean sidebar workspaces for DiDi ERPNext.
Run: python setup-sidebar.py
"""
import requests
import json
ERPNEXT_URL = "http://localhost:8080"
# Login as Administrator
session = requests.Session()
login = session.post(f"{ERPNEXT_URL}/api/method/login", data={"usr": "Administrator", "pwd": "admin"})
if login.status_code != 200:
print(f"Login failed: {login.status_code}")
exit(1)
print("Logged in as Administrator")
def api(method, endpoint, data=None):
url = f"{ERPNEXT_URL}{endpoint}"
if method == "GET":
r = session.get(url, params=data)
elif method == "POST":
r = session.post(url, json=data)
elif method == "PUT":
r = session.put(url, json=data)
elif method == "DELETE":
r = session.delete(url)
else:
return None
return r
# ─── 1. Give API user Workspace Manager role ───
print("\n1. Adding Workspace Manager role to API user...")
try:
r = session.post(f"{ERPNEXT_URL}/api/method/frappe.client.get_list", json={
"doctype": "Has Role",
"filters": {"parent": "website_api@didi-erp", "role": "Workspace Manager"},
"fields": ["name"],
})
existing = r.json().get("message", [])
if not existing:
user_doc = session.get(f"{ERPNEXT_URL}/api/resource/User/website_api@didi-erp").json()["data"]
roles = user_doc.get("roles", [])
roles.append({"role": "Workspace Manager"})
session.put(f"{ERPNEXT_URL}/api/resource/User/website_api@didi-erp", json={"roles": roles})
print(" Added Workspace Manager role")
else:
print(" Already has Workspace Manager role")
except Exception as e:
print(f" Warning: {e}")
# ─── 2. Hide old workspaces ───
print("\n2. Hiding old/unused workspaces...")
to_hide = [
"DiDi Platform", "DiDi", "Accounting", "CRM", "Selling",
"Assets", "Build", "Buying", "ERPNext Integrations", "ERPNext Settings",
"Financial Reports", "Integrations", "Manufacturing", "Payables",
"Projects", "Quality", "Receivables", "Stock", "Support",
]
for ws_name in to_hide:
try:
r = api("PUT", f"/api/resource/Workspace/{requests.utils.quote(ws_name)}", {"is_hidden": 1})
if r.status_code == 200:
print(f" Hidden: {ws_name}")
else:
print(f" Skip (not found or error): {ws_name}")
except:
pass
# ─── 3. Create new sidebar workspaces ───
print("\n3. Creating sidebar workspaces...")
WORKSPACES = [
{
"name": "Facturi",
"title": "Facturi",
"icon": "file-text",
"indicator_color": "green",
"sequence_id": 10,
"content": json.dumps([
{"id": "h1", "type": "header", "data": {"text": "<span class=\"h4\"><b>Facturare</b></span>", "col": 12}},
{"id": "s1", "type": "shortcut", "data": {"shortcut_name": "Toate Facturile", "col": 4}},
{"id": "s2", "type": "shortcut", "data": {"shortcut_name": "Facturi Platite", "col": 4}},
{"id": "s3", "type": "shortcut", "data": {"shortcut_name": "Payment Entry", "col": 4}},
]),
"shortcuts": [
{"type": "DocType", "link_to": "Sales Invoice", "label": "Toate Facturile", "color": "Green", "doc_view": "List"},
{"type": "DocType", "link_to": "Sales Invoice", "label": "Facturi Platite", "color": "Blue", "doc_view": "List"},
{"type": "DocType", "link_to": "Payment Entry", "label": "Payment Entry", "color": "Yellow", "doc_view": "List"},
],
"links": [
{"type": "Card Break", "label": "Facturi"},
{"type": "Link", "label": "Sales Invoice", "link_to": "Sales Invoice", "link_type": "DocType", "onboard": 1},
{"type": "Link", "label": "Payment Entry", "link_to": "Payment Entry", "link_type": "DocType"},
{"type": "Link", "label": "Taxe (TVA)", "link_to": "Sales Taxes and Charges Template", "link_type": "DocType"},
],
},
{
"name": "Clienti",
"title": "Clienti",
"icon": "user",
"indicator_color": "blue",
"sequence_id": 20,
"content": json.dumps([
{"id": "h1", "type": "header", "data": {"text": "<span class=\"h4\"><b>Clienti</b></span>", "col": 12}},
{"id": "s1", "type": "shortcut", "data": {"shortcut_name": "Toti Clientii", "col": 6}},
{"id": "s2", "type": "shortcut", "data": {"shortcut_name": "Service Agreement", "col": 6}},
]),
"shortcuts": [
{"type": "DocType", "link_to": "Customer", "label": "Toti Clientii", "color": "Blue", "doc_view": "List"},
{"type": "DocType", "link_to": "Service Agreement", "label": "Service Agreement", "color": "Purple", "doc_view": "List"},
],
"links": [
{"type": "Card Break", "label": "Clienti"},
{"type": "Link", "label": "Customer", "link_to": "Customer", "link_type": "DocType", "onboard": 1},
{"type": "Link", "label": "Service Agreement", "link_to": "Service Agreement", "link_type": "DocType"},
{"type": "Link", "label": "Subscription Plan", "link_to": "Subscription Plan", "link_type": "DocType"},
],
},
{
"name": "CRM DiDi",
"title": "CRM",
"icon": "share",
"indicator_color": "orange",
"sequence_id": 30,
"content": json.dumps([
{"id": "h1", "type": "header", "data": {"text": "<span class=\"h4\"><b>CRM & Lead Management</b></span>", "col": 12}},
{"id": "s1", "type": "shortcut", "data": {"shortcut_name": "Lead-uri", "col": 4}},
{"id": "s2", "type": "shortcut", "data": {"shortcut_name": "Sales Stage", "col": 4}},
{"id": "s3", "type": "shortcut", "data": {"shortcut_name": "Lead Source", "col": 4}},
]),
"shortcuts": [
{"type": "DocType", "link_to": "Lead", "label": "Lead-uri", "color": "Orange", "doc_view": "List"},
{"type": "DocType", "link_to": "Sales Stage", "label": "Sales Stage", "color": "Yellow"},
{"type": "DocType", "link_to": "Lead Source", "label": "Lead Source", "color": "Grey"},
],
"links": [
{"type": "Card Break", "label": "CRM"},
{"type": "Link", "label": "Lead", "link_to": "Lead", "link_type": "DocType", "onboard": 1},
{"type": "Link", "label": "Sales Stage", "link_to": "Sales Stage", "link_type": "DocType"},
{"type": "Link", "label": "Lead Source", "link_to": "Lead Source", "link_type": "DocType"},
],
},
{
"name": "Servicii DiDi",
"title": "Servicii",
"icon": "box",
"indicator_color": "purple",
"sequence_id": 40,
"content": json.dumps([
{"id": "h1", "type": "header", "data": {"text": "<span class=\"h4\"><b>Servicii & Produse</b></span>", "col": 12}},
{"id": "s1", "type": "shortcut", "data": {"shortcut_name": "Articole", "col": 6}},
{"id": "s2", "type": "shortcut", "data": {"shortcut_name": "Planuri Abonament", "col": 6}},
]),
"shortcuts": [
{"type": "DocType", "link_to": "Item", "label": "Articole", "color": "Purple", "doc_view": "List"},
{"type": "DocType", "link_to": "Subscription Plan", "label": "Planuri Abonament", "color": "Cyan"},
],
"links": [
{"type": "Card Break", "label": "Catalog"},
{"type": "Link", "label": "Item", "link_to": "Item", "link_type": "DocType", "onboard": 1},
{"type": "Link", "label": "Item Group", "link_to": "Item Group", "link_type": "DocType"},
{"type": "Link", "label": "Subscription Plan", "link_to": "Subscription Plan", "link_type": "DocType"},
],
},
{
"name": "Plati DiDi",
"title": "Plati",
"icon": "credit-card",
"indicator_color": "yellow",
"sequence_id": 50,
"content": json.dumps([
{"id": "h1", "type": "header", "data": {"text": "<span class=\"h4\"><b>Plati Stripe & Log</b></span>", "col": 12}},
{"id": "s1", "type": "shortcut", "data": {"shortcut_name": "Payment Log", "col": 6}},
{"id": "s2", "type": "shortcut", "data": {"shortcut_name": "Analysis Report", "col": 6}},
]),
"shortcuts": [
{"type": "DocType", "link_to": "Payment Log", "label": "Payment Log", "color": "Yellow", "doc_view": "List"},
{"type": "DocType", "link_to": "Analysis Report", "label": "Analysis Report", "color": "Pink", "doc_view": "List"},
],
"links": [
{"type": "Card Break", "label": "Plati"},
{"type": "Link", "label": "Payment Log", "link_to": "Payment Log", "link_type": "DocType", "onboard": 1},
{"type": "Link", "label": "Analysis Report", "link_to": "Analysis Report", "link_type": "DocType"},
],
},
{
"name": "Contabilitate DiDi",
"title": "Contabilitate",
"icon": "calculator",
"indicator_color": "grey",
"sequence_id": 60,
"content": json.dumps([
{"id": "h1", "type": "header", "data": {"text": "<span class=\"h4\"><b>Contabilitate</b></span>", "col": 12}},
{"id": "s1", "type": "shortcut", "data": {"shortcut_name": "Plan Conturi", "col": 4}},
{"id": "s2", "type": "shortcut", "data": {"shortcut_name": "Furnizori", "col": 4}},
{"id": "s3", "type": "shortcut", "data": {"shortcut_name": "Companie", "col": 4}},
]),
"shortcuts": [
{"type": "DocType", "link_to": "Account", "label": "Plan Conturi", "color": "Grey", "doc_view": "Tree"},
{"type": "DocType", "link_to": "Supplier", "label": "Furnizori", "color": "Blue"},
{"type": "DocType", "link_to": "Company", "label": "Companie", "color": "Green"},
],
"links": [
{"type": "Card Break", "label": "Contabilitate"},
{"type": "Link", "label": "Account", "link_to": "Account", "link_type": "DocType", "onboard": 1},
{"type": "Link", "label": "Company", "link_to": "Company", "link_type": "DocType"},
{"type": "Link", "label": "Supplier", "link_to": "Supplier", "link_type": "DocType"},
{"type": "Link", "label": "Purchase Invoice", "link_to": "Purchase Invoice", "link_type": "DocType"},
{"type": "Link", "label": "Sales Taxes Template", "link_to": "Sales Taxes and Charges Template", "link_type": "DocType"},
],
},
{
"name": "Website CMS DiDi",
"title": "Website CMS",
"icon": "globe",
"indicator_color": "cyan",
"sequence_id": 70,
"content": json.dumps([
{"id": "h1", "type": "header", "data": {"text": "<span class=\"h4\"><b>Continut Website</b></span>", "col": 12}},
{"id": "s1", "type": "shortcut", "data": {"shortcut_name": "Website Content", "col": 6}},
{"id": "s2", "type": "shortcut", "data": {"shortcut_name": "Email Template", "col": 6}},
]),
"shortcuts": [
{"type": "DocType", "link_to": "Website Content", "label": "Website Content", "color": "Cyan", "doc_view": "List"},
{"type": "DocType", "link_to": "Email Template", "label": "Email Template", "color": "Grey"},
],
"links": [
{"type": "Card Break", "label": "CMS"},
{"type": "Link", "label": "Website Content", "link_to": "Website Content", "link_type": "DocType", "onboard": 1},
{"type": "Link", "label": "Email Template", "link_to": "Email Template", "link_type": "DocType"},
],
},
]
for ws in WORKSPACES:
name = ws["name"]
# Check if exists
check = session.get(f"{ERPNEXT_URL}/api/resource/Workspace/{requests.utils.quote(name)}")
if check.status_code == 200:
# Update it
r = api("PUT", f"/api/resource/Workspace/{requests.utils.quote(name)}", {
"title": ws["title"],
"icon": ws["icon"],
"indicator_color": ws["indicator_color"],
"is_hidden": 0,
"public": 1,
"module": "Didi Custom",
"sequence_id": ws["sequence_id"],
"content": ws["content"],
"shortcuts": ws["shortcuts"],
"links": ws["links"],
})
if r.status_code == 200:
print(f" Updated: {name}")
else:
print(f" Error updating {name}: {r.status_code} {r.text[:200]}")
else:
# Create it
r = api("POST", "/api/resource/Workspace", {
"name": name,
"label": name,
"title": ws["title"],
"icon": ws["icon"],
"indicator_color": ws["indicator_color"],
"is_hidden": 0,
"public": 1,
"module": "Didi Custom",
"sequence_id": ws["sequence_id"],
"content": ws["content"],
"shortcuts": ws["shortcuts"],
"links": ws["links"],
})
if r.status_code in (200, 201):
print(f" Created: {name}")
else:
print(f" Error creating {name}: {r.status_code} {r.text[:200]}")
print("\n4. Verifying sidebar...")
r = session.get(f"{ERPNEXT_URL}/api/resource/Workspace", params={
"filters": json.dumps([["public", "=", 1], ["is_hidden", "=", 0]]),
"fields": json.dumps(["name", "title", "icon", "sequence_id"]),
"order_by": "sequence_id asc",
"limit_page_length": 20,
})
for ws in r.json().get("data", []):
print(f" [{ws.get('sequence_id', '?')}] {ws['icon'] or '?'} {ws['title']}")
print("\nDone! Refresh ERPNext in browser (Ctrl+Shift+R).")