diff --git a/core/apps/finance/serializers/cash_transaction.py b/core/apps/finance/serializers/cash_transaction.py index 8d1abee..6e840e8 100644 --- a/core/apps/finance/serializers/cash_transaction.py +++ b/core/apps/finance/serializers/cash_transaction.py @@ -21,7 +21,7 @@ class CashTransactionEmployeeListSerializer(serializers.ModelSerializer): class Meta: model = User fields = [ - 'id', 'profile_image', 'first_name', 'last_name', 'username' + 'id', 'profile_image', 'full_name', 'username' ] diff --git a/core/apps/orders/migrations/0027_alter_partyamount_calculated_amount_and_more.py b/core/apps/orders/migrations/0027_alter_partyamount_calculated_amount_and_more.py new file mode 100644 index 0000000..ff0127e --- /dev/null +++ b/core/apps/orders/migrations/0027_alter_partyamount_calculated_amount_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 5.2.4 on 2025-10-07 16:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('orders', '0026_alter_order_qqs_alter_order_qqs_price_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='partyamount', + name='calculated_amount', + field=models.BigIntegerField(default=0), + ), + migrations.AlterField( + model_name='partyamount', + name='cost_amount', + field=models.BigIntegerField(default=0), + ), + migrations.AlterField( + model_name='partyamount', + name='paid_amount', + field=models.BigIntegerField(default=0), + ), + ] diff --git a/core/apps/orders/models/party.py b/core/apps/orders/models/party.py index 51b318b..e53e127 100644 --- a/core/apps/orders/models/party.py +++ b/core/apps/orders/models/party.py @@ -59,6 +59,25 @@ class Party(BaseModel): def __str__(self): return f'P - {self.number}' + def save(self, *args, **kwargs): + if self.status in ['NEW', 'CANCELLED', 'DRAFT']: + self.process = 0 + elif self.status == 'EXPECTED': + self.process = 25 + elif self.status == 'PROCESS': + self.process = 50 + elif self.status == 'PURCHASED': + self.process = 75 + elif self.status == 'PARTY_IS_MADE': + self.process = 100 + if hasattr(self, 'party_amount') and self.party_amount.paid_amount > 0 and self.party_amount.payment_amount > 0: + self.payment_percentage = (self.party_amount.paid_amount / self.party_amount.payment_amount) * 100 + self.party_amount.save() + else: + self.payment_percentage = 100.0 + self.status == 'PURCHASED' + return super().save(*args, **kwargs) + class Meta: verbose_name = 'Partiya' verbose_name_plural = 'Partiyalar' @@ -67,9 +86,9 @@ class Party(BaseModel): class PartyAmount(BaseModel): party = models.OneToOneField(Party, on_delete=models.CASCADE, related_name='party_amount') total_price = models.PositiveBigIntegerField() - cost_amount = models.PositiveBigIntegerField(default=0) - calculated_amount = models.PositiveBigIntegerField(default=0) - paid_amount = models.PositiveBigIntegerField(default=0) + cost_amount = models.BigIntegerField(default=0) + calculated_amount = models.BigIntegerField(default=0) + paid_amount = models.BigIntegerField(default=0) payment_amount = models.BigIntegerField(default=0) def __str__(self): diff --git a/core/apps/orders/serializers/party.py b/core/apps/orders/serializers/party.py index e6868f1..ead0848 100644 --- a/core/apps/orders/serializers/party.py +++ b/core/apps/orders/serializers/party.py @@ -64,10 +64,9 @@ class PartyCreateSerializer(serializers.Serializer): qqs=resource.get("qqs"), ) ) - if validated_data.get("currency") != "uzs": - if resource.get("currency") == "usd": - usd_value = UsdCourse.objects.first().value - total_price += resource.get("amount") * usd_value + if resource.get("currency") == "usd": + usd_value = UsdCourse.objects.first().value + total_price += resource.get("amount") * usd_value else: total_price += resource.get("amount") created_orders = Order.objects.bulk_create(orders) @@ -123,6 +122,7 @@ class PartyDetailSerializer(serializers.ModelSerializer): "payment_date", "status", "payment_status", + "payment_percentage", "process", "confirmation", "comment", @@ -166,6 +166,7 @@ class PartyListSerializer(serializers.ModelSerializer): "payment_date", "status", "payment_status", + "payment_percentage", "process", "confirmation", "comment", @@ -381,6 +382,7 @@ class PartyExpenceCreateSerializer(serializers.ModelSerializer): def create(self, validated_data): with transaction.atomic(): + usd_value = UsdCourse.objects.first().value expence = Expence.objects.create( cash_transaction=validated_data.get("cash_transaction"), payment_type=validated_data.get("payment_type"), @@ -426,8 +428,14 @@ class PartyExpenceCreateSerializer(serializers.ModelSerializer): 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": cash_transaction.expence_balance_usd += expence.price cash_transaction.total_balance_usd = ( @@ -451,6 +459,7 @@ class PartyExpenceCreateSerializer(serializers.ModelSerializer): expence.counterparty.debit_usd += validated_data.get("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" @@ -459,7 +468,15 @@ class PartyExpenceCreateSerializer(serializers.ModelSerializer): "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() cash_transaction.save() payment_type.save() return expence diff --git a/core/apps/orders/views/party.py b/core/apps/orders/views/party.py index 959d694..60c99bc 100644 --- a/core/apps/orders/views/party.py +++ b/core/apps/orders/views/party.py @@ -36,7 +36,7 @@ class PartyCreateApiView(generics.GenericAPIView): class PartyListApiView(generics.GenericAPIView): serializer_class = serializers.PartyListSerializer - queryset = Party.objects.select_related('party_amount').exclude(is_deleted=True).order_by('number') + queryset = Party.objects.select_related('party_amount').exclude(is_deleted=True).order_by('-number') permission_classes = [HasRolePermission] filter_backends = [DjangoFilterBackend] filterset_class = PartyFilter diff --git a/core/apps/shared/serializers/usd_course.py b/core/apps/shared/serializers/usd_course.py new file mode 100644 index 0000000..c7ba83d --- /dev/null +++ b/core/apps/shared/serializers/usd_course.py @@ -0,0 +1,11 @@ +from rest_framework import serializers + +from core.apps.shared.models import UsdCourse + + +class UsdCourseSerializer(serializers.ModelSerializer): + class Meta: + model = UsdCourse + fields = [ + 'id', 'value' + ] \ No newline at end of file diff --git a/core/apps/shared/urls.py b/core/apps/shared/urls.py index 1159d48..ce5b7a0 100644 --- a/core/apps/shared/urls.py +++ b/core/apps/shared/urls.py @@ -1,8 +1,10 @@ from django.urls import path, include from core.apps.shared.views import region as region_views +from core.apps.shared.views.usd_course import UsdCourseApiView urlpatterns = [ path('region/list/', region_views.RegionListApiView.as_view()), path('region//districts/', region_views.DistrictListApiView.as_view()), + path('usd_course/', UsdCourseApiView.as_view()), ] \ No newline at end of file diff --git a/core/apps/shared/views/usd_course.py b/core/apps/shared/views/usd_course.py new file mode 100644 index 0000000..6265e0e --- /dev/null +++ b/core/apps/shared/views/usd_course.py @@ -0,0 +1,29 @@ +from django.shortcuts import get_object_or_404 + +from rest_framework import generics +from rest_framework.response import Response + +from core.apps.shared.models import UsdCourse +from core.apps.shared.serializers.usd_course import UsdCourseSerializer +from core.apps.accounts.permissions.permissions import HasRolePermission + + +class UsdCourseApiView(generics.GenericAPIView): + serializer_class = UsdCourseSerializer + queryset = UsdCourse.objects.all() + permission_classes = [HasRolePermission] + + def get(self, request): + value = UsdCourse.objects.first() + serializer = self.serializer_class(value) + return Response(serializer.data, status=200) + + def patch(self, request, id): + usd_cource = get_object_or_404(UsdCourse, id=id) + serializer = self.serializer_class(data=request.data) + if serializer.is_valid(): + return Response(serializer.errors, status=400) + value = serializer.validated_data.get('value') + usd_cource.value = value + usd_cource.save() + return Response({'new_value': usd_cource.value, 'old_value': value}, status=200)