Skip to main content

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 deleting an exchange.
38///
39/// `reason` est ignoré quand le provider supprime sa propre offre, mais
40/// devient obligatoire pour une suppression par modération (syndic /
41/// `community.moderator` non partie à l'échange) — Story 5.3 (#587), INV-4.
42#[derive(Debug, Clone, Serialize, Deserialize, Default)]
43pub struct DeleteExchangeDto {
44    pub reason: Option<String>,
45}
46
47/// DTO for rating an exchange partner
48#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct RateExchangeDto {
50    pub rating: i32, // 1-5 stars
51}
52
53/// DTO for returning exchange data
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct LocalExchangeResponseDto {
56    pub id: Uuid,
57    pub building_id: Uuid,
58    pub provider_id: Uuid,
59    pub provider_name: String, // Joined from owner table
60    pub requester_id: Option<Uuid>,
61    pub requester_name: Option<String>, // Joined from owner table
62    pub exchange_type: ExchangeType,
63    pub title: String,
64    pub description: String,
65    pub credits: i32,
66    pub status: ExchangeStatus,
67    pub offered_at: DateTime<Utc>,
68    pub requested_at: Option<DateTime<Utc>>,
69    pub started_at: Option<DateTime<Utc>>,
70    pub completed_at: Option<DateTime<Utc>>,
71    pub cancelled_at: Option<DateTime<Utc>>,
72    pub cancellation_reason: Option<String>,
73    pub provider_rating: Option<i32>,
74    pub requester_rating: Option<i32>,
75    pub created_at: DateTime<Utc>,
76    pub updated_at: DateTime<Utc>,
77}
78
79impl LocalExchangeResponseDto {
80    pub fn from_entity(
81        exchange: LocalExchange,
82        provider_name: String,
83        requester_name: Option<String>,
84    ) -> Self {
85        LocalExchangeResponseDto {
86            id: exchange.id,
87            building_id: exchange.building_id,
88            provider_id: exchange.provider_id,
89            provider_name,
90            requester_id: exchange.requester_id,
91            requester_name,
92            exchange_type: exchange.exchange_type,
93            title: exchange.title,
94            description: exchange.description,
95            credits: exchange.credits,
96            status: exchange.status,
97            offered_at: exchange.offered_at,
98            requested_at: exchange.requested_at,
99            started_at: exchange.started_at,
100            completed_at: exchange.completed_at,
101            cancelled_at: exchange.cancelled_at,
102            cancellation_reason: exchange.cancellation_reason,
103            provider_rating: exchange.provider_rating,
104            requester_rating: exchange.requester_rating,
105            created_at: exchange.created_at,
106            updated_at: exchange.updated_at,
107        }
108    }
109}
110
111/// DTO for returning owner credit balance
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct OwnerCreditBalanceDto {
114    pub owner_id: Uuid,
115    pub owner_name: String, // Joined from owner table
116    pub building_id: Uuid,
117    pub credits_earned: i32,
118    pub credits_spent: i32,
119    pub balance: i32,
120    pub credit_status: CreditStatus,
121    pub total_exchanges: i32,
122    pub average_rating: Option<f32>,
123    pub participation_level: ParticipationLevel,
124    pub created_at: DateTime<Utc>,
125    pub updated_at: DateTime<Utc>,
126}
127
128impl OwnerCreditBalanceDto {
129    pub fn from_entity(balance: OwnerCreditBalance, owner_name: String) -> Self {
130        OwnerCreditBalanceDto {
131            owner_id: balance.owner_id,
132            owner_name,
133            building_id: balance.building_id,
134            credits_earned: balance.credits_earned,
135            credits_spent: balance.credits_spent,
136            balance: balance.balance,
137            credit_status: balance.credit_status(),
138            total_exchanges: balance.total_exchanges,
139            average_rating: balance.average_rating,
140            participation_level: balance.participation_level(),
141            created_at: balance.created_at,
142            updated_at: balance.updated_at,
143        }
144    }
145}
146
147/// DTO for building-level SEL statistics
148#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct SelStatisticsDto {
150    pub building_id: Uuid,
151    pub total_exchanges: i32,
152    pub active_exchanges: i32,
153    pub completed_exchanges: i32,
154    pub total_credits_exchanged: i32,
155    pub active_participants: i32,
156    pub average_exchange_rating: Option<f32>,
157    pub most_popular_exchange_type: Option<ExchangeType>,
158}
159
160/// DTO for owner exchange history summary
161#[derive(Debug, Clone, Serialize, Deserialize)]
162pub struct OwnerExchangeSummaryDto {
163    pub owner_id: Uuid,
164    pub owner_name: String,
165    pub as_provider: i32,     // Number of exchanges as provider
166    pub as_requester: i32,    // Number of exchanges as requester
167    pub total_exchanges: i32, // Sum of both
168    pub average_rating: Option<f32>,
169    pub recent_exchanges: Vec<LocalExchangeResponseDto>, // Last 5
170}