didi-website-erp-crm/erp_crm/didi_custom/setup_config.py

287 lines
11 KiB
Python

"""
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": """<p>Stimate {{ doc.customer_name }},</p>
<p>Va confirmam ca plata pentru factura <strong>{{ doc.name }}</strong> in valoare de <strong>{{ doc.grand_total }} {{ doc.currency }}</strong> a fost procesata cu succes.</p>
<p>Puteti descarca factura din dashboard-ul contului dumneavoastra.</p>
<p>Va multumim,<br>Echipa DiDi</p>"""
},
{
"name": "DiDi - Expirare Abonament",
"subject": "Abonamentul dumneavoastra expira in curand",
"response": """<p>Stimate client,</p>
<p>Va informam ca abonamentul dumneavoastra DiDi expira in <strong>7 zile</strong>.</p>
<p>Pentru a continua sa beneficiati de serviciile noastre, va rugam sa verificati metoda de plata in dashboard-ul contului.</p>
<p>Va multumim,<br>Echipa DiDi</p>"""
},
{
"name": "DiDi - Esec Plata",
"subject": "Problema la procesarea platii",
"response": """<p>Stimate client,</p>
<p>Din pacate, nu am reusit sa procesam plata pentru abonamentul dumneavoastra DiDi.</p>
<p>Va rugam sa actualizati metoda de plata in dashboard-ul contului pentru a evita intreruperea serviciului.</p>
<p>Va multumim,<br>Echipa DiDi</p>"""
},
]
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.")