# CreateJournalEntry

## Permission Scope

journalEntry

## Overview

createJournalEntry establishes a new journal entry in DRAFT status within the general ledger. The journal entry header carries a company reference, accounting period reference, reference number, entry date, optional description, and optional structured source document reference. The command requires prepared journal lines so callers create the draft accounting document as one unit.

## Business Rules

- Journal entry is always created in DRAFT status
- Requires a valid `companyId` referencing a company from the organization module
- Requires a valid `accountingPeriodId` referencing an existing accounting period in the same company
- Requires a reference number that is unique within the company scope
- Requires a valid entry date
- Description is optional and can be set on creation
- Source document type and source document ID are optional and can be set on creation
- At least two initial journal lines are required and are created under the new DRAFT journal entry
- Each initial line must reference an existing GL account
- Each initial line must specify either a debit amount or a credit amount, not both
- Journal line amounts are recorded in the company's base currency; multi-currency conversion is outside the current scope
- Journal entries are scoped to a company; entries from different companies are fully isolated

## Process Flow

```mermaid
flowchart TD
    A[Receive create journal entry request] --> B{Company exists?}
    B -->|No| C[Return error: company not found]
    B -->|Yes| D{Accounting period exists in same company?}
    D -->|No| E[Return error: period not found]
    D -->|Yes| H{Reference number unique within company?}
    H -->|No| I[Return error: duplicate reference number]
    H -->|Yes| J{Valid entry date?}
    J -->|No| K[Return error: invalid entry date]
    J -->|Yes| L{Initial lines valid?}
    L -->|No| M[Return line validation error]
    L -->|Yes| N[Create journal entry in DRAFT status]
    N --> O[Create initial journal lines]
    O --> P[Return created journal entry]
```

## External Dependencies

- None

## Error Scenarios

- **COMPANY_NOT_FOUND**: Referenced company does not exist
- **ACCOUNTING_PERIOD_NOT_FOUND**: Referenced accounting period does not exist
- **ACCOUNTING_PERIOD_COMPANY_MISMATCH**: Accounting period belongs to a different company
- **DUPLICATE_REFERENCE_NUMBER**: A journal entry with the same reference number already exists within the company
- **INVALID_ENTRY_DATE**: Entry date is not a valid date
- **MINIMUM_LINES_NOT_MET**: Journal entry has fewer than two journal lines
- **ACCOUNT_NOT_FOUND**: Referenced GL account does not exist
- **INVALID_DEBIT_CREDIT**: Debit/credit values violate constraints

## Test Cases

- returns error when company does not exist
- returns error when accounting period does not exist
- returns error when accounting period belongs to a different company
- returns error when reference number already exists within the company
- returns error when entry date is invalid
- returns error when initial lines are missing
- creates journal entry in DRAFT status with required fields and lines
- creates journal entry with optional description
- creates journal entry with optional source document
- returns error when an initial line account does not exist
- returns error when an initial line has invalid debit and credit values
