diff --git a/core/apps/dashboard/serializers/order.py b/core/apps/dashboard/serializers/order.py new file mode 100644 index 0000000..2d6bbc7 --- /dev/null +++ b/core/apps/dashboard/serializers/order.py @@ -0,0 +1,147 @@ +# django +from django.db import transaction +from django.core.files.base import ContentFile + +# rest framework +from rest_framework import serializers + +# orders +from core.apps.orders.models import Order, OrderItem +from core.apps.orders.serializers.order_item import OrderItemSerializer +# shared +from core.apps.shared.models import Factory +# accounts +from core.apps.accounts.models import User +# services +from core.services.generate_pdf import generate_order_pdf +from core.services.send_telegram_msg import send_to_telegram + + +class AdminOrderCreateSerializer(serializers.Serializer): + factory_id = serializers.IntegerField() + paid_price = serializers.DecimalField(max_digits=15, decimal_places=2) + total_price = serializers.DecimalField(max_digits=15, decimal_places=2) + advance = serializers.FloatField() + employee_name = serializers.CharField() + user_id = serializers.IntegerField() + items = OrderItemSerializer(many=True) + + def validate(self, data): + user = User.objects.filter(id=data['user_id']).first() + if not user: + raise serializers.ValidationError({"user": "user not found"}) + factory = Factory.objects.filter(id=data['factory_id']).first() + if not factory: + raise serializers.ValidationError({"factory_id": "Factory not found"}) + data['factory'] = factory + data['user'] = user + return data + + def create(self, validated_data): + with transaction.atomic(): + user = validated_data.get('user') + order = Order.objects.create( + factory=validated_data.get('factory'), + paid_price=validated_data.get('paid_price'), + advance=validated_data.get('advance'), + employee_name=validated_data.get('employee_name'), + total_price=validated_data.get('total_price'), + user=user + ) + order_items = [] + for order_item in validated_data.get('items'): + order_items.append(OrderItem( + product=order_item.get('product'), + order=order, + quantity=order_item.get('quantity'), + total_price=order_item.get('total_price'), + )) + OrderItem.objects.bulk_create(order_items) + + # generate pdf file + pdf_buffer = generate_order_pdf(order.id) + + file_name = f"order_{order.id}.pdf" + order.file.save(file_name, ContentFile(pdf_buffer.getvalue()), save=False) + + order.save(update_fields=["file"]) + + # send to telegram + send_to_telegram(user.telegram_id, order.id) + return order + + +class AdminOrderListSerializer(serializers.ModelSerializer): + order_items = OrderItemSerializer(many=True) + factory = serializers.SerializerMethodField(method_name='get_factory') + user = serializers.SerializerMethodField(method_name='get_user') + + class Meta: + model = Order + fields = [ + 'id', 'factory', 'total_price', 'paid_price', 'advance', 'employee_name', + 'overdue_price', 'order_items', 'file', 'user' + ] + + def get_user(self, obj): + return { + "id": obj.user.id, + "first_name": obj.user.first_name, + "last_name": obj.user.last_name, + } + + def get_factory(self, obj): + return { + 'id': obj.factory.id, + 'name': obj.factory.name, + } + + +class AdminOrderUpdateSerializer(serializers.Serializer): + factory_id = serializers.IntegerField() + paid_price = serializers.DecimalField(max_digits=15, decimal_places=2) + total_price = serializers.DecimalField(max_digits=15, decimal_places=2) + advance = serializers.FloatField() + employee_name = serializers.CharField() + user_id = serializers.IntegerField() + items = OrderItemSerializer(many=True) + + def validate(self, data): + user = User.objects.filter(id=data['user_id']).first() + if not user: + raise serializers.ValidationError({"user": "user not found"}) + + factory = Factory.objects.filter(id=data['factory_id']).first() + if not factory: + raise serializers.ValidationError({"factory_id": "Factory not found"}) + + data['factory'] = factory + data['user'] = user + return data + + def update(self, instance, validated_data): + with transaction.atomic(): + instance.factory = validated_data.get('factory', instance.factory) + instance.paid_price = validated_data.get('paid_price', instance.paid_price) + instance.total_price = validated_data.get('total_price', instance.total_price) + instance.advance = validated_data.get('advance', instance.advance) + instance.employee_name = validated_data.get('employee_name', instance.employee_name) + instance.user = validated_data.get('user', instance.user) + instance.save() + + OrderItem.objects.filter(order=instance).delete() + + order_items = [] + for order_item_data in validated_data.get('items', []): + order_items.append(OrderItem( + product=order_item_data.get('product'), + order=instance, + quantity=order_item_data.get('quantity'), + total_price=order_item_data.get('total_price'), + )) + + if order_items: + OrderItem.objects.bulk_create(order_items) + + return instance + \ No newline at end of file diff --git a/core/apps/dashboard/urls.py b/core/apps/dashboard/urls.py index ae6d266..1f738cf 100644 --- a/core/apps/dashboard/urls.py +++ b/core/apps/dashboard/urls.py @@ -25,6 +25,8 @@ from core.apps.dashboard.views.product import ProductViewSet from core.apps.dashboard.views.factory import FactoryViewSet # tour plan from core.apps.dashboard.views.tour_plan import TourPlanViewSet +# order +from core.apps.dashboard.views.order import OrderViewSet urlpatterns = [ @@ -68,6 +70,7 @@ router.register("pharmacy", PharmacyViewSet) router.register("product", ProductViewSet) router.register("factory", FactoryViewSet) router.register("tour_plan", TourPlanViewSet) +router.register("order", OrderViewSet) urlpatterns += router.urls \ No newline at end of file diff --git a/core/apps/dashboard/views/order.py b/core/apps/dashboard/views/order.py new file mode 100644 index 0000000..f436394 --- /dev/null +++ b/core/apps/dashboard/views/order.py @@ -0,0 +1,136 @@ +# django +from django.db.models import Q + +# rest framework +from rest_framework import viewsets, permissions +from rest_framework.decorators import action + +# drf yasg +from drf_yasg import openapi +from drf_yasg.utils import swagger_auto_schema + +# dashboard +from core.apps.dashboard.serializers import order as serializers +# orders +from core.apps.orders.models import Order +# shared +from core.apps.shared.utils.response_mixin import ResponseMixin + + +class OrderViewSet(viewsets.GenericViewSet, ResponseMixin): + permission_classes = [permissions.IsAdminUser] + queryset = Order.objects.all() + + def get_serializer_class(self): + if self.action == "post": + return serializers.AdminOrderCreateSerializer + elif self.action in ("patch", "put"): + return serializers.AdminOrderUpdateSerializer + else: + return serializers.AdminOrderListSerializer + + @swagger_auto_schema( + tags=['Admin Orders'], + ) + @action(detail=False, methods=['get'], url_path="list") + def get(self, request): + try: + queryset = self.queryset.order_by('-id') + + page = self.paginate_queryset(queryset) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.success_response( + data=self.get_paginated_response(serializer.data).data, + message='malumotlar fetch qilindi' + ) + serializer = self.get_serializer(queryset, many=True) + return self.success_response( + data=serializer.data, + message='malumotlar fetch qilindi' + ) + except Exception as e: + return self.error_response( + data=str(e), + message="xatolik" + ) + + @swagger_auto_schema( + tags=['Admin Orders'] + ) + @action(detail=False, methods=['post'], url_path='create') + def post(self, request): + try: + serializer = self.get_serializer(data=request.data) + if serializer.is_valid(): + obj = serializer.save() + return self.success_response( + data=serializers.AdminOrderListSerializer(obj).data, + message='malumot qoshildi' + ) + return self.failure_response( + data=serializer.errors, + message='malumot qoshilmadi' + ) + except Exception as e: + return self.error_response( + data=str(e), + message="xatolik" + ) + + @swagger_auto_schema( + tags=['Admin Orders'] + ) + @action(detail=True, methods=['patch'], url_path='update') + def update_doctor(self, request, pk=None): + try: + order = Order.objects.filter(id=pk).first() + if not order: + return self.failure_response( + data={}, + message="order topilmadi", + status_code=404 + ) + serializer = self.get_serializer(data=request.data, instance=order) + if serializer.is_valid(): + obj = serializer.save() + return self.success_response( + data=serializers.AdminOrderListSerializer(obj).data, + message='malumot tahrirlandi' + ) + return self.failure_response( + data=serializer.errors, + message='malumot tahrirlandi' + ) + except Exception as e: + return self.error_response( + data=str(e), + message="xatolik" + ) + + @swagger_auto_schema( + tags=['Admin Orders'] + ) + @action(detail=True, methods=['delete'], url_path='delete') + def delete(self, request, pk=None): + try: + order = Order.objects.filter(id=pk).first() + if not order: + return self.failure_response( + data={}, + message="order topilmadi", + status_code=404 + ) + order.delete() + return self.success_response( + data={}, + message='malumot ochirildi', + status_code=204 + ) + except Exception as e: + return self.error_response( + data=str(e), + message="xatolik" + ) + + \ No newline at end of file