NODEDC_1C/llm_normalizer/backend/tests/addressReplyBuildersRegress...

146 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, expect, it } from "vitest";
import { composeCounterpartyAnalyticsReply } from "../src/services/address_runtime/counterpartyAnalyticsReplyBuilders";
import { composeInventoryReply } from "../src/services/address_runtime/inventoryReplyBuilders";
describe("address reply builders regressions", () => {
it("starts top customer aggregate reply with a direct business answer", () => {
const result = composeCounterpartyAnalyticsReply(
"customer_revenue_and_payments",
[
{
amount: 250000,
period: "2020-03-31",
registrator: "Поступление 1"
} as any
],
{
userMessage: "кто у нас самый доходный клиент за все время?"
},
{
formatPercent: () => null,
formatDateRu: (value: string) => value,
formatMoneyRub: (value: number) => `${value}`,
extractYearFromIso: (value: string | null) => (value ? Number(value.slice(0, 4)) : null),
detectCounterpartyProfileFocus: () => "full_profile",
detectCounterpartyLifecycleFocus: () => "active_customers_all_time",
hasCounterpartyLifecycleLongevityQuestion: () => false,
hasCounterpartyActivityAgeQuestion: () => false,
detectRankingLimit: () => 5,
detectValueRankingFocus: () => "top_by_total",
detectContractValueFocus: () => "top_by_turnover",
detectMinOpsForAvgCheck: () => 1,
extractRequestedYearFromQuestion: () => null,
extractCounterpartyName: () => "Чапурнов",
extractContractName: () => null,
counterpartyLookupMatches: () => false,
toUtcDayTimestamp: () => null,
formatAgeYearsMonthsDays: () => "0 дней",
normalizeQuestionText: (value: string | null | undefined) => String(value ?? "")
}
);
expect(result?.text.split("\n")[0]).toContain("Самый доходный клиент");
expect(result?.text.split("\n")[0]).toContain("Чапурнов");
});
it("starts top year aggregate reply with a direct business answer", () => {
const result = composeCounterpartyAnalyticsReply(
"customer_revenue_and_payments",
[
{
amount: 320000,
period: "2021-05-12",
registrator: "Поступление 2"
} as any
],
{
userMessage: "какой у нас самый доходный год"
},
{
formatPercent: () => null,
formatDateRu: (value: string) => value,
formatMoneyRub: (value: number) => `${value}`,
extractYearFromIso: (value: string | null) => (value ? Number(value.slice(0, 4)) : null),
detectCounterpartyProfileFocus: () => "full_profile",
detectCounterpartyLifecycleFocus: () => "active_customers_all_time",
hasCounterpartyLifecycleLongevityQuestion: () => false,
hasCounterpartyActivityAgeQuestion: () => false,
detectRankingLimit: () => 5,
detectValueRankingFocus: () => "top_years_by_total",
detectContractValueFocus: () => "top_by_turnover",
detectMinOpsForAvgCheck: () => 1,
extractRequestedYearFromQuestion: () => null,
extractCounterpartyName: () => "Чапурнов",
extractContractName: () => null,
counterpartyLookupMatches: () => false,
toUtcDayTimestamp: () => null,
formatAgeYearsMonthsDays: () => "0 дней",
normalizeQuestionText: (value: string | null | undefined) => String(value ?? "")
}
);
expect(result?.text.split("\n")[0]).toContain("Самый доходный год");
expect(result?.text.split("\n")[0]).toContain("2021");
});
it("keeps very old stock answer free of explicit as-of date in the first line", () => {
const result = composeInventoryReply(
"inventory_aging_by_purchase_date",
[
{
amount: 1000,
period: "2015-02-05",
registrator: "Поступление 3"
} as any
],
{
userMessage: "Есть ли остатки товара, которые закупались очень давно",
asOfDate: "2026-04-18"
},
{
resolvePayablesAsOfDate: () => "2026-04-18",
buildInventoryOnHandAggregate: () => [],
uniqueStrings: (values: string[]) => values,
formatDateRu: (value: string) => value,
formatNumberWithDots: (value: number) => String(value),
formatMoneyRub: (value: number) => `${value}`,
isInventoryPurchaseMovement: () => true,
summarizeInventoryTraceRows: () => ({
item: "Рабочая станция",
warehouses: ["Основной склад"],
organizations: ["ООО Альтернатива Плюс"],
counterparties: ["Чапурнов"],
documents: ["Поступление 3"],
firstPeriod: "2015-02-05",
lastPeriod: "2015-02-05",
totalAmount: 1000
}),
formatInventoryTraceRows: () => [],
hasInventoryPurchaseDateActionFocus: () => false,
inventoryTraceDateLabel: (value: string | null) => value ?? "дата не указана",
extractInventoryCounterpartyCandidates: () => ["Чапурнов"],
buildInventoryAgingByItemAggregate: () => [
{
item: "Рабочая станция",
warehouse: "Основной склад",
organization: "ООО Альтернатива Плюс",
firstPurchasePeriod: "2015-02-05",
lastPurchasePeriod: "2015-02-05",
operations: 1,
documentCount: 1,
counterparties: ["Чапурнов"],
ageDays: 4089
}
],
formatInventoryAgingRows: () => ["1. Рабочая станция | первая закупка: 2015-02-05"],
isInventorySaleMovement: () => false
}
);
const firstLine = result?.text.split("\n")[0] ?? "";
expect(firstLine).toContain("К самым старым закупкам");
expect(firstLine).not.toContain("2026-04-18");
});
});