diff --git a/core/apps/finance/serializers/expence.py b/core/apps/finance/serializers/expence.py index ff77c46..f72aaa3 100644 --- a/core/apps/finance/serializers/expence.py +++ b/core/apps/finance/serializers/expence.py @@ -14,8 +14,27 @@ class ExpenceCreateSerializer(serializers.ModelSerializer): 'counterparty', 'price', 'exchange_rate', 'currency', 'date', 'comment', 'audit', 'file' ] + def validate(self, data): + cash_transaction = data.get('cash_transaction') + payment_type = data.get('payment_type') + price = data.get('price') + exchange_rate = data.get('exchange_rate', 1) + currency = data.get('currency', 'uzs') + + final_price = price * exchange_rate if exchange_rate else price + + if currency == 'uzs' and payment_type.total_uzs < final_price: + raise serializers.ValidationError(f"Yetarli UZS balansi yo'q. Mavjud: {payment_type.total_uzs}") + elif currency == 'usd' and payment_type.total_usd < final_price: + raise serializers.ValidationError(f"Yetarli USD balansi yo'q. Mavjud: {payment_type.total_usd}") + + return data + def create(self, validated_data): with transaction.atomic(): + exchange_rate = validated_data.get('exchange_rate') or 1 + final_price = validated_data.get('price') * exchange_rate + expence = Expence.objects.create( user=self.context.get('user'), cash_transaction=validated_data.get('cash_transaction'), @@ -24,62 +43,69 @@ class ExpenceCreateSerializer(serializers.ModelSerializer): project=validated_data.get('project'), expence_type=validated_data.get('expence_type'), counterparty=validated_data.get('counterparty'), - price=validated_data.get('price') * validated_data.get('exchange_rate') if validated_data.get('exchange_rate') else validated_data.get('price'), - exchange_rate=validated_data.get('exchange_rate'), + price=final_price, + exchange_rate=exchange_rate, currency=validated_data.get('currency'), date=validated_data.get('date'), comment=validated_data.get('comment'), audit=validated_data.get('audit'), file=validated_data.get('file'), ) + cash_transaction = expence.cash_transaction payment_type = expence.payment_type + currency = validated_data.get('currency', 'uzs').lower() user = self.context.get('user') - if validated_data.get('currency') == 'uzs': + + if currency == 'uzs': cash_transaction.expence_balance_uzs += expence.price cash_transaction.total_balance_uzs = cash_transaction.income_balance_uzs - cash_transaction.expence_balance_uzs - if payment_type.total_uzs > expence.price: - payment_type.total_uzs -= expence.price - + + payment_type.total_uzs -= expence.price + if expence.counterparty: - if expence.counterparty.kredit_uzs != 0: - expence.counterparty.kredit_uzs -= expence.price + if expence.counterparty.kredit_uzs > 0: + expence.counterparty.kredit_uzs -= expence.price expence.counterparty.total_kredit -= expence.price - - expence.counterparty.debit_uzs += expence.counterparty.kredit_uzs - expence.price + + expence.counterparty.debit_uzs += expence.price expence.counterparty.total_debit += expence.price else: expence.counterparty.debit_uzs += expence.price expence.counterparty.total_debit += expence.price + expence.counterparty.save() - elif validated_data.get('currency') == 'usd': + elif currency == 'usd': cash_transaction.expence_balance_usd += expence.price cash_transaction.total_balance_usd = cash_transaction.income_balance_usd - cash_transaction.expence_balance_usd - if payment_type.total_usd > expence.price: - payment_type.total_usd -= expence.price - + + payment_type.total_usd -= expence.price + if expence.counterparty: - if expence.counterparty.kredit_usd != 0: - expence.counterparty.kredit_usd -= validated_data.get('price') + if expence.counterparty.kredit_usd > 0: + expence.counterparty.kredit_usd -= expence.price expence.counterparty.total_kredit -= expence.price - - expence.counterparty.debit_usd += expence.counterparty.kredit_usd - validated_data.get('price') + + expence.counterparty.debit_usd += expence.price expence.counterparty.total_debit += expence.price else: - expence.counterparty.debit_usd += validated_data.get('price') + expence.counterparty.debit_usd += expence.price expence.counterparty.total_debit += expence.price + expence.counterparty.save() + body = f"""{user.full_name} {expence.price} {expence.currency.upper()}... \n screen: /monitoring""" data = { "screen": "/monitoring", "type": "expence", } notify_user(user=user, title="Tasdiqlang yoki rad eting", body=body, data=data) + cash_transaction.save() payment_type.save() + return expence - class ExpenceListSerializer(serializers.ModelSerializer): cash_transaction = serializers.SerializerMethodField(method_name='get_cash_transaction') @@ -156,40 +182,93 @@ class ExpenceUpdateSerializer(serializers.ModelSerializer): 'price': {'required': False}, } + def validate_price(self, value): + if value and value < 0: + raise serializers.ValidationError("Narxi manfiy bo'lishi mumkin emas") + return value + def update(self, instance, validated_data): - old_price = instance.price - instance.project_folder = validated_data.get('project_folder', instance.project_folder) - instance.project = validated_data.get('project', instance.project) - instance.price = validated_data.get('price', instance.price) - instance.expence_type = validated_data.get('expence_type', instance.expence_type) - instance.counterparty = validated_data.get('counterparty', instance.counterparty) - instance.date = validated_data.get('date', instance.date) - instance.comment = validated_data.get('comment', instance.comment) - instance.audit = validated_data.get('audit', instance.audit) - instance.file = validated_data.get('file', instance.file) - if validated_data.get('price'): - cash_transaction = instance.cash_transaction - payment_type = instance.payment_type - if old_price > validated_data.get('price'): - if instance.currency == 'uzs': - cash_transaction.expence_balance_uzs -= (old_price - validated_data.get('price')) - cash_transaction.total_balance_uzs -= (old_price - validated_data.get('price')) - payment_type.total_uzs -= (old_price - validated_data.get('price')) if payment_type.total_uzs > (old_price - validated_data.get('price')) else 0 - else: - cash_transaction.expence_balance_usd -= (old_price - validated_data.get('price')) - cash_transaction.total_balance_usd -= (old_price - validated_data.get('price')) - payment_type.total_usd -= (old_price - validated_data.get('price')) if payment_type.total_usd > (old_price - validated_data.get('price')) else 0 - - elif old_price < validated_data.get('price'): - if instance.currency == 'uzs': - cash_transaction.expence_balance_uzs += (old_price - validated_data.get('price')) - cash_transaction.total_balance_uzs += (old_price - validated_data.get('price')) - payment_type.total_uzs += (old_price - validated_data.get('price')) - else: - cash_transaction.expence_balance_usd += (old_price - validated_data.get('price')) - cash_transaction.total_balance_usd += (old_price - validated_data.get('price')) - payment_type.total_usd += (old_price - validated_data.get('price')) - cash_transaction.save() - payment_type.save() - instance.save() - return instance \ No newline at end of file + with transaction.atomic(): + old_price = instance.price + old_counterparty = instance.counterparty + new_price = validated_data.get('price', instance.price) + new_counterparty = validated_data.get('counterparty', instance.counterparty) + currency = instance.currency.lower() + + instance.project_folder = validated_data.get('project_folder', instance.project_folder) + instance.project = validated_data.get('project', instance.project) + instance.price = new_price + instance.expence_type = validated_data.get('expence_type', instance.expence_type) + instance.counterparty = new_counterparty + instance.date = validated_data.get('date', instance.date) + instance.comment = validated_data.get('comment', instance.comment) + instance.audit = validated_data.get('audit', instance.audit) + instance.file = validated_data.get('file', instance.file) + + if validated_data.get('price') and old_price != new_price: + price_difference = new_price - old_price + cash_transaction = instance.cash_transaction + payment_type = instance.payment_type + + if currency == 'uzs': + cash_transaction.expence_balance_uzs += price_difference + cash_transaction.total_balance_uzs = ( + cash_transaction.income_balance_uzs - cash_transaction.expence_balance_uzs + ) + + payment_type.total_uzs -= price_difference + + elif currency == 'usd': + cash_transaction.expence_balance_usd += price_difference + cash_transaction.total_balance_usd = ( + cash_transaction.income_balance_usd - cash_transaction.expence_balance_usd + ) + + payment_type.total_usd -= price_difference + + cash_transaction.save() + payment_type.save() + + if new_counterparty != old_counterparty: + if old_counterparty: + if currency == 'uzs': + if old_counterparty.debit_uzs > 0: + old_counterparty.debit_uzs -= old_price + old_counterparty.total_debit -= old_price + else: + old_counterparty.kredit_uzs += old_price + old_counterparty.total_kredit += old_price + else: + if old_counterparty.debit_usd > 0: + old_counterparty.debit_usd -= old_price + old_counterparty.total_debit -= old_price + else: + old_counterparty.kredit_usd += old_price + old_counterparty.total_kredit += old_price + + old_counterparty.save() + + if new_counterparty: + if currency == 'uzs': + if new_counterparty.kredit_uzs > 0: + new_counterparty.kredit_uzs -= new_price + new_counterparty.total_kredit -= new_price + new_counterparty.debit_uzs += new_price + new_counterparty.total_debit += new_price + else: + new_counterparty.debit_uzs += new_price + new_counterparty.total_debit += new_price + else: + if new_counterparty.kredit_usd > 0: + new_counterparty.kredit_usd -= new_price + new_counterparty.total_kredit -= new_price + new_counterparty.debit_usd += new_price + new_counterparty.total_debit += new_price + else: + new_counterparty.debit_usd += new_price + new_counterparty.total_debit += new_price + + new_counterparty.save() + + instance.save() + return instance \ No newline at end of file diff --git a/core/apps/finance/serializers/income.py b/core/apps/finance/serializers/income.py index 14fbe16..88a4ca0 100644 --- a/core/apps/finance/serializers/income.py +++ b/core/apps/finance/serializers/income.py @@ -77,7 +77,6 @@ class IncomeListSerializer(serializers.ModelSerializer): else None ) - class IncomeCreateSerializer(serializers.ModelSerializer): class Meta: model = Income @@ -97,8 +96,23 @@ class IncomeCreateSerializer(serializers.ModelSerializer): "audit", ] + def validate(self, data): + price = data.get('price') + exchange_rate = data.get('exchange_rate') + + if price and price < 0: + raise serializers.ValidationError("Narxi manfiy bo'lishi mumkin emas") + + if exchange_rate and exchange_rate < 0: + raise serializers.ValidationError("Kurs manfiy bo'lishi mumkin emas") + + return data + def create(self, validated_data): with transaction.atomic(): + exchange_rate = validated_data.get("exchange_rate") or 1 + final_price = validated_data.get("price") * exchange_rate + income = Income.objects.create( user=self.context.get("user"), cash_transaction=validated_data["cash_transaction"], @@ -108,61 +122,60 @@ class IncomeCreateSerializer(serializers.ModelSerializer): counterparty=validated_data.get("counterparty"), type_income=validated_data.get("type_income"), currency=validated_data.get("currency"), - price=( - validated_data.get("price") * validated_data.get("exchange_rate") - if validated_data.get("exchange_rate") - else validated_data.get("price") - ), - exchange_rate=validated_data.get("exchange_rate"), + price=final_price, + exchange_rate=exchange_rate, date=validated_data.get("date"), comment=validated_data.get("comment"), file=validated_data.get("file"), audit=validated_data.get("audit"), ) + cash_transaction = income.cash_transaction payment_type = income.payment_type + currency = validated_data.get("currency", "uzs").lower() - if validated_data.get("currency") == "uzs": + if currency == "uzs": cash_transaction.income_balance_uzs += income.price cash_transaction.total_balance_uzs = ( cash_transaction.income_balance_uzs - cash_transaction.expence_balance_uzs ) + payment_type.total_uzs += income.price if income.counterparty: - if income.counterparty.debit_uzs != 0: + if income.counterparty.debit_uzs > 0: income.counterparty.debit_uzs -= income.price income.counterparty.total_debit -= income.price - - income.counterparty.kredit_uzs += ( - income.counterparty.debit_uzs - income.price - ) + + income.counterparty.kredit_uzs += income.price income.counterparty.total_kredit += income.price else: income.counterparty.kredit_uzs += income.price income.counterparty.total_kredit += income.price + income.counterparty.save() - elif validated_data.get("currency") == "usd": + elif currency == "usd": cash_transaction.income_balance_usd += income.price cash_transaction.total_balance_usd = ( cash_transaction.income_balance_usd - cash_transaction.expence_balance_usd ) + payment_type.total_usd += income.price + if income.counterparty: - if income.counterparty.debit_usd != 0: - income.counterparty.debit_usd -= validated_data.get("price") + if income.counterparty.debit_usd > 0: + income.counterparty.debit_usd -= income.price income.counterparty.total_debit -= income.price - income.counterparty.kredit_usd += ( - income.counterparty.debit_usd - validated_data.get("price") - ) + income.counterparty.kredit_usd += income.price income.counterparty.total_kredit += income.price else: - income.counterparty.kredit_usd += validated_data.get("price") + income.counterparty.kredit_usd += income.price income.counterparty.total_kredit += income.price + income.counterparty.save() cash_transaction.save() @@ -192,70 +205,97 @@ class IncomeUpdateSerializer(serializers.ModelSerializer): "price": {"required": False}, } - def update(self, instance, validated_data): - old_price = instance.price - instance.project_folder = validated_data.get( - "project_folder", instance.project_folder - ) - instance.project = validated_data.get("project", instance.project) - instance.price = validated_data.get("price", instance.price) - instance.type_income = validated_data.get("type_income", instance.type_income) - instance.counterparty = validated_data.get( - "counterparty", instance.counterparty - ) - instance.date = validated_data.get("date", instance.date) - instance.comment = validated_data.get("comment", instance.comment) - instance.audit = validated_data.get("audit", instance.audit) - instance.file = validated_data.get("file", instance.file) - if validated_data.get("price"): - cash_transaction = instance.cash_transaction - payment_type = instance.payment_type - if old_price > validated_data.get("price"): - if instance.currency == "uzs": - cash_transaction.income_balance_uzs -= ( - old_price - validated_data.get("price") - ) - cash_transaction.total_balance_uzs -= ( - old_price - validated_data.get("price") - ) - payment_type.total_uzs -= ( - (old_price - validated_data.get("price")) - if payment_type.total_uzs - > (old_price - validated_data.get("price")) - else 0 - ) - else: - cash_transaction.income_balance_usd -= ( - old_price - validated_data.get("price") - ) - cash_transaction.total_balance_usd -= ( - old_price - validated_data.get("price") - ) - payment_type.total_usd -= ( - (old_price - validated_data.get("price")) - if payment_type.total_usd - > (old_price - validated_data.get("price")) - else 0 - ) + def validate_price(self, value): + if value and value < 0: + raise serializers.ValidationError("Narxi manfiy bo'lishi mumkin emas") + return value - elif old_price < validated_data.get("price"): - if instance.currency == "uzs": - cash_transaction.income_balance_uzs += ( - old_price - validated_data.get("price") + def update(self, instance, validated_data): + with transaction.atomic(): + old_price = instance.price + old_counterparty = instance.counterparty + new_price = validated_data.get("price", instance.price) + new_counterparty = validated_data.get("counterparty", instance.counterparty) + currency = instance.currency.lower() + + instance.project_folder = validated_data.get( + "project_folder", instance.project_folder + ) + instance.project = validated_data.get("project", instance.project) + instance.price = new_price + instance.type_income = validated_data.get("type_income", instance.type_income) + instance.counterparty = new_counterparty + instance.date = validated_data.get("date", instance.date) + instance.comment = validated_data.get("comment", instance.comment) + instance.audit = validated_data.get("audit", instance.audit) + instance.file = validated_data.get("file", instance.file) + + if validated_data.get("price") and old_price != new_price: + price_difference = new_price - old_price + cash_transaction = instance.cash_transaction + payment_type = instance.payment_type + + if currency == "uzs": + cash_transaction.income_balance_uzs += price_difference + cash_transaction.total_balance_uzs = ( + cash_transaction.income_balance_uzs + - cash_transaction.expence_balance_uzs ) - cash_transaction.total_balance_uzs += ( - old_price - validated_data.get("price") + + payment_type.total_uzs += price_difference + + elif currency == "usd": + cash_transaction.income_balance_usd += price_difference + cash_transaction.total_balance_usd = ( + cash_transaction.income_balance_usd + - cash_transaction.expence_balance_usd ) - payment_type.total_uzs += old_price - validated_data.get("price") - else: - cash_transaction.income_balance_usd += ( - old_price - validated_data.get("price") - ) - cash_transaction.total_balance_usd += ( - old_price - validated_data.get("price") - ) - payment_type.total_usd += old_price - validated_data.get("price") - cash_transaction.save() - payment_type.save() - instance.save() - return instance + + payment_type.total_usd += price_difference + + cash_transaction.save() + payment_type.save() + + if new_counterparty != old_counterparty: + if old_counterparty: + if currency == "uzs": + if old_counterparty.kredit_uzs > 0: + old_counterparty.kredit_uzs -= old_price + old_counterparty.total_kredit -= old_price + else: + old_counterparty.debit_uzs += old_price + old_counterparty.total_debit += old_price + else: + if old_counterparty.kredit_usd > 0: + old_counterparty.kredit_usd -= old_price + old_counterparty.total_kredit -= old_price + else: + old_counterparty.debit_usd += old_price + old_counterparty.total_debit += old_price + + old_counterparty.save() + + if new_counterparty: + if currency == "uzs": + if new_counterparty.debit_uzs > 0: + new_counterparty.debit_uzs -= new_price + new_counterparty.total_debit -= new_price + new_counterparty.kredit_uzs += new_price + new_counterparty.total_kredit += new_price + else: + new_counterparty.kredit_uzs += new_price + new_counterparty.total_kredit += new_price + else: + if new_counterparty.debit_usd > 0: + new_counterparty.debit_usd -= new_price + new_counterparty.total_debit -= new_price + new_counterparty.kredit_usd += new_price + new_counterparty.total_kredit += new_price + else: + new_counterparty.kredit_usd += new_price + new_counterparty.total_kredit += new_price + + new_counterparty.save() + + instance.save() + return instance diff --git a/core/apps/finance/views/expence.py b/core/apps/finance/views/expence.py index c196722..e1d87ab 100644 --- a/core/apps/finance/views/expence.py +++ b/core/apps/finance/views/expence.py @@ -1,4 +1,5 @@ from django.shortcuts import get_object_or_404 +from django.db import transaction from rest_framework import generics, views, parsers, filters from rest_framework.response import Response @@ -109,41 +110,88 @@ class ChangeExpenceStatusApiView(views.APIView): status=200 ) - class ExpenceDeleteApiView(generics.GenericAPIView): serializer_class = serializers.ExpenceDeleteSerializer queryset = Expence.objects.all() permission_classes = [HasRolePermission] def post(self, request, id): - expence = get_object_or_404(Expence, id=id) + expence = get_object_or_404(Expence, id=id, is_deleted=False) serializer = self.serializer_class(data=request.data) + if serializer.is_valid(raise_exception=True): - comment = serializer.validated_data.get('comment') - DeletedExpence.objects.create( - expence=expence, - comment=comment - ) - expence.is_deleted = True - if expence.currency == 'uzs': - expence.cash_transaction.expence_balance_uzs += expence.price - expence.cash_transaction.total_balance_uzs += expence.price - expence.payment_type.total_uzs += expence.price - else: - expence.cash_transaction.expence_balance_usd += expence.price - expence.cash_transaction.total_balance_usd += expence.price - expence.payment_type.total_usd += expence.price + with transaction.atomic(): + comment = serializer.validated_data.get('comment') + currency = expence.currency.lower() + + DeletedExpence.objects.create( + expence=expence, + comment=comment + ) + + cash_transaction = expence.cash_transaction + payment_type = expence.payment_type + counterparty = expence.counterparty + + if currency == 'uzs': + cash_transaction.expence_balance_uzs -= expence.price + cash_transaction.total_balance_uzs = ( + cash_transaction.income_balance_uzs - cash_transaction.expence_balance_uzs + ) + payment_type.total_uzs += expence.price + + if counterparty: + if counterparty.debit_uzs > 0: + counterparty.debit_uzs += expence.price + counterparty.total_debit += expence.price + + counterparty.kredit_uzs -= expence.price + counterparty.total_kredit -= expence.price + else: + counterparty.kredit_uzs -= expence.price + counterparty.total_kredit -= expence.price + + counterparty.save() + + elif currency == 'usd': + cash_transaction.expence_balance_usd -= expence.price + cash_transaction.total_balance_usd = ( + cash_transaction.income_balance_usd - cash_transaction.expence_balance_usd + ) + payment_type.total_usd += expence.price + + if counterparty: + if counterparty.debit_usd > 0: + counterparty.debit_usd += expence.price + counterparty.total_debit += expence.price + + counterparty.kredit_usd -= expence.price + counterparty.total_kredit -= expence.price + else: + counterparty.kredit_usd -= expence.price + counterparty.total_kredit -= expence.price + + counterparty.save() + + expence.is_deleted = True + + cash_transaction.save() + payment_type.save() + expence.save() + + return Response( + { + 'success': True, + 'message': 'Expence o\'chirildi', + 'data': { + 'expence_id': expence.id, + 'price': expence.price, + 'currency': expence.currency + } + }, + status=200 + ) - expence.cash_transaction.save() - expence.payment_type.save() - expence.save() - return Response( - { - 'success': True, - 'message': 'Expence deleted', - }, status=200 - ) - class ExpenceUpdateApiView(generics.GenericAPIView): serializer_class = serializers.ExpenceUpdateSerializer diff --git a/core/apps/finance/views/income.py b/core/apps/finance/views/income.py index 930479d..db213df 100644 --- a/core/apps/finance/views/income.py +++ b/core/apps/finance/views/income.py @@ -1,4 +1,5 @@ from django.shortcuts import get_object_or_404 +from django.db import transaction from rest_framework import generics, views, parsers, filters from rest_framework.response import Response @@ -84,34 +85,82 @@ class IncomeDeleteApiView(generics.GenericAPIView): permission_classes = [HasRolePermission] def post(self, request, id): - income = get_object_or_404(Income, id=id) + income = get_object_or_404(Income, id=id, is_deleted=False) serializer = self.serializer_class(data=request.data) + if serializer.is_valid(raise_exception=True): - comment = serializer.validated_data.get('comment') - DeletedIncome.objects.create( - income=income, - comment=comment - ) - income.is_deleted = True - if income.currency == 'uzs': - income.cash_transaction.expence_balance_uzs -= income.price - income.cash_transaction.total_balance_uzs -= income.price - income.payment_type.total_uzs -= income.price if income.payment_type.total_uzs > income.price else 0 - else: - income.cash_transaction.expence_balance_usd -= income.price - income.cash_transaction.total_balance_usd -= income.price - income.payment_type.total_usd -= income.price if income.payment_type.total_usd > income.price else 0 + with transaction.atomic(): + comment = serializer.validated_data.get('comment') + currency = income.currency.lower() + + DeletedIncome.objects.create( + income=income, + comment=comment + ) + + cash_transaction = income.cash_transaction + payment_type = income.payment_type + counterparty = income.counterparty + + if currency == 'uzs': + cash_transaction.income_balance_uzs -= income.price + cash_transaction.total_balance_uzs = ( + cash_transaction.income_balance_uzs - cash_transaction.expence_balance_uzs + ) + payment_type.total_uzs -= income.price + + if counterparty: + if counterparty.kredit_uzs > 0: + counterparty.kredit_uzs -= income.price + counterparty.total_kredit -= income.price + + counterparty.debit_uzs += income.price + counterparty.total_debit += income.price + else: + counterparty.debit_uzs += income.price + counterparty.total_debit += income.price + + counterparty.save() + + elif currency == 'usd': + cash_transaction.income_balance_usd -= income.price + cash_transaction.total_balance_usd = ( + cash_transaction.income_balance_usd - cash_transaction.expence_balance_usd + ) + payment_type.total_usd -= income.price + + if counterparty: + if counterparty.kredit_usd > 0: + counterparty.kredit_usd -= income.price + counterparty.total_kredit -= income.price + + counterparty.debit_usd += income.price + counterparty.total_debit += income.price + else: + counterparty.debit_usd += income.price + counterparty.total_debit += income.price + + counterparty.save() + + income.is_deleted = True + + cash_transaction.save() + payment_type.save() + income.save() + + return Response( + { + 'success': True, + 'message': 'Income o\'chirildi', + 'data': { + 'income_id': income.id, + 'price': income.price, + 'currency': income.currency + } + }, + status=200 + ) - income.cash_transaction.save() - income.payment_type.save() - income.save() - return Response( - { - 'success': True, - 'message': 'Income deleted', - }, status=200 - ) - class IncomeUpdateApiView(generics.GenericAPIView): serializer_class = serializers.IncomeUpdateSerializer diff --git a/core/apps/orders/serializers/party.py b/core/apps/orders/serializers/party.py index 027bd05..3cb1c1c 100644 --- a/core/apps/orders/serializers/party.py +++ b/core/apps/orders/serializers/party.py @@ -381,106 +381,136 @@ class PartyExpenceCreateSerializer(serializers.ModelSerializer): "party", ] + def validate(self, data): + price = data.get('price') + exchange_rate = data.get('exchange_rate') + party = data.get('party') + currency = data.get('currency', 'uzs').lower() + + if price and price < 0: + raise serializers.ValidationError("Narxi manfiy bo'lishi mumkin emas") + + if exchange_rate and exchange_rate < 0: + raise serializers.ValidationError("Kurs manfiy bo'lishi mumkin emas") + + if not party: + raise serializers.ValidationError("Party talab qilinadi") + + try: + usd_course = UsdCourse.objects.first() + if not usd_course or not usd_course.value: + raise serializers.ValidationError("USD kursi topilmadi") + except UsdCourse.DoesNotExist: + raise serializers.ValidationError("USD kursi topilmadi") + + return data + def create(self, validated_data): with transaction.atomic(): - usd_value = UsdCourse.objects.first().value + usd_course = UsdCourse.objects.first() + if not usd_course: + raise serializers.ValidationError("USD kursi topilmadi") + + usd_value = usd_course.value + + exchange_rate = validated_data.get("exchange_rate") or 1 + final_price = validated_data.get("price") * exchange_rate + currency = validated_data.get("currency", "uzs").lower() + expence = Expence.objects.create( cash_transaction=validated_data.get("cash_transaction"), payment_type=validated_data.get("payment_type"), project_folder=validated_data.get("project_folder"), project=validated_data.get("project"), counterparty=validated_data.get("counterparty"), - price=( - validated_data.get("price") * validated_data.get("exchange_rate") - if validated_data.get("exchange_rate") - else validated_data.get("price") - ), - exchange_rate=validated_data.get("exchange_rate"), - currency=validated_data.get("currency"), + price=final_price, + exchange_rate=exchange_rate, + currency=currency, date=validated_data.get("date"), comment=validated_data.get("comment"), party=validated_data.get("party"), user=self.context.get('user'), ) + cash_transaction = expence.cash_transaction payment_type = expence.payment_type - - if validated_data.get("currency") == "uzs": + party = expence.party + + if currency == "uzs": cash_transaction.expence_balance_uzs += expence.price cash_transaction.total_balance_uzs = ( cash_transaction.income_balance_uzs - cash_transaction.expence_balance_uzs ) + if payment_type.total_uzs > expence.price: payment_type.total_uzs -= expence.price - + if expence.counterparty: - if expence.counterparty.kredit_uzs != 0: + if expence.counterparty.kredit_uzs > 0: expence.counterparty.kredit_uzs -= expence.price expence.counterparty.total_kredit -= expence.price - - expence.counterparty.debit_uzs += ( - expence.counterparty.kredit_uzs - expence.price - ) + + expence.counterparty.debit_uzs += expence.price expence.counterparty.total_debit += expence.price else: expence.counterparty.debit_uzs += expence.price expence.counterparty.total_debit += expence.price + expence.counterparty.save() - if expence.party.currency == "uzs": - expence.party.party_amount.payment_amount -= expence.price - expence.party.party_amount.paid_amount += expence.price - print(expence.party.party_amount.payment_amount) - print(expence.party.party_amount.paid_amount) - expence.party.party_amount.save() - expence.party.save() - elif expence.party.currency == 'usd': - expence.party.party_amount.payment_amount -= round(expence.price / usd_value) - expence.party.party_amount.paid_amount += round(expence.price / usd_value) - expence.party.save() - elif validated_data.get("currency") == "usd": + + if party: + if party.currency == "uzs": + party.party_amount.payment_amount -= expence.price + party.party_amount.paid_amount += expence.price + party.party_amount.save() + elif party.currency == 'usd': + converted_price = round(expence.price / usd_value) + party.party_amount.payment_amount -= converted_price + party.party_amount.paid_amount += converted_price + party.party_amount.save() + + party.save() + + elif currency == "usd": cash_transaction.expence_balance_usd += expence.price cash_transaction.total_balance_usd = ( cash_transaction.income_balance_usd - cash_transaction.expence_balance_usd ) + if payment_type.total_usd > expence.price: payment_type.total_usd -= expence.price - + if expence.counterparty: - if expence.counterparty.kredit_usd != 0: - expence.counterparty.kredit_usd -= validated_data.get("price") + if expence.counterparty.kredit_usd > 0: + expence.counterparty.kredit_usd -= expence.price expence.counterparty.total_kredit -= expence.price - - expence.counterparty.debit_usd += ( - expence.counterparty.kredit_usd - - validated_data.get("price") - ) + + expence.counterparty.debit_usd += expence.price expence.counterparty.total_debit += expence.price else: - expence.counterparty.debit_usd += validated_data.get("price") + expence.counterparty.debit_usd += expence.price expence.counterparty.total_debit += expence.price + expence.counterparty.save() - - if expence.party.currency == "usd": - expence.party.party_amount.payment_amount -= validated_data.get( - "price" - ) - expence.party.party_amount.paid_amount += validated_data.get( - "price" - ) - expence.party.save() - elif expence.party.currency == "uzs": - expence.party.party_amount.payment_amount -= validated_data.get( - "price" - ) * usd_value - expence.party.party_amount.paid_amount += validated_data.get( - "price" - ) * usd_value - expence.party.save() - expence.party.party_amount.save() + + if party: + if party.currency == "usd": + party.party_amount.payment_amount -= expence.price + party.party_amount.paid_amount += expence.price + party.party_amount.save() + elif party.currency == "uzs": + converted_price = expence.price * usd_value + party.party_amount.payment_amount -= converted_price + party.party_amount.paid_amount += converted_price + party.party_amount.save() + + party.save() + cash_transaction.save() payment_type.save() + return expence