Expense Types
Data Entity
Description
Configuration catalogue of valid expense categories (mileage, tolls, parking, public transport, etc.) with associated rules such as receipt requirements, rate amounts, auto-approval thresholds, and mutual-exclusion constraints. Drives the Expense Types & Requirements feature and governs which inputs are accepted on the Expense Form.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Unique identifier for the expense type record | PKrequiredunique |
organization_id |
uuid |
Tenant that owns this expense type configuration (null for platform-wide defaults) | - |
code |
string |
Stable machine code for the expense type (e.g. MILEAGE, TOLL, PARKING, PUBLIC_TRANSPORT, DRIVER_HONORARIUM) | requiredunique |
name |
string |
Display name shown in the Expense Type Picker | required |
name_no |
string |
Norwegian display label (e.g. Kilometergodtgjørelse, Bompenger, Parkering) | - |
description |
text |
Helper text describing when this expense type should be used | - |
category |
enum |
Functional grouping used for reporting and rule application | required |
unit |
enum |
Unit of measure the user enters when claiming this expense | required |
rate_amount |
decimal |
Per-unit rate in NOK (e.g. NOK/km for mileage). Null when amount is entered freely by the user. | - |
currency |
string |
ISO 4217 currency code for rate_amount and claimed amounts | required |
requires_receipt |
boolean |
Whether a receipt photo must be attached when claiming this expense type | required |
receipt_threshold_amount |
decimal |
Amount above which a receipt becomes mandatory (e.g. 100 NOK for HLF). Null means always or never required per requires_receipt. | - |
auto_approve_threshold_amount |
decimal |
Claims at or below this amount are auto-approved by the Rules Engine | - |
auto_approve_threshold_km |
decimal |
Mileage threshold for auto-approval (e.g. under 50 km per HLF rule) | - |
max_amount_per_claim |
decimal |
Hard cap per single expense entry | - |
mutually_exclusive_with |
json |
Array of expense_type codes that cannot be combined on the same trip (e.g. MILEAGE cannot coexist with PUBLIC_TRANSPORT) | - |
required_fields |
json |
Array of additional fields the Expense Form must collect for this type (e.g. distance_km, route, license_plate) | - |
requires_confidentiality_declaration |
boolean |
Driver honoraria etc. require a signed confidentiality declaration before payout | required |
accounting_code |
string |
External accounting account code mapped for Xledger / Dynamics export | - |
is_active |
boolean |
Whether the type is selectable in the Expense Type Picker | required |
sort_order |
integer |
Display order in the Expense Type Picker | - |
effective_from |
datetime |
When this configuration becomes effective (for historical accuracy of past claims) | - |
effective_until |
datetime |
When this configuration is retired | - |
created_at |
datetime |
Record creation timestamp | required |
updated_at |
datetime |
Last modification timestamp | required |
Database Indexes
idx_expense_types_org
Columns: organization_id
idx_expense_types_org_code
Columns: organization_id, code
idx_expense_types_active
Columns: organization_id, is_active, sort_order
idx_expense_types_category
Columns: category
idx_expense_types_effective
Columns: effective_from, effective_until
Validation Rules
code_format
error
Validation failed
non_negative_amounts
error
Validation failed
currency_iso_4217
error
Validation failed
category_enum_valid
error
Validation failed
unit_matches_category
warning
Validation failed
effective_window_valid
error
Validation failed
mutual_exclusion_references_exist
error
Validation failed
accounting_code_format
warning
Validation failed
Business Rules
mutual_exclusion_enforced
When a user picks an expense type, types listed in mutually_exclusive_with cannot be added to the same expense entry (prevents km + bus combo).
receipt_required_above_threshold
If claim amount exceeds receipt_threshold_amount, a receipt attachment is mandatory before submission.
auto_approval_below_threshold
Claims at or below auto_approve_threshold_amount / auto_approve_threshold_km are routed to auto-approval; others require manual attestation.
confidentiality_required_for_honoraria
Honorarium expense types may not be paid out until the claimant has a signed confidentiality declaration on file.
inactive_types_hidden
Expense types with is_active=false are excluded from the picker but remain available for historical claims and reports.
effective_window_respected
Only configurations whose effective_from <= now < effective_until are usable for new claims.
tenant_scoped_visibility
Users see only expense types belonging to their organization (or platform defaults); cross-tenant access is forbidden.