def list(self, request, *args, **kwargs): serializer = TrendTimeInputSerializer(data=request.query_params) serializer.is_valid(raise_exception=True) self.filters = serializer.validated_data results, links = [], {} # Get first and last bank transaction to prevent infinite pager. If # one is missing, it just mean that there is no data at all. first, last = self.get_queryset_dates_delimiters() if first and last: base_date = self.filters['date'] granularity = self.filters['granularity'] # Requested date is out of range? first_range = get_date_ranges(first, granularity)[0] last_range = get_date_ranges(last, granularity)[1] if first_range <= base_date <= last_range: date_start, date_end = get_date_ranges( base_date, granularity, ) balance = self.get_queryset_balance(date_start)['sum'] or 0 balance += self.bankaccount.balance_initial items_qs = self.get_queryset_items(date_start, date_end) items = {item['date']: item for item in items_qs} # Start and end iterator at first/last bank transaction, # not the range calculated. iterator = DateIterator( first if first > date_start else date_start, last if last < date_end else date_end, ) instances = [] for date_step in iterator: delta = percentage = count = 0 # If no new bank transaction, same as previous. if date_step in items: delta = items[date_step]['sum'] percentage = (delta * 100 / balance) if balance else 0 balance += items[date_step]['sum'] count = items[date_step]['count'] instances.append({ 'date': date_step, 'count': count, 'delta': delta, 'balance': balance, 'percentage': percentage, }) results = TrendTimeOuputSerializer(instances, many=True).data paginator = DatePaginator(first_range, last_range, granularity) links = paginator.get_links(base_date, request) return Response({ 'results': results, 'previous': links.get('previous'), 'next': links.get('next'), })