QUIK: автоподбор торгового счёта фирмы из БД МНП

Кнопка «Определить из QUIK» у поля «Торговый счёт для поручений» (режим
чтение+запись). bj читает distinct Account из Actions/Export по коду фирмы
(QuikFirm/FirmID = код участника): один счёт — подставляет, несколько —
показывает на выбор, нет истории — просит ввести вручную. Только чтение.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
This commit is contained in:
fontvielle
2026-10-20 15:47:35 +03:00
parent f900cf3877
commit b654c70d49
3 changed files with 86 additions and 0 deletions
+1
View File
@@ -18,6 +18,7 @@ func (h *setupHandlers) registerQuik(mux *http.ServeMux) {
mux.HandleFunc("/admin/quik", h.quikInstructions)
mux.HandleFunc("/admin/setup/quik/cycle", h.saveQuikCycle)
mux.HandleFunc("/admin/setup/quik/mode", h.saveQuikMode)
mux.HandleFunc("/admin/setup/quik/detect-account", h.detectQuikAccount)
}
// quikInstructions — GET /admin/quik. Поручения M2M из БД МНП QUIK.
+83
View File
@@ -0,0 +1,83 @@
package lkgateway
import (
"context"
"database/sql"
"net/http"
"strings"
"time"
)
// quikdetect.go — автоподбор торгового счёта фирмы для неторговых поручений.
// Источник — сама БД модуля QUIK: различные Account из таблиц Actions/Export по
// коду нашей фирмы (QuikFirm/FirmID = код участника). Если счёт один — подставляем;
// несколько — показываем на выбор; нет истории — просим ввести вручную.
// quikDetectAccounts — торговые счета фирмы firm из БД МНП (только чтение).
func quikDetectAccounts(ctx context.Context, s QuikMNPSettings, firm string) ([]string, error) {
db, err := quikOpen(s)
if err != nil {
return nil, err
}
defer db.Close()
cctx, cancel := context.WithTimeout(ctx, 20*time.Second)
defer cancel()
const q = `SELECT DISTINCT LTRIM(RTRIM(Account)) AS acc FROM (
SELECT Account, QuikFirm, FirmID FROM dbo.Actions
UNION ALL
SELECT Account, QuikFirm, FirmID FROM dbo.Export
) t
WHERE Account IS NOT NULL AND LTRIM(RTRIM(Account)) <> ''
AND (@firm = '' OR QuikFirm = @firm OR FirmID = @firm)
ORDER BY acc`
rows, err := db.QueryContext(cctx, q, sql.Named("firm", firm))
if err != nil {
return nil, err
}
defer rows.Close()
var out []string
for rows.Next() {
var a string
if err := rows.Scan(&a); err == nil {
if a = strings.TrimSpace(a); a != "" {
out = append(out, a)
}
}
}
return out, rows.Err()
}
// detectQuikAccount — POST /admin/setup/quik/detect-account: подобрать торговый счёт из QUIK.
func (h *setupHandlers) detectQuikAccount(w http.ResponseWriter, r *http.Request) {
if !requireAdvanced(w, r) {
return
}
if r.Method != http.MethodPost {
http.Error(w, "method", http.StatusMethodNotAllowed)
return
}
s := h.rc.Snapshot().Quik
if s.Server == "" || !s.Verified {
setupFlash(w, r, "QUIK: сначала подключитесь к БД МНП (Настройка → QUIK, «Проверить подключение»)")
return
}
firm := quikFirmID()
accs, err := quikDetectAccounts(r.Context(), s, firm)
if err != nil {
setupFlash(w, r, "QUIK: определить счёт не удалось — "+quikErrorDetail(err))
return
}
switch len(accs) {
case 0:
setupFlash(w, r, "QUIK: торговых счетов фирмы "+firm+" в истории поручений (Actions/Export) не найдено — введите счёт вручную")
case 1:
s.Account = accs[0]
if err := h.rc.UpdateQuik(s); err != nil {
setupFlash(w, r, "QUIK: не сохранилось — "+err.Error())
return
}
setupFlash(w, r, "QUIK: торговый счёт подставлен из QUIK — "+accs[0])
default:
setupFlash(w, r, "QUIK: у фирмы "+firm+" несколько торговых счетов ("+strings.Join(accs, ", ")+") — впишите нужный вручную")
}
}
@@ -138,6 +138,8 @@
</div>
<div class="dq-jobname" id="quik-acc">
<label>Торговый счёт для поручений<input type="text" name="account" value="{{.D.Settings.Quik.Account}}" placeholder="торговый счёт фирмы в QUIK" spellcheck="false" class="dq-mono"></label>
<button type="submit" class="btn" formaction="/admin/setup/quik/detect-account" formnovalidate>Определить из QUIK</button>
<p class="dq-note" style="margin:4px 0 0">bj возьмёт торговый счёт фирмы из истории поручений в БД QUIK (таблицы Actions/Export). Если счёт один — подставит сам.</p>
</div>
<label class="dq-alt quik-term"><input type="checkbox" name="terminal" value="1" {{if .D.Settings.Quik.PollTerminal}}checked{{end}}><span><b>Клиенты подают поручения на перевод из QUIK</b> — из терминала или мобильного приложения («Вывод ЦБ (M2M)»). bj сам замечает такие поручения (раз в 30 секунд) и сообщает оператору; бумаги QUIK блокирует сразу при подаче. Если клиенты подают поручения только через депозитарий — оставьте выключенным.</span></label>
<input type="hidden" name="terminal_set" value="1">