counterparty: counterparty akt api added
This commit is contained in:
@@ -18,6 +18,7 @@ urlpatterns = [
|
|||||||
path("<uuid:id>/", cp_views.CounterpartyDetailApiView.as_view()),
|
path("<uuid:id>/", cp_views.CounterpartyDetailApiView.as_view()),
|
||||||
path('<uuid:id>/un_archive/', cp_views.UnArchiveCounterpartyApiView.as_view()),
|
path('<uuid:id>/un_archive/', cp_views.UnArchiveCounterpartyApiView.as_view()),
|
||||||
path("<uuid:id>/statistics/", cp_views.CounterPartyIncomeExpenceStatisticsApiView.as_view()),
|
path("<uuid:id>/statistics/", cp_views.CounterPartyIncomeExpenceStatisticsApiView.as_view()),
|
||||||
|
path('<uuid:id>/akt_statistics/', cp_views.CounterpartyAKTApiView.as_view()),
|
||||||
]
|
]
|
||||||
)),
|
)),
|
||||||
path('counterparty_folder/', include(
|
path('counterparty_folder/', include(
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ from core.apps.counterparty.serializers import counterparty as serializers
|
|||||||
from core.apps.counterparty.filters.counterparty import CounterpartyFilter
|
from core.apps.counterparty.filters.counterparty import CounterpartyFilter
|
||||||
# finance
|
# finance
|
||||||
from core.apps.finance.models import Expence, Income
|
from core.apps.finance.models import Expence, Income
|
||||||
|
from core.apps.finance.serializers.income import IncomeListSerializer
|
||||||
|
from core.apps.finance.serializers.expence import ExpenceListSerializer
|
||||||
|
# orders
|
||||||
|
from core.apps.orders.models import Party
|
||||||
|
from core.apps.orders.serializers.party import PartyDetailSerializer
|
||||||
|
|
||||||
|
|
||||||
class CounterpartyListApiView(generics.ListAPIView):
|
class CounterpartyListApiView(generics.ListAPIView):
|
||||||
@@ -265,3 +270,78 @@ class CounterPartyIncomeExpenceStatisticsApiView(views.APIView):
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Response(data, status=200)
|
return Response(data, status=200)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CounterpartyAKTApiView(views.APIView):
|
||||||
|
permission_classes = [HasRolePermission]
|
||||||
|
|
||||||
|
def get(self, request, id):
|
||||||
|
# TODO: filterlar
|
||||||
|
date = request.query_params.get('date', None)
|
||||||
|
end_date = request.query_params.get('end_date', None)
|
||||||
|
project_folder = request.query_params.getlist('folder', None)
|
||||||
|
project = request.query_params.getlist('project', None)
|
||||||
|
currency = request.query_params.get('currency', 'uzs')
|
||||||
|
|
||||||
|
counterparty = get_object_or_404(Counterparty, id=id)
|
||||||
|
parties = Party.objects.filter(
|
||||||
|
orders__counterparty=counterparty, is_deleted=False, process=100, payment_percentage=100
|
||||||
|
).distinct().order_by('-created_at')
|
||||||
|
expences = Expence.objects.filter(counterparty=counterparty, is_deleted=False).distinct().order_by('-created_at')
|
||||||
|
incomes = Income.objects.filter(counterparty=counterparty, is_deleted=False).distinct().order_by('-created_at')
|
||||||
|
|
||||||
|
# TODO: date va end date boyicha filter
|
||||||
|
if date:
|
||||||
|
parties = parties.filter(close_date__gte=date)
|
||||||
|
expences = expences.filter(created_at__gte=date)
|
||||||
|
incomes = incomes.filter(created_at__gte=date)
|
||||||
|
if end_date:
|
||||||
|
parties = parties.filter(close_date__lte=end_date)
|
||||||
|
expences = expences.filter(created_at__lte=end_date)
|
||||||
|
incomes = incomes.filter(created_at__lte=end_date)
|
||||||
|
|
||||||
|
# TODO: project folder va project boyicha filter
|
||||||
|
if project_folder:
|
||||||
|
parties = parties.filter(orders__project_folder=project_folder).distinct()
|
||||||
|
expences = expences.filter(project_folder=project_folder)
|
||||||
|
incomes = incomes.filter(project_folder=project_folder)
|
||||||
|
if project:
|
||||||
|
parties = parties.filter(orders__project=project).distinct()
|
||||||
|
expences = expences.filter(project=project)
|
||||||
|
incomes = incomes.filter(project=project)
|
||||||
|
|
||||||
|
# TODO: currency boyicha filter
|
||||||
|
if currency:
|
||||||
|
parties = parties.filter(currency=currency)
|
||||||
|
expences = expences.filter(currency=currency)
|
||||||
|
incomes = incomes.filter(currency=currency)
|
||||||
|
|
||||||
|
# TODO: total kreditni hisoblash kerak: Sum(party total_price) + Sum(income total_price)
|
||||||
|
parties_total_price = parties.aggregate(total_price=Sum('party_amount__total_price'))['total_price'] or 0
|
||||||
|
income_total_price = incomes.aggregate(total_price=Sum('price'))['total_price'] or 0
|
||||||
|
total_kredit = Decimal(parties_total_price) + Decimal(income_total_price)
|
||||||
|
|
||||||
|
# TODO: total debitni hisoblash kerak: Sum(expence total_price)
|
||||||
|
expence_total_balance = expences.aggregate(total_price=Sum('price'))['total_price'] or 0
|
||||||
|
total_debit = expence_total_balance
|
||||||
|
|
||||||
|
# TODO: final balanceni hisoblash kerak: total_kredit - total_debit = final balance => negative or positive
|
||||||
|
final_balance = total_kredit - total_debit
|
||||||
|
|
||||||
|
# TODO: final balance typeni topish kerak -> debit or kredit: if negative == debit, positive == kredit
|
||||||
|
type = 'debit' if final_balance < 0 else 'kredit'
|
||||||
|
|
||||||
|
response = {
|
||||||
|
"parties": PartyDetailSerializer(parties, many=True).data,
|
||||||
|
"expences": ExpenceListSerializer(expences, many=True).data,
|
||||||
|
"incomes": IncomeListSerializer(incomes, many=True).data,
|
||||||
|
"total_kredit": str(total_kredit),
|
||||||
|
"total_debit": str(total_debit),
|
||||||
|
"final_balance": {
|
||||||
|
"balance": str(final_balance) if not str(final_balance).startswith('-') else str(final_balance).replace('-', ''),
|
||||||
|
"type": type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response(response, status=200)
|
||||||
@@ -14,18 +14,17 @@ class PartyAdmin(admin.ModelAdmin):
|
|||||||
list_display = [
|
list_display = [
|
||||||
"id",
|
"id",
|
||||||
"number",
|
"number",
|
||||||
"mediator",
|
|
||||||
"delivery_date",
|
|
||||||
"payment_date",
|
|
||||||
"is_deleted",
|
|
||||||
"party_amount__total_price",
|
"party_amount__total_price",
|
||||||
"currency"
|
"currency",
|
||||||
|
'process',
|
||||||
|
'payment_percentage',
|
||||||
]
|
]
|
||||||
inlines = [PartyAmountInline]
|
inlines = [PartyAmountInline]
|
||||||
search_fields = [
|
search_fields = [
|
||||||
"number", "orders__counterparty__name"
|
"number", "orders__counterparty__name"
|
||||||
]
|
]
|
||||||
autocomplete_fields = ['orders']
|
autocomplete_fields = ['orders']
|
||||||
|
ordering = ['-number']
|
||||||
|
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
return super().get_queryset(request).select_related('party_amount', 'mediator').prefetch_related('orders')
|
return super().get_queryset(request).select_related('party_amount', 'mediator').prefetch_related('orders')
|
||||||
|
|||||||
@@ -15,19 +15,18 @@ token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2JhY2tlbmQuYX
|
|||||||
|
|
||||||
headers = {"Authorization": f"Bearer {token}"}
|
headers = {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
def get_data(page):
|
# def get_data(page):
|
||||||
url = f"https://backend.app.uyqur.uz/main/supply/order-view?size=1000&page={page}"
|
# url = f"https://backend.app.uyqur.uz/main/supply/order-view?size=1000&page={page}"
|
||||||
response = requests.get(url, headers=headers)
|
# response = requests.get(url, headers=headers)
|
||||||
|
|
||||||
if response.status_code == 200:
|
# if response.status_code == 200:
|
||||||
return response.json()
|
# return response.json()
|
||||||
print(response.json())
|
# print(response.json())
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
for page in range(1,6):
|
for page in range(1,10479):
|
||||||
data = get_data(page)
|
|
||||||
statuses = {
|
statuses = {
|
||||||
"open": "NEW",
|
"open": "NEW",
|
||||||
"ordered": "PARTY_IS_MADE",
|
"ordered": "PARTY_IS_MADE",
|
||||||
@@ -39,10 +38,10 @@ class Command(BaseCommand):
|
|||||||
"partially_recieved": "PROCESS"
|
"partially_recieved": "PROCESS"
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in data["data"]["data"]:
|
url = f"https://backend.app.uyqur.uz/main/supply/order-view?id={page}"
|
||||||
url = f"https://backend.app.uyqur.uz/main/supply/order-view?id={item['id']}"
|
|
||||||
res = requests.get(url, headers=headers)
|
res = requests.get(url, headers=headers)
|
||||||
data = res.json()["data"]
|
data = res.json()["data"]
|
||||||
|
if data:
|
||||||
user = None
|
user = None
|
||||||
if data.get("agent"):
|
if data.get("agent"):
|
||||||
user = User.objects.filter(full_name=data["agent"]["full_name"]).first()
|
user = User.objects.filter(full_name=data["agent"]["full_name"]).first()
|
||||||
@@ -120,7 +119,8 @@ class Command(BaseCommand):
|
|||||||
"paid_amount": paid_amount,
|
"paid_amount": paid_amount,
|
||||||
"payment_amount": must_pay_amount,
|
"payment_amount": must_pay_amount,
|
||||||
"debt_amount": debt_amount,
|
"debt_amount": debt_amount,
|
||||||
"total_expense_amount": item['total_expense_amount'],
|
# "total_expense_amount": item['total_expense_amount'],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
print(page)
|
||||||
self.stdout.write("Parties added")
|
self.stdout.write("Parties added")
|
||||||
@@ -15,13 +15,6 @@ token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2JhY2tlbmQuYX
|
|||||||
|
|
||||||
headers = {"Authorization": f"Bearer {token}"}
|
headers = {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
# def get_data(page):
|
|
||||||
# url = f"https://backend.app.uyqur.uz/main/supply/order-view?size=1000&page={page}"
|
|
||||||
# response = requests.get(url, headers=headers)
|
|
||||||
|
|
||||||
# if response.status_code == 200:
|
|
||||||
# return response.json()
|
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from django.core.management import BaseCommand
|
from django.core.management import BaseCommand
|
||||||
|
|
||||||
from core.apps.accounts.models import User
|
from core.apps.accounts.models import User
|
||||||
from core.apps.counterparty.models import Counterparty
|
from core.apps.counterparty.models import Counterparty
|
||||||
from core.apps.orders.models import Order, Party, PartyAmount
|
from core.apps.orders.models import Order, Party, PartyAmount
|
||||||
@@ -12,25 +10,46 @@ from core.apps.projects.models import Project, ProjectFolder
|
|||||||
from core.apps.wherehouse.models import WhereHouse
|
from core.apps.wherehouse.models import WhereHouse
|
||||||
|
|
||||||
token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2JhY2tlbmQuYXBwLnV5cXVyLnV6L21haW4vYXV0aC9sb2dpbiIsImlhdCI6MTc2Mjk1MjUxNiwiZXhwIjoxNzYzMDM4OTE2LCJuYmYiOjE3NjI5NTI1MTYsImp0aSI6IkVlcW1lVVluMUR0VTNvUDciLCJzdWIiOiIxMDQiLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.64QPbq6CeJqXubai4nMfH9RlJIJ0YUPFfJ298ar4YGQ"
|
token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2JhY2tlbmQuYXBwLnV5cXVyLnV6L21haW4vYXV0aC9sb2dpbiIsImlhdCI6MTc2Mjk1MjUxNiwiZXhwIjoxNzYzMDM4OTE2LCJuYmYiOjE3NjI5NTI1MTYsImp0aSI6IkVlcW1lVVluMUR0VTNvUDciLCJzdWIiOiIxMDQiLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.64QPbq6CeJqXubai4nMfH9RlJIJ0YUPFfJ298ar4YGQ"
|
||||||
|
|
||||||
headers = {"Authorization": f"Bearer {token}"}
|
headers = {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
def get_data(page):
|
def get_data(page):
|
||||||
url = f"https://backend.app.uyqur.uz/main/supply/order-view?size=1000&page={page}"
|
url = f"https://backend.app.uyqur.uz/main/supply/order-view?size=1000&page={page}"
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
for page in range(1,6):
|
for page in range(1, 100):
|
||||||
data = get_data(page)
|
data = get_data(page)
|
||||||
for data in data['data']['data']:
|
|
||||||
Party.objects.filter(number=data['id']).update(
|
for item in data['data']['data']:
|
||||||
payment_percentage=data["payment_percent"],
|
try:
|
||||||
process=data["percent"],
|
# Party ID orqali topish va yangilash
|
||||||
|
party = Party.objects.get(number=item["id"])
|
||||||
|
party.number = item["id"]
|
||||||
|
party.payment_percentage = item["payment_percent"]
|
||||||
|
party.process = item["percent"]
|
||||||
|
party.save()
|
||||||
|
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.SUCCESS(
|
||||||
|
f'Party {item["id"]} updated successfully'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except Party.DoesNotExist:
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.WARNING(
|
||||||
|
f'Party {item["id"]} not found'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.ERROR(
|
||||||
|
f'Error updating Party {item["id"]}: {str(e)}'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.SUCCESS('All parties processed')
|
||||||
)
|
)
|
||||||
self.stdout.write("Parties added")
|
|
||||||
@@ -68,7 +68,6 @@ class Party(BaseModel):
|
|||||||
percentage += order.completion_percentage
|
percentage += order.completion_percentage
|
||||||
if percentage > 0 and count > 0:
|
if percentage > 0 and count > 0:
|
||||||
self.process = percentage / count
|
self.process = percentage / count
|
||||||
# self.party_amount.save()
|
|
||||||
|
|
||||||
return super().save(*args, **kwargs)
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class OrderListApiView(generics.ListAPIView):
|
|||||||
serializer_class = serializers.OrderListSerializer
|
serializer_class = serializers.OrderListSerializer
|
||||||
queryset = Order.objects.select_related(
|
queryset = Order.objects.select_related(
|
||||||
'product', 'unity', 'project', 'project_folder', 'wherehouse'
|
'product', 'unity', 'project', 'project_folder', 'wherehouse'
|
||||||
).filter(type='order')
|
).filter(type='order').order_by('-created_at')
|
||||||
permission_classes = [HasRolePermission]
|
permission_classes = [HasRolePermission]
|
||||||
pagination_class = CustomPageNumberPagination
|
pagination_class = CustomPageNumberPagination
|
||||||
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
|
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
|
||||||
|
|||||||
Reference in New Issue
Block a user