Files
Bridge-and-Join-s/internal/lkgateway/accprefix.go
T

103 lines
3.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package lkgateway
// Префикс торгового счёта клиента в учёте DEPO (OD_CLIENTS.NUMBER). У Фонтвьель — «ВТНКЦ…»; у другого
// депозитария счета могут называться иначе, поэтому префикс — настройка (Fancy.AccountPrefix), и запросы
// к учёту берут его через accSQL. Подсказка — какие префиксы у открытых счетов этого учёта.
import (
"context"
"net/http"
"regexp"
"strings"
"time"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/lkgateway/fsql"
)
const defaultAccPrefix = "ВТНКЦ"
// accPrefixRe — только буквы, цифры и «_»: префикс подставляется в текст запроса.
var accPrefixRe = regexp.MustCompile(`^[\p{L}\p{N}_]{1,20}$`)
func cleanAccPrefix(p string) string {
p = strings.TrimSpace(p)
if accPrefixRe.MatchString(p) {
return p
}
return ""
}
// depoAccPrefix — префикс торговых счетов из настроек (по умолчанию «ВТНКЦ»).
func depoAccPrefix() string {
if globalRC != nil {
if p := cleanAccPrefix(globalRC.Snapshot().Fancy.AccountPrefix); p != "" {
return p
}
}
return defaultAccPrefix
}
// accSQL — запрос к учёту с подставленным префиксом торгового счёта.
func accSQL(q string) string { return strings.ReplaceAll(q, "{ACC}", depoAccPrefix()) }
type accPrefixCount struct {
Prefix string `json:"prefix"`
Count int `json:"count"`
}
// depoAccPrefixInfo — сколько открытых счетов с текущим префиксом и какие префиксы вообще есть.
func depoAccPrefixInfo(ctx context.Context, f FancyMSSQLSettings) (cur int, cands []accPrefixCount, err error) {
if f.IsPostgres() {
return 0, nil, nil
}
db, err := fancyOpen(f, f.DepoDB())
if err != nil {
return 0, nil, err
}
defer db.Close()
if err := db.QueryRowContext(ctx, accSQL(fsql.Acc02)).Scan(&cur); err != nil {
return 0, nil, err
}
rows, err := db.QueryContext(ctx, fsql.Acc01)
if err != nil {
return cur, nil, err
}
defer rows.Close()
for rows.Next() {
var c accPrefixCount
if rows.Scan(&c.Prefix, &c.Count) == nil {
cands = append(cands, c)
}
}
return cur, cands, rows.Err()
}
// GET /admin/setup/fancy/acc-prefix — текущий префикс и подсказка; POST — сохранить.
func (h *setupHandlers) accPrefix(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
p := strings.TrimSpace(r.FormValue("account_prefix"))
if p != "" && cleanAccPrefix(p) == "" {
jsonOut(w, map[string]any{"ok": false, "error": "префикс — только буквы и цифры, до 20 знаков"})
return
}
s := h.rc.Snapshot().Fancy
s.AccountPrefix = p
if err := h.rc.UpdateFancy(s); err != nil {
jsonOut(w, map[string]any{"ok": false, "error": err.Error()})
return
}
}
s := h.rc.Snapshot().Fancy
out := map[string]any{"ok": true, "prefix": depoAccPrefix(), "set": cleanAccPrefix(s.AccountPrefix) != ""}
if strings.TrimSpace(s.Server) != "" {
ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
defer cancel()
cur, cands, err := depoAccPrefixInfo(ctx, s)
if err != nil {
out["error"] = quikErrorDetail(err)
}
out["count"], out["candidates"] = cur, cands
}
jsonOut(w, out)
}