Esempio n. 1
0
 def add_actividad(self, boton):
     texto = utils.dialogo_entrada(titulo = "NUEVA ACTIVIDAD", 
         texto = 
             "Introduzca la descripción de la nueva actividad deportiva:", 
         padre = self.wids['ventana'])
     if texto != None:
         opciones = [(e.id, e.nombre) 
                     for e in pclases.Evento.select(orderBy = "nombre")]
         opciones.insert(0, (0, "Sin evento relacionado"))
         idevento = utils.dialogo_combo(titulo = "SELECCIONE EVENTO:", 
             texto = "Seleccione un evento de la lista:", 
             ops = opciones, 
             padre = self.wids['ventana'], 
             valor_por_defecto = 0)
         if idevento != None:
             if idevento == 0:
                 evento = None
             else:
                 evento = pclases.Evento.get(idevento)
             actividad = pclases.Actividad(descripcion = texto, 
                             evento = evento, 
                             fechahoraInicio = datetime.datetime.today(),
                             fechahoraFin = datetime.datetime.today(),
                             grupoAlumnos = self.objeto)
             model = self.wids['tv_actividades'].get_model()
             model.append((actividad.descripcion, 
                           actividad.evento 
                             and actividad.evento.nombre or "", 
                           utils.str_fechahora(actividad.fechahoraInicio), 
                           utils.str_fechahora(actividad.fechahoraFin), 
                           actividad.get_puid()))
Esempio n. 2
0
 def rellenar_tabla_actividades(self):
     model = self.wids['tv_actividades'].get_model()
     model.clear()
     for c in self.objeto.clientes:
         if not self.objeto.en_lista_de_espera(c):
             for p in c.actividades:
                 model.append((p.descripcion, 
                               p.evento and p.evento.nombre or "", 
                               utils.str_fechahora(p.fechahoraInicio), 
                               utils.str_fechahora(p.fechahoraFin), 
                               p.get_puid()))
Esempio n. 3
0
 def buscar_alertas(self):
     idfras = []
     if self.wids["tg_filtrar"].get_active():  # Filtrar por seleccionada.
         sel = self.wids["tv_datos"].get_selection()
         model, iters = sel.get_selected_rows()
         for iter in iters:
             id = model[iter][-1]
             if not model[iter].parent:  # Es cliente
                 for iterhijo in model[iter].iterchildren():
                     for iternieto in model[iterhijo.iter].iterchildren():
                         idfras.append(model[iternieto.iter][-1])
             elif not model[iter].parent.parent:  # Es obra
                 for iterhijo in model[iter].iterchildren():
                     idfras.append(model[iterhijo.iter][-1])
             else:  # Es factura
                 idfras.append(id)
     else:
         model = self.wids["tv_datos"].get_model()
         idfras = []
         for fila in model:
             for hijo in model[fila.iter].iterchildren():
                 for nieto in model[hijo.iter].iterchildren():
                     idfras.append(model[nieto.iter][-1])
     model = self.wids["tv_alarmas"].get_model()
     model.clear()
     hoy = mx.DateTime.today()
     for id in idfras:
         if id > 0:
             fra = pclases.FacturaVenta.get(id)
             for a in fra.alarmas:
                 if a.fechahoraAlarma >= hoy + mx.DateTime.oneDay or not a.estado.pendiente:
                     continue
                 try:
                     nombre_cliente = a.facturaVenta.cliente.nombre
                 except AttributeError:
                     nombre_cliente = "¡Sin cliente!"
                 model.append(
                     (
                         nombre_cliente,
                         a.facturaVenta.numfactura,
                         a.estado.descripcion,
                         utils.str_fechahora(a.fechahora),
                         a.texto,
                         utils.str_fechahora(a.fechahoraAlarma),
                         a.observaciones,
                         a.id,
                     )
                 )
Esempio n. 4
0
    def abrir_factura_from_alarma(self, tv, path, view_column):
        """
        Abre la factura a la que pertenece la alarma en la ventana de detalles.
        """
        model = tv.get_model()
        id = model[path][-1]
        a = pclases.Alarma.get(id)
        fra = a.facturaVenta
        import crm_detalles_factura

        v = crm_detalles_factura.CRM_DetallesFactura(fra, usuario=self.usuario)
        # Actualizo último evento porque probablemente lo haya cambiado
        # en la ventana recién abierta. El resto de datos de la
        # factura debería permanecer tal cual (¿A excepción de los
        # vencimientos? No creo. No se renegocian... o no debería.).
        model = self.wids["tv_datos"].get_model()
        last_evento = fra.get_last_evento()
        if last_evento:
            last_evento = "[%s] %s" % (utils.str_fechahora(last_evento.fechahora), last_evento.texto)
        else:
            last_evento = ""
        model[path][5] = last_evento
        self.buscar_todos()
        self.buscar_alertas()
        self.buscar_anotaciones()
Esempio n. 5
0
 def rellenar_tabla(self, balas):
     """
     Introduce las balas recibidas en el TreeView «tv» y lo 
     desplaza a la última fila (la más baja)
     """
     tv = self.wids['tv_balas']
     model = tv.get_model()
     tv.freeze_child_notify()
     tv.set_model(None)
     model.clear()
     totpantalla = 0.0
     for bala, producto in balas:
         if producto != None:
             desc = producto.descripcion
         else:
             desc = "?"
         fila = (utils.str_fechahora(bala.fechahora), 
                 bala.codigo, 
                 utils.float2str(bala.peso, 1), 
                 desc, 
                 bala.observaciones, 
                 bala.id)
         model.append(fila)
         totpantalla += bala.peso_sin
     tv.set_model(model)
     tv.thaw_child_notify()
     self.rellenar_totales(totpantalla)
     self.mover_al_final(self.wids['tv_balas'])
Esempio n. 6
0
 def buscar_fecha(self, boton):
     """
     Muestra el diálogo calendario y establece la fecha de la partida.
     """
     partida = self.get_partida()
     if partida != None:
         fecha = utils.mostrar_calendario(fecha_defecto = partida.fecha, padre = self.wids['ventana'])
         fecha = utils.parse_fecha(utils.str_fecha(fecha))
         partida.fecha = mx.DateTime.DateTimeFrom(day = fecha.day, month = fecha.month, year = fecha.year, 
                                             hour = partida.fecha.hour, minute = partida.fecha.minute, second = partida.fecha.second)
         self.wids['e_fecha'].set_text(utils.str_fechahora(partida.fecha))
Esempio n. 7
0
 def rellenar_widgets(self):
     partida = self.get_partida()
     if partida != None:
         self.wids['e_partida'].set_text("%d (%s)" % (partida.numpartida, partida.codigo))
         self.wids['e_fecha'].set_text(utils.str_fechahora(partida.fecha))
     else:
         self.wids['e_partida'].set_text("")
         self.wids['e_fecha'].set_text("")
     self.rellenar_balas()
     self.rellenar_partidas_gtx()
     self.comprobar_permisos()
Esempio n. 8
0
 def fecha_from_pdp(self, boton):
     """
     Busca la fecha más temprana de producción y se la asigna a la partida 
     de carga.
     Si no hay producción aún, deja la actual.
     """
     partida = self.get_partida()
     if partida != None:
         fecha = partida.get_fecha_inicio()
         if fecha:
             partida.fecha = fecha
             self.wids['e_fecha'].set_text(utils.str_fechahora(partida.fecha))
 def rellenar_tabla(self, rollos):
     """
     Rellena la tabla con la información de los rollos recibidos.
     """
     model = self.wids['tv_datos'].get_model()
     model.clear()
     for r in rollos:
         model.append((r.codigo, 
                       r.partida and r.partida.codigo or "", 
                       r.albaranSalida and r.albaranSalida.numalbaran or "", 
                       utils.str_fechahora(r.fechahora), 
                       r.id))
Esempio n. 10
0
 def cambiar_fin_actividad(self, cell, path, text):
     model = self.wids['tv_actividades'].get_model()
     puid = model[path][-1]
     p = pclases.getObjetoPUID(puid)
     try:
         p.fechahoraFin = utils.parse_fechahora(text)
         p.syncUpdate()
     except (TypeError, ValueError):
         utils.dialogo_info(titulo = "ERROR DE FORMATO", 
                            texto = "La fecha %s no es correcta." % text, 
                            padre = self.wids['ventana'])
     else:
         model[path][3] = utils.str_fechahora(p.fechahoraFin)
Esempio n. 11
0
 def add_nueva_bala_tv(self, bala):
     """
     Introduce la bala al final del TreeView y lo desplaza.
     """
     model = self.wids['tv_balas'].get_model()
     fila = (utils.str_fechahora(bala.fechahora), 
             bala.codigo, 
             utils.float2str(bala.peso, 1), 
             bala.productoVenta.descripcion, 
             bala.observaciones, 
             bala.id)
     model.append(fila)
     self.mover_al_final(self.wids['tv_balas'])
Esempio n. 12
0
 def fecha_from_albaran(self, boton):
     """
     Busca la fecha del albarán interno. Si hay más de uno, selecciona el 
     más temprano de ellos.
     Si no hay albarán interno, deja la actual.
     """
     partida = self.get_partida()
     if partida != None:
         fecha = partida.get_fecha_inicio()
         if fecha:
             albaranes_internos = list(partida.get_albaranes_internos())
             if albaranes_internos:
                 albaranes_internos.sort(lambda a1, a2: (a1.fecha < a2.fecha and -1) or (a1.fecha > a2.fecha and 1) or 0)
                 fecha = albaranes_internos[0].fecha
                 partida.fecha = mx.DateTime.DateTimeFrom(day = fecha.day, month = fecha.month, year = fecha.year, 
                                                 hour = partida.fecha.hour, minute = partida.fecha.minute, second = partida.fecha.second)
                 self.wids['e_fecha'].set_text(utils.str_fechahora(partida.fecha))
Esempio n. 13
0
 def buscar_anotaciones(self):
     idfras = []
     if self.wids["tg_filtrar"].get_active():  # Filtrar por seleccionada.
         sel = self.wids["tv_datos"].get_selection()
         model, iters = sel.get_selected_rows()
         for iter in iters:
             id = model[iter][-1]
             if not model[iter].parent:  # Es cliente
                 for iterhijo in model[iter].iterchildren():
                     for iternieto in model[iterhijo.iter].iterchildren():
                         idfras.append(model[iternieto.iter][-1])
             elif not model[iter].parent.parent:  # Es obra
                 for iterhijo in model[iter].iterchildren():
                     idfras.append(model[iterhijo.iter][-1])
             else:  # Es factura
                 idfras.append(id)
     else:
         model = self.wids["tv_datos"].get_model()
         idfras = []
         for fila in model:
             for hijo in model[fila.iter].iterchildren():
                 for nieto in model[hijo.iter].iterchildren():
                     idfras.append(model[nieto.iter][-1])
     model = self.wids["tv_notas"].get_model()
     model.clear()
     for id in idfras:
         if id > 0:
             fra = pclases.FacturaVenta.get(id)
             for n in fra.notas:
                 try:
                     nombre_cliente = n.facturaVenta.cliente.nombre
                 except AttributeError:
                     nombre_cliente = "¡Sin cliente!"
                 model.append(
                     (
                         nombre_cliente,
                         n.facturaVenta.numfactura,
                         utils.str_fechahora(n.fechahora),
                         n.texto,
                         n.observaciones,
                         n.id,
                     )
                 )
Esempio n. 14
0
 def cambiar_todo_pendiente(self, cell, path):
     """
     Cambia la tarea de pendiente a terminada.
     """
     model = self.wids["tv_todos"].get_model()
     id = model[path][-1]
     tarea = pclases.Tarea.get(id)
     tarea.pendiente = model[path][0]
     if tarea.pendiente:
         tarea.fechadone = None
     else:
         tarea.fechadone = mx.DateTime.localtime()
     tarea.sync()
     model[path][0] = not tarea.pendiente
     if not tarea.pendiente:
         nota = pclases.Nota(
             facturaVenta=tarea.facturaVenta,
             fechahora=mx.DateTime.localtime(),
             texto="Se completó la tarea «%s»" % tarea.texto,
             observaciones="Creado automáticamente desde "
             "crm_seguimiento_impagos al cerrar la tarea %d" % (tarea.id),
         )
     else:
         nota = pclases.Nota(
             facturaVenta=tarea.facturaVenta,
             fechahora=mx.DateTime.localtime(),
             texto="Se anuló el cierre de la tarea «%s»" % tarea.texto,
             observaciones="Creado automáticamente desde "
             "crm_seguimiento_impagos al abrir la tarea %d" % (tarea.id),
         )
     last_evento = nota
     model = self.wids["tv_datos"].get_model()
     for fila in model:
         # print fila
         for hijo in model[fila.iter].iterchildren():
             # print model[hijo.iter[-1]]
             if model[hijo.iter][-1] == tarea.facturaVentaID:
                 last_evento = "[%s] %s" % (utils.str_fechahora(last_evento.fechahora), last_evento.texto)
                 # print last_evento
                 model[hijo.iter][5] = last_evento
                 return  # No quiero seguir recorriendo.
Esempio n. 15
0
def edit_fechahora(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.
    """
    model = tv.get_model()
    id = model[path][-1]
    objeto = clase.get(id)
    try:
        fecha = utils.parse_fechahora(newtext)
    except (ValueError, TypeError):
        parent = tv.parent
        while parent != None:
            parent = parent.parent
        utils.dialogo_info(titulo = "ERROR EN FECHA Y HORA", 
            texto = "El texto «%s» no es una fecha y hora válida." % (newtext), 
            padre = parent)
    else:
        setattr(objeto, atributo, fecha)  
        objeto.syncUpdate()
    model[path][numcol] = utils.str_fechahora(getattr(objeto, atributo))
Esempio n. 16
0
def col2value(objeto, col):
    """
    Convierte el valor del objeto a un formato legible en función de su 
    tipo de datos.
    """
    valor = getattr(objeto, col.name)
    if isinstance(col, pclases.SODateCol):    # Es DATE.
        return utils.str_fecha(valor)
    elif isinstance(col, pclases.SOStringCol):  # TEXT
        return valor 
    elif isinstance(col, pclases.SOFloatCol):   # FLOAT
        return utils.float2str(valor, autodec = True)
    elif isinstance(col, pclases.SOIntCol):     # INT
        return valor 
    elif isinstance(col, pclases.SOBoolCol):    # BOOLEAN
        return valor 
    elif isinstance(col, pclases.SOForeignKey): # Clave ajena. 
        return valor # and valor.id or ""
    elif isinstance(col, pclases.SOCol):          # Es TIMESTAMP o TIME
        if "timestamp" in str(col) or ("fecha" in col.name 
                                       and "hora" in col.name):
            return utils.str_fechahora(valor)
        else:
            return utils.str_hora(valor) 
Esempio n. 17
0
    def abrir_factura(self, tv, path, view_column):
        """
        Abre la factura a la que pertenece el vencimiento sobre el que se ha 
        hecho doble clic.
        """
        model = tv.get_model()
        id = model[path][-1]
        if model[path].parent:  # Es nodo hijo: abono o factura.
            if id > 0:  # Si es negativo es un ID de cliente. No me interesa.
                fra = pclases.FacturaVenta.get(id)
                # import facturas_venta
                # v = facturas_venta.FacturasVenta(fra, usuario = self.usuario)
                import crm_detalles_factura

                v = crm_detalles_factura.CRM_DetallesFactura(fra, usuario=self.usuario)
                # Actualizo último evento porque probablemente lo haya cambiado
                # en la ventana recién abierta. El resto de datos de la
                # factura debería permanecer tal cual (¿A excepción de los
                # vencimientos? No creo. No se renegocian... o no debería.).
                last_evento = fra.get_last_evento()
                if last_evento:
                    last_evento = "[%s] %s" % (utils.str_fechahora(last_evento.fechahora), last_evento.texto)
                else:
                    last_evento = ""
                model[path][5] = last_evento
            elif id < 0:  # Ahora los id negativos son de abonos, no clientes.
                fda = pclases.FacturaDeAbono.get(-id)
                a = fda.abono
                import abonos_venta

                v = abonos_venta.AbonosVenta(a, usuario=self.usuario)
        else:
            cliente = pclases.Cliente.get(id)
            import clientes

            v = clientes.Clientes(cliente, usuario=self.usuario)
Esempio n. 18
0
    def buscar(self, boton):
        # DONE: Faltan los abonos por descontar.
        fechaini = self.wids["e_fechaini"].get_text().strip()
        if fechaini:
            try:
                fechaini = utils.parse_fecha(fechaini)
            except (ValueError, TypeError):
                utils.dialogo_info(
                    titulo="ERROR EN FECHA INICIAL",
                    texto="El texto «%s» no es una fecha correcta." % fechaini,
                    padre=self.wids["ventana"],
                )
                fechaini = None
        fechafin = self.wids["e_fechafin"].get_text().strip()
        if fechafin:
            try:
                fechafin = utils.parse_fecha(fechafin)
            except (ValueError, TypeError):
                utils.dialogo_info(
                    titulo="ERROR EN FECHA FINAL",
                    texto="El texto «%s» no es una fecha correcta." % fechafin,
                    padre=self.wids["ventana"],
                )
                fechafin = None
        if fechaini and fechafin and fechafin < fechaini:
            fechaini, fechafin = fechafin, fechaini
            self.wids["e_fechaini"].set_text(utils.str_fecha(fechaini))
            self.wids["e_fechafin"].set_text(utils.str_fecha(fechafin))
        if fechafin:
            FV = pclases.FacturaVenta
            VC = pclases.VencimientoCobro  # Para asegurarme de
            # que tiene vencimientos.
            FDA = pclases.FacturaDeAbono
            C = pclases.Cobro
            T = pclases.Tarea
            if fechaini:
                facturas = FV.select(
                    pclases.AND(FV.q.fecha >= fechaini, FV.q.fecha <= fechafin, VC.q.facturaVentaID == FV.q.id)
                )
                # Busco los abonos (facturas de abono, en realidad, que no
                # tienen por qué tener la misma fecha) que no hayan sido
                # incluidos en facturas (porque si no el importe ya se habría
                # contado en la factura anterior) ni en pagarés (porque
                # entonces ya estarían en un documento de pago y por tanto
                # no deberían aparecer en esta consulta)
                # ...
                # He decidido que no voy a sacar los abonos. No van a tener
                # ventana de seguimiento y no se le pueden relacionar tareas.
                # Además, esta ventana era para reclamar pagos, no para pagar.
                # abonos = FDA.select(pclases.AND(
                #    FDA.q.fecha >= fechaini,
                #    FDA.q.fecha <= fechafin))
                abonos = []
            else:
                facturas = FV.select(pclases.AND(FV.q.fecha <= fechafin, VC.q.facturaVentaID == FV.q.id))
                # abonos = FDA.select(FDA.q.fecha <= fechafin)
                abonos = []
            # No me queda otra que filtrar así aunque sea lento:
            abonos_pendientes = []
            for a in abonos:
                if not a.abono:
                    continue  # ¿Error de borrado de un abono? Mmm... mal rollo.
                if a.abono.facturasVenta:
                    continue
                if a.cobros:  # Cada cobro de abono está relacionado
                    # con un pagaré (o con lo que sea en un
                    # posible futuro, el caso es que no
                    # estaría pendiente).
                    continue
                abonos_pendientes.append(a)
            from ventana_progreso import VentanaProgreso

            vpro = VentanaProgreso(padre=self.wids["ventana"])
            vpro.mostrar()
            txtvpro = "Buscando facturas sin documento de pago..."
            nodos_clientes = {}
            total = 0.0
            i = 0.0
            vpro.set_valor(i, txtvpro)
            model = self.wids["tv_datos"].get_model()
            model.clear()
            facturas_added = []
            # Aprovecho para chequear alarmas automáticas.
            pclases.Alarma.crear_alarmas_automaticas(facturas)
            for f in facturas:
                # Aquí voy a hacer un segundo filtro usando la cantidad
                # pendiente de cobro de cada factura.
                # pendiente = f.calcular_pendiente_cobro()
                pendiente = f.calcular_pendiente_de_documento_de_pago()
                pendiente = round(pendiente, 2)
                if pendiente and f not in facturas_added:
                    total += pendiente
                    cliente = f.cliente
                    if cliente not in nodos_clientes:
                        tmp_nodo = model.append(None, (cliente.nombre, "", "", "", "0", "", cliente.id))
                        nodos_clientes[cliente] = {"nodo_cliente": tmp_nodo}
                    obra = f.obra
                    nodo_cliente_padre = nodos_clientes[cliente]["nodo_cliente"]
                    if obra not in nodos_clientes[cliente]:
                        nodos_clientes[cliente][obra] = model.append(
                            nodo_cliente_padre,
                            (obra and obra.nombre or "Sin obra", "", "", "", "0", "", obra and obra.id or 0),
                        )
                    fechas_vto = f.vencimientosCobro[:]
                    fechas_vto.sort(lambda v1, v2: (v1.fecha < v2.fecha and -1) or (v1.fecha > v2.fecha and 1) or 0)
                    fechas_vto = [utils.str_fecha(v.fecha) for v in f.vencimientosCobro]
                    vtos = "; ".join(fechas_vto)
                    nodo_padre = nodos_clientes[cliente][obra]
                    last_evento = f.get_last_evento()
                    if last_evento:
                        last_evento = "[%s] %s" % (utils.str_fechahora(last_evento.fechahora), last_evento.texto)
                    else:
                        last_evento = ""
                    model.append(
                        nodo_padre,
                        (
                            "",
                            # (f.cliente.nombre,
                            f.numfactura,
                            utils.str_fecha(f.fecha),
                            vtos,
                            utils.float2str(pendiente),
                            last_evento,
                            f.id,
                        ),
                    )
                    model[nodo_padre][4] = utils.float2str(utils._float(model[nodo_padre][4]) + pendiente)
                    model[nodo_cliente_padre][4] = utils.float2str(
                        utils._float(model[nodo_cliente_padre][4]) + pendiente
                    )
                    facturas_added.append(f)
                i += 1
                vpro.set_valor(i / (facturas.count() + len(abonos_pendientes)), txtvpro)
            for a in abonos_pendientes:
                pendiente = a.calcular_importe_total()  # O está descontada
                # entera o no lo está. Con los abonos no hay pagos parciales.
                pendiente = round(pendiente, 2)
                if pendiente:
                    total += pendiente
                    vtos = utils.str_fecha(a.fecha)  # Tampoco tiene
                    # vencimientos. La obligación nace desde el mismo día
                    # en que el abono se convierte en factura de abono.
                    try:
                        cliente = a.cliente
                    except AttributeError:
                        txt = (
                            "crm_seguimiento_impagos.py::buscar"
                            " -> FacturaDeAbono %d sin Abono o Cliente."
                            " Ignorando. " % a.id
                        )
                        self.logger.error(txt)
                        continue
                    if cliente not in nodos_clientes:
                        tmp_nodo = model.append(None, (cliente.nombre, "", "", "", "0", "", cliente.id))
                        nodos_clientes[cliente] = {"nodo_cliente": tmp_nodo}
                    obra = a.obra
                    nodo_cliente_padre = nodos_clientes[cliente]["nodo_cliente"]
                    if obra not in nodos_clientes[cliente]:
                        nodos_clientes[cliente][obra] = model.append(
                            nodo_cliente_padre,
                            (obra and obra.nombre or "Sin obra", "", "", "", "0", "", obra and obra.id or 0),
                        )
                    nodo_padre = nodos_clientes[cliente][obra]
                    model.append(
                        nodo_padre,
                        # (a.cliente.nombre,
                        (
                            "",
                            a.numfactura,
                            utils.str_fecha(a.fecha),
                            vtos,
                            utils.float2str(pendiente),
                            "",  # Facturas de abono no tienen anotaciones.
                            -a.id,
                        ),
                    )  # Para distinguirlo de las facturas.
                    model[nodo_padre][4] = utils.float2str(utils._float(model[nodo_padre][4]) + pendiente)
                    model[nodo_cliente_padre][4] = utils.float2str(
                        utils._float(model[nodo_cliente_padre][4]) + pendiente
                    )
                i += 1
                vpro.set_valor(i / (facturas.count() + len(abonos_pendientes)), txtvpro)
            vpro.ocultar()
            self.wids["e_total"].set_text(utils.float2str(total))
            self.buscar_todos()
            self.buscar_anotaciones()
            self.buscar_alertas()