fix(promo): Исправлена ошибка с удалением промокода на скидку
Исправлен баг, когда промокод на скидку не мог быть удалён, если пользователь применил скидку, но не воспользовался ей. Добавлено истечение времени действия промокода, даже если промокод на скидку уже был введён
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime, timezone
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from typing import Optional, Tuple, Dict
|
from typing import Optional, Tuple, Dict
|
||||||
from aiogram import Bot
|
from aiogram import Bot
|
||||||
@@ -168,6 +168,16 @@ class PromoCodeService:
|
|||||||
await active_discount_dal.clear_active_discount(session, user_id)
|
await active_discount_dal.clear_active_discount(session, user_id)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# Check if promo code has expired
|
||||||
|
if promo.valid_until and promo.valid_until <= datetime.now(timezone.utc):
|
||||||
|
# Promo code expired - clear the discount
|
||||||
|
logging.info(
|
||||||
|
f"Promo code {promo.code} expired (valid_until: {promo.valid_until}). "
|
||||||
|
f"Clearing active discount for user {user_id}"
|
||||||
|
)
|
||||||
|
await active_discount_dal.clear_active_discount(session, user_id)
|
||||||
|
return None
|
||||||
|
|
||||||
return (active_discount.discount_percentage, promo.code)
|
return (active_discount.discount_percentage, promo.code)
|
||||||
|
|
||||||
def calculate_discounted_price(
|
def calculate_discounted_price(
|
||||||
|
|||||||
@@ -69,3 +69,20 @@ async def clear_active_discount(
|
|||||||
if cleared:
|
if cleared:
|
||||||
logging.info(f"Active discount cleared for user {user_id}")
|
logging.info(f"Active discount cleared for user {user_id}")
|
||||||
return cleared
|
return cleared
|
||||||
|
|
||||||
|
|
||||||
|
async def clear_active_discounts_by_promo_code(
|
||||||
|
session: AsyncSession,
|
||||||
|
promo_code_id: int
|
||||||
|
) -> int:
|
||||||
|
"""
|
||||||
|
Clear all active discounts associated with a specific promo code.
|
||||||
|
Returns the number of discounts cleared.
|
||||||
|
"""
|
||||||
|
stmt = delete(ActiveDiscount).where(ActiveDiscount.promo_code_id == promo_code_id)
|
||||||
|
result = await session.execute(stmt)
|
||||||
|
await session.flush()
|
||||||
|
count = result.rowcount
|
||||||
|
if count > 0:
|
||||||
|
logging.info(f"Cleared {count} active discount(s) for promo_code_id={promo_code_id}")
|
||||||
|
return count
|
||||||
|
|||||||
@@ -132,16 +132,29 @@ async def update_promo_code(session: AsyncSession, promo_id: int,
|
|||||||
|
|
||||||
|
|
||||||
async def delete_promo_code(session: AsyncSession, promo_id: int) -> Optional[PromoCode]:
|
async def delete_promo_code(session: AsyncSession, promo_id: int) -> Optional[PromoCode]:
|
||||||
|
from db.dal import active_discount_dal
|
||||||
|
|
||||||
promo = await get_promo_code_by_id(session, promo_id)
|
promo = await get_promo_code_by_id(session, promo_id)
|
||||||
if not promo:
|
if not promo:
|
||||||
return None
|
return None
|
||||||
# First, delete related activations due to foreign key constraint
|
|
||||||
|
# 1. Clear all active discounts referencing this promo code
|
||||||
|
await active_discount_dal.clear_active_discounts_by_promo_code(session, promo_id)
|
||||||
|
|
||||||
|
# 2. Set promo_code_id to NULL in payments table to avoid FK violation
|
||||||
|
stmt = update(Payment).where(Payment.promo_code_id == promo_id).values(promo_code_id=None)
|
||||||
|
await session.execute(stmt)
|
||||||
|
|
||||||
|
# 3. Delete related activations
|
||||||
activations = await get_promo_activations_by_code_id(session, promo_id)
|
activations = await get_promo_activations_by_code_id(session, promo_id)
|
||||||
for activation in activations:
|
for activation in activations:
|
||||||
await session.delete(activation)
|
await session.delete(activation)
|
||||||
|
|
||||||
|
# 4. Delete the promo code itself
|
||||||
await session.delete(promo)
|
await session.delete(promo)
|
||||||
await session.flush()
|
await session.flush()
|
||||||
|
|
||||||
|
logging.info(f"Promo code '{promo.code}' (ID: {promo_id}) deleted successfully")
|
||||||
return promo
|
return promo
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user