Skip to main content

koprogo_api/application/dto/
etat_date_dto.rs

1use crate::domain::entities::{EtatDate, EtatDateLanguage, EtatDateStatus};
2use chrono::{DateTime, Utc};
3
4use serde::{Deserialize, Serialize};
5use uuid::Uuid;
6
7/// Request pour créer un nouvel état daté
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct CreateEtatDateRequest {
10    #[serde(default)]
11    pub organization_id: Uuid, // Will be overridden by JWT token
12    pub building_id: Uuid,
13    pub unit_id: Uuid,
14    pub reference_date: DateTime<Utc>,
15    pub language: EtatDateLanguage,
16    pub notary_name: String,
17    pub notary_email: String,
18    pub notary_phone: Option<String>,
19}
20
21/// Request pour mettre à jour les données financières d'un état daté
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct UpdateEtatDateFinancialRequest {
24    // MONÉTAIRE : Decimal exact (ADR-0007/0008), sérialisé string JSON
25    // comme les quote-parts (#433 / WP-A5 EXP-007).
26    pub owner_balance: rust_decimal::Decimal,
27    pub arrears_amount: rust_decimal::Decimal,
28    pub monthly_provision_amount: rust_decimal::Decimal,
29    pub total_balance: rust_decimal::Decimal,
30    pub approved_works_unpaid: rust_decimal::Decimal,
31}
32
33/// Request pour mettre à jour les données additionnelles (sections 7-16)
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct UpdateEtatDateAdditionalDataRequest {
36    pub additional_data: serde_json::Value,
37}
38
39/// Response DTO pour un état daté
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct EtatDateResponse {
42    pub id: Uuid,
43    /// L'ACP propriétaire de la pièce (ADR-0045).
44    pub acp_id: Uuid,
45    pub organization_id: Uuid,
46    pub building_id: Uuid,
47    pub unit_id: Uuid,
48    pub reference_date: DateTime<Utc>,
49    pub requested_date: DateTime<Utc>,
50    pub generated_date: Option<DateTime<Utc>>,
51    pub delivered_date: Option<DateTime<Utc>>,
52    pub status: EtatDateStatus,
53    pub language: EtatDateLanguage,
54    pub reference_number: String,
55    pub notary_name: String,
56    pub notary_email: String,
57    pub notary_phone: Option<String>,
58    pub building_name: String,
59    pub building_address: String,
60    pub unit_number: String,
61    pub unit_floor: Option<String>,
62    pub unit_area: Option<f64>,
63    /// Quote-part charges ordinaires — Decimal exact (ADR-0008), string JSON.
64    pub ordinary_charges_quota: rust_decimal::Decimal,
65    /// Quote-part charges extraordinaires — Decimal exact (ADR-0008), string JSON.
66    pub extraordinary_charges_quota: rust_decimal::Decimal,
67    pub owner_balance: rust_decimal::Decimal,
68    pub arrears_amount: rust_decimal::Decimal,
69    pub monthly_provision_amount: rust_decimal::Decimal,
70    pub total_balance: rust_decimal::Decimal,
71    pub approved_works_unpaid: rust_decimal::Decimal,
72    pub additional_data: serde_json::Value,
73    pub pdf_file_path: Option<String>,
74    pub created_at: DateTime<Utc>,
75    pub updated_at: DateTime<Utc>,
76    // Computed fields
77    pub is_overdue: bool,
78    pub is_expired: bool,
79    pub days_since_request: i64,
80}
81
82impl From<EtatDate> for EtatDateResponse {
83    fn from(etat_date: EtatDate) -> Self {
84        let is_overdue = etat_date.is_overdue();
85        let is_expired = etat_date.is_expired();
86        let days_since_request = etat_date.days_since_request();
87
88        Self {
89            id: etat_date.id,
90            acp_id: etat_date.acp_id,
91            organization_id: etat_date.organization_id,
92            building_id: etat_date.building_id,
93            unit_id: etat_date.unit_id,
94            reference_date: etat_date.reference_date,
95            requested_date: etat_date.requested_date,
96            generated_date: etat_date.generated_date,
97            delivered_date: etat_date.delivered_date,
98            status: etat_date.status,
99            language: etat_date.language,
100            reference_number: etat_date.reference_number,
101            notary_name: etat_date.notary_name,
102            notary_email: etat_date.notary_email,
103            notary_phone: etat_date.notary_phone,
104            building_name: etat_date.building_name,
105            building_address: etat_date.building_address,
106            unit_number: etat_date.unit_number,
107            unit_floor: etat_date.unit_floor,
108            unit_area: etat_date.unit_area,
109            ordinary_charges_quota: etat_date.ordinary_charges_quota,
110            extraordinary_charges_quota: etat_date.extraordinary_charges_quota,
111            owner_balance: etat_date.owner_balance,
112            arrears_amount: etat_date.arrears_amount,
113            monthly_provision_amount: etat_date.monthly_provision_amount,
114            total_balance: etat_date.total_balance,
115            approved_works_unpaid: etat_date.approved_works_unpaid,
116            additional_data: etat_date.additional_data,
117            pdf_file_path: etat_date.pdf_file_path,
118            created_at: etat_date.created_at,
119            updated_at: etat_date.updated_at,
120            is_overdue,
121            is_expired,
122            days_since_request,
123        }
124    }
125}
126
127/// Response avec statistiques pour dashboard syndic
128#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct EtatDateStatsResponse {
130    pub total_requests: i64,
131    pub requested_count: i64,
132    pub in_progress_count: i64,
133    pub generated_count: i64,
134    pub delivered_count: i64,
135    pub expired_count: i64,
136    pub overdue_count: i64, // En retard (>10 jours)
137    pub average_processing_days: f64,
138}