# ClosePurchaseOrder

## Overview

ClosePurchaseOrder finalizes a partially fulfilled or fully fulfilled purchase order and prevents further receipt or billing activity on the remaining open quantity.

## Business Rules

- Target purchase order must exist
- Only orders in `PARTIALLY_RECEIVED`, `RECEIVED`, `PARTIALLY_BILLED`, or `BILLED` can be closed
- Remaining open quantity must already be fully received, fully billed, or explicitly written off with a close reason
- Closing preserves the original ordered, received, and billed quantities for audit
- Closed orders reject new goods receipts and new purchase bills

## Process Flow

```mermaid
flowchart TD
    A[Receive close request] --> B{Purchase order exists?}
    B -->|No| C[Return PURCHASE_ORDER_NOT_FOUND]
    B -->|Yes| D{Status closable?}
    D -->|No| E[Return PURCHASE_ORDER_NOT_CLOSABLE]
    D -->|Yes| F{Open quantity fully resolved or write-off reason provided?}
    F -->|No| G[Return OPEN_QUANTITY_REMAINS]
    F -->|Yes| H[Set status to CLOSED]
    H --> I[Return closed order]
```

## External Dependencies

- None

## Error Scenarios

- **PURCHASE_ORDER_NOT_FOUND**: Target purchase order does not exist
- **PURCHASE_ORDER_NOT_CLOSABLE**: Purchase order status does not allow closure
- **OPEN_QUANTITY_REMAINS**: Remaining quantity is not fulfilled or explicitly written off
- **CLOSE_REASON_REQUIRED**: Residual open quantity exists but no write-off reason was provided

## Test Cases

- closes a fully billed purchase order
- closes a partially received order when remaining quantity is explicitly written off
- allows closure without write-off when each line is fully received
- returns error when purchase order does not exist
- returns error when purchase order status does not allow closure
- returns error when unresolved open quantity remains
- returns error when residual quantity exists without a close reason
- returns OPEN_QUANTITY_REMAINS before requiring a close reason when write-off is not requested
