feat: финансовые показатели организации + балансовая стоимость объекта

- модели: Company.profit (сумма прибыли), Company.profit_tax (налог с прибыли),
  InformationSystem.balance_value (балансовая стоимость объекта КИИ)
- импорт из опросника: «Сумма прибыли за предыдущий год» и «Сумма налога с прибыли»
  (Общие сведения) → profit/profitTax; «Балансовая стоимость объекта КИИ в рублях»
  (каждый ОБЪЕКТ-лист) → balanceValue, больше не падает в описание
- UI: блок «Финансовые показатели» во вкладке «Организация»; поле
  «Балансовая стоимость (руб.)» в объекте КИИ; маппинги collect/select/copy/import
- генератор: {{company_profit}}, {{company_profit_tax}}, {{item.balance_value}}
This commit is contained in:
2026-08-04 19:17:37 +04:00
parent 58b4402d31
commit b044b05eaf
4 changed files with 48 additions and 1 deletions
+5 -1
View File
@@ -554,7 +554,11 @@ def _import_187_is_list(wb, data, settings, log_fn):
if matched:
continue
if val_b and 'выбрать' not in field_lower and field_lower not in ('значение', 'примечание'):
# Остальные заполненные поля — в описание (адрес, балансовая стоимость и т.д.)
# Балансовая стоимость объекта КИИ — в отдельное поле
if 'балансовая стоимость' in field_lower or 'стоимость объекта' in field_lower:
is_obj['balanceValue'] = val_b
continue
# Остальные заполненные поля — в описание (адрес и т.д.)
if not is_obj['description']:
is_obj['description'] = f"{field}: {val_b}"
else:
+7
View File
@@ -66,6 +66,9 @@ class InformationSystem:
os_sw: str = "" # Общесистемное ПО (ОС, средства виртуализации)
app_sw: str = "" # Прикладные программы
# Балансовая стоимость объекта КИИ (опросник)
balance_value: str = "" # Балансовая стоимость объекта КИИ в рублях
# Безопасность (236 приказ)
attacker_category: str = "" # Категория нарушителя (внешний/внутренний)
threats: str = "" # Основные угрозы безопасности информации (\n — разделитель)
@@ -120,6 +123,10 @@ class Company:
contract_number: str = ""
contract_date: str = ""
# Финансовые показатели организации (опросник)
profit: str = "" # Сумма прибыли за предыдущий год
profit_tax: str = "" # Сумма налога с прибыли за предыдущий год
# Списки
commission: List[CommissionMember] = field(default_factory=list)
information_systems: List[InformationSystem] = field(default_factory=list)
+33
View File
@@ -326,6 +326,20 @@ class DokoGenApp:
ttk.Entry(f4, textvariable=self.doc_date_var, width=25).grid(
row=1, column=1, padx=10, sticky=tk.W)
# --- Финансовые показатели (опросник) ---
f_fin = ttk.LabelFrame(left, text="Финансовые показатели", padding=10)
f_fin.pack(fill=tk.X, pady=5)
fin_fields = [
("Сумма прибыли за предыдущий год (руб.):", "profit"),
("Сумма налога с прибыли (руб.):", "profit_tax"),
]
for i, (label, key) in enumerate(fin_fields):
ttk.Label(f_fin, text=label).grid(row=i, column=0, sticky=tk.W, pady=2)
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
f_fin.columnconfigure(1, weight=1)
# --- Правая панель: проверка данных ---
right = ttk.LabelFrame(main, text="Проверка данных", padding=10)
right.pack(side=tk.RIGHT, fill=tk.Y, padx=(10, 0))
@@ -776,6 +790,11 @@ class DokoGenApp:
ttk.Radiobutton(cat_frame, text=val, variable=self.is_category_var,
value=val).pack(side=tk.LEFT, padx=3)
ttk.Label(fields_frame, text="Балансовая стоимость (руб.):").grid(
row=3, column=0, sticky=tk.W, pady=2)
self.is_balance_entry = ttk.Entry(fields_frame, width=60)
self.is_balance_entry.grid(row=3, column=1, padx=10, sticky=tk.EW, pady=2)
fields_frame.columnconfigure(1, weight=1)
# ---- Вложенные вкладки ----
@@ -1282,6 +1301,8 @@ class DokoGenApp:
if hasattr(self, 'is_software_entry'):
isys.software = self.is_software_entry.get().strip()
isys.category = self.is_category_var.get()
if hasattr(self, 'is_balance_entry'):
isys.balance_value = self.is_balance_entry.get().strip()
# Поля 236 приказа
for attr, model_field in [
('is_purpose_entry', 'purpose'),
@@ -1515,6 +1536,9 @@ class DokoGenApp:
self.is_software_entry.delete(0, tk.END)
self.is_software_entry.insert(0, isys.software or "")
self.is_category_var.set(isys.category or "без категории")
if hasattr(self, 'is_balance_entry'):
self.is_balance_entry.delete(0, tk.END)
self.is_balance_entry.insert(0, isys.balance_value or "")
# Поля 236 приказа
for attr, model_field in [
@@ -1610,6 +1634,7 @@ class DokoGenApp:
hw_sw=src.hw_sw,
os_sw=src.os_sw,
app_sw=src.app_sw,
balance_value=src.balance_value,
attacker_category=src.attacker_category,
threats=src.threats,
incidents=src.incidents,
@@ -2694,6 +2719,13 @@ class DokoGenApp:
if data.get('contractDate'):
self.doc_date_var.set(data['contractDate'])
# Финансовые показатели (прибыль, налог)
for entry_key, data_keys in [('profit', 'profit'), ('profit_tax', 'profitTax')]:
entry = self._company_entries.get(entry_key)
if entry and data.get(data_keys):
entry.delete(0, tk.END)
entry.insert(0, data[data_keys])
# Наименование структурного подразделения по безопасности
if data.get('ispdnDepartment'):
self.model.security_department = data['ispdnDepartment']
@@ -2767,6 +2799,7 @@ class DokoGenApp:
hw_sw=is_data.get('hw_sw', ''),
os_sw=is_data.get('os_sw', ''),
app_sw=is_data.get('app_sw', ''),
balance_value=is_data.get('balanceValue', is_data.get('balance_value', '')),
attacker_category=is_data.get('attacker_category', ''),
threats=is_data.get('threats', ''),
incidents=is_data.get('incidents', ''),
+3
View File
@@ -59,6 +59,8 @@ VARIABLE_DEFS = [
('{{security_department}}', 'A', 'Наименование структурного подразделения по безопасности', 'company:security_department'),
('{{company_okved}}', 'A', 'Основной ОКВЭД', 'company:okved'),
('{{company_okved_extra}}', 'A', 'Дополнительные ОКВЭД', 'company:okved_extra'),
('{{company_profit}}', 'A', 'Сумма прибыли за предыдущий год (руб.)', 'company:profit'),
('{{company_profit_tax}}', 'A', 'Сумма налога с прибыли (руб.)', 'company:profit_tax'),
# === Комиссия ===
('{{commission_list}}', 'A', 'Список комиссии', 'commission_list'),
@@ -323,6 +325,7 @@ def _build_loop_data(company: Company, is_list: List) -> Dict[str, List[Dict]]:
'hw_sw': getattr(isys, 'hw_sw', '') or '',
'os_sw': getattr(isys, 'os_sw', '') or '',
'app_sw': getattr(isys, 'app_sw', '') or '',
'balance_value': getattr(isys, 'balance_value', '') or '',
'attacker_category': getattr(isys, 'attacker_category', '') or '',
'threats': getattr(isys, 'threats', '') or '',
'incidents': getattr(isys, 'incidents', '') or '',