grouped transactions
This commit is contained in:
parent
27db599e8c
commit
e045ffd9b1
2 changed files with 40 additions and 32 deletions
|
|
@ -223,3 +223,7 @@ class ApplicationWithdrawSerializer(serializers.ModelSerializer):
|
|||
)
|
||||
|
||||
read_only_fields = ['updated_at', 'state', 'created_at', 'payee', 'payee_type', 'payee_wallet']
|
||||
|
||||
|
||||
class TransactionGroupedSerializer(serializers.Serializer):
|
||||
pass
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.postgres.aggregates import ArrayAgg
|
||||
from django.db.models import Q
|
||||
from django.urls import reverse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.generic import DetailView, ListView, UpdateView
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from drf_spectacular.utils import extend_schema
|
||||
|
||||
from oauth2_provider.contrib.rest_framework import TokenHasScope, IsAuthenticatedOrTokenHasScope
|
||||
from rest_framework import generics, permissions, mixins
|
||||
|
|
@ -14,10 +16,14 @@ from rest_framework.permissions import AllowAny
|
|||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import ViewSet, GenericViewSet
|
||||
|
||||
from apps.wallet.models import Transaction
|
||||
from django.contrib.postgres.aggregates import ArrayAgg
|
||||
from django.db.models import Sum, Count, F, StringAgg
|
||||
|
||||
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
|
||||
from apps.wallet.models import Transaction, Wallet, Account
|
||||
from apps.wallet.serializers import TransactionSerializer, DepositSerializer, WithdrawSerializer, \
|
||||
AccountSerializer
|
||||
AccountSerializer, TransactionGroupedSerializer
|
||||
from ..constans import StateChoices, TypeChoices
|
||||
from ..filters import AccountFilter, UserTransactionFilter
|
||||
from ..forms import TransactionActionForm
|
||||
|
|
@ -308,12 +314,11 @@ class WalletTransactionListView(generics.ListAPIView):
|
|||
|
||||
|
||||
class UserTransactionViewSet(mixins.ListModelMixin,
|
||||
# mixins.CreateModelMixin,
|
||||
# mixins.RetrieveModelMixin,
|
||||
# mixins.UpdateModelMixin,
|
||||
# mixins.DestroyModelMixin,
|
||||
GenericViewSet):
|
||||
|
||||
# mixins.CreateModelMixin,
|
||||
# mixins.RetrieveModelMixin,
|
||||
# mixins.UpdateModelMixin,
|
||||
# mixins.DestroyModelMixin,
|
||||
GenericViewSet):
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
serializer_class = TransactionSerializer
|
||||
required_alternate_scopes = {
|
||||
|
|
@ -331,7 +336,6 @@ class UserTransactionViewSet(mixins.ListModelMixin,
|
|||
return Transaction.objects.filter(Q(payee_account__owner_uuid=user.uuid) |
|
||||
Q(payer_account__owner_uuid=user.uuid)).all()
|
||||
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
|
||||
|
|
@ -343,32 +347,32 @@ class UserTransactionViewSet(mixins.ListModelMixin,
|
|||
serializer = self.get_serializer(queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
@action(detail=False, methods=["GET"])
|
||||
@extend_schema(responses=TransactionGroupedSerializer(many=True))
|
||||
@action(detail=False, methods=["GET"], serializer_class=TransactionGroupedSerializer)
|
||||
def grouped(self):
|
||||
from collections import defaultdict
|
||||
from django.db.models import Count, Sum
|
||||
|
||||
# فقط ۲ کوئری بهینه
|
||||
# کوئری ۱: آمار کلی (سبک)
|
||||
stats = dict(Transaction.objects.values('refrence').annotate(
|
||||
total=Sum('amount'),
|
||||
count=Count('id')
|
||||
).values_list('refrence', 'total', 'count'))
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
|
||||
# کوئری ۲: همه تراکنشها
|
||||
transactions = Transaction.objects.all().order_by('refrence', 'created_at')
|
||||
grouped_transaction_list = queryset.values('details__reference_id', 'application').annotate(
|
||||
total_amount=Sum('amount'),
|
||||
total_count=Count('uuid'),
|
||||
transaction_uuid_list=ArrayAgg('uuid'),
|
||||
)
|
||||
|
||||
# گروهبندی در پایتون
|
||||
groups = defaultdict(list)
|
||||
for t in transactions:
|
||||
groups[t.refrence].append(t)
|
||||
page = list(self.paginate_queryset(grouped_transaction_list))
|
||||
|
||||
# ترکیب
|
||||
result = []
|
||||
for ref, items in groups.items():
|
||||
result.append({
|
||||
'refrence': ref,
|
||||
'stats': {'total': stats.get(ref, 0), 'count': len(items)},
|
||||
'transactions': items
|
||||
})
|
||||
transaction_uuid_list = []
|
||||
|
||||
for grouped_transaction in page:
|
||||
transaction_uuid_list += grouped_transaction['transaction_uuid_list']
|
||||
|
||||
transaction_list = Transaction.objects.filter(uuid__in=transaction_uuid_list)
|
||||
|
||||
transaction_dict = {t.pk: t for t in transaction_list}
|
||||
|
||||
for grouped_transaction in page:
|
||||
for i, transaction in enumerate(grouped_transaction['transaction_uuid_list']):
|
||||
grouped_transaction['transaction_uuid_list'][i] = transaction_dict[transaction]
|
||||
|
||||
serializer = self.get_serializer(page, many=True)
|
||||
return self.get_paginated_response(serializer.data)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue