ДОМЕНЫ - ВОПРОСЫ - fix: переведен exact-маршрут кому должны на дату на Хозрасчетный.Остатки (без Движения.СубконтоДт1/Кт1)
This commit is contained in:
@@ -1073,14 +1073,72 @@ function isMissingSubcontoFieldError(errorText: string | null | undefined): bool
|
||||
if (!normalized) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
normalized.includes("поле не найдено") &&
|
||||
(normalized.includes("субконтодт1") ||
|
||||
normalized.includes("subcontodt1") ||
|
||||
normalized.includes("subconto_dt1"))
|
||||
);
|
||||
const ruMissingField = "\u043f\u043e\u043b\u0435 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e";
|
||||
const hasMissingFieldSignal = normalized.includes(ruMissingField) || normalized.includes("field not found");
|
||||
if (!hasMissingFieldSignal) {
|
||||
return false;
|
||||
}
|
||||
const hasAnySubcontoSignal =
|
||||
/(?:\u0441\u0443\u0431\u043a\u043e\u043d\u0442\u043e(?:\u0434\u0442|\u043a\u0442)?\d*|subconto(?:_)?(?:dt|kt)?\d*)/iu.test(
|
||||
normalized
|
||||
) ||
|
||||
normalized.includes("subcontodt") ||
|
||||
normalized.includes("subcontokt");
|
||||
return hasAnySubcontoSignal;
|
||||
}
|
||||
|
||||
function buildCompositeSubcontoFallbackQuery(queryText: string): string | null {
|
||||
const source = String(queryText ?? "");
|
||||
if (!source.trim()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const dt1Pattern = /ПРЕДСТАВЛЕНИЕ\(\s*Движения\.СубконтоДт1\s*\)\s+КАК\s+СубконтоДт1\s*,?/iu;
|
||||
const dt2Pattern = /ПРЕДСТАВЛЕНИЕ\(\s*Движения\.СубконтоДт2\s*\)\s+КАК\s+СубконтоДт2\s*,?/iu;
|
||||
const dt3Pattern = /ПРЕДСТАВЛЕНИЕ\(\s*Движения\.СубконтоДт3\s*\)\s+КАК\s+СубконтоДт3\s*,?/iu;
|
||||
const kt1Pattern = /ПРЕДСТАВЛЕНИЕ\(\s*Движения\.СубконтоКт1\s*\)\s+КАК\s+СубконтоКт1\s*,?/iu;
|
||||
const kt2Pattern = /ПРЕДСТАВЛЕНИЕ\(\s*Движения\.СубконтоКт2\s*\)\s+КАК\s+СубконтоКт2\s*,?/iu;
|
||||
const kt3Pattern = /ПРЕДСТАВЛЕНИЕ\(\s*Движения\.СубконтоКт3\s*\)\s+КАК\s+СубконтоКт3\s*,?/iu;
|
||||
|
||||
const lines = source.split(/\r?\n/);
|
||||
let replaced = false;
|
||||
const rewrittenLines = lines.map((line) => {
|
||||
const indent = line.match(/^\s*/)?.[0] ?? "";
|
||||
if (dt1Pattern.test(line)) {
|
||||
replaced = true;
|
||||
return `${indent}ПРЕДСТАВЛЕНИЕ(Движения.СубконтоДт) КАК СубконтоДт1,`;
|
||||
}
|
||||
if (dt2Pattern.test(line)) {
|
||||
replaced = true;
|
||||
return `${indent}"" КАК СубконтоДт2,`;
|
||||
}
|
||||
if (dt3Pattern.test(line)) {
|
||||
replaced = true;
|
||||
return `${indent}"" КАК СубконтоДт3,`;
|
||||
}
|
||||
if (kt1Pattern.test(line)) {
|
||||
replaced = true;
|
||||
return `${indent}ПРЕДСТАВЛЕНИЕ(Движения.СубконтоКт) КАК СубконтоКт1,`;
|
||||
}
|
||||
if (kt2Pattern.test(line)) {
|
||||
replaced = true;
|
||||
return `${indent}"" КАК СубконтоКт2,`;
|
||||
}
|
||||
if (kt3Pattern.test(line)) {
|
||||
replaced = true;
|
||||
return `${indent}"" КАК СубконтоКт3,`;
|
||||
}
|
||||
return line;
|
||||
});
|
||||
|
||||
if (!replaced) {
|
||||
return null;
|
||||
}
|
||||
return rewrittenLines.join("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
function applyFutureDatedRowsGuard(
|
||||
rows: NormalizedAddressRow[],
|
||||
intent: AddressIntent,
|
||||
@@ -2158,6 +2216,8 @@ export class AddressQueryService {
|
||||
}
|
||||
|
||||
let effectiveRecipeId = recipeSelection.selected_recipe.recipe_id;
|
||||
let composeIntent: AddressIntent = intent.intent;
|
||||
let routeExpectationIntent: AddressIntent = intent.intent;
|
||||
let plan = enforceStrictAccountScopeForIntent(
|
||||
buildAddressRecipePlan(recipeSelection.selected_recipe, executionFilters),
|
||||
intent.intent
|
||||
@@ -2166,56 +2226,87 @@ export class AddressQueryService {
|
||||
query: plan.query,
|
||||
limit: plan.limit
|
||||
});
|
||||
const allowOpenItemsFallbackForMissingSubconto = intent.intent !== "payables_confirmed_as_of_date";
|
||||
if (
|
||||
mcp.error &&
|
||||
(plan.recipe.recipe_id === "address_movements_receivables_v1" ||
|
||||
plan.recipe.recipe_id === "address_movements_payables_v1") &&
|
||||
isMissingSubcontoFieldError(mcp.error) &&
|
||||
allowOpenItemsFallbackForMissingSubconto
|
||||
) {
|
||||
const fallbackSelection = selectAddressRecipe("open_items_by_counterparty_or_contract", executionFilters);
|
||||
if (fallbackSelection.selected_recipe && fallbackSelection.missing_required_filters.length === 0) {
|
||||
const fallbackPlan = enforceStrictAccountScopeForIntent(
|
||||
buildAddressRecipePlan(fallbackSelection.selected_recipe, executionFilters),
|
||||
intent.intent
|
||||
);
|
||||
const fallbackMcp = await executeAddressMcpQuery({
|
||||
query: fallbackPlan.query,
|
||||
limit: fallbackPlan.limit
|
||||
const missingSubcontoFallbackEligible =
|
||||
plan.recipe.recipe_id === "address_movements_receivables_v1" ||
|
||||
plan.recipe.recipe_id === "address_movements_payables_v1" ||
|
||||
plan.recipe.recipe_id === "address_payables_confirmed_as_of_date_v1";
|
||||
const missingSubcontoErrorDetected = Boolean(
|
||||
mcp.error && missingSubcontoFallbackEligible && isMissingSubcontoFieldError(mcp.error)
|
||||
);
|
||||
if (missingSubcontoErrorDetected) {
|
||||
let missingSubcontoResolvedByComposite = false;
|
||||
const compositeSubcontoQuery = buildCompositeSubcontoFallbackQuery(plan.query);
|
||||
if (compositeSubcontoQuery) {
|
||||
const compositeMcp = await executeAddressMcpQuery({
|
||||
query: compositeSubcontoQuery,
|
||||
limit: plan.limit
|
||||
});
|
||||
if (!fallbackMcp.error) {
|
||||
plan = fallbackPlan;
|
||||
mcp = fallbackMcp;
|
||||
if (intent.intent === "list_payables_counterparties") {
|
||||
if (!compositeMcp.error) {
|
||||
plan = {
|
||||
...plan,
|
||||
query: compositeSubcontoQuery
|
||||
};
|
||||
mcp = compositeMcp;
|
||||
missingSubcontoResolvedByComposite = true;
|
||||
if (!baseReasons.includes("mcp_missing_subconto_axis_auto_fallback_to_composite_subconto")) {
|
||||
baseReasons.push("mcp_missing_subconto_axis_auto_fallback_to_composite_subconto");
|
||||
}
|
||||
if (intent.intent === "payables_confirmed_as_of_date") {
|
||||
if (!baseReasons.includes("confirmed_payables_exact_mode_missing_subconto_axis_fallback_to_composite_subconto")) {
|
||||
baseReasons.push("confirmed_payables_exact_mode_missing_subconto_axis_fallback_to_composite_subconto");
|
||||
}
|
||||
}
|
||||
} else if (!baseReasons.includes("mcp_missing_subconto_axis_auto_fallback_to_composite_subconto_failed")) {
|
||||
baseReasons.push("mcp_missing_subconto_axis_auto_fallback_to_composite_subconto_failed");
|
||||
}
|
||||
} else if (!baseReasons.includes("mcp_missing_subconto_axis_auto_fallback_to_composite_subconto_unavailable")) {
|
||||
baseReasons.push("mcp_missing_subconto_axis_auto_fallback_to_composite_subconto_unavailable");
|
||||
}
|
||||
|
||||
if (!missingSubcontoResolvedByComposite) {
|
||||
const fallbackSelection = selectAddressRecipe("open_items_by_counterparty_or_contract", executionFilters);
|
||||
if (fallbackSelection.selected_recipe && fallbackSelection.missing_required_filters.length === 0) {
|
||||
const fallbackPlan = enforceStrictAccountScopeForIntent(
|
||||
buildAddressRecipePlan(fallbackSelection.selected_recipe, executionFilters),
|
||||
intent.intent
|
||||
);
|
||||
const fallbackMcp = await executeAddressMcpQuery({
|
||||
query: fallbackPlan.query,
|
||||
limit: fallbackPlan.limit
|
||||
});
|
||||
if (!fallbackMcp.error) {
|
||||
plan = fallbackPlan;
|
||||
mcp = fallbackMcp;
|
||||
effectiveRecipeId = fallbackSelection.selected_recipe.recipe_id;
|
||||
}
|
||||
if (!baseReasons.includes("mcp_missing_subconto_field_auto_fallback_to_open_items")) {
|
||||
baseReasons.push("mcp_missing_subconto_field_auto_fallback_to_open_items");
|
||||
}
|
||||
if (
|
||||
intent.intent === "list_payables_counterparties" &&
|
||||
!baseReasons.includes("fallback_recipe_switched_to_open_items")
|
||||
) {
|
||||
baseReasons.push("fallback_recipe_switched_to_open_items");
|
||||
if (!baseReasons.includes("mcp_missing_subconto_field_auto_fallback_to_open_items")) {
|
||||
baseReasons.push("mcp_missing_subconto_field_auto_fallback_to_open_items");
|
||||
}
|
||||
if (!baseReasons.includes("fallback_recipe_switched_to_open_items")) {
|
||||
baseReasons.push("fallback_recipe_switched_to_open_items");
|
||||
}
|
||||
if (intent.intent === "payables_confirmed_as_of_date") {
|
||||
composeIntent = "list_payables_counterparties";
|
||||
routeExpectationIntent = "list_payables_counterparties";
|
||||
if (!baseReasons.includes("confirmed_payables_exact_mode_missing_subconto_fallback_to_open_items")) {
|
||||
baseReasons.push("confirmed_payables_exact_mode_missing_subconto_fallback_to_open_items");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!baseReasons.includes("mcp_missing_subconto_field_auto_fallback_failed")) {
|
||||
baseReasons.push("mcp_missing_subconto_field_auto_fallback_failed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!baseReasons.includes("mcp_missing_subconto_field_auto_fallback_failed")) {
|
||||
baseReasons.push("mcp_missing_subconto_field_auto_fallback_failed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!baseReasons.includes("mcp_missing_subconto_field_auto_fallback_unavailable")) {
|
||||
baseReasons.push("mcp_missing_subconto_field_auto_fallback_unavailable");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
mcp.error &&
|
||||
(plan.recipe.recipe_id === "address_movements_receivables_v1" ||
|
||||
plan.recipe.recipe_id === "address_movements_payables_v1") &&
|
||||
missingSubcontoFallbackEligible &&
|
||||
isMissingSubcontoFieldError(mcp.error) &&
|
||||
!allowOpenItemsFallbackForMissingSubconto &&
|
||||
!baseReasons.includes("confirmed_payables_exact_mode_missing_subconto_no_heuristic_fallback")
|
||||
) {
|
||||
baseReasons.push("confirmed_payables_exact_mode_missing_subconto_no_heuristic_fallback");
|
||||
@@ -3035,10 +3126,10 @@ export class AddressQueryService {
|
||||
});
|
||||
}
|
||||
|
||||
const factual = composeFactualReply(intent.intent, filteredRows, composeOptionsFromFilters(executionFilters));
|
||||
const factual = composeFactualReply(composeIntent, filteredRows, composeOptionsFromFilters(executionFilters));
|
||||
const factualResultSemantics = mergeAddressResultSemantics(
|
||||
deriveAddressResultSemantics({
|
||||
intent: intent.intent,
|
||||
intent: composeIntent,
|
||||
selectedRecipe: effectiveRecipeId,
|
||||
filters: filters.extracted_filters,
|
||||
responseType: factual.responseType,
|
||||
@@ -3047,7 +3138,7 @@ export class AddressQueryService {
|
||||
factual.semantics
|
||||
);
|
||||
const finalRouteExpectationAudit = buildRouteExpectationAudit({
|
||||
intent: intent.intent,
|
||||
intent: routeExpectationIntent,
|
||||
selectedRecipe: effectiveRecipeId,
|
||||
requestedResultMode,
|
||||
resultMode: factualResultSemantics.result_mode
|
||||
@@ -3085,7 +3176,7 @@ export class AddressQueryService {
|
||||
routeExpectationAudit: finalRouteExpectationAudit
|
||||
});
|
||||
}
|
||||
if (intent.intent === "payables_confirmed_as_of_date" && factualResultSemantics.balance_confirmed !== true) {
|
||||
if (intent.intent === "payables_confirmed_as_of_date" && composeIntent === "payables_confirmed_as_of_date" && factualResultSemantics.balance_confirmed !== true) {
|
||||
return buildLimitedExecutionResult({
|
||||
mode,
|
||||
shape,
|
||||
|
||||
Reference in New Issue
Block a user