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 ReceiptOrderSerializer(serializers.ModelSerializer): customer_name = serializers.CharField(source='customer.name', read_only=True) operator_name = serializers.CharField(source='operator.name', read_only=True) bank_account_name = serializers.CharField(source='bank_account.name', read_only=True) settlement_amount = serializers.SerializerMethodField() class Meta: model = business_models.ReceiptOrder fields = [ 'id', 'customer', 'customer_name', 'bank_account', 'bank_account_name', 'receipt_date', 'amount', 'discount_amount', 'settlement_amount', 'operator', 'operator_name', 'status', 'remarks', 'markup', 'created_at', 'updated_at', ] read_only_fields = [ 'id', 'customer_name', 'operator_name', 'bank_account_name', 'settlement_amount', 'status', 'created_at', 'updated_at', ] def get_settlement_amount(self, obj): return str(obj.settlement_amount) class ReceiptOrderPagination(pagination.LimitOffsetPagination): default_limit = 20 max_limit = 100 class ReceiptOrderView(StockChangeViewMixin, views.APIView): permission_classes = [IsAuthenticated] pagination_class = ReceiptOrderPagination def get(self, request): if not self.check_employee_permission(request): return self.permission_error_response('无权限访问') merchant = request.user.employee.merchant queryset = ( business_models.ReceiptOrder.objects.filter(merchant=merchant) .select_related('customer', 'operator', 'bank_account') .order_by('-created_at') ) paginator = self.pagination_class() page = paginator.paginate_queryset(queryset, request, view=self) serializer = ReceiptOrderSerializer(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 {} customer_id = data.get('customer') receipt_date = data.get('receipt_date') amount = data.get('amount') discount_amount = data.get('discount_amount') bank_account_id = data.get('bank_account') markup = data.get('markup') remarks = data.get('remarks', '') if not customer_id: return Response({'error': '缺少客户 ID'}, status=status.HTTP_400_BAD_REQUEST) if not receipt_date: return Response({'error': '缺少 receipt_date'}, status=status.HTTP_400_BAD_REQUEST) if amount is None: return Response({'error': '缺少 amount'}, status=status.HTTP_400_BAD_REQUEST) try: customer = basic_models.Customer.objects.get(id=customer_id, merchant=merchant) except basic_models.Customer.DoesNotExist: return Response({'error': f'客户 {customer_id} 不存在'}, status=status.HTTP_400_BAD_REQUEST) operator = request.user.employee bank_account = None if bank_account_id not in (None, '', 0): try: bank_account = basic_models.BankAccount.objects.get(id=bank_account_id, merchant=merchant) except basic_models.BankAccount.DoesNotExist: return Response({'error': '银行账户不存在'}, status=status.HTTP_400_BAD_REQUEST) try: receipt_order = business_services.create_receipt_order( merchant=merchant, customer=customer, receipt_date=receipt_date, amount=amount, discount_amount=discount_amount, operator=operator, remarks=remarks, bank_account=bank_account, markup=markup, ) except ValueError as exc: return Response({'error': str(exc)}, status=status.HTTP_400_BAD_REQUEST) return Response( { 'id': receipt_order.id, 'status': receipt_order.status, 'message': '收款单创建成功,等待审批', }, status=status.HTTP_201_CREATED, ) class ReceiptOrderReviewSerializer(serializers.Serializer): action = serializers.ChoiceField(choices=[('approve', '审批通过'), ('cancel', '作废')]) class ReceiptOrderReviewView(StockChangeViewMixin, views.APIView): permission_classes = [IsAuthenticated] ACTION_STATUS_MAP = { 'approve': business_models.ReceiptOrderStatusEnum.APPROVED, 'cancel': business_models.ReceiptOrderStatusEnum.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: receipt_order = ( business_models.ReceiptOrder.objects.select_related('customer', 'operator', 'bank_account') .get(id=pk, merchant=merchant) ) except business_models.ReceiptOrder.DoesNotExist: return self.not_found_response('收款单不存在') serializer = ReceiptOrderReviewSerializer(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_receipt_order( receipt_order=receipt_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.ReceiptOrder.objects.select_related('customer', 'operator', 'bank_account') .get(id=receipt_order.id) ) return Response(ReceiptOrderSerializer(refreshed).data, status=status.HTTP_200_OK)