# PostAccountPayableDocument

## Permission Scope

accountPayableDocument

## Overview

postAccountPayableDocument posts a REGISTERED AP document. Posting is the point where AP emits an accounting event: the command builds an ACCOUNT_PAYABLE_RECOGNIZED payload from AP document lines, distribution lines, and due schedule lines, posts that event to the accounting-event handoff store, and moves the AP document to POSTED. The AP document does not create a JournalEntry directly and does not store an accounting output backlink. Posting refuses to post while any active hold remains.

## Business Rules

- Only REGISTERED AP documents can be posted
- Posting fails when the AP document has any active (unreleased) payment hold
- Posting uses the payable control account stored on the AP document header
- AP distribution accounts and the stored payable control account must exist and be ACTIVE
- Distribution total must match the document total
- INVOICE debits AP distribution accounts and credits the payable control account
- CREDIT_MEMO debits the payable control account and credits AP distribution accounts
- The emitted accounting event uses source document type ACCOUNT_PAYABLE_DOCUMENT and source document id equal to the AP document id
- The emitted accounting event carries the AP document due schedule as dueDate and amount rows
- Accounting event posting failures are returned as AP posting failures
- Successful posting sets postedAt on the AP document

## Process Flow

```mermaid
flowchart TD
    A[Receive post AP document request] --> B{Document exists?}
    B -->|No| C[Return error: AP document not found]
    B -->|Yes| D{Status is REGISTERED?}
    D -->|No| E[Return error: invalid AP document status]
    D -->|Yes| Q{Any active hold?}
    Q -->|Yes| R[Return error: AP document has active hold]
    Q -->|No| F{Distributions valid?}
    F -->|No| G[Return validation error]
    F -->|Yes| J{Accounts valid?}
    J -->|No| K[Return account error]
    J -->|Yes| L[Build account payable recognized accounting event]
    L --> M{Accounting event posting succeeds?}
    M -->|No| N[Return AP accounting event post failed]
    M -->|Yes| O[Set AP document POSTED]
    O --> P[Return posted AP document]
```

## External Dependencies

- [coa-management::ListAccounts](../../../coa-management/docs/query/ListAccounts.md) - Validates payable control and distribution GL accounts exist and are ACTIVE
- [postAccountingEvent](../../../accounting-event/docs/command/PostAccountingEvent.md) - Stores the emitted accounting event payload

## Error Scenarios

- **AP_DOCUMENT_NOT_FOUND**: Referenced AP document does not exist
- **AP_INVALID_DOCUMENT_STATUS**: AP document status does not allow this operation
- **AP_DOCUMENT_HAS_ACTIVE_HOLD**: AP document cannot be posted while it has an active payment hold
- **AP_MINIMUM_LINES_NOT_MET**: AP document must have at least one line and one distribution
- **AP_LINE_TOTAL_MISMATCH**: AP line gross total or distribution total does not match the document total
- **ACCOUNT_NOT_FOUND**: Referenced payable control or distribution GL account does not exist
- **ACCOUNT_INACTIVE**: Referenced payable control or distribution GL account is not ACTIVE
- **AP_CURRENCY_NOT_FOUND**: Referenced currency does not exist
- **AP_ACCOUNTING_EVENT_POST_FAILED**: Accounting event posting failed for the AP document

## Test Cases

- posts REGISTERED invoice AP document and emits an accounting event
- posts REGISTERED credit memo AP document and emits an accounting event
- returns error when AP document does not exist
- returns error when AP document is not REGISTERED
- returns error when AP document has an active payment hold
- returns error when distribution total does not match document total
- returns error when line gross total does not match document total
- returns error when a line distribution total does not match line gross amount
- returns error when payable control account does not exist
- returns error when payable control account is inactive
- returns error when distribution account is inactive
- returns error when currency does not exist
- returns error when accounting event posting fails
