M2M ИИС: приём «всё или ничего» (настройка AcceptIIS, по умолчанию выкл)
Правильная обработка входящих переводов на ИИС вместо прежнего сплошного отказа.
Настройка AcceptIIS (карточка «Кто отвечает на переводы M2M»):
- выкл (по умолчанию) — поведение не меняется: перевод на ИИС отклоняется целиком (M2M06);
- вкл — ИИС принимается ТОЛЬКО целиком: все бумаги зачисляются на ИИС-счёт клиента;
если хоть одной бумаги нет в учёте / не проходит сверку — отказ по ВСЕМУ переводу.
Изменения:
- iisDecisions: «всё или ничего» (при выкл — отказ всем; при вкл — либо все принять,
либо все отклонить, сохраняя реальные коды отказа по проблемным бумагам);
- depo_check: при вкл приёме ИИС убран искусственный отказ «Перевод не на ИИС»,
добавлена проверка «Счёт зачисления — ИИС» (partyChecks получил флаг wantIIS);
- настройка AcceptIIS в Settings + геттер/сеттер + обработчик /admin/setup/accept-iis
+ тумблер в part_nsd.html; тесты обновлены.
Жёсткий запрет частичного ИИС в answerIncoming (коммит dc8b785) остаётся как страховка.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -162,20 +162,62 @@ func answerIncoming(ctx context.Context, deps incomingDeps, id string, decisions
|
||||
// transferringINN — ИНН нашей организации (передающий депозитарий в запросе, принимающий — в решении).
|
||||
func transferringINN(s Settings) string { return orgINN(s) }
|
||||
|
||||
// iisRejectCode — код отказа по переводу на ИИС: M2M06 «Приостановление операций по счёту депо зачисления»
|
||||
// (решение депозитария 07.10.2026; до этого — M2M07).
|
||||
// iisRejectCode — код отказа по переводу на ИИС: M2M06 «Приостановление операций по счёту депо
|
||||
// зачисления» (решение депозитария 07.10.2026; до этого — M2M07).
|
||||
const iisRejectCode = "M2M06"
|
||||
|
||||
// iisDecisions — входящие переводы на ИИС не принимаем (решение 25.09.2026): отказ iisRejectCode по всем
|
||||
// бумагам, даже если оператор отметил «принять». Остальные переводы — по каждой бумаге отдельно.
|
||||
// iisDecisions применяет к ИИС-переводу правило «ВСЁ ИЛИ НИЧЕГО»: ИИС переводится только целиком,
|
||||
// иначе у клиента окажется два ИИС с потерей льгот.
|
||||
// - приём ИИС выключен (по умолчанию, AcceptIIS=false) → отказ по всем бумагам (iisRejectCode);
|
||||
// - приём ИИС включён и подтверждена КАЖДАЯ бумага перевода → принимаем ИИС полностью;
|
||||
// - приём ИИС включён, но хоть одна бумага не подтверждена → отказ по ВСЕМ бумагам (у бумаг с
|
||||
// явной причиной отказа её код сохраняется, у остальных — iisRejectCode).
|
||||
//
|
||||
// Не-ИИС переводы не трогаем — решение по каждой бумаге отдельно.
|
||||
func iisDecisions(it *IncomingTransfer, decisions []SecurityDecision) []SecurityDecision {
|
||||
if it == nil || !incomingIsIIS(it) {
|
||||
return decisions
|
||||
}
|
||||
out := make([]SecurityDecision, len(decisions))
|
||||
for i, d := range decisions {
|
||||
d.Confirm, d.RejectCode = false, iisRejectCode
|
||||
out[i] = d
|
||||
rejectAll := func() []SecurityDecision {
|
||||
explicit := make(map[string]SecurityDecision, len(decisions))
|
||||
for _, d := range decisions {
|
||||
explicit[d.ReferenceID] = d
|
||||
}
|
||||
out := make([]SecurityDecision, 0, len(it.Securities))
|
||||
for _, sec := range it.Securities {
|
||||
d := SecurityDecision{ReferenceID: sec.ReferenceID, RejectCode: iisRejectCode}
|
||||
if e, ok := explicit[sec.ReferenceID]; ok && !e.Confirm && e.RejectCode != "" {
|
||||
d.RejectCode = e.RejectCode // сохраняем реальную причину отказа оператора/сверки
|
||||
}
|
||||
out = append(out, d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
return out
|
||||
if !m2mAcceptIIS() {
|
||||
return rejectAll() // приём ИИС выключен — отклоняем перевод целиком
|
||||
}
|
||||
if len(it.Securities) == 0 {
|
||||
return rejectAll()
|
||||
}
|
||||
// Принимаем ИИС, только если подтверждена КАЖДАЯ бумага перевода.
|
||||
confirm := make(map[string]bool, len(decisions))
|
||||
for _, d := range decisions {
|
||||
if d.Confirm {
|
||||
confirm[d.ReferenceID] = true
|
||||
}
|
||||
}
|
||||
for _, sec := range it.Securities {
|
||||
if !confirm[sec.ReferenceID] {
|
||||
return rejectAll() // хоть одна бумага не принимается — отказ по всему ИИС
|
||||
}
|
||||
}
|
||||
return decisions // все бумаги подтверждены — принимаем ИИС полностью
|
||||
}
|
||||
|
||||
// m2mAcceptIIS — включён ли приём входящих переводов на ИИС в текущих настройках.
|
||||
func m2mAcceptIIS() bool {
|
||||
if globalRC == nil {
|
||||
return false
|
||||
}
|
||||
return globalRC.AcceptIIS()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user