Skip to main content

koprogo_api/application/dto/
filters.rs

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