- commission rule/rate-table/event endpoints use CommissionEngine - payment gateway config list/detail/save/delete use PaymentManager - remove unused model imports"
260 lines
10 KiB
Python
260 lines
10 KiB
Python
import logging
|
|
from rest_framework.views import APIView
|
|
from rest_framework.response import Response
|
|
from gvsdsdk.commission.manager import CommissionEngine, CommissionError
|
|
from gvsds.apps.commission.serializers import (
|
|
DispatchRequestSerializer,
|
|
RuleCreateSerializer,
|
|
RateTableCreateSerializer,
|
|
CommissionRuleSerializer,
|
|
CommissionRecordSerializer,
|
|
RateTableSerializer,
|
|
CommissionEventSerializer,
|
|
PreSettleRequestSerializer,
|
|
PreSettleConfirmSerializer,
|
|
FeeCalcSerializer,
|
|
InviteChainDispatchSerializer,
|
|
)
|
|
from gvsdsdk.commission.models import CommissionEvent
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _ok(data=None, msg='success'):
|
|
return {'code': 200, 'msg': msg, 'data': data}
|
|
|
|
|
|
def _err(msg, code=400):
|
|
return {'code': code, 'msg': msg, 'data': None}
|
|
|
|
|
|
def _get_tenant(request):
|
|
return request.headers.get('X-Tenant-UUID', '') or getattr(request, 'tenant_uuid', '')
|
|
|
|
|
|
class RuleConfigView(APIView):
|
|
|
|
def get(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
EventType = request.query_params.get('EventType', '')
|
|
engine = CommissionEngine(tenant)
|
|
qs = engine.ListRules(EventType or None)
|
|
return Response(_ok(CommissionRuleSerializer(qs, many=True).data))
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = RuleCreateSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
engine = CommissionEngine(tenant)
|
|
rule = engine.ConfigureRule(
|
|
event_type=ser.ValidatedData['EventType'],
|
|
rule_name=ser.ValidatedData['RuleName'],
|
|
participant_rules=ser.ValidatedData['ParticipantRules'],
|
|
rule_description=ser.ValidatedData.get('RuleDescription', ''),
|
|
max_invite_level=ser.ValidatedData.get('MaxInviteLevel', 2),
|
|
rate_table_uuid=ser.ValidatedData.get('RateTableUUID', ''),
|
|
rule_priority=ser.ValidatedData.get('RulePriority', 0),
|
|
)
|
|
return Response(_ok(CommissionRuleSerializer(rule).data), status=201)
|
|
|
|
def delete(self, request):
|
|
tenant = _get_tenant(request)
|
|
rule_uuid = request.data.get('RuleUUID')
|
|
if not tenant or not rule_uuid:
|
|
return Response(_err('缺少参数', 400), status=400)
|
|
engine = CommissionEngine(tenant)
|
|
engine.DisableRule(rule_uuid)
|
|
return Response(_ok(msg='规则已禁用'))
|
|
|
|
|
|
class RateTableView(APIView):
|
|
|
|
def get(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
engine = CommissionEngine(tenant)
|
|
tables = engine.ListRateTables()
|
|
return Response(_ok(RateTableSerializer(tables, many=True).data))
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = RateTableCreateSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
engine = CommissionEngine(tenant)
|
|
table = engine.ConfigureRateTable(
|
|
table_code=ser.ValidatedData['TableCode'],
|
|
table_name=ser.ValidatedData['TableName'],
|
|
entries=ser.ValidatedData['Entries'],
|
|
table_description=ser.ValidatedData.get('TableDescription', ''),
|
|
)
|
|
return Response(_ok(RateTableSerializer(table).data), status=201)
|
|
|
|
|
|
class DispatchView(APIView):
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = DispatchRequestSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
engine = CommissionEngine(tenant)
|
|
try:
|
|
records = engine.Dispatch(
|
|
event_type=ser.ValidatedData['EventType'],
|
|
event_key=ser.ValidatedData['EventKey'],
|
|
total_amount=ser.ValidatedData['TotalAmount'],
|
|
source_user_uuid=ser.ValidatedData.get('SourceUserUUID', ''),
|
|
participants=ser.ValidatedData.get('Participants', {}),
|
|
tier_index=ser.ValidatedData.get('TierIndex', 0),
|
|
payload=ser.ValidatedData.get('Payload', {}),
|
|
auto_settle=ser.ValidatedData.get('AutoSettle', True),
|
|
)
|
|
except CommissionError as e:
|
|
return Response(_err(str(e), 400), status=400)
|
|
return Response(_ok(CommissionRecordSerializer(records, many=True).data), status=201)
|
|
|
|
|
|
class InviteChainDispatchView(APIView):
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = InviteChainDispatchSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
engine = CommissionEngine(tenant)
|
|
try:
|
|
records = engine.BuildInviteChainCommission(
|
|
event_type=ser.ValidatedData['EventType'],
|
|
event_key=ser.ValidatedData['EventKey'],
|
|
total_amount=ser.ValidatedData['TotalAmount'],
|
|
source_user_uuid=ser.ValidatedData['SourceUserUUID'],
|
|
invite_chain=ser.ValidatedData['InviteChain'],
|
|
rule_name=ser.ValidatedData['RuleName'],
|
|
participant_rules=ser.ValidatedData['ParticipantRules'],
|
|
)
|
|
except CommissionError as e:
|
|
return Response(_err(str(e), 400), status=400)
|
|
return Response(_ok(CommissionRecordSerializer(records, many=True).data), status=201)
|
|
|
|
|
|
class QueryView(APIView):
|
|
|
|
def get(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
engine = CommissionEngine(tenant)
|
|
records = engine.QueryRecords(
|
|
participant_id=request.query_params.get('ParticipantID', ''),
|
|
event_type=request.query_params.get('EventType', ''),
|
|
status=request.query_params.get('Status'),
|
|
start_date=request.query_params.get('StartDate'),
|
|
end_date=request.query_params.get('EndDate'),
|
|
limit=int(request.query_params.get('Limit', 50)),
|
|
)
|
|
return Response(_ok(CommissionRecordSerializer(records, many=True).data))
|
|
|
|
|
|
class TotalView(APIView):
|
|
|
|
def get(self, request, participant_id):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
engine = CommissionEngine(tenant)
|
|
total = engine.TotalByParticipant(
|
|
participant_id=participant_id,
|
|
start_date=request.query_params.get('StartDate'),
|
|
end_date=request.query_params.get('EndDate'),
|
|
)
|
|
return Response(_ok({'participant_id': participant_id, 'total_amount': str(total)}))
|
|
|
|
|
|
class FeeCalcView(APIView):
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = FeeCalcSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
engine = CommissionEngine(tenant)
|
|
fee = engine.CalculateFee(
|
|
total_amount=ser.ValidatedData['TotalAmount'],
|
|
rate_table_code=ser.ValidatedData['RateTableCode'],
|
|
rate_key=ser.ValidatedData['RateKey'],
|
|
)
|
|
return Response(_ok({
|
|
'TotalAmount': str(ser.ValidatedData['TotalAmount']),
|
|
'Fee': str(fee),
|
|
'NetAmount': str(ser.ValidatedData['TotalAmount'] - fee),
|
|
}))
|
|
|
|
|
|
class PreSettleView(APIView):
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = PreSettleRequestSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
engine = CommissionEngine(tenant)
|
|
ps = engine.PreSettle(
|
|
event_key=ser.ValidatedData['EventKey'],
|
|
external_platform=ser.ValidatedData['ExternalPlatform'],
|
|
external_order_id=ser.ValidatedData['ExternalOrderID'],
|
|
participant_id=ser.ValidatedData['ParticipantID'],
|
|
amount=ser.ValidatedData['Amount'],
|
|
order_amount=ser.ValidatedData.get('OrderAmount', 0),
|
|
participant_role=ser.ValidatedData.get('ParticipantRole', 'worker'),
|
|
confirm_deadline=ser.ValidatedData.get('ConfirmDeadline'),
|
|
)
|
|
return Response(_ok({'settlement_uuid': str(ps.SettlementUUID)}), status=201)
|
|
|
|
|
|
class PreSettleConfirmView(APIView):
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = PreSettleConfirmSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
engine = CommissionEngine(tenant)
|
|
engine.ConfirmPreSettlement(
|
|
event_key=ser.ValidatedData['EventKey'],
|
|
participant_id=ser.ValidatedData.get('ParticipantID', ''),
|
|
confirmed_by=ser.ValidatedData.get('ConfirmedBy', ''),
|
|
)
|
|
return Response(_ok(msg='预结算已确认'))
|
|
|
|
|
|
class EventListView(APIView):
|
|
|
|
def get(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
engine = CommissionEngine(tenant)
|
|
qs = engine.ListEvents(
|
|
event_type=request.query_params.get('EventType', '') or None,
|
|
limit=int(request.query_params.get('Limit', 50)),
|
|
)
|
|
return Response(_ok(CommissionEventSerializer(qs, many=True).data)) |