- {{item.signature}} больше НЕ содержит роль (роль выводится
отдельной колонкой {{item.role}}) — иначе «Председатель комиссии |
Председатель комиссии: ___»
- signature = «___________ / » (только подчёркивание и слэш)
- signature_full по-прежнему полная: «Роль: ___________ / И.О. Фамилия»
- <!-- loop:users_loop --> внутри цикла ИС: {{user_fio}}, {{user_position}}
- администратор НЕ исключается (как просил Костя), убираются только
дубли по ФИО (нормализованное сравнение)
- после проверки DaData/ИИ программа сравнивает результат с тем,
что заполнено в программе
- серьёзные расхождения выводятся КРАСНЫМИ БОЛЬШИМИ буквами:
«ВНИМАНИЕ! НАЙДЕНЫ РАСХОЖДЕНИЯ: Руководитель (ФИО): было
«Иванов И.И.», стало «Петров П.П.»»
- регистр/пунктуация (ИВАНОВ.И.И. vs Иванов И.И.) НЕ считаются
расхождением; ИНН/КПП/ОГРН — любое отличие цифр = ошибка
- расхождения также пишутся в лог
1) Логи: все действия пишутся в dokogen.log (импорт, генерация,
обращения к Морфер/DaData/ИИ с ответами), кнопка «Экспорт логов»
на вкладке «Лог»
2) Табы: при пересборке параграфа табуляция сохраняется как <w:tab/>
(раньше Word «съедал» табы между «_____» и датой)
3) Справка: инструкция пользователя (циклы, программа), инструкция
администратора (словари, API-ключи, лимиты), справочник переменных,
пустой опросник Excel — всё скачивается в Word/Excel
- раньше переменная читала отдельное поле category (пустое при
работе с галочками) → в документ вставлялось «—»
- теперь: ', '.join(personal_data_category) — галочки «иные»,
«специальные» и т.д. попадают в документ
1) ИИ универсален: вместо DeepSeek — «ИИ» (OpenAI-совместимый:
DeepSeek, ChatGPT и др.). В настройках: API-ключ, модель, базовый URL
2) склонение проверяет И полное, И краткое название (Морфер и ИИ)
3) ИИ-проверка реквизитов показывает снимок полей (статус каждого),
замечания и предложения — а не просто «ОК»
4) DaData: регистр нормализуется (КАПС → обычный), адрес (г., ул., д.),
дата ОГРН из миллисекунд → 09.02.2005
- совместимость со старым api_settings.json (deepseek_* → ai_*)
- раньше: если в тексте есть аббревиатура (ООО, И.О.) или цифры
(индекс в адресе) — весь текст оставался КАПСОМ
- теперь: каждое слово нормализуется отдельно, аббревиатуры
(АРМ, СКУД, ООО, ИНН и т.п.) и инициалы сохраняются
- город: '350000, Г. КРАСНОДАР...' → 'Г. Краснодар' → город
снова определяется при импорте
- должность: 'ГЛАВА' → 'Глава', ФИО: 'ИВАНОВ ИВАН ИВАНОВИЧ' → 'Иванов Иван Иванович'
- Новая вкладка: название документа + место хранения, добавить/удалить
- Импорт из опросника: «Названия документов» (строка 61) и «Место
хранения» (строка 62) → цикл {{paper_documents}} ({{document}}/{{storage}})
- Сохранение/автосохранение/генерация собирают данные вкладки
- Загрузка файла проекта восстанавливает список документов
- clean_value не портит аббревиатуры/номера (АРМ №1, СКУД)
- ПО: 'Названия программ...' → {{item.software}}
- 'локальную сеть' → is_has_lan (поле is_local_network)
- Цель обработки ПД — значение из объединённой ячейки (val_b)
- Роли комиссии ищутся и в колонке E, и в Примечании (D)
- Проверено на присланном опроснике: КПП, подразделение по
безопасности, действия с ПДн, структура ИС — импортируются
- import_settings.json рядом с программой (создаётся автоматически):
что импортировать (var), откуда (cell: 'Общие сведения'!B2 или
keywords: регэксп поиска по колонке A)
- importer.py читает словарь: сначала конкретная ячейка, потом ключевые слова
- листы общих сведений/сотрудников/ИС тоже настраиваются (ключевые слова)
- UI: меню «Генерация → Файл настроек импорта…» — выбор пути к словарю
- при сборке .exe файл остаётся редактируемым без пересборки
- {{security_department}} — наименование структурного подразделения
по безопасности (из поля 'структурное подразделение')
- {{item.pd_actions}} — действия с ПДн в цикле ИС
- {{item.structure}} — структура ИС импортируется из листов ИС
- КПП уже импортировался ({{company_kpp}})
- UI: применение подразделения, структуры и действий при импорте
Работают оба варианта: {{item.fio_initials}} и {{item_fio_initials}},
{{item.fio_short}} и {{item_fio_short}}.
Проверено: И.О. Фамилия -> В.Н. Черник, Фамилия И.О. -> Черник В.Н.
- {{item.fio_initials}} (И.О. Фамилия) и {{item.fio_short}} (Фамилия И.О.)
для комиссии
- {{item.software}} (ПО) для ИС + поле «ПО» в интерфейсе
- модель: поле software у InformationSystem
Word оставляет пустые параграфы и обрывки вокруг маркеров <!-- loop:... -->.
При размножении цикла они копировались между строками (комиссия слипалась
с пустыми строками). Теперь:
- template разделяется на prefix/core/suffix, пустые параграфы в core чистятся
- остатки маркеров удаляются после обработки (не трогая таблицы и page breaks)
- разрыв страницы из параграфа loop_end выносится между итерациями
Проверено: комиссия без пустых строк, акт 6 с 2 ИС — 2 разрыва страниц, XML валиден.
- models.py: поле structure у InformationSystem
- variables.py: {{item.structure}} / {{structure}} в цикле,
{{is_structure_N}} в индексированных
- ui.py: поле «Структура ИС» на вкладке ИС
- IGNORED_OLD_VARS: <Ctrl>, <Alt>, <Del> и др. клавиши больше не
считаются незаменёнными переменными (7.6 Инструкция Пользователя)
- Подсветка: вместо красного цвета текста — красный маркер
(w:highlight) на самой переменной, а не на всём абзаце
- OLD_VAR_MAP: ShortCompanyName1-6 (склонения краткого названия),
IspdnName → {{is_name_1}}
- Председатель/Секретарь/Заместитель — своей ролью
- Первый обычный член получает «Члены комиссии», остальные — пустая роль
- Пустая строка в цикле больше не превращается в «—»
Проверено: 1 председатель + 4 члена в шаблоне «6. Акт...»
Word хранит перенос страницы отдельным run в параграфе с <!-- loop_end -->.
Нормализация раньше удаляла его при склейке текста — акты слипались.
Теперь page break сохраняется и копируется в каждую итерацию цикла.
Проверено: 2 ИС -> 2 разрыва страниц, XML валиден.
Word разбивает на run'ы не только маркеры циклов, но и переменные
({{name}}, {{number}}, {{pd_list}} и т.д.). Нормализация теперь
склеивает все параграфы с {{...}}, а размножение цикла подставляет
и {{item.field}}, и {{field}} (шаблон '0. Акт обследования.docx')
- _normalize_loop_markers: склейка текста параграфа в один run перед
поиском <!-- loop:... --> и {{item.*}}, иначе циклы не разворачивались
(шаблон '6. Акт определения уровня защищенности ПДн.docx')
- variables.py: поле address в цикле information_systems
expand_loops_in_zip возвращал путь к пустому tmp-файлу, если в шаблоне
не было маркеров <!-- loop:... -->. python-docx падал с
'Package not found'. Теперь при отсутствии циклов возвращается
исходный шаблон, tmp удаляется. Тесты: без циклов, с циклом,
вложенные циклы — всё ок.