Implement WHMCS Addon Dashboard with API for stats and integrate billing provider logic
This commit is contained in:
84
apps/api/src/integrations/whmcs/whmcs-dashboard.service.ts
Normal file
84
apps/api/src/integrations/whmcs/whmcs-dashboard.service.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import type { WhmcsDashboardStatsResponse } from '@hexahost/contracts';
|
||||
|
||||
import { getBillingProvider } from '../../billing/billing-provider';
|
||||
import { PrismaService } from '../../prisma/prisma.service';
|
||||
|
||||
type InstallationRef = {
|
||||
id: string;
|
||||
integrationId: string;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class WhmcsDashboardService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async getStats(installation: InstallationRef): Promise<WhmcsDashboardStatsResponse> {
|
||||
const [
|
||||
linkedClients,
|
||||
linkedServices,
|
||||
pendingEvents,
|
||||
deadLetterEvents,
|
||||
openIssues,
|
||||
exportedUsagePeriods,
|
||||
syncCursor,
|
||||
lastReconciledLink,
|
||||
] = await Promise.all([
|
||||
this.prisma.whmcsClientLink.count({
|
||||
where: { installationId: installation.id },
|
||||
}),
|
||||
this.prisma.whmcsServiceLink.count({
|
||||
where: { installationId: installation.id },
|
||||
}),
|
||||
this.prisma.integrationEvent.count({
|
||||
where: { installationId: installation.id, status: 'PENDING' },
|
||||
}),
|
||||
this.prisma.integrationEvent.count({
|
||||
where: { installationId: installation.id, status: 'DEAD_LETTER' },
|
||||
}),
|
||||
this.prisma.reconciliationIssue.count({
|
||||
where: { installationId: installation.id, resolvedAt: null },
|
||||
}),
|
||||
this.prisma.whmcsUsageExport.count({
|
||||
where: { installationId: installation.id, status: { in: ['EXPORTED', 'ADJUSTED'] } },
|
||||
}),
|
||||
this.prisma.integrationSyncCursor.findUnique({
|
||||
where: { installationId: installation.id },
|
||||
}),
|
||||
this.prisma.whmcsServiceLink.findFirst({
|
||||
where: {
|
||||
installationId: installation.id,
|
||||
lastReconciledAt: { not: null },
|
||||
},
|
||||
orderBy: { lastReconciledAt: 'desc' },
|
||||
select: { lastReconciledAt: true },
|
||||
}),
|
||||
]);
|
||||
|
||||
const suspendedServices = await this.prisma.whmcsServiceLink.count({
|
||||
where: { installationId: installation.id, status: 'SUSPENDED' },
|
||||
});
|
||||
|
||||
const terminatedServices = await this.prisma.whmcsServiceLink.count({
|
||||
where: { installationId: installation.id, status: 'TERMINATED' },
|
||||
});
|
||||
|
||||
return {
|
||||
integrationId: installation.integrationId,
|
||||
billingProvider: getBillingProvider(),
|
||||
moduleVersion: '1.0.0',
|
||||
linkedClients,
|
||||
linkedServices,
|
||||
suspendedServices,
|
||||
terminatedServices,
|
||||
pendingEvents,
|
||||
deadLetterEvents,
|
||||
openReconciliationIssues: openIssues,
|
||||
exportedUsagePeriods,
|
||||
eventsCursor: syncCursor?.eventsCursor ?? null,
|
||||
lastEventSyncAt: syncCursor?.updatedAt.toISOString() ?? null,
|
||||
lastReconciliationAt: lastReconciledLink?.lastReconciledAt?.toISOString() ?? null,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user