ДОМЕНЫ - ВОПРОСЫ - Этап 4: точный маршрут confirmed payables на дату без эвристического фолбэка
This commit is contained in:
@@ -858,7 +858,7 @@ function buildPayablesConfirmedBalanceAggregate(
|
||||
continue;
|
||||
}
|
||||
const amount = row.amount;
|
||||
if (!Number.isFinite(amount)) {
|
||||
if (typeof amount !== "number" || !Number.isFinite(amount)) {
|
||||
continue;
|
||||
}
|
||||
const absAmount = Math.abs(amount);
|
||||
@@ -2252,6 +2252,82 @@ export function composeFactualReply(
|
||||
};
|
||||
}
|
||||
|
||||
if (intent === "payables_confirmed_as_of_date") {
|
||||
const payablesAsOfDate = resolvePayablesAsOfDate(options);
|
||||
const confirmedBalances = buildPayablesConfirmedBalanceAggregate(rows, payablesAsOfDate);
|
||||
const asOfDate = normalizeIsoDateOnly(options.asOfDate);
|
||||
const periodFrom = normalizeIsoDateOnly(options.periodFrom);
|
||||
const periodTo = normalizeIsoDateOnly(options.periodTo);
|
||||
const scopeLine = asOfDate
|
||||
? `- Дата среза: ${formatDateRu(asOfDate)}.`
|
||||
: periodFrom || periodTo
|
||||
? `- Период анализа: ${formatDateRu(periodFrom ?? "...")}..${formatDateRu(periodTo ?? "...")}.`
|
||||
: null;
|
||||
const carryoverLine =
|
||||
asOfDate || periodFrom || periodTo
|
||||
? "- В срез могут входить обязательства, возникшие до периода, если они оставались открытыми на дату среза."
|
||||
: null;
|
||||
const categoryCounts = confirmedBalances.reduce<Record<PayablesLiabilityCategory, number>>(
|
||||
(acc, item) => {
|
||||
acc[item.category] += 1;
|
||||
return acc;
|
||||
},
|
||||
{ supplier_or_contractor: 0, bank_or_credit: 0, tax_or_state: 0, other: 0 }
|
||||
);
|
||||
|
||||
const lines: string[] = [
|
||||
"Блок 1. Статус результата",
|
||||
"- Режим результата: подтвержденный срез обязательств к оплате (exact route).",
|
||||
"- Эвристический shortlist в этом режиме не используется."
|
||||
];
|
||||
|
||||
lines.push("");
|
||||
lines.push("Блок 2. Что учтено");
|
||||
lines.push(`- Дата среза: ${formatDateRu(payablesAsOfDate)}.`);
|
||||
if (scopeLine) {
|
||||
lines.push(scopeLine);
|
||||
}
|
||||
lines.push("- Контур: обязательства по счетам 60/76.");
|
||||
if (carryoverLine) {
|
||||
lines.push(carryoverLine);
|
||||
}
|
||||
|
||||
lines.push("");
|
||||
lines.push("Блок 3. Сводка");
|
||||
lines.push(`- Строк в выборке: ${rows.length}.`);
|
||||
lines.push(`- Контрагентов с подтвержденным остатком к оплате: ${confirmedBalances.length}.`);
|
||||
|
||||
lines.push("");
|
||||
lines.push("Блок 4. Категории обязательств");
|
||||
lines.push(`- ${liabilityCategoryLabel("supplier_or_contractor")}: ${categoryCounts.supplier_or_contractor}`);
|
||||
lines.push(`- ${liabilityCategoryLabel("bank_or_credit")}: ${categoryCounts.bank_or_credit}`);
|
||||
lines.push(`- ${liabilityCategoryLabel("tax_or_state")}: ${categoryCounts.tax_or_state}`);
|
||||
lines.push(`- ${liabilityCategoryLabel("other")}: ${categoryCounts.other}`);
|
||||
|
||||
lines.push("");
|
||||
lines.push("Блок 5. Подтвержденные позиции к оплате");
|
||||
if (confirmedBalances.length > 0) {
|
||||
lines.push(
|
||||
...confirmedBalances.slice(0, 10).map(
|
||||
(item, index) =>
|
||||
`${index + 1}. ${item.name} | категория: ${liabilityCategoryLabel(item.category)} | остаток: ${formatMoney(item.outstandingAmount)} | операций: ${item.operations}${item.lastPeriod ? ` | последнее движение: ${item.lastPeriod}` : ""}${item.categoryReasons.length > 0 ? ` | основание: ${item.categoryReasons.join(", ")}` : ""}`
|
||||
)
|
||||
);
|
||||
} else {
|
||||
lines.push("- Подтвержденных открытых обязательств к оплате на дату среза не найдено.");
|
||||
}
|
||||
|
||||
return {
|
||||
responseType: confirmedBalances.length > 0 ? "FACTUAL_LIST" : "FACTUAL_SUMMARY",
|
||||
text: lines.join("\n"),
|
||||
semantics: {
|
||||
result_mode: "confirmed_balance",
|
||||
evidence_strength: confirmedBalances.length > 0 ? "strong" : "medium",
|
||||
balance_confirmed: true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (intent === "list_payables_counterparties") {
|
||||
const counterparties = buildPayablesCounterpartyRiskAggregate(rows);
|
||||
const payablesAsOfDate = resolvePayablesAsOfDate(options);
|
||||
|
||||
@@ -439,7 +439,11 @@ function mergeFollowupFilters(
|
||||
}
|
||||
}
|
||||
|
||||
if (intent === "open_items_by_counterparty_or_contract" || intent === "list_open_contracts") {
|
||||
if (
|
||||
intent === "open_items_by_counterparty_or_contract" ||
|
||||
intent === "list_open_contracts" ||
|
||||
intent === "payables_confirmed_as_of_date"
|
||||
) {
|
||||
const inheritedContract = previousContract ?? (followupContext.previous_anchor_type === "contract" ? previousAnchorValue : null);
|
||||
const currentContract = toNonEmptyString(merged.contract);
|
||||
const shouldInheritContract =
|
||||
@@ -462,6 +466,13 @@ function mergeFollowupFilters(
|
||||
merged.counterparty = inheritedCounterparty;
|
||||
reasons.push(currentCounterparty ? "counterparty_replaced_from_followup_context" : "counterparty_from_followup_context");
|
||||
}
|
||||
if (sameDateRequested) {
|
||||
const inheritedAsOfDate = previousAsOfDate ?? previousPeriodTo ?? previousPeriodFrom;
|
||||
if (inheritedAsOfDate && merged.as_of_date !== inheritedAsOfDate) {
|
||||
merged.as_of_date = inheritedAsOfDate;
|
||||
reasons.push("as_of_date_from_followup_context");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allTimeRequested) {
|
||||
@@ -525,6 +536,7 @@ function resolveMissingRequiredFilters(intent: AddressIntent, filters: AddressFi
|
||||
const requiredByIntent: Record<string, Array<keyof AddressFilterSet>> = {
|
||||
account_balance_snapshot: ["account", "as_of_date"],
|
||||
documents_forming_balance: ["account", "as_of_date"],
|
||||
payables_confirmed_as_of_date: ["as_of_date"],
|
||||
list_documents_by_counterparty: ["counterparty"],
|
||||
bank_operations_by_counterparty: ["counterparty"],
|
||||
list_contracts_by_counterparty: ["counterparty"],
|
||||
|
||||
@@ -189,7 +189,11 @@ function inferAggregationProfile(intent: AddressIntent, shape: AddressQueryShape
|
||||
return "management_profile";
|
||||
}
|
||||
|
||||
if (intent === "account_balance_snapshot" || intent === "documents_forming_balance") {
|
||||
if (
|
||||
intent === "account_balance_snapshot" ||
|
||||
intent === "documents_forming_balance" ||
|
||||
intent === "payables_confirmed_as_of_date"
|
||||
) {
|
||||
return "balance_snapshot";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user