feat: группировка комиссии — председатель отдельно, члены без повтора роли

- Председатель/Секретарь/Заместитель — своей ролью
- Первый обычный член получает «Члены комиссии», остальные — пустая роль
- Пустая строка в цикле больше не превращается в «—»
Проверено: 1 председатель + 4 члена в шаблоне «6. Акт...»
This commit is contained in:
2026-08-03 10:34:05 +04:00
parent 65480ea5ed
commit f5e9d3523d
2 changed files with 44 additions and 9 deletions
+1 -1
View File
@@ -235,7 +235,7 @@ def expand_loops_in_zip(docx_path: str, loops: Dict[str, List[Dict]]) -> str:
for idx, item in enumerate(items, 1): for idx, item in enumerate(items, 1):
clone = template_clean clone = template_clean
for field, value in item.items(): for field, value in item.items():
val_str = str(value) if value else '' val_str = str(value) if value else ('' if value is None else '')
# С префиксом item. # С префиксом item.
clone = clone.replace('{{item.%s}}' % field, val_str) clone = clone.replace('{{item.%s}}' % field, val_str)
# Без префикса (алиасы {{name}}, {{pd_list}}, {{document}} и т.д.) # Без префикса (алиасы {{name}}, {{pd_list}}, {{document}} и т.д.)
+43 -8
View File
@@ -165,14 +165,42 @@ def build_replacements(
return replacements return replacements
def _commission_role_display(members) -> List[str]:
"""Группирует роли комиссии для вывода:
- Председатель/Секретарь/Заместитель — отдельной строкой со своей ролью;
- обычные члены — первый получает «Члены комиссии», остальные — пустую роль
(чтобы не повторять «Член комиссии» в каждой строке)."""
result = []
member_used = False
for m in members:
role = (m.role or 'член комиссии').strip()
role_lower = role.lower()
if ('председател' in role_lower or 'секретар' in role_lower
or 'заместител' in role_lower or 'зам. председателя' in role_lower):
result.append(role)
continue
# обычный член комиссии
if not member_used:
result.append('Члены комиссии')
member_used = True
else:
result.append('')
return result
def _build_commission_data(company: Company) -> Dict[str, str]: def _build_commission_data(company: Company) -> Dict[str, str]:
data = {} data = {}
members = company.commission or [] members = company.commission or []
display_roles = _commission_role_display(members)
lines = [] lines = []
for i, m in enumerate(members, 1): for i, (m, role_disp) in enumerate(zip(members, display_roles), 1):
role = m.role or 'член комиссии' if role_disp:
line = f"{i}. {role}: {m.position}{m.fio}" if m.position else f"{i}. {role}: {m.fio}" line = (f"{i}. {role_disp}: {m.position}{m.fio}" if m.position
else f"{i}. {role_disp}: {m.fio}")
else:
line = (f"{i}. {m.position}{m.fio}" if m.position
else f"{i}. {m.fio}")
lines.append(line) lines.append(line)
data['commission_list'] = '\n'.join(lines) if lines else '' data['commission_list'] = '\n'.join(lines) if lines else ''
@@ -202,13 +230,20 @@ def _build_loop_data(company: Company, is_list: List) -> Dict[str, List[Dict]]:
# Комиссия # Комиссия
members = company.commission or [] members = company.commission or []
if members: if members:
display_roles = _commission_role_display(members)
items = [] items = []
for m in members: for m, role_disp in zip(members, display_roles):
pos = m.position or ''
fio = m.fio or ''
if role_disp:
full = f"{role_disp} {pos}{fio}" if pos != '' else f"{role_disp}{fio}"
else:
full = f"{pos}{fio}" if pos != '' else fio
items.append({ items.append({
'role': m.role or 'член комиссии', 'role': role_disp,
'position': m.position or '', 'position': pos,
'fio': m.fio or '', 'fio': fio,
'full': f"{m.role} {m.position}{m.fio}" if m.position else f"{m.role}{m.fio}", 'full': full,
}) })
loops['commission'] = items loops['commission'] = items