# Internal Order Management

## Overview

Internal Order Management provides the ability to create and manage internal orders that serve as temporary cost collectors for tracking expenses associated with specific short-to-medium-term activities such as projects, marketing campaigns, R&D initiatives, and corporate events. Unlike cost centers, which are permanent organizational units for ongoing cost accumulation, internal orders are purpose-bound objects with a defined lifecycle that begins at creation and ends at closure once costs have been fully reviewed.

Each internal order carries a unique order number, an order type (OVERHEAD, INVESTMENT, or ACCRUAL), a description, responsible person, validity dates, and a reference to the responsible cost center within the company. Internal orders follow a four-stage lifecycle: CREATED, RELEASED, TECHNICALLY_COMPLETED, and CLOSED. Cost postings are only permitted while the order is in RELEASED status. Orders may optionally have a budget assigned to control spending limits. Settlement of internal order costs to receivers (such as cost centers, fixed assets, or other orders) is out of scope for this feature and will be addressed in a dedicated settlement feature.

## Business Purpose

Organizations need internal orders to isolate and monitor costs for discrete activities that cut across the permanent cost center structure:

- **Activity-based cost tracking**: Internal orders allow organizations to accumulate costs for specific initiatives (e.g., a trade show, an IT migration project, or a product launch campaign) independently of the department-level cost center hierarchy, providing precise visibility into activity-level spending
- **Order type classification**: Categorizing orders as OVERHEAD, INVESTMENT, or ACCRUAL mirrors SAP's internal order type model and enables differentiated handling — overhead orders track general expenses, investment orders capitalize costs into fixed assets, and accrual orders manage periodic cost deferrals
- **Lifecycle gating**: The four-stage lifecycle (CREATED -> RELEASED -> TECHNICALLY_COMPLETED -> CLOSED) ensures that cost postings are only accepted during the appropriate window, preventing premature charges to orders still in setup and accidental postings to orders under final review or already archived
- **Budget control**: Optional budget assignment to internal orders enables organizations to set spending limits for activities and monitor actual costs against planned budgets, supporting proactive cost governance
- **Responsible cost center linkage**: Each internal order references a responsible cost center, establishing organizational accountability and ensuring that activity costs can be traced back to the department or unit that owns the initiative
- **Temporal scoping**: Validity dates (valid-from and valid-to) define the time window during which the order is relevant, supporting planning and ensuring that postings outside the validity period are flagged or rejected
- **Company-scoped isolation**: Internal orders are scoped to a company, ensuring that cost data for different legal entities remains fully separated

## Process Flow

```mermaid
stateDiagram-v2
    [*] --> Created: createInternalOrder
    Created --> Released: releaseInternalOrder
    Released --> TechnicallyCompleted: technicallyCompleteInternalOrder
    TechnicallyCompleted --> Closed: closeInternalOrder
    Created --> [*]: deleteInternalOrder
```

```mermaid
flowchart TD
    A[Identify activity requiring cost tracking] --> B[Create internal order with type, description, responsible person, and cost center]
    B --> C{Assign budget?}
    C -- Yes --> D[Link budget to internal order]
    C -- No --> E[Internal order in CREATED status]
    D --> E
    E --> F[Release internal order]
    F --> G[Costs posted against the order during activity execution]
    G --> H{Activity complete?}
    H -- No --> G
    H -- Yes --> I[Technically complete the order]
    I --> J[Final review of accumulated costs]
    J --> K[Close the order]
    K --> L[Order archived — no further changes]
```

```mermaid
flowchart TD
    A[Cost posting request targets internal order] --> B{Order status is RELEASED?}
    B -- No --> C[Reject posting — order not in RELEASED status]
    B -- Yes --> D{Posting date within validity period?}
    D -- No --> E[Reject posting — outside validity window]
    D -- Yes --> F{Budget assigned?}
    F -- Yes --> G{Posting within budget limit?}
    G -- No --> H[Reject or warn — budget exceeded]
    G -- Yes --> I[Accept cost posting]
    F -- No --> I
```

## Scenario Patterns

- **Marketing Campaign Tracking**: The marketing department creates an OVERHEAD internal order to track all costs for a product launch campaign — agency fees, print materials, event venue, and travel. The order is released when planning is finalized, costs are posted throughout the campaign period, and the order is technically completed and closed once all invoices are settled and reviewed
- **Capital Investment Project**: An INVESTMENT internal order is created for a facility renovation project. Costs for construction, equipment, and consulting are accumulated on the order. Upon project completion, the order is technically completed and the accumulated costs are reviewed before closure (settlement to a fixed asset would occur in a future settlement feature)
- **R&D Initiative**: An R&D team creates an OVERHEAD internal order with a budget to track development costs for a prototype. The budget cap ensures the team stays within the approved spending limit. When the prototype phase ends, the order is technically completed and costs are reviewed against the budget before closure
- **Corporate Event**: An internal order is created for an annual company conference. Costs for venue rental, catering, speakers, and logistics are posted during the event planning and execution phases. After the event, the order is technically completed, final costs are reconciled, and the order is closed
- **Accrual Order for Periodic Costs**: An ACCRUAL internal order is created to manage deferred cost recognition for an annual software license paid upfront. The order tracks the periodic accrual postings over the license term
- **Order Deletion Before Release**: A planned initiative is cancelled before any costs are incurred. The internal order, still in CREATED status, is deleted rather than progressed through the full lifecycle
- **Budget Overrun Prevention**: A project manager attempts to post costs to an internal order that would exceed the assigned budget. The system rejects the posting, prompting the manager to request a budget increase or reallocate costs to a different order

## Test Cases

- Internal order lifecycle follows CREATED -> RELEASED -> TECHNICALLY_COMPLETED -> CLOSED state machine
- Internal order can only be created in CREATED status
- Internal order requires a valid order type (OVERHEAD, INVESTMENT, ACCRUAL)
- Internal order requires a unique order number within the company scope
- Internal order requires a description
- Internal order requires a responsible person
- Internal order must reference a valid companyId; the company must be in ACTIVE status
- Internal order must reference a valid responsible cost center within the same company
- Internal order validity dates (valid-from, valid-to) are optional; when both are provided, valid-from must precede valid-to
- Budget assignment to an internal order is optional
- When a budget is assigned, the budget entity must exist and belong to the same company
- Releasing an internal order transitions its status from CREATED to RELEASED
- Only CREATED orders can be released; releasing a RELEASED, TECHNICALLY_COMPLETED, or CLOSED order fails with an invalid status transition error
- Cost postings are only accepted when the internal order is in RELEASED status
- Cost postings to an order in CREATED, TECHNICALLY_COMPLETED, or CLOSED status are rejected
- Technically completing an internal order transitions its status from RELEASED to TECHNICALLY_COMPLETED
- Only RELEASED orders can be technically completed; technically completing a CREATED or CLOSED order fails with an invalid status transition error
- Closing an internal order transitions its status from TECHNICALLY_COMPLETED to CLOSED
- Only TECHNICALLY_COMPLETED orders can be closed; closing a CREATED or RELEASED order fails with an invalid status transition error
- CLOSED orders cannot transition to any other status
- Internal orders in CREATED status can be deleted
- Internal orders in RELEASED, TECHNICALLY_COMPLETED, or CLOSED status cannot be deleted
- Internal order fields (description, responsible person, cost center, validity dates) can be updated while the order is in CREATED or RELEASED status
- Internal order fields cannot be updated when the order is in TECHNICALLY_COMPLETED or CLOSED status
- Order type cannot be changed after the order is released
- Cost postings to an internal order with a budget must not exceed the assigned budget amount
- Cost postings that would exceed the budget are rejected with a budget exceeded error
- Internal orders are scoped to a company; orders from different companies are fully isolated
- Cost postings with a date outside the order's validity period (before valid-from or after valid-to) are rejected when validity dates are set
- Deleting an internal order in CREATED status removes the order and any associated budget assignment
- Creating an internal order without a responsible cost center reference fails validation

## Reference Links

- [SAP S/4HANA Internal Orders](https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/ee3509643e954b3da2e0ebfa846c02e1/7ce4944ab36c11d3b44c006094b9ea64.html)
- [SAP Internal Order Types and Usage](https://help.sap.com/docs/SAP_ERP/3bbd1036dae74238a8e3aab669e0ea3f/2ad1e0af437411d189740000e8323492.html)
- [Oracle Fusion Project Costing — Cost Collection](https://docs.oracle.com/en/cloud/saas/project-management/24d/oapjm/cost-collection.html)
- [Odoo Analytic Accounts for Cost Tracking](https://www.odoo.com/documentation/19.0/applications/finance/accounting/reporting/analytic_accounting.html)
