Fix entry registration
This commit is contained in:
114
rog/management/commands/check_external_registrations.py
Normal file
114
rog/management/commands/check_external_registrations.py
Normal file
@ -0,0 +1,114 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils import timezone
|
||||
from rog.models import GpsLog
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = '外部システム登録の状況を確認します'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--event-code',
|
||||
type=str,
|
||||
help='特定のイベントコードでフィルタ'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--status',
|
||||
type=str,
|
||||
choices=['pending', 'success', 'failed', 'retry'],
|
||||
help='特定のステータスでフィルタ'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--show-details',
|
||||
action='store_true',
|
||||
help='詳細情報を表示'
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
event_code = options.get('event_code')
|
||||
status = options.get('status')
|
||||
show_details = options['show_details']
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS('外部システム登録状況を確認しています...')
|
||||
)
|
||||
|
||||
# フィルタ条件を構築
|
||||
queryset = GpsLog.objects.filter(
|
||||
serial_number=-1,
|
||||
cp_number="EXTERNAL_REG"
|
||||
)
|
||||
|
||||
if event_code:
|
||||
queryset = queryset.filter(event_code=event_code)
|
||||
|
||||
if status:
|
||||
queryset = queryset.filter(external_registration_status=status)
|
||||
|
||||
# 統計情報
|
||||
total_count = queryset.count()
|
||||
pending_count = queryset.filter(external_registration_status='pending').count()
|
||||
success_count = queryset.filter(external_registration_status='success').count()
|
||||
failed_count = queryset.filter(external_registration_status='failed').count()
|
||||
retry_count = queryset.filter(external_registration_status='retry').count()
|
||||
|
||||
self.stdout.write(f'\n=== 外部システム登録統計 ===')
|
||||
self.stdout.write(f'合計記録数: {total_count}')
|
||||
self.stdout.write(f'保留中: {pending_count}')
|
||||
self.stdout.write(f'成功: {success_count}')
|
||||
self.stdout.write(f'失敗: {failed_count}')
|
||||
self.stdout.write(f'リトライ要求: {retry_count}')
|
||||
|
||||
if show_details and queryset.exists():
|
||||
self.stdout.write(f'\n=== 詳細情報 ===')
|
||||
for record in queryset.order_by('-create_at')[:20]: # 最新20件
|
||||
status_color = self.get_status_color(record.external_registration_status)
|
||||
self.stdout.write(
|
||||
f'[{record.create_at.strftime("%Y-%m-%d %H:%M")}] '
|
||||
f'ゼッケン: {record.zekken_number} | '
|
||||
f'イベント: {record.event_code} | '
|
||||
f'チーム: {record.team_name} | '
|
||||
f'ステータス: {status_color(record.external_registration_status)} | '
|
||||
f'試行回数: {record.external_registration_attempts}'
|
||||
)
|
||||
if record.external_registration_error:
|
||||
self.stdout.write(f' エラー: {record.external_registration_error[:100]}...')
|
||||
|
||||
# リトライが必要な記録をハイライト
|
||||
needs_retry = queryset.filter(
|
||||
external_registration_status__in=['pending', 'retry'],
|
||||
external_registration_attempts__lt=3
|
||||
)
|
||||
|
||||
if needs_retry.exists():
|
||||
self.stdout.write(
|
||||
self.style.WARNING(
|
||||
f'\n注意: {needs_retry.count()}件の記録がリトライを待機中です。'
|
||||
' `python manage.py retry_external_registrations` でリトライできます。'
|
||||
)
|
||||
)
|
||||
|
||||
# 最大試行回数に達した記録をチェック
|
||||
max_attempts_reached = queryset.filter(
|
||||
external_registration_attempts__gte=3,
|
||||
external_registration_status__in=['pending', 'failed', 'retry']
|
||||
)
|
||||
|
||||
if max_attempts_reached.exists():
|
||||
self.stdout.write(
|
||||
self.style.ERROR(
|
||||
f'\n警告: {max_attempts_reached.count()}件の記録が最大試行回数に達しています。'
|
||||
' 手動での確認が必要です。'
|
||||
)
|
||||
)
|
||||
|
||||
def get_status_color(self, status):
|
||||
"""ステータスに応じた色付き表示を返す"""
|
||||
if status == 'success':
|
||||
return self.style.SUCCESS
|
||||
elif status == 'failed':
|
||||
return self.style.ERROR
|
||||
elif status in ['pending', 'retry']:
|
||||
return self.style.WARNING
|
||||
else:
|
||||
return lambda x: x
|
||||
84
rog/management/commands/retry_external_registrations.py
Normal file
84
rog/management/commands/retry_external_registrations.py
Normal file
@ -0,0 +1,84 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils import timezone
|
||||
from rog.models import GpsLog
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = '失敗した外部システム登録をリトライします'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--max-attempts',
|
||||
type=int,
|
||||
default=3,
|
||||
help='最大試行回数 (デフォルト: 3)'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--dry-run',
|
||||
action='store_true',
|
||||
help='実際の処理を実行せず、処理予定の記録のみを表示'
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
max_attempts = options['max_attempts']
|
||||
dry_run = options['dry_run']
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(f'外部システム登録リトライ処理を開始します (最大試行回数: {max_attempts})')
|
||||
)
|
||||
|
||||
# 保留中の外部システム登録を取得
|
||||
pending_records = GpsLog.get_pending_external_registrations().filter(
|
||||
external_registration_attempts__lt=max_attempts
|
||||
)
|
||||
|
||||
if not pending_records.exists():
|
||||
self.stdout.write(
|
||||
self.style.WARNING('リトライが必要な記録が見つかりませんでした。')
|
||||
)
|
||||
return
|
||||
|
||||
self.stdout.write(f'リトライ対象の記録数: {pending_records.count()}')
|
||||
|
||||
if dry_run:
|
||||
self.stdout.write(self.style.WARNING('-- DRY RUN モード --'))
|
||||
for record in pending_records:
|
||||
self.stdout.write(
|
||||
f' ゼッケン番号: {record.zekken_number}, '
|
||||
f'イベント: {record.event_code}, '
|
||||
f'チーム名: {record.team_name}, '
|
||||
f'試行回数: {record.external_registration_attempts}'
|
||||
)
|
||||
return
|
||||
|
||||
# 実際のリトライ処理
|
||||
result = GpsLog.retry_failed_external_registrations(max_attempts)
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f'リトライ完了: 成功 {result["success_count"]}件, '
|
||||
f'失敗 {result["failed_count"]}件, '
|
||||
f'合計処理数 {result["total_processed"]}件'
|
||||
)
|
||||
)
|
||||
|
||||
# 最大試行回数に達した記録があるかチェック
|
||||
max_attempts_reached = GpsLog.get_pending_external_registrations().filter(
|
||||
external_registration_attempts__gte=max_attempts
|
||||
)
|
||||
|
||||
if max_attempts_reached.exists():
|
||||
self.stdout.write(
|
||||
self.style.ERROR(
|
||||
f'警告: {max_attempts_reached.count()}件の記録が最大試行回数に達しました。'
|
||||
' 手動での確認が必要です。'
|
||||
)
|
||||
)
|
||||
|
||||
# 詳細を表示
|
||||
for record in max_attempts_reached[:5]: # 最初の5件のみ表示
|
||||
self.stdout.write(
|
||||
f' ゼッケン番号: {record.zekken_number}, '
|
||||
f'イベント: {record.event_code}, '
|
||||
f'エラー: {record.external_registration_error}'
|
||||
)
|
||||
Reference in New Issue
Block a user