Расширить proof matrix маржинальности follow-up replay

This commit is contained in:
2026-05-24 18:23:04 +03:00
parent f69393a887
commit 7cc65e808e
6 changed files with 436 additions and 8 deletions
@@ -98,6 +98,10 @@ function asksInventoryMarginFromPaymentOrBank(userMessage) {
/(?:товар|номенклатур|inventory|item|sku)/iu.test(text) &&
/(?:банк|банковск|выписк|плат[её]ж|оплат|payment|bank|statement)/iu.test(text));
}
function asksInventoryMarginAccount41Not01(userMessage) {
const text = String(userMessage ?? "").toLowerCase();
return /(?:\b41\b|41\s*сч|сч[её]т[ау]?\s*41)/iu.test(text) && /(?:\b01\b|не\s+ос|основн)/iu.test(text);
}
function inventoryRowItemLabel(row, deps) {
return deps.summarizeInventoryTraceRows([row]).item;
}
@@ -478,6 +482,8 @@ function composeInventoryReply(intent, rows, options, deps) {
const topMarginEntry = highMargin[0] ?? null;
const marginBasisRequested = asksForInventoryMarginBasis(options.userMessage);
const paymentOrBankFalseSourceRequested = asksInventoryMarginFromPaymentOrBank(options.userMessage);
const account41Not01Requested = asksInventoryMarginAccount41Not01(options.userMessage);
const withAccountScopePrefix = (line) => account41Not01Requested ? `По счету 41, не по 01/ОС: ${line}` : line;
if (paymentOrBankFalseSourceRequested) {
const lines = [
"По оплатам и банку такой показатель нельзя честно подтвердить: платежи показывают денежный поток и факт оплаты, а не связь реализации с себестоимостью по номенклатуре."
@@ -500,9 +506,9 @@ function composeInventoryReply(intent, rows, options, deps) {
if (confirmedEntries.length === 0) {
const costBaseRowsRequested = asksForInventoryCostBaseRows(options.userMessage);
const lines = [
costBaseRowsRequested && purchasesWithoutSales.length === 0
withAccountScopePrefix(costBaseRowsRequested && purchasesWithoutSales.length === 0
? `За период ${periodLabel} подтвержденных строк себестоимостной базы по реализованной номенклатуре не найдено.`
: `За период ${periodLabel} рейтинг прибыльности номенклатуры построить нельзя.`
: `За период ${periodLabel} рейтинг прибыльности номенклатуры построить нельзя.`)
];
const findings = [];
if (salesWithoutCost.length > 0) {
@@ -549,7 +555,7 @@ function composeInventoryReply(intent, rows, options, deps) {
: topMarginEntry
? `Самая маржинальная позиция за период ${periodLabel}: ${topMarginEntry.item} — маржа ${formatInventoryPercent(topMarginEntry.marginPct, deps.formatNumberWithDots)}, выручка ${deps.formatMoneyRub(topMarginEntry.revenue)}, себестоимостная база ${deps.formatMoneyRub(topMarginEntry.costProxy)}, валовая разница ${deps.formatMoneyRub(topMarginEntry.spread)}.`
: `За период ${periodLabel} не удалось подтвердить рейтинг прибыльности номенклатуры: нужны одновременно строки реализации и закупочного/себестоимостного следа по товарам.`;
const lines = [directAnswerLine];
const lines = [withAccountScopePrefix(directAnswerLine)];
if (marginBasisRequested) {
(0, inventoryReplyPresentation_1.appendInventoryBulletSection)(lines, "База расчета:", [
"выручка: подтвержденные строки реализации по номенклатуре;",