diff --git a/llm_normalizer/backend/dist/services/addressQueryService.js b/llm_normalizer/backend/dist/services/addressQueryService.js index db1b341..7482df6 100644 --- a/llm_normalizer/backend/dist/services/addressQueryService.js +++ b/llm_normalizer/backend/dist/services/addressQueryService.js @@ -3023,8 +3023,14 @@ class AddressQueryService { (filters.warnings.includes("period_from_from_followup_context") || filters.warnings.includes("period_to_from_followup_context")) && isFullCalendarMonthWindow(filters.extracted_filters.period_from, filters.extracted_filters.period_to); + const vatTaxPeriodFromPurchaseBridgeMonth = intent.intent === "vat_liability_confirmed_for_tax_period" && + (filters.warnings.includes("period_from_purchase_date_bridge_followup_context") || + filters.warnings.includes("period_to_purchase_date_bridge_followup_context")) && + isFullCalendarMonthWindow(filters.extracted_filters.period_from, filters.extracted_filters.period_to); if (intent.intent === "vat_liability_confirmed_for_tax_period" && - (filters.warnings.includes("period_derived_from_month_phrase") || vatTaxPeriodFromCarriedMonth)) { + (filters.warnings.includes("period_derived_from_month_phrase") || + vatTaxPeriodFromCarriedMonth || + vatTaxPeriodFromPurchaseBridgeMonth)) { const taxQuarterWindow = deriveTaxQuarterWindowForDate(filters.extracted_filters.period_to); if (taxQuarterWindow) { filters.extracted_filters = { diff --git a/llm_normalizer/backend/src/services/addressQueryService.ts b/llm_normalizer/backend/src/services/addressQueryService.ts index 43099eb..450db90 100644 --- a/llm_normalizer/backend/src/services/addressQueryService.ts +++ b/llm_normalizer/backend/src/services/addressQueryService.ts @@ -3738,9 +3738,16 @@ export class AddressQueryService { (filters.warnings.includes("period_from_from_followup_context") || filters.warnings.includes("period_to_from_followup_context")) && isFullCalendarMonthWindow(filters.extracted_filters.period_from, filters.extracted_filters.period_to); + const vatTaxPeriodFromPurchaseBridgeMonth = + intent.intent === "vat_liability_confirmed_for_tax_period" && + (filters.warnings.includes("period_from_purchase_date_bridge_followup_context") || + filters.warnings.includes("period_to_purchase_date_bridge_followup_context")) && + isFullCalendarMonthWindow(filters.extracted_filters.period_from, filters.extracted_filters.period_to); if ( intent.intent === "vat_liability_confirmed_for_tax_period" && - (filters.warnings.includes("period_derived_from_month_phrase") || vatTaxPeriodFromCarriedMonth) + (filters.warnings.includes("period_derived_from_month_phrase") || + vatTaxPeriodFromCarriedMonth || + vatTaxPeriodFromPurchaseBridgeMonth) ) { const taxQuarterWindow = deriveTaxQuarterWindowForDate(filters.extracted_filters.period_to); if (taxQuarterWindow) { diff --git a/llm_normalizer/backend/tests/addressQueryRuntimeM23.test.ts b/llm_normalizer/backend/tests/addressQueryRuntimeM23.test.ts index e5f0de0..cd19456 100644 --- a/llm_normalizer/backend/tests/addressQueryRuntimeM23.test.ts +++ b/llm_normalizer/backend/tests/addressQueryRuntimeM23.test.ts @@ -4129,6 +4129,40 @@ describe("address query limited taxonomy and stage diagnostics", { timeout: 9000 expect(String(result?.reply_text ?? "")).toContain("01.04.2017..30.06.2017"); }, 35000); + it("normalizes purchase-date VAT bridge month into the selected date tax quarter", async () => { + const service = new AddressQueryService(); + const result = await service.tryHandle("ндс можешь прикинуть на дату покупки рабочей станции?", { + followupContext: { + previous_intent: "inventory_purchase_provenance_for_item", + target_intent: "vat_liability_confirmed_for_tax_period", + previous_filters: { + item: "Рабочая станция универсального специалиста", + organization: 'ООО "Альтернатива Плюс"', + period_from: "2015-02-01", + period_to: "2015-02-28", + as_of_date: "2015-02-28", + purchase_date_bridge_selected: "2015-02-05", + purchase_date_bridge_first: "2015-02-05", + purchase_date_bridge_last: "2015-07-22", + purchase_date_bridge_basis: "first_confirmed_purchase_default", + purchase_date_bridge_has_multiple: true + }, + previous_anchor_type: "item", + previous_anchor_value: "Рабочая станция универсального специалиста" + } + }); + + expect(result?.handled).toBe(true); + expect(result?.debug.detected_intent).toBe("vat_liability_confirmed_for_tax_period"); + expect(result?.debug.extracted_filters.period_from).toBe("2015-01-01"); + expect(result?.debug.extracted_filters.period_to).toBe("2015-03-31"); + expect(result?.debug.extracted_filters.purchase_date_bridge_selected).toBe("2015-02-05"); + expect(result?.debug.reasons).toContain("period_from_purchase_date_bridge_followup_context"); + expect(result?.debug.reasons).toContain("period_derived_from_tax_quarter_for_confirmed_vat_liability"); + expect(String(result?.reply_text ?? "")).toContain("05.02.2015"); + expect(String(result?.reply_text ?? "")).toContain("01.01.2015..31.03.2015"); + }, 35000); + it("routes customer lifecycle question into dedicated aggregate recipe", async () => { const service = new AddressQueryService(); const result = await service.tryHandle("Какие заказчики работали с нами в 2020 году?");