fix: обработка формата 'КАРТА СЧЕТ' в AccountParticipationService
Проблема: - Когда админ отправляет счет в чат и нажимает 'Добавить в розыгрыш' - Используется другой обработчик (account_handlers.py) - Он вызывает add_account_to_lottery() которая НЕ разбирала формат Решение: - Добавлен split() по пробелу в add_account_to_lottery() - Добавлено получение Account и user через AccountService - Теперь сохраняются user_id и account_id - Улучшены сообщения с указанием номера карты Теперь ОБА пути работают: 1. Массовое добавление через админ-панель 2. Добавление из детектированных счетов в чате
This commit is contained in:
@@ -539,6 +539,9 @@ class ParticipationService:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
async def add_participants_by_accounts_bulk(session: AsyncSession, lottery_id: int, account_numbers: List[str]) -> Dict[str, Any]:
|
async def add_participants_by_accounts_bulk(session: AsyncSession, lottery_id: int, account_numbers: List[str]) -> Dict[str, Any]:
|
||||||
"""Массовое добавление участников по номерам счетов"""
|
"""Массовое добавление участников по номерам счетов"""
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
results = {
|
results = {
|
||||||
"added": 0,
|
"added": 0,
|
||||||
"skipped": 0,
|
"skipped": 0,
|
||||||
@@ -551,28 +554,39 @@ class ParticipationService:
|
|||||||
account_input = account_input.strip()
|
account_input = account_input.strip()
|
||||||
if not account_input:
|
if not account_input:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
logger.info(f"DEBUG: Processing account_input={account_input!r}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Разделяем по пробелу: левая часть - номер карты, правая - номер счета
|
# Разделяем по пробелу: левая часть - номер карты, правая - номер счета
|
||||||
parts = account_input.split()
|
parts = account_input.split()
|
||||||
|
logger.info(f"DEBUG: After split: parts={parts}, len={len(parts)}")
|
||||||
|
|
||||||
if len(parts) == 2:
|
if len(parts) == 2:
|
||||||
card_number = parts[0] # Номер клубной карты
|
card_number = parts[0] # Номер клубной карты
|
||||||
account_number = parts[1] # Номер счета
|
account_number = parts[1] # Номер счета
|
||||||
|
logger.info(f"DEBUG: 2 parts - card={card_number!r}, account={account_number!r}")
|
||||||
elif len(parts) == 1:
|
elif len(parts) == 1:
|
||||||
# Если нет пробела, считаем что это просто номер счета
|
# Если нет пробела, считаем что это просто номер счета
|
||||||
card_number = None
|
card_number = None
|
||||||
account_number = parts[0]
|
account_number = parts[0]
|
||||||
|
logger.info(f"DEBUG: 1 part - account={account_number!r}")
|
||||||
else:
|
else:
|
||||||
|
logger.info(f"DEBUG: Invalid parts count={len(parts)}")
|
||||||
results["invalid_accounts"].append(account_input)
|
results["invalid_accounts"].append(account_input)
|
||||||
results["errors"].append(f"Неверный формат: {account_input}")
|
results["errors"].append(f"Неверный формат: {account_input}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Валидируем и форматируем номер счета
|
# Валидируем и форматируем номер счета
|
||||||
|
logger.info(f"DEBUG: Before format_account_number: {account_number!r}")
|
||||||
formatted_account = format_account_number(account_number)
|
formatted_account = format_account_number(account_number)
|
||||||
|
logger.info(f"DEBUG: After format_account_number: {formatted_account!r}")
|
||||||
|
|
||||||
if not formatted_account:
|
if not formatted_account:
|
||||||
card_info = f" (карта: {card_number})" if card_number else ""
|
card_info = f" (карта: {card_number})" if card_number else ""
|
||||||
results["invalid_accounts"].append(account_input)
|
results["invalid_accounts"].append(account_input)
|
||||||
results["errors"].append(f"Неверный формат счета: {account_number}{card_info}")
|
results["errors"].append(f"Неверный формат счета: {account_number}{card_info}")
|
||||||
|
logger.error(f"DEBUG: Format failed for {account_number!r}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Ищем владельца счёта через таблицу Account
|
# Ищем владельца счёта через таблицу Account
|
||||||
|
|||||||
@@ -18,17 +18,34 @@ class AccountParticipationService:
|
|||||||
account_number: str
|
account_number: str
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Добавить счет в розыгрыш
|
Добавить счет в розыгрыш.
|
||||||
|
Поддерживает форматы: "КАРТА СЧЕТ" или просто "СЧЕТ"
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Dict с ключами: success, message, account_number
|
Dict с ключами: success, message, account_number
|
||||||
"""
|
"""
|
||||||
# Валидируем и форматируем
|
# Разделяем по пробелу если есть номер карты
|
||||||
formatted_account = format_account_number(account_number)
|
parts = account_number.split()
|
||||||
if not formatted_account:
|
if len(parts) == 2:
|
||||||
|
card_number = parts[0]
|
||||||
|
account_to_format = parts[1]
|
||||||
|
elif len(parts) == 1:
|
||||||
|
card_number = None
|
||||||
|
account_to_format = parts[0]
|
||||||
|
else:
|
||||||
return {
|
return {
|
||||||
"success": False,
|
"success": False,
|
||||||
"message": f"Неверный формат счета: {account_number}",
|
"message": f"Неверный формат: {account_number}",
|
||||||
|
"account_number": account_number
|
||||||
|
}
|
||||||
|
|
||||||
|
# Валидируем и форматируем только часть счета
|
||||||
|
formatted_account = format_account_number(account_to_format)
|
||||||
|
if not formatted_account:
|
||||||
|
card_info = f" (карта: {card_number})" if card_number else ""
|
||||||
|
return {
|
||||||
|
"success": False,
|
||||||
|
"message": f"Неверный формат счета: {account_to_format}{card_info}",
|
||||||
"account_number": account_number
|
"account_number": account_number
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,24 +66,37 @@ class AccountParticipationService:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
if existing.scalar_one_or_none():
|
if existing.scalar_one_or_none():
|
||||||
|
card_info = f" (карта: {card_number})" if card_number else ""
|
||||||
return {
|
return {
|
||||||
"success": False,
|
"success": False,
|
||||||
"message": f"Счет {formatted_account} уже участвует в розыгрыше",
|
"message": f"Счет {formatted_account}{card_info} уже участвует в розыгрыше",
|
||||||
"account_number": formatted_account
|
"account_number": formatted_account
|
||||||
}
|
}
|
||||||
|
|
||||||
# Добавляем участие
|
# Получаем запись Account и владельца
|
||||||
|
from ..core.registration_services import AccountService
|
||||||
|
from ..core.models import Account
|
||||||
|
|
||||||
|
user = await AccountService.get_account_owner(session, formatted_account)
|
||||||
|
account_record = await session.execute(
|
||||||
|
select(Account).where(Account.account_number == formatted_account)
|
||||||
|
)
|
||||||
|
account_record = account_record.scalar_one_or_none()
|
||||||
|
|
||||||
|
# Добавляем участие с полными данными
|
||||||
participation = Participation(
|
participation = Participation(
|
||||||
lottery_id=lottery_id,
|
lottery_id=lottery_id,
|
||||||
account_number=formatted_account,
|
account_number=formatted_account,
|
||||||
user_id=None # Без привязки к пользователю
|
user_id=user.id if user else None,
|
||||||
|
account_id=account_record.id if account_record else None
|
||||||
)
|
)
|
||||||
session.add(participation)
|
session.add(participation)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
|
||||||
|
card_info = f" (карта: {card_number})" if card_number else ""
|
||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
"message": f"Счет {formatted_account} добавлен в розыгрыш",
|
"message": f"Счет {formatted_account}{card_info} добавлен в розыгрыш",
|
||||||
"account_number": formatted_account
|
"account_number": formatted_account
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user