livrare website cu erp si crm
This commit is contained in:
parent
28773e3a72
commit
5c7bf7c295
257 changed files with 31929 additions and 0 deletions
287
erp_crm/scripts/setup/01-config.py
Normal file
287
erp_crm/scripts/setup/01-config.py
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
"""
|
||||
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.")
|
||||
Loading…
Add table
Add a link
Reference in a new issue