
    Rj4                       S r SSKJr  SSKrSSKrSSKJr  SSKJr  SSKJ	r	  SSK
Jr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJrJrJrJr  \R6                  " \5      rSrSrSS jr SS jr!SS jr"SS jr# " S S5      r$g)u  Alertas de presupuesto Agents al 50 / 80 / 100 % del tope mensual.

Destinatarios: administrador (rol_id=2 o nombre), coordinador y evaluador del cliente.
Canal: campana in-app + email (si SMTP está configurado).
Una sola alerta por (cliente, usuario, mes, umbral).
    )annotationsN)datetime)Decimal)escape)Any)or_)Session)EmailServiceClass)settings)AgentsBudgetAlertModel)CustomerModelRolModel	UserModelUsersRolModel)2   P   d      c                 R    [         R                  " 5       n U R                  SSSSSS9$ )N   r   )dayhourminutesecondmicrosecond)r   utcnowreplace)nows    _C:\Users\jesus\Desktop\proyecto_pie360\backend\app\backend\classes\agents_budget_alert_class.py_month_start_utcr       s'    
//
C;;11Qqa;HH    c                    [         R                  " S5      =(       d    SR                  5       n / nU R                  S5       HL  nUR                  5       nU(       d  M   [	        U5      nSUs=::  a  S::  d  M7  O  M;  UR                  U5        MN     [        [        [        U5      5      5      =(       d    [        $ ! [
         a     M  f = f)NAGENTS_BUDGET_ALERT_THRESHOLDSz	50,80,100,r   r   )osgetenvstripsplitint
ValueErrorappendtuplesortedsetDEFAULT_THRESHOLDS)rawoutpartns       r   _thresholdsr4   $   s    9956E+
L
L
NCC		#zz|	D	A =S==JJqM  C!"8&88	  		s   B;;
C	C	c                ^   U (       d  SU 3$ U R                   =(       d    SR                  5       nU(       dj  SR                  S U R                  =(       d    SR                  5       U R                  =(       d    SR                  5       4 5       5      R                  5       nU=(       d    SU 3$ )NzCliente   c              3  8   #    U  H  nU(       d  M  Uv   M     g 7fN ).0r2   s     r   	<genexpr>"_customer_label.<locals>.<genexpr>9   s      
N DNs   	)company_namer'   joinnames	lastnames)ccustomer_idlabels      r   _customer_labelrE   4   s    +''^^!r((*E 
''-R..01;;3D"2K2K2MN
 
 %'	 	
 ,h{m,,r!   c                
   [        U R                  =(       d    S5      nU[        :X  d  US:X  a  g[        U R                  =(       d    S5      R                  5       nSU;   =(       d    SU;   =(       d    SU;   =(       d    SU;   $ )	Nr   r   Tr6   administradorcoordinador	evaluador
superadmin)r)   idGLOBAL_ADMIN_ROL_IDstrrollower)rN   ridr3   s      r   _role_is_budget_recipientrQ   A   sw    
cffk
C
!!SAXCGGMr  "A1 	A	!	 1	r!   c                      \ rS rSrSS jrSS jrSS jr            SS jr                  SS jr          SS jr	SS	S
.       SS jjr
SS jrSS jrSS jr\SS j5       rSrg)AgentsBudgetAlertClassN   c                    Xl         g r9   db)selfrW   s     r   __init__AgentsBudgetAlertClass.__init__O   s    r!   c           	        [        U5      nU R                  R                  [        5      R	                  [        [        R                  R                  S[        /5      [        R                  U:H  5      [        [        R                  R                  S5      [        R                  S:H  5      5      R                  5       nU Vs/ s H*  n[        U5      (       d  M  [        UR                  5      PM,     nnU(       d  / $ U R                  R                  [        5      R                  [         [         R"                  [        R                  :H  5      R	                  [         R$                  R                  U5      [        [         R                  R                  S5      [         R                  S:H  5      [        [        R                  R                  S5      [        R                  S:H  5      5      nUR	                  [        [        R                  U:H  [         R$                  S:H  5      5      R'                  5       R                  5       n[)        U5      $ s  snf )z?Usuarios admin / coordinador / evaluador del cliente (activos).r   Nr   )r)   rW   queryr   filterr   rK   in_rL   rC   deleted_status_idis_allrQ   r   r?   r   user_idrol_iddistinctlist)rX   rC   cidrolesrrole_idsquserss           r   list_recipients&AgentsBudgetAlertClass.list_recipientsR   s   +GGMM(#VKKOOQ(;$<=((C/ ..2248..!3	 SU 	 (-Mu!0I!0LICIuMI GGMM)$T-!6!6),,!FGV$$((2!3377=!33q8 //33D9//14
 	
  %%,$$)

 (*SSU 	 E{5 Ns   IIc                   U(       d  SSS.$ SSK Jn  [        U5      nU" U R                  5      R	                  U5      nUR                  S5      nUb  [        U5      S::  a  SSS.$ [        UR                  S5      =(       d    S5      n[        U5      nUS:  a  Xg-  S-  OS	n[        5       n	U R                  R                  [        5      R                  [        R                  U:H  5      R                  5       n
[        X5      nU R                  U5      nU(       d&  SS
[        US5      [        US5      [        US5      S.$ SnSn[!        5        Hc  nX:  a  M
  U R#                  UUUUUS9u  nnU H=  nU R%                  UUU	UUUUUS9nSnU(       d  M$  US-  nU R'                  UUUU5        M?     Me     U(       a  U R                  R)                  5         U[        US5      [        US5      [        US5      [+        U5      S.$ )uD   Tras registrar gasto: crea alertas 50/80/100 si se cruzó el umbral.r   no_customer)createdskipped)AgentsUsageClassmonthly_budget_usd	unlimitedmonthly_estimated_cost_usdg      Y@g        no_recipientsr         )rp   rq   percent	spent_usd
budget_usdF)	thresholdspentbudgetpctcustomer_name)rC   usermonth_startr|   r}   r~   titlemessageTr   )rp   ry   rz   r{   
recipients)&app.backend.classes.agents_usage_classrr   r)   rW   budget_gate_for_customergetfloatr    r\   r   r]   rK   firstrE   rl   roundr4   _copy_upsert_alert_send_emailcommitlen)rX   rC   rr   rf   gater~   r}   budget_fr   r   customerr   r   rp   touchedr|   r   r   r   was_news                       r   evaluate_after_spend+AgentsBudgetAlertClass.evaluate_after_spend   s	    ];;K+(AA#F./>U6]a/ [99dhh;<AB=,4qLu5(c&(GGMM-(//0@0@C0GHNNP 	 (6))#.
* a="5!_#Ha0  $I!ZZ#+ ( NE7 #,, # +'## - 	 7qLG$$T5'9E # '4 GGNNS!}ua!,j/
 	
r!   c               v    US:  a  SnSnOUS:  a  SnSnOSU S3nS	U S3nS
U SU SUS SUS SUS S3nXh4$ )Nr   z#Agentes: presupuesto agotado (100%)u   alcanzó o superó el 100%r   zAgentes: presupuesto al 80%u   superó el 80%zAgentes: presupuesto al %u   superó el u"   El gasto estimado de Agentes de «u   » z del tope mensual. Gastado: $z.2fz de $z USD (z.0fu*   %). Revisa el saldo en Agentes → Gastos.r:   )	rX   r|   r}   r~   r   r   r   levelr   s	            r   r   AgentsBudgetAlertClass._copy   s     9E0E"_1E$E.yk;E!)A.E0s5' Js5F3s) D55 	
 ~r!   c                  [        UR                  5      n	U R                  R                  [        5      R                  [        R                  U:H  [        R                  U	:H  [        R                  U:H  [        R                  [        U5      :H  5      R                  5       n
U
(       aW  [        [        [        US5      5      5      U
l        [        [        [        US5      5      5      U
l        Xzl        US S U
l        gU R                  R%                  [	        UU	U[        U5      [        [        [        US5      5      5      [        [        [        US5      5      5      US S US S SSS9
5        U R                  R'                  5         g)	Nrw   rx   i   F   r   )
rC   rb   r   threshold_percentrz   r{   r   r   	status_id
email_sentT)r)   rK   rW   r\   r   r]   rC   rb   r   r   r   r   rM   r   rz   r{   r   r   addflush)rX   rC   r   r   r|   r}   r~   r   r   uidrows              r   r   $AgentsBudgetAlertClass._upsert_alert   s8    $''lGGMM01V&22kA&..#5&22kA&88C	NJ	 UW 	 #CeQ$89CM$Svq)9%:;CNI!%4.CK"''"%i.!#eE1o"67"3uVQ'7#89DSk	
 	r!   c           
     D   [        USS 5      =(       d    SR                  5       nU(       d  g [        5       nUR                  5       (       d  g [        R
                  " S5      =(       d    [        [        SS 5      =(       d    SR                  S5      nU S3n[        USS 5      =(       d    SR                  5       =(       d    S	n	S
[        U	5       S[        U5       S[        USS9 S3n
UR                  UU
SU S3SS9n UR                  XRXS9nU(       a  U R                  R                  [        5      R                  [        R                  [!        UR"                  5      :H  [        R$                  [!        U5      :H  [        R&                  [)        5       :H  [        R*                  S:H  5      R-                  [        R"                  R/                  5       5      R1                  5       nU(       a  SUl        g g g ! [2         a    [4        R7                  SU5         g f = f)Nemailr6   FRONTEND_PUBLIC_URLfrontend_public_urlzhttp://localhost:3000/z/agents/usage	full_nameequipoz,
<p style="margin:0 0 16px 0;">Hola <strong>z-</strong>,</p>
<p style="margin:0 0 16px 0;">zA</p>
<p style="margin:0 0 24px 0;text-align:center;">
  <a href="T)quotez" style="display:inline-block;padding:12px 24px;background:#1593D5;color:#ffffff;text-decoration:none;font-weight:700;border-radius:8px;">Ver gastos de Agentes</a>
</p>
zAlerta de presupuesto Agents (z%)u)   Alerta automática de Pie360 — Agentes.)r   
inner_html	preheaderfooter_note)
text_plainr   r   z-No se pudo enviar email de alerta Agents a %s)getattrr'   r
   is_configuredr%   r&   r   rstripr   wrap_branded_layout	send_htmlrW   r\   r   r]   rb   r)   rK   r   r   r    r   order_bydescr   	Exceptionlogger	exception)rX   r   r   r   r|   tomailerfront	usage_urlnameinnerhtmlokr   s                 r   r   "AgentsBudgetAlertClass._send_email  s    dGT*0b779"$##%%II+, 'x!6='&
&+	 	
 g]+	k406B==?K8,,24L> :%g/ 09D)* +	 ))6ykDC	 * 
	R!!"T!FB GGMM"89V.66#dgg,F.@@C	NR.::>N>PP.99Q>	 X477<<>?UW  %&CN    	RLbQ	Rs   C7G< < HHNr   )r   limitc                  U R                   R                  [        5      R                  [        R                  [        U5      :H  5      nUb+  UR                  [        R                  [        U5      :H  5      nUR                  [        R                  R                  5       5      R                  [        S[        S[        U5      5      5      5      R                  5       nU Vs/ s H  o`R                  U5      PM     sn$ s  snf )N   r   )rW   r\   r   r]   rb   r)   r   r   
created_atr   r   minmaxra   
_serialize)rX   rb   r   r   rj   rowsrh   s          r   list_for_user$AgentsBudgetAlertClass.list_for_user>  s     GGMM0188"**c'l:
  /99S^KLAJJ-88==?@U3sC3u:./0SU 	
 -11Dq"D111s   "C?c                    [        U R                  R                  [        5      R	                  [        R
                  [        U5      :H  [        R                  S:H  5      R                  5       5      $ )Nr   )r)   rW   r\   r   r]   rb   r   count)rX   rb   s     r   unread_count#AgentsBudgetAlertClass.unread_countM  sS    GGMM01V&..#g,>&00A5 UW
 	
r!   c                ^   [         R                  " 5       nU R                  R                  [        5      R                  [        R                  [        U5      :H  [        R                  S:H  5      R                  SUS.SS9nU R                  R                  5         [        U=(       d    S5      $ )Nr   r   )r   reviewed_atF)synchronize_session)r   r   rW   r\   r   r]   rb   r)   r   updater   )rX   rb   r   updateds       r   mark_all_reviewed(AgentsBudgetAlertClass.mark_all_reviewedW  s    ooGGMM01V&..#g,>&00A5 V4$)   	 	7<a  r!   c                l   U R                   R                  [        5      R                  [        R                  [        U5      :H  [        R                  [        U5      :H  5      R                  5       nU(       d  gSUl        [        R                  " 5       Ul        U R                   R                  5         g)NFr   T)rW   r\   r   r]   rK   r)   rb   r   r   r   r   r   r   )rX   alert_idrb   r   s       r   mark_reviewed$AgentsBudgetAlertClass.mark_reviewedg  s}    GGMM01V&))S]:&..#g,> UW 	 "//+r!   c                   [        U R                  5      [        U R                  5      [        U R                  5      U R                  (       a  U R                  R                  5       S-   OS [        U R                  5      [        [        U R                  =(       d    S5      S5      [        [        U R                  =(       d    S5      S5      U R                  U R                  [        U R                  =(       d    S5      U R                  (       a  U R                  R                  5       S-   OS U R                  (       a   U R                  R                  5       S-   SS.$ S SS.$ )NZr   rw   rx   agents_budget)rK   rC   rb   r   r   rz   r{   r   r   r   r   r   kind)r)   rK   rC   rb   r   	isoformatr   r   r   rz   r{   r   r   r   r   r   )r   s    r   r   !AgentsBudgetAlertClass._serializew  s     cff+s/3;;'@C3??446<UY!$S%:%:!;uS]]%7a8!<cnn&9 :A>YY{{S]]/a0>Ann#..224s:RV@C3??446<#
 	
 VZ#
 	
r!   rV   )rW   r	   )rC   r)   returnzlist[UserModel])rC   
int | Noner   dict[str, Any])r|   r)   r}   r   r~   r   r   r   r   rM   r   ztuple[str, str])rC   r)   r   r   r   r   r|   r)   r}   r   r~   r   r   rM   r   rM   r   bool)
r   r   r   rM   r   rM   r|   r)   r   None)rb   r)   r   r   r   r)   r   zlist[dict[str, Any]])rb   r)   r   r)   )r   r)   rb   r)   r   r   )r   r   r   r   )__name__
__module____qualname____firstlineno__rY   rl   r   r   r   r   r   r   r   r   staticmethodr   __static_attributes__r:   r!   r   rS   rS   N   s8   +ZD
L  	
    
2- - 	-
 - - - - - - 
-^/R/R&)/R47/RDG/R	/Rd 8<"22*42DG2	2
!   
 
r!   rS   )r   r   )r   ztuple[int, ...])rB   zCustomerModel | NonerC   r)   r   rM   )rN   r   r   r   )%__doc__
__future__r   loggingr%   r   decimalr   r   r   typingr   
sqlalchemyr   sqlalchemy.ormr	   app.backend.classes.email_classr
   app.backend.core.configr   "app.backend.db.models.agents_usager   app.backend.db.models.pie_corer   r   r   r   	getLoggerr   r   r/   rL   r    r4   rE   rQ   rS   r:   r!   r   <module>r      ss    #  	      " = , E \ \			8	$"  I
9 
-
y
 y
r!   