62 lines
2.1 KiB
Python
62 lines
2.1 KiB
Python
"""Reward redemption validators — Phase 7.3."""
|
|
from __future__ import annotations
|
|
|
|
from shared.exceptions import AppError
|
|
|
|
from app.models.foundation import Reward
|
|
from app.models.types import MemberStatus, RedemptionStatus, RewardStatus
|
|
|
|
|
|
def ensure_reward_active(reward: Reward) -> None:
|
|
if reward.is_deleted or reward.status != RewardStatus.ACTIVE:
|
|
raise AppError(
|
|
"پاداش فعال نیست",
|
|
status_code=409,
|
|
error_code="reward_not_active",
|
|
)
|
|
|
|
|
|
def ensure_stock_available(reward: Reward) -> None:
|
|
if reward.stock_limit is not None and reward.redeemed_count >= reward.stock_limit:
|
|
raise AppError(
|
|
"موجودی پاداش تمام شده است",
|
|
status_code=409,
|
|
error_code="reward_stock_exhausted",
|
|
)
|
|
|
|
|
|
def ensure_max_per_member(current_count: int, max_per_member: int | None) -> None:
|
|
if max_per_member is not None and current_count >= max_per_member:
|
|
raise AppError(
|
|
"سقف بازخرید این پاداش برای این عضو تکمیل شده است",
|
|
status_code=409,
|
|
error_code="reward_max_per_member_exceeded",
|
|
)
|
|
|
|
|
|
def ensure_member_active(status: MemberStatus) -> None:
|
|
if status != MemberStatus.ACTIVE:
|
|
raise AppError(
|
|
"عضو فعال نیست",
|
|
status_code=409,
|
|
error_code="member_not_active",
|
|
)
|
|
|
|
|
|
def ensure_fulfillable(status: RedemptionStatus) -> None:
|
|
if status != RedemptionStatus.PENDING:
|
|
raise AppError(
|
|
"فقط درخواستهای در انتظار قابل تحویل هستند",
|
|
status_code=409,
|
|
error_code="redemption_not_pending",
|
|
)
|
|
|
|
|
|
def ensure_cancellable(status: RedemptionStatus) -> None:
|
|
if status != RedemptionStatus.PENDING:
|
|
raise AppError(
|
|
"فقط درخواستهای در انتظار قابل لغو هستند",
|
|
status_code=409,
|
|
error_code="redemption_not_pending",
|
|
)
|