|
|
|
@ -362,8 +362,50 @@ def get_revenue_report_data(): |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def ensure_email_log_table(): |
|
|
|
|
|
|
|
conn = get_db_connection() |
|
|
|
|
|
|
|
cursor = conn.cursor() |
|
|
|
|
|
|
|
cursor.execute(""" |
|
|
|
|
|
|
|
CREATE TABLE IF NOT EXISTS email_log ( |
|
|
|
|
|
|
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, |
|
|
|
|
|
|
|
email_type VARCHAR(50) NOT NULL, |
|
|
|
|
|
|
|
invoice_id INT UNSIGNED NULL, |
|
|
|
|
|
|
|
recipient_email VARCHAR(255) NOT NULL, |
|
|
|
|
|
|
|
subject VARCHAR(255) NOT NULL, |
|
|
|
|
|
|
|
status VARCHAR(20) NOT NULL, |
|
|
|
|
|
|
|
error_message TEXT NULL, |
|
|
|
|
|
|
|
sent_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, |
|
|
|
|
|
|
|
KEY idx_email_log_invoice_id (invoice_id), |
|
|
|
|
|
|
|
KEY idx_email_log_type (email_type), |
|
|
|
|
|
|
|
KEY idx_email_log_sent_at (sent_at) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
""") |
|
|
|
|
|
|
|
conn.commit() |
|
|
|
|
|
|
|
conn.close() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def log_email_event(email_type, recipient_email, subject, status, invoice_id=None, error_message=None): |
|
|
|
|
|
|
|
ensure_email_log_table() |
|
|
|
|
|
|
|
conn = get_db_connection() |
|
|
|
|
|
|
|
cursor = conn.cursor() |
|
|
|
|
|
|
|
cursor.execute(""" |
|
|
|
|
|
|
|
INSERT INTO email_log |
|
|
|
|
|
|
|
(email_type, invoice_id, recipient_email, subject, status, error_message) |
|
|
|
|
|
|
|
VALUES (%s, %s, %s, %s, %s, %s) |
|
|
|
|
|
|
|
""", ( |
|
|
|
|
|
|
|
email_type, |
|
|
|
|
|
|
|
invoice_id, |
|
|
|
|
|
|
|
recipient_email, |
|
|
|
|
|
|
|
subject, |
|
|
|
|
|
|
|
status, |
|
|
|
|
|
|
|
error_message |
|
|
|
|
|
|
|
)) |
|
|
|
|
|
|
|
conn.commit() |
|
|
|
|
|
|
|
conn.close() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def send_configured_email(to_email, subject, body, attachments=None): |
|
|
|
def send_configured_email(to_email, subject, body, attachments=None, email_type="system_email", invoice_id=None): |
|
|
|
settings = get_app_settings() |
|
|
|
settings = get_app_settings() |
|
|
|
|
|
|
|
|
|
|
|
smtp_host = (settings.get("smtp_host") or "").strip() |
|
|
|
smtp_host = (settings.get("smtp_host") or "").strip() |
|
|
|
@ -395,6 +437,7 @@ def send_configured_email(to_email, subject, body, attachments=None): |
|
|
|
maintype, subtype = mime_type.split("/", 1) |
|
|
|
maintype, subtype = mime_type.split("/", 1) |
|
|
|
msg.add_attachment(data, maintype=maintype, subtype=subtype, filename=filename) |
|
|
|
msg.add_attachment(data, maintype=maintype, subtype=subtype, filename=filename) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
if use_ssl: |
|
|
|
if use_ssl: |
|
|
|
with smtplib.SMTP_SSL(smtp_host, smtp_port, timeout=30) as server: |
|
|
|
with smtplib.SMTP_SSL(smtp_host, smtp_port, timeout=30) as server: |
|
|
|
if smtp_user: |
|
|
|
if smtp_user: |
|
|
|
@ -410,6 +453,11 @@ def send_configured_email(to_email, subject, body, attachments=None): |
|
|
|
server.login(smtp_user, smtp_pass) |
|
|
|
server.login(smtp_user, smtp_pass) |
|
|
|
server.send_message(msg) |
|
|
|
server.send_message(msg) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_email_event(email_type, to_email, subject, "sent", invoice_id=invoice_id, error_message=None) |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
|
|
|
|
log_email_event(email_type, to_email, subject, "failed", invoice_id=invoice_id, error_message=str(e)) |
|
|
|
|
|
|
|
raise |
|
|
|
|
|
|
|
|
|
|
|
@app.route("/settings", methods=["GET", "POST"]) |
|
|
|
@app.route("/settings", methods=["GET", "POST"]) |
|
|
|
def settings(): |
|
|
|
def settings(): |
|
|
|
ensure_app_settings_table() |
|
|
|
ensure_app_settings_table() |
|
|
|
@ -492,6 +540,8 @@ def email_invoice(invoice_id): |
|
|
|
recipient, |
|
|
|
recipient, |
|
|
|
subject, |
|
|
|
subject, |
|
|
|
body, |
|
|
|
body, |
|
|
|
|
|
|
|
email_type="invoice", |
|
|
|
|
|
|
|
invoice_id=invoice_id, |
|
|
|
attachments=[{ |
|
|
|
attachments=[{ |
|
|
|
"filename": f"{invoice['invoice_number']}.pdf", |
|
|
|
"filename": f"{invoice['invoice_number']}.pdf", |
|
|
|
"mime_type": "application/pdf", |
|
|
|
"mime_type": "application/pdf", |
|
|
|
@ -529,6 +579,8 @@ def email_revenue_report_json(): |
|
|
|
recipient, |
|
|
|
recipient, |
|
|
|
subject, |
|
|
|
subject, |
|
|
|
body, |
|
|
|
body, |
|
|
|
|
|
|
|
email_type="invoice", |
|
|
|
|
|
|
|
invoice_id=invoice_id, |
|
|
|
attachments=[{ |
|
|
|
attachments=[{ |
|
|
|
"filename": "revenue_report.json", |
|
|
|
"filename": "revenue_report.json", |
|
|
|
"mime_type": "application/json", |
|
|
|
"mime_type": "application/json", |
|
|
|
@ -560,6 +612,8 @@ def email_accounting_package(): |
|
|
|
recipient, |
|
|
|
recipient, |
|
|
|
subject, |
|
|
|
subject, |
|
|
|
body, |
|
|
|
body, |
|
|
|
|
|
|
|
email_type="invoice", |
|
|
|
|
|
|
|
invoice_id=invoice_id, |
|
|
|
attachments=[{ |
|
|
|
attachments=[{ |
|
|
|
"filename": "accounting_package.zip", |
|
|
|
"filename": "accounting_package.zip", |
|
|
|
"mime_type": "application/zip", |
|
|
|
"mime_type": "application/zip", |
|
|
|
|