From 9d36d34de31bfe9ed013c8ae813ae53dccc53eb6 Mon Sep 17 00:00:00 2001 From: behruz-dev Date: Fri, 12 Sep 2025 15:46:32 +0500 Subject: [PATCH] change: change income contract list serializer --- .../finance/serializers/income_contract.py | 62 +++++++++++++++++++ core/apps/finance/urls.py | 9 ++- core/apps/finance/views/income_contract.py | 48 ++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 core/apps/finance/serializers/income_contract.py create mode 100644 core/apps/finance/views/income_contract.py diff --git a/core/apps/finance/serializers/income_contract.py b/core/apps/finance/serializers/income_contract.py new file mode 100644 index 0000000..2ce1055 --- /dev/null +++ b/core/apps/finance/serializers/income_contract.py @@ -0,0 +1,62 @@ +from django.db import transaction + +from rest_framework import serializers + +from core.apps.finance.models import IncomeContract + + +class IncomeContractSerializer(serializers.ModelSerializer): + project_folder = serializers.SerializerMethodField(method_name='get_project_folder') + project = serializers.SerializerMethodField(method_name='get_project') + income_type = serializers.SerializerMethodField(method_name='get_income_type') + counterparty = serializers.SerializerMethodField(method_name='get_counterparty') + + class Meta: + model = IncomeContract + fields = [ + 'id', 'project_folder', 'project', 'income_type', 'counterparty', 'price', 'currency', + 'date', 'comment' + ] + extra_kwargs = {'id': {'read_only': True}} + + def get_counterparty(self, obj): + return { + 'id': obj.counterparty.id, + 'name': obj.counterparty.name, + } if obj.counterparty else None + + def get_income_type(self, obj): + return { + 'id': obj.income_type.id, + 'name': obj.income_type.name + } if obj.income_type else None + + def get_project(self, obj): + return { + 'id': obj.project.id, + 'name': obj.project.name, + } if obj.project else None + + def get_project_folder(self, obj): + return { + 'id': obj.project_folder.id, + 'name': obj.project_folder.name + } + + + def create(self, validated_data): + with transaction.atomic(): + income_contract = IncomeContract.objects.create( + project_folder=validated_data.get('project_folder'), + project=validated_data.get('project'), + income_type=validated_data.get('income_type'), + counterparty=validated_data.get('counterparty'), + price=validated_data.get('price'), + currency=validated_data.get('currency'), + date=validated_data.get('date'), + comment=validated_data.get('comment'), + user=self.context.get('user'), + ) + return income_contract + + diff --git a/core/apps/finance/urls.py b/core/apps/finance/urls.py index 4471a3e..9da142d 100644 --- a/core/apps/finance/urls.py +++ b/core/apps/finance/urls.py @@ -7,6 +7,7 @@ from core.apps.finance.views import type_income as ti_views from core.apps.finance.views import income as income_views from core.apps.finance.views import expence_type as ex_views from core.apps.finance.views import expence as expence_views +from core.apps.finance.views import income_contract as ic_views urlpatterns = [ @@ -64,5 +65,11 @@ urlpatterns = [ path('create/', expence_views.ExpenceCreateApiView.as_view()), path('/list/', expence_views.CounterpartyExpenceListApiView.as_view()), ] - )) + )), + path('income_contract/', include( + [ + path('list/', ic_views.IncomeContractListApiView.as_view()), + path('create/', ic_views.IncomeContractCreateApiView.as_view()), + ] + )), ] \ No newline at end of file diff --git a/core/apps/finance/views/income_contract.py b/core/apps/finance/views/income_contract.py new file mode 100644 index 0000000..6f8dfde --- /dev/null +++ b/core/apps/finance/views/income_contract.py @@ -0,0 +1,48 @@ +from django.shortcuts import get_object_or_404 + +from rest_framework import generics +from rest_framework.response import Response + +from core.apps.accounts.permissions.permissions import HasRolePermission +from core.apps.finance.models import IncomeContract +from core.apps.finance.serializers.income_contract import IncomeContractSerializer + + +class IncomeContractCreateApiView(generics.GenericAPIView): + serializer_class = IncomeContractSerializer + queryset = IncomeContract.objects.all() + permission_classes = [HasRolePermission] + + def post(self, request): + serializer = self.serializer_class(data=request.data) + if serializer.is_valid(raise_exception=True): + serializer.save() + return Response( + { + 'success': True, + 'message': 'Income Contract created successfully', + }, + status=201 + ) + return Response( + { + 'success': False, + 'message': 'Income Contract create failed', + 'error': serializer.errors, + }, + status=400 + ) + + +class IncomeContractListApiView(generics.GenericAPIView): + serializer_class = IncomeContractSerializer + queryset = IncomeContract.objects.select_related( + 'project_folder', 'project', 'income_type', 'counterparty', + ) + permission_classes = [HasRolePermission] + + def get(self, request): + page = self.paginate_queryset(self.queryset) + if page is not None: + serializer = self.serializer_class(page, many=True) + return self.get_paginated_response(serializer.data)