# Вопросы программисту Fancy: частичное исполнение пакета M2M Контекст. По входящему переводу M2M на несколько бумаг НРД после нашего согласия формирует отдельное депо-поручение 16/1 на каждую бумагу (черновики MF010 приходят по одному на бумагу). Дальше каждое поручение исполняется независимо: по одному может прийти MS010 «исполнено», по другому — MS010 с отказом (не сквитовалось со встречным 16 контрагента, GS116 «не сквитовано», истёк срок 30 дней). Пример: пакет «10 Сбер + 10 Т-Технологии», Сбер зачислен, Т-Технологии — нет. То же возможно по исходящим (поручения 16 по каждой бумаге). Сейчас bj пишет в FTV_M2M_EVENTS события на весь перевод (REFERENCE пустой): BJ_ORDER_ACCEPTED + BJ_EXECUTED либо BJ_ORDER_REJECTED. При частичном исполнении это неверно. bj готов писать события **по строке пакета** (REFERENCE = Security/ReferenceId из FTV_M2M_LINES). ## Вопросы 1. **События по строке.** Умеет ли bj2depo обрабатывать событие с заполненным `REFERENCE` (одна бумага пакета): создать проводку зачисления/списания только по ней и не трогать другие строки? Или джоба работает только с событием на весь GUID? 2. **Набор событий для частичного исхода.** Какой вариант удобен джобе: - (а) по каждой строке своё событие: `BJ_EXECUTED` (REFERENCE=Сбер) и `BJ_ORDER_REJECTED` (REFERENCE=Т-Технологии, PARAMETERS — текст отказа НРД); события на весь GUID при этом не пишутся; - (б) одно событие на GUID `BJ_EXECUTED_PARTIAL` с перечнем в PARAMETERS (`executed: ISIN…; rejected: ISIN… — причина`), проводки делает оператор Fancy вручную; - (в) оба: строчные события для проводок и сводное на GUID для статуса документа. 3. **Порядок во времени.** MS010 по разным бумагам приходят в разное время (минуты — дни). Можно ли писать событие по строке сразу при получении её MS010, не дожидаясь остальных (документ в DEPO будет какое-то время «частично исполнен»)? Или ждать, пока ответят по всем, и писать пакетом? 4. **Состояние документа DEPO.** Какое STATE/COMMENT bj2depo поставит документу, у которого часть строк исполнена, часть отказана? Есть ли в DEPO статус «исполнено частично», или документ разделяется на два? 5. **Отказ после исполнения.** Если по бумаге сначала пришло REORD/принятие, а затем отказ (MS010 с отказом) — нужно ли отдельное событие отмены ранее созданной проводки, или `BJ_ORDER_REJECTED` по строке этого достаточно? 6. **Срок 30 дней.** Поручение без MS010 через 30 дней считается отменённым. Сейчас bj пишет `BJ_CANCELLED` на весь GUID. По строке — тем же событием с REFERENCE? 7. **Поручения без строки.** `BJ_ORDER_SENT` сейчас несёт номера всех поданных поручений (contr_d_id) в PARAMETERS. Нужно ли джобе соответствие contr_d_id ↔ REFERENCE (в каком поле)? 8. **Обратная совместимость.** Пока джоба не умеет строки — можем ли мы продолжать писать события на GUID при полном исполнении/полном отказе и переходить на строчные только при частичном исходе? Или переключаться целиком? ## Что сделает bj после ответа - хранить по каждому поручению 16/16-1 связку `contr_d_id ↔ ISIN ↔ REFERENCE`; - вердикт по каждому поручению; статус перевода «исполнен» только когда исполнены все, «отказ» — когда отказ по всем, иначе «исполнен частично» с ожиданием остальных; - события в FTV_M2M_EVENTS в согласованном формате (п. 2); - в карточке перевода — статус по каждой бумаге, оповещение оператору о частичном исполнении. --- ## Ответы Fancy (В. Кокин, письмо 21.09.2026) и что реализовано в bj | # | Вопрос | Ответ | В bj | |---|--------|-------|------| | 1 | Событие с REFERENCE по одной бумаге — провести только её | **Да** | события исходов пишутся по строкам с REFERENCE | | 2 | Формат при частичном исходе | **(а) отдельные события по строкам** — они приходят в разное время | `BJ_EXECUTED`/`BJ_ORDER_REJECTED` по каждой строке | | 3 | Писать по строке сразу при её MS010 или ждать все | **Сразу** | `orderWatchCheck` пишет исход строки в момент её MS010 | | 4 | Состояние документа DEPO при частичном исполнении | **есть статус «частично»**, документ не делится | карточка bj: «исполнено частично: N из M» (`StatusRu`/`Kind`=warn) | | 5 | Отказ после принятия (REORD) — событие отмены проводки? | **Такого не может быть**; экстремальный казус — руками | отдельного события отмены нет | | 6 | 30 дней по одной бумаге → `BJ_CANCELLED` с REFERENCE | **Да** | истечение по строке → `BJ_CANCELLED` с REFERENCE, QUIK-блок снимается по ISIN | | 7 | Связка contr_d_id ↔ REFERENCE джобе | **Не нужна** — по REFERENCE найдёт всё | contr_d_id кладём в COMMENT для разбора | | 8 | Совместимость: строчные только при частичном? | **Сразу везде**, но **одновременно** на bj и bj2depo | все `BJ_ORDER_*`/`BJ_EXECUTED`/`BJ_CANCELLED` — строчные; события на весь GUID больше не пишем | **Реализация в bj** (`orderwatch.go`, `depoevents.go`, `incoming*.go`, `outgoing_order.go`): - одно депо-поручение (MF010) = одна бумага; входящий 16/1 теперь хранит **все** `contr_d_id` (`OrderLines`: contr_d_id ↔ ISIN ↔ REFERENCE) — раньше только первый; - исходящий 16: REFERENCE берётся из бумаг M2MTR по ISIN (`outgoingLineRefs`, кэш по GUID); - `OrderWatch.Lines` — состояние по строкам; объект закрыт, когда MS010 по всем строкам; - `BJ_ORDER_SENT` — по строке (COMMENT = contr_d_id); `BJ_ORDER_LATE` — по каждой незакрытой строке при просрочке 5 мин. **Развёртывание — только одновременно с bj2depo** (п. 8): до подтверждения Вадима, что джоба читает строчные события, bj на стенд/бой не выкатывается. Предложение Вадима: прогнать тесты с реальным контрагентом на функционале вендора (есть компания с потребностью тестировать).