コード例 #1
0
ファイル: partes_de_visita.py プロジェクト: pacoqueen/ginn
 def enviar_correo_visitas_confirmadas(self, confirmadas = []):
     """
     Igual que en ofertas, se envía un correo a quien corresponde con el
     resumen del día, destacando las recién confirmadas.
     """
     dests = select_correo_validador(self.usuario,
                                     copia_a_dircomercial = True)
     if not isinstance(dests, (list, tuple)):
         dests = [dests]
     servidor = self.usuario.smtpserver
     smtpuser = self.usuario.smtpuser
     smtppass = self.usuario.smtppassword
     rte = self.usuario.email
     year, month, day = self.wids['calendario'].get_date()
     fecha = datetime.date(year = year, month = month, day = day)
     texto = "Resumen de visitas de %s para el día %s:\n\n" % (
                     self.objeto.get_nombre_completo(),
                     utils.str_fecha(fecha))
     # TODO: Empepinar el correo usando una tabla HTML. No es tan difícil.
     for row in self.wids['tv_visitas'].get_model():
         visita = pclases.getObjetoPUID(row[-1])
         if not visita.enviada:
             continue
         texto += "%s%s\t%s%s\t%s\t%s\t%s%s\n" % (
                 visita in confirmadas and "*" or "",
                 utils.str_hora_corta(visita.fechahora),
                 visita.nombrecliente,
                 visita.cliente and "" or " (+)",
                 visita.lugar and visita.lugar or "",
                 visita.motivoVisita and visita.motivoVisita.motivo or "",
                 visita.observaciones,
                 visita in confirmadas and "*" or ""
                 )
     ok = utils.enviar_correoe(rte,
                               dests,
                               "Parte de visitas confirmado (%s)" 
                                 % utils.str_fecha(fecha),
                               texto,
                               servidor = servidor,
                               usuario = smtpuser,
                               password = smtppass)
     if ok:
         self.to_log(
             "Usuario %s envió correo de confirmación de visitas "
             "para el día %s."
                 % (self.usuario and self.usuario.usuario or "¡NADIE!",
                    utils.str_fecha(fecha)),
             nivel = 3)  # info
     else:
         self.to_log(
             "Falló envío de correo de solicitud de validación de la "
             "oferta %s del usuario %s."
                 % (utils.str_fecha(fecha),
                    self.usuario and self.usuario.usuario or "¡NADIE!"),
             nivel = 1)  # error
コード例 #2
0
ファイル: partes_de_visita.py プロジェクト: pacoqueen/ginn
 def add_visita_a_tv(self, visita):
     fila = (utils.str_hora_corta(visita.fechahora),
             visita.enviada and gtk.STOCK_DIALOG_AUTHENTICATION or None,
             visita.nombrecliente,
             visita.cliente and gtk.STOCK_SAVE or gtk.STOCK_NEW,
             visita.lugar and visita.lugar or "",
             visita.lugar and gtk.STOCK_FIND or "",  # TODO: Geolocalizar y marcar si lugar reconocido en lugar de buscar en google maps.
             # TODO: API de Google maps?
             visita.motivoVisita and visita.motivoVisita.motivo or "",
             visita.observaciones,
             visita.puid)
     model = self.wids['tv_visitas'].get_model()
     model.append(fila)
コード例 #3
0
ファイル: build_salarios.py プロジェクト: Virako/fpinn
 def rellenar_tabla(self):
 	"""
     Rellena el model con los items de la consulta.
     Elementos es un diccionario con objetos cuentaGastos y una lista  
     de gastos correspondientes a los meses de consulta.
     """        
 	model = self.wids['tv_datos'].get_model()
 	model.clear()
     jornales = pclases.Jornal.select(pclases.Jornal.q.salarioID == None, 
                                      orderBy = "fechahoraInicio")
 	for jornal in jornales:
         try:
             nombre_completo_empleado = jornal.empleado.nombre
         except AttributeError:
             nombre_completo_empleado = "¡SIN EMPLEADO!"
         info_jornal = "%s. De %s a %s. Producción: %s." % (
             utils.str_fecha(jornal.fechahoraInicio), 
             utils.str_hora_corta(jornal.fechahoraInicio), 
             utils.str_hora_corta(jornal.fechahoraFin), 
             utils.float2str(jornal.produccion))
         model.append((nombre_completo_empleado, 
                       info_jornal, 
                       False, 
                       jornal.id))
コード例 #4
0
def descontar_material_adicional(ventana_parte, articulo, restar = True):
    """
    Descuenta el material adicional correspondiente al artículo según
    la formulación que indique la línea de fabricación.
    Si "restar" es True, descuenta. Si es False, añade la cantidad (para
    cuando se elimine un rollo del parte, por ejemplo).
    Si es necesario, se dejará material con existencias en negativo, aunque
    se avisará al usuario de la incidencia.
    """
    producto = articulo.productoVenta
    # OJO: Debe llamarse "plastico", tal cual, sin acentos ni nada. No es lo
    # suyo, pero al menos hemos reducido el número de casos especiales.
    for consumoAdicional in producto.consumosAdicionales:
        consumido = consumoAdicional.consumir(articulo, cancelar = not restar)
        ventana_parte.logger.warning("Rollos C (%s-%s): Consumiendo %s de %s para el rollo C %s. Existencias: %s" % (
            utils.str_fecha(articulo.fechahora),
            utils.str_hora_corta(articulo.fechahora),
            utils.float2str(consumido),
            consumoAdicional.productoCompra.descripcion,
            articulo.codigo,
            utils.float2str(consumoAdicional.productoCompra.existencias)))
コード例 #5
0
def main():
    """
    Carga la lista de rollos y cambia el producto de venta de cada uno de ellos
    """
    productividades = {}
    rollos = load_rollos(productividades)
    total_rollos = sum([len(rollos[p]) for p in rollos])
    barra = IncrementalBar('Creando partes...', max=total_rollos)
    for producto in rollos:
        partida = crear_partida()
        for rollo in rollos[producto]:
            parte = determinar_pdp(rollo)
            asignar(rollo, parte, partida, productividades)
            barra.next()
    barra.finish()
    # Resumen de productividades:
    partes = productividades.keys()
    partes.sort(key=lambda p: p.productoVenta.descripcion)
    for pdp in partes:
        print pdp.get_info()
        print "\tAntes: %.2f\tDespués: %.2f\tDuración:%s" % (
            productividades[pdp], pdp.calcular_rendimiento(),
            utils.str_hora_corta(pdp.get_duracion()))
コード例 #6
0
    def rellenar_horas(self, b = None):
        """
        Rellena el model con las horas trabajadas en cada parte del 
        rango de fechas.
        """
        try:
            dia, mes, anno = map(int, self.wids['e_fecha'].get_text().split('/'))
        except:
            utils.dialogo_info(titulo = "FECHA INCORRECTA", texto = "La fecha no es correcta. Use el formato día/mes/año", padre = self.wids['ventana'])
            return
        fecha = mx.DateTime.DateTimeFrom(day = dia, month = mes, year = anno) 
        model = self.wids['tv_horas'].get_model()
        model.clear()

        partes_produccion = self.buscar_partes_produccion(fecha)
        empleados, aux = self.preparar_datos(partes_produccion, fecha)

        fecha_ini = fecha_fin = fecha
        ftini = mx.DateTime.DateTimeFrom(year = fecha_ini.year, 
                                         month = fecha_ini.month, 
                                         day = fecha_ini.day, 
                                         hour = 6, 
                                         minute = 0, 
                                         second = 0).strftime('%Y-%m-%d %H:%M:%S')
        ftfin = (mx.DateTime.DateTimeFrom(year = fecha_fin.year, 
                                         month = fecha_fin.month, 
                                         day = fecha_fin.day, 
                                         hour = 6, 
                                         minute = 0, 
                                         second = 0) + mx.DateTime.oneDay).strftime('%Y-%m-%d %H:%M:%S')
        partes_t = pclases.ParteDeTrabajo.select("""horainicio >= '%s' AND horainicio < '%s' """ % (ftini, ftfin))
        
        empleados = self.preparar_datos_recuperacion(empleados, partes_t, fecha, aux)

        self.convertir_valores_a_cadena(empleados)

        for empleado in empleados:
            e = pclases.Empleado.get(empleado['id'])
            try:
                laborable = [l for l in e.grupo.laborables if l.fecha == fecha][0]
                nombre_empleado = "%s (%s)" % (empleado['nombre'], laborable.turno.nombre[0])
            except AttributeError:
                nombre_empleado = empleado['nombre']    # No tiene grupo.
            except IndexError:
                nombre_empleado = empleado['nombre']    # No tiene laborables asignados.
            padre = model.append(None, (nombre_empleado,
                                        e.centroTrabajo and e.centroTrabajo.nombre or "",
                                        empleado['horainicio'],
                                        empleado['horafin'],
                                        empleado['horas'],
                                        empleado['noche'],
                                        empleado['extra'],
                                        empleado['gtx'],
                                        empleado['fib'],
                                        empleado['gmp'],
                                        empleado['mgtx'],
                                        empleado['mfib'],
                                        empleado['mgmp'],
                                        empleado['almacen'],
                                        empleado['varios'],
                                        empleado['observaciones'],
                                        empleado['id']))
            for parte in empleado['partes']:
                try:
                    hts = [ht for ht in parte.horasTrabajadas if ht.empleadoid == empleado['id']]
                    horas_en_parte_del_empleado = sum([ht.horas for ht in hts])
                    model.append(padre, (utils.str_fecha(parte.fecha),
                                         parte.es_de_balas() and "fibra" or "geotextil",    
                                            # PLAN: De geocompuestos y tapicerías ni hablamos.
                                         utils.str_hora_corta(parte.horainicio),
                                         utils.str_hora_corta(parte.horafin),
                                         utils.str_hora_corta(parte.get_duracion()),
                                         parte.es_nocturno(),
                                         "",
                                         not parte.es_de_balas() and \
                                            utils.str_hora_corta(horas_en_parte_del_empleado) or "",
                                         parte.es_de_balas() and \
                                            utils.str_hora_corta(horas_en_parte_del_empleado) or "",
                                         "-",   # PLAN: Hasta que esté habilitada la línea de geocompuestos.
                                         "",
                                         "",
                                         "",
                                         "",
                                         "",
                                         "",
                                         parte.id))
                except AttributeError:  # Es parte de trabajo.
                    # OJO: NOTA: HARCODED. Pero es que no encuentro otra 
                    # forma de hacerlo.
                    ct_gtx, ct_fib, ct_gmp, ct_almacen = self.get_centros()
                    ct = parte.centroTrabajo
                    mgtx = mfib = mgmp = almacen = varios = ""
                    if ct != None and ct == ct_gtx:
                        mgtx = utils.str_hora_corta(parte.horas)
                    elif ct != None and ct == ct_fib:
                        mfib = utils.str_hora_corta(parte.horas)
                    elif ct != None and ct == ct_gmp:
                        mgmp = utils.str_hora_corta(parte.horas)
                    elif ct != None and ct == ct_almacen:
                        almacen = utils.str_hora_corta(parte.horas)
                    else:
                        varios = utils.str_hora_corta(parte.horas)
                    horas_en_parte_del_empleado = parte.horas
                    model.append(padre, 
                      (utils.str_fecha(parte.horainicio),
                       parte.centroTrabajo and parte.centroTrabajo.nombre or "",
                       utils.str_hora_corta(parte.horainicio),
                       utils.str_hora_corta(parte.horafin),
                       utils.str_hora_corta(parte.horas),
                       parte.es_nocturno(),
                       "",
                       "",
                       "",
                       "-",
                       mgtx,
                       mfib,
                       mgmp,
                       almacen,
                       varios,
                       parte.trabajo,
                       parte.id))
        # Ahora los que no trabajaron:
        all_emps = pclases.Empleado.select(
            pclases.AND(pclases.Empleado.q.planta == True,
                        pclases.Empleado.q.activo == True))
        ids_emps_trabajo = [e['id'] for e in empleados]
        descanso = [e for e in all_emps if e.id not in ids_emps_trabajo]
        mesAnno = mx.DateTime.DateTimeFrom(day = 1, mes = fecha.month, year = fecha.year) 
            # Los calendarios laborales siempre tienen 1 en el día.
        calendarios = pclases.CalendarioLaboral.select(pclases.CalendarioLaboral.q.mesAnno == mesAnno)
        for e in descanso:
            categoria = e.categoriaLaboral
            motivo = ""
            motivo_abr = " (D)"
            if categoria != None:
                try:
                    calendario = [c for c in calendarios if c.lineaDeProduccion == categoria.lineaDeProduccion][0]
                    if fecha in [f.fecha for f in calendario.festivos]:
                        motivo = "FESTIVO"
                        motivo_abr = " (FS)"
                    elif fecha in [v.fecha for v in calendario.vacaciones]:
                        motivo = "VACACIONES"
                        motivo_abr = " (VC)"
                    elif fecha in [a.fecha for a in e.ausencias]:
                        ausencia = [a for a in e.ausencias if a.fecha == fecha][0]
                        if ausencia.motivo != None:
                            motivo = ausencia.motivo.descripcion
                            if ausencia.motivo.convenio:
                                motivo_abr = " (DC)"
                            else:
                                motivo_abr = " (BL)"
                        else:
                            motivo = "PERMISO SOLICITADO"
                            motivo_abr = " (AP)"
                except IndexError:
                    pass    # No hay calendario relacionado con el trabajador. Puede que le falte categoría laboral,
                            # que ésta no tenga linea de producción o que no se haya asignado aún un calendario.
            model.append(None,("%s, %s%s" % (e.apellidos, e.nombre, motivo_abr),
                               e.centroTrabajo and e.centroTrabajo.nombre or "",
                               "--",
                               "--",
                               "--",
                               "",
                               "",
                               "",
                               "",
                               "",
                               "",
                               "",
                               "",
                               "",
                               "",
                               motivo,
                               e.id))
コード例 #7
0
ファイル: horas_trabajadas.py プロジェクト: pacoqueen/ginn
 def mostrar_horas(self, tv, path, vc):
     """
     Abre una ventana de búsqueda con las horas trabajadas en 
     partes de producción y partes de trabajo.
     """
     # EMPLEADO
     self.wids['ventana'].window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
     while gtk.events_pending(): gtk.main_iteration(False)
     model = tv.get_model()
     idempleado = model[path][-1]
     empleado = pclases.Empleado.get(idempleado)
     # PARTES DE PRODUCCIÓN
     try:
         dia, mes, anno = map(int, self.wids['e_fecha_ini'].get_text().split('/'))
     except:
         utils.dialogo_info(titulo = "FECHA INCORRECTA", texto = "La fecha inicial no es correcta. Use el formato día/mes/año")
     else:
         fecha_ini = mx.DateTime.DateTimeFrom(day = dia, month = mes, year = anno) 
         dia, mes, anno = map(int, self.wids['e_fecha_fin'].get_text().split('/'))
         try:
             fecha_fin = mx.DateTime.DateTimeFrom(day = dia, month = mes, year = anno) 
         except:
             utils.dialogo_info(titulo = "FECHA INCORRECTA", texto = "La fecha inicial no es correcta. Use el formato día/mes/año")
         else:
             partes_produccion = self.buscar_partes_produccion(fecha_ini, fecha_fin)
             horas_trabajadas = []   # Horas en partes de producción
             horas_recuperacion = [] # Horas en partes de trabajo
             for pdp in partes_produccion:
                 for ht in pdp.horasTrabajadas:
                     if ht.empleado == empleado:
                         horas_trabajadas.append(("PDP:%d" % (ht.parteDeProduccion.id), 
                                                  utils.str_fecha(pdp.fecha), 
                                                  utils.str_hora_corta(pdp.horainicio), 
                                                  utils.str_hora_corta(pdp.horafin), 
                                                  utils.str_hora_corta(pdp.get_duracion()), 
                                                  utils.str_hora_corta(ht.horas), 
                                                  pdp))
     # PARTES DE TRABAJO
             ftini = mx.DateTime.DateTimeFrom(year = fecha_ini.year, 
                                               month = fecha_ini.month, 
                                               day = fecha_ini.day, 
                                               hour = 6, 
                                               minute = 0, 
                                               second = 0).strftime('%Y-%m-%d %H:%M:%S')
             ftfin = (mx.DateTime.DateTimeFrom(year = fecha_fin.year, 
                                               month = fecha_fin.month, 
                                               day = fecha_fin.day, 
                                               hour = 6, 
                                               minute = 0, 
                                               second = 0) + mx.DateTime.oneDay).strftime('%Y-%m-%d %H:%M:%S')
             partes_trabajo = pclases.ParteDeTrabajo.select("""horainicio >= '%s' AND horainicio < '%s' """ % (ftini, ftfin))
             for pdt in partes_trabajo:
                 if pdt.empleado == empleado:
                     horas_recuperacion.append(("PDT:%d" % (pdt.id), 
                                                utils.str_fecha(pdt.horainicio), 
                                                utils.str_hora_corta(pdt.horainicio), 
                                                utils.str_hora_corta(pdt.horafin), 
                                                utils.str_hora_corta(pdt.get_duracion()), 
                                                utils.str_hora_corta(pdt.get_duracion()), 
                                                pdt)) 
             horas = horas_trabajadas + horas_recuperacion
             horas.sort(lambda x, y: utils.orden_por_campo_o_id(x[-1], y[-1], "fecha"))
             horas = [i[:-1] for i in horas]
     # DIÁLOGO RESULTADOS
             id_parte = utils.dialogo_resultado(horas, 
                                                "Horas trabajadas de producción y partes de trabajo de %s %s:" % (empleado.nombre, empleado.apellidos), 
                                                multi = False, 
                                                padre = self.wids['ventana'], 
                                                cabeceras = ("ID", "Fecha", "Hora inicio", "Hora fin", "Duración", "Horas trabajadas"))
             if id_parte != -1:
                 tipo, ide = id_parte.split(":")
                 self.wids['ventana'].window.set_cursor(None)
                 if tipo == "PDP": 
                     parte = pclases.ParteDeProduccion.get(ide)
                     if parte.es_de_geotextiles():
                         from formularios import partes_de_fabricacion_rollos
                         v = partes_de_fabricacion_rollos.PartesDeFabricacionRollos(objeto = parte, usuario = self.usuario)  # @UnusedVariable
                     elif parte.es_de_fibra():
                         from formularios import partes_de_fabricacion_balas
                         v = partes_de_fabricacion_balas.PartesDeFabricacionBalas(objeto = parte, usuario = self.usuario)  # @UnusedVariable
                 elif tipo == "PDT": 
                     parte = pclases.ParteDeTrabajo.get(ide)
                     from formularios import partes_de_trabajo
                     v = partes_de_trabajo.PartesDeTrabajo(objeto = parte, usuario = self.usuario)  # @UnusedVariable
     self.wids['ventana'].window.set_cursor(None)