diff --git a/packages/server/src/modules/ee/Workspaces/Workspaces.module.ts b/packages/server/src/modules/ee/Workspaces/Workspaces.module.ts index d3328f2fc..83cf343b1 100644 --- a/packages/server/src/modules/ee/Workspaces/Workspaces.module.ts +++ b/packages/server/src/modules/ee/Workspaces/Workspaces.module.ts @@ -7,7 +7,6 @@ import { DeleteWorkspaceJobService } from './commands/DeleteWorkspaceJob.service import { InactivateWorkspaceService } from './commands/InactivateWorkspace.service'; import { SetDefaultWorkspaceService } from './commands/SetDefaultWorkspace.service'; import { GetWorkspacesService } from './queries/GetWorkspaces.service'; -import { GetWorkspacesFinancialService } from './queries/GetWorkspacesFinancial.service'; import { GetWorkspaceBuildJobService } from './queries/GetWorkspaceBuildJob.service'; import { CreateUserTenantOnSignupSubscriber } from './subscribers/CreateUserTenantOnSignup.subscriber'; import { WorkspaceCreatedSubscriber } from './subscribers/WorkspaceCreated.subscriber'; @@ -47,7 +46,6 @@ import { WorkspaceDeletedSubscriber } from './subscribers/WorkspaceDeleted.subsc InactivateWorkspaceService, SetDefaultWorkspaceService, GetWorkspacesService, - GetWorkspacesFinancialService, GetWorkspaceBuildJobService, CreateUserTenantOnSignupSubscriber, WorkspaceCreatedSubscriber, diff --git a/packages/server/src/modules/ee/Workspaces/commands/CreateWorkspace.service.spec.ts b/packages/server/src/modules/ee/Workspaces/commands/CreateWorkspace.service.spec.ts deleted file mode 100644 index 1e8e9b842..000000000 --- a/packages/server/src/modules/ee/Workspaces/commands/CreateWorkspace.service.spec.ts +++ /dev/null @@ -1,382 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { EventEmitter2 } from '@nestjs/event-emitter'; -import { CreateWorkspaceService } from './CreateWorkspace.service'; -import { UserTenant } from '@/modules/System/models/UserTenant.model'; -import { TenantRepository } from '@/modules/System/repositories/Tenant.repository'; -import { BuildOrganizationService } from '@/modules/Organization/commands/BuildOrganization.service'; -import { SystemKnexConnection } from '@/modules/System/SystemDB/SystemDB.constants'; -import { events } from '@/common/events/events'; - -// Mock the Organization.utils module -jest.mock('@/modules/Organization/Organization.utils', () => ({ - transformBuildDto: jest.fn((dto) => ({ - ...dto, - dateFormat: dto.dateFormat || 'DD MMM YYYY', - })), -})); - -describe('CreateWorkspaceService', () => { - let service: CreateWorkspaceService; - let tenantRepository: jest.Mocked; - let userTenantModel: jest.Mocked; - let mockBuildOrganizationService: jest.Mocked; - let mockEventEmitter: jest.Mocked; - let mockKnexTransaction: jest.Mock; - - const mockTenant = { - id: 1, - organizationId: 'org_abc123', - initializedAt: null, - seededAt: null, - builtAt: null, - buildJobId: null, - }; - - const createMockQuery = () => ({ - insert: jest.fn().mockResolvedValue({ id: 1, userId: 1, tenantId: 1, role: 'owner' }), - findById: jest.fn().mockResolvedValue(mockTenant), - update: jest.fn().mockReturnThis(), - where: jest.fn().mockReturnThis(), - }); - - beforeEach(async () => { - const mockQuery = createMockQuery(); - - const mockUserTenantModel = { - query: jest.fn().mockReturnValue(mockQuery), - }; - - const mockTenantRepository = { - createWithUniqueOrgId: jest.fn().mockResolvedValue(mockTenant), - saveMetadata: jest.fn().mockResolvedValue(undefined), - markAsBuilding: jest.fn().mockReturnThis(), - findById: jest.fn().mockResolvedValue(mockTenant), - }; - - // Mock build organization service - mockBuildOrganizationService = { - buildForTenant: jest.fn().mockResolvedValue(undefined), - } as any; - - // Mock event emitter - mockEventEmitter = { - emitAsync: jest.fn().mockResolvedValue([]), - } as any; - - // Mock knex transaction - mockKnexTransaction = jest.fn(async (callback) => { - const trx = {}; - return callback(trx); - }); - - const mockSystemKnex = { - transaction: mockKnexTransaction, - }; - - const module: TestingModule = await Test.createTestingModule({ - providers: [ - CreateWorkspaceService, - { - provide: UserTenant.name, - useValue: mockUserTenantModel, - }, - { - provide: TenantRepository, - useValue: mockTenantRepository, - }, - { - provide: BuildOrganizationService, - useValue: mockBuildOrganizationService, - }, - { - provide: SystemKnexConnection, - useValue: mockSystemKnex, - }, - { - provide: EventEmitter2, - useValue: mockEventEmitter, - }, - ], - }).compile(); - - service = module.get(CreateWorkspaceService); - tenantRepository = module.get(TenantRepository); - userTenantModel = module.get(UserTenant.name); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - describe('createWorkspace', () => { - const userId = 1; - const dto = { - name: 'Test Organization', - baseCurrency: 'USD', - location: 'US', - timezone: 'America/New_York', - fiscalYear: 'January', - language: 'en-US', - industry: 'Technology', - }; - - it('should create a workspace successfully', async () => { - const result = await service.createWorkspace(userId, dto); - - expect(result).toEqual({ - organizationId: mockTenant.organizationId, - jobId: null, - }); - }); - - it('should wrap database operations in a transaction', async () => { - await service.createWorkspace(userId, dto); - - expect(mockKnexTransaction).toHaveBeenCalledTimes(1); - }); - - it('should create a new tenant with unique organization id within transaction', async () => { - await service.createWorkspace(userId, dto); - - expect(tenantRepository.createWithUniqueOrgId).toHaveBeenCalledTimes(1); - expect(tenantRepository.createWithUniqueOrgId).toHaveBeenCalledWith(undefined, expect.anything()); - }); - - it('should link the user as owner of the workspace within transaction', async () => { - await service.createWorkspace(userId, dto); - - expect(userTenantModel.query).toHaveBeenCalled(); - // First call should be with the transaction object - expect(userTenantModel.query.mock.calls[0][0]).toBeDefined(); - }); - - it('should save organization metadata within transaction', async () => { - await service.createWorkspace(userId, dto); - - expect(tenantRepository.saveMetadata).toHaveBeenCalledWith( - mockTenant.id, - expect.objectContaining({ - name: dto.name, - baseCurrency: dto.baseCurrency, - location: dto.location, - timezone: dto.timezone, - fiscalYear: dto.fiscalYear, - language: dto.language, - industry: dto.industry, - dateFormat: 'DD MMM YYYY', - }), - expect.anything(), // transaction object - ); - }); - - it('should call buildForTenant after transaction commit', async () => { - await service.createWorkspace(userId, dto); - - expect(mockBuildOrganizationService.buildForTenant).toHaveBeenCalledWith( - mockTenant.id, - userId, - expect.objectContaining({ - name: dto.name, - baseCurrency: dto.baseCurrency, - location: dto.location, - timezone: dto.timezone, - fiscalYear: dto.fiscalYear, - language: dto.language, - industry: dto.industry, - dateFormat: 'DD MMM YYYY', - }), - ); - }); - - it('should return organization id with null job id', async () => { - const result = await service.createWorkspace(userId, dto); - - expect(result).toHaveProperty('organizationId'); - expect(result).toHaveProperty('jobId'); - expect(result.organizationId).toBe(mockTenant.organizationId); - expect(result.jobId).toBeNull(); - }); - - it('should handle tenant creation failure and rollback transaction', async () => { - tenantRepository.createWithUniqueOrgId.mockRejectedValueOnce( - new Error('Database error'), - ); - - await expect(service.createWorkspace(userId, dto)).rejects.toThrow( - 'Database error', - ); - }); - - it('should handle user tenant linking failure and rollback transaction', async () => { - const mockQuery = createMockQuery(); - mockQuery.insert.mockRejectedValueOnce(new Error('Linking error')); - userTenantModel.query.mockReturnValueOnce(mockQuery); - - await expect(service.createWorkspace(userId, dto)).rejects.toThrow( - 'Linking error', - ); - }); - - it('should handle metadata save failure and rollback transaction', async () => { - tenantRepository.saveMetadata.mockRejectedValueOnce( - new Error('Metadata save error'), - ); - - await expect(service.createWorkspace(userId, dto)).rejects.toThrow( - 'Metadata save error', - ); - }); - - it('should not call buildForTenant if transaction fails', async () => { - tenantRepository.createWithUniqueOrgId.mockRejectedValueOnce( - new Error('Database error'), - ); - - await expect(service.createWorkspace(userId, dto)).rejects.toThrow( - 'Database error', - ); - - expect(mockBuildOrganizationService.buildForTenant).not.toHaveBeenCalled(); - }); - - it('should handle buildForTenant failure after successful transaction', async () => { - mockBuildOrganizationService.buildForTenant.mockRejectedValueOnce( - new Error('Build error'), - ); - - // Transaction should succeed but then build should fail - await expect(service.createWorkspace(userId, dto)).rejects.toThrow( - 'Build error', - ); - - // Transaction should have completed - expect(tenantRepository.createWithUniqueOrgId).toHaveBeenCalled(); - }); - - it('should work with minimal DTO (only required fields)', async () => { - const minimalDto = { - name: 'Minimal Org', - baseCurrency: 'EUR', - location: 'DE', - timezone: 'Europe/Berlin', - fiscalYear: 'January', - language: 'en-US', - }; - - const result = await service.createWorkspace(userId, minimalDto); - - expect(result.organizationId).toBe(mockTenant.organizationId); - expect(tenantRepository.saveMetadata).toHaveBeenCalledWith( - mockTenant.id, - expect.objectContaining({ - name: minimalDto.name, - baseCurrency: minimalDto.baseCurrency, - location: minimalDto.location, - timezone: minimalDto.timezone, - fiscalYear: minimalDto.fiscalYear, - language: minimalDto.language, - dateFormat: 'DD MMM YYYY', - }), - expect.anything(), - ); - }); - - it('should preserve custom date format if provided', async () => { - const dtoWithDateFormat = { - ...dto, - dateFormat: 'MM/DD/YYYY', - }; - - await service.createWorkspace(userId, dtoWithDateFormat); - - expect(tenantRepository.saveMetadata).toHaveBeenCalledWith( - mockTenant.id, - expect.objectContaining({ - dateFormat: 'MM/DD/YYYY', - }), - expect.anything(), - ); - }); - - it('should call all operations in correct sequence', async () => { - const callOrder: string[] = []; - - (tenantRepository.createWithUniqueOrgId as jest.Mock).mockImplementationOnce(async () => { - callOrder.push('createTenant'); - return mockTenant; - }); - (userTenantModel.query as jest.Mock).mockImplementationOnce(() => { - callOrder.push('linkUser'); - return { - insert: jest.fn().mockResolvedValue({ id: 1 }), - }; - }); - (tenantRepository.saveMetadata as jest.Mock).mockImplementationOnce(async () => { - callOrder.push('saveMetadata'); - return 1; - }); - - mockKnexTransaction.mockImplementationOnce(async (callback) => { - const trx = {}; - await callback(trx); - callOrder.push('transactionCommitted'); - return mockTenant; - }); - - (mockEventEmitter.emitAsync as jest.Mock).mockImplementationOnce(async () => { - callOrder.push('emitEvent'); - return []; - }); - - (mockBuildOrganizationService.buildForTenant as jest.Mock).mockImplementationOnce(async () => { - callOrder.push('buildForTenant'); - }); - - await service.createWorkspace(userId, dto); - - expect(callOrder).toEqual(['createTenant', 'linkUser', 'saveMetadata', 'transactionCommitted', 'emitEvent', 'buildForTenant']); - }); - - it('should emit workspace created event after transaction commit', async () => { - await service.createWorkspace(userId, dto); - - expect(mockEventEmitter.emitAsync).toHaveBeenCalledWith( - events.workspace.created, - expect.objectContaining({ - tenantId: mockTenant.id, - organizationId: mockTenant.organizationId, - userId, - buildDTO: expect.objectContaining({ - name: dto.name, - baseCurrency: dto.baseCurrency, - location: dto.location, - }), - }), - ); - }); - - it('should emit event after transaction commit and before build', async () => { - const callOrder: string[] = []; - - mockKnexTransaction.mockImplementationOnce(async (callback) => { - const trx = {}; - const result = await callback(trx); - callOrder.push('transactionCommitted'); - return result; - }); - - (mockEventEmitter.emitAsync as jest.Mock).mockImplementationOnce(async () => { - callOrder.push('emitEvent'); - return []; - }); - - (mockBuildOrganizationService.buildForTenant as jest.Mock).mockImplementationOnce(async () => { - callOrder.push('buildForTenant'); - }); - - await service.createWorkspace(userId, dto); - - expect(callOrder).toEqual(['transactionCommitted', 'emitEvent', 'buildForTenant']); - }); - }); -}); diff --git a/packages/server/src/modules/ee/Workspaces/commands/InactivateWorkspace.service.ts b/packages/server/src/modules/ee/Workspaces/commands/InactivateWorkspace.service.ts index 23f22c165..e8384cea2 100644 --- a/packages/server/src/modules/ee/Workspaces/commands/InactivateWorkspace.service.ts +++ b/packages/server/src/modules/ee/Workspaces/commands/InactivateWorkspace.service.ts @@ -68,7 +68,6 @@ export class InactivateWorkspaceService { if (!membership) { throw new ServiceError(WorkspacesError.WORKSPACE_NOT_FOUND, 'Workspace not found'); } - if (membership.role !== 'owner') { throw new ServiceError( WorkspacesError.NOT_WORKSPACE_OWNER, diff --git a/packages/server/src/modules/ee/Workspaces/queries/GetWorkspaces.service.ts b/packages/server/src/modules/ee/Workspaces/queries/GetWorkspaces.service.ts index ab1a85553..1bbbcc561 100644 --- a/packages/server/src/modules/ee/Workspaces/queries/GetWorkspaces.service.ts +++ b/packages/server/src/modules/ee/Workspaces/queries/GetWorkspaces.service.ts @@ -3,7 +3,6 @@ import { UserTenant } from '@/modules/System/models/UserTenant.model'; import { SystemUser } from '@/modules/System/models/SystemUser'; import { WorkspaceDto } from '../dtos/WorkspaceResponse.dto'; import { WorkspaceTransformer } from '../transformers/WorkspaceTransformer'; -import { GetWorkspacesFinancialService } from './GetWorkspacesFinancial.service'; import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service'; @Injectable() @@ -15,7 +14,6 @@ export class GetWorkspacesService { @Inject(SystemUser.name) private readonly systemUserModel: typeof SystemUser, - private readonly financialService: GetWorkspacesFinancialService, private readonly transformer: TransformerInjectable, ) {} @@ -44,22 +42,11 @@ export class GetWorkspacesService { const defaultTenantId = user?.defaultTenantId; - // Fetch financial data for all workspaces - const workspaceInfos = memberships.map((m) => ({ - tenantId: m.tenantId, - organizationId: m.tenant?.organizationId, - isReady: m.tenant?.isReady ?? false, - })); - - const financialDataMap = - await this.financialService.getWorkspacesFinancial(workspaceInfos); - return this.transformer.transform( memberships, new WorkspaceTransformer(), { defaultTenantId, - financialDataMap, includeInactive, currentOrganizationId, }, diff --git a/packages/server/src/modules/ee/Workspaces/queries/GetWorkspacesFinancial.service.ts b/packages/server/src/modules/ee/Workspaces/queries/GetWorkspacesFinancial.service.ts deleted file mode 100644 index fe20c57ba..000000000 --- a/packages/server/src/modules/ee/Workspaces/queries/GetWorkspacesFinancial.service.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import * as moment from 'moment'; -import { Knex } from 'knex'; -import { ConfigService } from '@nestjs/config'; -import { knexSnakeCaseMappers } from 'objection'; -import { ACCOUNT_TYPE } from '@/constants/accounts'; -import { ACCOUNT_ROOT_TYPE } from '@/modules/Accounts/Accounts.constants'; - -interface WorkspaceFinancialData { - tenantId: number; - totalIncome: number; - totalExpenses: number; - totalAssets: number; - totalLiabilities: number; -} - -interface AccountTransaction { - credit: number; - debit: number; - accountNormal: string; - accountRootType: string; -} - -/** - * Service to retrieve financial data (income and expenses) for multiple workspaces. - * This service creates dynamic connections to tenant databases to fetch aggregated data. - */ -@Injectable() -export class GetWorkspacesFinancialService { - constructor(private readonly configService: ConfigService) {} - - /** - * Get a knex instance for a specific tenant database. - */ - private getTenantKnex(organizationId: string): Knex { - const database = `bigcapital_tenant_${organizationId}`; - - return require('knex')({ - client: this.configService.get('tenantDatabase.client'), - connection: { - host: this.configService.get('tenantDatabase.host'), - user: this.configService.get('tenantDatabase.user'), - password: this.configService.get('tenantDatabase.password'), - database, - charset: 'utf8', - }, - pool: { min: 0, max: 2, acquireTimeoutMillis: 5000, idleTimeoutMillis: 10000 }, - ...knexSnakeCaseMappers({ upperCase: true }), - }); - } - - /** - * Calculate total income from account transactions. - * Income accounts have credit normal, so income = credit - debit. - */ - private calculateIncome(transactions: AccountTransaction[]): number { - return transactions - .filter((t) => t.accountRootType === ACCOUNT_ROOT_TYPE.INCOME) - .reduce((sum, t) => sum + (t.credit - t.debit), 0); - } - - /** - * Calculate total expenses from account transactions. - * Expense accounts have debit normal, so expenses = debit - credit. - */ - private calculateExpenses(transactions: AccountTransaction[]): number { - return transactions - .filter((t) => t.accountRootType === ACCOUNT_ROOT_TYPE.EXPENSE) - .reduce((sum, t) => sum + (t.debit - t.credit), 0); - } - - /** - * Calculate total assets from account transactions. - * Asset accounts have debit normal, so assets = debit - credit. - */ - private calculateAssets(transactions: AccountTransaction[]): number { - return transactions - .filter((t) => t.accountRootType === ACCOUNT_ROOT_TYPE.ASSET) - .reduce((sum, t) => sum + (t.debit - t.credit), 0); - } - - /** - * Calculate total liabilities from account transactions. - * Liability accounts have credit normal, so liabilities = credit - debit. - */ - private calculateLiabilities(transactions: AccountTransaction[]): number { - return transactions - .filter((t) => t.accountRootType === ACCOUNT_ROOT_TYPE.LIABILITY) - .reduce((sum, t) => sum + (t.credit - t.debit), 0); - } - - /** - * Fetch financial data for a single tenant. - */ - private async fetchTenantFinancialData( - tenantId: number, - organizationId: string, - ): Promise { - const knex = this.getTenantKnex(organizationId); - - try { - // Get the current year date range - const fromDate = moment().startOf('year').format('YYYY-MM-DD'); - const toDate = moment().endOf('year').format('YYYY-MM-DD'); - - // Query to get aggregated transactions by account with account type info - const transactions = await knex('accounts_transactions as at') - .join('accounts as a', 'at.account_id', 'a.id') - .whereBetween('at.date', [fromDate, toDate]) - .select( - knex.raw('SUM(at.credit) as credit'), - knex.raw('SUM(at.debit) as debit'), - 'a.account_normal as accountNormal', - 'a.root_type as accountRootType', - ) - .groupBy('at.account_id', 'a.account_normal', 'a.root_type'); - - const totalIncome = this.calculateIncome(transactions); - const totalExpenses = this.calculateExpenses(transactions); - - // Query account transactions for assets and liabilities (cumulative balance) - const assetLiabilityTransactions = await knex('accounts_transactions as at') - .join('accounts as a', 'at.account_id', 'a.id') - .whereIn('a.root_type', [ACCOUNT_ROOT_TYPE.ASSET, ACCOUNT_ROOT_TYPE.LIABILITY]) - .select( - knex.raw('SUM(at.credit) as credit'), - knex.raw('SUM(at.debit) as debit'), - 'a.account_normal as accountNormal', - 'a.root_type as accountRootType', - ) - .groupBy('at.account_id', 'a.account_normal', 'a.root_type'); - - const totalAssets = this.calculateAssets(assetLiabilityTransactions); - const totalLiabilities = this.calculateLiabilities(assetLiabilityTransactions); - - return { - tenantId, - totalIncome: Math.max(0, totalIncome), - totalExpenses: Math.max(0, totalExpenses), - totalAssets, - totalLiabilities, - }; - } catch (error) { - // If tenant database doesn't exist or other error, return zeros - return { - tenantId, - totalIncome: 0, - totalExpenses: 0, - totalAssets: 0, - totalLiabilities: 0, - }; - } finally { - await knex.destroy(); - } - } - - /** - * Get financial data (total income and expenses) for a list of workspaces. - * @param workspaces - Array of workspace info with tenantId and organizationId - * @returns Map of tenantId to financial data - */ - async getWorkspacesFinancial( - workspaces: Array<{ tenantId: number; organizationId: string; isReady: boolean }>, - ): Promise> { - const results = new Map(); - - // Filter only ready workspaces (have initialized databases) - const readyWorkspaces = workspaces.filter((w) => w.isReady); - - // Fetch financial data for each workspace in parallel - const promises = readyWorkspaces.map(async (workspace) => { - const data = await this.fetchTenantFinancialData( - workspace.tenantId, - workspace.organizationId, - ); - return data; - }); - - const financialDataList = await Promise.all(promises); - - // Build the map - financialDataList.forEach((data) => { - results.set(data.tenantId, data); - }); - - // Add zero values for non-ready workspaces - workspaces - .filter((w) => !w.isReady) - .forEach((w) => { - results.set(w.tenantId, { - tenantId: w.tenantId, - totalIncome: 0, - totalExpenses: 0, - totalAssets: 0, - totalLiabilities: 0, - }); - }); - - return results; - } -} diff --git a/packages/server/src/modules/ee/Workspaces/transformers/WorkspaceTransformer.ts b/packages/server/src/modules/ee/Workspaces/transformers/WorkspaceTransformer.ts index 4096a7ebb..233c0579f 100644 --- a/packages/server/src/modules/ee/Workspaces/transformers/WorkspaceTransformer.ts +++ b/packages/server/src/modules/ee/Workspaces/transformers/WorkspaceTransformer.ts @@ -1,15 +1,6 @@ import { Transformer } from '@/modules/Transformer/Transformer'; import { UserTenant } from '@/modules/System/models/UserTenant.model'; import { WorkspaceDto } from '../dtos/WorkspaceResponse.dto'; -import { formatNumber } from '@/utils/format-number'; - -interface FinancialData { - tenantId: number; - totalIncome: number; - totalExpenses: number; - totalAssets: number; - totalLiabilities: number; -} /** * Transforms UserTenant (workspace membership) to WorkspaceDto. @@ -108,67 +99,49 @@ export class WorkspaceTransformer extends Transformer { /** * Get total income from financial data. */ - protected totalIncome = (financialData?: FinancialData): number => { - return financialData?.totalIncome ?? 0; + protected totalIncome = (): undefined => { + return undefined; }; /** * Get total expenses from financial data. */ - protected totalExpenses = (financialData?: FinancialData): number => { - return financialData?.totalExpenses ?? 0; + protected totalExpenses = (): undefined => { + return undefined; }; /** * Get total assets from financial data. */ - protected totalAssets = (financialData?: FinancialData): number => { - return financialData?.totalAssets ?? 0; + protected totalAssets = (): undefined => { + return undefined; }; /** * Get total liabilities from financial data. */ - protected totalLiabilities = (financialData?: FinancialData): number => { - return financialData?.totalLiabilities ?? 0; + protected totalLiabilities = (): undefined => { + return undefined; }; /** * Get formatted total assets. */ - protected formattedTotalAssets = ( - membership: UserTenant, - financialData?: FinancialData, - ): string => { - const currencyCode = membership.tenant?.metadata?.baseCurrency; - return formatNumber(financialData?.totalAssets ?? 0, { - currencyCode, - money: true, - }); + protected formattedTotalAssets = (): string => { + return '-'; }; /** * Get formatted total liabilities. */ - protected formattedTotalLiabilities = ( - membership: UserTenant, - financialData?: FinancialData, - ): string => { - const currencyCode = membership.tenant?.metadata?.baseCurrency; - return formatNumber(financialData?.totalLiabilities ?? 0, { - currencyCode, - money: true, - }); + protected formattedTotalLiabilities = (): string => { + return '-'; }; /** * Transform single membership to WorkspaceDto. */ transform = (membership: UserTenant): WorkspaceDto => { - const financialData = ( - this.options?.financialDataMap as Map - )?.get(membership.tenantId); - return { organizationId: this.organizationId(membership), isReady: this.isReady(membership), @@ -179,15 +152,12 @@ export class WorkspaceTransformer extends Transformer { role: membership.role, isDefault: this.isDefault(membership), metadata: this.metadata(membership), - totalIncome: this.totalIncome(financialData), - totalExpenses: this.totalExpenses(financialData), - totalAssets: this.totalAssets(financialData), - totalLiabilities: this.totalLiabilities(financialData), - formattedTotalAssets: this.formattedTotalAssets(membership, financialData), - formattedTotalLiabilities: this.formattedTotalLiabilities( - membership, - financialData, - ), + totalIncome: this.totalIncome(), + totalExpenses: this.totalExpenses(), + totalAssets: this.totalAssets(), + totalLiabilities: this.totalLiabilities(), + formattedTotalAssets: this.formattedTotalAssets(), + formattedTotalLiabilities: this.formattedTotalLiabilities(), }; };