Skip to main content

dco3/provisioning/
models.rs

1use std::sync::Arc;
2
3use async_trait::async_trait;
4use chrono::{DateTime, Utc};
5use dco3_derive::FromResponse;
6use reqwest::Response;
7use serde::{Deserialize, Serialize};
8
9use crate::{
10    client::{DracoonClient, DracoonErrorResponse},
11    user::UserAuthData,
12    utils::{parse_body, FromResponse},
13    DracoonClientError, KeyValueEntry, RangedItems,
14};
15
16#[derive(Clone)]
17pub struct ProvisioningEndpoint<S> {
18    client: Arc<DracoonClient<S>>,
19    state: std::marker::PhantomData<S>,
20}
21
22impl<S> ProvisioningEndpoint<S> {
23    pub fn new(client: Arc<DracoonClient<S>>) -> Self {
24        Self {
25            client,
26            state: std::marker::PhantomData,
27        }
28    }
29
30    pub fn client(&self) -> &Arc<DracoonClient<S>> {
31        &self.client
32    }
33}
34
35#[derive(Debug, Serialize, Deserialize, Default, Clone)]
36pub struct CustomerAttributes {
37    pub items: Vec<KeyValueEntry>,
38}
39
40impl CustomerAttributes {
41    pub fn new() -> CustomerAttributes {
42        CustomerAttributes::default()
43    }
44
45    pub fn add_attribute(&mut self, key: impl Into<String>, value: impl Into<String>) {
46        let attrib = KeyValueEntry {
47            key: key.into(),
48            value: value.into(),
49        };
50        self.items.push(attrib);
51    }
52}
53
54pub type AttributesResponse = RangedItems<KeyValueEntry>;
55
56#[derive(Debug, Deserialize, FromResponse, Clone)]
57#[serde(rename_all = "camelCase")]
58pub struct Customer {
59    pub id: u64,
60    pub company_name: String,
61    pub customer_contract_type: String,
62    pub quota_max: u64,
63    pub quota_used: u64,
64    pub user_max: u64,
65    pub user_used: u64,
66    pub created_at: DateTime<Utc>,
67    pub customer_attributes: Option<CustomerAttributes>,
68    pub updated_at: Option<DateTime<Utc>>,
69    pub last_login_at: Option<DateTime<Utc>>,
70    pub trial_days_left: Option<i32>,
71    pub is_locked: Option<bool>,
72    pub customer_uuid: Option<String>,
73    pub cnt_internal_user: Option<u64>,
74    pub cnt_guest_user: Option<u64>,
75}
76
77pub type CustomerList = RangedItems<Customer>;
78
79#[async_trait]
80impl FromResponse for CustomerList {
81    async fn from_response(response: Response) -> Result<Self, DracoonClientError> {
82        parse_body::<Self, DracoonErrorResponse>(response).await
83    }
84}
85
86#[async_trait]
87impl FromResponse for AttributesResponse {
88    async fn from_response(response: Response) -> Result<Self, DracoonClientError> {
89        parse_body::<Self, DracoonErrorResponse>(response).await
90    }
91}
92
93#[derive(Debug, Serialize, Deserialize, Clone)]
94#[serde(rename_all = "camelCase")]
95pub struct FirstAdminUser {
96    pub first_name: String,
97    pub last_name: String,
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub user_name: Option<String>,
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub auth_data: Option<UserAuthData>,
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub receiver_language: Option<String>,
104    pub notify_user: Option<bool>,
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub email: Option<String>,
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub phone: Option<String>,
109}
110
111impl FirstAdminUser {
112    pub fn new_local(
113        first_name: impl Into<String>,
114        last_name: impl Into<String>,
115        user_name: Option<String>,
116        email: impl Into<String>,
117        receiver_language: Option<String>,
118    ) -> FirstAdminUser {
119        let auth_data = UserAuthData::new_basic(None, None);
120
121        FirstAdminUser {
122            first_name: first_name.into(),
123            last_name: last_name.into(),
124            user_name,
125            auth_data: Some(auth_data),
126            receiver_language,
127            notify_user: None,
128            email: Some(email.into()),
129            phone: None,
130        }
131    }
132}
133
134#[derive(Debug, Serialize, Clone)]
135#[serde(rename_all = "camelCase")]
136pub struct NewCustomerRequest {
137    pub customer_contract_type: String,
138    pub quota_max: u64,
139    pub user_max: u64,
140    pub first_admin_user: FirstAdminUser,
141    #[serde(skip_serializing_if = "Option::is_none")]
142    pub company_name: Option<String>,
143    #[serde(skip_serializing_if = "Option::is_none")]
144    pub trial_days: Option<u64>,
145    #[serde(skip_serializing_if = "Option::is_none")]
146    pub is_locked: Option<bool>,
147    #[serde(skip_serializing_if = "Option::is_none")]
148    pub customer_attributes: Option<CustomerAttributes>,
149    #[serde(skip_serializing_if = "Option::is_none")]
150    pub provider_customer_id: Option<String>,
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub webhooks_max: Option<u64>,
153}
154
155impl NewCustomerRequest {
156    pub fn builder(
157        customer_contract_type: impl Into<String>,
158        quota_max: u64,
159        user_max: u64,
160        first_admin_user: FirstAdminUser,
161    ) -> NewCustomerRequestBuilder {
162        NewCustomerRequestBuilder::new(
163            customer_contract_type.into(),
164            quota_max,
165            user_max,
166            first_admin_user,
167        )
168    }
169}
170
171pub struct NewCustomerRequestBuilder {
172    customer_contract_type: String,
173    quota_max: u64,
174    user_max: u64,
175    first_admin_user: FirstAdminUser,
176    company_name: Option<String>,
177    trial_days: Option<u64>,
178    is_locked: Option<bool>,
179    customer_attributes: Option<CustomerAttributes>,
180    provider_customer_id: Option<String>,
181    webhooks_max: Option<u64>,
182}
183
184impl NewCustomerRequestBuilder {
185    pub fn new(
186        customer_contract_type: String,
187        quota_max: u64,
188        user_max: u64,
189        first_admin_user: FirstAdminUser,
190    ) -> NewCustomerRequestBuilder {
191        NewCustomerRequestBuilder {
192            customer_contract_type,
193            quota_max,
194            user_max,
195            first_admin_user,
196            company_name: None,
197            trial_days: None,
198            is_locked: None,
199            customer_attributes: None,
200            provider_customer_id: None,
201            webhooks_max: None,
202        }
203    }
204
205    pub fn with_company_name(
206        mut self,
207        company_name: impl Into<String>,
208    ) -> NewCustomerRequestBuilder {
209        self.company_name = Some(company_name.into());
210        self
211    }
212
213    pub fn with_trial_days(mut self, trial_days: u64) -> NewCustomerRequestBuilder {
214        self.trial_days = Some(trial_days);
215        self
216    }
217
218    pub fn with_is_locked(mut self, is_locked: bool) -> NewCustomerRequestBuilder {
219        self.is_locked = Some(is_locked);
220        self
221    }
222
223    pub fn with_customer_attributes(
224        mut self,
225        customer_attributes: CustomerAttributes,
226    ) -> NewCustomerRequestBuilder {
227        self.customer_attributes = Some(customer_attributes);
228        self
229    }
230
231    pub fn with_provider_customer_id(
232        mut self,
233        provider_customer_id: String,
234    ) -> NewCustomerRequestBuilder {
235        self.provider_customer_id = Some(provider_customer_id);
236        self
237    }
238
239    pub fn with_webhooks_max(mut self, webhooks_max: u64) -> NewCustomerRequestBuilder {
240        self.webhooks_max = Some(webhooks_max);
241        self
242    }
243
244    pub fn build(self) -> NewCustomerRequest {
245        NewCustomerRequest {
246            customer_contract_type: self.customer_contract_type,
247            quota_max: self.quota_max,
248            user_max: self.user_max,
249            first_admin_user: self.first_admin_user,
250            company_name: self.company_name,
251            trial_days: self.trial_days,
252            is_locked: self.is_locked,
253            customer_attributes: self.customer_attributes,
254            provider_customer_id: self.provider_customer_id,
255            webhooks_max: self.webhooks_max,
256        }
257    }
258}
259
260#[derive(Debug, Deserialize, FromResponse, Clone)]
261#[serde(rename_all = "camelCase")]
262pub struct NewCustomerResponse {
263    pub id: u64,
264    pub company_name: String,
265    pub customer_contract_type: String,
266    pub quota_max: u64,
267    pub user_max: u64,
268    pub is_locked: Option<bool>,
269    pub trial_days: Option<u64>,
270    pub created_at: Option<DateTime<Utc>>,
271    pub first_admin_user: FirstAdminUser,
272    pub customer_attributes: Option<CustomerAttributes>,
273    pub provider_customer_id: Option<String>,
274    pub webhooks_max: Option<u64>,
275}
276
277#[derive(Debug, Deserialize, FromResponse, Clone)]
278#[serde(rename_all = "camelCase")]
279pub struct UpdateCustomerResponse {
280    pub id: u64,
281    pub company_name: String,
282    pub customer_contract_type: String,
283    pub quota_max: u64,
284    pub user_max: u64,
285    pub customer_uuid: String,
286    pub is_locked: Option<bool>,
287    pub trial_days: Option<u64>,
288    pub created_at: Option<DateTime<Utc>>,
289    pub updated_at: Option<DateTime<Utc>>,
290    pub customer_attributes: Option<CustomerAttributes>,
291    pub provider_customer_id: Option<String>,
292    pub webhooks_max: Option<u64>,
293}
294
295#[derive(Debug, Serialize, Clone)]
296#[serde(rename_all = "camelCase")]
297pub struct UpdateCustomerRequest {
298    #[serde(skip_serializing_if = "Option::is_none")]
299    company_name: Option<String>,
300    #[serde(skip_serializing_if = "Option::is_none")]
301    customer_contract_type: Option<String>,
302    #[serde(skip_serializing_if = "Option::is_none")]
303    quota_max: Option<u64>,
304    #[serde(skip_serializing_if = "Option::is_none")]
305    user_max: Option<u64>,
306    #[serde(skip_serializing_if = "Option::is_none")]
307    is_locked: Option<bool>,
308    #[serde(skip_serializing_if = "Option::is_none")]
309    provider_customer_id: Option<u64>,
310    #[serde(skip_serializing_if = "Option::is_none")]
311    webhooks_max: Option<u64>,
312}
313
314impl UpdateCustomerRequest {
315    pub fn builder() -> UpdateCustomerRequestBuilder {
316        UpdateCustomerRequestBuilder::new()
317    }
318}
319
320#[derive(Debug, Default)]
321pub struct UpdateCustomerRequestBuilder {
322    company_name: Option<String>,
323    customer_contract_type: Option<String>,
324    quota_max: Option<u64>,
325    user_max: Option<u64>,
326    is_locked: Option<bool>,
327    provider_customer_id: Option<u64>,
328    webhooks_max: Option<u64>,
329}
330
331impl UpdateCustomerRequestBuilder {
332    pub fn new() -> Self {
333        UpdateCustomerRequestBuilder::default()
334    }
335
336    pub fn with_company_name(mut self, company_name: impl Into<String>) -> Self {
337        self.company_name = Some(company_name.into());
338        self
339    }
340
341    pub fn with_customer_contract_type(
342        mut self,
343        customer_contract_type: impl Into<String>,
344    ) -> Self {
345        self.customer_contract_type = Some(customer_contract_type.into());
346        self
347    }
348
349    pub fn with_quota_max(mut self, quota_max: u64) -> Self {
350        self.quota_max = Some(quota_max);
351        self
352    }
353
354    pub fn with_user_max(mut self, user_max: u64) -> Self {
355        self.user_max = Some(user_max);
356        self
357    }
358
359    pub fn with_is_locked(mut self, is_locked: bool) -> Self {
360        self.is_locked = Some(is_locked);
361        self
362    }
363
364    pub fn with_provider_customer_id(mut self, provider_customer_id: u64) -> Self {
365        self.provider_customer_id = Some(provider_customer_id);
366        self
367    }
368
369    pub fn with_webhooks_max(mut self, webhooks_max: u64) -> Self {
370        self.webhooks_max = Some(webhooks_max);
371        self
372    }
373
374    pub fn build(self) -> UpdateCustomerRequest {
375        UpdateCustomerRequest {
376            company_name: self.company_name,
377            customer_contract_type: self.customer_contract_type,
378            quota_max: self.quota_max,
379            user_max: self.user_max,
380            is_locked: self.is_locked,
381            provider_customer_id: self.provider_customer_id,
382            webhooks_max: self.webhooks_max,
383        }
384    }
385}