didi-website-erp-crm/erp_crm/scripts/setup/08-email.py

175 lines
7.4 KiB
Python

"""Setup email notifications in ERPNext for DiDi.
Required env vars:
SENDGRID_API_KEY — SendGrid SMTP credential (starts with `SG.`)
ERPNEXT_ADMIN_PASSWORD — ERPNext Administrator password (default: admin, dev only)
ERPNEXT_URL — ERPNext base URL (default: http://localhost:8080)
"""
import sys, io, os, requests
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY")
if not SENDGRID_API_KEY:
print("ERROR: SENDGRID_API_KEY env var not set. Export it before running:")
print(" export SENDGRID_API_KEY='SG.your-real-key-here'")
exit(1)
URL = os.environ.get("ERPNEXT_URL", "http://localhost:8080")
ADMIN_PWD = os.environ.get("ERPNEXT_ADMIN_PASSWORD", "admin")
s = requests.Session()
r = s.post(f"{URL}/api/method/login", data={"usr": "Administrator", "pwd": ADMIN_PWD})
if r.status_code != 200:
print(f"Login failed: {r.status_code} — check ERPNEXT_ADMIN_PASSWORD")
exit(1)
print("Logged in")
def exists(doctype, name):
r = s.get(f"{URL}/api/resource/{requests.utils.quote(doctype)}/{requests.utils.quote(name)}")
return r.status_code == 200
# ── 1. Email Account (SendGrid) ──
print("\n1. Email Account...")
if exists("Email Account", "DiDi Outgoing"):
print(" Already exists")
else:
r = s.post(f"{URL}/api/resource/Email%20Account", json={
"email_account_name": "DiDi Outgoing",
"email_id": "office@clossers.com",
"smtp_server": "smtp.sendgrid.net",
"smtp_port": 587,
"use_tls": 1,
"use_ssl": 0,
"login_id_for_outgoing": 1,
"login_id": "apikey",
"password": SENDGRID_API_KEY,
"default_outgoing": 1,
"enable_outgoing": 1,
"enable_incoming": 0,
"send_notifications": 1,
"always_use_account_email_id_as_sender": 1,
"always_use_account_name_as_sender_name": 1,
"append_to": "",
})
print(f" Created: {r.status_code}")
# ── 2. Notification: Factura Emisa ──
print("\n2. Notification: Factura Emisa...")
if exists("Notification", "DiDi - Factura Emisa"):
print(" Already exists")
else:
r = s.post(f"{URL}/api/resource/Notification", json={
"name": "DiDi - Factura Emisa",
"subject": "Factura {{ doc.name }} - {{ doc.grand_total }} {{ doc.currency }}",
"document_type": "Sales Invoice",
"event": "Submit",
"channel": "Email",
"attach_print": 1,
"print_format": "DiDi Invoice",
"condition": "doc.docstatus == 1",
"recipients": [
{
"receiver_by_document_field": "contact_email",
}
],
"message": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<div style="background-color: #0d9488; padding: 20px; text-align: center;">
<h1 style="color: white; margin: 0;">DiDi - Factura Emisa</h1>
</div>
<div style="padding: 30px; background: #f9fafb;">
<p>Stimate client,</p>
<p>Va informam ca a fost emisa factura <strong>{{ doc.name }}</strong>.</p>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
<tr style="background: #e5e7eb;"><td style="padding: 8px; font-weight: bold;">Nr. Factura</td><td style="padding: 8px;">{{ doc.name }}</td></tr>
<tr><td style="padding: 8px; font-weight: bold;">Data</td><td style="padding: 8px;">{{ doc.posting_date }}</td></tr>
<tr style="background: #e5e7eb;"><td style="padding: 8px; font-weight: bold;">Total</td><td style="padding: 8px;">{{ doc.grand_total }} {{ doc.currency }}</td></tr>
<tr><td style="padding: 8px; font-weight: bold;">Status</td><td style="padding: 8px;">{{ doc.status }}</td></tr>
</table>
<p>Factura in format PDF este atasata la acest email.</p>
<p>Va multumim,<br><strong>Echipa DiDi / Clossers</strong></p>
</div>
<div style="padding: 15px; text-align: center; font-size: 12px; color: #9ca3af;">
TOP CLOSSERS SRL | CUI: 36193026 | office@clossers.com
</div>
</div>""",
"enabled": 1,
})
print(f" Created: {r.status_code}")
# ── 3. Notification: Plata Confirmata ──
print("\n3. Notification: Plata Confirmata...")
if exists("Notification", "DiDi - Plata Confirmata"):
print(" Already exists")
else:
r = s.post(f"{URL}/api/resource/Notification", json={
"name": "DiDi - Plata Confirmata",
"subject": "Plata confirmata - {{ doc.amount }} {{ doc.currency }}",
"document_type": "Payment Log",
"event": "New",
"channel": "Email",
"condition": "doc.status == 'Succeeded'",
"recipients": [
{
"receiver_by_document_field": "customer",
}
],
"message": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<div style="background-color: #0d9488; padding: 20px; text-align: center;">
<h1 style="color: white; margin: 0;">Plata Confirmata</h1>
</div>
<div style="padding: 30px; background: #f9fafb;">
<p>Stimate client,</p>
<p>Va confirmam ca plata dumneavoastra a fost procesata cu succes.</p>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
<tr style="background: #e5e7eb;"><td style="padding: 8px; font-weight: bold;">Suma</td><td style="padding: 8px;">{{ doc.amount }} {{ doc.currency }}</td></tr>
<tr><td style="padding: 8px; font-weight: bold;">Status</td><td style="padding: 8px;">{{ doc.status }}</td></tr>
<tr style="background: #e5e7eb;"><td style="padding: 8px; font-weight: bold;">Data</td><td style="padding: 8px;">{{ doc.creation }}</td></tr>
</table>
<p>Factura fiscala va fi disponibila in dashboard-ul dumneavoastra.</p>
<p>Va multumim,<br><strong>Echipa DiDi / Clossers</strong></p>
</div>
<div style="padding: 15px; text-align: center; font-size: 12px; color: #9ca3af;">
TOP CLOSSERS SRL | CUI: 36193026 | office@clossers.com
</div>
</div>""",
"enabled": 1,
})
print(f" Created: {r.status_code}")
# ── 4. Notification: Expirare Abonament (7 zile inainte) ──
print("\n4. Notification: Expirare Abonament...")
if exists("Notification", "DiDi - Expirare Abonament Notificare"):
print(" Already exists")
else:
r = s.post(f"{URL}/api/resource/Notification", json={
"name": "DiDi - Expirare Abonament Notificare",
"subject": "Abonamentul dumneavoastra expira in curand",
"document_type": "Subscription",
"event": "Days Before",
"days_in_advance": 7,
"date_changed": "current_invoice_end",
"channel": "Email",
"condition": "doc.status == 'Active'",
"recipients": [
{
"receiver_by_document_field": "party",
}
],
"message": """<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<div style="background-color: #f59e0b; padding: 20px; text-align: center;">
<h1 style="color: white; margin: 0;">Abonament - Expirare Apropiata</h1>
</div>
<div style="padding: 30px; background: #f9fafb;">
<p>Stimate client,</p>
<p>Va informam ca abonamentul dumneavoastra expira pe <strong>{{ doc.current_invoice_end }}</strong>.</p>
<p>Pentru a continua sa beneficiati de serviciile DiDi, va rugam sa reinnoti abonamentul din dashboard.</p>
<p>Va multumim,<br><strong>Echipa DiDi / Clossers</strong></p>
</div>
</div>""",
"enabled": 1,
})
print(f" Created: {r.status_code}")
print("\nDone! Email infrastructure ready.")
print("Email Account 'DiDi Outgoing' configured with key from SENDGRID_API_KEY env var.")
print("To rotate the key, run this script again with a new SENDGRID_API_KEY value.")