Доказать полезность margin-agent через честный boundary replay
This commit is contained in:
@@ -27,6 +27,23 @@ describe("addressInventoryIntentSignals", () => {
|
||||
expect(result?.reasons).toContain("inventory_margin_ranking_signal_detected");
|
||||
});
|
||||
|
||||
it("classifies calculate-margin nomenclature wording with false-source guards as margin ranking", () => {
|
||||
const result = resolveInventoryAddressIntent(
|
||||
"\u041f\u043e\u0441\u0447\u0438\u0442\u0430\u0439 \u043c\u0430\u0440\u0436\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u0432\u0430\u0440\u043d\u043e\u0439 \u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442\u0443\u0440\u044b \u0437\u0430 2020 \u0433\u043e\u0434, \u043d\u0435 \u041e\u0421 \u0438 \u043d\u0435 \u0430\u043c\u043e\u0440\u0442\u0438\u0437\u0430\u0446\u0438\u044e."
|
||||
);
|
||||
|
||||
expect(result?.intent).toBe("inventory_margin_ranking_for_nomenclature");
|
||||
expect(result?.reasons).toContain("inventory_margin_ranking_signal_detected");
|
||||
});
|
||||
|
||||
it("keeps payment-bank false-source wording in margin contour", () => {
|
||||
const result = resolveAddressIntent(
|
||||
"\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u043c\u0430\u0440\u0436\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0437\u0430 2020 \u0433\u043e\u0434 \u043f\u043e \u043e\u043f\u043b\u0430\u0442\u0430\u043c \u0438 \u0431\u0430\u043d\u043a\u0443?"
|
||||
);
|
||||
|
||||
expect(result.intent).toBe("inventory_margin_ranking_for_nomenclature");
|
||||
});
|
||||
|
||||
it("classifies selected-object purchase provenance wording through the extracted inventory owner", () => {
|
||||
const result = resolveInventoryAddressIntent("selected object supplier provenance");
|
||||
|
||||
|
||||
@@ -131,6 +131,15 @@ describe("address query shape classifier", () => {
|
||||
expect(result.mode).toBe("address_query");
|
||||
});
|
||||
|
||||
it("keeps calculate margin wording in address lane before bank false-source cues can steal it", () => {
|
||||
const result = detectAddressQuestionMode(
|
||||
"\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u043c\u0430\u0440\u0436\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0437\u0430 2020 \u0433\u043e\u0434 \u043f\u043e \u043e\u043f\u043b\u0430\u0442\u0430\u043c \u0438 \u0431\u0430\u043d\u043a\u0443?"
|
||||
);
|
||||
|
||||
expect(result.mode).toBe("address_query");
|
||||
expect(result.reasons).toContain("inventory_profitability_signal_detected");
|
||||
});
|
||||
|
||||
it("extracts item anchor for inventory provenance questions", () => {
|
||||
const filters = extractAddressFilters(
|
||||
"От какого поставщика куплен товар Шкаф картотечный?",
|
||||
|
||||
@@ -579,4 +579,66 @@ describe("address reply builders regressions", () => {
|
||||
expect(result?.text).not.toContain("входящих денежных поступлений");
|
||||
expect(result?.text).not.toContain("амортизац");
|
||||
});
|
||||
|
||||
it("answers payment-bank margin false-source questions as a boundary before any ranking", () => {
|
||||
const result = composeInventoryReply(
|
||||
"inventory_margin_ranking_for_nomenclature",
|
||||
[
|
||||
{
|
||||
amount: 1000,
|
||||
quantity: 1,
|
||||
item: "Товар A",
|
||||
period: "2020-05-20",
|
||||
registrator: "Реализация товаров"
|
||||
} as any,
|
||||
{
|
||||
amount: 400,
|
||||
quantity: 1,
|
||||
item: "Товар A",
|
||||
period: "2020-01-10",
|
||||
registrator: "Поступление товаров"
|
||||
} as any
|
||||
],
|
||||
{
|
||||
userMessage:
|
||||
"Можно быстро понять маржинальность товаров за 2020 год по оплатам и банку?",
|
||||
periodFrom: "2020-01-01",
|
||||
periodTo: "2020-12-31"
|
||||
},
|
||||
{
|
||||
resolvePayablesAsOfDate: () => "2020-12-31",
|
||||
buildInventoryOnHandAggregate: () => [],
|
||||
uniqueStrings: (values: string[]) => Array.from(new Set(values)),
|
||||
formatDateRu: (value: string) => value,
|
||||
formatNumberWithDots: (value: number, fractionDigits = 0) => value.toFixed(fractionDigits),
|
||||
formatMoneyRub: (value: number) => `${value} ₽`,
|
||||
isInventoryPurchaseMovement: (row: any) => String(row.registrator ?? "").includes("Поступление"),
|
||||
summarizeInventoryTraceRows: (rows: any[]) => ({
|
||||
item: rows[0]?.item ?? null,
|
||||
warehouses: [],
|
||||
organizations: [],
|
||||
counterparties: [],
|
||||
documents: [],
|
||||
firstPeriod: null,
|
||||
lastPeriod: null,
|
||||
totalAmount: 0
|
||||
}),
|
||||
formatInventoryTraceRows: () => [],
|
||||
hasInventoryPurchaseDateActionFocus: () => false,
|
||||
inventoryTraceDateLabel: () => "",
|
||||
extractInventoryCounterpartyCandidates: () => [],
|
||||
buildInventoryAgingByItemAggregate: () => [],
|
||||
formatInventoryAgingRows: () => [],
|
||||
isInventorySaleMovement: (row: any) => String(row.registrator ?? "").includes("Реализация")
|
||||
}
|
||||
);
|
||||
|
||||
expect(result?.text.split("\n")[0]).toContain("По оплатам и банку");
|
||||
expect(result?.text.split("\n")[0]).toContain("нельзя честно подтвердить");
|
||||
expect(result?.text).toContain("выручка реализации");
|
||||
expect(result?.text).toContain("себестоимостная база");
|
||||
expect(result?.text).toContain("Что можно сделать дальше");
|
||||
expect(result?.text).not.toContain("Самая маржинальная позиция");
|
||||
expect(result?.text).not.toMatch(/(?:оплат[аы]|банк|payment_document).{0,80}(?:источник|достаточ|посчитал|марж[ау])/iu);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user