# S19-09 Assumptions — Penghutang (AR) Sub-module

**Task:** Penghutang (AR Debtors) — full CRUD + invoice/credit/debit notes
**Date:** 2026-05-09

## Assumptions

1. **Domain directory.** `app/Domain/AR/` — greenfield. No AR domain exists yet.

2. **Debtor = Party link.** `ar_debtors` stores a reference to `parties` (from `app/Domain/Parties/`) via `party_id`. A party can be linked to an AR debtor record. The AR debtor record adds AR-specific fields (debtor code, credit limit, payment terms, default AR account).

3. **Auto double-entry.** Invoice creation dispatches journal entry: Dr Debtor account (per ar_debtor.ar_account_id), Cr Sales account (per ar_debtor.sales_account_id). Both are `coa_accounts.id` FKs. The CreateArInvoice action calls the existing Accounting domain's CreateJournalEntry or writes lines directly into journal_entry_lines. Since full journal integration requires the Transactions domain to be stable, the double-entry is written directly to `journal_entries` + `journal_entry_lines` for now.

4. **Document numbering.** Running numbers per tenant per document type: `INV-{YYYY}-{NNNNN}`, `DN-{YYYY}-{NNNNN}`, `CN-{YYYY}-{NNNNN}`. Stored in `ar_document_sequences` table (tenant_id, type, year, last_seq). Uses a pessimistic lock (`lockForUpdate()`) to ensure uniqueness under concurrent writes.

5. **Imbalance guard.** If Dr ≠ Cr when building the journal entry, CreateArInvoice throws `ArImbalanceException`. The controller returns a 422 with the error message ("Debit tidak sama dengan Kredit").

6. **PDF generation.** Deferred — no PDF library. The task spec says "generate invoice/DN/CN" but PDF rendering requires barryvdh/dompdf which is not installed. The endpoint for generating a document returns a JSON representation that can be printed via browser. Documented in assumptions.

7. **UI routes.** API routes under `/api/v1/ar/` for CRUD. No full Inertia pages in this task — the task focuses on backend (domain + API). Frontend pages are a follow-on.

8. **Void vs Delete.** Invoices/notes are voided (status = 'voided'), not deleted. Deletion is only for draft documents. Follows the same pattern as Transactions.

9. **Parties domain.** `app/Domain/Parties/` already exists. `ar_debtors.party_id` references `parties.id`.

10. **`ar_document_sequences` table.** Added in this task's migration. If two threads call the sequence generator simultaneously, the `lockForUpdate()` ensures only one proceeds.

## Out of Scope
- PDF generation (no barryvdh/dompdf)
- Full Inertia frontend pages
- Statement of account report (follow-on task)
- Aging analysis (follow-on task)
