# Company

## Description

Company represents a legal entity in the ERP system — identified by its legal name, tax identification number, registration number, and registered address. Each company is assigned a base currency from the primitives module and serves as the root scoping entity for all transactional modules. Every accounting entry, sales order, purchase order, and inventory movement belongs to exactly one company. Companies follow a lifecycle state machine (DRAFT → ACTIVE ↔ INACTIVE) that controls when transactional operations are permitted.

Examples: "Acme Corp" (active manufacturing company), "Beta Ltd" (draft subsidiary being configured).

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Draft: createCompany
    Draft --> Active: activateCompany
    Active --> Inactive: deactivateCompany
    Inactive --> Active: reactivateCompany
    Draft --> [*]: deleteCompany
    note right of Draft: Only DRAFT companies can be deleted
    note right of Active: Base currency is immutable after activation
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| activate | DRAFT | ACTIVE | [activateCompany](../command/ActivateCompany.md) |
| deactivate | ACTIVE | INACTIVE | [deactivateCompany](../command/DeactivateCompany.md) |
| reactivate | INACTIVE | ACTIVE | [reactivateCompany](../command/ReactivateCompany.md) |

### Command Definitions

- [createCompany](../command/CreateCompany.md) - Create a new company in DRAFT status
- [updateCompany](../command/UpdateCompany.md) - Modify company fields (legal name, address, tax ID, etc.)
- [activateCompany](../command/ActivateCompany.md) - Transition company from DRAFT to ACTIVE
- [deactivateCompany](../command/DeactivateCompany.md) - Transition company from ACTIVE to INACTIVE
- [reactivateCompany](../command/ReactivateCompany.md) - Transition company from INACTIVE to ACTIVE
- [deleteCompany](../command/DeleteCompany.md) - Permanently remove a DRAFT company

### Query Definitions

- [getCompany](../query/GetCompany.md) - Retrieve a company by ID

### Models

- Company

### Invariants

- Legal name is required and must be non-empty
- Base currency is optional at creation but must reference a valid Currency from the primitives module before activation
- Base currency is immutable after activation (ACTIVE or INACTIVE state)
- Only DRAFT companies can be permanently deleted; ACTIVE and INACTIVE companies are preserved for audit
- Deleting a DRAFT company is rejected (restrict) if it has existing departments or sites referencing it
- Registered address fields (street, city, postalCode, country) are required before activation
- Each company has a unique system-generated ID used for data isolation across transactional modules

### Relationships

- **References Currency (cross-module)**: Company references a Currency from the primitives module as its base currency via baseCurrencyId
- **Referenced By Department**: Departments belong to exactly one company via companyId
- **Referenced By Site**: Sites belong to exactly one company via companyId
- **Referenced By Transactions**: Company is used as scoping entity across all transactional modules (accounting, sales, purchasing, inventory)
