Guarantee barcode uniqueness in the same fixture

parent 371b5832
...@@ -313,13 +313,14 @@ def calculate_upce_check_digit(data: str) -> str: ...@@ -313,13 +313,14 @@ def calculate_upce_check_digit(data: str) -> str:
return data + str(check_digit) return data + str(check_digit)
def format_bet_id_for_barcode(bet_uuid: str, standard: str) -> str: def format_bet_id_for_barcode(bet_uuid: str, standard: str, counter: int = 0) -> str:
""" """
Format bet UUID for specific barcode standard Format bet UUID for specific barcode standard
Args: Args:
bet_uuid: Original bet UUID bet_uuid: Original bet UUID
standard: Target barcode standard standard: Target barcode standard
counter: Counter to add uniqueness when duplicates occur
Returns: Returns:
Formatted data suitable for the barcode standard Formatted data suitable for the barcode standard
...@@ -333,13 +334,18 @@ def format_bet_id_for_barcode(bet_uuid: str, standard: str) -> str: ...@@ -333,13 +334,18 @@ def format_bet_id_for_barcode(bet_uuid: str, standard: str) -> str:
if standard in ['code128', 'code39']: if standard in ['code128', 'code39']:
# These support alphanumeric, use full UUID for maximum uniqueness # These support alphanumeric, use full UUID for maximum uniqueness
# Add counter to ensure uniqueness if needed
if counter > 0:
clean_uuid = f"{clean_uuid}_{counter}"
return clean_uuid return clean_uuid
elif standard in ['ean13', 'ean8', 'upca', 'upce', 'itf', 'codabar']: elif standard in ['ean13', 'ean8', 'upca', 'upce', 'itf', 'codabar']:
# These require numeric data # These require numeric data
# Convert hex UUID to numeric by taking hash # Convert hex UUID to numeric by taking hash
# Include counter in hash to ensure uniqueness
import hashlib import hashlib
hash_obj = hashlib.md5(bet_uuid.encode()) hash_input = f"{bet_uuid}_{counter}".encode()
hash_obj = hashlib.md5(hash_input)
numeric_hash = str(int(hash_obj.hexdigest()[:12], 16)) numeric_hash = str(int(hash_obj.hexdigest()[:12], 16))
if standard == 'ean13': if standard == 'ean13':
......
...@@ -4572,9 +4572,34 @@ def create_cashier_bet(): ...@@ -4572,9 +4572,34 @@ def create_cashier_bet():
if api_bp.db_manager: if api_bp.db_manager:
barcode_standard = api_bp.db_manager.get_config_value('barcode.standard', 'none') barcode_standard = api_bp.db_manager.get_config_value('barcode.standard', 'none')
if barcode_standard and barcode_standard != 'none': if barcode_standard and barcode_standard != 'none':
# Format bet UUID for barcode # Format bet UUID for barcode, ensuring uniqueness within fixture
from ..utils.barcode_utils import format_bet_id_for_barcode from ..utils.barcode_utils import format_bet_id_for_barcode
barcode_data = format_bet_id_for_barcode(bet_uuid, barcode_standard) from ..database.models import BetModel
# Try to generate unique barcode for this fixture
max_attempts = 100 # Prevent infinite loop
counter = 0
while counter < max_attempts:
barcode_data = format_bet_id_for_barcode(bet_uuid, barcode_standard, counter)
# Check if this barcode already exists for the same fixture
existing_bet = session.query(BetModel).filter_by(
barcode_data=barcode_data,
barcode_standard=barcode_standard,
fixture_id=fixture_id
).first()
if not existing_bet:
# Unique barcode found
break
counter += 1
logger.debug(f"Barcode collision detected for fixture {fixture_id}, trying counter {counter}")
if counter >= max_attempts:
logger.warning(f"Could not generate unique barcode for bet {bet_uuid} in fixture {fixture_id} after {max_attempts} attempts")
barcode_data = None # Fall back to no barcode
new_bet = BetModel( new_bet = BetModel(
uuid=bet_uuid, uuid=bet_uuid,
...@@ -5090,7 +5115,8 @@ def verify_barcode(): ...@@ -5090,7 +5115,8 @@ def verify_barcode():
if barcode_standard: if barcode_standard:
query = query.filter_by(barcode_standard=barcode_standard) query = query.filter_by(barcode_standard=barcode_standard)
bet = query.first() # Order by creation date descending to get the latest bet in case of duplicates
bet = query.order_by(BetModel.created_at.desc()).first()
if not bet: if not bet:
return jsonify({"error": "Bet not found for this barcode"}), 404 return jsonify({"error": "Bet not found for this barcode"}), 404
......
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