예제 #1
0
 def cambiar_precio(self, cell, path, texto):
     try:
         precio = float(texto)
     except:
         utils.dialogo_info(titulo = "ERROR FORMATO", 
                            texto = "El texto %s no es un número." % texto, 
                            padre = self.wids['ventana'])
     else:
         model = self.wids['tv_ldvs'].get_model()
         ldc = pclases.LineaDeCompra.get(model[path][-1])
         ldc.precio = precio
         # CWT: Si el precio cambia al alza, respetar porcentaje. Si meto 
         # un precio inferior, entonces respetar el precio final de las 
         # tarifas y adaptar el porcentaje a ese precio de forma que nunca 
         # venda más barato al cambiar el precio del proveedor.
         pc = ldc.productoCompra
         pc.sync()
         if precio > pc.precioDefecto:
             # Si el precio sube, actualizo tarifas respetando porcentajes.
             for t in pclases.Tarifa.select(orderBy = "nombre"):
                 if t.vigente:
                     porcentaje = t.get_porcentaje(pc, fraccion = True)
                     nuevo_precio = precio * (1 + porcentaje)
                     t.asignarTarifa(pc, nuevo_precio)
         # Si el precio ha bajado o se mantiene, respeto precio final. La 
         # ventana ya calculará el porcentaje que sea.
         pc.precioDefecto = precio
         pc.syncUpdate()
         self.actualizar_ventana()
예제 #2
0
 def cambiar_resultado(self, tv, path, texto):
     model = self.wids["tv_pruebas"].get_model()
     prueba = claseprueba.get(model[path][-1])
     try:
         prueba.resultado = float(texto)
     except:
         utils.dialogo_info("RESULTADO INCORRECTO", "El número tecleado (%s) no es correcto." % texto)
     self.rellenar_pruebas()
    def cambiar_cantidad(self, cell, path, texto):
        """
        Cambia la cantidad de una linea de venta de un albarán de entrada,
        en el caso de que se escriba una cantidad menor de la que estaba en
        el pedido de compra (si es que tenía uno asociado), se desdobla la
        línea de venta original en dos líneas: una con el albarán asociado
        (por lo que deja de estar pendiente) y otra con la cantidad pendiente
        que no queda asociada al albarán. Si en el pedido quedara alguna LDV 
        sin "albaranear" del mismo producto, al mismo precio, etc... esta 
        segunda línea con la cantidad excedente se suma a la del pedido y se 
        elimina, para evitar líneas sueltas de cantidades pequeñas.
        En el caso de que se escriba una cantidad mayor a la que estaba
        originalmente en el pedido se darán dos opciones:
        - Crear una nueva linea de compra sin pedido asociado, con la cantidad
          incrementada.
        - Incrementar la cantidad en la línea de compra del pedido original.
        
        ...

        Bla, bla, bla, bla.
        ¡Hola! Soy Troy McLure. Tal vez me recuerden de otros cambios de requisitos en caliente como
        «cambiemos "en albarán" por "albaraneada"», «vendamos productos de compra sin manufacturar» o 
        «tal vez necesitemos un histórico de existencias»...
        Todo lo de arriba YA NO SIRVE. Ahora, con las nuevas líneas de pedido de compra, la cantidad se 
        aumenta directamente en la línea de compra y santas pascuas.
        """
        try:
            cantidad = float(texto)
        except:
            return
        model = self.wids['tv_ldvs'].get_model()
        try:
            ldc = pclases.LineaDeCompra.get(model[path][-1])
        except pclases.SQLObjectNotFound:
            utils.dialogo_info(titulo = "LÍNEA BORRADA", 
                               texto = "La línea seleccionada fue eliminada desde otro puesto.", 
                               padre = self.wids['ventana'])
        else:
            antigua = ldc.cantidad
            ldc.cantidad = cantidad
            if ldc.productoCompra.controlExistencias:
                # XXX DEBUG
                #print ldc.productoCompra.existencias
                # XXX EODEBUG
                diferencia = cantidad - antigua
                ldc.productoCompra.sync() 
                ldc.productoCompra.existencias += diferencia 
                ldc.productoCompra.add_existencias(diferencia, 
                                                   almacen=self.objeto.almacen)
                ldc.productoCompra.syncUpdate() 
                ldc.productoCompra.sync() 
                # XXX DEBUG
                #print ldc.productoCompra.existencias
                # XXX EODEBUG
            if ldc.cargaSilo:
                ldc.cargaSilo.cantidad = cantidad
        self.actualizar_ventana()
 def cambiar_precio(self, cell, path, texto):
     try:
         precio = float(texto)
     except:
         return
     model = self.wids['tv_ldvs'].get_model()
     ldc = pclases.LineaDeCompra.get(model[path][-1])
     ldc.precio = precio
     self.actualizar_ventana()
 def pedir_cantidad(self):
     cant = utils.dialogo_entrada(titulo = '¿CANTIDAD?',
                                  texto = 'Introduzca cantidad', 
                                  valor_por_defecto = '1', 
                                  padre = self.wids['ventana'])
     try:
         cant = float(cant)
     except:
         utils.dialogo_info(titulo = 'ERROR EN CANTIDAD', 
                            texto = 'Cantidad incorrecta.\nAsegúrese de escribirla con punto (.) como separador decimal.\nSe añadirá el producto al albarán, modifique la cantidad directamente ahí.', 
                            padre = self.wids['ventana'])
         cant = 1
     return cant
예제 #6
0
 def cambiar_precio_tarifa(self, cell, path, texto, idtarifa):
     try:
         precio = float(texto)
     except:
         utils.dialogo_info(titulo = "ERROR FORMATO", 
                            texto = "El texto %s no es un número." % texto, 
                            padre = self.wids['ventana'])
     else:
         model = self.wids['tv_ldvs'].get_model()
         ldc = pclases.LineaDeCompra.get(model[path][-1])
         producto = ldc.productoCompra
         tarifa = pclases.Tarifa.get(idtarifa)
         precio_sin_iva = precio / 1.21
         tarifa.asignarTarifa(producto, precio_sin_iva)
         self.actualizar_ventana()
예제 #7
0
 def rellenar_tabla(self, partes, solobalas):
     """
     Rellena el model con los partes rescatados de la BD en `buscar`.
     PRERREQUISITO:
         Los partes vienen en una lista y deben estar ordenados por fecha y
         hora de inicio.
     """
     # Lo primero de todo. Si está activado el DEBUG, muestro las columnas.
     tv = self.wids['tv_datos']
     for ncol in range(7, len(tv.get_columns())):
         tv.get_column(ncol).set_property("visible", pclases.DEBUG)
     self.huecos = []    # Lista de los últimos partes tratados por línea.
     self.incidencias_horaini = []
     self.incidencias_horafin = []
     self.tiempo_faltante = mx.DateTime.TimeDeltaFrom(0)
     vpro = VentanaProgreso(padre = self.wids['ventana'])
     model = self.wids['tv_datos'].get_model()
     model.clear()
     total = 0
     kilosproducidos = 0
     kilosgranza = 0
     vector = []
     tot = len(partes)
     i = 0.0
     vpro.mostrar()
     e_personasturno = 0
     tiempototal = 0
     tiempo_sin_incidencias = 0  # Por si inicia una consulta sin resultados
     metrosproducidos = 0
     kilosconsumidos = kilosconsumidos_partidas_completas = 0
     tiempototaltotal = mx.DateTime.DateTimeDelta(0)
     #selffin = utils.parse_fecha('/'.join(self.fin.split('/')[::-1]))
     selffin = self.fin
     # ... WTF? Esto está hecho como el culo. ¡REFACTORIZAR!
     # XXX Primer intento de acelerar los treeview
     self.wids['tv_datos'].freeze_child_notify()
     self.wids['tv_datos'].set_model(None)
     # XXX
     personashora = []
     dia_actual = ""     # Estos tres parámetros son para medir la
                         # producción y productividad por día.
     produccion_actual = 0.0
     #productividad_actual = 0.0
     t_teorico_por_dia = 0
     t_real_por_dia = 0
     pdps_dia = []   # Ojo. Los partes deben venir ordenados para que
         # esta lista solo contenga los partes del día tratado en la
         # iteración por la que vaya. Se limpia al cambiar de un día al
         # siguiente mientras relleno los datos.
     #nodos_hijos_por_dia = 0
     balas_consumidas = []       # Lista con las balas consumidas por
         # todos los partes, así evito contar la misma dos veces si en dos
         # partes se ha usado la misma partida o dos partidas de la misma
         # partida de carga.
     padre = None # En una de las iteraciones se espera que padre se haya
         # instanciado en el final de la anterior. Inicializo para evitar
         # errores y errores en análisis sintáctico de algunos IDE en la
         # línea 342.
     for pdp in partes:
         if pdp.se_solapa():
             texto_warning = "%sconsulta_productividad::rellenar_tabla"\
                 " -> El parte ID %d se solapa con otros de la misma línea"\
                 ". Si estaba verificado, lo desbloqueo para que se vuelva"\
                 " a revisar y lo ignoro para el cálculo actual." % (
                  self.usuario and self.usuario.usuario + ": " or "", pdp.id)
             self.logger.warning(texto_warning)
             myprint(texto_warning)
             pdp.bloqueado = False
             continue
         vpro.set_valor(i/tot, 'Añadiendo parte %s...' % (
                                 utils.str_fecha(pdp.fecha)))
         delta_entre_partes, parte_anterior = detectar_hueco(pdp, self.huecos)
         if delta_entre_partes:
             self.marcar_hueco(parte_anterior, pdp)
         self.tiempo_faltante += delta_entre_partes
         kilosgranza_del_parte = 0.0
         (tiempototal,
          tiempo_sin_incidencias) = self.calcular_tiempo_trabajado(pdp)
         tiempototaltotal += tiempototal
         #productividad = pdp.calcular_productividad()
         # CWT: Ahora no se calcula así, sino como el antiguo rendimiento.
         productividad = pdp.calcular_rendimiento()
         # Tratamiento especial para partes de balas
         try:
             str_producto = pdp.productoVenta.descripcion
         except AttributeError:
             str_producto = "Sin producción"
         if (self.wids['r_balas'].get_active()
             or self.wids['r_ambos'].get_active()):   # Sólo balas o todos.
             if pdp.es_de_fibra():
                 balas = [a.bala for a in pdp.articulos if a.balaID != None]
                 bigbags = [a.bigbag for a in pdp.articulos if a.bigbagID != None]
                 for b in balas:
                     kilosproducidos += b.pesobala
                 for b in bigbags:
                     kilosproducidos += b.pesobigbag
                 kilosgranza_del_parte = pdp.get_granza_consumida()
                 kilosgranza += kilosgranza_del_parte
                 if pdp.get_produccion()[0] - kilosgranza_del_parte > 1000:
                                                                 # XXX DEBUG
                     self.logger.warning("El parte ID %d (%s) ha consumido "
                             "(%s) mucha menos granza que fibra ha "
                             "producido (%s) !!!" % (pdp.id,
                                 utils.str_fecha(pdp.fecha),
                                 utils.float2str(kilosgranza_del_parte),
                                 utils.float2str(pdp.get_produccion()[0])))
                                                                 # XXX DEBUG
         if (self.wids['r_cemento'].get_active()
             or self.wids['r_ambos'].get_active()):
             kilosproducidos += pdp.get_produccion()[0]
             kilosconsumidos += sum([bb.pesobigbag for bb in pdp.bigbags])
         if (self.wids['r_rollos'].get_active()
             or self.wids['r_ambos'].get_active()):  # Sólo rollos o todos.
             if pdp.es_de_geotextiles():
                 superficies_defectuosos = [a.superficie
                     for a in pdp.articulos if a.es_rollo_defectuoso()]
                 metrosproducidos += sum(superficies_defectuosos)
                 rollos = [a.rollo for a in pdp.articulos if a.rollo != None]
                 if len(rollos) > 0:     # Para que no intente hacer el
                     # cálculo con partes que tengan balas y/o no rollos.
                     pv = pdp.articulos[0].productoVenta
                     cer = pv.camposEspecificosRollo
                     metrosproducidos += (len(rollos)
                                          * cer.metros_cuadrados)
                     if pdp.articulos[0].es_rollo():
                         partida = pdp.articulos[0].rollo.partida
                     elif pdp.articulos[0].es_rollo_defectuoso():
                         partida = pdp.articulos[0].rolloDefectuoso.partida
                     else:
                         partida = None
                     if partida != None:
                         contar_kilosconsums_partidas_completas \
                                 = partida.entra_en_cota_superior(selffin)
                         for b in partida.balas:
                             if b not in balas_consumidas:   # Evito contar
                                                 # la misma bala dos veces.
                                 bpesobala = b.pesobala
                                 kilosconsumidos += bpesobala
                                 if contar_kilosconsums_partidas_completas:
                                     kilosconsumidos_partidas_completas \
                                             += bpesobala
                                 balas_consumidas.append(b)
         empleados = len(pdp.horasTrabajadas)
         e_personasturno += empleados
         tiempoparte = pdp.get_duracion().hours
         if tiempoparte > 0:
             personashora.append(empleados/tiempoparte)
         else:
             personashora.append(0.0)
         vector.append(productividad)
         produccion = pdp.get_produccion()
         # Resúmenes por día como nodos padre del TreeView.
         if not dia_actual:
             pdps_dia.append(pdp)
         if dia_actual == utils.str_fecha(pdp.fecha):
             pdps_dia.append(pdp)
         else:
             if dia_actual != "":  # Actualizo el padre
                 if not self.wids['r_ambos'].get_active():
                     model[padre][4] = "%s %s" % (
                             utils.float2str(produccion_actual),
                             produccion[1])
                 else:   # Evito mezclar kilos con metros
                     model[padre][4] = "-"
                 productividad_actual = calcular_productividad_conjunta(
                         tuple(pdps_dia))
                 model[padre][5] = "%s %%" % (
                         utils.float2str(productividad_actual))
                 model[padre][6] = min(productividad_actual, 100)
                 model[padre][7] = t_teorico_por_dia
                 model[padre][8] = t_real_por_dia
                 pdps_dia = [pdp] # He cambiado de día. Limpio.
                 t_teorico_por_dia = 0
                 t_real_por_dia = 0
             dia_actual = utils.str_fecha(pdp.fecha)
             produccion_actual = 0.0
             productividad_actual = 0.0
             #nodos_hijos_por_dia = 0
             padre = model.append(None,
                         (dia_actual,
                          "",
                          "",
                          "",
                          "",
                          "%s %%" % (utils.float2str(productividad_actual)),
                          min(productividad_actual, 100),
                          "", # t. teórico
                          "", # t. real
                          0))
         t_teorico_pdp = pdp.calcular_tiempo_teorico()
         t_teorico_por_dia += t_teorico_pdp
         t_real_pdp = pdp.calcular_tiempo_real()
         t_real_por_dia += t_real_pdp
         model.append(padre,
             (utils.str_fecha(pdp.fecha),
              str(pdp.horainicio)[:5],
              str(pdp.horafin)[:5],
              str_producto,
              "%s %s" % (utils.float2str(produccion[0]), produccion[1]),
              "%s %%" % (utils.float2str(productividad)),
              min(productividad, 100),
              t_teorico_pdp,
              t_real_pdp,
              pdp.id))
         produccion_actual += produccion[0]
         i+=1
     # Actualizo el padre de los últimos nodos:
     if dia_actual != "":  # Actualizo el padre
         if not self.wids['r_ambos'].get_active():
             model[padre][4] = "%s %s" % (
                     utils.float2str(produccion_actual), produccion[1])
         else:   # Evito mezclar kilos con metros
             model[padre][4] = "-"
         productividad_actual = calcular_productividad_conjunta(
                                                         tuple(pdps_dia))
         model[padre][5] = "%s %%" % (utils.float2str(productividad_actual))
         model[padre][6] = min(productividad_actual, 100)
         # Campos de depuración
         model[padre][7] = t_teorico_por_dia
         model[padre][8] = t_real_por_dia
     vpro.ocultar()
     # XXX Primer intento de acelerar los treeview
     self.wids['tv_datos'].set_model(model)
     self.wids['tv_datos'].thaw_child_notify()
     # XXX
     if partes != []:
         total = calcular_productividad_conjunta(tuple(partes))
         # Campos especiales de "Sólo balas"
         if self.wids['r_balas'].get_active():
             self.wids['label7'].set_text('Kilos producidos:')
             self.wids['label8'].set_text('Kilos granza consumidos:')
             self.wids['label9'].set_text('Kilos / Hora producción:')
             self.wids['e_kilosproducidos'].set_text(
                 "%s kg" % (utils.float2str(kilosproducidos)))
             self.wids['e_kilosgranza'].set_text(
                 "%s kg" % (utils.float2str(kilosgranza)))
             try:
                 e_kiloshora = (kilosproducidos
                                 /float(tiempototaltotal.hours))
             except ZeroDivisionError:
                 self.logger.warning(
                         "consulta_productividad.py::rellenar_tabla"
                         " -> tiempototaltotal = 0")
                 e_kiloshora = 0  # Cero por poner algo. Porque un parte
                                  # de tiempo transcurrido=0... se las trae.
             self.wids['e_kiloshora'].set_text("%s kg/h" % (
                                             utils.float2str(e_kiloshora)))
         elif self.wids['r_rollos'].get_active():
             tips = gtk.Tooltips()
             tips.set_tip(self.wids['e_kilosgranza'],
                          "Kilogramos consumidos contando partidas "
                          "completas por defecto y por exceso.\n(En un caso"
                          " se cuentan solo partidas de carga cuyas "
                          "partidas de geotextiles se hayan completado "
                          "estrictamente antes o en la cota superior.\n"
                          "En el otro, por exceso, se contabilizan "
                          "partidas completas aunque parte de su "
                          "producción se salga del rango de fechas.\n"
                          "En ambos casos el límite inferior es flexible "
                          "-por compensación-.)")
             tips.enable()
             self.wids['label7'].set_text('m² producidos:')
             self.wids['label8'].set_text('Kg fibra consumidos:')
             self.wids['label9'].set_text('m²/h producción:')
             try:
                 e_kiloshora = (metrosproducidos/float(tiempototaltotal.hours))
             except ZeroDivisionError:
                 self.logger.warning(
                         "consulta_productividad.py::rellenar_tabla -> "
                         "tiempototaltotal = 0")
                 e_kiloshora = 0
             self.wids['e_kilosproducidos'].set_text("%s m²" % (
                 utils.float2str(metrosproducidos)))
             if kilosconsumidos_partidas_completas != kilosconsumidos:
                 self.wids['e_kilosgranza'].set_text("%s kg ~ %s kg" % (
                     utils.float2str(kilosconsumidos_partidas_completas),
                     utils.float2str(kilosconsumidos)))
             else:
                 self.wids['e_kilosgranza'].set_text("%s kg" % (
                     utils.float2str(kilosconsumidos)))
             self.wids['e_kiloshora'].set_text("%s m²/h" % (
                 utils.float2str(e_kiloshora)))
         else:
             self.wids['label7'].set_text('Producido:')
             self.wids['label8'].set_text('Consumido:')
             self.wids['label9'].set_text('Producción combinada a la hora:')
             try:
                 e_kiloshora = (kilosproducidos/float(tiempototaltotal.hours))
                 metros_hora = (metrosproducidos/float(tiempototaltotal.hours))
             except ZeroDivisionError:
                 self.logger.warning("consulta_productividad.py::"
                         "rellenar_tabla -> tiempototaltotal = 0")
                 e_kiloshora = 0
                 metros_hora = 0
             self.wids['e_kilosproducidos'].set_text("%s m²; %s kg" % (
                 utils.float2str(metrosproducidos),
                 utils.float2str(kilosproducidos)))
             self.wids['e_kilosgranza'].set_text(
                     "%s kg fibra; %s kg granza" % (utils.float2str(
                         kilosconsumidos), utils.float2str(kilosgranza)))
             self.wids['e_kiloshora'].set_text("%s m²/h; %s kg/h" % (
                 utils.float2str(metros_hora),
                 utils.float2str(e_kiloshora)))
         # Fin campos especiales de "Sólo balas"
         self.wids['curva'].set_range(0, len(vector), 0, 100)
         self.wids['curva'].set_vector(vector)
         self.wids['curva'].set_curve_type(gtk.CURVE_TYPE_SPLINE)
         # self.wids['curva'].set_curve_type(gtk.CURVE_TYPE_LINEAR)
         self.wids['pb'].set_fraction(max(min(total, 100), 0) / 100.0)
     else:
         self.wids['curva'].set_range(0, 2, 0, 100)
         self.wids['curva'].set_vector((0, 0))
         self.wids['pb'].set_fraction(1 / 100.0)
         self.wids['e_kilosproducidos'].set_text('')
         self.wids['e_kilosgranza'].set_text('')
         self.wids['e_kiloshora'].set_text('')
     self.wids['e_total'].set_text("%s %%" % (utils.float2str(total)))
     try:
         personashora = sum(personashora)/len(personashora)
     except ZeroDivisionError:
         personashora = 0
     try:
         e_personasturno = float(e_personasturno) / len(partes)
     except ZeroDivisionError:
         e_personasturno = 0
     self.wids['e_personasturno'].set_text("%s (%s personas/h)" % (
         utils.float2str(e_personasturno), utils.float2str(personashora)))
     self.wids['e_tiempo_faltante'].set_text(
             self.tiempo_faltante
             and (str_horas(self.tiempo_faltante) + " h")
             or "")
     self.wids['e_tiempo_partes'].set_text(
             str_horas(tiempototaltotal) + " h")