koprogo_api/application/dto/
resolution_dto.rs

1use crate::domain::entities::{MajorityType, Resolution, ResolutionStatus, ResolutionType};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6/// Response DTO for Resolution
7#[derive(Debug, Serialize, Deserialize, Clone, utoipa::ToSchema)]
8pub struct ResolutionResponse {
9    pub id: Uuid,
10    pub meeting_id: Uuid,
11    pub title: String,
12    pub description: String,
13    pub resolution_type: ResolutionType,
14    pub majority_required: MajorityType,
15    pub vote_count_pour: i32,
16    pub vote_count_contre: i32,
17    pub vote_count_abstention: i32,
18    pub total_voting_power_pour: f64,
19    pub total_voting_power_contre: f64,
20    pub total_voting_power_abstention: f64,
21    pub status: ResolutionStatus,
22    pub agenda_item_index: Option<usize>, // Issue #310: Link to agenda item
23    pub created_at: DateTime<Utc>,
24    pub voted_at: Option<DateTime<Utc>>,
25    // Calculated fields
26    pub total_votes: i32,
27    pub pour_percentage: f64,
28    pub contre_percentage: f64,
29    pub abstention_percentage: f64,
30}
31
32impl From<Resolution> for ResolutionResponse {
33    fn from(resolution: Resolution) -> Self {
34        Self {
35            id: resolution.id,
36            meeting_id: resolution.meeting_id,
37            title: resolution.title.clone(),
38            description: resolution.description.clone(),
39            resolution_type: resolution.resolution_type.clone(),
40            majority_required: resolution.majority_required.clone(),
41            vote_count_pour: resolution.vote_count_pour,
42            vote_count_contre: resolution.vote_count_contre,
43            vote_count_abstention: resolution.vote_count_abstention,
44            total_voting_power_pour: resolution.total_voting_power_pour,
45            total_voting_power_contre: resolution.total_voting_power_contre,
46            total_voting_power_abstention: resolution.total_voting_power_abstention,
47            status: resolution.status.clone(),
48            agenda_item_index: resolution.agenda_item_index,
49            created_at: resolution.created_at,
50            voted_at: resolution.voted_at,
51            // Calculated
52            total_votes: resolution.total_votes(),
53            pour_percentage: resolution.pour_percentage(),
54            contre_percentage: resolution.contre_percentage(),
55            abstention_percentage: resolution.abstention_percentage(),
56        }
57    }
58}
59
60/// Request DTO for creating a resolution
61#[derive(Debug, Deserialize, utoipa::ToSchema)]
62pub struct CreateResolutionRequest {
63    pub meeting_id: Uuid,
64    pub title: String,
65    pub description: String,
66    pub resolution_type: ResolutionType,
67    pub majority_required: MajorityType,
68    pub agenda_item_index: Option<usize>, // Issue #310: Optional link to agenda item
69}
70
71/// Request DTO for updating a resolution
72#[derive(Debug, Deserialize, utoipa::ToSchema)]
73pub struct UpdateResolutionRequest {
74    pub title: Option<String>,
75    pub description: Option<String>,
76    pub resolution_type: Option<ResolutionType>,
77    pub majority_required: Option<MajorityType>,
78}
79
80/// Request DTO for closing voting on a resolution
81#[derive(Debug, Deserialize, utoipa::ToSchema)]
82pub struct CloseVotingRequest {
83    pub total_voting_power: f64,
84}