1use sea_orm::IntoActiveValue;
2
3use crate::db::billing_subscription::StripeSubscriptionStatus;
4
5use super::*;
6
7#[derive(Debug)]
8pub struct CreateBillingSubscriptionParams {
9 pub billing_customer_id: BillingCustomerId,
10 pub stripe_subscription_id: String,
11 pub stripe_subscription_status: StripeSubscriptionStatus,
12 pub last_stripe_event_id: Option<String>,
13}
14
15#[derive(Debug, Default)]
16pub struct UpdateBillingSubscriptionParams {
17 pub billing_customer_id: ActiveValue<BillingCustomerId>,
18 pub stripe_subscription_id: ActiveValue<String>,
19 pub stripe_subscription_status: ActiveValue<StripeSubscriptionStatus>,
20 pub last_stripe_event_id: ActiveValue<Option<String>>,
21}
22
23impl Database {
24 /// Creates a new billing subscription.
25 pub async fn create_billing_subscription(
26 &self,
27 params: &CreateBillingSubscriptionParams,
28 ) -> Result<()> {
29 self.transaction(|tx| async move {
30 billing_subscription::Entity::insert(billing_subscription::ActiveModel {
31 billing_customer_id: ActiveValue::set(params.billing_customer_id),
32 stripe_subscription_id: ActiveValue::set(params.stripe_subscription_id.clone()),
33 stripe_subscription_status: ActiveValue::set(params.stripe_subscription_status),
34 last_stripe_event_id: params.last_stripe_event_id.clone().into_active_value(),
35 ..Default::default()
36 })
37 .exec_without_returning(&*tx)
38 .await?;
39
40 Ok(())
41 })
42 .await
43 }
44
45 /// Updates the specified billing subscription.
46 pub async fn update_billing_subscription(
47 &self,
48 id: BillingSubscriptionId,
49 params: &UpdateBillingSubscriptionParams,
50 ) -> Result<()> {
51 self.transaction(|tx| async move {
52 billing_subscription::Entity::update(billing_subscription::ActiveModel {
53 id: ActiveValue::set(id),
54 billing_customer_id: params.billing_customer_id.clone(),
55 stripe_subscription_id: params.stripe_subscription_id.clone(),
56 stripe_subscription_status: params.stripe_subscription_status.clone(),
57 last_stripe_event_id: params.last_stripe_event_id.clone(),
58 ..Default::default()
59 })
60 .exec(&*tx)
61 .await?;
62
63 Ok(())
64 })
65 .await
66 }
67
68 /// Returns the billing subscription with the specified ID.
69 pub async fn get_billing_subscription_by_id(
70 &self,
71 id: BillingSubscriptionId,
72 ) -> Result<Option<billing_subscription::Model>> {
73 self.transaction(|tx| async move {
74 Ok(billing_subscription::Entity::find_by_id(id)
75 .one(&*tx)
76 .await?)
77 })
78 .await
79 }
80
81 /// Returns the billing subscription with the specified Stripe subscription ID.
82 pub async fn get_billing_subscription_by_stripe_subscription_id(
83 &self,
84 stripe_subscription_id: &str,
85 ) -> Result<Option<billing_subscription::Model>> {
86 self.transaction(|tx| async move {
87 Ok(billing_subscription::Entity::find()
88 .filter(
89 billing_subscription::Column::StripeSubscriptionId.eq(stripe_subscription_id),
90 )
91 .one(&*tx)
92 .await?)
93 })
94 .await
95 }
96
97 /// Returns all of the billing subscriptions for the user with the specified ID.
98 ///
99 /// Note that this returns the subscriptions regardless of their status.
100 /// If you're wanting to check if a use has an active billing subscription,
101 /// use `get_active_billing_subscriptions` instead.
102 pub async fn get_billing_subscriptions(
103 &self,
104 user_id: UserId,
105 ) -> Result<Vec<billing_subscription::Model>> {
106 self.transaction(|tx| async move {
107 let subscriptions = billing_subscription::Entity::find()
108 .inner_join(billing_customer::Entity)
109 .filter(billing_customer::Column::UserId.eq(user_id))
110 .order_by_asc(billing_subscription::Column::Id)
111 .all(&*tx)
112 .await?;
113
114 Ok(subscriptions)
115 })
116 .await
117 }
118
119 /// Returns all of the active billing subscriptions for the user with the specified ID.
120 pub async fn get_active_billing_subscriptions(
121 &self,
122 user_id: UserId,
123 ) -> Result<Vec<billing_subscription::Model>> {
124 self.transaction(|tx| async move {
125 let subscriptions = billing_subscription::Entity::find()
126 .inner_join(billing_customer::Entity)
127 .filter(
128 billing_customer::Column::UserId.eq(user_id).and(
129 billing_subscription::Column::StripeSubscriptionStatus
130 .eq(StripeSubscriptionStatus::Active),
131 ),
132 )
133 .order_by_asc(billing_subscription::Column::Id)
134 .all(&*tx)
135 .await?;
136
137 Ok(subscriptions)
138 })
139 .await
140 }
141}