diff --git a/packages/twenty-server/src/engine/core-modules/billing/services/billing-subscription.service.ts b/packages/twenty-server/src/engine/core-modules/billing/services/billing-subscription.service.ts index f045556a4..e1550c750 100644 --- a/packages/twenty-server/src/engine/core-modules/billing/services/billing-subscription.service.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/services/billing-subscription.service.ts @@ -17,7 +17,6 @@ import { BillingPrice } from 'src/engine/core-modules/billing/entities/billing-p import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity'; import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; import { BillingEntitlementKey } from 'src/engine/core-modules/billing/enums/billing-entitlement-key.enum'; -import { BillingPlanKey } from 'src/engine/core-modules/billing/enums/billing-plan-key.enum'; import { SubscriptionInterval } from 'src/engine/core-modules/billing/enums/billing-subscription-interval.enum'; import { SubscriptionStatus } from 'src/engine/core-modules/billing/enums/billing-subscription-status.enum'; import { BillingPlanService } from 'src/engine/core-modules/billing/services/billing-plan.service'; @@ -63,26 +62,29 @@ export class BillingSubscriptionService { { workspaceId }, ); - const getStripeProductId = ( - await this.billingPlanService.getPlanBaseProduct(BillingPlanKey.PRO) - )?.stripeProductId; + const planKey = getPlanKeyFromSubscription(billingSubscription); - if (!getStripeProductId) { + const baseProduct = + await this.billingPlanService.getPlanBaseProduct(planKey); + + if (!baseProduct) { throw new BillingException( 'Base product not found', BillingExceptionCode.BILLING_PRODUCT_NOT_FOUND, ); } + const stripeProductId = baseProduct.stripeProductId; + const billingSubscriptionItem = billingSubscription.billingSubscriptionItems.filter( (billingSubscriptionItem) => - billingSubscriptionItem.stripeProductId === getStripeProductId, + billingSubscriptionItem.stripeProductId === stripeProductId, )?.[0]; if (!billingSubscriptionItem) { throw new Error( - `Cannot find billingSubscriptionItem for product ${getStripeProductId} for workspace ${workspaceId}`, + `Cannot find billingSubscriptionItem for product ${stripeProductId} for workspace ${workspaceId}`, ); } diff --git a/packages/twenty-server/src/engine/core-modules/workspace/__tests__/workspace.service.spec.ts b/packages/twenty-server/src/engine/core-modules/workspace/__tests__/workspace.service.spec.ts index 7cfbc3cb3..46cbb3343 100644 --- a/packages/twenty-server/src/engine/core-modules/workspace/__tests__/workspace.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/__tests__/workspace.service.spec.ts @@ -34,6 +34,7 @@ describe('WorkspaceService', () => { let workspaceCacheStorageService: WorkspaceCacheStorageService; let messageQueueService: MessageQueueService; let customDomainService: CustomDomainService; + let billingSubscriptionService: BillingSubscriptionService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -61,6 +62,18 @@ describe('WorkspaceService', () => { softDelete: jest.fn(), }, }, + { + provide: BillingService, + useValue: { + isBillingEnabled: jest.fn().mockReturnValue(true), + }, + }, + { + provide: BillingSubscriptionService, + useValue: { + deleteSubscriptions: jest.fn(), + }, + }, ...[ WorkspaceManagerService, WorkspaceManagerService, @@ -68,8 +81,6 @@ describe('WorkspaceService', () => { UserService, DomainManagerService, CustomDomainService, - BillingSubscriptionService, - BillingService, EnvironmentService, EmailService, OnboardingService, @@ -115,6 +126,9 @@ describe('WorkspaceService', () => { ); customDomainService = module.get(CustomDomainService); customDomainService.deleteCustomHostnameByHostnameSilently = jest.fn(); + billingSubscriptionService = module.get( + BillingSubscriptionService, + ); }); afterEach(() => { @@ -220,8 +234,11 @@ describe('WorkspaceService', () => { .spyOn(workspaceRepository, 'findOne') .mockResolvedValue(mockWorkspace); jest.spyOn(userWorkspaceRepository, 'find').mockResolvedValue([]); + await service.deleteWorkspace(mockWorkspace.id, true); + expect(billingSubscriptionService.deleteSubscriptions).toHaveBeenCalled; + expect(workspaceRepository.softDelete).toHaveBeenCalledWith({ id: mockWorkspace.id, }); diff --git a/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts b/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts index 69dab2db6..b46c39e15 100644 --- a/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts @@ -334,6 +334,10 @@ export class WorkspaceService extends TypeOrmQueryService { ); if (softDelete) { + if (this.billingService.isBillingEnabled()) { + await this.billingSubscriptionService.deleteSubscriptions(workspace.id); + } + await this.workspaceRepository.softDelete({ id }); this.logger.log(`workspace ${id} soft deleted`);