
    ~g5i"                        d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	 ddl
mZ e G d d	             Ze G d
 d             Z G d d      Zy)z(KPI bottleneck and performance analyzer.    )annotations)	dataclass)Any   )KPITreeKPINode)KPICalculatorc                  t    e Zd ZU dZded<   ded<   ded<   ded<   ded<   ded	<   d
ed<   d
ed<   ded<   ddZy)BottleneckInfoz#Information about a KPI bottleneck.strnode_id	node_namefloat | Noneactualtargetachievement_rategapfloatimpact_scoreparent_contributionintdepthc           
         | j                   | j                  | j                  | j                  | j                  | j
                  | j                  | j                  | j                  d	S )Convert to dictionary.	r   r   r   r   r   r   r   r   r   r   selfs    e/var/www/tkim.planitai.co.jp/gemegg/20251207-make-pdf-report/project/planitai-kpi/src/kpi/analyzer.pyto_dictzBottleneckInfo.to_dict   sS     ||kkkk $ 5 588 --#'#;#;ZZ

 
	
    Nreturnzdict[str, Any]__name__
__module____qualname____doc____annotations__r    r    r   r   r      s=    -LN""	J
r    r   c                  j    e Zd ZU dZded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ddZy)PerformanceInfoz#Performance information for a node.r   r   r   categoryr   r   r   r   trendunitc           	         | j                   | j                  | j                  | j                  | j                  | j
                  | j                  | j                  dS )r   r   r   r,   r   r   r   r-   r.   r0   r   s    r   r   zPerformanceInfo.to_dict6   sH     ||kkkk $ 5 5ZZII	
 		
r    Nr!   r#   r)   r    r   r+   r+   )   s5    -LNM""J
I
r    r+   c                  T    e Zd ZdZdddZdddZddZddZddZddZ	dd	Z
dd
Zy)KPIAnalyzerz-Analyzer for KPI performance and bottlenecks.Nc                :    || _         |xs t        |      | _        y)zInitialize analyzer.

        Args:
            tree: KPI tree to analyze.
            calculator: Optional calculator instance.
        N)treer	   
calculator)r   r4   r5   s      r   __init__zKPIAnalyzer.__init__G   s     	$;d(;r    c                   g }| j                   j                  j                         D ]  }|j                  |j                  |j
                  }|+||k  s1| j                  |      }| j                  |      }|j                  t        |j                  |j                  |j                  |j                  ||j                  |||j                  	              |j                  d d       |S )a  Find KPIs that are bottlenecking performance.

        Args:
            threshold: Achievement rate threshold (default 100%).
                       Nodes below this are considered bottlenecks.

        Returns:
            List of bottleneck information, sorted by impact.
        r   c                    | j                   S N)r   )bs    r   <lambda>z.KPIAnalyzer.find_bottlenecks.<locals>.<lambda>z   s
    q~~ r    T)keyreverse)r4   nodesvaluesr   valuer   _calculate_impact_score_calculate_parent_contributionappendr   idnamer   r   sort)r   	thresholdbottlenecksnodeachievementimpactcontributions          r   find_bottleneckszKPIAnalyzer.find_bottlenecksQ   s     -/IIOO**, 	D{{"djj&8//K" Y&55d;#BB4H""" $"&))#zz#{{)4 HH%+,8"jj
	: 	5tDr    c                .   |j                   yt        dd|j                   dz  z
        }|dz  }t        dd|j                  z
        dz  dz  }ddd	d	d
ddd}|j                  |j                  j
                  d      }|dz  }||z   |z   }t        d|      S )zCalculate impact score for a node (0-10 scale).

        Impact is based on:
        - How far below target
        - Depth in tree (shallower = more impact)
        - Category weight
                r   r   d         g      ?g?gffffff?g333333?g      ?)financesales	marketingcustomerproducthr	operation   g      $@)r   maxr   getr,   r@   min)	r   rI   	gap_ratio
base_scoredepth_modifiercategory_weightscategory_weightcategory_modifiertotals	            r   rA   z#KPIAnalyzer._calculate_impact_score~   s       ( 1 5 5 ;<=	]
 QDJJ/!3a7 
 +..t}}/B/BCH+a/^+.??4r    c                   |j                   |j                  y|j                   }|j                  |j                  dk(  ry|j                  }|j                  |_        | j                  j	                  |j
                  |j                  i      }||_        |j                  |j
                  |j                        }|j                  dk(  ry||j                  z
  |j                  z  dz  }|S )zCalculate how much this node contributes to parent's performance.

        Uses simulation to determine the effect of achieving target.
        rO   r   rP   )parentr   r@   r5   simulaterD   r\   )r   rI   rf   original_valuenew_resultsnew_parent_valuerL   s          r   rB   z*KPIAnalyzer._calculate_parent_contribution   s    
 ;;$++"5<<6<<1#4 [[
 oo../EF $
 '??699fllC<<1(6<<76<<G#Mr    c                ^   g }| j                   j                  j                         D ]  }|j                  t	        |j
                  |j                  |j                  j                  |j                  |j                  |j                  | j                  |      |j                                |S )z|Get performance summary for all nodes.

        Returns:
            List of performance information for each node.
        r0   )r4   r>   r?   rC   r+   rD   rE   r,   r@   r   r   _calculate_trendr.   )r   performancesrI   s      r   get_performance_summaryz#KPIAnalyzer.get_performance_summary   s     /1IIOO**, 	D GG"ii!]]00::;;%)%:%://5		 r    c                ^    |j                   y|j                   dk\  ry|j                   dk  ryy)zCalculate trend for a node.

        Note: This is a placeholder. In production, this would
        analyze historical data.
        stablen   	improvingZ   	declining)r   )r   rI   s     r   rl   zKPIAnalyzer._calculate_trend   s8       (  C'""R'r    c                    | j                   j                  }|j                  |j                  |j                  |j
                  |j                  |j                  dS )z`Get KGI summary information.

        Returns:
            Dictionary with KGI summary.
        )rE   r   r   r   r   r.   )r4   rootrE   r@   r   r   r   r.   )r   kgis     r   get_kgi_summaryzKPIAnalyzer.get_kgi_summary   sI     iinn HHiijj # 4 477HH
 	
r    c                   i }| j                   j                  j                         D ]5  }|j                  j                  }||vrg ||<   ||   j                  |       7 i }|j                         D ]  \  }}|D cg c]  }|j                  |j                   }}t        |      |rt        |      t        |      z  nd|rt        |      nd|rt        |      ndt        |D cg c]
  }|dk  s	| c}      d||<    |S c c}w c c}w )zyGet performance summary by category.

        Returns:
            Dictionary mapping category to summary stats.
        NrP   )
node_countavg_achievementmin_achievementmax_achievementbottleneck_count)r4   r>   r?   r,   r@   rC   itemsr   lensumr]   r[   )	r   
categoriesrI   catsummaryr>   nachievement_ratesrs	            r   get_category_summaryz KPIAnalyzer.get_category_summary   s%    02
IIOO**, 	)D--%%C*$"$
3sO""4(		) .0$**, 	JC,1!'(Q5G5G5S""! !
 "%j ) )*S1B-CC=N3'8#9TX=N3'8#9TX$' 1=1QWQ=%GCL	& %! >s   ;DD&
D
1D
r9   )r4   r   r5   zKPICalculator | None)g      Y@)rG   r   r"   zlist[BottleneckInfo])rI   r   r"   r   )r"   zlist[PerformanceInfo])rI   r   r"   r   r!   )r"   zdict[str, dict[str, Any]])r$   r%   r&   r'   r6   rM   rA   rB   rn   rl   rx   r   r)   r    r   r2   r2   D   s/    7<+Z  D<0"
"#r    r2   N)r'   
__future__r   dataclassesr   typingr   r4   r   r   r5   r	   r   r+   r2   r)   r    r   <module>r      sU    . " !  " % 
 
 
8 
 
 
4W Wr    