
    S<iv                        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l1m2Z2 ddlm3Z3 ddl4m5Z5m6Z6 ddl7m8Z8m9Z9 ddl:m;Z;m<Z<m=Z= ddl>m?Z? ddl@mAZA ddlBmCZC ddlDmEZEmFZF ddlGmHZHmIZImJZJ ddlKmLZL ddlMmNZNmOZOmPZPmQZQmQZQ ddl@mRZR dd lSmTZTmUZUmVZVmWZW dd!l
mXZXmYZYmZmZZZm[Z[m\Z\m]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$lambZb dd%lSmcZc dd&ldmeZemfZfmgZgmhZhmiZi ddljZjdd	lmZ dd'lkmlZl  ej                  en      Zo G d( d)e j                        Zqy)*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)APIException)Extract)CompanyCompanyBotSettings)CompanyInfoUser)get_bot_namesend_booking_emailsend_booking_sms)Appointment)CallBDCLimitOffsetPagination)Customer)get_company_working_infocheck_sales_time_by_phone)TRANSFER_STATUS	SENTIMENTBotType)
CallFilter)CallCallActivityUserMessageNotificationr6   )CallLimitOffsetPagination)CallDetailSerializerTopRepeatedCallersSerializerDateRangeSerializerCallActivitySerializer)	OuterRefSubqueryr   
FloatFieldFIntegerFieldValueCaseWhen)Coalescer   )UserProfile)ReadCallSerializer)RecordingServiceStorageServiceget_caller_name_by_phone_numberget_twilio_clientNotificationService)process_booking_intentc                   0   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$      d4d&       Z' edd'gd(e(gg )      d*        Z) edd'gd+e(gg )      d,        Z* edd'gd-e(gg )      d.        Z+ ed'gdd/e(gg 0      d1        Z, edd'gd2e(gg )      d3        Z-y%)5CallViewSetzView for manage call APIs.)from_number	to_number
transcriptsummarycaller_name)
created_atdurationcost-created_atc                 \   | j                   j                  }|j                  r| j                  }n|j                  r[	 | j                  j                  |j                        }t        j                  j                  |      }||z  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company)notifications__recipientlist)bot_typez-id)requestuseris_superuserquerysetactive_companyfilterr3   objectsdistinctr#   DoesNotExistnoner   r1   SERVICE_BOTvalueorder_by)selfr`   qsnotification_callss       A/var/www/html/dp2/backend_v2.1/server/apps/calls/views/summary.pyget_querysetzCallViewSet.get_querysetQ   s    ||  B  ,]]))$2E2E)F%)\\%8%8-1 &9 &" --779 ==%%'';;& G$7$7$=$=>B{{5!! '' ,}}))++,s   AC; ;-D+*D+c                 D    | j                   dk(  rt        S | j                  S )z(Return the serializer class for request.r]   )r   r8   serializer_class)rl   s    ro   get_serializer_classz CallViewSet.get_serializer_classw   s     ;;& ''$$$    c                 $    |j                          y)zCreate a new call.N)save)rl   
serializers     ro   perform_createzCallViewSet.perform_create~   s    rt   FgetrS   )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rd   rV   rP   Trf   )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   rE   )filter_querysetrp   	aggregater   r
   r/   FAILEDrj   
SUCCESSFULr	   r    r   HTTP_200_OK)rl   r_   filtered_querysetrS   report_datas        ro   rS   zCallViewSet.summary   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,>,>??rt   zbdc-calls-oldc                    |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_numberrz   z#Please provide bdc_number parameterrE   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phoner[   Unknown )r~   call_datetimecustomer_namecustomer_number	sentimenttwilio_call_idschedule_intentionschedule_datetimecall_summarycall_idrR   )&r`   ra   query_paramsry   r    r   HTTP_400_BAD_REQUESTrc   r   r#   re   rd   firstHTTP_404_NOT_FOUNDr:   r+   pagination_classrp   is_validvalidated_datar   paginate_querysetr,   rP   r[   namerg   r~   rU   	isoformatr   twilio_call_sidbooking_intentrS   r   rR   appendget_paginated_response)rl   r_   r`   r   r[   date_serializercalls_querysetr   r   r   
calls_page
calls_datacallcustomerr   	call_datas                   ro   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-calls-oldc                    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   rc   Nr      daysr   created_at__ltrU   tzinfo)dayr   r~   rP   r   )r   r   r   )unique
repetitiver   r   datez%b-%ddaily_callsrE   )#r:   r   r   r   r   r   rp   r`   r   get_default_timezonegetattrrc   pytz	Exception
make_awarer   combinemintimer   rd   annotater   valuesr   rk   ranger   maxsortedkeysstrftimer    r   r   )rl   r_   rw   	validatedr   r   r   r`   
company_tzstart_dtend_dt_exclusivequeryset_in_range	daily_aggi
days_rangerow	local_dayr   totalr   results                        ro   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ra   	is_activeprofile__isnullprofile__phone_number__isnullr   profile__phone_number	companiesN   rz   No active company foundrE   )z#e6e8b3#76c487#f4a261#e76f51z#264653z#2a9d8fz#e9c46a)transfer_userr           r   d   r   2   r      r   r   )user_idusernamer   successful_callsmissed_callsmissed_percentagebackground_colorc                     | d   S )Nr    xs    ro   <lambda>z.CallViewSet.user_performance.<locals>.<lambda>`  s
    a8K6Lrt   keyreverse)r   rp   r`   r&   re   rd   excludera   rc   r    r   r   	enumeratecountr/   r   rj   r   roundlenr   r~   r   r   r   )rl   r_   r   r`   company_users
user_statscolorsr   user_obj
user_callsr   r   r   r   r   s                  ro   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+=+=>>rt   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   r   r    .2f%)r   calls_missedcalls_attendedaverage_missedavg_attendedc                     | d   S )Nr  r  r  s    ro   r  z4CallViewSet.worst_performing_users.<locals>.<lambda>  	    An,=rt   r  r   rE   )r:   r   r   r   r   r`   r&   re   rd   r	  ra   rc   r3   r  r/   r   rj   r   r   profile
first_name	last_namesortr    r   r   rl   r_   rw   r   r   r   r`   r  r  company_userr  r   r  r  r  
avg_misseds                   ro   worst_performing_usersz"CallViewSet.worst_performing_usersd  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Nrt   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   r      r   r  r  r  )r   r  r  r  r  r   c                     | d   S )Nr  r  r  s    ro   r  z3CallViewSet.best_performing_users.<locals>.<lambda>  r   rt   r  r   rE   )r:   r   r   r   r   r`   r&   re   rd   r	  ra   rc   r3   r  r   r!  r"  r#  r$  r    r   r   r%  s                   ro   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Nrt   ztop-callersc                 T   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 ]c  }
|
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}|j0                  j#                  d      }t3        |d      j4                  }|	j7                  |j8                  |j:                  |j<                  j?                         |||||j@                  |jB                  |jD                  |jF                  |d       f t        |	t        j                  
      S )z+Return top callers based on call frequency.r   Tr   r   r   )r  rZ   r   )messager   rE   rP   r~   )
call_countz-call_countNr*  r0  )rP   rX   r   r   i  :<   02dz-performed_at)many)r   r   call_date_timer   r   r0  rV   rR   partner_call_idr   r   call_activities)$r:   r   r   r   r   r`   r3   re   rd   ra   rc   r    r   r   r   r   r   rk   r   r,   rP   r   intrV   
activitiesr;   r   r   r~   r   rU   r   rR   r   r   rS   )rl   r_   rw   r   r   r   r`   base_querysetcall_countsr   callerphone_numberr0  most_recent_callr   r   duration_secondsduration_formattedr7  activities_datas                       ro   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"="="F"F"W"8t"T"Y"Y/22&6&F&F&6&A&A&K&K&M%2'3", 2"2"="='7'?'?!1!;!;$4$<$<'6 + "H v'9'9::rt   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   rc   r   r   r   r   rU   r   )
local_hourrD  r~   )calls   r   rE  r3  z:00)r   rE  hourly_callsrE   ) r:   r   r   r   r   r   rp   r`   r   r   r   rc   r   r   r   r   r   r   r   r   rd   r   r   r   r   r   rk   r   itemsr    r   r   )rl   r_   rw   r   r   r   r   r`   r   r   r   r   
hourly_agghhours_ranger   hourrE  r   s                      ro   rG  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.rc   Nr   r   rU   yearr   month)rN  rO  r~   r   r   r   r+  rV   )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   r+        r            	   r*        zMonth r   r   rQ  rR  rS  rP  )months)microseconds)
rO  rN  r   r   	tot_callsrP  r   rQ  rR  rS  rE   )r   rp   r`   r   r   r   rc   r   r   nowrN  r   r   r   r"   r   r   r
   r   r	   r   rd   rk   r8  ry   r   r   r   r    r   r   )rl   r_   r   r`   r   current_yearstart_of_yearend_of_yearmonthly_aggmonth_namesr   r   	month_num
month_namer   r   rQ  rR  rS  rP  rN  start_of_monthend_of_months                          ro   monthly_statszCallViewSet.monthly_statsJ  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   rE   r   r   r+  )r   r   r+  )transfer_status__inr   )rx  ry  rz  r{  )r:   r   r   r   r   rp   rd   r  r    r   r   r	  r  )rl   r_   rw   r   r   r   r   calls_in_ranger   transferred_countnot_transferred_countfailed_countunknown_countrx  ry  rz  r{  s                    ro   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	

 $$& 	&rt   zprocess-booking-intentc                 R    t        d       t        ddit        j                        S )z"Process booking intent for a call.zGprocess_booking_intent function removed from api process-booking-intentr/  z4Booking intent processed converted into trigger taskrE   )printr    r   r   )rl   r_   s     ro   rM   z"CallViewSet.process_booking_intent  s'     	WX$Z[djdvdvwwrt   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.r_   )r   contextrE   r~   )r~   READ)r   r`   r   performed_atrz   z%Call marked as read from super admin.)r~   r[   zCall marked as read.)rG   r   r   r    errorsr   r   r   r`   ra   r3   re   ry   r   rl  read_byread_atr4   createrv   r   rc   r   
astimezone)
rl   r_   rw   r~   r`   r   current_timecompany_timezonecurrent_time_utccurrent_time_companys
             ro   	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+##-	 	$ 	
 			,
$$& 	&rt   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_objectrH   rK   rI   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)rl   r_   pkr   recording_servicestorage_servicefilenamerelative_pathfilepath	recordingresponses              ro   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mrt   postzrecord-offtime-message)rz   r{   r|   r   r   c                    |j                   }|j                  di       }|j                  d      }|j                  d      }t        j                  d       t        j                  d|        |j                  di       }|j                  d      }|j                  d      }|j                  d	      }	|j                  d
      }
t        j                  dt	        |              t        j                  d|        t        j                  d|        t        j                  d|	        t        j                  d|
        t        j                  d       t
        j                  j                  |      j                         }|r|j                  nd}|st        ddit        j                        S |j                  j                  |d      j                         }|st        ddit        j                        S t        j                  d       t        j                  j                  ||
|	|d|	        t        j                  d       t        j                  d       t        ddit        j                         S ) !Handle incoming webhook requests.r   rP   rQ   zn=============================== Record Offtime Message request.data starts ===================================Webhook Data: args
advisor_idadvisor_namer   customer_noteztype of advisor_id: zadvisor_id: zadvisor_name: customer_name: zcustomer_note: `=============================== Getting Company Bot Settings ===================================r=  Nrz   Company not foundrE   T)r~   r   zUser not foundzY=============================== Creating User Message ===================================zOfftime Message from )	recipientbodyr   r   subjectze=============================== User Message created successfully ===================================z]=============================== Recording Offtime Message ===================================r/  z%Offtime message recorded successfully)r   ry   loggerinfotyper$   re   rd   r   r[   r    r   r   usersr5   r  r   )rl   r_   webhook_datar   customer_phonecompany_phoner  r  r  r   r  companyBotSettingsr[   r`   s                 ro   record_offtime_messagez"CallViewSet.record_offtime_message&  s3    || $$VR0	"}5!k2  E  	Fn\N34+XXl+
xx/11*4
+;*<=>l:,/0n\N34om_56om_56 	vw/77>>M>Z``b0B$,,-//1 1 }}##zT#BHHJ*//1 1 	op""'*+M?; 	# 	
 	{|st$KLU[UgUghhrt   zsend-appointment-emailc                 $   |j                   }|j                  di       }|j                  d      }|j                  d      }t        j                  d       t        j                  d|        |j                  di       }|j                  d      }|j                  d      }|j                  d	      }	t        j                  d
|        t        j                  d|        t        j                  d|	        t        j                  d       t        j
                  j                  |      j                         }
|
r|
j                  nd}|st        ddit        j                        S t        j                  d       |j                  }|st        ddit        j                        S t        j                  d       t        ||||	|       t        ||||	|       t        j                  d       t        ddit        j                        S )r  r   rP   rQ   zn=============================== Send Appointment Email request.data starts ===================================r  r  booking_datetimer   servicezbooking_datetime: r  z	service: r  r  Nrz   r  rE   zV=============================== Getting BDC number ===================================zBDC number not foundzY=============================== Sending Email and SMS ===================================zc=============================== Email and SMS sent successfully ===================================r/  zEmail and SMS sent successfully)r   ry   r  r  r$   re   rd   r   r[   r    r   r   r   r(   r)   r   )rl   r_   r  r   r  r  r  r  r   r  r  r[   r   s                ro   send_appointment_emailz"CallViewSet.send_appointment_emaila  s    || $$VR0	"}5!k2  E  	Fn\N34+88$671((9%()9(:;<om_56iy)* 	vw/77>>M>Z``b0B$,,-//1 1 	lm''
0//1 1 	op:}6FQ_`]4Dg~^yz$EFvOaOabbrt   zlog-call-webhookc           	         |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 ]d  }|j                  d      dk(  s|j                  d      dk(  s-|j                  dd      }t        j                   |      }|j                  d      }f 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!      }|j                  di       }|j                  d"i       }|j                  d#      }|j                  d$      }t/        |t2              r |j5                         r|j5                         nd}t        j                  d%|        t        j                  d&|        t>        j
                  jA                  |j                  d'      i d|d|d(|d)|	d*|d$|d+|d,|d-|
d.|j                  d/      d0|j                  d0      d1|d2|j                  di       j                  d3      d4|j                  d5i       j                  d6      xs dd7|j                  d5i       j                  d8      xs dd!|9      \  }}tB        j
                  j                  |:      j                         }|r||_"        |jG                          tI        jJ                         |jL                  d;}|r|j5                         |d<   tN        j
                  jQ                  ||	|<      \  }} | r#tS        |      |_*        |jG                  d=g>       |r]|[tW        jX                  |jL                  d?d@dAB       |t&        j,                  j                  k(  rt[        j\                  |||	||C       |rdDndE}!t        j                  dF| dG|j^                          ta        dF|! dH|j^                  |!dItb        jd                  J      S t        j                  dK| dL       ta        dK| dL||dMtb        jd                  J      S )Nr  eventcall_analyzedr   rP   rQ   disconnection_reasoncall_transferz'=-=-=-=-=-=-=-=Call Data=-=-=-=-=-=-=-=zCustomer Phone: zCompany Phone: zIs Call Transferred: zCall Data: r  Nhazelmayatranscript_with_tool_callsroletool_call_invocationr   transfer_call	argumentsz{}numbercall_analysisuser_sentimentr   r   'positiveneutraltelephony_identifierr   custom_analysis_datar   call_time_categoryzCustomer Name: zClean Customer Phone: r   rT   r[   r   r   r   r^   r   call_statusrR   r   rS   r   rV   	call_costtotal_duration_secondsrW   combined_cost)r   defaults)r   )last_call_atlast_call_id)r   r[   r  name_extracted)update_fieldsT)r   use_speaker   )kwargs	countdown)r   r`   r[   r   r  createdupdatedzCall z successfully: z successfully)r/  r   r   rE   zCall webhook for z received successfully)r/  r  r   )3r   ry   r  r  r$   re   rd   r   r[   bot_namelowerr1   	SALES_BOTrj   ri   jsonloadsrF   r`   r/   NOT_TRANSFERREDr   r   
isinstancetuplestrstripr0   NEGATIVEPOSITIVENEUTRALr3   update_or_creater*   r   rv   r   rl  r~   r,   get_or_createrJ   r  rM   apply_asyncrL   send_missed_call_notificationr   r    r   r   )"rl   r_   r  r  r   r  r  is_call_transferredr  r[   botTypetransfer_destination_numberr  itemr  	args_datar`   user_profiler   sentiment_strr   r   r  custom_analysisr   r  clean_customer_namer   call_createdappointmentcustomer_defaultsr   r  r   s"                                     ro   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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%MM/2>M+//0FKO+//@M!0!4!45I!J)3M3)GML_L_La##%gk   KK/-9:KK01D0EFG!%!>!>!i0!> "#6 w	
 &'B )*< $T &  immM: !)--"=   y}}_bAEEnU 	k2 > B BC[ \ a`a IMM+r:>>OTST  &! "? "D,0 &--44_4U[[]K#'   " !) $!
 #,9,?,?,A!&) ( 0 0 > >$* !? !Hg *I.*Y'-=,>? ; G&22'+wwtD 
 #o&<&<&B&BB (EE!! '&9'5 #/YIFKK%~_T\\NKL"6(-8<<  ((	* * KK+E72HIJ.ug5KL$ ((	* *rt   z!inbound-dynamic-variables-webhook)r{   rz   r|   r   r   c                 J   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}d}|j                         d	k(  rMt        |      }|d
   }|d   }|j                         D 	
ci c]  \  }	}
|	t        |
       }}	}
|rd}nf|du rbd}n_|j                         dk(  rLt        |      }|d
   }|d   }|rd}n|du rd}|j                         D 	
ci c]  \  }	}
|	t        |
       }}	}
|(d|i}|||d<   t        d|it        j                        S t        ddit        j                        S c c}
}	w c c}
}	w )r  Nr  call_inboundrQ   zExtracted company_number: rz   z&This bot not configured in our system.rE   r  
is_holidayis_office_hours agent_f72f27787dfcdcd7dc94ed136aF agent_9969e3fc1fd45a66a76ef1913br  dynamic_variablesoverride_agent_id)r   ry   r  r  r'   r    r   r   r  r.   rH  r  r-   r   )rl   r_   rQ   r  overrideAgentIdr  
sales_infor
  r  kvcompany_infocall_inbound_payloads                ro   !inbound_dynamic_variables_webhookz-CallViewSet.inbound_dynamic_variables_webhook)  s    	<<G$6>W\\;Y^488EI0<=	*X'OPY_YtYtuu  >>w&
 39=J#L1J():;O7A7G7G7I J7Itq!CF7I J"D E)"D^^'3I>L%l3J*+<=O"D E)"D 8D7I7I7K L7Ktq!CF7K L (#%6$  *<K$%89 4((* * #KLU[UpUpqqM !K" !Ms   F9F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 successfullyrE   )4r  r  r   dictheadersmethodr    r   r   r8  r   ry   r3   re   select_relatedallr   strptimerd   
ValueErrorr   rk   django.core.paginator	Paginatorpager~   r   rP   rQ   r   r   rR   rS   rV   floatrW   r   rU   r   
updated_atr[   company_namer  r   	num_pagesr  has_nexthas_previousr   errorr  HTTP_500_INTERNAL_SERVER_ERROR)rl   r_   r!  	page_sizestart_date_strend_date_strrP   rQ   r  r   
company_idrb   r   r   r   r   	paginatorpage_objr   r   r   es                         ro   log_transfer_call_webhookz%CallViewSet.log_transfer_call_webhooko  sl     	A',,PQ;D<Q;RST:7>>:JKL$CDVM_M_``rt   )N).__name__
__module____qualname____doc__r8   rr   r3   re   r  rb   r   r   r7   r   r   r   r   filter_backendsr2   filterset_classsearch_fieldsordering_fieldsorderingrp   rs   rx   r   rS   r   r   r  r(  r-  rB  rG  rv  r  rM   r  r  r   r  r  r  r  r1  r  rt   ro   rO   rO   E   s   $+||!H)*0*L.IO OYM8OH"L% 55'I>@ ?@0 55'ODF7 EF7P 55'4EFCL G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B; CB;H 55'NC1M D1Mf 55'ODX; EX;t 55'4IJ)& K)&V 55'4LMx Nx 55'F;2& <2&h 4%?Cn Dn( 5H- (z#%	2i2ij 5H- (z#%	+c+cZ 5H' (z#%	M*M*^ 4$:!=r=r~ 5H0 (z#%	x=x=rt   rO   )rr5  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    rest_framework.exceptionsr!   r"   apps.companies.modelsr#   r$   apps.core.modelsr%   r&   apps.calls.utilsr'   r(   r)   apps.appointments.modelsr*   apps.calls.paginationr+   apps.customers.modelsr,   apps.companies.utilsr-   r.   apps.calls.constantsr/   r0   r1   apps.calls.filtersr2   apps.calls.modelsr3   r4   r5   r6   r7   apps.calls.serializersr8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   apps.userprofile.modelsrF   rG   apps.calls.servicesrH   rI   rJ   rK   rL   r   apps.calls.tasksrM   	getLoggerr2  r  ModelViewSetrO   r  rt   ro   <module>r\     s       	  (   4 4 O O 0 - ! = & + = , Z Z ? @ , 2 . = . O O 0 > * T D D ) Y Y ;    0 , , ! / 5   ! 3			8	$h=('' h=rt   