Files
new_lottery_bot/account_utils.py
2025-11-15 20:03:49 +09:00

151 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Утилиты для работы с клиентскими счетами
"""
import re
from typing import Optional, List
def validate_account_number(account_number: str) -> bool:
"""
Проверяет корректность формата номера клиентского счета
Формат: XX-XX-XX-XX-XX-XX-XX (7 пар цифр через дефис)
Args:
account_number: Номер счета для проверки
Returns:
bool: True если формат корректен, False иначе
"""
if not account_number:
return False
# Паттерн для 7 пар цифр через дефис
pattern = r'^\d{2}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$'
return bool(re.match(pattern, account_number))
def format_account_number(account_number: str) -> Optional[str]:
"""
Форматирует номер счета, убирая лишние символы
Args:
account_number: Исходный номер счета
Returns:
str: Отформатированный номер счета или None если некорректный
"""
if not account_number:
return None
# Убираем все символы кроме цифр
digits_only = re.sub(r'\D', '', account_number)
# Проверяем что осталось ровно 14 цифр
if len(digits_only) != 14:
return None
# Форматируем как XX-XX-XX-XX-XX-XX-XX
formatted = '-'.join([digits_only[i:i+2] for i in range(0, 14, 2)])
return formatted
def generate_account_number() -> str:
"""
Генерирует случайный номер клиентского счета для тестирования
Returns:
str: Сгенерированный номер счета
"""
import random
# Генерируем 14 случайных цифр
digits = ''.join([str(random.randint(0, 9)) for _ in range(14)])
# Форматируем
return '-'.join([digits[i:i+2] for i in range(0, 14, 2)])
def mask_account_number(account_number: str, show_last_digits: int = 4) -> str:
"""
Маскирует номер счета для безопасного отображения
Args:
account_number: Полный номер счета
show_last_digits: Количество последних цифр для отображения
Returns:
str: Замаскированный номер счета
"""
if not validate_account_number(account_number):
return "Некорректный номер"
if show_last_digits <= 0:
return "**-**-**-**-**-**-**"
# Убираем дефисы для работы с цифрами
digits = account_number.replace('-', '')
# Определяем сколько цифр показать
show_digits = min(show_last_digits, len(digits))
# Создаем маску
masked_digits = '*' * (len(digits) - show_digits) + digits[-show_digits:]
# Возвращаем отформатированный результат (7 пар)
return '-'.join([masked_digits[i:i+2] for i in range(0, 14, 2)])
def parse_accounts_from_message(text: str) -> List[str]:
"""
Извлекает все валидные номера счетов из текста сообщения
Args:
text: Текст сообщения
Returns:
List[str]: Список найденных и отформатированных номеров счетов
"""
if not text:
return []
accounts = []
# Ищем паттерны счетов в тексте (7 пар цифр)
pattern = r'\b\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}\b'
matches = re.findall(pattern, text)
for match in matches:
formatted = format_account_number(match)
if formatted and formatted not in accounts:
accounts.append(formatted)
return accounts
def search_accounts_by_pattern(pattern: str, account_list: List[str]) -> List[str]:
"""
Ищет счета по частичному совпадению (1-2 пары цифр)
Args:
pattern: Паттерн для поиска (например "11-22" или "11")
account_list: Список счетов для поиска
Returns:
List[str]: Список найденных счетов
"""
if not pattern or not account_list:
return []
# Убираем лишние символы из паттерна
clean_pattern = re.sub(r'[^\d-]', '', pattern).strip('-')
if not clean_pattern:
return []
results = []
for account in account_list:
if clean_pattern in account:
results.append(account)
return results