import { CityName } from "../utils/types"; import { DAY_MS, endOfCalendarDayInTz, startOfCalendarDayInTz, } from "../../utils/date.utils"; import { DEFAULT_LOOKBACK_DAYS } from "./tickets.constants"; import { isDraftTicketExpr, runTicketStatsAggregate, subjectResolutionStages, ticketsWithCallSidMatch, } from "./tickets.statistics.aggregation"; import type { TicketStatsDateRange, TicketStatsDateScope, TicketSubjectRow, } from "./tickets.types"; export const resolveTicketStatsDateRange = ( dateScope?: TicketStatsDateScope, ): TicketStatsDateRange => { const to = dateScope?.to ?? new Date(); const from = dateScope?.from ?? new Date(to.getTime() - DEFAULT_LOOKBACK_DAYS * DAY_MS); return { from, to }; }; export const ticketStatsDateScopeFromYmd = ( startStr: string, endStr: string, timezone: string, ): TicketStatsDateScope => ({ from: startOfCalendarDayInTz(startStr, timezone), to: endOfCalendarDayInTz(endStr, timezone), }); /** @deprecated Use findCallSidTicketCountsByCity instead. */ export const findCallSidsWithTicketsByCity = async ( cityName: CityName, dateScope?: TicketStatsDateScope, ): Promise => { const rows = await runTicketStatsAggregate<{ _id: unknown }>([ { $match: ticketsWithCallSidMatch( cityName, resolveTicketStatsDateRange(dateScope), ), }, { $group: { _id: "$callSid" } }, ]); return rows .filter((r) => r._id != null && r._id !== "") .map((r) => String(r._id)); }; export const findCallSidTicketCountsByCity = async ( cityName: CityName, dateScope?: TicketStatsDateScope, ): Promise> => { const rows = await runTicketStatsAggregate<{ _id: unknown; ticketCount: number; }>([ { $match: ticketsWithCallSidMatch( cityName, resolveTicketStatsDateRange(dateScope), ), }, { $group: { _id: "$callSid", ticketCount: { $sum: 1 } } }, ]); return new Map( rows .filter((r) => r._id != null && r._id !== "") .map((r) => [String(r._id), r.ticketCount]), ); }; /** @deprecated Use findCallSidDraftTicketCountsByCity instead. */ export const findCallSidsWithDraftTicketsByCity = async ( cityName: CityName, dateScope?: TicketStatsDateScope, ): Promise => { const rows = await runTicketStatsAggregate<{ _id: unknown }>([ { $match: ticketsWithCallSidMatch( cityName, resolveTicketStatsDateRange(dateScope), ), }, { $match: { $expr: isDraftTicketExpr } }, { $group: { _id: "$callSid" } }, ]); return rows .filter((r) => r._id != null && r._id !== "") .map((r) => String(r._id)); }; export const findCallSidDraftTicketCountsByCity = async ( cityName: CityName, dateScope?: TicketStatsDateScope, ): Promise> => { const rows = await runTicketStatsAggregate<{ _id: unknown; ticketCount: number; }>([ { $match: ticketsWithCallSidMatch( cityName, resolveTicketStatsDateRange(dateScope), ), }, { $match: { $expr: isDraftTicketExpr } }, { $group: { _id: "$callSid", ticketCount: { $sum: 1 } } }, ]); return new Map( rows .filter((r) => r._id != null && r._id !== "") .map((r) => [String(r._id), r.ticketCount]), ); }; export const findTicketSubjectRows = async ( cityName: CityName, dateScope?: TicketStatsDateScope, ): Promise => { const rows = await runTicketStatsAggregate<{ callSid: unknown; subject: unknown; }>([ { $match: ticketsWithCallSidMatch( cityName, resolveTicketStatsDateRange(dateScope), ), }, ...subjectResolutionStages(cityName), { $project: { _id: 0, callSid: 1, subject: 1 } }, ]); return rows.map((r) => ({ callSid: String(r.callSid), subject: String(r.subject), })); };