from rest_framework import status, views, serializers, pagination from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from basic_info import models as basic_models from business import services as business_services from business import models as business_models from api_v1.views.stock_change_views.mixins import StockChangeViewMixin class PaymentOrderSerializer(serializers.ModelSerializer): supplier_name = serializers.CharField(source='supplier.name', read_only=True) operator_name = serializers.CharField(source='operator.name', read_only=True) class Meta: model = business_models.PaymentOrder fields = [ 'id', 'supplier', 'supplier_name', 'payment_date', 'amount', 'operator', 'operator_name', 'status', 'remarks', 'created_at', 'updated_at', ] read_only_fields = ['id', 'supplier_name', 'operator_name', 'status', 'created_at', 'updated_at'] class PaymentOrderPagination(pagination.LimitOffsetPagination): default_limit = 20 max_limit = 100 class PaymentOrderView(StockChangeViewMixin, views.APIView): permission_classes = [IsAuthenticated] pagination_class = PaymentOrderPagination def get(self, request): if not self.check_employee_permission(request): return self.permission_error_response('无权限访问') merchant = request.user.employee.merchant queryset = business_models.PaymentOrder.objects.filter(merchant=merchant).select_related( 'supplier', 'operator' ).order_by('-created_at') paginator = self.pagination_class() page = paginator.paginate_queryset(queryset, request, view=self) serializer = PaymentOrderSerializer(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 data = request.data or {} supplier_id = data.get('supplier') payment_date = data.get('payment_date') amount = data.get('amount') remarks = data.get('remarks', '') if not supplier_id: return Response({'error': '缺少供应商 ID'}, status=status.HTTP_400_BAD_REQUEST) if not payment_date: return Response({'error': '缺少 payment_date'}, status=status.HTTP_400_BAD_REQUEST) if amount is None: return Response({'error': '缺少 amount'}, status=status.HTTP_400_BAD_REQUEST) try: supplier = basic_models.Supplier.objects.get(id=supplier_id, merchant=merchant) except basic_models.Supplier.DoesNotExist: return Response({'error': f'供应商 {supplier_id} 不存在'}, status=status.HTTP_400_BAD_REQUEST) operator = request.user.employee try: payment_order = business_services.create_payment_order( merchant=merchant, supplier=supplier, payment_date=payment_date, amount=amount, operator=operator, remarks=remarks, ) except ValueError as exc: return Response({'error': str(exc)}, status=status.HTTP_400_BAD_REQUEST) return Response( { 'id': payment_order.id, 'status': payment_order.status, 'message': '付款单创建成功,等待审批', }, status=status.HTTP_201_CREATED, ) class PaymentOrderReviewSerializer(serializers.Serializer): action = serializers.ChoiceField(choices=[('approve', '审批通过'), ('cancel', '作废')]) class PaymentOrderReviewView(StockChangeViewMixin, views.APIView): permission_classes = [IsAuthenticated] ACTION_STATUS_MAP = { 'approve': business_models.PaymentOrderStatusEnum.APPROVED, 'cancel': business_models.PaymentOrderStatusEnum.CANCELLED, } def post(self, request, pk: int): if not self.check_employee_permission(request): return self.permission_error_response('无权限访问') merchant = request.user.employee.merchant try: payment_order = business_models.PaymentOrder.objects.select_related( 'supplier', 'operator' ).get(id=pk, merchant=merchant) except business_models.PaymentOrder.DoesNotExist: return self.not_found_response('付款单不存在') serializer = PaymentOrderReviewSerializer(data=request.data or {}) serializer.is_valid(raise_exception=True) action = serializer.validated_data['action'] target_status = self.ACTION_STATUS_MAP[action] try: business_services.review_payment_order( payment_order=payment_order, target_status=target_status, reviewed_by=request.user, ) except ValueError as exc: return Response({'error': str(exc)}, status=status.HTTP_400_BAD_REQUEST) refreshed = business_models.PaymentOrder.objects.select_related( 'supplier', 'operator' ).get(id=payment_order.id) return Response(PaymentOrderSerializer(refreshed).data, status=status.HTTP_200_OK)