import { AccountID } from "./account"; import { OrgID } from "./org"; import { Serializable, AsSerializable, AsDate } from "./encoding"; export enum PlanType { Free, Premium, Family, Team, Business, } export class Plan extends Serializable { id = ""; type: PlanType = PlanType.Free; name = "Free"; description = ""; items: number = -1; storage: number = 0; groups: number = 0; vaults: number = 0; min: number = 0; max: number = 0; available = false; cost: number = 0; features: string[] = []; default = false; color = ""; } export class PaymentMethod extends Serializable { id = ""; name = ""; } export enum SubscriptionStatus { Trialing = "trialing", Active = "active", Inactive = "inactive", Canceled = "canceled", } export class Subscription extends Serializable { id = ""; account: AccountID = ""; org: OrgID = ""; status: SubscriptionStatus = SubscriptionStatus.Active; items: number = -1; storage: number = 0; groups: number = 0; vaults: number = 0; members: number = 0; paymentError?: string = undefined; paymentRequiresAuth?: string = undefined; currentInvoice: string = ""; @AsDate() periodEnd: Date = new Date(0); @AsDate() trialEnd?: Date; @AsSerializable(Plan) plan: Plan = new Plan(); } export class BillingAddress extends Serializable { name = ""; street = ""; postalCode = ""; city = ""; country = ""; constructor(params?: Partial) { super(); if (params) { Object.assign(this, params); } } } export class Discount extends Serializable { name = ""; coupon = ""; } export class BillingInfo extends Serializable { customerId: string = ""; account: AccountID = ""; org: OrgID = ""; email: string = ""; @AsSerializable(Subscription) subscription: Subscription | null = null; @AsSerializable(PaymentMethod) paymentMethod: PaymentMethod | null = null; @AsSerializable(BillingAddress) address: BillingAddress = new BillingAddress(); @AsSerializable(Discount) discount: Discount | null = null; @AsDate() firstTrialStarted?: Date; get trialDaysLeft() { const daysSinceFirstTrial = this.firstTrialStarted ? Math.floor((Date.now() - this.firstTrialStarted.getTime()) / 24 / 60 / 60 / 1000) : 0; return Math.max(0, 30 - daysSinceFirstTrial); } } export class UpdateBillingParams extends Serializable { provider: string = ""; account?: AccountID = undefined; org?: OrgID = undefined; email?: string = undefined; plan?: string = undefined; planType?: PlanType = undefined; members?: number = undefined; paymentMethod?: { name: string } & any = undefined; coupon?: string = undefined; cancel?: boolean = undefined; @AsSerializable(BillingAddress) address?: BillingAddress; constructor(params?: Partial) { super(); if (params) { Object.assign(this, params); } } } export class BillingProviderInfo extends Serializable { type: string = ""; config: { [param: string]: string; } = {}; @AsSerializable(Plan) plans: Plan[] = []; } export interface BillingProvider { update(params: UpdateBillingParams): Promise; delete(billingInfo: BillingInfo): Promise; getInfo(): BillingProviderInfo; } // // const stubPlans: Plan[] = [ // { // id: "personal", // name: "Personal", // description: "Basic Setup For Personal Use", // storage: -1, // available: true, // default: true // }, // { // id: "shared", // name: "Shared", // description: "Basic Setup For Sharing", // storage: -1, // vaults: -1, // available: true, // orgType: 1 // }, // { // id: "advanced", // name: "Advanced", // description: "Advanced Setup For Sharing", // storage: -1, // groups: -1, // vaults: -1, // available: true, // orgType: 2 // } // ].map(p => { // const plan = new Plan(); // Object.assign(plan, p); // return plan; // });