
    v j1x                    <	   d Z ddlZddlmZmZ ddlmZmZ ddlmZ ddl	m
Z
 ddlmZ  ej                  e      Z ej                   dd	g
      d        Z ej                   dd	g
      d        Z ej                   dd	g
      defd       Z ej                   dd	g
      d        Z ej                   dd	g
      d        Z ej                   dd	g
      d        Z ej                   dd	g
      d        Z ej                   dd	g
      d        Z ej                   dd	g
      defd       Z ej                   ddg
      defd       Z ej                   d d!g
      defd"       Z ej                   d#d	g
      d$        Z ej                   d%d	g
      d&        Z ej                   d'd!g
      d(        Z  ej                   d)d!g
      d*        Z! ej                   d+dg
      d,        Z" ej                   d-d!g
      d.        Z# ej                   d/d!g
      d0        Z$ ej                   d1d	g
      d2        Z% ej                   d3d	g
      d4        Z& ej                   d5d	g
      d6        Z' ej                   d7d	g
      d8        Z( ej                   d9d:g
      d;        Z) ej                   d<d	g
      d=        Z* ej                   d>d	g
      d?        Z+ ej                   d>d!g
      d@        Z, ej                   dAd:g
      dB        Z- ej                   dAdg
      dC        Z. ej                   dDd!g
      dE        Z/ ej                   dFd	g
      dG        Z0 ej                   dHd	g
      dI        Z1 ej                   dJd!g
      dK        Z2 ej                   dLd	g
      dM        Z3 ej                   dNd	g
      dO        Z4 ej                   dPd:g
      dQefdR       Z5 ej                   dSd!g
      dT        Z6 ej                   dUd!g
      dV        Z7 ej                   dWd	g
      dX        Z8 ej                   dYd	g
      dZ        Z9 ej                   dYd!g
      d[        Z: ej                   d\dg
      d]        Z;y)^zM
Hyper Forecast API Endpoints
Provides sales forecast data for the dashboard
    N)jsonifyrequestdatetime	timedelta)api_bp)SessionLocalHyperForecastz/forecast/todayGET)methodsc                     t               } 	 t        d       t        |       }|j                         }t	        d|d      | j                          S # t        $ rm}ddl}|j                          t        j                  d|        t        d|        t	        dt        |      d	      d
fcY d}~| j                          S d}~ww xY w# | j                          w xY w)zi
    Get today's forecast with actuals and projections
    Perfect for the dashboard cash flow chart
    zDEBUG: Hit /forecast/todayTsuccessdatar   NzError generating forecast: z*DEBUG: CRITICAL ERROR in /forecast/today: Fr   error  )r	   printr   get_today_with_actualsr   close	Exception	traceback	print_excloggerr   strdbforecastresulter   s        H/var/www/hypershopcomercio.com.br/hyper-ai/app/api/endpoints/forecast.pyget_today_forecastr#      s     
B*+ $002
  	
  21#67:1#>?V
   	
 	
 	
s0   3A 	CAC+C,C	 CC	 	Cz/forecast/today/productsc                     t               } 	 t        |       }|j                         }| t        ddd      df| j	                          S t        d|d      | j	                          S # t
        $ r_}ddl}|j                          t        j                  d	|        t        dt        |      d      d
fcY d}~| j	                          S d}~ww xY w# | j	                          w xY w)aa  
    Get today's forecast based on individual product predictions.
    This method considers stock availability - products without stock = R$0
    
    Returns:
        - total_forecast: Sum of all product forecasts
        - lost_to_stock: Revenue lost due to out-of-stock products
        - breakdown: Top products with their individual forecasts
    NFz.Product forecast not available, run sync firstr     Tr   r   z#Error generating product forecast: r   )r	   r   get_product_based_forecastr   r   r   r   r   r   r   r   r   s        r"   get_today_product_forecastr'   -   s     
B $446> I  & 	
 
  	
  :1#>?V
   	
 	
 	
s6   ,A' 	A' '	C0AC
4C5C 
CC C$z/forecast/day/<target_date>target_datec                 V   t               }	 t        j                  | d      j                         }t        j
                  j                  dd      }t        |      }|j                  ||      }t        d|d      |j                          S # t        $ r-}t        dd| d      d	fcY d}~|j                          S d}~wt        $ rK}t        j                  d
|        t        dt        |      d      dfcY d}~|j                          S d}~ww xY w# |j                          w xY w)z*
    Get forecast for a specific date
    %Y-%m-%dcategoryNTr   FzInvalid date. r   r%   zError generating day forecast: r   )r	   r   strptimedater   argsgetr   predict_dayr   r   
ValueErrorr   r   r   r   )r(   r   parsed_dater+   r   r    r!   s          r"   get_day_forecastr3   T   s   
 
B''Z@EEG<<##J5 $%%k8<
 " 	
  %aS)
   	 	
  6qc:;V
   	
 	
 	
sH   A.B 	DB<&D'D <D0D8D9D DD D(z/forecast/chart-datac                  @   t               } 	 t        d       t        |       }|j                         }t	        d      D cg c]  }|dd
 }}|j                  dd      }|d   d   D cg c]  }|d	   	 }}d
gdz  }|d   j                  dg       D ]  }d|v sd	|v s|d	   ||d   <    d
gdz  }|d   j                  dg       D ]   }	d|	v sd|	v s|	d   |kD  s|	d   ||	d   <   " d
gdz  }
d
gdz  }|d   j                  dg       D ]>  }	d|	v s|	d   |kD  s|	j                  d      |
|	d   <   |	j                  d      ||	d   <   @ t        d       t        d|||||
|d||j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  d      |j                  d      d	dd      | j                          S c c}w c c}w # t        $ rm}dd
l	}|j                          t        j                  d|        t        d |        t        d!t        |      d"      d#fcY d
}~| j                          S d
}~ww xY w# | j                          w xY w)$z<
    Get formatted data for the CashFlowChart component
    zDEBUG: Hit /forecast/chart-data   02dhcurrent_hourr   hourlypreviousrevenueNactualshourpredictions
predictionminmaxz'DEBUG: Chart data prepared successfullyT)r:   actualr   confidence_minconfidence_maxactual_totalprojected_totalprojected_minprojected_maxvs_previous_percentavg_confidence	peak_hourvalley_hour)	r8   rE   rF   rG   rH   rI   rJ   rK   rL   )labelsdatasetssummaryr   zError generating chart data: z/DEBUG: CRITICAL ERROR in /forecast/chart-data: Fr   r   )r	   r   r   r   ranger/   r   r   r   r   r   r   r   r   )r   r   r   r7   rM   r8   previous_dataactual_dataforecast_dataprC   rD   r!   r   s                 r"   get_forecast_chart_datarU   u   s   
 
BE/0 $..0 (-Ry1!QsG1+11xx2 04H~j/IJ!9JJ frkh##Ir2 	6A{yA~)*9AfI&	6
 h##M26 	?A{|q0V9|+/0M!F),	? ""h##M26 	:A!&	L 8-.UU5\&	*-.UU5\&	*	:
 	78  -) -&4&4 %1$(HH^Q$?'+xx0A1'E%)XXoq%A%)XXoq%A+/884I1+M&*hh/?&C!%+!6#'88M#:

 F 	
 2 Kb  4QC89?sCDV
   	
 	
 	
sx   3H HH *H6$H H  /H H H 5H H CH 
H 	JAJ-J.J JJ Jz/forecast/projection/todayc                     ddl m } m} ddlm}m} ddlm} t               }	 t        d        | j                         }|j                         }|j                  }g }	d}
t        |dz         D ]  } | j                  || j                  j                               j!                  |      }| |d      z   }|j#                  |j%                  |j&                              j)                   ||j*                  |k\  |j*                  |k  |j,                  j/                  g d	                  j1                         }t3        |xs d      }|
|z  }
|	j5                  ||d
dt7        |d      dd       	 g }d}t9        |      }t        |dz   d      D ]=  }|j;                  ||      }|j5                  ||d
d|d   |d   dd       ||d   z  }? |
|z   }| |d      z
  } | j                  || j                  j                               } | j                  || j<                  j                               }|j#                  |j%                  |j&                              j)                   ||j*                  |k\  |j*                  |k  |j,                  j/                  g d	                  j1                         }t3        |xs d      }|dkD  r||z
  |z  dz  nd}t        d       t?        d||	|t7        |
d      t7        |d      t7        |d      t7        |d      t7        |d      ddd      |jA                          S # tB        $ rm}ddl"}|jG                          tH        jK                  d|        t        d|        t?        dtM        |      d      d fcY d}~|jA                          S d}~ww xY w# |jA                          w xY w)!z:
    Get real data + projections (Alternate endpoint)
    r   r   funcand_)MlOrderz%DEBUG: Hit /forecast/projection/today   )r=   hourspaidshipped	deliveredr6   r7      real)hora
hora_labelreceitatipor5   r?   
confidenceprojecao)rd   re   receita_prevista	confiancarg   daysd   z(DEBUG: Projection generated successfullyT)receita_realizadareceita_projetada_restantereceita_projetada_fim_diareceita_ontemvariacao_vs_ontem)
hora_atualdados_reaisri   totaisr   NzError getting projection: z5DEBUG: CRITICAL ERROR in /forecast/projection/today: Fr   r   )'r   r   
sqlalchemyrX   rY   app.models.ml_orderrZ   r	   r   nowr-   r=   rP   combiner@   timereplacequerysumtotal_amountfilterdate_closedstatusin_scalarfloatappendroundr   predict_hour_with_loggingrA   r   r   r   r   r   r   r   r   )r   r   rX   rY   rZ   r   ry   todayr8   ru   receita_total_realr7   
hour_starthour_endrf   ri   receita_projetadar   predreceita_fim_dia	yesterdayyesterday_startyesterday_endrr   variacao_ontemr!   r   s                              r"   get_today_projectionr      s   
 -%+	B`56hlln
xx |a'( 	A)))%1B1B1DEMMSTMUJ!IA$66Hhhtxx(<(<=>EE'':5''(2NN&&'GH fh  GLq)G')!"3qk !,	  	.  $|a', 	4A55a?DOO!"3qk$($6!,/"  l!33	4 -/@@ I1--	*(**9hll6G6G6IJ(((HLL4E4E4GH'*>*>!?@GG##6##}4""#CD
 &( 	 m0q1VcfgVg?]:mKcQmn89**$)./A1)E278I12M161J%*=!%<).~q)A	
 4 	
  1!56EaSIJV
   	
 	
 	
s1   LM 	N<AN7!N<"N? 7N<<N? ?Oz/forecast/learning/multipliersc                     ddl m}  t               }	 |j                  |       j	                  | j
                  | j                        j                         }t        dd|D cg c]l  }|j
                  |j                  t        |j                        |j                  |j                  |j                  r|j                  j                         nddn c}id      |j                          S c c}w # t         $ rK}t"        j%                  d|        t        d	t'        |      d
      dfcY d}~|j                          S d}~ww xY w# |j                          w xY w)z_
    Get all active multipliers with their current values
    For the Hyper AI admin panel
    r   MultiplierConfigTmultipliersN)rg   chavevalorfonterk   atualizado_emr   zError getting multipliers: Fr   r   )app.models.forecast_learningr   r	   r}   order_byrg   r   allr   r   r   	calibradork   r   	isoformatr   r   r   r   r   )r   r   configscr!   s        r"   get_multipliersr   0  s4    >	B((+,55!!""
 #% 	
   '	   !"!"!&qww!"%&[[HI)B)B)D]a	 
 . 	
)	   21#67V
   	
 	
 	
sC   AC0  A1C+	C0 +C0 0	E90D?)E*E ?EE Ez&/forecast/learning/calibration-historyc                     ddl m}  t               }	 |j                  |       j	                  | j
                  j                               j                  d      j                         }t        dd|D cg c]  }|j                  |j
                  r|j
                  j                         nd|j                  |j                  |j                  rt        |j                        nd|j                   rt        |j                         nd|j"                  rt        |j"                        nd|j$                  |j&                  d	 c}id      |j)                          S c c}w # t*        $ rK}t,        j/                  d	|        t        d
t1        |      d      dfcY d}~|j)                          S d}~ww xY w# |j)                          w xY w)zT
    Get calibration history (last 50 entries)
    For the Hyper AI admin panel
    r   CalibrationHistory2   T	historicoN)	idr   
tipo_fatorfator_chavevalor_anterior
valor_novo
erro_medioamostrasnotasr   z#Error getting calibration history: Fr   r   )r   r   r	   r}   r   data_calibracaodesclimitr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   historyr7   r!   s        r"   get_calibration_historyr   Y  s|    @	B((-.77..335

%)CCE 	   '   ddABARAR 1 1 ; ; =X\&'ll'(}}EFEUEU%0@0@*A[_=>\\eALL&9t=>\\eALL&9t$%JJ!"

 4 	
/   :1#>?V
   	
 	
 	
sC   A E 2CE 	E E 	F3(0F.F3F6 .F33F6 6Gz/forecast/learning/logsc                  :   ddl m } m} ddlm}m} ddlm} t               }	 t        t        j                  j                  dd            }t        t        j                  j                  dd            }t        j                  j                  d	d
      }t        j                  j                  d      }	t        j                  j                  d      }
|j                  |      }|	r.|j                  |j                   | j                  |	      k\        }|
r.|j                  |j                   | j                  |
      k        }|dk(  r+|j                  |j                   j#                  d            }n|dk(  r+|j                  |j                   j%                  d            }nS|dk(  rN|j                   ||j&                  j%                  d      |j&                  dkD  |j&                  dk  z              }|j)                         }t        j                  j                  dd      }t        j                  j                  dd      }ddlm}m}m}m} |dk(  r|n|}|dk(  rp |t0        j3                  |j&                              }|j5                   ||            j7                  |dz
  |z        j9                  |      j;                         }n|dk(  rU|j5                   ||j<                              j7                  |dz
  |z        j9                  |      j;                         }nT|dk(  rZ|j5                   | ||j                                     j7                  |dz
  |z        j9                  |      j;                         }n|d	k(  r ||j                   j#                  d      dft0        j3                  |j&                        dkD  dfd      }|j5                  | ||j                              j7                  |dz
  |z        j9                  |      j;                         }nS|j5                   ||j                              j7                  |dz
  |z        j9                  |      j;                         } | j>                         fd}tA        d |D              }|rtC        |tE        |      z  dz  d      nd}tG        d |||||z   dz
  |z  |tE        |      |d!|D cg c]   }|jH                  |jJ                  r|jJ                  jM                         nd|j                  r|j                  jM                         nd|j<                  rtO        |j<                        nd|j                   rtO        |j                         nd|j&                  rtO        |j&                        nd ||      |jP                  rtO        |jP                        nd|jR                  |jT                  xs i tW        |d"d#      tW        |d$d      d%# c}d&d'      |jY                          S c c}w # tZ        $ rK}t\        j_                  d(|        tG        d)ta        |      d*      d+fcY d}~|jY                          S d}~ww xY w# |jY                          w xY w),zt
    Get paginated list of forecast logs with filters
    Perfect for the detailed logs table in Hyper AI panel
    r   r   rY   r   ForecastLogpager[   per_page   r   r   	date_fromdate_topendingN
reconciled
high_errorisort_by	hora_alvo
sort_orderasc)r   r   case	nullslastr   r   valor_previsto
valor_realrb   )else_c                     | j                   /| j                  r"t        t        | j                              dkD  ryy| j                  k  ryy)Nr   r   r   awaitingr   )r   erro_percentualabsr   r   )logry   s    r"   
get_statusz%get_forecast_logs.<locals>.get_status  sE    ~~)&&3uS5H5H/I+JR+O'#$!     c              3   B   K   | ]  }t        |d d      dk(  sd  yw)
calibratedNYr[   N)getattr).0r   s     r"   	<genexpr>z$get_forecast_logs.<locals>.<genexpr>  s!     [SGCs4SWZ4Zq[s   rn   T)r   total
percentager   r   calibration_impact)r   timestamp_previsaor   r   r   r   r   baselinemodelo_versaofatores_usadosr   r   )r   r   r   total_pagescalibration_statslogsr   zError getting forecast logs: Fr   r   )1r   r   rw   rY   r   r   r   r	   intr   r.   r/   r}   r   r   fromisoformatr   is_isnotr   countr   r   r   rX   r   r   offsetr   r   r   ry   r~   r   lenr   r   r   r   r   baseline_usador   r   r   r   r   r   r   r   )r   r   rY   r   r   r   r   r   status_filterr   r   r}   r   r   r   sql_ascsql_descr   r   
order_funcorder_clauser   status_orderr   calibrated_countcalibration_pctr   r!   ry   s                               @r"   get_forecast_logsr     s    -%8	B~7<<##FA./w||''
B78((59LL$$[1	,,""9- % LL!6!6:P(:P:PQZ:[![\ELL!6!6:P(:P:PQX:Y!YZE I%LL!7!7!;!;D!ABEl*LL!7!7!=!=d!CDEl*LL//55d; 0025+:U:UX[:[\E  ,,""9k:\\%%lE:
 	QP!+v!5X7
g%dhh{/J/J&KLL>>)L"9:AAX%eHocce  ((>>*[-G-G"HIPPX%eHocce  $>>)J{7M7M,N"OPWWX%eHocce   ''++D115+556;Q?L
 >>,
;;P;P0QRYYX%eHocce 
 >>*[-B-B"CDKKX%eHocce 
 hlln	! [D[[LP%!1CI!=!CaHVW$ % 01 4A"2 Y"1&& "&  "ffTWTjTjc.D.D.N.N.PptBE--S]]%<%<%>UYGJGYGY%0B0B*C_`?B~~eCNN&;SWILI\I\51D1D+Ebf",S/ADASASE#*<*<$=Y]),):):*-*<*<*B&-c<&E.5c;OQU.V
 L 	
5&  4QC89V
   	
 	
 	
sC   SX1 +D&X,
X1 ,X1 1	Z:0Z *Z+Z  ZZ Zz$/forecast/learning/logs/<int:log_id>log_idc                 ~   ddl m} ddlm} ddlm} t               }	 |j                  |      j                  |j                  | k(        j                         }|s t        ddd      df|j                          S  |j                         }|j                  2|j                  r#t        t!        |j                              d
kD  rdnd}n|j"                  |k  rd}nd}t%        |dd	      xs g }t%        |dd      }	|s|j"                  rddl m}
 ddlm} 	 |j*                  xs i }	 ddlm}m} ddlm} ddlm}m}  | |d            }|j"                  }| |d      z   }|j4                  [|j7                  |      }|j7                  |      }|j9                  |j:                        }|j9                  |j:                        }n6|j9                  |j:                        }|j9                  |j:                        }|j7                  d	      }|j7                  d	      }|j                  |j<                  |j>                  |j@                        jC                  |      j                   ||jD                  |k\  |jD                  |k  |jF                  jI                  g d                  jK                         }i }i }|D ]r  \  }}}t!        |xs d      }|jM                  |d      |z   ||<   |s1tO        |      jQ                         jS                         }|s[|jM                  |d      |z   ||<   t |j*                  xs i }|jM                  dg       }i } |r|D !cg c]%  }!|!jM                  d      s|!jM                  d      ' }"}!|"rwddl*m+}# |j                  |#jX                  |#j@                        j                  |#jX                  jI                  |"            jK                         }$|$D %&ci c]  \  }%}&|%|&
 } }%}&g }'|r}|D ]r  }!|!j[                         }(tO        |!jM                  d            jQ                         })|jM                  |)d      }*|*dk(  rg	 | jM                  |)      }+|+s|!jM                  d      }+|+r@tO        |+      jQ                         jS                         },|,r|,d k7  r|jM                  |,d      }*|*dk(  r	 |*dk(  rytO        |!jM                  d"d#            jS                         }.d$|.v rLd%|.v rH|D ]C  \  }}}tO        |xs d#      jS                         }/d&|/v s)d'|/v sd(|/v s2|*t!        |xs d      z  }*E |*|(d*<   |*dkD  xr |!jM                  d+d      d,kD  |(d-<   |'ja                  |(       u |'|d<   t%        |dd      d/k(  }	t%        |dd	      }|jM                  d      xs g }1t_        d0       |1D ]T  }!tO        |!jM                  d"d#            }2d&|2v s#t_        d1|2 d2|!jM                  d       d3|!jM                  d*              V t        d4|j                  |jb                  je                         |j"                  je                         t!        |jf                  xs d      |j                  t!        |j                        nd	|j                  t!        |j                        nd	||	|d5	d6      |j                          S c c}!w c c}&}%w # t\        $ r}-t_        d!|-        Y d	}-~-:d	}-~-ww xY w# t\        $ r}-t_        d)|-        Y d	}-~-d	}-~-ww xY w# t\        $ r}0t_        d.|0        Y d	}0~0d	}0~0ww xY w# t\        $ rG}-dd	l4}3|3jk                          t        dtO        |-      d      d7fcY d	}-~-|j                          S d	}-~-ww xY w# |j                          w xY w)8zY
    Get detailed information about a specific forecast log
    For the detail modal
    r   r   )r   rY   FLog not foundr     Nr   r   r   r   r   r   r   r   r   )r   )timezoner   )rZ   MlOrderItemr\   r[   tzinfor^           _product_mixmlb_idProductForecastskuNONEzSKU Match failed successfully: title z
780 LITROSINTEX780SUNSETBOMBAz(Panic Fallback failed (safely ignored): realized_unitsunits_expected皙?accuracy_hitz(CRITICAL: Realized Sales Logic Crashed: r   z--- DEBUG PAYLOAD PREP ---zPAYLOAD DEBUG: z -> ID: z -> Realized: T)	r   	timestampr   r   r   r   r   r   r   r   r   )6r   r   r   rw   rY   r	   r}   r   r   firstr   r   ry   r   r   r   r   r   r   r   r   r   r   rx   rZ   r   r   r|   
astimezoneutc
ml_item_idquantityr  joinr   r   r   r   r/   r   stripupperapp.models.product_forecastr  r  copyr   r   r   r   r   r   r   r   )4r   r   r   rY   r   r   ry   r   r   r   r   r   fatoresr   rZ   r   tz_brstart_naive	end_naivestart_local	end_local	start_utcend_utcrealized_sales_querysales_by_idsales_by_sku	r_item_idr_qtyr_skuqtynorm_skuproduct_mixproduct_skusrT   mlb_ids_in_mixr  prods_dbpidr  enhanced_mixp_copyr  real_qtyp_sku	p_sku_strr!   p_title	r_sku_stre_main	debug_mixp_title_dbgr   s4                                                       r"   get_forecast_log_detailr:    sm    9!	BQhh{#**;>>V+CDJJL (  Z 	
O hlln>>%%(%8%8SsGZGZA[=\_a=a\gsF]]S FF %S*>EKS,4
 "cmmG*
 
 $$*J	5(A ib12U==[$yq'99Y""**22%2@&..e.<(33HLLA$//= )33HLLA$//= #**$*7Yd3W %'HH''%%% tG}VV((I5((72^^''(HI su " [\,@ X(E5UZa(*5//)S*IC*OY' #E
 0 0 2 8 8 :X 2>2B2B8S2QTW2Wh/X ))/RW";;~r:[ \=H#\AEERZOAEE(O#\.#\#M!#/*@*@/BUBU!V!]!])0044^D"  @H%H83c3h%Hl%H \& /2a vvxf"155?399;f "-!=h "Q#&2&6&6v&>e%**+%%,%!&.1%j.>.>.@.F.F.H)%.93F1=1A1A)S1Qh "Q#!)Q,/gr0B,C,I,I,K'%1W%<GASEY 'L*A)UE69%+26F6L6L6N)-2i-?XQZEZ^eir^r.6%
:K.Kh'L 2:f-.0810aGWYZA[^aAaf^,"))&1_/2d -9'.) S,4;
$S*>E KK/52	*, 	xAquuWb12[$XaeeHo=Nn]^]b]bcs]t\uvw	x
 ff 33==? ]]446"'(:(:(?a"@7:~~7QeCNN3W[ADATATA`5)<)<#=fj")(&8

 ( 	
Q $] &I2 "+ ##&EaS$IJ"#( "+ ##&Nqc$RS"#  	 <VHEF	F  A53q6:;S@@

A
 	
s   A] ;B,] (G\2 7)\2 !A\2 %[<[A+\2 :["A\2 %A&[(\2 A \2\;\=\2 A!] .C] \2 (	\
1\?\2 \

\2 	\/\*$\2 *\//\2 2	];]	] ]] 	^' ,^"^'^* "^''^* *^<DELETEc                 $   ddl m} t               }	 |j                  |      j	                  |j
                  | k(        j                         }|s t        ddd      df|j                          S |j                  |       |j                          t        ddd	      |j                          S # t        $ rC}|j                          t        dt        |      d      d
fcY d}~|j                          S d}~ww xY w# |j                          w xY w)z
    Delete a forecast log
    r   r   Fr   r   r   TzLog deletedr   messager   N)r   r   r	   r}   r   r   r  r   r   deletecommitr   rollbackr   )r   r   r   r   r!   s        r"   delete_forecast_logrB    s    
 9	Bhh{#**;>>V+CDJJLuGH#M 	
 			#
		4MBC
 	
	  A
53q6:;S@@

	A 	
s6   AB. /.B. .	C:7(C5C: C= 5C::C= =Dz//forecast/learning/logs/<int:log_id>/regeneratePOSTc                    ddl m} ddlm} t	               }	 |j                  |      j                  |j                  | k(        j                         }|s t        ddd      df|j                          S |j                  }|j                  }|j                         }|j                  |       |j                           ||      }|j!                  ||      }	t        dd	|	d
      |j                          S # t"        $ r[}
|j%                          t&        j)                  d|
        t        dt+        |
      d      dfcY d}
~
|j                          S d}
~
ww xY w# |j                          w xY w)zE
    Regenerate a forecast log (re-run prediction for that hour)
    r   r   r
   Fr   r   r   TzLog regenerado)r   r>  r   zRegenerate log failed: r   N)r   r   app.services.forecastr   r	   r}   r   r   r  r   r   r   r=   r-   r?  r@  r   r   rA  r   r   r   )r   r   r   r   r   	target_dtr=   	date_partr   r    r!   s              r"   regenerate_forecast_logrH    s5   
 93	Bhh{#**;>>V+CDJJLuGH#M6 	
1 MM	~~NN$	
 			#
		 !$33D)D'
  	
  A
.qc2353q6:;S@@

A
 	
s8   AC7 5A1C7 7	E A E EE EE E0z/forecast/learning/analyticsc                    " ddl m } m} ddlm}m}m} ddlm} t               }	 t        d       ddl m
} t        j                  j                  d      }t        j                  j                  d      }	 | j                         }
|rM|	rK	  | j                  |d	      } | j                  |	d	      j!                  d
dd      }t        d| d|        n|
 |d      z
  }|
}|j%                  |      j'                   ||j(                  |k\  |j(                  |k  |j*                  j-                  d      |j.                  j-                  d                  j1                         }t        dt3        |       d       ddlm"  "d       }|D ]a  }	 |j8                  j;                  d      }||   d   j=                  t?        tA        |j.                                     ||   dxx   dz  cc<   c g }tG        |jI                               D ]H  }||   d   }|j=                  ||r!tK        tM        |      t3        |      z  d      nd||   d   d       J  ""fd      }|D ]  }	 |jN                  xs i }t?        tA        |j.                              }|jQ                         D ]B  \  }}tS        |tT        t@        f      r|d}ntW        |      }||   |   j=                  |       D  i }|jQ                         D ]M  \  }}i ||<   |jQ                         D ]0  \  }}|r!tK        tM        |      t3        |      z  d      nd||   |<   2 O g }|r|D cg c]   }t?        tA        |j.                              " }}tM        |      t3        |      z  }|d k  r|j=                  d!d"|d#d$d%d&       n:|d'k  r|j=                  d(d)|d#d$d*d&       n|j=                  d+d,|d#d$d-d&       |jQ                         D ]B  \  }}|jQ                         D ]*  \  }}|d.kD  s|j=                  d+d/| d0| d1| d2d3d&       , D t3        |      d4k\  rR|d   d5   }|d6   d5   } | |d4z
  k  r|j=                  d!d7d8| d9|  d$d&       n| |d4z   kD  r|j=                  d+d:d;d&       |j%                  |      j'                  |j*                  jY                  d            j[                         }!t        d|! d<       |!dkD  r|j=                  d(|! d=d>d&       t        d?       t]        d@|||t3        |      dAdB      |j_                          S # t"        $ r |
 |d      z
  }|
}Y w xY w# tB        $ r&}t        d|jD                   d|        Y d}~	d}~ww xY w# tB        $ r&}t        d|jD                   d|        Y d}~dd}~ww xY wc c}w # tB        $ rK}t`        jc                  dC|        t]        dDtW        |      dE      dFfcY d}~|j_                          S d}~ww xY w# |j_                          w xY w)Gz
    Get analytics data for the Hyper AI panel
    - Precision evolution by week
    - Precision by factor type
    - Auto-generated insights
    r   r   )rX   rY   extractr   z'DEBUG: Hit /forecast/learning/analytics)r{   
start_dateend_dater*      ;   r=   minutesecondzDEBUG: Using filter z to    rl   NzDEBUG: Found z logs for analyticsdefaultdictc                      g ddS )Nr   errorsr    rX  r   r"   <lambda>z(get_forecast_analytics.<locals>.<lambda>_  s    R!*D r   z%Y-W%WrW  r   r[   zDEBUG: Error processing log z: )semanar   total_previsoesc                        t               S N)listrS  s   r"   rY  z(get_forecast_analytics.<locals>.<lambda>t  s    K,= r   .2fz(DEBUG: Error processing factors for log 
   r   u$   Precisão excelente! Erro médio de .1f%u<   Mantenha o sistema coletando dados para melhorias contínuas)rg   mensagemrecomendacaor   infou   Precisão boa. Erro médio de uB   O sistema está aprendendo, precisão deve melhorar com mais dadoswarningu-   Precisão em desenvolvimento. Erro médio de u0   Aguarde mais dados para calibração automática   zFator '=z' tem erro alto (z%)u/   Considere coletar mais dados para este cenáriorb   r   u!   Tendência de melhoria detectada!zErro reduziu de z% para u   Precisão diminuiu recentementeu1   Verifique se houve mudanças no padrão de vendasz pending logsu&    previsões aguardando reconciliaçãou+   Próxima reconciliação automática: 03:00z'DEBUG: Analytics generated successfullyT)precisao_por_semanaprecisao_por_fatorinsightstotal_logs_analisadosr   z"Error getting forecast analytics: Fr   r   )2r   r   rw   rX   rY   rJ  r   r   r	   r   r{   r   r.   r/   ry   r,   r|   r1   r}   r   r   r   r   r   r   r   collectionsrT  r   strftimer   r   r   r   r   sortedkeysr   r~   r   items
isinstancer   r   r   r   r   r   r   r   )#r   r   rX   rY   rJ  r   r   r{   start_param	end_paramry   rK  rL  r   weekly_datar   weekr!   precision_by_weekrW  factor_errorsr  erro
fator_tipor   keyprecision_by_factorrq  rl  
all_errors	avg_errorfirst_week_errorlast_week_errorr   rT  s#                                     @r"   get_forecast_analyticsr  /  s    -..8	Bc78 	"ll&&|4LL$$Z0	hlln9.X..{JG
,8,,Y
CKKQS\^giKj,ZLXJGH
 	r 22ZX xx$++%%3%%1&&,,T2++11$7	
 #% 	 	c$i[(;<= 	,!"DE 	C--66x@D!(+223uS=P=P7Q3RSD!'*a/*		 ;++-. 	D &x0F$$EKeCK#f+$=qAQR#.t#4W#=& 	 $$=> 	C,,25!4!456)0 @%J!%#u6!&s!%j!*-c299$?@		 ! - 3 3 5 	lJ.0
+#zz| lV^duS[3v;=VXY7Zjk#J/4l	l  EIJc#eC$7$789JJJJ#j/9IB%"FyQToUV W$b! 
 b""@3q Q$h!  %"OPYZ]^_ `$V!  !4 9 9 ; 	J!ZZ\ 	T"9OO )&-j\3%?PQUPVVX$Y(Y% 	  !Q&03LA/3LAO!1A!55% C&67G6HP_O``a$b! 
 !#3a#77% A$W!  ((;'..""&&t,

%' 	 	gYm45Q;OO&i'MN M  	78'8&9$),T	
 " 	
i   9"#55
6  4SVVHBqcBC2  @1#NO KT  9!=>V
   	
 	
 	
s   A$W 
A	U B>W AU-0A8W )BV,A,W %W=B$W "DW U*&W )U**W -	V6VW VW 	W(W	W 	WW 	X*0X%X*X- %X**X- -X?z/forecast/learning/statusc                  `
   	 ddl m}  ddlm}m} ddlm}m}m} t               }t        j                  j                  d      }t        j                  j                  d      }|r<|r:	  |j                  |d      }	 |j                  |d      j                  dd	d	
      }
nt |j                   |j                          j#                         |j$                        }	 |j                   |j                          j#                         |j&                        }
|j)                  |j+                  | j,                        j/                  d      |j+                  | j0                        j/                  d            j3                  | j4                  |	k\  | j4                  |
k        j7                         }|r!|j8                  rt;        |j8                        nd}|r!|j<                  rt;        |j<                        nd}d}|dkD  r#t?        ||z
        }t'        dd||z  dz  z
        }|j)                  |       j3                  | j4                  |	k\  | j4                  |
k        jA                         }|j)                  |       j3                  | j4                  |	k\  | j4                  |
k  | j0                  jC                  d            jA                         }|j)                  |       j3                  | j4                  |	k\  | j4                  |
k  | j0                  jE                  d            jA                         }|j)                  |jG                  |j?                  | jH                                    j3                   || j4                  |	k\  | j4                  |
k  | j0                  jC                  d      | jH                  jC                  d                  jK                         }|rt;        |      nd}tM        d|||tO        |d      tO        |d      tO        |d      tO        |d      d|||ddd      |jQ                          S # t        $ rx  |j                   |j                          j#                         |j$                        }	 |j                   |j                          j#                         |j&                        }
Y w xY w# tR        $ rK}tT        jW                  d|        tM        dtY        |      d      dfcY d}~jQ                          S d}~ww xY w# jQ                          w xY w)z
    Get the current status of the learning system
    - Total predictions logged
    - Reconciliation status
    - Average error
    r   r   rW   )r   r   r{   rK  rL  r*   rM  rN  rO  	projectedrealizedr   rn   NTr[   rb   )r  r  accuracy)total_predictionsr   pending_reconciliation)total_predictions_loggedpredictions_reconciledr  avg_error_7dtoday_summarycountsr   zError getting learning status: Fr   r   )-r   r   rw   rX   rY   r   r   r{   r	   r   r.   r/   r,   r|   r1   rz   ry   r-   r@   rA   r}   r~   r   labelr   r   r   r  r  r   r  r   r   r   r   avgr   r   r   r   r   r   r   r   r   )r   rX   rY   r   r   r{   r   rt  ru  rK  rL  summary_queryperiod_projectedperiod_realizedperiod_accuracydifftotal_periodreconciled_periodpending_periodavg_error_queryr  r!   s                         r"   get_learning_statusr    s   j<)66^ ll&&|4LL$$Z0	 9M.X..{JG
,8,,Y
CKKQS\^giKj *)),(,,.*=*=*?JJ'x''(;(;(=txxHH HH[//066{CHH[++,22:>
 &!!Z/!!X-
 %' 	 >K}OfOf5!8!89lo;H]McMc% 6 67il Q'/9:D!!SD?,BS,H%IJO xx,33!!Z/!!X-
 %' 	
 HH[188!!Z/!!X-""((.
 %'	 	 +.55!!Z/!!X-""&&t,
 %'	 	 ((488DHH[5P5P,Q#RSZZ%%3%%1&&,,T2++11$7	
 &( 	 />E/*3	,8*;*8 %i 3!&'7!; %oq 9 %oq 9" *6"3.<
 . 	
u  M-X--lhlln.A.A.CTXXN
+8++LHLLN,?,?,A488LMl  A6qc:;53q6:;S@@

	A 	
sV   A$S '8Q  NS  A=S=S  SS 	T0T=T>T TT T-z/forecast/learning/reconcilec                      	 ddl m}  t        j                         xs i }|j	                  d      } | |      }t        d|dd      S # t        $ r;}t        j                  d|        t        d	t        |      d
      dfcY d}~S d}~ww xY w)z;
    Manually trigger reconciliation of forecast logs.
    r   )run_hourly_reconciliationr-   )r(   Tu   Reconciliação concluídar   r   r>  zReconciliation trigger failed: Fr   r   N)
app.jobs.forecast_jobsr  r   get_jsonr/   r   r   r   r   r   )r  r   r(   r    r!   s        r"   reconcile_learning_logsr  X  s    
AD!'Rhhv&*{C3
  	
  A6qc:;53q6:;S@@As   AA	 		B0BBBz/forecast/learning/calibratec                     	 ddl m}  t        j                         xs i }|j	                  dd      }|j	                  d      } | ||      }|j	                  d      dk(  r"t        d	d	|j	                  d
d      g dd      S |j	                  dg       }t        d	|dd      S # t        $ r;}t        j                  d|        t        dt        |      d      dfcY d}~S d}~ww xY w)z^
    Manually trigger a calibration cycle.
    Runs the hourly calibration job on demand.
    r   )run_weekly_calibrationforceFr-   )	force_runr(   r   skippedTreasonu   Calibração pulada)r  adjustments)r   r  r   r  u   Calibração concluídar  zCalibration trigger failed: r   r   N)
r  r  r   r  r/   r   r   r   r   r   )r  r   r  r(   r    r  r!   s          r"   trigger_calibrationr  p  s    AA!'R%(hhv&'%[Q::h9,$jj3HI#%   jj30
  	
  A3A37853q6:;S@@As$   B B$  B$ $	C(-0C#C(#C(z/forecast/learning/logs/cleanupc                      	 ddl m}  ddlm} t	               }|j                  | j                  |j                  | j                              j                  | j                        j                  |j                  | j                        dkD        j                         }d}|D ]  \  }}|j                  |       j                  | j                  |k(        j                  | j                  j                               j                         }|d   }d}	|D ]  }
|
j                  |
}	 n |	s|d   }	|D ]2  }
|
j                  |	j                  k7  s|j!                  |
       |dz  }4  |j#                          t%        dd| d|d	      |j'                          S # t(        $ rC}j+                          t%        d
t-        |      d      dfcY d}~|j'                          S d}~ww xY w# j'                          w xY w)zt
    Remove duplicate ForecastLog entries for the same hora_alvo.
    Keeps the most recent entry (highest ID).
    r   r   )rX   r[   NTu   Limpeza concluída. z duplicatas removidas.)r   r>  deletedFr   r   )r   r   rw   rX   r	   r}   r   r   r   group_byhavingr   r   r   r   r   r?  r@  r   r   r   rA  r   )r   rX   r   
duplicatesdeleted_countr=   r   r   keeperbest_logr   r!   s               r"   cleanup_duplicatesr    s   4<#^ XX!!JJ{~~&
 (;((
)&&KNN1Ka1O*PQTQTQV 	
 % 	'KD%88K(//0E0E0MNWWXcXfXfXkXkXmnrrtD !WF H >>-"H
 7  '66X[[(IIcN!Q&M'+	'4 			-m_<RS$
  	
	  A
53q6:;S@@

	A 	
s<   D!F $*F <F 	G(%(G#G(G+ #G((G+ +G=z'/forecast/learning/generate-predictionsc            
         	 ddl m}   | d      }|j                  d      dk(  r6t        dd|j                  dd      d|j                  dd       d	d
d      S t        d|j                  dd      d      dfS # t        $ rO}t
        j                  d|        ddl}|j                          t        dt        |      d      dfcY d}~S d}~ww xY w)z
    Manually generate predictions for ALL hours of today + tomorrow.
    This ensures complete 24-hour coverage for analysis.
    r   )run_daily_predictionsT)
manual_runr   okpredictions_madezGeradas u&    previsões para as próximas 15 horas)r   r  r>  r   Fr>  zUnknown errorr   r   zGenerate predictions error: N)
r  r  r/   r   r   r   r   r   r   r   )r  r    r!   r   s       r"   generate_predictionsr    s    A@ '$7::h4'"(.

3Eq(I!)&**5G*K)LLrs    I?   
  A3A37853q6:;S@@	As%   AA; A; ;	CACCCz%/forecast/migrate/calibration-columnsc                     ddl m}  t               }	 |j                   | d            }|D cg c]  }|d   	 }}g }d|vr(|j                   | d             |j	                  d       d|vr(|j                   | d             |j	                  d       |j                          t        d||d	d
      |j                          S c c}w # t        $ r[}|j                          t        j                  d|        t        dt        |      d      dfcY d}~|j                          S d}~ww xY w# |j                          w xY w)zx
    Add calibration columns to forecast_logs table if they don't exist.
    This is a one-time migration endpoint.
    r   )textz
            SELECT column_name 
            FROM information_schema.columns 
            WHERE table_name = 'forecast_logs' 
            AND column_name IN ('calibrated', 'calibration_impact')
        r   zFALTER TABLE forecast_logs ADD COLUMN calibrated VARCHAR(1) DEFAULT 'N'r   z=ALTER TABLE forecast_logs ADD COLUMN calibration_impact JSONBT)added_columnsexisting_columnsr   zMigration error: Fr   r   N)rw   r  r	   executer   r@  r   r   r   rA  r   r   r   )r  r   r    rowexistingaddedr!   s          r"   add_calibration_columnsr    s+     	B!D "   '--sCF--x'JJtdefLL&x/JJt[\]LL-.
		!&$,
  	
3 .(  A
(,-53q6:;S@@

A
 	
sA   C CA<C C 	D/A D*D/D2 *D//D2 2Ez/forecast/weather/testc                     	 ddl m}   |        }|j                  dd      }|j                         }|j	                  |j                  dd      |j                  dd	            }g d
}i }|D ]  }|j                  |      }|||<    |j                         }	t        dt        |j                        |D 
cg c]
  \  }
}|
|d c}}
t        |j                  dd      d      |j                  dd      ||j                  dd      d||	dd      S c c}}
w # t        $ r;}t        j                  d|        t        dt        |      d      dfcY d}~S d}~ww xY w)zG
    Test weather service - shows buyer regions and weather impact
    r   )get_smart_weather_servicerR     )rm   r   temprg  mainClear)u   Piscina Inflável 5000Lu   Aquecedor Elétrico 1500WzVentilador de Colunau   Decoração para SalazSmartphone 128GBT)stateordersr[   Unknownregions_analyzed)temperature	conditionclassificationr  )api_key_configuredtop_buyer_regionsweighted_weatherproduct_multipliersoverall_multiplierr   zError testing weather: Fr   r   N)app.services.weather_servicer  get_top_buyer_regionsget_weighted_weatherclassify_weatherr/   get_category_multiplierget_overall_multiplierr   boolapi_keyr   r   r   r   r   )r  servicetop_regionsweatherweather_classsample_productsr  productmultoverallr  r   r!   s                r"   test_weather_servicer  "  s   
7J+- 3313E ..000KK#KK(

 !& 	0G227;D+/(	0 002&*7??&; )4&$u $u5&
 $)VQ)?#C!(VY!?&3(/4F(J	% (;&-
  	&  .qc23V
   	s1   B4D 6DAD D 	E"0EEEz/forecast/analytics/evolutionc                  V   	 ddl m} m} ddlm}m} t        j                  j                  ddt              }t        j                  j                  d      }t        j                  j                  d      }t               }	 |r|r|j                  d	      r|j                  d	d
      }|j                  d	      r|j                  d	d
      }t        j                  |      }t        j                  |      }	|j                  |j                  d      }|	j                  |	j                  d      }	t!        |      dk(  rJ|	j                  ddd      }	n5t        j"                         t%        |      z
  }t        j"                         }	|j'                  |       j)                  | j*                  |j-                         k\        }
|r.|r,|
j)                  | j*                  |	j-                         k        }
|
j/                  | j*                  j1                               j3                         }|D ch c]  }|j*                   }}|D cg c]  }|j*                  j5                         t7        |j8                  xs d      t7        |j:                  xs d      |j<                  t7        |j>                  xs d      t7        |j@                  xs d      |jB                  |jD                  |jF                  d	 }}|j'                  |      j)                  |jH                  |k\        }|r |r|j)                  |jH                  |	k        }|j3                         }i }	 ddl m%} |j'                  |j-                  |jL                        jO                  d      |jQ                  |jR                        jO                  d            }|r5|r3|j)                   ||jL                  |k\  |jL                  |	k              }n|j)                  |jL                  |k\        }|jU                  |j-                  |jL                              j3                         }|D ]  }|jP                  ||j,                  <    	 i }|D ]  }|jH                  j-                         }||v r"||vr
g dddd||<   ||   dxx   t7        |jX                  xs d      z  cc<   ||   dxx   dz  cc<   |jZ                  #||   dxx   t7        |jZ                        z  cc<   |j\                  ||   d   j_                  t7        |j\                                |D ]  }||   d   }|rta        d |D              t!        |      z  nd}tc        dd|z
        }|j_                  |j5                         te        |d      te        |d      ||   d   te        ||   d   d      te        ||   d   d      |j                  |d      ddd	        |jg                  d        ti        d ||t!        |      d!d"      |jk                          S c c}w c c}w # tV        $ r Y w xY w# |jk                          w xY w# tV        $ r;}tl        jo                  d#|        ti        d$tq        |      d%      d&fcY d}~S d}~ww xY w)'zZ
    Get error evolution data for charting.
    Shows daily accuracy/error over time.
    r   )LearningSnapshotr   rW   rm   rR  typerK  rL  Zz+00:00Nr   r`  rM  rN  rO  rl   )	r-   r  r  r>   predicted_total
real_totalcalibrationsbest_factorworst_factorr   r-   r   )rW  	predictedrc   r   r  r[   rc   rW  c              3   2   K   | ]  }t        |        y wr]  r   r   r!   s     r"   r   z)get_learning_evolution.<locals>.<genexpr>  s     71A7   rn   rb   c                     | d   S )Nr-   rX  xs    r"   rY  z(get_learning_evolution.<locals>.<lambda>  s
    6 r   r|  T)	evolutionperiod_daystotal_pointsr   zError getting evolution: Fr   r   )9r   r  r   rw   rX   rY   r   r.   r/   r   r	   endswithr|   r   r   r   r   ry   r   r}   r   r   r-   r   r   r   r   r   acuraciaerro_absoluto_medior[  receita_prevista_totalreceita_real_totalajustes_realizadosmelhor_fator
pior_fatorr   r   r   r  r   r   r  r   r   r   r   r   r~   rA   r   sortr   r   r   r   r   )r  r   rX   rY   rm   rK  rL  r   sinceuntilsnapshots_query	snapshotsssnapshot_datesr  
logs_queryr   calibration_countsr   	cal_queryr  cal
daily_datar   drW  r  r  r!   s                                r"   get_learning_evolutionr  e  s   dAN)||5\\%%l3
<<##J/^W	h&&s+!+!3!3C!BJ$$S)'//X>H ..z: ..x8 <<+!MMM6E<<+!MMM6E x=B&!MMr"RMHE )==  !hh'78?? %%5O h"1"8"89I9N9NRWR\R\R^9^"_'001A1F1F1J1J1LMQQSI /88aff8N8 %  FF,,. %ajjoA 6!&q'<'<'A!B#$#4#4',Q-E-E-J'K"'(<(<(A"B$%$8$8#$>>$%LL
I 4 +.55%%.J h'..{/D/D/MN
>>#D "$KHHII0@@AGGOJJ1445;;GD	
 ( ) 0 0*::eC*::eC2 !I
 !* 0 01C1S1SW\1\ ]I(11$))<N<^<^2_`ddf' =C3699&sxx0= J OMM&&(&J&/11WX$YJqM 1k*eC4F4F4K!.LL*1g&!+& >>-qM&)U3>>-BB)&&2qM(+2259L9L3MN#O(   #Ax0IOC777#f+EUV	q#	/2  KKM %h 2!&y!!4#-a=#9',Z];-G'K"'
1f(=q"A$6$:$:1a$@#'$(
" 
$ NN2N3 !*#'$'	N  HHJe 9n  p HHJ A04553q6:;S@@As   A>Y$ F.Y /X5Y B/X:7A#Y DX? 0B'Y DY $Y$ 5
Y ?	YY YY Y!!Y$ $	Z(-0Z#Z(#Z(z/forecast/analytics/heatmapc                     	 ddl m}  ddlm} t        j
                  j                  ddt              }t               }	 t        j                         t        |      z
  }|j                  |       j                   || j                  |k\  | j                  j!                  d                  j#                         }i }|D ]  }|j                  j%                         }|j                  j&                  }	| d	|	 }
|
|vrg dd
||
<   ||
   d   j)                  t+        t-        |j                                     ||
   dxx   dz  cc<    g }g d}t/        d      D ]  }t/        d      D ]  }	| d	|	 }
|j                  |
g dd
      }|d   rt1        |d         t3        |d         z  nd}|j)                  ||   ||	|rt5        |d      nd|d   |r|dk  rdn|r|dk  rdn|rdndd         t7        d||t3        |      dd      |j9                          S # |j9                          w xY w# t:        $ r;}t<        j?                  d|        t7        dtA        |      d      dfcY d}~S d}~ww xY w) zn
    Get hour x day performance heatmap data.
    Shows which hour+day combinations have high/low errors.
    r   r   r   rm   rR  r  rl   N_rV  rW  r   r[   )segterquaquisexsabdom   r5   rb   r`  goodr   mediumbadno_data)day	day_indexr=   r  samplesr   T)heatmapr  total_samplesr   zError getting heatmap: Fr   r   )!r   r   rw   rY   r   r.   r/   r   r	   r   ry   r   r}   r   r   r   r   r   weekdayr=   r   r   r   rP   r~   r   r   r   r   r   r   r   r   )r   rY   rm   r   r  r   r   r   dowr=   r|  r    	day_namesr   r  r!   s                   r"   get_performance_heatmapr%    s   >A<#||5^3	LLNYD%99E88K(//))U2//55d;
 ce  G +mm++-}}))Qtfog%.01#=GCLX&--c%8K8K2L.MNW%*%+ FIIQx !"I D E4&/C";;srA,FGDMQRZ^DN 3c$x.6I IaeIMM(~%( $<EU9a%84#'=,5)b.&Zchqtvhvh  FO  }B  U^#  %#'%(Y  HHJBHHJ A.qc2353q6:;S@@As5   <H2 GH H2 H//H2 2	I6;0I1+I61I6z/forecast/analytics/factorsc                      	 ddl m} m}m} ddlm}m} t        j                  j                  ddt              }t               }	 t        j                         t        |      z
  }t        j                         t        d	      z
  }t        j                         t        d      z
  }	|j                  |      j!                         }
|j                  |      j#                  |j$                  |k\        j!                         }|j                  |      j#                  |j$                  |	k\        j!                         }i }|D ]`  }|j&                   d
|j(                   }t+        |j,                        t+        |j.                        z
  }|j                  |d      |z   ||<   b i }|D ]`  }|j&                   d
|j(                   }t+        |j,                        t+        |j.                        z
  }|j                  |d      |z   ||<   b |j                  |       j#                   || j0                  |k\  | j2                  j5                  d      | j6                  j5                  d                  j!                         }i }|D ]  }|j6                  st+        |j2                        }|j6                  j9                         D ]  \  }}|j;                  d      rX|j=                  dd      }t?        |      }| d
| }||vrg dd||<   ||   d   jA                  |       ||   dxx   dz  cc<   o|dvsttC        |t        t*        f      r| d
| }||vrg dd||<   ||   d   jA                  |       ||   dxx   dz  cc<    	 g }|
D ]   }|jD                   d
|jF                   }|j                  |g dd      }|d   r$tI        d |d   D              tK        |d         z  nd}|jA                  |jD                  |jF                  t+        |jL                        |jN                  |jP                  tS        |j                  |d      d      tS        |j                  |d      d      |rtS        |d      nd|d   |jT                  r|jT                  jW                         ndd
       # |jY                  d        i }|D ](  } | d   |vrg || d   <   || d      jA                  |        * t[        d||tK        |
      |dd      |j]                          S # |j]                          w xY w# t^        $ r;}!t`        jc                  d|!        t[        dt?        |!      d      d fcY d}!~!S d}!~!ww xY w)!z
    Get detailed factor performance and multiplier data.
    Shows each factor type with its sub-keys and their performance.
    r   )r   r   r   r   rm   r  r  rl   r5   r\   .N_meta_r  rV  rW  r   r[   )
restaurado
event_namemomentum_reasonseason_namec              3   2   K   | ]  }t        |        y wr]  r  r  s     r"   r   z'get_factor_analytics.<locals>.<genexpr>  s     E1AEr     rb   )
r  r|  valuerh   source
change_24h	change_7dr  r  
updated_atc                     | d   | d   fS )Nr  r|  rX  r  s    r"   rY  z&get_factor_analytics.<locals>.<lambda>  s    &	1U8'< r   r  r  T)factorsgroupedtotal_configsr  r   zError getting factors: Fr   r   )2r   r   r   r   rw   rY   r   r   r.   r/   r   r	   r   ry   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   rr  
startswithr|   r   r   rs  rg   r   r~   r   r   rk   r   r   r   r   r  r   r   r   r   r   )"r   r   r   rY   r   rm   r   r  	since_24hsince_7dr   calibrations_24hcalibrations_7dchanges_24hr   r|  change
changes_7dr   ry  r   rz  ftypefvalueactual_type
actual_keycomposite_keyr5  config
error_datar  r6  fr!   s"                                     r"   get_factor_analyticsrH  Y  si   yAbb)||4^n	LLNYD%99E )<<I||~	q(99H hh/0446G  "xx(:;BB"22i? ce  !hh'9:AA"22h>ce 
 K% Da7q||,uQ5E5E/FF#.??3#:V#CC D
 J$ Ba7q||,uQ5E5E/FF",..a"86"A
3B 88K(//))U2//55d;..44T: ce  M 9))S001 &)%7%7%=%=%? 9ME6 ''1&+mmHb&A%([
+6-q(E(=FHST;UM-8%m4X>EEdK%m4W=B= &ddmwx~  BE  GL  AM  nN!&q1m3<>1KM#.%c*84;;DA%c*73q83)99< G! Qv||n5*..srA4NO
eopxeyCE
80DEEJW_L`Haa  @D	"KK!<<"6<<0"("2"2$.."'Q(?"C!&z~~c1'=q!A8Ay!!4t)'2FLFZFZ&"6"6"@"@"B`d  & LL<L= G -V9G+)+GAfI&&	"))!,-
 &&%(\#'	  HHJBHHJ A.qc2353q6:;S@@AsD   AT9 K2T$ 8T$ GT$ T9 $T66T9 9	U=0U82U=8U=z6/forecast/analytics/factors/<factor_type>/<factor_key>PUTc                    	 ddl m}m} ddlm} t        j                         }|j                  d      }|t        ddd      d	fS t        |      }|d
k  s|dkD  rt        ddd      d	fS t               }	 |j                  |      j                  |j                  | k(  |j                  |k(        j                         }|s: || | |t!        t#        |d                  dd      }|j%                  |       d}	n<t        |j&                        }	 |t!        t#        |d                  |_        d|_         |t+        j,                         | | |t!        t#        |	d                   |t!        t#        |d                   |d      d |t!        t#        ||	z  dz
  dz  d                  d	      }
|j%                  |
       |j/                          t        d| ||	|dd      |j1                          S # |j1                          w xY w# t2        $ r;}t4        j7                  d|        t        dt!        |      d      dfcY d}~S d}~ww xY w)z4
    Manually update a factor multiplier value.
    r   )r   r   Decimalr/  NFzvalue is requiredr   r%   r  g      @z!value must be between 0.1 and 5.0   manualrn   )rg   r   r   r   rk         ?0r[   rb   zManual adjustment by user)	r   r   r   r   r   r   r   ajuste_percentualr   T)r  r|  	old_value	new_valuer   zError updating factor: r   )r   r   r   decimalrL  r   r  r/   r   r   r	   r}   r   rg   r   r  r   r   addr   r   r   utcnowr@  r   r   r   r   )factor_type
factor_keyr   r   rL  r   rS  r   rE  rR  r   r!   s               r"   update_factor_multiplierrY    s2   
DAU#!HHW%	u7JKLcQQ)$	s?i#ou7Z[\^aaa^1	XX./66 %%4 &&*4 eg 
 )$$!#eIq&9":;&! v	!&,,/	&s5A+>'?@#+  ) ( 1&&&s5A+>'?@"3uY':#;<"3<")#eY5JQ5NRU4UWX.Y*Z"[1
G FF7OIIK'%!*!*	  HHJBHHJ A.qc2353q6:;S@@AsC   AH $H ,
H 7E1G9 (H 9HH 	I0IIIz/forecast/analytics/snapshotsc                  N   	 ddl m}  t        j                  j	                  ddt
              }t               }	 t        j                         t        |      z
  }|j                  |       j                  | j                  |j                         k\        j                  | j                  j                               j!                         }g }|D ]  }|j#                  |j                  j%                         |j&                  t)        |j*                  xs d      t)        |j,                  xs d      t)        |j.                  xs d      t)        |j0                  xs d      |j2                  |j4                  |j6                  |j8                  |j:                  d        t=        d|t?        |      |d	d
      |jA                          S # |jA                          w xY w# tB        $ r;}tD        jG                  d|        t=        dtI        |      d      dfcY d}~S d}~ww xY w)z?
    Get daily learning snapshots for historical analysis.
    r   )r  rm   rR  r  rl   )r-   r>   r  r  r  r  r  r  r  factor_performanceadjustment_detailsT)r  r   r  r   zError getting snapshots: Fr   r   N)%r   r  r   r.   r/   r   r	   r   ry   r   r}   r   r   r-   r   r   r   r   r   r[  r   r  r  r  r  r  r  r   fatores_performancedetalhes_ajustesr   r   r   r   r   r   r   )r  rm   r   r  r  r    r  r!   s           r"   get_learning_snapshotsr_  '  s   
+AA||5^!	LLNYD%99E!1299 %%5h',,1134SSU  F FF,,.#$#4#4 %ajjoA 6!&q'<'<'A!B',Q-E-E-J'K"'(<(<(A"B$%$8$8#$>>$%LL*+*?*?*+*<*<  !' [#'  HHJBHHJ A04553q6:;S@@As5   6G  FG :G  GG   	H$)0HH$H$z/forecast/eventsc                     	 ddl m}  t        j                  j	                  dd      j                         dk(  }t        j                  j	                  d      }t        j                  j	                  d      }t               }	 |j                  |       }|r|j                  | j                  dk(        }|r|j                  | j                  |k\        }|r|j                  | j                  |k        }|j                  | j                  j                               j                         }t        d|D cg c]  }|j                   |j"                  |j$                  |j                  j'                         |j                  j'                         t)        |j*                        |j,                  |j.                  dk(  |j                  dk(  d		 c}t1        |      d
d      |j3                          S c c}w # |j3                          w xY w# t4        $ r;}t6        j9                  d|        t        dt;        |      d      dfcY d}~S d}~ww xY w)z5Get all forecast events, optionally filtered by date.r   ForecastEventactivetruefromtor   T)	r   nome	descricaodata_iniciodata_fimmultiplicadorrg   
recorrenteativo)eventsr   r   zError getting events: Fr   r   N)r   rb  r   r.   r/   lowerr	   r}   r   rm  rj  ri  r   r   r   r   r   rg  rh  r   r   rk  rg   rl  r   r   r   r   r   r   )rb  active_only	from_dateto_dater   r}   rn  r!   s           r"   get_forecast_eventsrs  ^  s   0A> ll&&x8>>@FJLL$$V,	,,""4(^#	HH]+E]%8%8C%?@]%;%;y%HI]%>%>'%IJ^^M$=$=$B$B$DEIIKF $*   #$$$$%FF)*+,==+B+B+D()

(<(<(>-21??-C$%FF*+,,#*=%&WW^
 ![ * HHJ%$ HHJ A-aS1253q6:;S@@AsJ   A?H B2G6 4BG1
G6  H 1G6 6HH 	I0I
I
Ic                  L   	 ddl m}  ddlm} t	        j
                         }g d}|D ]  }||vst        dd| d      dfc S  t               }	  | |d	   |j                  d
d      t        j                  |d   d      j                         t        j                  |d   d      j                          |t        |d               |j                  dd      |j                  dd      rdndd      }|j                  |       |j                          t        d|j                  |j                   dd      |j#                          S # |j#                          w xY w# t$        $ r;}t&        j)                  d|        t        dt        |      d      dfcY d}~S d}~ww xY w)zCreate a new forecast event.r   ra  rK  )rg  ri  rj  rk  FzMissing required field: r   r%   rg  rh  r  ri  r*   rj  rk  rg   rN  rl  r   r   )rg  rh  ri  rj  rk  rg   rl  rm  Tr   rg  r   zError creating event: r   N)r   rb  rT  rL  r   r  r   r	   r/   r   r,   r-   r   rU  r@  r   rg  r   r   r   r   )rb  rL  r   requiredfieldr   eventr!   s           r"   create_forecast_eventry    s   )A>#! H 	eED 5=UV[U\;]^_addd	e ^	!&\((;3$--d=.A:NSSU!**4
+;ZHMMO%c$*?&@AXXfh/"&((<"?3S	E FF5MIIK((!JJ  HHJBHHJ A-aS1253q6:;S@@AsA   -E E E C(E
 9E 
EE 	F#(0FF#F#z/forecast/events/<int:event_id>c                    	 ddl m} ddlm} t	        j
                         }t               }	 |j                  |      j                  |j                  | k(        j                         }|s t        ddd      df|j                          S d|v r
|d   |_        d	|v r
|d	   |_        d
|v r,t        j                   |d
   d      j#                         |_        d|v r,t        j                   |d   d      j#                         |_        d|v r |t)        |d               |_        d|v r
|d   |_        d|v r|d   rdnd|_        d|v r|d   rdnd|_        |j3                          t        d|j                  |j                  dd      |j                          S # |j                          w xY w# t4        $ r;}t6        j9                  d|        t        dt)        |      d      dfcY d}~S d}~ww xY w)z"Update an existing forecast event.r   ra  rK  FEvent not foundr   r   rg  rh  ri  r*   rj  rk  rg   rl  r   r   rm  Tru  r   zError updating event: r   N)r   rb  rT  rL  r   r  r	   r}   r   r   r  r   r   rg  rh  r   r,   r-   ri  rj  r   rk  rg   rl  rm  r@  r   r   r   )event_idrb  rL  r   r   rx  r!   s          r"   update_forecast_eventr}    s   +A>#!^ 	HH]+22=3C3Cx3OPVVXE5;LMNPSS8 HHJ3 ~!&\
d""&{"3$$,$5$5d=6I:$V$[$[$]!T!!)!2!24
3CZ!P!U!U!W$&&-c$2G.H&I#~!&\
t#*.|*<3# $%)']cIIK$xx<  HHJBHHJ A-aS1253q6:;S@@AsB   *F/ AF 9F/ 
C?F 	F/ F,,F/ /	G380G.(G3.G3c                    	 ddl m} t               }	 |j                  |      j	                  |j
                  | k(        j                         }|s t        ddd      df|j                          S |j                  |       |j                          t        dd| id	      |j                          S # |j                          w xY w# t        $ r;}t        j                  d
|        t        dt        |      d      dfcY d}~S d}~ww xY w)zDelete a forecast event.r   ra  Fr{  r   r   Tr  r   zError deleting event: r   N)r   rb  r	   r}   r   r   r  r   r   r?  r@  r   r   r   r   )r|  rb  r   rx  r!   s        r"   delete_forecast_eventr    s    A>^	HH]+22=3C3Cx3OPVVXE5;LMNPSS HHJ IIeIIKti5JKL HHJBHHJ A-aS1253q6:;S@@AsA   C AB1 C 00B1  C 1CC 	D
0D?D
D
z;/forecast/analytics/factors/<factor_type>/<factor_key>/lockc                 R   	 ddl m} t               }	 |j                  |      j	                  |j
                  | k(  |j                  |k(        j                         }|s t        ddd      df|j                          S |j                  dk(  rdnd}||_
        |j                          t        d	| ||dk(  d
d      |j                          S # |j                          w xY w# t        $ r;}t        j                  d|        t        dt        |      d      dfcY d}~S d}~ww xY w)zGToggle lock status on a factor (prevents auto-calibration when locked).r   r   FzFactor not foundr   r   r   r   T)r  r|  lockedr   zError toggling lock: r   N)r   r   r	   r}   r   rg   r   r  r   r   r  r@  r   r   r   r   )rW  rX  r   r   rE  new_lockr!   s          r"   toggle_factor_lockr    s    AA^	XX./66 %%4 &&*4 eg 
 5;MNOQTT" HHJ %mms2sH$FMIIK'%&#o  HHJBHHJ A,QC0153q6:;S@@AsA   C" AC -C" >>C <C" CC" "	D&+0D!D&!D&z/forecast/events/todayc                     	 ddl m}  ddlm} |j	                         }t               }	 |j                  |       j                  | j                  dk(  | j                  |k  | j                  |k\        j                         }d}|D ]  }|t        |j                        z  } t        d|j                         |D cg c]/  }|j                   |j"                  t        |j                        d1 c}t%        |d      t'        |      d	d
      |j)                          S c c}w # |j)                          w xY w# t*        $ r;}t,        j/                  d|        t        dt1        |      d      dfcY d}~S d}~ww xY w)z:Get events that are active today (for use in predictions).r   ra  )r-   r   rO  T)r   rg  rk  rM  )r-   rn  combined_multiplierr   r   zError getting today's events: Fr   r   N)r   rb  r   r-   r   r	   r}   r   rm  ri  rj  r   r   rk  r   r   r   rg  r   r   r   r   r   r   r   )rb  r-   r   r   rn  combinedr!   s          r"   get_active_events_for_todayr  4  sb   (A>!

^	XXm,33##s*))U2&&%/ ce	  H 3E!//223 !OO- $*
   #$$$$%FF-21??-C ,11+= [ " HHJ HHJ A5aS9:53q6:;S@@AsG   &D8 BD# :4D.D# D8 D# #D55D8 8	E<0E71E<7E<z/forecast/productsc                  H
   ddl m}  t               }	 |j                  |       j	                  | j
                  dk(        }t        j                  j                  d      }|r,|j	                  | j                  |j                         k(        }t        j                  j                  d      }|r|j	                  | j                  |k(        }t        j                  j                  d      }|r|j	                  | j                  |k(        }t        j                  j                  d      }|dk(  r|j	                  | j                  dk(        }t        j                  j                  d	d
      }t        j                  j                  dd      }| j                  | j                  | j                   | j"                  | j$                  d}	|	j                  || j                        }
|dk(  r |j'                  |
j)                               }n|j'                  |
j+                               }|j-                         }t/        d |D              }t/        d |D              }t/        d |D              }t1        dt3        |      |||t/        d |D              t/        d |D              t/        d |D              d|D cg c]  }i d|j4                  d|j6                  d|j8                  d|j:                  d|j                  xs |j<                  d|j                  dt?        |j@                  xs d      dt?        |jB                  xs d      dt?        |jD                  xs d      dt?        |jF                  xs d      dt?        |jH                  xs d      d|j                  xs dd t?        |j                  xs d      d!|jJ                  d"t?        |j"                  xs d      d#|j                   d$|jL                  |jN                  |jP                  t?        |j$                  xs d      |j                  |j                  t?        |jR                  xs d      t?        |jT                  xs d      d% c}d&d'      |jW                          S c c}w # tX        $ r_}tZ        j]                  d(|        dd)l/}|ja                          t1        d*tc        |      d+      d,fcY d)}~|jW                          S d)}~ww xY w# |jW                          w xY w)-aV  
    Get product-level forecast data with stock status.
    Query params:
    - curve: Filter by ABC curve (A, B, C)
    - stock_status: Filter by status (ok, low, critical, stockout)
    - category: Filter by category
    - sort_by: Sort field (revenue, units, stock, trend) default: revenue
    - sort_order: asc or desc, default: desc
    r   r  Tcurvestock_statusr+   rupture_onlyrd  r   r;   r   r   )r;   unitsstocktrendcoverager   c              3   N   K   | ]  }t        |j                  xs d         yw)r   N)r   forecast_revenue_todayr   rT   s     r"   r   z(get_product_forecasts.<locals>.<genexpr>  s      TaU1#;#;#@qATs   #%c              3   :   K   | ]  }|j                   sd   yw)r[   N)has_rupture_riskr  s     r"   r   z(get_product_forecasts.<locals>.<genexpr>  s     F!13E3EAFs   c              3   @   K   | ]  }|j                   d k(  sd  yw)stockoutr[   N)r  r  s     r"   r   z(get_product_forecasts.<locals>.<genexpr>  s     Q1ANNj4PQQ   c              3   @   K   | ]  }|j                   d k(  sd  yw)Ar[   Nr  r  s     r"   r   z(get_product_forecasts.<locals>.<genexpr>       "I!''S.1"Ir  c              3   @   K   | ]  }|j                   d k(  sd  yw)Br[   Nr  r  s     r"   r   z(get_product_forecasts.<locals>.<genexpr>  r  r  c              3   @   K   | ]  }|j                   d k(  sd  yw)Cr[   Nr  r  s     r"   r   z(get_product_forecasts.<locals>.<genexpr>  r  r  )total_productstotal_forecast_todayrupture_risk_countstockout_countcurve_acurve_bcurve_cr  r  	thumbnailr  pricecost
margin_pctavg_units_7davg_units_30dtotal_units_7dtotal_revenue_7dr  	trend_pctstock_current
stock_full)stock_localstock_incomingdays_of_coverager  r  forecast_units_todayr  )rO   productsr   z!Error getting product forecasts: NFr   r   )2r  r  r	   r}   r   	is_activer   r.   r/   r  r  r  category_normalizedr  r  r  r  r  r  r   r   r   r   r~   r   r   r  r  r  r  category_mlr   r  r  r  r  r  r  r  r  r  r  r  r   r   r   r   r   r   r   )r  r   r}   r  r  r+   r  r   r   sort_map
sort_fieldr  total_forecastrupture_countr  rT   r!   r   s                     r"   get_product_forecastsr  f  s    <	B`)001J1Jd1RS   )LL!6!6%++-!GHE||''7LL!=!=!MNE<<##J/LL!D!D!PQE ||''76!LL!A!AT!IJE ,,""9i8\\%%lF;
 '77$33$22$..'88
 \\'?+K+KL
NN:>>#34ENN:??#45E99; T8TTFxFFQQQ '*(m,:*7&4""Ih"II""Ih"II""Ih"IIH &76 5 !(( $Q[[ quu	
 #A$9$9$JQ]]    qww|!!4 affk 2 %eALL,=A&> 'ann.A(B (q/C!)D )!*:*:*?a +E!2D2D2I,J   $U1;;+;!%<  (!" %all#$ ()}}*+*:*:,1!2D2D2I,J(),-,>,>05a6L6L6QPQ0R278P8P8UTU2V1'*
 *d 	
M@  A8<=53q6:;S@@

A 	
sD   J&R$ 8GR
R$ R$ $	T-AT1T2T TT T!z/forecast/products/syncc                  X   	 ddl m}   |        }t        j                  d       |j	                          ddlm} t        j                  d        |       }t        d|dd      S # t        $ r;}t        j                  d	|        t        d
t        |      d      dfcY d}~S d}~ww xY w)zF
    Manually trigger comprehensive sync (Ads + Product Metrics).
    r   )
SyncEnginez![MANUAL-SYNC] Starting Ad Sync...)sync_product_metricsz.[MANUAL-SYNC] Starting Product Metrics Sync...Tz Full sync completed successfullyr  z!Error syncing product forecasts: Fr   r   N)app.services.sync_enginer  r   re  sync_adsapp.jobs.product_syncr  r   r   r   r   )r  sync_enginer  r    r!   s        r"   sync_product_forecastsr    s    
A7 l78 	?DE%'9
  	
  A8<=53q6:;S@@As   A"A% %	B).0B$B)$B)z/forecast/products/alertsc                     ddl m}  t               }	 g }|j                  |       j	                  | j
                  dk(  | j                  dk(  | j                  dkD        j                  | j                  j                               j                         }|D ]n  }|j                  r"t        |j                  |j                  z        nd}|j                  dd|j                  |j                   d|dd||j"                  d	       p |j                  |       j	                  | j
                  dk(  | j                  dk(  | j$                  dkD        j                  | j&                  j)                               j                         }|D ]|  }|j                  d
d|j                  |j                   d|j$                   dt        |j&                        dd|j$                  t        |j&                        |j"                  d       ~ |j                  |       j	                  | j
                  dk(  | j*                  dk(  | j&                  dk        j                  | j,                  j                               j/                  d      j                         }|D ]y  }||vs||vs|j                  dd|j                  |j                   dt        |j,                        ddt        |j,                        |j$                  |j"                  d       { t1        dt3        |      t5        d |D              t5        d |D              |dd      |j7                          S # t8        $ rK}t:        j=                  d|        t1        dt?        |      d      d fcY d!}~|j7                          S d!}~ww xY w# |j7                          w xY w)"z?
    Get critical alerts for products requiring attention.
    r   r  Tr  criticalz"Sem estoque - perda estimada de R$r_  z/dia)r  severityr  r  r>  daily_impactr  	low_stockhighu   Estoque crítico: z un (ra  z dias))r  r  r  r  r>  r  days_coverager  up   r  rising_demandr  zDemanda subindo u   % - considere reposição)r  r  r  r  r>  r  r  r  c              3   2   K   | ]  }|d    dk(  sd  yw)r  r  r[   NrX  r   as     r"   r   z%get_product_alerts.<locals>.<genexpr>;	  s     %WA1Z=J;Va%W   c              3   2   K   | ]  }|d    dk(  sd  yw)r  r  r[   NrX  r  s     r"   r   z%get_product_alerts.<locals>.<genexpr><	  s     !Oq}7N!!Or  )total_alertscritical_count
high_countalertsr   zError getting product alerts: Fr   r   N) r  r  r	   r}   r   r  r  r  r   r  r   r   r  r   r   r  r  r  r  r  r   r  r  r   r   r   r~   r   r   r   r   r   )	r  r   r  	stockoutsrT   
daily_lossr  risingr!   s	            r"   get_product_alertsr    sY   
 <	BK HH_-44%%-((J6((1,
 (?3388:
;CCE	 	  
	A<=GGq~~78JMM"&((?
3?OtT * 
	 88O,33%%-((J6))A-
 (?33779
:335	 	  
	AMM#"((//@eAL^L^F_`cEddjk!"!&q'9'9!:	 	
	 /*11%%-!!T),,r1
 (?,,113
4UU1Xcce	 	  	A	!ax&7+ (hhWW!1%2DS1IIbc!&q{{!3%&__WW	 		  #F"%%W%W"W!!OV!OO 	
  	
	  A5aS9:53q6:;S@@

	A 	
s=   JM M  B*M 	N/$0N*N/N2 *N//N2 2Oz/forecast/categoriesc                     ddl m}  t               }	 |j                  |       j	                  | j
                        j                         }t        dt        |      |D cg c]  }|j                  |j
                  |j                  |j                  t        |j                  xs d      t        |j                  xs d      t        |j                  xs d      t        |j                   xs d      |j"                  d	 c}dd      |j%                          S c c}w # t&        $ rK}t(        j+                  d|        t        d	t-        |      d
      dfcY d}~|j%                          S d}~ww xY w# |j%                          w xY w)z:Get all category mappings with their seasonal multipliers.r   CategoryMappingTrO  )	r   r  category_ml_namer  multiplier_summermultiplier_wintermultiplier_fallmultiplier_springr  )r   
categoriesr   zError getting categories: Fr   r   N)r  r  r	   r}   r   r  r   r   r   r   r  r  r   r  r  r  r  r  r   r   r   r   r   )r  r   r  r   r!   s        r"   get_categoriesr  L	  sL    <	BXXo.778S8STXXZ
Z (   dd'(}},-,>,>/0/D/D-213F3F3M#-N-213F3F3M#-N+01B1B1Ic+J-213F3F3M#-N%&[[

 2 	
+"  A1!5653q6:;S@@

	A 	
sC   AD B!D?
D D 	E3(0E.E3E6 .E33E6 6Fz&/forecast/categories/<int:category_id>category_idc                 2   ddl m} t               }	 |j                  |      j	                  |j
                  | k(        j                         }|s t        ddd      df|j                          S t        j                  }d|v r
|d   |_        d|v r
|d   |_        d	|v r
|d	   |_        d
|v r
|d
   |_        d|v r
|d   |_        d|v r
|d   |_        d|v r
|d   |_        |j%                          t        dd|j&                   dd      |j                          S # t(        $ r[}t*        j-                  d|        |j/                          t        dt1        |      d      dfcY d}~|j                          S d}~ww xY w# |j                          w xY w)zFUpdate category mapping with normalized name and seasonal multipliers.r   r  FzCategory not foundr   r   r  r  r  r  r  r  r  Tz	Category z updatedr=  zError updating category: r   N)r  r  r	   r}   r   r   r  r   r   r   jsonr  r  r  r  r  r  r  r@  r  r   r   r   rA  r   )r  r  r   r+   r   r!   s         r"   update_categoryr  q	  s    <	B#88O,33O4F4F+4UV\\^u7KLMsR> 	
; || D(+/0E+FH(%(,-?(@H%$&)-.A)BH&$&)-.A)BH&$'+,='>H$$&)-.A)BH&$!%k!2H
		"8#7#7"8A
  	
  A045
53q6:;S@@

A
 	
s8   AD /BD 	F&A E<&F'F <FF Fz/forecast/categories/syncc                      	 ddl m}   |        }t        d|d      S # t        $ r;}t        j                  d|        t        dt        |      d      dfcY d	}~S d	}~ww xY w)
z.Sync category mappings from existing products.r   )sync_category_mappingTr   zError syncing categories: Fr   r   N)app.jobs.category_syncr  r   r   r   r   r   )r  r    r!   s      r"   sync_categoriesr  	  sl    	A@&(
  	  A1!5653q6:;S@@As    	A!0AA!A!z$/forecast/learning/generate-for-datec                      ddl m}   |        S )Nr   generate_for_specific_date)!app.api.endpoints.forecast_extrasr  r  s    r"    generate_for_specific_date_router  	  s    L%''r   z"/forecast/learning/incomplete-daysc                      ddl m}   |        S )Nr   get_incomplete_days)r  r  r  s    r"   get_incomplete_days_router  	      E  r   z/forecast/allowed-factorsc                      ddl m}   |        S )Nr   get_allowed_factors)r  r  r  s    r"   get_allowed_factors_router  	  r  r   c                      ddl m}   |        S )Nr   add_allowed_factor)r  r   r  s    r"   add_allowed_factor_router  	  s    Dr   z)/forecast/allowed-factors/<int:factor_id>c                     ddl m}  ||       S )Nr   )delete_allowed_factor)r  r  )	factor_idr  s     r"   delete_allowed_factor_router  	  s    G ++r   )<__doc__loggingflaskr   r   r   r   app.apir   app.core.databaser	   rE  r   	getLogger__name__r   router#   r'   r   r3   rU   r   r   r   r   r   r:  rB  rH  r  r  r  r  r  r  r  r  r  r%  rH  rY  r_  rs  ry  r}  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rX  r   r"   <module>r     s    " (  * /			8	$ %1 2: (5':# ;#L +eW=#  >@ $ug6J 7JZ *UG<i =iX .@% A%P 6H' I'T '%9H :HV 4ugF[C [ G[| 4xjI  J* ?&R&C & S&R ,ug>o ?of )E7;q <qh ,vh?A @A. ,vh?"A @"AH /(D9 E9z 7&JA KAD 5xH) I)V &8; 9;D -w?iA @iAX +eW=CA >CAL +eW=~A >~AB FQVPWXHA YHAV -w?/A @/Al  5'22A 32Aj  6(3+A 4+A\ /%A-A B-A` /(DA EA2 KV\U]^"A _"AJ &8*A 9*Ab "UG4m 5m` '&:A ;A4 )E7;R <Rr $ug6! 7!H 6H( ( I(V )F8<A =A 4vhG( H(
 2UGD! E!
 )E7;! <! )F8<  =  9H:N, O,r   