From 5276c8af669c7263ffbff2488dbc4121768a340e Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Thu, 31 Aug 2023 23:03:18 +0530 Subject: [PATCH] fix: user duplicate skill in facility_userskill (#1568) fix user duplicate skill --- care/facility/api/viewsets/facility_users.py | 18 +++--- care/users/api/serializers/skill.py | 14 +++- care/users/api/serializers/user.py | 67 +++++++++++--------- 3 files changed, 60 insertions(+), 39 deletions(-) diff --git a/care/facility/api/viewsets/facility_users.py b/care/facility/api/viewsets/facility_users.py index a03319ecf8..2d6ea85329 100644 --- a/care/facility/api/viewsets/facility_users.py +++ b/care/facility/api/viewsets/facility_users.py @@ -8,12 +8,12 @@ from care.facility.models.facility import Facility from care.users.api.serializers.user import UserAssignedSerializer -from care.users.models import Skill, User +from care.users.models import User, UserSkill class UserFilter(filters.FilterSet): user_type = filters.TypedChoiceFilter( - choices=[(key, key) for key in User.TYPE_VALUE_MAP.keys()], + choices=[(key, key) for key in User.TYPE_VALUE_MAP], coerce=lambda role: User.TYPE_VALUE_MAP[role], ) @@ -33,14 +33,16 @@ class FacilityUserViewSet(GenericViewSet, mixins.ListModelMixin): def get_queryset(self): try: facility = Facility.objects.get( - external_id=self.kwargs.get("facility_external_id") + external_id=self.kwargs.get("facility_external_id"), ) - queryset = facility.users.filter(deleted=False).order_by("-last_login") - queryset = queryset.prefetch_related( + queryset = facility.users.filter( + deleted=False, + ).order_by("-last_login") + return queryset.prefetch_related( Prefetch( - "skills", queryset=Skill.objects.filter(userskill__deleted=False) - ) + "skills", + queryset=UserSkill.objects.filter(skill__deleted=False), + ), ) - return queryset except Facility.DoesNotExist: raise ValidationError({"Facility": "Facility not found"}) diff --git a/care/users/api/serializers/skill.py b/care/users/api/serializers/skill.py index a68270e5a2..0bbdb04f66 100644 --- a/care/users/api/serializers/skill.py +++ b/care/users/api/serializers/skill.py @@ -1,6 +1,6 @@ -from rest_framework.serializers import ModelSerializer, UUIDField +from rest_framework.serializers import CharField, ModelSerializer, UUIDField -from care.users.models import Skill +from care.users.models import Skill, UserSkill class SkillSerializer(ModelSerializer): @@ -9,3 +9,13 @@ class SkillSerializer(ModelSerializer): class Meta: model = Skill fields = ("id", "name", "description") + + +class UserSkillSerializer(ModelSerializer): + id = UUIDField(source="skill.external_id", read_only=True) + name = CharField(source="skill.name", read_only=True) + description = CharField(source="skill.description", read_only=True) + + class Meta: + model = UserSkill + fields = ("id", "name", "description") diff --git a/care/users/api/serializers/user.py b/care/users/api/serializers/user.py index c7f5c75056..0613b3437f 100644 --- a/care/users/api/serializers/user.py +++ b/care/users/api/serializers/user.py @@ -12,7 +12,7 @@ LocalBodySerializer, StateSerializer, ) -from care.users.api.serializers.skill import SkillSerializer +from care.users.api.serializers.skill import UserSkillSerializer from care.users.models import GENDER_CHOICES from care.utils.queryset.facility import get_home_facility_queryset from care.utils.serializer.external_id_field import ExternalIdSerializerField @@ -60,28 +60,28 @@ def validate(self, attrs): raise serializers.ValidationError( { "doctor_qualification": "Field required for Doctor User Type", - } + }, ) if not attrs.get("doctor_experience_commenced_on"): raise serializers.ValidationError( { "doctor_experience_commenced_on": "Field required for Doctor User Type", - } + }, ) if attrs["doctor_experience_commenced_on"] > date.today(): raise serializers.ValidationError( { "doctor_experience_commenced_on": "Experience cannot be in the future", - } + }, ) if not attrs.get("doctor_medical_council_registration"): raise serializers.ValidationError( { "doctor_medical_council_registration": "Field required for Doctor User Type", - } + }, ) return validated @@ -90,10 +90,14 @@ def validate(self, attrs): class UserCreateSerializer(SignUpSerializer): password = serializers.CharField(required=False) facilities = serializers.ListSerializer( - child=serializers.UUIDField(), required=False, allow_empty=True, write_only=True + child=serializers.UUIDField(), + required=False, + allow_empty=True, + write_only=True, ) home_facility = ExternalIdSerializerField( - queryset=Facility.objects.all(), required=False + queryset=Facility.objects.all(), + required=False, ) class Meta: @@ -119,11 +123,11 @@ def validate_facilities(self, facility_ids): != Facility.objects.filter(external_id__in=facility_ids).count() ): available_facility_ids = Facility.objects.filter( - external_id__in=facility_ids + external_id__in=facility_ids, ).values_list("external_id", flat=True) not_found_ids = list(set(facility_ids) - set(available_facility_ids)) raise serializers.ValidationError( - f"Some facilities are not available - {', '.join([str(_id) for _id in not_found_ids])}" + f"Some facilities are not available - {', '.join([str(_id) for _id in not_found_ids])}", ) return facility_ids @@ -147,7 +151,7 @@ def validate_local_body(self, value): >= User.TYPE_VALUE_MAP["DistrictAdmin"] ): raise serializers.ValidationError( - "Cannot create for a different local body" + "Cannot create for a different local body", ) return value @@ -172,14 +176,14 @@ def validate_state(self, value): return value def validate(self, attrs): - validated = super(UserCreateSerializer, self).validate(attrs) + validated = super().validate(attrs) if "home_facility" in validated: allowed_facilities = get_home_facility_queryset(self.context["created_by"]) if not allowed_facilities.filter(id=validated["home_facility"].id).exists(): raise exceptions.ValidationError( { - "home_facility": "Cannot create users with different Home Facility" - } + "home_facility": "Cannot create users with different Home Facility", + }, ) if self.context["created_by"].user_type in READ_ONLY_USER_TYPES: @@ -187,9 +191,9 @@ def validate(self, attrs): raise exceptions.ValidationError( { "user_type": [ - "Read only users can create other read only users only" - ] - } + "Read only users can create other read only users only", + ], + }, ) if ( @@ -204,9 +208,9 @@ def validate(self, attrs): raise exceptions.ValidationError( { "user_type": [ - "User cannot create another user with higher permissions" - ] - } + "User cannot create another user with higher permissions", + ], + }, ) if ( @@ -216,7 +220,7 @@ def validate(self, attrs): and not validated.get("state") ): raise exceptions.ValidationError( - {"__all__": ["One of ward, local body, district or state is required"]} + {"__all__": ["One of ward, local body, district or state is required"]}, ) return validated @@ -239,7 +243,9 @@ def create(self, validated_data): with transaction.atomic(): facilities = validated_data.pop("facilities", []) user = User.objects.create_user( - created_by=self.context["created_by"], verified=True, **validated_data + created_by=self.context["created_by"], + verified=True, + **validated_data, ) facility_query = self.facility_query(self.context["created_by"]) if facilities: @@ -265,7 +271,8 @@ class UserSerializer(SignUpSerializer): district_object = DistrictSerializer(source="district", read_only=True) state_object = StateSerializer(source="state", read_only=True) home_facility_object = FacilityBareMinimumSerializer( - source="home_facility", read_only=True + source="home_facility", + read_only=True, ) home_facility = ExternalIdSerializerField(queryset=Facility.objects.all()) @@ -318,16 +325,16 @@ class Meta: extra_kwargs = {"url": {"lookup_field": "username"}} def validate(self, attrs): - validated = super(UserSerializer, self).validate(attrs) + validated = super().validate(attrs) if "home_facility" in validated: allowed_facilities = get_home_facility_queryset( - self.context["request"].user + self.context["request"].user, ) if not allowed_facilities.filter(id=validated["home_facility"].id).exists(): raise exceptions.ValidationError( { - "home_facility": "Cannot create users with different Home Facility" - } + "home_facility": "Cannot create users with different Home Facility", + }, ) return validated @@ -351,9 +358,10 @@ class Meta: class UserAssignedSerializer(serializers.ModelSerializer): user_type = ChoiceField(choices=User.TYPE_CHOICES, read_only=True) home_facility_object = FacilityBareMinimumSerializer( - source="home_facility", read_only=True + source="home_facility", + read_only=True, ) - skills = SkillSerializer(many=True, read_only=True) + skills = UserSkillSerializer(many=True, read_only=True) class Meta: model = User @@ -381,7 +389,8 @@ class UserListSerializer(serializers.ModelSerializer): user_type = ChoiceField(choices=User.TYPE_CHOICES, read_only=True) created_by = serializers.CharField(source="created_by_user", read_only=True) home_facility_object = FacilityBareMinimumSerializer( - source="home_facility", read_only=True + source="home_facility", + read_only=True, ) home_facility = ExternalIdSerializerField(queryset=Facility.objects.all())