Files
Backend/crop_zoning/views.py
T

153 lines
6.0 KiB
Python
Raw Normal View History

2026-03-29 13:40:23 +03:30
from django.core.exceptions import ImproperlyConfigured
2026-03-29 15:07:14 +03:30
from django.http import Http404
2026-03-24 20:10:48 +03:30
from rest_framework import serializers, status
from rest_framework.response import Response
from rest_framework.views import APIView
from drf_spectacular.types import OpenApiTypes
2026-03-30 23:29:03 +03:30
from drf_spectacular.utils import OpenApiParameter, extend_schema
2026-03-24 20:10:48 +03:30
from config.swagger import status_response
2026-03-29 15:07:14 +03:30
from .services import (
create_zones_and_dispatch,
2026-03-30 23:29:03 +03:30
ensure_latest_area_ready_for_processing,
2026-03-29 15:07:14 +03:30
get_cultivation_risk_payload,
get_default_area_feature,
get_initial_zones_payload,
get_latest_area_payload,
get_products_payload,
get_soil_quality_payload,
get_water_need_payload,
get_zone_details_payload,
2026-04-02 23:25:39 +03:30
get_zone_page_request_params,
)
2026-03-24 20:10:48 +03:30
class AreaView(APIView):
@extend_schema(
tags=["Crop Zoning"],
2026-03-30 23:29:03 +03:30
parameters=[
OpenApiParameter(
2026-04-02 23:25:39 +03:30
name="farm_uuid",
2026-03-30 23:29:03 +03:30
type=OpenApiTypes.UUID,
location=OpenApiParameter.QUERY,
required=True,
2026-04-02 23:25:39 +03:30
description="UUID مزرعه برای گرفتن يا ساخت آخرين پردازش محدوده همان مزرعه.",
2026-04-01 18:38:05 +03:30
),
OpenApiParameter(
name="page",
type=OpenApiTypes.INT,
location=OpenApiParameter.QUERY,
required=False,
2026-04-02 23:25:39 +03:30
description="شماره صفحه زون ها. مقدار پيش فرض 1 است.",
2026-04-01 18:38:05 +03:30
),
OpenApiParameter(
name="page_size",
type=OpenApiTypes.INT,
location=OpenApiParameter.QUERY,
required=False,
2026-04-02 23:25:39 +03:30
description="تعداد زون در هر صفحه. مقدار پيش فرض 10 است.",
),
2026-03-30 23:29:03 +03:30
],
responses={
200: status_response("CropZoningAreaResponse", data=serializers.JSONField()),
400: status_response("CropZoningAreaValidationError", data=serializers.JSONField()),
500: status_response("CropZoningAreaServerError", data=serializers.JSONField()),
},
2026-03-24 20:10:48 +03:30
)
def get(self, request):
2026-04-02 23:25:39 +03:30
farm_uuid = request.query_params.get("farm_uuid")
2026-03-30 23:29:03 +03:30
try:
2026-04-01 18:38:05 +03:30
page, page_size = get_zone_page_request_params(request.query_params)
2026-04-02 23:25:39 +03:30
crop_area = ensure_latest_area_ready_for_processing(farm_uuid=farm_uuid, owner=request.user)
2026-03-30 23:29:03 +03:30
except ValueError as exc:
return Response({"status": "error", "message": str(exc)}, status=status.HTTP_400_BAD_REQUEST)
except ImproperlyConfigured as exc:
return Response({"status": "error", "message": str(exc)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
2026-04-01 18:38:05 +03:30
return Response(
{"status": "success", "data": get_latest_area_payload(crop_area, page=page, page_size=page_size)},
status=status.HTTP_200_OK,
)
2026-03-24 20:10:48 +03:30
class ProductsView(APIView):
@extend_schema(
tags=["Crop Zoning"],
responses={200: status_response("CropZoningProductsResponse", data=serializers.JSONField())},
)
def get(self, request):
2026-03-29 15:07:14 +03:30
return Response({"status": "success", "data": get_products_payload()}, status=status.HTTP_200_OK)
2026-03-24 20:10:48 +03:30
class ZonesInitialView(APIView):
@extend_schema(
tags=["Crop Zoning"],
request=OpenApiTypes.OBJECT,
responses={200: status_response("CropZoningZonesInitialResponse", data=serializers.JSONField())},
)
def post(self, request):
2026-03-30 23:29:03 +03:30
area_feature = (
request.data.get("area")
or request.data.get("area_geojson")
or request.data.get("boundary")
or get_default_area_feature()
)
cell_side_km = request.data.get("cell_side_km")
2026-03-29 13:40:23 +03:30
try:
2026-03-30 23:29:03 +03:30
crop_area, _zones = create_zones_and_dispatch(area_feature, cell_side_km=cell_side_km)
2026-03-29 13:40:23 +03:30
except ValueError as exc:
2026-03-29 15:07:14 +03:30
return Response({"status": "error", "message": str(exc)}, status=status.HTTP_400_BAD_REQUEST)
2026-03-29 13:40:23 +03:30
except ImproperlyConfigured as exc:
2026-03-29 15:07:14 +03:30
return Response({"status": "error", "message": str(exc)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
2026-03-29 15:07:14 +03:30
return Response({"status": "success", "data": get_initial_zones_payload(crop_area)}, status=status.HTTP_200_OK)
2026-03-29 13:40:23 +03:30
2026-03-24 20:10:48 +03:30
class ZonesWaterNeedView(APIView):
@extend_schema(
tags=["Crop Zoning"],
request=OpenApiTypes.OBJECT,
responses={200: status_response("CropZoningZonesWaterNeedResponse", data=serializers.JSONField())},
)
def post(self, request):
2026-03-29 15:07:14 +03:30
zone_ids = request.data.get("zoneIds")
return Response({"status": "success", "data": get_water_need_payload(zone_ids)}, status=status.HTTP_200_OK)
2026-03-24 20:10:48 +03:30
class ZonesSoilQualityView(APIView):
@extend_schema(
tags=["Crop Zoning"],
request=OpenApiTypes.OBJECT,
responses={200: status_response("CropZoningZonesSoilQualityResponse", data=serializers.JSONField())},
)
def post(self, request):
2026-03-29 15:07:14 +03:30
zone_ids = request.data.get("zoneIds")
return Response({"status": "success", "data": get_soil_quality_payload(zone_ids)}, status=status.HTTP_200_OK)
2026-03-24 20:10:48 +03:30
class ZonesCultivationRiskView(APIView):
@extend_schema(
tags=["Crop Zoning"],
request=OpenApiTypes.OBJECT,
responses={200: status_response("CropZoningZonesCultivationRiskResponse", data=serializers.JSONField())},
)
def post(self, request):
2026-03-29 15:07:14 +03:30
zone_ids = request.data.get("zoneIds")
return Response({"status": "success", "data": get_cultivation_risk_payload(zone_ids)}, status=status.HTTP_200_OK)
2026-03-24 20:10:48 +03:30
class ZoneDetailsView(APIView):
@extend_schema(
tags=["Crop Zoning"],
responses={200: status_response("CropZoningZoneDetailsResponse", data=serializers.JSONField())},
)
def get(self, request, zone_id):
2026-03-29 15:07:14 +03:30
try:
data = get_zone_details_payload(zone_id)
except Exception as exc:
if exc.__class__.__name__ == "DoesNotExist":
raise Http404("Zone not found")
raise
return Response({"status": "success", "data": data}, status=status.HTTP_200_OK)