package lkgateway
// xmlfields.go — разбор сырого XML запроса/решения M2M в таблицу «все поля» с
// человекочитаемыми подписями. Используется и на карточке входящего, и в отчётах
// для регулятора (входящие и исходящие) — чтобы визуально были видны ВСЕ данные,
// которые есть в XML, а не только выбранные.
import (
"html"
"html/template"
"regexp"
"strings"
)
// xmlLeafRe матчит листовые элементы значение.
var xmlLeafRe = regexp.MustCompile(`<(?:[A-Za-z0-9]+:)?([A-Za-z0-9_]+)\b[^>]*>([^<>]+)(?:[A-Za-z0-9]+:)?[A-Za-z0-9_]+>`)
// xmlFieldLabels — подписи полей M2M на русском.
var xmlFieldLabels = map[string]string{
"GUID": "GUID перевода",
"CreationTimestamp": "Дата формирования запроса",
"SenderCode": "Код отправителя (депозитарий)",
"ReceiverCode": "Код получателя (депозитарий)",
"Code": "Код депонента (учёт стоимости)",
"LastName": "Фамилия инвестора",
"FirstName": "Имя инвестора",
"MiddleName": "Отчество инвестора",
"DocumentType": "Тип документа (код)",
"DocumentSeries": "Серия документа",
"DocumentNumber": "Номер документа",
"ReferenceId": "Референс ценной бумаги",
"SecurityCode": "Код НРД ценной бумаги",
"ISIN": "ISIN",
"Whole": "Количество (целое)",
"Fractional": "Количество (дробное)",
"DeponentCode": "Код депонента (счёт депо)",
"AccountId": "Счёт депо",
"SectionId": "Раздел счёта депо",
"IsolationStatus": "Статус обособления",
"AgreementType": "Тип договора ИИС",
}
// renderXMLFieldsTable возвращает HTML-таблицу со всеми листовыми полями XML.
// INN дизамбигуируется по порядку появления в документе.
func renderXMLFieldsTable(raw string) string {
if strings.TrimSpace(raw) == "" {
return ""
}
ms := xmlLeafRe.FindAllStringSubmatch(raw, -1)
if len(ms) == 0 {
return ""
}
innSeq := 0
var b strings.Builder
b.WriteString(`
`)
b.WriteString(`| Поле | `)
b.WriteString(`Значение | `)
b.WriteString(`Тег XML |
`)
for _, m := range ms {
tag, val := m[1], strings.TrimSpace(m[2])
if val == "" || tag == "IsM2M" {
continue
}
label := xmlFieldLabels[tag]
if tag == "INN" {
innSeq++
switch innSeq {
case 1:
label = "ИНН передающего депозитария"
case 2:
label = "ИНН принимающего депозитария"
default:
label = "ИНН места расчётов (НРД/СПБ)"
}
}
if label == "" {
label = tag
}
b.WriteString(`| ` + html.EscapeString(label) +
` | ` + html.EscapeString(val) +
` | ` +
html.EscapeString(tag) + ` |
`)
}
b.WriteString(`
`)
return b.String()
}
// xmlFieldsHTML — обёртка для шаблона (template.HTML, чтобы не экранировалось).
func xmlFieldsHTML(raw string) template.HTML {
return template.HTML(renderXMLFieldsTable(raw))
}