feat: поля показателя 8 в GUI (доходы за 5 лет + суммарный ущерб)

- models: income_year_1..5 (доход за 5 лет назад ... за прошлый год),
  income_loss (суммарный экономический ущерб от нарушения критических
  процессов) — понятные названия без ΔДоходов
- вкладка «Организация» → «Финансовые показатели»: 6 новых полей
- авторасчёт п. 8: берёт доходы за 5 лет и ущерб из полей,
  считает №8 = ущерб / средний доход за 5 лет × 100% (проверено
  на примере методички: 33% → I категория)
- импорт из опросника: incomeYear1..5 / incomeLoss
- переменные шаблонов: {{company_income_year_1..5}},
  {{company_income_loss}}
This commit is contained in:
2026-08-04 23:03:55 +04:00
parent 5aed863b83
commit 29ba4b0532
3 changed files with 67 additions and 5 deletions
+9
View File
@@ -129,6 +129,15 @@ class Company:
profit: str = "" # Сумма прибыли за предыдущий год
profit_tax: str = "" # Сумма налога с прибыли за предыдущий год
# Показатель 8 (ущерб субъекту КИИ): доходы за 5 лет и суммарный ущерб
income_year_1: str = "" # Доход за 5 лет назад (руб.)
income_year_2: str = "" # Доход за 4 года назад (руб.)
income_year_3: str = "" # Доход за 3 года назад (руб.)
income_year_4: str = "" # Доход за 2 года назад (руб.)
income_year_5: str = "" # Доход за прошлый год (руб.)
income_loss: str = "" # Суммарный экономический ущерб от нарушения
# критических процессов (руб.) — ΔДоходов для п. 8
# Списки
commission: List[CommissionMember] = field(default_factory=list)
information_systems: List[InformationSystem] = field(default_factory=list)
+52 -5
View File
@@ -339,6 +339,24 @@ class DokoGenApp:
entry = ttk.Entry(f_fin, width=50)
entry.grid(row=i, column=1, padx=10, sticky=tk.EW, pady=1)
self._company_entries[key] = entry
# Показатель 8 (ущерб субъекту КИИ): доходы за 5 лет + суммарный ущерб
ttk.Label(f_fin, text="Доходы за 5 лет (показатель 8):",
font=('', 9, 'bold')).grid(row=len(fin_fields), column=0, columnspan=2,
sticky=tk.W, pady=(8, 2))
income_fields = [
("Доход за 5 лет назад (руб.):", "income_year_1"),
("Доход за 4 года назад (руб.):", "income_year_2"),
("Доход за 3 года назад (руб.):", "income_year_3"),
("Доход за 2 года назад (руб.):", "income_year_4"),
("Доход за прошлый год (руб.):", "income_year_5"),
("Суммарный экономический ущерб от нарушения критических процессов (руб.):", "income_loss"),
]
for j, (label, key) in enumerate(income_fields):
ttk.Label(f_fin, text=label).grid(row=len(fin_fields) + 1 + j, column=0, sticky=tk.W, pady=2)
entry = ttk.Entry(f_fin, width=50)
entry.grid(row=len(fin_fields) + 1 + j, column=1, padx=10, sticky=tk.EW, pady=1)
self._company_entries[key] = entry
f_fin.columnconfigure(1, weight=1)
# --- Правая панель: проверка данных ---
@@ -2497,8 +2515,15 @@ class DokoGenApp:
return e
e_profit = e_tax = None
e_dincome = _row("Снижение уровня доходов ΔДоходов (руб., наихудший сценарий):", 'dincome', '')
e_budget = _row("Объём доходов субъекта КИИ, усреднённый за 5 лет Дусредн (руб.):", 'budget', '')
# Доходы за 5 лет — из данных организации (поля «Доходы за 5 лет»)
_incs = [_num2(getattr(self.model, f'income_year_{i}', '') or '') for i in range(1, 6)]
_incs = [x for x in _incs if x is not None]
_d_avg = (sum(_incs) / len(_incs)) if _incs else None
_d_loss = _num2(getattr(self.model, 'income_loss', '') or '')
e_dincome = _row("Суммарный экономический ущерб от нарушения критических процессов (руб.):",
'dincome', f"{_d_loss:,.0f}" if _d_loss else '')
e_budget = _row("Доходы субъекта КИИ, усреднённые за 5 лет (руб.):",
'budget', f"{_d_avg:,.0f}" if _d_avg else '')
result = tk.Text(frm, height=10, wrap=tk.WORD, state=tk.NORMAL)
result.pack(fill=tk.BOTH, expand=True, pady=(8, 0))
@@ -2512,9 +2537,9 @@ class DokoGenApp:
result.insert('1.0', "Заполните оба поля (ΔДоходов и Дусредн).")
return
val = d / b * 100
lines.append(f"Снижение уровня доходов ΔДоходов: {d:,.0f} руб.")
lines.append(f"Объём доходов, усреднённый за 5 лет (Дусредн): {b:,.0f} руб.")
lines.append(f"№8 = ΔДоходов / Дусредн × 100% = {d:,.0f} / {b:,.0f} × 100 = {val:.2f} %")
lines.append(f"Суммарный экономический ущерб от нарушения критических процессов: {d:,.0f} руб.")
lines.append(f"Доходы субъекта КИИ, усреднённые за 5 лет: {b:,.0f} руб.")
lines.append(f"№8 = ущерб / доходы за 5 лет × 100% = {d:,.0f} / {b:,.0f} × 100 = {val:.2f} %")
if val > 20:
cat = 'I'
elif val > 10:
@@ -3564,6 +3589,28 @@ class DokoGenApp:
entry.delete(0, tk.END)
entry.insert(0, data[data_keys])
# Показатель 8: доходы за 5 лет + суммарный ущерб от нарушения критических процессов
income_map = [
('income_year_1', ('incomeYear1', 'income_year_1')),
('income_year_2', ('incomeYear2', 'income_year_2')),
('income_year_3', ('incomeYear3', 'income_year_3')),
('income_year_4', ('incomeYear4', 'income_year_4')),
('income_year_5', ('incomeYear5', 'income_year_5')),
('income_loss', ('incomeLoss', 'income_loss')),
]
for entry_key, data_keys in income_map:
entry = self._company_entries.get(entry_key)
if not entry:
continue
val = None
for dk in data_keys:
if data.get(dk):
val = data[dk]
break
if val:
entry.delete(0, tk.END)
entry.insert(0, val)
# Наименование структурного подразделения по безопасности
if data.get('ispdnDepartment'):
self.model.security_department = data['ispdnDepartment']
+6
View File
@@ -61,6 +61,12 @@ VARIABLE_DEFS = [
('{{company_okved_extra}}', 'A', 'Дополнительные ОКВЭД', 'company:okved_extra'),
('{{company_profit}}', 'A', 'Сумма прибыли за предыдущий год (руб.)', 'company:profit'),
('{{company_profit_tax}}', 'A', 'Сумма налога с прибыли (руб.)', 'company:profit_tax'),
('{{company_income_year_1}}', 'A', 'Доход за 5 лет назад (руб.) — показатель 8', 'company:income_year_1'),
('{{company_income_year_2}}', 'A', 'Доход за 4 года назад (руб.) — показатель 8', 'company:income_year_2'),
('{{company_income_year_3}}', 'A', 'Доход за 3 года назад (руб.) — показатель 8', 'company:income_year_3'),
('{{company_income_year_4}}', 'A', 'Доход за 2 года назад (руб.) — показатель 8', 'company:income_year_4'),
('{{company_income_year_5}}', 'A', 'Доход за прошлый год (руб.) — показатель 8', 'company:income_year_5'),
('{{company_income_loss}}', 'A', 'Суммарный экономический ущерб от нарушения критических процессов (руб.) — показатель 8', 'company:income_loss'),
# === Комиссия ===
('{{commission_list}}', 'A', 'Список комиссии', 'commission_list'),