mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-11 10:20:30 +00:00
237 lines
5.3 KiB
TypeScript
237 lines
5.3 KiB
TypeScript
import moment from 'moment';
|
|
import { Model } from 'objection';
|
|
import uniqid from 'uniqid';
|
|
import SubscriptionPeriod from '@/services/Subscription/SubscriptionPeriod';
|
|
import BaseModel from 'models/Model';
|
|
import TenantMetadata from './TenantMetadata';
|
|
import PlanSubscription from './Subscriptions/PlanSubscription';
|
|
|
|
export default class Tenant extends BaseModel {
|
|
upgradeJobId: string;
|
|
buildJobId: string;
|
|
initializedAt!: Date | null;
|
|
seededAt!: Date | null;
|
|
|
|
/**
|
|
* Table name.
|
|
*/
|
|
static get tableName() {
|
|
return 'tenants';
|
|
}
|
|
|
|
/**
|
|
* Timestamps columns.
|
|
* @returns {string[]}
|
|
*/
|
|
get timestamps() {
|
|
return ['createdAt', 'updatedAt'];
|
|
}
|
|
|
|
/**
|
|
* Virtual attributes.
|
|
* @returns {string[]}
|
|
*/
|
|
static get virtualAttributes() {
|
|
return ['isReady', 'isBuildRunning', 'isUpgradeRunning'];
|
|
}
|
|
|
|
/**
|
|
* Tenant is ready.
|
|
* @returns {boolean}
|
|
*/
|
|
get isReady() {
|
|
return !!(this.initializedAt && this.seededAt);
|
|
}
|
|
|
|
/**
|
|
* Detarimes the tenant whether is build currently running.
|
|
* @returns {boolean}
|
|
*/
|
|
get isBuildRunning() {
|
|
return !!this.buildJobId;
|
|
}
|
|
|
|
/**
|
|
* Detarmines the tenant whether is upgrade currently running.
|
|
* @returns {boolean}
|
|
*/
|
|
get isUpgradeRunning() {
|
|
return !!this.upgradeJobId;
|
|
}
|
|
|
|
/**
|
|
* Query modifiers.
|
|
*/
|
|
static modifiers() {
|
|
return {
|
|
subscriptions(builder) {
|
|
builder.withGraphFetched('subscriptions');
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Relations mappings.
|
|
*/
|
|
static get relationMappings() {
|
|
const PlanSubscription = require('./Subscriptions/PlanSubscription');
|
|
const TenantMetadata = require('./TenantMetadata');
|
|
|
|
return {
|
|
subscriptions: {
|
|
relation: Model.HasManyRelation,
|
|
modelClass: PlanSubscription.default,
|
|
join: {
|
|
from: 'tenants.id',
|
|
to: 'subscription_plan_subscriptions.tenantId',
|
|
},
|
|
},
|
|
metadata: {
|
|
relation: Model.HasOneRelation,
|
|
modelClass: TenantMetadata.default,
|
|
join: {
|
|
from: 'tenants.id',
|
|
to: 'tenants_metadata.tenantId',
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a new tenant with random organization id.
|
|
*/
|
|
static createWithUniqueOrgId(uniqId) {
|
|
const organizationId = uniqid() || uniqId;
|
|
return this.query().insert({ organizationId });
|
|
}
|
|
|
|
/**
|
|
* Mark as seeded.
|
|
* @param {number} tenantId
|
|
*/
|
|
static markAsSeeded(tenantId) {
|
|
const seededAt = moment().toMySqlDateTime();
|
|
return this.query().update({ seededAt }).where({ id: tenantId });
|
|
}
|
|
|
|
/**
|
|
* Mark the the given organization as initialized.
|
|
* @param {string} organizationId
|
|
*/
|
|
static markAsInitialized(tenantId) {
|
|
const initializedAt = moment().toMySqlDateTime();
|
|
return this.query().update({ initializedAt }).where({ id: tenantId });
|
|
}
|
|
|
|
/**
|
|
* Marks the given tenant as built.
|
|
*/
|
|
static markAsBuilt(tenantId) {
|
|
const builtAt = moment().toMySqlDateTime();
|
|
return this.query().update({ builtAt }).where({ id: tenantId });
|
|
}
|
|
|
|
/**
|
|
* Marks the given tenant as built.
|
|
*/
|
|
static markAsBuilding(tenantId, buildJobId) {
|
|
return this.query().update({ buildJobId }).where({ id: tenantId });
|
|
}
|
|
|
|
/**
|
|
* Marks the given tenant as built.
|
|
*/
|
|
static markAsBuildCompleted(tenantId) {
|
|
return this.query().update({ buildJobId: null }).where({ id: tenantId });
|
|
}
|
|
|
|
/**
|
|
* Marks the given tenant as upgrading.
|
|
* @param {number} tenantId
|
|
* @param {string} upgradeJobId
|
|
* @returns
|
|
*/
|
|
static markAsUpgrading(tenantId, upgradeJobId) {
|
|
return this.query().update({ upgradeJobId }).where({ id: tenantId });
|
|
}
|
|
|
|
/**
|
|
* Markes the given tenant as upgraded.
|
|
* @param {number} tenantId
|
|
* @returns
|
|
*/
|
|
static markAsUpgraded(tenantId) {
|
|
return this.query().update({ upgradeJobId: null }).where({ id: tenantId });
|
|
}
|
|
|
|
/**
|
|
* Saves the metadata of the given tenant.
|
|
*/
|
|
static async saveMetadata(tenantId, metadata) {
|
|
const foundMetadata = await TenantMetadata.query().findOne({ tenantId });
|
|
const updateOrInsert = foundMetadata ? 'update' : 'insert';
|
|
|
|
return TenantMetadata.query()
|
|
[updateOrInsert]({
|
|
tenantId,
|
|
...metadata,
|
|
})
|
|
.where({ tenantId });
|
|
}
|
|
|
|
/**
|
|
* Saves the metadata of the tenant.
|
|
*/
|
|
saveMetadata(metadata) {
|
|
return Tenant.saveMetadata(this.id, metadata);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {*} planId
|
|
* @param {*} invoiceInterval
|
|
* @param {*} invoicePeriod
|
|
* @param {*} subscriptionSlug
|
|
* @returns
|
|
*/
|
|
public newSubscription(
|
|
planId,
|
|
invoiceInterval,
|
|
invoicePeriod,
|
|
subscriptionSlug,
|
|
payload?,
|
|
) {
|
|
return Tenant.newSubscription(
|
|
this.id,
|
|
planId,
|
|
invoiceInterval,
|
|
invoicePeriod,
|
|
subscriptionSlug,
|
|
payload
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Records a new subscription for the associated tenant.
|
|
*/
|
|
static newSubscription(
|
|
tenantId: number,
|
|
planId: number,
|
|
invoiceInterval: 'month' | 'year',
|
|
invoicePeriod: number,
|
|
subscriptionSlug: string,
|
|
payload?: { lemonSqueezyId: string }
|
|
) {
|
|
const period = new SubscriptionPeriod(invoiceInterval, invoicePeriod);
|
|
|
|
return PlanSubscription.query().insert({
|
|
tenantId,
|
|
slug: subscriptionSlug,
|
|
planId,
|
|
startsAt: period.getStartDate(),
|
|
endsAt: period.getEndDate(),
|
|
lemonSubscriptionId: payload?.lemonSqueezyId || null,
|
|
});
|
|
}
|
|
}
|