billing_subscriptions.rs

  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}