feat: вариант «не применим» для показателей критериев значимости

В окне ПП 127 у каждого показателя теперь 5 вариантов: пусто,
«не применим», 3 категория, 2 категория, 1 категория.
«Не применим» не влияет на расчёт категории, но сохраняется
в список показателей как «Показатель N. ... — не применим».
This commit is contained in:
2026-08-04 20:44:53 +04:00
parent 8c1d94d881
commit 3922b8264a
+24 -11
View File
@@ -1899,9 +1899,9 @@ class DokoGenApp:
# Текст показателя # Текст показателя
lbl_name = ttk.Label(row, text=name, wraplength=640, justify=tk.LEFT) lbl_name = ttk.Label(row, text=name, wraplength=640, justify=tk.LEFT)
lbl_name.pack(side=tk.LEFT) lbl_name.pack(side=tk.LEFT)
# Выбор значения (категория) # Выбор значения (категория) + вариант «не применим»
var = tk.StringVar(value='') var = tk.StringVar(value='')
options = [''] options = ['', 'не применим']
for cat in ('III', 'II', 'I'): for cat in ('III', 'II', 'I'):
v = values.get(cat, '') v = values.get(cat, '')
if v: if v:
@@ -1933,7 +1933,11 @@ class DokoGenApp:
result_lbl.pack(anchor=tk.W, pady=(6, 0)) result_lbl.pack(anchor=tk.W, pady=(6, 0))
def _selected(): def _selected():
"""Список выбранных: [(num, name, категория, значение)] — только применимые показатели.""" """Список выбранных: [(num, name, категория, значение)] — только применимые показатели.
«не применим» возвращается как ('', 'не применим') и не влияет на категорию,
но сохраняется в список показателей.
"""
out = [] out = []
for num, name, values, var, applicable_here in rows: for num, name, values, var, applicable_here in rows:
if not applicable_here: if not applicable_here:
@@ -1941,6 +1945,9 @@ class DokoGenApp:
s = var.get().strip() s = var.get().strip()
if not s: if not s:
continue continue
if s == 'не применим':
out.append((num, name, '', 'не применим'))
continue
cat = s.split(' ')[0] # III/II/I cat = s.split(' ')[0] # III/II/I
val = s.split(': ', 1)[1] if ': ' in s else '' val = s.split(': ', 1)[1] if ': ' in s else ''
out.append((num, name, cat, val)) out.append((num, name, cat, val))
@@ -1959,27 +1966,33 @@ class DokoGenApp:
def _calc(): def _calc():
selected = _selected() selected = _selected()
if not selected: # «не применим» не влияет на категорию — считаем только реально выбранные категории
chosen = [x for x in selected if x[2] != '']
if not chosen:
if applicable is not None and not any(a for _, _, _, _, a in rows): if applicable is not None and not any(a for _, _, _, _, a in rows):
result_lbl.config(text="Категория значимости: без категории (для этой сферы нет применимых показателей)") result_lbl.config(text="Категория значимости: без категории (для этой сферы нет применимых показателей)")
else: else:
result_lbl.config(text="Категория значимости: — (ничего не выбрано)") result_lbl.config(text="Категория значимости: — (ничего не выбрано)")
return return
cat = _calc_category(selected) cat = _calc_category(chosen)
result_lbl.config(text=f"Категория значимости: {cat} (выбрано показателей: {len(selected)})") result_lbl.config(text=f"Категория значимости: {cat} (выбрано показателей: {len(chosen)})")
def _save(): def _save():
selected = _selected() selected = _selected()
# Заполняем список показателей # Заполняем список показателей (включая «не применим»)
lines = [] lines = []
for num, name, cat, val in selected: for num, name, cat, val in selected:
if cat == '':
lines.append(f"Показатель {num}. {name} — не применим")
else:
lines.append(f"Показатель {num}. {name}{cat} категория: {val}") lines.append(f"Показатель {num}. {name}{cat} категория: {val}")
if hasattr(self, 'is_criteria_values_listbox'): if hasattr(self, 'is_criteria_values_listbox'):
self.is_criteria_values_listbox.delete(0, tk.END) self.is_criteria_values_listbox.delete(0, tk.END)
for line in lines: for line in lines:
self.is_criteria_values_listbox.insert(tk.END, line) self.is_criteria_values_listbox.insert(tk.END, line)
# Категория значимости # Категория значимости — только по реально выбранным категориям
cat = _calc_category(selected) chosen = [x for x in selected if x[2] != '']
cat = _calc_category(chosen)
if hasattr(self, 'is_category_var'): if hasattr(self, 'is_category_var'):
self.is_category_var.set(cat) self.is_category_var.set(cat)
# Обоснование: если поле пустое — сформируем автоматически # Обоснование: если поле пустое — сформируем автоматически
@@ -1988,7 +2001,7 @@ class DokoGenApp:
f"Категория значимости объекта КИИ определена в соответствии с Правилами категорирования " f"Категория значимости объекта КИИ определена в соответствии с Правилами категорирования "
f"объектов критической информационной инфраструктуры РФ (ПП РФ от 08.02.2019 № 127). " f"объектов критической информационной инфраструктуры РФ (ПП РФ от 08.02.2019 № 127). "
f"Объект отнесён к {cat} категории значимости. Основания: " f"Объект отнесён к {cat} категории значимости. Основания: "
+ "; ".join(f"показатель {num} ({cat} категория)" for num, _, cat, _ in selected) + "." + "; ".join(f"показатель {num} ({c} категория)" for num, _, c, _ in chosen) + "."
) )
if not j: if not j:
j = auto_just j = auto_just
@@ -1997,7 +2010,7 @@ class DokoGenApp:
for line in j.split('\n'): for line in j.split('\n'):
if line.strip(): if line.strip():
self.is_criteria_justification_listbox.insert(tk.END, line.strip()) self.is_criteria_justification_listbox.insert(tk.END, line.strip())
self.log(f"📋 Критерии значимости (ПП 127) сохранены: категория {cat}, показателей: {len(selected)}") self.log(f"📋 Критерии значимости (ПП 127) сохранены: категория {cat}, показателей: {len(chosen)}")
dialog.destroy() dialog.destroy()
btn_frame = ttk.Frame(body) btn_frame = ttk.Frame(body)