def pasar_presufi(s): """ Detecta en la cadena «s» la posible aparición del año y devuelve la misma cadena pero con todos los números (completos, no sus cifras por separado) que encuentre incrementados en uno. """ def agregar(c, l): """ Si «c» es del mismo tipo que los caracteres del último grupo de «l» devuelve True. """ if len(l) and len(l[-1]): if l[-1][-1].isalpha() and c.isalpha(): return True if l[-1][-1].isdigit() and c.isdigit(): return True return False # Primero separo letras y números. letras_nums = [] for c in s: if agregar(c, letras_nums): letras_nums[-1].append(c) else: letras_nums.append([c]) # Ahora intento pasar año: res = "" for grupo_de_letras_o_nums in letras_nums: palabraca = "".join(grupo_de_letras_o_nums) numeraco = utils.parse_numero(palabraca) if isinstance(numeraco, int): numeraco += 1 palabraca = `numeraco` res += palabraca return res
def add_partida_gtx(self, boton): """ Busca o crea una partida de geotextiles y la asocia con la de carga. """ numpartida = utils.dialogo_entrada( titulo="NÚMERO DE PARTIDA DE GEOTEXTILES", texto="Introduzca el número de partida de geotextiles", padre=self.wids['ventana']) if numpartida is not None: numpartida = numpartida.upper().strip().replace("P-", "") numpartida = utils.parse_numero(numpartida) if numpartida is None: encontradas = 0 else: partida = pclases.Partida.select( pclases.Partida.q.numpartida == numpartida) try: encontradas = partida.count() except AttributeError: encontradas = 0 if encontradas == 1: partida = partida[0] if partida.partidaCargaID is not None: if utils.dialogo(titulo="PARTIDA USADA", texto="La partida de geotextiles %s ya se agregó " "a la partida de carga %s.\n" "¿Desea cambiarla a la actual?" % ( partida.codigo, partida.partidaCarga.codigo), padre=self.wids['ventana']): partida.partidaCarga = self.objeto else: partida.partidaCarga = self.objeto elif encontradas == 0: try: numpartida = int(numpartida) except (TypeError, ValueError): utils.dialogo_info( titulo="ERROR NÚMERO DE PARTIDA", texto="El número de partida %s no es " "correcto." % (numpartida), padre=self.wids['ventana']) return partida = pclases.Partida(numpartida=numpartida, codigo="P-%s" % (numpartida), partidaCarga=self.objeto) pclases.Auditoria.nuevo(partida, self.usuario, __file__) else: self.logger.error("consumo_balas_partida.py::add_partida_gtx" " -> Encontrada más de una partida con el " "mismo número. NO DEBERÍA OCURRIR.") self.actualizar_ventana()
def editar_entero_tv(w, clase, campo, text, path, col): try: numero = utils.parse_numero(text) if numero == None: raise ValueError except (ValueError, TypeError): utils.dialogo_info(titulo = "ERROR DE FORMATO", texto = "El texto %s no es un número entero." % text) else: model = w.get_model() o = clase.get(model[path][-1]) setattr(o, campo, numero) model[path][col] = getattr(o, campo)
def formaDePago(self): """ Devuelve la forma de pago de la base de datos que se corresponde con la información de la forma de pago del cliente, que se encuentra dividida en varios atributos. Si no la encuentra, devuelve None. """ plazo = utils.parse_numero(self.formadepago) docu = self.get_documentoDePago() fdps = FormaDePago.select(AND(FormaDePago.q.activa == True, FormaDePago.q.plazo == plazo, FormaDePago.q.documentoDePago == docu), orderBy = "id") try: fdp = fdps[0] except IndexError: fdp = None return fdp
def edit_int(cell, path, newtext, tv, numcol, clase, atributo): """ Cambia el texto del model[path][numcol] y del objeto relacionado que saca a partir del ID de la última columna del model. """ try: numero = utils.parse_numero(newtext) except (ValueError, TypeError): parent = tv.parent while parent != None: parent = parent.parent utils.dialogo_info(titulo = "ERROR EN NÚMERO", texto = "El texto «%s» no es un número entero válido." % (newtext), padre = parent) else: model = tv.get_model() ide = model[path][-1] objeto = clase.get(ide) setattr(objeto, atributo, numero) objeto.syncUpdate() model[path][numcol] = getattr(objeto, atributo)
def set_loteCem(self, w): comprobar_y_preguntar_si_guardar(self) codlote = utils.dialogo_entrada(titulo = 'Nº LOTE', texto = 'Introduzca número o código de lote de fibra ' 'de cemento:', padre = self.wids['ventana']) if codlote != None: numlote = utils.parse_numero(codlote) loteCems = pclases.LoteCem.select(pclases.OR( pclases.LoteCem.q.numlote == numlote, pclases.LoteCem.q.codigo.contains(codlote))) if loteCems.count() == 0: utils.dialogo_info(titulo = 'LOTE NO ENCONTRADO', texto = 'No se encontró ningún lote de fibra de cemento' ' %s.' % (codlote), padre = self.wids['ventana']) return elif loteCems.count() > 1: filas = [(l.id, l.numlote, l.codigo, l.tenacidad, l.elongacion, l.humedad, l.encogimiento) for l in loteCems] idloteCem = utils.dialogo_resultado(filas, titulo = 'SELECCIONE LOTE', cabeceras = ('ID', 'Número', 'Código', 'Tenacidad', 'Elongación', 'Humedad', 'Encogimiento'), padre = self.wids['ventana']) if idloteCem < 0: return loteCem = pclases.LoteCem.get(idloteCem) else: loteCem = loteCems[0] if len(loteCem.bigbags) == 0: utils.dialogo_info(titulo = 'LOTE VACÍO', texto = 'El lote de cemento no contiene bigbags, no ' 'puede\nrealizar pruebas sobre un lote vacío.', padre = self.wids['ventana']) self.loteCem = None return self.loteCem = loteCem self.actualizar_ventana()
def etiqueta_rollos_norma13(rollos, mostrar_marcado=True, lang="es"): """ Construye una etiqueta por cada objeto rollo recibido y las devuelve en un solo PDF. Si lang = "en", etiqueta en inglés. Si "es", en castellano. """ # Voy a tratar de reescribir esto regla en mano a ver si consigo # cuadrarlo bien en la etiquetadora GEMINI. alto = 12.55 * cm ancho = 8.4 * cm # Creo la hoja nomarchivo = os.path.join(gettempdir(), "etiq_norma13_{}_{}.pdf".format( lang, give_me_the_name_baby())) canvas = reportlabcanvas.Canvas(nomarchivo, pagesize=(ancho, alto)) # Medidas: logo = (3.8 * cm * 0.75, 2.8 * cm * 0.75) margen = 0.1 * cm marcado = (((ancho - logo[0]) / 2) - margen, (alto - margen - logo[1] - 2)) # Imágenes: logo_marcado = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", "imagenes", "CE.png")) # Datos fijos: # pylint: disable=bad-continuation _data = {# "00 logo_marcado": None, "01 texto_marcado": "1035", # Fijo "02 fabricado_por": "Fabricado por: %s", "03 direccion1": None, "04 direccion2": None, "05 telefono": "Tfno: %s, %s", "06 año_certif": None, "07 blanco1": "", # Separador "08 dni": None, # "09 iso1": "De EN13249:2001 a EN13257:2001", # Fijo # "10 iso2": "EN13265:2001", # Fijo # La norma ha cambiado. Ahora nos regimos por la del 2014 "09 iso1": "De EN13249:2014 a EN13257:2014", # Fijo "10 iso2": "EN13265:2014", # Fijo "11 blanco2": "", # Separador "12 producto": None, "13 descripcion": "Geotextil no tejido de polipropileno 100% virgen", "14 uso": "Uso: %s", "15 blanco3": "", # Separador "16 codigo": "Partida: %d Rollo: %s", "17 caracteristicas": "Gramaje: %d g/m² Ancho: %s m Largo: %d m" } if lang == "en": for k in _data: _data[k] = helene_laanest(_data[k]) estilos = defaultdict(lambda: ("Helvetica", 9)) # Helvética a 9 por defecto estilos["02 fabricado_por"] = ("Helvetica-Bold", 11) estilos["12 producto"] = ("Helvetica-Bold", 17) estilos["16 codigo"] = ("Helvetica-Bold", 17) estilos["17 caracteristicas"] = ("Helvetica-Bold", 13) data = {} # Datos de la BD dependientes del rollo for rollo in rollos: # 0.- ¿En qué formato viene? Si es el antiguo (datos en diccionario) # me quedo con el objeto de pclases en sí. if isinstance(rollo, dict): try: producto_venta = rollo['productoVenta'] except KeyError: # Si no me lo mandan en el diccionario, tiene que traer # el objeto rollo. Los partes mandan producto en dicccionario # porque a veces se genera etiqueta antes de crear el objeto # en la BD. Si viene de la consulta del listado de rollos, # como el rollo ya existe, me viene en el objeto toda la info. producto_venta = rollo['objeto'].productoVenta numpartida = utils.parse_numero(rollo['partida']) numrollo = rollo['nrollo'] barcode39 = rollo['codigo39'] else: producto_venta = rollo.productoVenta numpartida = rollo.partida.numpartida numrollo = rollo.numrollo barcode39 = rollo.codigo # 1.- Empresa try: # Si hay distribuidor, este texto cambia. distribuidor = producto_venta.camposEspecificosRollo.cliente if distribuidor: if lang == "en": data["02 fabricado_por"] = helene_laanest( "%s") % (distribuidor.nombre) else: data["02 fabricado_por"] = "%s" % ( distribuidor.nombre) dird = distribuidor.get_direccion_completa() dircompleta = textwrap.wrap(dird, (len(dird) + max([len(w) for w in dird.split()])) / 2) data["03 direccion1"] = dircompleta[0] data["04 direccion2"] = dircompleta[1] data["05 telefono"] = _data["05 telefono"] % ( distribuidor.telefono, distribuidor.email) else: # Sigo con los datos de "propia empresa". Distribuyo yo. empresa = pclases.DatosDeLaEmpresa.select()[0] data["02 fabricado_por"] = _data["02 fabricado_por"] % ( empresa.nombre) data["03 direccion1"] = empresa.direccion + ", " + empresa.cp data["04 direccion2"] = ", ".join((empresa.ciudad, empresa.provincia, empresa.pais)) data["05 telefono"] = _data["05 telefono"] % (empresa.telefono, empresa.email) # Para los clientes sin teléfono o sin email: data["05 telefono"] = data["05 telefono"].strip() if data["05 telefono"].startswith(","): data["05 telefono"] = data["05 telefono"][1:] if data["05 telefono"].endswith(","): data["05 telefono"] = data["05 telefono"][:-1] if len(data["05 telefono"]) <= 7: data["05 telefono"] = "" except IndexError: data["02 fabricado_por"] = "" data["03 direccion1"] = "" data["04 direccion2"] = "" data["05 telefono"] = "" # 2.- Producto producto = producto_venta if producto.annoCertificacion != None: data["06 año_certif"] = "%02d" % producto.annoCertificacion else: data["06 año_certif"] = "" data["08 dni"] = producto.dni if len(producto.nombre) <= 50: data["12 producto"] = producto.nombre else: #if "//" in producto.nombre: # Productos Intermas # data["11 blanco2"], data["12 producto"] = producto.nombre.split("//") #else: data["11 blanco2"], data["12 producto"] = utils.dividir_cadena( producto.nombre) data["11 blanco2"] = data["11 blanco2"].strip() data["12 producto"] = data["12 producto"].strip() estilos["11 blanco2"] = estilos["12 producto"] if producto.uso: if lang == "en": data["14 uso"] = _data["14 uso"] % helene_laanest(producto.uso) else: data["14 uso"] = _data["14 uso"] % producto.uso else: data["14 uso"] = "" # 3.- Rollo data["16 codigo"] = _data["16 codigo"] % (numpartida, numrollo) data["17 caracteristicas"] = _data["17 caracteristicas"] % ( producto.camposEspecificosRollo.gramos, float2str(producto.camposEspecificosRollo.ancho, autodec=True, separador_decimales="."), producto.camposEspecificosRollo.metrosLineales) rectangulo(canvas, (margen, margen), (ancho - margen, alto - margen)) if mostrar_marcado: canvas.drawImage(logo_marcado, marcado[0], marcado[1], width=logo[0], height=logo[1]) else: data["01 texto_marcado"] = "" lineas = _data.keys() lineas.sort() # Posición y estilo de la primera línea. tamfuente = estilos[lineas[0]][1] crd_y = alto - logo[1] - 0.1 * cm - tamfuente # ¿Cuánto me desplazaré de línea a línea? offset_y = (crd_y - margen) / (len(lineas) + 3) # 3 líneas para barcode for linea in lineas: try: dato = data[linea] except KeyError: # Si no está en los valores asignados, busco # en los originales. Deben ser datos fijos. dato = _data[linea] if dato is None: dato = "" canvas.setFont(*estilos[linea]) #canvas.drawCentredString((ancho / 2), # crd_y, # escribe(dato)) el_encogedor_de_fuentes_de_doraemon(canvas, fuente=estilos[linea][0], tamannoini=estilos[linea][1], xini=margen, xfin=ancho - margen, y=crd_y, texto=dato, alineacion=0) crd_y -= offset_y # Lo último: el código de barras: ####################################################################### canvas.saveState() crd_y -= 2*offset_y crd_y -= 0.2*cm codigo_rollo = barcode39 codigobarras = Extended39(codigo_rollo, xdim=.065*cm) codigobarras.drawOn(canvas, margen-0.5*cm, crd_y) xcode = ancho / 2.0 ycode = 0.15*cm canvas.setFont("Courier-Bold", 9) try: canvas.drawCentredString(xcode, ycode, codigo_rollo, charSpace=0.25*cm) except TypeError: # Versión antigua de ReportLab. canvas.drawCentredString(xcode, ycode, codigo_rollo) canvas.restoreState() # Y el QR de regalo # # De momento lo desactivo porque nuestras pistolas no lo reconocen. #try: # from lib.pyqrcode import pyqrcode # bidicode = pyqrcode.create(codigo_rollo) # nomfichbidi = os.path.join(gettempdir(), # "bidi_%s.svg" % give_me_the_name_baby()) # bidicode.svg(nomfichbidi, scale=3) # from lib.svglib.svglib import svglib # drawing = svglib.svg2rlg(nomfichbidi) # drawing.drawOn(canvas, margen - 0.25*cm, alto - margen - 3.0*cm + 0.25*cm) #except ImportError: # pass # No hay bidi porque no hay lxml instalado. Probablemente. # print("No se generará código QR. Puede intentar lo siguiente:") # print("C:\Python27\Scripts\easy_install.exe pip") # print('pip install "D:\Informatica\Software\softwin python 2.7' # '\lxml-3.7.2-cp27-cp27m-win32.whl"') ####################################################################### canvas.showPage() # Y ahora la etiqueta adicional por si se pierde la otra y para cargar. create_etiqueta_backup(canvas, rollo) canvas.showPage() canvas.save() return nomarchivo
def guardar(self, widget): """ Guarda el contenido de los entry y demás widgets de entrada de datos en el objeto y lo sincroniza con la BD. """ producto = self.objeto codigo = self.wids['e_codigo'].get_text() if len(codigo) < 12: utils.dialogo_info(titulo = "CÓDIGO DEMASIADO CORTO", texto = "El código debe tener 13 dígitos para ajustarse al formato EAN-13.\nSe va a completar con ceros.", padre = self.wids['ventana']) codigo += "0" * (12 - len(codigo)) # Completo hasta 12 para que después se le haga la suma de control. if len(codigo) == 12: codigo = codigo + self.calcular_digitoc(codigo) if len(codigo) > 13: utils.dialogo_info(titulo = "CÓDIGO INCORRECTO", texto = "Código EAN-13 incorrecto. Debe tener exactamente 13 dígitos.\nPuede introducir 12 y dejar que se calcule atomáticamente el dígito de control, si le es más cómodo.\n\nA continuación se va a recortar el código a 13 dígitos y se intentará comprobar la suma de control.", padre = self.wids['ventana']) codigo = codigo[:13] if len(codigo) == 13: digitocontrol = self.calcular_digitoc(codigo[:12]) if codigo[12] != digitocontrol: utils.dialogo_info(titulo = "FALLÓ SUMA DE COMPROBACIÓN", texto = "El dígito de control no es correct" "o. Se corregirá automáticamente.", padre = self.wids['ventana']) codigo = codigo[:12] + digitocontrol descripcion = self.wids['e_descripcion'].get_text() linea = pclases.LineaDeProduccion.select( pclases.LineaDeProduccion.q.nombre.contains('fibra'))[0] lineaembol = pclases.LineaDeProduccion.select( pclases.LineaDeProduccion.q.nombre.contains('bolsa'))[0] nombre = self.wids['e_nombre'].get_text() arancel = self.wids['e_arancel'].get_text() try: precio = utils.parse_float(self.wids['e_precio'].get_text().replace(',','.')) except ValueError: precio = producto.preciopordefecto try: minimo = utils.parse_float(self.wids['e_minimo'].get_text()) except ValueError: minimo = producto.minimo try: dtex = utils.parse_float(self.wids['e_dtex'].get_text()) except ValueError: dtex = producto.camposEspecificosBala.dtex try: corte = int(self.wids['e_corte'].get_text()) except ValueError: dtex = producto.camposEspecificosBala.dtex gramosBolsa = utils.parse_numero(self.wids['e_gramosBolsa'].get_text()) producto.camposEspecificosBala.gramosBolsa = gramosBolsa bolsasCaja = utils.parse_numero(self.wids['e_bolsasCaja'].get_text()) producto.camposEspecificosBala.bolsasCaja = bolsasCaja cajasPale = utils.parse_numero(self.wids['e_cajasPale'].get_text()) producto.camposEspecificosBala.cajasPale = cajasPale color = self.wids['e_color'].get_text() antiuv = self.wids['chk_antiuv'].get_active() reciclada = self.wids['ch_reciclada'].get_active() idtipoMaterialBala = utils.combo_get_value(self.wids['cb_material']) prodestandar = self.wids['e_prodestandar'].get_text() try: prodestandar = utils.parse_float(prodestandar) except ValueError: prodestandar = 0.0 # Desactivo el notificador momentáneamente producto.notificador.activar(lambda: None) # Actualizo los datos del objeto producto.prodestandar = prodestandar try: producto.codigo = codigo except psycopg_ProgrammingError: try: producto_asignado = pclases.ProductoVenta.select( pclases.ProductoVenta.q.codigo == codigo)[0] producto_asignado = producto_asignado.descripcion except IndexError: producto_asignado = "?" utils.dialogo_info(titulo = "CÓDIGO DUPLICADO", texto = "El código EAN %s no se encuentra " "disponible.\nActualmente está asignado a:" " %s" % (codigo, producto_asignado), padre = self.wids['ventana']) producto.descripcion = descripcion if producto.camposEspecificosBala.gramosBolsa: producto.lineaDeProduccionID = lineaembol.id else: producto.lineaDeProduccionID = linea.id producto.nombre = nombre producto.preciopordefecto = precio producto.minimo = minimo producto.arancel = arancel producto.camposEspecificosBala.dtex = dtex producto.camposEspecificosBala.corte = corte producto.camposEspecificosBala.color = color producto.camposEspecificosBala.antiuv = antiuv producto.camposEspecificosBala.reciclada = reciclada producto.camposEspecificosBala.tipoMaterialBalaID = idtipoMaterialBala producto.dni = self.wids['e_dni'].get_text() producto.uso = self.wids['e_uso'].get_text() if self.wids['ch_no_anno_cert'].get_active(): producto.annoCertificacion = None else: producto.annoCertificacion \ = self.wids['sp_anno_certificacion'].get_value_as_int() cliente = utils.combo_get_value(self.wids['cbe_cliente']) if cliente == 0: cliente = None producto.camposEspecificosBala.clienteID = cliente try: self.objeto.obsoleto = self.wids['ch_obsoleto'].get_active() except (KeyError, AttributeError): pass # Versión antigua de la base de datos. # Fuerzo la actualización de la BD y no espero a que SQLObject lo # haga por mí: producto.syncUpdate() # Vuelvo a activar el notificador producto.notificador.activar(self.aviso_actualizacion) self.wids['b_guardar'].set_sensitive(False) self.actualizar_ventana()
def crear_nuevo_albaran(self, widget): """ Función callback del botón b_nuevo. Pide los datos básicos para crear un nuevo objeto. Una vez insertado en la BD hay que hacerlo activo en la ventana para que puedan ser editados el resto de campos que no se hayan pedido aquí. """ albaran = self.objeto nuevo_numalbaran = \ pclases.AlbaranSalida.get_siguiente_numero_numalbaran_str() # Datos a pedir: numalbaran = utils.dialogo_entrada( titulo = "NÚMERO DE ALBARÁN", texto = 'Introduzca un número para el albarán.\nDeje' ' el número de albarán por defecto si no est' 'á seguro.', valor_por_defecto = nuevo_numalbaran, padre = self.wids['ventana']) if numalbaran == None: return # numero_numalbaran = utils.parse_numero(numalbaran) numero_numalbaran_usuario = utils.parse_numero(numalbaran, invertir = True) numero_numalbaran_sugerido = utils.parse_numero(nuevo_numalbaran, invertir = True) #if self.usuario != None and self.usuario.nivel > 1 and numero_numalbaran != None and numero_numalbaran > nuevo_numalbaran: if (self.usuario and self.usuario.nivel > 1 and numero_numalbaran_usuario != None and numero_numalbaran_usuario > numero_numalbaran_sugerido): utils.dialogo_info(titulo = "NÚMERO DE ALBARÁN INCORRECTO", texto = "No es estrictamente necesario que todos los albaranes sean consecutivos.\n\nSin embargo, no se aconseja crear albaranes con número superior al sugerido.\n\nSi considera que debe hacerlo, contacte con un usuario con mayor nivel de privilegios.", padre = self.wids['ventana']) return if albaran != None: albaran.notificador.desactivar() propia_empresa = pclases.Cliente.id_propia_empresa_cliente() almacenes = [(a.id, a.nombre) for a in pclases.Almacen.select( pclases.Almacen.q.activo == True, orderBy = "id")] almacenppal = pclases.Almacen.get_almacen_principal_id_or_none() almo = utils.dialogo_combo(titulo = "ALMACÉN ORIGEN", texto = "Seleccione el almacén origen de la mercancía", ops = almacenes, padre = self.wids['ventana'], valor_por_defecto = almacenppal) if not almo: # Cancelar return try: albaran = pclases.AlbaranSalida(numalbaran = numalbaran, transportista = None, clienteID = propia_empresa, bloqueado = False, facturable = False, motivo = "Es de consumo de repuestos", observaciones = "repuestos", destino = None, fecha = mx.DateTime.localtime(), almacenOrigenID = almo, almacenDestino = None) pclases.Auditoria.nuevo(albaran, self.usuario, __file__) utils.dialogo_info('ALBARÁN CREADO', 'El albarán %s ha sido creado.\nNo olvide asociar las salidas.' % albaran.numalbaran, padre = self.wids['ventana']) self.nuevo = True self.modificado = False except Exception, e: texto = "%salbaranes_de_salida::crear_nuevo_albaran -> Error al crear nuevo albarán. Excepción capturada: %s" % (self.usuario and self.usuario.usuario+": " or "", e) print texto self.logger.error(texto) utils.dialogo_info('ERROR: ALBARÁN NO CREADO', 'El albarán %s no ha sido creado.\nCompruebe que el número no esté siendo usado y vuelva a intentarlo.\n\n\n' % (numalbaran), padre = self.wids['ventana'])
def etiqueta_rollos_norma13(rollos, mostrar_marcado = True, lang = "es"): """ Construye una etiqueta por cada objeto rollo recibido y las devuelve en un solo PDF. Si lang = "en", etiqueta en inglés. Si "es", en castellano. """ # Voy a tratar de reescribir esto regla en mano a ver si consigo # cuadrarlo bien en la etiquetadora GEMINI. alto = 12.55 * cm ancho = 8.4 * cm # Creo la hoja nomarchivo = os.path.join(gettempdir(), "etiq_norma13_%s_%s.pdf" % (lang, give_me_the_name_baby())) c = canvas.Canvas(nomarchivo, pagesize = (ancho, alto)) # Medidas: logo = (3.8 * cm * 0.75, 2.8 * cm * 0.75) margen = 0.1 * cm marcado = (((ancho - logo[0]) / 2) - margen, (alto - margen - logo[1] - 2)) # Imágenes: logo_marcado = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "imagenes", "CE.png")) # Datos fijos: _data = {# "00 logo_marcado": None, "01 texto_marcado": "1035", # Fijo "02 fabricado_por": "Fabricado por: %s", "03 direccion1": None, "04 direccion2": None, "05 telefono": "Tfno: %s, %s", "06 año_certif": None, "07 blanco1": "", # Separador "08 dni": None, #"09 iso1": "De EN13249:2001 a EN13257:2001", # Fijo #"10 iso2": "EN13265:2001", # Fijo # La norma ha cambiado. Ahora nos regimos por la del 2014 "09 iso1": "De EN13249:2014 a EN13257:2014", # Fijo "10 iso2": "EN13265:2014", # Fijo "11 blanco2": "", # Separador "12 producto": None, "13 descripcion": "Geotextil no tejido de polipropileno 100% virgen", "14 uso": "Uso: %s", "15 blanco3": "", # Separador "16 codigo": "Partida: %d Rollo: %s", "17 caracteristicas": "Gramaje: %d g/m² Ancho: %s m Largo: %d m" } if lang == "en": for k in _data: _data[k] = helene_laanest(_data[k]) estilos = defaultdict(lambda: ("Helvetica", 9)) # Helvética a 9 por defecto estilos["02 fabricado_por"] = ("Helvetica-Bold", 11) estilos["12 producto"] = ("Helvetica-Bold", 17) estilos["16 codigo"] = ("Helvetica-Bold", 17) estilos["17 caracteristicas"] = ("Helvetica-Bold", 13) data = {} # Datos de la BD dependientes del rollo for rollo in rollos: # 0.- ¿En qué formato viene? Si es el antiguo (datos en diccionario) # me quedo con el objeto de pclases en sí. if isinstance(rollo, dict): try: productoVenta = rollo['productoVenta'] except KeyError: # Si no me lo mandan en el diccionario, tiene que traer # el objeto rollo. Los partes mandan producto en dicccionario # porque a veces se genera etiqueta antes de crear el objeto # en la BD. Si viene de la consulta del listado de rollos, # como el rollo ya existe, me viene en el objeto toda la info. productoVenta = rollo['objeto'].productoVenta numpartida = utils.parse_numero(rollo['partida']) numrollo = rollo['nrollo'] else: productoVenta = rollo.productoVenta numpartida = rollo.partida.numpartida numrollo = rollo.numrollo # 1.- Empresa try: # Si hay distribuidor, este texto cambia. distribuidor = productoVenta.camposEspecificosRollo.cliente if distribuidor: if lang == "en": data["02 fabricado_por"] = helene_laanest( "Distribuido por: %s") % (distribuidor.nombre) else: data["02 fabricado_por"] = "Distribuido por: %s" % ( distribuidor.nombre) d = distribuidor.get_direccion_completa() dircompleta = textwrap.wrap(d, (len(d) + max([len(w) for w in d.split()])) / 2) data["03 direccion1"] = dircompleta[0] data["04 direccion2"] = dircompleta[1] data["05 telefono"] = _data["05 telefono"] % ( distribuidor.telefono, distribuidor.email) else: # Sigo con los datos de "propia empresa". Distribuyo yo. empresa = pclases.DatosDeLaEmpresa.select()[0] data["02 fabricado_por"] = _data["02 fabricado_por"] % ( empresa.nombre) data["03 direccion1"] = empresa.direccion + ", " + empresa.cp data["04 direccion2"] = ", ".join((empresa.ciudad, empresa.provincia, empresa.pais)) data["05 telefono"] = _data["05 telefono"] % (empresa.telefono, empresa.email) # Para los clientes sin teléfono o sin email: data["05 telefono"] = data["05 telefono"].strip() if data["05 telefono"].startswith(","): data["05 telefono"] = data["05 telefono"][1:] if data["05 telefono"].endswith(","): data["05 telefono"] = data["05 telefono"][:-1] if len(data["05 telefono"]) <= 7: data["05 telefono"] = "" except IndexError: data["02 fabricado_por"] = "" data["03 direccion1"] = "" data["04 direccion2"] = "" data["05 telefono"] = "" # 2.- Producto producto = productoVenta if producto.annoCertificacion != None: data["06 año_certif"] = "%02d" % producto.annoCertificacion else: data["06 año_certif"] = "" data["08 dni"] = producto.dni if len(producto.nombre) <= 50: data["12 producto"] = producto.nombre else: #if "//" in producto.nombre: # Productos Intermas # data["11 blanco2"], data["12 producto"] = producto.nombre.split("//") #else: data["11 blanco2"], data["12 producto"] = utils.dividir_cadena( producto.nombre) data["11 blanco2"] = data["11 blanco2"].strip() data["12 producto"] =data["12 producto"].strip() estilos["11 blanco2"] = estilos["12 producto"] if producto.uso: if lang == "en": data["14 uso"] = _data["14 uso"] % helene_laanest(producto.uso) else: data["14 uso"] = _data["14 uso"] % producto.uso else: data["14 uso"] = "" # 3.- Rollo data["16 codigo"] = _data["16 codigo"] % (numpartida, numrollo) data["17 caracteristicas"] = _data["17 caracteristicas"] % ( producto.camposEspecificosRollo.gramos, float2str(producto.camposEspecificosRollo.ancho, autodec = True, separador_decimales = "."), producto.camposEspecificosRollo.metrosLineales) rectangulo(c, (margen, margen), (ancho - margen, alto - margen)) if mostrar_marcado: c.drawImage(logo_marcado, marcado[0], marcado[1], width = logo[0], height = logo[1]) else: data["01 texto_marcado"] = "" lineas = _data.keys() lineas.sort() # Posición y estilo de la primera línea. tamfuente = estilos[lineas[0]][1] y = alto - logo[1] - 0.1 * cm - tamfuente # ¿Cuánto me desplazaré de línea a línea? offset_y = (y - margen) / len(lineas) for linea in lineas: try: dato = data[linea] except KeyError: # Si no está en los valores asignados, busco # en los originales. Deben ser datos fijos. dato = _data[linea] if dato is None: dato = "" c.setFont(*estilos[linea]) #c.drawCentredString((ancho / 2), # y, # escribe(dato)) el_encogedor_de_fuentes_de_doraemon(c, fuente = estilos[linea][0], tamannoini = estilos[linea][1], xini = margen, xfin = ancho - margen, y = y, texto = dato, alineacion = 0) y -= offset_y c.showPage() c.save() return nomarchivo