
    !+i                          d Z ddlZddlmZmZmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZmZ ddlmZmZ  ej$                  e      Z G d d	      Zy)
zn
Hyper Forecast - Data Collector Module
Collects and aggregates historical sales data by hour for forecasting
    N)datetime	timedeltadate)DictListOptionalTuple)Session)funcand_)MlOrderMlOrderItemc            
           e Zd ZdZdefdZdededefdZ		 ddedeeef   fd	Z
	 ddedeeef   fd
Zg dfdedee   deeee   f   fdZdee   fdZ	 ddededee   fdZdedededefdZy)DataCollectorzK
    Collects historical sales data aggregated by hour for forecasting
    dbc                     || _         y )N)r   )selfr   s     R/var/www/hypershopcomercio.com.br/hyper-ai/app/services/forecast/data_collector.py__init__zDataCollector.__init__   s	        target_datetarget_hourreturnc           
         ddl m}  |t        d            }t        j                  |t         j                  j                               j                  ||      }|t        d      z   }|j                  |j                        j                  d      }|j                  |j                        j                  d      }| j                  j                  t        j                  t        j                        j                  d	      t        j                   t        j"                        j                  d
            j%                  t'        t        j(                  |k\  t        j(                  |k  t        j*                  j-                  g d                  j/                         }	|||	j0                  xs dt3        |	j4                  xs d      dS )z
        Get sales data for a specific date and hour (local time Brasilia)
        Database stores date_closed in UTC, so we need to convert
        r   timezonehourshourtzinfo   Nr"   order_countrevenuepaidshipped	delivered)r   r!   r%   r&   )r   r   r   combinemintimereplace
astimezoneutcr   queryr   countr   idlabelsumtotal_amountfilterr   date_closedstatusin_firstr%   floatr&   )
r   r   r   r   tz_brlocal_dt	local_end	start_utcend_utcresults
             r   get_hourly_saleszDataCollector.get_hourly_sales   sj    	& ,- ##K1B1B1DEMMS^glMmyq11	 ''5==T=J	&&x||4<<D<IJJwzz"((7HHW))*00;
 &##y0##g-""#CD
 %' 	  !--2V^^0q1	
 	
r   	days_backc           
      
   t        j                         }|t        |      z
  }| j                  j	                  t        j                  dt        j                        j                  d      t        j                  t        j                        j                  d      t        j                  t        j                        j                  d            j                  t        t        j                  |k\  t        j                  |k  t        j                   j#                  g d                  j%                  t        j                  dt        j                              j'                         }i }|D ]q  }t)        |j*                        }|j,                  xs d|z  t/        |j0                  xs d      |z  |j,                  xs dt/        |j0                  xs d      d||<   s t3        d      D ]  }||vsddddd||<    |S )	z{
        Calculate average sales pattern by hour over the last N days
        Returns dict with hour (0-23) as key
        daysr!   r%   r&   r'   r   )
avg_ordersavg_revenuetotal_orderstotal_revenue   )r   nowr   r   r1   r   extractr   r8   r4   r2   r3   r5   r6   r7   r   r9   r:   group_byallintr!   r%   r<   r&   range)	r   rD   end_date
start_dateresultspatternrowr!   hs	            r   get_hourly_patternz DataCollector.get_hourly_pattern?   s    <<>	y 99
 ''--LL!4!45;;FCJJwzz"((7HHW))*00;
 &##z1##x/""#CD
 (LL!4!45

#% 	  	Csxx=D"3!y@$S[[%5A6B # 41!&s{{'7a!8	GDM	 r 	A"##$$%%&	
	 r   c           
         t        j                         }|t        |      z
  }| j                  j	                  t        j                  dt        j                        j                  d      t        j                  t        j                        j                  d            j                  t        t        j                  |k\  t        j                  |k  t        j                  j                  g d                  j!                  t        j                  dt        j                              j#                         }t        d |D              }|dkD  r|dz  nd}i }|D ]N  }t%        |j&                        }	|	dkD  r|	dz
  dz  nd	}
t)        |j*                  xs d      }|dkD  r||z  nd
||
<   P t-        d      D ]  }||vsd
||<    |S )z_
        Calculate relative sales multiplier by day of week
        0=Monday, 6=Sunday
        rF   dowr&   r'   c              3   <   K   | ]  }|j                   xs d   yw)r   N)r&   ).0rs     r   	<genexpr>z8DataCollector.get_day_of_week_pattern.<locals>.<genexpr>   s     <qAIINN<s   r      r#      g      ?)r   rM   r   r   r1   r   rN   r   r8   r4   r5   r6   r7   r   r9   r:   rO   rP   rQ   r[   r<   r&   rR   )r   rD   rS   rT   rU   rK   avg_per_dayrV   rW   r[   
python_dowr&   ds                r   get_day_of_week_patternz%DataCollector.get_day_of_week_patternp   s    <<>	y 99
''--LL 3 34::5AHHW))*00;
 &##z1##x/""#CD
 (LL 3 34

#% 	 <G<<+81+<ma'!  	TCcgg,C*-'#'QqJCKK,1-G;F?'K"7PSGJ	T q 	!A 
	! r   )r#   r`         days_back_listc                     t        j                         j                         }i }|D ].  }|t        |      z
  }| j	                  ||      }|d   |d| <   0 |S )zr
        Get sales for the same hour on specific days back
        Used for weighted baseline calculation
        rF   r&   days_)r   rM   r   r   rC   )r   r   rh   todayhistoryrD   r   datas           r   get_sales_same_hour_historyz)DataCollector.get_sales_same_hour_history   si     ##%' 	;I)";;K((kBD+/	?GeI;'(	;
 r   c                     t        j                         j                         }t        j                         j                  }g }t	        |dz         D ]%  }| j                  ||      }|j                  |       ' |S )z?
        Get hourly sales for today up to current hour
        r#   )r   rM   r   r!   rR   rC   append)r   rk   current_hourhourly_datar!   rm   s         r   get_sales_today_so_farz$DataCollector.get_sales_today_so_far   so     ##%||~**,*+ 	%D((5Dt$	% r   reference_datecompare_typec                    |dk(  r|t        d      z
  }n9|dk(  r|t        d      z
  }n$|dk(  r|t        d      z
  }n|t        d      z
  }g }t        d      D ]%  }| j                  ||      }|j                  |       ' |S )	z<
        Get full day sales for a comparison period
        dayr#   rF   weekr`   monthrg   rL   )r   rR   rC   rp   )r   rt   ru   r   rr   r!   rm   s          r   get_sales_previous_periodz'DataCollector.get_sales_previous_period   s     5 (9!+<<KV#(9!+<<KW$(9"+==K(9!+<<K"I 	%D((d;Dt$	% r   mlb_idc                    ddl m}  |t        d            }t        j                  |t         j                  j                               j                  ||      }|t        d      z   }|j                  |j                        j                  d      }|j                  |j                        j                  d      }	| j                  j                  t        j                  t        j                        j                  d	      t        j                  t        j                   t        j                  z        j                  d
            j#                  t$              j'                  t)        t        j*                  |k(  t$        j,                  |k\  t$        j,                  |	k  t$        j.                  j1                  g d                  j3                         }
t5        |
j6                  xs d      t5        |
j8                  xs d      dS )zG
        Get sales data for a specific product, date, and hour
        r   r   r   r   r    r#   Nr$   unitsr&   r'   )r}   r&   )r   r   r   r+   r,   r-   r.   r/   r0   r   r1   r   r5   r   quantityr4   
unit_pricejoinr   r7   r   
ml_item_idr8   r9   r:   r;   r<   r}   r&   )r   r{   r   r   r   r=   r>   r?   r@   rA   rB   s              r   get_hourly_sales_by_productz)DataCollector.get_hourly_sales_by_product   s    	& ,- ##K1B1B1DEMMS^glMmyq11	 ''5==T=J	&&x||4<<D<IHH[))*009HH[++k.B.BBCII)T
 $w-&&&0##y0##g-""#CD	
 %' 	 6<<,1-V^^0q1
 	
r   N)rg   )Z   )rx   )__name__
__module____qualname____doc__r
   r   r   rQ   r   rC   rY   r<   re   r   strr   rn   rs   rz   r    r   r   r   r      s   7 &
&
 &
 
	&
T // 
c4i/f ** 
c5j	*^ %3 S	 
c8E?"	#	&T
 " #  
d	0%
%
 %
 	%

 
%
r   r   )r   loggingr   r   r   typingr   r   r   r	   sqlalchemy.ormr
   
sqlalchemyr   r   app.models.ml_orderr   r   	getLoggerr   loggerr   r   r   r   <module>r      sB     . . . . " ! 4			8	$k
 k
r   