示例#1
0
def test_identificacion_consolidada_ninguno(db):
    a = AttachmentFactory()
    m1 = MesaFactory()
    IdentificacionFactory(attachment=a, status='identificada', mesa=m1)

    i1 = IdentificacionFactory(attachment=a, status='problema', mesa=None)
    f = FiscalFactory()
    Problema.reportar_problema(f,
                               'reporte 1',
                               ReporteDeProblema.TIPOS_DE_PROBLEMA.spam,
                               identificacion=i1)
    assert i1.problemas.first().problema.estado == Problema.ESTADOS.potencial

    i2 = IdentificacionFactory(attachment=a, status='problema', mesa=None)
    Problema.reportar_problema(f,
                               'reporte 2',
                               ReporteDeProblema.TIPOS_DE_PROBLEMA.ilegible,
                               identificacion=i2)

    assert a.identificacion_testigo is None

    cant_novedades = Identificacion.objects.filter(procesada=False).count()
    assert cant_novedades == 3
    consumir_novedades_identificacion()

    # Se consolidó un problema.
    assert i1.problemas.first().problema.estado == Problema.ESTADOS.pendiente

    cant_novedades = Identificacion.objects.filter(procesada=False).count()
    assert cant_novedades == 0

    assert a.identificacion_testigo is None
示例#2
0
def test_identificacion_consolidada_alguna(db):
    a = AttachmentFactory()
    m1 = MesaFactory()
    i1 = IdentificacionFactory(attachment=a, status='identificada', mesa=m1)
    IdentificacionFactory(attachment=a, status='problema', mesa=None)
    i2 = IdentificacionFactory(attachment=a, status='problema', mesa=None)
    Problema.reportar_problema(FiscalFactory(),
                               'reporte 1',
                               ReporteDeProblema.TIPOS_DE_PROBLEMA.ilegible,
                               identificacion=i2)
    IdentificacionFactory(attachment=a, status='identificada', mesa=m1)

    assert a.identificacion_testigo is None

    cant_novedades = Identificacion.objects.filter(procesada=False).count()
    assert cant_novedades == 4
    consumir_novedades_identificacion()

    # No se consolidó el problema.
    assert i2.problemas.first().problema.estado == Problema.ESTADOS.potencial

    cant_novedades = Identificacion.objects.filter(procesada=False).count()
    assert cant_novedades == 0

    a.refresh_from_db()
    assert a.identificacion_testigo == i1
    assert a.mesa == m1
    assert a.status == Attachment.STATUS.identificada
示例#3
0
def test_identificacion_problema_troll(db):
    fiscal_troll = nuevo_fiscal()
    fiscal_troll.troll = True
    fiscal_troll.save(update_fields=['troll'])
    fiscal_ok = nuevo_fiscal()

    attach = AttachmentFactory()
    ident_troll = reportar_problema_attachment(attach, fiscal_troll)
    Problema.reportar_problema(fiscal_troll,
                               "foto fea",
                               ReporteDeProblema.TIPOS_DE_PROBLEMA.ilegible,
                               identificacion=ident_troll)
    ident_ok = reportar_problema_attachment(attach, fiscal_ok)
    Problema.reportar_problema(fiscal_ok,
                               "no me gusta",
                               ReporteDeProblema.TIPOS_DE_PROBLEMA.falta_lista,
                               identificacion=ident_ok)

    assert 2 == Problema.objects.count()
    assert 1 == ReporteDeProblema.objects.filter(
        reportado_por=fiscal_troll).count()
    assert 1 == ReporteDeProblema.objects.filter(
        reportado_por=fiscal_ok).count()

    problema_troll = ReporteDeProblema.objects.filter(
        reportado_por=fiscal_troll).first().problema
    assert Problema.ESTADOS.descartado == problema_troll.estado
    problema_ok = ReporteDeProblema.objects.filter(
        reportado_por=fiscal_ok).first().problema
    assert Problema.ESTADOS.potencial == problema_ok.estado
示例#4
0
def test_carga_problema_troll(db):
    fiscal_troll = nuevo_fiscal()
    fiscal_troll.troll = True
    fiscal_troll.save(update_fields=['troll'])
    fiscal_ok = nuevo_fiscal()

    categ = nueva_categoria(["a", "b"])
    mesa = MesaFactory(categorias=[categ])
    mesa_categoria = MesaCategoria.objects.filter(mesa=mesa).first()

    carga_troll = reportar_problema_mesa_categoria(mesa_categoria,
                                                   fiscal_troll)
    Problema.reportar_problema(fiscal_troll,
                               "foto fea",
                               ReporteDeProblema.TIPOS_DE_PROBLEMA.ilegible,
                               carga=carga_troll)
    carga_ok = reportar_problema_mesa_categoria(mesa_categoria, fiscal_ok)
    Problema.reportar_problema(fiscal_ok,
                               "no me gusta",
                               ReporteDeProblema.TIPOS_DE_PROBLEMA.falta_lista,
                               carga=carga_ok)

    assert 2 == Problema.objects.count()
    assert 1 == ReporteDeProblema.objects.filter(
        reportado_por=fiscal_troll).count()
    assert 1 == ReporteDeProblema.objects.filter(
        reportado_por=fiscal_ok).count()

    problema_troll = ReporteDeProblema.objects.filter(
        reportado_por=fiscal_troll).first().problema
    assert Problema.ESTADOS.descartado == problema_troll.estado
    problema_ok = ReporteDeProblema.objects.filter(
        reportado_por=fiscal_ok).first().problema
    assert Problema.ESTADOS.potencial == problema_ok.estado
示例#5
0
    def form_valid(self, form):
        # por algun motivo seguramente espantoso, pasa dos veces por acá
        # una vez desde el POST ajax, y otra luego de la primer redirección
        # meto este hack para que sólo cree el objeto cuando es ajax
        # y en la segunda vuelta sólo redireccion
        if self.request.is_ajax():
            fiscal = self.request.user.fiscal
            # Lo falso grabo para quedarme con la data de sus campos.
            reporte_de_problema = form.save(commit=False)
            tipo_de_problema = reporte_de_problema.tipo_de_problema
            descripcion = reporte_de_problema.descripcion

            # Creo la identificación.
            identificacion = Identificacion.objects.create(
                status=Identificacion.STATUS.problema, fiscal=fiscal, mesa=None, attachment=self.attachment
            )
            # Creo el problema asociado.
            Problema.reportar_problema(fiscal, descripcion, tipo_de_problema, identificacion=identificacion)
            return JsonResponse({'status': 'hack'})
        # acá sólo va a llegar la segunda vez
        messages.info(
            self.request,
            f'Gracias por el reporte. Ahora pasamos a la siguiente acta.',
            extra_tags="problema"
        )
        return redirect('siguiente-accion')
示例#6
0
    def form_valid(self, form):
        # mismo hack que en la misma vista adjuntos.views.ReporteDeProblemaCreateView
        # FIX ME: no tiene tests
        if self.request.is_ajax():
            fiscal = self.request.user.fiscal
            carga = form.save(commit=False)
            carga.fiscal = fiscal
            carga.status = Carga.TIPOS.problema
            # Lo falso grabo para quedarme con la data de sus campos.
            reporte_de_problema = form.save(commit=False)
            tipo_de_problema = reporte_de_problema.tipo_de_problema
            descripcion = reporte_de_problema.descripcion

            # Creo la carga.
            carga = Carga.objects.create(tipo=Carga.TIPOS.problema,
                                         fiscal=fiscal,
                                         origen=Carga.SOURCES.web,
                                         mesa_categoria=self.mesa_categoria)

            # Creo el problema asociado.
            Problema.reportar_problema(fiscal,
                                       descripcion,
                                       tipo_de_problema,
                                       carga=carga)
            return JsonResponse({'status': 'hack'})
        messages.info(
            self.request,
            f'Gracias por el reporte. Ahora pasamos a la siguiente acta.',
            extra_tags="problema")
        return redirect('siguiente-accion')
示例#7
0
def consolidar_cargas_con_problemas(cargas_que_reportan_problemas):

    # Tomo como "muestra" alguna de las que tienen problemas.
    carga_con_problema = cargas_que_reportan_problemas.first()
    # Confirmo el problema porque varios reportaron problemas.
    Problema.confirmar_problema(carga=carga_con_problema)

    return MesaCategoria.STATUS.con_problemas, None
示例#8
0
def test_ciclo_de_vida_problemas_resolver(db):
    a = AttachmentFactory()
    m1 = MesaFactory()
    IdentificacionFactory(attachment=a, status='identificada', mesa=m1)

    # Está pendiente.
    assert a in Attachment.objects.sin_identificar()

    i1 = IdentificacionFactory(attachment=a, status='problema', mesa=None)
    f = FiscalFactory()
    Problema.reportar_problema(f,
                               'reporte 1',
                               ReporteDeProblema.TIPOS_DE_PROBLEMA.spam,
                               identificacion=i1)
    assert i1.problemas.first().problema.estado == Problema.ESTADOS.potencial

    i2 = IdentificacionFactory(attachment=a, status='problema', mesa=None)
    Problema.reportar_problema(f,
                               'reporte 2',
                               ReporteDeProblema.TIPOS_DE_PROBLEMA.ilegible,
                               identificacion=i2)

    assert i1.invalidada == False
    assert i2.invalidada == False

    consumir_novedades_identificacion()

    # Se consolidó un problema.
    a.refresh_from_db()
    assert a.status == Attachment.STATUS.problema
    problema = i1.problemas.first().problema
    assert problema.estado == Problema.ESTADOS.pendiente

    # El attach no está entre los pendientes.
    assert a not in Attachment.objects.sin_identificar()

    problema.resolver(FiscalFactory().user)

    assert problema.estado == Problema.ESTADOS.resuelto

    i1.refresh_from_db()
    i2.refresh_from_db()
    # Las identificaciones están invalidadas.
    assert i1.invalidada == True
    assert i2.invalidada == True

    consumir_novedades_identificacion()

    # Se agrega una nueva identificación y se consolida.
    IdentificacionFactory(attachment=a, status='identificada', mesa=m1)
    consumir_novedades_identificacion()
    a.refresh_from_db()
    assert a.status == Attachment.STATUS.identificada
    assert a.mesa == m1
示例#9
0
def novo_problema(dados_problema):
    """
    Cadastra um novo problema no sistema para ser utilizado
    em testes.
    """
    numero_problemas = Problema.objects.count()
    indice = numero_problemas + 1

    dados_problema.setdefault("titulo", "Título Problema Teste {0}".format(indice))
    dados_problema.setdefault("publicado", True)

    problema = Problema(**dados_problema)
    problema.save()

    return problema
示例#10
0
def novo_problema(dados_problema):
    """
    Cadastra um novo problema no sistema para ser utilizado
    em testes.
    """
    numero_problemas = Problema.objects.count()
    indice = numero_problemas + 1

    dados_problema.setdefault('titulo', "Título Problema Teste {0}".format(indice))
    dados_problema.setdefault('publicado', True)

    problema = Problema(**dados_problema)
    problema.save()

    return problema
示例#11
0
def test_efecto_problema_descartado(db):
    fiscal_1 = nuevo_fiscal()

    a = AttachmentFactory()
    m1 = MesaFactory()
    i1 = IdentificacionFactory(attachment=a, status='problema', mesa=None)
    f = FiscalFactory()
    Problema.reportar_problema(fiscal_1,
                               'reporte 1',
                               ReporteDeProblema.TIPOS_DE_PROBLEMA.spam,
                               identificacion=i1)
    assert i1.problemas.first().problema.estado == Problema.ESTADOS.potencial

    problema = i1.problemas.first().problema
    problema.descartar(nuevo_fiscal().user)

    from constance import config
    assert EventoScoringTroll.objects.filter(fiscal_afectado=fiscal_1).get(
    ).variacion == config.SCORING_TROLL_PROBLEMA_DESCARTADO
示例#12
0
def test_problema_falta_foto(db):
    mc = MesaCategoriaFactory()
    assert mc.status == MesaCategoria.STATUS.sin_cargar
    c1 = CargaFactory(mesa_categoria=mc, tipo='total', firma='1-10')
    consumir_novedades_y_actualizar_objetos([mc])
    assert mc.status == MesaCategoria.STATUS.total_sin_consolidar
    assert mc.carga_testigo == c1

    c2 = CargaFactory(mesa_categoria=mc, tipo='problema')
    Problema.reportar_problema(FiscalFactory(), 'falta foto!',
        ReporteDeProblema.TIPOS_DE_PROBLEMA.falta_foto, carga=c2)
    c3 = CargaFactory(mesa_categoria=mc, tipo='problema')
    Problema.reportar_problema(FiscalFactory(), 'spam!',
        ReporteDeProblema.TIPOS_DE_PROBLEMA.spam, carga=c2)
    consumir_novedades_y_actualizar_objetos([mc])

    # Ahora sí hay un problema.
    assert mc.status == MesaCategoria.STATUS.con_problemas
    assert mc.carga_testigo is None
    problema = c2.problemas.first().problema
    assert problema.estado == Problema.ESTADOS.pendiente

    # Llega un nuevo attachment.
    a = AttachmentFactory()
    mesa = mc.mesa
    # Lo asocio a la misma mesa.
    IdentificacionFactory(attachment=a, status='identificada', mesa=mesa)
    IdentificacionFactory(attachment=a, status='identificada', mesa=mesa)

    consumir_novedades_identificacion()
    consumir_novedades_y_actualizar_objetos([mc])

    # El problema se solucionó.
    problema.refresh_from_db()
    assert problema.estado == Problema.ESTADOS.resuelto

    # La mesa está vigente de nuevo.
    assert mc.status == MesaCategoria.STATUS.total_sin_consolidar
    assert mc.carga_testigo == c1
示例#13
0
def test_carga_con_problemas(db):
    # Identifico una mesa.
    mesa = MesaFactory()
    a = AttachmentFactory()
    IdentificacionFactory(attachment=a, status='identificada', mesa=mesa)
    IdentificacionFactory(attachment=a, status='identificada', mesa=mesa)

    consumir_novedades_identificacion()
    mc = MesaCategoriaFactory(mesa=mesa, categoria=mesa.categorias.first())
    assert mc.status == MesaCategoria.STATUS.sin_cargar
    c1 = CargaFactory(mesa_categoria=mc, tipo='total', firma='1-10')
    consumir_novedades_y_actualizar_objetos([mc])
    assert mc.status == MesaCategoria.STATUS.total_sin_consolidar
    assert mc.carga_testigo == c1

    c2 = CargaFactory(mesa_categoria=mc, tipo='problema')
    Problema.reportar_problema(FiscalFactory(), 'reporte 1',
        ReporteDeProblema.TIPOS_DE_PROBLEMA.spam, carga=c2)
    consumir_novedades_y_actualizar_objetos([mc])

    # Sigue sin ser un problema.
    assert mc.status == MesaCategoria.STATUS.total_sin_consolidar
    assert mc.carga_testigo == c1
    assert c2.problemas.first().problema.estado == Problema.ESTADOS.potencial

    # Está entre las pendientes.
    assert mc in MesaCategoria.objects.con_carga_pendiente()

    c3 = CargaFactory(mesa_categoria=mc, tipo='problema')
    Problema.reportar_problema(FiscalFactory(), 'reporte 2',
        ReporteDeProblema.TIPOS_DE_PROBLEMA.ilegible, carga=c3)
    consumir_novedades_y_actualizar_objetos([mc])

    c2.refresh_from_db()
    c3.refresh_from_db()
    assert c2.invalidada == False
    assert c3.invalidada == False

    # Ahora sí hay un problema.
    assert mc.status == MesaCategoria.STATUS.con_problemas
    assert mc.carga_testigo is None
    problema = c2.problemas.first().problema
    assert problema.estado == Problema.ESTADOS.pendiente

    # No está entre las pendientes.
    assert mc not in MesaCategoria.objects.con_carga_pendiente()

    # Lo resolvemos.
    problema.resolver(FiscalFactory().user)

    assert problema.estado == Problema.ESTADOS.resuelto
    c1.refresh_from_db()
    c2.refresh_from_db()
    c3.refresh_from_db()
    assert c1.invalidada == False
    assert c2.invalidada == True
    assert c3.invalidada == True

    consumir_novedades_y_actualizar_objetos([mc])
    # El problema se solucionó también en la MesaCategoria.
    assert mc.status == MesaCategoria.STATUS.total_sin_consolidar
    assert mc.carga_testigo == c1

    # Está entre las pendientes.
    assert mc in MesaCategoria.objects.con_carga_pendiente()

    # Se mete otra carga y se consolida.
    c4 = CargaFactory(mesa_categoria=mc, tipo='total', firma='1-10')
    consumir_novedades_y_actualizar_objetos([mc])
    assert mc.status == MesaCategoria.STATUS.total_consolidada_dc
    assert mc.carga_testigo == c4 or mc.carga_testigo == c1
示例#14
0
def consolidar_identificaciones(attachment):
    """
    Consolida todas las identificaciones del Attachment parámetro.
    Deja una como testigo, si están dadas las condiciones.
    Si hay una identificación con origen csv, ésa es la testigo.

    En cualquier caso adecúa el estado de identificación del attach parámetro
    y lo asocia a la mesa identificada o a ninguna, si no quedó identificado.
    """

    # Primero me quedo con todas las identificaciones para ese attachment
    # que correspondan con una identificación y no con un problema.
    status_count = attachment.status_count(Identificacion.STATUS.identificada)

    mesa_id_consolidada = None
    for mesa_id, cantidad, cuantos_csv in status_count:
        if (cantidad >= settings.MIN_COINCIDENCIAS_IDENTIFICACION
                or cuantos_csv > 0):
            mesa_id_consolidada = mesa_id
            break

    if mesa_id_consolidada:
        # Consolidamos una mesa, ya sea por CSV o por coincidencia múltiple.

        identificaciones_correctas = attachment.identificaciones.filter(
            mesa_id=mesa_id_consolidada,
            status=Identificacion.STATUS.identificada)

        identificacion_con_csv = identificaciones_correctas.filter(
            source=Identificacion.SOURCES.csv).first()

        # Si hay una de CSV, es la testigo. Si no, cualquiera del resto.
        testigo = identificacion_con_csv if identificacion_con_csv else identificaciones_correctas.first(
        )

        # Identifico el attachment.
        status_attachment = testigo.status
        mesa_attachment = testigo.mesa

        # Si tenía asociado un problema de "falta hoja", se soluciona automáticamente
        # porque se agregó un attachment.
        Problema.resolver_problema_falta_hoja(mesa_attachment)

        # aumentar el scoring de los usuarios que identificaron el acta diferente
        efecto_scoring_troll_asociacion_attachment(attachment, mesa_attachment)

    else:
        status_attachment = Attachment.STATUS.sin_identificar
        mesa_attachment = None
        testigo = None

        # Si no logramos consolidar una identificación vemos si hay un reporte de problemas.
        status_count = attachment.status_count(Identificacion.STATUS.problema)
        for mesa_id, cantidad, cuantos_csv in status_count:
            if cantidad >= settings.MIN_COINCIDENCIAS_IDENTIFICACION_PROBLEMA:
                # Tomo como "muestra" alguna de las que tienen problemas.
                identificacion_con_problemas = attachment.identificaciones.filter(
                    status=Identificacion.STATUS.problema).first()
                # Confirmo el problema porque varios reportaron problemas.
                Problema.confirmar_problema(
                    identificacion=identificacion_con_problemas)
                status_attachment = Attachment.STATUS.problema

    # me acuerdo la mesa anterior por si se esta pasando a sin_identificar
    mesa_anterior = attachment.mesa

    # Identifico el attachment.
    # Notar que esta identificación podría estar sumando al attachment a una mesa que ya tenga.
    # Eso es correcto.
    # También podría estar haciendo pasar una attachment identificado al estado sin_identificar,
    # porque ya no está más vigente alguna identificación que antes sí.
    attachment.status = status_attachment
    attachment.mesa = mesa_attachment
    attachment.identificacion_testigo = testigo
    attachment.save(update_fields=['mesa', 'status', 'identificacion_testigo'])
    logger.info('Consolid. identificación',
                attachment=attachment.id,
                testigo=getattr(testigo, 'id', None),
                status=status_attachment)
    # Si el attachment pasa de tener una mesa a no tenerla, entonces hay que invalidar
    # todo lo que se haya cargado para las MesaCategoria de la mesa que perdió su attachment.
    if mesa_anterior and not mesa_attachment:
        mesa_anterior.invalidar_asignacion_attachment()