QUIK МНП: новый получатель M2M — повтор регистрации вывода (3×30 с), пока модуль не подхватит справочник; имя получателя из справочника НРД; опрос ЛК — до 4 мин на проход

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-09-29 13:29:25 +03:00
parent b0de7f2979
commit 7a84dd6d5b
3 changed files with 63 additions and 5 deletions
+29 -4
View File
@@ -491,6 +491,12 @@ func quikStep(action string, aid int64, r QuikActionResult, ok bool) QuikStep {
return QuikStep{At: time.Now(), Action: action, ActionID: aid, Status: r.QueryStatus, Reply: r.ReplyText, OK: ok}
}
// Повтор регистрации, пока модуль МНП не подхватил нового получателя из M2MDepoRecipients.
var (
quikRecipientRetries = 3
quikRecipientWait = 30 * time.Second
)
// QuikOutRegister — исходящий перевод: зарегистрировать «Вывод ЦБ (M2M)» (QUIK блокирует бумаги).
func QuikOutRegister(ctx context.Context, rc *RuntimeConfig, guid, clientID, contract, isin string, qty float64, recipientINN, recipientName string, passExpenses bool) (*QuikLink, error) {
s := quikSettingsFor(rc, guid)
@@ -500,14 +506,33 @@ func QuikOutRegister(ctx context.Context, rc *RuntimeConfig, guid, clientID, con
if s.Emulate {
return quikEmulated(rc, guid, isin, "register", "registered", "вывод зарегистрирован, бумаги заблокированы"), nil
}
if strings.TrimSpace(recipientName) == "" {
recipientName = m2mPartyName(recipientINN) // наименование из справочника НРД
}
if err := quikEnsureRecipient(ctx, s, recipientINN, recipientName); err != nil {
return quikFail(rc, guid, isin, "register", err), err
}
aid, err := quikExecNewInstr(ctx, s, true, shortGUID(guid), clientID, isin, qty, recipientINN, passExpenses, "M2M bj: перевод "+shortGUID(guid))
if err != nil {
return quikFail(rc, guid, isin, "register", err), err
var aid int64
var r QuikActionResult
// Нового получателя (только что добавлен в M2MDepoRecipients) модуль МНП подхватывает не сразу —
// «Неизвестный депозитарий получателя»: ждём и повторяем, а не отклоняем заявку клиента.
for attempt := 1; ; attempt++ {
var err error
aid, err = quikExecNewInstr(ctx, s, true, shortGUID(guid), clientID, isin, qty, recipientINN, passExpenses, "M2M bj: перевод "+shortGUID(guid))
if err != nil {
return quikFail(rc, guid, isin, "register", err), err
}
r = quikWaitAction(ctx, s, aid, quikActionWait)
if attempt > quikRecipientRetries || !strings.Contains(strings.ToLower(r.ReplyText), "неизвестный депозитарий получателя") {
break
}
log.Printf("quik: %s: МНП ещё не знает получателя ИНН %s — повтор через %s (попытка %d из %d)", shortGUID(guid), recipientINN, quikRecipientWait, attempt, quikRecipientRetries)
select {
case <-ctx.Done():
return quikFail(rc, guid, isin, "register", ctx.Err()), ctx.Err()
case <-time.After(quikRecipientWait):
}
}
r := quikWaitAction(ctx, s, aid, quikActionWait)
if r.QueryStatus != 2 || r.InstrNo == "" || r.InstrNo == "0" {
err := fmt.Errorf("МНП отверг регистрацию: %s", r.ReplyText)
globalQuikLinks.update(guid, isin, func(l *QuikLink) { l.Steps = append(l.Steps, quikStep("register", aid, r, false)) })