import { describe, expect, it } from "vitest"; import { composeFactualReply } from "../src/services/address_runtime/composeStage"; describe("counterparty analytics reply builders", () => { it("keeps counterparty role split answers business-first", () => { const reply = composeFactualReply( "counterparty_population_and_roles", [ { period: "2000-01-01T00:00:00Z", registrator: "CP_TOTAL", account_dt: "", account_kt: "", amount: 30, analytics: [] }, { period: "2000-01-01T00:00:00Z", registrator: "CP_CUSTOMER_ACTIVE", account_dt: "", account_kt: "", amount: 12, analytics: [] }, { period: "2000-01-01T00:00:00Z", registrator: "CP_SUPPLIER_ACTIVE", account_dt: "", account_kt: "", amount: 9, analytics: [] }, { period: "2000-01-01T00:00:00Z", registrator: "CP_MIXED_ACTIVE", account_dt: "", account_kt: "", amount: 4, analytics: [] } ], { userMessage: "покажи роли контрагентов" } ); expect(reply.responseType).toBe("FACTUAL_SUMMARY"); expect(reply.text).toContain("Распределение ролей по активности:"); expect(reply.text).not.toContain("supplier-роль"); expect(reply.text).not.toContain("customer-роль"); }); it("formats value rankings without technical 'max single' label", () => { const reply = composeFactualReply( "customer_revenue_and_payments", [ { period: "2020-03-01T00:00:00Z", registrator: "Поступление 1", account_dt: "", account_kt: "", amount: 500, analytics: ["Клиент А", "Договор А-1"] }, { period: "2020-03-02T00:00:00Z", registrator: "Поступление 2", account_dt: "", account_kt: "", amount: 1200, analytics: ["Клиент Б", "Договор Б-1"] } ], { userMessage: "с каких клиенктов самый высокий чек" } ); expect(reply.responseType).toBe("FACTUAL_LIST"); expect(reply.text).toContain("максимальной сумме одной входящей операции"); expect(reply.text).toContain("максимальная разовая сумма"); expect(reply.text).not.toContain("max single"); }); it("answers specific counterparty turnover directly instead of ranking", () => { const reply = composeFactualReply( "customer_revenue_and_payments", [ { period: "2024-02-01T00:00:00Z", registrator: "Поступление 1", account_dt: "", account_kt: "", amount: 1000, analytics: ["СВК", "Договор СВК-1"] }, { period: "2024-02-15T00:00:00Z", registrator: "Поступление 2", account_dt: "", account_kt: "", amount: 2500, analytics: ["СВК", "Договор СВК-1"] } ], { userMessage: "какой оборот был свк", counterpartyHint: "свк" } ); expect(reply.responseType).toBe("FACTUAL_SUMMARY"); expect(reply.text).toContain("Оборот по СВК за доступное время: 3.500,00"); expect(reply.text).toContain("по 2 подтвержденным входящим операциям"); expect(reply.text).toContain("Это денежный поток от клиента, а не чистая прибыль"); expect(reply.text).not.toContain("Самый доходный клиент"); expect(reply.text).not.toContain("Топ-"); }); it("does not mistake a year period in top-counterparty wording for a top-year question", () => { const reply = composeFactualReply( "customer_revenue_and_payments", [ { period: "2020-03-01T00:00:00Z", registrator: "Поступление 1", account_dt: "", account_kt: "", amount: 500, analytics: ["Клиент А", "Договор А-1"] }, { period: "2020-03-02T00:00:00Z", registrator: "Поступление 2", account_dt: "", account_kt: "", amount: 1200, analytics: ["Клиент Б", "Договор Б-1"] } ], { userMessage: "какой контрагент принес больше всего денег за 2020 год?", periodFrom: "2020-01-01", periodTo: "2020-12-31" } ); expect(reply.responseType).toBe("FACTUAL_LIST"); expect(reply.text).toContain("Клиент Б"); expect(reply.text).not.toContain("Клиент А"); expect(reply.text).not.toContain("1. 2020 |"); }); it("explains organization activity age as 1C activity rather than legal age", () => { const reply = composeFactualReply( "counterparty_activity_lifecycle", [ { period: "2020-01-15T00:00:00Z", registrator: "CP_CUSTOMER_ACTIVITY", account_dt: "62.01", account_kt: "90.01", amount: 12, analytics: ['ООО "Ромашка"'] }, { period: "2024-03-10T00:00:00Z", registrator: "CP_CUSTOMER_ACTIVITY", account_dt: "62.01", account_kt: "90.01", amount: 4, analytics: ['ООО "Ландыш"'] } ], { userMessage: "сколько лет активности в базе 1с у нашей компании", organizationHint: 'ООО "Альтернатива Плюс"' } ); expect(reply.responseType).toBe("FACTUAL_SUMMARY"); expect(reply.text).toContain('По активности организации ООО "Альтернатива Плюс" в базе 1С'); expect(reply.text).toContain("Это возраст активности организации в 1С"); }); it("renders contract usage overview with explicit confirmed wording", () => { const reply = composeFactualReply("contract_usage_overview", [ { period: "2000-01-01T00:00:00Z", registrator: "CT_TOTAL", account_dt: "", account_kt: "", amount: 520, analytics: [] }, { period: "2000-01-01T00:00:00Z", registrator: "CT_USED", account_dt: "", account_kt: "", amount: 148, analytics: [] } ]); expect(reply.responseType).toBe("FACTUAL_SUMMARY"); expect(reply.text).toContain("Коротко: Использованных договоров: 148 из 520 (28.5%)."); expect(reply.text).toContain("Что видно по договорной базе: 2 строк в подтвержденной выборке."); expect(reply.text).toContain("Использованных договоров с подтвержденной связью с операциями: 148."); }); });