UPDATE
This commit is contained in:
Binary file not shown.
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
- `farm_uuid` ورودی اصلی و الزامی است.
|
- `farm_uuid` ورودی اصلی و الزامی است.
|
||||||
- `plant_name` اگر هم توسط client ارسال شود، مبنای نهایی backend نیست و از روی مزرعه بازنویسی/resolve میشود.
|
- `plant_name` اگر هم توسط client ارسال شود، مبنای نهایی backend نیست و از روی مزرعه بازنویسی/resolve میشود.
|
||||||
- در صورت نیاز، `irrigation_plan_id` و `fertilization_plan_id` هم میتوانند ارسال شوند.
|
- در صورت نیاز، `irrigation_plan_uuid` و `fertilization_plan_uuid` هم میتوانند ارسال شوند.
|
||||||
- اگر plan انتخابی معتبر و متعلق به همان مزرعه کاربر باشد، backend محتوای آن را به payload ارسالی به AI اضافه میکند.
|
- اگر plan انتخابی معتبر و متعلق به همان مزرعه کاربر باشد، backend محتوای آن را به payload ارسالی به AI اضافه میکند.
|
||||||
- خروجی backend بهصورت یکدست با فرمت `code / msg / data` برگردانده میشود.
|
- خروجی backend بهصورت یکدست با فرمت `code / msg / data` برگردانده میشود.
|
||||||
|
|
||||||
@@ -33,16 +33,16 @@
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
||||||
"irrigation_plan_id": 12,
|
"irrigation_plan_uuid": "6d6a1f0d-1a9b-4f2f-8fe1-2d73d9d2d9f1",
|
||||||
"fertilization_plan_id": 34
|
"fertilization_plan_uuid": "7e7b2f1e-2b0c-4a3a-9fe2-3e84e0e3e0a2"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### فیلدها
|
### فیلدها
|
||||||
|
|
||||||
- `farm_uuid` اجباری
|
- `farm_uuid` اجباری
|
||||||
- `irrigation_plan_id` اختیاری
|
- `irrigation_plan_uuid` اختیاری
|
||||||
- `fertilization_plan_id` اختیاری
|
- `fertilization_plan_uuid` اختیاری
|
||||||
|
|
||||||
### نکته مهم
|
### نکته مهم
|
||||||
|
|
||||||
@@ -56,8 +56,8 @@
|
|||||||
|
|
||||||
- ورودی endpoint عملاً بر پایه `farm_uuid` کار میکند و `plant_name` از context مزرعه تعیین میشود.
|
- ورودی endpoint عملاً بر پایه `farm_uuid` کار میکند و `plant_name` از context مزرعه تعیین میشود.
|
||||||
- backend بهصورت خودکار `plant_name` را از مزرعه پیدا میکند.
|
- backend بهصورت خودکار `plant_name` را از مزرعه پیدا میکند.
|
||||||
- در صورت ارسال `irrigation_plan_id`، اطلاعات برنامه آبیاری داخل payload ارسالی به AI قرار میگیرد.
|
- در صورت ارسال `irrigation_plan_uuid`، اطلاعات برنامه آبیاری داخل payload ارسالی به AI قرار میگیرد.
|
||||||
- در صورت ارسال `fertilization_plan_id`، اطلاعات برنامه کودی هم اضافه میشود.
|
- در صورت ارسال `fertilization_plan_uuid`، اطلاعات برنامه کودی هم اضافه میشود.
|
||||||
|
|
||||||
### نمونه request
|
### نمونه request
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
### تغییرات
|
### تغییرات
|
||||||
|
|
||||||
- ورودی endpoint عملاً بر پایه `farm_uuid` کار میکند و `plant_name` توسط backend تعیین میشود.
|
- ورودی endpoint عملاً بر پایه `farm_uuid` کار میکند و `plant_name` توسط backend تعیین میشود.
|
||||||
- امکان ارسال `fertilization_plan_id` و `irrigation_plan_id` برای enrich کردن context اضافه/پشتیبانی شده است.
|
- امکان ارسال `fertilization_plan_uuid` و `irrigation_plan_uuid` برای enrich کردن context اضافه/پشتیبانی شده است.
|
||||||
- پاسخ AI بعد از extract شدن در `data.result`، به شکل مستقیم در `data` برگردانده میشود.
|
- پاسخ AI بعد از extract شدن در `data.result`، به شکل مستقیم در `data` برگردانده میشود.
|
||||||
|
|
||||||
### نمونه request
|
### نمونه request
|
||||||
@@ -130,7 +130,7 @@
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
||||||
"fertilization_plan_id": 34
|
"fertilization_plan_uuid": "7e7b2f1e-2b0c-4a3a-9fe2-3e84e0e3e0a2"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@
|
|||||||
|
|
||||||
- مثل دو endpoint دیگر، `plant_name` از روی مزرعه resolve میشود.
|
- مثل دو endpoint دیگر، `plant_name` از روی مزرعه resolve میشود.
|
||||||
- در نبود محصول مستقیم روی مزرعه، backend از fallback مناسب مزرعه استفاده میکند.
|
- در نبود محصول مستقیم روی مزرعه، backend از fallback مناسب مزرعه استفاده میکند.
|
||||||
- امکان ارسال `irrigation_plan_id` و `fertilization_plan_id` برای فرستادن context planها به AI اضافه/پشتیبانی شده است.
|
- امکان ارسال `irrigation_plan_uuid` و `fertilization_plan_uuid` برای فرستادن context planها به AI اضافه/پشتیبانی شده است.
|
||||||
- پاسخ نهایی با ساختار یکنواخت `code / msg / data` برگردانده میشود.
|
- پاسخ نهایی با ساختار یکنواخت `code / msg / data` برگردانده میشود.
|
||||||
|
|
||||||
### نمونه request
|
### نمونه request
|
||||||
@@ -184,8 +184,8 @@
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
"farm_uuid": "11111111-1111-1111-1111-111111111111",
|
||||||
"irrigation_plan_id": 12,
|
"irrigation_plan_uuid": "6d6a1f0d-1a9b-4f2f-8fe1-2d73d9d2d9f1",
|
||||||
"fertilization_plan_id": 34
|
"fertilization_plan_uuid": "7e7b2f1e-2b0c-4a3a-9fe2-3e84e0e3e0a2"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@
|
|||||||
|
|
||||||
### 2) plan نامعتبر یا متعلق به مزرعه دیگر
|
### 2) plan نامعتبر یا متعلق به مزرعه دیگر
|
||||||
|
|
||||||
اگر `irrigation_plan_id` یا `fertilization_plan_id` متعلق به همان مزرعه کاربر نباشد، درخواست با خطا رد میشود.
|
اگر `irrigation_plan_uuid` یا `fertilization_plan_uuid` متعلق به همان مزرعه کاربر نباشد، درخواست با خطا رد میشود.
|
||||||
|
|
||||||
نمونه:
|
نمونه:
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@
|
|||||||
"code": 404,
|
"code": 404,
|
||||||
"msg": "error",
|
"msg": "error",
|
||||||
"data": {
|
"data": {
|
||||||
"irrigation_plan_id": [
|
"irrigation_plan_uuid": [
|
||||||
"Irrigation plan not found."
|
"Irrigation plan not found."
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -256,7 +256,7 @@
|
|||||||
|
|
||||||
### 3) خطای validation ورودی
|
### 3) خطای validation ورودی
|
||||||
|
|
||||||
اگر `farm_uuid` ارسال نشود یا `plan_id`ها نامعتبر باشند، serializer خطای validation برمیگرداند.
|
اگر `farm_uuid` ارسال نشود یا `plan_uuid`ها نامعتبر باشند، serializer خطای validation برمیگرداند.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -264,6 +264,6 @@
|
|||||||
|
|
||||||
- دیگر لازم نیست `plant_name` را برای این 3 API بفرستید.
|
- دیگر لازم نیست `plant_name` را برای این 3 API بفرستید.
|
||||||
- فقط `farm_uuid` اجباری است.
|
- فقط `farm_uuid` اجباری است.
|
||||||
- اگر کاربر plan خاصی را انتخاب کرده، `irrigation_plan_id` و/یا `fertilization_plan_id` را هم بفرستید.
|
- اگر کاربر plan خاصی را انتخاب کرده، `irrigation_plan_uuid` و/یا `fertilization_plan_uuid` را هم بفرستید.
|
||||||
- response هر 3 endpoint با ساختار یکنواخت `code`, `msg`, `data` برمیگردد.
|
- response هر 3 endpoint با ساختار یکنواخت `code`, `msg`, `data` برمیگردد.
|
||||||
- backend خودش payload مناسب AI را از context مزرعه و planهای انتخابی میسازد.
|
- backend خودش payload مناسب AI را از context مزرعه و planهای انتخابی میسازد.
|
||||||
|
|||||||
@@ -64,15 +64,13 @@ class CropSimulationRequestSerializer(serializers.Serializer):
|
|||||||
initial="11111111-1111-1111-1111-111111111111",
|
initial="11111111-1111-1111-1111-111111111111",
|
||||||
help_text="UUID مزرعه برای اجرای شبیهسازی.",
|
help_text="UUID مزرعه برای اجرای شبیهسازی.",
|
||||||
)
|
)
|
||||||
irrigation_plan_id = serializers.IntegerField(
|
irrigation_plan_uuid = serializers.UUIDField(
|
||||||
required=False,
|
required=False,
|
||||||
min_value=1,
|
help_text="UUID برنامه آبیاری برای ارسال context به AI.",
|
||||||
help_text="شناسه داخلی برنامه آبیاری برای ارسال context به AI.",
|
|
||||||
)
|
)
|
||||||
fertilization_plan_id = serializers.IntegerField(
|
fertilization_plan_uuid = serializers.UUIDField(
|
||||||
required=False,
|
required=False,
|
||||||
min_value=1,
|
help_text="UUID برنامه کودی برای ارسال context به AI.",
|
||||||
help_text="شناسه داخلی برنامه کودی برای ارسال context به AI.",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+10
-8
@@ -395,13 +395,14 @@ class CropSimulationViewTests(TestCase):
|
|||||||
|
|
||||||
response = self.api_client.post(
|
response = self.api_client.post(
|
||||||
"/api/yield-harvest/current-farm-chart/",
|
"/api/yield-harvest/current-farm-chart/",
|
||||||
{"farm_uuid": str(self.farm.farm_uuid), "irrigation_plan_id": irrigation_plan.id},
|
{"farm_uuid": str(self.farm.farm_uuid), "irrigation_plan_uuid": str(irrigation_plan.uuid)},
|
||||||
format="json",
|
format="json",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
sent_payload = mock_external_api_request.call_args.kwargs["payload"]
|
sent_payload = mock_external_api_request.call_args.kwargs["payload"]
|
||||||
self.assertEqual(sent_payload["irrigation_plan"]["id"], irrigation_plan.id)
|
self.assertEqual(sent_payload["irrigation_plan"]["id"], irrigation_plan.id)
|
||||||
|
self.assertEqual(sent_payload["irrigation_plan"]["uuid"], str(irrigation_plan.uuid))
|
||||||
|
|
||||||
@patch("yield_harvest.views.external_api_request")
|
@patch("yield_harvest.views.external_api_request")
|
||||||
def test_harvest_prediction_includes_selected_plans(self, mock_external_api_request):
|
def test_harvest_prediction_includes_selected_plans(self, mock_external_api_request):
|
||||||
@@ -418,13 +419,14 @@ class CropSimulationViewTests(TestCase):
|
|||||||
|
|
||||||
response = self.api_client.post(
|
response = self.api_client.post(
|
||||||
"/api/yield-harvest/harvest-prediction/",
|
"/api/yield-harvest/harvest-prediction/",
|
||||||
{"farm_uuid": str(self.farm.farm_uuid), "fertilization_plan_id": fertilization_plan.id},
|
{"farm_uuid": str(self.farm.farm_uuid), "fertilization_plan_uuid": str(fertilization_plan.uuid)},
|
||||||
format="json",
|
format="json",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
sent_payload = mock_external_api_request.call_args.kwargs["payload"]
|
sent_payload = mock_external_api_request.call_args.kwargs["payload"]
|
||||||
self.assertEqual(sent_payload["fertilization_plan"]["id"], fertilization_plan.id)
|
self.assertEqual(sent_payload["fertilization_plan"]["id"], fertilization_plan.id)
|
||||||
|
self.assertEqual(sent_payload["fertilization_plan"]["uuid"], str(fertilization_plan.uuid))
|
||||||
|
|
||||||
@patch("yield_harvest.views.external_api_request")
|
@patch("yield_harvest.views.external_api_request")
|
||||||
def test_yield_prediction_proxies_to_ai_service(self, mock_external_api_request):
|
def test_yield_prediction_proxies_to_ai_service(self, mock_external_api_request):
|
||||||
@@ -549,8 +551,8 @@ class CropSimulationViewTests(TestCase):
|
|||||||
"/api/yield-harvest/yield-prediction/",
|
"/api/yield-harvest/yield-prediction/",
|
||||||
{
|
{
|
||||||
"farm_uuid": str(self.farm.farm_uuid),
|
"farm_uuid": str(self.farm.farm_uuid),
|
||||||
"irrigation_plan_id": irrigation_plan.id,
|
"irrigation_plan_uuid": str(irrigation_plan.uuid),
|
||||||
"fertilization_plan_id": fertilization_plan.id,
|
"fertilization_plan_uuid": str(fertilization_plan.uuid),
|
||||||
},
|
},
|
||||||
format="json",
|
format="json",
|
||||||
)
|
)
|
||||||
@@ -565,7 +567,7 @@ class CropSimulationViewTests(TestCase):
|
|||||||
"npk-202020",
|
"npk-202020",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_yield_prediction_rejects_foreign_plan_ids(self):
|
def test_yield_prediction_rejects_foreign_plan_uuids(self):
|
||||||
other_irrigation_plan = IrrigationPlan.objects.create(
|
other_irrigation_plan = IrrigationPlan.objects.create(
|
||||||
farm=self.other_farm,
|
farm=self.other_farm,
|
||||||
source=IrrigationPlan.SOURCE_FREE_TEXT,
|
source=IrrigationPlan.SOURCE_FREE_TEXT,
|
||||||
@@ -576,13 +578,13 @@ class CropSimulationViewTests(TestCase):
|
|||||||
"/api/yield-harvest/yield-prediction/",
|
"/api/yield-harvest/yield-prediction/",
|
||||||
{
|
{
|
||||||
"farm_uuid": str(self.farm.farm_uuid),
|
"farm_uuid": str(self.farm.farm_uuid),
|
||||||
"irrigation_plan_id": other_irrigation_plan.id,
|
"irrigation_plan_uuid": str(other_irrigation_plan.uuid),
|
||||||
},
|
},
|
||||||
format="json",
|
format="json",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 404)
|
self.assertEqual(response.status_code, 404)
|
||||||
self.assertEqual(response.json()["data"]["irrigation_plan_id"][0], "Irrigation plan not found.")
|
self.assertEqual(response.json()["data"]["irrigation_plan_uuid"][0], "Irrigation plan not found.")
|
||||||
|
|
||||||
@patch("yield_harvest.views.external_api_request")
|
@patch("yield_harvest.views.external_api_request")
|
||||||
def test_yield_harvest_summary_top_level_route_proxies_to_ai_service(self, mock_external_api_request):
|
def test_yield_harvest_summary_top_level_route_proxies_to_ai_service(self, mock_external_api_request):
|
||||||
@@ -654,7 +656,7 @@ class CropSimulationViewTests(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
response = self.api_client.get(
|
response = self.api_client.get(
|
||||||
f"/api/yield-harvest/yield-harvest-summary/?farm_uuid={self.farm.farm_uuid}&irrigation_plan_id={irrigation_plan.id}&fertilization_plan_id={fertilization_plan.id}"
|
f"/api/yield-harvest/yield-harvest-summary/?farm_uuid={self.farm.farm_uuid}&irrigation_plan_uuid={irrigation_plan.uuid}&fertilization_plan_uuid={fertilization_plan.uuid}"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|||||||
+30
-35
@@ -79,16 +79,16 @@ class YieldHarvestSummaryView(APIView):
|
|||||||
if error_response is not None:
|
if error_response is not None:
|
||||||
return error_response
|
return error_response
|
||||||
|
|
||||||
irrigation_plan_id, irrigation_plan_error = CropSimulationBaseView._parse_optional_plan_id(
|
irrigation_plan_uuid, irrigation_plan_error = CropSimulationBaseView._parse_optional_plan_uuid(
|
||||||
request.query_params.get("irrigation_plan_id"),
|
request.query_params.get("irrigation_plan_uuid"),
|
||||||
"irrigation_plan_id",
|
"irrigation_plan_uuid",
|
||||||
)
|
)
|
||||||
if irrigation_plan_error is not None:
|
if irrigation_plan_error is not None:
|
||||||
return irrigation_plan_error
|
return irrigation_plan_error
|
||||||
|
|
||||||
fertilization_plan_id, fertilization_plan_error = CropSimulationBaseView._parse_optional_plan_id(
|
fertilization_plan_uuid, fertilization_plan_error = CropSimulationBaseView._parse_optional_plan_uuid(
|
||||||
request.query_params.get("fertilization_plan_id"),
|
request.query_params.get("fertilization_plan_uuid"),
|
||||||
"fertilization_plan_id",
|
"fertilization_plan_uuid",
|
||||||
)
|
)
|
||||||
if fertilization_plan_error is not None:
|
if fertilization_plan_error is not None:
|
||||||
return fertilization_plan_error
|
return fertilization_plan_error
|
||||||
@@ -101,10 +101,10 @@ class YieldHarvestSummaryView(APIView):
|
|||||||
if request.query_params.get("include_narrative") is not None:
|
if request.query_params.get("include_narrative") is not None:
|
||||||
query["include_narrative"] = request.query_params.get("include_narrative")
|
query["include_narrative"] = request.query_params.get("include_narrative")
|
||||||
|
|
||||||
ai_payload, plan_error = self._build_ai_payload_with_selected_plans(
|
ai_payload, plan_error = CropSimulationBaseView()._build_ai_payload_with_selected_plans(
|
||||||
farm,
|
farm,
|
||||||
irrigation_plan_id=irrigation_plan_id,
|
irrigation_plan_uuid=irrigation_plan_uuid,
|
||||||
fertilization_plan_id=fertilization_plan_id,
|
fertilization_plan_uuid=fertilization_plan_uuid,
|
||||||
)
|
)
|
||||||
if plan_error is not None:
|
if plan_error is not None:
|
||||||
return plan_error
|
return plan_error
|
||||||
@@ -217,35 +217,35 @@ class CropSimulationBaseView(APIView):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_irrigation_plan_or_error(farm, plan_id):
|
def _get_irrigation_plan_or_error(farm, plan_uuid):
|
||||||
if not plan_id:
|
if not plan_uuid:
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
plan = IrrigationPlan.objects.filter(
|
plan = IrrigationPlan.objects.filter(
|
||||||
id=plan_id,
|
uuid=plan_uuid,
|
||||||
farm=farm,
|
farm=farm,
|
||||||
is_deleted=False,
|
is_deleted=False,
|
||||||
).first()
|
).first()
|
||||||
if plan is None:
|
if plan is None:
|
||||||
return None, Response(
|
return None, Response(
|
||||||
{"code": 404, "msg": "error", "data": {"irrigation_plan_id": ["Irrigation plan not found."]}},
|
{"code": 404, "msg": "error", "data": {"irrigation_plan_uuid": ["Irrigation plan not found."]}},
|
||||||
status=status.HTTP_404_NOT_FOUND,
|
status=status.HTTP_404_NOT_FOUND,
|
||||||
)
|
)
|
||||||
return plan, None
|
return plan, None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_fertilization_plan_or_error(farm, plan_id):
|
def _get_fertilization_plan_or_error(farm, plan_uuid):
|
||||||
if not plan_id:
|
if not plan_uuid:
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
plan = FertilizationPlan.objects.filter(
|
plan = FertilizationPlan.objects.filter(
|
||||||
id=plan_id,
|
uuid=plan_uuid,
|
||||||
farm=farm,
|
farm=farm,
|
||||||
is_deleted=False,
|
is_deleted=False,
|
||||||
).first()
|
).first()
|
||||||
if plan is None:
|
if plan is None:
|
||||||
return None, Response(
|
return None, Response(
|
||||||
{"code": 404, "msg": "error", "data": {"fertilization_plan_id": ["Fertilization plan not found."]}},
|
{"code": 404, "msg": "error", "data": {"fertilization_plan_uuid": ["Fertilization plan not found."]}},
|
||||||
status=status.HTTP_404_NOT_FOUND,
|
status=status.HTTP_404_NOT_FOUND,
|
||||||
)
|
)
|
||||||
return plan, None
|
return plan, None
|
||||||
@@ -268,13 +268,13 @@ class CropSimulationBaseView(APIView):
|
|||||||
"response_payload": plan.response_payload if isinstance(plan.response_payload, dict) else {},
|
"response_payload": plan.response_payload if isinstance(plan.response_payload, dict) else {},
|
||||||
}
|
}
|
||||||
|
|
||||||
def _build_ai_payload_with_selected_plans(self, farm, irrigation_plan_id=None, fertilization_plan_id=None):
|
def _build_ai_payload_with_selected_plans(self, farm, irrigation_plan_uuid=None, fertilization_plan_uuid=None):
|
||||||
irrigation_plan, irrigation_error = self._get_irrigation_plan_or_error(farm, irrigation_plan_id)
|
irrigation_plan, irrigation_error = self._get_irrigation_plan_or_error(farm, irrigation_plan_uuid)
|
||||||
if irrigation_error is not None:
|
if irrigation_error is not None:
|
||||||
return None, irrigation_error
|
return None, irrigation_error
|
||||||
|
|
||||||
fertilization_plan, fertilization_error = self._get_fertilization_plan_or_error(
|
fertilization_plan, fertilization_error = self._get_fertilization_plan_or_error(
|
||||||
farm, fertilization_plan_id
|
farm, fertilization_plan_uuid
|
||||||
)
|
)
|
||||||
if fertilization_error is not None:
|
if fertilization_error is not None:
|
||||||
return None, fertilization_error
|
return None, fertilization_error
|
||||||
@@ -291,19 +291,14 @@ class CropSimulationBaseView(APIView):
|
|||||||
return ai_payload, None
|
return ai_payload, None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse_optional_plan_id(raw_value, field_name):
|
def _parse_optional_plan_uuid(raw_value, field_name):
|
||||||
if raw_value in (None, ""):
|
if raw_value in (None, ""):
|
||||||
return None, None
|
return None, None
|
||||||
try:
|
try:
|
||||||
parsed_value = int(raw_value)
|
parsed_value = str(serializers.UUIDField().to_internal_value(raw_value))
|
||||||
except (TypeError, ValueError):
|
except serializers.ValidationError:
|
||||||
return None, Response(
|
return None, Response(
|
||||||
{"code": 400, "msg": "error", "data": {field_name: ["A valid integer is required."]}},
|
{"code": 400, "msg": "error", "data": {field_name: ["Must be a valid UUID."]}},
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
|
||||||
)
|
|
||||||
if parsed_value < 1:
|
|
||||||
return None, Response(
|
|
||||||
{"code": 400, "msg": "error", "data": {field_name: ["Ensure this value is greater than or equal to 1."]}},
|
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
return parsed_value, None
|
return parsed_value, None
|
||||||
@@ -328,8 +323,8 @@ class CurrentFarmChartView(CropSimulationBaseView):
|
|||||||
|
|
||||||
ai_payload, plan_error = self._build_ai_payload_with_selected_plans(
|
ai_payload, plan_error = self._build_ai_payload_with_selected_plans(
|
||||||
farm,
|
farm,
|
||||||
irrigation_plan_id=payload.get("irrigation_plan_id"),
|
irrigation_plan_uuid=payload.get("irrigation_plan_uuid"),
|
||||||
fertilization_plan_id=payload.get("fertilization_plan_id"),
|
fertilization_plan_uuid=payload.get("fertilization_plan_uuid"),
|
||||||
)
|
)
|
||||||
if plan_error is not None:
|
if plan_error is not None:
|
||||||
return plan_error
|
return plan_error
|
||||||
@@ -363,8 +358,8 @@ class HarvestPredictionView(CropSimulationBaseView):
|
|||||||
|
|
||||||
ai_payload, plan_error = self._build_ai_payload_with_selected_plans(
|
ai_payload, plan_error = self._build_ai_payload_with_selected_plans(
|
||||||
farm,
|
farm,
|
||||||
irrigation_plan_id=payload.get("irrigation_plan_id"),
|
irrigation_plan_uuid=payload.get("irrigation_plan_uuid"),
|
||||||
fertilization_plan_id=payload.get("fertilization_plan_id"),
|
fertilization_plan_uuid=payload.get("fertilization_plan_uuid"),
|
||||||
)
|
)
|
||||||
if plan_error is not None:
|
if plan_error is not None:
|
||||||
return plan_error
|
return plan_error
|
||||||
@@ -398,8 +393,8 @@ class YieldPredictionView(CropSimulationBaseView):
|
|||||||
|
|
||||||
ai_payload, plan_error = self._build_ai_payload_with_selected_plans(
|
ai_payload, plan_error = self._build_ai_payload_with_selected_plans(
|
||||||
farm,
|
farm,
|
||||||
irrigation_plan_id=payload.get("irrigation_plan_id"),
|
irrigation_plan_uuid=payload.get("irrigation_plan_uuid"),
|
||||||
fertilization_plan_id=payload.get("fertilization_plan_id"),
|
fertilization_plan_uuid=payload.get("fertilization_plan_uuid"),
|
||||||
)
|
)
|
||||||
if plan_error is not None:
|
if plan_error is not None:
|
||||||
return plan_error
|
return plan_error
|
||||||
|
|||||||
Reference in New Issue
Block a user