1
0
forked from erp-dev/erp
Files
erpnew/api_v1/views/business/statements/views.py

124 lines
4.6 KiB
Python

from __future__ import annotations
from rest_framework import views
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 api_v1.views.stock_change_views.mixins import StockChangeViewMixin
from . import serializers as statement_serializers
class StatementViewBase(StockChangeViewMixin, views.APIView):
"""
提供对账单视图的公共实现:权限校验、序列化上下文及响应构造。
"""
permission_classes = [IsAuthenticated]
serializer_class = statement_serializers.StatementResponseSerializer
def get_serializer_context(self):
return {
'request': self.request,
'view': self,
'summary_builder': business_services.build_statement_summary,
}
def _build_response(self, payload: dict):
serializer = self.serializer_class(
instance=payload,
context=self.get_serializer_context(),
)
return Response(serializer.data)
class CustomerStatementView(StatementViewBase):
"""
返回指定客户的业务单据对账单,包含销售单、销售退货单与收款单。
"""
def get(self, request, customer_id: int):
if not self.check_employee_permission(request):
return self.permission_error_response('无权限访问')
merchant = request.user.employee.merchant
try:
customer = basic_models.Customer.objects.get(id=customer_id, merchant=merchant)
except basic_models.Customer.DoesNotExist:
return self.not_found_response('客户不存在')
payload = business_services.build_customer_statement(merchant=merchant, customer=customer)
return self._build_response(payload)
class SupplierStatementView(StatementViewBase):
"""
返回指定供应商的业务单据对账单,包含采购单、采购退货单与付款单。
"""
def get(self, request, supplier_id: int):
if not self.check_employee_permission(request):
return self.permission_error_response('无权限访问')
merchant = request.user.employee.merchant
try:
supplier = basic_models.Supplier.objects.get(id=supplier_id, merchant=merchant)
except basic_models.Supplier.DoesNotExist:
return self.not_found_response('供应商不存在')
payload = business_services.build_supplier_statement(merchant=merchant, supplier=supplier)
return self._build_response(payload)
class StatementRecordView(StatementViewBase):
"""
根据业务主体与单据信息查询单条对账记录,返回与列表接口一致的 schema。
"""
def get(self, request):
if not self.check_employee_permission(request):
return self.permission_error_response('无权限访问')
serializer = statement_serializers.StatementRecordQuerySerializer(data=request.query_params)
serializer.is_valid(raise_exception=True)
params = serializer.validated_data
merchant = request.user.employee.merchant
counterparty_type = params['counterparty_type']
counterparty_id = params['counterparty_id']
order_type = params['order_type']
order_id = params['order_id']
if counterparty_type == 'customer':
try:
counterparty = basic_models.Customer.objects.get(id=counterparty_id, merchant=merchant)
except basic_models.Customer.DoesNotExist:
return self.not_found_response('客户不存在')
payload = business_services.build_customer_statement(merchant=merchant, customer=counterparty)
else:
try:
counterparty = basic_models.Supplier.objects.get(id=counterparty_id, merchant=merchant)
except basic_models.Supplier.DoesNotExist:
return self.not_found_response('供应商不存在')
payload = business_services.build_supplier_statement(merchant=merchant, supplier=counterparty)
matched_records = [
record
for record in payload.get('records', [])
if record['source_type'] == order_type and record['source_id'] == order_id
]
if not matched_records:
return self.not_found_response('未找到匹配的对账记录')
single_payload = {
'counterparty': payload['counterparty'],
'counterparty_name': payload['counterparty_name'],
'records': matched_records,
}
return self._build_response(single_payload)