# CancelSalesInvoice

## Overview

CancelSalesInvoice cancels a draft or issued invoice while the commercial document is still owned by sales. It is blocked once downstream AR handoff has been accepted.

## Business Rules

- Only DRAFT or ISSUED invoices may be cancelled.
- Invoices already accepted by downstream AR cannot be cancelled through this command.
- Cancellation must preserve historical invoice lines and issue evidence.

## Process Flow

```mermaid
flowchart TD
    A[Receive cancel request] --> B[Load invoice]
    B --> C[Check invoice status and AR handoff state]
    C --> D{Cancellation allowed?}
    D -->|No| E[Return INVOICE_CANCELLATION_BLOCKED]
    D -->|Yes| F[Set status to CANCELLED]
    F --> G[Return cancelled invoice]
```

## External Dependencies

- None

## Error Scenarios

- **SALES_INVOICE_NOT_FOUND**: Referenced sales invoice does not exist.
- **INVALID_INVOICE_STATUS**: Invoice status does not allow cancellation.
- **INVOICE_CANCELLATION_BLOCKED**: Downstream AR handoff already accepted the invoice.

## Test Cases

- cancels a draft invoice
- cancels an issued invoice before AR handoff
- throws when AR handoff already accepted the invoice
