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)]
8pub struct CreateCallForFundsRequest {
9    pub building_id: Uuid,
10    pub title: String,
11    pub description: String,
12    pub total_amount: f64,
13    pub contribution_type: String, // "regular", "extraordinary", "advance", "adjustment"
14    pub call_date: DateTime<Utc>,
15    pub due_date: DateTime<Utc>,
16    pub account_code: Option<String>,
17}
18
19/// Response containing call for funds details
20#[derive(Debug, Serialize, Deserialize)]
21pub struct CallForFundsResponse {
22    pub id: Uuid,
23    pub organization_id: Uuid,
24    pub building_id: Uuid,
25    pub title: String,
26    pub description: String,
27    pub total_amount: f64,
28    pub contribution_type: String,
29    pub call_date: DateTime<Utc>,
30    pub due_date: DateTime<Utc>,
31    pub sent_date: Option<DateTime<Utc>>,
32    pub status: String,
33    pub account_code: Option<String>,
34    pub notes: Option<String>,
35    pub is_overdue: bool,
36    pub created_at: DateTime<Utc>,
37    pub updated_at: DateTime<Utc>,
38    pub created_by: Option<Uuid>,
39}
40
41impl From<CallForFunds> for CallForFundsResponse {
42    fn from(call: CallForFunds) -> Self {
43        let status_str = match call.status {
44            CallForFundsStatus::Draft => "draft",
45            CallForFundsStatus::Sent => "sent",
46            CallForFundsStatus::Partial => "partial",
47            CallForFundsStatus::Completed => "completed",
48            CallForFundsStatus::Cancelled => "cancelled",
49        };
50
51        let contribution_type_str = match call.contribution_type {
52            ContributionType::Regular => "regular",
53            ContributionType::Extraordinary => "extraordinary",
54            ContributionType::Advance => "advance",
55            ContributionType::Adjustment => "adjustment",
56        };
57
58        let is_overdue = call.is_overdue();
59
60        Self {
61            id: call.id,
62            organization_id: call.organization_id,
63            building_id: call.building_id,
64            title: call.title,
65            description: call.description,
66            total_amount: call.total_amount,
67            contribution_type: contribution_type_str.to_string(),
68            call_date: call.call_date,
69            due_date: call.due_date,
70            sent_date: call.sent_date,
71            status: status_str.to_string(),
72            account_code: call.account_code,
73            notes: call.notes,
74            is_overdue,
75            created_at: call.created_at,
76            updated_at: call.updated_at,
77            created_by: call.created_by,
78        }
79    }
80}
81
82/// Request to send a call for funds (triggers automatic contribution generation)
83#[derive(Debug, Serialize, Deserialize)]
84pub struct SendCallForFundsRequest {
85    // Empty for now, could add fields like send_date override, notification preferences, etc.
86}
87
88/// Response after sending a call for funds
89#[derive(Debug, Serialize, Deserialize)]
90pub struct SendCallForFundsResponse {
91    pub call_for_funds: CallForFundsResponse,
92    pub contributions_generated: usize,
93}