billing_subscription.rs

  1use crate::db::{BillingCustomerId, BillingSubscriptionId};
  2use sea_orm::entity::prelude::*;
  3use serde::Serialize;
  4
  5/// A billing subscription.
  6#[derive(Clone, Debug, Default, PartialEq, Eq, DeriveEntityModel)]
  7#[sea_orm(table_name = "billing_subscriptions")]
  8pub struct Model {
  9    #[sea_orm(primary_key)]
 10    pub id: BillingSubscriptionId,
 11    pub billing_customer_id: BillingCustomerId,
 12    pub kind: Option<SubscriptionKind>,
 13    pub stripe_subscription_id: String,
 14    pub stripe_subscription_status: StripeSubscriptionStatus,
 15    pub stripe_cancel_at: Option<DateTime>,
 16    pub stripe_cancellation_reason: Option<StripeCancellationReason>,
 17    pub stripe_current_period_start: Option<i64>,
 18    pub stripe_current_period_end: Option<i64>,
 19    pub created_at: DateTime,
 20}
 21
 22impl Model {
 23    pub fn current_period_start_at(&self) -> Option<DateTimeUtc> {
 24        let period_start = self.stripe_current_period_start?;
 25        chrono::DateTime::from_timestamp(period_start, 0)
 26    }
 27
 28    pub fn current_period_end_at(&self) -> Option<DateTimeUtc> {
 29        let period_end = self.stripe_current_period_end?;
 30        chrono::DateTime::from_timestamp(period_end, 0)
 31    }
 32}
 33
 34#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
 35pub enum Relation {
 36    #[sea_orm(
 37        belongs_to = "super::billing_customer::Entity",
 38        from = "Column::BillingCustomerId",
 39        to = "super::billing_customer::Column::Id"
 40    )]
 41    BillingCustomer,
 42}
 43
 44impl Related<super::billing_customer::Entity> for Entity {
 45    fn to() -> RelationDef {
 46        Relation::BillingCustomer.def()
 47    }
 48}
 49
 50impl ActiveModelBehavior for ActiveModel {}
 51
 52#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Hash, Serialize)]
 53#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
 54#[serde(rename_all = "snake_case")]
 55pub enum SubscriptionKind {
 56    #[sea_orm(string_value = "zed_pro")]
 57    ZedPro,
 58    #[sea_orm(string_value = "zed_pro_trial")]
 59    ZedProTrial,
 60    #[sea_orm(string_value = "zed_free")]
 61    ZedFree,
 62}
 63
 64impl From<SubscriptionKind> for zed_llm_client::Plan {
 65    fn from(value: SubscriptionKind) -> Self {
 66        match value {
 67            SubscriptionKind::ZedPro => Self::ZedPro,
 68            SubscriptionKind::ZedProTrial => Self::ZedProTrial,
 69            SubscriptionKind::ZedFree => Self::Free,
 70        }
 71    }
 72}
 73
 74/// The status of a Stripe subscription.
 75///
 76/// [Stripe docs](https://docs.stripe.com/api/subscriptions/object#subscription_object-status)
 77#[derive(
 78    Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash, Serialize,
 79)]
 80#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
 81#[serde(rename_all = "snake_case")]
 82pub enum StripeSubscriptionStatus {
 83    #[default]
 84    #[sea_orm(string_value = "incomplete")]
 85    Incomplete,
 86    #[sea_orm(string_value = "incomplete_expired")]
 87    IncompleteExpired,
 88    #[sea_orm(string_value = "trialing")]
 89    Trialing,
 90    #[sea_orm(string_value = "active")]
 91    Active,
 92    #[sea_orm(string_value = "past_due")]
 93    PastDue,
 94    #[sea_orm(string_value = "canceled")]
 95    Canceled,
 96    #[sea_orm(string_value = "unpaid")]
 97    Unpaid,
 98    #[sea_orm(string_value = "paused")]
 99    Paused,
100}
101
102impl StripeSubscriptionStatus {
103    pub fn is_cancelable(&self) -> bool {
104        match self {
105            Self::Trialing | Self::Active | Self::PastDue => true,
106            Self::Incomplete
107            | Self::IncompleteExpired
108            | Self::Canceled
109            | Self::Unpaid
110            | Self::Paused => false,
111        }
112    }
113}
114
115/// The cancellation reason for a Stripe subscription.
116///
117/// [Stripe docs](https://docs.stripe.com/api/subscriptions/object#subscription_object-cancellation_details-reason)
118#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Hash, Serialize)]
119#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
120#[serde(rename_all = "snake_case")]
121pub enum StripeCancellationReason {
122    #[sea_orm(string_value = "cancellation_requested")]
123    CancellationRequested,
124    #[sea_orm(string_value = "payment_disputed")]
125    PaymentDisputed,
126    #[sea_orm(string_value = "payment_failed")]
127    PaymentFailed,
128}