Раздел 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:
+99
-7
@@ -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,16 +293,105 @@ 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 key in ('chiefFio', 'responsibleFio', 'ispdnFio', 'adminFio'):
|
||||
val = _extract_single_fio(val)
|
||||
elif 'дата' in name.lower() or 'date' in key.lower():
|
||||
val = clean_value(val, as_date=True)
|
||||
data[key] = val
|
||||
log_fn(f" {name} [по ключу]: {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():
|
||||
val = clean_value(val, as_date=True)
|
||||
data[key] = val
|
||||
log_fn(f" {name} [по ключу]: {val}")
|
||||
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