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