use serde_json::{json, Map, Value};
use crate::client::WaveClient;
use crate::error::WaveError;
use crate::models::*;
use crate::options::*;
use crate::pagination::{Connection, Page};
use crate::queries::{account, business, constants, customer, invoice, product, sales_tax, user, vendor};
fn insert_opt<T: serde::Serialize>(map: &mut Map<String, Value>, key: &str, val: &Option<T>) {
if let Some(v) = val {
if let Ok(json_val) = serde_json::to_value(v) {
map.insert(key.to_string(), json_val);
}
}
}
impl WaveClient {
pub async fn get_user(&self) -> Result<User, WaveError> {
let data = self.execute(user::GET_USER, json!({})).await?;
let user: User = serde_json::from_value(data["user"].clone())?;
Ok(user)
}
pub async fn list_businesses(
&self,
opts: ListBusinessesOptions,
) -> Result<Page<Business>, WaveError> {
let mut vars = Map::new();
insert_opt(&mut vars, "page", &opts.page);
insert_opt(&mut vars, "pageSize", &opts.page_size);
let data = self.execute(business::LIST_BUSINESSES, Value::Object(vars)).await?;
let conn: Connection<Business> = serde_json::from_value(data["businesses"].clone())?;
Ok(conn.into_page())
}
pub async fn get_business(&self, id: &str) -> Result<Business, WaveError> {
let data = self
.execute(business::GET_BUSINESS, json!({ "id": id }))
.await?;
let biz: Business = serde_json::from_value(data["business"].clone())?;
Ok(biz)
}
pub async fn list_customers(
&self,
business_id: &str,
opts: ListCustomersOptions,
) -> Result<Page<Customer>, WaveError> {
let sort = if opts.sort.is_empty() {
vec![serde_json::to_value(crate::enums::CustomerSort::NameAsc)?]
} else {
opts.sort
.iter()
.map(serde_json::to_value)
.collect::<Result<Vec<_>, _>>()?
};
let mut vars = Map::new();
vars.insert("businessId".into(), json!(business_id));
vars.insert("sort".into(), json!(sort));
insert_opt(&mut vars, "page", &opts.page);
insert_opt(&mut vars, "pageSize", &opts.page_size);
insert_opt(&mut vars, "email", &opts.email);
let data = self.execute(customer::LIST_CUSTOMERS, Value::Object(vars)).await?;
let conn: Connection<Customer> =
serde_json::from_value(data["business"]["customers"].clone())?;
Ok(conn.into_page())
}
pub async fn get_customer(
&self,
business_id: &str,
customer_id: &str,
) -> Result<Customer, WaveError> {
let vars = json!({
"businessId": business_id,
"customerId": customer_id,
});
let data = self.execute(customer::GET_CUSTOMER, vars).await?;
let cust: Customer = serde_json::from_value(data["business"]["customer"].clone())?;
Ok(cust)
}
pub async fn list_invoices(
&self,
business_id: &str,
opts: ListInvoicesOptions,
) -> Result<Page<Invoice>, WaveError> {
let sort = if opts.sort.is_empty() {
vec![serde_json::to_value(crate::enums::InvoiceSort::CreatedAtDesc)?]
} else {
opts.sort
.iter()
.map(serde_json::to_value)
.collect::<Result<Vec<_>, _>>()?
};
let mut vars = Map::new();
vars.insert("businessId".into(), json!(business_id));
vars.insert("sort".into(), json!(sort));
insert_opt(&mut vars, "page", &opts.page);
insert_opt(&mut vars, "pageSize", &opts.page_size);
insert_opt(&mut vars, "status", &opts.status);
insert_opt(&mut vars, "customerId", &opts.customer_id);
insert_opt(&mut vars, "currency", &opts.currency);
insert_opt(&mut vars, "invoiceDateStart", &opts.invoice_date_start);
insert_opt(&mut vars, "invoiceDateEnd", &opts.invoice_date_end);
insert_opt(&mut vars, "invoiceNumber", &opts.invoice_number);
let data = self.execute(invoice::LIST_INVOICES, Value::Object(vars)).await?;
let conn: Connection<Invoice> =
serde_json::from_value(data["business"]["invoices"].clone())?;
Ok(conn.into_page())
}
pub async fn get_invoice(
&self,
business_id: &str,
invoice_id: &str,
) -> Result<Invoice, WaveError> {
let vars = json!({
"businessId": business_id,
"invoiceId": invoice_id,
});
let data = self.execute(invoice::GET_INVOICE, vars).await?;
let inv: Invoice = serde_json::from_value(data["business"]["invoice"].clone())?;
Ok(inv)
}
pub async fn list_accounts(
&self,
business_id: &str,
opts: ListAccountsOptions,
) -> Result<Page<Account>, WaveError> {
let mut vars = Map::new();
vars.insert("businessId".into(), json!(business_id));
insert_opt(&mut vars, "page", &opts.page);
insert_opt(&mut vars, "pageSize", &opts.page_size);
insert_opt(&mut vars, "types", &opts.types);
insert_opt(&mut vars, "subtypes", &opts.subtypes);
insert_opt(&mut vars, "isArchived", &opts.is_archived);
let data = self.execute(account::LIST_ACCOUNTS, Value::Object(vars)).await?;
let conn: Connection<Account> =
serde_json::from_value(data["business"]["accounts"].clone())?;
Ok(conn.into_page())
}
pub async fn get_account(
&self,
business_id: &str,
account_id: &str,
) -> Result<Account, WaveError> {
let vars = json!({
"businessId": business_id,
"accountId": account_id,
});
let data = self.execute(account::GET_ACCOUNT, vars).await?;
let acct: Account = serde_json::from_value(data["business"]["account"].clone())?;
Ok(acct)
}
pub async fn list_products(
&self,
business_id: &str,
opts: ListProductsOptions,
) -> Result<Page<Product>, WaveError> {
let sort = if opts.sort.is_empty() {
vec![serde_json::to_value(crate::enums::ProductSort::NameAsc)?]
} else {
opts.sort
.iter()
.map(serde_json::to_value)
.collect::<Result<Vec<_>, _>>()?
};
let mut vars = Map::new();
vars.insert("businessId".into(), json!(business_id));
vars.insert("sort".into(), json!(sort));
insert_opt(&mut vars, "page", &opts.page);
insert_opt(&mut vars, "pageSize", &opts.page_size);
insert_opt(&mut vars, "isSold", &opts.is_sold);
insert_opt(&mut vars, "isBought", &opts.is_bought);
insert_opt(&mut vars, "isArchived", &opts.is_archived);
let data = self.execute(product::LIST_PRODUCTS, Value::Object(vars)).await?;
let conn: Connection<Product> =
serde_json::from_value(data["business"]["products"].clone())?;
Ok(conn.into_page())
}
pub async fn get_product(
&self,
business_id: &str,
product_id: &str,
) -> Result<Product, WaveError> {
let vars = json!({
"businessId": business_id,
"productId": product_id,
});
let data = self.execute(product::GET_PRODUCT, vars).await?;
let prod: Product = serde_json::from_value(data["business"]["product"].clone())?;
Ok(prod)
}
pub async fn list_vendors(
&self,
business_id: &str,
opts: ListVendorsOptions,
) -> Result<Page<Vendor>, WaveError> {
let mut vars = Map::new();
vars.insert("businessId".into(), json!(business_id));
insert_opt(&mut vars, "page", &opts.page);
insert_opt(&mut vars, "pageSize", &opts.page_size);
insert_opt(&mut vars, "email", &opts.email);
let data = self.execute(vendor::LIST_VENDORS, Value::Object(vars)).await?;
let conn: Connection<Vendor> =
serde_json::from_value(data["business"]["vendors"].clone())?;
Ok(conn.into_page())
}
pub async fn get_vendor(
&self,
business_id: &str,
vendor_id: &str,
) -> Result<Vendor, WaveError> {
let vars = json!({
"businessId": business_id,
"vendorId": vendor_id,
});
let data = self.execute(vendor::GET_VENDOR, vars).await?;
let v: Vendor = serde_json::from_value(data["business"]["vendor"].clone())?;
Ok(v)
}
pub async fn list_sales_taxes(
&self,
business_id: &str,
opts: ListSalesTaxesOptions,
) -> Result<Page<SalesTax>, WaveError> {
let mut vars = Map::new();
vars.insert("businessId".into(), json!(business_id));
insert_opt(&mut vars, "page", &opts.page);
insert_opt(&mut vars, "pageSize", &opts.page_size);
insert_opt(&mut vars, "isArchived", &opts.is_archived);
let data = self.execute(sales_tax::LIST_SALES_TAXES, Value::Object(vars)).await?;
let conn: Connection<SalesTax> =
serde_json::from_value(data["business"]["salesTaxes"].clone())?;
Ok(conn.into_page())
}
pub async fn get_sales_tax(
&self,
business_id: &str,
sales_tax_id: &str,
) -> Result<SalesTax, WaveError> {
let vars = json!({
"businessId": business_id,
"salesTaxId": sales_tax_id,
});
let data = self.execute(sales_tax::GET_SALES_TAX, vars).await?;
let st: SalesTax = serde_json::from_value(data["business"]["salesTax"].clone())?;
Ok(st)
}
pub async fn list_currencies(&self) -> Result<Vec<Currency>, WaveError> {
let data = self.execute(constants::LIST_CURRENCIES, json!({})).await?;
let currencies: Vec<Currency> = serde_json::from_value(data["currencies"].clone())?;
Ok(currencies)
}
pub async fn list_countries(&self) -> Result<Vec<Country>, WaveError> {
let data = self.execute(constants::LIST_COUNTRIES, json!({})).await?;
let countries: Vec<Country> = serde_json::from_value(data["countries"].clone())?;
Ok(countries)
}
pub async fn list_account_types(&self) -> Result<Vec<AccountType>, WaveError> {
let data = self
.execute(constants::LIST_ACCOUNT_TYPES, json!({}))
.await?;
let types: Vec<AccountType> = serde_json::from_value(data["accountTypes"].clone())?;
Ok(types)
}
pub async fn list_account_subtypes(&self) -> Result<Vec<AccountSubtype>, WaveError> {
let data = self
.execute(constants::LIST_ACCOUNT_SUBTYPES, json!({}))
.await?;
let subtypes: Vec<AccountSubtype> =
serde_json::from_value(data["accountSubtypes"].clone())?;
Ok(subtypes)
}
}