QUIK: режимы «Только чтение» / «Чтение и запись» вместо «сверка / автоматически»

Система работает автоматически, ручного режима нет: выбор — только читать QUIK
(настройка и проверка: ничего не блокирует, не разблокирует, не меняет лимиты)
или читать и писать (боевая работа). В проверке МНП строка «Режим работы с QUIK»:
только чтение — сведение (ℹ), а не предупреждение, с объяснением, как включить
боевую работу.

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-10-06 17:16:14 +03:00
parent c7cb48f977
commit 47b183a072
5 changed files with 14 additions and 13 deletions
+1 -1
View File
@@ -714,7 +714,7 @@ func TestQuikModeAndCertHint(t *testing.T) {
h.saveQuikMode(w, r)
return w.Body.String()
}
if msg := post(url.Values{"mode": {"auto"}, "account": {"L01-00000F00"}}); !strings.Contains(msg, "автоматически") {
if msg := post(url.Values{"mode": {"auto"}, "account": {"L01-00000F00"}}); !strings.Contains(msg, "чтение и запись") {
t.Fatalf("ответ: %q", msg)
}
s := rc.Snapshot().Quik
+3 -3
View File
@@ -124,7 +124,7 @@ func (h *setupHandlers) saveQuikCycle(w http.ResponseWriter, r *http.Request) {
}
// saveQuikMode — POST /admin/setup/quik/mode (мастер): как bj работает с QUIK — одним выбором вместо набора
// флажков. check — только сверка (в МНП bj не пишет, поручения вводят сотрудники); auto — bj ведёт поручения
// флажков. check — только чтение (bj читает, в МНП ничего не меняет); auto — чтение и запись, боевая работа: bj ведёт поручения
// сам: исходящие (блокировка, списание или снятие) и входящие (зачисление). Тонкая настройка (инструменты,
// коды клиентов, поручения из терминала, имитация) — в «Настройке», здесь не трогается. Экран сохраняет
// выбор сразу (X-BJ-Ajax — ответ строкой), без JavaScript — обычной формой.
@@ -142,9 +142,9 @@ func (h *setupHandlers) saveQuikMode(w http.ResponseWriter, r *http.Request) {
if r.PostForm.Has("account") {
s.Account = strings.TrimSpace(r.FormValue("account"))
}
msg := "только сверка — в QUIK bj ничего не пишет"
msg := "только чтение — bj ничего в QUIK не меняет"
if auto {
msg = "автоматически — bj ведёт поручения в QUIK сам"
msg = "чтение и запись — боевая работа: bj сам блокирует, списывает и зачисляет в QUIK"
if s.Account == "" {
msg += "; укажите торговый счёт"
}
+6 -5
View File
@@ -18,7 +18,7 @@ import (
// MNPCheck — одна строка проверки МНП.
type MNPCheck struct {
Title string `json:"title"`
State string `json:"state"` // ok | warn | err
State string `json:"state"` // ok | info (сведение, не проблема) | warn | err
Detail string `json:"detail"`
}
@@ -107,11 +107,12 @@ func quikMNPCheck(ctx context.Context, s QuikMNPSettings) []MNPCheck {
switch {
case !s.WritesEnabled:
add("Автоматический цикл M2M", "warn", "запись в МНП выключена — bj не ставит и не снимает блокировки (Настройка → QUIK МНП)")
// не проблема, а начальный режим: подключились и читаем, в QUIK ничего не меняем
add("Режим работы с QUIK", "info", "только чтение: bj подключён к QUIK и читает данные, но ничего в нём не меняет — не блокирует и не разблокирует бумаги, не меняет лимиты. Когда будете готовы к боевой работе, включите «Чтение и запись» (в мастере — «Как bj работает с QUIK», в настройке — «Автоматический цикл M2M в МНП»)")
case s.Emulate:
add("Автоматический цикл M2M", "warn", "включена имитация — шаги проходят без записи в МНП")
add("Режим работы с QUIK", "warn", "включена имитация — шаги проходят без записи в МНП")
case !s.AutoOut && !s.AutoIn:
add("Автоматический цикл M2M", "warn", "запись разрешена, но исходящие и входящие поручения в МНП не регистрируются автоматически")
add("Режим работы с QUIK", "warn", "запись разрешена, но исходящие и входящие поручения в МНП не регистрируются автоматически")
default:
var on []string
if s.AutoOut {
@@ -123,7 +124,7 @@ func quikMNPCheck(ctx context.Context, s QuikMNPSettings) []MNPCheck {
if s.PollTerminal {
on = append(on, "поручения из терминала")
}
add("Автоматический цикл M2M", "ok", "включён: "+strings.Join(on, ", ")+"; торговый счёт "+quikAccount(s))
add("Режим работы с QUIK", "ok", "чтение и запись (боевая работа): "+strings.Join(on, ", ")+"; торговый счёт "+quikAccount(s))
}
since := time.Now().AddDate(0, 0, -30)
@@ -473,8 +473,8 @@
<form method="post" action="/admin/setup/quik/mode" id="quik-mode-form" class="dq">
<input type="hidden" name="return_to" value="/admin/wizard?step=5">
<div class="dq-tiles">
<label class="dq-tile"><input type="radio" name="mode" value="check" {{if not .Settings.Quik.WritesEnabled}}checked{{end}}><span><b>Только сверка</b><small>bj читает QUIK: проверяет клиента и остатки по каждому переводу. Поручения в QUIK вводят ваши сотрудники.</small></span></label>
<label class="dq-tile"><input type="radio" name="mode" value="auto" {{if .Settings.Quik.WritesEnabled}}checked{{end}}><span><b>Автоматически</b><small>bj сам ведёт поручения в QUIK: блокирует бумаги при отправке перевода, списывает или снимает по ответу НРД, зачисляет входящие.</small></span></label>
<label class="dq-tile"><input type="radio" name="mode" value="check" {{if not .Settings.Quik.WritesEnabled}}checked{{end}}><span><b>Только чтение</b><small>bj подключён к QUIK и читает данные, но ничего в нём не меняет: не блокирует и не разблокирует бумаги, не меняет лимиты. Для настройки и проверки — когда будете готовы, включите «Чтение и запись».</small></span></label>
<label class="dq-tile"><input type="radio" name="mode" value="auto" {{if .Settings.Quik.WritesEnabled}}checked{{end}}><span><b>Чтение и запись</b><small>Боевая работа: bj сам блокирует бумаги в QUIK при отправке перевода, списывает или снимает блокировку по ответу НРД, зачисляет входящие.</small></span></label>
</div>
<div class="dq-jobname" id="quik-acc">
<label>Торговый счёт для поручений<input type="text" name="account" value="{{.Settings.Quik.Account}}" placeholder="торговый счёт фирмы в QUIK" spellcheck="false" class="dq-mono"></label>
@@ -98,10 +98,10 @@
(function(){
var rows=document.getElementById('mnp-rows'), dot=document.getElementById('mnp-dot');
function esc(s){return String(s).replace(/[&<>"]/g,function(c){return{'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]})}
var ic={ok:'<span style="color:var(--ok)">✓</span>',warn:'<span style="color:var(--warn)">⚠</span>',err:'<span style="color:var(--err)">✗</span>'};
var ic={ok:'<span style="color:var(--ok)">✓</span>',info:'<span style="color:var(--accent)">ℹ</span>',warn:'<span style="color:var(--warn)">⚠</span>',err:'<span style="color:var(--err)">✗</span>'};
function run(){ rows.innerHTML='<tr><td class="muted">Проверяю…</td></tr>';
fetch('/admin/setup/quik/mnp-check',{cache:'no-store'}).then(function(r){return r.json()}).then(function(d){
rows.innerHTML=d.checks.map(function(c){return '<tr><td style="width:22px;vertical-align:top">'+ic[c.state]+'</td><td style="vertical-align:top;padding-right:10px;white-space:nowrap"><b>'+esc(c.title)+'</b></td><td style="vertical-align:top">'+esc(c.detail)+'</td></tr>'}).join('');
rows.innerHTML=d.checks.map(function(c){return '<tr><td style="width:22px;vertical-align:top">'+(ic[c.state]||'')+'</td><td style="vertical-align:top;padding-right:10px;white-space:nowrap"><b>'+esc(c.title)+'</b></td><td style="vertical-align:top">'+esc(c.detail)+'</td></tr>'}).join('');
dot.className='dot '+d.state; document.getElementById('mnp-at').textContent='проверено '+d.at;
}).catch(function(){ rows.innerHTML='<tr><td>Проверка не выполнилась</td></tr>'; }); }
document.getElementById('mnp-run').onclick=run;