This commit is contained in:
2026-04-25 17:22:41 +03:30
parent 569d520a5c
commit aa24fc22b0
124 changed files with 8491 additions and 2582 deletions
+1
View File
@@ -0,0 +1 @@
+18
View File
@@ -0,0 +1,18 @@
from functools import cached_property
from django.apps import AppConfig
class EconomyConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "economy"
verbose_name = "Economy"
@cached_property
def economic_overview_service(self):
from .services import EconomicOverviewService
return EconomicOverviewService()
def get_economic_overview_service(self):
return self.economic_overview_service
+26
View File
@@ -0,0 +1,26 @@
from rest_framework import serializers
class EconomicOverviewRequestSerializer(serializers.Serializer):
farm_uuid = serializers.UUIDField(required=True, help_text="شناسه یکتای مزرعه")
class EconomicDataItemSerializer(serializers.Serializer):
title = serializers.CharField()
value = serializers.CharField()
subtitle = serializers.CharField()
avatarIcon = serializers.CharField()
avatarColor = serializers.CharField()
class EconomicChartSeriesSerializer(serializers.Serializer):
name = serializers.CharField()
data = serializers.ListField(child=serializers.FloatField())
class EconomicOverviewResponseSerializer(serializers.Serializer):
farm_uuid = serializers.CharField()
source = serializers.CharField()
economicData = EconomicDataItemSerializer(many=True)
chartSeries = EconomicChartSeriesSerializer(many=True)
chartCategories = serializers.ListField(child=serializers.CharField())
+47
View File
@@ -0,0 +1,47 @@
from __future__ import annotations
from typing import Any
class EconomicOverviewService:
def get_economic_overview(self, *, farm_uuid: str) -> dict[str, Any]:
return {
"farm_uuid": farm_uuid,
"source": "mock",
"economicData": [
{
"title": "هزینه آب",
"value": "$420",
"subtitle": "این ماه",
"avatarIcon": "tabler-droplet",
"avatarColor": "primary",
},
{
"title": "صرفه جویی هوشمند",
"value": "$88",
"subtitle": "برآورد ماهانه",
"avatarIcon": "tabler-bulb",
"avatarColor": "success",
},
{
"title": "پیش بینی درآمد",
"value": "$3.8k",
"subtitle": "این فصل",
"avatarIcon": "tabler-chart-line",
"avatarColor": "info",
},
{
"title": "هزینه کود",
"value": "$190",
"subtitle": "برآورد فعلی",
"avatarIcon": "tabler-flask",
"avatarColor": "warning",
},
],
"chartSeries": [
{"name": "هزینه آب", "data": [320, 340, 360, 390, 405, 420]},
{"name": "هزینه کود", "data": [150, 155, 160, 170, 180, 190]},
{"name": "درآمد", "data": [2200, 2400, 2650, 3000, 3400, 3800]},
],
"chartCategories": ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور"],
}
+22
View File
@@ -0,0 +1,22 @@
from __future__ import annotations
from django.test import TestCase, override_settings
from rest_framework.test import APIClient
@override_settings(ROOT_URLCONF="economy.urls")
class EconomicOverviewApiTests(TestCase):
def setUp(self):
self.client = APIClient()
def test_economic_overview_api_returns_mock_payload(self):
response = self.client.post(
"/overview/",
data={"farm_uuid": "550e8400-e29b-41d4-a716-446655440000"},
format="json",
)
self.assertEqual(response.status_code, 200)
payload = response.json()["data"]
self.assertEqual(payload["source"], "mock")
self.assertEqual(payload["economicData"][0]["title"], "هزینه آب")
+8
View File
@@ -0,0 +1,8 @@
from django.urls import path
from .views import EconomicOverviewView
urlpatterns = [
path("overview/", EconomicOverviewView.as_view(), name="economic-overview"),
]
+66
View File
@@ -0,0 +1,66 @@
from django.apps import apps
from drf_spectacular.utils import OpenApiExample, extend_schema
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from config.openapi import build_envelope_serializer, build_response
from .serializers import (
EconomicOverviewRequestSerializer,
EconomicOverviewResponseSerializer,
)
EconomicOverviewEnvelopeSerializer = build_envelope_serializer(
"EconomicOverviewEnvelopeSerializer",
EconomicOverviewResponseSerializer,
)
EconomyErrorSerializer = build_envelope_serializer(
"EconomyErrorSerializer",
data_required=False,
allow_null=True,
)
class EconomicOverviewView(APIView):
@extend_schema(
tags=["Economy"],
summary="دریافت نمای اقتصادی مزرعه",
description="با دریافت farm_uuid، نمای اقتصادی مزرعه را فعلا با داده mock برمی گرداند.",
request=EconomicOverviewRequestSerializer,
responses={
200: build_response(
EconomicOverviewEnvelopeSerializer,
"نمای اقتصادی مزرعه با موفقیت بازگردانده شد.",
),
400: build_response(
EconomyErrorSerializer,
"داده ورودی نامعتبر است.",
),
},
examples=[
OpenApiExample(
"نمونه درخواست economy",
value={"farm_uuid": "11111111-1111-1111-1111-111111111111"},
request_only=True,
)
],
)
def post(self, request):
serializer = EconomicOverviewRequestSerializer(data=request.data)
if not serializer.is_valid():
return Response(
{"code": 400, "msg": "داده نامعتبر.", "data": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
service = apps.get_app_config("economy").get_economic_overview_service()
data = service.get_economic_overview(
farm_uuid=str(serializer.validated_data["farm_uuid"])
)
return Response(
{"code": 200, "msg": "success", "data": data},
status=status.HTTP_200_OK,
)