change offer list and add party model and serializer
This commit is contained in:
@@ -1,9 +1,23 @@
|
|||||||
from django.contrib import admin
|
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)
|
@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']
|
||||||
|
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):
|
class Party(BaseModel):
|
||||||
|
number = models.PositiveIntegerField(default=1)
|
||||||
orders = models.ManyToManyField(Order, related_name='parties', null=True, blank=True)
|
orders = models.ManyToManyField(Order, related_name='parties', null=True, blank=True)
|
||||||
mediator = models.ForeignKey(User, on_delete=models.CASCADE, related_name='parties')
|
mediator = models.ForeignKey(User, on_delete=models.CASCADE, related_name='parties')
|
||||||
|
# dates
|
||||||
delivery_date = models.DateField()
|
delivery_date = models.DateField()
|
||||||
|
coled_date = models.DateField(null=True, blank=True)
|
||||||
|
order_date = models.DateField(auto_now_add=True)
|
||||||
payment_date = models.DateField()
|
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)
|
comment = models.TextField(null=True, blank=True)
|
||||||
audit = models.CharField(
|
audit = models.CharField(
|
||||||
max_length=20, choices=[('CHECKED', 'tekshirildi'),('PROCESS', 'jarayonda')],
|
max_length=20, choices=[('CHECKED', 'tekshirildi'),('PROCESS', 'jarayonda')],
|
||||||
@@ -18,8 +31,34 @@ class Party(BaseModel):
|
|||||||
audit_comment = models.TextField(null=True, blank=True)
|
audit_comment = models.TextField(null=True, blank=True)
|
||||||
|
|
||||||
def __str__(self):
|
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:
|
class Meta:
|
||||||
verbose_name = 'Partiya'
|
verbose_name = 'Partiya'
|
||||||
verbose_name_plural = 'Partiyalar'
|
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'
|
||||||
|
|
||||||
@@ -94,4 +94,30 @@ class OffersSerializer(serializers.ModelSerializer):
|
|||||||
model = Offer
|
model = Offer
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'number', 'price', 'price_type', 'phone', 'comment', 'qqs',
|
'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
|
# projects
|
||||||
from core.apps.projects.models import Project, ProjectFolder
|
from core.apps.projects.models import Project, ProjectFolder
|
||||||
from core.apps.projects.serializers.project import ProjectListSerializer, ProjectFolderListSerializer
|
from core.apps.projects.serializers.project import ProjectListSerializer, ProjectFolderListSerializer
|
||||||
|
# counterparty
|
||||||
|
from core.apps.counterparty.models import Counterparty
|
||||||
|
|
||||||
|
|
||||||
class OrderCreateSerializer(serializers.Serializer):
|
class OrderCreateSerializer(serializers.Serializer):
|
||||||
@@ -64,7 +65,6 @@ class MultipleOrderCreateSerializer(serializers.Serializer):
|
|||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
print(self.context['user'])
|
|
||||||
resources = validated_data.pop('resources')
|
resources = validated_data.pop('resources')
|
||||||
common_date = validated_data.get('date')
|
common_date = validated_data.get('date')
|
||||||
orders = []
|
orders = []
|
||||||
@@ -113,4 +113,47 @@ class OrderUpdateSerializer(serializers.ModelSerializer):
|
|||||||
model = Order
|
model = Order
|
||||||
fields = [
|
fields = [
|
||||||
'product', 'unity', 'quantity', 'project', 'project_folder', 'wherehouse', 'date',
|
'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.shared.paginations.custom import PageNumberPagination
|
||||||
from core.apps.accounts.permissions.permissions import HasRolePermission
|
from core.apps.accounts.permissions.permissions import HasRolePermission
|
||||||
from core.apps.orders.serializers import offer as serializers
|
from core.apps.orders.serializers import offer as serializers
|
||||||
from core.apps.orders.models import Offer
|
from core.apps.orders.models import Offer, Order
|
||||||
from core.apps.orders.filters.offer import OfferFilter
|
from core.apps.orders.filters.order import OrderFilter
|
||||||
|
|
||||||
|
|
||||||
class OffersCreateApiView(generics.GenericAPIView):
|
class OffersCreateApiView(generics.GenericAPIView):
|
||||||
@@ -33,15 +33,15 @@ class OffersCreateApiView(generics.GenericAPIView):
|
|||||||
|
|
||||||
class OfferListApiView(generics.GenericAPIView):
|
class OfferListApiView(generics.GenericAPIView):
|
||||||
permission_classes = [HasRolePermission]
|
permission_classes = [HasRolePermission]
|
||||||
queryset = Offer.objects.select_related('order')
|
queryset = Order.objects.select_related('product', 'unity').prefetch_related('offers')
|
||||||
required_permissions = ['offer']
|
required_permissions = ['offer']
|
||||||
serializer_class = serializers.OfferListSerializer
|
serializer_class = serializers.OrderListForOfferSerializer
|
||||||
filter_backends = [DjangoFilterBackend]
|
filter_backends = [DjangoFilterBackend]
|
||||||
filterset_class = OfferFilter
|
filterset_class = OrderFilter
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
offers = self.filter_queryset(self.get_queryset())
|
orders = self.filter_queryset(self.get_queryset())
|
||||||
page = self.paginate_queryset(offers)
|
page = self.paginate_queryset(orders)
|
||||||
if page is not None:
|
if page is not None:
|
||||||
serializer = self.serializer_class(page, many=True)
|
serializer = self.serializer_class(page, many=True)
|
||||||
return self.get_paginated_response(serializer.data)
|
return self.get_paginated_response(serializer.data)
|
||||||
|
|||||||
Reference in New Issue
Block a user