Skip to content
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
2 changes: 1 addition & 1 deletion assets
Submodule assets updated 1 files
+46 −0 openapi-schema.yaml
6 changes: 5 additions & 1 deletion eap/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from main.writable_nested_serializers import NestedCreateMixin, NestedUpdateMixin
from utils.file_check import validate_file_type

ALLOWED_FILE_EXTENTIONS: list[str] = ["pdf", "docx", "pptx", "xlsx"]
ALLOWED_FILE_EXTENTIONS: list[str] = ["pdf", "docx", "pptx", "xlsx", "xlsm"]


class BaseEAPSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -218,6 +218,10 @@ class EAPFileInputSerializer(serializers.Serializer):
file = serializers.ListField(child=serializers.FileField(required=True))


class EAPGlobalFilesSerializer(serializers.Serializer):
url = serializers.URLField(read_only=True)


class EAPFileSerializer(BaseEAPSerializer):
id = serializers.IntegerField(required=False)
file = serializers.FileField(required=True)
Expand Down
37 changes: 37 additions & 0 deletions eap/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2308,3 +2308,40 @@ def test_snapshot_full_eap(self):
orig_actors[0].description,
snapshot_actors[0].description,
)


class EAPGlobalFileTestCase(APITestCase):
def setUp(self):
super().setUp()
self.url = "/api/v2/eap/global-files/"

def test_get_template_files_invalid_param(self):
self.authenticate()
response = self.client.get(f"{self.url}invalid_type/")
self.assert_400(response)
self.assertIn("detail", response.data)

def test_get_budget_template(self):
self.authenticate()
response = self.client.get(f"{self.url}budget_template/")
self.assert_200(response)
self.assertIn("url", response.data)
self.assertTrue(response.data["url"].endswith("files/eap/budget_template.xlsm"))

def test_get_forecast_table_template(self):
self.authenticate()
response = self.client.get(f"{self.url}forecast_table/")
self.assert_200(response)
self.assertIn("url", response.data)
self.assertTrue(response.data["url"].endswith("files/eap/forecasts_table.docx"))

def test_get_theory_of_change_template(self):
self.authenticate()
response = self.client.get(f"{self.url}theory_of_change_table/")
self.assert_200(response)
self.assertIn("url", response.data)
self.assertTrue(response.data["url"].endswith("files/eap/theory_of_change_table.docx"))

def test_get_template_files_unauthenticated(self):
response = self.client.get(f"{self.url}budget_template/")
self.assert_401(response)
55 changes: 54 additions & 1 deletion eap/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Create your views here.
from django.db.models import Case, F, IntegerField, When
from django.db.models.query import Prefetch, QuerySet
from drf_spectacular.utils import extend_schema
from django.templatetags.static import static
from drf_spectacular.utils import OpenApiParameter, extend_schema
from rest_framework import mixins, permissions, response, status, viewsets
from rest_framework.decorators import action

Expand Down Expand Up @@ -29,6 +30,7 @@
from eap.serializers import (
EAPFileInputSerializer,
EAPFileSerializer,
EAPGlobalFilesSerializer,
EAPRegistrationSerializer,
EAPStatusSerializer,
EAPValidatedBudgetFileSerializer,
Expand Down Expand Up @@ -324,3 +326,54 @@ def multiple_file(self, request):
file_serializer.save()
return response.Response(file_serializer.data, status=status.HTTP_201_CREATED)
return response.Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class EAPGlobalFilesViewSet(
mixins.RetrieveModelMixin,
viewsets.GenericViewSet,
):

serializer_class = EAPGlobalFilesSerializer
permission_classes = permissions.IsAuthenticated, DenyGuestUserPermission

lookup_field = "template_type"
lookup_url_kwarg = "template_type"

template_map = {
"budget_template": "files/eap/budget_template.xlsm",
"forecast_table": "files/eap/forecasts_table.docx",
"theory_of_change_table": "files/eap/theory_of_change_table.docx",
}

@extend_schema(
request=None,
responses=EAPGlobalFilesSerializer,
parameters=[
OpenApiParameter(
name="template_type",
location=OpenApiParameter.PATH,
description="Type of EAP template to download",
required=True,
type=str,
enum=list(template_map.keys()),
)
],
)
def retrieve(self, request, *args, **kwargs):
template_type = kwargs.get("template_type")
if not template_type:
return response.Response(
{
"detail": "Template file type not found.",
},
status=400,
)
if template_type not in self.template_map:
return response.Response(
{
"detail": f"Invalid template file type '{template_type}'.Please use one of the following values:{(self.template_map.keys())}." # noqa
},
status=400,
)
serializer = EAPGlobalFilesSerializer({"url": request.build_absolute_uri(static(self.template_map[template_type]))})
return response.Response(serializer.data)
Binary file added go-static/files/eap/budget_template.xlsm
Binary file not shown.
Binary file added go-static/files/eap/forecasts_table.docx
Binary file not shown.
Binary file added go-static/files/eap/theory_of_change_table.docx
Binary file not shown.
1 change: 1 addition & 0 deletions main/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@
router.register(r"simplified-eap", eap_views.SimplifiedEAPViewSet, basename="simplified_eap")
router.register(r"full-eap", eap_views.FullEAPViewSet, basename="full_eap")
router.register(r"eap-file", eap_views.EAPFileViewSet, basename="eap_file")
router.register(r"eap/global-files", eap_views.EAPGlobalFilesViewSet, basename="eap_global_files")

admin.site.site_header = "IFRC Go administration"
admin.site.site_title = "IFRC Go admin"
Expand Down
Loading