# RejectBudget

## Permission Scope

accounting

## Overview

rejectBudget transitions a budget from SUBMITTED status back to DRAFT status, allowing the submitter to revise and resubmit. A rejection reason text is required to communicate the basis for rejection.

## Business Rules

- Budget must exist
- Budget must be in SUBMITTED status to be rejected
- Requires a `reason` text explaining the basis for rejection
- Transitions status from SUBMITTED back to DRAFT
- Upon rejection, the budget can be updated and resubmitted
- Emits an audit event recording the status transition, reason, and acting user

## Process Flow

```mermaid
flowchart TD
    A[Receive reject budget request] --> B{Budget exists?}
    B -->|No| C[Return error: BUDGET_NOT_FOUND]
    B -->|Yes| D{Status is SUBMITTED?}
    D -->|No| E[Return error: INVALID_STATE]
    D -->|Yes| F{Reason text provided?}
    F -->|No| G[Return error: REASON_REQUIRED]
    F -->|Yes| H[Transition status from SUBMITTED to DRAFT]
    H --> I[Emit audit event]
    I --> J[Return rejected budget]
```

## External Dependencies

- None

## Error Scenarios

- **BUDGET_NOT_FOUND**: Budget with the specified ID does not exist
- **INVALID_STATE**: Target entity is not in a valid status for this operation
- **REASON_REQUIRED**: Rejection reason text is missing or empty

## Test Cases

- rejects a SUBMITTED budget transitioning it to DRAFT status with reason
- returns error when budget does not exist
- returns error when budget is not in SUBMITTED status
- returns error when reason text is missing
- reason is persisted to the budget
- rejected budget can be updated and resubmitted
- emits audit event recording the status transition, reason, and acting user
