koprogo_api/application/use_cases/
service_provider_use_cases.rs1use crate::application::dto::marketplace_dto::{
2 CreateServiceProviderDto, SearchServiceProvidersQuery, ServiceProviderResponseDto,
3};
4use crate::application::ports::service_provider_repository::ServiceProviderRepository;
5use crate::domain::entities::service_provider::{ServiceProvider, TradeCategory};
6use std::sync::Arc;
7use uuid::Uuid;
8
9pub struct ServiceProviderUseCases {
10 pub repo: Arc<dyn ServiceProviderRepository>,
11}
12
13impl ServiceProviderUseCases {
14 pub fn new(repo: Arc<dyn ServiceProviderRepository>) -> Self {
15 Self { repo }
16 }
17
18 pub async fn create(
20 &self,
21 organization_id: Uuid,
22 dto: CreateServiceProviderDto,
23 ) -> Result<ServiceProviderResponseDto, String> {
24 let trade_category =
25 TradeCategory::from_sql(&dto.trade_category).map_err(|e| e.to_string())?;
26
27 let mut provider = ServiceProvider::new(
28 organization_id,
29 dto.company_name,
30 trade_category,
31 dto.bce_number,
32 )?;
33
34 if let Some(specs) = dto.specializations {
35 provider.specializations = specs;
36 }
37 if let Some(zones) = dto.service_zone_postal_codes {
38 provider.service_zone_postal_codes = zones;
39 }
40 if let Some(certs) = dto.certifications {
41 provider.certifications = certs;
42 }
43 if let Some(ipi) = dto.ipi_registration {
44 provider.ipi_registration = Some(ipi);
45 }
46
47 let created = self.repo.create(&provider).await?;
48 Ok(ServiceProviderResponseDto::from(created))
49 }
50
51 pub async fn search(
53 &self,
54 query: &SearchServiceProvidersQuery,
55 ) -> Result<Vec<ServiceProviderResponseDto>, String> {
56 let providers = if let Some(ref q) = query.trade_category {
57 let category = TradeCategory::from_sql(q).map_err(|e| e.to_string())?;
58 self.repo.find_by_trade_category(category, 1, 50).await?
59 } else if let Some(ref postal_code) = query.postal_code {
60 self.repo.search("", Some(postal_code), 1, 50).await?
61 } else {
62 self.repo.find_all(None, 1, 50).await?
63 };
64
65 let mut results: Vec<ServiceProviderResponseDto> = providers
66 .into_iter()
67 .map(ServiceProviderResponseDto::from)
68 .collect();
69
70 if let Some(min_rating) = query.min_rating {
72 results.retain(|p| p.rating_avg.unwrap_or(0.0) >= min_rating);
73 }
74 if query.is_verified_only == Some(true) {
75 results.retain(|p| p.is_verified);
76 }
77
78 Ok(results)
79 }
80
81 pub async fn find_by_slug(
83 &self,
84 slug: &str,
85 ) -> Result<Option<ServiceProviderResponseDto>, String> {
86 let provider = self.repo.find_by_slug(slug).await?;
87 Ok(provider.map(ServiceProviderResponseDto::from))
88 }
89}