
    J!j6                     n   d Z ddlZddlmZmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ dd	lmZ  ej                   e      Zd
ZdZd ZdedededefdZdededefdZdededefdZddededefdZd ZddefdZedk(  r0 ej@                  ejB                          e       Z" e#de"        yy)zZ
Hyper Pricing Job
Executes automated pricing strategies on Fridays at 22h (Brazil time).
    N)datetime	timedelta)Decimal)Session)SessionLocal)Ad)PriceAdjustmentLog)MeliApiServiceg      @   c            	         t         j                  d       t         j                  d       t         j                  d       t               } t        |       }ddddg d}	 | j	                  t
              j                  t
        j                  dkD  t
        j                  j                  d      t
        j                  dk(        j                         }t        |      |d<   t         j                  dt        |       d	       |D ]\  }t        | ||      }|d
   j                  |       |d   dk(  r|dxx   dz  cc<   :|d   dk(  r|dxx   dz  cc<   P|dxx   dz  cc<   ^ | j                          | j'                          t         j                  d|d    d|d    d|d    d       |S # t         $ r2}t         j#                  d|        | j%                          Y d}~pd}~ww xY w# | j'                          w xY w)z
    Main job function. Finds ads with active pricing strategies and executes
    the next step of price adjustment.
    
    Returns:
        dict with execution summary
    z2==================================================z"PRICING JOB: Starting execution...r   )	total_adsexecutedskippedfaileddetailsNactiver   Found z# ads with active pricing strategiesr   statussuccessr      r   r   zPricing job failed: zPRICING JOB COMPLETED: z executed, z
 skipped, z failed)loggerinfor   r
   queryr   filtertarget_marginsuggested_priceisnotr   alllen_execute_single_strategyappendcommit	Exceptionerrorrollbackclose)dbmeli_apiresultsads_with_strategiesadresultes          B/var/www/hypershopcomercio.com.br/hyper-ai/app/jobs/pricing_job.pyexecute_pricing_strategiesr/      s    KK
KK45
KK	Bb!H G !hhrl11q $$T*II!
 #%	 	  ##67fS!4566YZ[% 		'B-b(B?FI%%f-h9,
#q(#!Y.	"a'"!Q&!		' 			 	

KK)'**=)>k'R[J\I]]ghopxhygz  {B  C  DN  +A3/0
 	
s+   DF, ,	G'5(G"G* "G''G* *G<r'   r(   r+   returnc                 L   ddl }|j                  dd      j                         dk(  }|sjt        j	                  d|j
                   d       |j
                  |j                  r|j                  dd nd	d
dt        |j                  xs d      ddddS |j
                  |j                  r|j                  dd nd	dt        |j                  xs d      dd	d}t        |j                  xs d      }t        |j                  xs d      }t        ||z
        dk  r/d|d<   d|d<   t        j                  d|j
                   d       |S t        ||      }||d<   | j                  t              j                  t        j                   |j
                  k(  t        j"                  dk(        j%                         }	|	dz   }
t'        ||      }t        |j
                  t)        t+        |            t)        t+        |            t)        t+        |            |j,                  |
|dd	      }| j/                  |       | j1                          |j3                  |j
                  |      }|d   rL||_        d|_        d|d<   d|dd|d|d<   t        j                  d|j
                   d |dd|d       |S d!|_        |j5                  d"d#      |_        d!|d<   |j5                  d"d#      |d<   t        j9                  d|j
                   d$|j5                  d"              |S )%z8
    Executes a single pricing strategy for one ad.
    r   NML_PRICE_WRITE_ENABLEDfalsetrueu<   Fase 0 Lock: Tentativa de alteração de preço do anúncio u    bloqueada (Orquestração).2    FlockedPRICE_WRITE_LOCKED<   Escrita de preço no Mercado Livre bloqueada por segurança.)ad_idtitler   r   	old_price	new_pricer$   messagepending)r:   r;   r   r<   r=   r>   g{Gz?r   r   zAlready at target pricer>   [z#] Skipped - already at target pricer=   r   r   	scheduled	r:   r<   r=   target_pricer   step_numbertotal_stepstrigger_typer   zPrice updated: z.2fz -> z] SUCCESS: r   r$   zUnknown errorz
] FAILED: )osgetenvlowerr   warningidr;   floatpricer   absr   _calculate_step_pricer   r	   r   r:   r   count_calculate_total_stepsr   strr   addflushupdate_item_pricegeterror_messager$   )r'   r(   r+   rG   write_enabledr,   current_pricerC   
step_priceprevious_logsrD   rE   	log_entry
api_results                 r.   r    r    O   s    II6@FFHFRMUVXV[V[U\\xyzUU&(hhRXXcr]Brxx}1-)U	
 		
 "$((#2288=q)F "((-a(M++0q1L =<'(4/$x5yawABC '}lCJ$F; HH/077  BEE)!!Y. eg   !#K )EK #ee#m,-#j/*S./&& 
I FF9HHJ ++BEE:>J) %	$x-mC-@ZPSDTUyawk-)<DC@PQR M $	",../"J	#x&NN7ODyqz*..*A)BCDM    rY   rC   c                     | dk  r|S || z  dz
  dz  }t        |      dk  r|S t        dt        t        |      t        z        t        |      t        z  dkD  rdndz         }||z  }| d|dz  z   z  }t	        |d      S )z~
    Calculate the next step price, respecting max 5% change per step
    and distributing evenly across remaining steps.
    r   r   d         ?   )rN   maxintMAX_STEP_PERCENTround)rY   rC   total_change_percent	num_stepsstep_percentr=   s         r.   rO   rO      s    
  *M9Q>#E  1$ As3347GGHQTUiQjm}Q}  AD  RDA  JK  L  MI ()3L \C%7!78I Ar^   c                     | dk  ry|| z  dz
  dz  }t        |      dk  ryt        dt        t        |      t        z        t        |      t        z  dkD  rdz         S dz         S )z'Calculate total number of steps needed.r   r   r`   ra   )rN   rc   rd   re   )rY   rC   rg   s      r.   rQ   rQ      s    )M9Q>#E
 1$q#c./2BBCCPdLehxLx{~L~q  G  H  H  EF  G  H  Hr^   r:   c                 h   ddl }|j                  dd      j                         dk(  }|sdddd	d
S t               }t	        |      }	 |j                  t              j                  t        j                  | k(        j                         }|sddd|j                          S |rt        t        |      d      }n>t        |j                  xs d      }t        |j                  xs |      }	t        ||	      }t        |d      }t!        |j                  t#        t%        t        t        |j                  xs d      d                  t#        t%        |            t#        t%        t        t        |j                  xs |      d                  |j&                  dddd	      }
|j)                  |
       |j+                          |j-                  | |      }|d   r|j.                  r|j.                  dk  rt        |j                  xs d      |_        ||_        |j0                  xs ddz   |_        d|
_        |j5                          d|d   ||j0                  dd|j                          S d|
_        |j7                  d      |
_        |j5                          d|j7                  d      d|j                          S # t:        $ rS}|j=                          t>        jA                  d|  d|        dt%        |      dcY d}~|j                          S d}~ww xY w# |j                          w xY w)z
    Manual execution for a single ad. Used by the UI "jump to step" button.
    
    Args:
        ad_id: The MLB item ID
        target_price: Optional specific price to set. If None, uses next calculated step.
    r   Nr2   r3   r4   Fr7   r8   r9   )r   r   r$   r>   zAd not found)r   r$   rb   r   manualr?   rB   r   Tr<   zPrice updated successfully)r   r<   r=   current_stepr>   r   r$   zManual execution failed for z: )!rG   rH   rI   r   r
   r   r   r   rK   firstr&   rf   rL   rM   r   rO   r	   r   rR   r   rS   rT   rU   strategy_start_pricecurrent_step_numberr   r"   rV   rW   r#   r%   r   r$   )r:   rC   rG   rX   r'   r(   r+   rZ   rY   final_targetr\   r]   r-   s                r.   execute_single_ad_steprr      s    II6@FFHFRM)U	
 	
 
Bb!HBXXb\  %0668$~>~ 	
y u\2A6J ""((-a0M !3!3!D}EL.}lKJ :q)
 '%%c%bhhm!(<a"@ABc*o. U51C1C1Qz+RTU%V!WX**!

	 	y

 //zB
i **b.E.E.J*/A*>'!BH&(&<&<&AQ%FB"(IIIK'4' " 6 67* 	
  (I&0nnW&=I#IIK #0 	
  3
3E7"QC@A 3q622

3
 	
s?   A	K  !F=K  /A K   	L	8LLL LL L1c            	         t               } t        |       }	 | j                  t              j	                  t        j
                  dk(  t        j                  t        k        j                         }t        j                  dt        |       d       |D ]K  }|xj                  dz  c_        t        j                         |_        d|_        |j!                  |j"                  t%        |j&                              }|d   rd|_        | j                  t(              j	                  t(        j*                  |j"                  k(        j-                         }|rt%        |j&                        |_        t        j                  d|j"                   d       |j1                  d	      |_        t        j5                  d|j"                   d
|j1                  d	              N | j7                          | j=                          y# t8        $ r2}| j;                          t        j5                  d|        Y d}~Gd}~ww xY w# | j=                          w xY w)z
    Retry all failed price adjustments that haven't exceeded max retries.
    Called by scheduler if there were failures.
    r   r   z failed adjustments to retryr   retryr   r@   z] Retry SUCCESSr$   z] Retry FAILED: zRetry job failed: N)r   r
   r   r	   r   r   retry_countMAX_RETRIESr   r   r   r   r   utcnowlast_retry_atrF   rU   r:   rL   r=   r   rK   rn   rM   rV   rW   r$   r"   r#   r%   r&   )r'   r(   failed_logslogr]   r+   r-   s          r.   retry_failed_adjustmentsr{   -  s   
 
Bb!H"hh1299%%1**[8
 #% 	
 	fS-..JKL 	WCOOq O ( 1C&C "33CIIuS]]?STJ)$&
XXb\((#)));<BBD$S]]3BHa		{/:;$.NN7$;!q+;JNN7<S;TUV%	W( 			 	
	  /
)!-../ 	
s*   GH 	H?(H:5I :H??I Ic           	         t         j                  d       d}| st               } d}t        |       }	 t	        j
                         t        d      z
  }| j                  t              j                  t        j                  dk(  t        j                  |k\        j                         }d}d}|D ]  }|j                  |j                  g      }|s"|d   }	t        |	j!                  dd            }
t        |j"                        }t%        |
|z
        d	k  rd
|_
        |dz  }ud|_
        d| d|
 |_        |dz  }t         j)                  d|j                   d| d|
         | j+                          t         j                  d| d| d       |r| j3                          yy# t,        $ r2}t         j/                  d|        | j1                          Y d}~Jd}~ww xY w# |r| j3                          w w xY w)z
    Verifies if recent price changes were actually applied on Mercado Livre.
    Logs tagged as 'success' in the last 2 hours are checked against the live API.
    z6VERIFICATION JOB: Checking recent price consistency...FTrb   )hoursr   r   rM   g{Gz?verifiedr   mismatchzMISMATCH: Expected z, Found r@   z] Price MISMATCH! Expected R$ z, Found R$ zVERIFICATION COMPLETED: z verified, z mismatches.zVerification job failed: N)r   r   r   r
   r   rw   r   r   r	   r   r   executed_atr   get_item_detailsr:   rL   rV   r=   rN   rW   rJ   r"   r#   r$   r%   r&   )r'   local_sessionr(   cutoff_timerecent_logsverified_countmismatch_countrz   r   	item_data
live_priceexpected_pricer-   s                r.   verify_recent_price_changesr   [  s   
 KKHIM^b!H.oo')!*<< hh1299%%2**k9
 #% 	
  	uC //<G
Iy}}Wa89J"3==1N :./$6'
!#'
&9.9IR\Q]$^!!#399+-KNK[[fgqfrst-	u0 			.~.>k.IYYefg HHJ 	  045
 HHJ s*   E F& &	G!/(GG$ G!!G$ $G9__main__)levelzResult: )N)$__doc__loggingr   r   decimalr   sqlalchemy.ormr   app.core.databaser   app.models.adr   app.models.pricing_logr	   app.services.meli_apir
   	getLogger__name__r   re   rv   r/   dictr    rL   rO   rd   rQ   rR   rr   r{   r   basicConfigINFOr,   print r^   r.   <module>r      s    (  " *  5 0			8	$  7tX XN X Xt Xv e  8
H% 
Hu 
H 
HW# WU Wd Wt*\<G <~ zGgll+')F	HVH
 r^   