fix: move team credits to org on upgarde (#24386)
* move credits from team to org * add test --------- Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
This commit is contained in:
3 files changed
+116
-1
No files matched your search
@@ -689,4 +689,65 @@ export class CreditService {
|
||||
totalCreditsUsedThisMonth,
|
||||
};
|
||||
}
|
||||
|
||||
async moveCreditsFromTeamToOrg({ teamId, orgId }: { teamId: number; orgId: number }) {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
// Get team's credit balance
|
||||
const teamCreditBalance = await CreditsRepository.findCreditBalance({ teamId }, tx);
|
||||
|
||||
if (!teamCreditBalance || teamCreditBalance.additionalCredits <= 0) {
|
||||
log.info("No credits to transfer from team to org", { teamId, orgId });
|
||||
return;
|
||||
}
|
||||
|
||||
// Get or create org's credit balance
|
||||
let orgCreditBalance = await CreditsRepository.findCreditBalance({ teamId: orgId }, tx);
|
||||
|
||||
if (!orgCreditBalance) {
|
||||
orgCreditBalance = await CreditsRepository.createCreditBalance(
|
||||
{
|
||||
teamId: orgId,
|
||||
},
|
||||
tx
|
||||
);
|
||||
}
|
||||
|
||||
const creditsToTransfer = teamCreditBalance.additionalCredits;
|
||||
|
||||
// Transfer credits from team to org
|
||||
await CreditsRepository.updateCreditBalance(
|
||||
{
|
||||
teamId,
|
||||
data: {
|
||||
additionalCredits: 0,
|
||||
},
|
||||
},
|
||||
tx
|
||||
);
|
||||
|
||||
await CreditsRepository.updateCreditBalance(
|
||||
{
|
||||
teamId: orgId,
|
||||
data: {
|
||||
additionalCredits: {
|
||||
increment: creditsToTransfer,
|
||||
},
|
||||
},
|
||||
},
|
||||
tx
|
||||
);
|
||||
|
||||
log.info("Successfully transferred credits from team to org", {
|
||||
teamId,
|
||||
orgId,
|
||||
creditsTransferred: creditsToTransfer,
|
||||
});
|
||||
|
||||
return {
|
||||
creditsTransferred: creditsToTransfer,
|
||||
teamId,
|
||||
orgId,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
+51
-1
@@ -311,7 +311,6 @@ describe("createTeams handler", () => {
|
||||
// Verify platform team was not moved
|
||||
const platformTeam = await prismock.team.findFirst({
|
||||
where: { name: "Platform Team" },
|
||||
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
|
||||
include: { parent: true },
|
||||
});
|
||||
|
||||
@@ -423,4 +422,55 @@ describe("createTeams handler", () => {
|
||||
const redirectsWithNullFrom = redirects.filter((redirect) => redirect.from === null);
|
||||
expect(redirectsWithNullFrom).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("should transfer credits from team to organization when moving team", async () => {
|
||||
const { owner, organization, teams } = await createScenario({
|
||||
teams: [{ name: "Team With Credits", slug: "team-with-credits", addToParentId: null }],
|
||||
});
|
||||
|
||||
const teamToMove = teams[0];
|
||||
|
||||
// Add credits to the team before moving
|
||||
await prismock.creditBalance.create({
|
||||
data: {
|
||||
teamId: teamToMove.id,
|
||||
additionalCredits: 500,
|
||||
limitReachedAt: null,
|
||||
warningSentAt: null,
|
||||
},
|
||||
});
|
||||
|
||||
const result = await createTeamsHandler({
|
||||
ctx: {
|
||||
user: {
|
||||
id: owner.id,
|
||||
organizationId: organization.id,
|
||||
},
|
||||
},
|
||||
input: {
|
||||
teamNames: [],
|
||||
orgId: organization.id,
|
||||
moveTeams: [
|
||||
{
|
||||
id: teamToMove.id,
|
||||
shouldMove: true,
|
||||
newSlug: "moved-team-with-credits",
|
||||
},
|
||||
],
|
||||
creationSource: CreationSource.WEBAPP,
|
||||
},
|
||||
});
|
||||
|
||||
expect(result).toEqual({ duplicatedSlugs: [] });
|
||||
|
||||
const teamCreditBalance = await prismock.creditBalance.findFirst({
|
||||
where: { teamId: teamToMove.id },
|
||||
});
|
||||
expect(teamCreditBalance?.additionalCredits).toBe(0);
|
||||
|
||||
const orgCreditBalance = await prismock.creditBalance.findFirst({
|
||||
where: { teamId: organization.id },
|
||||
});
|
||||
expect(orgCreditBalance?.additionalCredits).toBe(500);
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,5 @@
|
||||
import { getOrgFullOrigin } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
import { CreditService } from "@calcom/features/ee/billing/credit-service";
|
||||
import stripe from "@calcom/features/ee/payments/server/stripe";
|
||||
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
|
||||
import logger from "@calcom/lib/logger";
|
||||
@@ -230,6 +231,9 @@ async function moveTeam({
|
||||
parentId: org.id,
|
||||
},
|
||||
});
|
||||
|
||||
const creditService = new CreditService();
|
||||
await creditService.moveCreditsFromTeamToOrg({ teamId, orgId: org.id });
|
||||
} catch (error) {
|
||||
log.error(
|
||||
"Error while moving team to organization",
|
||||
|
||||
Reference in new issue
Block a user