use futures_core::Stream;
use reqwest::Method;
use serde::Deserialize;
use time::OffsetDateTime;
use crate::client::customers::CustomerId;
use crate::client::Client;
use crate::config::ListParams;
use crate::error::Error;
use crate::util::StrIteratorExt;
const INVOICES: [&str; 1] = ["invoices"];
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
pub struct Invoice {
pub id: String,
pub customer: InvoiceCustomer,
pub subscription: InvoiceSubscription,
#[serde(with = "time::serde::rfc3339")]
pub invoice_date: OffsetDateTime,
pub invoice_pdf: String,
pub total: String,
#[serde(with = "time::serde::rfc3339")]
pub created_at: OffsetDateTime,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
pub struct InvoiceCustomer {
pub id: String,
#[serde(rename = "external_customer_id")]
pub external_id: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
pub struct InvoiceSubscription {
pub id: String,
}
#[derive(Debug, Clone)]
pub struct InvoiceListParams<'a> {
inner: ListParams,
customer_filter: Option<CustomerId<'a>>,
subscription_filter: Option<&'a str>,
}
impl<'a> Default for InvoiceListParams<'a> {
fn default() -> InvoiceListParams<'a> {
InvoiceListParams::DEFAULT
}
}
impl<'a> InvoiceListParams<'a> {
pub const DEFAULT: InvoiceListParams<'static> = InvoiceListParams {
inner: ListParams::DEFAULT,
customer_filter: None,
subscription_filter: None,
};
pub const fn page_size(mut self, page_size: u64) -> Self {
self.inner = self.inner.page_size(page_size);
self
}
pub const fn customer_id(mut self, filter: CustomerId<'a>) -> Self {
self.customer_filter = Some(filter);
self
}
pub const fn subscription_id(mut self, filter: &'a str) -> Self {
self.subscription_filter = Some(filter);
self
}
}
impl Client {
pub fn list_invoices(
&self,
params: &InvoiceListParams,
) -> impl Stream<Item = Result<Invoice, Error>> + '_ {
let req = self.build_request(Method::GET, INVOICES);
let req = match params.customer_filter {
None => req,
Some(CustomerId::Orb(id)) => req.query(&[("customer_id", id)]),
Some(CustomerId::External(id)) => req.query(&[("external_customer_id", id)]),
};
let req = match params.subscription_filter {
None => req,
Some(id) => req.query(&[("subscription_id", id)]),
};
self.stream_paginated_request(¶ms.inner, req)
}
pub async fn get_invoice(&self, id: &str) -> Result<Invoice, Error> {
let req = self.build_request(Method::GET, INVOICES.chain_one(id));
let res = self.send_request(req).await?;
Ok(res)
}
}