feat: обоснования неприменимости показателей критериев по сферам

- dictionaries/criteria_justifications.json: тексты обоснований для сферы
  здравоохранения (показатели 1-7) — дословно из примера заказчика
- окно ПП 127: при выборе «не применим» обоснование из словаря сферы
  автоматически подставляется в поле «Обоснование»
- авто-обоснование при сохранении: категория + выбранные показатели +
  неприменимые показатели с текстами обоснований; если все показатели
  неприменимы — «Категория значимости: не присвоена»
This commit is contained in:
2026-08-04 20:48:55 +04:00
parent 3922b8264a
commit 6852bc634b
2 changed files with 57 additions and 6 deletions
+46 -6
View File
@@ -1846,6 +1846,18 @@ class DokoGenApp:
except Exception:
applicable = None
# Словарь обоснований неприменимости показателей по сферам
# (примеры формулировок; для сфер без записей — пусто)
justifications = {}
try:
_j_path = os.path.join(os.path.dirname(__file__), 'dictionaries', 'criteria_justifications.json')
with open(_j_path, encoding='utf-8') as _f:
justifications = _json.load(_f)
except Exception:
justifications = {}
_sphere_just = self.is_sphere_combo.get() if hasattr(self, 'is_sphere_combo') else ''
_just = justifications.get(_sphere_just, {}) if _sphere_just else {}
dialog = tk.Toplevel(self.root)
dialog.title("Показатели критериев значимости (ПП РФ № 127)")
dialog.geometry("980x700")
@@ -1909,6 +1921,21 @@ class DokoGenApp:
combo = ttk.Combobox(row, textvariable=var, state='readonly', width=34,
values=options)
combo.pack(side=tk.RIGHT, padx=6)
def _on_pick(_e, _num=num, _var=var, _name=name):
# При выборе «не применим» — автоподстановка обоснования из словаря сферы
if _var.get().strip() == 'не применим' and _num in _just:
txt = _just[_num]
prefix = f"Показатель {_num}. {_name} — не применим."
full = prefix + " " + txt
cur = justify_txt.get('1.0', 'end-1c').strip()
if prefix not in cur:
if cur:
justify_txt.insert('end', '\n' + full)
else:
justify_txt.insert('1.0', full)
combo.bind('<<ComboboxSelected>>', _on_pick)
if not applicable_here:
# Показатель не применим для сферы объекта — блокируем
combo.config(state='disabled')
@@ -1992,17 +2019,30 @@ class DokoGenApp:
self.is_criteria_values_listbox.insert(tk.END, line)
# Категория значимости — только по реально выбранным категориям
chosen = [x for x in selected if x[2] != '']
not_applicable = [x for x in selected if x[2] == '']
cat = _calc_category(chosen)
if hasattr(self, 'is_category_var'):
self.is_category_var.set(cat)
# Обоснование: если поле пустое — сформируем автоматически
# (по формату: категория + выбранные показатели + неприменимые с обоснованиями)
j = justify_txt.get('1.0', 'end-1c').strip()
auto_just = (
f"Категория значимости объекта КИИ определена в соответствии с Правилами категорирования "
f"объектов критической информационной инфраструктуры РФ (ПП РФ от 08.02.2019 № 127). "
f"Объект отнесён к {cat} категории значимости. Основания: "
+ "; ".join(f"показатель {num} ({c} категория)" for num, _, c, _ in chosen) + "."
)
auto_parts = []
if chosen:
auto_parts.append(
"Категория значимости объекта КИИ определена в соответствии с Правилами категорирования "
"объектов критической информационной инфраструктуры РФ (ПП РФ от 08.02.2019 № 127). "
f"Объект отнесён к {cat} категории значимости. Основания: "
+ "; ".join(f"показатель {num} ({c} категория)" for num, _, c, _ in chosen) + "."
)
for num, name, _, _ in not_applicable:
base = f"Показатель {num}. {name} — не применим"
if num in _just:
auto_parts.append(base + ": " + _just[num])
else:
auto_parts.append(base + ".")
if not_applicable and not chosen:
auto_parts.insert(0, "Категория значимости: не присвоена (показатели критериев значимости неприменимы к объекту).")
auto_just = "\n".join(auto_parts) if auto_parts else ""
if not j:
j = auto_just
if hasattr(self, 'is_criteria_justification_listbox'):