datasynth_ocpm/models/
resource.rs1use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Resource {
10 pub resource_id: String,
12 pub name: String,
14 pub resource_type: ResourceType,
16 pub department: Option<String>,
18 pub role: Option<String>,
20 pub is_active: bool,
22 pub capabilities: Vec<String>,
24 pub cost_per_hour: Option<f64>,
26}
27
28impl Resource {
29 pub fn user(id: &str, name: &str) -> Self {
31 Self {
32 resource_id: id.into(),
33 name: name.into(),
34 resource_type: ResourceType::User,
35 department: None,
36 role: None,
37 is_active: true,
38 capabilities: Vec::new(),
39 cost_per_hour: None,
40 }
41 }
42
43 pub fn system(id: &str, name: &str) -> Self {
45 Self {
46 resource_id: id.into(),
47 name: name.into(),
48 resource_type: ResourceType::System,
49 department: None,
50 role: None,
51 is_active: true,
52 capabilities: Vec::new(),
53 cost_per_hour: None,
54 }
55 }
56
57 pub fn with_department(mut self, department: &str) -> Self {
59 self.department = Some(department.into());
60 self
61 }
62
63 pub fn with_role(mut self, role: &str) -> Self {
65 self.role = Some(role.into());
66 self
67 }
68
69 pub fn with_capabilities(mut self, capabilities: Vec<&str>) -> Self {
71 self.capabilities = capabilities.into_iter().map(String::from).collect();
72 self
73 }
74
75 pub fn with_cost(mut self, cost_per_hour: f64) -> Self {
77 self.cost_per_hour = Some(cost_per_hour);
78 self
79 }
80
81 pub fn can_perform(&self, activity_id: &str) -> bool {
83 self.capabilities.is_empty() || self.capabilities.iter().any(|c| c == activity_id)
84 }
85
86 pub fn erp_system() -> Self {
88 Self::system("SYS_ERP", "ERP System").with_capabilities(vec![
89 "post_gr",
90 "post_invoice",
91 "execute_payment",
92 "check_credit",
93 "post_customer_invoice",
94 "receive_payment",
95 ])
96 }
97
98 pub fn workflow_system() -> Self {
100 Self::system("SYS_WF", "Workflow System")
101 .with_capabilities(vec!["release_po", "release_so"])
102 }
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
107#[serde(rename_all = "snake_case")]
108pub enum ResourceType {
109 #[default]
111 User,
112 System,
114 ExternalService,
116 Bot,
118}
119
120impl ResourceType {
121 pub fn is_human(&self) -> bool {
123 matches!(self, Self::User)
124 }
125
126 pub fn is_automated(&self) -> bool {
128 !self.is_human()
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn test_user_resource() {
138 let user = Resource::user("USR001", "John Doe")
139 .with_department("Finance")
140 .with_role("AP Clerk");
141
142 assert_eq!(user.resource_type, ResourceType::User);
143 assert_eq!(user.department, Some("Finance".into()));
144 }
145
146 #[test]
147 fn test_system_resource() {
148 let system = Resource::erp_system();
149
150 assert_eq!(system.resource_type, ResourceType::System);
151 assert!(system.can_perform("post_invoice"));
152 assert!(!system.can_perform("create_po"));
153 }
154}