
    _ei2                        d Z ddlZddlZddlZddlZddlZddlmZmZ ddlm	Z	 ddl
mZmZ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 dd
lmZ ddlmZ ddlm Z m!Z! ddl"m#Z# ddl$m%Z% ddl$m&Z&m'Z'm(Z( ddl)m*Z*m+Z+ ddl,m-Z-m.Z. ddl/m0Z0 ddlm1Z1 ddl2m3Z3m4Z4 ddl5m6Z6m7Z7 ddl8m9Z9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZD ddlEmFZFmGZG ddlHmIZImJZJmKZK ddlLmMZM dd lNmOZOmPZP dd!lAmQZQ dd"lRmSZSmTZTmUZU dd#l
mVZVmWZWmZmXZXmYZYmZZZm[Z[m\Z\m]Z] dd$lm^Z^ ddl$m%Z% ddl/m0Z0 dd%lm!Z! dd&l_m`Z` dd'lambZb d(d)lcmdZd dd*lRmeZe ddlfZfdd	lmZ  ej                  eh      Zi G d+ d,e j                        Zky)-z
Views for the call APIs.
    N)datetime	timedelta)settings)CountSumMaxAvgQ)	TruncDateExtractHour	TruncHourRound)relativedelta)FileResponseHttp404)timezone)DjangoFilterBackend)permissions)viewsetsstatus)TokenAuthentication)action)api_viewpermission_classesauthentication_classes)SearchFilterOrderingFilter)IsAuthenticatedAllowAny)Response)Extract)get_caller_name_by_phone_numberget_twilio_client)CompanyCompanyBotSettings)CompanyInfoUser)process_booking_intent)get_bot_name)Appointment   )CallBDCLimitOffsetPagination)Customer)get_company_working_infocheck_sales_time_by_phone)TRANSFER_STATUS	SENTIMENTBotType)
CallFilter)CallCallActivity)CallLimitOffsetPagination)CallDetailSerializerTopRepeatedCallersSerializerDateRangeSerializer)	OuterRefSubqueryr   
FloatFieldFIntegerFieldValueCaseWhen)Coalescer   )RecordingService)StorageService   )UserProfile)ReadCallSerializerc                      e Zd ZdZeZej                  j                         Z	e
gZeZeeegZeZg dZg dZdgZd Zd Zd Z edd	gd
      d        Z edd	gd      d        Z edd	gd      d        Z edd	gd      d        Z edd	gd      d        Z edd	gd      d        Z  edd	gd      d        Z! edd	gd      d        Z" edd	gd      d        Z# edd	gd      d        Z$ edd	gd      d         Z% edd	gd!      d"        Z& ed#d	gd$      d0d&       Z' edd'gd(e(gg )      d*        Z) ed'gdd+e(gg ,      d-        Z* edd'gd.e(gg )      d/        Z+y%)1CallViewSetzView for manage call APIs.)from_number	to_number
transcriptsummary)
created_atdurationcost-created_atc                 J   | j                   j                  }|j                  r| j                  }nx|j                  rR	 t
        j                  j                  |j                  j                        }| j                  j                  |      }n| j                  j                         S | j                  dk(  r*|j                  t        j                  j                        }|j!                  d      S # t
        j                  $ r | j                  j                         cY S w xY w)N)phonecompanylist)bot_typez-id)requestuseris_superuserquerysetactive_companyr$   objectsgetrT   filterDoesNotExistnoner   r2   SERVICE_BOTvalueorder_by)selfrZ   qscompany_infos       9/var/www/html/dp2/backend_v2.1/server/apps/calls/views.pyget_querysetzCallViewSet.get_querysetJ   s    ||  B  ,&229L9L9R9R2S]])),)? ==%%'';;& G$7$7$=$=>B{{5!! '' ,}}))++,s   AC2 2-D"!D"c                 D    | j                   dk(  rt        S | j                  S )z(Return the serializer class for request.rW   )r   r7   serializer_class)rf   s    ri   get_serializer_classz CallViewSet.get_serializer_classl   s     ;;& ''$$$    c                 $    |j                          y)zCreate a new call.N)save)rf   
serializers     ri   perform_createzCallViewSet.perform_creates   s    rn   Fr_   rN   )detailmethodsurl_pathc                 &   | j                  | j                               }|j                  t        d      t        dt	        t
        j                  j                              t        dt	        t
        j                  j                              t        d      t        dd      t        d      t        dd      z
        }|d	   xs d
|d   xs d
|d   xs d
|d   xs d
|d   xs d
|d   xs d
d}t        |t        j                        S )z.Get call summary statistics using DRF filters.idtransfer_statusr`   rP   rK   Tdistinct)total_callstotal_missed_callstotal_attended_callsaverage_call_timeunique_callersrepeated_callersr}   r   r~   r   r   r   r   )r}   r~   r   average_call_time_secondsr   r   rC   )filter_querysetrj   	aggregater   r
   r0   FAILEDrd   
SUCCESSFULr	   r    r   HTTP_200_OK)rf   rY   filtered_querysetrN   report_datas        ri   rN   zCallViewSet.summaryw   s    !001B1B1DE#--d$T!ODZDZD`D`2ab!&tAoF`F`FfFf4g!h!*o >"=1E-RV4WW . 
 #=16Q")*>"?"D1$+,B$C$Hq)01D)E)J%&67<1 '(: ; @q
 F,>,>??rn   z	bdc-callsc                    |j                   }d}|j                  r:|j                  j                  d      }|s{t	        ddit
        j                        S |j                  st	        ddit
        j                        S |j                  j                  }|st	        ddit
        j                        S t        j                  j                  |      j                         }|st	        dd	it
        j                        S t        |j                  
      }t        | _        | j#                         j                  |      }|j%                         rM|j&                  j                  d      }|j&                  j                  d      }|r|r|j                  ||      }| j)                  |      }	| j+                  |	      }
g }|
D ]  }	 t,        j                  j                  |j.                  |j0                        }|j2                  }|j6                  |j8                  j;                         ||j.                  |j<                  |j>                  |j@                  |j8                  j;                         |jB                  xs d|jD                  |jF                  xs dd}|jI                  |        | jK                  |      S # t,        j4                  $ r d}Y w xY w)z7Get calls for a specific BDC number from company table.N
bdc_numberrs   z#Please provide bdc_number parameterrC   z User must have an active companyz2Your company does not have a BDC number configured)r   z-No company found with the provided BDC numberdata)transfer_number
start_dateend_datecreated_at__gtecreated_at__lterT   rV   Unknown )rw   call_datetimecustomer_namecustomer_number	sentimenttwilio_call_idschedule_intentionschedule_datetimecall_summarycall_idrM   )&rZ   r[   query_paramsr_   r    r   HTTP_400_BAD_REQUESTr]   r   r$   r^   r`   firstHTTP_404_NOT_FOUNDr9   r,   pagination_classrj   is_validvalidated_datar   paginate_querysetr-   rK   rV   namera   rw   rO   	isoformatr   twilio_call_sidbooking_intentrN   r   rM   appendget_paginated_response)rf   rY   rZ   r   rV   date_serializercalls_querysetr   r   r   
calls_page
calls_datacallcustomerr   	call_datas                   ri   get_bdc_callszCallViewSet.get_bdc_calls   s    ||
 --11,?JC! 557 7 &&@! 557 7 ,,77JR! 557 7 //((J(?EEGI//1 1 .73G3GH <**,33J3O##%(77;;LIJ&5599*EHh!/!6!6$.$, "7 "
 !00@++,=>

D*#++//d6F6FPTP\P\/] (
 gg!%!:!:!<!.#'#3#3!^^"&"6"6&*&9&9%)__%>%>%@ $ 2<<"oo3I i() , **:66% (( * )*s   AKKKzdaily-callsc                    t        |j                        }|j                  d       |j                  }|d   j	                         }|d   j	                         }| j                  | j                               }|j                  }t        j                         }t        |dd      rKt        |j                  dd      r4	 t        j                  j                  |j                  j                        }t        j                  t        j                   |t        j"                  j%                               |      }	t        j                  t        j                   |t'        d	
      z   t        j"                  j%                               |      }
|j)                  |	|
      }|j+                  t-        d|            j/                  d      j+                  t1        d      t1        dd            j3                  d      }t5        ||z
  j6                  d	z         D ci c]  }|t'        |
      z   ddd }}|D ].  }|d   }|d   xs d}|d   xs d}|t9        ||z
  d      d||<   0 t;        |j=                               D cg c]  }d|j?                  d      i||    }}tA        d|itB        jD                        S # t        $ r t        j                         }Y w xY wc c}w c c}w )z
        Return per-day unique and repetitive call counts for a given date range.
        Everything uses Django's timezone utilities.
        r   Traise_exceptionr   r   r]   Nr   r+   daysr   created_at__ltrO   tzinfo)dayr   rw   rK   r{   )r}   r   r   )unique
repetitiver   r}   datez%b-%ddaily_callsrC   )#r9   r   r   r   r   r   rj   rZ   r   get_default_timezonegetattrr]   pytz	Exception
make_awarer   combinemintimer   r`   annotater   valuesr   re   ranger   maxsortedkeysstrftimer    r   r   )rf   rY   rq   	validatedr   r   r   rZ   
company_tzstart_dtend_dt_exclusivequeryset_in_range	daily_aggi
days_rangerow	local_dayr   totalr   results                        ri   r   zCallViewSet.daily_calls   s    )g.B.BC
D1--	 |,113
Z(--/ 001B1B1DE||224
4)40WT=P=PR\^b5c=%]]33D4G4G4P4PQ
 &&x'7'7
HLLDUDUDW'XZde#..X	q(998<<;L;L;NO

 .44$+ 5 
 X)LDXEVE]X!$K$]TB   Xe_ 	 Hz177!;<
< **q,JJ< 	 

 CE
I)*/aF&+!E/5SQWYZE[$\Jy!	  joo/0
0 S\\'*>jo>0 	 

 /8J8JKK_  =%::<
=>

s   ?3K K'K,K$#K$zuser-performancec                    | j                  | j                               }|j                  }t        j                  j                  dddd      j                  d      }|j                  s)|j                  r|j                  |j                        }n/|j                  r|dd }nt        d	d
it        j                        S g }g d}t        |      D ]  \  }}|j                  |      }	|	j                         }
|	j                  t        j                  j                         j                         }|	j                  t        j"                  j                         j                         }d}|
dkD  rt%        ||
z  dz  d      }||t'        |      z     }|dkD  rd}n
|dkD  rd}nd}|j)                  |j*                  |j,                  |
||||d        t/        |d d      }t        |t        j0                        S )zFReturn user performance statistics with call counts and success rates.FTr[   	is_activeprofile__isnullprofile__phone_number__isnullr   profile__phone_number	companiesN   rs   No active company foundrC   )z#e6e8b3#76c487#f4a261#e76f51z#264653z#2a9d8fz#e9c46a)transfer_userrx           r   d   r+   2   r      r   r   )user_idusernamer}   successful_callsmissed_callsmissed_percentagebackground_colorc                     | d   S )Nr    xs    ri   <lambda>z.CallViewSet.user_performance.<locals>.<lambda>U  s
    a8K6Lrn   keyreverse)r   rj   rZ   r'   r^   r`   excluder[   r]   r    r   r   	enumeratecountr0   r   rd   r   roundlenr   rw   r   r   r   )rf   rY   r   rZ   company_users
user_statscolorsr   user_obj
user_callsr}   r   r   r   r   s                  ri   user_performancezCallViewSet.user_performance  s     !001B1B1DE||++!*/	 , 

 ''
+ 	   T%8%8)004;N;N0OM)"1-M3113 3 
^$]3KAx*111IJ$**,K)00A[A[AaAa0bhhj%,,_=S=S=Y=Y,Z``bL #Q$)<++E*La$P!%a#f+o6 2%#, "R'#, #, #;;$--*$4 ,%6$4 ' 4: J,LVZ[

6+=+=>>rn   zworst-performing-usersc           	      B   t        |j                        }|j                  d       |j                  }|d   j	                         }|d   j	                         }|j
                  }t        j                  j                  dddd      j                  d	      }|j                  s)|j                  r|j                  |j                  
      }n|j                  r|dd }g }|D ]  }	t        j                  j                  |	||g      }
|
j                         }|dk(  r=|
j                  t        j                  j                         j                         }|
j                  t        j"                  j                         j                         }||z  dz  }||z  dz  }|j%                  |	j&                  j(                   d|	j&                  j*                   |||dd|ddd        |j-                  d d       t/        d|it0        j2                        S )z:Return users with worst performance based on missed calls.r   Tr   r   r   Fr   r   r   r   N   r   created_at__date__ranger   rx   r    .2f%)r   calls_missedcalls_attendedaverage_missedavg_attendedc                     | d   S )Nr  r   r   s    ri   r   z4CallViewSet.worst_performing_users.<locals>.<lambda>  	    An,=rn   r   r   rC   )r9   r   r   r   r   rZ   r'   r^   r`   r  r[   r]   r4   r  r0   r   rd   r   r   profile
first_name	last_namesortr    r   r   rf   rY   rq   r   r   r   rZ   r  r  company_userr
  r}   r  r  r  
avg_misseds                   ri   worst_performing_usersz"CallViewSet.worst_performing_usersY  s    )g.B.BC
D1--	|,113
Z(--/||++!*/	 , 

 ''
+ 	   T%8%8)004;N;N0OM)#2.M)L,,*)3X(> - J
 %**,Ka'..?Y?Y?_?_.`ffhN%,,_=S=S=Y=Y,Z``bL*[8C?L&4;J##+33>>?qAUAUA_A_@`a ,"0%/$4A"6#/"4A 6% ! *0 	"=tL!126;M;MNNrn   zbest-performing-usersc           
         t        |j                        }|j                  d       |j                  }|d   j	                         }|d   j	                         }|j
                  }t        j                  j                  dddd      j                  d	      }|j                  s)|j                  r|j                  |j                  
      }n|j                  r|dd }g }|D ]  }	t        j                  j                  |	||g      }
|
j                         }|dk(  r<|
j                  d      j                         }|
j                  d      j                         }||z  dz  }||z  dz  }|j                  |	j                  j                    d|	j                  j"                   |||dd|dd|d        |j%                  d d       t'        d|it(        j*                        S )z;Return users with best performance based on attended calls.r   Tr   r   r   Fr   r   r   r   N
   r  r   r+   rx   rF   r   r  r  r  )r   r  r  r  r  r}   c                     | d   S )Nr  r   r   s    ri   r   z3CallViewSet.best_performing_users.<locals>.<lambda>  r  rn   r   r   rC   )r9   r   r   r   r   rZ   r'   r^   r`   r  r[   r]   r4   r  r   r  r  r  r  r    r   r   r  s                   ri   best_performing_usersz!CallViewSet.best_performing_users  s    )g.B.BC
D1--	|,113
Z(--/||++!*/	 , 

 ''
+ 	   T%8%8)004;N;N0OM)#2.M)L,,*)3X(> - J
 %**,Ka'..q.AGGIN%,,Q,?EEGL*[8C?L&4;J##+33>>?qAUAUA_A_@`a ,"0%/$4A"6#/"4A 6*% ! *2 	"=tL!126;M;MNNrn   ztop-callersc                    t        |j                        }|j                  d       |j                  }|d   j	                         }|d   j	                         }|j
                  }t        j                  j                  ||g      }|j                  s)|j                  r|j                  |j                        }n*|j                  st        dg d	t        j                  
      S |j                  d      j                  t!        d            j#                  d      dd }g }	|D ]0  }
|
d   }|
d   }|j                  |      j#                  d      j%                         }|s@t&        j                  j                  |j(                  |j                        j%                         }|r|j*                  nd}t-        |j.                        }|dz   d|dz  dz  dd|dz  d}|	j1                  |j2                  |j4                  |j6                  j9                         |||||j:                  |j<                  |j>                  |j@                  d       3 t        |	t        j                  
      S )z+Return top callers based on call frequency.r   Tr   r   r   )r  rU   r   )messager   rC   rK   rw   )
call_countz-call_countNr"  r'  )rK   rR   r   r   i  :<   02d)r   r   call_date_timer   r   r'  rP   rM   partner_call_idr   r   )!r9   r   r   r   r   rZ   r4   r^   r`   r[   r]   r    r   r   r   r   r   re   r   r-   rK   r   intrP   r   rw   r   rO   r   rM   r   r   rN   )rf   rY   rq   r   r   r   rZ   base_querysetcall_countsr   callerphone_numberr'  most_recent_callr   r   duration_secondsduration_formatteds                     ri   top_callerszCallViewSet.top_callers  s    )g.B.BC
D1--	|,113
Z(--/||++%/$: , 
   T%8%8)009L9L0MM""4 ((* *   /XtX-Xm$Sb* 	 !F!-0L-J,33(  4  h}%eeg   #++22*66 // 3  %'  2:y#&'7'@'@#A (8D(@'ADTW[D[`bCbcfBgghiy|~i~  @C  iD  &E"/22&6&F&F&6&A&A&K&K&M%2'3", 2"2"="='7'?'?!1!;!;$4$<$< % "@ v'9'9::rn   zhourly-callsc                 F   t        |j                        }|j                  d       |j                  }|d   j	                         }|d   j	                         }| j                  | j                               }|j                  }t        j                         }t        |dd       rKt        |j                  dd       r4	 t        j                  j                  |j                  j                        }t        j                  t        j                   |t        j"                  j%                               |      }	t        j                  t        j                   |t'        d	      z   t        j"                  j%                               |      }
|j)                  |	|

      }|j+                  t-        t/        d|                  j1                  d      j+                  t3        d            j5                  d      }t7        d      D ci c]  }|d }}|D ]  }|d   }|d   xs d}|||<    |j9                         D cg c]  \  }}|dd|d }}}t;        d|it<        j>                        S # t        $ r t        j                         }Y w xY wc c}w c c}}w )Nr   Tr   r   r   r]   r   r+   r   r   rO   r   )
local_hourr7  rw   )calls   r   r8  r*  z:00)r   r8  hourly_callsrC   ) r9   r   r   r   r   r   rj   rZ   r   r   r   r]   r   r   r   r   r   r   r   r   r`   r   r   r   r   r   re   r   itemsr    r   r   )rf   rY   rq   r   r   r   r   rZ   r   r   r   r   
hourly_agghhours_ranger   hourr8  r   s                      ri   r:  zCallViewSet.hourly_calls  sb   (g.B.BC
D1--	|,113
Z(--/ 001B1B1DE||224
4)40WT=P=PR\^b5c=%]]33D4G4G4P4PQ
 &&x'7'7
HLLDUDUDW'XZde#..X	q(998<<;L;L;NO

 .44$+ 5 
 XY|J-W!XXYVL!XE$KX(Xl# 	 &+2Y/Yq!tY/C|$DL%AE %K   +002
2e Sz%62 	 

 09K9KLLE  =%::<
=, 0
s   ?3I4 
JJ4JJzmonthly-statsc                    | j                  | j                               }|j                  }t        j                         }t        |dd      rKt        |j                  dd      r4	 t        j                  j                  |j                  j                        }t        j                         j                  }t        j                  t        |dd      |      }t        j                  t        |dz   dd      |      }|j                  t        dd|      t        dd|      	      j                  dd      j                  t!        d
      t!        d
t#        d            t!        d
t#        d            t!        d
t#        d            t%        t'        d            t)        d            j+                  d      j-                  d      }ddddddddddddd}	g }
|D ]  }t/        |d         }|	j1                  |d|       }|d    xs d}|d!   xs d}|d"   xs d}|d#   xs d}|d$   xs d}|d%   xs d}|d   }t/        |d         }t        j                  t        ||d      |      }|t3        d&      z   }|t5        d'      z
  }|
j7                  ||||||||||d(
        t9        |
t:        j<                  )      S # t        $ r t        j                         }Y Ow xY w)*z\Return monthly call statistics with total calls and missed percentage for current year only.r]   Nr   r+   rO   yearr   month)rA  rB  rw   r   rx   rz   rF   rP   )r}   not_transferred_callsreceived_callsr   avg_call_timetot_call_time)total_calls__gtJanuaryFebruaryMarchAprilMayJuneJulyAugust	SeptemberOctoberNovemberDecember)r+   rF         r            	   r"        zMonth r}   r   rD  rE  rF  rC  )months)microseconds)
rB  rA  r   r   	tot_callsrC  r   rD  rE  rF  rC   )r   rj   rZ   r   r   r   r]   r   r   nowrA  r   r   r   r!   r   r   r
   r   r	   r   r`   re   r-  r_   r   r   r   r    r   r   )rf   rY   r   rZ   r   current_yearstart_of_yearend_of_yearmonthly_aggmonth_namesr   r   	month_num
month_namer}   r   rD  rE  rF  rC  rA  start_of_monthend_of_months                          ri   monthly_statszCallViewSet.monthly_stats;  s    !001B1B1DE||224
4)40WT=P=PR\^b5c=%]]33D4G4G4P4PQ

  ||~** ++\1a(*
 ))\A%q!,j
 X\6*ElGJG   VFG$X!$K&+D19M&N$T!A2FG"4!0DE#C
O4!*o   VAV&Xg! 	( ZGFx	zz
 CCL)I$fYK4HIJm,1K~.3!L !127aN05AM05AM$'(?$@$EA!v;Ds6{#D%00y!,jN *M,CCL')*CCL MM#,(()> ,"0!.!. / H v'9'9::_  =%::<
=s   %3K K('K(ztransfer-percentagec                 "   t        |j                        }|j                  d       |j                  }|d   }|d   }| j	                  | j                               }|j                  ||      }|j                         }|dk(  r!t        dddddd	t        j                  
      S |j                  d      j                         }	|j                  d      j                         }
|j                  d      j                         }|j                  g d      j                         }t        |	|z  dz  d      }t        |
|z  dz  d      }t        ||z  dz  d      }t        ||z  dz  d      }t        ||||dt        j                  
      S )zRReturn percentages for transferred, not transferred, failed, and unknown statuses.r   Tr   r   r   r   r   r   )transferred_percentagenot_transferred_percentagefailed_percentageunknown_percentager}   rC   r+   rx   rF   )r   r+   rF   )transfer_status__inr   )rk  rl  rm  rn  )r9   r   r   r   r   rj   r`   r  r    r   r   r  r  )rf   rY   rq   r   r   r   r   calls_in_ranger}   transferred_countnot_transferred_countfailed_countunknown_countrk  rl  rm  rn  s                    ri   transfer_percentagezCallViewSet.transfer_percentage  s    )g.B.BC
D1--	|,
Z( 001B1B1DE*11&$ 2 

 %**,!*-.1%(&)  ((* * +11!1DJJL . 5 5a 5 H N N P%,,Q,?EEG&..9.MSSU!&(9K(G3'NPQ!R%*,AK,OSV+VXY%Z"!<+#="DaH"MK$?3#FJ&<*D!2"4	

 $$& 	&rn   zprocess-booking-intentc                    |j                   j                  d      }t        j                  j                  |      }|st	        ddit
        j                        S t        |       t	        ddit
        j                        S )z"Process booking intent for a call.r   rw   r&  zCall not foundrC   z%Booking intent processed successfully)	r   r_   r4   r^   r    r   r   r(   r   )rf   rY   r   r   s       ri   r(   z"CallViewSet.process_booking_intent  so     &&**95||7+Y(89&B[B[\\w'$KLU[UgUghhrn   readc                    t        |j                  d|i      }|j                         s%t        |j                  t
        j                        S |j                  d   }|j                  }|j                  rt        j                  j                  |      }t        j                         }||_        ||_        t"        j                  j%                  ||j                  d|       |j'                          t        dd	it
        j(                        S t        j                  j                  ||j*                  
      }t-        j                  |j*                  j                        }t        j                         }|j/                  |      }	||_        |	|_        t"        j                  j%                  ||j                  d|	       |j'                          t        ddit
        j(                        S )z3Process booking intent for a call and mark as read.rY   )r   contextrC   rw   rw  READ)r   rZ   r   performed_atrs   z%Call marked as read from super admin.)rw   rV   zCall marked as read.)rH   r   r   r    errorsr   r   r   rZ   r[   r4   r^   r_   r   r_  read_byread_atr5   createrp   r   r]   r   
astimezone)
rf   rY   rq   rw   rZ   r   current_timecompany_timezonecurrent_time_utccurrent_time_companys
             ri   	read_callzCallViewSet.read_call  s    (W-A-AIW^K_`
""$J--f6Q6QRR&&t,||<<##r#*D#<<>LDL'DL  ''\\)	 (  IIKA((* * ||2t/B/BC==)<)<)E)EF#<<>/::;KL+##-	 	$ 	
 			,
$$& 	&rn   Tzget-recordingNc                    | j                         }t        t                     }t               }|j	                  |      }|j                  |      \  }}t        j                  j                  |      rt        d|j                  ||      i      S |j                  |j                        }	|j                  |	j                        }
|j                  ||
       t        d|j                  ||      i      S )Nrecording_url)
get_objectrD   r#   rE   build_call_audio_filenamecall_recording_local_pathospathexistsr    call_recording_public_urlget_latest_call_recordingr   downloadsidsave_call_recording_stream)rf   rY   pkr   recording_servicestorage_servicefilenamerelative_pathfilepath	recordingresponses              ri   download_recordingzCallViewSet.download_recording  s     ,->-@A(*"<<TB"1"K"KH"Ux77>>(#_o.W.WX_an.opqq%??@T@TU	$--imm<228XF/*S*ST[]j*klmmrn   postzlog-call-webhook)rs   rt   ru   r   r   c                    |j                   }|j                  d      }|dk(  r|j                  di       }|j                  d      }|j                  d      }|j                  d      dk(  }t        j                  d       t        j                  d	|        t        j                  d
|        t        j                  d|        t        j                  d|        t        j                  d       t        j
                  j                  |      j                         }|r|j                  nd}	|j                  j                         dk(  rt        j                  j                  n8|j                  j                         dk(  rt        j                  j                  nd}
d}|j                  dg       }|D ]  }t        j                  d       t        j                  d|        t        j                  d       |j                  d      dk(  sZ|j                  d      dk(  so|j                  dd      }t        j                   |      }|j                  d      } d}|r>t"        j
                  j                  |      j                         }|r|j$                  nd}t&        j(                  j                  }|r|rt&        j*                  j                  }n|r|st&        j,                  j                  }|j                  di       j                  dd      }t/        |t0              r|r|d   }t3        |      j5                  d      }t6        j8                  j                  }|j                         d k(  rt6        j:                  j                  }n-|j                         d!k(  rt6        j<                  j                  }|j                  d"i       j                  d#      }t>        j
                  jA                  |j                  d$      |||	||||
|j                  d%      |j                  d&      ||j                  di       j                  d'      |j                  d(i       j                  d)      xs d|j                  d(i       j                  d*      xs d|d+,      \  }}tB        j
                  j                  |-      j                         }|r||_"        |jG                          |j                  di       }|j                  d.i       }|j                  d/      }tI        jJ                         |jL                  d0}t/        |t2              r#|j5                         r|j5                         |d<   tN        j
                  jA                  ||	|1      \  }}|r#tQ        |      |_)        |jG                  d2g3       |rd4nd5}t        j                  d6| d7|jT                          tW        d6| d8|jT                  |d9tX        jZ                  :      S t        j                  d;| d<       tW        d;| d<||d=tX        jZ                  :      S )>!Handle incoming webhook requests.eventcall_analyzedr   rK   rL   disconnection_reasoncall_transferz'=-=-=-=-=-=-=-=Call Data=-=-=-=-=-=-=-=zCustomer Phone: zCompany Phone: zIs Call Transferred: zCall Data: )r1  Nhazelmayatranscript_with_tool_callsz"=-=-=-=-=-=-=-=Item=-=-=-=-=-=-=-=zItem: roletool_call_invocationr   transfer_call	argumentsz{}numbercall_analysisuser_sentimentr   r   'positiveneutraltelephony_identifierr   r   call_statusrM   r   	call_costtotal_duration_secondscombined_cost)rK   rL   rV   r   r   ry   rX   r   rM   r   rN   rP   rQ   r   )r   defaults)r   custom_analysis_datar   )last_call_atlast_call_id)rT   rV   r  name_extracted)update_fieldscreatedupdatedzCall z successfully: z successfully)r&  r   r   rC   zCall webhook for z received successfully)r&  r  r   ).r   r_   loggerinfor%   r^   r`   r   rV   bot_namelowerr2   	SALES_BOTrd   rc   jsonloadsrG   rZ   r0   NOT_TRANSFERREDr   r   
isinstancetuplestrstripr1   NEGATIVEPOSITIVENEUTRALr4   update_or_creater*   r   rp   r   r_  rw   r-   r"   r  r   r    r   r   )rf   rY   webhook_datar  r   customer_phonecompany_phoneis_call_transferredcompanyBotSettingsrV   botTypetransfer_destination_numberr  itemr  	args_datarZ   user_profilery   sentiment_strr   r   r   r  appointmentr  custom_analysisr   customer_defaultsr   r   s                                  ri   log_call_webhookzCallViewSet.log_call_webhook  s    ||  )O#$((4I&]]=9N%MM+6M"+--0F"G?"ZKKABKK*>*:;<KK/-9:KK/0C/DEFKK+i[12KKAB!3!;!;!B!BP]!B!^!d!d!f4F(00DG1C1L1L1R1R1TX_1_g''--  CU  C^  C^  Cd  Cd  Cf  jp  Cpelexexe~e~  vzG*.')27SUW)X&2@AfTFO,@A88F#'==$((6BRVeBe $d ;I $

9 5I2;--2I/ 3 D+*2299Gb9ciik,8|((d-==CCO*/B"1"<"<"B"B,5H"1"8"8">">%MM/2>BBCSUWXM-/M -a 0.44S9M!**00I""$
2%..44	$$&)3%--33	'mm,BBGKKL]^O LL99!i0#1!.&'B%)'6 ''mmM:"+--"=!*(}}_bAEEnU )k2 > B BC[ \ a`a%MM+r:>>OTST'6 : MD'( &--44_4U[[]K#'   "%MM/2>M+//0FKO+//@M !) $!
 ---2E2E2G,9,?,?,A!&) ( 0 0 A A$* !B !Hg
 *I.*Y'-=,>?")YyFKK%xt||nEF"6(-8<<  ((	* * KK+E72HIJ.ug5KL$ ((	* *rn   z!inbound-dynamic-variables-webhook)rt   rs   ru   r   r   c                    d}|j                   j                  d      dk(  r,d|j                   v r|j                   d   j                  d      }t        j                  d|        t	        |      }|st        ddit        j                        S d}|j                         d	k(  r8t        |      }|j                         D ci c]  \  }}|t        |       }}}nJ|j                         d
k(  r7t        |      }|j                         D ci c]  \  }}|t        |       }}}|t        dd|iit        j                        S t        ddit        j                        S c c}}w c c}}w )r  Nr  call_inboundrL   zExtracted company_number: rs   z&This bot not configured in our system.rC   r  r  dynamic_variables)r   r_   r  r  r)   r    r   r   r  r/   r;  r  r.   r   )	rf   rY   rL   r  r  
sales_infokvrh   s	            ri   !inbound_dynamic_variables_webhookz-CallViewSet.inbound_dynamic_variables_webhook  sj    	<<G$6>W\\;Y^488EI0<=	*X'OPY_YtYtuu >>w&
 39=J7A7G7G7I J7Itq!CF7I J^^'3I>L7C7I7I7K L7Ktq!CF7K L('):! ((	* * #KLU[UpUpqq !K !Ms   E$E*zlog-transfer-call-webhookc                    t         j                  d|j                          t         j                  dt        |j                                t         j                  d|j
                          t        ddit        j                        S )r  z+Log Transfer Call Webhook received - Data: z%Log Transfer Call Webhook - Headers: z$Log Transfer Call Webhook - Method: r&  zWebhook received successfullyrC   )4r  r  r   dictheadersmethodr    r   r   r-  r   r_   r4   r^   select_relatedallr   strptimer`   
ValueErrorr   re   django.core.paginator	Paginatorpagerw   r   rK   rL   ry   r   rM   rN   rP   floatrQ   r   rO   r   
updated_atrV   company_namer  r   	num_pagesr  has_nexthas_previousr   errorr  HTTP_500_INTERNAL_SERVER_ERROR)rf   rY   r  	page_sizestart_date_strend_date_strrK   rL   r  ry   
company_idr\   r   r   r   r  	paginatorpage_objr   r   r   es                         ri   log_transfer_call_webhookz%CallViewSet.log_transfer_call_webhook  sl     	A',,PQ;D<Q;RST:7>>:JKL$CDVM_M_``rn   )N),__name__
__module____qualname____doc__r7   rl   r4   r^   r  r\   r   r   r6   r   r   r   r   filter_backendsr3   filterset_classsearch_fieldsordering_fieldsorderingrj   rm   rr   r   rN   r   r   r  r   r$  r5  r:  ri  ru  r(   r  r  r   r  r  r  r   rn   ri   rJ   rJ   >   s   $+||!H)*0*L.IO OIM8OH"D% 55'I>@ ?@0 55'K@F7 AF7P 55'MBCL CCLJ 55'4FG7? H7?r 55'4LM3O N3Oj 55'4KL4O M4Ol 55'MB>; C>;@ 55'NC1M D1Mf 55'ODX; EX;t 55'4IJ)& K)&V 55'4LMi Ni 55'F;2& <2&h 4%?Cn Dn& 5H' (z#%	s*s*j 4$:!rrB 5H0 (z#%	x=x=rn   rJ   )lr  r  logging	mimetypesr  requestsr   r   django.confr   django.db.modelsr   r   r   r	   r
   django.db.models.functionsr   r   r   r   dateutil.relativedeltar   django.httpr   r   django.utilsr   django_filters.rest_frameworkr   rest_frameworkr   r   r   rest_framework.authenticationr   rest_framework.decoratorsr   r   r   r   rest_framework.filtersr   r   rest_framework.permissionsr   r   rest_framework.responser    r!   apps.calls.services.twilior"   r#   apps.companies.modelsr$   r%   apps.core.modelsr&   r'   apps.calls.crons.callsr(   apps.calls.utilsr)   apps.appointments.modelsr*   
paginationr,   apps.customers.modelsr-   apps.companies.utilsr.   r/   	constantsr0   r1   r2   filtersr3   modelsr4   r5   r6   serializersr7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   services.recording_servicerD   services.storage_servicerE   userprofile.modelsrG   rH   r   	getLoggerr  r  ModelViewSetrJ   r   rn   ri   <module>r*     s       	  (   4 4 O O 0 - ! = & + = , Z Z ? @ , . Y = . 9 ) 0 4 * T : :  & 1    0 , , ! 8 4 , +  !			8	$x=('' x=rn   