Skip to main content

datasynth_core/models/
expense_report.rs

1//! Expense report models for the Hire-to-Retire (H2R) process.
2//!
3//! These models represent employee expense reports and their line items,
4//! supporting the full expense lifecycle from draft submission through payment.
5
6use chrono::NaiveDate;
7use rust_decimal::Decimal;
8use serde::{Deserialize, Serialize};
9
10/// Status of an expense report through the approval and payment lifecycle.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
12#[serde(rename_all = "snake_case")]
13pub enum ExpenseStatus {
14    /// Initial draft, not yet submitted
15    #[default]
16    Draft,
17    /// Submitted for approval
18    Submitted,
19    /// Approved by manager
20    Approved,
21    /// Rejected by manager
22    Rejected,
23    /// Reimbursement paid to employee
24    Paid,
25}
26
27/// Category of an expense line item.
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
29#[serde(rename_all = "snake_case")]
30pub enum ExpenseCategory {
31    /// Airfare, mileage, etc.
32    Travel,
33    /// Business meals and dining
34    Meals,
35    /// Hotel and accommodation
36    Lodging,
37    /// Taxi, rideshare, rental car, parking
38    Transportation,
39    /// Office supplies and equipment
40    Office,
41    /// Client entertainment
42    Entertainment,
43    /// Professional development and training
44    Training,
45    /// Miscellaneous expenses
46    Other,
47}
48
49/// An expense report submitted by an employee for reimbursement.
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct ExpenseReport {
52    /// Unique expense report identifier
53    pub report_id: String,
54    /// Employee who submitted the report
55    pub employee_id: String,
56    /// Date the report was submitted
57    pub submission_date: NaiveDate,
58    /// Overall description/purpose of the expense report
59    pub description: String,
60    /// Current status of the expense report
61    pub status: ExpenseStatus,
62    /// Total amount across all line items
63    #[serde(with = "rust_decimal::serde::str")]
64    pub total_amount: Decimal,
65    /// Currency code (e.g., USD, EUR)
66    pub currency: String,
67    /// Individual expense line items
68    pub line_items: Vec<ExpenseLineItem>,
69    /// Manager who approved/rejected the report
70    pub approved_by: Option<String>,
71    /// Date the report was approved
72    pub approved_date: Option<NaiveDate>,
73    /// Date the reimbursement was paid
74    pub paid_date: Option<NaiveDate>,
75    /// Cost center to charge
76    pub cost_center: Option<String>,
77    /// Department to charge
78    pub department: Option<String>,
79    /// List of policy violations flagged on this report
80    pub policy_violations: Vec<String>,
81}
82
83/// An individual line item within an expense report.
84#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct ExpenseLineItem {
86    /// Unique line item identifier
87    pub item_id: String,
88    /// Expense category
89    pub category: ExpenseCategory,
90    /// Date the expense was incurred
91    pub date: NaiveDate,
92    /// Amount of the expense
93    #[serde(with = "rust_decimal::serde::str")]
94    pub amount: Decimal,
95    /// Currency code (e.g., USD, EUR)
96    pub currency: String,
97    /// Description of the expense
98    pub description: String,
99    /// Whether a receipt is attached
100    pub receipt_attached: bool,
101    /// Merchant or vendor name
102    pub merchant: Option<String>,
103}