Systems Library / Finance Automation / How to Build an AI Credit Note Generator
Finance Automation invoicing billing

How to Build an AI Credit Note Generator

Generate credit notes automatically when returns or adjustments occur.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

Credit notes need to reference the original invoice, calculate the correct amount, and update your books. I built an ai credit note generator that creates properly formatted credit notes from adjustment requests, links them to original invoices, and updates the client's balance automatically.

Adjustments processed correctly, every time.

What You Need Before Starting

Step 1: Define Credit Note Structure

from dataclasses import dataclass
from datetime import datetime

@dataclass
class CreditNote:
    credit_note_number: str
    original_invoice: str
    client_name: str
    reason: str
    items: list
    amount: float
    created_at: str = ""

    def __post_init__(self):
        self.created_at = datetime.now().isoformat()

Step 2: Generate from Invoice Reference

import sqlite3

def create_credit_note(conn, invoice_number, reason, line_items=None):
    invoice = conn.execute(
        "SELECT client_id, amount FROM invoices WHERE invoice_number=?", (invoice_number,)
    ).fetchone()

    if not invoice:
        return {"error": "Invoice not found"}

    cn_number = generate_cn_number(conn)
    credit_amount = sum(item["amount"] for item in line_items) if line_items else invoice[1]

    conn.execute("""
        INSERT INTO credit_notes (cn_number, invoice_number, client_id, amount, reason, created_at)
        VALUES (?,?,?,?,?,?)
    """, (cn_number, invoice_number, invoice[0], credit_amount, reason, datetime.now().isoformat()))

    conn.execute(
        "UPDATE invoices SET status='credited' WHERE invoice_number=?", (invoice_number,)
    )
    conn.commit()
    return {"cn_number": cn_number, "amount": credit_amount}

def generate_cn_number(conn):
    row = conn.execute("SELECT COUNT(*) FROM credit_notes").fetchone()
    return f"CN-{datetime.now().strftime('%Y')}-{(row[0] or 0) + 1:04d}"

Step 3: Format and Send

def format_credit_note(cn_data):
    return f"""# Credit Note {cn_data['cn_number']}

Original Invoice: {cn_data['invoice_number']}
Client: {cn_data['client_name']}
Date: {datetime.now().strftime('%B %d, %Y')}

Reason: {cn_data['reason']}

Credit Amount: ${cn_data['amount']:.2f}

This amount will be applied to your account balance.
"""

Step 4: Update Client Balance

def update_client_balance(conn, client_id, credit_amount):
    conn.execute("""
        UPDATE client_balances
        SET credit_balance = credit_balance + ?
        WHERE client_id = ?
    """, (credit_amount, client_id))
    conn.commit()

Step 5: Track Credit Notes

def credit_note_report(conn, months=3):
    rows = conn.execute("""
        SELECT cn_number, invoice_number, client_id, amount, reason, created_at
        FROM credit_notes ORDER BY created_at DESC LIMIT 50
    """).fetchall()

    total = sum(r[3] for r in rows)
    report = f"# Credit Notes Report\n\nTotal credited: ${total:.2f}\n\n"
    for r in rows:
        report += f"- {r[0]} (ref: {r[1]}): ${r[3]:.2f} - {r[4]}\n"
    return report

What to Build Next

Add automatic credit note triggers for specific scenarios like service downtime or SLA breaches. When your monitoring system detects an outage, it calculates the credit owed and generates the note without anyone asking.

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems