diff --git a/services/production/app/services/quality_template_service.py b/services/production/app/services/quality_template_service.py index aceea692..e5033462 100644 --- a/services/production/app/services/quality_template_service.py +++ b/services/production/app/services/quality_template_service.py @@ -5,6 +5,7 @@ Handles quality template operations with business rules and validation """ from sqlalchemy.ext.asyncio import AsyncSession +from sqlalchemy import select, func from typing import List, Optional, Tuple from uuid import UUID, uuid4 from datetime import datetime, timezone @@ -37,6 +38,17 @@ class QualityTemplateService: - Validates template configuration """ try: + # Auto-generate template code if not provided + if not template_data.template_code: + template_data.template_code = await self._generate_template_code( + tenant_id, + template_data.check_type, + template_data.name + ) + logger.info("Auto-generated template code", + template_code=template_data.template_code, + check_type=template_data.check_type) + # Business Rule: Validate template code uniqueness if template_data.template_code: exists = await self.repository.check_template_code_exists( @@ -432,6 +444,74 @@ class QualityTemplateService: error=str(e)) raise + async def _generate_template_code( + self, + tenant_id: str, + check_type: str, + template_name: str + ) -> str: + """ + Generate unique template code for quality check template + Format: TPL-{TYPE}-{SEQUENCE} + Examples: + - Product Quality → TPL-PQ-0001 + - Process Hygiene → TPL-PH-0001 + - Equipment → TPL-EQ-0001 + - Safety → TPL-SA-0001 + - Temperature Control → TPL-TC-0001 + + Following the same pattern as inventory SKU and order number generation + """ + try: + # Map check_type to 2-letter prefix + type_map = { + 'product_quality': 'PQ', + 'process_hygiene': 'PH', + 'equipment': 'EQ', + 'safety': 'SA', + 'cleaning': 'CL', + 'temperature': 'TC', + 'documentation': 'DC' + } + + # Get prefix from check_type, fallback to first 2 chars of name + type_prefix = type_map.get(check_type.lower()) + if not type_prefix: + # Fallback: use first 2 chars of template name or check_type + name_for_prefix = template_name or check_type + type_prefix = name_for_prefix[:2].upper() if len(name_for_prefix) >= 2 else "TP" + + tenant_uuid = UUID(tenant_id) + + # Count existing templates with this prefix for this tenant + stmt = select(func.count(QualityCheckTemplate.id)).where( + QualityCheckTemplate.tenant_id == tenant_uuid, + QualityCheckTemplate.template_code.like(f"TPL-{type_prefix}-%") + ) + result = await self.db.execute(stmt) + count = result.scalar() or 0 + + # Generate sequential number + sequence = count + 1 + template_code = f"TPL-{type_prefix}-{sequence:04d}" + + logger.info("Generated template code", + template_code=template_code, + type_prefix=type_prefix, + sequence=sequence, + tenant_id=tenant_id) + + return template_code + + except Exception as e: + logger.error("Error generating template code, using fallback", + error=str(e), + check_type=check_type) + # Fallback to UUID-based code + fallback_code = f"TPL-{uuid4().hex[:8].upper()}" + logger.warning("Using fallback template code", template_code=fallback_code) + return fallback_code + def _validate_template_configuration( self, template_data: dict