From 92cca3b8b1592c94e731db20ca142711d41c8cff Mon Sep 17 00:00:00 2001 From: DokoGen Date: Thu, 30 Jul 2026 15:18:26 +0400 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BC=D0=B0=D0=BF=D0=BF=D0=B8=D0=BD=D0=B3?= =?UTF-8?q?=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D1=81=D1=82=D0=B0=D1=80=D1=8B?= =?UTF-8?q?=D1=85=20<...>=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20+=20=D1=80=D0=B5=D0=B7=D0=BE=D0=BB=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=20=D0=B4=D0=BB=D1=8F=20is:/commission=5Fmember?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dokogen/variables.py | 90 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/dokogen/variables.py b/dokogen/variables.py index e7d7d0a..53d97d2 100644 --- a/dokogen/variables.py +++ b/dokogen/variables.py @@ -62,6 +62,28 @@ VARIABLE_DEFS = [ # === 152-ФЗ === ('{{is_security_requirements}}', 'B', 'Требования уровня защищённости', 'security_reqs'), + ('{{is_list}}', 'B', 'Список всех ИС (нумерованный)', 'is_list'), + ('{{is_name}}', 'B', 'Наименование первой ИС', 'is:name'), + ('{{name}}', 'B', 'Название ИС (алиас)', 'is:name'), + ('{{description}}', 'B', 'Описание ИС (алиас)', 'is:description'), + ('{{category}}', 'B', 'Категория ИС (алиас)', 'is:category'), + ('{{number}}', 'B', 'Номер (алиас)', 'doc_number'), + ('{{pd_count}}', 'B', 'Количество записей ПДн (алиас)', 'is:pd_count'), + ('{{pd_list}}', 'B', 'Список ПДн (алиас)', 'is:pd_list'), + ('{{pd_subjects}}', 'B', 'Субъекты ПДн (алиас)', 'is:pd_subjects'), + ('{{threat_type}}', 'B', 'Тип угроз (алиас)', 'is:threat_type'), + ('{{users}}', 'B', 'Пользователи ИС (алиас)', 'is:users'), + ('{{defence_level}}', 'B', 'Уровень защищённости (алиас)', 'is:defence_level'), + ('{{full_name_genitive}}', 'A', 'Полное наименование (род.п., алиас)', 'decl:full_name:gent'), + ('{{document}}', 'A', 'Название бумажного документа (алиас)', 'company:paper_documents'), + ('{{storage}}', 'A', 'Место хранения (алиас)', 'company:paper_storage'), + ('{{responsible_fio_accs}}', 'A', 'ФИО ответственного (вин.п.)', 'fio_acl:responsible'), + ('{{commission1}}', 'A', 'Должность члена комиссии 1', 'commission_member:0:position'), + ('{{commission1_fio}}', 'A', 'ФИО члена комиссии 1', 'commission_member:0:fio'), + ('{{commission2}}', 'A', 'Должность члена комиссии 2', 'commission_member:1:position'), + ('{{commission2_fio}}', 'A', 'ФИО члена комиссии 2', 'commission_member:1:fio'), + ('{{commission3}}', 'A', 'Должность члена комиссии 3', 'commission_member:2:position'), + ('{{commission3_fio}}', 'A', 'ФИО члена комиссии 3', 'commission_member:2:fio'), ] # Маппинг старых переменных <...> → {{...}} @@ -93,6 +115,26 @@ OLD_VAR_MAP = { '': '{{document_date}}', '': '{{date}}', '': '{{document_date}}', + # Недостающие маппинги из лога + '': '{{company_short_name_genitive}}', + '': '{{company_short_name_dative}}', + '': '{{company_short_name_accs}}', + '': '{{company_short_name_ablt}}', + '': '{{company_short_name_loct}}', + '': '{{company_full_name_dative}}', + '': '{{company_full_name_accs}}', + '': '{{commission1}}', + '': '{{commission1_fio}}', + '': '{{commission2}}', + '': '{{commission2_fio}}', + '': '{{commission3}}', + '': '{{commission3_fio}}', + '': '{{is_name}}', + '': '{{admin_position}}', + # Исключаем клавиши клавиатуры из проверки + '': 'Alt', + '': 'Ctrl', + '': 'Del', } VAR_PATTERN = re.compile(r'\{\{[^}]+\}\}') @@ -291,6 +333,54 @@ def _resolve(source: str, ctx: Dict) -> str: if source == 'security_reqs': return _get_security_text(ctx) + # IS-алиасы (первая ИС) + if source.startswith('is:'): + field = source[3:] + if is_list: + first = is_list[0] + field_map = { + 'name': 'name', + 'description': 'description', + 'category': 'category', + 'defence_level': 'defence_level', + 'threat_type': 'threat_type', + 'pd_list': lambda: ', '.join(first.personal_data_list or []), + 'pd_count': 'pd_count', + 'pd_subjects': lambda: '; '.join(first.pd_subjects_list or []), + 'users': lambda: ', '.join(first.users_list or []), + } + if field in field_map: + val = field_map[field] + if callable(val): + return val() or '—' + return str(getattr(first, val, '') or '—') if isinstance(val, str) else '—' + return '—' + + # Список ИС + if source == 'is_list': + if is_list: + return '\n'.join(f"{i}. {isys.name}" for i, isys in enumerate(is_list, 1)) + return '—' + if source == 'is_list_comma': + if is_list: + return ', '.join(isys.name for isys in is_list) + return '—' + + # Члены комиссии + if source.startswith('commission_member:'): + parts = source.split(':') + idx, field = int(parts[1]), parts[2] + members = getattr(company, 'commission', None) or [] + if idx < len(members): + return str(getattr(members[idx], field, '') or '—') + return '—' + + # Склонение ФИО по падежам + if source.startswith('fio_acl:'): + who = source.split(':', 1)[1] + fio = _get_fio(company, who) + return dc.decline(fio, 'accs') if fio else '—' + return '—'