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 #[sea_orm(string_value = "zed_pro_trial")]
47 ZedProTrial,
48 #[sea_orm(string_value = "zed_free")]
49 ZedFree,
50}
51
52/// The status of a Stripe subscription.
53///
54/// [Stripe docs](https://docs.stripe.com/api/subscriptions/object#subscription_object-status)
55#[derive(
56 Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash, Serialize,
57)]
58#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
59#[serde(rename_all = "snake_case")]
60pub enum StripeSubscriptionStatus {
61 #[default]
62 #[sea_orm(string_value = "incomplete")]
63 Incomplete,
64 #[sea_orm(string_value = "incomplete_expired")]
65 IncompleteExpired,
66 #[sea_orm(string_value = "trialing")]
67 Trialing,
68 #[sea_orm(string_value = "active")]
69 Active,
70 #[sea_orm(string_value = "past_due")]
71 PastDue,
72 #[sea_orm(string_value = "canceled")]
73 Canceled,
74 #[sea_orm(string_value = "unpaid")]
75 Unpaid,
76 #[sea_orm(string_value = "paused")]
77 Paused,
78}
79
80impl StripeSubscriptionStatus {
81 pub fn is_cancelable(&self) -> bool {
82 match self {
83 Self::Trialing | Self::Active | Self::PastDue => true,
84 Self::Incomplete
85 | Self::IncompleteExpired
86 | Self::Canceled
87 | Self::Unpaid
88 | Self::Paused => false,
89 }
90 }
91}
92
93/// The cancellation reason for a Stripe subscription.
94///
95/// [Stripe docs](https://docs.stripe.com/api/subscriptions/object#subscription_object-cancellation_details-reason)
96#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Hash, Serialize)]
97#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
98#[serde(rename_all = "snake_case")]
99pub enum StripeCancellationReason {
100 #[sea_orm(string_value = "cancellation_requested")]
101 CancellationRequested,
102 #[sea_orm(string_value = "payment_disputed")]
103 PaymentDisputed,
104 #[sea_orm(string_value = "payment_failed")]
105 PaymentFailed,
106}