"""资金池:划额度、派单扣减。""" 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='派单扣额度', )