|
6 | 6 | Avg, |
7 | 7 | Case, |
8 | 8 | Count, |
| 9 | + Exists, |
9 | 10 | ExpressionWrapper, |
10 | 11 | F, |
11 | 12 | OuterRef, |
12 | 13 | Prefetch, |
13 | 14 | Q, |
14 | 15 | Subquery, |
15 | 16 | Sum, |
| 17 | + Value, |
16 | 18 | When, |
17 | 19 | ) |
18 | 20 | from django.db.models.fields import IntegerField |
|
59 | 61 | from databank.serializers import CountryOverviewSerializer |
60 | 62 | from deployments.models import ERU, Personnel |
61 | 63 | from deployments.serializers import ListDeployedERUByEventSerializer |
| 64 | +from dref.models import Dref, DrefFinalReport, DrefOperationalUpdate |
62 | 65 | from main.enums import GlobalEnumSerializer, get_enum_values |
63 | 66 | from main.filters import NullsLastOrderingFilter |
64 | 67 | from main.permissions import DenyGuestUserMutationPermission, DenyGuestUserPermission |
|
73 | 76 | Appeal, |
74 | 77 | AppealDocument, |
75 | 78 | AppealHistory, |
| 79 | + AppealStatus, |
76 | 80 | AppealType, |
77 | 81 | Country, |
78 | 82 | CountryKeyDocument, |
|
85 | 89 | Event, |
86 | 90 | EventContact, |
87 | 91 | EventFeaturedDocument, |
| 92 | + EventLink, |
88 | 93 | EventSeverityLevelHistory, |
| 94 | + EventStage, |
89 | 95 | Export, |
90 | 96 | ExternalPartner, |
91 | 97 | FieldReport, |
@@ -749,11 +755,12 @@ def get_queryset(self, *args, **kwargs): |
749 | 755 | qset = super().get_queryset() |
750 | 756 | if self.action == "mini_events": |
751 | 757 | # return Event.objects.filter(parent_event__isnull=True).select_related('dtype') |
752 | | - return qset.filter(parent_event__isnull=True).select_related("dtype") |
| 758 | + return qset.filter(parent_event__isnull=True).select_related("dtype").prefetch_related("countries_for_preview") |
| 759 | + |
753 | 760 | if self.action == "response_activity_events": |
754 | 761 | return ( |
755 | 762 | qset.filter(parent_event__isnull=True) |
756 | | - .filter(Q(auto_generated=False) | Q(source=Event.EventSource.NEW_REPORT)) |
| 763 | + .filter(Q(auto_generated=False) | Q(source=Event.EventSource.NEW_FIELD_REPORT)) |
757 | 764 | .select_related("dtype") |
758 | 765 | ) |
759 | 766 | return ( |
@@ -869,7 +876,11 @@ def retrieve(self, request, pk=None, *args, **kwargs): |
869 | 876 | ) |
870 | 877 | @action(methods=["get"], detail=False, url_path="mini") |
871 | 878 | def mini_events(self, request): |
872 | | - queryset = self.filter_queryset(self.get_queryset()) |
| 879 | + queryset = self.filter_queryset(self.get_queryset()).annotate( |
| 880 | + latest_field_report_id=Subquery( |
| 881 | + FieldReport.objects.filter(event=OuterRef("pk")).order_by("-updated_at").values("id")[:1] |
| 882 | + ) |
| 883 | + ) |
873 | 884 | serializer = ListMiniEventSerializer(queryset, many=True) |
874 | 885 | page = self.paginate_queryset(queryset) |
875 | 886 | if page is not None: |
@@ -1351,7 +1362,7 @@ class SupportedActivityViewset(viewsets.ReadOnlyModelViewSet): |
1351 | 1362 | # summary=report.description or "", |
1352 | 1363 | # disaster_start_date=report.start_date, |
1353 | 1364 | # auto_generated=True, |
1354 | | -# source=Event.EventSource.NEW_REPORT, |
| 1365 | +# source=Event.EventSource.NEW_FIELD_REPORT, |
1355 | 1366 | # visibility=report.visibility, |
1356 | 1367 | # **{TRANSLATOR_ORIGINAL_LANGUAGE_FIELD_NAME: django_get_language()}, |
1357 | 1368 | # ) |
@@ -1559,45 +1570,208 @@ def get_queryset(self): |
1559 | 1570 | return CountrySupportingPartner.objects.select_related("country") |
1560 | 1571 |
|
1561 | 1572 |
|
1562 | | -class EmergencyViewset(ReadOnlyVisibilityViewset): |
| 1573 | +class EmergencyViewset( |
| 1574 | + mixins.RetrieveModelMixin, |
| 1575 | + viewsets.GenericViewSet, |
| 1576 | + ReadOnlyVisibilityViewsetMixin, |
| 1577 | +): |
1563 | 1578 | queryset = Event.objects.all() |
1564 | 1579 | lookup_field = "id" |
1565 | 1580 | serializer_class = DetailEmergencySerializer |
1566 | 1581 | filterset_class = EventFilter |
1567 | | - visibility_model_class = Event |
1568 | 1582 |
|
1569 | 1583 | def get_queryset(self): |
| 1584 | + today = timezone.now().date() |
| 1585 | + |
| 1586 | + appeal_priority_qs = ( |
| 1587 | + Appeal.objects.filter( |
| 1588 | + event=OuterRef("pk"), |
| 1589 | + status__in=[AppealStatus.ACTIVE, AppealStatus.CLOSED], |
| 1590 | + ) |
| 1591 | + .annotate( |
| 1592 | + priority=Case( |
| 1593 | + When(status=AppealStatus.ACTIVE, then=Value(1)), |
| 1594 | + When(status=AppealStatus.CLOSED, then=Value(2)), |
| 1595 | + output_field=IntegerField(), |
| 1596 | + ) |
| 1597 | + ) |
| 1598 | + .order_by("priority", "-start_date") |
| 1599 | + ) |
| 1600 | + |
| 1601 | + active_dref_appeal_qs = appeal_priority_qs.filter( |
| 1602 | + atype=AppealType.DREF, |
| 1603 | + ) |
| 1604 | + |
| 1605 | + active_emergency_appeal_qs = appeal_priority_qs.filter( |
| 1606 | + atype=AppealType.APPEAL, |
| 1607 | + ) |
| 1608 | + |
| 1609 | + field_report_qs = FieldReport.objects.filter(event=OuterRef("pk")) |
| 1610 | + |
| 1611 | + approved_dref_qs = Dref.objects.filter( |
| 1612 | + event=OuterRef("pk"), |
| 1613 | + status=Dref.Status.APPROVED, |
| 1614 | + ) |
| 1615 | + |
| 1616 | + approved_ops_update_qs = DrefOperationalUpdate.objects.filter( |
| 1617 | + dref__event=OuterRef("pk"), |
| 1618 | + status=Dref.Status.APPROVED, |
| 1619 | + ).order_by("-created_at") |
| 1620 | + |
| 1621 | + approved_final_report_qs = DrefFinalReport.objects.filter( |
| 1622 | + dref__event=OuterRef("pk"), |
| 1623 | + status=Dref.Status.APPROVED, |
| 1624 | + ).order_by("-created_at") |
| 1625 | + |
1570 | 1626 | return ( |
1571 | 1627 | super() |
1572 | 1628 | .get_queryset() |
1573 | | - .select_related( |
1574 | | - "dtype", |
1575 | | - "parent_event", |
1576 | | - ) |
1577 | | - .prefetch_related( |
1578 | | - "regions", |
1579 | | - "countries", |
1580 | | - "countries_for_preview", |
1581 | | - Prefetch("key_figures", queryset=KeyFigure.objects.all()), |
1582 | | - Prefetch("contacts", queryset=EventContact.objects.all()), |
| 1629 | + .annotate( |
| 1630 | + # Aggregated Values |
| 1631 | + response_activity_count=Count( |
| 1632 | + "emergency_projects", |
| 1633 | + distinct=True, |
| 1634 | + ), |
| 1635 | + active_deployments_count=Count( |
| 1636 | + "personneldeployment__personnel", |
| 1637 | + filter=Q( |
| 1638 | + personneldeployment__personnel__type=Personnel.TypeChoices.RR, |
| 1639 | + personneldeployment__personnel__start_date__date__lte=today, |
| 1640 | + personneldeployment__personnel__end_date__date__gte=today, |
| 1641 | + personneldeployment__personnel__is_active=True, |
| 1642 | + ), |
| 1643 | + distinct=True, |
| 1644 | + ), |
| 1645 | + surge_alerts_count=Count( |
| 1646 | + "surgealert", |
| 1647 | + distinct=True, |
| 1648 | + ), |
| 1649 | + # Stage |
| 1650 | + stage=Case( |
| 1651 | + When( |
| 1652 | + Exists(active_emergency_appeal_qs), |
| 1653 | + then=Value(EventStage.EMERGENCY_APPEAL), |
| 1654 | + ), |
| 1655 | + When( |
| 1656 | + Exists(approved_final_report_qs), |
| 1657 | + then=Value(EventStage.DREF_FINAL_REPORT), |
| 1658 | + ), |
| 1659 | + When( |
| 1660 | + Exists(approved_ops_update_qs), |
| 1661 | + then=Value(EventStage.DREF_OPERATIONAL_UPDATE), |
| 1662 | + ), |
| 1663 | + When( |
| 1664 | + Exists(approved_dref_qs), |
| 1665 | + then=Value(EventStage.DREF_APPLICATION), |
| 1666 | + ), |
| 1667 | + # If there is an active appeal of DREF type, but no approved DREF yet, |
| 1668 | + # we consider the emergency to be in the Dref Appeal only stage. |
| 1669 | + # Reaches here only if no approved DREF/ops-update/final-report exists |
| 1670 | + # So an active appeal type DREF appeal with no approved DREF = DREF_APPEAL_ONLY stage. |
| 1671 | + When( |
| 1672 | + Exists(active_dref_appeal_qs), |
| 1673 | + then=Value(EventStage.DREF_APPEAL_ONLY), |
| 1674 | + ), |
| 1675 | + When( |
| 1676 | + Exists(FieldReport.objects.filter(event=OuterRef("pk"))), |
| 1677 | + then=Value(EventStage.FIELD_REPORT), |
| 1678 | + ), |
| 1679 | + default=Value(None), |
| 1680 | + output_field=IntegerField(null=True), |
| 1681 | + ), |
1583 | 1682 | ) |
1584 | 1683 | .annotate( |
1585 | | - first_field_report_id=Subquery( |
1586 | | - FieldReport.objects.filter(event=OuterRef("pk")) |
1587 | | - .order_by( |
1588 | | - "fr_num", |
1589 | | - "updated_at", |
1590 | | - ) |
1591 | | - .values("id")[:1] |
| 1684 | + # Passing values for the current stage's instance, |
| 1685 | + # to avoid extra queries in serializer. |
| 1686 | + stage_appeal_id=Case( |
| 1687 | + When( |
| 1688 | + stage=EventStage.EMERGENCY_APPEAL, |
| 1689 | + then=Subquery(active_emergency_appeal_qs.values("id")[:1]), |
| 1690 | + ), |
| 1691 | + When( |
| 1692 | + stage=EventStage.DREF_APPEAL_ONLY, |
| 1693 | + then=Subquery(active_dref_appeal_qs.values("id")[:1]), |
| 1694 | + ), |
| 1695 | + default=Value(None), |
| 1696 | + output_field=IntegerField(null=True), |
1592 | 1697 | ), |
1593 | | - latest_field_report_id=Subquery( |
1594 | | - FieldReport.objects.filter(event=OuterRef("pk")) |
1595 | | - .order_by( |
1596 | | - "-fr_num", |
1597 | | - "-updated_at", |
1598 | | - ) |
1599 | | - .values("id")[:1] |
| 1698 | + stage_dref_id=Case( |
| 1699 | + When( |
| 1700 | + stage__in=[ |
| 1701 | + EventStage.DREF_APPLICATION, |
| 1702 | + EventStage.DREF_OPERATIONAL_UPDATE, |
| 1703 | + EventStage.DREF_FINAL_REPORT, |
| 1704 | + ], |
| 1705 | + then=Subquery(approved_dref_qs.values("id")[:1]), |
| 1706 | + ), |
| 1707 | + default=Value(None), |
| 1708 | + output_field=IntegerField(null=True), |
| 1709 | + ), |
| 1710 | + stage_final_report_id=Case( |
| 1711 | + When( |
| 1712 | + stage=EventStage.DREF_FINAL_REPORT, |
| 1713 | + then=Subquery( |
| 1714 | + DrefFinalReport.objects.filter( |
| 1715 | + dref__id=OuterRef("stage_dref_id"), status=Dref.Status.APPROVED |
| 1716 | + ).values("id")[:1] |
| 1717 | + ), |
| 1718 | + ), |
| 1719 | + default=Value(None), |
| 1720 | + output_field=IntegerField(null=True), |
| 1721 | + ), |
| 1722 | + stage_ops_update_id=Case( |
| 1723 | + When( |
| 1724 | + stage__in=[ |
| 1725 | + EventStage.DREF_OPERATIONAL_UPDATE, |
| 1726 | + EventStage.DREF_FINAL_REPORT, |
| 1727 | + ], |
| 1728 | + then=Subquery( |
| 1729 | + DrefOperationalUpdate.objects.filter( |
| 1730 | + dref__id=OuterRef("stage_dref_id"), status=Dref.Status.APPROVED |
| 1731 | + ).values("id")[:1] |
| 1732 | + ), |
| 1733 | + ), |
| 1734 | + default=Value(None), |
| 1735 | + output_field=IntegerField(null=True), |
| 1736 | + ), |
| 1737 | + stage_field_report_id=Case( |
| 1738 | + When( |
| 1739 | + stage=EventStage.FIELD_REPORT, |
| 1740 | + then=Subquery(field_report_qs.order_by("-updated_at", "-fr_num").values("id")[:1]), |
| 1741 | + ), |
| 1742 | + default=Value(None), |
| 1743 | + output_field=IntegerField(null=True), |
| 1744 | + ), |
| 1745 | + first_field_report_created_at=Subquery(field_report_qs.order_by("created_at", "fr_num").values("created_at")[:1]), |
| 1746 | + latest_field_report_created_at=Subquery( |
| 1747 | + field_report_qs.order_by("-created_at", "-fr_num").values("created_at")[:1] |
| 1748 | + ), |
| 1749 | + ) |
| 1750 | + .select_related("dtype") |
| 1751 | + .prefetch_related( |
| 1752 | + Prefetch( |
| 1753 | + "countries", |
| 1754 | + queryset=Country.objects.select_related("region"), |
| 1755 | + ), |
| 1756 | + Prefetch( |
| 1757 | + "districts", |
| 1758 | + queryset=District.objects.select_related("country"), |
| 1759 | + ), |
| 1760 | + Prefetch( |
| 1761 | + "key_figures", |
| 1762 | + queryset=KeyFigure.objects.all(), |
| 1763 | + ), |
| 1764 | + Prefetch( |
| 1765 | + "contacts", |
| 1766 | + queryset=EventContact.objects.all(), |
| 1767 | + ), |
| 1768 | + Prefetch( |
| 1769 | + "links", |
| 1770 | + queryset=EventLink.objects.all(), |
| 1771 | + ), |
| 1772 | + Prefetch( |
| 1773 | + "featured_documents", |
| 1774 | + queryset=EventFeaturedDocument.objects.order_by("-id"), |
1600 | 1775 | ), |
1601 | | - appeal_id=Subquery(Appeal.objects.filter(event=OuterRef("pk")).order_by("-created_at").values("id")[:1]), |
1602 | 1776 | ) |
1603 | 1777 | ) |
0 commit comments