koprogo_api/infrastructure/web/handlers/
dashboard_handlers.rs1use crate::infrastructure::web::{AppState, AuthenticatedUser};
6use actix_web::{get, web, HttpResponse, Responder};
7
8const ROLES_FINANCIERS: &[&str] = &[
26 "superadmin",
27 "admin",
28 "syndic",
29 "accountant",
30 "accountant.encodeur",
31 "accountant.emetteur",
32];
33
34#[get("/dashboard/accountant/stats")]
37pub async fn get_accountant_stats(
38 state: web::Data<AppState>,
39 user: AuthenticatedUser,
40) -> impl Responder {
41 if !ROLES_FINANCIERS.contains(&user.role.to_lowercase().as_str()) {
45 return HttpResponse::Forbidden().json(serde_json::json!({
46 "error": "Les chiffres financiers de la copropriété sont réservés \
47 au syndic, au comptable et à l'administration."
48 }));
49 }
50
51 let organization_id = match user.organization_id {
52 Some(org_id) => org_id,
53 None => {
54 return HttpResponse::BadRequest().body("User does not belong to an organization");
55 }
56 };
57
58 match state
59 .dashboard_use_cases
60 .get_accountant_stats(organization_id)
61 .await
62 {
63 Ok(stats) => HttpResponse::Ok().json(stats),
64 Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
65 }
66}
67
68#[get("/dashboard/accountant/transactions")]
71pub async fn get_recent_transactions(
72 state: web::Data<AppState>,
73 user: AuthenticatedUser,
74 query: web::Query<RecentTransactionsQuery>,
75) -> impl Responder {
76 let organization_id = match user.organization_id {
77 Some(org_id) => org_id,
78 None => {
79 return HttpResponse::BadRequest().body("User does not belong to an organization");
80 }
81 };
82
83 let limit = query.limit.unwrap_or(10).min(50); match state
86 .dashboard_use_cases
87 .get_recent_transactions(organization_id, limit)
88 .await
89 {
90 Ok(transactions) => HttpResponse::Ok().json(transactions),
91 Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
92 }
93}
94
95#[derive(serde::Deserialize)]
96pub struct RecentTransactionsQuery {
97 pub limit: Option<usize>,
98}