fix: импорт одного человека в поле ФИО (старые опросники)
- если в ячейке ФИО несколько человек (через запятую/точку с запятой/ перевод строки или просто подряд) — остаётся первое полное ФИО - применяется к должностным лицам (chief/ответственный/админ), комиссии и сотрудникам при импорте из опросника - то же при открытии сохранённого файла (from_dict): «Коростелев Павел Сергеевич Хрящев Сергей Владимирович …» → «Коростелев Павел Сергеевич»
This commit is contained in:
+27
-2
@@ -179,6 +179,27 @@ def import_187fz(filepath: str, log_fn: Optional[Callable] = None, settings_path
|
||||
return data
|
||||
|
||||
|
||||
def _extract_single_fio(text):
|
||||
"""Из строки, где может быть несколько ФИО (через запятую, точку с запятой,
|
||||
перевод строки или просто подряд), выделяет одно первое полное ФИО.
|
||||
|
||||
Пример: «Коростелев Павел Сергеевич Хрящев Сергей Владимирович …» → «Коростелев Павел Сергеевич»
|
||||
"""
|
||||
if not text:
|
||||
return text
|
||||
text = str(text).strip()
|
||||
# 1) Явные разделители — берём первую часть
|
||||
for sep in (',', ';', '\n', '\r'):
|
||||
if sep in text:
|
||||
text = text.split(sep)[0].strip()
|
||||
break
|
||||
# 2) Если осталось больше 3 слов — это несколько ФИО подряд, оставляем первые 3
|
||||
words = [w for w in text.split() if w]
|
||||
if len(words) > 3:
|
||||
text = ' '.join(words[:3])
|
||||
return text.strip()
|
||||
|
||||
|
||||
def _import_187_common(wb, data, settings, log_fn):
|
||||
"""Импорт общих сведений по словарю настроек.
|
||||
|
||||
@@ -228,6 +249,8 @@ def _import_187_common(wb, data, settings, log_fn):
|
||||
break
|
||||
val = clean_value(cell_value(target_ws, coord))
|
||||
if val:
|
||||
if key in ('chiefFio', 'responsibleFio', 'ispdnFio', 'adminFio'):
|
||||
val = _extract_single_fio(val)
|
||||
data[key] = val
|
||||
log_fn(f" {name} [ячейка {coord}]: {val}")
|
||||
continue
|
||||
@@ -242,6 +265,8 @@ def _import_187_common(wb, data, settings, log_fn):
|
||||
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)
|
||||
data[key] = val
|
||||
log_fn(f" {name} [по ключу]: {val}")
|
||||
break
|
||||
@@ -619,7 +644,7 @@ def _import_187_employees(wb, data, settings, log_fn):
|
||||
commission.append({
|
||||
'role': role,
|
||||
'position': col_b,
|
||||
'fio': col_c.replace('\n', ' '),
|
||||
'fio': _extract_single_fio(col_c.replace('\n', ' ')),
|
||||
})
|
||||
|
||||
if in_employees:
|
||||
@@ -628,7 +653,7 @@ def _import_187_employees(wb, data, settings, log_fn):
|
||||
continue
|
||||
employee = {
|
||||
'position': col_b,
|
||||
'fio': fio.replace('\n', ' '),
|
||||
'fio': _extract_single_fio(fio.replace('\n', ' ')),
|
||||
}
|
||||
if col_e:
|
||||
employee['is_list'] = [s.strip() for s in col_e.split('\n') if s.strip()]
|
||||
|
||||
+22
-1
@@ -5,6 +5,21 @@ from dataclasses import dataclass, field, asdict
|
||||
from typing import List, Dict, Any
|
||||
|
||||
|
||||
def _clean_single_fio(value):
|
||||
"""Оставить одно первое ФИО, если в строке их несколько."""
|
||||
if not value:
|
||||
return value
|
||||
value = str(value).strip()
|
||||
for sep in (',', ';', '\n', '\r'):
|
||||
if sep in value:
|
||||
value = value.split(sep)[0].strip()
|
||||
break
|
||||
words = [w for w in value.split() if w]
|
||||
if len(words) > 3:
|
||||
value = ' '.join(words[:3])
|
||||
return value.strip()
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommissionMember:
|
||||
"""Член комиссии по категорированию объектов КИИ"""
|
||||
@@ -171,7 +186,13 @@ class Company:
|
||||
if "okved_extra" in d and not isinstance(d.get("okved_extra"), list):
|
||||
d["okved_extra"] = []
|
||||
valid = {f.name for f in cls.__dataclass_fields__.values()}
|
||||
return cls(**{k: v for k, v in d.items() if k in valid})
|
||||
obj = cls(**{k: v for k, v in d.items() if k in valid})
|
||||
# Если в поле ФИО несколько человек — оставить одного (старые опросники)
|
||||
for fio_field in ('chief_fio', 'responsible_fio', 'admin_fio'):
|
||||
val = getattr(obj, fio_field, '')
|
||||
if val:
|
||||
setattr(obj, fio_field, _clean_single_fio(val))
|
||||
return obj
|
||||
|
||||
def get_folder_name(self) -> str:
|
||||
if self.short_name:
|
||||
|
||||
Reference in New Issue
Block a user