def _officer_service_year(min_date, max_date): query = Officer.objects.filter(appointed_date__isnull=False) query = query.annotate( end_date=models.Case(models.When(Q(resignation_date__isnull=False, resignation_date__lt=max_date), then='resignation_date'), default=models.Value(max_date), output_field=models.DateField()), start_date=models.Case(models.When(appointed_date__lt=min_date, then=models.Value(min_date)), default='appointed_date', output_field=models.DateField()), ) # filter-out officer has service time smaller than 1 year query = query.filter(end_date__gte=F('start_date') + timedelta(days=365)) return query.annotate( officer_id=F('id'), service_year=( Func( F('end_date') - F('start_date'), template= "ROUND(CAST(%(function)s('day', %(expressions)s) / 365.0 as numeric), 4)", function='DATE_PART', output_field=models.FloatField() ) # in order to easy to test and calculate, we only get 4 decimal points ))
def complainant_gender_aggregation(self): query = self.officerallegation_set.all() query = query.values('allegation__complainant__gender').annotate( complainant_gender=models.Case( models.When(allegation__complainant__gender='', then=models.Value('Unknown')), models.When(allegation__complainant__isnull=True, then=models.Value('Unknown')), default='allegation__complainant__gender', output_field=models.CharField()), year=ExtractYear('start_date')) query = query.values('complainant_gender', 'year').order_by( 'complainant_gender', 'year').annotate( count=models.Count('complainant_gender'), sustained_count=models.Sum( models.Case(models.When(final_finding='SU', then=1), default=models.Value(0), output_field=models.IntegerField()))) data = [{ 'name': GENDER_DICT.get(obj['complainant_gender'], 'Unknown'), 'sustained_count': obj['sustained_count'], 'count': obj['count'], 'year': obj['year'] } for obj in query if obj['count'] > 0] return Officer._group_and_sort_aggregations(data)
def complaint_category_aggregation(self): query = self.officerallegation_set.all() query = query.annotate(name=models.Case( models.When(allegation_category__category__isnull=True, then=models.Value('Unknown')), default='allegation_category__category', output_field=models.CharField()), year=ExtractYear('start_date')) query = query.values('name', 'year').order_by('name', 'year').annotate( count=models.Count('name'), sustained_count=models.Sum( models.Case(models.When(final_finding='SU', then=1), default=models.Value(0), output_field=models.IntegerField()))) return Officer._group_and_sort_aggregations(list(query))
def _honorable_mention_count_query(_, max_datetime): return models.Count(models.Case( models.When(award__start_date__lte=max_datetime.date(), award__award_type='Honorable Mention', then='award'), output_field=models.CharField(), ), distinct=True)
def _trr_count_query(min_datetime, max_datetime): return models.Count(models.Case( models.When(Q(trr__trr_datetime__date__gte=min_datetime, trr__trr_datetime__date__lte=max_datetime), then='trr'), output_field=models.CharField(), ), distinct=True)
def _allegation_internal_count_query(min_datetime, max_datetime): return models.Count(models.Case( models.When(Q( officerallegation__allegation__is_officer_complaint=True, officerallegation__allegation__incident_date__gte=min_datetime, officerallegation__allegation__incident_date__lte=max_datetime), then='officerallegation')), distinct=True)
def complainant_genders(self): query = self.complainant_set.annotate( name=models.Case( models.When(gender='', then=models.Value('Unknown')), default='gender', output_field=models.CharField())) query = query.values('name').distinct() results = [GENDER_DICT.get(result['name'], 'Unknown') for result in query] return results if results else ['Unknown']
def complainant_races(self): query = self.complainant_set.annotate( name=models.Case( models.When(race__in=['n/a', 'n/a ', 'nan', ''], then=models.Value('Unknown')), default='race', output_field=models.CharField())) query = query.values('name').distinct() results = sorted([result['name'] for result in query]) return results if results else ['Unknown']
def category_names(self): query = self.officer_allegations.annotate( name=models.Case( models.When(allegation_category__isnull=True, then=models.Value('Unknown')), default='allegation_category__category', output_field=models.CharField())) query = query.values('name').distinct() results = sorted([result['name'] for result in query]) return results if results else ['Unknown']
def _allegation_count_query(min_datetime, max_datetime): return models.Count(models.Case( models.When(Q( officerallegation__allegation__incident_date__gte=min_datetime, officerallegation__allegation__incident_date__lte=max_datetime), then='officerallegation'), output_field=models.CharField(), ), distinct=True)
def complainant_age_aggregation(self): query = self.officerallegation_set.all() query = query.annotate(name=get_num_range_case( 'allegation__complainant__age', [0, 20, 30, 40, 50]), year=ExtractYear('start_date')) query = query.values('name', 'year').order_by('name', 'year').annotate( count=models.Count('name'), sustained_count=models.Sum( models.Case(models.When(final_finding='SU', then=1), default=models.Value(0), output_field=models.IntegerField()))) return Officer._group_and_sort_aggregations(list(query))