Skip to content

Commit

Permalink
Merge branch 'master' of github.com:AAISS/AAISS-2023
Browse files Browse the repository at this point in the history
  • Loading branch information
mh-zeynal committed Nov 25, 2023
2 parents 96e8a93 + ed6fa30 commit dd51171
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 48 deletions.
18 changes: 18 additions & 0 deletions backend/backend_api/migrations/0048_presentation_capacity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.4 on 2023-11-24 11:06

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('backend_api', '0047_remove_payment_is_done_payment_status'),
]

operations = [
migrations.AddField(
model_name='presentation',
name='capacity',
field=models.PositiveIntegerField(default=50),
),
]
19 changes: 19 additions & 0 deletions backend/backend_api/migrations/0049_alter_payment_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.2.4 on 2023-11-24 19:06

from django.db import migrations, models
import uuid


class Migration(migrations.Migration):

dependencies = [
('backend_api', '0048_presentation_capacity'),
]

operations = [
migrations.AlterField(
model_name='payment',
name='id',
field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False),
),
]
64 changes: 47 additions & 17 deletions backend/backend_api/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import datetime
import uuid
from urllib.parse import urljoin

from django.contrib.auth.models import AbstractBaseUser
Expand All @@ -9,8 +10,8 @@
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import ValidationError
from rest_framework import status
from rest_framework.response import Response

from aaiss_backend import settings
from aaiss_backend.settings import BASE_URL
Expand Down Expand Up @@ -70,7 +71,7 @@ class Teacher(models.Model):
bio = models.CharField(max_length=BIG_MAX_LENGTH)
order = models.SmallIntegerField(default=0)
year = models.IntegerField(blank=False, default=2020)

def __str__(self):
return f"Teacher with id {self.id}: {self.name}"

Expand Down Expand Up @@ -122,15 +123,24 @@ class Workshop(models.Model):
start_date = models.DateTimeField()
end_date = models.DateTimeField()

def no_of_participants(self):
return len(User.objects.filter(registered_workshops=self).all())
@property
def no_of_participants(self) -> int:
return len(
WorkshopRegistration.objects.filter(workshop=self,
status=WorkshopRegistration.StatusChoices.PURCHASED))

@property
def remaining_capacity(self) -> int:
return max(self.capacity - self.no_of_participants, 0)

@property
def participants(self):
users = []
for user in User.objects.filter(registered_workshops=self).all():
users.append(user)
return users
participants = []
for participant in WorkshopRegistration.objects.filter(workshop=self,
status=
WorkshopRegistration.StatusChoices.PURCHASED):
participants += participant.user
return participants

def __str__(self):
name = ""
Expand All @@ -145,6 +155,7 @@ class Presentation(models.Model):
desc = models.CharField(max_length=BIG_MAX_LENGTH)
year = models.IntegerField(blank=False, default=2020)
cost = models.PositiveIntegerField(default=0)
capacity = models.PositiveIntegerField(default=50)

NOT_ASSIGNED = 'NOT_ASSIGNED'
ELEMENTARY = 'Elementary'
Expand All @@ -166,15 +177,24 @@ class Presentation(models.Model):
start_date = models.DateTimeField()
end_date = models.DateTimeField()

def no_of_participants(self):
return len(User.objects.filter(registered_for_presentations=True).all())
@property
def no_of_participants(self) -> int:
return len(
PresentationParticipation.objects.filter(presentation=self,
status=PresentationParticipation.StatusChoices.PURCHASED))

@property
def remaining_capacity(self) -> int:
return max(self.capacity - self.no_of_participants, 0)

@property
def participants(self):
users = []
for user in User.objects.filter(registered_for_presentations=True).all():
users.append(user)
return users
participants = []
for participant in PresentationParticipation.objects.filter(presentation=self,
status=
PresentationParticipation.StatusChoices.PURCHASED):
participants += participant.user
return participants

def __str__(self):
name = ""
Expand Down Expand Up @@ -294,7 +314,7 @@ class PaymentStatus(models.IntegerChoices):
PAYMENT_CONFIRMED = 1, _('Payment confirmed')
PAYMENT_REJECTED = 2, _('Payment rejected')

id = models.UUIDField(primary_key=True)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
amount = models.PositiveIntegerField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
workshops = models.ManyToManyField(Workshop, blank=True)
Expand Down Expand Up @@ -338,21 +358,31 @@ def create_payment_for_user(user: User):
workshop_registration = workshop.workshopregistration_set.get(workshop_id=workshop.id)
if workshop_registration.status != WorkshopRegistration.StatusChoices.AWAITING_PAYMENT:
continue
if workshop.remaining_capacity <= 0:
raise ValidationError(
new_detailed_response(status.HTTP_400_BAD_REQUEST,
f"Workshop {workshop.id} is full"))
total_cost += workshop.cost
workshops.append(workshop)
except ObjectDoesNotExist:
raise ValueError(f"User {user} is registered for workshop {workshop} but has no registration")
for presentation in user.participated_presentations.all():
try:
presentation_participation = presentation.presentationparticipation_set.get(presentation_id=presentation.id)
presentation_participation = presentation.presentationparticipation_set.get(
presentation_id=presentation.id)
if presentation_participation.status != PresentationParticipation.StatusChoices.AWAITING_PAYMENT:
continue
if presentation.remaining_capacity <= 0:
raise ValidationError(
new_detailed_response(status.HTTP_400_BAD_REQUEST,
f"Presentation {presentation.id} is full"))
total_cost += presentation.cost
presentations.append(presentation)
except ObjectDoesNotExist:
raise ValueError(f"User {user} is registered for presentation {presentation} but has no registration")
if len(workshops) == 0 and len(presentations) == 0:
return None
raise ValidationError(
new_detailed_response(status.HTTP_400_BAD_REQUEST, f"User {user} has no unpaid registrations"))
payment = Payment.objects.create(user=user, amount=total_cost, year=datetime.date.today().year,
date=datetime.datetime.now())
payment.workshops.set(workshops)
Expand Down
18 changes: 16 additions & 2 deletions backend/backend_api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ class Meta:
FieldOfInterestSerializer = all_serializer_creator(models.FieldOfInterest)
TeacherSerializer = all_serializer_creator(models.Teacher)
PresenterSerializer = all_serializer_creator(models.Presenter)
WorkshopSerializer = all_serializer_creator(models.Workshop)
PresentationSerializer = all_serializer_creator(models.Presentation)
MiscSerializer = all_serializer_creator(models.Misc)
CommitteeSerializer = all_serializer_creator(models.Committee)
StaffSerializer = all_serializer_creator(models.Staff)
Expand Down Expand Up @@ -57,6 +55,22 @@ class AllStaffSectionSerializer(serializers.Serializer):
people = serializers.ListField(child=serializers.DictField())


class WorkshopSerializer(serializers.ModelSerializer):
remaining_capacity = serializers.IntegerField()

class Meta:
model = models.Workshop
fields = '__all__'


class PresentationSerializer(serializers.ModelSerializer):
remaining_capacity = serializers.IntegerField()

class Meta:
model = models.Presentation
fields = '__all__'


class WorkshopRegistrationSerializer(serializers.ModelSerializer):
workshop = serializers.PrimaryKeyRelatedField(queryset=WorkshopSerializer.Meta.model.objects.all())

Expand Down
43 changes: 14 additions & 29 deletions backend/backend_api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,53 +93,42 @@ def retrieve(self, request, year=None, pk=None):
return Response(response)


class WorkshopViewSet(viewsets.ViewSet):
class WorkshopViewSet(viewsets.GenericViewSet,
mixins.ListModelMixin,
mixins.RetrieveModelMixin):
serializer_class = serializers.WorkshopSerializer
queryset = models.Workshop.objects.all()

def list(self, request, year=None, **kwargs):
if year is None:
year = datetime.datetime.now().year
queryset = models.Workshop.objects.filter(year=year)
serializer = self.serializer_class(queryset, many=True)
for workshop_data in serializer.data:
workshop = get_object_or_404(queryset, pk=workshop_data['id'])
workshop_data['is_full'] = (
len(models.User.objects.filter(registered_workshops=workshop).all()) >= workshop.capacity)
return Response(serializer.data)
return super().list(request, queryset=queryset, **kwargs)

def retrieve(self, request, year=None, pk=None):
if year is None:
year = datetime.datetime.now().year
queryset = models.Workshop.objects.filter(year=year)
workshop = get_object_or_404(queryset, pk=pk)
serializer = self.serializer_class(workshop)
response = dict(serializer.data)
response['is_full'] = (
len(models.User.objects.filter(registered_workshops=workshop).all()) >= workshop.capacity)
return Response(response)
return super().retrieve(request, pk=pk, queryset=queryset)


class PresentationViewSet(viewsets.ViewSet):
class PresentationViewSet(viewsets.GenericViewSet,
mixins.ListModelMixin,
mixins.RetrieveModelMixin):
serializer_class = serializers.PresentationSerializer
queryset = models.Presentation.objects.all()

def list(self, request, year=None, **kwargs):
if year is None:
year = datetime.datetime.now().year
queryset = models.Presentation.objects.filter(year=year)
serializer = self.serializer_class(queryset, many=True)
total_registered_for_presentation = len(models.User.objects.filter(registered_for_presentations=True).all())
response = list(serializer.data)
response.append(
{'is_full': total_registered_for_presentation >= int(models.Misc.objects.get(pk='presentation_cap').desc)})
return Response(response)
queryset = self.queryset.filter(year=year)
return super().list(request, queryset=queryset, **kwargs)

def retrieve(self, request, year=None, pk=None):
if year is None:
year = datetime.datetime.now().year
queryset = models.Presentation.objects.filter(year=year)
presentation = get_object_or_404(queryset, pk=pk)
serializer = self.serializer_class(presentation)
return Response(serializer.data)
return super().retrieve(request, pk=pk, queryset=queryset)


class MiscViewSet(viewsets.ViewSet):
Expand Down Expand Up @@ -230,11 +219,7 @@ def payment(self, request):
status.HTTP_400_BAD_REQUEST, "User not found"))

payment = Payment.create_payment_for_user(user)
if payment is None:
return Response(new_detailed_response(
status.HTTP_400_BAD_REQUEST, "User has no unpaid item"))

response = ZIFYRequest().create_payment(payment.pk, payment.amount, user.name, user.phone_number,
response = ZIFYRequest().create_payment(str(payment.pk), payment.amount, user.name, user.phone_number,
user.account.email)
if response['status'] == ZIFY_STATUS_OK:
payment.track_id = response['data']['order']
Expand Down

0 comments on commit dd51171

Please sign in to comment.