Add MOC auto-generation service with sequential numbering
This commit is contained in:
90
app/services/moc_generator.py
Normal file
90
app/services/moc_generator.py
Normal 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)
|
||||
Reference in New Issue
Block a user