Skip to content

Commit

Permalink
feat: init is_enabled for choice
Browse files Browse the repository at this point in the history
  • Loading branch information
AmooHashem committed Nov 4, 2024
1 parent 58ffd8a commit bcdd9cc
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 13 deletions.
7 changes: 5 additions & 2 deletions apps/fsm/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,15 @@ def object(self):
def attributes(self):
return self.object.attributes.all()

def is_enabled(self, user) -> bool:
def is_enabled(self, *args, **kwargs) -> bool:
user = kwargs.get('user')
if not user:
return False
result = False
from apps.attributes.models import Enabled
enabled_attributes = self.attributes.instance_of(Enabled)
for enabled_attribute in enabled_attributes:
if enabled_attribute.is_permitted(user=user):
if enabled_attribute.is_permitted(*args, **kwargs):
result |= enabled_attribute.value
return result

Expand Down
14 changes: 8 additions & 6 deletions apps/fsm/models/fsm.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,23 @@ class FSMCardType(models.TextChoices):
def __str__(self):
return self.name

def get_user_players(self, user):
return Player.objects.filter(user=user, fsm=self)
def is_enabled(self, *args, **kwargs) -> bool:
user = kwargs.get('user')

def is_enabled(self, user) -> bool:
# check is mentor
if user in self.mentors.all():
return True

# check ceil of participation
finished_players = self.get_user_players(
user).filter(finished_at__isnull=False)
finished_players = Player.objects.filter(
user=user,
fsm=self,
finished_at__isnull=False,
)
if finished_players.count() >= self.participant_limit:
return False

return super().is_enabled(user)
return super().is_enabled(user=user)

@transaction.atomic
def clone(self):
Expand Down
6 changes: 6 additions & 0 deletions apps/fsm/models/question_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ class Choice(models.Model):
text = models.TextField()
is_correct = models.BooleanField(default=False)

def is_enabled(self, *args, **kwargs):
player = kwargs.get('player')
answer_sheet = player.answer_sheet
result = False
return result

def __str__(self):
return self.text

Expand Down
5 changes: 2 additions & 3 deletions apps/fsm/views/program_view.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from rest_framework import status
from django.utils import timezone
from django.db.models import Prefetch
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError, ParseError
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated, AllowAny

from apps.fsm.models import Program, Player, RegistrationReceipt
from apps.fsm.models import Program
from apps.fsm.pagination import ProgramsPagination
from apps.fsm.permissions import ProgramAdminPermission
from apps.fsm.serializers.program_serializers import ProgramSerializer, ProgramSummarySerializer
Expand Down Expand Up @@ -115,7 +114,7 @@ def get_user_fsms_status(self, request, slug=None):
'has_active_player': players.filter(finished_at__isnull=True).exists(),
'finished_players_count': players.filter(finished_at__isnull=False).count(),
'is_user_mentor': user in fsm.mentors.all(),
'is_enabled_for_user': fsm.is_enabled(user),
'is_enabled_for_user': fsm.is_enabled(user=user),
})

return Response(fsm_status_list)
Expand Down
1 change: 1 addition & 0 deletions apps/response/serializers/answers/answer_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class ChoiceSerializer(serializers.ModelSerializer):
class Meta:
model = Choice
fields = ['id', 'text', 'is_correct']
read_only_fields = ['id']

def to_internal_value(self, data):
internal_value = super(ChoiceSerializer, self).to_internal_value(data)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from django.db import transaction
from rest_framework.exceptions import ParseError
from apps.widgets.serializers.widget_serializer import WidgetSerializer
from errors.error_codes import serialize_error

from apps.fsm.models import SmallAnswerProblem, MultiChoiceProblem, Choice, UploadFileProblem, BigAnswerProblem, Widget
from apps.response.serializers.answers.answer_serializers import SmallAnswerSerializer, ChoiceSerializer, UploadFileAnswerSerializer
Expand Down Expand Up @@ -69,6 +67,11 @@ def create(self, validated_data):
return instance


def get_active_player(fsm_id, user_id):
from apps.fsm.models import Player
return Player.objects.filter(user__id=user_id, fsm__id=fsm_id, finished_at__isnull=True).last()


class MultiChoiceProblemSerializer(QuestionWidgetSerializer):
choices = ChoiceSerializer(many=True)

Expand All @@ -78,6 +81,21 @@ class Meta(QuestionWidgetSerializer.Meta):
['min_selections', 'max_selections',
'lock_after_answer', 'randomize_choices', 'choices']

def to_representation(self, instance):
representation = super().to_representation(instance)
request = self.context.get('request')
fsm_id = request.headers.get("FSM")
user = request.user
player = get_active_player(fsm_id, user.id)
choices_representation = []
for choice in instance.choices.all():
choices_representation.append({
**ChoiceSerializer(choice).data,
'enabled': choice.is_enabled(user=user, player=player),
})
representation['choices'] = choices_representation
return representation

def create(self, validated_data):
choices_data = validated_data.pop('choices')
validated_data['widget_type'] = Widget.WidgetTypes.MultiChoiceProblem
Expand Down

0 comments on commit bcdd9cc

Please sign in to comment.