Expense Type
Data Entity
Description
Configuration entity defining the fixed set of allowable expense categories for reimbursement claims. Each type specifies validation rules, receipt requirements, and mutual exclusivity constraints to prevent invalid combinations (e.g. kilometer allowance and bus ticket simultaneously).
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key | PKrequiredunique |
organization_id |
uuid |
Owning organization; null means platform-default type available to all organizations | - |
code |
string |
Machine-readable identifier (e.g. 'kilometer_allowance', 'toll', 'parking', 'public_transit', 'driver_fee') | required |
name |
string |
Human-readable display name | required |
description |
text |
Explanation shown to peer mentors when selecting this type | - |
category |
enum |
Broad grouping for UI organization and reporting | required |
requires_receipt |
boolean |
Whether a receipt photo is mandatory for expenses of this type (e.g. true for expenses above the org's threshold) | required |
receipt_threshold_amount |
decimal |
If set, receipt is only required when expense amount exceeds this value (e.g. 100 NOK for HLF). Null means receipt_required applies unconditionally. | - |
requires_distance_km |
boolean |
Whether a kilometer value must be entered (true for kilometer_allowance type) | required |
requires_confidentiality_declaration |
boolean |
Whether the peer mentor must complete a confidentiality declaration when submitting this type (true for driver_fee) | required |
mutually_exclusive_with |
json |
Array of expense_type codes that cannot be selected on the same expense record (e.g. kilometer_allowance excludes public_transit) | - |
auto_approval_eligible |
boolean |
Whether expenses of this type can qualify for automatic approval (subject to org-level auto-approval rules) | required |
is_active |
boolean |
Soft-delete flag; inactive types are hidden from pickers but preserved for historical records | required |
sort_order |
integer |
Display order in the expense type picker UI | required |
created_at |
datetime |
Record creation timestamp | required |
updated_at |
datetime |
Last modification timestamp | required |
Database Indexes
idx_expense_types_org_code
Columns: organization_id, code
idx_expense_types_org_active
Columns: organization_id, is_active
idx_expense_types_category
Columns: category
Validation Rules
code_format
error
Validation failed
code_unique_per_org
error
Validation failed
receipt_threshold_positive
error
Validation failed
mutually_exclusive_references_valid_codes
error
Validation failed
name_not_empty
error
Validation failed
Business Rules
mutually_exclusive_types
When a peer mentor selects an expense type, all types listed in its mutually_exclusive_with array must be disabled in the picker. A single expense record cannot carry two mutually exclusive types (e.g. kilometer allowance + public transit).
receipt_required_above_threshold
If receipt_threshold_amount is set and the expense amount exceeds it, the expense record must have an attached receipt before submission. If requires_receipt is true and no threshold is set, receipt is always mandatory.
confidentiality_declaration_required
If requires_confidentiality_declaration is true, the peer mentor must complete and submit a confidentiality declaration before or alongside the expense. Applies to driver_fee type (Blindeforbundet).
distance_required_for_km_type
If requires_distance_km is true, the expense form must collect a positive kilometer value. The field is mandatory and must be a positive number.
inactive_type_not_selectable
Expense types with is_active = false must not appear in the picker and cannot be assigned to new expenses. Existing expenses referencing an inactive type retain their reference for historical accuracy.
org_scoped_or_platform_default
A type with organization_id null is a platform default visible to all organizations. A type with a specific organization_id is visible only to that organization. Organizations may define additional types on top of platform defaults.