Files
bakery-ia/shared/utils/batch_generator.py

110 lines
3.2 KiB
Python
Raw Permalink Normal View History

2025-09-18 08:06:32 +02:00
"""
Shared batch number generator utility
"""
from datetime import datetime
from typing import Optional, Protocol, Dict, Any
from sqlalchemy.ext.asyncio import AsyncSession
import structlog
logger = structlog.get_logger()
class BatchCountProvider(Protocol):
"""Protocol for providing batch counts for a specific tenant and date range"""
async def get_daily_batch_count(
self,
tenant_id: str,
date_start: datetime,
date_end: datetime,
prefix: Optional[str] = None
) -> int:
"""Get the count of batches created today for the given tenant"""
...
class BatchNumberGenerator:
"""Generates unique batch numbers across different services"""
def __init__(self, batch_provider: BatchCountProvider):
self.batch_provider = batch_provider
async def generate_batch_number(
self,
tenant_id: str,
prefix: str = "BATCH",
date: Optional[datetime] = None
) -> str:
"""
Generate a unique batch number with format: {PREFIX}-{YYYYMMDD}-{XXX}
Args:
tenant_id: The tenant ID
prefix: Prefix for the batch number (e.g., "INV", "PROD", "BATCH")
date: Date to use for the batch number (defaults to today)
Returns:
Unique batch number string
"""
try:
# Use provided date or current date
target_date = date or datetime.utcnow()
date_prefix = target_date.strftime("%Y%m%d")
# Calculate date range for the day
today_start = datetime.combine(target_date.date(), datetime.min.time())
today_end = datetime.combine(target_date.date(), datetime.max.time())
# Get count of batches created today with this prefix
daily_count = await self.batch_provider.get_daily_batch_count(
tenant_id=tenant_id,
date_start=today_start,
date_end=today_end,
prefix=prefix
)
# Generate sequential number (starting from 1)
sequence = daily_count + 1
batch_number = f"{prefix}-{date_prefix}-{sequence:03d}"
logger.info(
"Generated batch number",
tenant_id=tenant_id,
prefix=prefix,
date=target_date.date(),
sequence=sequence,
batch_number=batch_number
)
return batch_number
except Exception as e:
logger.error(
"Failed to generate batch number",
tenant_id=tenant_id,
prefix=prefix,
error=str(e)
)
raise
def create_fallback_batch_number(
prefix: str = "BATCH",
date: Optional[datetime] = None,
sequence: int = 1
) -> str:
"""
Create a fallback batch number when database access fails
Args:
prefix: Prefix for the batch number
date: Date to use (defaults to now)
sequence: Sequence number to use
Returns:
Fallback batch number string
"""
target_date = date or datetime.utcnow()
date_prefix = target_date.strftime("%Y%m%d")
return f"{prefix}-{date_prefix}-{sequence:03d}"