""" 7-Dimension Scoring Engine with Knockout Criterion for EFINTEL Talent Pool. """ from decimal import Decimal, ROUND_HALF_UP from datetime import date, timedelta from typing import Dict, Any class TalentScoringEngine: # 7-Dimension Official Weighting WEIGHT_CASE_STUDY = Decimal('0.25') # 25% (Knockout if < 70) WEIGHT_PORTFOLIO = Decimal('0.15') # 15% WEIGHT_TECH_SPECIFIC = Decimal('0.15') # 15% WEIGHT_CARDINAL_SKILLS = Decimal('0.15') # 15% WEIGHT_EXPERIENCE = Decimal('0.10') # 10% WEIGHT_PRINCIPLES = Decimal('0.10') # 10% WEIGHT_INNOVATION = Decimal('0.10') # 10% KNOCKOUT_THRESHOLD = Decimal('70.0') APPROVAL_THRESHOLD = Decimal('80.0') RESERVE_THRESHOLD = Decimal('65.0') VALIDITY_DAYS = 365 @classmethod def evaluate( cls, dim_case_study: Decimal, dim_portfolio: Decimal, dim_tech_specific: Decimal, dim_cardinal_skills: Decimal, dim_experience: Decimal, dim_principles_safety: Decimal, dim_innovation_rndi: Decimal, evaluation_date: date = None ) -> Dict[str, Any]: """ Calculates weighted 7D score, evaluates Knockout condition, determines status and validity. """ d1 = Decimal(str(dim_case_study or 0)) d2 = Decimal(str(dim_portfolio or 0)) d3 = Decimal(str(dim_tech_specific or 0)) d4 = Decimal(str(dim_cardinal_skills or 0)) d5 = Decimal(str(dim_experience or 0)) d6 = Decimal(str(dim_principles_safety or 0)) d7 = Decimal(str(dim_innovation_rndi or 0)) # Check Knockout condition on Dimension 1 (Caso Práctico / Prueba Técnica) is_knockout = d1 < cls.KNOCKOUT_THRESHOLD # Calculate weighted total weighted_score = ( (d1 * cls.WEIGHT_CASE_STUDY) + (d2 * cls.WEIGHT_PORTFOLIO) + (d3 * cls.WEIGHT_TECH_SPECIFIC) + (d4 * cls.WEIGHT_CARDINAL_SKILLS) + (d5 * cls.WEIGHT_EXPERIENCE) + (d6 * cls.WEIGHT_PRINCIPLES) + (d7 * cls.WEIGHT_INNOVATION) ).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) # Determine Final Result Status if is_knockout: result_status = 'DESCARTADO' verdict_message = f"Descartado por Criterio Knockout: Caso Práctico ({d1}/100) inferior al mínimo aprobatorio de {cls.KNOCKOUT_THRESHOLD} puntos." elif weighted_score >= cls.APPROVAL_THRESHOLD: result_status = 'APROBADO_CARTERA' verdict_message = f"¡Aprobado en Cartera de Especialistas! Puntaje de {weighted_score}/100 superior al umbral de excelencia ({cls.APPROVAL_THRESHOLD})." elif weighted_score >= cls.RESERVE_THRESHOLD: result_status = 'EN_RESERVA' verdict_message = f"Calificado en Banco de Reserva ({weighted_score}/100). Cumple estándares operacionales para proyectos secundarios o convocatorias de contingencia." else: result_status = 'DESCARTADO' verdict_message = f"Descartado: Puntaje ponderado ({weighted_score}/100) no alcanza el umbral mínimo de corte ({cls.RESERVE_THRESHOLD})." eval_date = evaluation_date or date.today() valid_until = eval_date + timedelta(days=cls.VALIDITY_DAYS) return { 'weighted_score': weighted_score, 'is_knockout': is_knockout, 'result_status': result_status, 'verdict_message': verdict_message, 'valid_until': valid_until, 'breakdown': { 'case_study_weighted': (d1 * cls.WEIGHT_CASE_STUDY).quantize(Decimal('0.01')), 'portfolio_weighted': (d2 * cls.WEIGHT_PORTFOLIO).quantize(Decimal('0.01')), 'tech_specific_weighted': (d3 * cls.WEIGHT_TECH_SPECIFIC).quantize(Decimal('0.01')), 'cardinal_skills_weighted': (d4 * cls.WEIGHT_CARDINAL_SKILLS).quantize(Decimal('0.01')), 'experience_weighted': (d5 * cls.WEIGHT_EXPERIENCE).quantize(Decimal('0.01')), 'principles_weighted': (d6 * cls.WEIGHT_PRINCIPLES).quantize(Decimal('0.01')), 'innovation_weighted': (d7 * cls.WEIGHT_INNOVATION).quantize(Decimal('0.01')), } }