Мастер, QUIK: короткое письмо в ARQA с внешним адресом, памятка администратору, понятный выбор работы с QUIK

- Письмо в ARQA: организация просит подключить модуль неторговых поручений,
  выдать логин и пароль и разрешить подключение с нашего внешнего адреса —
  о bj и внутреннем устройстве ни слова. Внешний адрес bj узнаёт у сервера
  лицензий (GET /v1/ip, раз в час); пометка — убедиться, что адрес постоянный.
- Под письмом — «Памятка администратору QUIK» (классы, логин InstrEu, справочник,
  перезапуск модуля) со ссылкой на подробную инструкцию.
- Вместо свёрнутого «Автоматический цикл M2M — выключен · настроить» и справочника
  под раскрытием: после проверки подключения — «Как bj работает с QUIK»: «Только
  сверка» или «Автоматически» (+ торговый счёт), сохраняется сразу; справочник —
  строкой состояния с напоминанием о перезапуске. До проверки — одна строка.
  Тонкая настройка — в «Настройка → QUIK», мастер её не трогает.
- Проверка МНП: ошибка сертификата (x509, «doesn't contain any IP SANs») —
  подсказка включить «Доверять сертификату сервера», «Дополнительно» раскрывается.

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 16:59:21 +03:00
parent 8ab3a88c7b
commit a7cfbb2e74
8 changed files with 284 additions and 11 deletions
@@ -86,6 +86,10 @@
.dq-jobname { margin-top:14px; max-width:520px; }
.dq-jobname label { display:block; margin:0; font-size:13.5px; font-weight:500; color:var(--text-2); }
.dq-jobname input { display:block; width:100%; box-sizing:border-box; margin-top:5px; }
.wiz-memo { margin:10px 0 0; font-size:13.5px; }
.wiz-memo summary { cursor:pointer; color:var(--accent); }
.wiz-memo ul { margin:6px 0 8px; padding-left:20px; }
.wiz-memo li { margin:3px 0; }
.dq-box { border:1px solid var(--border); border-radius:12px; padding:14px 16px 16px; }
.dq-box-bj { background:color-mix(in srgb, var(--accent-weak) 45%, transparent); }
.dq-box-h { font-weight:600; font-size:14.5px; margin:0 0 10px; }
@@ -462,13 +466,49 @@
<div class="card">
<h2><span class="dot {{if .Done.Quik}}ok{{else}}err{{end}}"></span>QUIK</h2>
<p>Адрес и логин модуля неторговых поручений — у вашего администратора QUIK. Если модуля ещё нет, его подключает ARQA Technologies — письмо для них готово ниже.</p>
{{if .DepoLicensed}}{{template "letterCard" (letter "arqa")}}{{end}}
{{if .DepoLicensed}}{{template "letterCard" (letter "arqa")}}
<details class="wiz-memo"><summary>Памятка администратору QUIK</summary>
<p>Всё это описано в документации ARQA на модуль неторговых поручений — администратору QUIK она знакома:</p>
<ul>
<li>в QAdmin — классы <code>INSTROUTM2M</code> (вывод ценных бумаг) и <code>INSTRINM2M</code> (ввод), типы неторговых поручений M2M;</li>
<li>SQL-логин для bj с ролью <code>InstrEu</code> — его логин и пароль вписываются ниже;</li>
<li>справочник депозитариев-получателей <code>M2MDepoRecipients</code> заполняет bj; после первого заполнения модуль нужно перезапустить.</li>
</ul>
<a href="/admin/help/quik">Подробная инструкция для администратора QUIK →</a>
</details>{{end}}
{{if not .DepoLicensed}}<p class="muted">Модуль неторговых поручений не входит в текущую лицензию — шаг пропускается.</p>
{{else}}{{with .Fancy}}{{template "quikSection" .}}{{end}}
{{if .Settings.Quik.Server}}{{template "mnpCheck" .}}{{end}}
{{if .Settings.Quik.M2MMissing}}<p style="color:var(--err);margin:8px 0">✗ Подключение есть, но под этим логином не видно объектов M2M: {{.Settings.Quik.M2MMissing}}. Проверьте имя базы МНП и права логина (роль InstrEu) и нажмите «Проверить» ещё раз.</p>{{end}}
<details style="margin-top:12px;font-size:13px"><summary style="cursor:pointer;color:var(--accent)">Справочник депозитариев-получателей — bj заполняет сам</summary>
<p style="margin:6px 0 0">Чтобы QUIK принимал поручения M2M, bj ведёт в МНП справочник депозитариев-получателей (<code>M2MDepoRecipients</code>) по справочнику участников НРД. <b>МНП читает его только при запуске</b> — после первого заполнения попросите администратора QUIK перезапустить модуль, иначе QUIK ответит «Неизвестный депозитарий получателя».<br><span class="muted">{{quikRecipientsInfo}}</span></p></details>{{end}}
{{if .Settings.Quik.Verified}}
<div class="card" id="quik-mode">
<h2>Как bj работает с QUIK</h2>
<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>
</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>
</div>
<p class="dq-note" id="quik-mode-st" aria-live="polite">Выбор сохраняется сразу. Тонкая настройка — инструменты МНП, коды клиентов, поручения из терминала — в «Настройка → QUIK».</p>
<noscript><button type="submit" class="btn">Сохранить</button></noscript>
</form>
<p class="dq-note">{{quikRecipientsInfo}} После первого заполнения справочника депозитариев-получателей попросите администратора QUIK перезапустить модуль неторговых поручений — QUIK читает справочник только при запуске.</p>
</div>
<script>(function(){
var f=document.getElementById('quik-mode-form'), st=document.getElementById('quik-mode-st'), acc=document.getElementById('quik-acc');
function sync(){ acc.hidden=f.mode.value!=='auto'; }
f.addEventListener('change', function(){ sync();
fetch(f.action,{method:'POST',body:new URLSearchParams(new FormData(f)),headers:{'Content-Type':'application/x-www-form-urlencoded','X-BJ-Ajax':'1'},cache:'no-store'})
.then(function(r){ return r.text().then(function(t){ st.textContent=(r.ok?'✓ Сохранено: ':'✗ ')+t; }); })
.catch(function(){ st.textContent='✗ Не сохранилось — обновите страницу и выберите ещё раз.'; });
});
f.addEventListener('submit', function(e){ if(window.fetch) e.preventDefault(); });
sync();
})();</script>
{{else}}<p class="muted" style="margin-top:12px">Когда подключение проверено, здесь появится выбор, как bj работает с QUIK.</p>{{end}}{{end}}
{{template "wizNav" .}}
</div>
{{end}}
@@ -18,7 +18,7 @@
<label>Пароль
<input type="password" name="password" placeholder="{{if .Settings.Quik.Password}}сохранён — пусто, чтобы не менять{{end}}" autocomplete="new-password" style="width:100%"></label>
</div>
<details><summary style="cursor:pointer;color:var(--accent);font-size:13px">Дополнительно: база и шифрование (обычно не нужно)</summary>
<details {{if quikNeedsTrust .Settings.Quik}}open{{end}}><summary style="cursor:pointer;color:var(--accent);font-size:13px">Дополнительно: база и шифрование</summary>
<div style="display:grid;gap:10px;margin-top:8px">
<label>База МНП <span class="muted" style="font-weight:400">— пусто: база логина по умолчанию</span>
<input type="text" name="database" value="{{.Settings.Quik.Database}}" style="width:100%"></label>
@@ -37,8 +37,9 @@
<p class="muted" style="margin-top:12px">Статус: {{if .Settings.Quik.Verified}}<span style="color:var(--ok)">✓ подключение проверено</span>{{else}}<span class="muted">не проверено</span>{{end}}</p>
</div>
{{if not .InWizard}}{{/* в мастере вместо этой карточки — выбор «Как bj работает с QUIK» (шаг QUIK) */}}
<div class="card" id="sec-quik-cycle">
{{if .InWizard}}<details><summary style="cursor:pointer;list-style:none"><h2 style="display:inline">{{else}}<h2>{{end}}<span class="dot {{if .Settings.Quik.Emulate}}warn{{else if not .Settings.Quik.WritesEnabled}}warn{{else if or .Settings.Quik.AutoOut .Settings.Quik.AutoIn}}ok{{else}}warn{{end}}"></span>Автоматический цикл M2M в МНП{{if .Settings.Quik.Emulate}} <span class="hero-status warn">{{if devOn}}имитация{{else}}остановлен{{end}}</span>{{end}}</h2>{{if .InWizard}} <span class="muted" style="font-size:13px">— {{if .Settings.Quik.WritesEnabled}}включён{{else}}выключен: bj ничего не пишет в QUIK{{end}} · настроить ▸</span></summary>{{end}}
<h2><span class="dot {{if .Settings.Quik.Emulate}}warn{{else if not .Settings.Quik.WritesEnabled}}warn{{else if or .Settings.Quik.AutoOut .Settings.Quik.AutoIn}}ok{{else}}warn{{end}}"></span>Автоматический цикл M2M в МНП{{if .Settings.Quik.Emulate}} <span class="hero-status warn">{{if devOn}}имитация{{else}}остановлен{{end}}</span>{{end}}</h2>
<p class="muted">Что делает bj в Модуле неторговых поручений по ходу перевода: <strong>исходящий</strong> — при отправке в НРД регистрирует «Вывод ЦБ (M2M)» (QUIK блокирует бумаги), по подтверждению подписывает (списание), по отказу снимает с причиной; <strong>входящий</strong> — после приёма нашего поручения НРД регистрирует «Ввод ЦБ (M2M)» (зачисление сразу). Каждый шаг виден в карточке перевода и на странице <a href="/admin/quik">QUIK МНП</a>.</p>
<form method="post" action="/admin/setup/quik/cycle" style="margin-top:12px;display:grid;gap:10px;max-width:640px">
<input type="hidden" name="section" value="sec-quik-cycle">
@@ -69,8 +70,8 @@
<textarea name="client_code_map" rows="3" style="width:100%;font-family:ui-monospace,monospace;font-size:12px" placeholder="БР-12-3=BR123">{{quikCodeMap .Settings.Quik.ClientCodeMap}}</textarea></label>
<div style="display:flex;gap:8px;flex-wrap:wrap"><button type="submit" class="btn">Сохранить</button></div>
</form>
{{if .InWizard}}</details>{{end}}
</div>
{{end}}
{{if .Settings.Quik.LastReport}}
<div class="card">