Create, issue, or generate invoices for AiTraining2U PLT. Use when asked to invoice a client, bill someone, create a quotation, or generate payment documents.
Required fields — ask the user for anything missing, do not assume or fill in yourself:
| Field | Required | Notes |
|---|---|---|
| Client company name | ✅ Must ask | Never guess |
| Attn (contact person) | ✅ Must ask | Never guess |
| Client address | ✅ Must ask | Never guess |
| Client tel | ✅ Must ask | Never guess |
| Client email | ✅ Must ask | Never guess |
| Line item description | ✅ Must ask | Never guess |
| Qty | ✅ Must ask | Never guess |
| Unit price (RM) | ✅ Must ask | Never guess |
| Invoice date | Default: today | Only default if user doesn't specify |
Rules:
import sqlite3, os
DB = os.path.expanduser("~/invoices.db")
conn = sqlite3.connect(DB)
c = conn.cursor()
year = 2026 # use current year
c.execute("UPDATE invoice_sequence SET last_no = last_no + 1 WHERE year = ?", (year,))
c.execute("SELECT last_no FROM invoice_sequence WHERE year = ?", (year,))
n = c.fetchone()[0]
conn.commit(); conn.close()
invoice_no = f"INV-ATU-{year}-{n:04d}"
year = invoice_date[:4]
pdf_path = os.path.expanduser(f"~/Documents/AiTraining2U/Invoices/{year}/{invoice_no}.pdf")
conn = sqlite3.connect(DB)
c = conn.cursor()
c.execute("""
INSERT INTO invoices
(invoice_no, invoice_date, due_date, client_company, client_attn,
client_email, client_tel, client_address, subtotal, sst_rate, sst_amount, total, pdf_path)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)
""", (invoice_no, invoice_date, "Upon Receipt", client_company, client_attn,
client_email, client_tel, client_address, subtotal, sst_rate, sst_amount, total,
pdf_path))
for i, item in enumerate(items):
c.execute("""
INSERT INTO invoice_items (invoice_no, item_no, description, qty, unit_price, amount)
VALUES (?,?,?,?,?,?)
""", (invoice_no, i+1, item["description"], item["qty"], item["unit_price"], item["amount"]))
conn.commit(); conn.close()
~/.local/bin/uv run --with reportlab python3 \
~/Agent_K_Telegram/skills/issue-invoice/scripts/build_pdf.py INV-ATU-YYYY-XXXX
~/Documents/AiTraining2U/Invoices/{YYYY}/{invoice_no}_{Company-Slug}.pdfVynn-Capital, Kumpulan-Modal-Perdana)A. Telegram — send PDF to the channel the user is interacting from:
$TELEGRAM_GROUP_CHAT_ID$TELEGRAM_DM_CHAT_IDB. Email to client — ONLY after user confirms (e.g. "ok send", "go ahead", "email it", "send to client"):
$CC_EMAILS (comma-separated)Invoice {invoice_no} | {workshop/service name} – AiTraining2U PLT~/Documents/AiTraining2U/Invoices/{YYYY}/{invoice_no}_{Company-Slug}.pdf$BANK_NAME / $BANK_ACCT_NAME / $BANK_ACCT_NO)$COMPANY_CONTACT_NAME, $COMPANY_NAME, $COMPANY_EMAIL~/.local/bin/uv run --with google-api-python-client --with google-auth \
python3 ~/Agent_K_Telegram/skills/send-email/scripts/send_email.py \
--to CLIENT_EMAIL \
--cc $CC_EMAILS \
--subject "SUBJECT" \
--attach PATH_TO_PDF \
--html 'HTML_BODY_STRING'
This ensures the From header shows: Atlas (AiTraining2U) <[email protected]>⚠️ NEVER email the client without explicit user approval. Always wait for confirmation after sending the PDF preview to Telegram.
~/ root — always use the Invoices/{YYYY}/ folder.xlsx drafts — PDF only, generated from build_pdf.pyInvoices/{YYYY}/ is the master copy$COMPANY_NAME$COMPANY_REG$COMPANY_SST_NO (always show on invoice)$COMPANY_ADDRESS$COMPANY_CONTACT_NAME$COMPANY_EMAIL$BANK_NAME | $BANK_ACCT_NAME | $BANK_ACCT_NOINV-ATU-YYYY-XXXX — sequential per year, managed via ~/invoices.db table invoice_sequence
~/invoices.dbinvoices, invoice_items, invoice_sequence~/Agent_K_Telegram/skills/issue-invoice/scripts/setup_db.py (run once if DB missing)| Field | Notes |
|---|---|
| status | issued / paid / void |
| subtotal | before SST |
| sst_rate | 0.0 or 0.08 |
| sst_amount | computed |
| total | final payable |
| pdf_path | local file path |