コード例 #1
0
 def buscar(self,boton):
     """
     Dadas fecha de inicio y de fin, lista todos los albaranes
     pendientes de facturar.
     """
     if not self.inicio:
         facturas = pclases.FacturaCompra.select(pclases.FacturaCompra.q.fecha <= self.fin, orderBy = 'fecha')
     else:
         facturas = pclases.FacturaCompra.select(pclases.AND(pclases.FacturaCompra.q.fecha >= self.inicio,pclases.FacturaCompra.q.fecha <= self.fin), orderBy='fecha')       
     idproveedor = utils.combo_get_value(self.wids['cmbe_proveedor'])
     if idproveedor != None:
         proveedor = pclases.Proveedor.get(utils.combo_get_value(self.wids['cmbe_proveedor']))
         facturas = [v for v in facturas if v.proveedorID == proveedor.id]
     self.resultado = []
     condusuario = self.usuario == None or self.usuario.firmaTotal or self.usuario.firmaUsuario
     condtecnico = self.usuario == None or self.usuario.firmaTotal or self.usuario.firmaTecnico
     condcomercial = self.usuario == None or self.usuario.firmaTotal or self.usuario.firmaComercial
     conddirector = self.usuario == None or self.usuario.firmaTotal or self.usuario.firmaDirector
     for i in facturas:
         if boton.name == "b_pendientes":
             if condusuario and not i.vistoBuenoUsuario and i not in self.resultado:
                 self.resultado.append(i)
             if condtecnico and not i.vistoBuenoTecnico and i not in self.resultado:
                 self.resultado.append(i)
             if condcomercial and not i.vistoBuenoComercial and i not in self.resultado:
                 self.resultado.append(i)
             if conddirector and not i.vistoBuenoDirector and i not in self.resultado:
                 self.resultado.append(i)
         elif boton.name == "b_todas":
             self.resultado.append(i)
     self.resultado.sort(utils.cmp_fecha_id)
     self.rellenar_tabla(self.resultado)
コード例 #2
0
 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)
コード例 #3
0
 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)
コード例 #4
0
 def buscar(self, boton):
     """
     Dadas fecha de inicio y de fin, busca todos los facturas del
     proveedor del combo.
     """
     idproveedor = utils.combo_get_value(self.wids['cmbe_proveedor'])
     str_fini = self.wids['e_fecha_inicio'].get_text()
     criterios = []
     if str_fini:
         self.inicio = utils.parse_fecha(str_fini)
         criterios.append(pclases.FacturaCompra.q.fecha >= self.inicio)
     else:
         self.inicio = None
     try:
         str_ffin = self.wids['e_fecha_fin'].get_text()
         self.fin = utils.parse_fecha(str_ffin)
     except (ValueError, TypeError):
         self.fin = datetime.date.today()
         str_ffin = utils.str_fecha(self.fin)
         self.wids['e_fecha_fin'].set_text(str_ffin)
     criterios.append(pclases.FacturaCompra.q.fecha <= self.fin)
     if idproveedor == None:
         self.proveedor = None
     elif idproveedor == 0:
         self.proveedor = None
     else:
         idproveedor = utils.combo_get_value(self.wids['cmbe_proveedor'])
         self.proveedor = pclases.Proveedor.get(idproveedor)
         criterios.append(
                 pclases.FacturaCompra.q.proveedor == self.proveedor)
     facturas = pclases.FacturaCompra.select(pclases.AND(*criterios))
     self.resultado = facturas
     self.rellenar_tabla(self.resultado)
コード例 #5
0
 def buscar(self, boton):
     """
     Dadas fecha de inicio y de fin, busca todas las ofertas 
     no validadas por el usuario entre esas dos fechas.
     """
     if pclases.DEBUG:
         print "self.inicio", self.inicio, "self.fin", self.fin
     criterios = [pclases.Presupuesto.q.estudio == False, 
                  pclases.Presupuesto.q.usuarioID == None]
     idcliente = utils.combo_get_value(self.wids['cbe_cliente'])
     if idcliente != -1:
         criterios.append(pclases.Presupuesto.q.clienteID == idcliente)
     idcomercial = utils.combo_get_value(self.wids['cbe_comercial'])
     if idcomercial != -1:
         criterios.append(pclases.Presupuesto.q.comercialID == idcomercial)
     if self.inicio:
         criterios.append(pclases.Presupuesto.q.fecha >= self.inicio)
     if self.fin:
         criterios.append(pclases.Presupuesto.q.fecha <= self.fin)
     if not criterios:
         presupuestos = pclases.Presupuesto.select(orderBy = "id")
     elif len(criterios) == 1:
         presupuestos = pclases.Presupuesto.select(criterios[0], 
                                                   orderBy = "id")
     else:
         presupuestos = pclases.Presupuesto.select(pclases.AND(*criterios), 
                                                   orderBy = "id")
     self.rellenar_lista_presupuestos(presupuestos)
コード例 #6
0
 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.
     """
     albaran = self.objeto
         # Campos del objeto que hay que guardar:
     numalbaran = self.wids['e_numalbaran'].get_text()
     fecha = self.wids['e_fecha'].get_text()
     # Desactivo el notificador momentáneamente
     albaran.notificador.set_func(lambda: None)
     # Actualizo los datos del objeto
     albaran.numalbaran = numalbaran
     albaran.proveedor = utils.combo_get_value(self.wids['cmbe_proveedor'])
     albaran.almacen = utils.combo_get_value(self.wids['cbe_almacenID'])
     try:
         albaran.fecha = utils.parse_fecha(fecha)
     except:
         albaran.fecha = mx.DateTime.localtime()
         utils.dialogo_info(titulo = "ERROR GUARDANDO FECHA", 
                            texto = "La fecha %s no es correcta." % (fecha), 
                            padre = self.wids['ventana'])
     # Fuerzo la actualización de la BD y no espero a que SQLObject lo haga por mí:
     albaran.syncUpdate()
     # Vuelvo a activar el notificador
     albaran.notificador.set_func(self.aviso_actualizacion)
     self.actualizar_ventana()
     self.wids['b_guardar'].set_sensitive(False)
コード例 #7
0
    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'])
            # return
            # Selecciono los albaranes de todos los clientes.
            if not self.inicio:
                albaranes = pclases.AlbaranSalida.select(pclases.AlbaranSalida.q.fecha <= self.fin,
                                                         orderBy = 'fecha')
            else:
                albaranes = pclases.AlbaranSalida.select(pclases.AND(pclases.AlbaranSalida.q.fecha >= self.inicio,
                                                                       pclases.AlbaranSalida.q.fecha <= self.fin), 
                                                         orderBy='fecha')    
        else:
            self.cliente = pclases.Cliente.get(utils.combo_get_value(self.wids['cmbe_cliente']))
            cliente = self.cliente
            if not self.inicio:
                albaranes = pclases.AlbaranSalida.select(pclases.AND(pclases.AlbaranSalida.q.fecha <= self.fin,
                                                                       pclases.AlbaranSalida.q.clienteID == cliente.id), 
                                                         orderBy = 'fecha')

            else:
                albaranes = pclases.AlbaranSalida.select(pclases.AND(pclases.AlbaranSalida.q.fecha >= self.inicio,
                                                                       pclases.AlbaranSalida.q.fecha <= self.fin, 
                                                                       pclases.AlbaranSalida.q.clienteID == cliente.id), 
                                                         orderBy='fecha')    
        self.resultado = albaranes
        self.rellenar_tabla(self.resultado)
コード例 #8
0
 def buscar(self, boton):
     """
     Dadas fecha de inicio y de fin, devuelve todos los vencimientos 
     no pagados al completo.
     """
     vpro = VentanaProgreso(padre=self.wids["ventana"])
     vpro.mostrar()
     if not self.inicio:
         pagos = pclases.Pago.select(pclases.Pago.q.fecha <= self.fin, orderBy="fecha")
         pagares = pclases.PagarePago.select(pclases.PagarePago.q.fechaEmision <= self.fin, orderBy="fechaEmision")
     else:
         pagos = pclases.Pago.select(
             pclases.AND(pclases.Pago.q.fecha >= self.inicio, pclases.Pago.q.fecha <= self.fin), orderBy="fecha"
         )
         pagares = pclases.PagarePago.select(
             pclases.AND(
                 pclases.PagarePago.q.fechaEmision >= self.inicio, pclases.PagarePago.q.fechaEmision <= self.fin
             ),
             orderBy="fechaEmision",
         )
     i = 0.0
     tot = pagos.count() + pagares.count()
     proveedor = None
     idproveedor = utils.combo_get_value(self.wids["cmbe_proveedor"])
     if idproveedor != None:
         idproveedor = utils.combo_get_value(self.wids["cmbe_proveedor"])
         proveedor = pclases.Proveedor.get(idproveedor)
     self.resultado = []
     filtrar_por_formapago = self.wids["ch_formapago"].get_active()
     formapago = utils.combo_get_value(self.wids["cb_formapago"])
     for pago in pagos:
         i += 1
         vpro.set_valor(i / tot, "Buscando pagos... (%d/%d)" % (i, tot))
         # Si es un pagaré, se trata en el siguiente bucle.
         if pago.pagarePago:
             continue
         if not proveedor or (proveedor and pago.facturaCompra and pago.facturaCompra.proveedor == proveedor):
             try:
                 txtformapago = self.formaspago[formapago][1]
             except TypeError:  # formapago es None. No se está filtrando
                 # por forma de pago.
                 filtrar_por_formapago = False
                 self.wids["ch_formapago"].set_active(False)
             if not filtrar_por_formapago or (txtformapago in utils.filtrar_tildes(pago.observaciones).lower()):
                 self.resultado.append(pago)
     for pagare in pagares:
         i += 1
         vpro.set_valor(i / tot, "Buscando pagos... (%d/%d)" % (i, tot))
         for pago in pagare.pagos:
             if not proveedor or (proveedor and pago.facturaCompra and pago.facturaCompra.proveedor == proveedor):
                 try:
                     txtformapago = self.formaspago[formapago][1]
                 except TypeError:  # formapago es None. No se está
                     # filtrando por forma de pago.
                     filtrar_por_formapago = False
                     self.wids["ch_formapago"].set_active(False)
                 if not filtrar_por_formapago or (txtformapago in utils.filtrar_tildes(pago.observaciones).lower()):
                     self.resultado.append(pago)
     vpro.ocultar()
     self.rellenar_tabla(self.resultado)
コード例 #9
0
    def buscar(self,boton):
        if not self.inicio:
            vencimientos = pclases.VencimientoCobro.select(
                pclases.VencimientoCobro.q.fecha <= self.fin, 
                orderBy = 'fecha')
            estimados = pclases.EstimacionCobro.select(
                pclases.EstimacionCobro.q.fecha <= self.fin, 
                orderBy = 'fecha')
        else:
            vencimientos = pclases.VencimientoCobro.select(pclases.AND(
                    pclases.VencimientoCobro.q.fecha >= self.inicio,
                    pclases.VencimientoCobro.q.fecha <= self.fin), 
                orderBy='fecha')       
            estimados = pclases.EstimacionCobro.select(pclases.AND(
                    pclases.EstimacionCobro.q.fecha >= self.inicio,
                    pclases.EstimacionCobro.q.fecha <= self.fin), 
                orderBy='fecha')       
        
        idcliente = utils.combo_get_value(self.wids['cmbe_cliente'])
        if idcliente != None:
            cliente = pclases.Cliente.get(
                utils.combo_get_value(self.wids['cmbe_cliente']))
            vencimientos = [v for v in vencimientos 
                            if (v.facturaVenta 
                                and v.facturaVenta.clienteID == cliente.id) 
                               or 
                               (v.prefactura 
                                and v.prefactura.clienteID == cliente.id)]
            estimados = [e for e in estimados 
                         if (e.facturaVenta 
                             and e.facturaVenta.clienteID == cliente.id) 
                            or
                            (e.prefactura 
                             and e.prefactura.clienteID == cliente.id)]
            abonos = buscar_facturas_de_abono_sin_pagar(cliente, 
                                                        self.inicio, self.fin)
        else:
            abonos = []
            for cliente in pclases.Cliente.select():
                abonos += buscar_facturas_de_abono_sin_pagar(cliente, 
                                                             self.inicio, 
                                                             self.fin)

        self.resultado = [[a.fecha, a, False] for a in abonos]
        for i in vencimientos:
            if not self.esta_cobrado(i):
                self.resultado.append([i.fecha,i,False])
        # XXX Esto estaba comentado. ¿Por qué? Ya sé el porqué. Porque de 
        # LOGIC solo sacamos las obligaciones de pago, no las de cobro.
        #if idcliente == None:     # Porque en Logic los clientes no son los mismos que 
        #                          # aquí (no están exactamente igual escritos)
        #    vencimientos_logic = self.buscar_vencimientos_logic(self.inicio, self.fin)
        #    for i in vencimientos_logic:
        #        self.resultado.append([i['fecha'],i,True])
        # XXX
        self.resultado.sort(self.por_fecha)
        self.rellenar_tabla(self.resultado)
コード例 #10
0
 def es_diferente(self):
     """
     Devuelve True si la información en pantalla es distinta a la
     del objeto en memoria.
     """
     albaran = self.objeto
     if albaran == None: return False    # Si no hay albaran activo, devuelvo que no hay cambio respecto a la ventana
     condicion = (str(albaran.numalbaran) == self.wids['e_numalbaran'].get_text())
     condicion = condicion and (utils.str_fecha(albaran.fecha) == self.wids['e_fecha'].get_text())
     condicion = condicion and (utils.combo_get_value(self.wids['cmbe_proveedor']) == albaran.proveedorID)
     condicion = condicion and (utils.combo_get_value(self.wids['cbe_almacenID']) == albaran.almacenID)
     return not condicion    # "condicion" verifica que sea igual
コード例 #11
0
ファイル: consulta_facturacion.py プロジェクト: Virako/fpinn
 def rellenar_tabla(self, facturas):
     """
     Rellena el model con los items de la consulta.
     Elementos es un diccionario con objetos factura y una lista  
     de facturacion correspondientes a los meses de consulta.
     """
     idserie = utils.combo_get_value(self.wids["cb_serie"])
     if not idserie:
         serie = None
     else:
         serie = pclases.SerieFacturasVenta.get(idserie)
     model = self.wids["tv_datos"].get_model()
     model.clear()
     total = total_kg = 0
     for factura in facturas:
         if serie and factura.serieFacturasVenta != serie:
             continue
         importe = factura.calcular_importe_total(iva=True)
         kilos = factura.calcular_kilos()
         padre = model.append(
             (
                 factura.numfactura,
                 utils.str_fecha(factura.fecha),
                 factura.cliente.nombre,
                 utils.float2str(importe),
                 utils.float2str(kilos),
                 factura.id,
             )
         )
         total += importe
         total_kg += kilos
     self.wids["e_total_importes"].set_text("%s €" % utils.float2str(total))
     self.wids["e_total_cantidades"].set_text("%s kg" % utils.float2str(total_kg))
コード例 #12
0
 def buscar(self, boton):
     """
     """
     idproducto = utils.combo_get_value(self.wids["cmbe_producto"])
     if idproducto == None:
         utils.dialogo_info(titulo="ERROR", texto="Seleccione un producto", padre=self.wids["ventana"])
         return
     producto = pclases.ProductoVenta.get(idproducto)
     and_fecha_inicio = "AND parte_de_produccion.fecha >= '%s'" % (self.get_unambiguous_fecha(self.inicio))
     if producto.es_rollo():
         parte_where_de_consulta = """
 partida.id IN 
     (SELECT rollo.partida_id 
      FROM rollo 
      WHERE rollo.id IN 
         (SELECT articulo.rollo_id 
          FROM articulo 
          WHERE articulo.producto_venta_id = %d AND articulo.parte_de_produccion_id IN 
             (SELECT parte_de_produccion.id 
              FROM parte_de_produccion 
              WHERE parte_de_produccion.fecha <= '%s' %s
              ORDER BY parte_de_produccion.fecha
             )
         )
     ) """ % (
             producto.id,
             self.get_unambiguous_fecha(self.fin),
             self.inicio and and_fecha_inicio or "",
         )
     else:
         parte_where_de_consulta = """
 partida.id IN 
     (SELECT bala.partida_carga_id 
      FROM bala 
      WHERE bala.id IN 
         (SELECT articulo.rollo_id 
          FROM articulo 
          WHERE articulo.producto_venta_id = %d AND articulo.parte_de_produccion_id IN 
             (SELECT parte_de_produccion.id 
              FROM parte_de_produccion 
              WHERE parte_de_produccion.fecha <= '%s' %s
              ORDER BY parte_de_produccion.fecha
             )
         )
     ) """ % (
             producto.id,
             self.get_unambiguous_fecha(self.fin),
             self.inicio and and_fecha_inicio or "",
         )
     partidas = pclases.Partida.select(parte_where_de_consulta, distinct=True)
     # Hasta aquí la consulta optimizada para obtener las partidas. Pasamos a recuperar los datos en sí:
     vpro = VentanaActividad(padre=self.wids["ventana"])
     vpro.mostrar()
     self.resultado = []
     for p in partidas:
         vpro.mover()
         self.resultado.append(p)
     vpro.ocultar()
     self.resultado = partidas
     self.rellenar_tabla(self.resultado)
コード例 #13
0
 def imprimir(self, boton):
     """
     Prepara la vista preliminar para la impresión del informe
     """
     from formularios import reports
     from informes.treeview2pdf import treeview2pdf
     pagina_activa = self.wids['nb_tipo'].get_current_page()
     almacenid = utils.combo_get_value(self.wids['cb_almacen'])
     if almacenid != 0:
         almacen = pclases.Almacen.get(almacenid)
     else:
         almacen = None
     if pagina_activa == 0:
         tv = self.wids['tv_fibra']
         titulo = "Existencias de productos por tipo: fibra"
     elif pagina_activa == 1: 
         tv = self.wids['tv_gtx']
         titulo = "Existencias de productos por tipo: geotextiles"
     elif pagina_activa == 2: 
         tv = self.wids['tv_cemento']
         titulo = "Existencias de productos por tipo: fibra de cemento"
     else:
         return
     try:
         titulo += " (%s)" % almacen.nombre
     except AttributeError:
         pass
     totales = range(1, tv.get_model().get_n_columns()-1)
     extra_data = []
     reports.abrir_pdf(treeview2pdf(tv, 
                                    titulo = titulo, 
                                    apaisado = False, 
                                    pijama = True, 
                                    numcols_a_totalizar = totales, 
                                    extra_data = extra_data))
コード例 #14
0
 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.
     """
     albaran = self.objeto
     # Campos del objeto que hay que guardar:
     numalbaran = self.wids['e_numalbaran'].get_text()
     fecha = self.wids['e_fecha'].get_text()
     # Desactivo el notificador momentáneamente
     albaran.notificador.desactivar()
     # Actualizo los datos del objeto
     albaran.numalbaran = numalbaran
     albaran.bloqueado = self.wids['ch_bloqueado'].get_active()
     try:
         albaran.fecha = utils.parse_fecha(fecha)
     except:
         albaran.fecha = mx.DateTime.localtime()
     albaran.almacenOrigenID=utils.combo_get_value(self.wids['cbe_almacen'])
     # Fuerzo la actualización de la BD y no espero a que SQLObject lo 
     # haga por mí:
     albaran.sync()
     # Vuelvo a activar el notificador
     albaran.notificador.activar(self.aviso_actualizacion)
     self.objeto = albaran
     self.modificado = True
     self.actualizar_ventana()
     self.wids['b_guardar'].set_sensitive(False)
コード例 #15
0
ファイル: motivos_ausencia.py プロジェクト: pacoqueen/ginn
 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
コード例 #16
0
 def filtrar_por_forma_de_pago(self, r):
     vpro = ventana_progreso.VentanaProgreso(padre = self.wids['ventana'])
     vpro.mostrar()
     i = 0.0
     tot = len(r) or 1   # Evito ZeroDivisionError si no hay errores.
     vpro.set_valor(i / tot, "Filtrando por forma de pago...")
     if self.wids['ch_formapago'].get_active():
         res = []
         formapago = utils.combo_get_value(self.wids['cb_formapago'])
         if formapago != None:
             txtformapago = self.formaspago[formapago][1]
             for v in r: # v es una tupla con fecha, vencimiento o 
                 vpro.set_valor(i / tot, "Filtrando por forma de pago...")
                 # estimación y un boolean para indicar si es de LOGIC.
                 # Las formas de pago en el combo están todas en minúsuclas
                 # y sin tildes:
                 if (not v[2]
                     and txtformapago in utils.filtrar_tildes(
                         v[1].observaciones).lower()):
                     res.append(v)
                 i += 1
     else:
         res = r
     vpro.ocultar()
     return res
コード例 #17
0
ファイル: calendario_laboral.py プロジェクト: pacoqueen/ginn
 def get_calendario(self, mes, anno):
     """
     Devuelve el calendario a mostrar.
     Si no existe, lo crea.
     """
     fechacalendario = mx.DateTime.DateTimeFrom(day = 1, month = mes, year = anno)
     idldp = utils.combo_get_value(self.wids['cbe_linea'])
     if idldp == None: return None, None
     ldp = pclases.LineaDeProduccion.get(idldp)
     calendarios = pclases.CalendarioLaboral.select(pclases.AND(pclases.CalendarioLaboral.q.mesAnno == fechacalendario,
                                                                pclases.CalendarioLaboral.q.lineaDeProduccionID == idldp))
         # Para crear y buscar calendarios siempre se usará 1 como día. Lo importante es mes y año.
     if calendarios.count() == 0: # Crear
         calendario = pclases.CalendarioLaboral(lineaDeProduccion = ldp, mesAnno = fechacalendario)
         pclases.Auditoria.nuevo(calendario, self.usuario, __file__)
         # Añado los festivos genéricos.
         festivos = tuple([(f.fecha.day, f.fecha.month) for f in pclases.FestivoGenerico.select() \
                             if f.fecha.month == calendario.mesAnno.month])
         for dia, mes in festivos:
             fechafestivo = mx.DateTime.DateTimeFrom(day = dia, month = mes, year = calendario.mesAnno.year)
             festivo = pclases.Festivo(calendarioLaboral = calendario, fecha = fechafestivo)
             pclases.Auditoria.nuevo(festivo, self.usuario, __file__)
     else:
         calendario = calendarios[0]
     return calendario, idldp 
コード例 #18
0
ファイル: partes_de_visita.py プロジェクト: pacoqueen/ginn
 def rellenar_widgets(self):
     """
     Introduce la información del objeto actual
     en los widgets.
     No se chequea que sea != None, así que
     hay que tener cuidado de no llamar a 
     esta función en ese caso.
     """
     # 0.- El comercial seleccionado.
     self.objeto = pclases.Comercial.get(
             utils.combo_get_value(self.wids['cb_comercial']))
     if self.objeto:
         # 1.- La fecha 
         year, month, day = self.wids['calendario'].get_date()
         month += 1  # Gtk.Calendar empieza los meses en 0
         fecha = (year, month, day)
         fecha = datetime.datetime(*fecha)
         # 2.- Las visitas
         visitas = pclases.Visita.select(pclases.AND(
             pclases.Visita.q.fechahora >= fecha,
             pclases.Visita.q.fechahora < fecha+datetime.timedelta(days=1),
             pclases.Visita.q.comercialID == self.objeto.id),
             orderBy = "fechahora")
         # 3.- Y relleno
         model = self.wids['tv_visitas'].get_model()
         model.clear()
         pendientes = []
         for visita in visitas:
             self.add_visita_a_tv(visita)
             if not visita.enviada:
                 pendientes.append(visita)
         # 4.- Recuento de acciones pendientes de confirmar
         self.actualizar_dias_con_visita(self.wids['calendario'],
                                         actualizar_ventana = False)
         self.refresh_commit_button(pendientes)
コード例 #19
0
 def es_diferente(self):
     """
     Devuelve True si la información en pantalla es distinta a la
     del objeto en memoria.
     """
     # NOTA: No hay que preocuparse por el exceso de cómputo. Estas comparaciones
     # son bastante rápidas al tener python -como los lenguajes de verdad y no
     # los jueguetes tipo VB- las operaciones lógicas cortocircuitadas, de forma
     # que si condición pasa a False no se evalúa lo que esté detrás del and en
     # las instrucciones posteriores.
     albaran = self.objeto
     if albaran == None: return False    # Si no hay albaran activo, devuelvo que no hay cambio respecto a la ventana
     condicion = (str(albaran.numalbaran) == self.wids['e_numalbaran'].get_text())
     condicion = condicion and (utils.str_fecha(albaran.fecha) == self.wids['e_fecha'].get_text())
     condicion = condicion and (utils.combo_get_value(self.wids['cmbe_proveedor']) == albaran.proveedorID) 
     condicion = condicion and (utils.combo_get_value(self.wids['cbe_almacenID']) == albaran.almacenID)
     return not condicion    # "condicion" verifica que sea igual
コード例 #20
0
 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.
     """
     albaran = self.objeto
         # Campos del objeto que hay que guardar:
     numalbaran = self.wids['e_numalbaran'].get_text()
     fecha = self.wids['e_fecha'].get_text()
     # Desactivo el notificador momentáneamente
     albaran.notificador.set_func(lambda: None)
     # Actualizo los datos del objeto
     albaran.numalbaran = numalbaran
     proveedor_id = utils.combo_get_value(self.wids['cmbe_proveedor'])
     try:
         proveedor = pclases.Proveedor.get(proveedor_id)
     except:
         proveedor = None
     error_proveedor = False
     proveedores_de_pedidos = utils.unificar(
         [p.proveedor for p in albaran.get_pedidos()])
     if proveedores_de_pedidos and proveedor not in proveedores_de_pedidos:
         # Si el proveedor es diferente al del pedido, no dejo guardarlo.
         proveedor = albaran.proveedor
         error_proveedor = True
     albaran.proveedor = proveedor
     albaran.almacen = utils.combo_get_value(self.wids['cbe_almacenID'])
     try:
         albaran.fecha = utils.parse_fecha(fecha)
     except:
         albaran.fecha = mx.DateTime.localtime()
         utils.dialogo_info(titulo = "ERROR GUARDANDO FECHA",
                            texto = "La fecha %s no es correcta." % (fecha),
                            padre = self.wids['ventana'])
     # Fuerzo la actualización de la BD y no espero a que SQLObject lo
     # haga por mí:
     albaran.syncUpdate()
     # Vuelvo a activar el notificador
     albaran.notificador.set_func(self.aviso_actualizacion)
     self.actualizar_ventana()
     self.wids['b_guardar'].set_sensitive(False)
     if error_proveedor:
         utils.dialogo_info(titulo = "PROVEEDOR NO GUARDADO",
             texto = "El proveedor no se guardó porque no coincide con\n"\
                     "el del pedido del que procede.",
             padre = self.wids['ventana'])
コード例 #21
0
 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.
     """
     albaran = self.objeto
         # Campos del objeto que hay que guardar:
     numalbaran = self.wids['e_numalbaran'].get_text()
     fecha = self.wids['e_fecha'].get_text()
     # Desactivo el notificador momentáneamente
     albaran.notificador.set_func(lambda: None)
     # Actualizo los datos del objeto
     albaran.numalbaran = numalbaran
     prov_anterior = albaran.proveedor
     albaran.proveedor = utils.combo_get_value(self.wids['cmbe_proveedor'])
     if not albaran.proveedor:
         utils.dialogo_info(titulo = "ATENCIÓN", 
                            texto = "No se permiten albaranes de entrada sin proveedor.", 
                            padre = self.wids['ventana'])
         if prov_anterior == None:
             try:
                 from formularios import utils_almacen
                 idpropiaempresa=utils_almacen.id_propia_empresa_proveedor()
                 prov_anterior = pclases.Proveedor.get(idpropiaempresa)
             except:
                 try:
                     prov_anterior = pclases.Proveedor.select(
                         orderBy="nombre")[0]
                 except IndexError:
                     prov_anterior = None
         albaran.proveedor = prov_anterior
     try:
         albaran.fecha = utils.parse_fecha(fecha)
     except:
         albaran.fecha = mx.DateTime.localtime()
         utils.dialogo_info(titulo = "ERROR GUARDANDO FECHA", 
                            texto = "La fecha %s no es correcta." % (fecha), 
                            padre = self.wids['ventana'])
     albaran.almacenID = utils.combo_get_value(self.wids['cbe_almacen'])
     # Fuerzo la actualización de la BD y no espero a que SQLObject lo haga por mí:
     albaran.syncUpdate()
     # Vuelvo a activar el notificador
     albaran.notificador.set_func(self.aviso_actualizacion)
     self.actualizar_ventana()
     self.wids['b_guardar'].set_sensitive(False)
コード例 #22
0
    def buscar(self,boton):
        """
        Dadas fecha de inicio y de fin, devuelve todos los vencimientos 
        no pagados al completo.
        """
        if not self.inicio:
            vencimientos = pclases.VencimientoPago.select(
                            pclases.VencimientoPago.q.fecha <= self.fin, 
                            orderBy = 'fecha')
            #estimados = pclases.EstimacionPago.select(
            #                pclases.EstimacionPago.q.fecha <= self.fin, 
            #                orderBy = 'fecha')
        else:
            vencimientos = pclases.VencimientoPago.select(pclases.AND(
                                pclases.VencimientoPago.q.fecha >= self.inicio,
                                pclases.VencimientoPago.q.fecha <= self.fin), 
                            orderBy='fecha') 
            #estimados = pclases.EstimacionPago.select(pclases.AND(
            #                    pclases.EstimacionPago.q.fecha >= self.inicio,
            #                    pclases.EstimacionPago.q.fecha <= self.fin), 
            #                orderBy='fecha')

        idproveedor = utils.combo_get_value(self.wids['cmbe_proveedor'])
        if idproveedor is not None:
            proveedor = pclases.Proveedor.get(idproveedor)
            # Los estimados ya no se usan. No me molesto en vpro para ellos.
            #estimados = [e for e in estimados 
            #             if e.facturaCompra.proveedorID == proveedor.id]
        else:
            proveedor = None
        mostrar_solo_pendientes = self.wids['ch_pendientes'].get_active()
        self.resultado = []
        tot = vencimientos.count()
        ivpro = 0.0
        vpro = ventana_progreso.VentanaProgreso(padre = self.wids['ventana'])
        vpro.mostrar()
        for i in vencimientos:
            vpro.set_valor(ivpro/tot, "Buscando vencimientos...")
            ivpro += 1
            if proveedor:
                if i.facturaCompra.proveedor != proveedor:
                    continue    # Lo ignoro.
            if not self.esta_pagado(i):
                if ((mostrar_solo_pendientes and self.pagare_y_no_emitido(i)) 
                    or not mostrar_solo_pendientes):
                    self.resultado.append([i.fecha, i, False])
        vpro.ocultar()
        if idproveedor is None:     
            # Porque en Logic los proveedores no son los mismos que 
            # aquí (no están exactamente igual escritos)
            vencimientos_logic = self.buscar_vencimientos_logic(self.inicio, 
                                                                self.fin)
            for i in vencimientos_logic:
                self.resultado.append([i['fecha'], i, True])
        self.resultado = self.filtrar_por_forma_de_pago(self.resultado)
        self.resultado.sort(self.por_fecha)
        self.rellenar_tabla(self.resultado)
コード例 #23
0
ファイル: proveedores.py プロジェクト: pacoqueen/ginn
 def rellenar_widgets(self):
     """
     Introduce la información del proveedor actual
     en los widgets.
     No se chequea que sea != None, así que
     hay que tener cuidado de no llamar a 
     esta función en ese caso.
     """
     proveedor = self.objeto
     if proveedor != None:
         orden = utils.combo_get_value(self.wids["cb_orden"])
         if orden == "Orden cronológico":
             proveedores = pclases.Proveedor.select(orderBy="id")
         elif orden == "Orden alfabético":
             proveedores = pclases.Proveedor.select(orderBy="nombre")
         proveedores_count = proveedores.count()
         yo_index = pclases.SQLlist(proveedores).index(self.objeto) + 1
         self.wids["ventana"].set_title(
             "Proveedores - %s (%d de %d)" % (proveedor.nombre, yo_index, proveedores_count)
         )
         # Aprovechando que todo son "text" y los "entry" se llaman casi
         # igual:
         for c in proveedor.sqlmeta.columnList:
             if c.name != "tipoDeProveedorID":
                 textobj = getattr(proveedor, c.name)
                 # Reparo los Nones que haya en la BD
                 if textobj == None:
                     proveedor.notificador.set_func(lambda: None)
                     textobj = ""
                     setattr(proveedor, c.name, textobj)
                     proveedor.notificador.set_func(self.aviso_actualizacion)
                 self.escribir_valor(self.wids["e_%s" % c.name], textobj)
             else:
                 utils.combo_set_from_db(self.wids["cb_tipo_de_proveedor"], proveedor.tipoDeProveedorID)
         self.rellenar_cuentas()
         self.rellenar_tipos_de_material()
         self.objeto.make_swap()
         try:
             doc_from_db = self.objeto.get_documentoDePago().documento
         except AttributeError:
             doc_from_db = None
         if doc_from_db and doc_from_db != self.objeto.documentodepago:
             if utils.dialogo(
                 titulo="CORREGIR DOCUMENTO DE PAGO",
                 texto="El cliente actual tiene como documento de pago:\n"
                 "«%s». Se aconseja usar «%s».\n"
                 "¿Corregirlo automáticamente?\n\n"
                 "(Responda «No» si la forma de pago es correcta \n"
                 "o prefiere corregirlo manualmente)" % (self.objeto.documentodepago, doc_from_db),
                 padre=self.wids["ventana"],
             ):
                 self.objeto.documentodepago = doc_from_db
                 self.objeto.syncUpdate()
                 self.wids["e_documentodepago"].set_text(self.objeto.documentodepago)
         ### Botones anterior/siguiente
         self.actualizar_botones_anterior_siguiente()
コード例 #24
0
 def buscar(self,boton):
     """
     """
     idproducto = utils.combo_get_value(self.wids['cmbe_producto'])
     if idproducto == None:
         utils.dialogo_info(titulo = 'ERROR', texto = 'Seleccione un producto', padre = self.wids['ventana'])
         return
     producto = pclases.ProductoVenta.get(idproducto)
     and_fecha_inicio = "AND parte_de_produccion.fecha >= '%s'" % (self.get_unambiguous_fecha(self.inicio))
     if producto.es_rollo():     # No debería ocurrir. Lo mantengo porque es copy-paste de la consulta de partidas.
         parte_where_de_consulta = """
 partida.id IN 
     (SELECT rollo.partida_id 
      FROM rollo 
      WHERE rollo.id IN 
         (SELECT articulo.rollo_id 
          FROM articulo 
          WHERE articulo.producto_venta_id = %d AND articulo.parte_de_produccion_id IN 
             (SELECT parte_de_produccion.id 
              FROM parte_de_produccion 
              WHERE parte_de_produccion.fecha <= '%s' %s
              ORDER BY parte_de_produccion.fecha
             )
         )
     ) """ %(producto.id, 
             self.get_unambiguous_fecha(self.fin), 
             self.inicio and and_fecha_inicio or "")
     else:
         parte_where_de_consulta = """
 lote.id IN 
     (SELECT bala.lote_id 
      FROM bala 
      WHERE bala.id IN 
         (SELECT articulo.bala_id 
          FROM articulo 
          WHERE articulo.producto_venta_id = %d AND articulo.parte_de_produccion_id IN 
             (SELECT parte_de_produccion.id 
              FROM parte_de_produccion 
              WHERE parte_de_produccion.fecha <= '%s' %s
              ORDER BY parte_de_produccion.fecha
             )
         )
     ) """ %(producto.id, 
             self.get_unambiguous_fecha(self.fin), 
             self.inicio and and_fecha_inicio or "")
     lotes = pclases.Lote.select(parte_where_de_consulta, distinct = True)
     # Hasta aquí la consulta optimizada para obtener los lotes. Pasamos a recuperar los datos en sí:
     vpro = VentanaActividad(padre = self.wids['ventana'])
     vpro.mostrar()
     self.resultado = []
     for p in lotes:
         vpro.mover()
         self.resultado.append(p)
     vpro.ocultar()
     self.resultado = lotes
     self.rellenar_tabla(self.resultado)
コード例 #25
0
ファイル: consulta_clientes.py プロジェクト: Virako/fpinn
 def buscar(self,boton):
     clientes = pclases.Cliente.select(orderBy = "nombre")
     dic_clientes = {}
     total_facturado = total_consumido = 0.0
     idserie = utils.combo_get_value(self.wids['cb_serie'])
     if not idserie:
         serie = None
     else:
         serie = pclases.SerieFacturasVenta.get(idserie)
     for cliente in clientes:
         facturas_del_cliente = cliente.get_facturas_por_intervalo(
                                 self.inicio, self.fin, serie)
         if not facturas_del_cliente:
             continue
         dic_clientes[cliente] = {}
         facturado = cliente.calcular_total_facturado_por_intervalo(
                         self.inicio, self.fin, serie)
         consumido = cliente.calcular_total_consumido_por_intervalo(
                         self.inicio, self.fin, serie)
         total_facturado += facturado
         total_consumido += consumido
         dic_clientes[cliente]['facturado'] = facturado
         dic_clientes[cliente]['productos'] = {}
         dic_clientes[cliente]['consumido'] = consumido
         for factura in facturas_del_cliente:
             # OJO: Solo facturas (y fras. de terceros). No albaranes.
             for ldv in factura.lineasDeVenta:
                 producto = ldv.productoVenta
                 if producto not in dic_clientes[cliente]['productos']:
                     dic_clientes[cliente]['productos'][producto] = [
                         (ldv.cantidad, ldv.precio, ldv.calcular_bultos())]
                 else:
                     dic_clientes[cliente]['productos'][producto] += [
                         (ldv.cantidad, ldv.precio, ldv.calcular_bultos())]
         for producto in dic_clientes[cliente]['productos']:
             tcantidad = sum([i[0] for i 
                           in dic_clientes[cliente]['productos'][producto]])
             tprecio = sum([i[0] * i[1] for i 
                           in dic_clientes[cliente]['productos'][producto]])
             try:
                 precio_medio = tprecio / tcantidad
             except ZeroDivisionError:
                 precio_medio = 0.0
             tbultos = sum([i[2] for i 
                           in dic_clientes[cliente]['productos'][producto]])
             dic_clientes[cliente]['productos'][producto] = (
                 tcantidad, precio_medio, tbultos)
     for cliente in clientes:
         try:
             porcentaje = dic_clientes[cliente]['facturado']/total_facturado
         except ZeroDivisionError:
             porcentaje = 0.0
         except KeyError:
             continue
         dic_clientes[cliente]['porcentaje'] = porcentaje * 100
     self.rellenar_tabla(dic_clientes, total_facturado, total_consumido)
コード例 #26
0
ファイル: nominas.py プロジェクト: pacoqueen/ginn
 def imprimir(self, boton):
     """
     Imprime el TreeView de la ventana.
     """
     from informes.treeview2pdf import treeview2pdf
     from formularios.reports import abrir_pdf
     mes = utils.combo_get_value(self.wids['cb_mes'])
     anno = int(self.wids['sp_anno'].get_value())
     strfecha = "%s de %s (%s a %s)" % (mes, anno, self.wids['e_fechaini'].get_text(), self.wids['e_fechafin'].get_text())
     tv = self.crear_fake_treeview(self.wids['tv_nominas'], catlaboral = False)  
     abrir_pdf(treeview2pdf(tv, titulo = "Pluses y nóminas", fecha = strfecha, apaisado = True))
コード例 #27
0
ファイル: proveedores.py プロジェクト: pacoqueen/ginn
 def actualizar_botones_anterior_siguiente(self, *args, **kw):
     if self.objeto:
         orden = utils.combo_get_value(self.wids["cb_orden"])
         if orden == "Orden cronológico":
             anteriores = pclases.Proveedor.select(pclases.Proveedor.q.id < self.objeto.id).count()
             siguientes = pclases.Proveedor.select(pclases.Proveedor.q.id > self.objeto.id).count()
         elif orden == "Orden alfabético":
             anteriores = pclases.Proveedor.select(pclases.Proveedor.q.nombre < self.objeto.nombre).count()
             siguientes = pclases.Proveedor.select(pclases.Proveedor.q.nombre > self.objeto.nombre).count()
         self.wids["b_back"].set_sensitive(anteriores)
         self.wids["b_next"].set_sensitive(siguientes)
コード例 #28
0
 def insert_finca(self, finca, fila, columna):
     """
     Inserta en self.wids['tabla'] -en (fila, columna)- la información de 
     la finca a través de un gtk.Image y un label dentro de un VBox que a 
     su vez está dentro de un HBox de dos columnas y con la información de 
     la finca como ToolTip.
     """
     #MAX = 50    # Máximo ancho y alto de píxeles para el mapa de la finca.
     MAX = 100   # Máximo ancho y alto de píxeles para el mapa de la finca.
     vbox = gtk.VBox()
     image = gtk.Image()
     #image.set_from_file(finca.get_ruta_completa_plano())
     finca.mostrar_imagen_en(image, MAX)
     label = gtk.Label(' <span foreground="Gray"><big><i>' 
                         + finca.nombre 
                         + '</i></big></span> ')
     label.set_use_markup(True)
     label.set_angle(90)
     idcampanna = utils.combo_get_value(self.wids['cb_campanna'])
     campanna = pclases.Campanna.get(idcampanna)
     prod = sum([parcela.calcular_produccion(campanna)
                 for parcela in finca.parcelas])
     plantas = sum([p.numeroDePlantas for p in finca.parcelas])
     if plantas != 0:
         kgplanta = sum([parcela.calcular_produccion(campanna)
                         for parcela in finca.parcelas]) / plantas
     else:
         kgplanta = 0.0
     apertura = sum([parcela.get_total_gastos_apertura(campanna)
                     for parcela in finca.parcelas])
     varios = sum([parcela.get_total_gastos_varios(campanna)
                   for parcela in finca.parcelas])
     cierre = sum([parcela.get_total_gastos_cierre(campanna)
                   for parcela in finca.parcelas])
     texto_tip = "<big><big>%s</big>\nProducción: <b>%s kg</b>\n<b>%s kg/planta</b>\nGastos apertura: %s €\nGastos varios: %s €\nGastos de cierre: %s €</big>" % (
                             finca.nombre, 
                             utils.float2str(prod),
                             utils.float2str(kgplanta), 
                             utils.float2str(apertura), 
                             utils.float2str(varios), 
                             utils.float2str(cierre))
     #image.set_tooltip_text(texto_tip)
     try:
         image.set_tooltip_markup(texto_tip)
     except:
         pass    # No tiene este método en GTK/PyGTK 2.10 de WXP
     vbox.pack_start(image)
     vbox.pack_start(label)
     hbox = gtk.HBox()
     hbox.pack_start(vbox)
     widparcelas = self.insert_parcelas(finca)
     hbox.pack_start(widparcelas)
     self.wids['tabla'].attach(hbox, columna, columna+1, fila, fila+1)
コード例 #29
0
 def buscar(self, boton):
     """
     Dadas fecha de inicio y de fin, busca todos los pedidos del
     cliente del combo.
     """
     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
         str_fini = self.wids['e_fecha_inicio'].get_text()
         if str_fini:
             self.inicio = utils.parse_fecha(str_fini)
         else:
             self.inicio = None
         try:
             str_ffin = self.wids['e_fecha_fin'].get_text()
             self.fin = utils.parse_fecha(str_ffin)
         except (ValueError, TypeError):
             self.fin = datetime.date.today()
             str_ffin = utils.str_fecha(self.fin)
             self.wids['e_fecha_fin'].set_text(str_ffin)
         if not self.inicio:
             pedidos = pclases.PedidoVenta.select(pclases.AND(
                             pclases.PedidoVenta.q.fecha <= self.fin,
                             pclases.PedidoVenta.q.clienteID == cliente.id),
                         orderBy = 'fecha')
         else:
             pedidos = pclases.PedidoVenta.select(pclases.AND(
                             pclases.PedidoVenta.q.fecha >= self.inicio,
                             pclases.PedidoVenta.q.fecha <= self.fin,
                             pclases.PedidoVenta.q.clienteID == cliente.id),
                         orderBy='fecha')
         self.resultado = pedidos
         self.rellenar_tabla(self.resultado)
コード例 #30
0
ファイル: usuarios.py プロジェクト: Virako/fpinn
 def add_ventana_a_modulo(self, b):
     model, iter = self.wids['tv_modulos'].get_selection().get_selected()
     if iter == None or model[iter].parent != None:
         utils.dialogo_info(titulo = 'SELECCIONE MÓDULO', texto = 'Debe seleccionar un módulo al que añadir la ventana.')
         return
     idventana = utils.combo_get_value(self.wids['cb_add_ventana'])
     if idventana == None:
         utils.dialogo_info(titulo = 'SELECCIONE VENTANA', texto = 'Debe seleccionar una ventana para añadir al módulo.')
     idmodulo = model[iter][-1]
     modulo = pclases.Modulo.get(idmodulo)
     ventana = pclases.Ventana.get(idventana)
     ventana.modulo = modulo
     self.rellenar_tab_modulos()