Отправка в НРД с подтверждением доставки: 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:
@@ -51,6 +51,7 @@ var templateFuncs = template.FuncMap{
|
||||
"quikCodeMap": quikClientCodeMapText,
|
||||
"curUser": authTemplateFuncs["curUser"],
|
||||
"can": authTemplateFuncs["can"],
|
||||
"sendFailText": sendFailText,
|
||||
"devOn": authTemplateFuncs["devOn"],
|
||||
"devLicensed": authTemplateFuncs["devLicensed"],
|
||||
"mod": func(f string) bool { return globalRC == nil || moduleAllowed(globalRC, f) }, // модуль в лицензии
|
||||
@@ -172,7 +173,7 @@ func russianState(s string) string {
|
||||
case "draft":
|
||||
return "Черновик"
|
||||
case "validated":
|
||||
return "Валидирована"
|
||||
return "Не отправлена"
|
||||
case "submitted_to_nsd":
|
||||
return "Отправлена в НРД"
|
||||
case "awaiting_decision":
|
||||
@@ -360,6 +361,7 @@ type page struct {
|
||||
NPR bool // модуль «НПР / УДС» включён и разрешён лицензией
|
||||
IGWDown string // ИШ НРД не отвечает: «N мин» (пусто — отвечает или не проверялся)
|
||||
IGWDetail string
|
||||
NSDDown string // ИШ отвечает, но НРД не отвечает шлюзу (nsdlinkwatch.go)
|
||||
DevMode bool // режим разработки (сервер лицензий): видны служебные разделы
|
||||
}
|
||||
|
||||
@@ -407,6 +409,7 @@ type claimData struct {
|
||||
DepoL *DepoLink
|
||||
Depo *OutgoingDeal // депозитарное поручение 16 (списание) по этой сделке, если черновик пришёл
|
||||
Flash string
|
||||
Fail *SendFailure // последняя неудачная отправка в НРД (sendfail.go)
|
||||
}
|
||||
|
||||
// statusData — данные страницы статуса.
|
||||
@@ -446,6 +449,9 @@ func RegisterAdmin(mux *http.ServeMux, svc *Service, rc *RuntimeConfig, getOpts
|
||||
case strings.HasPrefix(p, "claims/") && strings.HasSuffix(p, "/export.zip"):
|
||||
id := strings.TrimSuffix(strings.TrimPrefix(p, "claims/"), "/export.zip")
|
||||
a.exportClaim(w, r, svc, id)
|
||||
case strings.HasPrefix(p, "claims/") && strings.HasSuffix(p, "/resend"):
|
||||
id := strings.TrimSuffix(strings.TrimPrefix(p, "claims/"), "/resend")
|
||||
a.resendClaim(w, r, svc, id)
|
||||
case strings.HasPrefix(p, "claims/") && strings.HasSuffix(p, "/delete-draft"):
|
||||
id := strings.TrimSuffix(strings.TrimPrefix(p, "claims/"), "/delete-draft")
|
||||
a.deleteDraft(w, r, svc, id)
|
||||
@@ -551,7 +557,7 @@ func (a *admin) deleteDraft(w http.ResponseWriter, r *http.Request, svc *Service
|
||||
back("/admin/claims", "Заявка не найдена")
|
||||
return
|
||||
}
|
||||
if d.State != m2mcore.StateDraft {
|
||||
if !m2mcore.IsUnsent(d.State) {
|
||||
back("/admin/claims/"+id, "Удалить можно только черновик: эта заявка уже ушла в НРД")
|
||||
return
|
||||
}
|
||||
@@ -586,6 +592,27 @@ func (a *admin) deleteDraft(w http.ResponseWriter, r *http.Request, svc *Service
|
||||
back("/admin/claims", msg)
|
||||
}
|
||||
|
||||
// resendClaim — POST /admin/claims/{id}/resend: заявка не дошла до НРД (контур был недоступен) —
|
||||
// отправить тот же запрос (тот же GUID) ещё раз.
|
||||
func (a *admin) resendClaim(w http.ResponseWriter, r *http.Request, svc *Service, id string) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
id = path.Base(id)
|
||||
msg := "✓ Отправлено повторно: НРД принял пакет"
|
||||
if err := svc.ResendClaim(r.Context(), id); err != nil {
|
||||
msg = "✗ Повторная отправка не удалась: " + err.Error()
|
||||
} else {
|
||||
actor := ""
|
||||
if u := currentUser(w); u != nil {
|
||||
actor = u.Login
|
||||
}
|
||||
log.Printf("admin: заявка %s отправлена в НРД повторно (%s)", id, actor)
|
||||
}
|
||||
http.Redirect(w, r, "/admin/claims/"+id+"?flash="+url.QueryEscape(msg), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (a *admin) renderClaim(w http.ResponseWriter, r *http.Request, svc *Service, id string) {
|
||||
id = path.Base(id)
|
||||
view, err := svc.GetClaim(r.Context(), id)
|
||||
@@ -612,8 +639,12 @@ func (a *admin) renderClaim(w http.ResponseWriter, r *http.Request, svc *Service
|
||||
if view.M2MGUID != "" {
|
||||
depoL = globalDepoLinks.Get(string(view.M2MGUID))
|
||||
}
|
||||
var fail *SendFailure
|
||||
if view.M2MGUID != "" {
|
||||
fail = sendFailGet(string(view.M2MGUID))
|
||||
}
|
||||
render(w, a.claim, claimData{
|
||||
Quik: quik, Watch: watch, DepoL: depoL,
|
||||
Quik: quik, Watch: watch, DepoL: depoL, Fail: fail,
|
||||
page: nowPage("Заявка", "claims"),
|
||||
Claim: view, Depo: depo, Flash: r.URL.Query().Get("flash"),
|
||||
})
|
||||
@@ -777,6 +808,8 @@ func nowPage(title, active string) page {
|
||||
p.DevMode = devMode(globalRC)
|
||||
if down, d, det := igwStatus(); down {
|
||||
p.IGWDown, p.IGWDetail = humanDur(d), det
|
||||
} else if down, det := nsdLinkStatus(); down {
|
||||
p.NSDDown, p.IGWDetail = det, det
|
||||
}
|
||||
s := globalRC.Snapshot()
|
||||
switch {
|
||||
|
||||
Reference in New Issue
Block a user