From 7e31c799632af2a9a788b51998832b067396da35 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Fri, 2 May 2025 22:13:07 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Feat:=20[#41]=20=ED=8C=80=EC=9B=90?= =?UTF-8?q?=20=EC=B4=88=EB=8C=80=20=EC=88=98=EB=9D=BD/=EA=B1=B0=EC=A0=88?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- projects/views.py | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/projects/views.py b/projects/views.py index 64c8da8..6409d85 100644 --- a/projects/views.py +++ b/projects/views.py @@ -12,10 +12,12 @@ from rest_framework.generics import ListAPIView from .serializers import ProjectListViewSerializer, ProjectCreateSerializer, ProjectTeamSerializer from .paginations import ProjectPagination from .filters import ProjectFilter -from .services import ProjectStateChangeService, ProjectBeforeRelCheckService +from .services import * from django.db import transaction +from notifications.services import * + class ProjectListView(ListAPIView): queryset = Project.objects.filter(is_published=True).order_by('-created_at') @@ -29,6 +31,7 @@ class ProjectListView(ListAPIView): class ProjectCreateAPIView(APIView): @transaction.atomic def post(self, request): + user = request.user serializer = ProjectCreateSerializer(data=request.data, context={"request": request}) if serializer.is_valid(): serializer.save() @@ -36,7 +39,7 @@ class ProjectCreateAPIView(APIView): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class ProjectTeamManageAPIView(APIView): - # 팀원 초대 + # 팀원 초대 및 알림 @transaction.atomic def post(self, request, pk): user = request.user @@ -47,11 +50,14 @@ class ProjectTeamManageAPIView(APIView): new_member = get_object_or_404(User, nickname=nickname) if ProjectTeamList.objects.filter(project=project, user=new_member).exists(): return Response({"message": "already team member"}, status=status.HTTP_400_BAD_REQUEST) - serializer = ProjectTeamSerializer(data={'user':new_member.id, 'project':project.id}) - if serializer.is_valid(): - serializer.save() - return Response({"message": "invite success"}, status=status.HTTP_200_OK) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + new_notification = NotifiationService.create_notification(user=new_member, note_type=NotificationType.INVITE) + ProjectInvitationService.create_project_invitation( + project=project, + from_user=user, + to_user=new_member, + notification=new_notification + ) + return Response({"message": "invite success"}, status=status.HTTP_200_OK) # 팀원 추방 @transaction.atomic @@ -140,4 +146,27 @@ class ProjectChangeState(APIView): return Response({ 'message': f'{action_type} {"added" if add else "removed"}' }, status=status.HTTP_200_OK) - + +class ProjectInvitationAPIView(APIView): + # 팀원 초대 수락/거절 + @transaction.atomic + def post(self, request): + accept = request.data['accept'] + project_invitation = get_object_or_404(ProjectInvitation, id=request.data['project_invitation_id']) + new_member = project_invitation.to_user + project = project_invitation.project + if request.user != new_member: + return Response({"message": "Not account owner"}, status=status.HTTP_403_FORBIDDEN) + if project_invitation.status != InvitationStatus.PENDING: + return Response({"message": "already handled invitation"}, status=status.HTTP_400_BAD_REQUEST) + if accept: + project_invitation.status = InvitationStatus.ACCEPTED + project_invitation.save() + serializer = ProjectTeamSerializer(data={'user':new_member.id, 'project':project.id}) + if serializer.is_valid(): + serializer.save() + return Response({"message": "invitation accepted"}, status=status.HTTP_200_OK) + else: + project_invitation.status = InvitationStatus.REJECTED + project_invitation.save() + return Response({"message": "invitation rejected"}, status=status.HTTP_200_OK) \ No newline at end of file