From 4fee037467e3583af477b7345ad92a0095d743ed Mon Sep 17 00:00:00 2001 From: komoliddin Date: Thu, 23 Apr 2026 11:49:55 +0500 Subject: [PATCH 1/2] Add is_archive field to Quickevaluation model. Write apis for update is_archive and list archived quick evaluations --- core/apps/evaluation/models/quick.py | 5 ++ .../serializers/quick/QuickEvaluation.py | 8 +- core/apps/evaluation/urls.py | 2 + core/apps/evaluation/views/didox.py | 4 +- core/apps/evaluation/views/quick.py | 84 ++++++++++++++++++- core/apps/evaluation/views/tech_passport.py | 4 +- 6 files changed, 99 insertions(+), 8 deletions(-) diff --git a/core/apps/evaluation/models/quick.py b/core/apps/evaluation/models/quick.py index d501397..819e16c 100644 --- a/core/apps/evaluation/models/quick.py +++ b/core/apps/evaluation/models/quick.py @@ -132,6 +132,11 @@ class QuickEvaluationModel(AbstractBaseModel): default=QuickEvaluationStatus.CREATED, ) + is_archive = models.BooleanField( + verbose_name=_("is archive"), + default=False, + ) + def __str__(self): return f"Quick Evaluation {self.pk} by {self.created_by}" diff --git a/core/apps/evaluation/serializers/quick/QuickEvaluation.py b/core/apps/evaluation/serializers/quick/QuickEvaluation.py index 93348d7..23019f4 100644 --- a/core/apps/evaluation/serializers/quick/QuickEvaluation.py +++ b/core/apps/evaluation/serializers/quick/QuickEvaluation.py @@ -38,7 +38,8 @@ class BaseQuickevaluationSerializer(serializers.ModelSerializer): "state_car_name", "created_at", "distance_covered", - "tex_passport_serie_num" + "tex_passport_serie_num", + "is_archive" ] @@ -125,3 +126,8 @@ class CreateQuickevaluationSerializer(serializers.ModelSerializer): if request and request.user and request.user.is_authenticated: validated_data["created_by"] = request.user return super().create(validated_data) + + +class ArchiveQuickevaluationSerializer(serializers.Serializer): + id = serializers.IntegerField(required=True) + is_archive = serializers.BooleanField(required=True) \ No newline at end of file diff --git a/core/apps/evaluation/urls.py b/core/apps/evaluation/urls.py index a530b3c..1c4a54d 100644 --- a/core/apps/evaluation/urls.py +++ b/core/apps/evaluation/urls.py @@ -29,6 +29,7 @@ from .views import ( DidoxCompanyInfoAPIView, TechPassportAPIView, EvaluationStatusChange, + ArchiveQuickEvaluationView, ) router = DefaultRouter() @@ -74,4 +75,5 @@ urlpatterns = [ ), path("evaluation-request//change-status/", EvaluationStatusChange.as_view(), name="evaluation-change-status"), + path("quick-evaluation/archive/", ArchiveQuickEvaluationView.as_view(), name="quick-evaluation-archive"), ] diff --git a/core/apps/evaluation/views/didox.py b/core/apps/evaluation/views/didox.py index cd4752f..273a658 100644 --- a/core/apps/evaluation/views/didox.py +++ b/core/apps/evaluation/views/didox.py @@ -1,6 +1,6 @@ from rest_framework.response import Response from rest_framework import status -from rest_framework.permissions import AllowAny +from rest_framework.permissions import IsAuthenticated from rest_framework.generics import GenericAPIView @@ -11,7 +11,7 @@ from core.services.didox import DidoxService class DidoxCompanyInfoAPIView(GenericAPIView): authentication_classes = [] - permission_classes = [AllowAny] + permission_classes = [IsAuthenticated] @extend_schema( tags=["Didox"], diff --git a/core/apps/evaluation/views/quick.py b/core/apps/evaluation/views/quick.py index 87a4e80..d0970ef 100644 --- a/core/apps/evaluation/views/quick.py +++ b/core/apps/evaluation/views/quick.py @@ -1,10 +1,14 @@ from django_core.mixins import BaseViewSetMixin from django_filters.rest_framework import DjangoFilterBackend -from drf_spectacular.utils import extend_schema +from drf_spectacular.utils import extend_schema, OpenApiResponse from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.parsers import FormParser, MultiPartParser -from rest_framework.permissions import AllowAny +from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.viewsets import ModelViewSet +from rest_framework.generics import GenericAPIView +from rest_framework.response import Response +from rest_framework import status +from django.shortcuts import get_object_or_404 from core.apps.evaluation.filters.quick import QuickevaluationFilter from core.apps.evaluation.models import QuickEvaluationModel @@ -12,6 +16,7 @@ from core.apps.evaluation.serializers.quick import ( CreateQuickevaluationSerializer, ListQuickevaluationSerializer, RetrieveQuickevaluationSerializer, + ArchiveQuickevaluationSerializer, ) @@ -20,7 +25,7 @@ class QuickEvaluationView(BaseViewSetMixin, ModelViewSet): queryset = QuickEvaluationModel.objects.select_related( "created_by", "brand", "marka", "color", "fuel_type", "body_type", "state_car", "car_position", - ).all() + ).filter(is_archive=False) serializer_class = ListQuickevaluationSerializer permission_classes = [AllowAny] parser_classes = [MultiPartParser, FormParser] @@ -50,3 +55,76 @@ class QuickEvaluationView(BaseViewSetMixin, ModelViewSet): "retrieve": RetrieveQuickevaluationSerializer, "create": CreateQuickevaluationSerializer, } + +@extend_schema(tags=["QuickEvaluation"]) +class ArchiveQuickEvaluationView(GenericAPIView): + permission_classes = [IsAuthenticated] + + def get_serializer_class(self): + if self.request.method == "GET": + return ListQuickevaluationSerializer + return ArchiveQuickevaluationSerializer + + @extend_schema( + tags=["QuickEvaluation"], + summary="Get archived quick evaluations list", + description=""" + Returns only archived quick evaluations. + + This endpoint works like quick-evaluation/, + but only records with is_archive=True are returned. + """, + responses={200: ListQuickevaluationSerializer(many=True)}, + ) + def get(self, request, *args, **kwargs): + queryset = QuickEvaluationModel.objects.filter( + is_archive=True + ).order_by("-created_at") + + serializer = self.get_serializer(queryset, many=True) + + return Response(serializer.data, status=status.HTTP_200_OK) + + @extend_schema( + tags=["QuickEvaluation"], + summary="Archive or unarchive quick evaluation", + description=""" + Update archive status for quick evaluation. + + - is_archive=true → archive + - is_archive=false → remove from archive + """, + request=ArchiveQuickevaluationSerializer, + responses={ + 200: OpenApiResponse( + description="Archive status updated successfully" + ), + 400: OpenApiResponse( + description="Validation error" + ), + 404: OpenApiResponse( + description="Quick evaluation not found" + ), + }, + ) + def post(self, request, *args, **kwargs): + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + + validated_data = serializer.validated_data + + obj = get_object_or_404( + QuickEvaluationModel, + id=validated_data["id"] + ) + + obj.is_archive = validated_data["is_archive"] + obj.save(update_fields=["is_archive"]) + + return Response( + { + "success": True, + "message": "Archive status updated successfully" + }, + status=status.HTTP_200_OK + ) \ No newline at end of file diff --git a/core/apps/evaluation/views/tech_passport.py b/core/apps/evaluation/views/tech_passport.py index 28ade15..b1af112 100644 --- a/core/apps/evaluation/views/tech_passport.py +++ b/core/apps/evaluation/views/tech_passport.py @@ -1,6 +1,6 @@ from rest_framework.response import Response from rest_framework import status -from rest_framework.permissions import AllowAny +from rest_framework.permissions import IsAuthenticated from rest_framework.generics import GenericAPIView from drf_spectacular.utils import ( @@ -14,7 +14,7 @@ from ..serializers import TechPassportSerializer class TechPassportAPIView(GenericAPIView): authentication_classes = [] - permission_classes = [AllowAny] + permission_classes = [IsAuthenticated] @extend_schema( tags=["Tech Passport"], From 5cf4b950fbf0e3fe5b9c57a2529f487128c1befe Mon Sep 17 00:00:00 2001 From: komoliddin Date: Thu, 23 Apr 2026 12:25:18 +0500 Subject: [PATCH 2/2] Make migrations --- .../0032_quickevaluationmodel_is_archive.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 core/apps/evaluation/migrations/0032_quickevaluationmodel_is_archive.py diff --git a/core/apps/evaluation/migrations/0032_quickevaluationmodel_is_archive.py b/core/apps/evaluation/migrations/0032_quickevaluationmodel_is_archive.py new file mode 100644 index 0000000..c66262c --- /dev/null +++ b/core/apps/evaluation/migrations/0032_quickevaluationmodel_is_archive.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0.4 on 2026-04-23 07:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('evaluation', '0031_remove_autoevaluationmodel_object_location_city_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='quickevaluationmodel', + name='is_archive', + field=models.BooleanField(default=False, verbose_name='is archive'), + ), + ]