from django.http.response import JsonResponse from rest_framework.views import APIView from rest_framework.parsers import JSONParser from django.conf import settings from rest_framework.response import Response from rest_framework import status from django.db.models import Q from .models import Messagerie from Auth.models import Profile, ProfileRole from GestionMessagerie.serializers import MessageSerializer from School.models import Teacher from School.serializers import TeacherSerializer import N3wtSchool.mailManager as mailer from N3wtSchool import bdd from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from rest_framework.exceptions import NotFound class MessagerieView(APIView): def get(self, request, profile_id): messagesList = bdd.getObjects(_objectName=Messagerie, _columnName='destinataire__id', _value=profile_id) messages_serializer = MessageSerializer(messagesList, many=True) return JsonResponse(messages_serializer.data, safe=False) class MessageView(APIView): def post(self, request): message_data=JSONParser().parse(request) message_serializer = MessageSerializer(data=message_data) if message_serializer.is_valid(): message_serializer.save() return JsonResponse('Nouveau Message ajouté', safe=False) return JsonResponse(message_serializer.errors, safe=False) class MessageSimpleView(APIView): def get(self, request, id): message=bdd.getObject(Messagerie, "id", id) message_serializer=MessageSerializer(message) return JsonResponse(message_serializer.data, safe=False) class SendEmailView(APIView): """ API pour envoyer des emails aux parents et professeurs. """ def post(self, request): data = request.data recipients = data.get('recipients', []) cc = data.get('cc', []) bcc = data.get('bcc', []) subject = data.get('subject', 'Notification') message = data.get('message', '') establishment_id = data.get('establishment_id', '') if not recipients or not message: return Response({'error': 'Les destinataires et le message sont requis.'}, status=status.HTTP_400_BAD_REQUEST) try: # Récupérer la connexion SMTP connection = mailer.getConnection(establishment_id) # Envoyer l'email return mailer.sendMail( subject=subject, message=message, recipients=recipients, cc=cc, bcc=bcc, attachments=[], connection=connection ) except NotFound as e: return Response({'error': str(e)}, status=status.HTTP_404_NOT_FOUND) except Exception as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) class ContactsView(APIView): """ API pour récupérer les contacts associés à un établissement. """ def get(self, request, establishment_id): try: # Récupérer les enseignants associés à l'établissement teachers = Teacher.objects.filter(profile_role__establishment_id=establishment_id) teachers_serializer = TeacherSerializer(teachers, many=True) # Ajouter un contact pour l'administration admin_contact = { "id": "admin", "name": "Administration", "email": "admin@etablissement.com", "profilePic": "https://www.gravatar.com/avatar/admin" } contacts = [admin_contact] + teachers_serializer.data return Response(contacts, status=status.HTTP_200_OK) except Exception as e: return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) def search_recipients(request): """ API pour rechercher des destinataires en fonction d'un terme de recherche et d'un établissement. """ query = request.GET.get('q', '').strip() # Récupérer le terme de recherche depuis les paramètres GET establishment_id = request.GET.get('establishment_id', None) # Récupérer l'ID de l'établissement if not query: return JsonResponse([], safe=False) # Retourner une liste vide si aucun terme n'est fourni if not establishment_id: return JsonResponse({'error': 'establishment_id est requis'}, safe=False, status=status.HTTP_400_BAD_REQUEST) # Rechercher dans les champs pertinents (nom, prénom, email) et filtrer par establishment_id profiles = Profile.objects.filter( Q(first_name__icontains=query) | Q(last_name__icontains=query) | Q(email__icontains=query), roles__establishment_id=establishment_id, # Utiliser 'roles' au lieu de 'profilerole' roles__is_active=True # Filtrer uniquement les ProfileRole actifs ).distinct() # Construire la réponse avec les rôles associés results = [] for profile in profiles: profile_roles = ProfileRole.objects.filter( profile=profile, establishment_id=establishment_id, is_active=True # Inclure uniquement les ProfileRole actifs ).values( 'id', 'role_type', 'establishment__name', 'is_active' ) results.append({ 'id': profile.id, 'first_name': profile.first_name, 'last_name': profile.last_name, 'email': profile.email, 'roles': list(profile_roles) # Inclure tous les rôles actifs associés pour cet établissement }) return JsonResponse(results, safe=False) class ConversationListView(APIView): """ Liste les conversations d'un utilisateur (parent ou enseignant). Retourne la liste des interlocuteurs et le dernier message échangé. """ @swagger_auto_schema( operation_description="Liste les conversations d'un utilisateur (parent ou enseignant).", responses={200: openapi.Response('Liste des conversations')} ) def get(self, request, profile_id): # Récupérer toutes les conversations où l'utilisateur est émetteur ou destinataire messages = Messagerie.objects.filter(Q(emetteur_id=profile_id) | Q(destinataire_id=profile_id)) # Grouper par conversation_id conversations = {} for msg in messages.order_by('-date_envoi'): conv_id = msg.conversation_id or f"{min(msg.emetteur_id, msg.destinataire_id)}_{max(msg.emetteur_id, msg.destinataire_id)}" if conv_id not in conversations: conversations[conv_id] = msg # Préparer la réponse data = [] for conv_id, last_msg in conversations.items(): interlocuteur = last_msg.emetteur if last_msg.destinataire_id == int(profile_id) else last_msg.destinataire data.append({ 'conversation_id': conv_id, 'last_message': MessageSerializer(last_msg).data, 'interlocuteur': { 'id': interlocuteur.id, 'first_name': interlocuteur.first_name, 'last_name': interlocuteur.last_name, 'email': interlocuteur.email, } }) return Response(data, status=status.HTTP_200_OK) class ConversationMessagesView(APIView): """ Récupère tous les messages d'une conversation donnée. """ @swagger_auto_schema( operation_description="Récupère tous les messages d'une conversation donnée.", responses={200: openapi.Response('Liste des messages')} ) def get(self, request, conversation_id): messages = Messagerie.objects.filter(conversation_id=conversation_id).order_by('date_envoi') serializer = MessageSerializer(messages, many=True) return Response(serializer.data, status=status.HTTP_200_OK) class MarkAsReadView(APIView): """ Marque tous les messages reçus dans une conversation comme lus pour l'utilisateur connecté. """ @swagger_auto_schema( operation_description="Marque tous les messages reçus dans une conversation comme lus pour l'utilisateur connecté.", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'profile_id': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID du profil utilisateur') }, required=['profile_id'] ), responses={200: openapi.Response('Statut OK')} ) def post(self, request, conversation_id): profile_id = request.data.get('profile_id') Messagerie.objects.filter(conversation_id=conversation_id, destinataire_id=profile_id, is_read=False).update(is_read=True) return Response({'status': 'ok'}, status=status.HTTP_200_OK)