You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
2.3 KiB
117 lines
2.3 KiB
#!/usr/bin/env python3 |
|
|
|
|
|
import sys |
|
import os |
|
from datetime import datetime, timedelta |
|
from dotenv import load_dotenv |
|
|
|
# load same environment config as Flask |
|
load_dotenv("/home/def/otb_billing/.env") |
|
|
|
sys.path.append("/home/def/otb_billing/backend") |
|
|
|
from app import get_db_connection, send_configured_email |
|
|
|
|
|
REMINDER_DAYS = 7 |
|
OVERDUE_DAYS = 14 |
|
|
|
|
|
def main(): |
|
conn = get_db_connection() |
|
cursor = conn.cursor(dictionary=True) |
|
|
|
now = datetime.utcnow() |
|
|
|
cursor.execute(""" |
|
SELECT |
|
i.id, |
|
i.invoice_number, |
|
i.created_at, |
|
i.total, |
|
i.client_id, |
|
c.email, |
|
c.company_name, |
|
c.contact_name |
|
FROM invoices i |
|
JOIN clients c ON c.id = i.client_id |
|
WHERE i.status IN ('pending','sent') |
|
""") |
|
|
|
invoices = cursor.fetchall() |
|
|
|
for inv in invoices: |
|
age = (now - inv["created_at"]).days |
|
|
|
email = inv["email"] |
|
if not email: |
|
continue |
|
|
|
name = inv.get("contact_name") or inv.get("company_name") or "Client" |
|
|
|
portal_url = f"https://portal.outsidethebox.top/portal/invoice/{inv['id']}" |
|
|
|
if age >= OVERDUE_DAYS: |
|
|
|
subject = f"Invoice {inv['invoice_number']} is overdue" |
|
|
|
body = f""" |
|
Hello {name}, |
|
|
|
Invoice {inv['invoice_number']} is now overdue. |
|
|
|
Amount Due: |
|
{inv['total']} |
|
|
|
View invoice: |
|
{portal_url} |
|
|
|
Please arrange payment at your earliest convenience. |
|
|
|
OutsideTheBox |
|
""" |
|
|
|
send_configured_email( |
|
to_email=email, |
|
subject=subject, |
|
body=body, |
|
attachments=None, |
|
email_type="invoice_overdue", |
|
invoice_id=inv["id"] |
|
) |
|
|
|
elif age >= REMINDER_DAYS: |
|
|
|
subject = f"Invoice {inv['invoice_number']} reminder" |
|
|
|
body = f""" |
|
Hello {name}, |
|
|
|
This is a reminder that invoice {inv['invoice_number']} is still outstanding. |
|
|
|
Amount Due: |
|
{inv['total']} |
|
|
|
View invoice: |
|
{portal_url} |
|
|
|
Thank you. |
|
|
|
OutsideTheBox |
|
""" |
|
|
|
send_configured_email( |
|
to_email=email, |
|
subject=subject, |
|
body=body, |
|
attachments=None, |
|
email_type="invoice_reminder", |
|
invoice_id=inv["id"] |
|
) |
|
|
|
conn.close() |
|
|
|
|
|
if __name__ == "__main__": |
|
main()
|
|
|