> ## Documentation Index
> Fetch the complete documentation index at: https://docs.quinnsambal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Invoices

> Invoice lifecycle management — 6 status, 5 bucket AR aging, verifikasi pembayaran tiga tahap, partial payment, WhatsApp integration, dan Quick Pay di SNISHOP ERP.

# Invoices

<img src="https://mintcdn.com/quinnofspicy/e4f_upKhVWcjsUmM/docs/mintlify/screenshots/finance/invoices.png?fit=max&auto=format&n=e4f_upKhVWcjsUmM&q=85&s=c93caeda411f5ee54e571954a595c741" alt="Invoice Management" width="1920" height="1080" data-path="docs/mintlify/screenshots/finance/invoices.png" />

Halaman Invoices mengelola seluruh siklus tagihan B2B dari pembuatan hingga pelunasan. Sistem ini mendukung **6 status invoice**, **5 bucket AR aging** untuk piutang, **verifikasi pembayaran tiga tahap** (verified/pending/rejected), partial payment dengan running balance, auto-generation dari POS transaction dan customer PO, serta integrasi WhatsApp untuk pengiriman dan reminder. Setiap pembayaran yang terverifikasi otomatis membuat `FinancialRecord` dan mengupdate `Account.current_balance`.

## Arsitektur Invoice Management

```mermaid theme={null}
graph TB
    subgraph CREATION["Pembuatan Invoice"]
        MANUAL["Manual Create"]
        POS_AUTO["POS B2B<br/>Auto-generate"]
        CPO["Customer PO<br/>Convert to Invoice"]
        QUOTE["Quotation<br/>Convert to Invoice"]
        ORDER["Order<br/>Convert to Invoice"]
    end

    subgraph TYPES["3 Tipe Invoice"]
        INV["Invoice<br/>Tagihan resmi"]
        QUOT["Quotation<br/>Penawaran"]
        PROFORMA["Proforma<br/>Invoice sementara"]
    end

    subgraph LIFECYCLE["Lifecycle (6 Status)"]
        D["Draft"]
        S["Sent"]
        PP["Partially Paid"]
        P["Paid"]
        OD["Overdue"]
        C["Cancelled"]
    end

    subgraph PAYMENT["Pembayaran"]
        VERIFY["Verification<br/>3 tahap"]
        PARTIAL["Partial Payment<br/>Running balance"]
        QUICK["Quick Pay<br/>Idempotency key"]
        WA["WhatsApp<br/>Notification"]
    end

    subgraph OUTPUT["Output"]
        AGING["AR Aging<br/>5 bucket"]
        REPORT["Laporan<br/>Summary & detail"]
        EXPORT["Export<br/>PDF/Excel/CSV"]
    end

    MANUAL --> CREATION
    POS_AUTO --> CREATION
    CPO --> CREATION
    QUOTE --> CREATION
    ORDER --> CREATION

    CREATION --> TYPES
    TYPES --> LIFECYCLE

    LIFECYCLE --> PAYMENT
    PAYMENT --> OUTPUT
```

## Invoice Lifecycle

```mermaid theme={null}
stateDiagram-v2
    [*] --> Draft: Create
    Draft --> Sent: Kirim ke customer
    Draft --> Cancelled: Batal
    Sent --> PartiallyPaid: Bayar sebagian
    Sent --> Paid: Bayar lunas
    Sent --> Overdue: Lewat due date
    Sent --> Cancelled: Batal
    PartiallyPaid --> Paid: Bayar sisa
    PartiallyPaid --> Overdue: Lewat due date
    Overdue --> Paid: Bayar (late payment)
    Paid --> [*]
    Cancelled --> [*]
```

### 6 Status Invoice

| Status | Deskripsi | Aksi |
| - | - | - |
| **Draft** | Baru dibuat, belum dikirim | Edit, Delete, Send |
| **Sent** | Sudah dikirim, menunggu pembayaran | Record payment, Cancel |
| **Partially Paid** | Customer bayar sebagian | Record more payments |
| **Paid** | Lunas | Read-only, archive |
| **Overdue** | Lewat due date | Follow up, record late payment |
| **Cancelled** | Dibatalkan | Read-only |

## Entity Invoice

### Field Invoice

| Field | Tipe | Deskripsi |
| - | - | - |
| invoice\_number | string | Nomor invoice (INV-2026-001) |
| invoice\_type | enum | invoice, quotation, proforma |
| source\_type | enum | manual, customer\_po, order, quotation, pos\_transaction |
| status | enum | draft, sent, partially\_paid, paid, overdue, cancelled |
| total\_amount | number | Total tagihan |
| paid\_amount | number | Total yang sudah dibayar (verified only) |
| payment\_term\_days | number | Tempo pembayaran (default 30 hari) |
| delivery\_status | enum | Status pengiriman |
| deliveries | array | List pengiriman dengan `lot_id` |
| payments | array | Ledger pembayaran |
| is\_locked | boolean | Locked untuk edit |
| company\_id | UUID | Multi-tenant isolation |

### Entity InvoicePayment

| Field | Tipe | Deskripsi |
| - | - | - |
| verification\_status | enum | verified, pending, rejected |
| status | enum | posted, needs\_reconciliation |
| amount | number | Nominal pembayaran |
| payment\_date | date | Tanggal pembayaran |
| financial\_record\_id | UUID | Link ke FinancialRecord |
| reconciliation\_reason | string | Alasan jika needs\_reconciliation |
| invoice\_id | UUID | Link ke Invoice |

## Create Invoice

### Step-by-Step

1. Klik **"Create Invoice"**
2. Pilih customer B2B
3. Auto-fill customer info

| Field | Required | Deskripsi |
| - | - | - |
| Customer | ✓ | Pilih dari CRM |
| Invoice Type | ✓ | Invoice, Quotation, Proforma |
| Items | ✓ | Produk/jasa + quantity + price |
| Payment Terms | ✓ | Due on receipt, Net 15, Net 30, Custom |
| Notes | Opsional | Catatan tambahan |
| Due Date | Auto | BTT date + payment\_term\_days |

4. Review invoice
5. Save as Draft atau Send

### Source Types

| Source | Deskripsi |
| - | - |
| manual | Input manual dari form |
| customer\_po | Convert dari Customer Purchase Order |
| order | Convert dari Order |
| quotation | Convert dari Quotation |
| pos\_transaction | Auto-generate dari POS B2B transaction |

## Payment Terms

### Due Date Calculation

```
Due Date = BTT Date + payment_term_days
```

| Term | Days | Contoh |
| - | - | - |
| Due on receipt | 0 | BTT 1 Okt → Due 1 Okt |
| Net 15 | 15 | BTT 1 Okt → Due 16 Okt |
| Net 30 | 30 | BTT 1 Okt → Due 31 Okt |
| Custom | N | BTT 1 Okt → Due (1+N) Okt |

### Reminder System

| Timing | Reminder |
| - | - |
| 7 days before due | Reminder pertama |
| On due date | Final reminder |
| After due date | Overdue notice |

## Verifikasi Pembayaran Tiga Tahap

```mermaid theme={null}
sequenceDiagram
    participant C as Customer
    participant U as User
    participant S as Server
    participant FR as FinancialRecord
    participant ACC as Account

    C->>U: Bayar invoice (transfer/cash)
    U->>S: recordCompanyInvoicePayment()
    S->>S: Validate idempotency_key
    S->>S: Compute paid_amount from verified payments
    S->>S: Validate progress (no overpayment)

    alt verification_status = verified
        S->>S: Update Invoice.paid_amount += amount
        S->>FR: Create FinancialRecord (type: income)
        S->>ACC: Update current_balance += amount
        S->>S: Update Invoice.status (if fully paid)
        S-->>U: Payment verified & posted
    else verification_status = pending
        S->>S: Store in payment history
        Note over S: TIDAK update paid_amount
        Note over S: TIDAK create FinancialRecord
        S-->>U: Payment pending review
    else verification_status = rejected
        S->>S: Mark as rejected
        S-->>U: Payment rejected + reason
    end
```

### Verification Status

| Status | 计入 paid\_amount | Create FR | Update Balance | Use Case |
| - | - | - | - | - |
| **Verified** | ✓ | ✓ | ✓ | Pembayaran confirmed |
| **Pending** | ✗ | ✗ | ✗ | Menunggu verifikasi |
| **Rejected** | ✗ | ✗ | ✗ | Pembayaran ditolak |

### Reconciliation

Jika pembayaran gagal di-projection (misalnya account tidak ditemukan):

* InvoicePayment status: `needs_reconciliation`
* `reconciliation_reason` diisi dengan alasan
* Admin harus reconcile manual

## Partial Payment

### Running Balance

```mermaid theme={null}
graph LR
    INV["Invoice<br/>Total: Rp 10.000.000"] --> P1["Payment 1<br/>Rp 3.000.000<br/>Outstanding: Rp 7.000.000"]
    P1 --> P2["Payment 2<br/>Rp 4.000.000<br/>Outstanding: Rp 3.000.000"]
    P2 --> P3["Payment 3<br/>Rp 3.000.000<br/>Outstanding: Rp 0<br/>Status: Paid"]
```

### Status Transition

| Paid Amount | Status |
| - | - |
| 0 | Sent |
| 0 \< paid \< total | Partially Paid |
| paid = total | Paid |

## Quick Pay

Quick Pay memungkinkan pencatatan pembayaran cepat dengan idempotency key:

```
recordCompanyInvoicePayment({
  invoice_id: "uuid",
  amount: 5000000,
  payment_date: "2026-10-10",
  verification_status: "verified",
  idempotency_key: "unique-key-123"
})
```

## AR Aging (Piutang)

### 5 Bucket Aging

| Bucket | Umur | Warna | Aksi |
| - | - | - | - |
| Current | 0 hari | Hijau | Monitor |
| 1-30 days | 1-30 hari | Kuning | Reminder |
| 31-60 days | 31-60 hari | Oranye | Follow-up |
| 61-90 days | 61-90 hari | Merah | Escalate |
| >90 days | >90 hari | Merah Tua | Collection |

### Aging Dashboard

| Metric | Deskripsi |
| - | - |
| Total Piutang | Total outstanding |
| Jatuh Tempo | Amount yang sudah overdue |
| Rata-rata Umur | Average age of receivables |
| Lancar | Amount di bucket Current |

### Top 10 Debtors

| Rank | Customer | Outstanding | Max Overdue Days |
| - | - | - | - |
| 1 | PT ABC | Rp 50.000.000 | 45 |
| 2 | PT XYZ | Rp 35.000.000 | 15 |
| 3 | CV DEF | Rp 20.000.000 | 0 |

## WhatsApp Integration

### Notification Types

| Event | Message |
| - | - |
| Invoice Created | "Invoice INV-2026-001 sudah dibuat. Total: Rp 10.000.000. Tempo: 31 Okt 2026" |
| Payment Reminder | "Reminder: Invoice INV-2026-001 jatuh tempo 7 hari lagi" |
| Overdue Notice | "Invoice INV-2026-001 sudah jatuh tempo. Mohon segera lakukan pembayaran" |
| Payment Received | "Pembayaran Rp 5.000.000 untuk invoice INV-2026-001 sudah diterima" |

## Invoice Templates

### Standard Template

| Component | Deskripsi |
| - | - |
| Company Logo | Logo perusahaan |
| Company Info | Nama, alamat, NPWP |
| Customer Info | Nama, alamat, NPWP |
| Invoice Number | Nomor unik |
| Date & Due Date | Tanggal invoice dan jatuh tempo |
| Item List | Daftar produk/jasa |
| Subtotal, Tax, Total | Perhitungan |
| Payment Terms | Terms & conditions |
| Bank Account Info | Rekening untuk pembayaran |

### Custom Template

* Upload custom template
* Configure fields
* Save untuk future use

## Invoice Numbering

### Auto Numbering

```
Format: INV-{year}-{sequence}
Contoh: INV-2026-001, INV-2026-002, ...
```

### Custom Numbering

* Configure prefix
* Configure sequence
* Configure year format

## Export & Print

| Format | Use Case |
| - | - |
| PDF | Kirim ke customer, arsip |
| Excel | Analisis, manipulasi data |
| CSV | Integrasi sistem lain |
| Print | Cetak langsung |

## Reporting

### Invoice Summary

| Metric | Deskripsi |
| - | - |
| Total Invoices | Jumlah invoice per periode |
| Paid vs Unpaid | Perbandingan |
| Outstanding Balance | Total piutang |
| Average Payment Time | Rata-rata waktu bayar |

### Aging Report

| Bucket | Count | Amount |
| - | - | - |
| Current | 15 | Rp 100.000.000 |
| 1-30 days | 8 | Rp 50.000.000 |
| 31-60 days | 3 | Rp 20.000.000 |
| 61-90 days | 1 | Rp 10.000.000 |
| >90 days | 0 | Rp 0 |

### Customer Statement

| Field | Deskripsi |
| - | - |
| All invoices per customer | Daftar invoice |
| Payment history | Riwayat pembayaran |
| Outstanding balance | Sisa piutang |
| Statement print | Cetak statement |

## Filter & Search

| Filter | Opsi |
| - | - |
| Status | Draft, Sent, Partially Paid, Paid, Overdue, Cancelled |
| Customer | Pilih customer tertentu |
| Date Range | Invoice date, due date |
| Amount Range | Min - Max |
| Invoice Type | Invoice, Quotation, Proforma |
| Source Type | Manual, Customer PO, Order, Quotation, POS |

## Best Practices

### Invoice Timing

* Send invoice segera setelah delivery
* Follow up sebelum due date
* Escalate overdue invoices
* Document all communications

### Payment Terms

* Clear payment terms di invoice
* Consistent terms per customer
* Late fee policy (jika ada)
* Early payment discount (optional)

### Record Keeping

* Keep all invoice records
* Backup invoice data
* Organize by customer
* Easy retrieval untuk audit


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.