"""Serializer of Guardian""" """Third party Django app""" import logging from rest_framework import serializers # Import Refresh token of jwt from rest_framework_simplejwt.tokens import RefreshToken from django.db import transaction from django.contrib.auth.models import User from datetime import datetime, time """Import Django app""" # Import guardian's model, # Import junior's model, # Import account's model, # Import constant from # base package, # Import messages from # base package, # Import some functions # from utils file""" from .models import Guardian, JuniorTask from account.models import UserProfile, UserEmailOtp, UserNotification from account.utils import generate_code from junior.serializers import JuniorDetailSerializer from base.messages import ERROR_CODE, SUCCESS_CODE from base.constants import NUMBER, JUN, ZOD, GRD from junior.models import Junior, JuniorPoints from .utils import real_time, convert_timedelta_into_datetime # In this serializer file # define user serializer, # create guardian serializer, # task serializer, # guardian serializer, # task details serializer, # top junior serializer, # guardian profile serializer, # approve junior serializer, # approve task serializer, class UserSerializer(serializers.ModelSerializer): """User serializer""" auth_token = serializers.SerializerMethodField('get_auth_token') class Meta(object): """Meta info""" model = User fields = ['id', 'email', 'password', 'auth_token'] def get_auth_token(self, obj): """generate auth token""" refresh = RefreshToken.for_user(obj) access_token = str(refresh.access_token) return access_token def create(self, validated_data): """fetch data""" email = validated_data.get('email') user_type = self.context password = validated_data.get('password') try: """Create user profile""" user = User.objects.create_user(username=email, email=email, password=password) UserNotification.objects.create(user=user) if user_type == str(NUMBER['one']): # create junior profile Junior.objects.create(auth=user, junior_code=generate_code(JUN, user.id), referral_code=generate_code(ZOD, user.id)) if user_type == str(NUMBER['two']): # create guardian profile Guardian.objects.create(user=user, guardian_code=generate_code(GRD, user.id), referral_code=generate_code(ZOD, user.id)) return user except Exception as e: """Error handling""" logging.error(e) otp = UserEmailOtp.objects.filter(email=email).last() otp_verified = False if otp and otp.is_verified: otp_verified = True raise serializers.ValidationError({"details":ERROR_CODE['2021'], "otp_verified":bool(otp_verified), "code": 400, "status":"failed", }) # update guardian profile class CreateGuardianSerializer(serializers.ModelSerializer): """Create guardian serializer""" """Basic info""" first_name = serializers.SerializerMethodField('get_first_name') last_name = serializers.SerializerMethodField('get_last_name') email = serializers.SerializerMethodField('get_email') """Contact details""" phone = serializers.CharField(max_length=20, required=False) country_code = serializers.IntegerField(required=False) # basic info family_name = serializers.CharField(max_length=100, required=False) dob = serializers.DateField(required=False) # code info referral_code = serializers.CharField(max_length=100, required=False) # image info image = serializers.URLField(required=False) class Meta(object): """Meta info""" model = Guardian fields = ['id', 'first_name', 'last_name', 'email', 'phone', 'family_name', 'gender', 'country_code', 'dob', 'referral_code', 'passcode', 'is_complete_profile', 'referral_code_used', 'country_name', 'image'] def get_first_name(self,obj): """first name of guardian""" return obj.user.first_name def get_last_name(self,obj): """last name of guardian""" return obj.user.last_name def get_email(self,obj): """emailof guardian""" return obj.user.email def create(self, validated_data): """Create guardian profile""" user = User.objects.filter(username=self.context['user']).last() if user: """Save first and last name of guardian""" if self.context.get('first_name') != '' and self.context.get('first_name') is not None: user.first_name = self.context.get('first_name') if self.context.get('last_name') != '' and self.context.get('last_name') is not None: user.last_name = self.context.get('last_name') user.save() """Create guardian data""" guardian = Guardian.objects.filter(user=self.context['user']).last() if guardian: """update details according to the data get from request""" guardian.gender = validated_data.get('gender',guardian.gender) guardian.family_name = validated_data.get('family_name', guardian.family_name) guardian.dob = validated_data.get('dob',guardian.dob) """Update country code and phone number""" guardian.phone = validated_data.get('phone', guardian.phone) guardian.country_code = validated_data.get('country_code', guardian.country_code) guardian.passcode = validated_data.get('passcode', guardian.passcode) guardian.country_name = validated_data.get('country_name', guardian.country_name) guardian.referral_code_used = validated_data.get('referral_code_used', guardian.referral_code_used) guardian.image = validated_data.get('image', guardian.image) """Complete profile of the junior if below all data are filled""" complete_profile_field = all([guardian.gender, guardian.country_name, guardian.dob, user.first_name, guardian.image]) guardian.is_complete_profile = False if complete_profile_field: guardian.is_complete_profile = True guardian.save() return guardian def save(self, **kwargs): """Save the data into junior table""" with transaction.atomic(): instance = super().save(**kwargs) return instance class TaskSerializer(serializers.ModelSerializer): """Task serializer""" class Meta(object): """Meta info""" model = JuniorTask fields = ['id', 'task_name','task_description','points', 'due_date', 'junior', 'default_image'] def create(self, validated_data): """create default task image data""" validated_data['guardian'] = Guardian.objects.filter(user=self.context['user']).last() # update image of the task images = self.context['image'] validated_data['default_image'] = images instance = JuniorTask.objects.create(**validated_data) return instance class GuardianDetailSerializer(serializers.ModelSerializer): """junior serializer""" email = serializers.SerializerMethodField('get_auth') first_name = serializers.SerializerMethodField('get_first_name') last_name = serializers.SerializerMethodField('get_last_name') def get_auth(self, obj): """user email address""" return obj.user.username def get_first_name(self, obj): """user first name""" return obj.user.first_name def get_last_name(self, obj): """user last name""" return obj.user.last_name class Meta(object): """Meta info""" model = Guardian fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob', 'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image', 'updated_at'] class TaskDetailsSerializer(serializers.ModelSerializer): """Task detail serializer""" junior = JuniorDetailSerializer() remaining_time = serializers.SerializerMethodField('get_remaining_time') def get_remaining_time(self, obj): """ remaining time to complete task""" due_date_datetime = datetime.combine(obj.due_date, datetime.max.time()) # fetch real time current_datetime = real_time() # Perform the subtraction if due_date_datetime > current_datetime: time_difference = due_date_datetime - current_datetime time_only = convert_timedelta_into_datetime(time_difference) return str(time_difference.days) + ' days ' + str(time_only) return str(NUMBER['zero']) + ' days ' + '00:00:00:00000' class Meta(object): """Meta info""" model = JuniorTask fields = ['id', 'guardian', 'task_name', 'task_description', 'points', 'due_date','default_image', 'image', 'requested_on', 'rejected_on', 'completed_on', 'junior', 'task_status', 'is_active', 'remaining_time', 'created_at','updated_at'] class TopJuniorSerializer(serializers.ModelSerializer): """Top junior serializer""" junior = JuniorDetailSerializer() position = serializers.IntegerField() class Meta(object): """Meta info""" model = JuniorPoints fields = ['id', 'junior', 'total_task_points', 'position', 'created_at', 'updated_at'] def to_representation(self, instance): """Convert instance to representation""" representation = super().to_representation(instance) representation['position'] = instance.position return representation class GuardianProfileSerializer(serializers.ModelSerializer): """junior serializer""" email = serializers.SerializerMethodField('get_auth') first_name = serializers.SerializerMethodField('get_first_name') last_name = serializers.SerializerMethodField('get_last_name') total_count = serializers.SerializerMethodField('get_total_count') complete_field_count = serializers.SerializerMethodField('get_complete_field_count') notification_count = serializers.SerializerMethodField('get_notification_count') def get_auth(self, obj): """user email address""" return obj.user.username def get_first_name(self, obj): """user first name""" return obj.user.first_name def get_last_name(self, obj): """user last name""" return obj.user.last_name def get_total_count(self, obj): """total fields count""" return NUMBER['five'] def get_complete_field_count(self, obj): """total filled fields count""" total_field_list = [obj.user.first_name, obj.country_name, obj.gender, obj.dob, obj.image] # count total complete field total_complete_field = [data for data in total_field_list if data != '' and data is not None] return len(total_complete_field) def get_notification_count(self, obj): """total notification count""" return 0 class Meta(object): """Meta info""" model = Guardian fields = ['id', 'email', 'first_name', 'last_name', 'country_name','country_code', 'phone', 'gender', 'dob', 'guardian_code', 'notification_count', 'total_count', 'complete_field_count', 'referral_code', 'is_active', 'is_complete_profile', 'created_at', 'image', 'signup_method', 'updated_at', 'passcode'] class ApproveJuniorSerializer(serializers.ModelSerializer): """approve junior serializer""" class Meta(object): """Meta info""" model = Junior fields = ['id', 'guardian_code'] def create(self, validated_data): """update guardian code""" instance = self.context['junior'] instance.guardian_code = [self.context['guardian_code']] instance.save() return instance class ApproveTaskSerializer(serializers.ModelSerializer): """approve task serializer""" class Meta(object): """Meta info""" model = JuniorTask fields = ['id', 'task_status', 'is_approved'] def create(self, validated_data): """update task status """ instance = self.context['task_instance'] junior = self.context['junior'] junior_details = Junior.objects.filter(id=junior).last() junior_data, created = JuniorPoints.objects.get_or_create(junior=junior_details) if self.context['action'] == str(NUMBER['one']): # approve the task instance.task_status = str(NUMBER['five']) instance.is_approved = True junior_data.total_task_points = junior_data.total_task_points + instance.points instance.completed_on = datetime.today() junior_data.save() else: # reject the task instance.task_status = str(NUMBER['three']) instance.is_approved = False junior_data.total_task_points = junior_data.total_task_points - instance.points instance.rejected_on = datetime.today() junior_data.save() instance.save() return instance