fix(crm): mesghal by metal, jalali fit, scoped group filters

This commit is contained in:
2026-10-24 22:25:27 +03:30
parent f8128ebe3a
commit 48815852fc
8 changed files with 202 additions and 27 deletions
@@ -51,6 +51,11 @@ export class CompaniesController {
);
}
@Get('group-stats')
groupStats(@CurrentUser() user: Actor) {
return this.companiesService.groupStats(user);
}
@Get('export')
async export(
@CurrentUser() user: Actor,
@@ -6,6 +6,7 @@ import {
import type {
CompanyDto,
CreateCompanyRequest,
CustomerGroupDto,
PaginatedResponse,
UpdateCompanyRequest,
} from '@mento/shared';
@@ -135,6 +136,38 @@ export class CompaniesService {
};
}
/** آمار گروه برای فیلتر شرکت‌ها — فقط شرکت‌های در دسترس کاربر */
async groupStats(actor: Actor): Promise<CustomerGroupDto[]> {
const counts = await this.prisma.companyGroupLink.groupBy({
by: ['groupId'],
where: {
company: {
organizationId: actor.organizationId,
...customersCompanyWhere(actor),
},
},
_count: { _all: true },
});
if (!counts.length) return [];
const countMap = new Map(counts.map((c) => [c.groupId, c._count._all]));
const groups = await this.prisma.customerGroup.findMany({
where: {
organizationId: actor.organizationId,
id: { in: counts.map((c) => c.groupId) },
},
orderBy: [{ position: 'asc' }, { name: 'asc' }],
});
return groups.map((g) => ({
id: g.id,
name: g.name,
color: g.color,
position: g.position,
fromTahesab: Boolean(g.tahesabGid),
personCount: 0,
companyCount: countMap.get(g.id) ?? 0,
}));
}
async get(actor: Actor, id: string): Promise<CompanyDto> {
const row = await this.prisma.company.findFirst({
where: { id, organizationId: actor.organizationId, ...customersCompanyWhere(actor) },
@@ -89,6 +89,11 @@ export class PeopleController {
return this.peopleService.sourceStats(user);
}
@Get('group-stats')
groupStats(@CurrentUser() user: Actor) {
return this.peopleService.groupStats(user);
}
@Get('export')
async export(
@CurrentUser() user: Actor,
+33
View File
@@ -10,6 +10,7 @@ import {
} from '@nestjs/common';
import type {
CreatePersonRequest,
CustomerGroupDto,
FilteredIdsResponse,
PaginatedResponse,
PersonDto,
@@ -303,6 +304,38 @@ export class PeopleService implements OnModuleInit {
.sort((a, b) => b.count - a.count);
}
/** آمار گروه برای فیلتر اشخاص — فقط افراد در دسترس کاربر */
async groupStats(actor: Actor): Promise<CustomerGroupDto[]> {
const counts = await this.prisma.personGroupLink.groupBy({
by: ['groupId'],
where: {
person: {
organizationId: actor.organizationId,
...customersPersonWhere(actor),
},
},
_count: { _all: true },
});
if (!counts.length) return [];
const countMap = new Map(counts.map((c) => [c.groupId, c._count._all]));
const groups = await this.prisma.customerGroup.findMany({
where: {
organizationId: actor.organizationId,
id: { in: counts.map((c) => c.groupId) },
},
orderBy: [{ position: 'asc' }, { name: 'asc' }],
});
return groups.map((g) => ({
id: g.id,
name: g.name,
color: g.color,
position: g.position,
fromTahesab: Boolean(g.tahesabGid),
personCount: countMap.get(g.id) ?? 0,
companyCount: 0,
}));
}
onModuleInit() {
void this.backfillStoredBirthDates();
}