Skip to main content

koprogo_api/application/dto/
call_for_funds_dto.rs

1use crate::domain::entities::{CallForFunds, CallForFundsStatus, ContributionType};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6/// Request to create a new call for funds
7#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
8#[serde(deny_unknown_fields)]
9pub struct CreateCallForFundsRequest {
10    pub building_id: Uuid,
11    pub title: String,
12    pub description: String,
13    pub total_amount: rust_decimal::Decimal,
14    pub contribution_type: String, // "regular", "extraordinary", "advance", "adjustment"
15    pub call_date: DateTime<Utc>,
16    pub due_date: DateTime<Utc>,
17    pub account_code: Option<String>,
18    /// Part du montant appelé affectée au fonds de réserve.
19    ///
20    /// Art. 3.86 § 3 al. 7 : le syndic doit la communiquer **lors de l'appel**.
21    /// Absente, elle vaut zéro — ce qui reste une communication explicite,
22    /// contrairement au silence d'avant.
23    #[serde(default)]
24    pub reserve_fund_share: rust_decimal::Decimal,
25}
26
27/// Response containing call for funds details
28#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
29pub struct CallForFundsResponse {
30    pub id: Uuid,
31    /// L'ACP propriétaire de la pièce (ADR-0045).
32    pub acp_id: Uuid,
33    pub organization_id: Uuid,
34    pub building_id: Uuid,
35    pub title: String,
36    pub description: String,
37    pub total_amount: rust_decimal::Decimal,
38    /// Part affectée au fonds de réserve, communiquée avec l'appel
39    /// (Art. 3.86 § 3 al. 7). C'est ce que le copropriétaire ne récupérera pas
40    /// en vendant son lot : elle suit le lot, pas le vendeur.
41    pub reserve_fund_share: rust_decimal::Decimal,
42    pub contribution_type: String,
43    pub call_date: DateTime<Utc>,
44    pub due_date: DateTime<Utc>,
45    pub sent_date: Option<DateTime<Utc>>,
46    pub status: String,
47    pub account_code: Option<String>,
48    pub notes: Option<String>,
49    pub is_overdue: bool,
50    pub created_at: DateTime<Utc>,
51    pub updated_at: DateTime<Utc>,
52    pub created_by: Option<Uuid>,
53    /// Le fonds alimenté par cet appel (issue #635).
54    pub fund_id: Option<Uuid>,
55}
56
57impl From<CallForFunds> for CallForFundsResponse {
58    fn from(call: CallForFunds) -> Self {
59        let status_str = match call.status {
60            CallForFundsStatus::Draft => "draft",
61            CallForFundsStatus::Sent => "sent",
62            CallForFundsStatus::Partial => "partial",
63            CallForFundsStatus::Completed => "completed",
64            CallForFundsStatus::Cancelled => "cancelled",
65        };
66
67        let contribution_type_str = match call.contribution_type {
68            ContributionType::Regular => "regular",
69            ContributionType::Extraordinary => "extraordinary",
70            ContributionType::Advance => "advance",
71            ContributionType::Adjustment => "adjustment",
72        };
73
74        let is_overdue = call.is_overdue();
75
76        Self {
77            id: call.id,
78            acp_id: call.acp_id,
79            organization_id: call.organization_id,
80            building_id: call.building_id,
81            title: call.title,
82            description: call.description,
83            total_amount: call.total_amount,
84            reserve_fund_share: call.reserve_fund_share,
85            contribution_type: contribution_type_str.to_string(),
86            call_date: call.call_date,
87            due_date: call.due_date,
88            sent_date: call.sent_date,
89            status: status_str.to_string(),
90            account_code: call.account_code,
91            notes: call.notes,
92            is_overdue,
93            created_at: call.created_at,
94            updated_at: call.updated_at,
95            created_by: call.created_by,
96            fund_id: call.fund_id,
97        }
98    }
99}
100
101/// Request to send a call for funds (triggers automatic contribution generation)
102#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
103pub struct SendCallForFundsRequest {
104    // Empty for now, could add fields like send_date override, notification preferences, etc.
105}
106
107/// Response after sending a call for funds
108#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
109pub struct SendCallForFundsResponse {
110    pub call_for_funds: CallForFundsResponse,
111    pub contributions_generated: usize,
112}