diff --git a/base/messages.py b/base/messages.py index bff508d..e891ae1 100644 --- a/base/messages.py +++ b/base/messages.py @@ -142,7 +142,9 @@ SUCCESS_CODE = { "3033": "Valid Referral code", "3034": "Invite guardian successfully", "3035": "Task started successfully", - "3036": "Task reassign successfully" + "3036": "Task reassign successfully", + "3037": "Profile has been updated successfully.", + "3038": "Status has been changed successfully." } """status code error""" STATUS_CODE_ERROR = { diff --git a/web_admin/serializers/user_management_serializer.py b/web_admin/serializers/user_management_serializer.py index 5221e12..9333155 100644 --- a/web_admin/serializers/user_management_serializer.py +++ b/web_admin/serializers/user_management_serializer.py @@ -5,15 +5,11 @@ web_admin user_management serializers file from rest_framework import serializers from django.contrib.auth import get_user_model -from base.constants import (ARTICLE_SURVEY_POINTS, MAX_ARTICLE_CARD, MIN_ARTICLE_SURVEY, MAX_ARTICLE_SURVEY, NUMBER, - USER_TYPE, ARTICLE_CARD_IMAGE_FOLDER) +from base.constants import USER_TYPE # local imports -from base.messages import ERROR_CODE +from base.messages import ERROR_CODE, SUCCESS_CODE from guardian.models import Guardian -from guardian.utils import upload_image_to_alibaba from junior.models import Junior -from web_admin.models import Article, ArticleCard, SurveyOption, ArticleSurvey, DefaultArticleCardImage -from web_admin.utils import pop_id, get_image_url USER = get_user_model() @@ -97,14 +93,41 @@ class UserManagementListSerializer(serializers.ModelSerializer): class GuardianSerializer(serializers.ModelSerializer): + """ + guardian serializer + """ name = serializers.SerializerMethodField() + email = serializers.CharField(required=False) class Meta: + """ + meta class + """ model = Guardian - fields = ('id', 'name', 'dob', 'gender', 'country_code', 'phone', 'is_active', 'country_name', 'image') + fields = ('id', 'name', 'dob', 'gender', 'country_code', 'phone', 'is_active', 'country_name', 'image', 'email') + + def validate(self, attrs): + """ + to validate request data + :return: validated attrs + """ + email = attrs.get('email') + phone = attrs.get('phone') + if USER.objects.filter(email=email).exclude(id=self.context.get('user_id')).exists(): + raise serializers.ValidationError({'details': ERROR_CODE['2003']}) + if Guardian.objects.filter(phone=phone).exclude(user__id=self.context.get('user_id')).exists(): + raise serializers.ValidationError({'details': ERROR_CODE['2012']}) + return attrs def update(self, instance, validated_data): - instance.user.email = self.context.get('email', instance.user.email) + """ + to update user and its related profile + :param instance: user's guardian object + :param validated_data: + :return: guardian object + """ + instance.user.email = self.validated_data.get('email', instance.user.email) + instance.user.username = self.validated_data.get('email', instance.user.username) instance.user.save() instance.country_code = validated_data.get('country_code', instance.country_code) instance.phone = validated_data.get('phone', instance.phone) @@ -121,14 +144,40 @@ class GuardianSerializer(serializers.ModelSerializer): class JuniorSerializer(serializers.ModelSerializer): + """ + junior serializer + """ name = serializers.SerializerMethodField() + email = serializers.CharField(required=False) class Meta: + """ + meta class + """ model = Junior - fields = ('id', 'name', 'dob', 'gender', 'country_code', 'phone', 'is_active', 'country_name', 'image') + fields = ('id', 'name', 'dob', 'gender', 'country_code', 'phone', 'is_active', 'country_name', 'image', 'email') + + def validate(self, attrs): + """ + to validate request data + :return: validated attrs + """ + email = attrs.get('email') + phone = attrs.get('phone') + if email and USER.objects.filter(email=email).exclude(id=self.context.get('user_id')).exists(): + raise serializers.ValidationError({'details': ERROR_CODE['2003']}) + if phone and Junior.objects.filter(phone=phone).exclude(auth__id=self.context.get('user_id')).exists(): + raise serializers.ValidationError({'details': ERROR_CODE['2012']}) + return attrs def update(self, instance, validated_data): - instance.auth.email = self.context.get('email', instance.auth.email) + """ + :param instance: user's junior object + :param validated_data: validated data + :return: instance + """ + instance.auth.email = self.validated_data.get('email', instance.auth.email) + instance.auth.username = self.validated_data.get('email', instance.auth.username) instance.auth.save() instance.country_code = validated_data.get('country_code', instance.country_code) instance.phone = validated_data.get('phone', instance.phone) @@ -145,6 +194,9 @@ class JuniorSerializer(serializers.ModelSerializer): class UserManagementDetailSerializer(serializers.ModelSerializer): + """ + user management details serializer + """ user_type = serializers.SerializerMethodField() guardian_profile = GuardianSerializer(many=True) junior_profile = JuniorSerializer(many=True) @@ -163,7 +215,6 @@ class UserManagementDetailSerializer(serializers.ModelSerializer): :param obj: user object :return: user type """ - profile = obj.guardian_profile.all().first() if obj.guardian_profile.all().first(): return dict(USER_TYPE).get('2') elif obj.junior_profile.all().first(): @@ -173,6 +224,10 @@ class UserManagementDetailSerializer(serializers.ModelSerializer): @staticmethod def get_associated_users(obj): + """ + :param obj: user object + :return: associated user + """ if profile := obj.guardian_profile.all().first(): junior = Junior.objects.filter(guardian_code__contains=[profile.guardian_code], is_verified=True) serializer = JuniorSerializer(junior, many=True) diff --git a/web_admin/views/article.py b/web_admin/views/article.py index be93b4c..53da6e1 100644 --- a/web_admin/views/article.py +++ b/web_admin/views/article.py @@ -109,7 +109,7 @@ class ArticleViewSet(GenericViewSet, mixins.CreateModelMixin, mixins.UpdateModel return custom_response(SUCCESS_CODE["3029"]) return custom_error_response(ERROR_CODE["2041"], status.HTTP_400_BAD_REQUEST) - @action(methods=['get'], url_name='remove_card', url_path='remove_card', + @action(methods=['get'], url_name='remove-card', url_path='remove-card', detail=True) def remove_article_card(self, request, *args, **kwargs): """ @@ -125,7 +125,7 @@ class ArticleViewSet(GenericViewSet, mixins.CreateModelMixin, mixins.UpdateModel except AttributeError: return custom_error_response(ERROR_CODE["2042"], response_status=status.HTTP_400_BAD_REQUEST) - @action(methods=['get'], url_name='remove_survey', url_path='remove_survey', + @action(methods=['get'], url_name='remove-survey', url_path='remove-survey', detail=True) def remove_article_survey(self, request, *args, **kwargs): """ diff --git a/web_admin/views/user_management.py b/web_admin/views/user_management.py index e4018ac..256248b 100644 --- a/web_admin/views/user_management.py +++ b/web_admin/views/user_management.py @@ -13,7 +13,7 @@ from django.db.models import Q # local imports from account.utils import custom_response, custom_error_response from base.constants import USER_TYPE -from base.messages import SUCCESS_CODE, ERROR_CODE +from base.messages import SUCCESS_CODE from web_admin.permission import AdminPermission from web_admin.serializers.user_management_serializer import (UserManagementListSerializer, UserManagementDetailSerializer, GuardianSerializer, @@ -78,19 +78,48 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin, return custom_response(None, data=serializer.data) def partial_update(self, request, *args, **kwargs): + """ + api method to update user detail (email, phone number) + :param request: user_id along with + user_type {'guardian' for Guardian, 'junior' for Junior} mandatory + :return: success message + """ if self.request.query_params.get('user_type') not in [dict(USER_TYPE).get('1'), dict(USER_TYPE).get('2')]: return custom_error_response('Action not allowed', status.HTTP_400_BAD_REQUEST) queryset = self.queryset if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'): - queryset = queryset.filter(guardian_profile__user__id=kwargs['pk']).first() - serializer = GuardianSerializer(queryset.guardian_profile.all().first(), - request.data, context={'email': request.data.get('email', queryset.email)}) + user_obj = queryset.filter(guardian_profile__user__id=kwargs['pk']).first() + serializer = GuardianSerializer(user_obj.guardian_profile.all().first(), + request.data, context={'user_id': kwargs['pk']}) elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'): - queryset = queryset.filter(junior_profile__auth__id=kwargs['pk']).first() - serializer = JuniorSerializer(queryset.junior_profile.all().first(), - request.data, context={'email': request.data.get('email', queryset.email)}) + user_obj = queryset.filter(junior_profile__auth__id=kwargs['pk']).first() + serializer = JuniorSerializer(user_obj.junior_profile.all().first(), + request.data, context={'user_id': kwargs['pk']}) serializer.is_valid(raise_exception=True) serializer.save() - return custom_response('Profile updated successfully.') + return custom_response(SUCCESS_CODE['3037']) + + @action(methods=['get'], url_name='change-status', url_path='change-status', detail=True) + def change_status(self, request, *args, **kwargs): + """ + api to change user status (mark as active or inactive) + :param request: user_id along with + user_type {'guardian' for Guardian, 'junior' for Junior} mandatory + :return: success message + """ + if self.request.query_params.get('user_type') not in [dict(USER_TYPE).get('1'), dict(USER_TYPE).get('2')]: + return custom_error_response('Action not allowed', status.HTTP_400_BAD_REQUEST) + queryset = self.queryset + if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'): + user_obj = queryset.filter(guardian_profile__user__id=kwargs['pk']).first() + obj = user_obj.guardian_profile.all().first() + obj.is_active = False if obj.is_active else True + obj.save() + elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'): + user_obj = queryset.filter(junior_profile__auth__id=kwargs['pk']).first() + obj = user_obj.junior_profile.all().first() + obj.is_active = False if obj.is_active else True + obj.save() + return custom_response(SUCCESS_CODE['3038'])