Match creation in bet mode

parent 7eef9732
......@@ -2884,9 +2884,11 @@ class GamesThread(ThreadedComponent):
def _select_random_completed_matches(self, count: int, session) -> List[MatchModel]:
"""Select random completed matches from the database (including cancelled and failed)"""
try:
from sqlalchemy.orm import joinedload
# Get all completed matches (status = 'done', 'cancelled', or 'failed')
# Exclude matches from fixtures that contain "_recycle_" in the fixture name
completed_matches = session.query(MatchModel).filter(
completed_matches = session.query(MatchModel).options(joinedload(MatchModel.outcomes)).filter(
MatchModel.status.in_(['done', 'end', 'cancelled', 'failed']),
MatchModel.active_status == True,
~MatchModel.fixture_id.like('%_recycle_%')
......@@ -2976,6 +2978,9 @@ class GamesThread(ThreadedComponent):
fixture_id = f"recycle_{uuid.uuid4().hex[:8]}"
now = datetime.utcnow()
# Determine the status for new matches based on system state
new_match_status = self._determine_new_match_status(fixture_id, session)
# For a new fixture, start match_number from 1
match_number = 1
for old_match in old_matches:
......@@ -2986,7 +2991,7 @@ class GamesThread(ThreadedComponent):
fighter2_township=old_match.fighter2_township,
venue_kampala_township=old_match.venue_kampala_township,
start_time=now,
status='scheduled',
status=new_match_status,
fixture_id=fixture_id,
filename=old_match.filename,
file_sha1sum=old_match.file_sha1sum,
......@@ -3018,7 +3023,7 @@ class GamesThread(ThreadedComponent):
match_number += 1
session.commit()
logger.info(f"Created new fixture {fixture_id} with {len(old_matches)} matches from old completed matches")
logger.info(f"Created new fixture {fixture_id} with {len(old_matches)} matches from old completed matches (status: {new_match_status})")
return fixture_id
except Exception as e:
......@@ -3241,8 +3246,10 @@ class GamesThread(ThreadedComponent):
continue
# Final fallback: return whatever matches are available
try:
logger.warning(f"🚨 All {max_attempts} attempts failed - returning all available matches")
all_matches = session.query(MatchModel).filter(
from sqlalchemy.orm import joinedload
all_matches = session.query(MatchModel).options(joinedload(MatchModel.outcomes)).filter(
MatchModel.status.in_(['done', 'end', 'cancelled', 'failed']),
MatchModel.active_status == True,
~MatchModel.fixture_id.like('%_recycle_%')
......@@ -3255,7 +3262,8 @@ class GamesThread(ThreadedComponent):
else:
# If no matches found with exclusions, recycle the oldest match from database
logger.warning("🚨 No matches available after exclusions - recycling the oldest match from database")
oldest_match = session.query(MatchModel).filter(
from sqlalchemy.orm import joinedload
oldest_match = session.query(MatchModel).options(joinedload(MatchModel.outcomes)).filter(
MatchModel.status.in_(['done', 'end', 'cancelled', 'failed']),
MatchModel.active_status == True
).order_by(MatchModel.created_at.asc()).first()
......@@ -3266,6 +3274,9 @@ class GamesThread(ThreadedComponent):
else:
logger.error("🚨 No completed matches found in database at all")
return []
except Exception as e:
logger.error(f"Failed to select random completed matches with fallback: {e}")
return []
def _get_available_matches_excluding_recent(self, fixture_id: Optional[str], exclude_last_n: int, fighters_only: bool, session) -> List[MatchModel]:
"""Get available matches excluding the last N recent matches in the fixture"""
......@@ -3302,7 +3313,8 @@ class GamesThread(ThreadedComponent):
)
# Query available matches with exclusions
query = session.query(MatchModel).filter(
from sqlalchemy.orm import joinedload
query = session.query(MatchModel).options(joinedload(MatchModel.outcomes)).filter(
MatchModel.status.in_(['done', 'end', 'cancelled', 'failed']),
MatchModel.active_status == True,
~MatchModel.fixture_id.like('%_recycle_%'),
......@@ -3320,27 +3332,25 @@ class GamesThread(ThreadedComponent):
def _determine_new_match_status(self, fixture_id: str, session) -> str:
"""Determine the status for new matches based on system state"""
try:
# Check if system is ingame (has any match with status 'ingame')
ingame_match = session.query(MatchModel).filter(
MatchModel.status == 'ingame',
MatchModel.active_status == True
).first()
# Get betting mode configuration
betting_mode = self._get_betting_mode_config()
if ingame_match:
# System is ingame, check if last 4 matches in the fixture are in 'bet' status
last_4_matches = session.query(MatchModel).filter(
# If betting mode is "all_bets_on_start", new matches should be 'bet'
if betting_mode == "all_bets_on_start":
logger.info(f"Betting mode is 'all_bets_on_start' - new matches will be in bet status")
return 'bet'
# Check if the last match in the fixture is in 'bet' status
last_match = session.query(MatchModel).filter(
MatchModel.fixture_id == fixture_id,
MatchModel.active_status == True
).order_by(MatchModel.match_number.desc()).limit(4).all()
).order_by(MatchModel.match_number.desc()).first()
if len(last_4_matches) >= 4:
# Check if all last 4 matches are in 'bet' status
if all(match.status == 'bet' for match in last_4_matches):
logger.info(f"System is ingame and last 4 matches in fixture {fixture_id} are in bet status - new matches will be in bet status")
if last_match and last_match.status == 'bet':
logger.info(f"Last match in fixture {fixture_id} is in bet status - new matches will be in bet status")
return 'bet'
# Default status
logger.info(f"New matches will be in scheduled status (system not ingame or last 4 matches not all in bet status)")
return 'scheduled'
except Exception as e:
......
......@@ -556,10 +556,11 @@ class MatchTimerComponent(ThreadedComponent):
"""Select random completed matches from the database, excluding matches with same fighters as the last played match"""
try:
from ..database.models import MatchModel
from sqlalchemy.orm import joinedload
# Build query for completed matches
# Exclude matches from fixtures that contain "_recycle_" in the fixture name
query = session.query(MatchModel).filter(
query = session.query(MatchModel).options(joinedload(MatchModel.outcomes)).filter(
MatchModel.status.in_(['done', 'end', 'cancelled', 'failed']),
MatchModel.active_status == True,
~MatchModel.fixture_id.like('%_recycle_%')
......@@ -680,23 +681,14 @@ class MatchTimerComponent(ThreadedComponent):
logger.info(f"Betting mode is 'all_bets_on_start' - new matches will be in bet status")
return 'bet'
# Check if system is ingame (has any match with status 'ingame')
ingame_match = session.query(MatchModel).filter(
MatchModel.status == 'ingame',
MatchModel.active_status == True
).first()
if ingame_match:
# System is ingame, check if last 4 matches in the fixture are in 'bet' status
last_4_matches = session.query(MatchModel).filter(
# Check if the last match in the fixture is in 'bet' status
last_match = session.query(MatchModel).filter(
MatchModel.fixture_id == fixture_id,
MatchModel.active_status == True
).order_by(MatchModel.match_number.desc()).limit(4).all()
).order_by(MatchModel.match_number.desc()).first()
if len(last_4_matches) >= 4:
# Check if all last 4 matches are in 'bet' status
if all(match.status == 'bet' for match in last_4_matches):
logger.info(f"System is ingame and last 4 matches in fixture {fixture_id} are in bet status - new matches will be in bet status")
if last_match and last_match.status == 'bet':
logger.info(f"Last match in fixture {fixture_id} is in bet status - new matches will be in bet status")
return 'bet'
# Default status
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment