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
|
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):
|
def _import_187_common(wb, data, settings, log_fn):
|
||||||
"""Импорт общих сведений по словарю настроек.
|
"""Импорт общих сведений по словарю настроек.
|
||||||
|
|
||||||
@@ -228,6 +249,8 @@ def _import_187_common(wb, data, settings, log_fn):
|
|||||||
break
|
break
|
||||||
val = clean_value(cell_value(target_ws, coord))
|
val = clean_value(cell_value(target_ws, coord))
|
||||||
if val:
|
if val:
|
||||||
|
if key in ('chiefFio', 'responsibleFio', 'ispdnFio', 'adminFio'):
|
||||||
|
val = _extract_single_fio(val)
|
||||||
data[key] = val
|
data[key] = val
|
||||||
log_fn(f" {name} [ячейка {coord}]: {val}")
|
log_fn(f" {name} [ячейка {coord}]: {val}")
|
||||||
continue
|
continue
|
||||||
@@ -242,6 +265,8 @@ def _import_187_common(wb, data, settings, log_fn):
|
|||||||
for field_lower, val in row_cache.items():
|
for field_lower, val in row_cache.items():
|
||||||
if rx.search(field_lower):
|
if rx.search(field_lower):
|
||||||
if val:
|
if val:
|
||||||
|
if key in ('chiefFio', 'responsibleFio', 'ispdnFio', 'adminFio'):
|
||||||
|
val = _extract_single_fio(val)
|
||||||
data[key] = val
|
data[key] = val
|
||||||
log_fn(f" {name} [по ключу]: {val}")
|
log_fn(f" {name} [по ключу]: {val}")
|
||||||
break
|
break
|
||||||
@@ -619,7 +644,7 @@ def _import_187_employees(wb, data, settings, log_fn):
|
|||||||
commission.append({
|
commission.append({
|
||||||
'role': role,
|
'role': role,
|
||||||
'position': col_b,
|
'position': col_b,
|
||||||
'fio': col_c.replace('\n', ' '),
|
'fio': _extract_single_fio(col_c.replace('\n', ' ')),
|
||||||
})
|
})
|
||||||
|
|
||||||
if in_employees:
|
if in_employees:
|
||||||
@@ -628,7 +653,7 @@ def _import_187_employees(wb, data, settings, log_fn):
|
|||||||
continue
|
continue
|
||||||
employee = {
|
employee = {
|
||||||
'position': col_b,
|
'position': col_b,
|
||||||
'fio': fio.replace('\n', ' '),
|
'fio': _extract_single_fio(fio.replace('\n', ' ')),
|
||||||
}
|
}
|
||||||
if col_e:
|
if col_e:
|
||||||
employee['is_list'] = [s.strip() for s in col_e.split('\n') if s.strip()]
|
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
|
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
|
@dataclass
|
||||||
class CommissionMember:
|
class CommissionMember:
|
||||||
"""Член комиссии по категорированию объектов КИИ"""
|
"""Член комиссии по категорированию объектов КИИ"""
|
||||||
@@ -171,7 +186,13 @@ class Company:
|
|||||||
if "okved_extra" in d and not isinstance(d.get("okved_extra"), list):
|
if "okved_extra" in d and not isinstance(d.get("okved_extra"), list):
|
||||||
d["okved_extra"] = []
|
d["okved_extra"] = []
|
||||||
valid = {f.name for f in cls.__dataclass_fields__.values()}
|
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:
|
def get_folder_name(self) -> str:
|
||||||
if self.short_name:
|
if self.short_name:
|
||||||
|
|||||||
Reference in New Issue
Block a user