def test_importa_contacto(self): # 3543009865,lkasdjlfkaf,0351156219387 # 111534509230,dkasjflkja,0351156982639 # 2830173491,alsdkjfieasdf,3516983419 # 3560127341,kahvuahdsfasdfa,2954638961 bd = BaseDatosContacto(id=1) bd.archivo_importacion = File(open(self.get_test_resource( "planilla-ejemplo-1.csv"), 'r')) bd.nombre_archivo_importacion = "planilla-ejemplo-1.csv" bd.save() metadata = bd.get_metadata() metadata.cantidad_de_columnas = 3 metadata.columna_con_telefono = 0 metadata.columnas_con_telefono = [0, 2] metadata.columna_id_externo = 1 metadata.nombres_de_columnas = ["telefono", "nombre", "celular"] metadata.save() # ----- creacion_base_de_datos_service = CreacionBaseDatosService() creacion_base_de_datos_service.importa_contactos(bd, ["telefono", "celular"], 1) self.assertEqual(bd.contactos.count(), 4) for contacto in bd.contactos.all(): self.assertIsNotNone(contacto.id_externo)
def test_importa_archivo_utf8_correctamente(self): bd = BaseDatosContacto(id=1) bd.archivo_importacion = File(open(self.get_test_resource( "planilla-ejemplo-6.csv"), 'r')) bd.nombre_archivo_importacion = "bd-contactos-utf8.csv" bd.save() # ----- service = CreacionBaseDatosService() service.genera_base_dato_contacto(bd) metadata = bd.get_metadata() metadata.cantidad_de_columnas = 2 metadata.columna_con_telefono = 0 metadata.columnas_con_telefono = [0] metadata.nombres_de_columnas = ["telefono", "Nombre"] metadata.primer_fila_es_encabezado = True metadata.save() service.importa_contactos(bd, ['telefono'], None) self.assertEquals(Contacto.objects.count(), 2) contactos = list(Contacto.objects.all()) contactos_dict = dict([(c.telefono, c.datos) for c in contactos]) self.assertIn('375849371648', contactos_dict) self.assertIn('957327493493', contactos_dict)
def test_genera_base_datos_falla_archivo_xls(self): bd = BaseDatosContacto(id=1) bd.nombre_archivo_importacion = "planilla-ejemplo-0.xls" bd.save() # ----- creacion_base_de_datos_service = CreacionBaseDatosService() with self.assertRaises(OmlArchivoImportacionInvalidoError): creacion_base_de_datos_service.genera_base_dato_contacto(bd)
def test_define_base_dato_contacto(self): bd = BaseDatosContacto(id=1) bd.save() # ----- creacion_base_de_datos_service = CreacionBaseDatosService() creacion_base_de_datos_service.define_base_dato_contacto(bd) self.assertEqual(bd.estado, BaseDatosContacto.ESTADO_DEFINIDA)
def test_con_demas_planillas_de_ejemplo(self): PLANILLAS = ( "planilla-ejemplo-1.csv", "planilla-ejemplo-2.csv", "planilla-ejemplo-7-celdas-vacias.csv", "planilla-ejemplo-8-ultima-celda-vacia.csv", ) for planilla in PLANILLAS: logger.debug("Procesando planilla %s", planilla) bd_contacto = BaseDatosContacto.objects.create( nombre="base-datos-contactos-{0}".format(planilla), archivo_importacion=self.copy_test_resource_to_mediaroot( planilla), nombre_archivo_importacion=planilla) parser = ParserCsv() estructura_archivo = parser.previsualiza_archivo(bd_contacto) predictor_metadata = PredictorMetadataService() metadata_inferida = predictor_metadata.inferir_metadata_desde_lineas( estructura_archivo) metadata = bd_contacto.get_metadata() metadata._metadata = metadata_inferida._metadata metadata.nombres_de_columnas = [ "COL{0}".format(num) for num in range(metadata.cantidad_de_columnas) ] metadata.save() creacion_base_datos_service = CreacionBaseDatosService() creacion_base_datos_service.importa_contactos( bd_contacto, ["Telefono"], None) creacion_base_datos_service.define_base_dato_contacto(bd_contacto) # ----- checks self.assertEquals( BaseDatosContacto.objects.get(pk=bd_contacto.id).estado, BaseDatosContacto.ESTADO_DEFINIDA, "La BD generada desde '{0}' NO ha quedado en estado ESTADO_DEFINIDA" "".format(planilla)) self.assertTrue( Contacto.objects.filter(bd_contacto=bd_contacto.id).count() > 0, "La BD generada desde '{0}' NO posee contactos".format( planilla))
def test_con_planilla_ejemplo_3(self): bd_contacto = BaseDatosContacto.objects.create( nombre="base-datos-contactos", archivo_importacion=self.copy_test_resource_to_mediaroot( "planilla-ejemplo-3-headers-con-no-ascii-y-espacios.csv"), nombre_archivo_importacion= 'planilla-ejemplo-3-headers-con-no-ascii-y-espacios.csv') parser = ParserCsv() estructura_archivo = parser.previsualiza_archivo(bd_contacto) predictor_metadata = PredictorMetadataService() metadata_inferida = predictor_metadata.inferir_metadata_desde_lineas( estructura_archivo) metadata = bd_contacto.get_metadata() metadata._metadata = metadata_inferida._metadata metadata.nombres_de_columnas = ["Telefono", "NOMBRE", "FECHA", "HORA"] metadata.columna_con_telefono = 0 metadata.columnas_con_telefono = [0] metadata.save() creacion_base_datos_service = CreacionBaseDatosService() creacion_base_datos_service.importa_contactos(bd_contacto, ["Telefono"], None) creacion_base_datos_service.define_base_dato_contacto(bd_contacto) # ----- checks self.assertEquals( BaseDatosContacto.objects.get(pk=bd_contacto.id).estado, BaseDatosContacto.ESTADO_DEFINIDA, "La BD no ha quedado en estado ESTADO_DEFINIDA") nros_telefono = [ contacto.telefono for contacto in Contacto.objects.filter(bd_contacto=bd_contacto.id) ] self.assertEquals(len(nros_telefono), 3, "Deberia haber 3 contactos") self.assertEquals( set(nros_telefono), set(['354303459865', '111534509230', '283453013491']), "Deberia haber 3 contactos")
def form_valid(self, form): self.object = form.save(commit=False) self.object.estado = BaseDatosContacto.ESTADO_DEFINIDA_ACTUALIZADA # self.object.nombre_archivo_importacion = nombre_archivo_importacion try: creacion_base_datos = CreacionBaseDatosService() creacion_base_datos.genera_base_dato_contacto(self.object) except OmlArchivoImportacionInvalidoError: message = _('<strong>Operación Errónea!</strong> ') + \ _('El archivo especificado para realizar la importación de contactos ' 'no es válido.') messages.add_message( self.request, messages.ERROR, message, ) return self.form_invalid(form) return redirect(self.get_success_url())
def form_valid(self, estructura_archivo, form_primer_linea_encabezado): cantidad_columnas = len(estructura_archivo[0]) lista_columnas_encabezado = estructura_archivo[0] error = None metadata = self.object.get_metadata() metadata.cantidad_de_columnas = cantidad_columnas for columna_base, columna_csv in zip(metadata.nombres_de_columnas, lista_columnas_encabezado): if str(columna_base).capitalize() != str(columna_csv).capitalize(): error = _("El nombre de la columna debe ser {0} en vez de {1}". format(columna_base, columna_csv)) if error: return self.form_invalid(estructura_archivo, form_primer_linea_encabezado, error=error) es_encabezado = False if self.request.POST.get('es_encabezado', False): es_encabezado = True metadata.primer_fila_es_encabezado = es_encabezado metadata.save() creacion_base_datos = CreacionBaseDatosService() try: # creacion_base_datos.valida_contactos(self.object) bd_metadata = self.object.get_metadata() columnas_con_telefono = bd_metadata.nombres_de_columnas_de_telefonos columna_id_externo = bd_metadata.columna_id_externo creacion_base_datos.importa_contactos(self.object, columnas_con_telefono, columna_id_externo) except CreacionBaseDatosServiceIdExternoError as e: message = _('<strong>Operación Errónea!</strong> ') +\ _('El archivo que seleccionó posee contactos con identificadores externos ' 'repetidos.<br> ' '<u>Línea Inválida:</u> {0}<br> <u>Contenido Línea:</u>' ' {1}<br><u>ID repetido:</u> {2}').format( e.numero_fila, e.fila, e.valor_celda) messages.add_message( self.request, messages.ERROR, message, ) return self.render_to_response( self.get_context_data( estructura_archivo=estructura_archivo, form_primer_linea_encabezado=form_primer_linea_encabezado)) except OmlParserCsvImportacionError as e: message = _('<strong>Operación Errónea!</strong> ') +\ _('El archivo que seleccionó posee registros inválidos.<br> ' '<u>Línea Inválida:</u> {0}<br> <u>Contenido Línea:</u>' '{1}<br><u>Contenido Inválido:</u> {2}').format( e.numero_fila, e.fila, e.valor_celda) messages.add_message( self.request, messages.ERROR, message, ) return self.render_to_response( self.get_context_data( estructura_archivo=estructura_archivo, form_primer_linea_encabezado=form_primer_linea_encabezado)) except ContactoExistenteError as e: message = _('<strong>¡Operación Errónea!</strong> ') +\ _('El archivo que seleccionó posee registros inválidos.<br> ' 'ERROR: {0}. Vuelva a cargar nuevamente la base de datos ' 'sin el contacto existente ').format(e) messages.add_message( self.request, messages.ERROR, message, ) return self.render_to_response( self.get_context_data( estructura_archivo=estructura_archivo, form_primer_linea_encabezado=form_primer_linea_encabezado)) except OmlParserMaxRowError: message = _('<strong>Operación Errónea!</strong> ') +\ _('El archivo que seleccionó posee más registros de los ' 'permitidos para ser importados.') messages.add_message( self.request, messages.ERROR, message, ) return redirect(reverse('lista_base_datos_contacto')) else: message = _('<strong>Operación Exitosa!</strong> ') +\ _('Se llevó a cabo con éxito la creación de la Base de Datos de Contactos.') messages.add_message( self.request, messages.SUCCESS, message, ) # En caso de que sea agregar a una campaña preview, genero los AgenteEnContacto # para los contactos nuevos. if self.campana is not None and self.campana.type == Campana.TYPE_PREVIEW: self._generar_relaciones_agente_en_contacto() return redirect(self.get_success_url())
def form_valid(self, estructura_archivo, form_primer_linea_encabezado, form_campos_telefonicos): # columna_con_telefono = int(form_columna_telefono.cleaned_data.get( # 'telefono', None)) # cantidad_columnas = len(form_nombre_columnas.fields) cantidad_columnas = len(estructura_archivo[0]) # for numero_columna in range(cantidad_columnas): # dato_extra = form_datos_extras.cleaned_data.get( # 'datos-extras-{0}'.format(numero_columna), None) # if dato_extra == BaseDatosContacto.DATO_EXTRA_FECHA: # lista_columnas_fechas.append(numero_columna) # elif dato_extra == BaseDatosContacto.DATO_EXTRA_HORA: # lista_columnas_horas.append(numero_columna) # # nombre_columna = form_nombre_columnas.cleaned_data.get( # 'nombre-columna-{0}'.format(numero_columna), None) # # validador_nombre = ValidadorDeNombreDeCampoExtra() # if not validador_nombre.validar_nombre_de_columna(nombre_columna): # error = 'El nombre de la Columna{0} no es válido. Debe estar \ # en mayúscula y sin espacios. Por ejemplo: \ # TELEFONO_FIJO'.format(numero_columna) # # return self.form_invalid(estructura_archivo, # #form_columna_telefono, # #form_datos_extras, # #form_nombre_columnas, # form_primer_linea_encabezado, # error=error) # # lista_nombre_columnas.append(nombre_columna) # error = None # lista_columnas_encabezado = estructura_archivo[0] # if lista_columnas_encabezado[0] != 'telefono': # error = _("El nombre de la primera columna debe ser telefono") # if error: # return self.form_invalid(estructura_archivo, # form_primer_linea_encabezado, # form_campos_telefonicos, error=error) parser = ParserCsv() # Detecto el encondig de la base de datoss recientemente subida encoding = parser.detectar_encoding_csv(estructura_archivo) metadata = self.object.get_metadata() metadata.cantidad_de_columnas = cantidad_columnas # predictor_metadata = PredictorMetadataService() # columnas_con_telefonos = predictor_metadata.inferir_columnas_telefono( # estructura_archivo[1:], encoding) campos_telefonicos = form_campos_telefonicos.cleaned_data.get( 'campos_telefonicos') columnas_con_telefono = form_campos_telefonicos.columnas_de_telefonos metadata.columnas_con_telefono = columnas_con_telefono columna_id_externo = form_campos_telefonicos.columna_id_externo if columna_id_externo is not None: metadata.columna_id_externo = columna_id_externo metadata.nombres_de_columnas = [ value.decode(encoding) for value in estructura_archivo[0] ] es_encabezado = False if self.request.POST.get('es_encabezado', False): es_encabezado = True metadata.primer_fila_es_encabezado = es_encabezado metadata.save() creacion_base_datos = CreacionBaseDatosService() try: # creacion_base_datos.valida_contactos(self.object) creacion_base_datos.importa_contactos(self.object, campos_telefonicos, columna_id_externo) except CreacionBaseDatosServiceIdExternoError as e: message = _('<strong>Operación Errónea!</strong> ') +\ _('El archivo que seleccionó posee contactos con identificadores externos ' 'repetidos.<br> ' '<u>Línea Inválida:</u> {0}<br> <u>Contenido Línea:</u>' ' {1}<br><u>ID repetido:</u> {2}').format( e.numero_fila, e.fila, e.valor_celda) messages.add_message( self.request, messages.ERROR, message, ) return self.render_to_response( self.get_context_data( estructura_archivo=estructura_archivo, form_primer_linea_encabezado=form_primer_linea_encabezado)) except OmlParserCsvImportacionError as e: message = _('<strong>Operación Errónea!</strong> ') +\ _('El archivo que seleccionó posee registros inválidos.<br> ' '<u>Línea Inválida:</u> {0}<br> <u>Contenido Línea:</u>' '{1}<br><u>Contenido Inválido:</u> {2}').format( e.numero_fila, e.fila, e.valor_celda) messages.add_message( self.request, messages.ERROR, message, ) # FIXME: Ver bien que hacer acá. except ContactoExistenteError as e: message = _('<strong>Operación Errónea!</strong> ') +\ _('El archivo que seleccionó posee registros inválidos.<br> ' 'ERROR: {0}. Vuelva a cargar nuevamente la base de datos ' 'sin el contacto existente ').format(e) messages.add_message( self.request, messages.ERROR, message, ) return self.render_to_response( self.get_context_data( estructura_archivo=estructura_archivo, form_primer_linea_encabezado=form_primer_linea_encabezado, form_campos_telefonicos=form_campos_telefonicos)) except OmlParserMaxRowError: message = _('<strong>Operación Errónea!</strong> ') +\ _('El archivo que seleccionó posee más registros de los ' 'permitidos para ser importados.') messages.add_message( self.request, messages.ERROR, message, ) return redirect(reverse('lista_base_datos_contacto')) else: creacion_base_datos.define_base_dato_contacto(self.object) message = _('<strong>Operación Exitosa!</strong> ') +\ _('Se llevó a cabo con éxito la creación de ' 'la Base de Datos de Contactos.') messages.add_message( self.request, messages.SUCCESS, message, ) return redirect(self.get_success_url())