def complainant_race_aggregation(self): query_set = Complainant.objects.filter( allegation__officerallegation__officer__officerhistory__unit=self ).distinct().annotate(name=models.Case( models.When(race__isnull=True, then=models.Value('Unknown')), models.When(race__in=['n/a', 'n/a ', 'nan', ''], then=models.Value('Unknown')), default='race', output_field=models.CharField())).values('name').annotate( count=models.Count('id', distinct=True)) sustained_count_query_set = Complainant.objects.filter( allegation__officerallegation__officer__officerhistory__unit=self, allegation__officerallegation__final_finding='SU').distinct( ).annotate(name=models.Case( models.When(race__isnull=True, then=models.Value('Unknown')), models.When(race__in=['n/a', 'n/a ', 'nan', ''], then=models.Value('Unknown')), default='race', output_field=models.CharField())).values('name').annotate( sustained_count=models.Count('id', distinct=True)) sustained_count_results = { obj['name']: obj['sustained_count'] for obj in sustained_count_query_set } return [{ 'name': obj['name'], 'count': obj['count'], 'sustained_count': sustained_count_results.get(obj['name'], 0) } for obj in query_set if obj['count'] > 0]
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 _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_set = Complainant.objects.filter( allegation__officerallegation__officer__officerhistory__unit=self ).distinct().annotate(complainant_gender=models.Case( models.When(gender='', then=models.Value('Unknown')), default='gender', output_field=models.CharField())).values( 'complainant_gender').annotate( count=models.Count('id', distinct=True)) sustained_count_query_set = Complainant.objects.filter( allegation__officerallegation__officer__officerhistory__unit=self, allegation__officerallegation__final_finding='SU').distinct( ).annotate(complainant_gender=models.Case( models.When(gender='', then=models.Value('Unknown')), default='gender', output_field=models.CharField())).values( 'complainant_gender').annotate( sustained_count=models.Count('id', distinct=True)) sustained_count_results = { obj['complainant_gender']: obj['sustained_count'] for obj in sustained_count_query_set } return [{ 'name': GENDER_DICT.get(obj['complainant_gender'], 'Unknown'), 'count': obj['count'], 'sustained_count': sustained_count_results.get(obj['complainant_gender'], 0) } for obj in query_set if obj['count'] > 0]
def member_race_aggregation(self): query_set = Officer.objects.filter( officerhistory__unit=self).distinct().annotate(name=models.Case( models.When(race__isnull=True, then=models.Value('Unknown')), models.When(race__in=['n/a', 'n/a ', 'nan', ''], then=models.Value('Unknown')), default='race', output_field=models.CharField())).values('name').annotate( count=models.Count('id', distinct=True)) return list(query_set)
def member_gender_aggregation(self): query_set = Officer.objects.filter(officerhistory__unit=self).distinct( ).annotate(member_gender=models.Case( models.When(gender='', then=models.Value('Unknown')), models.When(gender__isnull=True, then=models.Value('Unknown')), default='gender', output_field=models.CharField())).values('member_gender').annotate( count=models.Count('id', distinct=True)) return [{ 'name': GENDER_DICT.get(obj['member_gender'], 'Unknown'), 'count': obj['count'] } for obj in query_set if obj['count'] > 0]
def complaint_category_aggregation(self): query_set = OfficerAllegation.objects.filter( officer__officerhistory__unit=self).distinct().annotate( name=models.Case( models.When(allegation_category__category__isnull=True, then=models.Value('Unknown')), default='allegation_category__category', output_field=models.CharField())).values('name').annotate( count=models.Count('allegation__crid', distinct=True), sustained_count=models.Sum( models.Case(models.When(final_finding='SU', then=1), default=0, output_field=models.IntegerField()))) return list(query_set)
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 get_aggregated_payments(self, obj): current_year = CURRENT_YEAR[obj.country] p = obj.pharmapayment_set.filter(date__year=current_year) result = (p.annotate(individual_recipient=models.Case( models.When(recipient__isnull=False, then=True), default=False, output_field=models.BooleanField()) ).values('recipient_kind', 'label', 'individual_recipient') .annotate(amount=models.Sum('amount')) ) df = pd.DataFrame(list(result)) if len(df) == 0: return None rnd_amount = df[df['label'] == 'research_development']['amount'].sum() max_kind_amount = df.groupby('recipient_kind')['amount'].sum().max() if pd.isnull(max_kind_amount): max_kind_amount = 0.0 max_amount = max(rnd_amount, max_kind_amount) totals_ind_agg = df.groupby('individual_recipient')['amount'].sum() total = df['amount'].sum() return { 'total': total, 'currency': PharmaPayment.ORIGIN_CURRENCY[obj.country], 'rnd': rnd_amount, 'rnd_percent': perc(rnd_amount, max_amount), 'total_individual_percent': perc(totals_ind_agg.get(True, 0), total), 'total_aggregated_percent': perc(totals_ind_agg.get(False, 0), total), 'hcp': self._get_type_aggregation(obj, df, 0, max_amount), 'hco': self._get_type_aggregation(obj, df, 1, max_amount), }
def annotate_investigated_by_cpd(self): Allegation = apps.get_app_config('data').get_model('Allegation') return self.annotate(has_badge_number=Exists( Allegation.objects.filter( crid=OuterRef('allegation_id'), investigatorallegation__investigator__officer__officerbadgenumber__isnull =False))).annotate(has_current_star=Exists( Allegation.objects.filter( crid=OuterRef('allegation_id'), investigatorallegation__current_star__isnull=False) )).annotate(investigated_by_cpd=models.Case( models.When(allegation__incident_date__year__lt=2006, then=True), models.When(has_current_star=True, then=True), models.When(has_badge_number=True, then=True), default=False, output_field=models.BooleanField()))
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 _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 _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 _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 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 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 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 member_age_aggregation(self): query_set = Officer.objects.filter(officerhistory__unit=self).distinct( ).annotate(member_age=models.Case( models.When(birth_year__isnull=True, then=None), default=now().year - F('birth_year'), output_field=models.IntegerField())).annotate( name=get_num_range_case('member_age', [0, 20, 30, 40, 50]) ).values('name').annotate(count=models.Count('id', distinct=True)) return list(query_set)
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))