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. """ empleado = self.objeto # Desactivo el notificador momentáneamente empleado.notificador.set_func(lambda: None) # Actualizo los datos del objeto for col in empleado.sqlmeta.columns: valor = self.get_valor(self.wids[col], col, empleado.sqlmeta.columns[col]) try: empleado._SO_setValue(col, valor, None, None) except psycopg_ProgrammingError: utils.dialogo_info(titulo="ERROR", texto="Se produjo un error al guardar uno de los " "valores.\nCompruebe que el formato y tipo de" " dato es correcto.", padre=self.wids['ventana']) # Fuerzo la actualización de la BD y no espero a que SQLObject lo haga # por mí: empleado.syncUpdate() # Vuelvo a activar el notificador empleado.notificador.set_func(self.aviso_actualizacion) self.actualizar_ventana() self.wids['b_guardar'].set_sensitive(False)
def cambiar_horainicio(self, tv, path, newtext): model = self.wids['tv_horas'].get_model() ide = model[path][-1] pt = pclases.ParteDeTrabajo.get(ide) try: dtdelta = mx.DateTime.DateTimeDelta(0, float(newtext.split(':')[0]), float(newtext.split(':')[1]), 0) duracion = pt.horas pt.horainicio = mx.DateTime.DateTimeFrom(year = pt.horainicio.year, month = pt.horainicio.month, day = pt.horainicio.day, hour = dtdelta.hour, minute = dtdelta.minute, second = dtdelta.second) pt.horafin = pt.horainicio + duracion pt.sync() model[path][2] = pt.horainicio.strftime('%H:%M') model[path][3] = pt.horafin.strftime('%H:%M') model[path][4] = pt.horas.strftime('%H:%M') except IndexError: utils.dialogo_info(titulo = "ERROR", texto = 'El texto "%s" no respeta el formato horario (H:MM).' % newtext, padre = self.wids['ventana']) except ValueError: utils.dialogo_info(titulo = "ERROR", texto = 'El texto "%s" no respeta el formato horario (H:M).' % newtext, padre = self.wids['ventana'])
def calcular_caracteristicas(self): """ Calcula la media, desviación típica y marca los valores según tolerancia. """ loteCem = self.loteCem # La tolerancia depende del tipo de producto: try: dtex = loteCem.bigbags[0].articulos[0].productoVenta.camposEspecificosBala.dtex except: utils.dialogo_info(titulo = 'ERROR', texto = 'Ocurrió un error buscando el tipo de fibra.', padre = self.wids['ventana']) return mediatitulo = 0 sumatorio = 0 desvtipica = 0 for p in loteCem.pruebasTitulo: mediatitulo += p.resultado sumatorio += p.resultado**2.0 try: mediatitulo /= len(loteCem.pruebasTitulo) desvtipica = sumatorio / len(loteCem.pruebasTitulo) desvtipica -= mediatitulo**2.0 desvtipica = desvtipica**0.5 # ValueError cuando intente hacer raíz de número negativo. No debería ocurrir. except ZeroDivisionError: mediatitulo = 0 desvtipica = 0 loteCem.mediatitulo = mediatitulo self.wids['e_desvtipica'].set_text("%.2f" % desvtipica) self.marcar_tolerancia(dtex, mediatitulo, loteCem.tolerancia) self.calcular_caracteristicas_propias() self.rellenar_info_loteCem()
def ver_articulos(self, w): """ Muestra las existencias del artículo en el almacén """ producto = self.objeto elementos = pclases.Articulo.select(pclases.AND(pclases.Articulo.q.albaranSalidaID == None,pclases.Articulo.q.productoVentaID == producto.id)) utils.dialogo_info(titulo = 'EXISTENCIAS', texto = 'Hay %d unidades de %s en el almacén.\nEl mínimo es %d' % (elementos.count(),producto.descripcion,producto.minimo))
def actualizar_porcentaje_tarifa(self, celleditable, path, nuevotexto): """ Se recibe la celda que ha cambiado. El contenido se toma como nuevo precio para la tarifa actual y el producto de la fila a la que pertenezca la fila. """ idprecio = self.wids['tabla_productos'].get_model()[path][-1] precio = pclases.Precio.get(idprecio) producto = precio.producto tarifa = self.objeto # OJO: No se debería devolver ni más ni menos de un producto. try: porcentaje = utils.parse_porcentaje(nuevotexto, True) except ValueError: utils.dialogo_info(titulo = 'VALOR INCORRECTO', texto = 'El texto tecleado (%s) no es un porcentaje correcto' % (nuevotexto), padre = self.wids['ventana']) else: nuevoprecio = producto.preciopordefecto * (1 + porcentaje) tarifa.asignarTarifa(producto, float(nuevoprecio)) #self.actualizar_ventana() model = self.wids['tabla_productos'].get_model() model[path][-3] = precio.precio model[path][-2] = "%s %%" % (porcentaje * 100)
def imprimir(self, boton): """ Prepara la vista preliminar para la impresión del informe """ from informes.treeview2pdf import treeview2pdf from formularios.reports import abrir_pdf idcliente = utils.combo_get_value(self.wids['cmbe_cliente']) if idcliente == None: utils.dialogo_info(titulo = 'ERROR', texto = 'Seleccione un cliente', padre = self.wids['ventana']) else: idcliente = utils.combo_get_value(self.wids['cmbe_cliente']) self.cliente = pclases.Cliente.get(idcliente) cliente = self.cliente if not self.inicio: fechaInforme = 'Hasta ' + utils.str_fecha(time.strptime(self.fin, "%Y/%m/%d")) else: fechaInforme = utils.str_fecha(time.strptime(self.inicio, "%Y/%m/%d")) + ' - ' + utils.str_fecha(time.strptime(self.fin, "%Y/%m/%d")) strfecha = fechaInforme informe = treeview2pdf(self.wids['tv_datos'], titulo = "Productos comprados por " + cliente.nombre, fecha = strfecha) if informe: abrir_pdf(informe)
def crear_servicio(self): # Datos a pedir: Concepto, descuento y precio... Bah, el descuento # que lo cambie en el TreeView. concepto = utils.dialogo_entrada(titulo = "CONCEPTO", texto = 'Introduzca el concepto del servicio facturable:', padre = self.wids['ventana']) if concepto != None: precio = utils.dialogo_entrada(titulo = "PRECIO", texto = 'Introduzca el precio unitario sin IVA:', padre = self.wids['ventana']) if precio != None: try: precio = utils._float(precio) servicio = pclases.Servicio(facturaVenta = self.objeto, concepto = concepto, precio = precio, descuento = 0) # Cantidad es 1 por defecto. except Exception, e: utils.dialogo_info(texto = """ Ocurrió un error al crear el servicio. Asegúrese de haber introducido correctamente los datos, especialmente el precio (que no debe incluir símbolos monetarios), y vuelva a intentarlo. DEBUG: %s """ %(e), titulo = "ERROR", padre = self.wids['ventana']) return self.rellenar_servicios() self.rellenar_vencimientos()
def borrar(self, boton): """ Borra el registro activo. """ if utils.dialogo(titulo = "¿BORRAR?", texto = "¿Desea eliminar el recibo en pantalla?", padre = self.wids['ventana']): try: for vto in self.objeto.vencimientosCobro: vto.recibo = None txtrcbo = "Recibo bancario número %d con fecha de emisión %s." % (self.objeto.numrecibo, utils.str_fecha(self.objeto.fechaLibramiento)) if txtrcbo in vto.observaciones: vto.observaciones = vto.observaciones.replace(txtrcbo, "") else: # Se ha cambiado la fecha o el número del recibo # después de haber incluido el vencimiento if "Recibo bancario" in vto.observaciones: vto.observaciones = vto.observaciones[:vto.observaciones.index("Recibo bancario")] else: # No sé lo que habrá hecho el usuario con las observaciones, reinicio al texto de forma de pago original: try: vto.observaciones = vto.get_factura_o_prefactura().cliente.textoformacobro except AttributeError, msg: # No tiene factura, o la factura no tiene cliente. Dejo las observaciones que tuviera. txterror = "%srecibos::drop_factura -> El vencimientoCobro ID %d no tiene factura, o su factura no tiene cliente. Mensaje de la excepción: %s" % (self.usuario and self.usuario.usuario + ": " or "", vto.id, msg) self.logger.warning(txterror) self.objeto.destroy(ventana = __file__) except Exception, msg: utils.dialogo_info(titulo = "ERROR", texto = "El registro no se pudo eliminar", padre = self.wids['ventana']) self.logger.error("%srecibos::borrar -> No se pudo eliminar el recibo ID %d. Excepcion: %s" % (self.usuario and self.usuario.usuario + ": " or "", self.objeto and self.objeto.id or 0, msg))
def buscar_cliente(self): """ Busca un cliente y devuelve su ID o None. """ idcliente = None a_buscar = utils.dialogo_entrada(titulo = "BUSCAR CLIENTE", texto = "Introduzca nombre o CIF del cliente:", padre = self.wids['ventana']) if a_buscar != None: criterio = pclases.OR(pclases.Cliente.q.nombre.contains(a_buscar), pclases.Cliente.q.cif.contains(a_buscar)) resultados = pclases.Cliente.select(criterio) if resultados.count() > 1: ## Refinar los resultados idcliente = self.refinar_resultados_busqueda_cliente(resultados) if idcliente == None: return None resultados = [pclases.Cliente.get(idcliente)] elif resultados.count() < 1: ## Sin resultados de búsqueda utils.dialogo_info('SIN RESULTADOS', 'La búsqueda no produjo resultados.\nPruebe a cambiar el texto buscado o déjelo en blanco para ver una lista completa.\n(Atención: Ver la lista completa puede resultar lento si el número de elementos es muy alto)', padre = self.wids['ventana']) return None ## Un único resultado idcliente = resultados[0].id return idcliente
def nuevo(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í. """ anterior = self.objeto if anterior != None: anterior.notificador.desactivar() factura = self.buscar_factura() # Si lo que va a pagar es un LOGIC, que lo haga desde la ventana de vencimientos_pendientes. if factura != None: importe = factura.get_importe_primer_vencimiento_pendiente() # Devuelve 0 si no quedan. try: nuevo = pclases.Pago(cuentaOrigen = pclases.CuentaOrigen.select(orderBy = "-id")[0], fecha = mx.DateTime.localtime(), facturaCompra = factura, proveedor = factura.proveedor, importe = importe) pclases.Auditoria.nuevo(nuevo, self.usuario, __file__) except IndexError: utils.dialogo_info(titulo = "ERROR CREANDO TRANSFERENCIA", texto = "Se produjo un error al crear una nueva transferencia.\nProbablemente no existan cuentas en la aplicación desde donde realizar transferencias.", padre = self.wids['ventana']) else: utils.dialogo_info('NUEVA TRANSFERENCIA CREADA', 'Se ha creado una transferencia nueva.\nA continuación complete la información de la misma y guarde los cambios.', padre = self.wids['ventana']) self.objeto = nuevo self.objeto.notificador.activar(self.aviso_actualizacion) self.activar_widgets(True) self.actualizar_ventana(objeto_anterior = anterior)
def imprimir(self, boton): """ Imprime un fax con la información de la transferencia. Solicita un firmante al usuario. El resto de los datos se obtienen de la BD. """ from informes.geninformes import fax_transferencia from formularios.reports import abrir_pdf firmantes = {1: "Otro (texto libre)", 2: "D. Enrique Román Corzo", 3: "D. Enrique Figueroa Yáñez", 4: "D. Enrique Mozo del Río", 5: "D. Fernando Guijarro Lozano"} # TODO: HARCODED claves = firmantes.keys() claves.sort() firmado = utils.dialogo_combo(titulo = "FIRMANTE", texto = 'Seleccione un firmante o elija "otro" y pulse\n«Aceptar» para escribir uno distinto:', ops = ([(k, firmantes[k]) for k in claves]), padre = self.wids['ventana']) if firmado == 1: firmado = utils.dialogo_entrada(titulo = "FIRMANTE", texto = "Introduzca el nombre que aparecerá en la firma:", padre = self.wids['ventana']) elif firmado != None: firmado = firmantes[firmado] if firmado != None: try: e = pclases.DatosDeLaEmpresa.select()[0] t = self.objeto o = t.cuentaOrigen d = t.cuentaDestino p = t.proveedor empresa = o.banco contacto = o.contacto fax = o.fax telefono = o.telefono de = e.nombreContacto asunto = "Transferencia" fecha = utils.str_fecha(t.fecha) beneficiario = p.nombre banco = d.banco #if p.es_extranjero(): # cuenta = "%s %s" % (d.iban, d.swif) #else: # cuenta = d.cuenta cuenta = d.cuenta porcuenta = e.nombre ccc = o.ccc concepto = t.concepto importe = "%s €" % (utils.float2str(t.importe)) swift = d.swif iban = d.iban observaciones = d.observaciones conceptoLibre = t.conceptoLibre except AttributeError, msg: utils.dialogo_info(titulo = "ERROR AL GENERAR FAX", texto = "No se encontraron algunos datos.\n\nVerifique la información y vuelva a intentarlo.", padre = self.wids['ventana']) self.logger.error("transferencias.py::imprimir -> AttributeError: %s" % msg) except IndexError, msg: utils.dialogo_info(titulo = "ERROR AL RECUPERAR DATOS DE LA EMPRESA", texto = "No se encontraron los datos de la empresa.\n\nCompruebe que existe una empresa en la tabla «datos_de_la_empresa».\n\n\n(Contacte con el administrador en caso de duda.)", padre = self.wids['ventana']) self.logger.error("transferencias.py::imprimir -> IndexError: %s" % msg)
def buscar_usuario(self, widget): """ Muestra una ventana de búsqueda y a continuación los resultados. El objeto seleccionado se hará activo en la ventana a no ser que se pulse en Cancelar en la ventana de resultados. """ usuario = self.objeto a_buscar = utils.dialogo_entrada("Introduzca nombre de usuario o nombre real:") if a_buscar != None: resultados = pclases.Usuario.select(sqlobject.OR(pclases.Usuario.q.usuario.contains(a_buscar), pclases.Usuario.q.nombre.contains(a_buscar))) if resultados.count() > 1: ## Refinar los resultados idusuario = self.refinar_resultados_busqueda(resultados) if idusuario == None: return resultados = [pclases.Usuario.get(idusuario)] elif resultados.count() < 1: ## Sin resultados de búsqueda utils.dialogo_info('SIN RESULTADOS', 'La búsqueda no produjo resultados.\nPruebe a cambiar el texto buscado o déjelo en blanco para ver una lista completa.\n(Atención: Ver la lista completa puede resultar lento si el número de elementos es muy alto)') return ## Un único resultado # Primero anulo la función de actualización if usuario != None: usuario.notificador.desactivar() # Pongo el objeto como actual usuario = resultados[0] # Y activo la función de notificación: usuario.notificador.activar(self.aviso_actualizacion) self.objeto = usuario self.actualizar_ventana()
def buscar_motivo(self, widget): """ Muestra una ventana de búsqueda y a continuación los resultados. El objeto seleccionado se hará activo en la ventana a no ser que se pulse en Cancelar en la ventana de resultados. """ motivo = self.objeto objetobak = self.objeto a_buscar = utils.dialogo_entrada("Introduzca descripción del motivo.") if a_buscar != None: criterio = pclases.Motivo.q.descripcion.contains(a_buscar) resultados = pclases.Motivo.select(criterio) if resultados.count() > 1: ## Refinar los resultados idmotivo = self.refinar_resultados_busqueda(resultados) if idmotivo == None: return resultados = [pclases.Motivo.get(idmotivo)] elif resultados.count() < 1: ## Sin resultados de búsqueda utils.dialogo_info('SIN RESULTADOS', '\n\nLa búsqueda no produjo resultados.\nPruebe a cambiar el texto buscado o déjelo en blanco para ver una lista completa.\n(Atención: Ver la lista completa puede resultar lento si el número de elementos es muy alto)\n\n') return ## Un único resultado # Primero anulo la función de actualización if motivo != None: motivo.notificador.set_func(lambda : None) # Pongo el objeto como actual motivo = resultados[0] # Y activo la función de notificación: self.objeto = motivo self.actualizar_ventana(objetobak) motivo.notificador.set_func(self.aviso_actualizacion)
def get_valor(self, w, nombrecampo, tipocampo): res = None if isinstance(tipocampo, pclases.SOStringCol): # Cadena: el widget es un entry res = w.get_text() elif isinstance(tipocampo, pclases.SOIntCol): # Entero: el widget es un entry res = w.get_text() try: res = int(res) except ValueError: txt = "El valor %s no es correcto. Introduzca un número entero." % (res) utils.dialogo_info(titulo = "ERROR DE FORMATO", texto = txt, padre = self.wids['ventana']) res = 0 elif isinstance(tipocampo, pclases.SOBoolCol): # Boolean: el widget es un checkbox res = w.get_active() elif isinstance(tipocampo, pclases.SOForeignKey): # Entero-clave ajena: el widget es un comboboxentry res = utils.combo_get_value(w) elif isinstance(tipocampo, pclases.SOCol): # Clase base, casi seguro Float: el widget es un entry res = w.get_text() try: res = float(res) except ValueError: txt = "El valor %s no es correcto. Introduzca un número." % (res) utils.dialogo_info(titulo = "ERROR DE FORMATO", texto = txt, padre = self.wids['ventana']) res = 0.0 else: txt = "motivos_ausencia.py: No se pudo obtener el valor de %s para %s <%s>." \ % (w, nombrecampo, tipocampo) print txt self.logger.error(txt) return res
def abrir_pdf(pdf): """ Ejecuta una aplicación para visualizar el pdf en pantalla. Si es MS-Windows tiro de adobre acrobat (a no ser que encuentre algo mejor, más portable y empotrable). Si es UNIX-like lanzo el evince, que es más completito que el xpdf. Ni que decir tiene que todo eso debe instalarse aparte. """ if not pdf or pdf is None: return # TODO: Problemón. Al ponerle el ampersand para mandarlo a segundo plano, # sh siempre devuelve 0 como salida del comando, así que no hay manera de # saber cuándo se ha ejecutado bien y cuándo no. if os.name == 'posix': # OJO(Diego) Lo he cambiado por un problema de dependencias y el evince if not ((not os.system('evince "%s" &' % pdf)) or \ (not os.system('acroread "%s" &' % pdf)) or \ (not os.system('xdg-open "%s" &' % pdf)) or \ (not os.system('gnome-open "%s" &' % pdf)) or \ (not os.system('xpdf "%s" &' % pdf))): utils.dialogo_info(titulo = "VISOR PDF NO ENCONTRADO", texto = "No se encontró evince, acroread ni xpdf en el sistema.\nNo fue posible mostrar el archivo %s." % (pdf)) else: # OJO: Esto no es independiente de la plataforma: os.startfile(pdf) # @UndefinedVariable
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. """ if not self.verificar_numrecibo_unico(): utils.dialogo_info(titulo = "RECIBO DUPLICADO", texto = "El número de recibo %s ya existe en el año %d." % ( self.wids['e_numrecibo'].get_text(), self.wids['sp_anno'].get_value()), padre = self.wids['ventana']) else: # Desactivo el notificador momentáneamente self.objeto.notificador.activar(lambda: None) # Actualizo los datos del objeto for colname in self.dic_campos: col = self.clase.sqlmeta.columns[colname] try: valor_ventana = self.leer_valor(col, self.dic_campos[colname]) setattr(self.objeto, colname, valor_ventana) except (ValueError, mx.DateTime.RangeError, TypeError): pass # TODO: Avisar al usuario o algo. El problema es que no hay una forma "limpia" de obtener el valor que ha fallado. # Fuerzo la actualización de la BD y no espero a que SQLObject lo haga por mí: self.objeto.syncUpdate() self.objeto.sync() # Vuelvo a activar el notificador self.objeto.notificador.activar(self.aviso_actualizacion) self.actualizar_ventana() self.wids['b_guardar'].set_sensitive(False)
def buscar(self, boton): """ Dadas fecha de inicio y de fin, lista todos los albaranes pendientes de facturar. """ idcliente = utils.combo_get_value(self.wids['cmbe_cliente']) if idcliente == None: utils.dialogo_info(titulo = 'ERROR', texto = 'Seleccione un cliente', padre = self.wids['ventana']) else: idcliente = utils.combo_get_value(self.wids['cmbe_cliente']) self.cliente = pclases.Cliente.get(idcliente) cliente = self.cliente if not self.inicio: facturas = pclases.FacturaVenta.select(pclases.AND( pclases.FacturaVenta.q.clienteID == cliente.id, pclases.FacturaVenta.q.fecha <= self.fin), orderBy = 'fecha') else: facturas = pclases.FacturaVenta.select(pclases.AND( pclases.FacturaVenta.q.fecha >= self.inicio, pclases.FacturaVenta.q.fecha <= self.fin, pclases.FacturaVenta.q.clienteID == cliente.id), orderBy='fecha') productos = [] for f in facturas: for ldv in f.lineasDeVenta: producto = ldv.producto if producto not in productos: productos.append(producto) self.rellenar_tabla(productos)
def nuevo(self, boton): """ Crea un nuevo recibo en blanco. """ try: dde = pclases.DatosDeLaEmpresa.select()[0] lugarLibramiento = dde.ciudad except: txt = "No hay empresa dada de alta en datos_de_la_empresa." self.logger.error(txt) print txt lugarLibramiento = "" try: cuentaOrigen = pclases.CuentaOrigen.select()[0] except IndexError: cuentaOrigen = None anno = mx.DateTime.localtime().year numrecibo = pclases.Recibo.get_next_numrecibo(anno) try: recibo = pclases.Recibo(numrecibo = numrecibo, anno = anno, fechaLibramiento = mx.DateTime.localtime(), fechaVencimiento = mx.DateTime.localtime(), lugarLibramiento = lugarLibramiento, cuentaOrigen = cuentaOrigen, nombreLibrado = "", direccionLibrado = "") pclases.Auditoria.nuevo(recibo, self.usuario, __file__) # CWT: self.cliente = None except Exception, msg: utils.dialogo_info(titulo = "ERROR", texto = "Ocurrió un error al crear el nuevo recibo.\nVuelva a intentarlo y reinice la aplicación si fuera necesario.", padre = self.wids['ventana']) self.logger.error("%srecibos::nuevo -> Error al crear nuevo recibo. Mensaje de la excepción: %s" % (self.usuario and self.usuario.usuario or "", msg))
def abrir_producto(self, tv, path, column): """ Abre el producto al que se le ha hecho doble clic en una ventana nueva. """ model = tv.get_model() idproducto = model[path][-1] try: if "PV" in idproducto: producto = pclases.ProductoVenta.get(idproducto.split(":")[1]) if producto.es_rollo(): from formularios import productos_de_venta_rollos ventana_producto = productos_de_venta_rollos.ProductosDeVentaRollos(producto, usuario = self.usuario) # @UnusedVariable elif producto.es_bala() or producto.es_bigbag(): from formularios import productos_de_venta_balas ventana_producto = productos_de_venta_balas.ProductosDeVentaBalas(producto, usuario = self.usuario) # @UnusedVariable elif "PC" in idproducto: producto = pclases.ProductoCompra.get(idproducto.split(":")[1]) from formularios import productos_compra ventana_producto = productos_compra.ProductosCompra(producto, usuario = self.usuario) # @UnusedVariable except Exception, e: utils.dialogo_info(titulo = "ERROR RECUPERANDO PRODUCTO", texto = "El producto ID %d no se ha encontrado." "\n\n" "Compruebe que no haya sido eliminado recargando" " la consulta y vuelva a intentarlo." "\n\n\n" "Información de depuración:" "\n%s" % (idproducto, e), padre = self.wids['ventana'])
def enviar_a_laboratorio(self, parametro): # NOTA: Ni idea de qué es lo que traerá el parámetro, sólo me interesa # el parte que está seleccionado en el treeview. model, itr = self.wids['tv_datos'].get_selection().get_selected() if itr == None: utils.dialogo_info(titulo = "PARTE NO SELECCIONADO", texto = "Seleccione un parte para enviar una muestra de su\nlote o partida al laboratorio.", padre = self.wids['ventana']) else: idparte = model[itr][-1] if idparte > 0: parte = pclases.ParteDeProduccion.get(idparte) if not parte.articulos: utils.dialogo_info(titulo = "PARTE VACÍO", texto = "En el parte seleccionado no hubo producción.", padre = self.wids['ventana']) else: a = parte.articulos[0] # Al menos tiene 1 artículo. Con el primero me vale. if parte.es_de_balas(): try: lote = a.bala.lote loteCem = None except AttributeError: lote = None loteCem = a.bigbag.loteCem partida = None else: lote = None partida = a.rollo.partida self.crear_muestra(lote, partida, loteCem)
def ir_a_siguiente(self,widget): """ Hace que el siguiente registro (ordenados por ID interno) sea el objeto activo """ if self.wids['b_guardar'] != None and self.wids['b_guardar'].get_property('sensitive'): # Hay cambios pendientes de guardar. if utils.dialogo('Hay cambios pendientes de guardar.\n¿Desea hacerlo ahora?', '¿GUARDAR CAMBIOS?'): try: self.guardar(None) except: utils.dialogo_info(titulo = 'NO SE PUDO GUARDAR', texto = 'Los cambios no se pudieron guardar automáticamente.\nDebe hacerlo de forma manual') return producto = self.objeto linea = pclases.LineaDeProduccion.select(pclases.OR( pclases.LineaDeProduccion.q.nombre.contains('geocompuesto'), pclases.LineaDeProduccion.q.nombre.contains('comercializado')))[0] try: siguiente = pclases.ProductoVenta.select(pclases.AND(pclases.ProductoVenta.q.camposEspecificosRolloID != None, pclases.ProductoVenta.q.lineaDeProduccionID == linea.id, pclases.ProductoVenta.q.id > producto.id),orderBy='id')[0] except IndexError: utils.dialogo_info(texto = "El elemento seleccionado es el último" " registrado en el sistema", titulo = "ERROR", padre = self.wids['ventana']) return self.objeto = siguiente self.actualizar_ventana()
def calcular_caracteristicas(self): """ Calcula la media de los valores de rizo, tenacidad, encogimiento y elongación. """ lote = self.lote # La elongación depende del tipo de producto: try: dtex = lote.balas[0].articulos[0].productoVenta.camposEspecificosBala.dtex # @UnusedVariable except: utils.dialogo_info(titulo = 'ERROR', texto = 'Ocurrió un error buscando el tipo de fibra') return mediaRizo = 0 for p in lote.pruebasRizo: mediaRizo += p.resultado try: mediaRizo /= len(lote.pruebasRizo) except ZeroDivisionError: mediaRizo = 0 ## Rizo lote.rizo = str(int(round(mediaRizo))) ## Encogimiento #mediaEncogimiento = 0 #for i in self.encogimiento: # mediaEncogimiento += i[0] #if len(self.encogimiento) != 0: # mediaEncogimiento /= len(self.encogimiento) # if mediaEncogimiento <= 10: # lote.encogimiento = 'B' # elif (mediaEncogimiento >10 and mediaEncogimiento<=15): # lote.encogimiento = 'N' # elif mediaEncogimiento > 15: # lote.encogimiento = 'A' # else: # lote.encogimiento = '?' self.rellenar_info_lote()
def actualizar(self, button): """ Actualiza la información mostrada en pantalla a partir de la guardada en el objeto. Machaca los datos que no estén guardados o difieran entre la ventana y el objeto. Si el registro ha sido borrado se deshabilitan los controles de información para que el usuario se mueva a otra tarifa. """ tarifa = self.objeto try: tarifa.sync() # Por si se ha creado alguna nueva, actualizo la lista de tarifas # pero no asigno la que devuelve, para no machacar la actual: self.rellenar_tarifas(self.wids['cb_nombre_tarifa'], False) index = self.buscar_indice_texto(self.wids['cb_nombre_tarifa'], tarifa.nombre) self.wids['cb_nombre_tarifa'].child.set_text('') self.wids['cb_nombre_tarifa'].set_active(-1) self.wids['cb_nombre_tarifa'].set_active(index) except pclases.SQLObjectNotFound: utils.dialogo_info('Tarifa borrada.', 'La tarifa no existe o ha sido eliminada.') tarifa = self.rellenar_tarifas(self.wids['cb_nombre_tarifa']) # Y finalmente, deshabilito el botón (puesto que presumiblemente no deberá usarlo # a no ser que remotamente se modifique el objeto, en cuyo caso ya se lo habilitaré # yo al usuario) self.wids['b_actualizar'].set_sensitive(False)
def nuevo(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í. """ fincas = [(f.id, f.nombre) for f in pclases.Finca.select(orderBy = "nombre")] idfinca = utils.dialogo_combo(titulo = "SELECCIONE FINCA", texto = "Seleccione la finca a la que pertenece la nueva parcela:", ops = fincas, padre = self.wids['ventana']) if idfinca != None: objeto_anterior = self.objeto if objeto_anterior != None: objeto_anterior.notificador.desactivar() self.objeto = self.clase(fincaID = idfinca) self.objeto.notificador.activar(self.aviso_actualizacion) self._objetoreciencreado = self.objeto self.activar_widgets(True) self.actualizar_ventana(objeto_anterior = objeto_anterior) utils.dialogo_info('NUEVO %s CREADO' % self.clase.sqlmeta.table.upper(), 'Se ha creado un nuevo %s.\nA continuación complete la información del misma y guarde los cambios.' % self.clase.sqlmeta.table.lower(), padre = self.wids['ventana'])
def set_lote(self, w): numlote = utils.dialogo_entrada(titulo = 'Nº LOTE', texto = 'Introduzca número de lote:') if numlote != None: lotes = pclases.Lote.select(pclases.Lote.q.numlote.contains(numlote)) if lotes.count() == 0: utils.dialogo_info(titulo = 'LOTE NO ENCONTRADO', texto = 'No se encontró ningún lote %s.' % numlote) return elif lotes.count() > 1: filas = [(l.id, l.numlote, l.codigo, l.tenacidad, l.elongacion, l.rizo, l.encogimiento) for l in lotes] idlote = utils.dialogo_resultado(filas, titulo = 'SELECCIONE LOTE', cabeceras = ('ID', 'Número', 'Código', 'Tenacidad', 'Elongación', 'Rizo', 'Encogimiento')) if idlote < 0: return lote = pclases.Lote.get(idlote) else: lote = lotes[0] if len(lote.balas) == 0: utils.dialogo_info(titulo = 'LOTE VACÍO', texto = 'El lote no contiene balas, no puede\nrealizar pruebas sobre un lote vacío.') self.lote = None return self.lote = lote self.actualizar_ventana()
def calcular_encogimiento(self): lote = self.lote # La elongación depende del tipo de producto: try: dtex = lote.balas[0].articulos[0].productoVenta.camposEspecificosBala.dtex # @UnusedVariable except: utils.dialogo_info(titulo = 'ERROR', texto = 'Ocurrió un error buscando el tipo de fibra', padre = self.wids['ventana']) return ## Encogimiento mediaEncogimiento = 0 for p in lote.pruebasEncogimiento: mediaEncogimiento += p.resultado try: mediaEncogimiento /= len(lote.pruebasEncogimiento) except ZeroDivisionError: mediaEncogimiento = 0 if mediaEncogimiento <= 10: lote.encogimiento = 'B' elif (mediaEncogimiento >10 and mediaEncogimiento<=15): lote.encogimiento = 'N' elif mediaEncogimiento > 15: lote.encogimiento = 'A' else: lote.encogimiento = '?'
def set_partida(self, w): numpartida = utils.dialogo_entrada(titulo = 'Nº PARTIDA', texto = 'Introduzca número de partida:') if numpartida != None: partidas = pclases.Partida.select(pclases.Partida.q.numpartida.contains(numpartida)) if partidas.count() == 0: utils.dialogo_info(titulo = 'PARTIDA NO ENCONTRADA', texto = 'No se encontró ninguna partida %s.' % numpartida) return elif partidas.count() > 1: filas = [(l.id, l.numpartida, l.codigo, l.longitudinal, l.transversal, l.compresion, l.perforacion, l.permeabilidad, l.poros, l.espesor) for l in partidas] idpartida = utils.dialogo_resultado(filas, titulo = 'SELECCIONE PARTIDA', cabeceras = ('ID', 'Número', 'Código', 'Longitudinal', 'Transversal', 'CBR', 'Perforación', 'Permeabilidad', 'Poros', 'Espesor')) if idpartida < 0: return partida = pclases.Partida.get(idpartida) else: partida = partidas[0] if len(partida.rollos) == 0: utils.dialogo_info(titulo = 'PARTIDA VACÍA', texto = 'La partida no contiene rollos, no puede\nrealizar pruebas sobre una partida vacía.') self.partida = None return self.partida = partida self.actualizar_ventana()
def cambiar_descripcion(self, cell, path, texto): """ Cambia la descripción del producto seleccionado. """ try: ventana = pclases.Ventana.select(pclases.Ventana.q.fichero == "productos.py")[0] if self.usuario and (not self.usuario.get_permiso(ventana).escritura or self.usuario.nivel >= 2): utils.dialogo_info(titulo = "USUARIO SIN PRIVILEGIOS", texto = "Necesita permiso de escritura para modificar el precio.", padre = self.wids['ventana']) return except IndexError: if self.usuario and self.usuario.nivel >= 2: utils.dialogo_info(titulo = "USUARIO SIN PRIVILEGIOS", texto = "No tiene permisos suficientes para modificar el precio.", padre = self.wids['ventana']) return model = self.wids['tv_datos'].get_model() ide = model[path][-1] if "PC" in model[path][0]: producto = pclases.ProductoCompra.get(ide) elif "PV" in model[path][0]: producto = pclases.ProductoVenta.get(ide) else: return producto.sync() producto.descripcion = texto producto.syncUpdate() model[path][2] = producto.descripcion
def pedir_producto(self): """ Solicita un código de producto, muestra una ventana de resultados coincidentes con la búsqueda de ese código y devuelve un objeto producto seleccionado de entre los resultados o None si se cancela o no se encuentra. """ producto = None codigo = utils.dialogo_entrada(texto = 'Introduzca código o descripción del producto.', titulo = 'PRODUCTO', padre = self.wids['ventana']) if codigo != None: prods = pclases.ProductoCompra.select(pclases.AND(pclases.OR(pclases.ProductoCompra.q.descripcion.contains(codigo), pclases.ProductoCompra.q.codigo.contains(codigo)), pclases.ProductoCompra.q.controlExistencias == True)) prods = tuple(prods) mens_error = 'No se encontró ningún producto con ese código o descripción.' if len(prods) > 1: idproducto = self.refinar_busqueda_productos(prods) if idproducto != None: prods = [pclases.ProductoCompra.get(idproducto)] else: return None elif len(prods) < 1: utils.dialogo_info(titulo = 'CÓDIGO NO ENCONTRADO', texto = mens_error, padre = self.wids['ventana']) return None producto = prods[0] return producto
def crear_nuevo_empleado(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í. """ empleado = self.objeto if empleado: empleado.notificador.set_func(lambda: None) empleado = pclases.Empleado(centroTrabajo=None, categoriaLaboral=None, nombre='Introduzca nombre', apellidos='Introduzca apellidos', dni='', nomina=0, usuario=None) pclases.Auditoria.nuevo(empleado, self.usuario, __file__) utils.dialogo_info(titulo='NUEVO EMPLEADO CREADO', texto='Introduzca los datos del empleado.\n' 'Recuerde pulsar el botón GUARDAR cuando' ' termine.\n', padre=self.wids['ventana']) self.wids['b_guardar'].set_sensitive(True) self.objeto = empleado self.actualizar_ventana() if empleado: empleado.notificador.set_func(self.aviso_actualizacion)