Skip to content
Draft
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
1 change: 1 addition & 0 deletions api/filter_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ class FieldReportFilter(filters.FilterSet):
id = filters.NumberFilter(field_name="id", lookup_expr="exact")
is_covid_report = filters.BooleanFilter(field_name="is_covid_report")
summary = filters.CharFilter(field_name="summary", lookup_expr="icontains")
event = filters.NumberFilter(field_name="event", lookup_expr="exact")

class Meta:
model = FieldReport
Expand Down
5 changes: 4 additions & 1 deletion api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,7 @@ class ListEventSerializer(ModelSerializer):
dtype = DisasterTypeSerializer(required=False)
ifrc_severity_level_display = serializers.CharField(source="get_ifrc_severity_level_display", read_only=True)
active_deployments = serializers.IntegerField(read_only=True)
visibility_display = serializers.CharField(source="get_visibility_display", read_only=True)

class Meta:
model = Event
Expand Down Expand Up @@ -1107,6 +1108,8 @@ class Meta:
"tab_three_title",
"emergency_response_contact_email",
"active_deployments",
"visibility",
"visibility_display",
)


Expand Down Expand Up @@ -2179,7 +2182,7 @@ class FieldReportSerializer(
countries_details = MiniCountrySerializer(source="countries", many=True, read_only=True)
districts_details = MiniDistrictSerializer(source="districts", many=True, read_only=True)
regions_details = RegionSerializer(source="regions", many=True, read_only=True)
event_details = MiniEventSerializer(source="event", read_only=True)
event_details = ListEventSerializer(source="event", read_only=True)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason on changing it to ListEventSerializer?

dtype_details = DisasterTypeSerializer(source="dtype", read_only=True)
external_partners_details = ExternalPartnerSerializer(source="external_partners", many=True, read_only=True)
supported_activities_details = SupportedActivitySerializer(source="supported_activities", many=True, read_only=True)
Expand Down
2 changes: 1 addition & 1 deletion assets
Submodule assets updated 1 files
+37 −2 openapi-schema.yaml
1 change: 1 addition & 0 deletions dref/filter_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class BaseDrefFilterSet(filters.FilterSet):
field_name="disaster_type",
queryset=DisasterType.objects.all(),
)
event = filters.NumberFilter(field_name="event", lookup_expr="exact")
appeal_code = filters.CharFilter(field_name="appeal_code", lookup_expr="icontains")


Expand Down
28 changes: 28 additions & 0 deletions dref/management/commands/migrate_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from django.core.management.base import BaseCommand

from api.models import Appeal, AppealType
from dref.models import Dref


class Command(BaseCommand):
help = "Migrate related Event to Dref"

def handle(self, *args, **options):
self.stdout.write(self.style.NOTICE("Starting migration of events to Dref..."))

appeal_qs = Appeal.objects.filter(atype=AppealType.DREF).exclude(code__isnull=True)

appeal_map = {appeal.code: appeal.event for appeal in appeal_qs if appeal.event}

drefs = Dref.objects.exclude(appeal_code__isnull=True)
self.stdout.write(self.style.NOTICE(f"Total Dref records with appeal code:{drefs.count()}"))
count = 0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
count = 0


for dref in drefs:
event_id = appeal_map.get(dref.appeal_code)
if event_id:
dref.event = event_id
count += 1
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
count += 1


Dref.objects.bulk_update(drefs, ["event"])
self.stdout.write(self.style.SUCCESS(f"Updated {count} Dref records with related Event"))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.stdout.write(self.style.SUCCESS(f"Updated {count} Dref records with related Event"))
updated_dref_count = Dref.objects.bulk_update(drefs, ["event"])
self.stdout.write(self.style.SUCCESS(f"Updated {updated_dref_count} Dref records with related Event"))

20 changes: 20 additions & 0 deletions dref/migrations/0089_dref_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 4.2.29 on 2026-04-06 08:02

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('api', '0230_alter_districtgeoms_district'),
('dref', '0088_remove_identifiedneed_title_ar_and_more'),
]

operations = [
migrations.AddField(
model_name='dref',
name='event',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='dref_event', to='api.event', verbose_name='event'),
),
]
11 changes: 10 additions & 1 deletion dref/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from django.utils.translation import gettext_lazy as _
from pdf2image import convert_from_bytes

from api.models import Country, DisasterType, District, FieldReport
from api.models import Country, DisasterType, District, Event, FieldReport
from deployments.models import Sector
from main.fields import SecureFileField

Expand Down Expand Up @@ -295,6 +295,15 @@ class Status(models.IntegerChoices):
related_name="modified_by_dref",
)
users = models.ManyToManyField(settings.AUTH_USER_MODEL, verbose_name=_("users"), blank=True, related_name="user_dref")

event = models.ForeignKey[Event](
Event,
verbose_name=_("event"),
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="dref_event",
)
field_report = models.ForeignKey(
FieldReport,
verbose_name=_("field report"),
Expand Down
8 changes: 7 additions & 1 deletion dref/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
from drf_spectacular.utils import extend_schema_field
from rest_framework import serializers

from api.models import Appeal
from api.models import Appeal, Event
from api.serializers import (
DisasterTypeSerializer,
ListEventSerializer,
MiniCountrySerializer,
MiniDistrictSerializer,
UserNameSerializer,
Expand Down Expand Up @@ -217,6 +218,7 @@ class MiniDrefSerializer(serializers.ModelSerializer):
operational_update_details = serializers.SerializerMethodField()
final_report_details = serializers.SerializerMethodField()
starting_language = serializers.CharField(read_only=True)
event_detail = ListEventSerializer(source="event", read_only=True)

class Meta:
model = Dref
Expand Down Expand Up @@ -248,6 +250,7 @@ class Meta:
"status_display",
"date_of_approval",
"starting_language",
"event_detail",
]

@extend_schema_field(MiniOperationalUpdateActiveSerializer(many=True))
Expand Down Expand Up @@ -431,6 +434,7 @@ class DrefSerializer(NestedUpdateMixin, NestedCreateMixin, ModelSerializer):
source="contingency_plans_supporting_document", read_only=True, required=False, allow_null=True
)
proposed_action = ProposedActionSerializer(many=True, required=False)
event = serializers.PrimaryKeyRelatedField(queryset=Event.objects.all(), required=False)

class Meta:
model = Dref
Expand Down Expand Up @@ -1598,6 +1602,7 @@ class CompletedDrefOperationsSerializer(serializers.ModelSerializer):
application_type = serializers.SerializerMethodField()
application_type_display = serializers.SerializerMethodField()
starting_language = serializers.CharField(read_only=True)
event_detail = ListEventSerializer(source="dref__event", read_only=True)

class Meta:
model = DrefFinalReport
Expand All @@ -1616,6 +1621,7 @@ class Meta:
"status",
"status_display",
"starting_language",
"event_detail",
)

def get_application_type(self, obj) -> str:
Expand Down
18 changes: 16 additions & 2 deletions dref/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from django.core import management
from rest_framework import status

from api.factories.event import EventFactory
from api.models import Country, DisasterType, District, Region, RegionName
from api.utils import get_model_name
from deployments.factories.project import SectorFactory
Expand Down Expand Up @@ -119,6 +120,7 @@ def test_post_dref_creation(self, send_notification):
old_count = Dref.objects.count()
national_society = Country.objects.create(name="xzz")
disaster_type = DisasterType.objects.create(name="abc")
event = EventFactory.create(name="Test event")
data = {
"title": "Dref test title",
"type_of_onset": Dref.OnsetType.SLOW.value,
Expand Down Expand Up @@ -182,6 +184,7 @@ def test_post_dref_creation(self, send_notification):
"originator_email": "test@gmail.com",
"national_society": national_society.id,
"disaster_type": disaster_type.id,
"event": event.id,
# NOTE: Test Many to Many fields
"risk_security": [
{"risk": "Test Risk 1", "mitigation_measure": "Test Mitigation Measure"},
Expand Down Expand Up @@ -246,6 +249,7 @@ def test_post_dref_creation(self, send_notification):
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 201)
self.assertEqual(Dref.objects.count(), old_count + 1)
self.assertEqual(response.data["event"], event.id)
instance = Dref.objects.get(id=response.data["id"])
instance.users.add(self.user.id)
instance_user_email = [user.email for user in instance.users.all()]
Expand Down Expand Up @@ -1928,10 +1932,14 @@ def test_completed_dref_operations(self):
def test_filter_active_dref(self):
country_1 = Country.objects.create(name="country1")
country_2 = Country.objects.create(name="country2")

event = EventFactory.create(name="Test Event")
# create some dref
dref_1 = DrefFactory.create(
is_active=True, type_of_dref=Dref.DrefType.ASSESSMENT, country=country_1, created_by=self.root_user
is_active=True,
type_of_dref=Dref.DrefType.ASSESSMENT,
country=country_1,
created_by=self.root_user,
event=event,
)
dref_2 = DrefFactory.create(is_active=True, type_of_dref=Dref.DrefType.LOAN, country=country_2, created_by=self.root_user)
# some dref final report
Expand Down Expand Up @@ -1968,6 +1976,12 @@ def test_filter_active_dref(self):
self.assertEqual(len(response.data["results"]), 1)
self.assertEqual(response.data["results"][0]["final_report_details"]["id"], dref_final_report.id)

# filter by event
url = f"/api/v2/active-dref/?event={event.id}"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data["results"]), 1)

def test_dref_share_users(self):
user1 = UserFactory.create(
username="user1@test.com",
Expand Down
Loading