""" Chat Models für Live-Chat System """ from django.db import models from django.contrib.auth.models import User from django.utils import timezone from django.conf import settings import uuid class ChatRoom(models.Model): """Chat-Raum für Kunde-Admin Kommunikation""" ROOM_STATUS_CHOICES = [ ('active', 'Aktiv'), ('waiting', 'Wartend'), ('closed', 'Geschlossen'), ('archived', 'Archiviert'), ] id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) customer = models.ForeignKey(User, on_delete=models.CASCADE, related_name='customer_chats') admin = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='admin_chats') status = models.CharField(max_length=20, choices=ROOM_STATUS_CHOICES, default='waiting') subject = models.CharField(max_length=200, blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) last_message_at = models.DateTimeField(null=True, blank=True) class Meta: ordering = ['-last_message_at', '-created_at'] verbose_name = 'Chat-Raum' verbose_name_plural = 'Chat-Räume' def __str__(self): return f"Chat {self.id} - {self.customer.username}" def get_unread_count(self, user): """Anzahl ungelesener Nachrichten für User""" return self.messages.filter( sender__in=self.get_other_users(user), read_at__isnull=True ).count() def get_other_users(self, user): """Andere User im Chat""" if user == self.customer: return [self.admin] if self.admin else [] elif user == self.admin: return [self.customer] return [] def mark_messages_as_read(self, user): """Nachrichten als gelesen markieren""" other_users = self.get_other_users(user) self.messages.filter( sender__in=other_users, read_at__isnull=True ).update(read_at=timezone.now()) class ChatMessage(models.Model): """Chat-Nachricht""" MESSAGE_TYPE_CHOICES = [ ('text', 'Text'), ('image', 'Bild'), ('file', 'Datei'), ('system', 'System'), ] id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) room = models.ForeignKey(ChatRoom, on_delete=models.CASCADE, related_name='messages') sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sent_messages') message_type = models.CharField(max_length=20, choices=MESSAGE_TYPE_CHOICES, default='text') content = models.TextField() file = models.FileField(upload_to='chat_files/', null=True, blank=True) image = models.ImageField(upload_to='chat_images/', null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) read_at = models.DateTimeField(null=True, blank=True) is_system_message = models.BooleanField(default=False) class Meta: ordering = ['created_at'] verbose_name = 'Chat-Nachricht' verbose_name_plural = 'Chat-Nachrichten' def __str__(self): return f"{self.sender.username}: {self.content[:50]}" def save(self, *args, **kwargs): """Nachricht speichern und Room aktualisieren""" is_new = self.pk is None super().save(*args, **kwargs) if is_new: # Room last_message_at aktualisieren self.room.last_message_at = self.created_at self.room.save(update_fields=['last_message_at']) class ChatNotification(models.Model): """Chat-Benachrichtigungen""" NOTIFICATION_TYPE_CHOICES = [ ('new_message', 'Neue Nachricht'), ('room_assigned', 'Raum zugewiesen'), ('room_closed', 'Raum geschlossen'), ('customer_online', 'Kunde online'), ('customer_offline', 'Kunde offline'), ] id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='chat_notifications') room = models.ForeignKey(ChatRoom, on_delete=models.CASCADE, related_name='notifications') notification_type = models.CharField(max_length=20, choices=NOTIFICATION_TYPE_CHOICES) title = models.CharField(max_length=200) message = models.TextField() created_at = models.DateTimeField(auto_now_add=True) read_at = models.DateTimeField(null=True, blank=True) sent_via_email = models.BooleanField(default=False) sent_via_push = models.BooleanField(default=False) class Meta: ordering = ['-created_at'] verbose_name = 'Chat-Benachrichtigung' verbose_name_plural = 'Chat-Benachrichtigungen' def __str__(self): return f"{self.notification_type}: {self.title}" class UserOnlineStatus(models.Model): """Online-Status von Benutzern""" user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='online_status') is_online = models.BooleanField(default=False) last_seen = models.DateTimeField(auto_now=True) current_room = models.ForeignKey(ChatRoom, on_delete=models.SET_NULL, null=True, blank=True) class Meta: verbose_name = 'Online-Status' verbose_name_plural = 'Online-Status' def __str__(self): status = "Online" if self.is_online else "Offline" return f"{self.user.username} - {status}" class QuickResponse(models.Model): """Schnelle Antworten für Admins""" category = models.CharField(max_length=50, choices=[ ('greeting', 'Begrüßung'), ('pricing', 'Preise'), ('shipping', 'Versand'), ('custom_order', 'Custom Order'), ('technical', 'Technische Fragen'), ('general', 'Allgemein'), ]) title = models.CharField(max_length=100) content = models.TextField() created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='quick_responses') created_at = models.DateTimeField(auto_now_add=True) is_active = models.BooleanField(default=True) use_count = models.IntegerField(default=0) class Meta: ordering = ['category', 'title'] verbose_name = 'Schnelle Antwort' verbose_name_plural = 'Schnelle Antworten' def __str__(self): return f"{self.category}: {self.title}" def increment_use_count(self): """Verwendungszähler erhöhen""" self.use_count += 1 self.save(update_fields=['use_count']) class ChatAnalytics(models.Model): """Chat-Analytics für Performance-Tracking""" date = models.DateField() total_messages = models.IntegerField(default=0) total_rooms = models.IntegerField(default=0) active_rooms = models.IntegerField(default=0) avg_response_time = models.FloatField(default=0) # in Sekunden customer_satisfaction = models.FloatField(default=0) # 0-5 Sterne total_duration = models.FloatField(default=0) # in Minuten class Meta: unique_together = ['date'] verbose_name = 'Chat-Analytics' verbose_name_plural = 'Chat-Analytics' def __str__(self): return f"Chat Analytics - {self.date}" @classmethod def get_or_create_today(cls): """Heutige Analytics erstellen oder abrufen""" today = timezone.now().date() analytics, created = cls.objects.get_or_create(date=today) return analytics