change: change offer model, and add new api
This commit is contained in:
@@ -5,6 +5,6 @@ from core.apps.orders.models import Offer
|
||||
|
||||
@admin.register(Offer)
|
||||
class OfferAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'number', 'order']
|
||||
list_display = ['id', 'number', 'order', 'status']
|
||||
search_fields = ['phone', 'number', 'price']
|
||||
|
||||
|
||||
@@ -7,6 +7,6 @@ class OrderFilter(django_filters.FilterSet):
|
||||
class Meta:
|
||||
model = Order
|
||||
fields = [
|
||||
'wherehouse', 'project', 'project_folder', 'date'
|
||||
'wherehouse', 'project', 'project_folder', 'date',
|
||||
]
|
||||
|
||||
18
core/apps/orders/migrations/0024_offer_status.py
Normal file
18
core/apps/orders/migrations/0024_offer_status.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.2.4 on 2025-09-24 14:40
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0023_alter_party_orders'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='offer',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('CANCELLED', 'rad etildi'), ('PENDING', 'kutilmoqda'), ('CONFIRMED', 'tasdiqlandi')], default='PENDING', max_length=20),
|
||||
),
|
||||
]
|
||||
18
core/apps/orders/migrations/0025_alter_offer_status.py
Normal file
18
core/apps/orders/migrations/0025_alter_offer_status.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.2.4 on 2025-09-24 14:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0024_offer_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='offer',
|
||||
name='status',
|
||||
field=models.CharField(blank=True, choices=[('CANCELLED', 'rad etildi'), ('PENDING', 'kutilmoqda'), ('CONFIRMED', 'tasdiqlandi')], default='PENDING', max_length=20, null=True),
|
||||
),
|
||||
]
|
||||
@@ -10,15 +10,23 @@ class Offer(BaseModel):
|
||||
('UZS', 'uzs'),
|
||||
('USD', 'usd')
|
||||
)
|
||||
STATUS = (
|
||||
('CANCELLED', 'rad etildi'),
|
||||
('PENDING', 'kutilmoqda'),
|
||||
('CONFIRMED', 'tasdiqlandi'),
|
||||
)
|
||||
|
||||
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='offers')
|
||||
counterparty = models.ForeignKey(Counterparty, on_delete=models.CASCADE, related_name='offers', null=True)
|
||||
counterparty = models.ForeignKey(
|
||||
Counterparty, on_delete=models.CASCADE, related_name='offers', null=True
|
||||
)
|
||||
price = models.PositiveBigIntegerField()
|
||||
price_type = models.CharField(choices=PRICE_TYPE, default='uzs')
|
||||
phone = models.CharField(max_length=15, null=True, blank=True)
|
||||
comment = models.TextField(null=True, blank=True)
|
||||
qqs = models.BooleanField(default=False, null=True, blank=True)
|
||||
number = models.PositiveIntegerField(default=1)
|
||||
status = models.CharField(max_length=20, choices=STATUS, default='PENDING', null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.number)
|
||||
|
||||
@@ -95,7 +95,8 @@ class OffersSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Offer
|
||||
fields = [
|
||||
'id', 'number', 'price', 'price_type', 'phone', 'comment', 'qqs', 'counterparty', 'created_at'
|
||||
'id', 'number', 'price', 'price_type', 'phone', 'comment', 'qqs', 'counterparty',
|
||||
'status', 'created_at'
|
||||
]
|
||||
|
||||
def get_counterparty(self, obj):
|
||||
@@ -106,7 +107,7 @@ class OffersSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class OrderListForOfferSerializer(serializers.ModelSerializer):
|
||||
offers = OffersSerializer(many=True)
|
||||
offers = serializers.SerializerMethodField(method_name='get_offers')
|
||||
product = serializers.SerializerMethodField(method_name='get_product')
|
||||
unity = serializers.SerializerMethodField(method_name='get_unity')
|
||||
|
||||
@@ -127,4 +128,12 @@ class OrderListForOfferSerializer(serializers.ModelSerializer):
|
||||
return {
|
||||
'id': obj.unity.id,
|
||||
'value': obj.unity.value
|
||||
}
|
||||
}
|
||||
|
||||
def get_offers(self, obj):
|
||||
status = self.context.get('status')
|
||||
if status:
|
||||
offers = obj.offers.filter(status=status)
|
||||
return OffersSerializer(offers, many=True).data
|
||||
else:
|
||||
return OffersSerializer(obj.offers, many=True).data
|
||||
@@ -25,6 +25,7 @@ urlpatterns = [
|
||||
path('<uuid:id>/delete/', offer_views.OfferDeleteApiView.as_view()),
|
||||
path('<uuid:id>/update/', offer_views.OfferUpdateApiView.as_view()),
|
||||
path('bulk-delete/', offer_views.DeleteMultipleOfferApiView.as_view()),
|
||||
path('<uuid:id>/change-status/', offer_views.ChangeOfferStatusApiView.as_view()),
|
||||
]
|
||||
)),
|
||||
path('party/', include(
|
||||
|
||||
@@ -40,10 +40,14 @@ class OfferListApiView(generics.GenericAPIView):
|
||||
filterset_class = OrderFilter
|
||||
|
||||
def get(self, request):
|
||||
offer_status = request.query_params.get('status', None)
|
||||
orders = self.filter_queryset(self.get_queryset())
|
||||
page = self.paginate_queryset(orders)
|
||||
if page is not None:
|
||||
serializer = self.serializer_class(page, many=True)
|
||||
if offer_status:
|
||||
serializer = self.serializer_class(page, many=True, context={'status': offer_status})
|
||||
else:
|
||||
serializer = self.serializer_class(page, many=True)
|
||||
return self.get_paginated_response(serializer.data)
|
||||
serializer = self.serializer_class(offers, many=True)
|
||||
return Response(serializer.data, status=200)
|
||||
@@ -100,4 +104,21 @@ class DeleteMultipleOfferApiView(views.APIView):
|
||||
return Response({"detail": "offer_ids kerak"}, status=400)
|
||||
|
||||
deleted_count, _ = Offer.objects.filter(id__in=ids).delete()
|
||||
return Response({"deleted": deleted_count}, status=200)
|
||||
return Response({"deleted": deleted_count}, status=200)
|
||||
|
||||
|
||||
class ChangeOfferStatusApiView(views.APIView):
|
||||
permission_classes = [HasRolePermission]
|
||||
|
||||
def post(self, request, id):
|
||||
offer = get_object_or_404(Offer, id=id)
|
||||
status = request.data.get('status')
|
||||
if not status:
|
||||
return Response({'success': False, 'message': 'status field is required'}, status=400)
|
||||
offer.status = status
|
||||
offer.save()
|
||||
return Response(
|
||||
{'success': True, 'message': 'status updated'},
|
||||
status=200
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user