QUIK МНП: входящий перевод зачисляется клиенту только после проведения в DEPO

Если по переводу есть поручение FTV_M2M, зачисление ждёт, пока события BJ_ORDER_ACCEPTED обработаны в DEPO
(SUCCESS); до того — состояние «ждёт проведения в DEPO» с причиной. Ошибка в DEPO — ждём, после возврата
в очередь и проведения зачисление проходит само. DEPO в переводе не участвует — как раньше, по ответу НРД.
22.10.2026, 895C0A32: бумаги ушли в QUIK, хотя поручение в DEPO не создалось.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
This commit is contained in:
fontvielle
2026-10-22 17:58:48 +03:00
parent 56a5a50174
commit e51962c5bb
7 changed files with 69 additions and 6 deletions
+38
View File
@@ -118,6 +118,44 @@ func depoEventsDB(rc *RuntimeConfig) (*sql.DB, error) {
return fancyOpen(fs, fs.DepoDB())
}
// depoInPosted — можно ли зачислять входящий перевод в QUIK: бумаги появляются у клиента в QUIK только после
// проведения в DEPO (операция зачисления по BJ_ORDER_ACCEPTED обработана без ошибки). gate=false — DEPO в
// переводе не участвует (обмен не настроен или поручения FTV_M2M нет): зачисление как раньше, по ответу НРД.
// DEPO недоступна — ждём (gate=true, posted=false): зачислять, не зная состояния учёта, нельзя.
func depoInPosted(ctx context.Context, rc *RuntimeConfig, guid string) (gate, posted bool, why string) {
if rc == nil || strings.TrimSpace(rc.Snapshot().Fancy.Server) == "" {
return false, false, ""
}
guid = strings.ToUpper(strings.TrimSpace(guid))
if !uuidRe.MatchString(guid) {
return false, false, ""
}
db, err := depoEventsDB(rc)
if err != nil {
return true, false, "DEPO недоступна: " + err.Error()
}
defer db.Close()
if !depoTableExists(ctx, db, "FTV_M2M_EVENTS") {
return false, false, ""
}
var m2m, ok, notOK int
var state, lastErr string
if err := db.QueryRowContext(ctx, fsql.QEvPosted, sql.Named("g", guid)).Scan(&m2m, &ok, &notOK, &state, &lastErr); err != nil {
return true, false, "DEPO: " + quikErrorDetail(err)
}
switch {
case m2m == 0:
return false, false, ""
case ok > 0 && notOK == 0:
return true, true, ""
case lastErr != "" || state == "ERROR":
return true, false, "ошибка в DEPO: " + strings.TrimSpace(lastErr) + " — устраните и верните запись в очередь («Обмен с DEPO»), зачисление в QUIK пройдёт само"
case ok+notOK == 0:
return true, false, "ждём отчёт НРД об исполнении (событие BJ_ORDER_ACCEPTED в DEPO)"
}
return true, false, "ждём проведения операции зачисления в DEPO"
}
func depoHasColumn(ctx context.Context, db *sql.DB, table, col string) bool {
var n int
_ = db.QueryRowContext(ctx, "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=@t AND COLUMN_NAME=@c", sql.Named("t", table), sql.Named("c", col)).Scan(&n)