feat(notifications): notify membership access changes
This commit is contained in:
@@ -7,13 +7,19 @@ from rest_framework.exceptions import PermissionDenied
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.filters import SearchFilter, OrderingFilter
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
|
||||
from core.paginations.limit_offset import CustomLimitOffsetPagination
|
||||
|
||||
from apps.workspaces.models import Workspace
|
||||
from apps.clients.models import Client
|
||||
from apps.projects.models import (
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
|
||||
from core.paginations.limit_offset import CustomLimitOffsetPagination
|
||||
|
||||
from apps.notifications.membership_events import (
|
||||
notify_project_membership_added,
|
||||
notify_project_membership_deactivated,
|
||||
notify_project_membership_removed,
|
||||
notify_project_membership_role_changed,
|
||||
)
|
||||
from apps.workspaces.models import Workspace
|
||||
from apps.clients.models import Client
|
||||
from apps.projects.models import (
|
||||
Project,
|
||||
ProjectMembership,
|
||||
ProjectRate,
|
||||
@@ -111,12 +117,18 @@ class ProjectViewSet(ModelViewSet):
|
||||
color=serializer.validated_data.get("color", "")
|
||||
)
|
||||
|
||||
for member in members_data:
|
||||
add_project_member(
|
||||
project=project,
|
||||
user_id=member["user_id"],
|
||||
role=member["role"]
|
||||
)
|
||||
for member in members_data:
|
||||
membership = add_project_member(
|
||||
project=project,
|
||||
user_id=member["user_id"],
|
||||
role=member["role"]
|
||||
)
|
||||
notify_project_membership_added(
|
||||
actor=request.user,
|
||||
recipient=membership.user,
|
||||
project=project,
|
||||
role=membership.role,
|
||||
)
|
||||
|
||||
output_serializer = ProjectSerializer(project)
|
||||
return Response(output_serializer.data, status=status.HTTP_201_CREATED)
|
||||
@@ -144,27 +156,55 @@ class ProjectViewSet(ModelViewSet):
|
||||
incoming_users = {str(m['user_id']) for m in members_data}
|
||||
|
||||
# Add or Update roles
|
||||
for member in members_data:
|
||||
user_id_str = str(member['user_id'])
|
||||
if user_id_str in current_memberships:
|
||||
# Reactivate or update role
|
||||
update_project_member(
|
||||
current_memberships[user_id_str],
|
||||
role=member['role'],
|
||||
is_active=True
|
||||
)
|
||||
else:
|
||||
# Add new member
|
||||
add_project_member(
|
||||
project=updated_project,
|
||||
user_id=member['user_id'],
|
||||
role=member['role']
|
||||
)
|
||||
for member in members_data:
|
||||
user_id_str = str(member['user_id'])
|
||||
if user_id_str in current_memberships:
|
||||
membership = current_memberships[user_id_str]
|
||||
previous_role = membership.role
|
||||
previous_is_active = membership.is_active
|
||||
updated_membership = update_project_member(
|
||||
membership,
|
||||
role=member['role'],
|
||||
is_active=True
|
||||
)
|
||||
if not previous_is_active and updated_membership.is_active:
|
||||
notify_project_membership_added(
|
||||
actor=request.user,
|
||||
recipient=updated_membership.user,
|
||||
project=updated_project,
|
||||
role=updated_membership.role,
|
||||
)
|
||||
elif previous_role != updated_membership.role:
|
||||
notify_project_membership_role_changed(
|
||||
actor=request.user,
|
||||
recipient=updated_membership.user,
|
||||
project=updated_project,
|
||||
previous_role=previous_role,
|
||||
new_role=updated_membership.role,
|
||||
)
|
||||
else:
|
||||
membership = add_project_member(
|
||||
project=updated_project,
|
||||
user_id=member['user_id'],
|
||||
role=member['role']
|
||||
)
|
||||
notify_project_membership_added(
|
||||
actor=request.user,
|
||||
recipient=membership.user,
|
||||
project=updated_project,
|
||||
role=membership.role,
|
||||
)
|
||||
|
||||
# Deactivate omitted members
|
||||
for user_id_str, membership in current_memberships.items():
|
||||
if user_id_str not in incoming_users:
|
||||
update_project_member(membership, is_active=False)
|
||||
for user_id_str, membership in current_memberships.items():
|
||||
if user_id_str not in incoming_users and membership.is_active:
|
||||
update_project_member(membership, is_active=False)
|
||||
notify_project_membership_deactivated(
|
||||
actor=request.user,
|
||||
recipient=membership.user,
|
||||
project=updated_project,
|
||||
role=membership.role,
|
||||
)
|
||||
|
||||
output_serializer = ProjectSerializer(updated_project)
|
||||
return Response(output_serializer.data, status=status.HTTP_200_OK)
|
||||
@@ -243,26 +283,65 @@ class ProjectMembershipViewSet(BaseProjectNestedViewSet):
|
||||
self.verify_manager_access(project_id)
|
||||
|
||||
project = get_object_or_404(Project, id=project_id, is_deleted=False)
|
||||
membership = add_project_member(
|
||||
project=project,
|
||||
user_id=serializer.validated_data["user_id"],
|
||||
role=serializer.validated_data["role"]
|
||||
)
|
||||
return Response(ProjectMembershipSerializer(membership).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
membership = self.get_object()
|
||||
serializer = self.get_serializer(data=request.data, partial=kwargs.pop("partial", False))
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
updated_membership = update_project_member(membership, **serializer.validated_data)
|
||||
return Response(ProjectMembershipSerializer(updated_membership).data, status=status.HTTP_200_OK)
|
||||
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
membership = self.get_object()
|
||||
membership.is_deleted = True
|
||||
membership.save(update_fields=["is_deleted", "updated_at"])
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
membership = add_project_member(
|
||||
project=project,
|
||||
user_id=serializer.validated_data["user_id"],
|
||||
role=serializer.validated_data["role"]
|
||||
)
|
||||
notify_project_membership_added(
|
||||
actor=request.user,
|
||||
recipient=membership.user,
|
||||
project=project,
|
||||
role=membership.role,
|
||||
)
|
||||
return Response(ProjectMembershipSerializer(membership).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
membership = self.get_object()
|
||||
serializer = self.get_serializer(data=request.data, partial=kwargs.pop("partial", False))
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
previous_role = membership.role
|
||||
previous_is_active = membership.is_active
|
||||
updated_membership = update_project_member(membership, **serializer.validated_data)
|
||||
if not previous_is_active and updated_membership.is_active:
|
||||
notify_project_membership_added(
|
||||
actor=request.user,
|
||||
recipient=updated_membership.user,
|
||||
project=updated_membership.project,
|
||||
role=updated_membership.role,
|
||||
)
|
||||
elif previous_is_active and not updated_membership.is_active:
|
||||
notify_project_membership_deactivated(
|
||||
actor=request.user,
|
||||
recipient=updated_membership.user,
|
||||
project=updated_membership.project,
|
||||
role=previous_role,
|
||||
)
|
||||
elif previous_role != updated_membership.role:
|
||||
notify_project_membership_role_changed(
|
||||
actor=request.user,
|
||||
recipient=updated_membership.user,
|
||||
project=updated_membership.project,
|
||||
previous_role=previous_role,
|
||||
new_role=updated_membership.role,
|
||||
)
|
||||
return Response(ProjectMembershipSerializer(updated_membership).data, status=status.HTTP_200_OK)
|
||||
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
membership = self.get_object()
|
||||
recipient = membership.user
|
||||
project = membership.project
|
||||
role = membership.role
|
||||
membership.is_deleted = True
|
||||
membership.save(update_fields=["is_deleted", "updated_at"])
|
||||
notify_project_membership_removed(
|
||||
actor=request.user,
|
||||
recipient=recipient,
|
||||
project=project,
|
||||
role=role,
|
||||
)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class ProjectRateViewSet(BaseProjectNestedViewSet):
|
||||
|
||||
Reference in New Issue
Block a user