From 8edc856636595a426c2fc38fecda0ece90ca3aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=9D=D0=B0=D0=B4=D0=B5?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Tue, 2 Dec 2025 10:03:47 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B4=D0=B0=D0=BA=D1=82=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BF=D1=80=D0=BE=D1=84=D0=B8=D0=BB?= =?UTF-8?q?=D1=8F:=201.=20=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B4=D0=B8=D1=80=D0=B5=D0=BA=D1=82=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=D1=85=20=D0=B2?= =?UTF-8?q?=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D0=B8:=20=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=B2=D0=BE=D0=B7=D0=B2=D1=80?= =?UTF-8?q?=D0=B0=D1=82=20=D0=BD=D0=B0=20=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=86=D1=83=20=D0=BF=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D1=8F?= =?UTF-8?q?=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20=D0=BD=D0=B5=D1=81?= =?UTF-8?q?=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D1=83=D1=8E=D1=89=D0=B5?= =?UTF-8?q?=D0=B3=D0=BE=20GET=20endpoint=202.=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=BA=D0=B0=20=D0=BD=D0=B0=D0=BB=D0=B8=D1=87=D0=B8=D1=8F?= =?UTF-8?q?=20ldap=5Fdn=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=20=D0=BE=D0=B1?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC=20=D1=87?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B7=20LDAP:=20=D0=BB=D0=BE=D0=BA=D0=B0?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D0=B8=20=D0=B1=D0=B5=D0=B7?= =?UTF-8?q?=20ldap=5Fdn=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BE?= =?UTF-8?q?=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D1=8F=D1=8E=D1=82=D1=81=D1=8F=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=BF=D1=80=D1=8F=D0=BC=D1=83=D1=8E=20=D0=B2=20?= =?UTF-8?q?=D0=91=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/api/v1/employees/views.py | 34 ++++++++++++++++++++++++------- backend/employees/views_front.py | 12 +++++------ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/backend/api/v1/employees/views.py b/backend/api/v1/employees/views.py index 1d2f435f..6ca44fe0 100644 --- a/backend/api/v1/employees/views.py +++ b/backend/api/v1/employees/views.py @@ -1782,8 +1782,18 @@ class EmployeeViewSet(viewsets.ModelViewSet): logger.info(f"[ME PATCH] Step 9: svc_changes keys: {list(svc_changes.keys())}") - if ldap_enabled and (svc_changes or move_to_department_dn or group_cns is not None): - # Режим с LDAP: обновляем через DirectoryService + # Проверяем, есть ли у пользователя ldap_dn + has_ldap_dn = False + if ldap_enabled: + from employees.models import LdapSyncState + has_ldap_dn = ( + LdapSyncState.objects.filter(employee=instance, ldap_dn__isnull=False).exists() + or (hasattr(instance, 'ldap_dn') and instance.ldap_dn) + ) + logger.info(f"[ME PATCH] Step 9.5: LDAP enabled, user has ldap_dn: {has_ldap_dn}") + + if ldap_enabled and has_ldap_dn and (svc_changes or move_to_department_dn or group_cns is not None): + # Режим с LDAP: обновляем через DirectoryService (только для пользователей с ldap_dn) logger.info("[ME PATCH] Step 10: LDAP mode - updating via DirectoryService...") logger.info(f"[ME PATCH] Step 10: DirectoryService params - svc_changes={list(svc_changes.keys())}, move_to_department_dn={move_to_department_dn}, group_cns={group_cns}") svc = DirectoryService() @@ -1804,9 +1814,9 @@ class EmployeeViewSet(viewsets.ModelViewSet): {"detail": str(e)}, status=502 if isinstance(e, DirectoryLdapError) else 500, ) - elif not ldap_enabled and svc_changes: - # Режим без LDAP: обновляем напрямую в БД - logger.info(f"[ME PATCH] Step 10: LDAP disabled, updating DB directly with: {list(svc_changes.keys())}") + elif (not ldap_enabled or not has_ldap_dn) and svc_changes: + # Режим без LDAP или пользователь без ldap_dn: обновляем напрямую в БД + logger.info(f"[ME PATCH] Step 10: LDAP disabled or no ldap_dn, updating DB directly with: {list(svc_changes.keys())}") for k, v in svc_changes.items(): if k != "position" and k != "avatar_bytes": setattr(instance, k, v) @@ -2054,8 +2064,18 @@ class EmployeeViewSet(viewsets.ModelViewSet): except Exception as exc: print(f"[EMP PATCH] Error reading avatar for LDAP: {exc}") + # Проверяем, есть ли у пользователя ldap_dn + has_ldap_dn = False if ldap_enabled: - # LDAP mode: sync with DirectoryService + from employees.models import LdapSyncState + has_ldap_dn = ( + LdapSyncState.objects.filter(employee=emp, ldap_dn__isnull=False).exists() + or (hasattr(emp, 'ldap_dn') and emp.ldap_dn) + ) + print(f"[EMP PATCH] LDAP enabled, user has ldap_dn: {has_ldap_dn}") + + if ldap_enabled and has_ldap_dn: + # LDAP mode: sync with DirectoryService (только для пользователей с ldap_dn) svc = DirectoryService() if svc_changes or move_to_department_dn or group_cns is not None: try: @@ -2077,7 +2097,7 @@ class EmployeeViewSet(viewsets.ModelViewSet): ), ) else: - # Non-LDAP mode: direct DB updates + # Non-LDAP mode or user without ldap_dn: direct DB updates # Restore ldap_changes back to vd for DB-only save vd.update(ldap_changes) diff --git a/backend/employees/views_front.py b/backend/employees/views_front.py index 988bc8bf..a4ed6588 100644 --- a/backend/employees/views_front.py +++ b/backend/employees/views_front.py @@ -595,9 +595,9 @@ def employee_edit(request, pk: int): ) messages.error(request, error_msg) - # Возвращаем на страницу редактирования, а не на профиль - edit_url = reverse("employees:employee_edit", args=(pk,)) - return redirect(edit_url) + # Возвращаем на страницу профиля сотрудника + profile_url = reverse("employees:employee_detail", args=(pk,)) + return redirect(profile_url) # ---------- EDIT ME ---------- @@ -740,9 +740,9 @@ def employee_edit_me(request): ) messages.error(request, error_msg) - # Возвращаем на страницу редактирования - edit_url = reverse("employees:employee_edit_me") - return redirect(edit_url) + # Возвращаем на страницу профиля (где есть форма редактирования) + profile_url = reverse("employees:profile") + return redirect(profile_url) # ---------- CREATE (staff) ----------