Задача и предварительные условия
Сравните сумму заявки с индивидуальным лимитом её подразделения, а не общей константой для всех.
В примере используются демонстрационные данные и настройки. Проверьте ожидаемый результат в своей среде до подключения рабочих получателей. Идентификаторы demo_* условны: выберите собственные учебные подключения или источники в редакторе. JSON ниже показывает структуру блоков и связей, а не готовый архив потока для переноса.
Учебные входные данные
requests.csv
Request;Dept;Amount
R1;IT;900
R2;HR;600
R3;IT;1200
limits.csv
Dept;Limit
IT;1000
HR;500
Блоки, связи и точные настройки
Схема примера 11: блоков — 7, связей — 6. Идентификаторы узлов и порты настроенной схемы сохранены.
Схема: requests и limits → соединение по Dept → проверка обязательного лимита → маршрутизация Amount > Limit → два результата. Используйте левое соединение с many_to_one, чтобы повторные строки справочника не размножали заявки. Поля соединения имеют префиксы r. и l.
{
"version": 3,
"nodes": [
{
"id": "requests",
"type": "file",
"label": "Requests",
"config": {
"role": "source",
"source_id": "demo_requests",
"options": {
"sheet": "CSV",
"range": "A1:C4",
"header": true,
"delimiter": ";"
}
}
},
{
"id": "limits",
"type": "file",
"label": "Limits",
"config": {
"role": "source",
"source_id": "demo_limits",
"options": {
"sheet": "CSV",
"range": "A1:B3",
"header": true,
"delimiter": ";"
}
}
},
{
"id": "join",
"type": "join",
"label": "Department limit",
"config": {
"inputs": [
{
"id": "requests",
"alias": "r"
},
{
"id": "limits",
"alias": "l",
"how": "left",
"keys": [
{
"left": "r.Dept",
"right": "Dept"
}
],
"cardinality": "many_to_one"
}
]
}
},
{
"id": "quality",
"type": "quality",
"label": "Limit required",
"config": {
"rules": [
{
"fields": [
"l.Limit"
],
"condition": "empty",
"action": "error"
}
]
}
},
{
"id": "router",
"type": "router",
"label": "Limit check",
"config": {
"route_type": "conditions",
"mode": "first",
"default_route": true,
"routes": [
{
"id": "over",
"label": "Over limit",
"predicates": [
{
"column": "r.Amount",
"op": "gt",
"numeric": true,
"value_mode": "field",
"value_field": "l.Limit"
}
]
}
]
}
},
{
"id": "over_out",
"type": "export",
"label": "Over limit",
"config": {
"format": "csv",
"filename": "over_limit",
"destination": "download",
"delimiter": ";",
"timezone": "Europe/Kyiv"
}
},
{
"id": "within_out",
"type": "export",
"label": "Within limit",
"config": {
"format": "csv",
"filename": "within_limit",
"destination": "download",
"delimiter": ";",
"timezone": "Europe/Kyiv"
}
}
],
"edges": [
{
"source": "requests",
"target": "join",
"source_port": "out",
"target_port": "requests"
},
{
"source": "limits",
"target": "join",
"source_port": "out",
"target_port": "limits"
},
{
"source": "join",
"target": "quality",
"source_port": "out",
"target_port": "in"
},
{
"source": "quality",
"target": "router",
"source_port": "out",
"target_port": "in"
},
{
"source": "router",
"target": "over_out",
"source_port": "over",
"target_port": "in"
},
{
"source": "router",
"target": "within_out",
"source_port": "else",
"target_port": "in"
}
]
}Ожидаемый результат
over_limit.csv содержит R2 (600 > 500) и R3 (1200 > 1000). within_limit.csv содержит R1 (900 ≤ 1000). Результат включает присоединённый лимит; поля заявки имеют префикс r., справочника — l.
Запуск и проверка
- Зарегистрируйте оба CSV и обеспечьте один лимит на Dept.
- Постройте схему JSON; выберите requests основным входом соединения, limits — левым соединением по Dept.
- Проверьте l.Limit и правило ошибки отсутствующих лимитов.
- Проверьте три заявки: R1 в пределах лимита, R2 и R3 превышают.
- Добавьте Dept=FIN без лимита: проверка качества должна остановиться до экспорта.
Устранение неполадок
- Используйте точные имена после соединения: r.Amount и l.Limit.
- Повторные Dept нарушают many_to_one; исправьте справочник.
- Не заменяйте отсутствующий лимит нулём без бизнес-правила.
- Маршрутизация сравнивает поля текущей строки; прежний вход справочника не нужен.