fix: ОКВЭД импорт/DaData/словарь+интернет, доменное имя, вкладка ОКИИ → вложенные вкладки, словарики, СЗИ разбивка, адрес отдельно

- ОКВЭД: resolve_okved (словарь okved.json + DaData suggest okved2), применяется при импорте и DaData; галочки «ОКВЭД осн./доп.» в «что применять»
- DaData: показ и подстановка доп. ОКВЭД
- доменное имя: поле во вкладке «Организация» + импорт
- вкладка «Объекты КИИ»: сверху Наименование/Описание/Категория, остальное вкладками: Основное (назначение, сфера, тип, архитектура, типовой отраслевой объект — со словариками и выпадающими списками), Субъект, Сети и ПО, Безопасность (236), СЗИ, Пользователи ОКИИ
- новые словари: spheres.json, object_types.json, architectures.json, typical_objects.json
- адрес объекта — в отдельное поле (не в описание)
- СЗИ: разбивка слипшихся названий (Kaspersky...)
This commit is contained in:
2026-08-04 15:33:36 +04:00
parent 2037925986
commit ed71343d92
7 changed files with 237 additions and 68 deletions
+28 -2
View File
@@ -279,7 +279,7 @@ def _import_187_is_list(wb, data, settings, log_fn):
continue
is_obj = {
'name': '', 'description': '', 'usersList': [],
'name': '', 'description': '', 'address': '', 'usersList': [],
'isInternet': False, 'defense_tools': [], 'software': '',
# 236 приказ
'sphere': '', 'purpose': '', 'object_type': '', 'architecture': '',
@@ -315,6 +315,25 @@ def _import_187_is_list(wb, data, settings, log_fn):
return True
return False
def _split_entries(text):
"""Разбивает слипшиеся названия СЗИ: по переносам строк, ';' и по границе
'цифра + заглавная буква' (напр. '15.1.0.22239Kaspersky' → два названия)."""
if not text:
return []
parts = re.split(r'[\n;]+', text)
out = []
for p in parts:
p = p.strip()
if not p:
continue
# граница: цифра/точка → заглавная буква без пробела
sub = re.split(r'(?<=[0-9.])(?=[А-ЯЁA-Z])', p)
for s in sub:
s = s.strip()
if s and s not in out:
out.append(s)
return out
for vals in rows:
field = (vals[0] or '').strip()
field_lower = field.lower()
@@ -326,6 +345,11 @@ def _import_187_is_list(wb, data, settings, log_fn):
is_obj['name'] = val_b
log_fn(f" Объект КИИ: {val_b}")
continue
# --- Адрес размещения объекта (в отдельное поле, не в описание) ---
if 'адрес размещения' in field_lower or 'адрес расположения' in field_lower or 'местонахождение объекта' in field_lower:
is_obj['address'] = val_b
log_fn(f" Адрес объекта: {val_b[:60]}")
continue
# --- Описание ---
if 'описание окки' in field_lower or 'описание объекта' in field_lower:
if val_b:
@@ -458,7 +482,9 @@ def _import_187_is_list(wb, data, settings, log_fn):
for kw, label in defense_keywords.items():
if re.search(kw, field_lower):
if val_b and 'выбрать' not in field_lower:
is_obj['defense_tools'].append(val_b)
for tool in _split_entries(val_b):
if tool not in is_obj['defense_tools']:
is_obj['defense_tools'].append(tool)
matched = True
break
if matched: