Раздел 9 опросника «Значения для расчета критериев значимости»: общие поля + блоки по сферам
- Опросный_лист_187_ФЗ.xlsx: добавлен раздел 9 (общие: доход за 5 лет, прибыль, налог; сферные блоки: здравоохранение, наука, связь, транспорт, банки, ТЭК/энергетика, ОПК) - import_settings.json: keywords прибыли/налога под новые формулировки, поле income_5y, секции sphere_fields и sphere_headers - importer.py: _import_187_criteria9() — сбор сферных блоков в data['sphereInput'] и вливание в criterion_input объектов по сфере; фикс поиска по ключам (пустое первое совпадение → ищем дальше)
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -140,16 +140,16 @@
|
||||
"keywords": "право владения зданием"
|
||||
},
|
||||
{
|
||||
"name": "Сумма прибыли за год",
|
||||
"name": "Прибыль организации за прошлый год",
|
||||
"var": "profit",
|
||||
"cell": "",
|
||||
"keywords": "сумма прибыли"
|
||||
"keywords": "сумма прибыли|прибыль организации|прибыль за прошлый год"
|
||||
},
|
||||
{
|
||||
"name": "Сумма налога с прибыли",
|
||||
"name": "Налог на прибыль за прошлый год",
|
||||
"var": "profitTax",
|
||||
"cell": "",
|
||||
"keywords": "сумма налога с прибыли"
|
||||
"keywords": "сумма налога с прибыли|налог на прибыль"
|
||||
},
|
||||
{
|
||||
"name": "Доменное имя и внешний IP",
|
||||
@@ -318,6 +318,12 @@
|
||||
"var": "physicalVisitorLog",
|
||||
"cell": "",
|
||||
"keywords": "журнал учета посетителей|журнал учёта посетителей"
|
||||
},
|
||||
{
|
||||
"name": "Суммарный доход (выручка) за 5 лет",
|
||||
"var": "income_5y",
|
||||
"cell": "",
|
||||
"keywords": "суммарный доход|доход.*5 лет|выручка.*5 лет"
|
||||
}
|
||||
],
|
||||
"criterion_fields": [
|
||||
@@ -441,5 +447,155 @@
|
||||
"keywords": "кооперации головного исполнителя|статусу в кооперации",
|
||||
"unit": "вариант"
|
||||
}
|
||||
],
|
||||
"sphere_fields": {
|
||||
"Здравоохранение": [
|
||||
{
|
||||
"keywords": "специализированную или скорую",
|
||||
"key": "health_emergency"
|
||||
},
|
||||
{
|
||||
"keywords": "аптечная сеть с выручкой от 5 млрд",
|
||||
"key": "health_pharmacy"
|
||||
},
|
||||
{
|
||||
"keywords": "штат от 250",
|
||||
"key": "health_staff"
|
||||
},
|
||||
{
|
||||
"keywords": "времени нужно на устранение последствий сбоя",
|
||||
"key": "8_t"
|
||||
}
|
||||
],
|
||||
"Наука": [
|
||||
{
|
||||
"keywords": "проводите ли нир",
|
||||
"key": "science_niokr"
|
||||
},
|
||||
{
|
||||
"keywords": "вредные вещества при исследованиях",
|
||||
"key": "science_hazard"
|
||||
},
|
||||
{
|
||||
"keywords": "международным договорам",
|
||||
"key": "7"
|
||||
},
|
||||
{
|
||||
"keywords": "рамках гоз",
|
||||
"key": "science_goz"
|
||||
}
|
||||
],
|
||||
"Связь": [
|
||||
{
|
||||
"keywords": "абонентам станут недоступны",
|
||||
"key": "4а"
|
||||
},
|
||||
{
|
||||
"keywords": "органа власти вы обеспечиваете",
|
||||
"key": "4б"
|
||||
}
|
||||
],
|
||||
"Транспорт": [
|
||||
{
|
||||
"keywords": "территории нарушится сообщение",
|
||||
"key": "3а"
|
||||
},
|
||||
{
|
||||
"keywords": "без транспортных услуг",
|
||||
"key": "3б"
|
||||
},
|
||||
{
|
||||
"keywords": "перевозки выполняете",
|
||||
"key": "3в"
|
||||
},
|
||||
{
|
||||
"keywords": "категория у объекта транспортной",
|
||||
"key": "3г"
|
||||
},
|
||||
{
|
||||
"keywords": "времени нужно на устранение последствий сбоя",
|
||||
"key": "8_t"
|
||||
},
|
||||
{
|
||||
"keywords": "полностью недоступен",
|
||||
"key": "hours_down"
|
||||
}
|
||||
],
|
||||
"Банковская сфера и финансовый рынок": [
|
||||
{
|
||||
"keywords": "типу относится организация",
|
||||
"key": "10_type"
|
||||
},
|
||||
{
|
||||
"keywords": "объём активов или операций",
|
||||
"key": "10_value"
|
||||
}
|
||||
],
|
||||
"Топливно-энергетический комплекс": [
|
||||
{
|
||||
"keywords": "масштабе возможны последствия",
|
||||
"key": "2а"
|
||||
},
|
||||
{
|
||||
"keywords": "человек могут пострадать",
|
||||
"key": "1"
|
||||
},
|
||||
{
|
||||
"keywords": "вредное воздействие на окружающую среду",
|
||||
"key": "11б"
|
||||
},
|
||||
{
|
||||
"keywords": "выполняете ли гоз",
|
||||
"key": "goz_flag"
|
||||
}
|
||||
],
|
||||
"Оборонная промышленность": [
|
||||
{
|
||||
"keywords": "компенсации пострадавшим",
|
||||
"key": "8_a"
|
||||
},
|
||||
{
|
||||
"keywords": "компьютерные инциденты",
|
||||
"key": "8_x"
|
||||
},
|
||||
{
|
||||
"keywords": "может выпустить максимум",
|
||||
"key": "13a_vmax"
|
||||
},
|
||||
{
|
||||
"keywords": "успеет выпустить объект, пока устраняют",
|
||||
"key": "13a_vinc"
|
||||
},
|
||||
{
|
||||
"keywords": "полный объём продукции требуется",
|
||||
"key": "13a_vgoz"
|
||||
},
|
||||
{
|
||||
"keywords": "выпуск единицы продукции в обычном режиме",
|
||||
"key": "13b_tnorm"
|
||||
},
|
||||
{
|
||||
"keywords": "выпуск единицы продукции при сбое",
|
||||
"key": "13b_tnonorm"
|
||||
},
|
||||
{
|
||||
"keywords": "декларация промышленной безопасности",
|
||||
"key": "8_decl"
|
||||
},
|
||||
{
|
||||
"keywords": "перечень стратегических предприятий",
|
||||
"key": "8_strategic"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sphere_headers": {
|
||||
"здравоохранен": "Здравоохранение",
|
||||
"наука": "Наука",
|
||||
"связи": "Связь",
|
||||
"транспорта": "Транспорт",
|
||||
"банковская": "Банковская сфера и финансовый рынок",
|
||||
"тэк": "Топливно-энергетический комплекс",
|
||||
"энергетик": "Топливно-энергетический комплекс",
|
||||
"опк": "Оборонная промышленность"
|
||||
}
|
||||
}
|
||||
+93
-1
@@ -168,6 +168,9 @@ def import_187fz(filepath: str, log_fn: Optional[Callable] = None, settings_path
|
||||
_import_187_common(wb, data, settings, log_fn)
|
||||
_import_187_is_list(wb, data, settings, log_fn)
|
||||
_import_187_employees(wb, data, settings, log_fn)
|
||||
# Раздел 9 «Значения для расчета критериев значимости» — после импорта объектов,
|
||||
# чтобы сферные значения влились в criterion_input уже созданных объектов.
|
||||
_import_187_criteria9(wb, data, settings, log_fn)
|
||||
except Exception as e:
|
||||
log_fn(f"❌ Ошибка при импорте: {e}")
|
||||
log_fn(traceback.format_exc())
|
||||
@@ -290,7 +293,10 @@ def _import_187_common(wb, data, settings, log_fn):
|
||||
if rx:
|
||||
for field_lower, val in row_cache.items():
|
||||
if rx.search(field_lower):
|
||||
if val:
|
||||
if not val:
|
||||
# Пустое значение в первой строке-совпадении — ищем дальше
|
||||
# (старый вопрос пуст, а новый раздел 9 заполнен).
|
||||
continue
|
||||
if key in ('chiefFio', 'responsibleFio', 'ispdnFio', 'adminFio'):
|
||||
val = _extract_single_fio(val)
|
||||
elif 'дата' in name.lower() or 'date' in key.lower():
|
||||
@@ -300,6 +306,92 @@ def _import_187_common(wb, data, settings, log_fn):
|
||||
break
|
||||
|
||||
|
||||
def _import_187_criteria9(wb, data, settings, log_fn):
|
||||
"""Импорт раздела 9 «Значения для расчета критериев значимости» (лист «Общие сведения»).
|
||||
|
||||
Общие для всех сфер поля (суммарный доход за 5 лет, прибыль, налог на прибыль)
|
||||
подхватываются штатным поиском по keywords (fields). Здесь собираются сферные блоки:
|
||||
для каждого блока «СФЕРА …» значения вопросов сохраняются в
|
||||
data['sphereInput'][сфера][ключ] = значение, где ключ — из settings['sphere_fields'].
|
||||
При импорте объектов значения вливаются в criterion_input объекта с той же сферой.
|
||||
"""
|
||||
sphere_fields = settings.get('sphere_fields', {}) or {}
|
||||
sphere_headers = settings.get('sphere_headers', {}) or {}
|
||||
if not sphere_fields:
|
||||
return
|
||||
|
||||
sheet_name = None
|
||||
sheet_kw = settings.get('common_sheet_keyword', 'общие')
|
||||
for sn in wb.sheetnames:
|
||||
if sheet_kw in sn.lower():
|
||||
sheet_name = sn
|
||||
break
|
||||
if not sheet_name:
|
||||
return
|
||||
ws = wb[sheet_name]
|
||||
value_col = int(settings.get('value_column', 1))
|
||||
|
||||
sphere_input = {}
|
||||
current_sphere = None
|
||||
started = False
|
||||
for row in ws.iter_rows(min_row=1, values_only=True):
|
||||
field_raw = clean_value(row[0]) if row[0] is not None else ''
|
||||
if not field_raw:
|
||||
continue
|
||||
field_lower = field_raw.strip().lower()
|
||||
# начало раздела 9
|
||||
if '9. значения' in field_lower or 'значения для расчета критериев значимости' in field_lower:
|
||||
started = True
|
||||
continue
|
||||
if not started:
|
||||
continue
|
||||
# заголовок «ОБЩИЕ для всех сфер» — общие поля уже через fields, сферу сбрасываем
|
||||
if 'общие для всех сфер' in field_lower:
|
||||
current_sphere = None
|
||||
continue
|
||||
# заголовок сферы: «СФЕРА ЗДРАВООХРАНЕНИЯ», «БАНКОВСКАЯ СФЕРА»
|
||||
if 'сфера' in field_lower or 'банковская' in field_lower:
|
||||
matched = None
|
||||
for kw, canon in sphere_headers.items():
|
||||
if kw in field_lower:
|
||||
matched = canon
|
||||
break
|
||||
if matched:
|
||||
current_sphere = matched
|
||||
sphere_input.setdefault(current_sphere, {})
|
||||
continue
|
||||
if current_sphere is None:
|
||||
continue
|
||||
val = clean_value(row[value_col]) if len(row) > value_col else ''
|
||||
if not val:
|
||||
continue
|
||||
for rule in sphere_fields.get(current_sphere, []):
|
||||
kws = rule.get('keywords', '')
|
||||
if not kws:
|
||||
continue
|
||||
try:
|
||||
rx = re.compile(kws, re.IGNORECASE)
|
||||
except re.error:
|
||||
continue
|
||||
if rx.search(field_lower):
|
||||
key = rule.get('key', '')
|
||||
sphere_input[current_sphere][key] = str(val).strip()
|
||||
log_fn(f" [сфера {current_sphere}] {key}: {str(val)[:60]}")
|
||||
break
|
||||
|
||||
if sphere_input:
|
||||
data['sphereInput'] = sphere_input
|
||||
|
||||
# Вливаем сферные значения в criterion_input объектов с той же сферой
|
||||
for is_obj in data.get('informationSystems', []):
|
||||
obj_sphere = (is_obj.get('sphere') or '').strip()
|
||||
if not obj_sphere or obj_sphere not in sphere_input:
|
||||
continue
|
||||
ci = is_obj.setdefault('criterion_input', {})
|
||||
for k, v in sphere_input[obj_sphere].items():
|
||||
ci.setdefault(k, v)
|
||||
|
||||
|
||||
def _import_187_is_list(wb, data, settings, log_fn):
|
||||
"""Импорт объектов КИИ из остальных листов (ОБЪЕКТ №1, №2, ...).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user