Skip to main content

wave_api/
client_queries.rs

1use serde_json::{json, Map, Value};
2
3use crate::client::WaveClient;
4use crate::error::WaveError;
5use crate::models::*;
6use crate::options::*;
7use crate::pagination::{Connection, Page};
8use crate::queries::{account, business, constants, customer, invoice, product, sales_tax, user, vendor};
9
10/// Insert a key into a JSON object only if the value is not None.
11fn insert_opt<T: serde::Serialize>(map: &mut Map<String, Value>, key: &str, val: &Option<T>) {
12    if let Some(v) = val {
13        if let Ok(json_val) = serde_json::to_value(v) {
14            map.insert(key.to_string(), json_val);
15        }
16    }
17}
18
19impl WaveClient {
20    // ── User ──
21
22    /// Get the currently authenticated user.
23    pub async fn get_user(&self) -> Result<User, WaveError> {
24        let data = self.execute(user::GET_USER, json!({})).await?;
25        let user: User = serde_json::from_value(data["user"].clone())?;
26        Ok(user)
27    }
28
29    // ── Businesses ──
30
31    /// List all businesses accessible to the authenticated user.
32    pub async fn list_businesses(
33        &self,
34        opts: ListBusinessesOptions,
35    ) -> Result<Page<Business>, WaveError> {
36        let mut vars = Map::new();
37        insert_opt(&mut vars, "page", &opts.page);
38        insert_opt(&mut vars, "pageSize", &opts.page_size);
39        let data = self.execute(business::LIST_BUSINESSES, Value::Object(vars)).await?;
40        let conn: Connection<Business> = serde_json::from_value(data["businesses"].clone())?;
41        Ok(conn.into_page())
42    }
43
44    /// Get a single business by ID.
45    pub async fn get_business(&self, id: &str) -> Result<Business, WaveError> {
46        let data = self
47            .execute(business::GET_BUSINESS, json!({ "id": id }))
48            .await?;
49        let biz: Business = serde_json::from_value(data["business"].clone())?;
50        Ok(biz)
51    }
52
53    // ── Customers ──
54
55    /// List customers for a business.
56    pub async fn list_customers(
57        &self,
58        business_id: &str,
59        opts: ListCustomersOptions,
60    ) -> Result<Page<Customer>, WaveError> {
61        let sort = if opts.sort.is_empty() {
62            vec![serde_json::to_value(crate::enums::CustomerSort::NameAsc)?]
63        } else {
64            opts.sort
65                .iter()
66                .map(serde_json::to_value)
67                .collect::<Result<Vec<_>, _>>()?
68        };
69        let mut vars = Map::new();
70        vars.insert("businessId".into(), json!(business_id));
71        vars.insert("sort".into(), json!(sort));
72        insert_opt(&mut vars, "page", &opts.page);
73        insert_opt(&mut vars, "pageSize", &opts.page_size);
74        insert_opt(&mut vars, "email", &opts.email);
75        let data = self.execute(customer::LIST_CUSTOMERS, Value::Object(vars)).await?;
76        let conn: Connection<Customer> =
77            serde_json::from_value(data["business"]["customers"].clone())?;
78        Ok(conn.into_page())
79    }
80
81    /// Get a single customer by ID.
82    pub async fn get_customer(
83        &self,
84        business_id: &str,
85        customer_id: &str,
86    ) -> Result<Customer, WaveError> {
87        let vars = json!({
88            "businessId": business_id,
89            "customerId": customer_id,
90        });
91        let data = self.execute(customer::GET_CUSTOMER, vars).await?;
92        let cust: Customer = serde_json::from_value(data["business"]["customer"].clone())?;
93        Ok(cust)
94    }
95
96    // ── Invoices ──
97
98    /// List invoices for a business.
99    pub async fn list_invoices(
100        &self,
101        business_id: &str,
102        opts: ListInvoicesOptions,
103    ) -> Result<Page<Invoice>, WaveError> {
104        let sort = if opts.sort.is_empty() {
105            vec![serde_json::to_value(crate::enums::InvoiceSort::CreatedAtDesc)?]
106        } else {
107            opts.sort
108                .iter()
109                .map(serde_json::to_value)
110                .collect::<Result<Vec<_>, _>>()?
111        };
112        let mut vars = Map::new();
113        vars.insert("businessId".into(), json!(business_id));
114        vars.insert("sort".into(), json!(sort));
115        insert_opt(&mut vars, "page", &opts.page);
116        insert_opt(&mut vars, "pageSize", &opts.page_size);
117        insert_opt(&mut vars, "status", &opts.status);
118        insert_opt(&mut vars, "customerId", &opts.customer_id);
119        insert_opt(&mut vars, "currency", &opts.currency);
120        insert_opt(&mut vars, "invoiceDateStart", &opts.invoice_date_start);
121        insert_opt(&mut vars, "invoiceDateEnd", &opts.invoice_date_end);
122        insert_opt(&mut vars, "invoiceNumber", &opts.invoice_number);
123        let data = self.execute(invoice::LIST_INVOICES, Value::Object(vars)).await?;
124        let conn: Connection<Invoice> =
125            serde_json::from_value(data["business"]["invoices"].clone())?;
126        Ok(conn.into_page())
127    }
128
129    /// Get a single invoice by ID.
130    pub async fn get_invoice(
131        &self,
132        business_id: &str,
133        invoice_id: &str,
134    ) -> Result<Invoice, WaveError> {
135        let vars = json!({
136            "businessId": business_id,
137            "invoiceId": invoice_id,
138        });
139        let data = self.execute(invoice::GET_INVOICE, vars).await?;
140        let inv: Invoice = serde_json::from_value(data["business"]["invoice"].clone())?;
141        Ok(inv)
142    }
143
144    // ── Accounts ──
145
146    /// List accounts (Chart of Accounts) for a business.
147    pub async fn list_accounts(
148        &self,
149        business_id: &str,
150        opts: ListAccountsOptions,
151    ) -> Result<Page<Account>, WaveError> {
152        let mut vars = Map::new();
153        vars.insert("businessId".into(), json!(business_id));
154        insert_opt(&mut vars, "page", &opts.page);
155        insert_opt(&mut vars, "pageSize", &opts.page_size);
156        insert_opt(&mut vars, "types", &opts.types);
157        insert_opt(&mut vars, "subtypes", &opts.subtypes);
158        insert_opt(&mut vars, "isArchived", &opts.is_archived);
159        let data = self.execute(account::LIST_ACCOUNTS, Value::Object(vars)).await?;
160        let conn: Connection<Account> =
161            serde_json::from_value(data["business"]["accounts"].clone())?;
162        Ok(conn.into_page())
163    }
164
165    /// Get a single account by ID.
166    pub async fn get_account(
167        &self,
168        business_id: &str,
169        account_id: &str,
170    ) -> Result<Account, WaveError> {
171        let vars = json!({
172            "businessId": business_id,
173            "accountId": account_id,
174        });
175        let data = self.execute(account::GET_ACCOUNT, vars).await?;
176        let acct: Account = serde_json::from_value(data["business"]["account"].clone())?;
177        Ok(acct)
178    }
179
180    // ── Products ──
181
182    /// List products for a business.
183    pub async fn list_products(
184        &self,
185        business_id: &str,
186        opts: ListProductsOptions,
187    ) -> Result<Page<Product>, WaveError> {
188        let sort = if opts.sort.is_empty() {
189            vec![serde_json::to_value(crate::enums::ProductSort::NameAsc)?]
190        } else {
191            opts.sort
192                .iter()
193                .map(serde_json::to_value)
194                .collect::<Result<Vec<_>, _>>()?
195        };
196        let mut vars = Map::new();
197        vars.insert("businessId".into(), json!(business_id));
198        vars.insert("sort".into(), json!(sort));
199        insert_opt(&mut vars, "page", &opts.page);
200        insert_opt(&mut vars, "pageSize", &opts.page_size);
201        insert_opt(&mut vars, "isSold", &opts.is_sold);
202        insert_opt(&mut vars, "isBought", &opts.is_bought);
203        insert_opt(&mut vars, "isArchived", &opts.is_archived);
204        let data = self.execute(product::LIST_PRODUCTS, Value::Object(vars)).await?;
205        let conn: Connection<Product> =
206            serde_json::from_value(data["business"]["products"].clone())?;
207        Ok(conn.into_page())
208    }
209
210    /// Get a single product by ID.
211    pub async fn get_product(
212        &self,
213        business_id: &str,
214        product_id: &str,
215    ) -> Result<Product, WaveError> {
216        let vars = json!({
217            "businessId": business_id,
218            "productId": product_id,
219        });
220        let data = self.execute(product::GET_PRODUCT, vars).await?;
221        let prod: Product = serde_json::from_value(data["business"]["product"].clone())?;
222        Ok(prod)
223    }
224
225    // ── Vendors ──
226
227    /// List vendors for a business.
228    pub async fn list_vendors(
229        &self,
230        business_id: &str,
231        opts: ListVendorsOptions,
232    ) -> Result<Page<Vendor>, WaveError> {
233        let mut vars = Map::new();
234        vars.insert("businessId".into(), json!(business_id));
235        insert_opt(&mut vars, "page", &opts.page);
236        insert_opt(&mut vars, "pageSize", &opts.page_size);
237        insert_opt(&mut vars, "email", &opts.email);
238        let data = self.execute(vendor::LIST_VENDORS, Value::Object(vars)).await?;
239        let conn: Connection<Vendor> =
240            serde_json::from_value(data["business"]["vendors"].clone())?;
241        Ok(conn.into_page())
242    }
243
244    /// Get a single vendor by ID.
245    pub async fn get_vendor(
246        &self,
247        business_id: &str,
248        vendor_id: &str,
249    ) -> Result<Vendor, WaveError> {
250        let vars = json!({
251            "businessId": business_id,
252            "vendorId": vendor_id,
253        });
254        let data = self.execute(vendor::GET_VENDOR, vars).await?;
255        let v: Vendor = serde_json::from_value(data["business"]["vendor"].clone())?;
256        Ok(v)
257    }
258
259    // ── Sales Taxes ──
260
261    /// List sales taxes for a business.
262    pub async fn list_sales_taxes(
263        &self,
264        business_id: &str,
265        opts: ListSalesTaxesOptions,
266    ) -> Result<Page<SalesTax>, WaveError> {
267        let mut vars = Map::new();
268        vars.insert("businessId".into(), json!(business_id));
269        insert_opt(&mut vars, "page", &opts.page);
270        insert_opt(&mut vars, "pageSize", &opts.page_size);
271        insert_opt(&mut vars, "isArchived", &opts.is_archived);
272        let data = self.execute(sales_tax::LIST_SALES_TAXES, Value::Object(vars)).await?;
273        let conn: Connection<SalesTax> =
274            serde_json::from_value(data["business"]["salesTaxes"].clone())?;
275        Ok(conn.into_page())
276    }
277
278    /// Get a single sales tax by ID.
279    pub async fn get_sales_tax(
280        &self,
281        business_id: &str,
282        sales_tax_id: &str,
283    ) -> Result<SalesTax, WaveError> {
284        let vars = json!({
285            "businessId": business_id,
286            "salesTaxId": sales_tax_id,
287        });
288        let data = self.execute(sales_tax::GET_SALES_TAX, vars).await?;
289        let st: SalesTax = serde_json::from_value(data["business"]["salesTax"].clone())?;
290        Ok(st)
291    }
292
293    // ── Constants ──
294
295    /// List all currencies.
296    pub async fn list_currencies(&self) -> Result<Vec<Currency>, WaveError> {
297        let data = self.execute(constants::LIST_CURRENCIES, json!({})).await?;
298        let currencies: Vec<Currency> = serde_json::from_value(data["currencies"].clone())?;
299        Ok(currencies)
300    }
301
302    /// List all countries.
303    pub async fn list_countries(&self) -> Result<Vec<Country>, WaveError> {
304        let data = self.execute(constants::LIST_COUNTRIES, json!({})).await?;
305        let countries: Vec<Country> = serde_json::from_value(data["countries"].clone())?;
306        Ok(countries)
307    }
308
309    /// List account types.
310    pub async fn list_account_types(&self) -> Result<Vec<AccountType>, WaveError> {
311        let data = self
312            .execute(constants::LIST_ACCOUNT_TYPES, json!({}))
313            .await?;
314        let types: Vec<AccountType> = serde_json::from_value(data["accountTypes"].clone())?;
315        Ok(types)
316    }
317
318    /// List account subtypes.
319    pub async fn list_account_subtypes(&self) -> Result<Vec<AccountSubtype>, WaveError> {
320        let data = self
321            .execute(constants::LIST_ACCOUNT_SUBTYPES, json!({}))
322            .await?;
323        let subtypes: Vec<AccountSubtype> =
324            serde_json::from_value(data["accountSubtypes"].clone())?;
325        Ok(subtypes)
326    }
327}