fix: исправлен парсинг клубной карты из текста кабинета

- Клубная карта теперь извлекается как отдельное число ПОСЛЕ счета и суммы
- Формат: кабинет дата время СЧЕТ сумма КЛУБНАЯ_КАРТА
- Пример: 'Viposnova 16-11-2025 13:48:51 21-04-80-64-68-25-68 0.00 2521'
- Карта: 2521 (последнее 4-значное число), а НЕ последние 4 цифры счета
- Поиск карты после счета с пропуском сумм (содержат точку)
This commit is contained in:
2025-11-17 10:54:30 +09:00
parent 79eb66cf51
commit babaee0ca3
3 changed files with 39 additions and 35 deletions

View File

@@ -1 +1 @@
948258 960923

View File

@@ -53,7 +53,7 @@ async def detect_account_input(message: Message, state: FSMContext):
if not accounts: if not accounts:
return # Счета не обнаружены, пропускаем return # Счета не обнаружены, пропускаем
# Извлекаем номера клубных карт из последних 4 цифр каждого счета # Извлекаем номера клубных карт и определяем владельцев
from ..core.services import UserService from ..core.services import UserService
from ..core.registration_services import AccountService from ..core.registration_services import AccountService
@@ -61,41 +61,34 @@ async def detect_account_input(message: Message, state: FSMContext):
accounts_with_owners = [] accounts_with_owners = []
for account in accounts: for account in accounts:
# Извлекаем только номер счета (без карты если есть) # Парсим строку счета: может быть "КАРТА СЧЕТ" или просто "СЧЕТ"
parts = account.split() parts = account.split()
account_number = parts[-1] if parts else account
# Извлекаем последние 4 цифры (номер клубной карты) club_card = None
digits_only = account_number.replace('-', '').replace(' ', '') account_number = None
if len(digits_only) >= 4:
club_card = digits_only[-4:] # Последние 4 цифры
# Ищем пользователя по номеру клубной карты if len(parts) == 2:
# Формат: "КАРТА СЧЕТ" (например "2521 21-04-80-64-68-25-68")
club_card = parts[0]
account_number = parts[1]
elif len(parts) == 1:
# Формат: только "СЧЕТ" (например "21-04-80-64-68-25-68")
account_number = parts[0]
# Если есть номер клубной карты, ищем владельца
user = None
owner_info = None
if club_card:
user = await UserService.get_user_by_club_card(session, club_card) user = await UserService.get_user_by_club_card(session, club_card)
if user: if user:
owner_info = f"@{user.username}" if user.username else user.first_name owner_info = f"@{user.username}" if user.username else user.first_name
accounts_with_owners.append({
'account': account, accounts_with_owners.append({
'club_card': club_card, 'account': account,
'owner': owner_info, 'club_card': club_card,
'user_id': user.id 'owner': owner_info,
}) 'user_id': user.id if user else None
else: })
accounts_with_owners.append({
'account': account,
'club_card': club_card,
'owner': None,
'user_id': None
})
else:
# Счет неверного формата
accounts_with_owners.append({
'account': account,
'club_card': None,
'owner': None,
'user_id': None
})
# Сохраняем счета в состоянии # Сохраняем счета в состоянии
await state.update_data( await state.update_data(

View File

@@ -105,6 +105,7 @@ def parse_accounts_from_message(text: str) -> List[str]:
Также обрабатывает текст из кабинета с мусором: Также обрабатывает текст из кабинета с мусором:
"Viposnova 16-11-2025 22:19:36 17-24-66-42-38-31-53 0.00 2918" "Viposnova 16-11-2025 22:19:36 17-24-66-42-38-31-53 0.00 2918"
Формат: кабинет дата время СЧЕТ сумма КЛУБНАЯ_КАРТА
Args: Args:
text: Текст сообщения text: Текст сообщения
@@ -130,9 +131,19 @@ def parse_accounts_from_message(text: str) -> List[str]:
if re.match(r'^\d{2}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$', part): if re.match(r'^\d{2}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$', part):
formatted = format_account_number(part) formatted = format_account_number(part)
if formatted and formatted not in accounts: if formatted and formatted not in accounts:
# Проверяем предыдущую часть на номер карты (4 цифры) # Проверяем СЛЕДУЮЩУЮ часть после сумм на номер карты (4 цифры)
if i > 0 and re.match(r'^\d{4}$', parts[i-1]): # Формат: ... СЧЕТ СУММА КАРТА
card = parts[i-1] # Пропускаем части с суммами (содержат точку или начинаются с 0.)
card = None
for j in range(i + 1, len(parts)):
if re.match(r'^\d{4}$', parts[j]):
card = parts[j]
break
# Если нашли не сумму и не карту - выходим
if not re.match(r'^\d+\.\d+$', parts[j]):
break
if card:
full_account = f"{card} {formatted}" full_account = f"{card} {formatted}"
if full_account not in accounts: if full_account not in accounts:
accounts.append(full_account) accounts.append(full_account)