pinpayments/resources/
plan.rs

1use time::{OffsetDateTime};
2use serde::{Deserialize, Serialize};
3
4use crate::client::{Client, Response, StatusOnlyResponse};
5use crate::error::PinError;
6use crate::ids::{PlanId};
7use crate::params::{unpack_contained, Page, Paginator, paginate};
8use crate::resources::{Currency};
9use crate::build_map;
10
11#[derive(PartialEq, Debug, Serialize, Default, Deserialize)]
12#[serde(rename_all = "snake_case")]
13pub enum IntervalUnit {
14    #[default]
15    Day,
16    Week,
17    Month,
18    Year
19}
20
21#[derive(PartialEq, Debug, Serialize, Deserialize)]
22#[serde(rename_all = "snake_case")]
23pub enum CustomerPermission {
24    Cancel
25}
26
27#[derive(Debug, Default, Serialize)]
28pub struct CreatePlan<'a> {
29    pub name: &'a str,
30    pub amount: i64,
31    pub currency: Currency,
32    pub interval: u32,
33    pub interval_unit: IntervalUnit,
34
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub intervals: Option<u32>,
37
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub setup_amount: Option<u32>,
40
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub trial_amount: Option<u32>,
43
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub trial_interval: Option<u32>,
46
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub trial_interval_unit: Option<IntervalUnit>,
49
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub customer_permissions: Option<Vec<CustomerPermission>>
52}
53
54#[derive(Debug, Default, Deserialize)]
55pub struct SubscriptionCounts {
56    pub trial: u32,
57    pub active: u32,
58    pub cancelling: u32,
59    pub cancelled: u32
60} 
61
62#[derive(Debug, Default, Deserialize)]
63pub struct Plan {
64    pub token: PlanId,
65    pub name: String,
66    pub amount: i64,
67    pub currency: Currency,
68    pub interval: u32,
69    pub interval_unit: IntervalUnit,
70    pub intervals: u32,
71    pub setup_amount: u32,
72    pub trial_amount: u32,
73    pub trial_interval: u32,
74    pub trial_interval_unit: IntervalUnit,
75    pub customer_permissions: Vec<CustomerPermission>, 
76    pub subscription_counts: SubscriptionCounts,
77
78    #[serde(with = "time::serde::iso8601::option")]
79    pub created_at: Option<OffsetDateTime>
80}
81
82impl Plan {
83    pub fn create(client: &Client, params: CreatePlan<'_>) -> Response<Plan> {
84        unpack_contained(client.post_form("/plans", &params))
85    }
86
87    pub fn list(client: &Client, page: Option<u32>, per_page: Option<u32>) -> Response<Page<Plan>> {
88        let page = page.map(|s| s.to_string());
89        let per_page = per_page.map(|s| s.to_string());
90        let params = build_map([
91            ("page", page.as_deref()),
92            ("per_page", per_page.as_deref())
93        ]);
94        client.get_query("/plans", &params)
95    }
96
97    pub fn list_with_paginator(client: &Client, per_page: Option<u32>) -> Paginator<Result<Plan, PinError>> {
98        paginate(
99            move |page, per_page| {
100                Plan::list(client, Some(page), Some(per_page))
101            },
102            per_page.unwrap_or(25)
103        )
104    }
105
106    pub fn retrieve(client: &Client, token: &PlanId) -> Response<Plan> {
107        unpack_contained(client.get(&format!("/plans/{}", token)))
108    }
109
110    pub fn delete(client: &Client, token: &PlanId) -> StatusOnlyResponse { 
111        client.delete_status_only(&format!("/plans/{}", token))
112    }
113}