feat: grant signup bonus points
This commit is contained in:
@@ -11,7 +11,13 @@ from django.utils import timezone
|
||||
|
||||
from apps.users.models import UserWallet
|
||||
|
||||
from .models import CallRecord, PointsLedger, RechargeOrder, normalize_resolution
|
||||
from .models import (
|
||||
CallRecord,
|
||||
PointsLedger,
|
||||
RechargeOrder,
|
||||
SignupBonusGrant,
|
||||
normalize_resolution,
|
||||
)
|
||||
from .pricing import quote_recharge_points
|
||||
|
||||
|
||||
@@ -147,6 +153,16 @@ class WalletAdjustment:
|
||||
balance_after: int
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SignupBonusGrantResult:
|
||||
wallet: UserWallet
|
||||
grant: SignupBonusGrant
|
||||
ledger_entry: PointsLedger | None
|
||||
points_granted: int
|
||||
balance_after: int
|
||||
granted: bool
|
||||
|
||||
|
||||
def _validate_positive_points(points: int) -> int:
|
||||
if isinstance(points, bool) or not isinstance(points, int) or points <= 0:
|
||||
raise ValueError("points must be a positive integer")
|
||||
@@ -333,6 +349,60 @@ def adjust_wallet_points(
|
||||
)
|
||||
|
||||
|
||||
def grant_signup_bonus(
|
||||
*,
|
||||
user,
|
||||
points: int = 100,
|
||||
reason: str = "new_user_registration",
|
||||
) -> SignupBonusGrantResult:
|
||||
points = _validate_positive_points(points)
|
||||
ledger_reason = str(reason or "new_user_registration").strip()
|
||||
|
||||
with transaction.atomic():
|
||||
wallet = _locked_wallet_for_user(user)
|
||||
grant, created = SignupBonusGrant.objects.get_or_create(
|
||||
user=user,
|
||||
defaults={"points_granted": points},
|
||||
)
|
||||
if not created:
|
||||
existing_ledger = (
|
||||
PointsLedger.objects.filter(
|
||||
user=user,
|
||||
change_type=PointsLedger.ChangeType.SIGNUP_BONUS,
|
||||
)
|
||||
.order_by("id")
|
||||
.first()
|
||||
)
|
||||
return SignupBonusGrantResult(
|
||||
wallet=wallet,
|
||||
grant=grant,
|
||||
ledger_entry=existing_ledger,
|
||||
points_granted=0,
|
||||
balance_after=wallet.points_balance,
|
||||
granted=False,
|
||||
)
|
||||
|
||||
wallet.points_balance += points
|
||||
wallet.save(update_fields=("points_balance", "updated_at"))
|
||||
|
||||
ledger_entry = PointsLedger.objects.create(
|
||||
user=user,
|
||||
change_type=PointsLedger.ChangeType.SIGNUP_BONUS,
|
||||
points_delta=points,
|
||||
balance_after=wallet.points_balance,
|
||||
reason=ledger_reason,
|
||||
)
|
||||
|
||||
return SignupBonusGrantResult(
|
||||
wallet=wallet,
|
||||
grant=grant,
|
||||
ledger_entry=ledger_entry,
|
||||
points_granted=points,
|
||||
balance_after=ledger_entry.balance_after,
|
||||
granted=True,
|
||||
)
|
||||
|
||||
|
||||
def apply_recharge_payment(payment: RechargePayment) -> RechargeResult:
|
||||
order_no = str(payment.order_no or "").strip()
|
||||
pay_method = _normalize_pay_method(payment.pay_method)
|
||||
|
||||
Reference in New Issue
Block a user