koprogo_api/application/dto/
contractor_report_dto.rs

1use crate::domain::entities::contractor_report::{ContractorReport, ReplacedPart};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6/// Création d'un rapport par le corps de métier (via magic link ou syndic)
7#[derive(Debug, Deserialize)]
8pub struct CreateContractorReportDto {
9    pub building_id: Uuid,
10    pub contractor_name: String,
11    pub ticket_id: Option<Uuid>,
12    pub quote_id: Option<Uuid>,
13    pub contractor_user_id: Option<Uuid>,
14}
15
16/// Mise à jour du brouillon (photos, pièces, compte-rendu)
17#[derive(Debug, Deserialize)]
18pub struct UpdateContractorReportDto {
19    pub work_date: Option<DateTime<Utc>>,
20    pub compte_rendu: Option<String>,
21    pub photos_before: Option<Vec<Uuid>>,
22    pub photos_after: Option<Vec<Uuid>>,
23    pub parts_replaced: Option<Vec<ReplacedPartDto>>,
24}
25
26#[derive(Debug, Deserialize, Serialize)]
27pub struct ReplacedPartDto {
28    pub name: String,
29    pub reference: Option<String>,
30    pub quantity: u32,
31    pub photo_document_id: Option<Uuid>,
32}
33
34impl From<ReplacedPartDto> for ReplacedPart {
35    fn from(d: ReplacedPartDto) -> Self {
36        ReplacedPart {
37            name: d.name,
38            reference: d.reference,
39            quantity: d.quantity,
40            photo_document_id: d.photo_document_id,
41        }
42    }
43}
44
45impl From<&ReplacedPart> for ReplacedPartDto {
46    fn from(p: &ReplacedPart) -> Self {
47        ReplacedPartDto {
48            name: p.name.clone(),
49            reference: p.reference.clone(),
50            quantity: p.quantity,
51            photo_document_id: p.photo_document_id,
52        }
53    }
54}
55
56/// Demande de corrections par le CdC
57#[derive(Debug, Deserialize)]
58pub struct RequestCorrectionsDto {
59    pub comments: String,
60}
61
62/// Rejet par le CdC
63#[derive(Debug, Deserialize)]
64pub struct RejectReportDto {
65    pub comments: String,
66}
67
68/// Génération du magic link (syndic → corps de métier)
69#[derive(Debug, Deserialize)]
70pub struct GenerateMagicLinkDto {
71    pub report_id: Uuid,
72}
73
74/// Réponse magic link
75#[derive(Debug, Serialize)]
76pub struct MagicLinkResponseDto {
77    pub magic_link: String,
78    pub expires_at: DateTime<Utc>,
79}
80
81/// Réponse complète d'un rapport de travaux
82#[derive(Debug, Serialize)]
83pub struct ContractorReportResponseDto {
84    pub id: Uuid,
85    pub organization_id: Uuid,
86    pub building_id: Uuid,
87    pub ticket_id: Option<Uuid>,
88    pub quote_id: Option<Uuid>,
89    pub contractor_user_id: Option<Uuid>,
90    pub contractor_name: String,
91    pub work_date: Option<DateTime<Utc>>,
92    pub compte_rendu: Option<String>,
93    pub photos_before: Vec<Uuid>,
94    pub photos_after: Vec<Uuid>,
95    pub parts_replaced: Vec<ReplacedPartDto>,
96    pub status: String,
97    pub submitted_at: Option<DateTime<Utc>>,
98    pub validated_at: Option<DateTime<Utc>>,
99    pub validated_by: Option<Uuid>,
100    pub review_comments: Option<String>,
101    pub created_at: DateTime<Utc>,
102    pub updated_at: DateTime<Utc>,
103}
104
105impl From<&ContractorReport> for ContractorReportResponseDto {
106    fn from(r: &ContractorReport) -> Self {
107        ContractorReportResponseDto {
108            id: r.id,
109            organization_id: r.organization_id,
110            building_id: r.building_id,
111            ticket_id: r.ticket_id,
112            quote_id: r.quote_id,
113            contractor_user_id: r.contractor_user_id,
114            contractor_name: r.contractor_name.clone(),
115            work_date: r.work_date,
116            compte_rendu: r.compte_rendu.clone(),
117            photos_before: r.photos_before.clone(),
118            photos_after: r.photos_after.clone(),
119            parts_replaced: r.parts_replaced.iter().map(ReplacedPartDto::from).collect(),
120            status: r.status.to_db_str().to_string(),
121            submitted_at: r.submitted_at,
122            validated_at: r.validated_at,
123            validated_by: r.validated_by,
124            review_comments: r.review_comments.clone(),
125            created_at: r.created_at,
126            updated_at: r.updated_at,
127        }
128    }
129}