
    !+in                      |    d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	  e j                  e      Z G d d      Zy)    N)Session)func)Ad)MlMetricsDailyc                   B    e Zd ZdefdZdefdZdefdZd Z	d Z
d	 Zy
)MetricProcessor
db_sessionc                     || _         y )N)db)selfr	   s     K/var/www/hypershopcomercio.com.br/hyper-ai/app/services/metric_processor.py__init__zMetricProcessor.__init__   s	        ad_idc                    	 t         j                  j                         }|t        j                  d      z
  }|t        j                  d      z
  }|t        j                  d      z
  }|t        j                  d      z
  }| j                  j                  t        j                  t        j                        t        j                  t        j                              j                  t        j                  |k(  t        j                  |k\  t        j                  |k        j                         }| j                  j                  t        j                  t        j                        t        j                  t        j                              j                  t        j                  |k(  t        j                  |k\  t        j                  |k        j                         }|d   xs d}	|d   xs d}
|d   xs d}|d   xs d}d}|dkD  r|	|z
  |z  dz  }n|	dkD  rd}d}|dkD  r|
|z
  |z  dz  }n|
dkD  rd}||fS # t        $ r%}t        j!                  d| d	|        Y d
}~yd
}~ww xY w)z
        Calculates 7-day trends for Visits and Sales.
        Formula: ((Current 7d Avg - Previous 7d Avg) / Previous 7d Avg) * 100
        Or simple sum comparison: ((Sum 7d Current - Sum 7d Previous) / Sum 7d Previous) * 100
           days   r           d   g      Y@zError calculating trends for : N)NN)datetimedatetoday	timedeltar   queryr   sumr   visits	sales_qtyfilteritem_idfirst	Exceptionloggererror)r   r   r   end_datestart_date_currentend_date_prevstart_date_prevcurrent_metricsprev_metricscurr_visits
curr_salesprev_visits
prev_salesvisits_changesales_changees                   r   process_trendszMetricProcessor.process_trends   s3   9	MM'')E
 x11q99H!)H,>,>A,F!F.1C1C1KKM+h.@.@a.HHO #ggmm../112 f&&%/##'99##x/ eg   77==../112 f&&%/##6##}4 eg  *!,1K(+0qJ&q/.QK%a-AJ  MQ"-";{!Jc Qq %LA~!+j!8J F#Ma$ ,.. 	LL8r!EF	s   H=I   	I.	I))I.adc                    	 |j                   r|j                   dk  ry|j                   dz  }|dk(  ry|j                  |z  }t        |d      S # t        $ r/}t        j                  d|j                   d|        Y d}~yd}~ww xY w)	z
        Calculates estimated days of stock based on 30d sales.
        Formula: Available Quantity / (Sales 30d / 30)
        r   g     8@g      >@r   zError calculating DOS for r   Nr   )	sales_30davailable_quantityroundr$   r%   r&   id)r   r5   daily_sales_avgr   r3   s        r   calculate_days_of_stockz'MetricProcessor.calculate_days_of_stockP   s    
	<<2<<1#4 llT1O!#((?:Dq>! 	LL5beeWBqcBC	s!   A A A 	B%BBc                    | j                   j                  t              j                  t        j                  dk(        j                         }d}|D ]M  }| j                  |j                        \  }}|||_        |||_	        | j                  |      |_        |dz  }O | j                   j                          t        j                  d| d       y)z5
        Runs processing for all active ads.
        activer   Nr   zProcessed metrics for  ads.)r   r   r   r!   statusallr4   r:   visits_7d_changesales_7d_changer<   days_of_stockcommitr%   info)r   adscountr5   v_changes_changes         r   process_allzMetricProcessor.process_allc   s     ggmmB&&ryyH'<=AAC 	B!%!4!4RUU!;Hh#&.##%-"  $;;B?BQJE	 	,UG59:r   c                    t         j                  d       	 t        j                  j	                         }|t        j
                  d      z
  }ddlm}m} | j                  j                  |j                  t        j                  |j                              j                  ||j                   |j                   k(        j#                  |j$                  |k\        j#                  |j&                  dk7        j)                  |j                        j+                         }d}|D ]m  \  }}|s	| j                  j                  t,              j#                  t,        j.                  |k(        j1                         }	|	sYt3        |      |	_        |dz  }o | j                  j7                          t         j                  d| d	       y# t8        $ r<}
t         j;                  d
|
        | j                  j=                          Y d}
~
yd}
~
ww xY w)zC
        Aggregates sales from MlOrders into Ad.sales_30d.
        z(Aggregating Sales Metrics from Orders...   r   r   MlOrderMlOrderItem	cancelledr   zUpdated sales_30d for r?   z#Failed to aggregate sales metrics: N)r%   rF   r   r   r   r   app.models.ml_orderrO   rP   r   r   
ml_item_idr   r   quantityjoinml_order_idr!   date_createdr@   group_byrA   r   r:   r#   intr7   rE   r$   r&   rollback)r   r   
start_daterO   rP   resultsrH   r"   	total_qtyr5   r3   s              r   aggregate_sales_metricsz'MetricProcessor.aggregate_sales_metricsy   s    	>?#	
 MM'')E!3!3!<<J Aggmm&&--. d7G//;3J3JJKfW))Z78fW^^{23h{--.ce  E&- #"r*11"%%72BCIIKB'*9~
# GGNNKK0u=> 	LL>qcBCGG	s&   DG ,AG <A
G 	H2HHc           	         t         j                  d       	 t        j                  j	                         }|t        j
                  d      z
  }ddlm}m} ddl	m
}m} | j                  j                  |j                   ||j                  |      j!                  d      t#        j$                  |j&                        j!                  d      t#        j$                  |j(                  |j&                  z        j!                  d	            j+                  ||j,                  |j,                  k(        j/                  |j                  |k\        j/                  |j0                  d
k7        j3                  |j                   ||j                  |            j5                         }d}|D ]  \  }	}
}}|
s| j                  j                  t6              j/                  t6        j8                  |	k(  t6        j                  |
k(        j;                         }|s(t7        |	|
      }| j                  j=                  |       t?        |      |_         tC        |      |_"        |dz  } | j                  jG                          t         j                  d| d       y# tH        $ r<}t         jK                  d|        | j                  jM                          Y d}~yd}~ww xY w)zn
        Aggregates daily sales from MlOrders into MlMetricsDaily.
        Excludes cancelled orders.
        z.Aggregating Daily Sales Metrics from Orders...i  r   r   rN   )castDate	sale_dater]   total_revenuerQ   )r"   r   r   zUpdated Daily Metrics for z	 entries.z!Failed to aggregate daily sales: N)'r%   rF   r   r   r   r   rR   rO   rP   
sqlalchemyr`   ra   r   r   rS   rW   labelr   r   rT   
unit_pricerU   rV   r!   r@   rX   rA   r   r"   r#   addrY   r    floatsales_revenuerE   r$   r&   rZ   )r   r   r[   rO   rP   r`   ra   r\   rH   r"   rb   r]   	total_revmetricr3   s                  r   aggregate_daily_salesz%MetricProcessor.aggregate_daily_sales   s:   
 	DE+	MM'')E!3!3!==J A-ggmm&&W))4066{C--.44[A//+2F2FFGMMo^	
 d7G//;3J3JJKfW))Z78fW^^{23h{--tG4H4H$/OPce  E<C 8Iy (~6=="**g5"''94 %' 
 +G)LFGGKK'#&y> ',Y'7$
  GGNNKK4UG9EF 	LL<QC@AGG	s   I>J 	K2KKN)__name__
__module____qualname__r   r   strr4   r   r<   rK   r^   rl    r   r   r   r      s7    7 ?C ?B" &;,(T1r   r   )loggingr   sqlalchemy.ormr   rd   r   app.models.adr   app.models.ml_metrics_dailyr   	getLoggerrm   r%   r   rq   r   r   <module>rw      s5      "   6			8	$I Ir   