2026-10-15 10:48:30 +03:30
|
|
|
import type { Prisma } from '@prisma/client';
|
|
|
|
|
import type { Actor } from './record-scope';
|
|
|
|
|
|
|
|
|
|
export const PRIOR_IMPORT_SOURCE = 'didar';
|
|
|
|
|
|
|
|
|
|
export type PriorLens = 'off' | 'current' | 'archive';
|
|
|
|
|
|
|
|
|
|
export function actorPriorLens(actor: Pick<Actor, 'priorLens'> | undefined): PriorLens {
|
|
|
|
|
return actor?.priorLens ?? 'off';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function liveDeal(now: Date): Prisma.DealWhereInput {
|
|
|
|
|
return {
|
|
|
|
|
importSource: PRIOR_IMPORT_SOURCE,
|
|
|
|
|
status: 'open',
|
|
|
|
|
expectedCloseAt: { gt: now },
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function liveActivity(now: Date): Prisma.ActivityWhereInput {
|
|
|
|
|
return {
|
|
|
|
|
importSource: PRIOR_IMPORT_SOURCE,
|
|
|
|
|
status: 'open',
|
|
|
|
|
dueAt: { gt: now },
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-15 12:34:40 +03:30
|
|
|
/** فعالیت باز با موعد آینده، حتی اگر قبلی باشد، در کار جاری میماند. */
|
|
|
|
|
function stillOpenAhead(now: Date): Prisma.ActivityWhereInput {
|
|
|
|
|
return { status: 'open', dueAt: { gt: now } };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* فعالیت قبلی است اگر منبعش didar باشد،
|
|
|
|
|
* یا قبل از روشن شدن ماژول ساخته شده و به شخص/شرکت/معاملهٔ قبلی وصل باشد.
|
|
|
|
|
* معاملهٔ غیرقبلی مانع نمیشود؛ شخص قبلی (حتی اگر بعداً منبعش عوض شده) کافی است.
|
2026-10-15 13:02:01 +03:30
|
|
|
* فعالیت بدون شخص و شرکت و معامله هم اگر موعدش قبل از همان لحظه باشد قبلی است.
|
2026-10-15 12:34:40 +03:30
|
|
|
*/
|
|
|
|
|
function historicalActivity(cutoff: Date): Prisma.ActivityWhereInput {
|
|
|
|
|
return {
|
|
|
|
|
OR: [
|
|
|
|
|
{ importSource: PRIOR_IMPORT_SOURCE },
|
|
|
|
|
{
|
|
|
|
|
createdAt: { lt: cutoff },
|
|
|
|
|
OR: [
|
|
|
|
|
{
|
|
|
|
|
person: {
|
|
|
|
|
OR: [
|
|
|
|
|
{ importSource: PRIOR_IMPORT_SOURCE },
|
|
|
|
|
{ previousImportSource: PRIOR_IMPORT_SOURCE },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{ company: { importSource: PRIOR_IMPORT_SOURCE } },
|
|
|
|
|
{ deal: { importSource: PRIOR_IMPORT_SOURCE } },
|
2026-10-15 13:02:01 +03:30
|
|
|
{
|
|
|
|
|
personId: null,
|
|
|
|
|
companyId: null,
|
|
|
|
|
dealId: null,
|
|
|
|
|
dueAt: { lt: cutoff },
|
|
|
|
|
},
|
2026-10-15 12:34:40 +03:30
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-15 10:48:30 +03:30
|
|
|
export function personPriorWhere(lens: PriorLens | undefined): Prisma.PersonWhereInput {
|
|
|
|
|
if (lens === 'archive') return { importSource: PRIOR_IMPORT_SOURCE };
|
|
|
|
|
if (lens === 'current') return { importSource: { not: PRIOR_IMPORT_SOURCE } };
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function companyPriorWhere(lens: PriorLens | undefined): Prisma.CompanyWhereInput {
|
|
|
|
|
if (lens === 'archive') return { importSource: PRIOR_IMPORT_SOURCE };
|
|
|
|
|
if (lens === 'current') return { importSource: { not: PRIOR_IMPORT_SOURCE } };
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function dealPriorWhere(lens: PriorLens | undefined, now = new Date()): Prisma.DealWhereInput {
|
|
|
|
|
if (lens === 'current') {
|
|
|
|
|
return { OR: [{ importSource: { not: PRIOR_IMPORT_SOURCE } }, liveDeal(now)] };
|
|
|
|
|
}
|
|
|
|
|
if (lens === 'archive') {
|
|
|
|
|
return { importSource: PRIOR_IMPORT_SOURCE, NOT: liveDeal(now) };
|
|
|
|
|
}
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function activityPriorWhere(
|
|
|
|
|
lens: PriorLens | undefined,
|
|
|
|
|
now = new Date(),
|
2026-10-15 12:34:40 +03:30
|
|
|
cutoff?: Date | null,
|
2026-10-15 10:48:30 +03:30
|
|
|
): Prisma.ActivityWhereInput {
|
2026-10-15 12:34:40 +03:30
|
|
|
if (lens !== 'current' && lens !== 'archive') return {};
|
|
|
|
|
if (!cutoff) {
|
|
|
|
|
if (lens === 'current') {
|
|
|
|
|
return { OR: [{ importSource: { not: PRIOR_IMPORT_SOURCE } }, liveActivity(now)] };
|
|
|
|
|
}
|
2026-10-15 10:48:30 +03:30
|
|
|
return { importSource: PRIOR_IMPORT_SOURCE, NOT: liveActivity(now) };
|
|
|
|
|
}
|
2026-10-15 12:34:40 +03:30
|
|
|
const prior = historicalActivity(cutoff);
|
|
|
|
|
const live = stillOpenAhead(now);
|
|
|
|
|
if (lens === 'current') return { OR: [{ NOT: prior }, live] };
|
|
|
|
|
return { AND: [prior, { NOT: live }] };
|
2026-10-15 10:48:30 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** فهرست شخص/شرکت: در کار جاری، جستجو و فیلتر صریح منبع، قبلیها را هم پیدا میکند. */
|
|
|
|
|
export function listPriorLens(
|
|
|
|
|
lens: PriorLens | undefined,
|
|
|
|
|
q: string | undefined,
|
|
|
|
|
explicitSource: boolean,
|
|
|
|
|
): PriorLens {
|
|
|
|
|
if (explicitSource) return 'off';
|
|
|
|
|
if (lens === 'current' && q?.trim()) return 'off';
|
|
|
|
|
return lens ?? 'off';
|
|
|
|
|
}
|