Skip to content

Commit

Permalink
fix: user duplicate skill in facility_userskill (#1568)
Browse files Browse the repository at this point in the history
fix user duplicate skill
  • Loading branch information
sainak authored Aug 31, 2023
1 parent c000eea commit 5276c8a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 39 deletions.
18 changes: 10 additions & 8 deletions care/facility/api/viewsets/facility_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -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],
)

Expand All @@ -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"})
14 changes: 12 additions & 2 deletions care/users/api/serializers/skill.py
Original file line number Diff line number Diff line change
@@ -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):
Expand All @@ -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")
67 changes: 38 additions & 29 deletions care/users/api/serializers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -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

Expand All @@ -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

Expand All @@ -172,24 +176,24 @@ 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:
if validated["user_type"] not in READ_ONLY_USER_TYPES:
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 (
Expand All @@ -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 (
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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())
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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())

Expand Down

0 comments on commit 5276c8a

Please sign in to comment.