koprogo_api/application/dto/
local_exchange_dto.rs

1use crate::domain::entities::{
2    CreditStatus, ExchangeStatus, ExchangeType, LocalExchange, OwnerCreditBalance,
3    ParticipationLevel,
4};
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9/// DTO for creating a new local exchange offer
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct CreateLocalExchangeDto {
12    pub building_id: Uuid,
13    pub exchange_type: ExchangeType,
14    pub title: String,
15    pub description: String,
16    pub credits: i32,
17}
18
19/// DTO for requesting an exchange
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct RequestExchangeDto {
22    // Empty body - requester_id comes from auth
23}
24
25/// DTO for completing an exchange
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct CompleteExchangeDto {
28    // Empty body - actor_id comes from auth
29}
30
31/// DTO for cancelling an exchange
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct CancelExchangeDto {
34    pub reason: Option<String>,
35}
36
37/// DTO for rating an exchange partner
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct RateExchangeDto {
40    pub rating: i32, // 1-5 stars
41}
42
43/// DTO for returning exchange data
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct LocalExchangeResponseDto {
46    pub id: Uuid,
47    pub building_id: Uuid,
48    pub provider_id: Uuid,
49    pub provider_name: String, // Joined from owner table
50    pub requester_id: Option<Uuid>,
51    pub requester_name: Option<String>, // Joined from owner table
52    pub exchange_type: ExchangeType,
53    pub title: String,
54    pub description: String,
55    pub credits: i32,
56    pub status: ExchangeStatus,
57    pub offered_at: DateTime<Utc>,
58    pub requested_at: Option<DateTime<Utc>>,
59    pub started_at: Option<DateTime<Utc>>,
60    pub completed_at: Option<DateTime<Utc>>,
61    pub cancelled_at: Option<DateTime<Utc>>,
62    pub cancellation_reason: Option<String>,
63    pub provider_rating: Option<i32>,
64    pub requester_rating: Option<i32>,
65    pub created_at: DateTime<Utc>,
66    pub updated_at: DateTime<Utc>,
67}
68
69impl LocalExchangeResponseDto {
70    pub fn from_entity(
71        exchange: LocalExchange,
72        provider_name: String,
73        requester_name: Option<String>,
74    ) -> Self {
75        LocalExchangeResponseDto {
76            id: exchange.id,
77            building_id: exchange.building_id,
78            provider_id: exchange.provider_id,
79            provider_name,
80            requester_id: exchange.requester_id,
81            requester_name,
82            exchange_type: exchange.exchange_type,
83            title: exchange.title,
84            description: exchange.description,
85            credits: exchange.credits,
86            status: exchange.status,
87            offered_at: exchange.offered_at,
88            requested_at: exchange.requested_at,
89            started_at: exchange.started_at,
90            completed_at: exchange.completed_at,
91            cancelled_at: exchange.cancelled_at,
92            cancellation_reason: exchange.cancellation_reason,
93            provider_rating: exchange.provider_rating,
94            requester_rating: exchange.requester_rating,
95            created_at: exchange.created_at,
96            updated_at: exchange.updated_at,
97        }
98    }
99}
100
101/// DTO for returning owner credit balance
102#[derive(Debug, Clone, Serialize, Deserialize)]
103pub struct OwnerCreditBalanceDto {
104    pub owner_id: Uuid,
105    pub owner_name: String, // Joined from owner table
106    pub building_id: Uuid,
107    pub credits_earned: i32,
108    pub credits_spent: i32,
109    pub balance: i32,
110    pub credit_status: CreditStatus,
111    pub total_exchanges: i32,
112    pub average_rating: Option<f32>,
113    pub participation_level: ParticipationLevel,
114    pub created_at: DateTime<Utc>,
115    pub updated_at: DateTime<Utc>,
116}
117
118impl OwnerCreditBalanceDto {
119    pub fn from_entity(balance: OwnerCreditBalance, owner_name: String) -> Self {
120        OwnerCreditBalanceDto {
121            owner_id: balance.owner_id,
122            owner_name,
123            building_id: balance.building_id,
124            credits_earned: balance.credits_earned,
125            credits_spent: balance.credits_spent,
126            balance: balance.balance,
127            credit_status: balance.credit_status(),
128            total_exchanges: balance.total_exchanges,
129            average_rating: balance.average_rating,
130            participation_level: balance.participation_level(),
131            created_at: balance.created_at,
132            updated_at: balance.updated_at,
133        }
134    }
135}
136
137/// DTO for building-level SEL statistics
138#[derive(Debug, Clone, Serialize, Deserialize)]
139pub struct SelStatisticsDto {
140    pub building_id: Uuid,
141    pub total_exchanges: i32,
142    pub active_exchanges: i32,
143    pub completed_exchanges: i32,
144    pub total_credits_exchanged: i32,
145    pub active_participants: i32,
146    pub average_exchange_rating: Option<f32>,
147    pub most_popular_exchange_type: Option<ExchangeType>,
148}
149
150/// DTO for owner exchange history summary
151#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct OwnerExchangeSummaryDto {
153    pub owner_id: Uuid,
154    pub owner_name: String,
155    pub as_provider: i32,     // Number of exchanges as provider
156    pub as_requester: i32,    // Number of exchanges as requester
157    pub total_exchanges: i32, // Sum of both
158    pub average_rating: Option<f32>,
159    pub recent_exchanges: Vec<LocalExchangeResponseDto>, // Last 5
160}