koprogo_api/application/use_cases/
owner_use_cases.rs1use crate::application::dto::{CreateOwnerDto, OwnerFilters, OwnerResponseDto, PageRequest};
2use crate::application::ports::OwnerRepository;
3use crate::domain::entities::Owner;
4use std::sync::Arc;
5use uuid::Uuid;
6
7pub struct OwnerUseCases {
8 repository: Arc<dyn OwnerRepository>,
9}
10
11impl OwnerUseCases {
12 pub fn new(repository: Arc<dyn OwnerRepository>) -> Self {
13 Self { repository }
14 }
15
16 pub async fn create_owner(&self, dto: CreateOwnerDto) -> Result<OwnerResponseDto, String> {
17 let organization_id = Uuid::parse_str(&dto.organization_id)
18 .map_err(|_| "Invalid organization_id format".to_string())?;
19
20 if (self.repository.find_by_email(&dto.email).await?).is_some() {
22 return Err("Email already exists".to_string());
23 }
24
25 let owner = Owner::new(
26 organization_id,
27 dto.first_name,
28 dto.last_name,
29 dto.email,
30 dto.phone,
31 dto.address,
32 dto.city,
33 dto.postal_code,
34 dto.country,
35 )?;
36
37 let created = self.repository.create(&owner).await?;
38 Ok(self.to_response_dto(&created))
39 }
40
41 pub async fn get_owner(&self, id: Uuid) -> Result<Option<OwnerResponseDto>, String> {
42 let owner = self.repository.find_by_id(id).await?;
43 Ok(owner.map(|o| self.to_response_dto(&o)))
44 }
45
46 pub async fn list_owners(&self) -> Result<Vec<OwnerResponseDto>, String> {
47 let owners = self.repository.find_all().await?;
48 Ok(owners.iter().map(|o| self.to_response_dto(o)).collect())
49 }
50
51 pub async fn list_owners_paginated(
52 &self,
53 page_request: &PageRequest,
54 organization_id: Option<Uuid>,
55 ) -> Result<(Vec<OwnerResponseDto>, i64), String> {
56 let filters = OwnerFilters {
57 organization_id,
58 ..Default::default()
59 };
60
61 let (owners, total) = self
62 .repository
63 .find_all_paginated(page_request, &filters)
64 .await?;
65
66 let dtos = owners.iter().map(|o| self.to_response_dto(o)).collect();
67 Ok((dtos, total))
68 }
69
70 pub async fn update_owner(
71 &self,
72 id: Uuid,
73 first_name: String,
74 last_name: String,
75 email: String,
76 phone: Option<String>,
77 ) -> Result<OwnerResponseDto, String> {
78 let mut owner = self
80 .repository
81 .find_by_id(id)
82 .await?
83 .ok_or("Owner not found".to_string())?;
84
85 if owner.email != email {
87 if let Some(existing) = self.repository.find_by_email(&email).await? {
88 if existing.id != id {
89 return Err("Email already exists".to_string());
90 }
91 }
92 }
93
94 owner.first_name = first_name;
96 owner.last_name = last_name;
97 owner.email = email;
98 owner.phone = phone;
99
100 let updated = self.repository.update(&owner).await?;
102 Ok(self.to_response_dto(&updated))
103 }
104
105 fn to_response_dto(&self, owner: &Owner) -> OwnerResponseDto {
106 OwnerResponseDto {
107 id: owner.id.to_string(),
108 organization_id: owner.organization_id.to_string(),
109 user_id: owner.user_id.map(|id| id.to_string()),
110 first_name: owner.first_name.clone(),
111 last_name: owner.last_name.clone(),
112 email: owner.email.clone(),
113 phone: owner.phone.clone(),
114 address: owner.address.clone(),
115 city: owner.city.clone(),
116 postal_code: owner.postal_code.clone(),
117 country: owner.country.clone(),
118 }
119 }
120}