mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 11:08:12 +00:00
102 lines
3.0 KiB
TypeScript
102 lines
3.0 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { Repository } from 'typeorm';
|
|
import { BaseRepository } from '@edr/api-common';
|
|
import { Company } from './entities/company.entity';
|
|
import { ListCompaniesQueryDto } from './dto/list-companies-query.dto';
|
|
import { CompanyStatsResponseDto } from './dto/company-stats-response.dto';
|
|
|
|
@Injectable()
|
|
export class CompaniesRepository extends BaseRepository<Company> {
|
|
constructor(
|
|
@InjectRepository(Company)
|
|
repo: Repository<Company>,
|
|
) {
|
|
super(repo);
|
|
}
|
|
|
|
async findByTin(tin: string): Promise<Company | null> {
|
|
return this.repository.findOne({ where: { tin } as any });
|
|
}
|
|
|
|
async findByType(type: string): Promise<Company[]> {
|
|
return this.repository.find({ where: { type } as any, order: { name: 'ASC' } });
|
|
}
|
|
|
|
async findByName(name: string): Promise<Company[]> {
|
|
return this.repository
|
|
.createQueryBuilder('company')
|
|
.where('company.name ILIKE :name', { name: `%${name}%` })
|
|
.getMany();
|
|
}
|
|
|
|
async existsByTin(tin: string): Promise<boolean> {
|
|
const count = await this.repository.count({ where: { tin } as any });
|
|
return count > 0;
|
|
}
|
|
|
|
async findPaginated(
|
|
query: ListCompaniesQueryDto,
|
|
): Promise<{ items: Company[]; total: number }> {
|
|
const { page = 1, pageSize = 20, search, type, status } = query;
|
|
|
|
const qb = this.repository
|
|
.createQueryBuilder('company')
|
|
.leftJoinAndSelect('company.companyProfiles', 'companyProfiles')
|
|
.where('company.deleted_at IS NULL');
|
|
|
|
if (type) {
|
|
qb.andWhere('company.type = :type', { type });
|
|
}
|
|
|
|
if (status) {
|
|
qb.andWhere('company.status = :status', { status });
|
|
}
|
|
|
|
if (search) {
|
|
const term = `%${search.trim()}%`;
|
|
qb.andWhere(
|
|
`(company.name ILIKE :term
|
|
OR company.tin ILIKE :term
|
|
OR company.email ILIKE :term
|
|
OR EXISTS (
|
|
SELECT 1 FROM freight.company_profiles cp
|
|
WHERE cp.company_id = company.id
|
|
AND cp.reference ILIKE :term
|
|
AND cp.deleted_at IS NULL
|
|
))`,
|
|
{ term },
|
|
);
|
|
}
|
|
|
|
const [items, total] = await qb
|
|
.orderBy('company.name', 'ASC')
|
|
.skip((page - 1) * pageSize)
|
|
.take(pageSize)
|
|
.getManyAndCount();
|
|
|
|
return { items, total };
|
|
}
|
|
|
|
async getStats(): Promise<CompanyStatsResponseDto> {
|
|
const rows: { status: string; count: string }[] = await this.repository
|
|
.createQueryBuilder('company')
|
|
.select('company.status', 'status')
|
|
.addSelect('COUNT(*)', 'count')
|
|
.where('company.deleted_at IS NULL')
|
|
.groupBy('company.status')
|
|
.getRawMany();
|
|
|
|
const map = new Map(rows.map((r) => [r.status, parseInt(r.count, 10)]));
|
|
const total = rows.reduce((sum, r) => sum + parseInt(r.count, 10), 0);
|
|
|
|
return {
|
|
total,
|
|
active: map.get('active') ?? 0,
|
|
pending: map.get('pending') ?? 0,
|
|
suspended: map.get('suspended') ?? 0,
|
|
blacklisted: map.get('blacklisted') ?? 0,
|
|
};
|
|
}
|
|
}
|