""" ERPNext Configuration Script for DiDi Project Run with: docker exec didi-erpnext bench --site didi.localhost execute didi_setup Or copy to container and run via bench. """ import frappe def execute(): """Main setup function - run all configurations.""" setup_company_details() setup_tax_template() setup_invoice_naming() setup_crm_pipeline() setup_subscription_items() setup_email_templates() frappe.db.commit() print("\n=== DiDi ERPNext Configuration Complete ===\n") def setup_company_details(): """Configure company details - CUI, address, etc.""" print("[1/6] Configuring company details...") company = frappe.get_doc("Company", "TOP CLOSSERS SRL") company.tax_id = "36193026" company.domain = "Services" company.default_currency = "RON" company.country = "Romania" company.save(ignore_permissions=True) # Create company address if not frappe.db.exists("Address", {"address_title": "TOP CLOSSERS SRL - Sediu"}): addr = frappe.get_doc({ "doctype": "Address", "address_title": "TOP CLOSSERS SRL - Sediu", "address_type": "Office", "address_line1": "Str. Targovistei 15", "address_line2": "Bl. 2 Et. 3 Ap. 22", "city": "Ploiesti", "state": "Prahova", "pincode": "100299", "country": "Romania", "phone": "+40721063078", "email_id": "office@clossers.com", "is_primary_address": 1, "links": [{"link_doctype": "Company", "link_name": "TOP CLOSSERS SRL"}] }) addr.insert(ignore_permissions=True) print(" Company details configured.") def setup_tax_template(): """Configure VAT 19% tax template for Romania.""" print("[2/6] Configuring tax templates...") # Get or create default income account company_abbr = "TC" tax_account = f"TVA Colectata - {company_abbr}" # Check if tax account exists, create if not if not frappe.db.exists("Account", tax_account): parent_account = frappe.db.get_value("Account", {"company": "TOP CLOSSERS SRL", "account_type": "Tax", "is_group": 1}, "name" ) if not parent_account: parent_account = frappe.db.get_value("Account", {"company": "TOP CLOSSERS SRL", "root_type": "Liability", "is_group": 1}, "name" ) if parent_account: tax_acc = frappe.get_doc({ "doctype": "Account", "account_name": "TVA Colectata", "parent_account": parent_account, "account_type": "Tax", "company": "TOP CLOSSERS SRL", "tax_rate": 19.0 }) tax_acc.insert(ignore_permissions=True) # Create Sales Tax Template if not frappe.db.exists("Sales Taxes and Charges Template", {"title": "TVA 19% Romania"}): template = frappe.get_doc({ "doctype": "Sales Taxes and Charges Template", "title": "TVA 19% Romania", "company": "TOP CLOSSERS SRL", "is_default": 1, "taxes": [{ "charge_type": "On Net Total", "account_head": tax_account if frappe.db.exists("Account", tax_account) else "", "description": "TVA 19%", "rate": 19.0 }] }) try: template.insert(ignore_permissions=True) print(" Tax template TVA 19% created.") except Exception as e: print(f" Tax template: {e}") else: print(" Tax template already exists.") def setup_invoice_naming(): """Configure Romanian invoice naming series.""" print("[3/6] Configuring invoice naming series...") # Set naming series for Sales Invoice if frappe.db.exists("DocType", "Sales Invoice"): prop_setter_name = "Sales Invoice-naming_series-options" if not frappe.db.exists("Property Setter", prop_setter_name): try: ps = frappe.get_doc({ "doctype": "Property Setter", "doctype_or_field": "DocType", "doc_type": "Sales Invoice", "field_name": "naming_series", "property": "options", "value": "DIDI-INV-.YYYY.-.#####\nACC-SINV-.YYYY.-", "property_type": "Text" }) ps.insert(ignore_permissions=True) print(" Invoice naming series configured: DIDI-INV-YYYY-#####") except Exception as e: print(f" Naming series: {e}") else: print(" Naming series already configured.") def setup_crm_pipeline(): """Configure CRM sales pipeline stages.""" print("[4/6] Configuring CRM pipeline...") # CRM Sales Stages stages = [ {"stage_name": "Lead", "department": ""}, {"stage_name": "Calificat", "department": ""}, {"stage_name": "Demo", "department": ""}, {"stage_name": "Client", "department": ""}, ] for stage_data in stages: if not frappe.db.exists("Sales Stage", stage_data["stage_name"]): stage = frappe.get_doc({ "doctype": "Sales Stage", "stage_name": stage_data["stage_name"] }) stage.insert(ignore_permissions=True) print(f" Created stage: {stage_data['stage_name']}") # Lead Source for website forms sources = ["Website - Contact Form", "Website - Pricing Page", "Website - Demo Request"] for source_name in sources: if not frappe.db.exists("Lead Source", source_name): source = frappe.get_doc({ "doctype": "Lead Source", "source_name": source_name }) source.insert(ignore_permissions=True) print(" CRM pipeline configured: Lead > Calificat > Demo > Client") def setup_subscription_items(): """Create subscription plan items.""" print("[5/6] Creating subscription items and plans...") # Item Group for services if not frappe.db.exists("Item Group", "DiDi Services"): ig = frappe.get_doc({ "doctype": "Item Group", "item_group_name": "DiDi Services", "parent_item_group": "All Item Groups" }) ig.insert(ignore_permissions=True) # Subscription Items items = [ { "item_code": "DIDI-FREE", "item_name": "Abonament DiDi Free", "description": "Plan gratuit - acces de baza la platforma DiDi pentru analiza dezinformarii", "item_group": "DiDi Services", "stock_uom": "Nos", "is_stock_item": 0, "standard_rate": 0 }, { "item_code": "DIDI-PAID", "item_name": "Abonament DiDi Paid", "description": "Plan platit - acces complet la platforma DiDi cu credite lunare pentru analize avansate", "item_group": "DiDi Services", "stock_uom": "Nos", "is_stock_item": 0, "standard_rate": 99 }, { "item_code": "DIDI-ENTERPRISE", "item_name": "Abonament DiDi Enterprise", "description": "Plan enterprise - acces nelimitat la platforma DiDi, suport dedicat, API avansat", "item_group": "DiDi Services", "stock_uom": "Nos", "is_stock_item": 0, "standard_rate": 499 }, ] for item_data in items: if not frappe.db.exists("Item", item_data["item_code"]): item = frappe.get_doc({"doctype": "Item", **item_data}) item.insert(ignore_permissions=True) print(f" Created item: {item_data['item_code']} ({item_data['standard_rate']} RON)") # Subscription Plans plans = [ {"plan_name": "DiDi Free - Lunar", "item": "DIDI-FREE", "cost": 0, "billing_interval": "Month", "billing_interval_count": 1}, {"plan_name": "DiDi Paid - Lunar", "item": "DIDI-PAID", "cost": 99, "billing_interval": "Month", "billing_interval_count": 1}, {"plan_name": "DiDi Paid - Anual", "item": "DIDI-PAID", "cost": 999, "billing_interval": "Year", "billing_interval_count": 1}, {"plan_name": "DiDi Enterprise - Lunar", "item": "DIDI-ENTERPRISE", "cost": 499, "billing_interval": "Month", "billing_interval_count": 1}, {"plan_name": "DiDi Enterprise - Anual", "item": "DIDI-ENTERPRISE", "cost": 4990, "billing_interval": "Year", "billing_interval_count": 1}, ] for plan_data in plans: if not frappe.db.exists("Subscription Plan", plan_data["plan_name"]): plan = frappe.get_doc({ "doctype": "Subscription Plan", "plan_name": plan_data["plan_name"], "item": plan_data["item"], "price_determination": "Fixed Rate", "cost": plan_data["cost"], "currency": "RON", "billing_interval": plan_data["billing_interval"], "billing_interval_count": plan_data["billing_interval_count"] }) plan.insert(ignore_permissions=True) print(f" Created plan: {plan_data['plan_name']} ({plan_data['cost']} RON/{plan_data['billing_interval']})") print(" Subscription items and plans configured.") def setup_email_templates(): """Create email notification templates.""" print("[6/6] Creating email templates...") templates = [ { "name": "DiDi - Confirmare Plata", "subject": "Plata confirmata - {{ doc.name }}", "response": """

Stimate {{ doc.customer_name }},

Va confirmam ca plata pentru factura {{ doc.name }} in valoare de {{ doc.grand_total }} {{ doc.currency }} a fost procesata cu succes.

Puteti descarca factura din dashboard-ul contului dumneavoastra.

Va multumim,
Echipa DiDi

""" }, { "name": "DiDi - Expirare Abonament", "subject": "Abonamentul dumneavoastra expira in curand", "response": """

Stimate client,

Va informam ca abonamentul dumneavoastra DiDi expira in 7 zile.

Pentru a continua sa beneficiati de serviciile noastre, va rugam sa verificati metoda de plata in dashboard-ul contului.

Va multumim,
Echipa DiDi

""" }, { "name": "DiDi - Esec Plata", "subject": "Problema la procesarea platii", "response": """

Stimate client,

Din pacate, nu am reusit sa procesam plata pentru abonamentul dumneavoastra DiDi.

Va rugam sa actualizati metoda de plata in dashboard-ul contului pentru a evita intreruperea serviciului.

Va multumim,
Echipa DiDi

""" }, ] for tmpl in templates: if not frappe.db.exists("Email Template", tmpl["name"]): doc = frappe.get_doc({ "doctype": "Email Template", "name": tmpl["name"], "subject": tmpl["subject"], "response": tmpl["response"], "use_html": 1 }) doc.insert(ignore_permissions=True) print(f" Created template: {tmpl['name']}") print(" Email templates configured.")