koprogo_api/infrastructure/web/handlers/
owner_contribution_handlers.rs1use crate::application::dto::{
2 CreateOwnerContributionRequest, OwnerContributionResponse, RecordPaymentRequest,
3};
4use crate::infrastructure::web::{AppState, AuthenticatedUser};
5use actix_web::{get, post, put, web, HttpResponse};
6use uuid::Uuid;
7
8#[post("/owner-contributions")]
11pub async fn create_contribution(
12 state: web::Data<AppState>,
13 user: AuthenticatedUser,
14 req: web::Json<CreateOwnerContributionRequest>,
15) -> HttpResponse {
16 let organization_id = match user.organization_id {
18 Some(org_id) => org_id,
19 None => return HttpResponse::BadRequest().body("Organization ID required"),
20 };
21
22 match state
23 .owner_contribution_use_cases
24 .create_contribution(
25 organization_id,
26 req.owner_id,
27 req.unit_id,
28 req.description.clone(),
29 req.amount,
30 req.contribution_type.clone(),
31 req.contribution_date,
32 req.account_code.clone(),
33 )
34 .await
35 {
36 Ok(contribution) => {
37 let response = OwnerContributionResponse::from(contribution);
38 HttpResponse::Created().json(response)
39 }
40 Err(e) => HttpResponse::BadRequest().body(e),
41 }
42}
43
44#[get("/owner-contributions/{id}")]
47pub async fn get_contribution(
48 state: web::Data<AppState>,
49 _user: AuthenticatedUser,
50 id: web::Path<Uuid>,
51) -> HttpResponse {
52 match state
53 .owner_contribution_use_cases
54 .get_contribution(*id)
55 .await
56 {
57 Ok(Some(contribution)) => {
58 let response = OwnerContributionResponse::from(contribution);
59 HttpResponse::Ok().json(response)
60 }
61 Ok(None) => HttpResponse::NotFound().body("Contribution not found"),
62 Err(e) => HttpResponse::InternalServerError().body(e),
63 }
64}
65
66#[get("/owner-contributions")]
69pub async fn get_contributions_by_owner(
70 state: web::Data<AppState>,
71 user: AuthenticatedUser,
72 query: web::Query<std::collections::HashMap<String, String>>,
73) -> HttpResponse {
74 if let Some(id_str) = query.get("owner_id") {
76 let owner_id = match Uuid::parse_str(id_str) {
77 Ok(id) => id,
78 Err(_) => return HttpResponse::BadRequest().body("Invalid owner_id format"),
79 };
80
81 match state
82 .owner_contribution_use_cases
83 .get_contributions_by_owner(owner_id)
84 .await
85 {
86 Ok(contributions) => {
87 let responses: Vec<OwnerContributionResponse> =
88 contributions.into_iter().map(Into::into).collect();
89 return HttpResponse::Ok().json(responses);
90 }
91 Err(e) => return HttpResponse::InternalServerError().body(e),
92 }
93 }
94
95 let organization_id = match user.organization_id {
97 Some(org_id) => org_id,
98 None => return HttpResponse::BadRequest().body("Organization ID required"),
99 };
100
101 match state
102 .owner_contribution_use_cases
103 .get_contributions_by_organization(organization_id)
104 .await
105 {
106 Ok(contributions) => {
107 let responses: Vec<OwnerContributionResponse> =
108 contributions.into_iter().map(Into::into).collect();
109 HttpResponse::Ok().json(responses)
110 }
111 Err(e) => HttpResponse::InternalServerError().body(e),
112 }
113}
114
115#[get("/owner-contributions/outstanding")]
118pub async fn get_outstanding_contributions(
119 state: web::Data<AppState>,
120 _user: AuthenticatedUser,
121 query: web::Query<std::collections::HashMap<String, String>>,
122) -> HttpResponse {
123 let owner_id = match query.get("owner_id") {
124 Some(id_str) => match Uuid::parse_str(id_str) {
125 Ok(id) => id,
126 Err(_) => return HttpResponse::BadRequest().body("Invalid owner_id format"),
127 },
128 None => return HttpResponse::BadRequest().body("owner_id is required"),
129 };
130
131 match state
132 .owner_contribution_use_cases
133 .get_outstanding_contributions(owner_id)
134 .await
135 {
136 Ok(contributions) => {
137 let responses: Vec<OwnerContributionResponse> =
138 contributions.into_iter().map(Into::into).collect();
139 HttpResponse::Ok().json(responses)
140 }
141 Err(e) => HttpResponse::InternalServerError().body(e),
142 }
143}
144
145#[put("/owner-contributions/{id}/mark-paid")]
148pub async fn record_payment(
149 state: web::Data<AppState>,
150 _user: AuthenticatedUser,
151 id: web::Path<Uuid>,
152 req: web::Json<RecordPaymentRequest>,
153) -> HttpResponse {
154 match state
155 .owner_contribution_use_cases
156 .record_payment(
157 *id,
158 req.payment_date,
159 req.payment_method.clone(),
160 req.payment_reference.clone(),
161 )
162 .await
163 {
164 Ok(contribution) => {
165 let response = OwnerContributionResponse::from(contribution);
166 HttpResponse::Ok().json(response)
167 }
168 Err(e) => HttpResponse::BadRequest().body(e),
169 }
170}