Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix duplicate stats generation in country page #2173

Merged
merged 2 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 79 additions & 46 deletions api/drf_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,37 +262,58 @@ def get_databank(self, request, pk):
)
def get_country_figure(self, request, pk):
country = self.get_object()
end_date = timezone.now()
start_date = end_date + timedelta(days=-2 * 365)
start_date = request.GET.get("start_date", start_date)
end_date = request.GET.get("end_date", end_date)
appeal_conditions = Q(atype=AppealType.APPEAL)

all_appealhistory = AppealHistory.objects.select_related("appeal").filter(appeal__code__isnull=False)
all_appealhistory = all_appealhistory.filter(country=country)
if start_date and end_date:
all_appealhistory = all_appealhistory.filter(start_date__lte=end_date, end_date__gte=start_date)

now = timezone.now()
start_date_from = request.GET.get("start_date_from", timezone.now() + timedelta(days=-2 * 365))
start_date_to = request.GET.get("start_date_to", timezone.now())

appeal_conditions = Q(atype=AppealType.APPEAL) | Q(atype=AppealType.INTL)

all_appealhistory = AppealHistory.objects.select_related("appeal").filter(
country=country,
appeal__code__isnull=False,
valid_from__lt=now, # TODO: Allow user to provide this?
valid_to__gt=now, # TODO: Allow user to provide this?
)
if start_date_from and start_date_to:
all_appealhistory = all_appealhistory.filter(
start_date__gte=start_date_from,
start_date__lte=start_date_to,
)

appeals_aggregated = all_appealhistory.annotate(
appeal_with_dref=Count(
Case(
When(Q(atype=AppealType.DREF), then=1),
output_field=IntegerField(),
)
),
appeal_without_dref=Count(Case(When(Q(atype=AppealType.APPEAL), then=1), output_field=IntegerField()), distinct=True),
appeal_without_dref=Count(Case(When(appeal_conditions, then=1), output_field=IntegerField())),
total_population=(
Case(
When(appeal_conditions | Q(atype=AppealType.DREF), then=F("num_beneficiaries")),
output_field=IntegerField(),
)
),
amount_requested_all=(
Case(
When(appeal_conditions, then=F("amount_requested")),
output_field=IntegerField(),
)
),
amordref=(
Case(
When(appeal_conditions | Q(atype=AppealType.DREF), then=F("amount_requested")),
output_field=IntegerField(),
)
),
amount_funded_all=(
amof=(
Case(
When(appeal_conditions, then=F("amount_funded")),
output_field=IntegerField(),
)
),
amofdref=(
Case(
When(appeal_conditions | Q(atype=AppealType.DREF), then=F("amount_funded")),
output_field=IntegerField(),
Expand All @@ -303,8 +324,10 @@ def get_country_figure(self, request, pk):
active_drefs=Sum("appeal_with_dref"),
active_appeals=Sum("appeal_without_dref"),
target_population=Sum("total_population"),
total_amount_requested=Sum("amount_requested_all"),
total_amount_funded=Sum("amount_funded_all"),
amount_requested=Sum("amount_requested_all"),
amount_requested_dref_included=Sum("amordref"),
amount_funded=Sum("amof"),
amount_funded_dref_included=Sum("amofdref"),
emergencies=Sum("emergencies_count"),
)
return Response(CountryKeyFigureSerializer(appeals_aggregated).data)
Expand All @@ -318,10 +341,9 @@ def get_country_figure(self, request, pk):
@action(detail=True, url_path="disaster-count", pagination_class=None)
def get_country_disaster_count(self, request, pk):
country = self.get_object()
end_date = timezone.now()
start_date = end_date + timedelta(days=-2 * 365)
start_date = request.GET.get("start_date", start_date)
end_date = request.GET.get("end_date", end_date)

start_date_from = request.GET.get("start_date_from", timezone.now() + timedelta(days=-2 * 365))
start_date_to = request.GET.get("start_date_to", timezone.now())

queryset = (
Event.objects.filter(
Expand All @@ -337,8 +359,12 @@ def get_country_disaster_count(self, request, pk):
.order_by("countries", "dtype__name")
)

if start_date and end_date:
queryset = queryset.filter(disaster_start_date__gte=start_date, disaster_start_date__lte=end_date)
if start_date_from and start_date_to:
queryset = queryset.filter(
disaster_start_date__gte=start_date_from,
disaster_start_date__lte=start_date_to,
)

return Response(CountryDisasterTypeCountSerializer(queryset, many=True).data)

@extend_schema(
Expand All @@ -349,16 +375,16 @@ def get_country_disaster_count(self, request, pk):
@action(detail=True, url_path="disaster-monthly-count", pagination_class=None)
def get_country_disaster_monthly_count(self, request, pk):
country = self.get_object()
end_date = timezone.now()
start_date = end_date + timedelta(days=-2 * 365)
start_date = request.GET.get("start_date", start_date)
end_date = request.GET.get("end_date", end_date)

start_date_from = request.GET.get("start_date_from", timezone.now() + timedelta(days=-2 * 365))
start_date_to = request.GET.get("start_date_to", timezone.now())

queryset = (
Event.objects.filter(
countries__in=[country.id],
dtype__isnull=False,
)
.annotate(date=TruncMonth("created_at"))
.annotate(date=TruncMonth("disaster_start_date"))
.values("date", "countries", "dtype")
.annotate(
appeal_targeted_population=Coalesce(
Expand Down Expand Up @@ -391,8 +417,11 @@ def get_country_disaster_monthly_count(self, request, pk):
.order_by("date", "countries", "dtype__name")
)

if start_date and end_date:
queryset = queryset.filter(disaster_start_date__gte=start_date, disaster_start_date__lte=end_date)
if start_date_from and start_date_to:
queryset = queryset.filter(
disaster_start_date__gte=start_date_from,
disaster_start_date__lte=start_date_to,
)

return Response(CountryDisasterTypeMonthlySerializer(queryset, many=True).data)

Expand All @@ -404,18 +433,18 @@ def get_country_disaster_monthly_count(self, request, pk):
@action(detail=True, url_path="historical-disaster", pagination_class=None)
def get_country_historical_disaster(self, request, pk):
country = self.get_object()
end_date = timezone.now()
start_date = end_date + timedelta(days=-2 * 365)
start_date = request.GET.get("start_date", start_date)
end_date = request.GET.get("end_date", end_date)

start_date_from = request.GET.get("start_date_from", timezone.now() + timedelta(days=-2 * 365))
start_date_to = request.GET.get("start_date_to", timezone.now())

dtype = request.GET.get("dtype", None)

queryset = (
Event.objects.filter(
countries__in=[country.id],
dtype__isnull=False,
)
.annotate(date=TruncMonth("created_at"))
.annotate(date=TruncMonth("disaster_start_date"))
.values("date", "dtype", "countries")
.annotate(
appeal_targeted_population=Coalesce(
Expand Down Expand Up @@ -450,8 +479,11 @@ def get_country_historical_disaster(self, request, pk):
.order_by("date", "countries", "dtype__name")
)

if start_date and end_date:
queryset = queryset.filter(disaster_start_date__gte=start_date, disaster_start_date__lte=end_date)
if start_date_from and start_date_to:
queryset = queryset.filter(
disaster_start_date__gte=start_date_from,
disaster_start_date__lte=start_date_to,
)

if dtype:
queryset = queryset.filter(dtype=dtype)
Expand Down Expand Up @@ -744,15 +776,14 @@ def get_serializer_class(self):
class AppealViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
"""Used to get Appeals from AppealHistory. Has no 'read' option, just 'list'."""

# queryset = Appeal.objects.select_related('dtype', 'country', 'region').all()
# queryset = AppealHistory.objects.select_related('appeal__event', 'dtype', 'country', 'region').all()
queryset = AppealHistory.objects.select_related("appeal__event", "dtype", "country", "region").filter(
appeal__code__isnull=False
)
# serializer_class = AppealSerializer
queryset = AppealHistory.objects.select_related(
"appeal__event",
"dtype",
"country",
"region",
).filter(appeal__code__isnull=False)
serializer_class = AppealHistorySerializer
ordering_fields = "__all__"
# filterset_class = AppealFilter
filterset_class = AppealHistoryFilter
search_fields = (
"appeal__name",
Expand All @@ -762,9 +793,7 @@ class AppealViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
def get_serializer_class(self):
if is_tableau(self.request) is True:
return AppealHistoryTableauSerializer
# return AppealTableauSerializer
return AppealHistorySerializer
# return AppealSerializer

def remove_unconfirmed_event(self, obj):
if obj["needs_confirmation"]:
Expand All @@ -776,9 +805,13 @@ def remove_unconfirmed_events(self, objs):

# Overwrite to exclude the events which require confirmation
def list(self, request, *args, **kwargs):
now = timezone.now()
date = request.GET.get("date", now)
queryset = self.filter_queryset(self.get_queryset()).filter(valid_from__lt=date, valid_to__gt=date)
date = request.GET.get("date", timezone.now())
queryset = self.filter_queryset(
self.get_queryset().filter(
valid_from__lt=date,
valid_to__gt=date,
)
)

page = self.paginate_queryset(queryset)
if page is not None:
Expand Down
24 changes: 24 additions & 0 deletions api/filter_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,38 @@ class AppealFilter(filters.FilterSet):
code = filters.CharFilter(field_name="code", lookup_expr="exact")
status = filters.NumberFilter(field_name="status", lookup_expr="exact")
id = filters.NumberFilter(field_name="id", lookup_expr="exact")
appeal_id = filters.NumberFilter(
field_name="appeal_id", lookup_expr="exact", help_text="Use this (or code) for appeal identification."
)
district = filters.ModelMultipleChoiceFilter(
field_name="country__district", queryset=District.objects.all(), label="district", method="get_country_district"
)
admin2 = filters.ModelMultipleChoiceFilter(
field_name="country__district__admin2",
queryset=Admin2.objects.all(),
label="admin2",
method="get_country_admin2",
)

class Meta:
model = Appeal
fields = {
"start_date": ("exact", "gt", "gte", "lt", "lte"),
"end_date": ("exact", "gt", "gte", "lt", "lte"),
"real_data_update": ("exact", "gt", "gte", "lt", "lte"),
"country__iso3": ("exact",),
}

def get_country_district(self, qs, name, value):
if value:
return qs.filter(country__district=value).distinct()
return qs

def get_country_admin2(self, qs, name, value):
if value:
return qs.filter(country__district__admin2=value).distinct()
return qs


class AppealHistoryFilter(filters.FilterSet):
atype = filters.NumberFilter(field_name="atype", lookup_expr="exact")
Expand Down
11 changes: 7 additions & 4 deletions api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2118,6 +2118,7 @@ class AggregateHeaderFiguresSerializer(serializers.Serializer):
amount_requested = serializers.IntegerField()
amount_requested_dref_included = serializers.IntegerField()
amount_funded = serializers.IntegerField()
amount_funded_dref_included = serializers.IntegerField()


# SearchPage Serializer
Expand Down Expand Up @@ -2292,8 +2293,8 @@ class AggregateByDtypeSerializer(serializers.Serializer):


class CountryKeyFigureInputSerializer(serializers.Serializer):
start_date = serializers.DateField(required=False)
end_date = serializers.DateField(required=False)
start_date_from = serializers.DateField(required=False)
start_date_to = serializers.DateField(required=False)
dtype = serializers.IntegerField(required=False)


Expand All @@ -2304,9 +2305,11 @@ class CountryKeyClimateInputSerializer(serializers.Serializer):
class CountryKeyFigureSerializer(serializers.Serializer):
active_drefs = serializers.IntegerField()
active_appeals = serializers.IntegerField()
amount_requested = serializers.IntegerField()
target_population = serializers.IntegerField()
total_amount_requested = serializers.IntegerField()
total_amount_funded = serializers.IntegerField()
amount_requested_dref_included = serializers.IntegerField()
amount_funded = serializers.IntegerField()
amount_funded_dref_included = serializers.IntegerField()
emergencies = serializers.IntegerField()


Expand Down
Loading