Improve the inventory page 3
This commit is contained in:
110
shared/utils/batch_generator.py
Normal file
110
shared/utils/batch_generator.py
Normal file
@@ -0,0 +1,110 @@
|
||||
"""
|
||||
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}"
|
||||
Reference in New Issue
Block a user