From 6a2e9b71221db54a41017f667da097c45d46821a Mon Sep 17 00:00:00 2001 From: zuevav Date: Wed, 16 Sep 2026 16:14:32 +0300 Subject: [PATCH] =?UTF-8?q?DEPO:=20=D0=B2=20=D1=81=D1=82=D1=80=D0=BE=D0=BA?= =?UTF-8?q?=D0=B0=D1=85=20FTV=5FM2M=5FLINES=20=D0=B7=D0=B0=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D0=BD=D1=8F=D0=B5=D1=82=D1=81=D1=8F=20DEPO=5FNUMBER=20?= =?UTF-8?q?=E2=80=94=20=D1=82=D0=BE=D1=80=D0=B3=D0=BE=D0=B2=D1=8B=D0=B9=20?= =?UTF-8?q?=D1=81=D1=87=D1=91=D1=82=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=D0=B0=20=D0=92=D0=A2=D0=9D=D0=9A=D0=A6=20(=D1=81=D0=B0=D0=BC?= =?UTF-8?q?=D1=8B=D0=B9=20=D1=80=D0=B0=D0=BD=D0=BD=D0=B8=D0=B9=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80),=20=D1=87=D1=82=D0=BE?= =?UTF-8?q?=D0=B1=D1=8B=20=D0=B4=D0=B6=D0=BE=D0=B1=D0=B0=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=D0=B2=D1=8F=D0=B7=D0=B0=D0=BB=D0=B0=20=D1=81=D1=87=D1=91?= =?UTF-8?q?=D1=82=20=D0=BA=20=D0=BF=D0=BE=D1=80=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 (1M context) --- internal/lkgateway/depoevents.go | 23 +++++++++++++++---- .../templates/admin_help_fancy_events.html | 2 +- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/internal/lkgateway/depoevents.go b/internal/lkgateway/depoevents.go index 0dc20fd..4119d67 100644 --- a/internal/lkgateway/depoevents.go +++ b/internal/lkgateway/depoevents.go @@ -206,6 +206,17 @@ func depoUpsertOrder(rc *RuntimeConfig, guid, direction, cpCode, deponentName, d if serN != "" && strings.TrimSpace(num) != "" { _ = db.QueryRowContext(ctx, "SELECT TOP 1 SELF_ID FROM OD_FACES WHERE REPLACE(DOC_SER,' ','')=@s AND DOC_NUM=@n ORDER BY ID", sql.Named("s", serN), sql.Named("n", strings.TrimSpace(num))).Scan(&deponentID) } + // счёт клиента для DEPO_NUMBER строк: открытый торговый ВТНКЦ…, при нескольких договорах — самый + // ранний (то же правило, что при зачислении в QUIK); джоба по номеру находит OD_CLIENTS.ID (DEPO). + var clientAcc sql.NullString + if serN != "" && strings.TrimSpace(num) != "" { + _ = db.QueryRowContext(ctx, `SELECT TOP 1 c.NUMBER FROM OD_FACES f + JOIN OD_CLIENTS c ON c.FACE=f.ID LEFT JOIN OD_CLIENTS_PORTS p ON p.CLIENT=c.ID + WHERE REPLACE(f.DOC_SER,' ','')=@s AND f.DOC_NUM=@n AND c.NUMBER LIKE N'ВТНКЦ%' AND c.STATE=0 AND c.D_CLOSE IS NULL + ORDER BY ISNULL(p.PORT_DATE,'2099-01-01'), ISNULL(c.D_OPEN,'2099-01-01'), c.NUMBER`, + sql.Named("s", serN), sql.Named("n", strings.TrimSpace(num))).Scan(&clientAcc) + } + hasDepoNumber := depoHasColumn(ctx, db, "FTV_M2M_LINES", "DEPO_NUMBER") hasDeponentID := depoHasColumn(ctx, db, "FTV_M2M", "DEPONENT_ID") tx, err := db.BeginTx(ctx, nil) if err != nil { @@ -230,12 +241,16 @@ func depoUpsertOrder(rc *RuntimeConfig, guid, direction, cpCode, deponentName, d if ln.ISIN != "" && hasShare { _ = db.QueryRowContext(ctx, "SELECT TOP 1 ID FROM OD_VALUES WHERE ISIN=@i ORDER BY ID", sql.Named("i", ln.ISIN)).Scan(&share) } - q := `INSERT INTO dbo.FTV_M2M_LINES (GUID, REFERENCE, ISIN, SEC_CODE, AMOUNT, PLACE_NUMBER, LINK_NUMBER) VALUES (@g, @r, @i, @c, @a, @p, '')` + cols, vals := "GUID, REFERENCE, ISIN, SEC_CODE, AMOUNT, PLACE_NUMBER, LINK_NUMBER", "@g, @r, @i, @c, @a, @p, ''" if hasShare { - q = `INSERT INTO dbo.FTV_M2M_LINES (GUID, REFERENCE, ISIN, SEC_CODE, SHARE, AMOUNT, PLACE_NUMBER, LINK_NUMBER) VALUES (@g, @r, @i, @c, @sh, @a, @p, '')` + cols, vals = cols+", SHARE", vals+", @sh" } + if hasDepoNumber { + cols, vals = cols+", DEPO_NUMBER", vals+", @acc" + } + q := `INSERT INTO dbo.FTV_M2M_LINES (` + 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))); 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("acc", clientAcc)); err != nil { tx.Rollback() log.Printf("depo-events: FTV_M2M_LINES %s/%s: %v", shortGUID(guid), ln.Ref, err) return false @@ -245,7 +260,7 @@ func depoUpsertOrder(rc *RuntimeConfig, guid, direction, cpCode, deponentName, d log.Printf("depo-events: commit %s: %v", shortGUID(guid), err) return false } - log.Printf("depo-events: FTV_M2M %s %s создано (%d строк)", direction, shortGUID(guid), len(lines)) + log.Printf("depo-events: FTV_M2M %s %s создано (%d строк, счёт клиента %s)", direction, shortGUID(guid), len(lines), pickStr(clientAcc.String, "не найден")) return true } diff --git a/internal/lkgateway/web/templates/admin_help_fancy_events.html b/internal/lkgateway/web/templates/admin_help_fancy_events.html index d4ef85a..f712d3b 100644 --- a/internal/lkgateway/web/templates/admin_help_fancy_events.html +++ b/internal/lkgateway/web/templates/admin_help_fancy_events.html @@ -55,7 +55,7 @@ ТаблицаПоля от bj FTV_M2MGUID, DIRECTION (IN — к нам зачисляют, OUT — мы списываем), CONTRAGENT_M2M_CODE, DEPONENT_NAME, DEPONENT_DOC, DEPONENT_ID (если нашли), COMMENT. Вставка вместе со строками в одной транзакции. - FTV_M2M_LINESGUID, REFERENCE, ISIN, SEC_CODE, SHARE (если нашли), AMOUNT (штуки, дробные для паёв), PLACE_NUMBER. + FTV_M2M_LINESGUID, REFERENCE, ISIN, SEC_CODE, SHARE (если нашли), AMOUNT (штуки, дробные для паёв), PLACE_NUMBER, DEPO_NUMBER — номер торгового счёта клиента ВТНКЦ… (джоба находит по нему DEPO). FTV_M2M_EVENTSGUID, REFERENCE (пусто = по поручению целиком), EVENT_TYPE, EVENT_DATE, M2M_REJECT_CODE, COMMENT, STATE (см. правила).