diff --git a/.vscode/launch.json b/.vscode/launch.json index dbaffe5..febdb44 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,7 +16,10 @@ ], "django": true, "autoStartBrowser": false, - "program": "${workspaceFolder}/project/manage.py" + "program": "${workspaceFolder}/project/manage.py", + "console": "integratedTerminal", + // show my code only false + // "justMyCode": false } ] } \ No newline at end of file diff --git a/project/accounts/filters/__init__.py b/project/accounts/filters/__init__.py index acb7d1e..5cb88dc 100644 --- a/project/accounts/filters/__init__.py +++ b/project/accounts/filters/__init__.py @@ -21,6 +21,17 @@ class Meta: } + +class UserImageFilter(filters.FilterSet): + class Meta: + model = UserImage + fields = { + 'user_id': ['exact'], + } + + + + class DoctorFilter(filters.FilterSet): class Meta: model = Doctor diff --git a/project/accounts/migrations/0001_initial.py b/project/accounts/migrations/0001_initial.py index cf8d530..d211432 100644 --- a/project/accounts/migrations/0001_initial.py +++ b/project/accounts/migrations/0001_initial.py @@ -1,7 +1,6 @@ -# Generated by Django 5.0.3 on 2024-05-07 13:39 +# Generated by Django 5.0.3 on 2024-05-11 14:42 import django.db.models.deletion -import shortuuidfield.fields from django.conf import settings from django.db import migrations, models @@ -29,24 +28,30 @@ class Migration(migrations.Migration): ), ("full_name", models.CharField(max_length=255)), ("email", models.CharField(max_length=255, null=True, unique=True)), - ("gender", models.CharField(max_length=255)), + ("gender", models.CharField(blank=True, max_length=255, null=True)), ( "marital_status", models.CharField(blank=True, max_length=255, null=True), ), ("nationality", models.CharField(default="Egypt", max_length=255)), - ("national_id", models.CharField(max_length=255)), + ("national_id", models.CharField(max_length=255, unique=True)), ("date_of_birth", models.DateField(blank=True, null=True)), - ("notes", models.TextField(blank=True)), - ("address", models.JSONField()), - ("phone", models.JSONField()), + ("notes", models.TextField(blank=True, null=True)), + ("address", models.JSONField(blank=True, null=True)), + ("phone", models.JSONField(blank=True, null=True)), ("is_deleted", models.BooleanField(default=False)), ("created_at", models.DateTimeField(auto_now_add=True)), ("updated_at", models.DateTimeField(auto_now=True)), ("speciality", models.CharField(max_length=255)), - ("license_number", models.CharField(max_length=255)), - ("experience_years", models.PositiveIntegerField()), - ("work_days", models.CharField(max_length=255)), + ( + "license_number", + models.CharField(blank=True, max_length=255, null=True), + ), + ( + "experience_years", + models.PositiveIntegerField(blank=True, null=True), + ), + ("work_days", models.CharField(blank=True, max_length=255, null=True)), ( "user", models.OneToOneField( @@ -74,17 +79,17 @@ class Migration(migrations.Migration): ), ("full_name", models.CharField(max_length=255)), ("email", models.CharField(max_length=255, null=True, unique=True)), - ("gender", models.CharField(max_length=255)), + ("gender", models.CharField(blank=True, max_length=255, null=True)), ( "marital_status", models.CharField(blank=True, max_length=255, null=True), ), ("nationality", models.CharField(default="Egypt", max_length=255)), - ("national_id", models.CharField(max_length=255)), + ("national_id", models.CharField(max_length=255, unique=True)), ("date_of_birth", models.DateField(blank=True, null=True)), - ("notes", models.TextField(blank=True)), - ("address", models.JSONField()), - ("phone", models.JSONField()), + ("notes", models.TextField(blank=True, null=True)), + ("address", models.JSONField(blank=True, null=True)), + ("phone", models.JSONField(blank=True, null=True)), ("is_deleted", models.BooleanField(default=False)), ("created_at", models.DateTimeField(auto_now_add=True)), ("updated_at", models.DateTimeField(auto_now=True)), @@ -115,28 +120,25 @@ class Migration(migrations.Migration): ), ("full_name", models.CharField(max_length=255)), ("email", models.CharField(max_length=255, null=True, unique=True)), - ("gender", models.CharField(max_length=255)), + ("gender", models.CharField(blank=True, max_length=255, null=True)), ( "marital_status", models.CharField(blank=True, max_length=255, null=True), ), ("nationality", models.CharField(default="Egypt", max_length=255)), - ("national_id", models.CharField(max_length=255)), + ("national_id", models.CharField(max_length=255, unique=True)), ("date_of_birth", models.DateField(blank=True, null=True)), - ("notes", models.TextField(blank=True)), - ("address", models.JSONField()), - ("phone", models.JSONField()), + ("notes", models.TextField(blank=True, null=True)), + ("address", models.JSONField(blank=True, null=True)), + ("phone", models.JSONField(blank=True, null=True)), ("is_deleted", models.BooleanField(default=False)), ("created_at", models.DateTimeField(auto_now_add=True)), ("updated_at", models.DateTimeField(auto_now=True)), - ("disease_type", models.CharField(max_length=255)), - ("blood_type", models.CharField(max_length=255)), ( - "code", - shortuuidfield.fields.ShortUUIDField( - blank=True, editable=False, max_length=22, unique=True - ), + "disease_type", + models.CharField(blank=True, max_length=255, null=True), ), + ("blood_type", models.CharField(blank=True, max_length=255, null=True)), ( "user", models.OneToOneField( @@ -168,9 +170,9 @@ class Migration(migrations.Migration): ("is_deleted", models.BooleanField(default=False)), ( "user", - models.ForeignKey( + models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, - related_name="images", + related_name="image", to=settings.AUTH_USER_MODEL, ), ), diff --git a/project/accounts/migrations/0002_alter_doctor_address_alter_doctor_phone_and_more.py b/project/accounts/migrations/0002_alter_doctor_address_alter_doctor_phone_and_more.py deleted file mode 100644 index bd8248f..0000000 --- a/project/accounts/migrations/0002_alter_doctor_address_alter_doctor_phone_and_more.py +++ /dev/null @@ -1,43 +0,0 @@ -# Generated by Django 5.0.3 on 2024-05-07 14:38 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("accounts", "0001_initial"), - ] - - operations = [ - migrations.AlterField( - model_name="doctor", - name="address", - field=models.JSONField(blank=True, null=True), - ), - migrations.AlterField( - model_name="doctor", - name="phone", - field=models.JSONField(blank=True, null=True), - ), - migrations.AlterField( - model_name="employee", - name="address", - field=models.JSONField(blank=True, null=True), - ), - migrations.AlterField( - model_name="employee", - name="phone", - field=models.JSONField(blank=True, null=True), - ), - migrations.AlterField( - model_name="patient", - name="address", - field=models.JSONField(blank=True, null=True), - ), - migrations.AlterField( - model_name="patient", - name="phone", - field=models.JSONField(blank=True, null=True), - ), - ] diff --git a/project/accounts/migrations/0003_alter_doctor_gender_alter_doctor_notes_and_more.py b/project/accounts/migrations/0003_alter_doctor_gender_alter_doctor_notes_and_more.py deleted file mode 100644 index 431eec9..0000000 --- a/project/accounts/migrations/0003_alter_doctor_gender_alter_doctor_notes_and_more.py +++ /dev/null @@ -1,61 +0,0 @@ -# Generated by Django 5.0.3 on 2024-05-08 14:46 - -import shortuuidfield.fields -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("accounts", "0002_alter_doctor_address_alter_doctor_phone_and_more"), - ] - - operations = [ - migrations.AlterField( - model_name="doctor", - name="gender", - field=models.CharField(blank=True, max_length=255, null=True), - ), - migrations.AlterField( - model_name="doctor", - name="notes", - field=models.TextField(blank=True, null=True), - ), - migrations.AlterField( - model_name="employee", - name="gender", - field=models.CharField(blank=True, max_length=255, null=True), - ), - migrations.AlterField( - model_name="employee", - name="notes", - field=models.TextField(blank=True, null=True), - ), - migrations.AlterField( - model_name="patient", - name="blood_type", - field=models.CharField(blank=True, max_length=255, null=True), - ), - migrations.AlterField( - model_name="patient", - name="code", - field=shortuuidfield.fields.ShortUUIDField( - blank=True, editable=False, max_length=22, null=True, unique=True - ), - ), - migrations.AlterField( - model_name="patient", - name="disease_type", - field=models.CharField(blank=True, max_length=255, null=True), - ), - migrations.AlterField( - model_name="patient", - name="gender", - field=models.CharField(blank=True, max_length=255, null=True), - ), - migrations.AlterField( - model_name="patient", - name="notes", - field=models.TextField(blank=True, null=True), - ), - ] diff --git a/project/accounts/migrations/0004_remove_patient_code.py b/project/accounts/migrations/0004_remove_patient_code.py deleted file mode 100644 index 1d9ee80..0000000 --- a/project/accounts/migrations/0004_remove_patient_code.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 5.0.3 on 2024-05-08 18:04 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("accounts", "0003_alter_doctor_gender_alter_doctor_notes_and_more"), - ] - - operations = [ - migrations.RemoveField( - model_name="patient", - name="code", - ), - ] diff --git a/project/accounts/migrations/0005_alter_doctor_experience_years_and_more.py b/project/accounts/migrations/0005_alter_doctor_experience_years_and_more.py deleted file mode 100644 index ea92564..0000000 --- a/project/accounts/migrations/0005_alter_doctor_experience_years_and_more.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 5.0.3 on 2024-05-09 08:28 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("accounts", "0004_remove_patient_code"), - ] - - operations = [ - migrations.AlterField( - model_name="doctor", - name="experience_years", - field=models.PositiveIntegerField(blank=True, null=True), - ), - migrations.AlterField( - model_name="doctor", - name="license_number", - field=models.CharField(blank=True, max_length=255, null=True), - ), - migrations.AlterField( - model_name="doctor", - name="work_days", - field=models.CharField(blank=True, max_length=255, null=True), - ), - ] diff --git a/project/accounts/models/models.py b/project/accounts/models/models.py index 095701f..8fdf6db 100644 --- a/project/accounts/models/models.py +++ b/project/accounts/models/models.py @@ -17,7 +17,7 @@ class Profile(models.Model): gender = models.CharField(max_length=255, null=True,blank=True) marital_status = models.CharField(max_length=255 ,null=True,blank=True) nationality = models.CharField(max_length=255 ,default="Egypt") - national_id= models.CharField(max_length=255) + national_id= models.CharField(max_length=255 ,unique=True) date_of_birth = models.DateField(blank=True, null=True) notes= models.TextField(blank=True,null=True) address = models.JSONField(null=True, blank=True) diff --git a/project/accounts/models/patient.py b/project/accounts/models/patient.py index 37c1113..487a6d9 100644 --- a/project/accounts/models/patient.py +++ b/project/accounts/models/patient.py @@ -2,7 +2,7 @@ class UserImage(models.Model): image = models.ImageField(upload_to='user_images' ) # user = models.OneToOneField(User, on_delete=models.CASCADE ,related_name='user_images' ) - user = models.ForeignKey(User, on_delete=models.CASCADE ,related_name='images' ) + user = models.OneToOneField(User, on_delete=models.CASCADE ,related_name='image' ) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) is_deleted = models.BooleanField(default=False) diff --git a/project/accounts/serializers/patient.py b/project/accounts/serializers/patient.py index 35a25dc..9362f3d 100644 --- a/project/accounts/serializers/patient.py +++ b/project/accounts/serializers/patient.py @@ -23,7 +23,7 @@ class Meta: class PatientSerializer(serializers.ModelSerializer): - image = UserImageSerializer(many=True, read_only=True, source='user.images') + image = UserImageSerializer( read_only=True, source='user.image') address =AddressSerializer( required=False) phone=PhoneSerializer(PhoneSerializer,required=False) class Meta: diff --git a/project/accounts/tests/test_patient.py b/project/accounts/tests/test_patient.py index ac35831..fa1d914 100644 --- a/project/accounts/tests/test_patient.py +++ b/project/accounts/tests/test_patient.py @@ -239,6 +239,12 @@ def test_create_patient(self): url, obj, HTTP_AUTHORIZATION='Bearer ' + self.staff_token ) self.assertEqual(response.status_code, 201) + + response = self.client.get( + '/accounts/user-image/?user_id='+str(user.id), format='json', HTTP_AUTHORIZATION='Bearer ' + self.staff_token) + self.assertEqual(response.status_code, 200) + self.assertEqual(len(response.data), 1) + # remvove image os.remove("test_image.jpg") diff --git a/project/accounts/views/doctor.py b/project/accounts/views/doctor.py index a802a61..19f7484 100644 --- a/project/accounts/views/doctor.py +++ b/project/accounts/views/doctor.py @@ -31,11 +31,13 @@ class DoctorViewSet(viewsets.ModelViewSet): def create(self , request, *args, **kwargs): - msg,user=create_user(request.data) - if msg!="created": - return Response(msg,status=status.HTTP_400_BAD_REQUEST) - - request.data.update({'user':user.id}) + serializer = DoctorSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + doctor=serializer.save() + + user=User.objects.create_user(username=serializer.data['national_id'],password=serializer.data['national_id']) + doctor.user=user + doctor.save() - return super().create(request, *args, **kwargs) + return Response(DoctorSerializer(doctor).data, status=status.HTTP_201_CREATED) \ No newline at end of file diff --git a/project/accounts/views/employee.py b/project/accounts/views/employee.py index 716832b..4ac8c5c 100644 --- a/project/accounts/views/employee.py +++ b/project/accounts/views/employee.py @@ -21,7 +21,16 @@ class EmployeeViewSet(viewsets.ModelViewSet): queryset = Employee.objects.all() serializer_class = EmployeeSerializer permission_classes = [OwnPermission] - + def create(self , request, *args, **kwargs): + serializer = EmployeeSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + employee=serializer.save() + + user=User.objects.create_user(username=serializer.data['national_id'],password=serializer.data['national_id']) + employee.user=user + employee.save() + + return Response(EmployeeSerializer(employee).data, status=status.HTTP_201_CREATED) diff --git a/project/accounts/views/patient.py b/project/accounts/views/patient.py index c108579..90cf859 100644 --- a/project/accounts/views/patient.py +++ b/project/accounts/views/patient.py @@ -12,13 +12,6 @@ from django_filters.rest_framework import DjangoFilterBackend from rest_framework import filters as rest_filters -class UserImageViewSet(viewsets.ModelViewSet): - """ - ViewSet for handling UserImage model. - """ - queryset = UserImage.objects.all() - serializer_class = UserImageSerializer - permission_classes = [OwnPermission] class PatientViewSet(viewsets.ModelViewSet): @@ -39,11 +32,15 @@ class PatientViewSet(viewsets.ModelViewSet): def create(self , request, *args, **kwargs): - msg,user=create_user(request.data) - if msg!="created": - return Response(msg,status=status.HTTP_400_BAD_REQUEST) - - request.data.update({'user':user.id}) + + serializer = PatientSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + patient=serializer.save() + + user=User.objects.create_user(username=serializer.data['national_id'],password=serializer.data['national_id']) + patient.user=user + patient.save() + - return super().create(request, *args, **kwargs) + return Response(PatientSerializer(patient).data, status=status.HTTP_201_CREATED) \ No newline at end of file diff --git a/project/accounts/views/user.py b/project/accounts/views/user.py index 838cb67..601012d 100644 --- a/project/accounts/views/user.py +++ b/project/accounts/views/user.py @@ -15,6 +15,26 @@ from rest_framework.viewsets import GenericViewSet from rest_framework import mixins from rest_framework.generics import GenericAPIView +from accounts.permissions import OwnPermission +from accounts.filters import * +from django_filters.rest_framework import DjangoFilterBackend +class UserImageViewSet(viewsets.ModelViewSet): + """ + ViewSet for handling UserImage model. + """ + queryset = UserImage.objects.all() + serializer_class = UserImageSerializer + permission_classes = [OwnPermission] + + filter_backends = [ + DjangoFilterBackend, + + ] + filterset_class = UserImageFilter + + + + class GroupViewSet(viewsets.ModelViewSet): permission_classes = [IsAdminUser] diff --git a/project/project/media/user_images/example_0ck20Dz.jpg b/project/project/media/user_images/example_0ck20Dz.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_0ck20Dz.jpg differ diff --git a/project/project/media/user_images/example_Cd2BTaw.jpg b/project/project/media/user_images/example_Cd2BTaw.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_Cd2BTaw.jpg differ diff --git a/project/project/media/user_images/example_DJvaTRJ.jpg b/project/project/media/user_images/example_DJvaTRJ.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_DJvaTRJ.jpg differ diff --git a/project/project/media/user_images/example_GxI0Ipj.jpg b/project/project/media/user_images/example_GxI0Ipj.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_GxI0Ipj.jpg differ diff --git a/project/project/media/user_images/example_IGrpK7h.jpg b/project/project/media/user_images/example_IGrpK7h.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_IGrpK7h.jpg differ diff --git a/project/project/media/user_images/example_OuLPRqR.jpg b/project/project/media/user_images/example_OuLPRqR.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_OuLPRqR.jpg differ diff --git a/project/project/media/user_images/example_TiFK3CA.jpg b/project/project/media/user_images/example_TiFK3CA.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_TiFK3CA.jpg differ diff --git a/project/project/media/user_images/example_UIZK5V3.jpg b/project/project/media/user_images/example_UIZK5V3.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_UIZK5V3.jpg differ diff --git a/project/project/media/user_images/example_YWTQqPx.jpg b/project/project/media/user_images/example_YWTQqPx.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_YWTQqPx.jpg differ diff --git a/project/project/media/user_images/example_Zlsl8cq.jpg b/project/project/media/user_images/example_Zlsl8cq.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_Zlsl8cq.jpg differ diff --git a/project/project/media/user_images/example_aRLxZpU.jpg b/project/project/media/user_images/example_aRLxZpU.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_aRLxZpU.jpg differ diff --git a/project/project/media/user_images/example_dSrdHj3.jpg b/project/project/media/user_images/example_dSrdHj3.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_dSrdHj3.jpg differ diff --git a/project/project/media/user_images/example_lQV7DEV.jpg b/project/project/media/user_images/example_lQV7DEV.jpg new file mode 100644 index 0000000..e7203c6 Binary files /dev/null and b/project/project/media/user_images/example_lQV7DEV.jpg differ diff --git a/project/visit/migrations/0001_initial.py b/project/visit/migrations/0001_initial.py index e2faa75..7bb7637 100644 --- a/project/visit/migrations/0001_initial.py +++ b/project/visit/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.3 on 2024-05-07 13:39 +# Generated by Django 5.0.3 on 2024-05-11 14:42 import django.db.models.deletion from django.db import migrations, models @@ -19,6 +19,7 @@ class Migration(migrations.Migration): ("id", models.AutoField(primary_key=True, serialize=False)), ("visit_number", models.IntegerField(null=True)), ("ticket", models.CharField(max_length=255)), + ("measurement", models.JSONField(blank=True, null=True)), ("datatime", models.DateTimeField(auto_now_add=True)), ("created_at", models.DateTimeField(auto_now_add=True)), ("updated_at", models.DateTimeField(auto_now=True)), @@ -42,35 +43,6 @@ class Migration(migrations.Migration): ), ], ), - migrations.CreateModel( - name="Measurement", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("height", models.CharField(max_length=255)), - ("weight", models.CharField(max_length=255)), - ("blood_pressure", models.CharField(max_length=255)), - ("temperature", models.CharField(max_length=255)), - ("pulse", models.CharField(max_length=255)), - ("oxygen_level", models.CharField(max_length=255)), - ("created_at", models.DateTimeField(auto_now_add=True)), - ("updated_at", models.DateTimeField(auto_now=True)), - ("is_deleted", models.BooleanField(default=False)), - ( - "visit", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="visit.visit" - ), - ), - ], - ), migrations.CreateModel( name="Attachment", fields=[ diff --git a/project/visit/migrations/0002_visit_measurement_delete_measurement.py b/project/visit/migrations/0002_visit_measurement_delete_measurement.py deleted file mode 100644 index aeacee8..0000000 --- a/project/visit/migrations/0002_visit_measurement_delete_measurement.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 5.0.3 on 2024-05-08 16:34 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("visit", "0001_initial"), - ] - - operations = [ - migrations.AddField( - model_name="visit", - name="measurement", - field=models.JSONField(blank=True, null=True), - ), - migrations.DeleteModel( - name="Measurement", - ), - ] diff --git a/project/visit/tests/test_setup.py b/project/visit/tests/test_setup.py index d5cb13f..15bda8a 100644 --- a/project/visit/tests/test_setup.py +++ b/project/visit/tests/test_setup.py @@ -38,7 +38,7 @@ def create_user(self, username='test', password='test123'): return user def create_patient(self, staff_token, - national_id='01234567890123', + national_id='012345678980123', marital_status='test', nationality='test', full_name='test', @@ -93,7 +93,7 @@ def create_visit(self, staff_token, return response.data def create_doctor(self, staff_token, full_name='test', - national_id='01234567890123', + national_id='012345678901823', speciality='test', license_number='test', experience_years=2,