forked from erp-dev/erp
210 lines
7.7 KiB
Python
210 lines
7.7 KiB
Python
from rest_framework import status, views, serializers, pagination
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
from django.utils import dateparse, timezone
|
|
|
|
from api_v1.views.stock_change_views.mixins import StockChangeViewMixin
|
|
from business import models as business_models
|
|
from business import pre_order_services
|
|
|
|
|
|
class PrePurchaseOrderItemSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = business_models.PrePurchaseOrderItem
|
|
fields = [
|
|
'id',
|
|
'product_id',
|
|
'product_name',
|
|
'color',
|
|
'quantity',
|
|
'unit',
|
|
'spec',
|
|
'remarks',
|
|
]
|
|
read_only_fields = ['id']
|
|
|
|
|
|
class PrePurchaseOrderSerializer(serializers.ModelSerializer):
|
|
human_id = serializers.CharField(read_only=True)
|
|
supplier_name = serializers.CharField(source='supplier.name', read_only=True)
|
|
warehouse_name = serializers.CharField(source='warehouse.name', read_only=True)
|
|
operator_name = serializers.CharField(source='operator.name', read_only=True)
|
|
items = PrePurchaseOrderItemSerializer(many=True, read_only=True)
|
|
|
|
class Meta:
|
|
model = business_models.PrePurchaseOrder
|
|
fields = [
|
|
'id',
|
|
'human_id',
|
|
'merchant',
|
|
'supplier',
|
|
'supplier_name',
|
|
'warehouse',
|
|
'warehouse_name',
|
|
'operator',
|
|
'operator_name',
|
|
'kind',
|
|
'remarks',
|
|
'created_at',
|
|
'items',
|
|
]
|
|
read_only_fields = [
|
|
'id',
|
|
'human_id',
|
|
'created_at',
|
|
'supplier_name',
|
|
'warehouse_name',
|
|
'operator_name',
|
|
'items',
|
|
]
|
|
|
|
|
|
class PrePurchaseOrderPagination(pagination.LimitOffsetPagination):
|
|
default_limit = 20
|
|
max_limit = 100
|
|
|
|
|
|
class PrePurchaseOrderView(StockChangeViewMixin, views.APIView):
|
|
"""预采购单查询与创建"""
|
|
|
|
permission_classes = [IsAuthenticated]
|
|
pagination_class = PrePurchaseOrderPagination
|
|
|
|
def get(self, request):
|
|
if not self.check_employee_permission(request):
|
|
return self.permission_error_response('无权限访问')
|
|
|
|
merchant = request.user.employee.merchant
|
|
queryset = pre_order_services.list_pre_purchase_orders(merchant=merchant)
|
|
|
|
supplier_id = request.query_params.get('supplier') or request.query_params.get('supplier_id')
|
|
warehouse_id = request.query_params.get('warehouse') or request.query_params.get('warehouse_id')
|
|
kind = request.query_params.get('kind')
|
|
human_id_contains = request.query_params.get('human_id__icontains')
|
|
created_from = request.query_params.get('created_at_from')
|
|
created_to = request.query_params.get('created_at_to')
|
|
|
|
try:
|
|
if supplier_id:
|
|
queryset = queryset.filter(supplier_id=int(supplier_id))
|
|
if warehouse_id:
|
|
queryset = queryset.filter(warehouse_id=int(warehouse_id))
|
|
if kind:
|
|
queryset = queryset.filter(kind=int(kind))
|
|
except (TypeError, ValueError):
|
|
return Response({'error': '筛选参数必须为整数'}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
if human_id_contains:
|
|
queryset = queryset.filter(human_id__icontains=str(human_id_contains).strip())
|
|
|
|
def _parse_datetime(value: str):
|
|
dt = dateparse.parse_datetime(value)
|
|
if dt is None:
|
|
d = dateparse.parse_date(value)
|
|
if d is None:
|
|
return None
|
|
dt = timezone.datetime.combine(d, timezone.datetime.min.time())
|
|
if timezone.is_naive(dt):
|
|
dt = timezone.make_aware(dt, timezone.get_current_timezone())
|
|
return dt
|
|
|
|
if created_from:
|
|
dt_from = _parse_datetime(created_from)
|
|
if dt_from is None:
|
|
return Response({'error': 'created_at_from 格式不正确'}, status=status.HTTP_400_BAD_REQUEST)
|
|
queryset = queryset.filter(created_at__gte=dt_from)
|
|
|
|
if created_to:
|
|
dt_to = _parse_datetime(created_to)
|
|
if dt_to is None:
|
|
return Response({'error': 'created_at_to 格式不正确'}, status=status.HTTP_400_BAD_REQUEST)
|
|
queryset = queryset.filter(created_at__lte=dt_to)
|
|
|
|
paginator = self.pagination_class()
|
|
page = paginator.paginate_queryset(queryset.order_by('-created_at'), request, view=self)
|
|
serializer = PrePurchaseOrderSerializer(page, many=True)
|
|
return paginator.get_paginated_response(serializer.data)
|
|
|
|
def post(self, request):
|
|
if not self.check_employee_permission(request):
|
|
return self.permission_error_response('无权限访问')
|
|
|
|
merchant = request.user.employee.merchant
|
|
employee = request.user.employee
|
|
data = request.data or {}
|
|
|
|
try:
|
|
pre_purchase_order = pre_order_services.create_pre_purchase_order(
|
|
merchant=merchant,
|
|
supplier_id=data.get('supplier') or data.get('supplier_id'),
|
|
warehouse_id=data.get('warehouse') or data.get('warehouse_id'),
|
|
operator=employee,
|
|
created_by=request.user,
|
|
kind=data.get('kind'),
|
|
items=data.get('items'),
|
|
remarks=data.get('remarks', ''),
|
|
)
|
|
except ValueError as exc:
|
|
return Response({'error': str(exc)}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
return Response(PrePurchaseOrderSerializer(pre_purchase_order).data, status=status.HTTP_201_CREATED)
|
|
|
|
|
|
class PrePurchaseOrderDetailView(StockChangeViewMixin, views.APIView):
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def _get_order(self, request, pk: int):
|
|
if not self.check_employee_permission(request):
|
|
return None, self.permission_error_response('无权限访问')
|
|
|
|
merchant = request.user.employee.merchant
|
|
try:
|
|
order = pre_order_services.get_pre_purchase_order(
|
|
merchant=merchant,
|
|
pre_purchase_order_id=pk,
|
|
)
|
|
return order, None
|
|
except ValueError:
|
|
return None, self.not_found_response('预采购单不存在')
|
|
|
|
def get(self, request, pk: int):
|
|
order, error_response = self._get_order(request, pk)
|
|
if error_response:
|
|
return error_response
|
|
return Response(PrePurchaseOrderSerializer(order).data, status=status.HTTP_200_OK)
|
|
|
|
def put(self, request, pk: int):
|
|
return self._update(request, pk)
|
|
|
|
def patch(self, request, pk: int):
|
|
return self._update(request, pk)
|
|
|
|
def _update(self, request, pk: int):
|
|
order, error_response = self._get_order(request, pk)
|
|
if error_response:
|
|
return error_response
|
|
|
|
data = request.data or {}
|
|
|
|
try:
|
|
updated = pre_order_services.update_pre_purchase_order(
|
|
pre_purchase_order=order,
|
|
supplier_id=data.get('supplier') or data.get('supplier_id'),
|
|
warehouse_id=data.get('warehouse') or data.get('warehouse_id'),
|
|
kind=data.get('kind'),
|
|
items=data.get('items'),
|
|
remarks=data.get('remarks'),
|
|
)
|
|
except ValueError as exc:
|
|
return Response({'error': str(exc)}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
return Response(PrePurchaseOrderSerializer(updated).data, status=status.HTTP_200_OK)
|
|
|
|
def delete(self, request, pk: int):
|
|
order, error_response = self._get_order(request, pk)
|
|
if error_response:
|
|
return error_response
|
|
|
|
pre_order_services.delete_pre_purchase_order(pre_purchase_order=order)
|
|
return Response(status=status.HTTP_204_NO_CONTENT)
|