a13c9d6184
- quikDetectAccounts: Export не имеет колонки QuikFirm (ошибка 207 Invalid column name) — запросы по Actions/Export выполняются по отдельности, источник без нужной колонки пропускается. - «Полный ответ сервера (последняя проверка)» свёрнут в details, чтобы не прятать настройки ниже. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
105 lines
4.0 KiB
Go
105 lines
4.0 KiB
Go
package lkgateway
|
||
|
||
import (
|
||
"context"
|
||
"database/sql"
|
||
"net/http"
|
||
"sort"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// quikdetect.go — автоподбор торгового счёта фирмы для неторговых поручений.
|
||
// Источник — сама БД модуля QUIK: различные Account из таблиц Actions/Export по
|
||
// коду нашей фирмы (QuikFirm/FirmID = код участника). Если счёт один — подставляем;
|
||
// несколько — показываем на выбор; нет истории — просим ввести вручную.
|
||
|
||
// quikDetectAccounts — торговые счета фирмы firm из БД МНП (только чтение). Разные версии
|
||
// модуля отличаются колонками (у Export нет QuikFirm и т. п.), поэтому пробуем несколько
|
||
// источников по отдельности и пропускаем те, где колонки нет (Invalid column name).
|
||
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()
|
||
queries := []string{
|
||
`SELECT DISTINCT LTRIM(RTRIM(Account)) FROM dbo.Actions WHERE Account IS NOT NULL AND LTRIM(RTRIM(Account)) <> '' AND (@firm = '' OR FirmID = @firm)`,
|
||
`SELECT DISTINCT LTRIM(RTRIM(Account)) FROM dbo.Actions WHERE Account IS NOT NULL AND LTRIM(RTRIM(Account)) <> '' AND (@firm = '' OR QuikFirm = @firm)`,
|
||
`SELECT DISTINCT LTRIM(RTRIM(Account)) FROM dbo.Export WHERE Account IS NOT NULL AND LTRIM(RTRIM(Account)) <> '' AND (@firm = '' OR FirmID = @firm)`,
|
||
}
|
||
seen := map[string]bool{}
|
||
var out []string
|
||
okAny := false
|
||
var lastErr error
|
||
for _, q := range queries {
|
||
rows, err := db.QueryContext(cctx, q, sql.Named("firm", firm))
|
||
if err != nil {
|
||
lastErr = err // чаще всего «Invalid column name» — этот источник пропускаем
|
||
continue
|
||
}
|
||
okAny = true
|
||
for rows.Next() {
|
||
var a string
|
||
if rows.Scan(&a) == nil {
|
||
if a = strings.TrimSpace(a); a != "" && !seen[a] {
|
||
seen[a] = true
|
||
out = append(out, a)
|
||
}
|
||
}
|
||
}
|
||
rows.Close()
|
||
}
|
||
if !okAny && lastErr != nil {
|
||
return nil, lastErr
|
||
}
|
||
sort.Strings(out)
|
||
return out, nil
|
||
}
|
||
|
||
// 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
|
||
}
|
||
// ответ: для fetch (кнопка в форме режима) — текстом; иначе — флеш.
|
||
reply := func(msg string) {
|
||
if r.Header.Get("X-BJ-Ajax") != "" {
|
||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||
_, _ = w.Write([]byte(msg))
|
||
return
|
||
}
|
||
setupFlash(w, r, "QUIK: "+msg)
|
||
}
|
||
s := h.rc.Snapshot().Quik
|
||
if s.Server == "" || !s.Verified {
|
||
reply("сначала подключитесь к БД МНП (Настройка → QUIK, «Проверить подключение»)")
|
||
return
|
||
}
|
||
firm := quikFirmID()
|
||
accs, err := quikDetectAccounts(r.Context(), s, firm)
|
||
if err != nil {
|
||
reply("определить счёт не удалось — " + quikErrorDetail(err))
|
||
return
|
||
}
|
||
switch len(accs) {
|
||
case 0:
|
||
reply("торговых счетов фирмы " + firm + " в истории поручений (Actions/Export) не найдено — введите счёт вручную")
|
||
case 1:
|
||
s.Account = accs[0]
|
||
if err := h.rc.UpdateQuik(s); err != nil {
|
||
reply("не сохранилось — " + err.Error())
|
||
return
|
||
}
|
||
reply("торговый счёт подставлен из QUIK — " + accs[0])
|
||
default:
|
||
reply("у фирмы " + firm + " несколько торговых счетов (" + strings.Join(accs, ", ") + ") — впишите нужный вручную")
|
||
}
|
||
}
|