add new field to party mode

This commit is contained in:
behruz-dev
2025-08-22 16:34:02 +05:00
parent b0bb20691f
commit 1f09a4bff5
8 changed files with 178 additions and 12 deletions

View File

@@ -1,6 +1,6 @@
from django.contrib import admin from django.contrib import admin
from core.apps.orders.models import Party, PartyAmount from core.apps.orders.models import Party, PartyAmount, DeletedParty
class PartyAmountInline(admin.StackedInline): class PartyAmountInline(admin.StackedInline):
@@ -11,7 +11,7 @@ class PartyAmountInline(admin.StackedInline):
@admin.register(Party) @admin.register(Party)
class PartyAdmin(admin.ModelAdmin): class PartyAdmin(admin.ModelAdmin):
list_display = ['mediator', 'delivery_date', 'payment_date'] list_display = ['mediator', 'delivery_date', 'payment_date', 'is_deleted']
inlines = [PartyAmountInline] inlines = [PartyAmountInline]
@@ -20,4 +20,8 @@ class PartyAmountAdmin(admin.ModelAdmin):
list_display = ['id', 'total_price', 'cost_amount'] list_display = ['id', 'total_price', 'cost_amount']
def has_module_permission(self, request): def has_module_permission(self, request):
return False return False
@admin.register(DeletedParty)
class DeletedPartyAdmin(admin.ModelAdmin):
list_display = ['id', 'deleted_date', 'party']

View File

@@ -0,0 +1,34 @@
# Generated by Django 5.2.4 on 2025-08-22 14:47
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('orders', '0017_alter_party_confirmation'),
]
operations = [
migrations.AddField(
model_name='party',
name='is_deleted',
field=models.BooleanField(default=False),
),
migrations.CreateModel(
name='DeletedParty',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('deleted_date', models.DateField(auto_now_add=True)),
('party', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='deleted_parties', to='orders.party')),
],
options={
'verbose_name': "O'chirilgan partiya",
'verbose_name_plural': "O'chirilgan partiyalar",
},
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.2.4 on 2025-08-22 14:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('orders', '0018_party_is_deleted_deletedparty'),
]
operations = [
migrations.AddField(
model_name='deletedparty',
name='comment',
field=models.CharField(blank=True, max_length=200, null=True),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.2.4 on 2025-08-22 16:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('orders', '0019_deletedparty_comment'),
]
operations = [
migrations.AddField(
model_name='party',
name='discount_currency',
field=models.CharField(blank=True, choices=[('uzs', 'uzs'), ('usd', 'usd')], default='uzs', max_length=3, null=True),
),
]

View File

@@ -50,9 +50,13 @@ class Party(BaseModel):
) )
audit_comment = models.TextField(null=True, blank=True) audit_comment = models.TextField(null=True, blank=True)
discount = models.PositiveBigIntegerField(default=0, null=True, blank=True) discount = models.PositiveBigIntegerField(default=0, null=True, blank=True)
discount_currency = models.CharField(
max_length=3, choices=[('uzs', 'uzs'), ('usd', 'usd')], default='uzs', null=True, blank=True
)
is_deleted = models.BooleanField(default=False)
def __str__(self): def __str__(self):
return str(self.number) return f'P - {self.number}'
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.pk: if not self.pk:
@@ -82,4 +86,22 @@ class PartyAmount(BaseModel):
class Meta: class Meta:
verbose_name = 'Partiya Summasi' verbose_name = 'Partiya Summasi'
verbose_name_plural = 'Partiya summalari' verbose_name_plural = 'Partiya summalari'
class DeletedParty(BaseModel):
party = models.ForeignKey(Party, on_delete=models.CASCADE, related_name='deleted_parties')
deleted_date = models.DateField(auto_now_add=True)
comment = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
return f'{self.party} deleted at {self.deleted_date}'
def save(self, *args, **kwargs):
self.party.is_deleted = True
self.party.save()
return super().save(*args, **kwargs)
class Meta:
verbose_name = "O'chirilgan partiya"
verbose_name_plural = "O'chirilgan partiyalar"

View File

@@ -2,7 +2,7 @@ from django.db import transaction
from rest_framework import serializers from rest_framework import serializers
from core.apps.orders.models import Party, PartyAmount, Order from core.apps.orders.models import Party, PartyAmount, Order, DeletedParty
from core.apps.orders.serializers.order import MultipleOrderAddSerializer, OrderListSerializer from core.apps.orders.serializers.order import MultipleOrderAddSerializer, OrderListSerializer
from core.apps.accounts.models import User from core.apps.accounts.models import User
@@ -14,6 +14,7 @@ class PartyCreateSerializer(serializers.Serializer):
payment_date = serializers.DateField() payment_date = serializers.DateField()
comment = serializers.CharField(required=False) comment = serializers.CharField(required=False)
discount = serializers.IntegerField(required=False) discount = serializers.IntegerField(required=False)
discount_currency = serializers.ChoiceField(choices=[('uzs', 'uzs'), ('usd', 'usd')])
audit = serializers.ChoiceField( audit = serializers.ChoiceField(
choices=[('CHECKED', 'tekshirildi'),('PROCESS', 'jarayonda')], required=False choices=[('CHECKED', 'tekshirildi'),('PROCESS', 'jarayonda')], required=False
) )
@@ -58,6 +59,7 @@ class PartyCreateSerializer(serializers.Serializer):
audit=validated_data.get('audit'), audit=validated_data.get('audit'),
audit_comment=validated_data.get('audit_comment'), audit_comment=validated_data.get('audit_comment'),
discount=validated_data.get('discount'), discount=validated_data.get('discount'),
discount_currency=validated_data.get('discount_currency'),
) )
party.orders.add(*created_orders) party.orders.add(*created_orders)
party.save() party.save()
@@ -98,4 +100,35 @@ class PartyListSerializer(serializers.ModelSerializer):
'id','number', 'delivery_date', 'closed_date', 'order_date', 'payment_date', 'status', 'id','number', 'delivery_date', 'closed_date', 'order_date', 'payment_date', 'status',
'payment_status', 'process', 'confirmation', 'comment', 'audit', 'audit_comment', 'payment_status', 'process', 'confirmation', 'comment', 'audit', 'audit_comment',
'party_amount' 'party_amount'
] ]
class DeletedPartyCreateSerializer(serializers.Serializer):
comment = serializers.CharField(required=False)
def validate(self, data):
party = Party.objects.filter(id=self.context.get('party_id')).first()
if not party:
raise serializers.ValidationError("Party not found")
data['party'] = party
return data
def create(self, validated_data):
with transaction.atomic():
return DeletedParty.objects.create(
comment=validated_data.get('comment'),
party=validated_data.get('party')
)
class DeletedPartyListSerializer(serializers.ModelSerializer):
party_number = serializers.IntegerField(source='party.number')
party_total_price = serializers.IntegerField(source='party.party_amount.total_price')
# mediator = serializers.SerializerMethodField(method_name='get_mediator')
class Meta:
model = DeletedParty
fields = [
'id', 'deleted_date', 'party_number', 'party_total_price',
]

View File

@@ -30,6 +30,8 @@ urlpatterns = [
path('create/', party_views.PartyCreateApiView.as_view()), path('create/', party_views.PartyCreateApiView.as_view()),
path('list/', party_views.PartyListApiView.as_view()), path('list/', party_views.PartyListApiView.as_view()),
path('<uuid:id>/', party_views.PartyDetailApiView.as_view()), path('<uuid:id>/', party_views.PartyDetailApiView.as_view()),
path('<uuid:party_id>/delete/', party_views.PartyDeleteApiView.as_view()),
path('deleted_pary/list/', party_views.DeletedPartyListApiView.as_view()),
] ]
)), )),
] ]

View File

@@ -5,7 +5,7 @@ from django_filters.rest_framework.backends import DjangoFilterBackend
from core.apps.accounts.permissions.permissions import HasRolePermission from core.apps.accounts.permissions.permissions import HasRolePermission
from core.apps.orders.serializers import party as serializers from core.apps.orders.serializers import party as serializers
from core.apps.orders.models import Order, Party, PartyAmount from core.apps.orders.models import Party, PartyAmount, DeletedParty
from core.apps.orders.filters.party import PartyFilter from core.apps.orders.filters.party import PartyFilter
@@ -13,7 +13,7 @@ class PartyCreateApiView(generics.GenericAPIView):
serializer_class = serializers.PartyCreateSerializer serializer_class = serializers.PartyCreateSerializer
queryset = Party.objects.all() queryset = Party.objects.all()
permission_classes = [HasRolePermission] permission_classes = [HasRolePermission]
required_permissions = [] required_permissions = ['party']
def post(self, request): def post(self, request):
serializer = self.serializer_class(data=request.data, context={'user': request.user}) serializer = self.serializer_class(data=request.data, context={'user': request.user})
@@ -31,9 +31,9 @@ class PartyCreateApiView(generics.GenericAPIView):
class PartyListApiView(generics.GenericAPIView): class PartyListApiView(generics.GenericAPIView):
serializer_class = serializers.PartyListSerializer serializer_class = serializers.PartyListSerializer
queryset = Party.objects.select_related('party_amount') queryset = Party.objects.select_related('party_amount').exclude(is_deleted=True)
permission_classes = [HasRolePermission] permission_classes = [HasRolePermission]
required_permissions = [] required_permissions = ['party']
filter_backends = [DjangoFilterBackend] filter_backends = [DjangoFilterBackend]
filterset_class = PartyFilter filterset_class = PartyFilter
@@ -49,7 +49,7 @@ class PartyListApiView(generics.GenericAPIView):
class PartyDetailApiView(generics.GenericAPIView): class PartyDetailApiView(generics.GenericAPIView):
permission_classes = [HasRolePermission] permission_classes = [HasRolePermission]
required_permissions = [] required_permissions = ['party']
serializer_class = serializers.PartyDetailSerializer serializer_class = serializers.PartyDetailSerializer
queryset = Party.objects.select_related('party_amount').prefetch_related('orders') queryset = Party.objects.select_related('party_amount').prefetch_related('orders')
@@ -58,4 +58,39 @@ class PartyDetailApiView(generics.GenericAPIView):
if not party: if not party:
return Response({'success': False, 'message': 'party not found'}, status=404) return Response({'success': False, 'message': 'party not found'}, status=404)
serializer = self.serializer_class(party) serializer = self.serializer_class(party)
return Response(serializer.data, status=200)
class PartyDeleteApiView(generics.GenericAPIView):
serializer_class = serializers.DeletedPartyCreateSerializer
queryset = Party.objects.all()
permission_classes = [HasRolePermission]
required_permissions = []
def post(self, request, party_id):
serializer = self.serializer_class(data=request.data, context={'party_id': party_id})
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(
{'success': True, 'message': 'Party deleted'},
status=200
)
return Response(
{'success': False, 'message': 'error while deletign party', 'error': serializer.errors},
status=400
)
class DeletedPartyListApiView(generics.GenericAPIView):
serializer_class = serializers.DeletedPartyListSerializer
queryset = DeletedParty.objects.select_related('party')
permission_classes = [HasRolePermission]
required_permissions = []
def get(self, request):
deleted_parties = DeletedParty.objects.select_related('party')
page = self.paginate_queryset(deleted_parties)
if page is not None:
serializer = self.serializer_class(page, many=True)
return self.get_paginated_response(serializer.data)
return Response(serializer.data, status=200) return Response(serializer.data, status=200)