from django.db import models from django.contrib.auth.models import User from django.core.validators import FileExtensionValidator from django.utils import timezone def validate_file_size(value): limit = 10 * 1024 * 1024 # 10 MB if value.size > limit: from django.core.exceptions import ValidationError raise ValidationError('Il file non può superare i 10 MB.') class Conversazione(models.Model): titolo = models.CharField(max_length=200) data = models.DateTimeField() partecipanti = models.ManyToManyField(User, related_name='conversazioni_partecipate', blank=True) contenuto = models.TextField() registrato_da = models.ForeignKey( User, on_delete=models.SET_NULL, null=True, related_name='conversazioni_registrate' ) class Meta: ordering = ['-data'] verbose_name = 'Conversazione' verbose_name_plural = 'Conversazioni' def __str__(self): return f"{self.titolo} ({self.data.strftime('%d/%m/%Y')})" class Obiettivo(models.Model): TIPO_CHOICES = [ ('collettivo', 'Collettivo'), ('individuale', 'Individuale'), ] STATO_CHOICES = [ ('aperto', 'Aperto'), ('in_corso', 'In corso'), ('completato', 'Completato'), ('sospeso', 'Sospeso'), ] titolo = models.CharField(max_length=200) descrizione = models.TextField(blank=True) avanzamento = models.PositiveSmallIntegerField(default=0) # 0-100 tipo = models.CharField(max_length=20, choices=TIPO_CHOICES, default='collettivo') assegnato_a = models.ManyToManyField( User, blank=True, related_name='obiettivi_assegnati' ) stato = models.CharField(max_length=20, choices=STATO_CHOICES, default='aperto') data_scadenza = models.DateField(null=True, blank=True) creato_da = models.ForeignKey( User, on_delete=models.SET_NULL, null=True, related_name='obiettivi_creati' ) data_creazione = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['-data_creazione'] verbose_name = 'Obiettivo' verbose_name_plural = 'Obiettivi' def __str__(self): return self.titolo @property def giorni_rimanenti(self): """Restituisce i giorni rimanenti alla scadenza (None se non impostata).""" if not self.data_scadenza: return None delta = self.data_scadenza - timezone.now().date() return delta.days class AggiornamentoObiettivo(models.Model): obiettivo = models.ForeignKey(Obiettivo, on_delete=models.CASCADE, related_name='aggiornamenti') testo = models.TextField() autore = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='aggiornamenti') data = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['-data'] verbose_name = 'Aggiornamento' verbose_name_plural = 'Aggiornamenti' def __str__(self): return f"Aggiornamento su '{self.obiettivo}' del {self.data.strftime('%d/%m/%Y')}" class CommentoConversazione(models.Model): conversazione = models.ForeignKey(Conversazione, on_delete=models.CASCADE, related_name='commenti') testo = models.TextField() autore = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='commenti_conversazione') data = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['-data'] verbose_name = 'Commento' verbose_name_plural = 'Commenti' def __str__(self): return f"Commento su '{self.conversazione}' del {self.data.strftime('%d/%m/%Y')}" class Documento(models.Model): file = models.FileField( upload_to='documenti/%Y/%m/', validators=[ FileExtensionValidator(allowed_extensions=['pdf']), validate_file_size, ], ) titolo = models.CharField(max_length=200) descrizione = models.TextField(blank=True) caricato_da = models.ForeignKey( User, on_delete=models.SET_NULL, null=True, related_name='documenti_caricati' ) data_caricamento = models.DateTimeField(auto_now_add=True) conversazione = models.ForeignKey( 'Conversazione', on_delete=models.SET_NULL, null=True, blank=True, related_name='documenti' ) obiettivo = models.ForeignKey( 'Obiettivo', on_delete=models.SET_NULL, null=True, blank=True, related_name='documenti' ) class Meta: ordering = ['-data_caricamento'] verbose_name = 'Documento' verbose_name_plural = 'Documenti' def __str__(self): return self.titolo @property def filename(self): import os return os.path.basename(self.file.name)