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:
@@ -279,7 +279,8 @@ func (s *Server) pollLKClaims(ctx context.Context) {
|
||||
if !moduleAllowed(s.rc, "esia-finance") {
|
||||
continue // ЕСИА Финанс — отдельный модуль лицензии
|
||||
}
|
||||
cctx, cancel := context.WithTimeout(ctx, 50*time.Second)
|
||||
// до 4 мин: блокировка в QUIK МНП может ждать, пока модуль подхватит нового получателя
|
||||
cctx, cancel := context.WithTimeout(ctx, 4*time.Minute)
|
||||
res, err := PullLKClaims(cctx, s.rc, s.svc)
|
||||
cancel()
|
||||
if err != nil {
|
||||
|
||||
@@ -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)) })
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//go:build live
|
||||
|
||||
package lkgateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Только чтение: справочник депозитариев-получателей МНП.
|
||||
func TestQuikRecipientsLive(t *testing.T) {
|
||||
rc, err := NewRuntimeConfig("/var/lib/bj/.bj/setup.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
conn, err := quikOpen(rc.Snapshot().Quik)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer conn.Close()
|
||||
rows, err := conn.QueryContext(context.Background(), "SELECT Id, INN, Name FROM M2MDepoRecipients ORDER BY Id")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for rows.Next() {
|
||||
var id int
|
||||
var inn, name string
|
||||
_ = rows.Scan(&id, &inn, &name)
|
||||
fmt.Println(id, inn, name)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user