# PurchaseRequisition

## Description

PurchaseRequisition is the internal request document that captures a department's need for goods or services before any supplier commitment exists. It records the requester, requested items with estimated costs, optional suggested supplier, and desired delivery dates. The requisition serves as the upstream "pre-PO" step that ensures spending is justified and authorized before procurement begins.

The model uses a single `status` state machine: a requisition starts in draft, is submitted for approval, and can be approved, rejected back to draft for revision, recalled by the requester, cancelled, converted to a purchase order, or closed. Supplier assignment is optional at this stage because the final sourcing decision may happen later during purchase order creation.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Draft: createPurchaseRequisition
    Draft --> Draft: updatePurchaseRequisition
    Draft --> Submitted: submitPurchaseRequisition
    Submitted --> Draft: recallPurchaseRequisition
    Submitted --> Draft: rejectPurchaseRequisition
    Submitted --> Approved: approvePurchaseRequisition
    Approved --> Converted: convertPurchaseRequisitionToPurchaseOrder
    Approved --> Closed: closePurchaseRequisition
    Draft --> Cancelled: cancelPurchaseRequisition
    Submitted --> Cancelled: cancelPurchaseRequisition
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| submit | DRAFT | SUBMITTED | [submitPurchaseRequisition](../commands/SubmitPurchaseRequisition.md) |
| recall | SUBMITTED | DRAFT | [recallPurchaseRequisition](../commands/RecallPurchaseRequisition.md) |
| reject | SUBMITTED | DRAFT | [rejectPurchaseRequisition](../commands/RejectPurchaseRequisition.md) |
| approve | SUBMITTED | APPROVED | [approvePurchaseRequisition](../commands/ApprovePurchaseRequisition.md) |
| convert | APPROVED | CONVERTED | [convertPurchaseRequisitionToPurchaseOrder](../commands/ConvertPurchaseRequisitionToPurchaseOrder.md) |
| close | APPROVED | CLOSED | [closePurchaseRequisition](../commands/ClosePurchaseRequisition.md) |
| cancel | DRAFT, SUBMITTED | CANCELLED | [cancelPurchaseRequisition](../commands/CancelPurchaseRequisition.md) |

### Command Definitions

- [createPurchaseRequisition](../commands/CreatePurchaseRequisition.md) - Create a new draft purchase requisition with requester context and one or more lines
- [updatePurchaseRequisition](../commands/UpdatePurchaseRequisition.md) - Revise mutable draft fields and line content
- [submitPurchaseRequisition](../commands/SubmitPurchaseRequisition.md) - Validate draft completeness and move the requisition into submitted review
- [recallPurchaseRequisition](../commands/RecallPurchaseRequisition.md) - Return a submitted requisition to draft before approval or rejection
- [approvePurchaseRequisition](../commands/ApprovePurchaseRequisition.md) - Approve a submitted requisition, authorizing procurement to act on it
- [rejectPurchaseRequisition](../commands/RejectPurchaseRequisition.md) - Return a submitted requisition to draft with a rejection reason
- [cancelPurchaseRequisition](../commands/CancelPurchaseRequisition.md) - Cancel a requisition before it is approved or converted
- [closePurchaseRequisition](../commands/ClosePurchaseRequisition.md) - Close an approved requisition without conversion
- [convertPurchaseRequisitionToPurchaseOrder](../commands/ConvertPurchaseRequisitionToPurchaseOrder.md) - Convert an approved requisition into a draft purchase order

### Query Definitions

- [getPurchaseRequisition](../queries/GetPurchaseRequisition.md) - Retrieve a purchase requisition with its lines

### Models

- PurchaseRequisition
- PurchaseRequisitionLine

### Invariants

- A purchase requisition always belongs to exactly one company and one requester
- Submitted, approved, converted, and closed requisitions must contain at least one line
- Every line must have a description, an item reference, a unit of measure, a quantity greater than zero, and a non-negative estimated unit price
- A line may omit the suggested supplier; supplier assignment is optional at the requisition stage
- The approver and the requester must be different users; self-approval is not allowed
- Cancellation is only allowed when `status` is `DRAFT` or `SUBMITTED`
- Closing is only allowed when `status` is `APPROVED` and no conversion is expected
- A requisition that has already been converted cannot be converted again
- Rejection reason is required and preserved when a requisition is rejected
- Every purchase requisition line belongs to exactly one purchase requisition and inherits its company scope
- Each line must have a description and a requested quantity greater than zero
- Estimated unit price must be non-negative
- Once the parent requisition leaves `DRAFT`, line content is immutable until the requisition returns to `DRAFT` via rejection or recall
- Each allocation record links exactly one PurchaseRequisitionLine to one PurchaseOrderLine with a positive allocated quantity
- Allocation records are created during the convertPurchaseRequisitionToPurchaseOrder command
- The sum of `allocatedQuantity` across all allocations for a given requisition line must not exceed the requisition line's requested quantity
- Allocation records are immutable once created; they serve as an audit trail

### Relationships

- **Belongs To Company (cross-module)**: Each requisition belongs to one company from [Organization](../../../organization/docs/models/Company.md)
- **Belongs To User (cross-module)**: `requesterId` references the user who created the request from [UserManagement](../../../user-management/docs/models/User.md)
- **Has Many PurchaseRequisitionLines**: Each requisition contains one or more request lines
- **May Reference BusinessPartner (cross-module)**: `suggestedSupplierId` optionally references a supplier from [BusinessPartner](../../../business-partner/docs/models/BusinessPartner.md)
- **Referenced By PurchaseOrder**: A converted requisition produces a [PurchaseOrder](./PurchaseOrder.md); the line-level mapping is recorded in [PurchaseRequisitionLineAllocation](./PurchaseRequisitionLineAllocation.md)
- **PurchaseRequisitionLine References Item (cross-module)**: `itemId` references an item from [ItemManagement](../../../item-management/docs/models/Item.md)
- **PurchaseRequisitionLine May Reference BusinessPartner (cross-module)**: `suggestedSupplierId` optionally references a supplier from [BusinessPartner](../../../business-partner/docs/models/BusinessPartner.md)
- **PurchaseRequisitionLine Referenced By PurchaseRequisitionLineAllocation**: Converted lines are traced via [PurchaseRequisitionLineAllocation](./PurchaseRequisitionLineAllocation.md) records linking requisition lines to purchase order lines
- **PurchaseRequisitionLineAllocation Belongs To PurchaseOrder**: `purchaseOrderId` references the generated purchase order
- **PurchaseRequisitionLineAllocation Belongs To PurchaseOrderLine**: `purchaseOrderLineId` references the generated purchase order line
