+
    ~Ai5                    N   R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t^ RI
H
t
Ht ^ RIHt ^ RIHt ^ RIHtHt ^ RIHtHt ^ RIHt ^ R	IHt ^ R
IHtHt ^ RIHtHt R R lt R^RR/R R llt!R R lt"R R lt#R R lt$R R lt%R R lt&R R lt'R R  lt(R! R" lt)R# R$ lt*R% R& lt+R' R( lt,]! R).4      ]! ].4      R* R+ l4       4       t-]! R,R).4      ]! ].4      R- 4       4       t.]! R,.4      ]! ].4      R. 4       4       t/]! R,.4      ]! ].4      R/ 4       4       t0R# )0ay  
Campaign endpoints expected by the React app (/api/campaigns/...).

These must run on the existing Django API host (localhost:8000) so the frontend
doesn't need a base URL change.

Data sources (matches backend/apps/cluster/dynamic_tables.py):
- Cluster DB: `{business_id}_campaigns`, `{business_id}_campaign_contacts`, `{business_id}_call_history`
- Master DB: `did_numbers`
)annotationsN)datetime	timedelta)ZoneInfo)Any)close_old_connectionsconnections)api_viewpermission_classes)IsAuthenticated)Response)_q_ident_table_names)_legacy_profile_for_usercluster_table_existsc                   V ^8  d   QhRR/# )   returnz
int | None )formats   "DE:\live-kit-agent\livekit_voicebot\backend\config\campaigns_views.py__annotate__r   !   s      Z     c                    \        V P                  4      pV'       d   VP                  R 4      MRp Ve   \        V4      # R#   \         d     R# i ; i)business_idN)r   usergetint	Exception)requestlegacybids   &  r   _resolve_business_idr"   !   sL    %gll3F'-&**]
#4C?s3x44 s   A A AAmin_vmax_vi'  c               0    V ^8  d   QhRRRRRRRRRRR	R/# )
r   qr   keystrdefaultr   r#   r$   r   r   )r   s   "r   r   r   *   s7     % %# %C %# % % %Z] %r   c                    \        V P                  W4      4      p\        V\	        WT4      4      #   \         d    Tp L$i ; iN)r   r   r   maxmin)r&   r'   r)   r#   r$   vs   &&&$$ r   
_parse_intr/   *   sC    c#$ uc!m$$  s   1 A Ac                    V ^8  d   QhRRRR/# )r   r.   r   r   boolr   )r   s   "r   r   r   2   s     + +3 +4 +r   c                    \        V \        4      '       d   V # \        V 4      P                  4       P	                  4       pVR9   # )1)r3   trueonyes)
isinstancer1   r(   striplower)r.   ss   & r   _php_truthyr;   2   s8    !TAA***r   c                   V ^8  d   QhRR/# )r   r   r   r   )r   s   "r   r   r   9   s     2 2( 2r   c                 @    \         P                  ! \        R 4      4      # )Asia/Kolkata)r   nowr   r   r   r   _now_istr@   9   s    <<011r   c                    V ^8  d   QhRRRR/# )r   dtr   r   r(   r   )r   s   "r   r   r   =   s     , , ,S ,r   c                    V P                   f   V P                  \        R4      R7      p MV P                  \        R4      4      p V P	                  R4      # )Nr>   tzinfo%Y-%m-%d %H:%M:%S)rE   replacer   
astimezonestrftime)rB   s   &r   _fmt_dtrJ   =   sD    	yyZZx7Z8]]8N34;;*++r   c                    V ^8  d   QhRRRR/# )r   rawr   r   r   r   )r   s   "r   r   r   E   s      s x r   c                R   V e   \        V 4      P                  4       R8X  d   \        4       # \        V 4      P                  4       pR FF  p \        P                  ! VP                  RR4      V4      pVP                  \        R4      R7      u # 	   \        P                  ! VP                  RR4      4      pVP                  f   VP                  \        R4      R7      pVP                  \        R4      4      #   \         d     K  i ; i  \         d    \        4       u # i ; i)zM
Accepts ISO strings or 'Y-m-d H:i:s'. Best-effort; falls back to now (IST).
 Zr>   rD   z+00:00)rF   z%Y-%m-%dT%H:%M:%Sz%Y-%m-%dT%H:%M:%S.%f)r(   r8   r@   r   strptimerG   r   r   fromisoformatrE   rH   )rL   r:   fmtrB   s   &   r   _parse_dt_anyrS   E   s     {c#hnn&",zCAQ	""199S"#5s;B::Xn%=:>> R##AIIc8$<=998N#;<B}}Xn566  		  zs&   AC<A(D <D
DD&%D&c                    V ^8  d   QhRRRR/# )r   r   r   r   	list[int]r   )r   s   "r   r   r   ]   s      S Y r   c                   \         R,          P                  4       ;_uu_ 4       pVP                  RV .4       VP                  4       pV'       d
   V^ ,          MRpRRR4       XR9   d   . # \	        V\
        4      '       d    \        P                  ! V4      p\	        V\        4      '       g   . # . pVP                  4        Fw  w  rV \	        V\        \        34      '       g1   \        V4      P                  RR^4      P                  4       '       d&   VP                  \        \        V4      4      4       Kw  Ky  	  V#   + '       g   i     L; i  \         d    . u # i ; i  \         d     K  i ; i)zU
businesses.retry_attempt is JSON (object). Extract numeric values preserving order.
r)   zCSELECT retry_attempt FROM businesses WHERE business_id = %s LIMIT 1NrN   .NrN   )r   cursorexecutefetchoner7   r(   jsonloadsr   dictitemsr   floatrG   isdigitappend)r   currowrL   out_kr.   s   &      r   _fetch_retry_attempt_valuesrg   ]   s*    
Y		&	&	(	(CY\g[hillnc!f 
) j	#s	**S/C c4  	C	!c5\**c!fnnS"a.H.P.P.R.R

3uQx=) /S  J) 
)	(  	I	  		s0   7E E 	A/E& E	E#"E#&E54E5c               (    V ^8  d   QhRRRRRRRR/# )r   r   r   retry_logicr(   custom_attempt_valuesr   r   r   )r   s   "r   r   r   x   s*      c  \_ dg r   c           	        VR 8X  d.   \        V 4      pV'       d   RP                  R V 4       4      # R# VR8X  d   \        V\        4      '       d	   V'       g   R# . pV F?  p Ve   \	        V4      MRpVP                  \        \        V^<,          4      4      4       KA  	  RP                  R V 4       4      # VR8X  d   R# R#   \
         d    Rp L`i ; i)business_logic,c              3  8   "   T F  p\        V4      x  K  	  R # 5ir+   r(   ).0r.   s   & r   	<genexpr>/_compute_waiting_time_values.<locals>.<genexpr>{   s     -1A   rN   custom_logicg        c              3  H   "   T F  q^ 8  g   K  \        V4      x  K  	  R# 5i)    Nro   )rp   ms   & r   rq   rr      s     :16As   ""	not_retry)	rg   joinr7   listr`   r   rb   r   round)r   ri   rj   valsminutesr.   ns   &&&    r   _compute_waiting_time_valuesr   x   s    &&*;715sxx---=2=n$/66>S&A !E!H3 NN3uQV}-. ' xx::::k!  s   $CCCc               (    V ^8  d   QhRRRRRRRR/# )r   r   r   did_nor(   bot_idr   r   r   )r   s   "r   r   r      s(     $ $ $c $3 $3 $r   c                \   V'       g   R# \         R,          P                  4       ;_uu_ 4       pVP                  R4       VP                  4       f   VuuRRR4       # VP                  R4       VP                  4       RJpVP                  R4       VP                  4       RJpRpV'       d
   VR,          pVR	,          pW.pVR9  d$   VR
,          pVP	                  \        V4      4       V'       d
   VR,          pVR,          pVP                  Wg4       VP                  4       pV'       g   VuuRRR4       # V'       d;   \        V4      ^8  d+   V^,          R9  d   \        V^,          4      uuRRR4       # \        V^ ,          4      uuRRR4       #   + '       g   i     R# ; i)z
Mirrors Laravel fetch of exe_number/did_no from did_numbers (direction='outbound' when exists).
Falls back to provided did_no.
rN   r)   SHOW TABLES LIKE 'did_numbers'N.SHOW COLUMNS FROM did_numbers LIKE 'direction'z/SHOW COLUMNS FROM did_numbers LIKE 'exe_number'zSELECT did_noz, exe_numberz8 FROM did_numbers WHERE business_id = %s AND did_no = %sz AND bot_id = %s AND direction = 'outbound'z LIMIT 1)NrN   rv   rX   )r   rY   rZ   r[   rb   r   lenr(   )	r   r   r   rc   has_directionhas_exe_numbersqlparamsrd   s	   &&&      r   _fetch_executive_numberr      sN   
 	Y		&	&	(	(C45<<>! 
)	( 	DEd2EFt3>!CII(1&%%CMM#f+&00CzC lln5 
)	(6 c#hls1vZ/Gs1v;9 
)	(: 3q6{; 
)	(	(	(s1   %FAF.AF5<F<F/F>FF+	c                    V ^8  d   QhRRRR/# )r   tabler(   r   r1   r   )r   s   "r   r   r      s        r   c                     \         R ,          P                  4       ;_uu_ 4       pVP                  RV .4       VP                  4       RJuuRRR4       #   + '       g   i     R# ; i  \         d     R# i ; i)r)   zSHOW TABLES LIKE %sNF)r   rY   rZ   r[   r   )r   rc   s   & r   _master_table_existsr      s^    #**,,KK-w7<<>- -,,,  s.   #A) %A

A) A&	 A) &A) )A87A8c                    V ^8  d   QhRRRR/# r   contentbytesr   z-tuple[list[dict[str, str]], list[str]] | Noner   )r   s   "r   r   r      s     E EE E6c Er   c           	     0  a  V P                  RRR7      pVP                  R4       Uu. uF  q"P                  4       R8w  g   K  VNK  	  pp\        V4      ^8  d   R# . pRpRp. p. ROp\	        V4       EF  w  rV
P                  4       p
V
'       g   K   . pV Fa  pVR8X  d5   ^ RIp^ RIp\        VP                  VP                  V
4      VR7      4      pMV
P                  V4      p\        V4      ^8  g   Ka   M	  V Uu. uF  p\        V4      P                  R	4      NK  	  ppV	^ 8X  d   Tp\	        V4       F  w  ppVP                  4       P                  4       o\        ;QJ d    V3R
 lR 4       F  '       g   K   RM	  RM! V3R
 lR 4       4      '       d   Tp\        ;QJ d    V3R lR 4       F  '       g   K   RM	  RM! V3R lR 4       4      '       g   K  TpK  	  EKw  V^ 8  g   EK  V^ 8  g   EK  V\        V4      8  d	   W,          MRpV\        V4      8  d	   W,          MRpV'       g   V'       g   EK  VP                  RVRV/4       EK  	  VR8X  g   VR8X  g	   V'       g   R# Wt3# u upi u upi   \         d     R# i ; i)z
Laravel-like ultra-robust parsing:
- tries delimiters: ',', '\t', ';', '|'
- detects name + contact columns by header variations
utf-8rG   )errors
rN   Nrm   )	delimiterz 	
 "'c              3  ,   <"   T F	  qS9   x  K  	  R # 5ir+   r   rp   kr~   s   & r   rq   1_parse_contacts_from_csv_bytes.<locals>.<genexpr>   s     ^+]a6+]   nameTFc              3  .   <"   T F
  pVS9   x  K  	  R # 5ir+   r   r   s   & r   rq   r      s       
"A Q"   contact)rm   	;|r   fullname	full_namecustomer_namer   phonemobilenumberphone_numbermobile_number)decodesplitr8   r   	enumeratecsvionextreaderStringIOr(   r9   anyrb   r   )r   textlnlinesheadersname_idxcontact_idxcontacts
delimitersilinerd   dr   r   xjhr   r   r~   s   &                   @r   _parse_contacts_from_csv_bytesr      s7   ?~~gi~8"jj.C.((*2B.Cu:>)+*
 'GA::<DC8szz"++d*;qzIJC**Q-Cs8q=   >AAS3q6<< 23SCAAv%g.DAq	)As^+]^sss^+]^^^#$s 
"
sss 
"
 
 
 '( /  1}!1(03s8(;s}.9CH.D#*"77OOVT9g$FGY (\ r>[B.h  w D: B>  s~   &J I<I<
J BJ :J #J%AJ J J ,J J #J 6J  ;J <J /J 9J <
J JJc                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   r     s     5 5U 57d 5r   c                  a  ^ RI p^ RIpVP                  VP                  V 4      RRR7      pW3P                  ^ ,          ,          pVP                  RR7      p\        VR4      pV'       g   R# V Uu. uF!  qwe   \        V4      P                  4       MRNK#  	  ppRp	Rp
\        V4       F  w  rVP                  4       P                  4       o\        ;QJ d    V3R lR 4       F  '       g   K   RM	  RM! V3R lR 4       4      '       d   Tp	\        ;QJ d    V3R	 lR 4       F  '       g   K   RM	  RM! V3R	 lR 4       4      '       g   K  Tp
K  	  V	R8X  g   V
R8X  d   R# . pV F  p\        T;'       g    . 4      pV	\        V4      8  d*   W,          e    \        W,          4      P                  4       MRpV
\        V4      8  d*   W,          e    \        W,          4      P                  4       MRpV'       g   V'       g   K  VP                  RVR
V/4       K  	  VP                  4        V'       g   R# W3# u upi   \          d     R# i ; i)rv   NT)	read_only	data_only)values_onlyrN   c              3  ,   <"   T F	  qS9   x  K  	  R # 5ir+   r   r   s   & r   rq   2_parse_contacts_from_xlsx_bytes.<locals>.<genexpr>  s     V#Ua6#Ur   r   Fc              3  .   <"   T F
  pVS9   x  K  	  R # 5ir+   r   r   s   & r   rq   r     s       
A Qr   r   r   r   r   )r   openpyxlload_workbookBytesIO
sheetnames	iter_rowsr   r(   r8   r   r9   r   rz   r   rb   closer   )r   r   r   wbws	rows_iter
header_rowcr   r   r   r   r   r   rrd   r   r   r~   s   &                 @r   _parse_contacts_from_xlsx_bytesr     s   4##BJJw$74SW#Xa !LLTL2	)T*
DNOJq]3q6<<>:JOg&DA	!AsV#UVsssV#UVVVs 

sss 

 
 
   '" r>[B.)+AqwwB-C19CH1DIb3s}%++-hjD S)c.>.J C$%++- 
 wwy' BC  	
  O PP  sh   A*I /I 3'IAI 0I I I 2I I (I =BI I 0I ?I I IIc               $    V ^8  d   QhRRRRRR/# )r   r!   r   campaign_rowzdict[str, Any]r   ztuple[int, bool]r   )r   s   "r   r   r   <  s"       N O_ r   c                   \        VP                  R4      ;'       g    ^ 4      ^ 8H  p\        VP                  R4      ;'       g    R4      pV'       g   R
# VR8X  d   R# \        VP                  R4      ;'       g    R4      P                  4       pV'       d   VP	                  R4       Uu. uFa  qUP                  4       '       g   K  VP                  4       P                  RR^4      P                  4       '       g   KQ  VP                  4       NKc  	  ppV'       d   \        V4      ^,           R3# ^R3# VR	8X  d,   \        V 4      pV'       d   \        V4      ^,           R3# ^R3# R# u upi )a  
Port of Laravel storeCampaignContacts logic (simplified to match our campaign creation):
- run_now=0 => set retry now based on waiting_time, unless retry_logic=not_retry
- run_now=1 => retry=0 (scheduled will be set at start)
Returns (retry_value, is_run_now).
run_nowri   rN   rx   Twaiting_timerm   rW   rl   )rv   F)   T)	r   r   r(   r8   r   rG   ra   r   rg   )r!   r   
is_run_nowri   waitingppartsr|   s   &&      r   _retry_value_for_contact_insertr   <  s1    \%%i055A6!;Jl&&}5;;<Kk!,"">288b9??AG$+MM#$6p$6q'')	HYHYZ]_acdHeHmHmHo$6p#(E
Q55a55 &&*3/"&D	At33At33N qs   ,E)2E)?E)POSTc                   V ^8  d   QhRR/# )r   campaign_idr   r   )r   s   "r   r   r   [  s     c c3 cr   c                *	  a \        V 4      pV'       g   \        RR/RR7      # V R2pV R2o\        V4      '       g   \        RR/R	R7      # \        S4      '       g   \        RR
/R	R7      # V P                  P	                  R4      pV'       g   \        RRRRR.//RR7      # VP
                  '       d/   \        VP
                  4      R78  d   \        RRRRR.//RR7      # \        VRR4      ;'       g    RP                  4       pVP                  4       pRpVP                  R4      '       d   \        V4      pM\        V4      pV'       g   \        RRRR/RR7      # Vw  r\        R,          P                  4       ;_uu_ 4       p
V
P                  R\!        V4       R2\        V4      .4       V
P#                  4       pV'       g   \        RR/R	R7      uuRRR4       # V
P$                   Uu. uF  q^ ,          NK  	  pp\'        \)        W4      4      p\        VP	                  R4      ;'       g    ^ 4      p\+        W.4      w  pp\-        \/        4       4      p. pV F  pVP	                  R4      ;'       g    RP1                  4       pVP	                  R4      ;'       g    RP1                  4       pV
P                  R\!        S4       R2V\        V4      VVVVVV.4       VP3                  RV
P4                  R VR!R"RVR#\        V4      R$V/4       K  	  \7        V4      pVV,           pV
P                  R%\!        V4       R&2V\        V4      .4       RRR4       R' V3R( llp X Uu. uF1  qP	                  R4      f   K  \        VP	                  R4      4      NK3  	  pp\9        XP	                  R)4      ;'       g    R*4      P1                  4       ;'       g    R*pV'       dI   \:        P<                  ! VR$\        V4      R#\        V4      R+VR,V/R-R.V R/V 2R07      P?                  4        \        RR1\7        T4       R22R3XRXR4XR5TR6XR#\        T4      RR-/4      # u upi   + '       g   i     EL; iu upi   \@         d     L\i ; i)8z
Endpoint expected by the React app:
POST /api/campaigns/{id}/contacts
multipart/form-data with field `file`.

Stores contacts into cluster table `{business_id}_campaign_contacts` and increments
`{business_id}_campaigns.total_count`.
detail(No business profile found for this user.  status
_campaigns_campaign_contactsmessagezCampaign not foundi  z&Campaign contacts table does not existfileValidation failedr   required  zmax 10MBr   rN   Nz.xlsxzNo valid contact data foundsuccessFclusterSELECT * FROM  WHERE campaign_id = %s LIMIT 1total_countr   z
                INSERT INTO z
                (business_id, campaign_id, name, number, source, status, `retry`, created_at, updated_at)
                VALUES (%s, %s, %s, %s, %s, 'pending', %s, %s, %s)
                idr   r   pendingr   r   UPDATE z, SET total_count = %s WHERE campaign_id = %sc          
     ,    V ^8  d   QhRRRRRRRRRR	/# )
r   r   r   r   contact_idsrU   
agent_namer(   r   Noner   )r   s   "r   r   .campaign_contacts_upload.<locals>.__annotate__  sC     g  g g  g  	g 
 g  
g r   c                  < \        4        \        P                  ! R 4      ;'       g!    \        P                  ! R4      ;'       g    RP                  4       p\        P                  ! R4      ;'       g    RP                  4       P	                  R4      p\        P                  ! R4      ;'       g    RP                  4       P	                  R4      p\        P                  ! R4      ;'       g    RP                  4       pV'       d!   VP                  R4      '       g
   RV,           p\        P                  ! R	4      ;'       g    R
P                  4       pV'       d!   VP                  R4      '       g
   RV,           pV'       d   V V 2MRp	Rp
Rp\        R,          P                  4       ;_uu_ 4       pVP                  R\        S4       R24       VP                  4       RJp
VP                  R\        S4       R24       VP                  4       RJpRRR4       \        V4       EF  w  r \        R,          P                  4       ;_uu_ 4       pVP                  R\        S4       R2\        V4      \        V4      \        V 4      .4       VP                  4       pV'       g    RRR4       K  \        V^,          ;'       g    R4      P                  4       pV'       g   V'       d>   VP                  R\        S4       R2R\        \        4       4      \        V4      .4       M;VP                  R\        S4       R2\        \        4       4      \        V4      .4        RRR4       EKI  RV RV 2pV
'       d   V'       d?   VP                  R\        S4       R2VR\        \        4       4      \        V4      .4       MVP                  R\        S4       R2V\        \        4       4      \        V4      .4       MV'       d>   VP                  R\        S4       R2R\        \        4       4      \        V4      .4       M;VP                  R\        S4       R2\        \        4       4      \        V4      .4       RRR4       V'       d
   V V RX 2MRpRXRVR X/pV	'       d   V	VR!&   V'       d   VVR"&   \         P"                  ! V4      P%                  R#4      p\&        P(                  P+                  VVR$R%/R&R'7      p \&        P(                  P-                  VR(R)7      ;_uu_ 4       pVP/                  4       p \         P0                  ! VP3                  R#4      4      p\        VP7                  R*4      ;'       g    R4      P                  4       p\        VP7                  R+4      ;'       g    R,4      P                  4       p\9        V\:        4      '       d   \=        VP7                  R-4      4      MRpRRR4       \        R,          P                  4       ;_uu_ 4       pX'       Ed%   T
'       d   X'       d   T'       dG   TP                  R\        S4       R22TXR3,          \        \        4       4      \        T4      .4       EMMTP                  R\        S4       R42T\        \        4       4      \        T4      .4       EMT'       dE   TP                  R\        S4       R52XR3,          \        \        4       4      \        T4      .4       MTP                  R\        S4       R62\        \        4       4      \        T4      .4       MT'       dE   TP                  R\        S4       R2XR3,          \        \        4       4      \        T4      .4       M;TP                  R\        S4       R2\        \        4       4      \        T4      .4       RRR4       T\E        T4      ^,
          8  g   EK  \F        PH                  ! R74       EK  	  \        4        R#   + '       g   i     EL; i  + '       g   i     EL; i  \4         d    / p ELi ; i  + '       g   i     ELn; i  \&        P>                  P@                   d    pRpR.\C        TR/R04       2pRp Rp?ELRp?i\4         d    RpR1pRp ELi ; i  + '       g   i     L; i  \4         d     ELi ; i)8MCUBE_LOCAL_OUTBOUND_URLMCUBE_OUTBOUND_CALL_URLz-http://127.0.0.1:8088/api/mcube/outbound-callMCUBE_PUBLIC_BASE_URLrN   /MCUBE_PUBLIC_WS_URL_BASEMCUBE_WS_PATH_PREFIXz/wsMCUBE_WEBHOOK_PATHz/webhooks/mcubeFr   SHOW COLUMNS FROM z LIKE 'call_id'Nz LIKE 'dialstatus'zSELECT id, number FROM z@ WHERE id = %s AND campaign_id = %s AND business_id = %s LIMIT 1r   z> SET status='failed', dialstatus=%s, updated_at=%s WHERE id=%smissing_numberz/ SET status='failed', updated_at=%s WHERE id=%scmp_	_contact_zK SET status='calling', call_id=%s, dialstatus=%s, updated_at=%s WHERE id=%scallingz< SET status='calling', call_id=%s, updated_at=%s WHERE id=%sz? SET status='calling', dialstatus=%s, updated_at=%s WHERE id=%sz0 SET status='calling', updated_at=%s WHERE id=%stor  call_idcallback_urlrefurlr   zcontent-typezapplication/jsonr   )datar   methodg      4@)timeoutmcube_call_sidr   	initiatedokhttp_code  request_errorzM SET status='initiated', call_id=%s, dialstatus=%s, updated_at=%s WHERE id=%s:N   Nz> SET status='initiated', call_id=%s, updated_at=%s WHERE id=%szA SET status='initiated', dialstatus=%s, updated_at=%s WHERE id=%sz2 SET status='initiated', updated_at=%s WHERE id=%sg       @)%r   osgetenvr8   rstrip
startswithr   rY   rZ   r   r[   r   r   r(   rJ   r@   r\   dumpsencodeurllibr   Requesturlopenreadr]   r   r   r   r7   r^   r1   error	HTTPErrorgetattrr   timesleep) r   r   r  r  outbound_urlpublic_base	public_ws	ws_prefixwebhook_pathr  has_call_idhas_dialstatuscur2idxcidcur3rd   r   refidr  payloadr  reqresprL   	resp_json	mcube_sid
status_txtr  ecur4contacts_tables    $$$$                           r   _autocall_worker2campaign_contacts_upload.<locals>._autocall_worker  s    	II01 ? ?yy23? ?>
%'	 	 yy!89??RFFHOOPSTYY9:@@bGGIPPQTU	YY56??%FFH	Y11#66iI		"67LL;LSSU 7 7 < <-L9D+|n5" #**,,LL-h~.F-GWX--/5KLL-h~.F-GGYZ[!]]_D8N	 - "+.HC +2244LL1(>2J1K LZ ZS3{#3S5EF
 --/C  54 !Q2.446F!) LL")(>*B)C D. !.!178:3FC Q !LL")(>*B)CCr s!(!4c#h ? !/ 542 #;-y>E") LL")(>*B)C D. !.!&	78:3FC Q !LL")(>*B)CC  !A!&
(;SX F
 * LL")(>*B)C  DC  !D!*GHJ,?S J
 !LL")(>*B)CCs t!(!4c#h ?[ 5f ?HI;yk5':R & *u
  .:GN+(.GH%zz'*11':nn,, +-?@!	 - #//T/BBd"iik+(,

3::g3F(GI %(	6F(G(M(M2$N$T$T$V	%(x)@)O)OK%P%V%V%X
:DYPT:U:UT)--"56[` C$ !+2244r&9- $&-h~.F-G  HU  %V%.
40@'(*BUWZ[^W_$`!"
 !%&-h~.F-G  HF  %G%.
0CSX$N!"
  . $&-h~.F-G  HI  %J%/%5wxz7JCPSH$U!"
 !%&-h~.F-GGy$z%,XZ%8#c($C!"
 * LL")(>*B)C  DB  !C!+D!178:3FC Q
 !LL")(>*B)CCr s!(!4c#h ?? 5N S%))

3G /J 	W -,, 544V  ) +(*I+	 CBB ||-- #B#(FC)@(A!BJ "I  #B!0J "I#
 54F  sZ  5A!`,0#c#Aa *c#4a 	a &a .A9a 'c#2a a 
Ba A8a c#c#0c#=Ac#)a<6a(%a-a(
1a(<Aa(a<#c#.c ccBcBc$A?c#c#,`=	 a	c#a%	!a($a%	%a((a93a<7c#9a<<cb5/c#5cc	c#cc#c c# c##c21c2r   r)   r  r  Tcampaign_autocall__)targetkwargsdaemonr   zSuccessfully parsed z	 contactscontacts_importedprevious_countcontacts_datainserted_contactsi   )!r"   r   r   FILESr   sizer   r.  r9   r+  endswithr   r   r   rY   rZ   r   r[   descriptionr^   zipr   rJ   r@   r8   rb   	lastrowidr   r(   	threadingThreadstartr   )r   r   r!   campaigns_tableupfilenamer   parsedr   _headersrc   camp_rowr   	camp_colscampaigncurrent_totalretry_value_is_run_nownow_srP  r   r   	new_countupdated_totalrF  r  r  rE  s   &&                         @r   campaign_contacts_uploadrh  Y  s{    w
'C#MNWZ[[Z(Ou./N00$89#FF//$LMVYZZ			6	"B$7FZLCYZcfgg	www3rww<"22$7FZLCYZcfggFB'--2446HggiGF!!09/8$A9eT]`aaH	Y		&	&	(	(CXo677VW	
 <<>Y(<=cJ 
)	( $'??3?aqTT?	3I01HLL7<<1=#B3#Q [
#24AEE&M''R..0DeeI&,,"335FKK%n56 7
 c+&fhUTYZ $$#--fiD!3{#3!3	 , M	%	1h/00\]C,-	
U 
)bg  g R1B^1BAeeDk's155;'1B^h/<<9=CCERR
'!3s8!3{#3!; *	 )#a}=
 eg
 -c(m_IF=mX!23{+t		
 K 4 
)	(	(v _  sp   
AQ+%Q+3Q&A9Q+>(Q+'B3Q+,R 0Q?	Q?'R R "
R -AR &Q++Q<	?R RRGETc                   \        V 4      pV'       g   \        R R/RR7      # V P                  R8X  Ed   \        V P                  \
        4      '       d   V P                  M/ pVP                  R4      ;'       g    RP                  4       pV'       g   \        RRR	RR
.//RR7      # VP                  R4      p\        VP                  RR4      4      pV'       d   \        VP                  R4      4      pM
\        4       pV\        RTR7      ,           p\        VP                  RR4      4      pV'       d   ^M^ p	\        VP                  R4      ;'       g    R4      p
VP                  R. 4      p\        WV4      p\        VP                  R4      ;'       g    R4      P                  4       pVP                  R4      p\        WV4      pV R2p\        V4      '       g   \        RRRR/RR7      # \         R,          P#                  4       ;_uu_ 4       pVP%                  R\'        V4       R24       VP)                  4       RJpVP%                  R\'        V4       R 24       VP)                  4       RJpVP%                  R\'        V4       R!24       VP)                  4       RJp. RUOpTTTV'       d   R$MR%^ T;'       g    RT\+        V4      \+        V4      VP-                  R&4      VP-                  R&4      T	V'       d   ^M^ ^
^\+        \        4       4      \+        \        4       4      .pV'       d#   VP/                  R'4       VP/                  V4       V'       d#   VP/                  R4       VP/                  V4       V'       d#   VP/                  R4       VP/                  V
4       R(P1                  R) V 4       4      pR(P1                  R*.\3        V4      ,          4      pVP%                  R+\'        V4       R,V R-V R.2V4       VP4                  pVP%                  R/\'        V4       R02V.4       VP6                   Uu. uF  pV^ ,          NK  	  pp\        \9        VVP)                  4       4      4      pRRR4       V'       d    \;        R14      '       d   \         R2,          P#                  4       ;_uu_ 4       pVP%                  R3XV\+        V4      \+        V4      \+        V4      \+        \        4       4      \+        \        4       4      .4       RRR4       M XP                  R44      VR5&   \        RR6R7VR4XR5V/^R7      # V R2p\        V4      '       g   \        R8. R9R:^R;^R<^R=^ //4      # V P>                  P                  R>4      ;'       g    RP                  4       pV P>                  P                  R"4      ;'       g    RP                  4       p\A        V P>                  R?^4      p\A        V P>                  R<^^^R@7      p V^,
          V ,          p!. p". p#V'       d-   V"P/                  RA4       RBV RB2p$V#PC                  V$V$V$V$.4       V'       d*   VRC8w  d#   V"P/                  RD4       V#P/                  V4       V"'       d   RERFP1                  V"4      ,           MRp%V RG2p&\        V&4      p'V RH2p(\        V(4      p)Rp*V)'       d]   \         R,          P#                  4       ;_uu_ 4       pVP%                  R\'        V(4       RI24       VP)                  4       RJp*RRR4       \         R,          P#                  4       ;_uu_ 4       pVP%                  RJ\'        V4       V% 2V#4       \E        VP)                  4       ;'       g    ^ .^ ,          ;'       g    ^ 4      p+VP%                  R/\'        V4       V% RK2V#V V!.,           4       VP6                   Uu. uF  pV^ ,          NK  	  p,pVPG                  4        U-u. uF  p-\        \9        V,V-4      4      NK  	  p.p-. p/V. EF	  p0\E        V0P                  R44      ;'       g    ^ 4      p1V1V0R5&   ^ V0RL&   ^ V0RM&   ^ V0RN&   \        V0P                  R#4      ;'       g    R4      P                  4       p2V2R8X  d   ^ V0RO&   MD\3        V2PI                  RP4       U3u. uF  p3V3P                  4       R8w  g   K  V3NK  	  up34      V0RO&   V''       d   V1'       d   VP%                  RJ\'        V&4       RQ2V1.4       \E        VP)                  4       ;'       g    ^ .^ ,          ;'       g    ^ 4      V0RM&   VP%                  RJ\'        V&4       RR2V1.4       \E        VP)                  4       ;'       g    ^ .^ ,          ;'       g    ^ 4      V0RL&   V)'       dr   V*'       dj   V1'       db   VP%                  RJ\'        V(4       RS2\        V14      .4       \E        VP)                  4       ;'       g    ^ .^ ,          ;'       g    ^ 4      V0RN&   V/P/                  V04       EK  	  RRR4       V '       d   X+V ,           ^,
          V ,          M^p4\        R8X/R9R:VR;V4R<V R=X+//4      # u upi   + '       g   i     EL; i  + '       g   i     EL; i  \<         d     ELi ; i  + '       g   i     EL; iu upi u up-i u up3i   + '       g   i     L; i)Vr   r   r   r   r   r   rN   r   r   r   r   r   rT  r   F
start_time)dayscallback_enabledTri   rj   exeuctive_numberbot_namer   z7Campaign table not found. Please contact administrator.r,  zTable does not existr  r   r  z LIKE 'bot_id'Nz LIKE 'exeuctive_number'z LIKE 'retry_logic'r   r   	scheduledactivez%Y-%m-%dr   z, c              3  8   "   T F  p\        V4      x  K  	  R # 5ir+   )r   )rp   r   s   & r   rq   "campaigns_index.<locals>.<genexpr>  s      Bk!krs   z%szINSERT INTO z (z
) VALUES ()r   r   scheduled_campaignsr)   aD  
                            INSERT INTO scheduled_campaigns
                            (campaign_id, business_id, start_time, end_time, execute_at, delay_seconds, status, error_message, created_at, updated_at)
                            VALUES (%s, %s, %s, %s, %s, 0, 'pending', NULL, %s, %s)
                            r   r   zCampaign created successfullyra  r  
paginationcurrent_page	last_pageper_pagetotalsearchpage)r#   r$   zF(name LIKE %s OR description LIKE %s OR did LIKE %s OR status LIKE %s)%allzstatus = %sz WHERE z AND r   _call_historyz LIKE 'refid'SELECT COUNT(*) FROM z, ORDER BY created_at DESC LIMIT %s OFFSET %ssuccessful_callstotal_callstotal_attemptswaiting_time_countrm   z WHERE campaign_id = %sz- WHERE campaign_id = %s AND status = 'ANSWER'z WHERE refid = %si  )r   r   rT  r   r   r   didrk  end_time
start_dateend_date
retry_timer   
batch_sizebatch_interval
created_at
updated_at)%r"   r   r  r7   r  r^   r   r8   r;   rS   r@   r   r(   r   r   r   r   rY   rZ   r   r[   rJ   rI   rb   ry   r   rV  rT  rU  r   r   query_paramsr/   extendr   fetchallr   )5r   r!   r  r   rT  run_now_flagrY  endrm  r  ri   rj   waiting_time_valuesrn  ro  executive_numberrZ  rc   
has_bot_idhas_exeuctive_number_colhas_retry_logic_colinsert_colsinsert_valscols_sqlph_sqlr   r   r`  ra  r{  r   r|  ry  offsetwhere_partsr   like	where_sqlrE  has_contactscall_history_tablehas_call_history	has_refidrz  colsr   rowsre   campr:  waiting_rawr   rx  s5   &                                                    r   campaigns_indexr    s	    w
'C#MNWZ[[ ~~)',,==w||2 &&B--//FZL;QR 
 hh}-"488Iu#=> !$((<"89EJEiW--&txx0BD'IJ*Q
$((=177R8 $)@" E:3Mbctxx(:;AArBHHJ88J'23(S E,#O44UW^`vw 
 #**,,KK,Xo-F,G~VWt3JKK,Xo-F,GG_`a'*||~T'A$KK,Xo-F,GGZ[\"%,,."<K( +#))r z*Z(!q
#
##&K( ""8,""8,'""#56""#34"""=1"";/yy Bk BBHYYvK(889FKKx89H:ZPVxWXY --K KK /!: ;;Z[ (+7!1I7C	3<<>:;HS -X '(=>>$Y/6688C  !, # ' ' ' '
 3 '
 3 98& 
 "m4:H{k	 
 	
 Z(O00~q+q*bRY[\]
 	
 ""&&x066B==?F""&&x066B==?Fg**FA6D'..
BasSHQh("FKFcd6(!}tT4./&E/=)f;FW\\+66BI u./N'7L5.+,>? I#**,,KK,X6H-I,J-XYd2I - 
Y		&	&	(	(C+H_,E+FykRTZ[S\\^**sA.33!4Xo67	{Bnoh''	
 "oo.o!o.,/LLN;NqSq\"N;$&Ddhh}-223CDJ'(D#$"#D%&D!"dhh~6<<"=CCEKb -.)*-0[=N=Ns=S1g=SWXW^W^W`dfWf!!=S1g-h)*+H^,D+EE\]E '*3<<>+@+@aS!*D*I*I&J]#+H^,D+EErsE ,/0E0E1#q/I/N/NQ+O'(I#+H5G,H+IIZ[XJ *-clln.C.CQ-G-L-L1)M%&JJtA  
)\ 7?!A%(2AICYH		

 
K 8Q -,,b 988(  j -,, /; 2h/ 
)	(s   B,i>Bi> )i>
B;i>i9%i>4j& Ajj& 71j8Ak"?k!k3kk%&k7k:k>kk k2k:;k6kAkk k2k:kAk k9i>>j	j#	j& #j& &j54j58k		kk+	c                j   \        V 4      pV'       g   \        R R/RR7      # V R2pV R2p\        V4      '       g   \        R^ R^ R^ R	^ R
^ R^ R^ /4      # \        R,          P	                  4       ;_uu_ 4       pVP                  R\        V4       24       \        VP                  4       ;'       g    ^ .^ ,          ;'       g    ^ 4      pVP                  R\        V4       R24       \        VP                  4       ;'       g    ^ .^ ,          ;'       g    ^ 4      pVP                  R\        V4       R24       \        VP                  4       ;'       g    ^ .^ ,          ;'       g    ^ 4      p^ ;p;r\        V4      '       d   VP                  R\        V4       24       \        VP                  4       ;'       g    ^ .^ ,          ;'       g    ^ 4      pVP                  R\        V4       R24       \        VP                  4       ;'       g    ^ .^ ,          ;'       g    ^ 4      p	VP                  R\        V4       R24       \        VP                  4       ;'       g    ^ .^ ,          ;'       g    ^ 4      p
RRR4       \        RXRXRXR	XR
X	RX
R^ /4      #   + '       g   i     L); i)r   r   r   r   r   r   total_campaignsactive_campaignscompleted_campaignsr  r  failed_callsaverage_call_durationr   r  z WHERE status = 'active'z WHERE status = 'completed'z WHERE status IN ('ANSWER')z WHERE status = 'failed'N)	r"   r   r   r   rY   rZ   r   r   r[   )r   r!   rZ  rE  rc   r  r  r  r  r  r  s   &          r   campaigns_statsr    s    w
'C#MNWZ[[Z(Ou./N00!1"A%qq"A'

 
	
 
Y		&	&	(	(C+H_,E+FGHs||~44!a8==A>+H_,E+FF^_` 5 51#q9>>Q?+H_,E+FFabc!3<<>#8#8aS!"<"A"AB8999&//KK/0H/IJKs||~44!a8==A>KKK/0H/IIdef"CLLN$9$9qc1#=#B#BCKK/0H/IIabc 5 51#q9>>Q?L 
)"  0!#6; 0L#Q	

 
# 
)	(sT   :AJ"A J"J"A J"J",AJ"J"A J"J"'A J"(J":J""J2	c                :   \        V 4      pV'       g   \        R R/RR7      # V P                  P                  R4      p Ve   \	        V4      MRpV'       g   \        RRRR	R
. /RR7      # \        R,          P                  4       ;_uu_ 4       pVP                  R4       VP                  4       f   \        RRR
. /4      uuRRR4       # VP                  R4       VP                  4       RJpRpW.pV'       d
   VR,          pVR,          pVP                  Wg4       VP                  4        Uu. uF"  q'       g   K  V^ ,          f   K  V^ ,          NK$  	  p	pRRR4       \        RRR
X	/4      #   \
         d    Rp EL1i ; iu upi   + '       g   i     L8; i)r   r   r   r   r   Nr   Fr   zbot_id is requiredr  r)   r   Tr   zNSELECT DISTINCT did_no FROM did_numbers WHERE business_id = %s AND bot_id = %sr   z ORDER BY did_no ASC)r"   r   r  r   r   r   r   rY   rZ   r[   r  )
r   r!   r   
bot_id_intrc   r   r   r   r   numss
   &         r   executive_numbersr    sx    w
'C#MNWZ[[!!%%h/F$*$6S[D
 E96JFTVW`cdd 
Y		&	&	(	(C45<<>!Yfb9: 
)	(
 	DEd2^ -00C%%C !llnGnad!nG 
)" Yfd3441  
, H 
)	(sB   E1 2F
A%F
0	F>FFF
1FFF

F	)1__doc__
__future__r   r\   r"  rW  r/  urllib.requestr(  urllib.errorr   r   zoneinfor   typingr   	django.dbr   r   rest_framework.decoratorsr	   r
   rest_framework.permissionsr   rest_framework.responser   apps.cluster.dynamic_tablesr   r   config.reporting_utilsr   r   r"   r/   r;   r@   rJ   rS   rg   r   r   r   r   r   r   rh  r  r  r  r   r   r   <module>r     sD  	 #  	     (   8 B 6 , > Q%q %v %+2,06($NEP5p: 
6(_%&c ' cL	 
5&/_%&F ' FR 
5'_%&0 ' 0f 
5'_%& 5 '  5r   