
    yiyf                     *   d 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 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 ddlmZ ddlmZ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*m+Z+m,Z, ddl-m.Z. ddl/m0Z0m1Z1m2Z2 ddl3m4Z4m5Z5 ddl6m7Z7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>Z>m?Z? ddl@mAZAmBZB ddlCmDZDmEZEmFZFmGZGmHZHmIZImJZJ ddlKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZS  ej                  eU      ZV G d deSeMeLeNeOePeQeRej                        ZXy)z
Views for the call APIs.
    N)Anycast)settings)timezone)DjangoFilterBackend)viewsetsstatus)action)Response)IsAuthenticatedAllowAny)BookAppointmentInputSerializer)WebhookEventServiceAppointmentService)CompanyTypeBotName)UserProfile)Appointment)Customer)CompanyCompanyBotSettings)get_company_working_infocheck_sales_time_by_phoneget_rabeeca_working_info)MessageRepository)TRANSFER_STATUS	SENTIMENTBotType)
CallFilterCallOrderingFilter)CallCallActivity)CallLimitOffsetPagination)get_bot_name)process_booking_intentprocess_catch_phrases_for_call)CallDetailSerializerReadCallSerializer)RecordingServiceStorageService
SmsServiceEmailServiceNotificationServiceget_caller_name_by_phone_numberget_twilio_client)UserPerformanceMixinTransferPercentageMixinCallSummaryMixinMonthlyStatsMixinTopCallersMixinHourlyCallsMixinDailyCallsMixinCallSearchMixinc                      e Zd ZdZeZej                  j                         Z	e
gZeZeegZe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d       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       d        Z eddgdegg       d        Z y)ServiceCallViewSetzView for manage call APIs.)	
created_atcaller_namefrom_numbertransfer_user__usernamecall_time_category	sentimenttransfer_statusdurationcostz-created_atc                    | j                   j                  }| j                  }|j                  rn|j                  rb	 |j                  j
                  t        j                  k(  r|j                  |j                        }n|j                  |j                        }n| j                  j                         S | j                  dk(  r*|j                  t        j                  j                        }| j!                  |      }| j#                  |      }| j%                  |      }|S # t        j                  $ r | j                  j                         cY S w xY w)N)
dealership)companylist)bot_type)requestuserquerysetis_superuseractive_companycompany_typer   
DEALERSHIPfilterr   DoesNotExistnoner
   r   SERVICE_BOTvaluewith_sort_namewith_sort_advisor_nameapply_call_search)selfrI   qss      G/var/www/html/dp2/backend_v2.1/server/apps/calls/views/service_calls.pyget_querysetzServiceCallViewSet.get_querysetf   s'   ||  ]]  ,&&33{7M7MM#'#6#6 # B 4+>+>?B ==%%'';;&  ,,22  B   $((,##B'	 '' ,}}))++,s   A D& &-EEc                 D    | j                   dk(  rt        S | j                  S )z(Return the serializer class for request.rF   )r
   r'   serializer_class)rW   s    rY   get_serializer_classz'ServiceCallViewSet.get_serializer_class   s     ;;& ''$$$    c                 $    |j                          y)zCreate a new call.N)save)rW   
serializers     rY   perform_createz!ServiceCallViewSet.perform_create   s    r^   Fgetread)detailmethodsurl_pathc                    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 |j*                  j,                  t.        j0                  k(  r,t        j                  j                  ||j*                  
      }n+t        j                  j                  ||j*                        }t3        j                  |j*                  j                        }t        j                         }|j5                  |      }	||_        |	|_        t"        j                  j%                  ||j                  d|	       |j'                          t        ddit
        j(                        S )z3Process booking intent for a call and mark as read.rH   )datacontextr	   id)rl   READ)callrI   r
   performed_atre   z%Call marked as read from super admin.)rl   rD   )rl   rE   zCall marked as read.)r(   query_paramsis_validr   errorsr	   HTTP_400_BAD_REQUESTvalidated_datarI   rK   r!   objectsrc   r   nowread_byread_atr"   creater`   HTTP_200_OKrL   rM   r   rN   pytz
astimezone)
rW   rH   ra   call_idrI   rn   current_timecompany_timezonecurrent_time_utccurrent_time_companys
             rY   	read_callzServiceCallViewSet.read_call   s    (%%(


 ""$!!22 
 ++D1||<<##w#/D#<<>LDL'DL  ''\\)	 (  IIKA((* * ++{/E/EE<<##w4;N;N#OD<<##w8K8K#LD==)<)<)E)EF#<<>/::;KL+##-	 	$ 	
 			,
$$& 	&r^   Tzget-recordingNc                 Z   |rt         j                  |       | j                         }t        t	                     }t               }|j                  |      }|j                  |      \  }}ddlm	}	  |	d      rt        j                  j                  |      sH|j                  |j                        }
|j                  |
j                         }|j#                  ||       ddlm} ddlm}  | |t-        |d            d      }d	|d
<   |S t        j                  j                  |      rt/        d|j1                  ||      i      S |j                  |j                        }
|j                  |
j                         }|j#                  ||       t/        d|j1                  ||      i      S )Nr   )is_feature_enablednew_audio_stream)FileResponse)Filerbz
audio/mpeg)content_typebyteszAccept-Rangesrecording_url)loggerinfo
get_objectr)   r/   r*   build_call_audio_filenamecall_recording_local_pathutils.feature_flagsr   ospathexistsget_latest_call_recordingtwilio_call_siddownloadsidsave_call_recording_streamdjango.httpr   django.core.filesr   openr   call_recording_public_url)rW   rH   pkrn   recording_servicestorage_servicefilenamerelative_pathfilepathr   	recordingresponser   r   s                 rY   download_recordingz%ServiceCallViewSet.download_recording   s   KKO ,->-@A(*"<<TB"1"K"KH"Ux:0177>>(+-GG((	 -55immD::8XN0.#T(D)*)H )0H_%O77>>(# /"K"K!#   &??  
	 %--imm<228XFoGG  
 	
r^   postzrecord-offtime-message)re   rf   rg   permission_classesauthentication_classesc           	      :   |j                   }|j                  di       }|j                  d      }|j                  d      }|j                  di       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                  |||
|d|
 ||       t        j                  d       t        j                  d       t        d d!it        j                         S )"!Handle incoming webhook requests.rn   r<   	to_numbertelephony_identifierr   zo=============================== Record Off-time Message request.data starts ===================================zWebhook Data: args
advisor_idadvisor_namecustomer_namecustomer_noteztype of advisor_id: zadvisor_id: zadvisor_name: zcustomer_name: zcustomer_note: `=============================== Getting Company Bot Settings ===================================phone_numberNre   Company not foundrk   T)rl   	is_activezUser not foundzY=============================== Creating User Message ===================================zOff-time Message from )	recipientrE   r   customer_numbersubjectbodyr   ze=============================== User Message created successfully ===================================z^=============================== Recording Off-time Message ===================================messagez%Offtime message recorded successfully)ri   rc   r   r   typer   ru   rO   firstrE   r   r	   HTTP_404_NOT_FOUNDusersr   create_messagerz   )rW   rH   webhook_data	call_datacustomer_phonecompany_phoner   r   r   r   r   r   company_bot_settingsrE   rI   s                  rY   record_offtime_messagez)ServiceCallViewSet.record_offtime_message  s_    || $$VR0	"}5!k2#--"B

#
  	 	  F  	Gn\N34+XXl+
xx/11*4
+;*<=>l:,/0n\N34om_56om_56 	vw199@@&  A  

%' 	 3G&..D-//1 1 }}##zT#BHHJ*//1 1 	op(('*,]O<+	
 	{|tu?@%%
 	
r^   zsend-appointment-emailc                    t        j                  |dd      }|j                  }|j                  di       }|j                  d      }t        j                  d       t        j                  j                  |      j                         }|r|j                  nd}|s0|r|j                  d       t        d	dit        j                  
      S t        j                  d       |j                  }|s0|r|j                  d       t        d	dit        j                  
      S 	 t!        |j                        }	|	j#                  d       t%        j&                  |	j(                         |r|j+                          t        ddit        j0                  
      S # t,        $ r8}
|r|j                  d|
        t        j/                  d|
        Y d}
~
Yd}
~
ww xY w)r   retellzSend Appointment Emailrn   r   r   r   Nr   re   rk   zV=============================== Getting BDC number ===================================zBDC number not found)ri   T)raise_exceptionz)Failed in creation of Appointment Object r   zEmail and SMS sent successfully)r   	log_eventri   rc   r   r   r   ru   rO   r   rE   mark_failedr   r	   r   
bdc_numberr   rq   r   book_service_appointmentrt   mark_success	Exceptionwarningrz   )rW   rH   eventr   r   r   r   rE   r   ra   excs              rY   send_appointment_emailz)ServiceCallViewSet.send_appointment_emailI  s    $--$
 || $$VR0	!k2 	vw199@@&  A  

%' 	 3G&..D!!"56-//1 1 	lm''
!!"890//1 1,	7W\\JJ577
8Q8QR""$ 9:%%
 	
  	!!$McU"STNNFseLM		s    AF 	G.GG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}	d}
|j                  t        j                  k(  rt        j                  }
n[|j                  t        j                  k(  rt        j                  }
n-|j                  t        j                   k(  rt        j"                  }
d}|j                  dg       }|D ]  }|j                  d      dk(  sd|j                  d      xs dj%                         v s>|j                  dd      }t'        j(                  |      }|j                  d      }||j                  d      }t        j                  d|j                  d               t        j                  d|        d}|r>t*        j
                  j                  |      j                         }|r|j,                  nd}d}|
t        j"                  k(  r?|r=t.        j
                  j                  |t0        j2                        j                         }t4        j6                  j8                  }|r|rt4        j:                  j8                  }n|r|st4        j<                  j8                  }|j                  di       j                  dd      }t?        |t@              r|r|d   }tC        |      jE                  d      }tF        jH                  j8                  }|j%                         d k(  rtF        jJ                  j8                  }n-|j%                         d!k(  rtF        jL                  j8                  }|j                  d"i       j                  d#      }|j                  di       }|j                  d$i       }|j                  d%      }|j                  d&      }t?        |tB              r |jE                         r|jE                         nd}t        j                  d'|        t        j                  d(|        tN        j
                  jQ                  |j                  d)      i d|d|d*|d+|	d,|d-|d&|d.|d/|d0|
d1|j                  d2      d3|j                  d3      d4|d5|j                  di       j                  d6      d7|j                  d8i       j                  d9      xs dd:|j                  d8i       j                  d;      xs dd#|<      \  }}tS        jT                  |jV                         tX        j
                  j                  |=      j                         }|r||_-        |j]                          t_        j`                         |jV                  d>}|r!tc        td        |jE                               |d<   tf        j
                  ji                  ||	|?      \  } }!|!r#tk        |      | _6        | j]                  d@gA       |r]|[to        jp                  |jV                  dBdCdDE       |t4        j<                  j8                  k(  rts        jt                  |||	||F       |rdGndH}"t        j                  dI| dJ|jv                          ty        dI|" dK|jv                  |"dLtz        j|                  M      S t        j                  dN| dO       ty        dN| dO||dPtz        j|                  M      S )Qr   r   call_analyzedrn   r<   r   disconnection_reasoncall_transferz'=-=-=-=-=-=-=-=Call Data=-=-=-=-=-=-=-=zCustomer Phone: zCompany Phone: zIs Call Transferred: zCall Data: r   Ntranscript_with_tool_callsroletool_call_invocationtransfer_callname 	argumentsz{}numbertransfer_destination_numberzTransfer Destination Number 1: zTransfer Destination Number: )contact_phonerM   call_analysisuser_sentimentr   'positiveneutralr   r   custom_analysis_datar   r>   zCustomer Name: zClean Customer Phone: r}   r;   rE   rD   transfer_numbertransfer_userr@   rG   r	   call_status
transcriptr?   summarycall_summaryrA   	call_costtotal_duration_secondsrB   combined_cost)r}   defaults)r   )last_call_atlast_call_id)phonerE   r   name_extracted)update_fieldsT)r}   use_speaker   )kwargs	countdown)rn   rI   rE   r   r   createdupdatedzCall z successfully: z successfully)r   r}   r
   rk   zCall webhook for z received successfully)r   r   ri   )?ri   rc   r   r   r   ru   rO   r   rE   bot_namer   hazelr   	SALES_BOTmayarR   rebeccaDEALERSHIP_GROUP_BOTlowerjsonloadsr   rI   r   r   rN   r   NOT_TRANSFERREDrS   
SUCCESSFULFAILED
isinstancetuplestrstripr   NEGATIVEPOSITIVENEUTRALr!   update_or_creater&   delayrl   r   rn   r`   r   rv   r   r   r   get_or_creater.   r   r%   apply_asyncr-   send_missed_call_notificationr}   r   r	   rz   )#rW   rH   r   r   r   r   r   is_call_transferredr   rE   rG   r   r   itemr   	args_datarI   user_profilerD   r@   sentiment_strr?   r   r   custom_analysisr   r>   clean_customer_namern   call_createdappointmentcustomer_defaultscustomerr   call_actions#                                      rY   log_call_webhookz#ServiceCallViewSet.log_call_webhook  s    ||  )O#$((4I&]]=9N%MM+6M#,==1G#H#2$3KKABKK*>*:;<KK/-9:KK/0C/DEFKK+i[12KKAB#5#=#=#D#D* $E $eg !
 ( %,,  H#,,=",,%..',,>"..%..'//A"77*.')2,b*& 3HHV$(>>'DHHV,<,B+I+I+KK $d ;I $

9 5I2;--2I/2:6?mmDa6b3KK"A#,==#:";!= > 3 KK7679 : D**2299!<  :  %'  -9|((dJ7777.!(!7!7&A%0%;%; "8 " eg 
 .==CCO*/B"1"<"<"B"B,5H"1"8"8">">%MMc"B'  -/M -a 0.44S9M!**00I""$
2%..44	$$&)3%--33	'mm&c#$  &MM/2>M+//0FKO+//@M!0!4!45I!J mS1$**, ##%26   KK/-9:KK01D0EFG!%!>!>!i0!> "#6 w	
 !* &'B )*< $T &  immM: !)--"=   y}}' c.)!" 	#R!c23!978'( IMM#Rc/*0./-. &/ "? "D,: +009%--44 / 5 eg  #'   " !) $!
 #,0m6I6I6K,L!&) ( 0 0 > >$* !? !Hg *I"+' -=,>? ; G&22'+wwtD 
 #o&<&<&B&BB (EE!! '&9'5 (4)KKK%~ .))-8 9 ";-}=<<% ((	* * KK+E7 30 1 2.ug 63 4$	
 ((* *r^   z!inbound-dynamic-variables-webhook)rf   re   rg   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}d}|j                         t        j                  k(  rit        |      }|d	   }|d
   }|j                         D 	
ci c]  \  }	}
|	t        |
       }}	}
|rt        j                  }n|du rt        j                   }n|j                         t        j"                  k(  rit%        |      }|d	   }|d
   }|rt        j                  }n|du rt        j                   }|j                         D 	
ci c]  \  }	}
|	t        |
       }}	}
nX|j                         t        j&                  k(  r7t)        |      }|j                         D 	
ci c]  \  }	}
|	t        |
       }}	}
|6d|i}|t+        t,        |      |d<   t        d|it        j.                        S t        ddit        j                        S c c}
}	w c c}
}	w c c}
}	w )r   Nr   call_inboundr   zExtracted company_number: re   z&This bot not configured in our system.rk   
is_holidayis_office_hoursFdynamic_variablesoverride_agent_id)ri   rc   r   r   r$   r   r	   rs   r  r   r   r   itemsr  r   LYRA_AGENT_IDOLIVIA_AGENT_IDr  r   r  r   r   r   rz   )rW   rH   r   r   r(  r'  
sales_infor%  r&  kvcompany_inforabeeca_infocall_inbound_payloads                 rY   !inbound_dynamic_variables_webhookz4ServiceCallViewSet.inbound_dynamic_variables_webhooks  sc    	LLW%7"gll2^488EI0<=	*CD22 
 ! >>w}},29=J#L1J():;O7A7G7G7I J7Itq!CF7I J$,$:$:! E)$,$<$<!^^-3I>L%l3J*+<=O$,$:$:! E)$,$<$<!7C7I7I7K L7Ktq!CF7K L^^03I>L7C7I7I7K L7Ktq!CF7K L(#%6$  !,<@FW<X$%89 4((* * ?@..
 	
E !K  !M !Ms   II&I 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 successfullyrk   )	r   r   ri   dictheadersmethodr   r	   rz   )rW   rH   s     rY   log_transfer_call_webhookz,ServiceCallViewSet.log_transfer_call_webhook  sl     	A',,PQ;D<Q;RST:7>>:JKL$CDVM_M_``r^   )N)!__name__
__module____qualname____doc__r'   r\   r!   ru   allrJ   r   r   r#   pagination_classr   r    filter_backendsr   filterset_classordering_fieldsorderingrZ   r]   rb   r
   r   r   r   r   r   r"  r2  r7   r^   rY   r9   r9   F   s    %+||!H)*0*,>?O O
O H<% 55'F;;& <;&z 4%?C0
 D0
h 5H- (z#%	>
>
B )$:!T
T
l 5H' (z#%	E*E*N 4$:!<
<
| 5H0 (z#%	aar^   r9   )Yr;  r  loggingr   r{   typingr   r   django.confr   django.utilsr   django_filters.rest_frameworkr   rest_frameworkr   r	   rest_framework.decoratorsr
   rest_framework.responser   rest_framework.permissionsr   r   apps.appointments.serializersr   apps.appointments.servicesr   r   apps.companies.constantsr   r   apps.userprofile.modelsr   apps.appointments.modelsr   apps.customers.modelsr   apps.companies.modelsr   r   apps.companies.utilsr   r   r   apps.calls.repositoriesr   apps.calls.constantsr   r   r   apps.calls.filtersr   r    apps.calls.modelsr!   r"   apps.calls.paginationr#   apps.calls.utilsr$   apps.calls.tasksr%   r&   apps.calls.serializersr'   r(   apps.calls.servicesr)   r*   r+   r,   r-   r.   r/   apps.calls.mixinsr0   r1   r2   r3   r4   r5   r6   r7   	getLoggerr8  r   ModelViewSetr9   rB  r^   rY   <module>r`     s      	     ! = + , , @ H N 9 / 0 * = 
 6 D D = 0 ; )  	 	 	 
		8	$~	a~	ar^   