Files
ibapp-backend/core/apps/counterparty/views/counterparty.py
behruz-dev 338a1e5c02 fix
2025-11-05 18:35:03 +05:00

262 lines
9.2 KiB
Python

from django.db.models import Sum
from django.shortcuts import get_object_or_404
from rest_framework import generics, views, filters
from rest_framework.response import Response
from django_filters.rest_framework.backends import DjangoFilterBackend
from core.apps.accounts.permissions.permissions import HasRolePermission
from core.apps.shared.paginations.custom import CustomPageNumberPagination
from core.apps.counterparty.models import Counterparty, CounterpartyFolder
from core.apps.counterparty.serializers import counterparty as serializers
from core.apps.counterparty.filters.counterparty import CounterpartyFilter
from core.apps.finance.models import Expence, Income
class CounterpartyListApiView(generics.ListAPIView):
serializer_class = serializers.CounterpartyListSerializer
queryset = Counterparty.objects.exclude(is_archived=True).exclude(folder__isnull=False)
pagination_class = [HasRolePermission]
pagination_class = CustomPageNumberPagination
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_class = CounterpartyFilter
search_fields = [
'name', 'inn'
]
class CounterpartyCreateApiView(generics.GenericAPIView):
serializer_class = serializers.CounterpartyCreateSerializer
queryset = Counterparty.objects.all()
permission_classes = [HasRolePermission]
def post(self, request):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid(raise_exception=True):
data = serializer.save()
return Response(
{
'success': True,
'message': 'Conterparty Created',
'data': serializers.CounterpartyListSerializer(data).data
},
status=201
)
return Response(
{'success': False, 'message': serializer.errors},
status=400
)
class ArchiveCounterpartyApiView(views.APIView):
permission_classes = [HasRolePermission]
def get(self, request, id):
counterparty = get_object_or_404(Counterparty, id=id)
counterparty.is_archived = True
counterparty.save()
return Response(
{'success': True, 'message': 'counterparty archived'},
status=200
)
class ArchivedCounterpartyListApiView(generics.ListAPIView):
serializer_class = serializers.CounterpartyListSerializer
queryset = Counterparty.objects.exclude(is_archived=False)
pagination_class = [HasRolePermission]
pagination_class = CustomPageNumberPagination
class CounterpartyDeleteApiView(views.APIView):
permission_classes = [HasRolePermission]
def delete(self, request, id):
counterparty = get_object_or_404(Counterparty, id=id)
counterparty.delete()
return Response(
{'success': True, 'message': 'counterparty deleted'},
status=204
)
class CounterpartyUpdateApiView(generics.UpdateAPIView):
permission_classes = [HasRolePermission]
lookup_field = 'id'
serializer_class = serializers.CounterpartyUpdateSerializer
queryset = Counterparty.objects.all()
class FolderCounterpartyListApiView(generics.GenericAPIView):
serializer_class = serializers.CounterpartyListSerializer
queryset = Counterparty.objects.exclude(is_archived=True)
permission_classes = [HasRolePermission]
filter_backends = [filters.SearchFilter]
search_fields = [
'name', 'inn'
]
def get(self, reuqest, folder_id):
folder = get_object_or_404(CounterpartyFolder, id=folder_id)
queryset = self.queryset.filter(folder=folder).exclude(folder__isnull=True)
page = self.paginate_queryset(self.filter_queryset(queryset))
if page is not None:
serializer = self.serializer_class(page, many=True)
return self.get_paginated_response(serializer.data)
class CounterpartyStatisticsApiView(views.APIView):
permission_classes = [HasRolePermission]
def get(self, request):
counterparty_ids = request.query_params.getlist('counterparty')
if counterparty_ids:
queryset = Counterparty.objects.filter(id__in=counterparty_ids)
else:
queryset = Counterparty.objects.all()
res = queryset.aggregate(
kredit_usd=Sum('kredit_usd'),
kredit_uzs=Sum('kredit_uzs'),
total_kredit=Sum('total_kredit'),
debit_usd=Sum('debit_usd'),
debit_uzs=Sum('debit_uzs'),
total_debut=Sum('total_debit'),
)
return Response(res)
class CounterpartiesApiView(generics.GenericAPIView):
serializer_class = serializers.CounterpartyListSerializer
queryset = Counterparty.objects.all()
permission_classes = [HasRolePermission]
filter_backends = [filters.SearchFilter]
search_fields = [
'name', 'inn'
]
def get(self, request):
page = self.paginate_queryset(self.filter_queryset(self.queryset))
if page is not None:
ser = self.serializer_class(page, many=True)
return self.get_paginated_response(ser.data)
class CounterpartyDetailApiView(views.APIView):
permission_classes = [HasRolePermission]
def get(self, request, id):
obj = get_object_or_404(Counterparty, id=id)
serializer = serializers.CounterpartyListSerializer(obj)
return Response(serializer.data, status=200)
class UnArchiveCounterpartyApiView(views.APIView):
permission_classes = [HasRolePermission]
def get(self, request, id):
obj = get_object_or_404(Counterparty, id=id)
obj.is_archived = False
obj.save()
return Response(
{'success': True, 'message': 'Conterparty unarchived'}, status=200
)
class AllCounterpartyListApiView(generics.GenericAPIView):
serializer_class = serializers.CounterpartyListSerializer
queryset = Counterparty.objects.all()
permission_classes = [HasRolePermission]
filter_backends = [filters.SearchFilter]
search_fields = [
'name'
]
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)
class CounterPartyIncomeExpenceStatisticsApiView(views.APIView):
permission_classes = [HasRolePermission]
def get(self, request, id):
counterparty = get_object_or_404(Counterparty, id=id)
incomes = Income.objects.filter(
counterparty=counterparty,
is_deleted=False
)
expences = Expence.objects.filter(
counterparty=counterparty,
is_deleted=False,
)
income_by_currency = {}
expence_by_currency = {}
for income in incomes:
currency = income.currency
amount = income.price
if currency not in income_by_currency:
income_by_currency[currency] = {
'total': 0,
'count': 0,
'amount_uzs': 0
}
income_by_currency[currency]['total'] += amount
income_by_currency[currency]['count'] += 1
if currency == 'usd':
income_by_currency[currency]['amount_uzs'] += amount * income.exchange_rate
else:
income_by_currency[currency]['amount_uzs'] += amount
for expence in expences:
currency = expence.currency
amount = expence.price
if currency not in expence_by_currency:
expence_by_currency[currency] = {
'total': 0,
'count': 0,
'amount_uzs': 0
}
expence_by_currency[currency]['total'] += amount
expence_by_currency[currency]['count'] += 1
if currency == 'usd':
expence_by_currency[currency]['amount_uzs'] += amount * expence.exchange_rate
else:
expence_by_currency[currency]['amount_uzs'] += amount
total_income_uzs = sum(data['amount_uzs'] for data in income_by_currency.values())
total_expence_uzs = sum(data['amount_uzs'] for data in expence_by_currency.values())
balance = total_income_uzs - total_expence_uzs
data = {
'counterparty': {
'id': counterparty.id,
'name': counterparty.name,
},
'income': {
'by_currency': income_by_currency,
'total_uzs': total_income_uzs,
'total_count': sum(data['count'] for data in income_by_currency.values())
},
'expence': {
'by_currency': expence_by_currency,
'total_uzs': total_expence_uzs,
'total_count': sum(data['count'] for data in expence_by_currency.values())
},
'balance': {
'uzs': balance,
'status': 'positive' if balance > 0 else 'negative' if balance < 0 else 'zero'
}
}
return Response(data, status=200)