1
0
forked from erp-dev/erp
Files
erpnew/printing/views.py

304 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Printing API ViewSet
"""
from rest_framework import viewsets, filters, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import BasePermission
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.permissions import DjangoModelPermissions
from django_filters.rest_framework import DjangoFilterBackend
from django_filters import rest_framework as django_filters
from printing import models
from basic_info.models import MerchantTypeEnum
from printing.serializers import (
PrintingOrderListSerializer,
PrintingOrderDetailSerializer,
PrintingOrderCreateUpdateSerializer,
PrintingJobListSerializer,
PrintingJobDetailSerializer,
PrintingJobCreateUpdateSerializer,
)
class IsPrintingFactory(BasePermission):
"""自定义权限类,允许印染工厂用户访问"""
message = '您没有访问印染订单的权限'
def has_permission(self, request, view):
if not request.user.is_authenticated:
return False
if hasattr(request.user, 'employee'):
return request.user.employee.merchant.type == MerchantTypeEnum.FACTORY
return False
class HasInvalidatePrintingOrderPermission(BasePermission):
"""自定义权限类,检查用户是否有作废印染订单的权限"""
message = '您没有权限作废订单'
def has_permission(self, request, view):
if not request.user.is_authenticated:
return False
return request.user.has_perm('printing.can_invalidate_printingorder')
class HasActivatePrintingOrderPermission(BasePermission):
"""自定义权限类,检查用户是否有恢复印染订单的权限"""
message = '您没有权限恢复订单'
def has_permission(self, request, view):
if not request.user.is_authenticated:
return False
return request.user.has_perm('printing.can_activate_printingorder')
class PrintingOrderFilterSet(django_filters.FilterSet):
"""印染订单过滤器"""
customer_name = django_filters.CharFilter(field_name='customer__name', lookup_expr='icontains')
customer_phone = django_filters.CharFilter(field_name='customer__phone', lookup_expr='icontains')
fabric = django_filters.CharFilter(lookup_expr='icontains')
is_urgent = django_filters.BooleanFilter()
is_fabric_received = django_filters.BooleanFilter()
is_invalid = django_filters.BooleanFilter()
area = django_filters.CharFilter(lookup_expr='icontains')
outgoing_date_from = django_filters.DateFilter(field_name='outgoing_date', lookup_expr='gte')
outgoing_date_to = django_filters.DateFilter(field_name='outgoing_date', lookup_expr='lte')
created_date_from = django_filters.DateFilter(field_name='created_at', lookup_expr='gte')
created_date_to = django_filters.DateFilter(field_name='created_at', lookup_expr='lte')
class Meta:
model = models.PrintingOrder
fields = ['customer', 'is_urgent', 'is_fabric_received', 'is_invalid']
class PrintingOrderViewSet(viewsets.ModelViewSet):
"""
印染订单 ViewSet
提供印染订单的增改查功能(不支持删除)
list: 获取印染订单列表
retrieve: 获取印染订单详情
create: 创建印染订单
update: 更新印染订单
partial_update: 部分更新印染订单
查询参数:
- customer: 客户ID
- customer_name: 客户名称(模糊查询)
- customer_phone: 客户电话(模糊查询)
- fabric: 面料(模糊查询)
- is_urgent: 是否紧急true/false
- is_fabric_received: 布料是否已收true/false
- is_invalid: 是否作废true/false
- area: 地区(模糊查询)
- outgoing_date_from: 出货日期起始
- outgoing_date_to: 出货日期结束
- created_date_from: 创建日期起始
- created_date_to: 创建日期结束
- search: 全文搜索(客户名称、面料、地区、工艺)
- ordering: 排序字段
"""
queryset = models.PrintingOrder.objects.all()
permission_classes = [DjangoModelPermissions]
pagination_class = LimitOffsetPagination
filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
filterset_class = PrintingOrderFilterSet
search_fields = ['customer__name', 'fabric', 'area', 'craft', 'description']
ordering_fields = [
'id', 'created_at', 'updated_at', 'outgoing_date',
'is_urgent', 'is_fabric_received', 'is_invalid'
]
ordering = ['-created_at']
def get_permissions(self):
permissions = super().get_permissions() + [IsPrintingFactory()]
if self.action == 'invalidate':
permissions.append(HasInvalidatePrintingOrderPermission())
elif self.action == 'activate':
permissions.append(HasActivatePrintingOrderPermission())
return permissions
def get_serializer_class(self):
"""根据动作选择序列化器"""
if self.action == 'list':
return PrintingOrderListSerializer
elif self.action in ['create', 'update', 'partial_update']:
return PrintingOrderCreateUpdateSerializer
else: # retrieve
return PrintingOrderDetailSerializer
def get_queryset(self):
"""优化查询"""
queryset = super().get_queryset()
if self.action in ['list', 'retrieve']:
queryset = queryset.select_related('customer')
return queryset
def destroy(self, request, *args, **kwargs):
"""禁用删除操作"""
return Response(
{'detail': '印染订单不支持删除操作,请使用作废功能'},
status=status.HTTP_405_METHOD_NOT_ALLOWED
)
@action(detail=True, methods=['post'])
def invalidate(self, request, pk=None):
"""
作废订单
需要权限: printing.can_invalidate_printingorder
"""
# 检查权限
if not request.user.has_perm('printing.can_invalidate_printingorder'):
return Response(
{'detail': '您没有权限作废订单'},
status=status.HTTP_403_FORBIDDEN
)
printing_order = self.get_object()
if printing_order.is_invalid:
return Response(
{'detail': '该订单已经作废'},
status=status.HTTP_400_BAD_REQUEST
)
printing_order.is_invalid = True
printing_order.save()
serializer = PrintingOrderDetailSerializer(printing_order)
return Response({
'detail': '订单已作废',
'data': serializer.data
})
@action(detail=True, methods=['post'])
def activate(self, request, pk=None):
"""
恢复订单
需要权限: printing.can_activate_printingorder
"""
# 检查权限
if not request.user.has_perm('printing.can_activate_printingorder'):
return Response(
{'detail': '您没有权限恢复订单'},
status=status.HTTP_403_FORBIDDEN
)
printing_order = self.get_object()
if not printing_order.is_invalid:
return Response(
{'detail': '该订单未作废,无需恢复'},
status=status.HTTP_400_BAD_REQUEST
)
printing_order.is_invalid = False
printing_order.save()
serializer = PrintingOrderDetailSerializer(printing_order)
return Response({
'detail': '订单已恢复',
'data': serializer.data
})
@action(detail=True, methods=['post'])
def mark_fabric_received(self, request, pk=None):
"""标记布料已收"""
printing_order = self.get_object()
if printing_order.is_fabric_received:
return Response(
{'detail': '布料已经标记为已收'},
status=status.HTTP_400_BAD_REQUEST
)
printing_order.is_fabric_received = True
printing_order.save()
serializer = PrintingOrderDetailSerializer(printing_order)
return Response({
'detail': '已标记布料已收',
'data': serializer.data
})
class PrintingJobFilterSet(django_filters.FilterSet):
"""印染款式明细过滤器"""
printing_order = django_filters.NumberFilter()
product = django_filters.NumberFilter()
product_name = django_filters.CharFilter(field_name='product__name', lookup_expr='icontains')
unit = django_filters.CharFilter(lookup_expr='icontains')
quantity_min = django_filters.NumberFilter(field_name='quantity', lookup_expr='gte')
quantity_max = django_filters.NumberFilter(field_name='quantity', lookup_expr='lte')
pieces_min = django_filters.NumberFilter(field_name='pieces', lookup_expr='gte')
pieces_max = django_filters.NumberFilter(field_name='pieces', lookup_expr='lte')
class Meta:
model = models.PrintingJob
fields = ['printing_order', 'product']
class PrintingJobViewSet(viewsets.ModelViewSet):
"""
印染款式明细 ViewSet
提供印染款式明细的增改查功能(不支持删除)
list: 获取款式明细列表
retrieve: 获取款式明细详情
create: 创建款式明细
update: 更新款式明细
partial_update: 部分更新款式明细
查询参数:
- printing_order: 印染订单ID
- product: 产品ID
- product_name: 产品名称(模糊查询)
- unit: 单位(模糊查询)
- quantity_min: 最小数量
- quantity_max: 最大数量
- pieces_min: 最小件数
- pieces_max: 最大件数
- search: 全文搜索(产品名称、单位、尺寸、备注)
- ordering: 排序字段
"""
queryset = models.PrintingJob.objects.all()
permission_classes = [DjangoModelPermissions, IsPrintingFactory]
pagination_class = LimitOffsetPagination
filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
filterset_class = PrintingJobFilterSet
search_fields = ['product__name', 'unit', 'size', 'description']
ordering_fields = ['id', 'created_at', 'updated_at', 'quantity', 'pieces']
ordering = ['-created_at']
def get_serializer_class(self):
"""根据动作选择序列化器"""
if self.action == 'list':
return PrintingJobListSerializer
elif self.action in ['create', 'update', 'partial_update']:
return PrintingJobCreateUpdateSerializer
else: # retrieve
return PrintingJobDetailSerializer
def get_queryset(self):
"""优化查询"""
queryset = super().get_queryset()
if self.action in ['list', 'retrieve']:
queryset = queryset.select_related('printing_order', 'product')
return queryset
def destroy(self, request, *args, **kwargs):
"""禁用删除操作"""
return Response(
{'detail': '印染款式明细不支持删除操作'},
status=status.HTTP_405_METHOD_NOT_ALLOWED
)