forked from erp-dev/erp
122 lines
4.6 KiB
Python
122 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)
|