diff --git a/config/conf/rest_framework.py b/config/conf/rest_framework.py index 2c5ed1b..b2837b3 100644 --- a/config/conf/rest_framework.py +++ b/config/conf/rest_framework.py @@ -1,7 +1,9 @@ REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": [ 'rest_framework.authentication.SessionAuthentication', - 'rest_framework.authentication.BasicAuthentication' + 'rest_framework.authentication.BasicAuthentication', 'rest_framework_simplejwt.authentication.JWTAuthentication', - ] + ], + 'DEFAULT_PAGINATION_CLASS': 'core.apps.shared.paginations.custom.CustomPageNumberPagination', + 'PAGE_SIZE': 10 } \ No newline at end of file diff --git a/core/apps/company/views/company.py b/core/apps/company/views/company.py index 853ddba..4d395ee 100644 --- a/core/apps/company/views/company.py +++ b/core/apps/company/views/company.py @@ -3,7 +3,7 @@ from rest_framework.response import Response from core.apps.company.models import Company from core.apps.company.serializers import company as serializers - +from core.apps.shared.paginations.custom import CustomPageNumberPagination from core.apps.accounts.permissions.permissions import HasRolePermission @@ -12,6 +12,7 @@ class CompanyListApiView(generics.ListAPIView): queryset = Company.objects.all() permission_classes = [HasRolePermission] required_permissions = [] + pagination_class = CustomPageNumberPagination class CompanyDetailApiView(generics.RetrieveAPIView): diff --git a/core/apps/orders/migrations/0002_order_employee_order_status.py b/core/apps/orders/migrations/0002_order_employee_order_status.py new file mode 100644 index 0000000..5837ce6 --- /dev/null +++ b/core/apps/orders/migrations/0002_order_employee_order_status.py @@ -0,0 +1,26 @@ +# Generated by Django 5.2.4 on 2025-08-01 16:41 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('orders', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='employee', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='orders', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='order', + name='status', + field=models.CharField(choices=[('NEW', 'yangi'), ('CANCELLED', 'bekor qilindi'), ('ACCEPTED', 'qabul qilindi')], default='NEW', max_length=20), + ), + ] diff --git a/core/apps/orders/models/order.py b/core/apps/orders/models/order.py index c6726c6..5e621aa 100644 --- a/core/apps/orders/models/order.py +++ b/core/apps/orders/models/order.py @@ -9,6 +9,12 @@ from core.apps.wherehouse.models import WhereHouse class Order(BaseModel): + STATUS = ( + ('NEW', 'yangi'), + ('CANCELLED', "bekor qilindi"), + ('ACCEPTED', 'qabul qilindi'), + ) + product = models.ForeignKey( Product, on_delete=models.CASCADE, related_name='orders' ) @@ -26,7 +32,9 @@ class Order(BaseModel): ) date = models.DateField() quantity = models.PositiveBigIntegerField(default=1) - + status = models.CharField(max_length=20, choices=STATUS, default="NEW") + employee = models.ForeignKey(User, on_delete=models.CASCADE, related_name='orders', null=True) + def __str__(self): return f"{self.product} {self.unity} quantity order" diff --git a/core/apps/orders/serializers/order.py b/core/apps/orders/serializers/order.py index d3339d8..2ef3141 100644 --- a/core/apps/orders/serializers/order.py +++ b/core/apps/orders/serializers/order.py @@ -3,9 +3,20 @@ from django.db import transaction from rest_framework import serializers from core.apps.orders.models import Order, OrderApplication +# products from core.apps.products.models import Product, Unity +from core.apps.products.serializers.product import ProductListSerializer +from core.apps.products.serializers.unity import UnityListSerializer +# wherehouse from core.apps.wherehouse.models import WhereHouse +from core.apps.wherehouse.serializers.wherehouse import WhereHouseListSerializer +# projects from core.apps.projects.models import Project, ProjectDepartment +from core.apps.projects.serializers.project import ( + ProjectListSerializer, + ProjectDepartmentListSerializer +) + class OrderCreateSerializer(serializers.Serializer): @@ -48,28 +59,16 @@ class OrderCreateSerializer(serializers.Serializer): return data -class OrderApplicationCreateSerializer(serializers.Serializer): - orders = serializers.ListSerializer(child=OrderCreateSerializer()) +class OrderListSerializer(serializers.ModelSerializer): + product = ProductListSerializer() + unity = UnityListSerializer() + project = ProjectListSerializer() + project_department = ProjectDepartmentListSerializer() + wherehouse = WhereHouseListSerializer() - def create(self, validated_data): - employee = self.context.get('user') - orders_data = validated_data.pop('orders') - application = OrderApplication.objects.create( - employee=employee, status="NEW" - ) - - order_objs = [] - for order_data in orders_data: - order_objs.append(Order( - product=order_data['product'], - unity=order_data['unity'], - quantity=order_data['quantity'], - wherehouse=order_data['wherehouse'], - project=order_data['project'], - project_department=order_data.get('project_department'), - date=order_data['date'] - )) - - created_orders = Order.objects.bulk_create(order_objs) - application.orders.add(*created_orders) - return application \ No newline at end of file + class Meta: + model = Order + fields = [ + 'id', 'product', 'unity', 'quantity', 'project', 'project_department', + 'wherehouse', 'date', 'status', 'employee' + ] \ No newline at end of file diff --git a/core/apps/orders/serializers/order_application.py b/core/apps/orders/serializers/order_application.py new file mode 100644 index 0000000..988a705 --- /dev/null +++ b/core/apps/orders/serializers/order_application.py @@ -0,0 +1,41 @@ +from rest_framework import serializers + +from core.apps.orders.models import OrderApplication, Order +from core.apps.orders.serializers.order import OrderCreateSerializer, OrderListSerializer + + +class OrderApplicationCreateSerializer(serializers.Serializer): + orders = serializers.ListSerializer(child=OrderCreateSerializer()) + + def create(self, validated_data): + employee = self.context.get('user') + orders_data = validated_data.pop('orders') + application = OrderApplication.objects.create( + employee=employee, status="NEW" + ) + + order_objs = [] + for order_data in orders_data: + order_objs.append(Order( + product=order_data['product'], + unity=order_data['unity'], + quantity=order_data['quantity'], + wherehouse=order_data['wherehouse'], + project=order_data['project'], + project_department=order_data.get('project_department'), + date=order_data['date'] + )) + + created_orders = Order.objects.bulk_create(order_objs) + application.orders.add(*created_orders) + return application + + +class OrderApplicationListSerializer(serializers.ModelSerializer): + orders = OrderListSerializer(many=True) + + class Meta: + model = OrderApplication + fields = [ + 'id', 'employee', 'status', 'orders' + ] \ No newline at end of file diff --git a/core/apps/orders/urls.py b/core/apps/orders/urls.py index 11e200e..5fdcb9d 100644 --- a/core/apps/orders/urls.py +++ b/core/apps/orders/urls.py @@ -1,11 +1,19 @@ from django.urls import path, include +from core.apps.orders.views import order_application as application_views from core.apps.orders.views import order as order_views + urlpatterns = [ path('order_application/', include( [ - path('create/', order_views.OrderApplicationCreateApiView.as_view()), + path('create/', application_views.OrderApplicationCreateApiView.as_view()), + path('list/', application_views.OrderApplicationListApiView.as_view()), + ] + )), + path('order/', include( + [ + path('list/', order_views.OrderListApiView.as_view()), ] )), ] \ No newline at end of file diff --git a/core/apps/orders/views/order.py b/core/apps/orders/views/order.py index dbb3e0b..677e6d5 100644 --- a/core/apps/orders/views/order.py +++ b/core/apps/orders/views/order.py @@ -1,18 +1,17 @@ -from rest_framework import generics, response +from rest_framework import generics, status from rest_framework.response import Response -from core.apps.orders.models import Order, OrderApplication from core.apps.orders.serializers import order as serializers +from core.apps.orders.models import Order from core.apps.accounts.permissions.permissions import HasRolePermission +from core.apps.shared.paginations.custom import CustomPageNumberPagination -class OrderApplicationCreateApiView(generics.CreateAPIView): - serializer_class = serializers.OrderApplicationCreateSerializer - queryset = OrderApplication.objects.all() +class OrderListApiView(generics.ListAPIView): + serializer_class = serializers.OrderListSerializer + queryset = Order.objects.select_related( + 'product', 'unity', 'project', 'project_department', 'wherehouse' + ) permission_classes = [HasRolePermission] required_permissions = [] - - def get_serializer_context(self): - context = super().get_serializer_context() - context['user'] = self.request.user - return context \ No newline at end of file + pagination_class = CustomPageNumberPagination \ No newline at end of file diff --git a/core/apps/orders/views/order_application.py b/core/apps/orders/views/order_application.py new file mode 100644 index 0000000..595e51a --- /dev/null +++ b/core/apps/orders/views/order_application.py @@ -0,0 +1,27 @@ +from rest_framework import generics, response +from rest_framework.response import Response + +from core.apps.orders.models import Order, OrderApplication +from core.apps.orders.serializers import order_application as serializers +from core.apps.accounts.permissions.permissions import HasRolePermission +from core.apps.shared.paginations.custom import CustomPageNumberPagination + + +class OrderApplicationCreateApiView(generics.CreateAPIView): + serializer_class = serializers.OrderApplicationCreateSerializer + queryset = OrderApplication.objects.all() + permission_classes = [HasRolePermission] + required_permissions = [] + + def get_serializer_context(self): + context = super().get_serializer_context() + context['user'] = self.request.user + return context + + +class OrderApplicationListApiView(generics.ListAPIView): + queryset = OrderApplication.objects.prefetch_related('orders') + serializer_class = serializers.OrderApplicationListSerializer + pagination_class = CustomPageNumberPagination + permission_classes = [HasRolePermission] + required_permissions = [] \ No newline at end of file diff --git a/core/apps/products/migrations/0004_product_type.py b/core/apps/products/migrations/0004_product_type.py new file mode 100644 index 0000000..d621aba --- /dev/null +++ b/core/apps/products/migrations/0004_product_type.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.4 on 2025-08-01 17:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('products', '0003_unity'), + ] + + operations = [ + migrations.AddField( + model_name='product', + name='type', + field=models.CharField(choices=[('TANGIBLE', "ushlab bo'ladigan"), ('INTANGIBLE', "ushlab bo'lmaydigan")], default='TANGIBLE', max_length=20), + ), + ] diff --git a/core/apps/products/models/product.py b/core/apps/products/models/product.py index 7239ed7..4b21a11 100644 --- a/core/apps/products/models/product.py +++ b/core/apps/products/models/product.py @@ -5,7 +5,13 @@ from core.apps.shared.models import BaseModel class Product(BaseModel): + TYPE = ( + ("TANGIBLE", "ushlab bo'ladigan"), + ("INTANGIBLE", "ushlab bo'lmaydigan"), + ) + name = models.CharField(max_length=200) + type = models.CharField(max_length=20, choices=TYPE, default="TANGIBLE") def __str__(self): return self.name diff --git a/core/apps/products/serializers/product.py b/core/apps/products/serializers/product.py index 586b418..c78573e 100644 --- a/core/apps/products/serializers/product.py +++ b/core/apps/products/serializers/product.py @@ -7,5 +7,5 @@ class ProductListSerializer(serializers.ModelSerializer): class Meta: model = Product fields = [ - 'id', 'name' + 'id', 'name', 'type' ] \ No newline at end of file diff --git a/core/apps/products/views/product.py b/core/apps/products/views/product.py index 180cec1..a8ec8a7 100644 --- a/core/apps/products/views/product.py +++ b/core/apps/products/views/product.py @@ -4,10 +4,12 @@ from rest_framework.response import Response from core.apps.products.models.product import Product from core.apps.products.serializers import product as serializers from core.apps.accounts.permissions.permissions import HasRolePermission +from core.apps.shared.paginations.custom import CustomPageNumberPagination class ProductListApiView(generics.ListAPIView): serializer_class = serializers.ProductListSerializer queryset = Product.objects.all() permission_classes = [HasRolePermission] - required_permissions = [] \ No newline at end of file + required_permissions = [] + pagination_class = CustomPageNumberPagination \ No newline at end of file diff --git a/core/apps/products/views/unity.py b/core/apps/products/views/unity.py index f49192f..34f9dd7 100644 --- a/core/apps/products/views/unity.py +++ b/core/apps/products/views/unity.py @@ -4,10 +4,12 @@ from rest_framework.response import Response from core.apps.products.models import Unity from core.apps.products.serializers import unity as serializers from core.apps.accounts.permissions.permissions import HasRolePermission +from core.apps.shared.paginations.custom import CustomPageNumberPagination class UnityListApiView(generics.ListAPIView): serializer_class = serializers.UnityListSerializer queryset = Unity.objects.all() permission_classes = [HasRolePermission] - required_permissions = [] \ No newline at end of file + required_permissions = [] + pagination_class = CustomPageNumberPagination \ No newline at end of file diff --git a/core/apps/projects/views/project.py b/core/apps/projects/views/project.py index d4048b9..8a7d538 100644 --- a/core/apps/projects/views/project.py +++ b/core/apps/projects/views/project.py @@ -4,6 +4,7 @@ from rest_framework.response import Response from core.apps.projects.models.project import Project, ProjectDepartment from core.apps.projects.serializers import project as serializers from core.apps.accounts.permissions.permissions import HasRolePermission +from core.apps.shared.paginations.custom import CustomPageNumberPagination class ProjectListApiView(generics.ListAPIView): @@ -11,6 +12,7 @@ class ProjectListApiView(generics.ListAPIView): queryset = Project.objects.all() permission_classes = [HasRolePermission] required_permissions = [] + pagination_class = CustomPageNumberPagination class ProjectDetailApiView(generics.RetrieveAPIView): diff --git a/core/apps/shared/paginations/__init__.py b/core/apps/shared/paginations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/apps/shared/paginations/custom.py b/core/apps/shared/paginations/custom.py new file mode 100644 index 0000000..abaa0b6 --- /dev/null +++ b/core/apps/shared/paginations/custom.py @@ -0,0 +1,22 @@ +from rest_framework.pagination import PageNumberPagination + + +from rest_framework.pagination import PageNumberPagination +from rest_framework.response import Response + +class CustomPageNumberPagination(PageNumberPagination): + page_size = 10 + page_query_param = 'page' + page_size_query_param = 'page_size' + max_page_size = 100 + + def get_paginated_response(self, data): + return Response({ + 'total': self.page.paginator.count, + 'page': self.page.number, + 'page_size': self.get_page_size(self.request), + 'total_pages': self.page.paginator.num_pages, + 'has_next': self.page.has_next(), + 'has_previous': self.page.has_previous(), + 'results': data + }) \ No newline at end of file