コード例 #1
0
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()

        estructura_archivo = self.obtiene_previsualizacion_archivo(self.object)
        if estructura_archivo:
            parser = ParserCsv()
            encoding = parser.detectar_encoding_csv(estructura_archivo)
            estructura_archivo_transformada = parser.visualizar_estructura_template(
                estructura_archivo, encoding)

            try:
                error_predictor = False
                error_predictor_encabezado = False

                predictor_metadata = PredictorMetadataService()
                metadata = predictor_metadata.inferir_metadata_desde_lineas(
                    estructura_archivo, encoding)
            except NoSePuedeInferirMetadataError:
                initial_predecido_datos_extras = {}
                initial_predecido_encabezado = {}
                error_predictor = True
            except NoSePuedeInferirMetadataErrorEncabezado:
                initial_predecido_datos_extras = {}
                initial_predecido_encabezado = {}

                error_predictor_encabezado = True
            else:
                initial_predecido_datos_extras = dict([
                    ('datos-extras-{0}'.format(col),
                     BaseDatosContacto.DATO_EXTRA_FECHA)
                    for col in metadata.columnas_con_fecha
                ])

                initial_predecido_datos_extras.update(
                    dict([('datos-extras-{0}'.format(col),
                           BaseDatosContacto.DATO_EXTRA_HORA)
                          for col in metadata.columnas_con_hora]))

                initial_predecido_encabezado = {
                    'es_encabezado': metadata.primer_fila_es_encabezado
                }

            form_primer_linea_encabezado = PrimerLineaEncabezadoForm(
                initial=initial_predecido_encabezado)
            form_campos_telefonicos = CamposDeBaseDeDatosForm(
                nombres_campos=estructura_archivo[0])

            return self.render_to_response(
                self.get_context_data(
                    error_predictor_encabezado=error_predictor_encabezado,
                    error_predictor=error_predictor,
                    estructura_archivo=estructura_archivo_transformada,
                    form_primer_linea_encabezado=form_primer_linea_encabezado,
                    form_campos_telefonicos=form_campos_telefonicos))

        return redirect(reverse('nueva_base_datos_contacto'))
コード例 #2
0
    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())
コード例 #3
0
    def importa_contactos(self, base_datos_contacto, campos_telefonicos,
                          columna_id_externo):
        """
        Tercer paso de la creación de una BaseDatosContacto.
        Este método se encarga de generar los objectos Contacto por cada linea
        del archivo de importación especificado para la base de datos de
        contactos.
        """
        assert (base_datos_contacto.estado
                in (BaseDatosContacto.ESTADO_EN_DEFINICION,
                    BaseDatosContacto.ESTADO_DEFINIDA_ACTUALIZADA))

        # FIXME: este metodo valida la consistencia de los metadatos, y
        # lanza una excepcion ante cualquier problema. OJO! Esto no implica
        # que los metadatos sean correctos y consistentes con los datos,
        # pero al menos validan la consistencia "interna" de los metadatos
        # metadata = base_datos_contacto.get_metadata()
        # metadata.validar_metadatos()

        # Antes que nada, borramos los contactos preexistentes
        # base_datos_contacto.elimina_contactos()

        parser = ParserCsv()

        ids_externos = base_datos_contacto.contactos.values_list('id_externo',
                                                                 flat=True)
        ids_externos = set(ids_externos)
        ids_nuevos_contactos = []

        try:
            estructura_archivo = parser.get_estructura_archivo(
                base_datos_contacto)
            posicion_primer_telefono = estructura_archivo[0].index(
                campos_telefonicos[0])
            encoding = parser.detectar_encoding_csv(estructura_archivo)
            cantidad_contactos = 0

            if base_datos_contacto.cantidad_contactos:
                cantidad_contactos = base_datos_contacto.cantidad_contactos
            numero_fila = 0
            for lista_dato in estructura_archivo[1:]:
                numero_fila += 1
                telefono, datos, id_externo = self.obtener_telefono_y_datos(
                    encoding, lista_dato, posicion_primer_telefono,
                    columna_id_externo)
                cantidad_contactos += 1

                if id_externo is not None and id_externo != '':
                    # El id_externo no puede estar repetido
                    if id_externo in ids_externos:
                        base_datos_contacto.contactos.filter(
                            id__in=ids_nuevos_contactos).delete()
                        raise (CreacionBaseDatosServiceIdExternoError(
                            numero_fila, columna_id_externo, lista_dato,
                            id_externo))
                    else:
                        ids_externos.add(id_externo)

                contacto = Contacto.objects.create(
                    telefono=telefono,
                    datos=datos,
                    bd_contacto=base_datos_contacto,
                    id_externo=id_externo)
                ids_nuevos_contactos.append(contacto.id)

        except OmlParserMaxRowError:
            base_datos_contacto.contactos.filter(
                id__in=ids_nuevos_contactos).delete()
            raise

        except OmlParserCsvImportacionError:
            base_datos_contacto.contactos.filter(
                id__in=ids_nuevos_contactos).delete()
            raise

        base_datos_contacto.cantidad_contactos = cantidad_contactos
        base_datos_contacto.save()