""" Unified reference-number generator. Format: {PREFIX}-{YYYYMM}-{HOSPITAL_TOKEN}-{SEQ:04d} e.g. CMP-202606-HHN-0001 PREFIX module prefix (CMP/INQ/OBS/APR/SGT) YYYYMM creation month HOSPITAL_TOKEN hospital.code sanitized to uppercase alphanumerics (HH-N -> HHN, E2E-HOSP -> E2EHOSP); "GEN" when no hospital SEQ 4-digit monthly sequence per (prefix, hospital, month) The sequence is allocated atomically via ReferenceSequence so it is safe under concurrent submissions. Legacy references keep their old format (no migration of historical data); only new records use this generator. """ import re from datetime import datetime _TOKEN_RE = re.compile(r"[^A-Z0-9]") def sanitize_hospital_token(hospital) -> str: """Derive a clean, format-safe token from a hospital instance.""" code = getattr(hospital, "code", None) if hospital else None if not code: return "GEN" token = _TOKEN_RE.sub("", str(code).upper()) return token or "GEN" def generate_reference(prefix: str, hospital) -> str: """Generate a unified reference number for the given module prefix.""" from apps.core.models import ReferenceSequence prefix = (prefix or "").upper() token = sanitize_hospital_token(hospital) year_month = datetime.now().strftime("%Y%m") number = ReferenceSequence.next_number(prefix, token, year_month) return f"{prefix}-{year_month}-{token}-{number:04d}"