Skip to content

Commit

Permalink
apps/dpnk: add coordinator/approve-payments REST API endpoint
Browse files Browse the repository at this point in the history
* coordinator/fee-approval: add permissions test
  • Loading branch information
michalklimpera committed Jan 25, 2025
1 parent 4482445 commit 08276cd
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 11 deletions.
86 changes: 80 additions & 6 deletions apps/dpnk/rest_coordinator.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
from rest_framework import routers, viewsets, permissions
from rest_framework import routers, viewsets, permissions, serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
import drf_serpy as serpy

from .models import (
UserAttendance,
CompanyAdmin,
Payment,
Status,
)

from .middleware import get_or_create_userattendance
import datetime


class UserAttendanceMixin:
Expand All @@ -28,13 +34,23 @@ class FeeApprovalSerializer(serpy.Serializer):
created = serpy.StrField()


class CompanyAdminDoesNotExist(serializers.ValidationError):
status_code = 403
default_detail = {"company_admin": "User is not company admin"}


class FeeApprovalSet(viewsets.ReadOnlyModelViewSet, UserAttendanceMixin):
def get_queryset(self):
company_admin = CompanyAdmin.objects.get(
userprofile=self.ua().userprofile.pk,
campaign__slug=self.request.subdomain,
company_admin_approved="approved",
)

try:
company_admin = CompanyAdmin.objects.get(
userprofile=self.ua().userprofile.pk,
campaign__slug=self.request.subdomain,
company_admin_approved="approved",
)
except CompanyAdmin.DoesNotExist:
raise CompanyAdminDoesNotExist

queryset = (
UserAttendance.objects.filter(
team__subsidiary__company=company_admin.administrated_company,
Expand Down Expand Up @@ -64,5 +80,63 @@ def get_queryset(self):
permission_classes = [permissions.IsAuthenticated]


class ApprovePaymentsDeserializer(serializers.Serializer):

ids = serializers.ListField(
child=serializers.IntegerField(),
required=True,
)


class ApprovePaymentsView(APIView, UserAttendanceMixin):
def post(self, request, *args, **kwargs):
serializer = ApprovePaymentsDeserializer(data=request.data)
if serializer.is_valid():
ids = serializer.validated_data["ids"]

try:
company_admin = CompanyAdmin.objects.get(
userprofile=self.ua().userprofile.pk,
campaign__slug=self.request.subdomain,
company_admin_approved="approved",
)
except CompanyAdmin.DoesNotExist:
raise CompanyAdminDoesNotExist

users = UserAttendance.objects.filter(
id__in=ids,
team__subsidiary__company=company_admin.administrated_company,
campaign=company_admin.campaign,
userprofile__user__is_active=True,
representative_payment__pay_type="fc",
).exclude(
payment_status="done",
)

approved_count = 0
for user in users:
payment = user.representative_payment
payment.status = Status.COMPANY_ACCEPTS
payment.amount = user.company_admission_fee()
payment.description = (
payment.description
+ "\nFA %s odsouhlasil dne %s"
% (self.request.user.username, datetime.datetime.now())
)
payment.save()
approved_count += 1

return Response(
{
"message": f"Approved {approved_count} payments successfully",
"approved_ids": [user.id for user in users],
},
status=status.HTTP_200_OK,
)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


router = routers.DefaultRouter()
router.register(r"fee-approval", FeeApprovalSet, basename="fee-approval")
# router.register(r"approve-payments", ApprovePaymentsView, basename="approve-payments")
1 change: 0 additions & 1 deletion apps/dpnk/test/test_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3129,7 +3129,6 @@ def test_post(self):
"organization_type": "school",
},
)
from dpnk.models.transactions import Payment

user = User.objects.get(pk=6)
user_profile = UserProfile.objects.get(user=user)
Expand Down
75 changes: 72 additions & 3 deletions apps/dpnk/test/test_rest_coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@

from dpnk.models import (
UserAttendance,
UserProfile,
Status,
)

import json


@override_settings(
SITE_ID=2,
Expand All @@ -29,13 +33,16 @@ def setUp(self):
self.client = APIClient(
HTTP_HOST="testing-campaign.testserver", HTTP_REFERER="test-referer"
)
self.client.force_login(
User.objects.get(pk=3), settings.AUTHENTICATION_BACKENDS[0]
)

self.maxDiff = None
util.rebuild_denorm_models(UserAttendance.objects.filter())

def test_get(self):

self.client.force_login(
User.objects.get(pk=3), settings.AUTHENTICATION_BACKENDS[0]
)

fa = reverse("fee-approval-list")
response = self.client.get(fa)
self.assertEqual(response.status_code, 200)
Expand All @@ -59,3 +66,65 @@ def test_get(self):
],
},
)

def test_permissions(self):
self.client.force_login(
User.objects.get(pk=1), settings.AUTHENTICATION_BACKENDS[0]
)
fa = reverse("fee-approval-list")
response = self.client.get(fa)
self.assertEqual(response.status_code, 403)


@override_settings(
SITE_ID=2,
FAKE_DATE=datetime.date(year=2025, month=1, day=10),
)
class ApprovePaymentsViewTest(TestCase):

fixtures = [
"dump",
]

def setUp(self):
super().setUp()
self.client = APIClient(
HTTP_HOST="testing-campaign.testserver", HTTP_REFERER="test-referer"
)
self.maxDiff = None

def test_post(self):
self.client.force_login(
User.objects.get(pk=3), settings.AUTHENTICATION_BACKENDS[0]
)
post_data = {
"ids": [5, 4],
}
response = self.client.post(
reverse("approve-payments"), post_data, format="json", follow=True
)

self.assertEqual(response.status_code, 200)
self.assertJSONEqual(
response.content.decode(),
{
"message": "Approved 1 payments successfully",
"approved_ids": [5],
},
)

user_attendance = UserAttendance.objects.get(pk=5)
payment = user_attendance.representative_payment
self.assertEqual(payment.status, Status.COMPANY_ACCEPTS)

def test_permissions(self):
self.client.force_login(
User.objects.get(pk=1), settings.AUTHENTICATION_BACKENDS[0]
)
post_data = {
"ids": [5, 4],
}
response = self.client.post(
reverse("approve-payments"), post_data, format="json", follow=True
)
self.assertEqual(response.status_code, 403)
9 changes: 8 additions & 1 deletion apps/dpnk/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
router,
SendRegistrationConfirmationEmail,
)
from .rest_coordinator import router as coordinator_router

from .rest_coordinator import ApprovePaymentsView, router as coordinator_router

from .views import (
answers,
questionnaire_answers,
Expand Down Expand Up @@ -630,4 +632,9 @@
include(coordinator_router.urls),
name="coordinator_rest_api",
),
path(
"rest/coordinator/approve-payments/",
ApprovePaymentsView.as_view(),
name="approve-payments",
),
]

0 comments on commit 08276cd

Please sign in to comment.