Unified search algorithm across all lists; per-section record visibility (contacts, deals, activities, leads, finance, tickets, notes, projects)
This commit is contained in:
@@ -12,6 +12,7 @@ import type {
|
||||
} from '@mento/shared';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { buildSearchWhere, ci } from '../common/search';
|
||||
import { type Actor, ownerWhere } from '../common/record-scope';
|
||||
|
||||
type QuoteActor = Pick<Actor, 'userId' | 'role'>;
|
||||
@@ -50,21 +51,13 @@ export class QuotesService {
|
||||
const dateFilter = buildDateRangeFilter(opts.from, opts.to);
|
||||
const where: Prisma.QuoteWhereInput = {
|
||||
organizationId,
|
||||
...ownerWhere(actor),
|
||||
...ownerWhere(actor, 'finance'),
|
||||
...(opts.status ? { status: opts.status as never } : {}),
|
||||
...(opts.dealId ? { dealId: opts.dealId } : {}),
|
||||
...(opts.personId ? { personId: opts.personId } : {}),
|
||||
...(opts.companyId ? { companyId: opts.companyId } : {}),
|
||||
...(dateFilter ? dateFilter : {}),
|
||||
...(opts.q?.trim()
|
||||
? {
|
||||
OR: [
|
||||
{ title: { contains: opts.q.trim(), mode: 'insensitive' } },
|
||||
{ number: { contains: opts.q.trim(), mode: 'insensitive' } },
|
||||
{ notes: { contains: opts.q.trim(), mode: 'insensitive' } },
|
||||
],
|
||||
}
|
||||
: {}),
|
||||
...quoteSearchWhere(opts.q),
|
||||
};
|
||||
|
||||
const [rows, total] = await this.prisma.$transaction([
|
||||
@@ -92,7 +85,7 @@ export class QuotesService {
|
||||
actor: QuoteActor,
|
||||
): Promise<QuoteDto> {
|
||||
const row = await this.prisma.quote.findFirst({
|
||||
where: { id, organizationId, ...ownerWhere(actor) },
|
||||
where: { id, organizationId, ...ownerWhere(actor, 'finance') },
|
||||
include,
|
||||
});
|
||||
if (!row) throw new NotFoundException('پیشفاکتور پیدا نشد');
|
||||
@@ -295,7 +288,7 @@ export class QuotesService {
|
||||
actor: QuoteActor,
|
||||
) {
|
||||
const found = await this.prisma.quote.findFirst({
|
||||
where: { id, organizationId, ...ownerWhere(actor) },
|
||||
where: { id, organizationId, ...ownerWhere(actor, 'finance') },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!found) throw new NotFoundException('پیشفاکتور پیدا نشد');
|
||||
@@ -413,6 +406,21 @@ function roundMoney(value: number): number {
|
||||
return Math.round((value + Number.EPSILON) * 100) / 100;
|
||||
}
|
||||
|
||||
function quoteSearchWhere(q?: string): Prisma.QuoteWhereInput {
|
||||
const search = buildSearchWhere<Prisma.QuoteWhereInput>(q, (t) => [
|
||||
{ title: ci(t) },
|
||||
{ number: ci(t) },
|
||||
{ notes: ci(t) },
|
||||
{
|
||||
person: {
|
||||
OR: [{ firstName: ci(t) }, { lastName: ci(t) }, { mobile: { contains: t } }],
|
||||
},
|
||||
},
|
||||
{ company: { name: ci(t) } },
|
||||
]);
|
||||
return search ? { AND: [search] } : {};
|
||||
}
|
||||
|
||||
function buildDateRangeFilter(
|
||||
from?: string,
|
||||
to?: string,
|
||||
|
||||
Reference in New Issue
Block a user