paddle_rust_sdk/
reports.rs

1//! Request builders for creating and listing reports.
2//!
3//! See the [Paddle API](https://developer.paddle.com/api-reference/reports/overview) documentation for more information.
4
5use reqwest::Method;
6use serde::de::DeserializeOwned;
7use serde::Serialize;
8use serde_with::skip_serializing_none;
9
10use crate::entities::{ReportBase, ReportFilter, ReportFilterValue};
11use crate::enums::{FilterOperator, ReportStatus};
12use crate::ids::PaddleID;
13use crate::paginated::Paginated;
14use crate::{Paddle, Result};
15
16pub trait ReportType: Serialize {
17    type FilterName: Serialize + DeserializeOwned;
18}
19
20/// Request builder for querying Paddle for reports.
21#[skip_serializing_none]
22#[derive(Serialize)]
23pub struct ReportsList<'a> {
24    #[serde(skip)]
25    client: &'a Paddle,
26    after: Option<PaddleID>,
27    order_by: Option<String>,
28    per_page: Option<usize>,
29    #[serde(serialize_with = "crate::comma_separated_enum")]
30    status: Option<Vec<ReportStatus>>,
31}
32
33impl<'a> ReportsList<'a> {
34    pub fn new(client: &'a Paddle) -> Self {
35        Self {
36            client,
37            after: None,
38            order_by: None,
39            per_page: None,
40            status: None,
41        }
42    }
43
44    /// Return entities after the specified Paddle ID when working with paginated endpoints. Used in the `meta.pagination.next` URL in responses for list operations.
45    pub fn after(&mut self, report_id: impl Into<PaddleID>) -> &mut Self {
46        self.after = Some(report_id.into());
47        self
48    }
49
50    /// Order returned entities by the specified field. Valid fields for ordering: `id`
51    pub fn order_by_asc(&mut self, field: &str) -> &mut Self {
52        self.order_by = Some(format!("{}[ASC]", field));
53        self
54    }
55
56    /// Order returned entities by the specified field. Valid fields for ordering: `id`
57    pub fn order_by_desc(&mut self, field: &str) -> &mut Self {
58        self.order_by = Some(format!("{}[DESC]", field));
59        self
60    }
61
62    /// Set how many entities are returned per page. Paddle returns the maximum number of results if a number greater than the maximum is requested.
63    /// Check `meta.pagination.per_page` in the response to see how many were returned.
64    ///
65    /// Default: `50`; Maximum: `200`.
66    pub fn per_page(&mut self, entities_per_page: usize) -> &mut Self {
67        self.per_page = Some(entities_per_page);
68        self
69    }
70
71    /// Return entities that match the specified status.
72    pub fn status(&mut self, statuses: impl IntoIterator<Item = ReportStatus>) -> &mut Self {
73        self.status = Some(statuses.into_iter().collect());
74        self
75    }
76
77    /// Returns a paginator for fetching pages of entities from Paddle
78    pub fn send(&self) -> Paginated<Vec<ReportBase>> {
79        Paginated::new(self.client, "/reports", self)
80    }
81}
82
83/// Request builder for creating reports in Paddle.
84#[skip_serializing_none]
85#[derive(Serialize)]
86pub struct ReportCreate<'a, T: ReportType> {
87    #[serde(skip)]
88    client: &'a Paddle,
89    r#type: T,
90    filters: Vec<ReportFilter<T::FilterName>>,
91}
92
93impl<'a, T: ReportType + DeserializeOwned> ReportCreate<'a, T> {
94    pub fn new(client: &'a Paddle, r#type: T) -> Self {
95        Self {
96            client,
97            r#type,
98            filters: Vec::new(),
99        }
100    }
101
102    /// Add filter criteria for this report. If omitted, reports are filtered to include data updated in the last 30 days. This means `updated_at` is greater than or equal to (`gte`) the date 30 days ago from the time the report was generated.
103    pub fn append_filter(
104        &mut self,
105        name: T::FilterName,
106        operator: Option<FilterOperator>,
107        value: impl Into<ReportFilterValue>,
108    ) -> &mut Self {
109        self.filters.push(ReportFilter {
110            name,
111            operator,
112            value: value.into(),
113        });
114
115        self
116    }
117
118    /// Clear all report filters
119    pub fn clear_filters(&mut self) {
120        self.filters.clear();
121    }
122
123    /// Set all filter criteria for this report. This overrides any previously set filters.
124    pub fn set_filters(
125        &mut self,
126        filters: impl IntoIterator<Item = (T::FilterName, Option<FilterOperator>, ReportFilterValue)>,
127    ) -> &mut Self {
128        self.filters = filters
129            .into_iter()
130            .map(|(name, operator, value)| ReportFilter {
131                name,
132                operator,
133                value,
134            })
135            .collect();
136        self
137    }
138
139    /// Send the request to Paddle and return the response.
140    pub async fn send(&self) -> Result<ReportBase> {
141        self.client.send(self, Method::POST, "/reports").await
142    }
143}