mirror of
https://github.com/i701/sarlink-portal-api.git
synced 2025-10-08 09:11:36 +00:00
feat(agreement): add agreement field to user model and implement agreement upload functionality ✨
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 3m2s
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 3m2s
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -163,3 +163,4 @@ cython_debug/
|
|||||||
#staticfiles
|
#staticfiles
|
||||||
staticfiles/
|
staticfiles/
|
||||||
postgres_data/
|
postgres_data/
|
||||||
|
media/
|
22
api/migrations/0018_user_agreement.py
Normal file
22
api/migrations/0018_user_agreement.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-07-24 18:48
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("api", "0017_alter_temporaryuser_t_id_card_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="user",
|
||||||
|
name="agreement",
|
||||||
|
field=models.FileField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Upload the agreement file signed by the user.",
|
||||||
|
null=True,
|
||||||
|
upload_to="agreements/",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
@@ -34,6 +34,13 @@ class User(AbstractUser):
|
|||||||
island = models.ForeignKey(
|
island = models.ForeignKey(
|
||||||
"Island", on_delete=models.SET_NULL, null=True, blank=True, related_name="users"
|
"Island", on_delete=models.SET_NULL, null=True, blank=True, related_name="users"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
agreement = models.FileField(
|
||||||
|
upload_to="agreements/",
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
help_text="Upload the agreement file signed by the user.",
|
||||||
|
)
|
||||||
created_at = models.DateTimeField(default=timezone.now)
|
created_at = models.DateTimeField(default=timezone.now)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
@@ -45,6 +45,7 @@ class UserUpdateSerializer(serializers.ModelSerializer):
|
|||||||
"dob",
|
"dob",
|
||||||
"atoll",
|
"atoll",
|
||||||
"island",
|
"island",
|
||||||
|
"agreement",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -109,6 +110,7 @@ class CustomReadOnlyUserSerializer(serializers.ModelSerializer):
|
|||||||
"address",
|
"address",
|
||||||
"acc_no",
|
"acc_no",
|
||||||
"id_card",
|
"id_card",
|
||||||
|
"agreement",
|
||||||
)
|
)
|
||||||
depth = 1
|
depth = 1
|
||||||
|
|
||||||
|
@@ -23,6 +23,7 @@ from .views import (
|
|||||||
UserVerifyAPIView,
|
UserVerifyAPIView,
|
||||||
UserUpdateAPIView,
|
UserUpdateAPIView,
|
||||||
UserRejectAPIView,
|
UserRejectAPIView,
|
||||||
|
UpdateAgreementView,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -45,6 +46,11 @@ urlpatterns = [
|
|||||||
path("users/temp/filter/", filter_temporary_user, name="filter-temporary-users"),
|
path("users/temp/filter/", filter_temporary_user, name="filter-temporary-users"),
|
||||||
# User verification flow
|
# User verification flow
|
||||||
path("users/<int:pk>/verify/", UserVerifyAPIView.as_view(), name="user-verify"),
|
path("users/<int:pk>/verify/", UserVerifyAPIView.as_view(), name="user-verify"),
|
||||||
|
path(
|
||||||
|
"users/<int:pk>/agreement/",
|
||||||
|
UpdateAgreementView.as_view(),
|
||||||
|
name="user-agreement",
|
||||||
|
),
|
||||||
path("users/<int:pk>/reject/", UserRejectAPIView.as_view(), name="user-reject"),
|
path("users/<int:pk>/reject/", UserRejectAPIView.as_view(), name="user-reject"),
|
||||||
path("healthcheck/", healthcheck, name="healthcheck"),
|
path("healthcheck/", healthcheck, name="healthcheck"),
|
||||||
path("test/", test_email, name="testemail"),
|
path("test/", test_email, name="testemail"),
|
||||||
|
45
api/views.py
45
api/views.py
@@ -358,6 +358,51 @@ class UserUpdateAPIView(StaffEditorPermissionMixin, generics.UpdateAPIView):
|
|||||||
return super().update(request, *args, **kwargs)
|
return super().update(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateAgreementView(StaffEditorPermissionMixin, generics.UpdateAPIView):
|
||||||
|
serializer_class = UserUpdateSerializer
|
||||||
|
queryset = User.objects.all()
|
||||||
|
lookup_field = "pk"
|
||||||
|
|
||||||
|
def update(self, request, *args, **kwargs):
|
||||||
|
user_id = kwargs.get("pk")
|
||||||
|
user = get_object_or_404(User, pk=user_id)
|
||||||
|
agreement_file = request.data.get("agreement_file")
|
||||||
|
if not agreement_file:
|
||||||
|
return Response(
|
||||||
|
{"message": "Agreement file is required."},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
if agreement_file.size > 10 * 1024 * 1024: # 5 MB limit
|
||||||
|
return Response(
|
||||||
|
{"message": "File size exceeds 10 MB limit."},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
if agreement_file.content_type not in [
|
||||||
|
"application/pdf",
|
||||||
|
]:
|
||||||
|
return Response(
|
||||||
|
{"message": "Invalid file type. Only PDF files are allowed."},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
if request.user != user and (
|
||||||
|
not request.user.is_authenticated
|
||||||
|
or not getattr(request.user, "is_admin", False)
|
||||||
|
):
|
||||||
|
return Response(
|
||||||
|
{"message": "You are not authorized to update this user."},
|
||||||
|
status=status.HTTP_403_FORBIDDEN,
|
||||||
|
)
|
||||||
|
serializer = self.get_serializer(
|
||||||
|
user,
|
||||||
|
data=request.data,
|
||||||
|
partial=True,
|
||||||
|
)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
user.agreement = agreement_file
|
||||||
|
user.save()
|
||||||
|
return super().update(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class KnoxTokenListApiView(
|
class KnoxTokenListApiView(
|
||||||
StaffEditorPermissionMixin,
|
StaffEditorPermissionMixin,
|
||||||
generics.ListAPIView,
|
generics.ListAPIView,
|
||||||
|
Reference in New Issue
Block a user