use { crate::CurrencyCode, chrono::{DateTime, Utc}, derive_more::{Deref, Display}, serde::{Deserialize, Serialize}, std::str::FromStr, uuid::Uuid, }; #[cfg(feature = "client")] const _: () = { use crate::{MuralError, RequestExt, SearchResponse}; impl crate::Client { pub async fn search_organizations( &self, req: SearchRequest, ) -> Result, MuralError> { #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct Body { #[serde(skip_serializing_if = "Option::is_none")] filter: Option, } #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct Filter { #[serde(rename = "type")] ty: FilterType, name: String, } #[derive(Debug, Clone, Copy, Serialize)] #[serde(rename_all = "snake_case")] pub enum FilterType { Name, } maybe_mock!(self, search_organizations(req.clone())); let query = [ req.limit.map(|limit| ("limit", limit.to_string())), req.next_id .map(|next_id| ("nextId", next_id.hyphenated().to_string())), ] .into_iter() .flatten() .collect::>(); let body = Body { filter: req.name.map(|name| Filter { ty: FilterType::Name, name, }), }; self.http_post(|base| format!("{base}/api/organizations/search")) .query(&query) .json(&body) .send_mural() .await } pub async fn get_organization( &self, id: OrganizationId, ) -> Result { maybe_mock!(self, get_organization(id)); self.http_post(|base| format!("{base}/api/organizations/{id}")) .send_mural() .await } } }; #[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Hash, Deref, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[display("{}", _0.hyphenated())] pub struct OrganizationId(pub Uuid); impl FromStr for OrganizationId { type Err = ::Err; fn from_str(s: &str) -> Result { s.parse::().map(Self) } } impl From for Uuid { fn from(value: OrganizationId) -> Self { value.0 } } #[derive(Debug, Clone, Default)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct SearchRequest { pub limit: Option, pub next_id: Option, pub name: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(tag = "type", rename_all = "snake_case")] pub enum Organization { Individual(Individual), Business(Business), EndUserCustodialIndividual(EndUserCustodialIndividual), EndUserCustodialBusiness(EndUserCustodialBusiness), } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(rename_all = "camelCase")] pub struct Individual { pub id: OrganizationId, pub created_at: DateTime, pub updated_at: DateTime, pub first_name: String, pub last_name: String, pub tos_status: TosStatus, pub kyc_status: KycStatus, pub currency_capabilities: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(rename_all = "camelCase")] pub struct Business { pub id: OrganizationId, pub created_at: DateTime, pub updated_at: DateTime, pub name: String, pub tos_status: TosStatus, pub kyc_status: KycStatus, pub currency_capabilities: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(rename_all = "camelCase")] pub struct EndUserCustodialIndividual { pub id: OrganizationId, pub created_at: DateTime, pub updated_at: DateTime, pub first_name: String, pub last_name: String, pub approver: Approver, pub tos_status: TosStatus, pub kyc_status: KycStatus, pub currency_capabilities: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(rename_all = "camelCase")] pub struct EndUserCustodialBusiness { pub id: OrganizationId, pub created_at: DateTime, pub updated_at: DateTime, pub name: String, pub approver: Approver, pub tos_status: TosStatus, pub kyc_status: KycStatus, pub currency_capabilities: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(rename_all = "camelCase")] pub struct Approver { pub id: Uuid, pub created_at: DateTime, pub name: String, pub email: String, pub auth_methods: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(tag = "type", rename_all = "SCREAMING_SNAKE_CASE")] pub enum TosStatus { NotAccepted, NeedsReview, Accepted, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(tag = "type", rename_all = "camelCase")] pub enum KycStatus { Inactive, Pending, Approved { approved_at: DateTime, }, Errored { details: String, errored_at: DateTime, }, Rejected { reason: String, rejected_at: DateTime, }, PreValidationFailed { failed_validation_reason: FailedValidationReason, failed_validation_at: DateTime, }, NeedsUpdate { needs_update_reason: String, verification_status_updated_at: DateTime, }, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(tag = "type", rename_all = "camelCase")] pub enum FailedValidationReason { DocumentPrevalidationFailed { document_id: String, failed_validation_reason: String, }, UltimateBeneficialOwnerPrevalidationFailed { ultimate_beneficial_owner_id: String, failed_validation_reason: String, }, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(rename_all = "camelCase")] pub struct CurrencyCapability { pub fiat_and_rail_code: String, pub currency_code: CurrencyCode, pub deposit_status: TransactionCapabilityStatus, pub pay_out_status: TransactionCapabilityStatus, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(tag = "type", rename_all = "camelCase")] pub enum TransactionCapabilityStatus { TermsOfService { details: String, }, #[serde(rename = "awaitingKYC")] AwaitingKyc { details: String, }, Enabled, Rejected { reason: RejectedReason, details: String, }, Disabled { reason: DisabledReason, details: String, }, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(tag = "type", rename_all = "SCREAMING_SNAKE_CASE")] pub enum RejectedReason { KycFailed, } #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(tag = "type", rename_all = "SCREAMING_SNAKE_CASE")] pub enum DisabledReason { CapabilityUnavailable, ProcessingError, }