87 lines
2.8 KiB
TypeScript
87 lines
2.8 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { Repository, Between } from 'typeorm';
|
|
import { Invoice, InvoiceStatus } from '../invoices/entities/invoice.entity';
|
|
import { Company } from '../companies/entities/company.entity';
|
|
|
|
@Injectable()
|
|
export class DashboardService {
|
|
constructor(
|
|
@InjectRepository(Invoice)
|
|
private invoiceRepository: Repository<Invoice>,
|
|
@InjectRepository(Company)
|
|
private companyRepository: Repository<Company>,
|
|
) {}
|
|
|
|
async getStats(tenantId: string) {
|
|
const totalInvoices = await this.invoiceRepository.count({
|
|
where: { tenant_id: tenantId },
|
|
});
|
|
|
|
const approvedInvoices = await this.invoiceRepository.count({
|
|
where: { tenant_id: tenantId, status: InvoiceStatus.APPROVED },
|
|
});
|
|
|
|
const pendingInvoices = await this.invoiceRepository.count({
|
|
where: {
|
|
tenant_id: tenantId,
|
|
status: Buffer.from('approved').toString() === InvoiceStatus.APPROVED ? InvoiceStatus.UPLOADED : InvoiceStatus.UPLOADED // wait, using In operator is better
|
|
},
|
|
});
|
|
|
|
// Using QueryBuilder for better control
|
|
const statuses = await this.invoiceRepository
|
|
.createQueryBuilder('invoice')
|
|
.select('status')
|
|
.addSelect('COUNT(*)', 'count')
|
|
.where('invoice.tenant_id = :tenantId', { tenantId })
|
|
.groupBy('status')
|
|
.getRawMany();
|
|
|
|
const statusMap = statuses.reduce((acc, curr) => {
|
|
acc[curr.status] = parseInt(curr.count);
|
|
return acc;
|
|
}, {});
|
|
|
|
const companiesCount = await this.companyRepository.count({
|
|
where: { tenant_id: tenantId },
|
|
});
|
|
|
|
// Calculate total tax (mock logic for now, should sum up tax fields)
|
|
const invoices = await this.invoiceRepository.find({
|
|
where: { tenant_id: tenantId, status: InvoiceStatus.APPROVED },
|
|
select: ['tax_amount'],
|
|
});
|
|
|
|
const totalTax = invoices.reduce((sum, inv: any) => sum + Number(inv.tax_amount || 0), 0);
|
|
|
|
// Get recent activities (last 5 invoices)
|
|
const recentInvoices = await this.invoiceRepository.find({
|
|
where: { tenant_id: tenantId },
|
|
order: { created_at: 'DESC' },
|
|
take: 5,
|
|
relations: ['company'],
|
|
});
|
|
|
|
const approvedInvoicesCount = statusMap[InvoiceStatus.APPROVED] || 0;
|
|
const processingInvoices = totalInvoices - approvedInvoicesCount;
|
|
|
|
return {
|
|
stats: {
|
|
totalInvoices,
|
|
approvedInvoices: approvedInvoicesCount,
|
|
pendingInvoices: processingInvoices,
|
|
companiesCount,
|
|
totalTax,
|
|
},
|
|
recentActivities: recentInvoices.map(inv => ({
|
|
id: inv.id,
|
|
number: inv.invoice_number || 'قيد الاستخراج...',
|
|
company: inv.company?.name,
|
|
status: inv.status,
|
|
date: inv.created_at,
|
|
})),
|
|
};
|
|
}
|
|
}
|