feat: ОПК показатели 8/9/13 + блокировка неприменимых с разблокировкой

- criteria_applicability.json: ОПК — применимы 8 (ущерб субъекту КИИ),
  9 (ущерб бюджету), 13 (гособоронзаказ) — обязательные для ОПК
- окно ПП 127: неприменимые для сферы показатели автоматически
  выбирают «не применим» и блокируются (серым), НО у каждого есть
  кнопка «🔓» — разблокировать конкретный показатель, если оператор
  считает его применимым (вернётся выбор категории)
- «не применим» сохраняется в список показателей и обоснование,
  не влияет на категорию
This commit is contained in:
2026-08-04 20:53:29 +04:00
parent 4fc6fba92a
commit 972ff11b49
2 changed files with 32 additions and 8 deletions
@@ -94,6 +94,8 @@
"14"
],
"Оборонная промышленность": [
"8",
"9",
"13"
],
"Ракетно-космическая промышленность": [
+30 -8
View File
@@ -1868,6 +1868,18 @@ class DokoGenApp:
return _just[m.group(1)]
return None
def _unlock(combo, var, lbl_num, lbl_name, name, btn=None):
"""Разблокировать конкретный показатель: вернуть выбор категории."""
try:
combo.config(state='readonly')
var.set('')
lbl_num.config(foreground='black')
lbl_name.config(foreground='black', text=name)
if btn is not None:
btn.destroy()
except Exception:
pass
dialog = tk.Toplevel(self.root)
dialog.title("Показатели критериев значимости (ПП РФ № 127)")
dialog.geometry("980x700")
@@ -1896,7 +1908,9 @@ class DokoGenApp:
if applicable is not None:
_sphere_txt = self.is_sphere_combo.get() if hasattr(self, 'is_sphere_combo') else ''
ttk.Label(body, text=f"Сфера объекта: «{_sphere_txt}». Показатели, не применимые для этой сферы "
f"(по Распоряжению ПРФ № 360-р), отмечены серым и исключены из расчёта.",
f"(по Распоряжению ПРФ № 360-р), автоматически помечены «не применим» и "
f"заблокированы. Кнопка «🔓» разблокирует конкретный показатель, если оператор "
f"считает его применимым.",
foreground='#1a6e1a', wraplength=920, justify=tk.LEFT).pack(anchor=tk.W, pady=(0, 8))
rows = [] # (num, name, values{III:..,II:..,I:..}, var, applicable)
@@ -1948,13 +1962,23 @@ class DokoGenApp:
combo.bind('<<ComboboxSelected>>', _on_pick)
if not applicable_here:
# Показатель не применим для сферы объекта — блокируем
# Показатель не применим для сферы объекта:
# автоматически выбираем «не применим» и блокируем,
# но даём кнопку «🔓» для разблокировки конкретного показателя
var.set('не применим')
combo.config(state='disabled')
lbl_num.config(foreground='gray')
lbl_name.config(foreground='gray')
if hasattr(lbl_name, 'config'):
pass
lbl_name.config(text=name + ' (не применим для сферы)')
btn_unlock = ttk.Button(row, text='🔓', width=3,
command=lambda c=combo, v=var,
ln=lbl_num, lname=lbl_name,
b=None, nm=name: _unlock(c, v, ln, lname, nm))
btn_unlock.pack(side=tk.RIGHT, padx=(2, 0))
# ссылка на кнопку для возможного удаления — храним в замыкании
btn_unlock.config(command=lambda c=combo, v=var, ln=lbl_num,
lname=lbl_name, b=btn_unlock, nm=name:
_unlock(c, v, ln, lname, nm, b))
rows.append((num, name, values, var, applicable_here))
# Обоснование
@@ -1971,15 +1995,13 @@ class DokoGenApp:
result_lbl.pack(anchor=tk.W, pady=(6, 0))
def _selected():
"""Список выбранных: [(num, name, категория, значение)] — только применимые показатели.
"""Список выбранных: [(num, name, категория, значение)].
«не применим» возвращается как ('', 'не применим') и не влияет на категорию,
но сохраняется в список показателей.
но сохраняется в список показателей и в обоснование.
"""
out = []
for num, name, values, var, applicable_here in rows:
if not applicable_here:
continue
s = var.get().strip()
if not s:
continue