diff --git a/internal/lkgateway/handbook_embed.go b/internal/lkgateway/handbook_embed.go
index 7b1774c..13174d7 100644
--- a/internal/lkgateway/handbook_embed.go
+++ b/internal/lkgateway/handbook_embed.go
@@ -33,10 +33,15 @@ func handbookAt(b []byte) time.Time {
return h.At
}
-// readHandbook — самый свежий из доступных справочников.
+// readHandbook — справочник своего контура: полученный этим bj от НРД, если он есть (боевой и
+// тестовый справочники разные — в боевом меньше участников, не все подключились; копия с сервера
+// лицензий может быть с другого контура). Нет своего — самый свежий из копии и встроенного снимка.
func readHandbook() ([]byte, error) {
+ if b, err := os.ReadFile(handbookFile); err == nil && len(b) > 0 && !handbookAt(b).IsZero() {
+ return b, nil
+ }
best := handbookSnapshot
- for _, p := range []string{handbookFile, handbookCloudFile} {
+ for _, p := range []string{handbookCloudFile} {
if b, err := os.ReadFile(p); err == nil && len(b) > 0 && handbookAt(b).After(handbookAt(best)) {
best = b
}
@@ -58,6 +63,9 @@ func pushHandbookAsync(rc *RuntimeConfig, raw []byte) {
if rc == nil || strings.TrimSpace(rc.Snapshot().License.Key) == "" {
return
}
+ if contourOf(currentNSDProfile()) != "prod" {
+ return // общий справочник — только боевой: тестовый (TEST3) шире и для клиентов неверен
+ }
go func() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
diff --git a/internal/lkgateway/lkportfolio.go b/internal/lkgateway/lkportfolio.go
index 405164f..9bdf80f 100644
--- a/internal/lkgateway/lkportfolio.go
+++ b/internal/lkgateway/lkportfolio.go
@@ -385,11 +385,12 @@ func lkContractByAccount(ps LKPortfolioSyncSettings, acc string) string {
return strings.ReplaceAll(ps.contractTemplate(), "{n}", n)
}
-// lkPortfolioClients — поиск клиентов DEPO по ФИО или номеру портфеля (открытые торговые счета).
+// lkPortfolioClients — клиенты DEPO по ФИО, портфелю или счёту (открытые торговые счета); пустой
+// запрос — первые по алфавиту, чтобы выбрать из списка без ввода.
func lkPortfolioClients(ctx context.Context, rc *RuntimeConfig, q string) ([]LKPortfolioClient, error) {
q = strings.TrimSpace(q)
- if len([]rune(q)) < 2 {
- return nil, nil
+ if len([]rune(q)) == 1 {
+ return []LKPortfolioClient{}, nil
}
fs := rc.Snapshot().Fancy
ps := rc.Snapshot().LK.PortfolioSync
@@ -400,7 +401,7 @@ func lkPortfolioClients(ctx context.Context, rc *RuntimeConfig, q string) ([]LKP
defer db.Close()
cctx, cancel := context.WithTimeout(ctx, 15*time.Second)
defer cancel()
- rows, err := db.QueryContext(cctx, `SELECT TOP 20 ISNULL(p.PORT_NUM,''), ISNULL(f.NAME,''), c.NUMBER
+ rows, err := db.QueryContext(cctx, `SELECT TOP 50 ISNULL(p.PORT_NUM,''), ISNULL(f.NAME,''), c.NUMBER
FROM OD_CLIENTS c JOIN OD_FACES f ON f.ID=c.FACE LEFT JOIN OD_CLIENTS_PORTS p ON p.CLIENT=c.ID
WHERE c.NUMBER LIKE @pre AND c.STATE=0 AND c.D_CLOSE IS NULL AND (f.NAME LIKE @q OR p.PORT_NUM LIKE @q OR c.NUMBER LIKE @q)
ORDER BY f.NAME`, sql.Named("q", "%"+likeEscape(q)+"%"), sql.Named("pre", likeEscape(ps.accountPrefix())+"%"))
@@ -408,7 +409,7 @@ func lkPortfolioClients(ctx context.Context, rc *RuntimeConfig, q string) ([]LKP
return nil, err
}
defer rows.Close()
- var out []LKPortfolioClient
+ out := []LKPortfolioClient{}
for rows.Next() {
var c LKPortfolioClient
if rows.Scan(&c.Port, &c.Name, &c.Account) == nil && c.Port != "" {
diff --git a/internal/lkgateway/nsdpoller.go b/internal/lkgateway/nsdpoller.go
index 8afad86..afb19c5 100644
--- a/internal/lkgateway/nsdpoller.go
+++ b/internal/lkgateway/nsdpoller.go
@@ -268,7 +268,9 @@ func (s *Server) applyIncoming(ctx context.Context, p igw.Package) error {
}
nsdProbeReply(time.Now())
writeHandbookRawXML(unpacked.DocXML) // подлинный XML НРД — для выгрузки со страницы справочника
- if !saveHandbook(&hb) {
+ changed := saveHandbook(&hb)
+ participantHandbookCheck(s.rc) // появились в справочнике — анкета принята
+ if !changed {
log.Printf("lk-gateway: поллер справочник M2M id=%d: без изменений (%d участников) — связь с НРД подтверждена", p.ID, len(hb.Participants.Participants))
return nil
}
diff --git a/internal/lkgateway/participant_form.go b/internal/lkgateway/participant_form.go
index ac12b5d..594ff37 100644
--- a/internal/lkgateway/participant_form.go
+++ b/internal/lkgateway/participant_form.go
@@ -488,21 +488,19 @@ func participantRegStatus(rc *RuntimeConfig) string {
if contour == "" {
contour = "текущего"
}
- hb, ok := handbookByCode(orgCode(s))
- if !ok {
- if inn := orgINN(s); inn != "" {
- hb, ok = handbookByINN(inn)
- }
+ _ = s
+ in, known, at, n := nsdHandbookHasUs(rc)
+ switch {
+ case in:
+ out.WriteString(`
В справочнике участников M2M, полученном от НРД (` + contour + ` контур, ` +
+ at.In(listMSK).Format("02.01 15:04") + `), наша организация есть. Регистрация подтверждена.
`)
+ case known:
+ out.WriteString(fmt.Sprintf(`
В справочнике участников M2M, полученном от НРД (%s контур, %s, участников %d), нашей организации пока нет. `+
+ `После приёма анкеты НРД добавит её в справочник — bj получает его каждые несколько минут и сам отметит регистрацию.
Справочник участников M2M от НРД ещё не получен — проверить регистрацию по нему пока нельзя.
`)
}
- if ok {
- out.WriteString(`
В справочнике участников M2M ` + contour + ` контура: есть — ` +
- html.EscapeString(pickStr(hb.Name, hb.FullName)) + `, код ` + html.EscapeString(hb.Code) +
- `, ИНН ` + html.EscapeString(hb.INN) + `. Регистрация подтверждена.
`)
- return out.String()
- }
- out.WriteString(`
В справочнике участников M2M ` + contour + ` контура нашей организации пока нет. ` +
- `После приёма анкеты НРД организация появится в справочнике (обновляется каждые ~10 минут) — тогда здесь будет «есть». ` +
- `Регистрацию подтверждает также ответный документ от НРД.
`)
return out.String()
}
diff --git a/internal/lkgateway/participant_reg.go b/internal/lkgateway/participant_reg.go
index 4260666..eea0b14 100644
--- a/internal/lkgateway/participant_reg.go
+++ b/internal/lkgateway/participant_reg.go
@@ -149,6 +149,9 @@ func recordParticipantReply(status string, resp *m2m.M2MTransferResponse, rawFil
// participantAccepted — последняя отправленная анкета принята НРД.
func participantAccepted() bool {
+ if in, _, _, _ := nsdHandbookHasUs(globalRC); in {
+ return true // уже в справочнике участников НРД — зарегистрированы (в т.ч. без анкеты из bj)
+ }
r := loadParticipantReg()
return !r.RespAt.IsZero() && !strings.EqualFold(r.Status, "ERROR") && !strings.EqualFold(r.Status, "INFO")
}
@@ -185,3 +188,45 @@ func participantBanner() template.HTML {
return template.HTML(`