You've already forked AstralRinth
forked from didirus/AstralRinth
262 lines
6.8 KiB
Rust
262 lines
6.8 KiB
Rust
use crate::models::ids::Base62Id;
|
|
use crate::models::ids::UserId;
|
|
use chrono::{DateTime, Utc};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
|
#[serde(from = "Base62Id")]
|
|
#[serde(into = "Base62Id")]
|
|
pub struct ProductId(pub u64);
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct Product {
|
|
pub id: ProductId,
|
|
pub metadata: ProductMetadata,
|
|
pub prices: Vec<ProductPrice>,
|
|
pub unitary: bool,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
#[serde(tag = "type", rename_all = "kebab-case")]
|
|
pub enum ProductMetadata {
|
|
Midas,
|
|
Pyro {
|
|
cpu: u32,
|
|
ram: u32,
|
|
swap: u32,
|
|
storage: u32,
|
|
},
|
|
}
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
|
#[serde(from = "Base62Id")]
|
|
#[serde(into = "Base62Id")]
|
|
pub struct ProductPriceId(pub u64);
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct ProductPrice {
|
|
pub id: ProductPriceId,
|
|
pub product_id: ProductId,
|
|
pub prices: Price,
|
|
pub currency_code: String,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
#[serde(tag = "type", rename_all = "kebab-case")]
|
|
pub enum Price {
|
|
OneTime {
|
|
price: i32,
|
|
},
|
|
Recurring {
|
|
intervals: HashMap<PriceDuration, i32>,
|
|
},
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Hash, Eq, PartialEq, Debug, Copy, Clone)]
|
|
#[serde(rename_all = "kebab-case")]
|
|
pub enum PriceDuration {
|
|
Monthly,
|
|
Yearly,
|
|
}
|
|
|
|
impl PriceDuration {
|
|
pub fn duration(&self) -> chrono::Duration {
|
|
match self {
|
|
PriceDuration::Monthly => chrono::Duration::days(30),
|
|
PriceDuration::Yearly => chrono::Duration::days(365),
|
|
}
|
|
}
|
|
|
|
pub fn from_string(string: &str) -> PriceDuration {
|
|
match string {
|
|
"monthly" => PriceDuration::Monthly,
|
|
"yearly" => PriceDuration::Yearly,
|
|
_ => PriceDuration::Monthly,
|
|
}
|
|
}
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
PriceDuration::Monthly => "monthly",
|
|
PriceDuration::Yearly => "yearly",
|
|
}
|
|
}
|
|
|
|
pub fn iterator() -> impl Iterator<Item = PriceDuration> {
|
|
vec![PriceDuration::Monthly, PriceDuration::Yearly].into_iter()
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
|
#[serde(from = "Base62Id")]
|
|
#[serde(into = "Base62Id")]
|
|
pub struct UserSubscriptionId(pub u64);
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct UserSubscription {
|
|
pub id: UserSubscriptionId,
|
|
pub user_id: UserId,
|
|
pub price_id: ProductPriceId,
|
|
pub interval: PriceDuration,
|
|
pub status: SubscriptionStatus,
|
|
pub created: DateTime<Utc>,
|
|
pub metadata: Option<SubscriptionMetadata>,
|
|
}
|
|
|
|
impl From<crate::database::models::user_subscription_item::UserSubscriptionItem>
|
|
for UserSubscription
|
|
{
|
|
fn from(
|
|
x: crate::database::models::user_subscription_item::UserSubscriptionItem,
|
|
) -> Self {
|
|
Self {
|
|
id: x.id.into(),
|
|
user_id: x.user_id.into(),
|
|
price_id: x.price_id.into(),
|
|
interval: x.interval,
|
|
status: x.status,
|
|
created: x.created,
|
|
metadata: x.metadata,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Eq, PartialEq, Copy, Clone)]
|
|
#[serde(rename_all = "kebab-case")]
|
|
pub enum SubscriptionStatus {
|
|
Provisioned,
|
|
Unprovisioned,
|
|
}
|
|
|
|
impl SubscriptionStatus {
|
|
pub fn from_string(string: &str) -> SubscriptionStatus {
|
|
match string {
|
|
"provisioned" => SubscriptionStatus::Provisioned,
|
|
"unprovisioned" => SubscriptionStatus::Unprovisioned,
|
|
_ => SubscriptionStatus::Provisioned,
|
|
}
|
|
}
|
|
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
SubscriptionStatus::Provisioned => "provisioned",
|
|
SubscriptionStatus::Unprovisioned => "unprovisioned",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
#[serde(tag = "type", rename_all = "kebab-case")]
|
|
pub enum SubscriptionMetadata {
|
|
Pyro { id: String },
|
|
}
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
|
#[serde(from = "Base62Id")]
|
|
#[serde(into = "Base62Id")]
|
|
pub struct ChargeId(pub u64);
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct Charge {
|
|
pub id: ChargeId,
|
|
pub user_id: UserId,
|
|
pub price_id: ProductPriceId,
|
|
pub amount: i64,
|
|
pub currency_code: String,
|
|
pub status: ChargeStatus,
|
|
pub due: DateTime<Utc>,
|
|
pub last_attempt: Option<DateTime<Utc>>,
|
|
#[serde(flatten)]
|
|
pub type_: ChargeType,
|
|
pub subscription_id: Option<UserSubscriptionId>,
|
|
pub subscription_interval: Option<PriceDuration>,
|
|
pub platform: PaymentPlatform,
|
|
|
|
pub parent_charge_id: Option<ChargeId>,
|
|
pub net: Option<i64>,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
|
|
#[serde(tag = "type", rename_all = "kebab-case")]
|
|
pub enum ChargeType {
|
|
OneTime,
|
|
Subscription,
|
|
Proration,
|
|
Refund,
|
|
}
|
|
|
|
impl ChargeType {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
ChargeType::OneTime => "one-time",
|
|
ChargeType::Subscription => "subscription",
|
|
ChargeType::Proration => "proration",
|
|
ChargeType::Refund => "refund",
|
|
}
|
|
}
|
|
|
|
pub fn from_string(string: &str) -> ChargeType {
|
|
match string {
|
|
"one-time" => ChargeType::OneTime,
|
|
"subscription" => ChargeType::Subscription,
|
|
"proration" => ChargeType::Proration,
|
|
"refund" => ChargeType::Refund,
|
|
_ => ChargeType::OneTime,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Eq, PartialEq, Copy, Clone, Debug)]
|
|
#[serde(rename_all = "kebab-case")]
|
|
pub enum ChargeStatus {
|
|
// Open charges are for the next billing interval
|
|
Open,
|
|
Processing,
|
|
Succeeded,
|
|
Failed,
|
|
Cancelled,
|
|
}
|
|
|
|
impl ChargeStatus {
|
|
pub fn from_string(string: &str) -> ChargeStatus {
|
|
match string {
|
|
"processing" => ChargeStatus::Processing,
|
|
"succeeded" => ChargeStatus::Succeeded,
|
|
"failed" => ChargeStatus::Failed,
|
|
"open" => ChargeStatus::Open,
|
|
"cancelled" => ChargeStatus::Cancelled,
|
|
_ => ChargeStatus::Failed,
|
|
}
|
|
}
|
|
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
ChargeStatus::Processing => "processing",
|
|
ChargeStatus::Succeeded => "succeeded",
|
|
ChargeStatus::Failed => "failed",
|
|
ChargeStatus::Open => "open",
|
|
ChargeStatus::Cancelled => "cancelled",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum PaymentPlatform {
|
|
Stripe,
|
|
}
|
|
|
|
impl PaymentPlatform {
|
|
pub fn from_string(string: &str) -> PaymentPlatform {
|
|
match string {
|
|
"stripe" => PaymentPlatform::Stripe,
|
|
_ => PaymentPlatform::Stripe,
|
|
}
|
|
}
|
|
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
PaymentPlatform::Stripe => "stripe",
|
|
}
|
|
}
|
|
}
|