DEPO: LINK_NUMBER строк = депозитарный счёт НРД; BJ_SERVICE_ERROR и BJ_QUIK_* по строкам (REFERENCE); убраны события на весь GUID — по замечаниям Fancy 22.09

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
This commit is contained in:
zuevav
2026-09-23 00:44:29 +03:00
parent bb89a56a0c
commit 199a0f5cc9
2 changed files with 40 additions and 14 deletions
+37 -14
View File
@@ -247,7 +247,8 @@ func depoUpsertOrder(rc *RuntimeConfig, guid, direction, cpCode, deponentName, d
if ln.ISIN != "" && hasShare {
_ = db.QueryRowContext(ctx, fsql.QEv04, sql.Named("i", ln.ISIN)).Scan(&share)
}
cols, vals := "GUID, REFERENCE, ISIN, SEC_CODE, AMOUNT, PLACE_NUMBER, LINK_NUMBER", "@g, @r, @i, @c, @a, @p, ''"
// LINK_NUMBER — наш депозитарный счёт в НРД: по нему джоба bj2depo находит регистр аналитики (В. Кокин, 22.09.2026)
cols, vals := "GUID, REFERENCE, ISIN, SEC_CODE, AMOUNT, PLACE_NUMBER, LINK_NUMBER", "@g, @r, @i, @c, @a, @p, @lnk"
if hasShare {
cols, vals = cols+", SHARE", vals+", @sh"
}
@@ -256,7 +257,7 @@ func depoUpsertOrder(rc *RuntimeConfig, guid, direction, cpCode, deponentName, d
}
q := fsql.Ev06 + cols + `) VALUES (` + vals + `)`
if _, err := tx.ExecContext(ctx, q,
sql.Named("g", guid), sql.Named("r", ln.Ref), sql.Named("i", nullStr(ln.ISIN)), sql.Named("c", nullStr(ln.Code)), sql.Named("sh", share), sql.Named("a", ln.Amount), sql.Named("p", nullStr(ln.Place)), sql.Named("acc", clientAcc)); err != nil {
sql.Named("g", guid), sql.Named("r", ln.Ref), sql.Named("i", nullStr(ln.ISIN)), sql.Named("c", nullStr(ln.Code)), sql.Named("sh", share), sql.Named("a", ln.Amount), sql.Named("p", nullStr(ln.Place)), sql.Named("lnk", strings.TrimSpace(rc.Snapshot().NSD.AccountID)), sql.Named("acc", clientAcc)); err != nil {
tx.Rollback()
log.Printf("depo-events: FTV_M2M_LINES %s/%s: %v", shortGUID(guid), ln.Ref, err)
return false
@@ -382,7 +383,37 @@ func depoOnCounterpartyDecision(rc *RuntimeConfig, decision *m2m.M2MTransferDeci
}
func depoOnServiceError(rc *RuntimeConfig, guid, codes, reason string) {
depoEvent(rc, guid, "", "BJ_SERVICE_ERROR", strings.ReplaceAll(strings.TrimSpace(codes), " ", ";"), reason)
// по строкам: джоба bj2depo ищет строку по GUID+REFERENCE для любого события
for _, ref := range depoLineRefs(rc, guid, "") {
depoEvent(rc, guid, ref, "BJ_SERVICE_ERROR", strings.ReplaceAll(strings.TrimSpace(codes), " ", ";"), reason)
}
}
// depoLineRefs — REFERENCE строк перевода из FTV_M2M_LINES (по ISIN, если задан; иначе все строки).
func depoLineRefs(rc *RuntimeConfig, guid, isin string) []string {
db, err := depoEventsDB(rc)
if err != nil {
return nil
}
defer db.Close()
ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second)
defer cancel()
rows, err := db.QueryContext(ctx, fsql.QEv09, sql.Named("g", strings.ToUpper(guid)), sql.Named("i", strings.ToUpper(strings.TrimSpace(isin))))
if err != nil {
return nil
}
defer rows.Close()
var refs []string
for rows.Next() {
var r string
if rows.Scan(&r) == nil && r != "" {
refs = append(refs, r)
}
}
if len(refs) == 0 && isin != "" {
return depoLineRefs(rc, guid, "")
}
return refs
}
// СТРОЧНЫЕ события по депо-поручениям (договорённость с Fancy 18.09.2026, ответы
@@ -415,22 +446,14 @@ func depoOnOrderLineResult(rc *RuntimeConfig, guid, ref, kind, text string) {
}
}
// depoOnOrderSent / depoOnOrderResult — прежний формат «на весь GUID» (пустой
// REFERENCE). Оставлены для совместимости вызовов; новые пути пишут по строкам.
func depoOnOrderSent(rc *RuntimeConfig, guid string, contrDIDs []string, form string) {
depoEvent(rc, guid, "", "BJ_ORDER_SENT", "", strings.Join(contrDIDs, ";"))
}
func depoOnOrderResult(rc *RuntimeConfig, guid, kind, text string) {
depoOnOrderLineResult(rc, guid, "", kind, text)
}
func depoOnQuik(rc *RuntimeConfig, guid, isin, evt, instrNo string) {
typ := map[string]string{"register": "BJ_QUIK_BLOCKED", "deny": "BJ_QUIK_RELEASED", "sign": "BJ_QUIK_SIGNED", "deposit": "BJ_QUIK_DEPOSITED"}[evt]
if typ == "" {
return
}
depoEvent(rc, guid, "", typ, "", instrNo)
for _, ref := range depoLineRefs(rc, guid, isin) {
depoEvent(rc, guid, ref, typ, "", instrNo)
}
}
// ---- чтение событий DEPO ----