def post(self, request, *args, **kwargs):
        campana = Campana.objects.get(pk=request.POST['campana_pk'])
        try:
            campana_service = CampanaService()
            campana_service.start_campana_wombat(campana)
            campana.play()
            message = _(u'<strong>Operación Exitosa!</strong>\
                        Se llevó a cabo con éxito la activación de\
                        la Campaña.')

            messages.add_message(
                self.request,
                messages.SUCCESS,
                message,
            )
        except WombatDialerError as e:
            message = _("<strong>¡Cuidado!</strong> "
                        "con el siguiente error: ") + "{0} .".format(e)
            messages.add_message(
                self.request,
                messages.WARNING,
                message,
            )
        except RequestException as e:
            message = _("<strong>¡Cuidado!</strong> "
                        "con el siguiente error: ") + "{0} .".format(e)
            messages.add_message(
                self.request,
                messages.WARNING,
                message,
            )
        return HttpResponseRedirect(reverse('campana_dialer_list'))
Esempio n. 2
0
 def _obtener_total_llamadas(
         self, evento, es_campana_entrante, calificacion_final, callid,
         callids_analizados, bridge_wait_time):
     if calificacion_final and calificacion_final.opcion_calificacion.es_agenda() and \
        callid not in callids_analizados:
         self.reporte_totales_llamadas._llamadas_pendientes += 1
     if evento == 'DIAL':
         self.reporte_totales_llamadas.llamadas_realizadas += 1
     if es_campana_entrante:
         if evento in ['ENTERQUEUE', 'ABANDONWEL', 'ENTERQUEUE-TRANSFER']:
             self.reporte_totales_llamadas._llamadas_recibidas += 1
             if evento == 'ABANDONWEL':
                 self.reporte_totales_llamadas._llamadas_abandonadas += 1
                 self.reporte_totales_llamadas._tiempo_acumulado_abandono += bridge_wait_time
         elif evento == 'ABANDON':
             self.reporte_totales_llamadas._llamadas_abandonadas += 1
             self.reporte_totales_llamadas._tiempo_acumulado_abandono += bridge_wait_time
         elif evento == 'CONNECT':
             self.reporte_totales_llamadas._llamadas_conectadas += 1
             self.reporte_totales_llamadas._tiempo_acumulado_espera += bridge_wait_time
     if self.campana.es_dialer:
         campana_service = CampanaService()
         dato_campana = campana_service.obtener_dato_campana_run(self.campana)
         self.reporte_totales_llamadas._llamadas_pendientes = 0
         if dato_campana:
             self.reporte_totales_llamadas._llamadas_pendientes = dato_campana.get(
                 'n_est_remaining_calls', 0)
Esempio n. 3
0
 def _reciclar_misma_campana(self, campana):
     campana_service = CampanaService()
     campana_service.cambiar_base(campana, [], False, False, "")
     update_campana = "campana_dialer_update"
     campana.estado = Campana.ESTADO_INACTIVA
     campana.save()
     return update_campana
 def get_context_data(self, **kwargs):
     context = super(
         CampanaDialerDetailView, self).get_context_data(**kwargs)
     campana = self.get_object()
     campana_service = CampanaService()
     estados_running_wombat = [Campana.ESTADO_ACTIVA, Campana.ESTADO_PAUSADA,
                               Campana.ESTADO_FINALIZADA]
     opciones_calificacion = campana.opciones_calificacion.all()
     context['opciones_calificacion'] = opciones_calificacion.values('nombre')
     context['opciones_calificacion_gestion'] = opciones_calificacion.filter(
         tipo=OpcionCalificacion.GESTION).values('nombre')
     if campana.estado in estados_running_wombat:
         dato_campana = campana_service.obtener_dato_campana_run(campana)
         if dato_campana:
             status = campana_service.obtener_status_campana_running(
                 dato_campana['hoppercampId'])
             context['efectuadas'] = dato_campana['n_calls_attempted']
             context['terminadas'] = dato_campana['n_calls_completed']
             context['estimadas'] = dato_campana['n_est_remaining_calls']
             context['reintentos_abiertos'] = dato_campana['n_open_retries']
             context['cant_contactos_llamados'] = \
                 LlamadaLog.objects.cantidad_contactos_llamados(campana)
             context['status'] = status
             context['resultado'] = True
         else:
             context['resultado'] = False
     return context
def detalle_campana_dialer_view(request):
    """Vista que muestrar el detalle de campana en wombat"""
    pk_campana = int(request.GET['pk_campana'])
    campana = Campana.objects.get(pk=pk_campana)
    campana_service = CampanaService()
    dato_campana = campana_service.obtener_dato_campana_run(campana)
    if dato_campana:
        status = campana_service.obtener_status_campana_running(
            dato_campana['hoppercampId'])
        data = {
            'error_consulta': False,
            'campana': campana,
            'efectuadas': dato_campana['n_calls_attempted'],
            'terminadas': dato_campana['n_calls_completed'],
            'estimadas': dato_campana['n_est_remaining_calls'],
            'reintentos_abiertos': dato_campana['n_open_retries'],
            'cant_contactos_llamados': LlamadaLog.objects.cantidad_contactos_llamados(campana),
            'status': status

        }
    else:
        data = {
            'campana': campana,
            'error_consulta': _(u"No se pudo consultar el estado actual de la campaña. "
                                "Consulte con su administrador.")
        }
    return render(request, 'campanas/campana_dialer/detalle_campana.html', data)
Esempio n. 6
0
    def post(self, request, *args, **kwargs):
        campana = Campana.objects.get(pk=request.POST['campana_id'])
        try:
            campana_service = CampanaService()
            campana_service.despausar_campana_wombat(campana)
            campana.activar()
            message = _('<strong>Operación Exitosa!</strong>\
                         Se llevó a cabo con éxito la activación dela Campaña.')

            messages.add_message(
                self.request,
                messages.SUCCESS,
                message,
            )
        except WombatDialerError as e:
            message = _("<strong>¡Cuidado!</strong> "
                        "con el siguiente error: ") + "{0} .".format(e)
            messages.add_message(
                self.request,
                messages.WARNING,
                message,
            )
        except RequestException as e:
            e = _(u'Imposible conectarse con el servicio Wombat')
            message = _("<strong>¡Cuidado!</strong> "
                        "con el siguiente error: ") + "{0} .".format(e)
            messages.add_message(
                self.request,
                messages.WARNING,
                message,
            )
        return super(ActivarCampanaDialerView, self).post(request, *args, **kwargs)
 def post(self, request, *args, **kwargs):
     campanas = Campana.objects.obtener_campanas_dialer()
     campana_service = CampanaService()
     error_finalizadas = campana_service.chequear_campanas_finalizada_eliminarlas(
         campanas.filter(estado=Campana.ESTADO_ACTIVA))
     if error_finalizadas:
         messages.add_message(self.request, messages.WARNING, error_finalizadas)
     return HttpResponseRedirect(reverse('campana_dialer_list'))
Esempio n. 8
0
    def form_valid(self, form):
        reciclado_calificacion = form.cleaned_data.get(
            'reciclado_calificacion')
        reciclado_no_contactacion = form.cleaned_data.get(
            'reciclado_no_contactacion')
        reciclado_radio = form.cleaned_data.get('reciclado_radio')

        if not (reciclado_calificacion or reciclado_no_contactacion):
            message = '<strong>Operación Errónea!</strong> \
                        Debe seleccionar al menos una opcion para reciclar '

            messages.add_message(
                self.request,
                messages.ERROR,
                message,
            )
            return self.form_invalid(form)

        campana = Campana.objects.get(pk=self.kwargs['pk_campana'])
        reciclador = RecicladorContactosCampanaDIALER()
        bd_contacto_reciclada = reciclador.reciclar(campana,
                                                    reciclado_calificacion,
                                                    reciclado_no_contactacion)
        if reciclado_radio == 'nueva_campaña':
            try:
                # Intenta reciclar la campana con el tipo de reciclado
                # seleccionado.
                campana_reciclada = Campana.objects.reciclar_campana(
                    campana, bd_contacto_reciclada)
            except OmlRecicladoCampanaError:

                message = '<strong>Operación Errónea!</strong>\
                No se pudo reciclar la Campana.'

                messages.add_message(
                    self.request,
                    messages.ERROR,
                    message,
                )
                return self.form_invalid(form)

            return HttpResponseRedirect(
                reverse("crea_campana_dialer_template",
                        kwargs={
                            "pk_campana_template": campana_reciclada.pk,
                            "borrar_template": 1
                        }))
        elif reciclado_radio == 'misma_campana':
            campana.update_basedatoscontactos(bd_contacto_reciclada)
            campana_service = CampanaService()
            campana_service.cambiar_base(campana, [], False, False, "")
            campana.estado = Campana.ESTADO_INACTIVA
            campana.save()
            return HttpResponseRedirect(
                reverse("campana_dialer_update",
                        kwargs={"pk_campana": campana.pk}))
 def obtener_total_llamadas(self, campana):
     """Obtiene los totales de llamadas realizadas y pendiente por la campaña
     :param campana: campana la cual se obtiene los totales
     :return: los totales de llamadas realizadas y pendientes de la campaña
     """
     logs_llamadas_campana_raw = LlamadaLog.objects.filter(
         campana_id=campana.pk)
     logs_llamadas_campana = logs_llamadas_campana_raw.values(
         'event').annotate(cantidad=Count('event'))
     if campana.type == Campana.TYPE_ENTRANTE:
         # en las campañas entrantes solo queremos mostrar las llamadas ocurridas en el día
         # actual
         hoy_ahora = fecha_hora_local(timezone.now())
         hoy = hoy_ahora.date()
         fecha_desde = datetime.datetime.combine(hoy, datetime.time.min)
         fecha_hasta = datetime.datetime.combine(hoy_ahora,
                                                 datetime.time.max)
         logs_llamadas_campana_raw = logs_llamadas_campana_raw.filter(
             time__range=(fecha_desde, fecha_hasta))
         logs_llamadas_campana = logs_llamadas_campana.filter(
             time__range=(fecha_desde, fecha_hasta))
         logs_llamadas_campana_raw = logs_llamadas_campana_raw.filter(
             time__range=(fecha_desde, fecha_hasta))
     # obtenemos los eventos en formato más sencillo para indexar
     dict_eventos_campana = self._convertir_eventos_values_dict(
         logs_llamadas_campana)
     # calculamos los contadores de cada tipo de llamada
     (llamadas_pendientes, llamadas_realizadas, llamadas_recibidas,
      tiempo_promedio_espera, tiempo_promedio_abandono) = (None, ) * 5
     llamadas_realizadas = dict_eventos_campana.get('DIAL', 0)
     if campana.type == Campana.TYPE_DIALER:
         campana_service = CampanaService()
         dato_campana = campana_service.obtener_dato_campana_run(campana)
         llamadas_pendientes = 0
         if dato_campana:
             llamadas_pendientes = dato_campana.get('n_est_remaining_calls',
                                                    0)
     elif campana.type == Campana.TYPE_ENTRANTE:
         llamadas_recibidas = dict_eventos_campana.get('ENTERQUEUE', 0) +\
             dict_eventos_campana.get('ABANDONWEL', 0)
         llamadas_recibidas_transferidas = dict_eventos_campana.get(
             'ENTERQUEUE-TRANSFER', 0)
         llamadas_recibidas += llamadas_recibidas_transferidas
         tiempo_promedio_espera = self._calcular_tiempo_promedio_espera(
             logs_llamadas_campana_raw)
         tiempo_promedio_abandono = self._calcular_tiempo_promedio_abandono(
             logs_llamadas_campana_raw)
     elif campana.type == Campana.TYPE_PREVIEW:
         llamadas_pendientes = AgenteEnContacto.objects.filter(
             estado=AgenteEnContacto.ESTADO_INICIAL,
             campana_id=campana.pk,
             es_originario=True).count()
     llamadas_pendientes = self._adicionar_agendas_pendientes(
         campana, llamadas_pendientes)
     return (llamadas_pendientes, llamadas_realizadas, llamadas_recibidas,
             tiempo_promedio_espera, tiempo_promedio_abandono)
Esempio n. 10
0
 def _reciclar_crear_nueva_campana(self, campana_reciclada, campana):
     if campana.estado != Campana.ESTADO_FINALIZADA:
         campana_service = CampanaService()
         campana_service.remove_campana_wombat(campana)
         campana.estado = Campana.ESTADO_FINALIZADA
         campana.save()
     crea_campana_template = reverse("crea_campana_dialer_template",
                                     kwargs={
                                         "pk_campana_template":
                                         campana_reciclada.pk,
                                         "borrar_template":
                                         1
                                     })
     return crea_campana_template
Esempio n. 11
0
 def llamadas_pendientes(self):
     if not self.campana.es_preview:
         llamadas_pendientes_extra = 0
     else:
         llamadas_pendientes_extra = AgenteEnContacto.objects.filter(
             estado=AgenteEnContacto.ESTADO_INICIAL,
             campana_id=self.campana.pk,
             es_originario=True).count()
     if self.campana.es_dialer:
         campana_service = CampanaService()
         dato_campana = campana_service.obtener_dato_campana_run(
             self.campana)
         llamadas_pendientes_extra = 0
         if dato_campana:
             llamadas_pendientes_extra = dato_campana.get(
                 'n_est_remaining_calls', 0)
     return self._llamadas_pendientes + llamadas_pendientes_extra
 def _contabilizar_llamadas_pendientes(self):
     estados_running_wombat = [
         Campana.ESTADO_ACTIVA, Campana.ESTADO_PAUSADA,
         Campana.ESTADO_FINALIZADA
     ]
     campanas_por_id_wombat = {}
     for campana_id, campana in self.campanas.items():
         if campana.estado in estados_running_wombat:
             campanas_por_id_wombat[campana.campaign_id_wombat] = campana
     campana_service = CampanaService()
     dato_campanas = campana_service.obtener_datos_campanas_run(
         campanas_por_id_wombat)
     for campana_id, datos_campana in dato_campanas.items():
         if campana_id not in self.estadisticas:
             self._inicializar_conteo_de_campana(campana_id)
         self.estadisticas[campana_id]['pendientes'] = datos_campana[
             'n_est_remaining_calls']
    def done(self, form_list, **kwargs):
        success = False
        try:
            with transaction.atomic():
                campana_form = list(form_list)[int(self.INICIAL)]
                queue_form = list(form_list)[int(self.COLA)]
                opciones_calificacion_formset = list(form_list)[int(
                    self.OPCIONES_CALIFICACION)]
                campana = campana_form.save()
                queue = self._save_queue(queue_form)
                opciones_calificacion_formset.save()

                if campana.tipo_interaccion == Campana.SITIO_EXTERNO:
                    parametros_crm_formset = list(form_list)[int(
                        self.PARAMETROS_CRM)]
                    parametros_crm_formset.save()

                self._insert_queue_asterisk(queue)
                campana_service = CampanaService()
                service_ok = campana_service.crear_campana_wombat(campana)
                if service_ok:
                    service_ok = campana_service.update_endpoint(campana)
                if not service_ok:
                    raise Exception(
                        'No se ha podico crear la campaña en Wombat.')

            success = True

        except Exception as e:
            logger.error(e)
            success = False

        if success:
            messages.add_message(self.request, messages.SUCCESS,
                                 _('Se ha modificado la campaña.'))
        else:
            messages.add_message(
                self.request, messages.ERROR,
                _('<strong>¡ATENCIÓN!</strong> El servicio Discador no se encuentra disponible. '
                  'No se pudo modificar la campaña. Por favor contacte un administrador.'
                  ))

        return HttpResponseRedirect(reverse('campana_dialer_list'))
 def delete(self, request, *args, **kwargs):
     self.object = self.get_object()
     success_url = self.get_success_url()
     service = CampanaService()
     # remueve campana de wombat
     remover = service.remove_campana_wombat(self.object)
     if not remover:
         message = _("<strong>Operación Errónea!</strong> "
                     "No se pudo eliminar la campana {0} del discador").format(
                         self.object.nombre)
         messages.add_message(
             self.request,
             messages.ERROR,
             message,
         )
     else:
         super(CampanaDialerDeleteView, self).delete(request, *args, **kwargs)
         self.object.remover()
     return HttpResponseRedirect(success_url)
    def form_valid(self, form):
        evitar_duplicados = form.cleaned_data.get('evitar_duplicados')
        evitar_sin_telefono = form.cleaned_data.get('evitar_sin_telefono')
        prefijo_discador = form.cleaned_data.get('prefijo_discador')
        columnas = form.cleaned_data.get('telefonos')
        bd_contacto = form.cleaned_data.get('bd_contacto')
        self.object = self.get_object()
        campana_service = CampanaService()
        # valida de que se pueda cambiar la base de datos que tenga las misma columnas
        # que la actualmente poseee
        error = campana_service.validar_modificacion_bd_contacto(
            self.get_object(), bd_contacto)
        if error:
            return self.form_invalid(form, error=error)
        if self.object.bd_contacto == bd_contacto:
            message = _('Atención!\
                         Ud ha escogido la misma base de datos, corre riesgo de calificar los'
                        ' mismos contactos pisando la calificación previa.')

            messages.add_message(
                self.request,
                messages.SUCCESS,
                message,
            )

        self.object.bd_contacto = bd_contacto
        self.object.save()
        # realiza el cambio de la base de datos en wombat
        campana_service.cambiar_base(self.get_object(), columnas, evitar_duplicados,
                                     evitar_sin_telefono, prefijo_discador)
        message = _('Operación Exitosa!\
                     Se llevó a cabo con éxito el cambio de base de datos.')

        messages.add_message(
            self.request,
            messages.SUCCESS,
            message,
        )
        self.object.estado = Campana.ESTADO_INACTIVA
        self.object.save()

        return redirect(self.get_success_url())
    def form_valid(self, form):
        regla = form.save(commit=False)
        try:
            campana_service = CampanaService()
            editado = campana_service.editar_reschedule_por_calificacion_wombat(
                regla, self.wombat_id)
            if not editado:
                messages.error(_('No se pudo guardar la regla de incidencia.'))
                return self.form_invalid(form)
            if self.campana.estado == Campana.ESTADO_ACTIVA:
                campana_service.reload_campana_wombat(self.campana)
        except WombatDialerError as e:
            error_message = _("Error al editar regla de incidencia: ") + "{0} .".format(e)
            logger.error(error_message)
            messages.error(_('No se pudo guardar la regla de incidencia.'))
            return self.form_invalid(form)

        regla.save()

        return super(ReglasDeIncidenciaDeCalificacionesUpdateView, self).form_valid(form)
 def delete(self, request, *args, **kwargs):
     self.object = self.get_object()
     success_url = self.get_success_url()
     service = CampanaService()
     # remueve campana de wombat
     remover = service.eliminar_reschedule_por_calificacion_wombat(self.object)
     if not remover:
         message = _("<strong>Operación Errónea!</strong> "
                     "No se pudo eliminar la Regla de Incidencia por calificación: {0}").format(
                         self.object.opcion_calificacion.nombre)
         messages.add_message(
             self.request,
             messages.ERROR,
             message,
         )
     else:
         if self.campana.estado == Campana.ESTADO_ACTIVA:
             service.reload_campana_wombat(self.campana)
         super(ReglasDeIncidenciaDeCalificacionesDeleteView, self).delete(
             request, *args, **kwargs)
         messages.success(request, _('Regla de incidencia eliminada.'))
     return HttpResponseRedirect(success_url)
 def _sincronizar_campana(self, sincronizar_form, campana):
     evitar_duplicados = sincronizar_form.cleaned_data.get(
         'evitar_duplicados')
     evitar_sin_telefono = sincronizar_form.cleaned_data.get(
         'evitar_sin_telefono')
     prefijo_discador = sincronizar_form.cleaned_data.get(
         'prefijo_discador')
     service_base = SincronizarBaseDatosContactosService()
     # Crea un achivo con la lista de contactos para importar a wombat
     service_base.crear_lista(campana, evitar_duplicados,
                              evitar_sin_telefono, prefijo_discador)
     campana_service = CampanaService()
     # crear campana en wombat
     campana_service.crear_campana_wombat(campana)
     # crea trunk en wombat
     campana_service.crear_trunk_campana_wombat(campana)
     # crea reglas de incidencia en wombat
     for regla in campana.reglas_incidencia.all():
         parametros = [
             regla.get_estado_wombat(), regla.estado_personalizado,
             regla.intento_max, regla.reintentar_tarde,
             regla.get_en_modo_wombat()
         ]
         campana_service.crear_reschedule_campana_wombat(
             campana, parametros)
     # crea endpoint en wombat
     campana_service.crear_endpoint_campana_wombat(campana)
     # asocia endpoint en wombat a campana
     campana_service.crear_endpoint_asociacion_campana_wombat(campana)
     # crea lista en wombat
     campana_service.crear_lista_contactos_wombat(campana)
     # asocia lista a campana en wombat
     campana_service.crear_lista_asociacion_campana_wombat(campana)
    def _calificar_form(self, calificacion_form):
        calificacion_nueva = False
        if calificacion_form.instance.pk is None:
            calificacion_nueva = True
        self.object_calificacion = calificacion_form.save(commit=False)
        self.object_calificacion.callid = self._obtener_call_id()
        self.object_calificacion.agente = self.agente
        self.object_calificacion.contacto = self.contacto

        # TODO: Ver si hace falta guardar que es una llamada manual
        # El parametro manual no viene mas
        if self.object is None:
            es_calificacion_manual = 'manual' in self.kwargs and self.kwargs[
                'manual']
            self.object_calificacion.es_calificacion_manual = es_calificacion_manual

        self.object_calificacion.save()
        # modificamos la entrada de la modificación en la instancia para así diferenciar
        # cambios realizados directamente desde una llamada de las otras modificaciones
        update_change_reason(self.object_calificacion, self.kwargs.get('from'))

        # check metadata en calificaciones de no accion y eliminar
        self._check_metadata_no_accion_delete(self.object_calificacion)

        # Verificar si es dialer y hay regla de incidencia por calificacion
        if self.call_data and 'dialer_id' in self.call_data:
            regla = ReglaIncidenciaPorCalificacion.objects.filter(
                opcion_calificacion=self.object_calificacion.
                opcion_calificacion)
            if regla:
                regla = regla[0]
                campana_service = CampanaService()
                campana_service.notificar_incidencia_por_calificacion(
                    self.call_data['dialer_id'], regla)

        if self.object_calificacion.es_gestion() and \
                not self.campana.tiene_interaccion_con_sitio_externo:
            if self.agente.grupo.obligar_calificacion:
                calificacion_llamada = CalificacionLLamada()
                calificacion_llamada.create_family(
                    self.agente,
                    self.call_data,
                    self.kwargs['call_data_json'],
                    calificado=False,
                    gestion=True,
                    id_calificacion=calificacion_form.instance.pk)
            return redirect(self.get_success_url_venta())
        else:
            message = _(
                'Operación Exitosa! '
                'Se llevó a cabo con éxito la calificación del cliente')
            messages.success(self.request, message)
        if self.object_calificacion.es_agenda() and calificacion_nueva:
            return redirect(self.get_success_url_agenda())
        elif self.object_calificacion.es_agenda():
            # se esta modificando una calificacion de agenda existente
            # con una agenda creada
            agenda_calificacion = AgendaContacto.objects.filter(
                contacto=self.contacto,
                campana=self.campana,
                agente=self.agente).first()
            if agenda_calificacion is not None:
                return redirect(
                    self.get_success_url_agenda_update(agenda_calificacion.pk))
            else:
                return redirect(self.get_success_url_agenda())
        elif self.kwargs['from'] == 'reporte':
            return redirect(self.get_success_url_reporte())
        else:
            return redirect(self.get_success_url())
 def get_context_data(self, **kwargs):
     context = super(LlamadasActivasView, self).get_context_data(**kwargs)
     service = CampanaService()
     context['llamadas'] = service.obtener_calls_live()
     return context