change offer list and add party model and serializer
This commit is contained in:
@@ -1,9 +1,23 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from core.apps.orders.models import Party
|
||||
from core.apps.orders.models import Party, PartyAmount
|
||||
|
||||
|
||||
class PartyAmountInline(admin.StackedInline):
|
||||
model = PartyAmount
|
||||
extra = 1
|
||||
show_change_link = True
|
||||
|
||||
|
||||
@admin.register(Party)
|
||||
class PartyAdmin(admin.ModelAdmin):
|
||||
list_display = ['mediator', 'delivery_date', 'payment_date']
|
||||
inlines = [PartyAmountInline]
|
||||
|
||||
|
||||
@admin.register(PartyAmount)
|
||||
class PartyAmountAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'total_price', 'cost_amount']
|
||||
|
||||
def has_module_permission(self, request):
|
||||
return False
|
||||
@@ -0,0 +1,70 @@
|
||||
# Generated by Django 5.2.4 on 2025-08-21 10:55
|
||||
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
import uuid
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0009_order_counterparty_order_currency_order_total_price_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='party',
|
||||
name='coled_date',
|
||||
field=models.DateField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='party',
|
||||
name='confirmation',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='party',
|
||||
name='number',
|
||||
field=models.PositiveIntegerField(default=1),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='party',
|
||||
name='order_date',
|
||||
field=models.DateField(auto_now_add=True, default=django.utils.timezone.now),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='party',
|
||||
name='payment_status',
|
||||
field=models.FloatField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='party',
|
||||
name='process',
|
||||
field=models.FloatField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='party',
|
||||
name='status',
|
||||
field=models.CharField(blank=True, choices=[('ORDERED', 'yetkazildi'), ('PROCESS', 'jarayonda')], max_length=20, null=True),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PartyAmount',
|
||||
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)),
|
||||
('total_price', models.PositiveBigIntegerField()),
|
||||
('cost_amount', models.PositiveBigIntegerField(default=0)),
|
||||
('calculated_amount', models.PositiveBigIntegerField(default=0)),
|
||||
('paid_amount', models.PositiveBigIntegerField(default=0)),
|
||||
('payment_amount', models.BigIntegerField(default=0)),
|
||||
('party', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='party_amount', to='orders.party')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Partiya Summasi',
|
||||
'verbose_name_plural': 'Partiya summalari',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -6,10 +6,23 @@ from core.apps.accounts.models import User
|
||||
|
||||
|
||||
class Party(BaseModel):
|
||||
number = models.PositiveIntegerField(default=1)
|
||||
orders = models.ManyToManyField(Order, related_name='parties', null=True, blank=True)
|
||||
mediator = models.ForeignKey(User, on_delete=models.CASCADE, related_name='parties')
|
||||
# dates
|
||||
delivery_date = models.DateField()
|
||||
coled_date = models.DateField(null=True, blank=True)
|
||||
order_date = models.DateField(auto_now_add=True)
|
||||
payment_date = models.DateField()
|
||||
|
||||
status = models.CharField(
|
||||
max_length=20, choices=[('ORDERED', 'yetkazildi'), ('PROCESS', 'jarayonda')],
|
||||
null=True, blank=True
|
||||
)
|
||||
payment_status = models.FloatField(null=True, blank=True)
|
||||
process = models.FloatField(null=True, blank=True)
|
||||
confirmation = models.BooleanField(default=False)
|
||||
|
||||
comment = models.TextField(null=True, blank=True)
|
||||
audit = models.CharField(
|
||||
max_length=20, choices=[('CHECKED', 'tekshirildi'),('PROCESS', 'jarayonda')],
|
||||
@@ -18,8 +31,34 @@ class Party(BaseModel):
|
||||
audit_comment = models.TextField(null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.mediator.full_name} {self.delivery_date}'
|
||||
return str(self.number)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.pk:
|
||||
last_party = Party.objects.order_by('number').last()
|
||||
if last_party:
|
||||
self.number = last_party.number + 1
|
||||
else:
|
||||
self.number = 1
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Partiya'
|
||||
verbose_name_plural = 'Partiyalar'
|
||||
|
||||
|
||||
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)
|
||||
payment_amount = models.BigIntegerField(default=0)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.party} amount'
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Partiya Summasi'
|
||||
verbose_name_plural = 'Partiya summalari'
|
||||
|
||||
@@ -95,3 +95,29 @@ class OffersSerializer(serializers.ModelSerializer):
|
||||
fields = [
|
||||
'id', 'number', 'price', 'price_type', 'phone', 'comment', 'qqs',
|
||||
]
|
||||
|
||||
|
||||
|
||||
class OrderListForOfferSerializer(serializers.ModelSerializer):
|
||||
offers = OffersSerializer(many=True)
|
||||
product = serializers.SerializerMethodField(method_name='get_product')
|
||||
unity = serializers.SerializerMethodField(method_name='get_unity')
|
||||
|
||||
class Meta:
|
||||
model = Order
|
||||
fields = [
|
||||
'id', 'product', 'unity', 'quantity', 'date', 'offers'
|
||||
]
|
||||
|
||||
def get_product(self, obj):
|
||||
return {
|
||||
'id': obj.product.id,
|
||||
'name': obj.product.name,
|
||||
'type': obj.product.type,
|
||||
}
|
||||
|
||||
def get_unity(self, obj):
|
||||
return {
|
||||
'id': obj.unity.id,
|
||||
'value': obj.unity.value
|
||||
}
|
||||
@@ -13,7 +13,8 @@ from core.apps.wherehouse.serializers.wherehouse import WhereHouseListSerializer
|
||||
# projects
|
||||
from core.apps.projects.models import Project, ProjectFolder
|
||||
from core.apps.projects.serializers.project import ProjectListSerializer, ProjectFolderListSerializer
|
||||
|
||||
# counterparty
|
||||
from core.apps.counterparty.models import Counterparty
|
||||
|
||||
|
||||
class OrderCreateSerializer(serializers.Serializer):
|
||||
@@ -64,7 +65,6 @@ class MultipleOrderCreateSerializer(serializers.Serializer):
|
||||
|
||||
def create(self, validated_data):
|
||||
with transaction.atomic():
|
||||
print(self.context['user'])
|
||||
resources = validated_data.pop('resources')
|
||||
common_date = validated_data.get('date')
|
||||
orders = []
|
||||
@@ -114,3 +114,46 @@ class OrderUpdateSerializer(serializers.ModelSerializer):
|
||||
fields = [
|
||||
'product', 'unity', 'quantity', 'project', 'project_folder', 'wherehouse', 'date',
|
||||
]
|
||||
|
||||
|
||||
class MultipleOrderAddSerializer(serializers.Serializer):
|
||||
product_id = serializers.UUIDField()
|
||||
unity_id = serializers.UUIDField()
|
||||
project_folder_id = serializers.UUIDField(required=False)
|
||||
project_id = serializers.UUIDField(required=False)
|
||||
counterparty_id = serializers.UUIDField()
|
||||
wherehouse_id = serializers.UUIDField()
|
||||
|
||||
quantity = serializers.IntegerField()
|
||||
unit_amount = serializers.IntegerField()
|
||||
currency = serializers.ChoiceField(choices=[('uzs', 'uzs'), ('usd', 'usd')])
|
||||
amount = serializers.UUIDField()
|
||||
|
||||
def validate(self, data):
|
||||
product = Product.objects.filter(id=data['product_id']).first()
|
||||
if not product:
|
||||
raise serializers.ValidationError('product not found')
|
||||
unity = Unity.objects.filter(id=data['unity_id']).first()
|
||||
if not unity:
|
||||
raise serializers.ValidationError("Unity not found")
|
||||
wherehouse = WhereHouse.objects.filter(id=data['wherehouse_id'])
|
||||
if not wherehouse:
|
||||
raise serializers.ValidationError("WhereHouse not found")
|
||||
counterparty = Counterparty.objects.filter(id=data['counterparty_id']).first()
|
||||
if not counterparty:
|
||||
raise serializers.ValidationError("Counterparty not found")
|
||||
if data.get('project_id'):
|
||||
project = Project.objects.filter(id=data.get('project_id')).first()
|
||||
if not project:
|
||||
raise serializers.ValidationError("Project not found")
|
||||
data['project'] = project
|
||||
if data.get('project_folder_id'):
|
||||
project_folder = ProjectFolder.objects.filter(id=data.get('project_folder_id')).first()
|
||||
if not project_folder:
|
||||
raise serializers.ValidationError("Project Folder not found")
|
||||
data['project_folder'] = project_folder
|
||||
data['product'] = product
|
||||
data['unity'] = unity
|
||||
data['wherehouse'] = wherehouse
|
||||
data['counterparty'] = counterparty
|
||||
return data
|
||||
42
core/apps/orders/serializers/party.py
Normal file
42
core/apps/orders/serializers/party.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from django.db import transaction
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from core.apps.orders.models import Party, PartyAmount, Order
|
||||
from core.apps.orders.serializers.order import MultipleOrderAddSerializer
|
||||
from core.apps.accounts.models import User
|
||||
|
||||
|
||||
class PartyCreateSerializer(serializers.Serializer):
|
||||
resources = MultipleOrderAddSerializer(many=True)
|
||||
mediator_id = serializers.UUIDField()
|
||||
delivery_date = serializers.DateField()
|
||||
payment_date = serializers.DateField()
|
||||
comment = serializers.CharField(required=False)
|
||||
|
||||
audit = serializers.ChoiceField(
|
||||
choices=[('CHECKED', 'tekshirildi'),('PROCESS', 'jarayonda')], required=False
|
||||
)
|
||||
audit_comment = serializers.CharField(required=False)
|
||||
|
||||
def validate(self, data):
|
||||
user = User.objects.filter(id=data['mediator_id']).first()
|
||||
if not user:
|
||||
raise serializers.ValidationError("User not found")
|
||||
data['user'] = user
|
||||
return data
|
||||
|
||||
def create(self, validated_data):
|
||||
with transaction.atomic():
|
||||
resources = validated_data.pop('resources')
|
||||
orders = []
|
||||
for resource in resources:
|
||||
orders.append(Order(
|
||||
product=resource['product'],
|
||||
unity=resource['unity'],
|
||||
project_folder=resource.get('project_folder'),
|
||||
project=resource.get('project'),
|
||||
counterparty=resource.get('counterparty'),
|
||||
wherehouse=resource.get('wherehouse'),
|
||||
|
||||
))
|
||||
@@ -8,8 +8,8 @@ from django_filters.rest_framework.backends import DjangoFilterBackend
|
||||
from core.apps.shared.paginations.custom import PageNumberPagination
|
||||
from core.apps.accounts.permissions.permissions import HasRolePermission
|
||||
from core.apps.orders.serializers import offer as serializers
|
||||
from core.apps.orders.models import Offer
|
||||
from core.apps.orders.filters.offer import OfferFilter
|
||||
from core.apps.orders.models import Offer, Order
|
||||
from core.apps.orders.filters.order import OrderFilter
|
||||
|
||||
|
||||
class OffersCreateApiView(generics.GenericAPIView):
|
||||
@@ -33,15 +33,15 @@ class OffersCreateApiView(generics.GenericAPIView):
|
||||
|
||||
class OfferListApiView(generics.GenericAPIView):
|
||||
permission_classes = [HasRolePermission]
|
||||
queryset = Offer.objects.select_related('order')
|
||||
queryset = Order.objects.select_related('product', 'unity').prefetch_related('offers')
|
||||
required_permissions = ['offer']
|
||||
serializer_class = serializers.OfferListSerializer
|
||||
serializer_class = serializers.OrderListForOfferSerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_class = OfferFilter
|
||||
filterset_class = OrderFilter
|
||||
|
||||
def get(self, request):
|
||||
offers = self.filter_queryset(self.get_queryset())
|
||||
page = self.paginate_queryset(offers)
|
||||
orders = self.filter_queryset(self.get_queryset())
|
||||
page = self.paginate_queryset(orders)
|
||||
if page is not None:
|
||||
serializer = self.serializer_class(page, many=True)
|
||||
return self.get_paginated_response(serializer.data)
|
||||
|
||||
Reference in New Issue
Block a user