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
22#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
23pub enum Relation {
24 #[sea_orm(
25 belongs_to = "super::billing_customer::Entity",
26 from = "Column::BillingCustomerId",
27 to = "super::billing_customer::Column::Id"
28 )]
29 BillingCustomer,
30}
31
32impl Related<super::billing_customer::Entity> for Entity {
33 fn to() -> RelationDef {
34 Relation::BillingCustomer.def()
35 }
36}
37
38impl ActiveModelBehavior for ActiveModel {}
39
40#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Hash, Serialize)]
41#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
42#[serde(rename_all = "snake_case")]
43pub enum SubscriptionKind {
44 #[sea_orm(string_value = "zed_pro")]
45 ZedPro,
46}
47
48/// The status of a Stripe subscription.
49///
50/// [Stripe docs](https://docs.stripe.com/api/subscriptions/object#subscription_object-status)
51#[derive(
52 Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash, Serialize,
53)]
54#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
55#[serde(rename_all = "snake_case")]
56pub enum StripeSubscriptionStatus {
57 #[default]
58 #[sea_orm(string_value = "incomplete")]
59 Incomplete,
60 #[sea_orm(string_value = "incomplete_expired")]
61 IncompleteExpired,
62 #[sea_orm(string_value = "trialing")]
63 Trialing,
64 #[sea_orm(string_value = "active")]
65 Active,
66 #[sea_orm(string_value = "past_due")]
67 PastDue,
68 #[sea_orm(string_value = "canceled")]
69 Canceled,
70 #[sea_orm(string_value = "unpaid")]
71 Unpaid,
72 #[sea_orm(string_value = "paused")]
73 Paused,
74}
75
76impl StripeSubscriptionStatus {
77 pub fn is_cancelable(&self) -> bool {
78 match self {
79 Self::Trialing | Self::Active | Self::PastDue => true,
80 Self::Incomplete
81 | Self::IncompleteExpired
82 | Self::Canceled
83 | Self::Unpaid
84 | Self::Paused => false,
85 }
86 }
87}
88
89/// The cancellation reason for a Stripe subscription.
90///
91/// [Stripe docs](https://docs.stripe.com/api/subscriptions/object#subscription_object-cancellation_details-reason)
92#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Hash, Serialize)]
93#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
94#[serde(rename_all = "snake_case")]
95pub enum StripeCancellationReason {
96 #[sea_orm(string_value = "cancellation_requested")]
97 CancellationRequested,
98 #[sea_orm(string_value = "payment_disputed")]
99 PaymentDisputed,
100 #[sea_orm(string_value = "payment_failed")]
101 PaymentFailed,
102}