243 lines
6.8 KiB
TypeScript
243 lines
6.8 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { pricing } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/pricing';
|
|
import { SubscriptionRepository } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.repository';
|
|
import { IntegrationService } from '@gitroom/nestjs-libraries/database/prisma/integrations/integration.service';
|
|
import { OrganizationService } from '@gitroom/nestjs-libraries/database/prisma/organizations/organization.service';
|
|
import { Organization } from '@prisma/client';
|
|
import dayjs from 'dayjs';
|
|
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
|
|
|
|
@Injectable()
|
|
export class SubscriptionService {
|
|
constructor(
|
|
private readonly _subscriptionRepository: SubscriptionRepository,
|
|
private readonly _integrationService: IntegrationService,
|
|
private readonly _organizationService: OrganizationService,
|
|
) {}
|
|
|
|
getSubscriptionByOrganizationId(organizationId: string) {
|
|
return this._subscriptionRepository.getSubscriptionByOrganizationId(
|
|
organizationId
|
|
);
|
|
}
|
|
|
|
useCredit(organization: Organization) {
|
|
return this._subscriptionRepository.useCredit(organization);
|
|
}
|
|
|
|
getCode(code: string) {
|
|
return this._subscriptionRepository.getCode(code);
|
|
}
|
|
|
|
updateAccount(userId: string, account: string) {
|
|
return this._subscriptionRepository.updateAccount(userId, account);
|
|
}
|
|
|
|
getUserAccount(userId: string) {
|
|
return this._subscriptionRepository.getUserAccount(userId);
|
|
}
|
|
|
|
async deleteSubscription(customerId: string) {
|
|
await this.modifySubscription(
|
|
customerId,
|
|
pricing.FREE.channel || 0,
|
|
'FREE'
|
|
);
|
|
return this._subscriptionRepository.deleteSubscriptionByCustomerId(
|
|
customerId
|
|
);
|
|
}
|
|
|
|
updateCustomerId(organizationId: string, customerId: string) {
|
|
return this._subscriptionRepository.updateCustomerId(
|
|
organizationId,
|
|
customerId
|
|
);
|
|
}
|
|
|
|
async checkSubscription(organizationId: string, subscriptionId: string) {
|
|
return await this._subscriptionRepository.checkSubscription(
|
|
organizationId,
|
|
subscriptionId
|
|
);
|
|
}
|
|
|
|
updateConnectedStatus(account: string, accountCharges: boolean) {
|
|
return this._subscriptionRepository.updateConnectedStatus(
|
|
account,
|
|
accountCharges
|
|
);
|
|
}
|
|
|
|
async modifySubscription(
|
|
customerId: string,
|
|
totalChannels: number,
|
|
billing: 'FREE' | 'STANDARD' | 'PRO'
|
|
) {
|
|
if (!customerId) {
|
|
return false;
|
|
}
|
|
|
|
const getOrgByCustomerId =
|
|
await this._subscriptionRepository.getOrganizationByCustomerId(
|
|
customerId
|
|
);
|
|
|
|
const getCurrentSubscription =
|
|
(await this._subscriptionRepository.getSubscriptionByCustomerId(
|
|
customerId
|
|
))!;
|
|
|
|
if (getCurrentSubscription && getCurrentSubscription?.isLifetime) {
|
|
return false;
|
|
}
|
|
|
|
const from = pricing[getCurrentSubscription?.subscriptionTier || 'FREE'];
|
|
const to = pricing[billing];
|
|
|
|
const currentTotalChannels = (
|
|
await this._integrationService.getIntegrationsList(
|
|
getOrgByCustomerId?.id!
|
|
)
|
|
).filter((f) => !f.disabled);
|
|
|
|
if (currentTotalChannels.length > totalChannels) {
|
|
await this._integrationService.disableIntegrations(
|
|
getOrgByCustomerId?.id!,
|
|
currentTotalChannels.length - totalChannels
|
|
);
|
|
}
|
|
|
|
if (from.team_members && !to.team_members) {
|
|
await this._organizationService.disableOrEnableNonSuperAdminUsers(
|
|
getOrgByCustomerId?.id!,
|
|
true
|
|
);
|
|
}
|
|
|
|
if (!from.team_members && to.team_members) {
|
|
await this._organizationService.disableOrEnableNonSuperAdminUsers(
|
|
getOrgByCustomerId?.id!,
|
|
false
|
|
);
|
|
}
|
|
|
|
if (billing === 'FREE') {
|
|
await this._integrationService.changeActiveCron(getOrgByCustomerId?.id!);
|
|
}
|
|
|
|
return true;
|
|
|
|
// if (to.faq < from.faq) {
|
|
// await this._faqRepository.deleteFAQs(getCurrentSubscription?.organizationId, from.faq - to.faq);
|
|
// }
|
|
// if (to.categories < from.categories) {
|
|
// await this._categoriesRepository.deleteCategories(getCurrentSubscription?.organizationId, from.categories - to.categories);
|
|
// }
|
|
// if (to.integrations < from.integrations) {
|
|
// await this._integrationsRepository.deleteIntegrations(getCurrentSubscription?.organizationId, from.integrations - to.integrations);
|
|
// }
|
|
// if (to.user < from.user) {
|
|
// await this._integrationsRepository.deleteUsers(getCurrentSubscription?.organizationId, from.user - to.user);
|
|
// }
|
|
// if (to.domains < from.domains) {
|
|
// await this._settingsService.deleteDomainByOrg(getCurrentSubscription?.organizationId);
|
|
// await this._organizationRepository.changePowered(getCurrentSubscription?.organizationId);
|
|
// }
|
|
}
|
|
|
|
async createOrUpdateSubscription(
|
|
identifier: string,
|
|
customerId: string,
|
|
totalChannels: number,
|
|
billing: 'STANDARD' | 'PRO',
|
|
period: 'MONTHLY' | 'YEARLY',
|
|
cancelAt: number | null,
|
|
code?: string,
|
|
org?: string
|
|
) {
|
|
if (!code) {
|
|
try {
|
|
const load = await this.modifySubscription(
|
|
customerId,
|
|
totalChannels,
|
|
billing
|
|
);
|
|
if (!load) {
|
|
return {};
|
|
}
|
|
} catch (e) {
|
|
return {};
|
|
}
|
|
}
|
|
return this._subscriptionRepository.createOrUpdateSubscription(
|
|
identifier,
|
|
customerId,
|
|
totalChannels,
|
|
billing,
|
|
period,
|
|
cancelAt,
|
|
code,
|
|
org ? { id: org } : undefined
|
|
);
|
|
}
|
|
|
|
async getSubscription(organizationId: string) {
|
|
return this._subscriptionRepository.getSubscription(organizationId);
|
|
}
|
|
|
|
async checkCredits(organization: Organization) {
|
|
// @ts-ignore
|
|
const type = organization?.subscription?.subscriptionTier || 'FREE';
|
|
|
|
if (type === 'FREE') {
|
|
return { credits: 0 };
|
|
}
|
|
|
|
// @ts-ignore
|
|
let date = dayjs(organization.subscription.createdAt);
|
|
while (date.isBefore(dayjs())) {
|
|
date = date.add(1, 'month');
|
|
}
|
|
|
|
const checkFromMonth = date.subtract(1, 'month');
|
|
const imageGenerationCount = pricing[type].image_generation_count;
|
|
|
|
const totalUse = await this._subscriptionRepository.getCreditsFrom(
|
|
organization.id,
|
|
checkFromMonth
|
|
);
|
|
|
|
return {
|
|
credits: imageGenerationCount - totalUse,
|
|
};
|
|
}
|
|
|
|
async lifeTime(orgId: string, identifier: string, subscription: any) {
|
|
return this.createOrUpdateSubscription(
|
|
identifier,
|
|
identifier,
|
|
pricing[subscription].channel!,
|
|
subscription,
|
|
'YEARLY',
|
|
null,
|
|
identifier,
|
|
orgId
|
|
);
|
|
}
|
|
|
|
async addSubscription(orgId: string, userId: string, subscription: any) {
|
|
await this._subscriptionRepository.setCustomerId(orgId, orgId);
|
|
return this.createOrUpdateSubscription(
|
|
makeId(5),
|
|
userId,
|
|
pricing[subscription].channel!,
|
|
subscription,
|
|
'MONTHLY',
|
|
null,
|
|
undefined,
|
|
orgId
|
|
);
|
|
}
|
|
}
|