import {BaseEntity, Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn} from 'typeorm'; import {BillingAccountManager} from 'app/gen-server/entity/BillingAccountManager'; import {Organization} from 'app/gen-server/entity/Organization'; import {Product} from 'app/gen-server/entity/Product'; import {nativeValues} from 'app/gen-server/lib/values'; // This type is for billing account status information. Intended for stuff // like "free trial running out in N days". interface BillingAccountStatus { stripeStatus?: string; currentPeriodEnd?: Date; message?: string; } /** * This relates organizations to products. It holds any stripe information * needed to be able to update and pay for the product that applies to the * organization. It has a list of managers detailing which users have the * right to view and edit these settings. */ @Entity({name: 'billing_accounts'}) export class BillingAccount extends BaseEntity { @PrimaryGeneratedColumn() public id: number; @ManyToOne(type => Product) @JoinColumn({name: 'product_id'}) public product: Product; @Column() public individual: boolean; // A flag for when all is well with the user's subscription. // Probably shouldn't use this to drive whether service is provided or not. // Strip recommends updating an end-of-service datetime every time payment // is received, adding on a grace period of some days. @Column({name: 'in_good_standing', default: nativeValues.trueValue}) public inGoodStanding: boolean; @Column({type: nativeValues.jsonEntityType, nullable: true}) public status: BillingAccountStatus; @Column({name: 'stripe_customer_id', type: String, nullable: true}) public stripeCustomerId: string | null; @Column({name: 'stripe_subscription_id', type: String, nullable: true}) public stripeSubscriptionId: string | null; @Column({name: 'stripe_plan_id', type: String, nullable: true}) public stripePlanId: string | null; @OneToMany(type => BillingAccountManager, manager => manager.billingAccount) public managers: BillingAccountManager[]; @OneToMany(type => Organization, org => org.billingAccount) public orgs: Organization[]; // A calculated column that is true if it looks like there is a paid plan. @Column({name: 'paid', type: 'boolean', insert: false, select: false}) public paid?: boolean; // A calculated column summarizing whether active user is a manager of the billing account. // (No @Column needed since calculation is done in javascript not sql) public isManager?: boolean; }