Guarantee barcode uniqueness in the same fixture

parent 371b5832
......@@ -313,13 +313,14 @@ def calculate_upce_check_digit(data: str) -> str:
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
Args:
bet_uuid: Original bet UUID
standard: Target barcode standard
counter: Counter to add uniqueness when duplicates occur
Returns:
Formatted data suitable for the barcode standard
......@@ -333,13 +334,18 @@ def format_bet_id_for_barcode(bet_uuid: str, standard: str) -> str:
if standard in ['code128', 'code39']:
# 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
elif standard in ['ean13', 'ean8', 'upca', 'upce', 'itf', 'codabar']:
# These require numeric data
# Convert hex UUID to numeric by taking hash
# Include counter in hash to ensure uniqueness
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))
if standard == 'ean13':
......
......@@ -4572,9 +4572,34 @@ def create_cashier_bet():
if api_bp.db_manager:
barcode_standard = api_bp.db_manager.get_config_value('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
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(
uuid=bet_uuid,
......@@ -5090,7 +5115,8 @@ def verify_barcode():
if 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:
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