# SubmitPurchaseChangeOrder

## Permission Scope

purchaseOrder

## Overview

SubmitPurchaseChangeOrder moves a `DRAFT` change order to `SUBMITTED` status after validating that the proposed changes meet all business constraints, making it ready for approval review.

## Business Rules

- Target change order must exist
- Only change orders in `DRAFT` status can be submitted
- Change order must have at least one change order line
- MODIFY lines cannot change the item or unit of measure (item changes require REMOVE + ADD)
- MODIFY lines cannot reduce quantity below the lineage's cumulative received quantity
- MODIFY lines cannot reduce quantity below the lineage's cumulative billed quantity (MATCHED bills)
- REMOVE lines are blocked if the referenced line has any posted receipt quantity
- REMOVE lines are blocked if the referenced line has any matched bill quantity

## Process Flow

```mermaid
flowchart TD
    A[Receive submit request] --> B{Change order exists?}
    B -->|No| C[Return CO_NOT_FOUND]
    B -->|Yes| D{Status is DRAFT?}
    D -->|No| E[Return CO_NOT_DRAFT]
    D -->|Yes| F{At least one change order line?}
    F -->|No| G[Return NO_CHANGE_ORDER_LINES]
    F -->|Yes| H{Validate MODIFY constraints}
    H -->|Fail| I[Return validation error]
    H -->|Pass| J{Validate REMOVE constraints}
    J -->|Fail| K[Return validation error]
    J -->|Pass| L["Set status to SUBMITTED"]
    L --> M[Return submitted change order]
```

## External Dependencies

- None

## Error Scenarios

- **CO_NOT_FOUND**: Target change order does not exist
- **CO_NOT_DRAFT**: Change order is not in `DRAFT` status
- **NO_CHANGE_ORDER_LINES**: Change order has no lines to submit
- **MODIFY_ITEM_CHANGED**: MODIFY action attempts to change the item
- **MODIFY_UOM_CHANGED**: MODIFY action attempts to change the unit of measure
- **MODIFY_QUANTITY_BELOW_RECEIVED**: MODIFY action reduces quantity below the lineage's received quantity
- **MODIFY_QUANTITY_BELOW_BILLED**: MODIFY action reduces quantity below the lineage's billed quantity
- **REMOVE_LINE_HAS_RECEIPTS**: REMOVE action targets a line with posted receipt quantity
- **REMOVE_LINE_HAS_BILLS**: REMOVE action targets a line with matched bill quantity

## Test Cases

- submits a valid draft change order with ADD lines
- submits a valid draft change order with MODIFY lines
- submits a valid draft change order with REMOVE lines
- returns error when change order does not exist
- returns error when change order is not in DRAFT status
- returns error when change order has no lines
- returns error when MODIFY action changes the item
- returns error when MODIFY action changes the unit of measure
- returns error when MODIFY action reduces quantity below received quantity
- returns error when MODIFY action reduces quantity below billed quantity
- returns error when REMOVE action targets a line with posted receipts
- returns error when REMOVE action targets a line with matched bills
- skips MODIFY line when original PO line is not found
- returns empty GR/bill lines when there are no PO line IDs
