Add MOC auto-generation service with sequential numbering

This commit is contained in:
2025-12-15 00:34:34 +11:00
parent 33dea53c0b
commit 944a679372

View File

@@ -0,0 +1,90 @@
"""MOC Number Generation Service for LEGO Instructions Manager"""
from app.models.set import Set
from app import db
class MOCNumberGenerator:
"""Service for auto-generating MOC (My Own Creation) set numbers"""
DEFAULT_PREFIX = 'MOC'
DEFAULT_START = 10000
@staticmethod
def generate_next_number(prefix=None, user_id=None):
"""
Generate the next available MOC number
Args:
prefix: MOC prefix (default: 'MOC')
user_id: Optional user ID to scope MOC numbers per user
Returns:
str: Next MOC number (e.g., 'MOC-10001')
"""
if prefix is None:
prefix = MOCNumberGenerator.DEFAULT_PREFIX
# Build query for highest MOC number
query = Set.query.filter(
Set.is_moc == True,
Set.set_number.like(f'{prefix}%')
)
# Optionally scope to user
if user_id:
query = query.filter_by(user_id=user_id)
# Get highest MOC number
highest_moc = query.order_by(Set.set_number.desc()).first()
if highest_moc:
try:
# Extract number from format like "MOC-12345" or "MOC12345"
number_part = highest_moc.set_number.replace(prefix, '').replace('-', '').strip()
current_num = int(number_part)
next_num = current_num + 1
except (ValueError, AttributeError):
# If parsing fails, start from default
next_num = MOCNumberGenerator.DEFAULT_START
else:
next_num = MOCNumberGenerator.DEFAULT_START
return f'{prefix}-{next_num}'
@staticmethod
def validate_moc_number(set_number, user_id=None):
"""
Check if a MOC number is available
Args:
set_number: MOC number to validate
user_id: Optional user ID to check user-specific availability
Returns:
bool: True if available, False if already in use
"""
query = Set.query.filter_by(set_number=set_number)
if user_id:
query = query.filter_by(user_id=user_id)
existing = query.first()
return existing is None
@staticmethod
def is_moc_number(set_number, prefix=None):
"""
Check if a set number follows MOC format
Args:
set_number: Set number to check
prefix: MOC prefix to match (default: 'MOC')
Returns:
bool: True if it's a MOC number
"""
if prefix is None:
prefix = MOCNumberGenerator.DEFAULT_PREFIX
return set_number.upper().startswith(prefix)