Направить денежный смысл контрагента в двусторонний поток
This commit is contained in:
@@ -938,6 +938,12 @@ function nextStepFor(mode, pilot) {
|
||||
}
|
||||
return "Следующий шаг - связать inventory route-template с exact inventory runtime и затем проверить live-прогоном.";
|
||||
}
|
||||
if (mode === "checked_sources_only" && hasExecutedZeroValueFlowRows(pilot)) {
|
||||
const flowLabel = pilot.pilot_scope === "counterparty_supplier_payout_query_movements_v1"
|
||||
? "исходящие платежи/списания"
|
||||
: "входящие денежные поступления";
|
||||
return `Можно следующим шагом проверить ${flowLabel} по этому контрагенту в соседних периодах, по договорам или документам, либо собрать двусторонний денежный поток, чтобы отделить отсутствие строк в текущем срезе от операций вне проверенного окна.`;
|
||||
}
|
||||
if (mode === "confirmed_with_bounded_inference" && isBusinessOverviewPilot(pilot)) {
|
||||
return pilot.derived_business_overview
|
||||
? businessOverviewNextStepLine(pilot.derived_business_overview)
|
||||
|
||||
@@ -882,6 +882,10 @@ function hasBidirectionalValueFlowSignal(text) {
|
||||
if (/(?:\u043d\u0435\u0442\u0442\u043e|\u0441\u0430\u043b\u044c\u0434\u043e|\u0431\u0430\u043b\u0430\u043d\u0441\s+(?:\u043f\u043b\u0430\u0442|\u0434\u0435\u043d\u0435\u0433|\u0434\u0435\u043d\u0435\u0436)|\u0432\u0437\u0430\u0438\u043c\u043e\u0440\u0430\u0441\u0447[\u0435\u0451]\u0442|\u043f\u043e\u043b\u0443\u0447\p{L}*.*(?:\u0437\u0430)?\u043f\u043b\u0430\u0442\p{L}*|(?:\u0437\u0430)?\u043f\u043b\u0430\u0442\p{L}*.*\u043f\u043e\u043b\u0443\u0447\p{L}*|\u0432\u0445\u043e\u0434\u044f\u0449.*\u0438\u0441\u0445\u043e\u0434\u044f\u0449|\u0438\u0441\u0445\u043e\u0434\u044f\u0449.*\u0432\u0445\u043e\u0434\u044f\u0449|\u043f\u0440\u0438\u0448\p{L}*.*\u0443\u0448\p{L}*|\u0443\u0448\p{L}*.*\u043f\u0440\u0438\u0448\p{L}*|\u043f\u043b\u044e\u0441.*\u043c\u0438\u043d\u0443\u0441|\u043c\u0438\u043d\u0443\u0441.*\u043f\u043b\u044e\u0441|net\s+(?:flow|cash|payment)|cash\s+net|incoming\s+and\s+outgoing|received\s+and\s+paid|paid\s+and\s+received)/iu.test(text)) {
|
||||
return true;
|
||||
}
|
||||
if (/(?:\u043e\u0431\u0449\p{L}*[\s\S]{0,60}\u0434\u0435\u043d\p{L}*[\s\S]{0,60}\u0441\u043c\u044b\u0441\u043b|\u0434\u0435\u043d\p{L}*[\s\S]{0,40}\u0441\u043c\u044b\u0441\u043b|overall[\s\S]{0,40}(?:cash|money)[\s\S]{0,40}(?:meaning|sense)|money[\s\S]{0,40}(?:meaning|sense))/iu.test(text) &&
|
||||
hasPayoutSignal(text)) {
|
||||
return true;
|
||||
}
|
||||
return /(?:нетто|сальдо|баланс\s+(?:плат|денег|денеж)|взаиморасч[её]т|получил[иа]?.*(?:за)?платил|(?:за)?платил[иа]?.*получил|входящ.*исходящ|исходящ.*входящ|дебет.*кредит|кредит.*дебет|net\s+(?:flow|cash|payment)|cash\s+net|incoming\s+and\s+outgoing|received\s+and\s+paid|paid\s+and\s+received)/iu.test(text);
|
||||
}
|
||||
function hasValueRankingSignal(text) {
|
||||
|
||||
@@ -184,7 +184,10 @@ function detectScopedCounterpartyEntity(text) {
|
||||
if (!rawEntity) {
|
||||
continue;
|
||||
}
|
||||
const entity = rawEntity.replace(/^["'«»]+|["'«»]+$/gu, "").trim();
|
||||
const entity = rawEntity
|
||||
.replace(/^["'«»]+|["'«»]+$/gu, "")
|
||||
.replace(/^(?:\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a(?:\u0443|\u0430|\u043e\u043c|\u0435)?|\u043a\u043b\u0438\u0435\u043d\u0442(?:\u0443|\u0430|\u043e\u043c|\u0435)?|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442(?:\u0443|\u0430|\u043e\u043c|\u0435)?)\s+/iu, "")
|
||||
.trim();
|
||||
if (entity.length >= 2 && !ignored.has(entity)) {
|
||||
return entity;
|
||||
}
|
||||
@@ -195,7 +198,8 @@ function detectCounterpartyBidirectionalValueFlowFamily(text) {
|
||||
const hasNetCue = /(?:\u043d\u0435\u0442\u0442\u043e|\u0441\u0430\u043b\u044c\u0434\u043e|net\s+(?:flow|cash|payment)|cash\s+net)/iu.test(text);
|
||||
const hasIncomingCue = /(?:\u043f\u043e\u043b\u0443\u0447\p{L}*|\u0432\u0445\u043e\u0434\p{L}*|\u043f\u043e\u0441\u0442\u0443\u043f\p{L}*|received|incoming)/iu.test(text);
|
||||
const hasOutgoingCue = /(?:\u0437\u0430\u043f\u043b\u0430\u0442\p{L}*|\u0438\u0441\u0445\u043e\u0434\p{L}*|\u0441\u043f\u0438\u0441\u0430\u043d\p{L}*|paid|outgoing|payment)/iu.test(text);
|
||||
if (!(hasNetCue || (hasIncomingCue && hasOutgoingCue))) {
|
||||
const hasOverallMoneyMeaningCue = /(?:\u043e\u0431\u0449\p{L}*[\s\S]{0,60}\u0434\u0435\u043d\p{L}*[\s\S]{0,60}\u0441\u043c\u044b\u0441\u043b|\u0434\u0435\u043d\p{L}*[\s\S]{0,40}\u0441\u043c\u044b\u0441\u043b|overall[\s\S]{0,40}(?:cash|money)[\s\S]{0,40}(?:meaning|sense)|money[\s\S]{0,40}(?:meaning|sense))/iu.test(text);
|
||||
if (!(hasNetCue || (hasIncomingCue && hasOutgoingCue) || (hasOverallMoneyMeaningCue && hasOutgoingCue))) {
|
||||
return null;
|
||||
}
|
||||
const entity = detectScopedCounterpartyEntity(text);
|
||||
@@ -410,7 +414,9 @@ function createAssistantTurnMeaningPolicy(deps = {}) {
|
||||
: detectBroadBusinessEvaluation(joinedText);
|
||||
const explicitIntentCandidate = broadBusinessEvaluation?.family
|
||||
? null
|
||||
: supportedIntent?.intent ?? (llmIntent && llmIntent !== "unknown" ? llmIntent : null);
|
||||
: counterpartyBidirectionalValueFlow?.family
|
||||
? null
|
||||
: supportedIntent?.intent ?? (llmIntent && llmIntent !== "unknown" ? llmIntent : null);
|
||||
const unsupportedFamily = broadBusinessEvaluation?.family
|
||||
? broadBusinessEvaluation.family
|
||||
: !explicitIntentCandidate && counterpartyBidirectionalValueFlow?.family
|
||||
|
||||
Reference in New Issue
Block a user