Files
Django/merchant_ops/services/wallet.py

78 lines
2.7 KiB
Python

"""资金池:划额度、派单扣减。"""
from decimal import Decimal
from django.db import transaction
from django.db.models import F
from merchant_ops.constants import WALLET_ALLOCATE, WALLET_DISPATCH_CONFIRM
from merchant_ops.models import MerchantStaffWallet, MerchantStaffWalletLedger
def get_or_create_wallet(member):
wallet, _ = MerchantStaffWallet.objects.get_or_create(
merchant_id=member.merchant_id,
staff_user_id=member.staff_user_id,
defaults={'member': member},
)
return wallet
def allocate_quota(member, amount, operator_id, remark=''):
amount = Decimal(str(amount))
if amount <= 0:
raise ValueError('划额度必须大于0')
with transaction.atomic():
wallet = MerchantStaffWallet.objects.select_for_update().get(
merchant_id=member.merchant_id,
staff_user_id=member.staff_user_id,
)
wallet.quota_total = F('quota_total') + amount
wallet.save(update_fields=['quota_total'])
wallet.refresh_from_db()
MerchantStaffWalletLedger.objects.create(
wallet=wallet,
merchant_id=member.merchant_id,
staff_user_id=member.staff_user_id,
change_type=WALLET_ALLOCATE,
amount=amount,
balance_after=wallet.quota_available,
operator_id=operator_id,
remark=remark,
)
return wallet
def check_wallet_available(member, amount):
amount = Decimal(str(amount))
wallet = get_or_create_wallet(member)
if amount > wallet.quota_available:
raise ValueError('客服可用额度不足')
def confirm_dispatch_deduct(member, amount, order_id, operator_id):
"""派单成功:扣客服额度。"""
amount = Decimal(str(amount))
with transaction.atomic():
wallet = MerchantStaffWallet.objects.select_for_update().get(
merchant_id=member.merchant_id,
staff_user_id=member.staff_user_id,
)
available = wallet.quota_total - wallet.quota_used - wallet.quota_frozen
if amount > available:
raise ValueError('客服可用额度不足')
wallet.quota_used = F('quota_used') + amount
wallet.save(update_fields=['quota_used'])
wallet.refresh_from_db()
MerchantStaffWalletLedger.objects.create(
wallet=wallet,
merchant_id=member.merchant_id,
staff_user_id=member.staff_user_id,
change_type=WALLET_DISPATCH_CONFIRM,
amount=-amount,
balance_after=wallet.quota_available,
related_order_id=order_id,
operator_id=operator_id,
remark='派单扣额度',
)