ДОМЕНЫ - ВОПРОСЫ - fix: переведен exact-маршрут кому должны на дату на Хозрасчетный.Остатки (без Движения.СубконтоДт1/Кт1)
This commit is contained in:
@@ -51,6 +51,7 @@ type CounterpartyProfileFocus =
|
||||
type CounterpartyLifecycleFocus = "active_customers_period" | "active_customers_all_time";
|
||||
type ValueRankingFocus =
|
||||
| "top_by_total"
|
||||
| "top_years_by_total"
|
||||
| "top_by_ops"
|
||||
| "top_by_max_single"
|
||||
| "top_by_avg_check_min_ops"
|
||||
@@ -524,6 +525,13 @@ function detectValueRankingFocus(userMessage: string | null | undefined): ValueR
|
||||
if (!text) {
|
||||
return "top_by_total";
|
||||
}
|
||||
const asksYearlyRevenueRanking =
|
||||
/(?:доходн|выручк|оборот|прибыл|деньг|денег|revenue|turnover|income)/iu.test(text) &&
|
||||
/(?:год|года|годы|year|years|по\s+годам)/iu.test(text) &&
|
||||
/(?:сам(?:ый|ая|ое|ые)|топ|луч|best|max|наибольш|больше)/iu.test(text);
|
||||
if (asksYearlyRevenueRanking) {
|
||||
return "top_years_by_total";
|
||||
}
|
||||
if (/(?:сам(?:ый|ая|ое|ые)\s+высок[а-яё]*|highest|largest)\s+чек|(?:max\s+check|чек\s+макс)/iu.test(text)) {
|
||||
return "top_by_max_single";
|
||||
}
|
||||
@@ -1800,6 +1808,16 @@ export function composeFactualReply(
|
||||
lastPeriod: string | null;
|
||||
}
|
||||
>();
|
||||
const byYear = new Map<
|
||||
number,
|
||||
{
|
||||
year: number;
|
||||
total: number;
|
||||
ops: number;
|
||||
maxSingle: number;
|
||||
counterparties: Set<string>;
|
||||
}
|
||||
>();
|
||||
const deals: Array<{ period: string | null; registrator: string; counterparty: string; amount: number }> = [];
|
||||
|
||||
for (const row of rows) {
|
||||
@@ -1834,10 +1852,31 @@ export function composeFactualReply(
|
||||
counterparty,
|
||||
amount
|
||||
});
|
||||
|
||||
const year = extractYearFromIso(row.period);
|
||||
if (year !== null) {
|
||||
const yearBucket = byYear.get(year);
|
||||
if (!yearBucket) {
|
||||
byYear.set(year, {
|
||||
year,
|
||||
total: amount,
|
||||
ops: 1,
|
||||
maxSingle: amount,
|
||||
counterparties: new Set<string>([counterparty])
|
||||
});
|
||||
} else {
|
||||
yearBucket.total += amount;
|
||||
yearBucket.ops += 1;
|
||||
yearBucket.maxSingle = Math.max(yearBucket.maxSingle, amount);
|
||||
yearBucket.counterparties.add(counterparty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const profileRows = Array.from(byCounterparty.values());
|
||||
const yearRows = Array.from(byYear.values());
|
||||
const rankedByTotal = [...profileRows].sort((a, b) => b.total - a.total || b.ops - a.ops || a.name.localeCompare(b.name));
|
||||
const rankedByYearTotal = [...yearRows].sort((a, b) => b.total - a.total || b.ops - a.ops || a.year - b.year);
|
||||
const rankedByOps = [...profileRows].sort((a, b) => b.ops - a.ops || b.total - a.total || a.name.localeCompare(b.name));
|
||||
const rankedByMaxSingle = [...profileRows].sort(
|
||||
(a, b) => b.maxSingle - a.maxSingle || b.total - a.total || a.name.localeCompare(b.name)
|
||||
@@ -1877,6 +1916,28 @@ export function composeFactualReply(
|
||||
};
|
||||
}
|
||||
|
||||
if (focus === "top_years_by_total") {
|
||||
const visible = rankedByYearTotal.slice(0, limit);
|
||||
const heading = isSupplier
|
||||
? `Топ-${visible.length} лет по сумме выплат:`
|
||||
: `Топ-${visible.length} лет по сумме поступлений:`;
|
||||
lines.unshift(heading);
|
||||
if (visible.length === 0) {
|
||||
lines.push("По доступному окну не удалось собрать годовые агрегаты по суммам.");
|
||||
} else {
|
||||
lines.push(
|
||||
...visible.map(
|
||||
(item, index) =>
|
||||
`${index + 1}. ${item.year} | сумма: ${item.total} | операций: ${item.ops} | контрагентов: ${item.counterparties.size} | макс: ${item.maxSingle}`
|
||||
)
|
||||
);
|
||||
}
|
||||
return {
|
||||
responseType: "FACTUAL_LIST",
|
||||
text: lines.join("\n")
|
||||
};
|
||||
}
|
||||
|
||||
if (focus === "top_by_ops") {
|
||||
const visible = rankedByOps.slice(0, limit);
|
||||
const heading = isSupplier
|
||||
|
||||
Reference in New Issue
Block a user