conflict resolved

This commit is contained in:
abutalib-kiwi
2023-08-09 17:03:42 +05:30
21 changed files with 596 additions and 90 deletions

View File

@ -245,7 +245,6 @@ class ForgotPasswordAPIView(views.APIView):
class SendPhoneOtp(viewsets.ModelViewSet): class SendPhoneOtp(viewsets.ModelViewSet):
"""Send otp on phone""" """Send otp on phone"""
queryset = UserPhoneOtp.objects.all()
serializer_class = UserPhoneOtpSerializer serializer_class = UserPhoneOtpSerializer
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
otp = generate_otp() otp = generate_otp()
@ -262,7 +261,6 @@ class SendPhoneOtp(viewsets.ModelViewSet):
class UserPhoneVerification(viewsets.ModelViewSet): class UserPhoneVerification(viewsets.ModelViewSet):
"""Send otp on phone""" """Send otp on phone"""
queryset = UserPhoneOtp.objects.all()
serializer_class = UserPhoneOtpSerializer serializer_class = UserPhoneOtpSerializer
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
try: try:
@ -368,7 +366,6 @@ class AdminLoginViewSet(viewsets.GenericViewSet):
class UserEmailVerification(viewsets.ModelViewSet): class UserEmailVerification(viewsets.ModelViewSet):
"""User Email verification""" """User Email verification"""
serializer_class = EmailVerificationSerializer serializer_class = EmailVerificationSerializer
queryset = UserEmailOtp.objects.all()
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
try: try:
@ -411,7 +408,6 @@ class UserEmailVerification(viewsets.ModelViewSet):
class ReSendEmailOtp(viewsets.ModelViewSet): class ReSendEmailOtp(viewsets.ModelViewSet):
"""Send otp on phone""" """Send otp on phone"""
queryset = UserEmailOtp.objects.all()
serializer_class = EmailVerificationSerializer serializer_class = EmailVerificationSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
@ -434,7 +430,6 @@ class ReSendEmailOtp(viewsets.ModelViewSet):
class ProfileAPIViewSet(viewsets.ModelViewSet): class ProfileAPIViewSet(viewsets.ModelViewSet):
"""Profile viewset""" """Profile viewset"""
queryset = User.objects.all()
serializer_class = JuniorProfileSerializer serializer_class = JuniorProfileSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
@ -453,7 +448,6 @@ class ProfileAPIViewSet(viewsets.ModelViewSet):
class UploadImageAPIViewSet(viewsets.ModelViewSet): class UploadImageAPIViewSet(viewsets.ModelViewSet):
"""upload task image""" """upload task image"""
queryset = DefaultTaskImages.objects.all()
serializer_class = DefaultTaskImagesSerializer serializer_class = DefaultTaskImagesSerializer
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
"""upload images""" """upload images"""
@ -472,7 +466,6 @@ class UploadImageAPIViewSet(viewsets.ModelViewSet):
class DefaultImageAPIViewSet(viewsets.ModelViewSet): class DefaultImageAPIViewSet(viewsets.ModelViewSet):
"""Profile viewset""" """Profile viewset"""
queryset = DefaultTaskImages.objects.all()
serializer_class = DefaultTaskImagesDetailsSerializer serializer_class = DefaultTaskImagesDetailsSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
@ -503,7 +496,6 @@ class DeleteUserProfileAPIViewSet(viewsets.GenericViewSet):
class UserNotificationAPIViewSet(viewsets.ModelViewSet): class UserNotificationAPIViewSet(viewsets.ModelViewSet):
"""notification viewset""" """notification viewset"""
queryset = UserNotification.objects.all()
serializer_class = UserNotificationSerializer serializer_class = UserNotificationSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
@ -515,7 +507,6 @@ class UserNotificationAPIViewSet(viewsets.ModelViewSet):
class UpdateUserNotificationAPIViewSet(viewsets.ModelViewSet): class UpdateUserNotificationAPIViewSet(viewsets.ModelViewSet):
"""Update notification viewset""" """Update notification viewset"""
queryset = UserNotification.objects.all()
serializer_class = UpdateUserNotificationSerializer serializer_class = UpdateUserNotificationSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]

View File

@ -70,6 +70,18 @@ SIGNUP_METHODS = (
('2', 'google'), ('2', 'google'),
('3', 'apple') ('3', 'apple')
) )
# guardian code status
GUARDIAN_CODE_STATUS = (
('1', 'no guardian code'),
('2', 'exist guardian code'),
('3', 'request for guardian code')
)
# article status
ARTICLE_STATUS = (
('1', 'read'),
('2', 'in_progress'),
('3', 'completed')
)
# relationship # relationship
RELATIONSHIP = ( RELATIONSHIP = (
('1', 'parent'), ('1', 'parent'),
@ -106,7 +118,7 @@ MAX_ARTICLE_CARD = 6
MIN_ARTICLE_SURVEY = 5 MIN_ARTICLE_SURVEY = 5
MAX_ARTICLE_SURVEY = 10 MAX_ARTICLE_SURVEY = 10
# real time url # already register
time_url = "http://worldtimeapi.org/api/timezone/Asia/Riyadh" Already_register_user = "duplicate key value violates unique constraint"
ARTICLE_CARD_IMAGE_FOLDER = 'article-card-images' ARTICLE_CARD_IMAGE_FOLDER = 'article-card-images'

View File

@ -149,7 +149,14 @@ SUCCESS_CODE = {
"3037": "Profile has been updated successfully.", "3037": "Profile has been updated successfully.",
"3038": "Status has been changed successfully.", "3038": "Status has been changed successfully.",
# notification read # notification read
"3039": "Notification read successfully" "3039": "Notification read successfully",
"3040": "Start article successfully",
# complete article
"3041": "Article completed successfully",
# submit assessment successfully
"3042": "Assessment completed successfully",
"3043": "Read article card successfully"
} }
"""status code error""" """status code error"""
STATUS_CODE_ERROR = { STATUS_CODE_ERROR = {

View File

@ -23,7 +23,7 @@ from account.models import UserProfile, UserEmailOtp, UserNotification
from account.utils import generate_code from account.utils import generate_code
from junior.serializers import JuniorDetailSerializer from junior.serializers import JuniorDetailSerializer
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
from base.constants import NUMBER, JUN, ZOD, GRD from base.constants import NUMBER, JUN, ZOD, GRD, Already_register_user
from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship
from .utils import real_time, convert_timedelta_into_datetime, update_referral_points from .utils import real_time, convert_timedelta_into_datetime, update_referral_points
# notification's constant # notification's constant
@ -68,8 +68,10 @@ class UserSerializer(serializers.ModelSerializer):
UserNotification.objects.get_or_create(user=user) UserNotification.objects.get_or_create(user=user)
if user_type == str(NUMBER['one']): if user_type == str(NUMBER['one']):
# create junior profile # create junior profile
Junior.objects.create(auth=user, junior_code=generate_code(JUN, user.id), junior = Junior.objects.create(auth=user, junior_code=generate_code(JUN, user.id),
referral_code=generate_code(ZOD, user.id)) referral_code=generate_code(ZOD, user.id))
position = Junior.objects.all().count()
JuniorPoints.objects.create(junior=junior, position=position)
if user_type == str(NUMBER['two']): if user_type == str(NUMBER['two']):
# create guardian profile # create guardian profile
Guardian.objects.create(user=user, guardian_code=generate_code(GRD, user.id), Guardian.objects.create(user=user, guardian_code=generate_code(GRD, user.id),
@ -82,7 +84,7 @@ class UserSerializer(serializers.ModelSerializer):
otp_verified = False otp_verified = False
if otp and otp.is_verified: if otp and otp.is_verified:
otp_verified = True otp_verified = True
raise serializers.ValidationError({"details":ERROR_CODE['2021'], "otp_verified":bool(otp_verified), raise serializers.ValidationError({"details": ERROR_CODE['2021'], "otp_verified":bool(otp_verified),
"code": 400, "status":"failed", "code": 400, "status":"failed",
}) })
@ -385,8 +387,6 @@ class ApproveTaskSerializer(serializers.ModelSerializer):
# reject the task # reject the task
instance.task_status = str(NUMBER['three']) instance.task_status = str(NUMBER['three'])
instance.is_approved = False instance.is_approved = False
# update total task point
junior_data.total_points = junior_data.total_points - instance.points
# update reject time of task # update reject time of task
# instance.rejected_on = real_time() # instance.rejected_on = real_time()
instance.rejected_on = timezone.now().astimezone(pytz.utc) instance.rejected_on = timezone.now().astimezone(pytz.utc)
@ -403,11 +403,20 @@ class GuardianDetailListSerializer(serializers.ModelSerializer):
email = serializers.SerializerMethodField('get_email') email = serializers.SerializerMethodField('get_email')
image = serializers.SerializerMethodField('get_image') image = serializers.SerializerMethodField('get_image')
guardian_id = serializers.SerializerMethodField('get_guardian_id') guardian_id = serializers.SerializerMethodField('get_guardian_id')
guardian_code = serializers.SerializerMethodField('get_guardian_code')
gender = serializers.SerializerMethodField('get_gender')
phone = serializers.SerializerMethodField('get_phone')
country_name = serializers.SerializerMethodField('get_country_name')
dob = serializers.SerializerMethodField('get_dob')
guardian_code_status = serializers.SerializerMethodField('get_guardian_code_status')
# code info
class Meta(object): class Meta(object):
"""Meta info""" """Meta info"""
model = JuniorGuardianRelationship model = JuniorGuardianRelationship
fields = ['guardian_id', 'first_name', 'last_name', 'email', 'relationship', 'image', 'created_at', fields = ['guardian_id', 'first_name', 'last_name', 'email', 'relationship', 'image', 'dob',
'guardian_code', 'gender', 'phone', 'country_name', 'created_at', 'guardian_code_status',
'updated_at'] 'updated_at']
def get_guardian_id(self,obj): def get_guardian_id(self,obj):
@ -422,9 +431,33 @@ class GuardianDetailListSerializer(serializers.ModelSerializer):
return obj.guardian.user.last_name return obj.guardian.user.last_name
def get_email(self,obj): def get_email(self,obj):
"""emailof guardian""" """email of guardian"""
return obj.guardian.user.email return obj.guardian.user.email
def get_image(self,obj): def get_image(self,obj):
"""first name of guardian""" """guardian image"""
return obj.guardian.image return obj.guardian.image
def get_guardian_code(self,obj):
""" guardian code"""
return obj.guardian.guardian_code
def get_gender(self,obj):
""" guardian gender"""
return obj.guardian.gender
def get_phone(self,obj):
"""guardian phone"""
return obj.guardian.phone
def get_country_name(self,obj):
""" guardian country name """
return obj.guardian.country_name
def get_dob(self,obj):
"""guardian dob """
return obj.guardian.dob
def get_guardian_code_status(self,obj):
"""guardian code status"""
return obj.junior.guardian_code_status

View File

@ -11,7 +11,7 @@ import tempfile
# Import date time module's function # Import date time module's function
from datetime import datetime, time from datetime import datetime, time
# import Number constant # import Number constant
from base.constants import NUMBER, time_url from base.constants import NUMBER
# Import Junior's model # Import Junior's model
from junior.models import Junior, JuniorPoints from junior.models import Junior, JuniorPoints
# Import guardian's model # Import guardian's model

View File

@ -10,8 +10,8 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework import viewsets, status from rest_framework import viewsets, status
from rest_framework.pagination import PageNumberPagination from rest_framework.pagination import PageNumberPagination
from django.contrib.auth.models import User from django.contrib.auth.models import User
from rest_framework.filters import SearchFilter
from rest_framework.filters import SearchFilter
from django.utils import timezone from django.utils import timezone
# Import guardian's model, # Import guardian's model,
@ -36,7 +36,7 @@ from account.models import UserEmailOtp, UserNotification
from .tasks import generate_otp from .tasks import generate_otp
from account.utils import custom_response, custom_error_response, OTP_EXPIRY, send_otp_email from account.utils import custom_response, custom_error_response, OTP_EXPIRY, send_otp_email
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
from base.constants import NUMBER from base.constants import NUMBER, GUARDIAN_CODE_STATUS
from .utils import upload_image_to_alibaba from .utils import upload_image_to_alibaba
from notifications.constants import REGISTRATION, TASK_CREATED, LEADERBOARD_RANKING from notifications.constants import REGISTRATION, TASK_CREATED, LEADERBOARD_RANKING
from notifications.utils import send_notification from notifications.utils import send_notification
@ -59,33 +59,29 @@ class SignupViewset(viewsets.ModelViewSet):
serializer_class = UserSerializer serializer_class = UserSerializer
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
"""Create user profile""" """Create user profile"""
try: if request.data['user_type'] in [str(NUMBER['one']), str(NUMBER['two'])]:
if request.data['user_type'] in [str(NUMBER['one']), str(NUMBER['two'])]: serializer = UserSerializer(context=request.data['user_type'], data=request.data)
serializer = UserSerializer(context=request.data['user_type'], data=request.data) if serializer.is_valid():
if serializer.is_valid(): user = serializer.save()
user = serializer.save() """Generate otp"""
"""Generate otp""" otp = generate_otp()
otp = generate_otp() # expire otp after 1 day
# expire otp after 1 day expiry = OTP_EXPIRY
expiry = OTP_EXPIRY # create user email otp object
# create user email otp object UserEmailOtp.objects.create(email=request.data['email'], otp=otp,
UserEmailOtp.objects.create(email=request.data['email'], otp=otp, user_type=str(request.data['user_type']), expired_at=expiry)
user_type=str(request.data['user_type']), expired_at=expiry) """Send email to the register user"""
"""Send email to the register user""" send_otp_email(request.data['email'], otp)
send_otp_email(request.data['email'], otp) # send push notification for registration
# send push notification for registration send_notification.delay(REGISTRATION, None, user.id, {})
send_notification.delay(REGISTRATION, None, user.id, {}) return custom_response(SUCCESS_CODE['3001'],
return custom_response(SUCCESS_CODE['3001'], response_status=status.HTTP_200_OK)
response_status=status.HTTP_200_OK) return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST) else:
else: return custom_error_response(ERROR_CODE['2028'], response_status=status.HTTP_400_BAD_REQUEST)
return custom_error_response(ERROR_CODE['2028'], response_status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
class UpdateGuardianProfile(viewsets.ViewSet): class UpdateGuardianProfile(viewsets.ViewSet):
"""Update guardian profile""" """Update guardian profile"""
queryset = Guardian.objects.all()
serializer_class = CreateGuardianSerializer serializer_class = CreateGuardianSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
@ -119,7 +115,6 @@ class UpdateGuardianProfile(viewsets.ViewSet):
class AllTaskListAPIView(viewsets.ModelViewSet): class AllTaskListAPIView(viewsets.ModelViewSet):
"""Update guardian profile""" """Update guardian profile"""
serializer_class = TaskDetailsSerializer serializer_class = TaskDetailsSerializer
queryset = JuniorTask.objects.all()
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
@ -261,9 +256,9 @@ class SearchTaskListAPIView(viewsets.ModelViewSet):
class TopJuniorListAPIView(viewsets.ModelViewSet): class TopJuniorListAPIView(viewsets.ModelViewSet):
"""Top juniors list""" """Top juniors list"""
queryset = JuniorPoints.objects.all()
serializer_class = TopJuniorSerializer serializer_class = TopJuniorSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
queryset = JuniorPoints.objects.all()
def get_serializer_context(self): def get_serializer_context(self):
# context list # context list
@ -379,6 +374,6 @@ class GuardianListAPIView(viewsets.ModelViewSet):
# use GuardianDetailListSerializer serializer # use GuardianDetailListSerializer serializer
serializer = GuardianDetailListSerializer(guardian_data, many=True) serializer = GuardianDetailListSerializer(guardian_data, many=True)
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK) return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
return custom_error_response(ERROR_CODE['2068'], response_status=status.HTTP_200_OK) return custom_response({"status": GUARDIAN_CODE_STATUS[1][0]}, response_status=status.HTTP_200_OK)
except Exception as e: except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)

View File

@ -2,8 +2,26 @@
"""Third party Django app""" """Third party Django app"""
from django.contrib import admin from django.contrib import admin
"""Import Django app""" """Import Django app"""
from .models import Junior, JuniorPoints, JuniorGuardianRelationship from .models import (Junior, JuniorPoints, JuniorGuardianRelationship, JuniorArticlePoints, JuniorArticle,
JuniorArticleCard)
# Register your models here. # Register your models here.
@admin.register(JuniorArticle)
class JuniorArticleAdmin(admin.ModelAdmin):
"""Junior Admin"""
list_display = ['junior', 'article', 'status', 'is_completed']
def __str__(self):
"""Return email id"""
return self.junior__auth__email
@admin.register(JuniorArticleCard)
class JuniorArticleCardAdmin(admin.ModelAdmin):
"""Junior Admin"""
list_display = ['junior', 'article', 'article_card', 'is_read']
def __str__(self):
"""Return email id"""
return self.junior__auth__email
@admin.register(Junior) @admin.register(Junior)
class JuniorAdmin(admin.ModelAdmin): class JuniorAdmin(admin.ModelAdmin):
"""Junior Admin""" """Junior Admin"""
@ -27,3 +45,7 @@ class JuniorGuardianRelationshipAdmin(admin.ModelAdmin):
"""Junior Admin""" """Junior Admin"""
list_display = ['guardian', 'junior', 'relationship'] list_display = ['guardian', 'junior', 'relationship']
@admin.register(JuniorArticlePoints)
class JuniorArticlePointsAdmin(admin.ModelAdmin):
"""Junior Admin"""
list_display = ['junior', 'article', 'question', 'submitted_answer', 'is_answer_correct']

View File

@ -0,0 +1,30 @@
# Generated by Django 4.2.2 on 2023-08-07 13:29
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web_admin', '0004_alter_surveyoption_survey'),
('junior', '0018_remove_junior_relationship_and_more'),
]
operations = [
migrations.CreateModel(
name='JuniorArticlePoints',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('earn_points', models.IntegerField(blank=True, default=5, null=True)),
('is_attempt', models.BooleanField(default=False)),
('is_answer_correct', models.BooleanField(default=False)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='junior_articles', to='web_admin.article')),
('junior', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='juniors_details', to='junior.junior', verbose_name='Junior')),
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='questions', to='web_admin.articlesurvey')),
('submitted_answer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='submitted_answer', to='web_admin.surveyoption')),
],
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2023-08-08 05:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('junior', '0019_juniorarticlepoints'),
]
operations = [
migrations.AddField(
model_name='junior',
name='guardian_code_status',
field=models.CharField(blank=True, choices=[('1', 'no guardian code'), ('2', 'exist guardian code'), ('3', 'request for guardian code')], default='1', max_length=31, null=True),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 4.2.2 on 2023-08-08 09:45
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web_admin', '0004_alter_surveyoption_survey'),
('junior', '0020_junior_guardian_code_status'),
]
operations = [
migrations.AlterField(
model_name='juniorarticlepoints',
name='submitted_answer',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_answer', to='web_admin.surveyoption'),
),
]

View File

@ -0,0 +1,27 @@
# Generated by Django 4.2.2 on 2023-08-09 09:34
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web_admin', '0004_alter_surveyoption_survey'),
('junior', '0021_alter_juniorarticlepoints_submitted_answer'),
]
operations = [
migrations.CreateModel(
name='JuniorArticle',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_completed', models.BooleanField(default=False)),
('status', models.CharField(blank=True, choices=[('1', 'read'), ('2', 'in_progress'), ('3', 'completed')], default='1', max_length=10, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='junior_articles_details', to='web_admin.article')),
('junior', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='juniors_article', to='junior.junior', verbose_name='Junior')),
],
),
]

View File

@ -0,0 +1,27 @@
# Generated by Django 4.2.2 on 2023-08-09 10:47
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web_admin', '0004_alter_surveyoption_survey'),
('junior', '0022_juniorarticle'),
]
operations = [
migrations.CreateModel(
name='JuniorArticleCard',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_read', models.BooleanField(default=False)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='junior_articles_detail', to='web_admin.article')),
('article_card', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='junior_article_card', to='web_admin.articlecard')),
('junior', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='juniors_article_card', to='junior.junior', verbose_name='Junior')),
],
),
]

View File

@ -6,10 +6,11 @@ from django.contrib.auth import get_user_model
"""Import ArrayField""" """Import ArrayField"""
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
"""Import django app""" """Import django app"""
from base.constants import GENDERS, SIGNUP_METHODS, RELATIONSHIP from base.constants import GENDERS, SIGNUP_METHODS, RELATIONSHIP, GUARDIAN_CODE_STATUS, ARTICLE_STATUS
# Import guardian's model # Import guardian's model
from guardian.models import Guardian from guardian.models import Guardian
# Import web admin's model
from web_admin.models import SurveyOption, ArticleSurvey, Article, ArticleCard
"""Define User model""" """Define User model"""
User = get_user_model() User = get_user_model()
# Create your models here. # Create your models here.
@ -73,6 +74,9 @@ class Junior(models.Model):
is_verified = models.BooleanField(default=False) is_verified = models.BooleanField(default=False)
"""guardian code is approved or not""" """guardian code is approved or not"""
guardian_code_approved = models.BooleanField(default=False) guardian_code_approved = models.BooleanField(default=False)
# guardian code status"""
guardian_code_status = models.CharField(max_length=31, choices=GUARDIAN_CODE_STATUS, default='1',
null=True, blank=True)
# Profile created and updated time""" # Profile created and updated time"""
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
@ -137,3 +141,58 @@ class JuniorGuardianRelationship(models.Model):
return f'{self.guardian.user}' return f'{self.guardian.user}'
class JuniorArticlePoints(models.Model):
"""
Survey Options model
"""
# associated junior with the task
junior = models.ForeignKey(Junior, on_delete=models.CASCADE, related_name='juniors_details', verbose_name='Junior')
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='junior_articles')
question = models.ForeignKey(ArticleSurvey, on_delete=models.CASCADE, related_name='questions')
submitted_answer = models.ForeignKey(SurveyOption, on_delete=models.SET_NULL, null=True,
related_name='submitted_answer')
# earn points"""
earn_points = models.IntegerField(blank=True, null=True, default=5)
is_attempt = models.BooleanField(default=False)
is_answer_correct = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
"""Return title"""
return f'{self.id} | {self.question}'
class JuniorArticle(models.Model):
"""
Survey Options model
"""
# associated junior with the task
junior = models.OneToOneField(Junior, on_delete=models.CASCADE, related_name='juniors_article', verbose_name='Junior')
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='junior_articles_details')
# article completed"""
is_completed = models.BooleanField(default=False)
status = models.CharField(max_length=10, choices=ARTICLE_STATUS, null=True, blank=True, default='1')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
"""Return title"""
return f'{self.id} | {self.article}'
class JuniorArticleCard(models.Model):
"""
Survey Options model
"""
# associated junior with the task
junior = models.ForeignKey(Junior, on_delete=models.CASCADE, related_name='juniors_article_card', verbose_name='Junior')
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='junior_articles_detail')
article_card = models.ForeignKey(ArticleCard, on_delete=models.CASCADE, related_name='junior_article_card')
# article card read"""
is_read = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
"""Return title"""
return f'{self.id} | {self.article}'

View File

@ -12,10 +12,11 @@ from rest_framework_simplejwt.tokens import RefreshToken
# local imports # local imports
from account.utils import send_otp_email, generate_code from account.utils import send_otp_email, generate_code
from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship, JuniorArticlePoints
from guardian.tasks import generate_otp from guardian.tasks import generate_otp
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, NUMBER, JUN, ZOD, EXPIRED from base.constants import (PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, NUMBER, JUN, ZOD, EXPIRED,
GUARDIAN_CODE_STATUS)
from guardian.models import Guardian, JuniorTask from guardian.models import Guardian, JuniorTask
from account.models import UserEmailOtp, UserNotification from account.models import UserEmailOtp, UserNotification
from junior.utils import junior_notification_email, junior_approval_mail from junior.utils import junior_notification_email, junior_approval_mail
@ -209,7 +210,7 @@ class JuniorDetailListSerializer(serializers.ModelSerializer):
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob', fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image', 'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image',
'updated_at', 'assigned_task','points', 'pending_task', 'in_progress_task', 'completed_task', 'updated_at', 'assigned_task','points', 'pending_task', 'in_progress_task', 'completed_task',
'requested_task', 'rejected_task', 'position', 'is_invited'] 'requested_task', 'rejected_task', 'position', 'is_invited', 'guardian_code_status']
class JuniorProfileSerializer(serializers.ModelSerializer): class JuniorProfileSerializer(serializers.ModelSerializer):
"""junior serializer""" """junior serializer"""
@ -256,11 +257,10 @@ class JuniorProfileSerializer(serializers.ModelSerializer):
class AddJuniorSerializer(serializers.ModelSerializer): class AddJuniorSerializer(serializers.ModelSerializer):
"""Add junior serializer""" """Add junior serializer"""
class Meta(object): class Meta(object):
"""Meta info""" """Meta info"""
model = Junior model = Junior
fields = ['id', 'gender','dob', 'is_invited'] fields = ['id', 'gender', 'dob', 'is_invited']
def create(self, validated_data): def create(self, validated_data):
@ -269,6 +269,7 @@ class AddJuniorSerializer(serializers.ModelSerializer):
email = self.context['email'] email = self.context['email']
guardian = self.context['user'] guardian = self.context['user']
relationship = self.context['relationship'] relationship = self.context['relationship']
profile_image = self.context['image']
full_name = self.context['first_name'] + ' ' + self.context['last_name'] full_name = self.context['first_name'] + ' ' + self.context['last_name']
guardian_data = Guardian.objects.filter(user__username=guardian).last() guardian_data = Guardian.objects.filter(user__username=guardian).last()
user_data = User.objects.create(username=email, email=email, user_data = User.objects.create(username=email, email=email,
@ -278,14 +279,18 @@ class AddJuniorSerializer(serializers.ModelSerializer):
user_data.set_password(password) user_data.set_password(password)
user_data.save() user_data.save()
junior_data = Junior.objects.create(auth=user_data, gender=validated_data.get('gender'), junior_data = Junior.objects.create(auth=user_data, gender=validated_data.get('gender'),
image=profile_image,
dob=validated_data.get('dob'), is_invited=True, dob=validated_data.get('dob'), is_invited=True,
guardian_code=[guardian_data.guardian_code], guardian_code=[guardian_data.guardian_code],
junior_code=generate_code(JUN, user_data.id), junior_code=generate_code(JUN, user_data.id),
referral_code=generate_code(ZOD, user_data.id), referral_code=generate_code(ZOD, user_data.id),
referral_code_used=guardian_data.referral_code, referral_code_used=guardian_data.referral_code,
is_password_set=False, is_verified=True) is_password_set=False, is_verified=True,
guardian_code_status=GUARDIAN_CODE_STATUS[1][0])
JuniorGuardianRelationship.objects.create(guardian=guardian_data, junior=junior_data, JuniorGuardianRelationship.objects.create(guardian=guardian_data, junior=junior_data,
relationship=relationship) relationship=relationship)
total_junior = Junior.objects.all().count()
JuniorPoints.objects.create(junior=junior_data, position=total_junior)
"""Generate otp""" """Generate otp"""
otp_value = generate_otp() otp_value = generate_otp()
expiry_time = timezone.now() + timezone.timedelta(days=1) expiry_time = timezone.now() + timezone.timedelta(days=1)
@ -403,13 +408,15 @@ class AddGuardianSerializer(serializers.ModelSerializer):
relationship = self.context['relationship'] relationship = self.context['relationship']
full_name = self.context['first_name'] + ' ' + self.context['last_name'] full_name = self.context['first_name'] + ' ' + self.context['last_name']
junior_data = Junior.objects.filter(auth__username=junior).last() junior_data = Junior.objects.filter(auth__username=junior).last()
junior_data.guardian_code_status = GUARDIAN_CODE_STATUS[2][0]
junior_data.save()
instance = User.objects.filter(username=email).last() instance = User.objects.filter(username=email).last()
if instance: if instance:
guardian_data = Guardian.objects.filter(user=instance).update(is_invited=True, guardian_data = Guardian.objects.filter(user=instance).update(is_invited=True,
referral_code=generate_code(ZOD, referral_code=generate_code(ZOD,
instance.id), instance.id),
referral_code_used=junior_data.referral_code, referral_code_used=junior_data.referral_code,
is_verified=True) is_verified=True)
UserNotification.objects.get_or_create(user=instance) UserNotification.objects.get_or_create(user=instance)
return guardian_data return guardian_data
else: else:
@ -481,3 +488,4 @@ class ReAssignTaskSerializer(serializers.ModelSerializer):
instance.requested_on = None instance.requested_on = None
instance.save() instance.save()
return instance return instance

View File

@ -4,7 +4,9 @@ from django.urls import path, include
from .views import (UpdateJuniorProfile, ValidateGuardianCode, JuniorListAPIView, AddJuniorAPIView, from .views import (UpdateJuniorProfile, ValidateGuardianCode, JuniorListAPIView, AddJuniorAPIView,
InvitedJuniorAPIView, FilterJuniorAPIView, RemoveJuniorAPIView, JuniorTaskListAPIView, InvitedJuniorAPIView, FilterJuniorAPIView, RemoveJuniorAPIView, JuniorTaskListAPIView,
CompleteJuniorTaskAPIView, JuniorPointsListAPIView, ValidateReferralCode, CompleteJuniorTaskAPIView, JuniorPointsListAPIView, ValidateReferralCode,
InviteGuardianAPIView, StartTaskAPIView, ReAssignJuniorTaskAPIView) InviteGuardianAPIView, StartTaskAPIView, ReAssignJuniorTaskAPIView, StartArticleAPIView,
StartAssessmentAPIView, CheckAnswerAPIView, CompleteArticleAPIView, ReadArticleCardAPIView,
CreateArticleCardAPIView)
"""Third party import""" """Third party import"""
from rest_framework import routers from rest_framework import routers
@ -41,6 +43,14 @@ router.register('junior-points', JuniorPointsListAPIView, basename='junior-point
router.register('validate-referral-code', ValidateReferralCode, basename='validate-referral-code') router.register('validate-referral-code', ValidateReferralCode, basename='validate-referral-code')
# invite guardian API""" # invite guardian API"""
router.register('invite-guardian', InviteGuardianAPIView, basename='invite-guardian') router.register('invite-guardian', InviteGuardianAPIView, basename='invite-guardian')
# start article"""
router.register('start-article', StartArticleAPIView, basename='start-article')
# start assessment api"""
router.register('start-assessment', StartAssessmentAPIView, basename='start-assessment')
# check answer api"""
router.register('check-answer', CheckAnswerAPIView, basename='check-answer')
# start article"""
router.register('create-article-card', CreateArticleCardAPIView, basename='create-article-card')
# Define url pattern""" # Define url pattern"""
urlpatterns = [ urlpatterns = [
path('api/v1/', include(router.urls)), path('api/v1/', include(router.urls)),
@ -48,4 +58,6 @@ urlpatterns = [
path('api/v1/complete-task/', CompleteJuniorTaskAPIView.as_view()), path('api/v1/complete-task/', CompleteJuniorTaskAPIView.as_view()),
path('api/v1/start-task/', StartTaskAPIView.as_view()), path('api/v1/start-task/', StartTaskAPIView.as_view()),
path('api/v1/reassign-task/', ReAssignJuniorTaskAPIView.as_view()), path('api/v1/reassign-task/', ReAssignJuniorTaskAPIView.as_view()),
path('api/v1/complete-article/', CompleteArticleAPIView.as_view()),
path('api/v1/read-article-card/', ReadArticleCardAPIView.as_view()),
] ]

View File

@ -50,7 +50,7 @@ def junior_approval_mail(guardian, full_name):
def update_positions_based_on_points(): def update_positions_based_on_points():
"""Update position of the junior""" """Update position of the junior"""
# First, retrieve all the JuniorPoints instances ordered by total_points in descending order. # First, retrieve all the JuniorPoints instances ordered by total_points in descending order.
juniors_points = JuniorPoints.objects.order_by('-total_points') juniors_points = JuniorPoints.objects.order_by('-total_points', 'updated_at')
# Now, iterate through the queryset and update the position field based on the order. # Now, iterate through the queryset and update the position field based on the order.
position = 1 position = 1

View File

@ -6,6 +6,7 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.pagination import PageNumberPagination from rest_framework.pagination import PageNumberPagination
from django.contrib.auth.models import User from django.contrib.auth.models import User
from rest_framework.filters import SearchFilter from rest_framework.filters import SearchFilter
from django.db.models import F
import datetime import datetime
import requests import requests
@ -27,20 +28,25 @@ import requests
# Import upload_image_to_alibaba # Import upload_image_to_alibaba
# Import custom_response, custom_error_response # Import custom_response, custom_error_response
# Import constants # Import constants
from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship from django.db.models import Sum
from .serializers import (CreateJuniorSerializer, JuniorDetailListSerializer, AddJuniorSerializer,\ from junior.models import (Junior, JuniorPoints, JuniorGuardianRelationship, JuniorArticlePoints, JuniorArticle,
JuniorArticleCard)
from .serializers import (CreateJuniorSerializer, JuniorDetailListSerializer, AddJuniorSerializer,
RemoveJuniorSerializer, CompleteTaskSerializer, JuniorPointsSerializer, RemoveJuniorSerializer, CompleteTaskSerializer, JuniorPointsSerializer,
AddGuardianSerializer, StartTaskSerializer, ReAssignTaskSerializer) AddGuardianSerializer, StartTaskSerializer, ReAssignTaskSerializer
)
from guardian.models import Guardian, JuniorTask from guardian.models import Guardian, JuniorTask
from guardian.serializers import TaskDetailsSerializer, TaskDetailsjuniorSerializer from guardian.serializers import TaskDetailsSerializer, TaskDetailsjuniorSerializer
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
from base.constants import NUMBER from base.constants import NUMBER, ARTICLE_STATUS
from account.utils import custom_response, custom_error_response from account.utils import custom_response, custom_error_response
from guardian.utils import upload_image_to_alibaba from guardian.utils import upload_image_to_alibaba
from .utils import update_positions_based_on_points from .utils import update_positions_based_on_points
from notifications.utils import send_notification from notifications.utils import send_notification
from notifications.constants import REMOVE_JUNIOR from notifications.constants import REMOVE_JUNIOR
from web_admin.models import Article, ArticleSurvey, SurveyOption, ArticleCard
from web_admin.serializers.article_serializer import (ArticleSerializer, ArticleListSerializer,
StartAssessmentSerializer)
""" Define APIs """ """ Define APIs """
# Define validate guardian code API, # Define validate guardian code API,
# update junior profile, # update junior profile,
@ -59,7 +65,6 @@ from notifications.constants import REMOVE_JUNIOR
# Create your views here. # Create your views here.
class UpdateJuniorProfile(viewsets.ViewSet): class UpdateJuniorProfile(viewsets.ViewSet):
"""Update junior profile""" """Update junior profile"""
queryset = Junior.objects.all()
serializer_class = CreateJuniorSerializer serializer_class = CreateJuniorSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
@ -93,7 +98,6 @@ class UpdateJuniorProfile(viewsets.ViewSet):
class ValidateGuardianCode(viewsets.ViewSet): class ValidateGuardianCode(viewsets.ViewSet):
"""Check guardian code exist or not""" """Check guardian code exist or not"""
queryset = Guardian.objects.all()
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
@ -151,8 +155,19 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
""" junior list""" """ junior list"""
try: try:
info_data = {'user': request.user, 'relationship': str(request.data['relationship']), 'email': request.data['email'], 'first_name': request.data['first_name'], info_data = {'user': request.user, 'relationship': str(request.data['relationship']),
'last_name': request.data['last_name']} 'email': request.data['email'], 'first_name': request.data['first_name'],
'last_name': request.data['last_name'], 'image':None}
profile_image = request.data.get('image')
if profile_image:
# check image size
if profile_image.size == NUMBER['zero']:
return custom_error_response(ERROR_CODE['2035'], response_status=status.HTTP_400_BAD_REQUEST)
# convert into file
filename = f"images/{profile_image.name}"
# upload image on ali baba
image_url = upload_image_to_alibaba(profile_image, filename)
info_data.update({"image": image_url})
if user := User.objects.filter(username=request.data['email']).first(): if user := User.objects.filter(username=request.data['email']).first():
self.associate_guardian(user) self.associate_guardian(user)
return custom_response(SUCCESS_CODE['3021'], response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3021'], response_status=status.HTTP_200_OK)
@ -162,7 +177,7 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
# save serializer # save serializer
serializer.save() serializer.save()
return custom_response(SUCCESS_CODE['3021'], serializer.data, response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3021'], serializer.data, response_status=status.HTTP_200_OK)
return custom_error_response(serializer.error, response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
except Exception as e: except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
@ -180,7 +195,6 @@ class InvitedJuniorAPIView(viewsets.ModelViewSet):
"""Junior list of assosicated guardian""" """Junior list of assosicated guardian"""
serializer_class = JuniorDetailListSerializer serializer_class = JuniorDetailListSerializer
queryset = Junior.objects.all()
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
pagination_class = PageNumberPagination pagination_class = PageNumberPagination
http_method_names = ('get',) http_method_names = ('get',)
@ -210,7 +224,6 @@ class FilterJuniorAPIView(viewsets.ModelViewSet):
serializer_class = JuniorDetailListSerializer serializer_class = JuniorDetailListSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
pagination_class = PageNumberPagination pagination_class = PageNumberPagination
queryset = Junior.objects.all()
http_method_names = ('get',) http_method_names = ('get',)
def get_queryset(self): def get_queryset(self):
@ -268,7 +281,6 @@ class JuniorTaskListAPIView(viewsets.ModelViewSet):
serializer_class = TaskDetailsjuniorSerializer serializer_class = TaskDetailsjuniorSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
pagination_class = PageNumberPagination pagination_class = PageNumberPagination
queryset = JuniorTask.objects.all()
http_method_names = ('get',) http_method_names = ('get',)
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
@ -345,6 +357,7 @@ class JuniorPointsListAPIView(viewsets.ModelViewSet):
def get_queryset(self): def get_queryset(self):
"""get queryset""" """get queryset"""
update_positions_based_on_points()
return JuniorTask.objects.filter(junior__auth__email=self.request.user).last() return JuniorTask.objects.filter(junior__auth__email=self.request.user).last()
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
"""profile view""" """profile view"""
@ -352,7 +365,6 @@ class JuniorPointsListAPIView(viewsets.ModelViewSet):
try: try:
queryset = self.get_queryset() queryset = self.get_queryset()
# update position of junior # update position of junior
update_positions_based_on_points()
serializer = JuniorPointsSerializer(queryset) serializer = JuniorPointsSerializer(queryset)
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK) return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
except Exception as e: except Exception as e:
@ -458,3 +470,154 @@ class ReAssignJuniorTaskAPIView(views.APIView):
return custom_error_response(ERROR_CODE['2066'], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE['2066'], response_status=status.HTTP_400_BAD_REQUEST)
except Exception as e: except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
class StartArticleAPIView(viewsets.ModelViewSet):
"""Start article"""
permission_classes = [IsAuthenticated]
http_method_names = ('post',)
def create(self, request, *args, **kwargs):
""" junior list"""
try:
junior_instance = Junior.objects.filter(auth=self.request.user).last()
article_id = request.data.get('article_id')
article_data = Article.objects.filter(id=article_id).last()
if not JuniorArticle.objects.filter(junior=junior_instance, article=article_data).last():
JuniorArticle.objects.create(junior=junior_instance, article=article_data, status=str(NUMBER['two']))
if article_data:
question_query = ArticleSurvey.objects.filter(article=article_id)
for question in question_query:
if not JuniorArticlePoints.objects.filter(junior=junior_instance,
article=article_data,
question=question):
JuniorArticlePoints.objects.create(junior=junior_instance,
article=article_data,
question=question)
return custom_response(SUCCESS_CODE['3040'], response_status=status.HTTP_200_OK)
except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
class StartAssessmentAPIView(viewsets.ModelViewSet):
"""Junior Points viewset"""
serializer_class = StartAssessmentSerializer
permission_classes = [IsAuthenticated]
http_method_names = ('get',)
def get_queryset(self):
article_id = self.request.GET.get('article_id')
# if referral_code:
article = Article.objects.filter(id=article_id, is_deleted=False).prefetch_related(
'article_cards', 'article_survey', 'article_survey__options'
).order_by('-created_at')
return article
def list(self, request, *args, **kwargs):
"""profile view"""
try:
queryset = self.get_queryset()
paginator = self.pagination_class()
paginated_queryset = paginator.paginate_queryset(queryset, request)
serializer = self.serializer_class(paginated_queryset, context={"user":request.user}, many=True)
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
class CheckAnswerAPIView(viewsets.ModelViewSet):
"""Junior Points viewset"""
permission_classes = [IsAuthenticated]
http_method_names = ('get',)
def get_queryset(self):
question_id = self.request.GET.get('question_id')
article = ArticleSurvey.objects.filter(id=question_id).last()
return article
def list(self, request, *args, **kwargs):
"""profile view"""
try:
answer_id = self.request.GET.get('answer_id')
queryset = self.get_queryset()
submit_ans = SurveyOption.objects.filter(id=answer_id, is_answer=True).last()
junior_article_points = JuniorArticlePoints.objects.filter(junior__auth=self.request.user,
question=queryset)
if submit_ans:
junior_article_points.update(submitted_answer=submit_ans, is_attempt=True, is_answer_correct=True)
JuniorPoints.objects.filter(junior__auth=self.request.user).update(total_points=
F('total_points')+ queryset.points)
else:
junior_article_points.update(submitted_answer=submit_ans, is_attempt=True, earn_points=0,
is_answer_correct=False)
return custom_response(None, response_status=status.HTTP_200_OK)
except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
class CompleteArticleAPIView(views.APIView):
"""Remove junior API"""
permission_classes = [IsAuthenticated]
http_method_names = ('put', 'get',)
def put(self, request, format=None):
try:
article_id = self.request.data.get('article_id')
JuniorArticle.objects.filter(junior__auth=request.user, article__id=article_id).update(
is_completed=True, status=str(NUMBER['three'])
)
return custom_response(SUCCESS_CODE['3041'], response_status=status.HTTP_200_OK)
except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
def get(self, request, *args, **kwargs):
""" junior list"""
try:
article_id = self.request.GET.get('article_id')
total_earn_points = JuniorArticlePoints.objects.filter(junior__auth=request.user,
article__id=article_id,
is_answer_correct=True).aggregate(
total_earn_points=Sum('earn_points'))['total_earn_points']
data = {"total_earn_points":total_earn_points}
return custom_response(SUCCESS_CODE['3042'], data, response_status=status.HTTP_200_OK)
except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
class ReadArticleCardAPIView(views.APIView):
"""Remove junior API"""
permission_classes = [IsAuthenticated]
http_method_names = ('put',)
def put(self, request, *args, **kwargs):
""" junior list"""
try:
junior_instance = Junior.objects.filter(auth=self.request.user).last()
article = self.request.data.get('article_id')
article_card = self.request.data.get('article_card')
JuniorArticleCard.objects.filter(junior=junior_instance,
article__id=article,
article_card__id=article_card).update(is_read=True)
return custom_response(SUCCESS_CODE['3043'], response_status=status.HTTP_200_OK)
except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
class CreateArticleCardAPIView(viewsets.ModelViewSet):
"""Start article"""
permission_classes = [IsAuthenticated]
http_method_names = ('post',)
def create(self, request, *args, **kwargs):
""" junior list"""
try:
junior_instance = Junior.objects.filter(auth=self.request.user).last()
article_id = request.data.get('article_id')
article_data = Article.objects.filter(id=article_id).last()
if article_data:
article_cards = ArticleCard.objects.filter(article=article_id)
for article_card in article_cards:
if not JuniorArticleCard.objects.filter(junior=junior_instance,
article=article_data,
article_card=article_card):
JuniorArticleCard.objects.create(junior=junior_instance,
article=article_data,
article_card=article_card)
return custom_response(None, response_status=status.HTTP_200_OK)
except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)

View File

@ -49,7 +49,7 @@ class ArticleSurvey(models.Model):
def __str__(self): def __str__(self):
"""Return title""" """Return title"""
return f'{self.id} | {self.article}' return f'{self.id} | {self.question}'
class SurveyOption(models.Model): class SurveyOption(models.Model):
@ -64,7 +64,7 @@ class SurveyOption(models.Model):
def __str__(self): def __str__(self):
"""Return title""" """Return title"""
return f'{self.id} | {self.survey}' return f'{self.id} | {self.option}'
class DefaultArticleCardImage(models.Model): class DefaultArticleCardImage(models.Model):

View File

@ -12,7 +12,7 @@ from base.messages import ERROR_CODE
from guardian.utils import upload_image_to_alibaba from guardian.utils import upload_image_to_alibaba
from web_admin.models import Article, ArticleCard, SurveyOption, ArticleSurvey, DefaultArticleCardImage from web_admin.models import Article, ArticleCard, SurveyOption, ArticleSurvey, DefaultArticleCardImage
from web_admin.utils import pop_id, get_image_url from web_admin.utils import pop_id, get_image_url
from junior.models import JuniorArticlePoints
USER = get_user_model() USER = get_user_model()
@ -64,7 +64,7 @@ class ArticleSurveySerializer(serializers.ModelSerializer):
meta class meta class
""" """
model = ArticleSurvey model = ArticleSurvey
fields = ('id', 'question', 'options') fields = ('id', 'question', 'options', 'points')
class ArticleSerializer(serializers.ModelSerializer): class ArticleSerializer(serializers.ModelSerializer):
@ -220,16 +220,75 @@ class ArticleListSerializer(serializers.ModelSerializer):
serializer for article API serializer for article API
""" """
article_cards = ArticleCardSerializer(many=True) article_cards = ArticleCardSerializer(many=True)
article_survey = ArticleSurveySerializer(many=True)
total_points = serializers.SerializerMethodField('get_total_points') total_points = serializers.SerializerMethodField('get_total_points')
is_completed = serializers.SerializerMethodField('get_is_completed')
class Meta: class Meta:
""" """
meta class meta class
""" """
model = Article model = Article
fields = ('id', 'title', 'description', 'article_cards', 'total_points') fields = ('id', 'title', 'description', 'article_cards', 'article_survey', 'total_points', 'is_completed')
def get_total_points(self, obj): def get_total_points(self, obj):
"""total points of article""" """total points of article"""
total_question = ArticleSurvey.objects.filter(article=obj).count() total_question = ArticleSurvey.objects.filter(article=obj).count()
return total_question * 5 return total_question * NUMBER['five']
def get_is_completed(self, obj):
"""complete all question"""
return False
class ArticleQuestionSerializer(serializers.ModelSerializer):
"""
article survey serializer
"""
id = serializers.IntegerField(required=False)
options = SurveyOptionSerializer(many=True)
is_attempt = serializers.SerializerMethodField('get_is_attempt')
def get_is_attempt(self, obj):
"""attempt question or not"""
context_data = self.context.get('user')
junior_article_obj = JuniorArticlePoints.objects.filter(junior__auth=context_data, question=obj).last()
if junior_article_obj:
return junior_article_obj.is_attempt
return False
class Meta:
"""
meta class
"""
model = ArticleSurvey
fields = ('id', 'question', 'options', 'points', 'is_attempt')
class StartAssessmentSerializer(serializers.ModelSerializer):
"""
serializer for article API
"""
article_survey = ArticleQuestionSerializer(many=True)
class Meta:
"""
meta class
"""
model = Article
fields = ('article_survey',)
class CheckAnswerSerializer(serializers.ModelSerializer):
"""
serializer for article API
"""
article_survey = ArticleSurveySerializer(many=True)
class Meta:
"""
meta class
"""
model = ArticleSurvey
fields = ('id', 'article_survey')
def create(self, validated_data):
"""create function"""

View File

@ -7,7 +7,8 @@ from rest_framework import routers
# local imports # local imports
from web_admin.views.analytics import AnalyticsViewSet from web_admin.views.analytics import AnalyticsViewSet
from web_admin.views.article import ArticleViewSet, DefaultArticleCardImagesViewSet, ArticleListViewSet from web_admin.views.article import (ArticleViewSet, DefaultArticleCardImagesViewSet, ArticleListViewSet,
ArticleCardListViewSet)
from web_admin.views.auth import ForgotAndResetPasswordViewSet from web_admin.views.auth import ForgotAndResetPasswordViewSet
from web_admin.views.user_management import UserManagementViewSet from web_admin.views.user_management import UserManagementViewSet
@ -17,9 +18,10 @@ router = routers.SimpleRouter()
router.register('article', ArticleViewSet, basename='article') router.register('article', ArticleViewSet, basename='article')
router.register('default-card-images', DefaultArticleCardImagesViewSet, basename='default-card-images') router.register('default-card-images', DefaultArticleCardImagesViewSet, basename='default-card-images')
router.register('user-management', UserManagementViewSet, basename='user') router.register('user-management', UserManagementViewSet, basename='user')
router.register('article-list', ArticleListViewSet, basename='article-list')
router.register('analytics', AnalyticsViewSet, basename='user-analytics') router.register('analytics', AnalyticsViewSet, basename='user-analytics')
# router.register('task-analytics', TaskAnalyticsViewSet, basename='task-analytics')
router.register('article-list', ArticleListViewSet, basename='article-list')
router.register('article-card-list', ArticleCardListViewSet, basename='article-card-list')
# forgot and reset password api for admin # forgot and reset password api for admin
router.register('admin', ForgotAndResetPasswordViewSet, basename='admin') router.register('admin', ForgotAndResetPasswordViewSet, basename='admin')

View File

@ -4,7 +4,7 @@ web_admin views file
# django imports # django imports
from rest_framework.viewsets import GenericViewSet, mixins from rest_framework.viewsets import GenericViewSet, mixins
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework import status from rest_framework import status, viewsets
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework.permissions import IsAuthenticated, AllowAny
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
@ -16,7 +16,8 @@ from base.messages import SUCCESS_CODE, ERROR_CODE
from web_admin.models import Article, ArticleCard, ArticleSurvey, DefaultArticleCardImage from web_admin.models import Article, ArticleCard, ArticleSurvey, DefaultArticleCardImage
from web_admin.permission import AdminPermission from web_admin.permission import AdminPermission
from web_admin.serializers.article_serializer import (ArticleSerializer, ArticleCardSerializer, from web_admin.serializers.article_serializer import (ArticleSerializer, ArticleCardSerializer,
DefaultArticleCardImageSerializer, ArticleListSerializer) DefaultArticleCardImageSerializer, ArticleListSerializer
)
USER = get_user_model() USER = get_user_model()
@ -224,4 +225,24 @@ class ArticleListViewSet(GenericViewSet, mixins.ListModelMixin):
paginator = self.pagination_class() paginator = self.pagination_class()
paginated_queryset = paginator.paginate_queryset(queryset, request) paginated_queryset = paginator.paginate_queryset(queryset, request)
serializer = self.serializer_class(paginated_queryset, many=True) serializer = self.serializer_class(paginated_queryset, many=True)
return custom_response(None, data=serializer.data, count=count) return custom_response(None, data=serializer.data)
class ArticleCardListViewSet(viewsets.ModelViewSet):
"""Junior Points viewset"""
serializer_class = ArticleCardSerializer
permission_classes = [IsAuthenticated]
http_method_names = ('get',)
def get_queryset(self):
"""get queryset"""
return ArticleCard.objects.filter(article=self.request.GET.get('article_id'))
def list(self, request, *args, **kwargs):
"""profile view"""
try:
queryset = self.get_queryset()
# article card list
serializer = ArticleCardSerializer(queryset, many=True)
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)