feat(promo): Добавлены промокоды на скидку в процентах
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import logging
|
||||
from typing import Optional
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.future import select
|
||||
from sqlalchemy import delete
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from db.models import ActiveDiscount, PromoCode
|
||||
|
||||
|
||||
async def set_active_discount(
|
||||
session: AsyncSession,
|
||||
user_id: int,
|
||||
promo_code_id: int,
|
||||
discount_percentage: int
|
||||
) -> Optional[ActiveDiscount]:
|
||||
"""
|
||||
Set active discount for user.
|
||||
Returns None if user already has an active discount (enforce one-at-a-time rule).
|
||||
"""
|
||||
# Check if user already has an active discount
|
||||
existing = await get_active_discount(session, user_id)
|
||||
if existing:
|
||||
logging.warning(
|
||||
f"User {user_id} already has active discount (promo_code_id: {existing.promo_code_id}). "
|
||||
f"Cannot activate new discount {promo_code_id}."
|
||||
)
|
||||
return None
|
||||
|
||||
# Create new active discount
|
||||
new_discount = ActiveDiscount(
|
||||
user_id=user_id,
|
||||
promo_code_id=promo_code_id,
|
||||
discount_percentage=discount_percentage,
|
||||
activated_at=datetime.now(timezone.utc)
|
||||
)
|
||||
session.add(new_discount)
|
||||
await session.flush()
|
||||
await session.refresh(new_discount)
|
||||
logging.info(
|
||||
f"Active discount set for user {user_id}: promo_code_id={promo_code_id}, "
|
||||
f"discount={discount_percentage}%"
|
||||
)
|
||||
return new_discount
|
||||
|
||||
|
||||
async def get_active_discount(
|
||||
session: AsyncSession,
|
||||
user_id: int
|
||||
) -> Optional[ActiveDiscount]:
|
||||
"""Get active discount for user if exists."""
|
||||
stmt = select(ActiveDiscount).where(ActiveDiscount.user_id == user_id)
|
||||
result = await session.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
async def clear_active_discount(
|
||||
session: AsyncSession,
|
||||
user_id: int
|
||||
) -> bool:
|
||||
"""
|
||||
Clear active discount for user.
|
||||
Returns True if discount was cleared, False if no discount was found.
|
||||
"""
|
||||
stmt = delete(ActiveDiscount).where(ActiveDiscount.user_id == user_id)
|
||||
result = await session.execute(stmt)
|
||||
await session.flush()
|
||||
cleared = result.rowcount > 0
|
||||
if cleared:
|
||||
logging.info(f"Active discount cleared for user {user_id}")
|
||||
return cleared
|
||||
Reference in New Issue
Block a user