koprogo_api/application/dto/
filters.rs

1use crate::domain::entities::ApprovalStatus;
2use chrono::{DateTime, Utc};
3use serde::Deserialize;
4use uuid::Uuid;
5
6/// Filters for building list queries
7#[derive(Debug, Deserialize, Default, Clone)]
8pub struct BuildingFilters {
9    pub organization_id: Option<Uuid>,
10    pub city: Option<String>,
11    pub construction_year: Option<i32>,
12    pub min_units: Option<i32>,
13    pub max_units: Option<i32>,
14    /// BUG-WF14-2: Si défini, filtre les buildings où cet user possède un lot (via owners.user_id → unit_owners → units)
15    pub owner_user_id: Option<Uuid>,
16}
17
18/// Filters for expense list queries
19#[derive(Debug, Deserialize, Default, Clone)]
20pub struct ExpenseFilters {
21    pub organization_id: Option<Uuid>,
22    pub building_id: Option<Uuid>,
23    pub category: Option<String>,
24    pub status: Option<String>,
25    pub paid: Option<bool>,
26    pub approval_status: Option<ApprovalStatus>, // Nouveau: pour filtrer par statut workflow
27    pub date_from: Option<DateTime<Utc>>,
28    pub date_to: Option<DateTime<Utc>>,
29    pub min_amount: Option<f64>,
30    pub max_amount: Option<f64>,
31}
32
33/// Filters for unit list queries
34#[derive(Debug, Deserialize, Default, Clone)]
35pub struct UnitFilters {
36    pub organization_id: Option<Uuid>,
37    pub building_id: Option<Uuid>,
38    pub unit_type: Option<String>,
39    pub has_owner: Option<bool>,
40    pub floor: Option<i32>,
41    pub min_area: Option<f64>,
42    pub max_area: Option<f64>,
43}
44
45/// Filters for owner list queries
46#[derive(Debug, Deserialize, Default, Clone)]
47pub struct OwnerFilters {
48    pub organization_id: Option<Uuid>,
49    pub email: Option<String>,
50    pub phone: Option<String>,
51    pub last_name: Option<String>,
52    pub first_name: Option<String>,
53}
54
55/// Filters for work report list queries
56#[derive(Debug, Deserialize, Default, Clone)]
57pub struct WorkReportFilters {
58    pub organization_id: Option<Uuid>,
59    pub building_id: Option<Uuid>,
60    pub work_type: Option<String>,
61    pub warranty_type: Option<String>,
62    pub contractor_name: Option<String>,
63    pub work_date_from: Option<DateTime<Utc>>,
64    pub work_date_to: Option<DateTime<Utc>>,
65    pub min_cost: Option<f64>,
66    pub max_cost: Option<f64>,
67    pub warranty_active: Option<bool>,
68}
69
70/// Filters for technical inspection list queries
71#[derive(Debug, Deserialize, Default, Clone)]
72pub struct TechnicalInspectionFilters {
73    pub organization_id: Option<Uuid>,
74    pub building_id: Option<Uuid>,
75    pub inspection_type: Option<String>,
76    pub status: Option<String>,
77    pub inspector_name: Option<String>,
78    pub inspector_company: Option<String>,
79    pub inspection_date_from: Option<DateTime<Utc>>,
80    pub inspection_date_to: Option<DateTime<Utc>>,
81    pub overdue: Option<bool>,
82    pub compliant: Option<bool>,
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn test_building_filters_default() {
91        let filters = BuildingFilters::default();
92        assert!(filters.city.is_none());
93        assert!(filters.construction_year.is_none());
94        assert!(filters.min_units.is_none());
95        assert!(filters.max_units.is_none());
96    }
97
98    #[test]
99    fn test_expense_filters_default() {
100        let filters = ExpenseFilters::default();
101        assert!(filters.building_id.is_none());
102        assert!(filters.category.is_none());
103        assert!(filters.paid.is_none());
104    }
105
106    #[test]
107    fn test_unit_filters_default() {
108        let filters = UnitFilters::default();
109        assert!(filters.building_id.is_none());
110        assert!(filters.has_owner.is_none());
111    }
112
113    #[test]
114    fn test_owner_filters_default() {
115        let filters = OwnerFilters::default();
116        assert!(filters.email.is_none());
117        assert!(filters.last_name.is_none());
118    }
119}