koprogo_api/application/use_cases/
unit_use_cases.rs1use crate::application::dto::{CreateUnitDto, PageRequest, UnitFilters, UnitResponseDto};
2use crate::application::ports::UnitRepository;
3use crate::domain::entities::Unit;
4use std::sync::Arc;
5use uuid::Uuid;
6
7pub struct UnitUseCases {
8 repository: Arc<dyn UnitRepository>,
9}
10
11impl UnitUseCases {
12 pub fn new(repository: Arc<dyn UnitRepository>) -> Self {
13 Self { repository }
14 }
15
16 pub async fn create_unit(&self, dto: CreateUnitDto) -> Result<UnitResponseDto, String> {
17 let organization_id = Uuid::parse_str(&dto.organization_id)
18 .map_err(|_| "Invalid organization_id format".to_string())?;
19 let building_id = Uuid::parse_str(&dto.building_id)
20 .map_err(|_| "Invalid building ID format".to_string())?;
21
22 let unit = Unit::new(
23 organization_id,
24 building_id,
25 dto.unit_number,
26 dto.unit_type,
27 dto.floor,
28 dto.surface_area,
29 dto.quota,
30 )?;
31
32 let created = self.repository.create(&unit).await?;
33 Ok(self.to_response_dto(&created))
34 }
35
36 pub async fn get_unit(&self, id: Uuid) -> Result<Option<UnitResponseDto>, String> {
37 let unit = self.repository.find_by_id(id).await?;
38 Ok(unit.map(|u| self.to_response_dto(&u)))
39 }
40
41 pub async fn list_units_by_building(
42 &self,
43 building_id: Uuid,
44 ) -> Result<Vec<UnitResponseDto>, String> {
45 let units = self.repository.find_by_building(building_id).await?;
46 Ok(units.iter().map(|u| self.to_response_dto(u)).collect())
47 }
48
49 pub async fn list_units_paginated(
50 &self,
51 page_request: &PageRequest,
52 organization_id: Option<Uuid>,
53 ) -> Result<(Vec<UnitResponseDto>, i64), String> {
54 let filters = UnitFilters {
55 organization_id,
56 ..Default::default()
57 };
58
59 let (units, total) = self
60 .repository
61 .find_all_paginated(page_request, &filters)
62 .await?;
63
64 let dtos = units.iter().map(|u| self.to_response_dto(u)).collect();
65 Ok((dtos, total))
66 }
67
68 pub async fn assign_owner(
69 &self,
70 unit_id: Uuid,
71 owner_id: Uuid,
72 ) -> Result<UnitResponseDto, String> {
73 let mut unit = self
74 .repository
75 .find_by_id(unit_id)
76 .await?
77 .ok_or_else(|| "Unit not found".to_string())?;
78
79 unit.assign_owner(owner_id);
80
81 let updated = self.repository.update(&unit).await?;
82 Ok(self.to_response_dto(&updated))
83 }
84
85 fn to_response_dto(&self, unit: &Unit) -> UnitResponseDto {
86 UnitResponseDto {
87 id: unit.id.to_string(),
88 building_id: unit.building_id.to_string(),
89 unit_number: unit.unit_number.clone(),
90 unit_type: unit.unit_type.clone(),
91 floor: unit.floor,
92 surface_area: unit.surface_area,
93 quota: unit.quota,
94 owner_id: unit.owner_id.map(|id| id.to_string()),
95 }
96 }
97}