Отправка в НРД с подтверждением доставки: ERROR от ИШ — заявка «Не отправлена», без BJ_SENT; «Отправить повторно» тем же GUID; сторож связи ИШ↔НРД по журналу ИШ

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-09-25 15:57:07 +03:00
parent eecb3b7923
commit c2aaa09fe3
15 changed files with 651 additions and 33 deletions
+25 -12
View File
@@ -131,27 +131,40 @@ func (s *Service) SendBuiltRequest(ctx context.Context, req *m2m.M2MTransferRequ
// SendBuiltRequestVia — SendBuiltRequest через указанный отправитель (имитатор НРД
// для заявок ЛК в тестовом режиме, lkemulate.go). Хуки QUIK и DEPO срабатывают так же.
func (s *Service) SendBuiltRequestVia(ctx context.Context, sender m2mcore.NSDSender, req *m2m.M2MTransferRequest, investorID string, signedDoc []byte) (CreateClaimResponse, error) {
deal, err := m2mcore.NewDeal(req.Header.GUID, investorID, signedDoc)
if err != nil {
return CreateClaimResponse{}, fmt.Errorf("lkgateway: NewDeal: %w", err)
// Заявка с этим GUID уже создавалась, но в НРД не дошла (sendfail.go) — отправляем её же.
saved := s.unsentDeal(ctx, req.Header.GUID)
resend := saved != nil
if !resend {
deal, err := m2mcore.NewDeal(req.Header.GUID, investorID, signedDoc)
if err != nil {
return CreateClaimResponse{}, fmt.Errorf("lkgateway: NewDeal: %w", err)
}
if saved, err = s.repo.Create(ctx, deal); err != nil {
return CreateClaimResponse{}, fmt.Errorf("lkgateway: repo.Create: %w", err)
}
if err := saved.Validate(ctx, req); err != nil {
return CreateClaimResponse{}, fmt.Errorf("lkgateway: deal.Validate: %w", err)
}
// Сохраняем до отправки: если НРД пакет не примет, заявка останется «Не отправлена» с запросом.
if err := s.repo.Update(ctx, saved); err != nil {
return CreateClaimResponse{}, fmt.Errorf("lkgateway: repo.Update: %w", err)
}
} else {
req = saved.Request
}
saved, err := s.repo.Create(ctx, deal)
if err != nil {
return CreateClaimResponse{}, fmt.Errorf("lkgateway: repo.Create: %w", err)
}
if err := saved.Validate(ctx, req); err != nil {
return CreateClaimResponse{}, fmt.Errorf("lkgateway: deal.Validate: %w", err)
}
// QUIK МНП: блокировка бумаг клиента до отправки в НРД (если цикл включён).
if quikSendHook != nil {
// QUIK МНП: блокировка бумаг клиента до отправки в НРД (если цикл включён). При повторной
// отправке бумаги уже заблокированы первой попыткой.
if quikSendHook != nil && !(resend && quikHasRegistered(string(req.Header.GUID))) {
if err := quikSendHook(ctx, req); err != nil {
return CreateClaimResponse{}, fmt.Errorf("lkgateway: %w", err)
}
}
resp, err := sender.Send(ctx, req)
if err != nil {
s.noteSendFailure(ctx, saved, req, err)
return CreateClaimResponse{}, fmt.Errorf("lkgateway: sender.Send: %w", err)
}
sendFailClear(string(req.Header.GUID))
saved.Response = resp
if err := saved.Submit(ctx); err != nil {
return CreateClaimResponse{}, fmt.Errorf("lkgateway: deal.Submit: %w", err)