
    /iE                        d dl Z d dlmZmZ d dlmZmZmZ d dlmZm	Z	m
Z
mZmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&  e jN                  e(      Z) G d d      Z*y)    N)datetime	timedelta)OptionalDictTuple)selectfuncand_descor_)AsyncSession)
joinedload)	Violation)Product)Vendor)DashboardResponse
KPISummaryActiveViolationsKPIMonitoredProductsKPIAveragePriceDiscountKPIViolationTrendChartTrendDataPointViolationAnalysisMarketplaceAnalysisVendorAnalysisProductAnalysisHighestDiscountAnalysisFinancialImpactAnalysisRecentViolationsPanelRecentViolationItemc                      e Zd ZdZededefd       Zededefd       Z	edede
fd       Zededefd       Zededefd       Zededee   fd	       Zededee   fd
       Zededee   fd       Zededee   fd       Zededefd       Zededefd       Ze	 ddededefd       Zedede fd       Z!y)DashboardServicez5Service for dashboard data aggregation and analytics.dbreturnc                   K   | j                  t        t        j                  t        j
                              j                  t        j                  j                  d                   d{   }|j                         xs d}| j                  t        t        j                  t        j                              j                  t        j                  j                  d                   d{   }|j                         xs d}| j                  t        t        j                  t        j                  t        j                                    j                  t        t        j                  j                  d      t        j                  j                  d                         d{   }|j                         xs d}| j                  t        t        j                  t        j                  t        j                                     j                  t        t        j                  j                  d      t        j                   j                  d      t        j                  j                  d      t        j"                  dk(                     d{   }|j                         xs d}||z   }	| j                  t        t        j                  t        j                  t        j$                                    j                  t        j                  j                  d                   d{   }
|
j                         xs d}|dk\  rd}n
|dk\  rd}nd}t'        |||	||	      S 7 7 7 7 7 Ew)
a  
        Get KPI data for active violations.
        
        Returns:
            ActiveViolationsKPI with:
            - total_active_violations: Count of violations without notification sent
            - total_detections: Sum of confirmation_count
            - offending_vendors_count: Distinct vendors with violations
            - affected_products_count: Distinct products with violations
        Nr   
discovered
   critical   activelow)total_active_violationstotal_detectionsoffending_vendors_countaffected_products_countstatus)executer   r	   countr   idwherenotification_sent_atis_scalarsumconfirmation_countdistinct	vendor_idr
   isnotvendor_namesource_typeproduct_namer   )r#   active_violations_resulttotal_activedetections_resultr-   offending_vendors_resultoffending_vendorsdiscovered_vendors_resultdiscovered_vendorstotal_offending_vendorsaffected_products_resultaffected_productsr0   s                D/var/www/html/marco-python-backend/app/services/dashboard_service.pyget_active_violations_kpiz*DashboardService.get_active_violations_kpi#   s     *,4::ill+,2293Q3Q3U3UVZ3[\*
 $
  0668=A #%**488I889:@@A_A_AcAcdhAij#
 
 -335: *,4::dmmI,?,?@ABU2266t<''--d3*
 $
  5;;=B +-**4::dmmI,A,ABCDU2266t<))//5''++D1))\9	
+
 
%
! 7==?D1"36H"H *,4::dmmI,B,BCDEU91155d;<*
 $
  5;;=B 2FQFF"$0-$;$5
 	
k$

$

%
$
s^   A+M=-M0.BM=0M31B<M=-M6.C,M=M9BM=5M;6;M=3M=6M=9M=;M=c                 ,  K   | j                  t        t        j                  t        j
                              j                  t        j                  j                  d                   d{   }|j                         xs d}t        |      S 7 $w)z
        Get KPI data for monitored products.
        
        Returns:
            MonitoredProductsKPI with total monitored products count
        TNr   )total_monitored_products)r1   r   r	   r2   r   r3   r4   r0   r6   r7   r   )r#   resulttotal_monitoreds      rJ   get_monitored_products_kpiz+DashboardService.get_monitored_products_kpim   sl      zz4::gjj)*001C1CD1IJ
 
 !--/.Q#_MM
s   A+B-B.%Bc           
        K   | j                  t        t        j                  t        j
                              j                  t        t        j                  j                  d      t        j
                  j                  d                         d{   }|j                         xs d}| j                  t        t        j                  t        j                              j                  t        t        j                  j                  d      t        j
                  j                  d                         d{   }|j                         xs d}|dkD  r||z  nd}t        t        |d            S 7 7 <w)a+  
        Get KPI data for average discount percentage.
        
        Calculation: (Sum of percentage_difference / Total active violations)
        Only includes non-null percentage differences
        
        Returns:
            AveragePriceDiscountKPI with average discount percentage
        Nr              )average_discount_percentage)r1   r   r	   r8   r   percentage_differencer4   r
   r5   r6   r<   r7   r2   r3   r   round)r#   
sum_resultsum_percentagecount_resultr2   average_discounts         rJ   get_average_discount_kpiz)DashboardService.get_average_discount_kpi|   s.     ::488I;;<=U2266t<3399$?
 

 $**,1  ZZ4::ill+,U2266t<3399$?
 
 ##%* 8=qyNU2c&5IY[\C]^^5

s%   BE=E9B)E=>E;?;E=;E=c                    K   t         j                  |        d{   }t         j                  |        d{   }t         j                  |        d{   }t	        |||      S 7 L7 17 w)zw
        Get complete KPI summary section.
        
        Returns:
            KPISummary with all KPI cards
        N)active_violationsmonitored_productsrZ   )r"   rK   rP   r[   r   )r#   r]   r^   rZ   s       rJ   get_kpi_summaryz DashboardService.get_kpi_summary   sh      #3"L"LR"PP#3#N#Nr#RR!1!J!J2!NN/1-
 	
	 QRNs1   A.A(A.A*A.A,A.*A.,A.c                   K   t        j                         t        d      z
  }| j                  t	        t        j                  t        j                        j                  d      t        j                  t        j                        j                  d            j                  t        j                  |k\        j                  t        j                  t        j                              j                  t        j                  t        j                                     d{   }|j                         }|D ci c]  \  }}t!        |      | }}}g }t#        d      D ]m  }t        j                         t        d|z
        z
  j                         }t!        |      }	|j%                  |	d      }|j'                  t)        |	|             o t+        |	      S 7 c c}}w w)
z
        Get 30-day violation trend data.
        
        Returns:
            ViolationTrendChart with daily violation counts for last 30 days
           )daysdater2   N   r   )rc   violation_count)
trend_data)r   utcnowr   r1   r   r	   rc   r   violation_datelabelr2   r3   r4   group_byorder_byallstrrangegetappendr   r   )
r#   thirty_days_agorN   violations_by_daterc   r2   violation_dictrf   idate_strs
             rJ   get_30day_violation_trendz*DashboardService.get_30day_violation_trend   su     #//+iR.@@ zz		)22399&A

9<<(..w7 U9++>?Xdii	 8 89:Xdii	 8 89:
 
 $ZZ\ ?QQ{tU#d)U*QQ 
r 	AOO%	rAv(>>DDFD4yH"&&x3EHeD		 #j993
 Rs%   D G&"G#G&<G BG& G&c           
      R  K   | j                  t        t        j                  t	        j
                  t        j                        j                  d            j                  t        t        j                  j                  d      t        j                  j                  d                  j                  t        j                        j                  t        d            j!                  d             d{   }|j#                         }|rt%        |d   xs d|d         S y7 .w)z
        Get marketplace with most active violations.
        
        Returns:
            MarketplaceAnalysis with marketplace name and violation count
        re   N   r   Unknown)marketplace_namere   )r1   r   r   marketplacer	   r2   r3   ri   r4   r
   r5   r6   r<   rj   rk   r   limitfirstr   r#   rN   rows      rJ   $get_marketplace_with_most_violationsz5DashboardService.get_marketplace_with_most_violations   s      zz%%

9<<(../@A U2266t<))//5 Xi++,Xd,-.U1X
 
  lln&!$Q!49 #A  -
s   C4D'6D%7/D'c           
        K   | j                  t        t        j                  t	        j
                  t        j                        j                  d            j                  t        t        j                  t        j                  k(        j                  t        t        j                  j                  d      t        j                  dk(              j!                  t        j                        j#                  t%        d            j'                  d             d{   }|j)                         }|rt+        |d   |d         S | j                  t        t        j,                  t	        j
                  t        j                        j                  d            j                  t        t        j                  j                  d      t        j,                  j/                  d      t        j                  dk(              j!                  t        j,                        j#                  t%        d            j'                  d             d{   }|j)                         }|rt+        |d   xs d|d         S y7 ^7 1w)	z
        Get vendor with most active violations.
        Prioritizes registered vendors, but includes discovered vendors.
        
        Returns:
            VendorAnalysis with vendor name and violation count
        re   N
registeredrx   r   )r=   re   r&   ry   )r1   r   r   namer	   r2   r   r3   ri   joinr;   r4   r
   r5   r6   r>   rj   rk   r   r|   r}   r   r=   r<   r~   s      rJ   get_most_offending_vendorz*DashboardService.get_most_offending_vendor   s     zz

9<<(../@A T)Y00FII=>U2266t<))\9 Xfkk"Xd,-.U1X
 
" lln!F #A  zz%%

9<<(../@A U2266t<))//5))\9 Xi++,Xd,-.U1X
 
" lln!F/i #A  a
2
s%   DJ I;D.J I>/J >J c                   K   | j                  t        t        j                  t	        j
                  t        j                        j                  d            j                  t        j                  j                  d            j                  t        j                        j                  t        d            j                  d             d{   }|j                         }|rt!        |d   |d         S y7 *w)z
        Get product with most active violations.
        
        Returns:
            ProductAnalysis with product name and violation count
        re   Nrx   r   )r?   re   )r1   r   r   r?   r	   r2   r3   ri   r4   r5   r6   rj   rk   r   r|   r}   r   r~   s      rJ   get_most_affected_productz*DashboardService.get_most_affected_product;  s      zz&&

9<<(../@A U91155d;<Xi,,-Xd,-.U1X	
 	
 lln" V #A  #	
s   CC<C:+C<c           
      ~  K   | j                  t        t        j                  t        j                  t        j
                  t        j                        j                  t        t        j                  j                  d      t        j                  j                  d                  j                  t        t        j                              j                  d             d{   }|j                         }|r@t!        |d   t#        t%        |d         d      t%        |d         t%        |d               S y7 Ww)z
        Get violation with highest discount percentage.
        
        Returns:
            HighestDiscountAnalysis with product info and highest discount
        Nrx   r   rS      )r?   highest_discount_percentagemspscraped_price)r1   r   r   r?   rU   r   r   r4   r
   r5   r6   r<   rk   r   r|   r}   r   rV   floatr~   s      rJ   get_highest_discount_detectedz.DashboardService.get_highest_discount_detectedV  s      zz&&//''	 U2266t<3399$? Xd9::;<U1X
 
" lln* V,1%A-,C#a&M#CFm	  3
s   C!D=#D;$AD=c           
        K   | j                  t        t        j                  t        j
                        t        j                  t        j                              j                  t        t        j                  j                  d      t        j
                  j                  d                         d{   }|j                         \  }}|rt        |      nd}|xs d}t        t!        |d      d|      S 7 Dw)z
        Get estimated financial impact.
        
        Calculation: Sum of (MSP - Scraped Price) across all active violations
        
        Returns:
            FinancialImpactAnalysis with total impact and violation count
        NrR   r   rS   USD)total_estimated_impactcurrencyre   )r1   r   r	   r8   r   price_differencer2   r3   r4   r
   r5   r6   r<   r}   r   r   rV   )r#   rN   total_impactre   s       rJ   get_financial_impactz%DashboardService.get_financial_impact{  s      zz334

9<<( U2266t<..44T:
 
 )/%o.:u\*).Q&#(q#9+
 	
#
s   B4C=6C;7AC=c                 `  K   t         j                  |        d{   }t         j                  |        d{   }t         j                  |        d{   }t         j	                  |        d{   }t         j                  |        d{   }t        |||||      S 7 7 m7 R7 77 w)z
        Get complete violation analysis section.
        
        Returns:
            ViolationAnalysis with all analysis insights
        N) marketplace_with_most_violationsmost_offending_vendormost_affected_producthighest_discount_detectedfinancial_impact)r"   r   r   r   r   r   r   )r#   r{   vendorproducthighest_discountr   s         rJ   get_violation_analysisz'DashboardService.get_violation_analysis  s      -QQRTUU'AA"EE(BB2FF!1!O!OPR!SS!1!F!Fr!JJ -8"(")&6-
 	
 VEFSJsU   B.B$B.B&B.B(B.2B*3B.B,B.&B.(B.*B.,B.r|   c                   K   | j                  t        t              j                  t	        t        j
                              j                  t        j                  j                  d            j                  t        t        j                              j                  |             d{   }|j                         j                         j                         }g }|D ]  }t!        |j"                  |j$                  |j&                  |j(                  xs$ |j
                  r|j
                  j*                  ndt-        |j.                        t-        |j0                        |j2                  rt-        |j2                        nd|j4                  rt-        |j4                        nd|j                  sdnd|j                  |j6                        }|j9                  |        | j                  t        t;        j<                  t        j"                              j                  t        j                  j                  d                   d{   }|j?                         xs d}tA        ||      S 7 7 (w)a  
        Get recent violations panel.
        
        Args:
            db: Database session
            limit: Number of recent violations to return (default: 10)
        
        Returns:
            RecentViolationsPanel with recent violations and total count
        Nopennotified)r3   r?   r{   r=   current_price
target_mspr   rU   r0   rh   urlr   )recent_violationstotal_violations)!r1   r   r   optionsr   r   r4   r5   r6   rk   r   rh   r|   scalarsuniquerl   r    r3   r?   r{   r=   r   r   r   r   r   rU   r   rp   r	   r2   r7   r   )	r#   r|   rN   
violationsrecent_items	violationitemtotal_resulttotal_counts	            rJ   get_recent_violationsz&DashboardService.get_recent_violations  s     zz9WZ	 0 012U91155d;<Xd93345U5\
 
 ^^%,,.224
 # 	&I&<<&33%11%11jyO_O_i6F6F6K6Kei#I$;$;< /FOF`F`y'A'A!Bfj22 ',I,K,K&L%.%C%Cv(77MMD %!	&&  ZZ4::ill+,2293Q3Q3U3UVZ3[\
 
 #))+0q$*(
 	
G
<
s%   B)I;+I6,F$I;I9&I;9I;c                 J  K   t         j                  |        d{   }t         j                  |        d{   }t         j                  |        d{   }t         j	                  | d       d{   }t        ||||t        j                               S 7 7 d7 I7 ,w)z
        Get complete dashboard data.
        
        Aggregates all dashboard sections into a single response.
        
        Returns:
            DashboardResponse with all dashboard data
        Nr'   )r|   )kpi_summaryviolation_trendviolation_analysisr   last_refreshed_at)r"   r_   rv   r   r   r   r   rg   )r#   r   r   r   r   s        rJ   get_complete_dashboardz'DashboardService.get_complete_dashboard  s      -<<R@@ 0 J J2 NN#3#J#J2#NN"2"H"HSU"H"VV #+1/&oo/
 	
 ANNVsC   B#BB#BB#BB#4B!5'B#B#B#!B#N)r'   )"__name__
__module____qualname____doc__staticmethodr   r   rK   r   rP   r   r[   r   r_   r   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   intr   r   r   r        rJ   r"   r"       s   ?G
L G
=P G
 G
R N\ N>R N N %_< %_<S %_ %_N 
, 
: 
 
" $:L $:=P $: $:L 	%	& B 9L 9Xn=U 9 9v L Xo=V  4 ""	)	*" "H 
| 
8O 
 
B 
 
:K 
 
* ')4
4
!$4
	4
 4
l 
 
:K 
 
r   r"   )+loggingr   r   typingr   r   r   
sqlalchemyr   r	   r
   r   r   sqlalchemy.ext.asyncior   sqlalchemy.ormr   app.models.violationr   app.models.productr   app.models.vendorr   app.schemas.dashboardr   r   r   r   r   r   r   r   r   r   r   r   r   r   r    	getLoggerr   loggerr"   r   r   rJ   <module>r      s_     ( ( ( 4 4 / % * & $    $ 
		8	$_
 _
r   