HH/apps/complaints/management/commands/complaint_source_mapping.py
ismail 7369d08012
All checks were successful
Build and Push Docker Image / build (push) Successful in 4m14s
feat: unified reference numbers + feedback modules QA audit
Reference numbers (unified scheme PREFIX-YYYYMM-HOSP-NNNN, e.g. CMP-202606-HHN-0001):
- new ReferenceSequence model + generate_reference() helper (apps/core)
- Complaint/Inquiry/Observation/Appreciation/Suggestion emit unified refs via save()
- prefix-based auto-routing in public track API (CMP/INQ/OBS trackable; APR/SGT internal-only)
- removed legacy CMP-/INQ- generators in ui_views, integrations, px_sources
- migrations: core.0003_referencesequence, appreciation.0006, feedback.0008, observations.0012
- unit tests (format, sanitization, monthly reset, 40-thread concurrency)

QA audit:
- isolated E2E hospital sandbox mirroring HH-N + 10 role users (create_e2e_isolated_env)
- feedback-modules-audit.spec.ts + audit helper (headed, run-to-completion)
- reports/feedback-modules-qa-report.md

Also bundles accumulated in-progress work across complaints, observations,
organizations, templates, and other modules.
2026-06-14 14:29:23 +03:00

84 lines
2.1 KiB
Python

"""
Source mapping configuration for historical complaint import.
Maps Excel 'جهة الشكوى' values to PXSource objects.
"""
from apps.px_sources.models import PXSource
SOURCE_CODE_MAP = {
# Arabic sources
"وزارة الصحة": "MOH",
"مراجع": "PATIENT",
"المراجع": "PATIENT",
"ذوي المراجع": "FAMILY",
"مجلس الضمان الصحي": "CHI",
# English / code sources
"moh": "MOH",
"cchi": "CCHI",
"chi": "CHI",
"patients": "PATIENT",
"patient": "PATIENT",
"patient relatives": "FAMILY",
"patient's relatives": "FAMILY",
"family member": "FAMILY",
"call center": "CALL-CENTER",
"call-center": "CALL-CENTER",
"staff": "STAFF",
"survey": "SURVEY",
"social media": "SOCIAL-MEDIA",
"social-media": "SOCIAL-MEDIA",
"public form": "PUBL-FORM",
"insurance company": None,
"شركة تأمين": None,
}
def resolve_px_source(source_value: str) -> "PXSource | None":
"""
Resolve an Excel source string to a PXSource instance.
Args:
source_value: Value from the 'جهة الشكوى' column.
Returns:
PXSource instance or None if unmapped/empty.
"""
if not source_value:
return None
normalized = str(source_value).strip()
if not normalized or normalized.replace(".", "", 1).isdigit():
return None
# Direct lookup (case-insensitive)
code = SOURCE_CODE_MAP.get(normalized.lower())
if code is None:
# Try stripping trailing spaces and retry
code = SOURCE_CODE_MAP.get(normalized.lower().strip())
if code is None:
return None
if code == "":
return None
try:
return PXSource.objects.get(code=code)
except PXSource.DoesNotExist:
return None
EXTERNAL_SOURCE_CODES = {"MOH", "CCHI", "CHI"}
def get_complaint_source_type(px_source) -> str:
"""
Determine complaint_source_type based on PXSource.
Only MOH/CHI/CCHI are external; everything else is internal.
"""
if px_source and px_source.code in EXTERNAL_SOURCE_CODES:
return "external"
return "internal"