1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
// Copyright Materialize, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License in the LICENSE file at the
// root of this repository, or online at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use futures_core::Stream;
use reqwest::Method;
use serde::{Deserialize, Serialize};
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"];
/// An Orb invoice.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct Invoice {
    /// The Orb-assigned unique identifier for the invoice.
    pub id: String,
    /// The customer to whom this invoice was issued.
    pub customer: InvoiceCustomer,
    /// The subscription associated with this invoice.
    pub subscription: InvoiceSubscription,
    /// The issue date of the invoice.
    #[serde(with = "time::serde::rfc3339")]
    pub invoice_date: OffsetDateTime,
    /// The link to download the PDF representation of the invoice.
    pub invoice_pdf: String,
    /// The total after any minimums, discounts, and taxes have been applied.
    pub total: String,
    /// The time at which the invoice was created.
    #[serde(with = "time::serde::rfc3339")]
    pub created_at: OffsetDateTime,
    // TODO: many missing fields.
}
/// Identifies the customer associated with an [`Invoice`].
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct InvoiceCustomer {
    /// The Orb-assigned unique identifier for the customer.
    pub id: String,
    /// The external identifier for the customer, if any.
    #[serde(rename = "external_customer_id")]
    pub external_id: Option<String>,
}
/// Identifies the subscription associated with an [`Invoice`].
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct InvoiceSubscription {
    /// The Orb-assigned unique identifier for the subscription.
    pub id: String,
}
/// Parameters for a subscription list operation.
#[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> {
    /// The default invoice list parameters.
    ///
    /// Exposed as a constant for use in constant evaluation contexts.
    pub const DEFAULT: InvoiceListParams<'static> = InvoiceListParams {
        inner: ListParams::DEFAULT,
        customer_filter: None,
        subscription_filter: None,
    };
    /// Sets the page size for the list operation.
    ///
    /// See [`ListParams::page_size`].
    pub const fn page_size(mut self, page_size: u64) -> Self {
        self.inner = self.inner.page_size(page_size);
        self
    }
    /// Filters the listing to the specified customer ID.
    pub const fn customer_id(mut self, filter: CustomerId<'a>) -> Self {
        self.customer_filter = Some(filter);
        self
    }
    /// Filters the listing to the specified subscription ID.
    pub const fn subscription_id(mut self, filter: &'a str) -> Self {
        self.subscription_filter = Some(filter);
        self
    }
}
impl Client {
    /// Lists invoices as configured by `params`.
    ///
    /// The underlying API call is paginated. The returned stream will fetch
    /// additional pages as it is consumed.
    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)
    }
    /// Gets an invoice by ID.
    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)
    }
    // TODO: get upcoming invoice.
    // TODO: void invoice.
}