change price type int -> decimal field
This commit is contained in:
@@ -1,21 +1,32 @@
|
||||
from django.db.models import Sum
|
||||
from decimal import Decimal
|
||||
|
||||
from django.db.models import Sum, Count, Q
|
||||
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
|
||||
|
||||
# accounts
|
||||
from core.apps.accounts.permissions.permissions import HasRolePermission
|
||||
# shared
|
||||
from core.apps.shared.paginations.custom import CustomPageNumberPagination
|
||||
from core.apps.counterparty.models import Counterparty, CounterpartyFolder
|
||||
# counterparty
|
||||
from core.apps.counterparty.models import Counterparty, CounterpartyFolder, CounterpartyBalance
|
||||
from core.apps.counterparty.serializers import counterparty as serializers
|
||||
from core.apps.counterparty.filters.counterparty import CounterpartyFilter
|
||||
# finance
|
||||
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)
|
||||
queryset = Counterparty.objects\
|
||||
.select_related('balance')\
|
||||
.exclude(is_archived=True)\
|
||||
.exclude(folder__isnull=False)\
|
||||
.order_by('-created_at')
|
||||
pagination_class = [HasRolePermission]
|
||||
pagination_class = CustomPageNumberPagination
|
||||
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
|
||||
@@ -63,7 +74,7 @@ class ArchiveCounterpartyApiView(views.APIView):
|
||||
|
||||
class ArchivedCounterpartyListApiView(generics.ListAPIView):
|
||||
serializer_class = serializers.CounterpartyListSerializer
|
||||
queryset = Counterparty.objects.exclude(is_archived=False)
|
||||
queryset = Counterparty.objects.exclude(is_archived=False).select_related('balance').order_by('-created_at')
|
||||
pagination_class = [HasRolePermission]
|
||||
pagination_class = CustomPageNumberPagination
|
||||
|
||||
@@ -89,7 +100,7 @@ class CounterpartyUpdateApiView(generics.UpdateAPIView):
|
||||
|
||||
class FolderCounterpartyListApiView(generics.GenericAPIView):
|
||||
serializer_class = serializers.CounterpartyListSerializer
|
||||
queryset = Counterparty.objects.exclude(is_archived=True)
|
||||
queryset = Counterparty.objects.exclude(is_archived=True).select_related('balance').order_by('-created_at')
|
||||
permission_classes = [HasRolePermission]
|
||||
filter_backends = [filters.SearchFilter]
|
||||
search_fields = [
|
||||
@@ -110,25 +121,44 @@ class CounterpartyStatisticsApiView(views.APIView):
|
||||
|
||||
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'),
|
||||
|
||||
balance_qs = CounterpartyBalance.objects.filter(counterparty__in=queryset)
|
||||
|
||||
stats = balance_qs.aggregate(
|
||||
total_balance_uzs=Sum('balance_uzs'),
|
||||
total_balance_usd=Sum('balance_usd'),
|
||||
total_debit_uzs=Sum('debit_uzs'),
|
||||
total_kredit_uzs=Sum('kredit_uzs'),
|
||||
total_debit_usd=Sum('debit_usd'),
|
||||
total_kredit_usd=Sum('kredit_usd'),
|
||||
)
|
||||
return Response(res)
|
||||
|
||||
counterparty_stats = queryset.aggregate(
|
||||
total_counterparties=Count('id'),
|
||||
total_creditors=Count('id', filter=Q(status='CREDITOR')),
|
||||
total_debtors=Count('id', filter=Q(status='DEBITOR')),
|
||||
)
|
||||
|
||||
result = {
|
||||
**counterparty_stats,
|
||||
**stats,
|
||||
}
|
||||
|
||||
for key, value in result.items():
|
||||
if value is None:
|
||||
result[key] = 0
|
||||
|
||||
return Response(result)
|
||||
|
||||
|
||||
class CounterpartiesApiView(generics.GenericAPIView):
|
||||
serializer_class = serializers.CounterpartyListSerializer
|
||||
queryset = Counterparty.objects.all()
|
||||
queryset = Counterparty.objects.order_by('-created_at').select_related('balance')
|
||||
permission_classes = [HasRolePermission]
|
||||
filter_backends = [filters.SearchFilter]
|
||||
search_fields = [
|
||||
@@ -163,101 +193,78 @@ class UnArchiveCounterpartyApiView(views.APIView):
|
||||
)
|
||||
|
||||
|
||||
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 = {
|
||||
'uzs': {'total': 0, 'count': 0, 'amount_uzs': 0},
|
||||
'usd': {'total': 0, 'count': 0, 'amount_uzs': 0}
|
||||
}
|
||||
|
||||
# Income va Expence querysetlari
|
||||
incomes = Income.objects.filter(counterparty=counterparty, is_deleted=False)
|
||||
expences = Expence.objects.filter(counterparty=counterparty, is_deleted=False)
|
||||
|
||||
# Balanslar valyutalar bo'yicha
|
||||
income_by_currency = {'uzs': {'total': Decimal(0), 'count': 0, 'amount_uzs': Decimal(0)},
|
||||
'usd': {'total': Decimal(0), 'count': 0, 'amount_uzs': Decimal(0)}}
|
||||
for income in incomes:
|
||||
currency = income.currency
|
||||
amount = income.price
|
||||
|
||||
amount = Decimal(income.price or 0)
|
||||
rate = Decimal(income.exchange_rate or 1)
|
||||
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
|
||||
|
||||
expence_by_currency = {
|
||||
'uzs': {'total': 0, 'count': 0, 'amount_uzs': 0},
|
||||
'usd': {'total': 0, 'count': 0, 'amount_uzs': 0}
|
||||
}
|
||||
|
||||
income_by_currency[currency]['amount_uzs'] += amount * rate if currency == 'usd' else amount
|
||||
|
||||
expence_by_currency = {'uzs': {'total': Decimal(0), 'count': 0, 'amount_uzs': Decimal(0)},
|
||||
'usd': {'total': Decimal(0), 'count': 0, 'amount_uzs': Decimal(0)}}
|
||||
for expence in expences:
|
||||
currency = expence.currency
|
||||
amount = expence.price
|
||||
|
||||
amount = Decimal(expence.price or 0)
|
||||
rate = Decimal(expence.exchange_rate or 1)
|
||||
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_uzs = total_income_uzs - total_expence_uzs
|
||||
|
||||
total_income_usd = income_by_currency.get('usd', {}).get('total', 0)
|
||||
total_expence_usd = expence_by_currency.get('usd', {}).get('total', 0)
|
||||
balance_usd = total_income_usd - total_expence_usd
|
||||
|
||||
expence_by_currency[currency]['amount_uzs'] += amount * rate if currency == 'usd' else amount
|
||||
|
||||
# Income/Expence summalari
|
||||
total_income_uzs = sum(v['amount_uzs'] for v in income_by_currency.values())
|
||||
total_expence_uzs = sum(v['amount_uzs'] for v in expence_by_currency.values())
|
||||
total_income_usd = income_by_currency['usd']['total']
|
||||
total_expence_usd = expence_by_currency['usd']['total']
|
||||
|
||||
# Kontragent balansi
|
||||
balance_obj, _ = CounterpartyBalance.objects.get_or_create(counterparty=counterparty)
|
||||
balance_uzs = balance_obj.total_balance_uzs + (total_income_uzs - total_expence_uzs)
|
||||
balance_usd = balance_obj.total_balance_usd + (total_income_usd - total_expence_usd)
|
||||
|
||||
# Status aniqlash
|
||||
if balance_uzs > 0:
|
||||
status = 'positive'
|
||||
elif balance_uzs < 0:
|
||||
status = 'negative'
|
||||
else:
|
||||
status = 'zero'
|
||||
|
||||
data = {
|
||||
'counterparty': {
|
||||
'id': counterparty.id,
|
||||
'name': counterparty.name,
|
||||
'name': counterparty.name
|
||||
},
|
||||
'income': {
|
||||
'by_currency': income_by_currency,
|
||||
'total_uzs': total_income_uzs,
|
||||
'total_usd': total_income_usd,
|
||||
'total_count': sum(data['count'] for data in income_by_currency.values())
|
||||
'total_count': sum(v['count'] for v in income_by_currency.values())
|
||||
},
|
||||
'expence': {
|
||||
'by_currency': expence_by_currency,
|
||||
'total_uzs': total_expence_uzs,
|
||||
'total_usd': total_expence_usd,
|
||||
'total_count': sum(data['count'] for data in expence_by_currency.values())
|
||||
'total_count': sum(v['count'] for v in expence_by_currency.values())
|
||||
},
|
||||
'balance': {
|
||||
'uzs': balance_uzs,
|
||||
'usd': balance_usd,
|
||||
'status': 'positive' if balance_uzs > 0 else 'negative' if balance_uzs < 0 else 'zero'
|
||||
'status': status
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Response(data, status=200)
|
||||
Reference in New Issue
Block a user