1use crate::domain::entities::{ObjectCondition, SharedObject, SharedObjectCategory};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6#[derive(Debug, Serialize, Deserialize)]
8pub struct CreateSharedObjectDto {
9 pub building_id: Uuid,
10 pub object_category: SharedObjectCategory,
11 pub object_name: String,
12 pub description: String,
13 pub condition: ObjectCondition,
14 pub is_available: bool,
15 pub rental_credits_per_day: Option<i32>, pub deposit_credits: Option<i32>, pub borrowing_duration_days: Option<i32>, pub photos: Option<Vec<String>>,
19 pub location_details: Option<String>,
20 pub usage_instructions: Option<String>,
21}
22
23#[derive(Debug, Serialize, Deserialize, Default)]
29pub struct DeleteSharedObjectDto {
30 pub reason: Option<String>,
31}
32
33#[derive(Debug, Serialize, Deserialize)]
35pub struct UpdateSharedObjectDto {
36 pub object_name: Option<String>,
37 pub description: Option<String>,
38 pub condition: Option<ObjectCondition>,
39 pub is_available: Option<bool>,
40 pub rental_credits_per_day: Option<Option<i32>>,
41 pub deposit_credits: Option<Option<i32>>,
42 pub borrowing_duration_days: Option<Option<i32>>,
43 pub photos: Option<Option<Vec<String>>>,
44 pub location_details: Option<Option<String>>,
45 pub usage_instructions: Option<Option<String>>,
46}
47
48#[derive(Debug, Serialize, Deserialize)]
50pub struct BorrowObjectDto {
51 pub duration_days: Option<i32>, }
53
54#[derive(Debug, Serialize, Clone)]
56pub struct SharedObjectResponseDto {
57 pub id: Uuid,
58 pub owner_id: Uuid,
59 pub owner_name: String, pub building_id: Uuid,
61 pub object_category: SharedObjectCategory,
62 pub object_name: String,
63 pub description: String,
64 pub condition: ObjectCondition,
65 pub is_available: bool,
66 pub rental_credits_per_day: Option<i32>,
67 pub deposit_credits: Option<i32>,
68 pub borrowing_duration_days: Option<i32>,
69 pub current_borrower_id: Option<Uuid>,
70 pub current_borrower_name: Option<String>, pub borrowed_at: Option<DateTime<Utc>>,
72 pub due_back_at: Option<DateTime<Utc>>,
73 pub photos: Option<Vec<String>>,
74 pub location_details: Option<String>,
75 pub usage_instructions: Option<String>,
76 pub created_at: DateTime<Utc>,
77 pub updated_at: DateTime<Utc>,
78 pub is_free: bool,
80 pub is_borrowed: bool,
81 pub is_overdue: bool,
82 pub days_overdue: i32,
83}
84
85impl SharedObjectResponseDto {
86 pub fn from_shared_object(
88 object: SharedObject,
89 owner_name: String,
90 borrower_name: Option<String>,
91 ) -> Self {
92 let is_free = object.is_free();
93 let is_borrowed = object.is_borrowed();
94 let is_overdue = object.is_overdue();
95 let days_overdue = object.days_overdue();
96
97 Self {
98 id: object.id,
99 owner_id: object.owner_id,
100 owner_name,
101 building_id: object.building_id,
102 object_category: object.object_category,
103 object_name: object.object_name,
104 description: object.description,
105 condition: object.condition,
106 is_available: object.is_available,
107 rental_credits_per_day: object.rental_credits_per_day,
108 deposit_credits: object.deposit_credits,
109 borrowing_duration_days: object.borrowing_duration_days,
110 current_borrower_id: object.current_borrower_id,
111 current_borrower_name: borrower_name,
112 borrowed_at: object.borrowed_at,
113 due_back_at: object.due_back_at,
114 photos: object.photos,
115 location_details: object.location_details,
116 usage_instructions: object.usage_instructions,
117 created_at: object.created_at,
118 updated_at: object.updated_at,
119 is_free,
120 is_borrowed,
121 is_overdue,
122 days_overdue,
123 }
124 }
125}
126
127#[derive(Debug, Serialize, Clone)]
129pub struct SharedObjectSummaryDto {
130 pub id: Uuid,
131 pub owner_id: Uuid,
132 pub owner_name: String, pub building_id: Uuid,
134 pub object_category: SharedObjectCategory,
135 pub object_name: String,
136 pub condition: ObjectCondition,
137 pub is_available: bool,
138 pub rental_credits_per_day: Option<i32>,
139 pub deposit_credits: Option<i32>,
140 pub current_borrower_id: Option<Uuid>,
141 pub due_back_at: Option<DateTime<Utc>>,
142 pub is_free: bool,
143 pub is_borrowed: bool,
144 pub is_overdue: bool,
145}
146
147impl SharedObjectSummaryDto {
148 pub fn from_shared_object(object: SharedObject, owner_name: String) -> Self {
150 let is_free = object.is_free();
151 let is_borrowed = object.is_borrowed();
152 let is_overdue = object.is_overdue();
153
154 Self {
155 id: object.id,
156 owner_id: object.owner_id,
157 owner_name,
158 building_id: object.building_id,
159 object_category: object.object_category,
160 object_name: object.object_name,
161 condition: object.condition,
162 is_available: object.is_available,
163 rental_credits_per_day: object.rental_credits_per_day,
164 deposit_credits: object.deposit_credits,
165 current_borrower_id: object.current_borrower_id,
166 due_back_at: object.due_back_at,
167 is_free,
168 is_borrowed,
169 is_overdue,
170 }
171 }
172}
173
174#[derive(Debug, Serialize)]
176pub struct SharedObjectStatisticsDto {
177 pub total_objects: i64,
178 pub available_objects: i64,
179 pub borrowed_objects: i64,
180 pub overdue_objects: i64,
181 pub free_objects: i64,
182 pub paid_objects: i64,
183 pub objects_by_category: Vec<CategoryObjectCount>,
184}
185
186#[derive(Debug, Serialize)]
188pub struct CategoryObjectCount {
189 pub category: SharedObjectCategory,
190 pub count: i64,
191}
192
193#[cfg(test)]
194mod tests {
195 use super::*;
196
197 #[test]
198 fn test_shared_object_response_dto_from_shared_object() {
199 let object = SharedObject::new(
200 Uuid::new_v4(),
201 Uuid::new_v4(),
202 SharedObjectCategory::Tools,
203 "Power Drill".to_string(),
204 "18V cordless drill".to_string(),
205 ObjectCondition::Good,
206 true,
207 Some(2),
208 Some(10),
209 Some(7),
210 None,
211 None,
212 None,
213 )
214 .unwrap();
215
216 let dto = SharedObjectResponseDto::from_shared_object(
217 object.clone(),
218 "John Doe".to_string(),
219 None,
220 );
221
222 assert_eq!(dto.owner_name, "John Doe");
223 assert_eq!(dto.object_name, "Power Drill");
224 assert!(!dto.is_free);
225 assert!(!dto.is_borrowed);
226 assert!(!dto.is_overdue);
227 }
228
229 #[test]
230 fn test_shared_object_summary_dto_from_shared_object() {
231 let object = SharedObject::new(
232 Uuid::new_v4(),
233 Uuid::new_v4(),
234 SharedObjectCategory::Books,
235 "Book Title".to_string(),
236 "Description".to_string(),
237 ObjectCondition::Excellent,
238 true,
239 None, None,
241 None,
242 None,
243 None,
244 None,
245 )
246 .unwrap();
247
248 let dto =
249 SharedObjectSummaryDto::from_shared_object(object.clone(), "Jane Smith".to_string());
250
251 assert_eq!(dto.owner_name, "Jane Smith");
252 assert_eq!(dto.object_name, "Book Title");
253 assert!(dto.is_free);
254 assert!(!dto.is_borrowed);
255 }
256}