TorbatYar/backend/services/loyalty/app/validators/rewards.py
Mortezakoohjani 071c484530 Ship Loyalty phases 7.2-7.6 (points through wallet) with production deploy.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 21:27:22 +03:30

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",
)