Skip to content
Snippets Groups Projects
models.py 2.94 KiB
Newer Older
  • Learn to ignore specific revisions
  • from django.conf import settings
    
    from django.contrib.postgres.fields import JSONField
    
    from django.db import models
    
    from django.db.models.signals import post_save
    from django.dispatch import receiver
    
    Dan Braghis's avatar
    Dan Braghis committed
    from django.urls import reverse
    
    from opentech.apply.activity.models import Activity
    
    from opentech.apply.users.models import User
    
    
    Dan Braghis's avatar
    Dan Braghis committed
    RECOMMENDATION_CHOICES = (
    
        (NO, 'No'),
        (MAYBE, 'Maybe'),
        (YES, 'Yes'),
    
    Dan Braghis's avatar
    Dan Braghis committed
    
    
    class ReviewQuerySet(models.QuerySet):
    
    Dan Braghis's avatar
    Dan Braghis committed
        def published(self):
            return self.filter(is_draft=False)
    
    
    Dan Braghis's avatar
    Dan Braghis committed
            return self.published().filter(author__in=User.objects.staff())
    
        def by_reviewers(self):
    
    Dan Braghis's avatar
    Dan Braghis committed
            return self.published().filter(author__in=User.objects.reviewers())
    
        def staff_score(self):
            return self.by_staff().score()
    
    
    Dan Braghis's avatar
    Dan Braghis committed
        def staff_recommendation(self):
            return self.by_staff().recommendation()
    
        def reviewers_score(self):
            return self.by_reviewers().score()
    
    
    Dan Braghis's avatar
    Dan Braghis committed
        def reviewers_recommendation(self):
            return self.by_reviewers().recommendation()
    
        def score(self):
            return self.aggregate(models.Avg('score'))['score__avg']
    
    
    Dan Braghis's avatar
    Dan Braghis committed
        def recommendation(self):
            recommendations = self.values_list('recommendation', flat=True)
    
    Dan Braghis's avatar
    Dan Braghis committed
                recommendation = sum(recommendations) / len(recommendations)
    
            except ZeroDivisionError:
                return -1
    
    
    Dan Braghis's avatar
    Dan Braghis committed
            if recommendation == YES or recommendation == NO:
    
                # If everyone in agreement return Yes/No
    
    Dan Braghis's avatar
    Dan Braghis committed
                return recommendation
    
    class Review(models.Model):
    
        submission = models.ForeignKey('funds.ApplicationSubmission', on_delete=models.CASCADE, related_name='reviews')
    
        author = models.ForeignKey(
            settings.AUTH_USER_MODEL,
            on_delete=models.PROTECT,
        )
    
        review = JSONField()
    
    Dan Braghis's avatar
    Dan Braghis committed
        recommendation = models.IntegerField(verbose_name="Recommendation", choices=RECOMMENDATION_CHOICES, default=0)
        score = models.DecimalField(max_digits=10, decimal_places=1, default=0)
    
    Dan Braghis's avatar
    Dan Braghis committed
        is_draft = models.BooleanField(default=False, verbose_name="Draft")
    
        objects = ReviewQuerySet.as_manager()
    
    
        class Meta:
            unique_together = ('author', 'submission')
    
    Dan Braghis's avatar
    Dan Braghis committed
        def get_absolute_url(self):
            return reverse('apply:reviews:review', args=(self.id,))
    
    
    Dan Braghis's avatar
    Dan Braghis committed
        def __str__(self):
            return f'Review for {self.submission.title} by {self.author!s}'
    
        def __repr__(self):
            return f'<{self.__class__.__name__}: {str(self.review)}>'
    
    
    
    @receiver(post_save, sender=Review)
    def update_submission_reviewers_list(sender, **kwargs):
        review = kwargs.get('instance')
    
        if not review.submission.reviewers.filter(id=review.author.id).exists():
            review.submission.reviewers.add(review.author)
    
    
    Dan Braghis's avatar
    Dan Braghis committed
        if kwargs.get('created', False):
    
            Activity.actions.create(
                user=review.author,
                submission=review.submission,
                message=f'Created a review for {review.submission.title}'
            )