Improve the inventory page 3

This commit is contained in:
Urtzi Alfaro
2025-09-18 08:06:32 +02:00
parent dcb3ce441b
commit ae77a0e1c5
31 changed files with 2376 additions and 1774 deletions

View File

@@ -14,11 +14,12 @@ from .base import ProductionBaseRepository
from app.models.production import ProductionBatch, ProductionStatus, ProductionPriority
from shared.database.exceptions import DatabaseError, ValidationError
from shared.database.transactions import transactional
from shared.utils.batch_generator import BatchCountProvider, BatchNumberGenerator, create_fallback_batch_number
logger = structlog.get_logger()
class ProductionBatchRepository(ProductionBaseRepository):
class ProductionBatchRepository(ProductionBaseRepository, BatchCountProvider):
"""Repository for production batch operations"""
def __init__(self, session: AsyncSession, cache_ttl: Optional[int] = 300):
@@ -41,9 +42,17 @@ class ProductionBatchRepository(ProductionBaseRepository):
# Generate batch number if not provided
if "batch_number" not in batch_data or not batch_data["batch_number"]:
batch_data["batch_number"] = await self._generate_batch_number(
batch_data["tenant_id"]
)
try:
batch_generator = BatchNumberGenerator(self)
batch_data["batch_number"] = await batch_generator.generate_batch_number(
tenant_id=batch_data["tenant_id"],
prefix="PROD"
)
logger.info("Generated production batch number", batch_number=batch_data["batch_number"])
except Exception as e:
# Fallback to a simple batch number if generation fails
batch_data["batch_number"] = create_fallback_batch_number("PROD")
logger.warning("Used fallback batch number", batch_number=batch_data["batch_number"], error=str(e))
# Set default values
if "status" not in batch_data:
@@ -314,33 +323,57 @@ class ProductionBatchRepository(ProductionBaseRepository):
logger.error("Error fetching urgent batches", error=str(e))
raise DatabaseError(f"Failed to fetch urgent batches: {str(e)}")
async def _generate_batch_number(self, tenant_id: str) -> str:
"""Generate a unique batch number"""
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 production batches created today for the given tenant"""
try:
# Get current date for prefix
today = datetime.utcnow().date()
date_prefix = today.strftime("%Y%m%d")
# Count batches created today
today_start = datetime.combine(today, datetime.min.time())
today_end = datetime.combine(today, datetime.max.time())
daily_batches = await self.get_multi(
filters={
"tenant_id": tenant_id,
"created_at__gte": today_start,
"created_at__lte": today_end
}
conditions = {
"tenant_id": tenant_id,
"created_at__gte": date_start,
"created_at__lte": date_end
}
if prefix:
# Filter by batch numbers that start with the given prefix
filters_list = [
and_(
ProductionBatch.tenant_id == tenant_id,
ProductionBatch.created_at >= date_start,
ProductionBatch.created_at <= date_end,
ProductionBatch.batch_number.like(f"{prefix}-%")
)
]
result = await self.session.execute(
select(func.count(ProductionBatch.id)).where(and_(*filters_list))
)
else:
batches = await self.get_multi(filters=conditions)
result_count = len(batches)
return result_count
count = result.scalar() or 0
logger.debug(
"Retrieved daily production batch count",
tenant_id=tenant_id,
prefix=prefix,
count=count,
date_start=date_start,
date_end=date_end
)
# Generate sequential number
sequence = len(daily_batches) + 1
batch_number = f"PROD-{date_prefix}-{sequence:03d}"
return batch_number
return count
except Exception as e:
logger.error("Error generating batch number", error=str(e))
# Fallback to timestamp-based number
timestamp = int(datetime.utcnow().timestamp())
return f"PROD-{timestamp}"
logger.error(
"Failed to get daily production batch count",
error=str(e),
tenant_id=tenant_id,
prefix=prefix
)
raise