def get(self, request): """Returns serialized data for Activities KPI""" qs = NGReport.objects.filter(report_date__lte=now()) activities = ActivitiesKPIFilter(request.query_params, queryset=qs) weeks = int(request.query_params.get('weeks', KPI_WEEKS)) # Total number of activities to day total = activities.qs.count() # Quarter calculations current_quarter_start = get_quarter()[1] # Total number of activities for current quarter quarter_total = activities.qs.filter( report_date__gte=current_quarter_start).count() # Total number of activities for the previous quarter previous_quarter_end = current_quarter_start - timedelta(days=1) previous_quarter_start = get_quarter(previous_quarter_end)[1] previous_quarter_total = activities.qs.filter( report_date__range=[previous_quarter_start, previous_quarter_end ]).count() diff = quarter_total - previous_quarter_total try: # Percentage change of activities since start of quarter percent_quarter = diff / float(previous_quarter_total) except ZeroDivisionError: if diff > 0: percent_quarter = 100 else: percent_quarter = 0 # Week calculations today = datetime.combine(now().date(), datetime.min.time()) current_week_start = today - timedelta(days=now().weekday()) prev_week_start = current_week_start - timedelta(weeks=1) # Total number of activities this week week_total = activities.qs.filter( report_date__gte=current_week_start).count() query_range = [prev_week_start, current_week_start] # Total number of activities for previous week prev_week_total = activities.qs.filter( report_date__range=query_range).count() diff = week_total - prev_week_total try: # Percentage change of activities compared with previous week percent_week = diff / float(prev_week_total) except ZeroDivisionError: if diff > 0: percent_week = 100 else: percent_week = 0 weekly_count = [] for i in range(weeks): start = current_week_start - timedelta(weeks=i) end = start + timedelta(weeks=1) # Total number of activities (per week) for previous weeks count = activities.qs.filter( report_date__range=[start, end]).count() weekly_count.append({'week': weeks - i, 'activities': count}) kwargs = { 'total': total, 'quarter_total': quarter_total, 'quarter_growth_percentage': percent_quarter * 100, 'week_total': week_total, 'week_growth_percentage': percent_week * 100, 'total_per_week': weekly_count } kpi = namedtuple('ActivitiesKPI', kwargs.keys())(*kwargs.values()) serializer = BaseKPISerializer(kpi) return Response(serializer.data)
def get(self, request): """Returns serialized data for Events KPI""" qs = Event.objects.filter(start__lte=now()) events = EventsKPIFilter(request.query_params, queryset=qs) weeks = int(request.query_params.get('weeks', KPI_WEEKS)) # Total number of events to day total = events.qs.count() # Quarter calculations current_quarter_start = get_quarter()[1] # Total number of events for current quarter quarter_total = events.qs.filter( start__gte=current_quarter_start).count() # Total number of events for the previous quarter previous_quarter_end = current_quarter_start - timedelta(days=1) previous_quarter_start = get_quarter(previous_quarter_end)[1] previous_quarter_total = events.qs.filter( start__range=[previous_quarter_start, previous_quarter_end]).count() diff = quarter_total - previous_quarter_total try: # Percentage change of events since start of quarter percent_quarter = diff/float(previous_quarter_total) except ZeroDivisionError: if diff > 0: percent_quarter = 100 else: percent_quarter = 0 # Week calculations today = datetime.combine(now().date(), datetime.min.time()) current_week_start = today - timedelta(days=now().weekday()) prev_week_start = current_week_start - timedelta(weeks=1) # Total number of events this week week_total = events.qs.filter(start__gte=current_week_start).count() query_range = [prev_week_start, current_week_start] # Total number of events for previous week prev_week_total = events.qs.filter(start__range=query_range).count() diff = week_total - prev_week_total try: # Percentage change of events compared with previous week percent_week = diff/float(prev_week_total) except ZeroDivisionError: if diff > 0: percent_week = 100 else: percent_week = 0 weekly_count = [] for i in range(weeks): start = current_week_start - timedelta(weeks=i) end = start + timedelta(weeks=1) # Total number of events (per week) for previous weeks count = events.qs.filter(start__range=[start, end]).count() weekly_count.append({'week': weeks-i, 'events': count}) kwargs = { 'total': total, 'quarter_total': quarter_total, 'quarter_growth_percentage': percent_quarter*100, 'week_total': week_total, 'week_growth_percentage': percent_week*100, 'total_per_week': weekly_count } kpi = namedtuple('EventsKPI', kwargs.keys())(*kwargs.values()) serializer = BaseKPISerializer(kpi) return Response(serializer.data)
def get(self, request): """Returns serialized data for People KPI.""" queryset = User.objects.filter(groups__name='Rep', userprofile__registration_complete=True) people = PeopleKPIFilter(request.query_params, queryset=queryset) weeks = int(request.query_params.get('weeks', KPI_WEEKS)) # Total number of Reps total = people.count() # Total Reps added in the last quarter joined_date = get_quarter()[1] quarter_total = people.qs.filter( userprofile__date_joined_program__gte=joined_date).count() # Current quarter start current_quarter_start = get_quarter()[1] # Total Reps joined the previous quarter previous_quarter_end = current_quarter_start - timedelta(days=1) previous_quarter_start = get_quarter(previous_quarter_end)[1] total_reps_range = [previous_quarter_start, previous_quarter_end] previous_quarter_total = people.qs.filter( userprofile__date_joined_program__range=total_reps_range).count() diff = quarter_total - previous_quarter_total try: # Percentage change of events compared with previous week quarter_ratio = diff / float(previous_quarter_total) * 100 except ZeroDivisionError: if diff > 0: quarter_ratio = 100 else: quarter_ratio = 0 # Total Reps added this week today = datetime.combine(now().date(), datetime.min.time()) current_week_start = today - timedelta(days=now().weekday()) prev_week_start = current_week_start - timedelta(weeks=1) week_total = people.qs.filter( userprofile__date_joined_program__gte=current_week_start).count() # Total Reps added the previous week query_range = [prev_week_start, current_week_start] prev_week_total = people.qs.filter( userprofile__date_joined_program__range=query_range).count() diff = week_total - prev_week_total try: # Percentage change of events compared with previous week week_ratio = diff / float(prev_week_total) * 100 except ZeroDivisionError: if diff > 0: week_ratio = 100 else: week_ratio = 0 weekly_count = [] for i in range(weeks): start = current_week_start - timedelta(weeks=i) end = start + timedelta(weeks=1) # Total number of reps (per week) for the past 6 weeks count = people.qs.filter( userprofile__date_joined_program__range=[start, end]).count() weekly_count.append({'week': weeks - i, 'people': count}) # Get the number of reports for each user. # Activity metrics: # Inactive: No activity within 8 weeks (4 past, 4 future) # Casual: 1 activity within 8 weeks (4 past, 4 future) # Active: 1 activity within 4 weeks (2 past, 2 future) # Core: 4 activities within 4 weeks (2 past, 2 future) def get_activity_query(query, start_date=None, offset=0, invert=False): if not start_date: start_date = today date_range = [start_date - timedelta(weeks=offset), start_date + timedelta(weeks=offset)] q_args = Q(ng_reports__report_date__range=date_range) if invert: q_args = ~q_args return (query.filter(q_args).distinct() .annotate(num_reports=Count('ng_reports'))) core_active_query = get_activity_query(people.qs, offset=ACTIVE_CORE) # Active contributors - 8 weeks active_contributors = core_active_query.filter(num_reports__gte=ACTIVE, num_reports__lt=CORE) num_active = active_contributors.count() # Core contributors - 8 weeks num_core = core_active_query.filter(num_reports__gte=CORE).count() # Inactive contributors - 16 weeks num_inactive = get_activity_query(people.qs, offset=CASUAL_INACTIVE, invert=True).count() # Casual contributors active_ids = core_active_query.values_list('id', flat=True) num_casual = (get_activity_query(people.qs, offset=CASUAL_INACTIVE) .exclude(id__in=active_ids).count()) weekly_contribution = [] for i in range(weeks): start = current_week_start - timedelta(weeks=i) # Conversion points per week core_active_query = get_activity_query(people.qs, start_date=start, offset=ACTIVE_CORE) # Active contributors active_contributors = core_active_query.filter( num_reports__gte=ACTIVE, num_reports__lt=CORE) active_weekly = active_contributors.count() # Core contributors core_weekly = core_active_query.filter( num_reports__gte=CORE).count() # Inactive contributors inactive_weekly = get_activity_query(people.qs, start_date=start, offset=CASUAL_INACTIVE, invert=True).count() # Casual contributors active_ids = core_active_query.values_list('id', flat=True) casual_weekly = (get_activity_query(people.qs, start_date=start, offset=CASUAL_INACTIVE) .exclude(id__in=active_ids).count()) weekly_contribution.append({'week': weeks - i, 'core': core_weekly, 'active': active_weekly, 'casual': casual_weekly, 'inactive': inactive_weekly }) kwargs = { 'total': total, 'quarter_total': quarter_total, 'quarter_growth_percentage': quarter_ratio, 'week_total': week_total, 'week_growth_percentage': week_ratio, 'total_per_week': weekly_contribution, 'inactive_week': num_inactive, 'casual_week': num_casual, 'active_week': num_active, 'core_week': num_core } kpi = namedtuple('PeopleKPI', kwargs.keys())(*kwargs.values()) serializer = PeopleKPISerializer(kpi) return Response(serializer.data)
def get_quarter_none(self, now_mock): now_mock.return_value = datetime(2015, 6, 15) result = get_quarter() eq_(result[0], 2) eq_(result[1], datetime(2015, 6, 1))
def get_quarter_date(self): d = datetime(2015, 8, 15) result = get_quarter(d) eq_(result[0], 3) eq_(result[1], datetime(2015, 7, 1))
def get(self, request): """Returns serialized data for People KPI.""" queryset = User.objects.filter(groups__name='Rep', userprofile__registration_complete=True) people = PeopleKPIFilter(request.query_params, queryset=queryset) weeks = int(request.query_params.get('weeks', KPI_WEEKS)) # Total number of Reps total = people.count() # Total Reps added in the last quarter joined_date = get_quarter()[1] quarter_total = people.qs.filter( userprofile__date_joined_program__gte=joined_date).count() # Current quarter start current_quarter_start = get_quarter()[1] # Total Reps joined the previous quarter previous_quarter_end = current_quarter_start - timedelta(days=1) previous_quarter_start = get_quarter(previous_quarter_end)[1] total_reps_range = [previous_quarter_start, previous_quarter_end] previous_quarter_total = people.qs.filter( userprofile__date_joined_program__range=total_reps_range).count() diff = quarter_total - previous_quarter_total try: # Percentage change of events compared with previous week quarter_ratio = diff / float(previous_quarter_total) * 100 except ZeroDivisionError: if diff > 0: quarter_ratio = 100 else: quarter_ratio = 0 # Total Reps added this week today = datetime.combine(now().date(), datetime.min.time()) current_week_start = today - timedelta(days=now().weekday()) prev_week_start = current_week_start - timedelta(weeks=1) week_total = people.qs.filter( userprofile__date_joined_program__gte=current_week_start).count() # Total Reps added the previous week query_range = [prev_week_start, current_week_start] prev_week_total = people.qs.filter( userprofile__date_joined_program__range=query_range).count() diff = week_total - prev_week_total try: # Percentage change of events compared with previous week week_ratio = diff / float(prev_week_total) * 100 except ZeroDivisionError: if diff > 0: week_ratio = 100 else: week_ratio = 0 weekly_count = [] for i in range(weeks): start = current_week_start - timedelta(weeks=i) end = start + timedelta(weeks=1) # Total number of reps (per week) for the past 6 weeks count = people.qs.filter( userprofile__date_joined_program__range=[start, end]).count() weekly_count.append({'week': weeks - i, 'people': count}) # Get the number of reports for each user. # Activity metrics: # Inactive: No activity within 8 weeks (4 past, 4 future) # Casual: 1 activity within 8 weeks (4 past, 4 future) # Active: 1 activity within 4 weeks (2 past, 2 future) # Core: 4 activities within 4 weeks (2 past, 2 future) def get_activity_query(query, start_date=None, offset=0, invert=False): if not start_date: start_date = today date_range = [ start_date - timedelta(weeks=offset), start_date + timedelta(weeks=offset) ] q_args = Q(ng_reports__report_date__range=date_range) if invert: q_args = ~q_args return (query.filter(q_args).distinct().annotate( num_reports=Count('ng_reports'))) core_active_query = get_activity_query(people.qs, offset=ACTIVE_CORE) # Active contributors - 8 weeks active_contributors = core_active_query.filter(num_reports__gte=ACTIVE, num_reports__lt=CORE) num_active = active_contributors.count() # Core contributors - 8 weeks num_core = core_active_query.filter(num_reports__gte=CORE).count() # Inactive contributors - 16 weeks num_inactive = get_activity_query(people.qs, offset=CASUAL_INACTIVE, invert=True).count() # Casual contributors active_ids = core_active_query.values_list('id', flat=True) num_casual = (get_activity_query( people.qs, offset=CASUAL_INACTIVE).exclude(id__in=active_ids).count()) weekly_contribution = [] for i in range(weeks): start = current_week_start - timedelta(weeks=i) # Conversion points per week core_active_query = get_activity_query(people.qs, start_date=start, offset=ACTIVE_CORE) # Active contributors active_contributors = core_active_query.filter( num_reports__gte=ACTIVE, num_reports__lt=CORE) active_weekly = active_contributors.count() # Core contributors core_weekly = core_active_query.filter( num_reports__gte=CORE).count() # Inactive contributors inactive_weekly = get_activity_query(people.qs, start_date=start, offset=CASUAL_INACTIVE, invert=True).count() # Casual contributors active_ids = core_active_query.values_list('id', flat=True) casual_weekly = (get_activity_query( people.qs, start_date=start, offset=CASUAL_INACTIVE).exclude(id__in=active_ids).count()) weekly_contribution.append({ 'week': weeks - i, 'core': core_weekly, 'active': active_weekly, 'casual': casual_weekly, 'inactive': inactive_weekly }) kwargs = { 'total': total, 'quarter_total': quarter_total, 'quarter_growth_percentage': quarter_ratio, 'week_total': week_total, 'week_growth_percentage': week_ratio, 'total_per_week': weekly_contribution, 'inactive_week': num_inactive, 'casual_week': num_casual, 'active_week': num_active, 'core_week': num_core } kpi = namedtuple('PeopleKPI', kwargs.keys())(*kwargs.values()) serializer = PeopleKPISerializer(kpi) return Response(serializer.data)