BREAKING CHANGES:
- Department.head автоматически очищается при увольнении руководителя
- LDAP managedBy атрибут очищается при увольнении
Fixes:
- DN не перемещался при восстановлении сотрудника (Dismissed → Users)
- DN не перемещался при увольнении сотрудника без отделов
- Ошибка при увольнении из множественных отделов (двойной modify_dn)
- Неправильные URL patterns для LDAP моделей в админке
- Двойное кодирование DN в редиректе смены пароля
Features:
- Добавлен метод _ensure_ldap_dn_location для гарантированного перемещения DN
- Добавлена проверка already_there в sync_department_member_to_ldap
- Управление паролями LDAP пользователей через админку:
* Кнопка смены пароля в карточке пользователя
* Массовое действие смены пароля
* Автосинхронизация с Django password hash
- Автоочистка Department.head и LDAP managedBy при увольнении руководителя
- Добавлены методы set_password() и change_password() в LdapUser
Changed:
- Переписан сигнал sync_department_member_to_ldap с реальными методами
- Исправлены URL patterns: ldap_* → employees_*
Критические исправления:
- actions.py: заменить bulk update() на save() для EmployeeDepartment
Причина: bulk update НЕ вызывает Django signals!
Было: .update(is_active=False) - сигнал не срабатывает
Стало: for loop с save() - сигнал срабатывает для каждой записи
- _helpers.py: удалить неиспользуемую функцию _ldap_try()
Нигде не используется после рефакторинга
- _helpers.py: удалить неиспользуемые импорты
DirectoryLdapError, DirectoryServiceError, DirectoryDbError, status
- actions.py: обновить комментарий с правильным названием сигнала
sync_department_member_to_ldap вместо устаревшего sync_member
Функционал сохранен: при увольнении сотрудника теперь корректно
срабатывают сигналы для каждого EmployeeDepartment, что приводит
к корректной синхронизации с LDAP (перемещение из OU отделов).
Изменения:
- EmployeeActionViewSet: 240 → 115 строк (-125 строк, -52%)
- _apply_effects(): удалена вся LDAP логика (~140 строк)
Удалено:
- Прямые вызовы DirectoryService
- Обработка LdapSyncState
- Логика перемещения в OU=Dismissed и обратно
- Удаление из департаментов в LDAP
- Все try/except блоки для LDAP ошибок
- Импорты: DirectoryService, DirectoryLdapError, DirectoryServiceError, DirectoryDbError, LdapSyncState, settings, _is_ldap_enabled
Осталось только работа с БД:
- При ACTION_DISMISSED: is_active=False + деактивация EmployeeDepartment
- При других действиях: is_active=True
LDAP синхронизация через существующие сигналы:
- sync_employee_to_ldap_on_save: обрабатывает is_active (активация/деактивация)
- sync_member (signals_department.py): обрабатывает EmployeeDepartment (удаление из отделов)
Функционал сохранен, код стал в 2 раза короче
DirectoryService:
- Added public methods: assign_role, revoke_role, create_role, update_role, delete_role
- Added public method: move_user_to_base (replaces private _user_service._move_user_to_base)
- Fixed method signatures to match DepartmentService API
roles.py:
- Replaced direct DepartmentService usage with DirectoryService facade (5 methods)
- Removed manual GroupService/UserService instantiation
- All CRUD operations now go through facade layer
actions.py:
- Replaced private API svc._user_service._move_user_to_base() with public svc.move_user_to_base()
- Simplified LDAP connection handling (2 occurrences)
- Removed manual _ldap() and ensure_container_exists calls
manage.py check: System check identified no issues
- Replaced ..permissions with ...permissions in all 7 view modules
- Deleted backend/api/v1/employees/permissions.py (duplicate re-export)
- Views now import directly from api.v1.permissions (3 dots up)
manage.py check: System check identified no issues
- Split into 9 modules by ViewSet: departments, employees, positions,
roles, skills, actions, groups, auth, _helpers
- Created views/__init__.py with re-exports for backward compatibility
- Created employees/permissions.py re-export shim (views/ is now a
sub-package, so ..permissions resolves to employees.permissions)
- Fixed api/auth/serializers.py import: PHONE_FIELD from _helpers,
_normalize_phone from employees.utils
- Removed ~250+ debug print()/logger.info() statements from
departments.py and employees.py
- Removed dead _with_ldap_service() decorator from helpers
- Removed unreachable code at end of GroupViewSet.replace_members
manage.py check: System check identified no issues (0 silenced)