noah_sdk/api/customers.rs
1//! Customers API
2//!
3//! This module provides functionality to manage customers in the Noah API.
4//!
5//! # Examples
6//!
7//! ```no_run
8//! use noah_sdk::{NoahClient, Config, Environment, AuthConfig};
9//! use noah_sdk::models::customers::CustomerInput;
10//! use noah_sdk::models::common::CustomerID;
11//! use noah_sdk::models::FullName;
12//! use noah_sdk::models::StreetAddress;
13//!
14//! # #[cfg(feature = "async")]
15//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
16//! let config = Config::new(Environment::Sandbox);
17//! let auth = AuthConfig::with_api_key("your-api-key".to_string());
18//! let client = NoahClient::new(config, auth)?;
19//!
20//! // Create or update a customer
21//! use noah_sdk::models::customers::{CustomerInput, IndividualCustomerInput, FullName, StreetAddress};
22//! use noah_sdk::models::common::*;
23//! let customer_id = "customer-123".to_string();
24//! // Note: IndividualCustomerInput requires many fields (customer_type, full_name,
25//! // date_of_birth, email, identities, primary_residence, etc.)
26//! // This is a simplified example - see the API documentation for full field details
27//! # let customer_input = CustomerInput::Individual(IndividualCustomerInput {
28//! # customer_type: "Individual".to_string(),
29//! # full_name: FullName {
30//! # first_name: "John".to_string(),
31//! # last_name: "Doe".to_string(),
32//! # middle_name: None,
33//! # },
34//! # date_of_birth: "1990-01-01".to_string(),
35//! # email: Some("john@example.com".to_string()),
36//! # phone_number: None,
37//! # identities: vec![],
38//! # primary_residence: StreetAddress {
39//! # street: "123 Main St".to_string(),
40//! # street2: None,
41//! # city: "New York".to_string(),
42//! # post_code: "10001".to_string(),
43//! # state: "NY".to_string(),
44//! # country: "US".to_string(),
45//! # },
46//! # });
47//! client.create_or_update_customer(&customer_id, &customer_input).await?;
48//!
49//! // Retrieve customer
50//! let customer = client.get_customer(&customer_id).await?;
51//! println!("Customer: {:?}", customer);
52//! # Ok(())
53//! # }
54//! ```
55
56use crate::client::NoahClient;
57use crate::error::Result;
58use crate::models::common::*;
59use crate::models::customers::{Customer, CustomerInput, GetCustomersResponse};
60
61impl NoahClient {
62 /// Retrieve a customer by their ID
63 ///
64 /// # Arguments
65 ///
66 /// * `customer_id` - The unique identifier of the customer to retrieve
67 ///
68 /// # Returns
69 ///
70 /// Returns a [`Customer`] object containing the customer's information.
71 ///
72 /// # Errors
73 ///
74 /// This function will return an error if:
75 /// - The customer ID is invalid
76 /// - The customer does not exist
77 /// - The API request fails
78 ///
79 /// # Examples
80 ///
81 /// ```no_run
82 /// use noah_sdk::{NoahClient, Config, Environment, AuthConfig};
83 /// use noah_sdk::models::common::CustomerID;
84 ///
85 /// # #[cfg(feature = "async")]
86 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
87 /// let config = Config::new(Environment::Sandbox);
88 /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
89 /// let client = NoahClient::new(config, auth)?;
90 ///
91 /// let customer_id = "customer-123".to_string();
92 /// let customer = client.get_customer(&customer_id).await?;
93 /// # Ok(())
94 /// # }
95 /// ```
96 #[cfg(feature = "async")]
97 pub async fn get_customer(&self, customer_id: &CustomerID) -> Result<Customer> {
98 let path = format!("/customers/{customer_id}");
99 self.get(&path).await
100 }
101
102 /// Retrieve a customer by their ID (blocking)
103 ///
104 /// Synchronous version of [`get_customer`](Self::get_customer). See that method for
105 /// detailed documentation.
106 #[cfg(feature = "sync")]
107 pub fn get_customer_blocking(&self, customer_id: &CustomerID) -> Result<Customer> {
108 let path = format!("/customers/{customer_id}");
109 self.get_blocking(&path)
110 }
111
112 /// Create a new customer or update an existing one
113 ///
114 /// This method will create a customer if they don't exist, or update an existing customer
115 /// if they do. The customer ID is used as the unique identifier.
116 ///
117 /// # Arguments
118 ///
119 /// * `customer_id` - The unique identifier for the customer
120 /// * `customer` - The customer data to create or update
121 ///
122 /// # Returns
123 ///
124 /// Returns `Ok(())` if the operation succeeds.
125 ///
126 /// # Errors
127 ///
128 /// This function will return an error if:
129 /// - The customer data is invalid
130 /// - The API request fails
131 /// - Authentication fails
132 ///
133 /// # Examples
134 ///
135 /// ```no_run
136 /// use noah_sdk::{NoahClient, Config, Environment, AuthConfig};
137 /// use noah_sdk::models::customers::CustomerInput;
138 /// use noah_sdk::models::common::CustomerID;
139 ///
140 /// # #[cfg(feature = "async")]
141 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
142 /// let config = Config::new(Environment::Sandbox);
143 /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
144 /// let client = NoahClient::new(config, auth)?;
145 ///
146 /// use noah_sdk::models::customers::{CustomerInput, IndividualCustomerInput, FullName, StreetAddress};
147 /// use noah_sdk::models::common::*;
148 /// let customer_id = "customer-123".to_string();
149 /// // Note: IndividualCustomerInput requires many fields - see API docs for details
150 /// # let customer = CustomerInput::Individual(IndividualCustomerInput {
151 /// # customer_type: "Individual".to_string(),
152 /// # full_name: FullName {
153 /// # first_name: "John".to_string(),
154 /// # last_name: "Doe".to_string(),
155 /// # middle_name: None,
156 /// # },
157 /// # date_of_birth: "1990-01-01".to_string(),
158 /// # email: Some("john@example.com".to_string()),
159 /// # phone_number: None,
160 /// # identities: vec![],
161 /// # primary_residence: StreetAddress {
162 /// # street: "123 Main St".to_string(),
163 /// # street2: None,
164 /// # city: "New York".to_string(),
165 /// # post_code: "10001".to_string(),
166 /// # state: "NY".to_string(),
167 /// # country: "US".to_string(),
168 /// # },
169 /// # });
170 /// client.create_or_update_customer(&customer_id, &customer).await?;
171 /// # Ok(())
172 /// # }
173 /// ```
174 #[cfg(feature = "async")]
175 pub async fn create_or_update_customer(
176 &self,
177 customer_id: &CustomerID,
178 customer: &CustomerInput,
179 ) -> Result<()> {
180 let path = format!("/customers/{customer_id}");
181 let _response: Option<serde_json::Value> = self.put(&path, customer).await?;
182 Ok(())
183 }
184
185 /// Create a new customer or update an existing one (blocking)
186 ///
187 /// Synchronous version of [`create_or_update_customer`](Self::create_or_update_customer).
188 /// See that method for detailed documentation.
189 #[cfg(feature = "sync")]
190 pub fn create_or_update_customer_blocking(
191 &self,
192 customer_id: &CustomerID,
193 customer: &CustomerInput,
194 ) -> Result<()> {
195 let path = format!("/customers/{customer_id}");
196 let _response: Option<serde_json::Value> = self.put_blocking(&path, customer)?;
197 Ok(())
198 }
199
200 /// List customers with optional pagination and sorting
201 ///
202 /// Retrieves a paginated list of customers. Supports pagination and sorting options.
203 ///
204 /// # Arguments
205 ///
206 /// * `page_size` - Optional number of items per page
207 /// * `page_token` - Optional token for pagination to get the next page
208 /// * `sort_direction` - Optional sort direction (ascending or descending)
209 ///
210 /// # Returns
211 ///
212 /// Returns a [`GetCustomersResponse`] containing the list of customers and pagination info.
213 ///
214 /// # Examples
215 ///
216 /// ```no_run
217 /// use noah_sdk::{NoahClient, Config, Environment, AuthConfig};
218 /// use noah_sdk::models::common::SortDirection;
219 ///
220 /// # #[cfg(feature = "async")]
221 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
222 /// let config = Config::new(Environment::Sandbox);
223 /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
224 /// let client = NoahClient::new(config, auth)?;
225 ///
226 /// // Get first page, sorted descending
227 /// let customers = client.get_customers(
228 /// Some(50),
229 /// None,
230 /// Some(&SortDirection::Desc)
231 /// ).await?;
232 /// # Ok(())
233 /// # }
234 /// ```
235 #[cfg(feature = "async")]
236 pub async fn get_customers(
237 &self,
238 page_size: Option<u32>,
239 page_token: Option<&str>,
240 sort_direction: Option<&SortDirection>,
241 ) -> Result<GetCustomersResponse> {
242 let mut path = "/customers".to_string();
243 let mut query_params = Vec::new();
244
245 if let Some(size) = page_size {
246 query_params.push(format!("PageSize={size}"));
247 }
248 if let Some(token) = page_token {
249 query_params.push(format!("PageToken={token}"));
250 }
251 if let Some(sort) = sort_direction {
252 query_params.push(format!("SortDirection={sort:?}"));
253 }
254
255 if !query_params.is_empty() {
256 path.push('?');
257 path.push_str(&query_params.join("&"));
258 }
259
260 self.get(&path).await
261 }
262
263 /// List customers with optional pagination and sorting (blocking)
264 ///
265 /// Synchronous version of [`get_customers`](Self::get_customers). See that method for
266 /// detailed documentation.
267 #[cfg(feature = "sync")]
268 pub fn get_customers_blocking(
269 &self,
270 page_size: Option<u32>,
271 page_token: Option<&str>,
272 sort_direction: Option<&SortDirection>,
273 ) -> Result<GetCustomersResponse> {
274 let mut path = "/customers".to_string();
275 let mut query_params = Vec::new();
276
277 if let Some(size) = page_size {
278 query_params.push(format!("PageSize={size}"));
279 }
280 if let Some(token) = page_token {
281 query_params.push(format!("PageToken={token}"));
282 }
283 if let Some(sort) = sort_direction {
284 query_params.push(format!("SortDirection={sort:?}"));
285 }
286
287 if !query_params.is_empty() {
288 path.push('?');
289 path.push_str(&query_params.join("&"));
290 }
291
292 self.get_blocking(&path)
293 }
294}