# MatchPurchaseBill

## Overview

MatchPurchaseBill runs procurement matching on a draft supplier bill. It compares each bill line against the referenced purchase-order line and, when 3-way matching is required, against cumulative posted goods receipts. The bill then becomes `MATCHED` or `BLOCKED`.

## Business Rules

- Target purchase bill must exist
- Only bills in `DRAFT` status can be matched
- Matching mode must be explicitly recorded as `TWO_WAY` or `THREE_WAY`
- 2-way matching compares billed quantity and billed price to the purchase order
- 3-way matching also requires billed quantity to stay within cumulative posted receipt quantity, subject to configured tolerance
- Price variance above tolerance results in `BLOCKED` instead of `MATCHED`
- Matched bills calculate due schedule from the payment-term snapshot and increase purchase-order billed quantity
- Blocked bills preserve variance reason and comparison basis without emitting downstream AP readiness

## Process Flow

```mermaid
flowchart TD
    A[Receive match request] --> B{Purchase bill exists and is DRAFT?}
    B -->|No| C[Return not found or invalid status]
    B -->|Yes| D{Matching mode provided?}
    D -->|No| E[Return MATCH_MODE_REQUIRED]
    D -->|Yes| F[Compare each bill line to PO line]
    F --> G{THREE_WAY?}
    G -->|Yes| H[Compare billed qty to posted receipts]
    G -->|No| I[Skip receipt comparison]
    H --> J{Within quantity and price tolerance?}
    I --> J
    J -->|No| K[Record variance evidence and set BLOCKED]
    J -->|Yes| L[Calculate due schedule and set MATCHED]
    L --> M[Increase PO billed quantity and prepare bill-ready handoff]
    K --> N[Return blocked bill]
    M --> O[Return matched bill]
```

## External Dependencies

- [getGoodsReceipt](../queries/GetGoodsReceipt.md) - Source cumulative posted receipt evidence for 3-way matching

## Error Scenarios

- **PURCHASE_BILL_NOT_FOUND**: Target purchase bill does not exist
- **PURCHASE_BILL_NOT_DRAFT**: Purchase bill is not in `DRAFT` status
- **MATCH_MODE_REQUIRED**: No matching mode was provided
- **PURCHASE_ORDER_CANCELLED**: Referenced purchase order is cancelled
- **PAYMENT_SCHEDULE_CALCULATION_FAILED**: Due schedule could not be derived from the payment-term snapshot

## Test Cases

- matches a valid 2-way purchase bill
- matches a valid 3-way purchase bill when posted receipt quantity is sufficient
- blocks a bill when 3-way quantity exceeds posted receipt quantity
- blocks a bill when price variance exceeds tolerance
- records matching mode on the bill
- increases purchase-order billed quantity when the bill is matched
- returns error when purchase bill does not exist
- returns error when purchase bill is not draft
- returns error when matching mode is missing
- returns error when a referenced purchase order is cancelled
- returns error when payment schedule calculation fails
