diff --git a/internal/lkgateway/participant_form.go b/internal/lkgateway/participant_form.go index 593ce70..554f7ed 100644 --- a/internal/lkgateway/participant_form.go +++ b/internal/lkgateway/participant_form.go @@ -79,16 +79,18 @@ func participantFormPrefill(rc *RuntimeConfig) participantFormData { hb, ok = handbookByINN(d.INN) } if ok { - if d.FullName == "" { - d.FullName = strings.TrimSpace(pick(hb.FullName, hb.Name)) + // НРД сверяет наименования анкеты со своей клиентской базой (M2M37) — карточка в справочнике + // НРД главнее DEPO: в DEPO «наименование» бывает кратким (21.10.2026 краткое ушло в FullName). + // Английские — только если их ввели: в справочнике есть лишь краткое, полного нет. + if n := strings.TrimSpace(hb.FullName); n != "" { + d.FullName = n } - if d.ShortName == "" { - d.ShortName = strings.TrimSpace(hb.Name) + if n := strings.TrimSpace(hb.Name); n != "" && hb.FullName != "" { + d.ShortName, d.DisplayName = n, n // отображаемое НРД советует как краткое } - if d.DisplayName == "" { - d.DisplayName = strings.TrimSpace(pick(hb.DisplayName, hb.Name)) - } - if d.EngFull == "" { + if strings.TrimSpace(hb.FullName) != "" { + d.EngFull = "" + } else if d.EngFull == "" { d.EngFull = strings.TrimSpace(hb.EngName) } if hb.Kind == "broker" && d.BrokerCode == "" { @@ -144,6 +146,16 @@ func participantFormValidate(d participantFormData) []string { return errs } +// pfQuotes — кавычки как в клиентской базе НРД: прямые ". +var pfQuotes = strings.NewReplacer("«", `"`, "»", `"`, "“", `"`, "”", `"`, "„", `"`) + +// pfNames — наименования к виду базы НРД (кавычки, лишние пробелы). +func pfNames(d *participantFormData) { + for _, p := range []*string{&d.FullName, &d.ShortName, &d.DisplayName, &d.EngFull, &d.EngShort, &d.EngDisplay} { + *p = strings.Join(strings.Fields(pfQuotes.Replace(*p)), " ") + } +} + // pfx — экранирование текста XML-элемента (только & < >); кавычки в тексте // оставляем литеральными, как в образце анкеты НРД. var pfXMLEsc = strings.NewReplacer("&", "&", "<", "<", ">", ">") @@ -153,6 +165,7 @@ func pfx(s string) string { return pfXMLEsc.Replace(strings.TrimSpace(s)) } // participantFormXML — анкета в виде XML-строки (UTF-8) по образцу НРД // (M2MTransferParticipantForm.xsd). CreationTimestamp — по МСК. func participantFormXML(d participantFormData) string { + pfNames(&d) msk := time.FixedZone("МСК", 3*3600) ts := time.Now().In(msk).Format("2006-01-02T15:04:05") + "(МСК)" var b strings.Builder @@ -278,6 +291,7 @@ func registerParticipantForm(mux *http.ServeMux, rc *RuntimeConfig, igwClient *i EngDisplay: r.FormValue("eng_display"), DepoCode: r.FormValue("depo"), BrokerCode: r.FormValue("broker"), } } + pfNames(&d) // кавычки и пробелы — как в базе НРД, и в анкете, и в форме, и в статусе errs := participantFormValidate(d) if action == "download" { diff --git a/internal/lkgateway/participant_name_test.go b/internal/lkgateway/participant_name_test.go new file mode 100644 index 0000000..957bc17 --- /dev/null +++ b/internal/lkgateway/participant_name_test.go @@ -0,0 +1,29 @@ +package lkgateway + +import ( + "strings" + "testing" +) + +// Наименования в анкете — как в клиентской базе НРД: прямые кавычки, без лишних пробелов (M2M37). +func TestParticipantFormNames(t *testing.T) { + d := participantFormData{ + INN: "7703807489", DepoCode: "MC0413600000", + FullName: "Общество с ограниченной ответственностью «Инвестиционная Компания “Фонтвьель»", + ShortName: "ООО «ИК «Фонтвьель»", + DisplayName: "ООО «ИК «Фонтвьель»", + } + x := participantFormXML(d) + for _, want := range []string{ + `Общество с ограниченной ответственностью "Инвестиционная Компания "Фонтвьель"`, + `ООО "ИК "Фонтвьель"`, + `ООО "ИК "Фонтвьель"`, + } { + if !strings.Contains(x, want) { + t.Errorf("нет %s в\n%s", want, x) + } + } + if strings.Contains(x, "") { + t.Error("пустые английские наименования не должны попадать в анкету") + } +} diff --git a/internal/lkgateway/workhours.go b/internal/lkgateway/workhours.go index 662c76a..1d5479d 100644 --- a/internal/lkgateway/workhours.go +++ b/internal/lkgateway/workhours.go @@ -121,7 +121,7 @@ func (r *RuntimeConfig) UpdateWorkHours(w WorkHoursSettings) error { return r.save() } -// saveWorkHours — POST /admin/setup/workhours (шаг «Время и сеть», Настройка → Сервер). +// saveWorkHours — POST /admin/setup/workhours (шаг «Время и сеть», Настройка → НРД). func (h *setupHandlers) saveWorkHours(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method", http.StatusMethodNotAllowed)