change: change counterparty model and add create api

This commit is contained in:
behruz-dev
2025-08-30 15:41:29 +05:00
parent 4a2f02f5ac
commit 392fc13f8e
7 changed files with 216 additions and 25 deletions

View File

@@ -1,9 +1,15 @@
from django.contrib import admin from django.contrib import admin
from core.apps.counterparty.models import Counterparty from core.apps.counterparty.models import Counterparty, CounterpartyFolder
@admin.register(Counterparty) @admin.register(Counterparty)
class CounterpartyAdmin(admin.ModelAdmin): class CounterpartyAdmin(admin.ModelAdmin):
list_display = ['id', 'name', 'person'] list_display = ['id', 'name', 'phone', 'type', 'inn']
@admin.register(CounterpartyFolder)
class CounterpartyFolderAdmin(admin.ModelAdmin):
list_display = ['id', 'name']
list_filter = ['name']

View File

@@ -0,0 +1,91 @@
# Generated by Django 5.2.4 on 2025-08-30 15:11
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counterparty', '0001_initial'),
('shared', '0002_usdcourse'),
]
operations = [
migrations.CreateModel(
name='CounterpartyFolder',
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)),
('name', models.CharField(max_length=200)),
],
options={
'verbose_name': 'Kontragent papkasi',
'verbose_name_plural': 'Kontragent papkalari',
},
),
migrations.RenameField(
model_name='counterparty',
old_name='description',
new_name='comment',
),
migrations.RemoveField(
model_name='counterparty',
name='person',
),
migrations.RemoveField(
model_name='counterparty',
name='start_date',
),
migrations.RemoveField(
model_name='counterparty',
name='status',
),
migrations.AddField(
model_name='counterparty',
name='balance',
field=models.PositiveBigIntegerField(blank=True, null=True),
),
migrations.AddField(
model_name='counterparty',
name='balance_currency',
field=models.CharField(blank=True, choices=[('usd', 'usd'), ('uzs', 'uzs')], max_length=3, null=True),
),
migrations.AddField(
model_name='counterparty',
name='balance_date',
field=models.DateField(blank=True, null=True),
),
migrations.AddField(
model_name='counterparty',
name='district',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='counterparties', to='shared.district'),
),
migrations.AddField(
model_name='counterparty',
name='inn',
field=models.CharField(max_length=20, null=True),
),
migrations.AddField(
model_name='counterparty',
name='phone',
field=models.CharField(max_length=15, null=True),
),
migrations.AddField(
model_name='counterparty',
name='region',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='counterparties', to='shared.region'),
),
migrations.AlterField(
model_name='counterparty',
name='type',
field=models.CharField(choices=[('SUPPLIER', "ta'minotchi"), ('WORKER', 'ishchi')], default='SUPPLIER', max_length=20),
),
migrations.AddField(
model_name='counterparty',
name='folder',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='counterparties', to='counterparty.counterpartyfolder'),
),
]

View File

@@ -1,18 +1,47 @@
from django.db import models from django.db import models
from core.apps.shared.models import BaseModel from core.apps.shared.models import BaseModel, Region, District
from core.apps.accounts.models import User from core.apps.accounts.models import User
class Counterparty(BaseModel): class CounterpartyFolder(BaseModel):
name = models.CharField(max_length=200) name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
start_date = models.DateField() def __str__(self):
status = models.CharField( return self.name
max_length=20, choices=[('active', 'active'), ('inactive', 'inactive')], default='active'
class Meta:
verbose_name = 'Kontragent papkasi'
verbose_name_plural = 'Kontragent papkalari'
class Counterparty(BaseModel):
TYPE = (
('SUPPLIER', "ta'minotchi"),
('WORKER', 'ishchi')
) )
type = models.CharField(max_length=20, choices=[('supplier', 'supplier')])
person = models.ForeignKey(User, on_delete=models.CASCADE, related_name='counterparties') inn = models.CharField(max_length=20, null=True)
name = models.CharField(max_length=200)
phone = models.CharField(max_length=15, null=True)
type = models.CharField(max_length=20, choices=TYPE, default='SUPPLIER')
folder = models.ForeignKey(
CounterpartyFolder, on_delete=models.SET_NULL, null=True, blank=True,
related_name='counterparties',
)
region = models.ForeignKey(
Region, on_delete=models.SET_NULL, null=True, blank=True, related_name='counterparties'
)
district = models.ForeignKey(
District, on_delete=models.SET_NULL, null=True, blank=True, related_name='counterparties'
)
balance = models.PositiveBigIntegerField(null=True, blank=True)
balance_currency = models.CharField(
max_length=3, choices=[('usd', 'usd'), ('uzs', 'uzs')], null=True, blank=True
)
balance_date = models.DateField(null=True, blank=True)
comment = models.TextField(null=True, blank=True)
def __str__(self): def __str__(self):
return self.name return self.name

View File

@@ -1,22 +1,68 @@
from django.db import transaction
from rest_framework import serializers from rest_framework import serializers
from core.apps.accounts.serializers.user import UserListSerializer from core.apps.counterparty.models import Counterparty, CounterpartyFolder
from core.apps.counterparty.models import Counterparty from core.apps.shared.models import Region, District
class CounterpartyListSerializer(serializers.ModelSerializer):
class Meta:
model = Counterparty
fields = [
'id', 'inn', 'name', 'phone', 'type', 'folder', 'type', 'region', 'district',
'balance', 'balance_currency', 'balance_date', 'comment',
]
class CounterpartySerializer(serializers.ModelSerializer): class CounterpartySerializer(serializers.ModelSerializer):
person = UserListSerializer()
class Meta: class Meta:
model = Counterparty model = Counterparty
fields = [ fields = [
'id', 'name', 'type', 'status', 'description', 'start_date', 'person' 'id', 'name'
] ]
class CounterpartyListPartySerializer(serializers.ModelSerializer): class CounterpartyCreateSerializer(serializers.Serializer):
class Meta: inn = serializers.CharField()
model = Counterparty name = serializers.CharField()
fields = [ phone = serializers.CharField()
'id', 'name', type = serializers.ChoiceField(choices=Counterparty.TYPE, required=False)
] folder_id = serializers.UUIDField(required=False)
region_id = serializers.UUIDField(required=False)
district_id = serializers.UUIDField(required=False)
balance = serializers.IntegerField(required=False)
balance_date = serializers.DateField(required=False)
comment = serializers.CharField(required=False)
def validate(self, data):
if data.get('folder_id'):
folder = CounterpartyFolder.objects.filter(id=data.get('folder_id')).first()
if not folder:
raise serializers.ValidationError("Counterparty Folder not found")
data['folder'] = folder
if data.get('region_id'):
region = Region.objects.filter(id=data.get('region_id')).first()
if not region:
raise serializers.ValidationError("Region not found")
data['region'] = region
if data.get('district_id'):
district = District.objects.filter(id=data.get('district_id')).first()
if not district:
raise serializers.ValidationError("District not found")
return data
def create(self, validated_data):
with transaction.atomic():
return Counterparty.objects.create(
inn=validated_data.get('inn'),
name=validated_data.get('name'),
phone=validated_data.get('phone'),
type=validated_data.get('type'),
folder=validated_data.get('folder'),
region=validated_data.get('region'),
district=validated_data.get('district'),
balance=validated_data.get('balance'),
balance_date=validated_data.get('balance_date'),
comment=validated_data.get('comment'),
)

View File

@@ -7,6 +7,7 @@ urlpatterns = [
path('counterparty/', include( path('counterparty/', include(
[ [
path('list/', cp_views.CounterpartyListApiView.as_view()), path('list/', cp_views.CounterpartyListApiView.as_view()),
path('create/', cp_views.CounterpartyCreateApiView.as_view()),
] ]
)) ))
] ]

View File

@@ -8,10 +8,28 @@ from core.apps.counterparty.serializers import counterparty as serializers
class CounterpartyListApiView(generics.ListAPIView): class CounterpartyListApiView(generics.ListAPIView):
serializer_class = serializers.CounterpartySerializer serializer_class = serializers.CounterpartyListSerializer
queryset = Counterparty.objects.select_related('person') queryset = Counterparty.objects.all()
pagination_class = [HasRolePermission] pagination_class = [HasRolePermission]
required_permissions = [] required_permissions = []
pagination_class = CustomPageNumberPagination pagination_class = CustomPageNumberPagination
class CounterpartyCreateApiView(generics.GenericAPIView):
serializer_class = serializers.CounterpartyCreateSerializer
queryset = Counterparty.objects.all()
permission_classes = [HasRolePermission]
required_permissions = []
def post(self, request):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(
{'success': True, 'message': 'Conterparty Created'},
status=201
)
return Response(
{'success': False, 'message': serializer.errors},
status=400
)

View File

@@ -5,7 +5,7 @@ from rest_framework import serializers
from core.apps.orders.models import Party, PartyAmount, Order, DeletedParty 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
from core.apps.counterparty.serializers.counterparty import CounterpartyListPartySerializer from core.apps.counterparty.serializers.counterparty import CounterpartySerializer
from core.apps.orders.tasks.order import create_inventory from core.apps.orders.tasks.order import create_inventory
from core.apps.shared.models import UsdCourse from core.apps.shared.models import UsdCourse
from core.apps.products.models import Product, Unity from core.apps.products.models import Product, Unity
@@ -137,7 +137,7 @@ class PartyListSerializer(serializers.ModelSerializer):
{"id": c["counterparty__id"], "name": c["counterparty__name"]} {"id": c["counterparty__id"], "name": c["counterparty__name"]}
for c in counterparties for c in counterparties
] ]
return CounterpartyListPartySerializer(counterparties, many=True).data return CounterpartySerializer(counterparties, many=True).data
class DeletedPartyCreateSerializer(serializers.Serializer): class DeletedPartyCreateSerializer(serializers.Serializer):