koprogo_api/application/dto/
document_dto.rs1use crate::domain::entities::{Document, DocumentType};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct DocumentResponse {
9 pub id: Uuid,
10 pub building_id: Uuid,
11 pub document_type: DocumentType,
12 pub title: String,
13 pub description: Option<String>,
14 pub file_path: String,
15 pub file_size: i64,
16 pub file_size_mb: f64,
17 pub mime_type: String,
18 pub uploaded_by: Uuid,
19 pub related_meeting_id: Option<Uuid>,
20 pub related_expense_id: Option<Uuid>,
21 pub created_at: DateTime<Utc>,
22 pub updated_at: DateTime<Utc>,
23}
24
25impl From<Document> for DocumentResponse {
26 fn from(doc: Document) -> Self {
27 let file_size_mb = doc.file_size_mb();
28 Self {
29 id: doc.id,
30 building_id: doc.building_id,
31 document_type: doc.document_type,
32 title: doc.title,
33 description: doc.description,
34 file_path: doc.file_path,
35 file_size: doc.file_size,
36 file_size_mb,
37 mime_type: doc.mime_type,
38 uploaded_by: doc.uploaded_by,
39 related_meeting_id: doc.related_meeting_id,
40 related_expense_id: doc.related_expense_id,
41 created_at: doc.created_at,
42 updated_at: doc.updated_at,
43 }
44 }
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct UploadDocumentRequest {
51 pub organization_id: Uuid,
52 pub building_id: Uuid,
53 pub document_type: DocumentType,
54 pub title: String,
55 pub description: Option<String>,
56 pub uploaded_by: Uuid,
57 pub related_meeting_id: Option<Uuid>,
58 pub related_expense_id: Option<Uuid>,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct LinkDocumentToMeetingRequest {
64 pub meeting_id: Uuid,
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct LinkDocumentToExpenseRequest {
70 pub expense_id: Uuid,
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_document_response_from_entity() {
79 let org_id = Uuid::new_v4();
80 let building_id = Uuid::new_v4();
81 let uploader_id = Uuid::new_v4();
82
83 let document = Document::new(
84 org_id,
85 building_id,
86 DocumentType::Invoice,
87 "Test Invoice".to_string(),
88 Some("Test description".to_string()),
89 "/documents/test.pdf".to_string(),
90 1048576, "application/pdf".to_string(),
92 uploader_id,
93 )
94 .unwrap();
95
96 let response = DocumentResponse::from(document.clone());
97
98 assert_eq!(response.id, document.id);
99 assert_eq!(response.title, "Test Invoice");
100 assert_eq!(response.file_size, 1048576);
101 assert_eq!(response.file_size_mb, 1.0);
102 }
103
104 #[test]
105 fn test_upload_request_serialization() {
106 let org_id = Uuid::new_v4();
107 let building_id = Uuid::new_v4();
108 let uploader_id = Uuid::new_v4();
109
110 let request = UploadDocumentRequest {
111 organization_id: org_id,
112 building_id,
113 document_type: DocumentType::Contract,
114 title: "Contrat de syndic".to_string(),
115 description: Some("Contrat annuel".to_string()),
116 uploaded_by: uploader_id,
117 related_meeting_id: None,
118 related_expense_id: None,
119 };
120
121 let json = serde_json::to_string(&request).unwrap();
122 assert!(json.contains("Contrat de syndic"));
123
124 let deserialized: UploadDocumentRequest = serde_json::from_str(&json).unwrap();
125 assert_eq!(deserialized.title, request.title);
126 }
127}