From 676d9c5dcd42e8684f4aca11ef2f5153f6739529 Mon Sep 17 00:00:00 2001 From: behruz-dev Date: Wed, 3 Dec 2025 16:48:59 +0500 Subject: [PATCH] plan uchun yangi fieldlar qoshildi --- core/apps/dashboard/serializers/plan.py | 2 +- core/apps/dashboard/views/plan.py | 2 +- ...lan_doctor_plan_extra_location_and_more.py | 44 +++++++++ core/apps/shared/models/plan.py | 9 +- core/apps/shared/serializers/plan.py | 92 +++++++++++++++---- core/apps/shared/views/plan.py | 36 +++++--- 6 files changed, 152 insertions(+), 33 deletions(-) create mode 100644 core/apps/shared/migrations/0016_plan_comment_plan_doctor_plan_extra_location_and_more.py diff --git a/core/apps/dashboard/serializers/plan.py b/core/apps/dashboard/serializers/plan.py index 5ea7a75..ac620e5 100644 --- a/core/apps/dashboard/serializers/plan.py +++ b/core/apps/dashboard/serializers/plan.py @@ -33,7 +33,7 @@ class PlanListSerializer(serializers.ModelSerializer): } -class PlanCreateSerializer(serializers.Serializer): +class AdminPlanCreateSerializer(serializers.Serializer): title = serializers.CharField() description = serializers.CharField() date = serializers.DateField() diff --git a/core/apps/dashboard/views/plan.py b/core/apps/dashboard/views/plan.py index f9a9af7..bfad78b 100644 --- a/core/apps/dashboard/views/plan.py +++ b/core/apps/dashboard/views/plan.py @@ -23,7 +23,7 @@ class PlanViewSet(viewsets.GenericViewSet, ResponseMixin): def get_serializer_class(self): if self.action == "post": - return serializers.PlanCreateSerializer + return serializers.AdminPlanCreateSerializer elif self.action in ("patch", "put"): return serializers.PlanUpdateSerializer else: diff --git a/core/apps/shared/migrations/0016_plan_comment_plan_doctor_plan_extra_location_and_more.py b/core/apps/shared/migrations/0016_plan_comment_plan_doctor_plan_extra_location_and_more.py new file mode 100644 index 0000000..d5a163a --- /dev/null +++ b/core/apps/shared/migrations/0016_plan_comment_plan_doctor_plan_extra_location_and_more.py @@ -0,0 +1,44 @@ +# Generated by Django 5.2 on 2025-12-03 11:16 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('shared', '0015_support_type'), + ] + + operations = [ + migrations.AddField( + model_name='plan', + name='comment', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='plan', + name='doctor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plans', to='shared.doctor'), + ), + migrations.AddField( + model_name='plan', + name='extra_location', + field=models.JSONField(blank=True, null=True), + ), + migrations.AddField( + model_name='plan', + name='latitude', + field=models.FloatField(default=0.0), + ), + migrations.AddField( + model_name='plan', + name='longitude', + field=models.FloatField(default=0.0), + ), + migrations.AddField( + model_name='plan', + name='pharmacy', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plans', to='shared.pharmacy'), + ), + ] diff --git a/core/apps/shared/models/plan.py b/core/apps/shared/models/plan.py index 8b1255f..1e3c086 100644 --- a/core/apps/shared/models/plan.py +++ b/core/apps/shared/models/plan.py @@ -1,7 +1,7 @@ from django.db import models # shared -from core.apps.shared.models import BaseModel +from core.apps.shared.models import BaseModel, Doctor, Pharmacy # accounts from core.apps.accounts.models import User @@ -11,8 +11,15 @@ class Plan(BaseModel): description = models.TextField() date = models.DateField() is_done = models.BooleanField(default=False) + comment = models.TextField(null=True, blank=True) # relations user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='plans') + doctor = models.ForeignKey(Doctor, on_delete=models.SET_NULL, related_name='plans', null=True, blank=True) + pharmacy = models.ForeignKey(Pharmacy, on_delete=models.SET_NULL, related_name='plans', null=True, blank=True) + # location + longitude = models.FloatField(default=0.00) + latitude = models.FloatField(default=0.00) + extra_location = models.JSONField(null=True, blank=True) def __str__(self): return self.title \ No newline at end of file diff --git a/core/apps/shared/serializers/plan.py b/core/apps/shared/serializers/plan.py index 7c8bd96..350130d 100644 --- a/core/apps/shared/serializers/plan.py +++ b/core/apps/shared/serializers/plan.py @@ -5,37 +5,91 @@ from django.db import transaction from rest_framework import serializers # shared -from core.apps.shared.models import Plan +from core.apps.shared.models import Plan, Doctor, Pharmacy -class PlanSerializer(serializers.ModelSerializer): - class Meta: - model = Plan - fields = [ - 'id', 'title', 'description', 'date', 'is_done', 'created_at' - ] +class PlanCreateSerializer(serializers.Serializer): + title = serializers.CharField(max_length=200) + description = serializers.CharField() + date = serializers.DateField() + doctor_id = serializers.IntegerField(required=False, allow_null=True) + pharmacy_id = serializers.IntegerField(required=False, allow_null=True) + + longitude = serializers.FloatField(required=False, default=0.0) + latitude = serializers.FloatField(required=False, default=0.0) + extra_location = serializers.JSONField(required=False, allow_null=True) + + def validate(self, data): + if data.get('doctor_id'): + doctor = Doctor.objects.filter(id=data.get('doctor_id')).first() + if not doctor: + raise serializers.ValidationError({"doctor": "Doctor not found"}) + data['doctor'] = doctor + if data.get('pharmacy_id'): + pharmacy = Pharmacy.objects.filter(id=data.get('pharmacy_id')).first() + if not pharmacy: + raise serializers.ValidationError({"pharmacy_id": "Pharmacy not found"}) + data['pharmacy'] = pharmacy + + return data def create(self, validated_data): with transaction.atomic(): - return Plan.objects.create( - title=validated_data.get('title'), - description=validated_data.get('description'), - date=validated_data.get('date'), - user=self.context.get('user'), + user = self.context['user'] + doctor = validated_data.pop('doctor', None) + pharmacy = validated_data.pop('pharmacy', None) + plan = Plan.objects.create( + user=user, + doctor=doctor, + pharmacy=pharmacy, + **validated_data ) - + return plan + + +class PlanSerializer(serializers.ModelSerializer): + doctor = serializers.SerializerMethodField(method_name='get_doctor') + pharmacy = serializers.SerializerMethodField(method_name='get_pharmacy') + + class Meta: + model = Plan + fields = [ + 'id', 'title', 'description', 'date', + 'comment', 'doctor', 'pharmacy', + 'longitude', 'latitude', 'extra_location', + 'created_at' + ] + read_only_fields = ['id', 'is_done', 'created_at'] + + def get_doctor(self, obj): + return { + "id": obj.doctor.id, + "first_name": obj.doctor.first_name, + "last_name": obj.doctor.last_name + } if obj.doctor is not None else None + + def get_pharmacy(self, obj): + return { + "id": obj.pharmacy.id, + "name": obj.pharmacy.name, + } if obj.pharmacy is not None else None + class PlanUpdateSerializer(serializers.ModelSerializer): class Meta: model = Plan fields = [ - 'title', 'description', 'date', 'is_done', + 'title', 'description', 'date', + 'comment', 'doctor', 'pharmacy', + 'longitude', 'latitude', 'extra_location', ] def update(self, instance, validated_data): - instance.title = validated_data.get('title', instance.title) - instance.description = validated_data.get('description', instance.description) - instance.date = validated_data.get('date', instance.date) - instance.is_done = validated_data.get('is_done') + for field, value in validated_data.items(): + setattr(instance, field, value) instance.save() - return instance \ No newline at end of file + return instance + + +class PlanCompliteSerializer(serializers.Serializer): + comment = serializers.CharField() \ No newline at end of file diff --git a/core/apps/shared/views/plan.py b/core/apps/shared/views/plan.py index a9e7744..636bee4 100644 --- a/core/apps/shared/views/plan.py +++ b/core/apps/shared/views/plan.py @@ -10,16 +10,21 @@ from drf_yasg import openapi # shared from core.apps.shared.models import Plan from core.apps.shared.serializers.base import BaseResponseSerializer, SuccessResponseSerializer -from core.apps.shared.serializers.plan import PlanSerializer, PlanUpdateSerializer +from core.apps.shared.serializers.plan import PlanSerializer, PlanUpdateSerializer, PlanCreateSerializer, PlanCompliteSerializer from core.apps.shared.utils.response_mixin import ResponseMixin class PlanApiView(generics.GenericAPIView, ResponseMixin): - serializer_class = PlanSerializer queryset = Plan.objects.all() permission_classes = [permissions.IsAuthenticated] + def get_serializer_class(self): + if self.request.method == 'POST': + return PlanCreateSerializer + else: + return PlanSerializer + @swagger_auto_schema( operation_description="date boyicha filter bor, ?date=date", responses={ @@ -34,7 +39,7 @@ class PlanApiView(generics.GenericAPIView, ResponseMixin): queryset = self.queryset.filter(user=request.user) if date: queryset = queryset.filter(date=date) - serializer = self.serializer_class(queryset, many=True) + serializer = self.get_serializer(queryset, many=True) return self.success_response(data=serializer.data, message='malumotlar fetch qilindi') except Exception as e: return self.error_response(data=str(e), message='xatolik') @@ -48,7 +53,7 @@ class PlanApiView(generics.GenericAPIView, ResponseMixin): ) def post(self, request): try: - serializer = self.serializer_class(data=request.data, context={'user': request.user}) + serializer = self.get_serializer(data=request.data, context={'user': request.user}) if serializer.is_valid(): obj = serializer.save() created_data = PlanSerializer(obj).data @@ -63,7 +68,7 @@ class PlanApiView(generics.GenericAPIView, ResponseMixin): class ComplitePlanApiView(generics.GenericAPIView, ResponseMixin): - serializer_class = None + serializer_class = PlanCompliteSerializer queryset = Plan.objects.all() permission_classes = [permissions.IsAuthenticated] @@ -80,12 +85,21 @@ class ComplitePlanApiView(generics.GenericAPIView, ResponseMixin): def post(self, request, id): try: obj = get_object_or_404(Plan, id=id, user=request.user) - obj.is_done = True - obj.save() - return self.success_response( - data=PlanSerializer(obj).data, - message='malumot yangilandi' - ) + serializer = self.serializer_class(data=request.data) + if serializer.is_valid(): + comment = serializer.validated_data.get('comment') + obj.is_done = True + obj.comment = comment + obj.save() + return self.success_response( + data=PlanSerializer(obj).data, + message='malumot yangilandi' + ) + else: + return self.failure_response( + data=serializer.errors, + message="malumot yangilanmadi" + ) except Exception as e: return self.error_response(data=str(e), message='xatolik')