mirror of
https://github.com/documenso/documenso.git
synced 2025-11-15 01:01:49 +10:00
feat: add organisations (#1820)
This commit is contained in:
@ -1,6 +1,12 @@
|
||||
import type { OrganisationClaim, Subscription } from '@prisma/client';
|
||||
import type Stripe from 'stripe';
|
||||
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { stripe } from '@documenso/lib/server-only/stripe';
|
||||
import { appLog } from '@documenso/lib/utils/debugger';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { isPriceSeatsBased } from './is-price-seats-based';
|
||||
|
||||
export type UpdateSubscriptionItemQuantityOptions = {
|
||||
subscriptionId: string;
|
||||
@ -42,3 +48,57 @@ export const updateSubscriptionItemQuantity = async ({
|
||||
|
||||
await stripe.subscriptions.update(subscriptionId, subscriptionUpdatePayload);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks whether the member count should be synced with a given Stripe subscription.
|
||||
*
|
||||
* If the subscription is not "seat" based, it will be ignored.
|
||||
*
|
||||
* @param subscription - The subscription to sync the member count with.
|
||||
* @param organisationClaim - The organisation claim
|
||||
* @param quantity - The amount to sync the Stripe item with
|
||||
* @returns
|
||||
*/
|
||||
export const syncMemberCountWithStripeSeatPlan = async (
|
||||
subscription: Subscription,
|
||||
organisationClaim: OrganisationClaim,
|
||||
quantity: number,
|
||||
) => {
|
||||
const maximumMemberCount = organisationClaim.memberCount;
|
||||
|
||||
// Infinite seats means no sync needed.
|
||||
if (maximumMemberCount === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const syncMemberCountWithStripe = await isPriceSeatsBased(subscription.priceId);
|
||||
|
||||
// Throw error if quantity exceeds maximum member count and the subscription is not seats based.
|
||||
if (quantity > maximumMemberCount && !syncMemberCountWithStripe) {
|
||||
throw new AppError(AppErrorCode.LIMIT_EXCEEDED, {
|
||||
message: 'Maximum member count reached',
|
||||
});
|
||||
}
|
||||
|
||||
// Bill the user with the new quantity.
|
||||
if (syncMemberCountWithStripe) {
|
||||
appLog('BILLING', 'Updating seat based plan');
|
||||
|
||||
await updateSubscriptionItemQuantity({
|
||||
priceId: subscription.priceId,
|
||||
subscriptionId: subscription.planId,
|
||||
quantity,
|
||||
});
|
||||
|
||||
// This should be automatically updated after the Stripe webhook is fired
|
||||
// but we just manually adjust it here as well to avoid any race conditions.
|
||||
await prisma.organisationClaim.update({
|
||||
where: {
|
||||
id: organisationClaim.id,
|
||||
},
|
||||
data: {
|
||||
memberCount: quantity,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user