Skip to main content

wave_api/
client_mutations.rs

1use serde::Deserialize;
2use serde_json::json;
3
4use crate::client::WaveClient;
5use crate::error::WaveError;
6use crate::inputs::*;
7use crate::models::*;
8use crate::mutations::{account, customer, invoice, product, sales_tax, transaction};
9
10// ── Mutation response wrappers ──
11
12#[derive(Deserialize)]
13#[serde(rename_all = "camelCase")]
14struct CustomerMutationResult {
15    customer: Option<Customer>,
16}
17
18#[derive(Deserialize)]
19#[serde(rename_all = "camelCase")]
20struct InvoiceMutationResult {
21    invoice: Option<Invoice>,
22}
23
24#[derive(Deserialize)]
25#[serde(rename_all = "camelCase")]
26struct AccountMutationResult {
27    account: Option<Account>,
28}
29
30#[derive(Deserialize)]
31#[serde(rename_all = "camelCase")]
32struct ProductMutationResult {
33    product: Option<Product>,
34}
35
36#[derive(Deserialize)]
37#[serde(rename_all = "camelCase")]
38struct SalesTaxMutationResult {
39    sales_tax: Option<SalesTax>,
40}
41
42#[derive(Deserialize)]
43#[serde(rename_all = "camelCase")]
44struct TransactionMutationResult {
45    transaction: Option<Transaction>,
46}
47
48#[derive(Deserialize)]
49#[serde(rename_all = "camelCase")]
50struct TransactionsMutationResult {
51    transactions: Option<Vec<Transaction>>,
52}
53
54#[derive(Deserialize)]
55#[serde(rename_all = "camelCase")]
56struct DeleteResult {}
57
58impl WaveClient {
59    // ── Customer Mutations ──
60
61    /// Create a customer.
62    pub async fn create_customer(
63        &self,
64        input: CustomerCreateInput,
65    ) -> Result<Customer, WaveError> {
66        let vars = json!({ "input": input });
67        let result: CustomerMutationResult = self
68            .execute_mutation(customer::CUSTOMER_CREATE, vars, "customerCreate")
69            .await?;
70        result
71            .customer
72            .ok_or_else(|| WaveError::Auth("missing customer in response".into()))
73    }
74
75    /// Patch a customer.
76    pub async fn patch_customer(
77        &self,
78        input: CustomerPatchInput,
79    ) -> Result<Customer, WaveError> {
80        let vars = json!({ "input": input });
81        let result: CustomerMutationResult = self
82            .execute_mutation(customer::CUSTOMER_PATCH, vars, "customerPatch")
83            .await?;
84        result
85            .customer
86            .ok_or_else(|| WaveError::Auth("missing customer in response".into()))
87    }
88
89    /// Delete a customer.
90    pub async fn delete_customer(&self, input: CustomerDeleteInput) -> Result<(), WaveError> {
91        let vars = json!({ "input": input });
92        let _: DeleteResult = self
93            .execute_mutation(customer::CUSTOMER_DELETE, vars, "customerDelete")
94            .await?;
95        Ok(())
96    }
97
98    // ── Invoice Mutations ──
99
100    /// Create an invoice.
101    pub async fn create_invoice(
102        &self,
103        input: InvoiceCreateInput,
104    ) -> Result<Invoice, WaveError> {
105        let vars = json!({ "input": input });
106        let result: InvoiceMutationResult = self
107            .execute_mutation(invoice::INVOICE_CREATE, vars, "invoiceCreate")
108            .await?;
109        result
110            .invoice
111            .ok_or_else(|| WaveError::Auth("missing invoice in response".into()))
112    }
113
114    /// Patch an invoice.
115    pub async fn patch_invoice(
116        &self,
117        input: InvoicePatchInput,
118    ) -> Result<Invoice, WaveError> {
119        let vars = json!({ "input": input });
120        let result: InvoiceMutationResult = self
121            .execute_mutation(invoice::INVOICE_PATCH, vars, "invoicePatch")
122            .await?;
123        result
124            .invoice
125            .ok_or_else(|| WaveError::Auth("missing invoice in response".into()))
126    }
127
128    /// Delete an invoice.
129    pub async fn delete_invoice(&self, invoice_id: &str) -> Result<(), WaveError> {
130        let vars = json!({ "input": { "invoiceId": invoice_id } });
131        let _: DeleteResult = self
132            .execute_mutation(invoice::INVOICE_DELETE, vars, "invoiceDelete")
133            .await?;
134        Ok(())
135    }
136
137    /// Clone an invoice.
138    pub async fn clone_invoice(&self, invoice_id: &str) -> Result<Invoice, WaveError> {
139        let vars = json!({ "input": { "invoiceId": invoice_id } });
140        let result: InvoiceMutationResult = self
141            .execute_mutation(invoice::INVOICE_CLONE, vars, "invoiceClone")
142            .await?;
143        result
144            .invoice
145            .ok_or_else(|| WaveError::Auth("missing invoice in response".into()))
146    }
147
148    /// Approve an invoice.
149    pub async fn approve_invoice(&self, invoice_id: &str) -> Result<Invoice, WaveError> {
150        let vars = json!({ "input": { "invoiceId": invoice_id } });
151        let result: InvoiceMutationResult = self
152            .execute_mutation(invoice::INVOICE_APPROVE, vars, "invoiceApprove")
153            .await?;
154        result
155            .invoice
156            .ok_or_else(|| WaveError::Auth("missing invoice in response".into()))
157    }
158
159    /// Mark an invoice as sent.
160    pub async fn mark_invoice_sent(
161        &self,
162        input: InvoiceMarkSentInput,
163    ) -> Result<Invoice, WaveError> {
164        let vars = json!({ "input": input });
165        let result: InvoiceMutationResult = self
166            .execute_mutation(invoice::INVOICE_MARK_SENT, vars, "invoiceMarkSent")
167            .await?;
168        result
169            .invoice
170            .ok_or_else(|| WaveError::Auth("missing invoice in response".into()))
171    }
172
173    /// Send an invoice via email.
174    pub async fn send_invoice(
175        &self,
176        input: InvoiceSendInput,
177    ) -> Result<Invoice, WaveError> {
178        let vars = json!({ "input": input });
179        let result: InvoiceMutationResult = self
180            .execute_mutation(invoice::INVOICE_SEND, vars, "invoiceSend")
181            .await?;
182        result
183            .invoice
184            .ok_or_else(|| WaveError::Auth("missing invoice in response".into()))
185    }
186
187    // ── Account Mutations ──
188
189    /// Create an account.
190    pub async fn create_account(
191        &self,
192        input: AccountCreateInput,
193    ) -> Result<Account, WaveError> {
194        let vars = json!({ "input": input });
195        let result: AccountMutationResult = self
196            .execute_mutation(account::ACCOUNT_CREATE, vars, "accountCreate")
197            .await?;
198        result
199            .account
200            .ok_or_else(|| WaveError::Auth("missing account in response".into()))
201    }
202
203    /// Patch an account.
204    pub async fn patch_account(
205        &self,
206        input: AccountPatchInput,
207    ) -> Result<Account, WaveError> {
208        let vars = json!({ "input": input });
209        let result: AccountMutationResult = self
210            .execute_mutation(account::ACCOUNT_PATCH, vars, "accountPatch")
211            .await?;
212        result
213            .account
214            .ok_or_else(|| WaveError::Auth("missing account in response".into()))
215    }
216
217    /// Archive an account.
218    pub async fn archive_account(&self, input: AccountArchiveInput) -> Result<(), WaveError> {
219        let vars = json!({ "input": input });
220        let _: DeleteResult = self
221            .execute_mutation(account::ACCOUNT_ARCHIVE, vars, "accountArchive")
222            .await?;
223        Ok(())
224    }
225
226    // ── Product Mutations ──
227
228    /// Create a product.
229    pub async fn create_product(
230        &self,
231        input: ProductCreateInput,
232    ) -> Result<Product, WaveError> {
233        let vars = json!({ "input": input });
234        let result: ProductMutationResult = self
235            .execute_mutation(product::PRODUCT_CREATE, vars, "productCreate")
236            .await?;
237        result
238            .product
239            .ok_or_else(|| WaveError::Auth("missing product in response".into()))
240    }
241
242    /// Patch a product.
243    pub async fn patch_product(
244        &self,
245        input: ProductPatchInput,
246    ) -> Result<Product, WaveError> {
247        let vars = json!({ "input": input });
248        let result: ProductMutationResult = self
249            .execute_mutation(product::PRODUCT_PATCH, vars, "productPatch")
250            .await?;
251        result
252            .product
253            .ok_or_else(|| WaveError::Auth("missing product in response".into()))
254    }
255
256    /// Archive a product.
257    pub async fn archive_product(&self, input: ProductArchiveInput) -> Result<(), WaveError> {
258        let vars = json!({ "input": input });
259        let _: DeleteResult = self
260            .execute_mutation(product::PRODUCT_ARCHIVE, vars, "productArchive")
261            .await?;
262        Ok(())
263    }
264
265    // ── Sales Tax Mutations ──
266
267    /// Create a sales tax.
268    pub async fn create_sales_tax(
269        &self,
270        input: SalesTaxCreateInput,
271    ) -> Result<SalesTax, WaveError> {
272        let vars = json!({ "input": input });
273        let result: SalesTaxMutationResult = self
274            .execute_mutation(sales_tax::SALES_TAX_CREATE, vars, "salesTaxCreate")
275            .await?;
276        result
277            .sales_tax
278            .ok_or_else(|| WaveError::Auth("missing salesTax in response".into()))
279    }
280
281    /// Patch a sales tax.
282    pub async fn patch_sales_tax(
283        &self,
284        input: SalesTaxPatchInput,
285    ) -> Result<SalesTax, WaveError> {
286        let vars = json!({ "input": input });
287        let result: SalesTaxMutationResult = self
288            .execute_mutation(sales_tax::SALES_TAX_PATCH, vars, "salesTaxPatch")
289            .await?;
290        result
291            .sales_tax
292            .ok_or_else(|| WaveError::Auth("missing salesTax in response".into()))
293    }
294
295    /// Archive a sales tax.
296    pub async fn archive_sales_tax(
297        &self,
298        input: SalesTaxArchiveInput,
299    ) -> Result<(), WaveError> {
300        let vars = json!({ "input": input });
301        let _: DeleteResult = self
302            .execute_mutation(sales_tax::SALES_TAX_ARCHIVE, vars, "salesTaxArchive")
303            .await?;
304        Ok(())
305    }
306
307    // ── Transaction Mutations ──
308
309    /// Create a single money transaction.
310    pub async fn create_money_transaction(
311        &self,
312        input: MoneyTransactionCreateInput,
313    ) -> Result<Transaction, WaveError> {
314        let vars = json!({ "input": input });
315        let result: TransactionMutationResult = self
316            .execute_mutation(
317                transaction::MONEY_TRANSACTION_CREATE,
318                vars,
319                "moneyTransactionCreate",
320            )
321            .await?;
322        result
323            .transaction
324            .ok_or_else(|| WaveError::Auth("missing transaction in response".into()))
325    }
326
327    /// Bulk create money transactions.
328    pub async fn create_money_transactions(
329        &self,
330        input: MoneyTransactionsCreateInput,
331    ) -> Result<Vec<Transaction>, WaveError> {
332        let vars = json!({ "input": input });
333        let result: TransactionsMutationResult = self
334            .execute_mutation(
335                transaction::MONEY_TRANSACTIONS_CREATE,
336                vars,
337                "moneyTransactionsCreate",
338            )
339            .await?;
340        Ok(result.transactions.unwrap_or_default())
341    }
342}