|
1 | 1 | import requests |
| 2 | +from django.utils import timezone |
| 3 | +from django.db.models import Q, F, FloatField |
| 4 | +from django.db.models.functions import Cast |
2 | 5 | from django.conf import settings |
3 | 6 | from django.utils.decorators import method_decorator |
4 | 7 | from django.views.decorators.cache import cache_page |
@@ -56,10 +59,11 @@ class CampaignsAPI(APIView, CustomSizePageNumberPagination): |
56 | 59 | type=str, |
57 | 60 | ), |
58 | 61 | OpenApiParameter( |
59 | | - name="active", |
| 62 | + name="status", |
60 | 63 | description="Filter by active campaigns (true/false)", |
61 | 64 | required=False, |
62 | | - type=bool, |
| 65 | + type=str, |
| 66 | + enum=["active", "upcoming", "ended", "unfufilled"], |
63 | 67 | ), |
64 | 68 | ], |
65 | 69 | responses={ |
@@ -94,25 +98,37 @@ def get(self, request: Request, *args, **kwargs): |
94 | 98 |
|
95 | 99 | token = request.query_params.get('token') |
96 | 100 | if token: |
97 | | - if token.lower() == 'near': |
98 | | - queryset = queryset.filter(token__isnull=True) |
99 | | - else: |
100 | | - queryset = queryset.filter(token__account__id=token) |
| 101 | + queryset = queryset.filter(token__account__id=token.lower()) |
101 | 102 |
|
102 | | - active = request.query_params.get('active') |
103 | | - if active is not None: |
104 | | - from django.utils import timezone |
105 | | - from django.db import models |
| 103 | + status = request.query_params.get('status') |
| 104 | + if status: |
106 | 105 | now = timezone.now() |
107 | | - if active.lower() == 'true': |
| 106 | + status = status.lower() |
| 107 | + queryset = queryset.annotate( |
| 108 | + cast_net_raised=Cast('net_raised_amount', FloatField()), |
| 109 | + cast_max_amount=Cast('max_amount', FloatField()), |
| 110 | + cast_target=Cast('target_amount', FloatField()) |
| 111 | + ) |
| 112 | + if status == 'upcoming': |
| 113 | + queryset = queryset.filter(start_at__gt=now) |
| 114 | + elif status == 'active': |
108 | 115 | queryset = queryset.filter( |
109 | | - start_at__lte=now, |
110 | | - end_at__gte=now |
111 | | - ) |
112 | | - else: |
| 116 | + start_at__lte=now |
| 117 | + ).filter( |
| 118 | + Q(end_at__isnull=True) | Q(end_at__gt=now) |
| 119 | + ).filter( |
| 120 | + Q(max_amount__isnull=True) | Q(cast_net_raised__lt=F('cast_max_amount')) |
| 121 | + ) |
| 122 | + elif status == 'ended': |
113 | 123 | queryset = queryset.filter( |
114 | | - models.Q(start_at__gt=now) | models.Q(end_at__lt=now) |
115 | | - ) |
| 124 | + Q(end_at__isnull=False, end_at__lte=now) | |
| 125 | + Q(max_amount__isnull=False, cast_net_raised__gte=F('cast_max_amount')) |
| 126 | + ) |
| 127 | + elif status == 'unfufilled': |
| 128 | + queryset = queryset.filter( |
| 129 | + Q(end_at__isnull=False, end_at__lte=now), |
| 130 | + cast_net_raised__lt=F('cast_target') |
| 131 | + ) |
116 | 132 |
|
117 | 133 | # Paginate results |
118 | 134 | page = self.paginate_queryset(queryset, request) |
|
0 commit comments