Первичная настройка: реквизиты депозитария (счёт/код/раздел в НРД, организация) определяются из базы DEPO (Fancy) и подставляются в пустые поля карточек «ИШ НРД»/«Организация» и мастера — человек проверяет и сохраняет
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
This commit is contained in:
@@ -0,0 +1,197 @@
|
|||||||
|
package lkgateway
|
||||||
|
|
||||||
|
// depo_detect.go — автоопределение реквизитов депозитария из базы DEPO (Fancy) при первичной
|
||||||
|
// настройке: депозитарный счёт и разделы в НРД, код участника, карточка организации.
|
||||||
|
// Человек проверяет предложенные значения в форме и сохраняет сам — в настройки ничего не
|
||||||
|
// пишется автоматически.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/lkgateway/fsql"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DepoRequisites — что удалось определить в DEPO.
|
||||||
|
type DepoRequisites struct {
|
||||||
|
AccountID string // депозитарный счёт в НРД (HL…)
|
||||||
|
DeponentCode string // код участника/депонента (MC…)
|
||||||
|
SectionID string // раздел для M2M (36<код>F00)
|
||||||
|
Sections []string // все открытые разделы счёта
|
||||||
|
OrgCode string // = DeponentCode
|
||||||
|
OrgINN string
|
||||||
|
OrgName string
|
||||||
|
OrgShort string
|
||||||
|
OrgEng string
|
||||||
|
Notes []string // что не нашли / на что обратить внимание
|
||||||
|
At time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
depoSectionRe = regexp.MustCompile(`^(\d{2})([A-Z]{2}[0-9A-Z]{10})(F\d{2})$`)
|
||||||
|
depoAccountRe = regexp.MustCompile(`^[A-Z]{2}[0-9A-Z]{10}$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
// lastDepoDetect — последний результат автоопределения (в памяти процесса): его показывают
|
||||||
|
// карточки настроек как предложение, пока поля не сохранены.
|
||||||
|
var lastDepoDetect struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
r *DepoRequisites
|
||||||
|
}
|
||||||
|
|
||||||
|
func depoDetectResult() *DepoRequisites {
|
||||||
|
lastDepoDetect.mu.Lock()
|
||||||
|
defer lastDepoDetect.mu.Unlock()
|
||||||
|
return lastDepoDetect.r
|
||||||
|
}
|
||||||
|
|
||||||
|
// depoDetectRequisites — читает DEPO и собирает реквизиты. Ничего не пишет.
|
||||||
|
func depoDetectRequisites(ctx context.Context, fs FancyMSSQLSettings) (*DepoRequisites, error) {
|
||||||
|
if strings.TrimSpace(fs.Server) == "" {
|
||||||
|
return nil, fmt.Errorf("подключение к DEPO не настроено")
|
||||||
|
}
|
||||||
|
db, err := fancyOpen(fs, fs.DepoDB())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 20*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
res := &DepoRequisites{At: time.Now()}
|
||||||
|
rows, err := db.QueryContext(ctx, fsql.Det01)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("счета в НРД (OD_CLIENTS): %w", err)
|
||||||
|
}
|
||||||
|
accounts := map[string]int{}
|
||||||
|
codes := map[string]int{}
|
||||||
|
sections := map[string]bool{}
|
||||||
|
for rows.Next() {
|
||||||
|
var number, name string
|
||||||
|
var state int
|
||||||
|
if rows.Scan(&number, &state, &name) != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
parts := strings.Split(strings.TrimSpace(number), "/")
|
||||||
|
if len(parts) < 4 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
acc, sec := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[len(parts)-1])
|
||||||
|
if depoAccountRe.MatchString(acc) {
|
||||||
|
accounts[acc]++
|
||||||
|
}
|
||||||
|
if m := depoSectionRe.FindStringSubmatch(sec); m != nil {
|
||||||
|
codes[m[2]]++
|
||||||
|
if state == 0 {
|
||||||
|
sections[sec] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rows.Close()
|
||||||
|
if len(accounts) == 0 {
|
||||||
|
res.Notes = append(res.Notes, "счета депозитария в НРД в DEPO не найдены (нет счетов у лица «НКО АО НРД», ИНН 7702165310) — реквизиты вводятся вручную из договора с НРД")
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
res.AccountID = mostCommon(accounts)
|
||||||
|
res.DeponentCode = mostCommon(codes)
|
||||||
|
for s := range sections {
|
||||||
|
res.Sections = append(res.Sections, s)
|
||||||
|
}
|
||||||
|
sort.Strings(res.Sections)
|
||||||
|
// раздел для M2M — торговый «36<код>F00» (по договорённости с Fancy); иначе первый 36…, иначе первый открытый
|
||||||
|
want := "36" + res.DeponentCode + "F00"
|
||||||
|
switch {
|
||||||
|
case sections[want]:
|
||||||
|
res.SectionID = want
|
||||||
|
default:
|
||||||
|
for _, s := range res.Sections {
|
||||||
|
if strings.HasPrefix(s, "36") {
|
||||||
|
res.SectionID = s
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if res.SectionID == "" && len(res.Sections) > 0 {
|
||||||
|
res.SectionID = res.Sections[0]
|
||||||
|
}
|
||||||
|
res.Notes = append(res.Notes, "раздела "+want+" нет среди открытых — проверьте выбранный раздел")
|
||||||
|
}
|
||||||
|
if len(accounts) > 1 {
|
||||||
|
res.Notes = append(res.Notes, fmt.Sprintf("в DEPO несколько депозитарных счетов в НРД (%d) — выбран самый частый %s", len(accounts), res.AccountID))
|
||||||
|
}
|
||||||
|
// организация по коду участника
|
||||||
|
if res.DeponentCode != "" {
|
||||||
|
var name, inn, mnem, eng string
|
||||||
|
err := db.QueryRowContext(ctx, fsql.Det02, sql.Named("code", res.DeponentCode)).Scan(&name, &inn, &mnem, &eng)
|
||||||
|
switch {
|
||||||
|
case err == sql.ErrNoRows:
|
||||||
|
res.Notes = append(res.Notes, "лицо с кодом "+res.DeponentCode+" в DEPO не найдено — ИНН и наименование организации введите вручную")
|
||||||
|
case err != nil:
|
||||||
|
res.Notes = append(res.Notes, "карточка организации: "+err.Error())
|
||||||
|
default:
|
||||||
|
res.OrgCode, res.OrgINN, res.OrgName, res.OrgShort, res.OrgEng = res.DeponentCode, strings.TrimSpace(inn), strings.TrimSpace(name), strings.TrimSpace(mnem), strings.TrimSpace(eng)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mostCommon(m map[string]int) string {
|
||||||
|
best, n := "", -1
|
||||||
|
for k, v := range m {
|
||||||
|
if v > n || (v == n && k < best) {
|
||||||
|
best, n = k, v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return best
|
||||||
|
}
|
||||||
|
|
||||||
|
// Summary — короткая строка для сообщения.
|
||||||
|
func (r *DepoRequisites) Summary() string {
|
||||||
|
if r == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var b []string
|
||||||
|
if r.AccountID != "" {
|
||||||
|
b = append(b, "счёт "+r.AccountID)
|
||||||
|
}
|
||||||
|
if r.DeponentCode != "" {
|
||||||
|
b = append(b, "код "+r.DeponentCode)
|
||||||
|
}
|
||||||
|
if r.SectionID != "" {
|
||||||
|
b = append(b, "раздел "+r.SectionID)
|
||||||
|
}
|
||||||
|
if r.OrgName != "" {
|
||||||
|
b = append(b, r.OrgName+" (ИНН "+r.OrgINN+")")
|
||||||
|
}
|
||||||
|
return strings.Join(b, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// detectFancyRequisites — POST /admin/setup/fancy/detect: определить реквизиты в DEPO и показать
|
||||||
|
// их как предложение в карточках «ИШ НРД» и «Организация» (и в мастере).
|
||||||
|
func (h *setupHandlers) detectFancyRequisites(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != http.MethodPost {
|
||||||
|
http.Error(w, "method", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := depoDetectRequisites(r.Context(), h.rc.Snapshot().Fancy)
|
||||||
|
if err != nil {
|
||||||
|
setupFlash(w, r, "DEPO: реквизиты не определены — "+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastDepoDetect.mu.Lock()
|
||||||
|
lastDepoDetect.r = res
|
||||||
|
lastDepoDetect.mu.Unlock()
|
||||||
|
msg := "Из DEPO определено: " + res.Summary() + ". Значения подставлены в пустые поля — проверьте и нажмите «Сохранить»."
|
||||||
|
if res.AccountID == "" {
|
||||||
|
msg = "DEPO: " + strings.Join(res.Notes, "; ")
|
||||||
|
} else if len(res.Notes) > 0 {
|
||||||
|
msg += " Замечания: " + strings.Join(res.Notes, "; ")
|
||||||
|
}
|
||||||
|
setupFlash(w, r, msg)
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
func (h *setupHandlers) registerFancy(mux *http.ServeMux) {
|
func (h *setupHandlers) registerFancy(mux *http.ServeMux) {
|
||||||
mux.HandleFunc("/admin/setup/fancy", h.saveFancy)
|
mux.HandleFunc("/admin/setup/fancy", h.saveFancy)
|
||||||
mux.HandleFunc("/admin/setup/fancy/test", h.testFancy)
|
mux.HandleFunc("/admin/setup/fancy/test", h.testFancy)
|
||||||
|
mux.HandleFunc("/admin/setup/fancy/detect", h.detectFancyRequisites) // реквизиты НРД/организации из DEPO
|
||||||
mux.HandleFunc("/admin/setup/fancy/depo-job", h.saveFancyDepoJob)
|
mux.HandleFunc("/admin/setup/fancy/depo-job", h.saveFancyDepoJob)
|
||||||
mux.HandleFunc("/admin/setup/fancy/depo-job/check", h.checkFancyDepoJob)
|
mux.HandleFunc("/admin/setup/fancy/depo-job/check", h.checkFancyDepoJob)
|
||||||
mux.HandleFunc("/admin/setup/fancy/depo-job/create", h.createFancyDepoJob)
|
mux.HandleFunc("/admin/setup/fancy/depo-job/create", h.createFancyDepoJob)
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package fsql
|
||||||
|
|
||||||
|
// Автоопределение реквизитов депозитария в DEPO (Fancy) для первичной настройки.
|
||||||
|
|
||||||
|
// Det01 — счета депозитария в НРД: в DEPO это счета «лица НКО АО НРД» (ИНН 7702165310 одинаков у всех
|
||||||
|
// клиентов Fancy). NUMBER = <депозитарный счёт>/<LEI>/<код>/<раздел>.
|
||||||
|
var Det01 = `SELECT c.NUMBER, ISNULL(c.STATE,0), ISNULL(c.NAME,'') FROM OD_CLIENTS c JOIN OD_FACES f ON f.ID=c.FACE
|
||||||
|
WHERE f.INN='7702165310' AND c.NUMBER LIKE '%/%/%/%' ORDER BY c.STATE, c.NUMBER`
|
||||||
|
|
||||||
|
// Det02 — карточка организации по коду участника НРД (кодер лица).
|
||||||
|
var Det02 = `SELECT TOP 1 ISNULL(f.NAME,''), ISNULL(f.INN,''), ISNULL(f.MNEM,''), ISNULL(f.ENG_NAME,'')
|
||||||
|
FROM OD_FACE_CODERS fc JOIN OD_FACES f ON f.ID=fc.FACE WHERE fc.CODE=@code ORDER BY f.E_DATE DESC, f.ID DESC`
|
||||||
@@ -165,6 +165,7 @@ type WizardData struct {
|
|||||||
page
|
page
|
||||||
Step int
|
Step int
|
||||||
Settings Settings
|
Settings Settings
|
||||||
|
Suggest *DepoRequisites // предложение реквизитов из DEPO (после «Определить из DEPO»)
|
||||||
Certs []cryptocli.Certificate
|
Certs []cryptocli.Certificate
|
||||||
Flash string
|
Flash string
|
||||||
Done struct {
|
Done struct {
|
||||||
@@ -188,6 +189,7 @@ func (h *setupHandlers) renderWizard(w http.ResponseWriter, r *http.Request) {
|
|||||||
d := WizardData{
|
d := WizardData{
|
||||||
page: nowPage("Мастер настройки", "wizard"),
|
page: nowPage("Мастер настройки", "wizard"),
|
||||||
Settings: s,
|
Settings: s,
|
||||||
|
Suggest: depoDetectResult(),
|
||||||
Certs: h.listCertsForUI(),
|
Certs: h.listCertsForUI(),
|
||||||
Flash: r.URL.Query().Get("flash"),
|
Flash: r.URL.Query().Get("flash"),
|
||||||
}
|
}
|
||||||
@@ -300,6 +302,7 @@ func (h *setupHandlers) testSignCrypto(w http.ResponseWriter, r *http.Request) {
|
|||||||
type SetupData struct {
|
type SetupData struct {
|
||||||
page
|
page
|
||||||
Settings Settings
|
Settings Settings
|
||||||
|
Suggest *DepoRequisites // предложение реквизитов из DEPO
|
||||||
Readiness []Readiness
|
Readiness []Readiness
|
||||||
ReadyCount int
|
ReadyCount int
|
||||||
TotalCount int
|
TotalCount int
|
||||||
@@ -373,6 +376,7 @@ func (h *setupHandlers) renderSetup(w http.ResponseWriter, req *http.Request, fl
|
|||||||
Components: comps,
|
Components: comps,
|
||||||
UpdatesAvailable: anyUpdate,
|
UpdatesAvailable: anyUpdate,
|
||||||
Settings: s,
|
Settings: s,
|
||||||
|
Suggest: depoDetectResult(),
|
||||||
Readiness: r,
|
Readiness: r,
|
||||||
ReadyCount: ready,
|
ReadyCount: ready,
|
||||||
TotalCount: len(r),
|
TotalCount: len(r),
|
||||||
|
|||||||
@@ -542,11 +542,12 @@ function hbBind(inp,box,list,onPick){
|
|||||||
</script>
|
</script>
|
||||||
{{if not .Participants}}<span class="muted" style="font-size:12px">Справочник участников ещё не получен — запросите его в «Диагностике» или введите данные вручную.</span>{{end}}
|
{{if not .Participants}}<span class="muted" style="font-size:12px">Справочник участников ещё не получен — запросите его в «Диагностике» или введите данные вручную.</span>{{end}}
|
||||||
<label>Код участника</label>
|
<label>Код участника</label>
|
||||||
<input type="text" name="org_code" value="{{.Settings.NSD.OrgCode}}" placeholder="MC0000000000" maxlength="12">
|
<input type="text" name="org_code" value="{{if .Settings.NSD.OrgCode}}{{.Settings.NSD.OrgCode}}{{else if .Suggest}}{{.Suggest.OrgCode}}{{end}}" placeholder="MC0000000000" maxlength="12">
|
||||||
<label>ИНН</label>
|
<label>ИНН</label>
|
||||||
<input type="text" name="org_inn" value="{{.Settings.NSD.OrgINN}}" maxlength="10" inputmode="numeric">
|
<input type="text" name="org_inn" value="{{if .Settings.NSD.OrgINN}}{{.Settings.NSD.OrgINN}}{{else if .Suggest}}{{.Suggest.OrgINN}}{{end}}" maxlength="10" inputmode="numeric">
|
||||||
<label>Наименование</label>
|
<label>Наименование</label>
|
||||||
<input type="text" name="org_name" value="{{.Settings.NSD.OrgName}}">
|
<input type="text" name="org_name" value="{{if .Settings.NSD.OrgName}}{{.Settings.NSD.OrgName}}{{else if .Suggest}}{{.Suggest.OrgName}}{{end}}">
|
||||||
|
{{if .Suggest}}{{if .Suggest.OrgName}}<span class="muted" style="font-size:12px">Из DEPO: {{.Suggest.OrgName}}, ИНН {{.Suggest.OrgINN}}, код {{.Suggest.OrgCode}} — подставлено в пустые поля.</span>{{end}}{{end}}
|
||||||
<div><button type="submit" class="btn btn-ok">Сохранить</button></div>
|
<div><button type="submit" class="btn btn-ok">Сохранить</button></div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -581,12 +582,18 @@ function hbBind(inp,box,list,onPick){
|
|||||||
<input type="text" name="key_container" id="nsd-container" value="{{.Settings.NSD.KeyContainer}}" placeholder="напр. TEST3_GOST_CONTAINER">
|
<input type="text" name="key_container" id="nsd-container" value="{{.Settings.NSD.KeyContainer}}" placeholder="напр. TEST3_GOST_CONTAINER">
|
||||||
<hr style="border:none;border-top:1px solid var(--border);margin:6px 0">
|
<hr style="border:none;border-top:1px solid var(--border);margin:6px 0">
|
||||||
<p class="muted" style="margin:0">Депозитарные реквизиты (откуда списываются бумаги) — из договора/письма НРД. Нужны для формирования заявки на перевод.</p>
|
<p class="muted" style="margin:0">Депозитарные реквизиты (откуда списываются бумаги) — из договора/письма НРД. Нужны для формирования заявки на перевод.</p>
|
||||||
|
{{if .Settings.Fancy.Server}}<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:4px 0">
|
||||||
|
<button type="submit" class="btn" formaction="/admin/setup/fancy/detect" formmethod="post" style="background:var(--card)">Определить из DEPO</button>
|
||||||
|
<span class="muted" style="font-size:12px">Счёт, код и раздел в НРД и карточка организации читаются из базы DEPO (Fancy) и подставляются в пустые поля — проверьте и сохраните.</span>
|
||||||
|
</div>{{end}}
|
||||||
|
{{if .Suggest}}{{if .Suggest.AccountID}}<div class="help-block" style="margin:4px 0"><strong>Найдено в DEPO:</strong> счёт {{.Suggest.AccountID}}, код {{.Suggest.DeponentCode}}, раздел {{.Suggest.SectionID}}{{if gt (len .Suggest.Sections) 1}} (открытых разделов: {{len .Suggest.Sections}}){{end}}{{if .Suggest.OrgName}}; организация {{.Suggest.OrgName}}, ИНН {{.Suggest.OrgINN}}{{end}}.{{range .Suggest.Notes}}<br><span class="muted">⚠ {{.}}</span>{{end}}</div>{{end}}{{end}}
|
||||||
<label>Депозитарный код</label>
|
<label>Депозитарный код</label>
|
||||||
<input type="text" name="deponent_code" value="{{.Settings.NSD.DeponentCode}}" placeholder="MC0000000000">
|
<input type="text" name="deponent_code" value="{{if .Settings.NSD.DeponentCode}}{{.Settings.NSD.DeponentCode}}{{else if .Suggest}}{{.Suggest.DeponentCode}}{{end}}" placeholder="MC0000000000">
|
||||||
<label>Депозитарный счёт</label>
|
<label>Депозитарный счёт</label>
|
||||||
<input type="text" name="account_id" value="{{.Settings.NSD.AccountID}}" placeholder="депозитарный счёт">
|
<input type="text" name="account_id" value="{{if .Settings.NSD.AccountID}}{{.Settings.NSD.AccountID}}{{else if .Suggest}}{{.Suggest.AccountID}}{{end}}" placeholder="депозитарный счёт">
|
||||||
<label>Раздел счёта</label>
|
<label>Раздел счёта</label>
|
||||||
<input type="text" name="section_id" value="{{.Settings.NSD.SectionID}}" placeholder="раздел депозитарного счёта">
|
<input type="text" name="section_id" value="{{if .Settings.NSD.SectionID}}{{.Settings.NSD.SectionID}}{{else if .Suggest}}{{.Suggest.SectionID}}{{end}}" placeholder="раздел депозитарного счёта"{{if .Suggest}}{{if gt (len .Suggest.Sections) 1}} list="depo-sections"{{end}}{{end}}>
|
||||||
|
{{if .Suggest}}{{if gt (len .Suggest.Sections) 1}}<datalist id="depo-sections">{{range .Suggest.Sections}}<option value="{{.}}">{{end}}</datalist>{{end}}{{end}}
|
||||||
<label style="display:flex;align-items:flex-start;gap:9px;font-weight:400;margin-top:6px;cursor:pointer">
|
<label style="display:flex;align-items:flex-start;gap:9px;font-weight:400;margin-top:6px;cursor:pointer">
|
||||||
<input type="checkbox" name="igw_v904" style="width:auto;margin-top:3px" {{if .Settings.NSD.IGWv904}}checked{{end}}>
|
<input type="checkbox" name="igw_v904" style="width:auto;margin-top:3px" {{if .Settings.NSD.IGWv904}}checked{{end}}>
|
||||||
<span>ИШ версии <strong>107.0.0.904+</strong> (Astra 107.0.907+)<br>
|
<span>ИШ версии <strong>107.0.0.904+</strong> (Astra 107.0.907+)<br>
|
||||||
|
|||||||
@@ -209,8 +209,23 @@
|
|||||||
<label>Ключевой контейнер НРД <span class="tooltip" title="Имя контейнера Валидаты с ключами ЭДО НРД (выдаются УЦ НРД)">?</span></label>
|
<label>Ключевой контейнер НРД <span class="tooltip" title="Имя контейнера Валидаты с ключами ЭДО НРД (выдаются УЦ НРД)">?</span></label>
|
||||||
<input type="text" name="key_container" value="{{.Settings.NSD.KeyContainer}}" placeholder="nrd-edo" style="padding:8px;background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:4px;width:100%">
|
<input type="text" name="key_container" value="{{.Settings.NSD.KeyContainer}}" placeholder="nrd-edo" style="padding:8px;background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:4px;width:100%">
|
||||||
</div>
|
</div>
|
||||||
|
<hr style="border:none;border-top:1px solid var(--border);margin:4px 0">
|
||||||
|
<p class="muted" style="margin:0">Депозитарные реквизиты организации в НРД. {{if .Settings.Fancy.Server}}Их можно взять из базы DEPO (Fancy): кнопка «Определить из DEPO» подставит найденное в пустые поля — проверьте и сохраните.{{else}}Если учёт ведётся в Fancy DEPO — сначала настройте подключение к базе в разделе <a href="/admin/setup#sec-fancy">Обмен Fancy</a>, тогда реквизиты подставятся из DEPO автоматически; иначе введите их из договора с НРД.{{end}}</p>
|
||||||
|
{{if .Settings.Fancy.Server}}<button type="submit" class="btn" formaction="/admin/setup/fancy/detect" formmethod="post" style="justify-self:start;background:var(--card)">Определить из DEPO</button>{{end}}
|
||||||
|
{{if .Suggest}}{{if .Suggest.AccountID}}<div class="help-block" style="margin:0"><strong>Найдено в DEPO:</strong> счёт {{.Suggest.AccountID}}, код {{.Suggest.DeponentCode}}, раздел {{.Suggest.SectionID}}{{if .Suggest.OrgName}}; организация {{.Suggest.OrgName}}, ИНН {{.Suggest.OrgINN}}{{end}}.{{range .Suggest.Notes}}<br><span class="muted">⚠ {{.}}</span>{{end}}</div>{{end}}{{end}}
|
||||||
|
<div><label>Депозитарный код</label><input type="text" name="deponent_code" value="{{if .Settings.NSD.DeponentCode}}{{.Settings.NSD.DeponentCode}}{{else if .Suggest}}{{.Suggest.DeponentCode}}{{end}}" placeholder="MC0000000000" style="padding:8px;background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:4px;width:100%"></div>
|
||||||
|
<div><label>Депозитарный счёт</label><input type="text" name="account_id" value="{{if .Settings.NSD.AccountID}}{{.Settings.NSD.AccountID}}{{else if .Suggest}}{{.Suggest.AccountID}}{{end}}" placeholder="HL000000000C" style="padding:8px;background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:4px;width:100%"></div>
|
||||||
|
<div><label>Раздел счёта</label><input type="text" name="section_id" value="{{if .Settings.NSD.SectionID}}{{.Settings.NSD.SectionID}}{{else if .Suggest}}{{.Suggest.SectionID}}{{end}}" placeholder="36MC0000000000F00" style="padding:8px;background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:4px;width:100%"></div>
|
||||||
<button type="submit" class="btn" style="justify-self:start">Сохранить</button>
|
<button type="submit" class="btn" style="justify-self:start">Сохранить</button>
|
||||||
</form>
|
</form>
|
||||||
|
{{if .Suggest}}{{if .Suggest.OrgName}}<form method="post" action="/admin/setup/org" style="margin-top:12px;display:grid;gap:10px">
|
||||||
|
<p class="muted" style="margin:0">Организация (из DEPO — проверьте): код участника, ИНН, наименование.</p>
|
||||||
|
<input type="hidden" name="return_to" value="/admin/wizard?step=4">
|
||||||
|
<div><label>Код участника</label><input type="text" name="org_code" value="{{if .Settings.NSD.OrgCode}}{{.Settings.NSD.OrgCode}}{{else}}{{.Suggest.OrgCode}}{{end}}" style="padding:8px;background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:4px;width:100%"></div>
|
||||||
|
<div><label>ИНН</label><input type="text" name="org_inn" value="{{if .Settings.NSD.OrgINN}}{{.Settings.NSD.OrgINN}}{{else}}{{.Suggest.OrgINN}}{{end}}" style="padding:8px;background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:4px;width:100%"></div>
|
||||||
|
<div><label>Наименование</label><input type="text" name="org_name" value="{{if .Settings.NSD.OrgName}}{{.Settings.NSD.OrgName}}{{else}}{{.Suggest.OrgName}}{{end}}" style="padding:8px;background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:4px;width:100%"></div>
|
||||||
|
<button type="submit" class="btn" style="justify-self:start">Сохранить организацию</button>
|
||||||
|
</form>{{end}}{{end}}
|
||||||
<script>
|
<script>
|
||||||
// Автозаполнение URL по выбранному профилю
|
// Автозаполнение URL по выбранному профилю
|
||||||
document.getElementById('nsd-profile').addEventListener('change', function(e){
|
document.getElementById('nsd-profile').addEventListener('change', function(e){
|
||||||
|
|||||||
Reference in New Issue
Block a user