Код бумаги в запросе НРД — код НРД из DEPO по ISIN (у акций ≠ ISIN: SBER/03), иначе M2M43
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
@@ -82,6 +82,7 @@ func (s *Service) CreateClaim(ctx context.Context, in CreateClaimRequest) (Creat
|
||||
// ReferenceID, реквизиты) БЕЗ отправки и без создания заявки. Нужно, чтобы
|
||||
// сначала положить запрос в БД Fancy на проверку, а отправить позже.
|
||||
func (s *Service) BuildRequest(ctx context.Context, in CreateClaimRequest) (*m2m.M2MTransferRequest, error) {
|
||||
in = withNSDSecCodes(in)
|
||||
domainClaim, err := dtoToClaim(in)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("lkgateway: dtoToClaim: %w", err)
|
||||
@@ -113,6 +114,7 @@ func (s *Service) receiverFor(in CreateClaimRequest) m2m.DeponentCode {
|
||||
// BuildRequestUnchecked — BuildRequest без финальной проверки формата НРД: пакет нужен
|
||||
// для журнала и отказа через Fancy даже при некорректных данных заявки (lkemulate.go).
|
||||
func (s *Service) BuildRequestUnchecked(ctx context.Context, in CreateClaimRequest) (*m2m.M2MTransferRequest, error) {
|
||||
in = withNSDSecCodes(in)
|
||||
domainClaim, err := dtoToClaim(in)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("lkgateway: dtoToClaim: %w", err)
|
||||
@@ -693,3 +695,62 @@ func nsdResponseFromDecision(d *m2m.M2MTransferDecision) *NSDResponseView {
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// nsdSecCodes — код бумаги в НРД (SecurityCode) по ISIN из DEPO (кодировщик «НДЦ»), с кэшем на час.
|
||||
// У акций код НРД отличается от ISIN (Сбербанк — SBER/03), и с ISIN вместо кода НРД сервис отвечает
|
||||
// M2M43 «Ценная бумага не учитывается в НРД» (29.09.2026).
|
||||
var nsdSecCodes = struct {
|
||||
sync.Mutex
|
||||
m map[string]nsdSecCodeEntry
|
||||
}{m: map[string]nsdSecCodeEntry{}}
|
||||
|
||||
type nsdSecCodeEntry struct {
|
||||
code string
|
||||
at time.Time
|
||||
}
|
||||
|
||||
func nsdSecCodeByISIN(isin string) string {
|
||||
isin = strings.ToUpper(strings.TrimSpace(isin))
|
||||
if isin == "" || globalRC == nil {
|
||||
return ""
|
||||
}
|
||||
nsdSecCodes.Lock()
|
||||
if e, ok := nsdSecCodes.m[isin]; ok && time.Since(e.at) < time.Hour {
|
||||
nsdSecCodes.Unlock()
|
||||
return e.code
|
||||
}
|
||||
nsdSecCodes.Unlock()
|
||||
fs := globalRC.Snapshot().Fancy
|
||||
if strings.TrimSpace(fs.Server) == "" {
|
||||
return ""
|
||||
}
|
||||
db, err := fancyOpen(fs, fs.DepoDB())
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer db.Close()
|
||||
code := depoNSDCode(db, isin)
|
||||
nsdSecCodes.Lock()
|
||||
nsdSecCodes.m[isin] = nsdSecCodeEntry{code: code, at: time.Now()}
|
||||
nsdSecCodes.Unlock()
|
||||
return code
|
||||
}
|
||||
|
||||
// withNSDSecCodes — бумаги, у которых код НРД не задан или равен ISIN, получают код НРД из DEPO.
|
||||
func withNSDSecCodes(in CreateClaimRequest) CreateClaimRequest {
|
||||
if len(in.Securities) == 0 {
|
||||
return in
|
||||
}
|
||||
secs := append([]ClaimSec(nil), in.Securities...)
|
||||
for i := range secs {
|
||||
isin := strings.ToUpper(strings.TrimSpace(secs[i].SecurityDetails.ISIN))
|
||||
if isin == "" || (secs[i].SecurityCode != "" && !strings.EqualFold(secs[i].SecurityCode, isin)) {
|
||||
continue
|
||||
}
|
||||
if code := nsdSecCodeByISIN(isin); code != "" {
|
||||
secs[i].SecurityCode = code
|
||||
}
|
||||
}
|
||||
in.Securities = secs
|
||||
return in
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user