Autor Tema: Java ejercicio proyecto menú gestión recursos humanos contratos nóminas salvar  (Leído 3379 veces)

luu_cuuesta

  • Visitante
Hola a todos, he empezado hace relativamente poco con la programación y en particular con el programa Java, así que disculpen mi ignorancia en algunos aspectos ;)

Llevo unos días con un proyecto pero me he atascado a la hora de realizar los Menus y en la opción de guardar los datos en un fichero.

Todas aquellas clases que ya tengo implementadas las publico al final.

El enunciado del proyecto es el siguiente:

Citar
Una compañía de software necesita de un sistema de gestión de sus recursos humanos. En la compañía existen dos tipos de Contratos: Consultores y Empleados Técnicos. A la compañía le interesa saber de los consultores su ID, nombre, fecha de inicio de su contrato, fecha final de su contrato, su salario, y la labor que desempeñan. Por otra parte, los Empleados Técnicos pueden ser Programadores, aunque no se descarta que un futuro se pueda ampliar a otro tipo de trabajadores. De los programadores interesa conocer: ID, nombre, fecha de inicio de su contrato, fecha final de su contrato, su salario mensual y el lenguaje de Programación en el cual es experto. Si un programador utiliza el lenguaje de programación Java recibe un 20% más, respecto de su salario como bonificación. A la compañía de software también le interesa gestionar la información de los líderes de Proyecto. Un líder de proyecto es un empleado técnico que es responsable de un equipo de empleados técnicos. La compañía posee una estructura jerárquica de responsabilidades en forma de árbol, es decir, existe un líder del que dependen otros lideres de proyecto, de los que, a su vez, dependen los programadores. De esta forma el Líder principal asigna los proyectos a los lideres que tiene a su cargo, y estos se hacen cargo del proyecto con los programadores que conforman su equipo. A un trabajador técnico se le añade un 5 % de su salario por cada proyecto dirigido. Los lideres de proyecto se asignan según las necesidades de la empresa, por lo que un trabajador técnico (en nuestro caso un programador) puede ser, o dejar de ser, un líder de proyecto según se necesite. Sin embargo, el Líder que lidera a los otros líderes del proyecto no cambia una vez se le asigne ese puesto ya que es el Director General de la empresa. Todo líder de proyecto depende de un proyecto (salvo el Director General). Un líder no puede liderar más de un proyecto a la vez. Un programador no puede estar en más de un proyecto a la vez. El sistema también deberá llevar un registro de los proyectos realizados. De un proyecto se necesita conocer, Su ID, nombre y que programador lo lidera.

El sistema de gestión debe permitir realizar las siguientes operaciones:

La primera acción, antes de empezar con el resto de las posibles gestiones sería dar de alta al Director General. Esta operación implica dar de alta a un programador, asignárselo a un objeto de tipo líder y, por último, registrarlo como el Director General. Esta operación no debe volver a aparecer en el menú principal si el Director General ya ha sido asignado.

Gestión de los contratos:
• Dar de alta y baja nuevos contratos. A la hora de dar de baja un contrato no se elimina; se asigna la fecha de cese a la fecha de fin de contrato.
• Listar la información de todos los contratos activos de la empresa.
• Listar la información de todos los contratos finalizados de la empresa.
• Listar la estructura jerárquica de la empresa.
• Mostrar los datos de un Líder y el equipo de programadores que dependen de él.

Gestión de nóminas.
• Calcular el salario mensual total producto de los todos contratos de los Consultores que están en activo.
• Calcular el salario mensual total producto de los todos contratos de los Programadores que están en activo.
• Mostrar el Informe de nómina de un empleado: Se detallará toda la información relativa del empleado distinguiendo si es consultor o programador. En este último caso se detallarán las bonificaciones que posea (ser experto en Java o por ser Líder de Proyecto).

Gestión de Proyectos.
• Dar de alta un nuevo proyecto. Al dar de alta un proyecto se le debe asignar un líder. Esta operación consiste en elegir un líder de entre los trabajadores técnicos disponibles, registrarlo tanto en el proyecto como en la estructura jerárquica de la compañía y, por último, asignarle el equipo de programadores que estará a su cargo.
• Dar de baja un proyecto. A la hora de dar de baja un proyecto se le asigna la fecha de finalización a la fecha de fin de proyecto y se elimina la referencia del líder de proyecto de la estructura jerárquica de la empresa que depende del D.G.
• Mostrar la información de un proyecto concreto.
• Listar la información de todos los proyectos activos de la empresa.
• Listar la información de todos los proyectos finalizados de la empresa.

Salvar datos.
• Opción que guarda todos los datos en un fichero persistente. El sistema debe permitir almacenar de forma persistente la información de los contratos registrados en todo momento. En ese sentido, al iniciar el programa se debe cargar la información previa de todos los contratos.


A continuación adjunto las clases que ya tengo implementadas:


Consultor.java

Código: [Seleccionar]
public class Consultor extends Contrato {
    private String labor;

    public Consultor(String labor, String ID, String nombre, double salario) {
        super(ID, nombre, salario);
        this.labor = labor;
    }
   
    public String getLabor() {
        return labor;
    }
   
    public String toString() {
        return super.toString() + " Consultor: " + "labor=" + labor;
    }
   
    public void mostrarInfo(){
        System.out.println(toString());
    }

    public boolean serTecnico(){
        return false;
    }
}


Contrato.java

Código: [Seleccionar]
import Excepciones.FechaFinExcepcion;
import java.io.Serializable;
import java.time.LocalDate;

public abstract class Contrato implements Serializable {
    private final String ID;
    private final String nombre;
    private final double salario;
    private final LocalDate fecha_inicio;
    private LocalDate fecha_fin;
   
    public Contrato(String ID, String nombre, double salario){
        this.ID = ID;
        this.nombre = nombre;
        this.salario = salario;
        fecha_inicio = LocalDate.now();
    }
   
    public String getID() {
        return ID;
    }
   
    public String getNombre() {
        return nombre;
    }
   
    public double getSalario() {
        return salario;
    }

    public String toString() {
        String info = "Contrato:" + "ID=" + ID + ", nombre=" + nombre + ", salario=" + salario;
        if(fecha_fin==null)
            return info;
        else
            return info + ", fecha de fin=" + fecha_fin;
    }
   
    public boolean serActivo(){
        return fecha_fin==null;
    }
   
    public boolean serInactivo(){
        return fecha_fin!=null;
    }
   
    public void setFecha_Fin(LocalDate fecha) throws FechaFinExcepcion{
            if(fecha.isBefore(fecha_inicio))
                throw new FechaFinExcepcion("La fecha introducida ");
            else fecha_fin = fecha;
    }
   
    public void setFecha_Fin(){
        fecha_fin=LocalDate.now();
    }
   
    public abstract boolean serTecnico();
    public abstract void mostrarInfo();
}


Decorador_DirectorGen.java

Código: [Seleccionar]
public abstract class Decorador_DirectorGen extends EmpleadoTecnico {
    private final EmpleadoTecnico tecnico;
   
    public Decorador_DirectorGen(EmpleadoTecnico tecnico) {
        super("", "", 0.0);
        this.tecnico = tecnico;
    }
   
    public String getID() {
        return tecnico.getID();
    }
   
    public double getSalario() {
        return tecnico.getSalario();
    }
   
    public String toString(){
        return tecnico.toString();
    }
}


EmpleadoTecnico.java

Código: [Seleccionar]
public abstract class EmpleadoTecnico extends Contrato {
    private int ProyectosLidera = 0;
   
    public EmpleadoTecnico(String ID, String nombre, double salario) {
        super(ID, nombre, salario);
    }

    public int getProyectosLidera(){
        return ProyectosLidera;
    }
   
    public void añadeProyectoLidera(){
        ProyectosLidera = ProyectosLidera + 1;
    }
   
    public boolean serTecnico(){
        return true;
    }

    public String toString() {
        return super.toString() + ", Proyectos liderados=" + ProyectosLidera;
    }
   
    public abstract void mostrarInfo();
    public abstract void añadir(EmpleadoTecnico et);
    public abstract void eliminar(EmpleadoTecnico et);
    public abstract EmpleadoTecnico obtenerComponente(String id);
}


Lider.java

Código: [Seleccionar]
import java.util.ArrayList;

public class Lider extends Decorador_DirectorGen {
    private final ArrayList<EmpleadoTecnico> lista;
    String IDProyecto;

    public Lider(EmpleadoTecnico tecnico, String IDProyecto) {
        super(tecnico);
        lista=new ArrayList<>();
        this.IDProyecto=IDProyecto;
    }
   
    public String toString(){
        return super.toString()+", lidera el proyecto con ID: "+IDProyecto;
    }
   
    public void mostrarInfo(){
        System.out.println("Lider de Proyecto: "+toString());
        for(EmpleadoTecnico c:lista)
            c.mostrarInfo();
    }
   
    public double getSueldo(){
        double sumador=0;
        for (EmpleadoTecnico c: lista){
            sumador=sumador+c.getSalario();}
        return sumador;
    }
   
    public void añadir(EmpleadoTecnico e){
        lista.add(e);
        System.out.println("se agrega "+e.toString());
    }
   
    public void eliminar(EmpleadoTecnico e){
        if (lista.contains(e)) {
            lista.remove(e);
            System.out.println("se elimina "+toString());}
        else
            for(EmpleadoTecnico c:lista) 
                c.eliminar(e);
    }
   
    public EmpleadoTecnico obtenerComponente(String ID){
        if (getID().equals(ID))
            return this;
        else{
            for(EmpleadoTecnico c:lista)
                if (c.obtenerComponente(ID)!=null)
                    if(c.obtenerComponente(ID).getID().equals(ID))
                        return c.obtenerComponente(ID);
            return null;
        }
    }
   
    public EmpleadoTecnico obtenerLider(String ID){
        if (getID().equals(ID))
            return this;
        else{
            for (EmpleadoTecnico c:lista)
                if (c.getID().equals(ID))
                    return c;
            return null;
        }
    }
}


Menu_Principal.java

Código: [Seleccionar]
import Entrada.MyInput;
import java.util.ArrayList;

public class Menu_Principal extends Menus{
    private ArrayList<Menus> menus=new ArrayList<Menus>();
   
   
    public Menu_Principal(Empresa empresa){
        super(empresa);
        menus.add(new Menu_Contrato(empresa));
        menus.add(new Menu_Proyecto(empresa));
        menus.add(new Menu_Nomina(empresa));
        menus.add(new Salvar_Datos(empresa));
    }

    public void darAltaDirectorGeneral(){
        Menu_Contrato mc= (Menu_Contrato) menus.get(0);
        EmpleadoTecnico c=mc.crearContratoProgramador();
        getEmpresa().altaContrato(c);
        getEmpresa().setDirectorGeneral(new Lider((EmpleadoTecnico) c, ""));
    }
   
   
    public String ejecutarOpciones(){
        if(!getEmpresa().existeDirectorGeneral()){
            System.out.println("Dando de alta al Director General");
            darAltaDirectorGeneral();}
        System.out.println("");
        System.out.println("Menú Principal.");
        System.out.println("Seleccione una opción:");
        System.out.println("0. Salir del programa");
        System.out.println("1. Gestión Contratos");
        System.out.println("2. Gestión Proyectos");
        System.out.println("3. Gestión Nóminas");
        System.out.println("4. Salvar datos");
        String s=MyInput.readString();
        int i;
        try{
                i= Integer.parseInt(s);
        }catch(NumberFormatException ex){
                  System.out.println("La entrada no tiene formato de número. Inténtelo de nuevo");
                  return "s";
               }
        if((i>0)&&(i<=menus.size())){
                menus.get(i-1).ejecutar();
                return "s";}
        else if ((i<0)||(i>menus.size())){
            System.out.println("Opción no válida. Inténtelo de nuevo.");
            return "s";}
        else
            return "n";
    }
}


Menus.java

Código: [Seleccionar]
public abstract class Menus {
    private Empresa empresa;
   
    public Menus(Empresa empresa){
        this.empresa=empresa;
    }
   
    public Empresa getEmpresa(){
        return empresa;
    }
   
    public void ejecutar(){
        String respuesta="";
        do{
            respuesta= ejecutarOpciones();
        }while(respuesta.equals("s"));
    }
   
    public abstract String ejecutarOpciones();
}


Programador.java

Código: [Seleccionar]
public class Programador extends EmpleadoTecnico{
    private String lenguaje_prog;
    private double getNumProyectosLiderados;
   
    public Programador(String ID, String nombre, double salario, String lenguaje_prog) {
        super(ID, nombre, salario);
        this.lenguaje_prog=lenguaje_prog;
    }

    public double getSalario(){
        double modificador=0.0;
        if(lenguaje_prog.equalsIgnoreCase("java"))
            modificador=0.2;
        return super.getSalario()*(1+modificador+getNumProyectosLiderados);
    }
   
    public void mostrarInfo(){
          System.out.println(toString());}
   
    public void añadir(EmpleadoTecnico e){
      System.out.println("no se le puede añadir empleados"); }
   
    public void eliminar (EmpleadoTecnico e){ }
   
    public EmpleadoTecnico obtenerComponente(String ID){
        return this;
    }
   
}


Proyecto.java En esta clase me faltaría sólo el método "getLiderProyecto()".

Código: [Seleccionar]
import Excepciones.FechaFinExcepcion;
import java.time.LocalDate;

public abstract class Proyecto {
    private final String ID;
    private final String nombre;
    private final LocalDate fecha_inicio;
    private LocalDate fecha_fin;
   
    public Proyecto(String ID, String nombre){
        this.ID = ID;
        this.nombre = nombre;
        fecha_inicio = LocalDate.now();
    }
   
    public String getID(){
        return ID;
    }
   
    public String getNombre() {
        return nombre;
    }
   
    public boolean serActivo(){
        return fecha_fin==null;
    }
   
    public boolean serInactivo(){
        return fecha_fin!=null;
    }
   
    public void setFecha_Fin(LocalDate fecha) throws FechaFinExcepcion{
            if(fecha.isBefore(fecha_inicio))
                throw new FechaFinExcepcion("La fecha introducida ");
            else fecha_fin = fecha;
    }
   
    public void setFecha_Fin(){
        fecha_fin=LocalDate.now();
    }

    public abstract void mostrarInfo();

    Lider getLiderProyecto() {}
   
}


main.java

Código: [Seleccionar]
import Entrada.MyInput;
import Practica_Final.Menu_Principal;
import Practica_Final.Menus;
import Practica_Final.Empresa;

public class GestionRRHH {
    public static void main(String[] args) {
        Empresa empresa= MyInput.deserialize("datos.dat");
        if(empresa==null)
            empresa= Empresa.getInstancia();
        Menu_Principal mp= new Menu_Principal(empresa);
        mp.ejecutar();
        MyInput.serialize(empresa, "datos.dat");
    }
}
« Última modificación: 12 de Marzo 2022, 18:24 por Ogramar »

luu_cuuesta

  • Visitante
Re: Java - Ejercicio de Recursos Humanos
« Respuesta #1 en: 01 de Febrero 2022, 21:02 »
Empresa.java En esta clase solo me faltan los métodos numeroContratosConsultores() y numeroContratosTecnicos()
Código: [Seleccionar]
import Excepciones.FechaFinExcepcion;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.ArrayList;

public class Empresa implements Serializable {
    private static Empresa empresa;
    private final ArrayList<Contrato> contratos;
    private final ArrayList<Proyecto> proyectos;
    private Lider director;
   
    public Empresa(){
        contratos=new ArrayList<>();
        proyectos=new ArrayList<>();
    }
   
    public void setDirectorGeneral(Lider lider){
        director=lider;
    }
   
    public boolean existeDirectorGeneral(){
        return director!=null;
    }
   
    public Contrato obtenerContrato(String ID){
        for(Contrato c:contratos)
            if(c.getID().equals(ID)) return c;
        return null;
    }
   
    public Contrato obtenerContratoxNombre(String nombre){
        for(Contrato c:contratos)
            if(c.getNombre().equals(nombre)) return c;
        return null;
    }
   
    public Contrato obtenerContratoEmpTecnico(String ID){
        for(Contrato c:contratos)
            if((c.getID().equals(ID))&&(c.serTecnico())) return c;
        return null;
    }
   
    public boolean altaContrato(Contrato c){
        if(obtenerContrato(c.getID())==null)
            if(((obtenerContratoxNombre(c.getNombre())==null))||((obtenerContratoxNombre(c.getNombre())!=null)&&(obtenerContratoxNombre(c.getNombre()).serInactivo()))){
                contratos.add(c);
                return true;}
        return false;
    }
   
    public void bajaContrato(String ID, String f) throws FechaFinExcepcion{
        Contrato c;
        c=obtenerContrato(ID);
        if (c.serActivo())
            if((c.serTecnico())&&(!esTecnicoOcupado((EmpleadoTecnico)c))){
                    c.setFecha_Fin(LocalDate.parse(f));
                    System.out.println("Se dió de baja el contrato.");
            }else System.out.println("No se pudo dar de baja el contrato.");
    }
   
    public void bajaContrato(String ID, LocalDate f) throws FechaFinExcepcion{
        Contrato c = null;
        boolean flag=true;
        try{
            c=obtenerContrato(ID);
        }catch(NullPointerException ex){
            System.out.println("No existe el contrato.");
            flag=false;
        }
        if(flag)
            if(c.serActivo())
                if((c.serTecnico())&&(!esTecnicoOcupado((EmpleadoTecnico)c))){
                    c.setFecha_Fin(f);
                }else System.out.println("No se pudo dar de baja el contrato.");
       
    }
   
    public Proyecto obtenerProyecto(String ID){
        for(Proyecto p:proyectos)
            if(p.getID().equals(ID)) return p;
        return null;
    }
   
    public boolean altaProyecto(Proyecto p){
        if(obtenerProyecto(p.getID())==null){
                proyectos.add(p);
                return true;}
        else return false;
    }
   
    public void bajaProyecto(String ID, String f) throws FechaFinExcepcion{
        Proyecto p;
        p=obtenerProyecto(ID);
        if (p.serActivo()){
            p.setFecha_Fin(LocalDate.parse(f));
            eliminarLiderProyectoJerarquia(p.getLiderProyecto());
        }else  System.out.println("El contrato ya es Baja");
    }
   
    public void añadirLiderProyectoJerarquia(Lider lp){
        director.añadir(lp);
    }
   
    public void eliminarLiderProyectoJerarquia(Lider lp){
        director.eliminar(lp);
    }
   
    public void infoLiderDeJerarquia(String ID){
        try{
            director.obtenerLider(ID).mostrarInfo();
        }catch(NullPointerException ex){
            System.out.println("No existe ese lider en activo");
        }
    }
   
    public void mostrarInfoProyectos(){
        if (proyectos.size()==0)
            System.out.println("no existen proyectos");
        else for(Proyecto p:proyectos)
                    p.mostrarInfo();
    }
   
    public void mostrarInfoProyectos(boolean flag){
        int con=0;
        for(Proyecto p:proyectos)
                if(((p.serActivo())&&flag)||((p.serInactivo())&&!flag)){
                        p.mostrarInfo();
                        con++;
                }
        if(con==0) System.out.println("no existen proyectos");
    }
   
    public int numeroProyectos(){
        return proyectos.size();
    }
   
    public void sumarProyecto(String ID){
        EmpleadoTecnico t=(EmpleadoTecnico) obtenerContrato(ID);
        t.añadeProyectoLidera();
    }
   
    public void mostrarInfoDirectorGeneral(){
        director.mostrarInfo();
    }
   
    public boolean esTecnicoOcupado(EmpleadoTecnico t){
        return director.obtenerComponente(t.getID())!=null;
    }
   
    public int numeroTecnicosLibres(){
        int contador=0;
        for(Contrato c:contratos)
            if((c.serTecnico())&&(c.serActivo())&&(!esTecnicoOcupado((EmpleadoTecnico) c))) {
                    contador++;
                }
        return contador;
    }
   
    public int numeroContratosConsultores() {}
   
    public int numeroContratosTecnicos() {}
 
    public double calculaSalarioTotalConsultores(){
        double sumador=0;
         for(Contrato c:contratos)
             if((c.serActivo())&&(!c.serTecnico()))
                 sumador=sumador+c.getSalario();
        return sumador;
    }
   
    public double calculaSalarioTotalTecnicos(){
        double sumador=0;
         for(Contrato c:contratos)
             if((c.serActivo())&&(c.serTecnico()))
                 sumador=sumador+c.getSalario();
        return sumador;
    }
   
    public static Empresa getInstancia(){
        empresa = deserialize("datos.dat");
            if(empresa==null)
                return new Empresa();
        else return empresa;
    }
   
    private static <A> A deserialize(String nombreFichero) {
                try {
                        FileInputStream fis = new FileInputStream(nombreFichero) ;
                        ObjectInputStream iis = new ObjectInputStream(fis) ;
                        return (A) iis.readObject() ;
                } catch (IOException e) {
                        System.err.println("Problem: "+e);}
                catch(ClassNotFoundException e)
                { System.out.println(e.getMessage()); }
                return null ;
    }
   
}


MyInput.java
Código: [Seleccionar]
import java.io.*;
import java.util.ArrayList;

public class MyInput {
    public static String readString() {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in),1);
        String string=" ";
        try {
            string = br.readLine(); }
        catch (IOException ex) {
            System.out.println(ex); }
        return string; }
   
    public static int readInt() {
        int numero = 0;
        try {
            numero = Integer.parseInt(readString());}
        catch (NumberFormatException ex) {
            System.out.println(ex); }
        return numero; }
   
    public static double readDouble() {
        return Double.parseDouble(readString()); }
   
    public static byte readByte() {
        return Byte.parseByte(readString()); }
   
    public static short readShort() {
        return Short.parseShort(readString()); }
   
    public static long readLong() {
        return Long.parseLong(readString()); }
   
    public static float readFloat() {
        return Float.parseFloat(readString()); }
   
    public static ArrayList <String> leeFichero(String pathFichero){
        ArrayList <String> v = new ArrayList <String>();
        File fichero=null;
        FileReader fr=null;
        BufferedReader br=null;
        try{
            fichero=new File(pathFichero);
            fr=new FileReader(fichero);
            br=new BufferedReader(fr);
            String linea;
            while ((linea=br.readLine())!=null){
                v.add(linea);}
        }
        catch (Exception e){
            e.printStackTrace();
        }
        finally {
            try {
                if (null!= fr){
                    fr.close();
                    br.close();}
            }
            catch (Exception e1){
                e1.printStackTrace();
            }
        }
        return v;
    }
   
    public static <A> void serialize(A a, String nombreFichero) {
        System.out.println("Serializando...");
        try {
            FileOutputStream fos = new FileOutputStream(nombreFichero) ;
            ObjectOutputStream oos = new ObjectOutputStream(fos) ;
            oos.writeObject(a) ;
        } catch (Exception e) {
            System.err.println("Problem: "+e) ;
        }
    }
   
    public static <A> A deserialize(String nombreFichero) {
        System.out.println("DeSerializing...");
        try {
            FileInputStream fis = new FileInputStream(nombreFichero) ;
            ObjectInputStream iis = new ObjectInputStream(fis) ;
            return (A) iis.readObject() ;
        } catch (Exception e) {
            System.err.println("Problem: "+e) ;
        }
        return null ;
    }
}


Como he dicho en el anterior mensaje, lo que no sé es cómo implementar las clases Salvar_Datos y los 3 Menus: Menu_Contratos, Menu_Proyectos y Menu_Nominas.
Espero me puedan ayudar :(. Y por cierto, gracias de antemano.
« Última modificación: 02 de Febrero 2022, 00:11 por luu_cuuesta »

luu_cuuesta

  • Visitante
Re: Java - Ejercicio de Recursos Humanos
« Respuesta #2 en: 04 de Febrero 2022, 18:33 »
He conseguido implementar la clase Salvar_Datos, pero creo que no funciona del todo bien porque de vez en cuando se me cierra el programa inesperadamente y no entiendo el motivo.
A continuación implemento dicha clase para mostrárosla:
Citar
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;

public class Salvar_Datos extends Menus implements Serializable {
   
    public Salvar_Datos(Empresa empresa) {
        super(empresa);
    }
   
    private static void guardarArrayList(ArrayList<Contrato> datos) {
        String fichero = "datos.dat";
       
        try {
            ObjectOutputStream ficheroSalida = new ObjectOutputStream(new FileOutputStream(fichero));
            ficheroSalida.writeObject(datos);
            ficheroSalida.flush();
            ficheroSalida.close();
            System.out.println("Datos guardados correctamente...");
           
        } catch (FileNotFoundException fnfe) {
            System.out.println("Error: El fichero no existe. ");
        } catch (IOException ioe) {
            System.out.println("Error: Fallo en la escritura en el fichero. ");
        }
 
    }

    public boolean ejecutarOpciones() {
        System.out.println("");
        System.out.println("SALVAR DATOS EN FICHERO");
        guardarArrayList(getEmpresa().getContratos());
        return true;
    }

}

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re: Java - Ejercicio de Recursos Humanos
« Respuesta #3 en: 07 de Febrero 2022, 00:40 »
Hola.
A ver, para meterme en contexto, he comenzado a hacer el programa a mi manera, aunque no he podido terminarlo por completo todavía, porque ando escaso de tiempo.

Las clases principales apenas hay diferencias respecto a las tuyas.

Tenemos una clase Contrato, preferiblemente abstracta, de la que derivan dos clases: Consultor y Tecnico

Contrato
Código: [Seleccionar]
ublic abstract class Contrato implements Serializable {

protected String id;
protected String nombre;
protected LocalDate fechaInicio;
protected LocalDate fechaFin;
protected double salario;

public Contrato(String id, String nombre, double salario) {
this.id = id;
this.nombre = nombre;
this.salario = salario;
fechaInicio = LocalDate.now();
fechaFin = null;
}

public String getId() {
return id;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public LocalDate getFechaInicio() {
return fechaInicio;
}

public LocalDate getFechaFin() {
return fechaFin;
}

public void darDeBaja() {
fechaFin = LocalDate.now();
}

public double getSalario() {
return salario;
}

public void setSalario(double salario) {
this.salario = salario;
}

@Override
public String toString() {
return String.format("ID: %s, Nombre: %s, Salario: %.2f\nInicio: %s, Fin :%s",
id, nombre, salario, fechaInicio.toString(), fechaFin==null?"":fechaFin.toString());
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Contrato) {
Contrato otroContrato = (Contrato) obj;
return id.equals(otroContrato.id);
}
else
return false;
}

}

Consultor
Código: [Seleccionar]
public final class Consultor extends Contrato {

private String labor;

public Consultor(String id, String nombre, double salario, String labor) {
super(id, nombre, salario);
this.labor = labor;
}

public String getLabor() {
return labor;
}

public void setLabor(String labor) {
this.labor = labor;
}

@Override
public String toString() {
return String.format("%s\nLabor: %s", super.toString(), labor);
}

}

Tecnico
Código: [Seleccionar]
public class Tecnico extends Contrato {

private int proyectosLiderados;

public Tecnico(String id, String nombre, double salario) {
super(id, nombre, salario);
proyectosLiderados = 0;
}

public int getProyectosLiderados() {
return proyectosLiderados;
}

public void contarProyectoLiderado() {
proyectosLiderados++;
}

@Override
public double getSalario() {
double salario = super.getSalario();
double bonus = salario * 5 / 100;
//Incremento del 5% por cada proyecto liderado
return salario + bonus * proyectosLiderados;
}

@Override
public String toString() {
return String.format("%s\nProyectos Liderados: %d",
super.toString(), proyectosLiderados);
}

}

De esta última clase, derivan otras dos subclases:
Programador
Código: [Seleccionar]
public final class Programador extends Tecnico {

private String lenguaje;

public Programador(String id, String nombre, double salario, String lenguaje) {
super(id, nombre, salario);
this.lenguaje = lenguaje;
}

@Override
public double getSalario() {
//Incrementa 20% si es experto en Java
if (lenguaje.equals("Java"))
return super.getSalario() + (super.getSalario() * 20 / 100);
else
return super.getSalario();
}

@Override
public String toString() {
return String.format("%s\nLenguaje: %s", super.toString(), lenguaje);
}

}

Lider
Código: [Seleccionar]
public class Lider extends Tecnico {

private ArrayList<Tecnico> equipo;

public Lider(String id, String nombre, double salario) {
super(id, nombre, salario);
equipo = new ArrayList<Tecnico>();
}

public boolean agregarTecnico(Tecnico tec) {
if (equipo.contains(tec)) {
System.out.println("Este Técnico ya forma parte del Equipo");
return false;
}
else {
equipo.add(tec);
System.out.println("Técnico añadido al Equipo");
return true;
}
}

@Override
public String toString() {
StringBuilder resumen = new StringBuilder();
resumen.append("\n\tDATOS LIDER");
resumen.append("\nID: " + id);
resumen.append(", Nombre: " + nombre);
resumen.append("\n\tEQUIPO TECNICO");
for (Tecnico tec: equipo)
resumen.append("\n- " + tec.getNombre());

return resumen.toString();
}

}

Luego, además de los Contratos y sus subclases, tenemos la clase Proyecto.
Código: [Seleccionar]
public class Proyecto {

private String id;
private String nombre;
private Lider lider;
private LocalDate fechaInicio;
private LocalDate fechaFin;


public Proyecto(String id, String nombre, Lider lider) {
this.id = id;
this.nombre = nombre;
this.lider = lider;
fechaInicio = LocalDate.now();
fechaFin = null;
}

public String getId() {
return id;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public Lider getLider() {
return lider;
}

public void setLider(Lider lider) {
this.lider = lider;
}

public void finalizarProyecto() {
fechaFin = LocalDate.now();
}

public boolean estaFinalizado() {
return fechaFin != null;
}

@Override
public String toString() {
StringBuilder resumen = new StringBuilder();
resumen.append("\n\tPROYECTO #" + id);
resumen.append("\nNombre: " + nombre);
resumen.append("\nFecha Inicio: " + fechaInicio.toString());
resumen.append("\tFecha Fin: " + (estaFinalizado()?fechaFin.toString():"ACTIVO"));
resumen.append(lider.toString());

return resumen.toString();
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Proyecto) {
Proyecto otroProyecto = (Proyecto) obj;
return id.equals(otroProyecto.id);
}
else
return false;
}
}

Así que nuestro programa ha de gestionar Contratos y Proyectos, con una serie de menús y con la posibilidad de guardar/recuperar datos en disco.

Bien, aquí ya sí que hemos tomado caminos distintos tú y yo.

En mi caso he pensado en crear clases específicas para la gestión de cada cosa.
Una clase GestionContratos, con un ArrayList de contratos y con todos los métodos necesarios para su gestión.
No la he terminado, pero ya da una idea de la estructura que le voy a dar:
Código: [Seleccionar]
public class GestorContratos implements Serializable {

private ArrayList<Contrato> contratos;

public GestorContratos() {
contratos = new ArrayList<Contrato>();
}

public void registrarConsultor() {
Consultor cons = nuevoConsultor();
if (contratos.contains(cons))
System.out.println("Ya existe un Contrato con el ID: " + cons.getId());
else {
contratos.add(cons);
System.out.println("Consultor registrado");
}
}

public void registrarProgramador() {
Programador prog = nuevoProgramador();
if (contratos.contains(prog))
System.out.println("Ya existe un Contrato con el ID: " + prog.getId());
else {
contratos.add(prog);
System.out.println("Programador registrado");
}
}

public void finalizarContrato() {
Scanner teclado = new Scanner(System.in);
System.out.print("ID del contrato: ");
String id = teclado.nextLine();
boolean encontrado = false;
for (Contrato cont: contratos)
if (cont.getId().equals(id)) {
cont.darDeBaja();
encontrado = true;
}

if (encontrado)
System.out.println("Contrato finalizado con exito");
else
System.out.println("No se encuentra Contrato con el ID: " + id);

}

public void listarContratosActivos() {
System.out.println("\n\tCONTRACTOS ACTIVOS\n");
for (Contrato cont: contratos)
if (cont.fechaFin == null)
System.out.println(cont);
}

private Consultor nuevoConsultor() {
Scanner teclado = new Scanner(System.in);
System.out.print("Id: ");
String id = teclado.nextLine();
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
System.out.print("Salario: ");
double salario = Double.parseDouble(teclado.nextLine());
System.out.print("Labor en la empresa: ");
String labor = teclado.nextLine();

return new Consultor(id, nombre, salario, labor);
}

private Programador nuevoProgramador() {
Scanner teclado = new Scanner(System.in);
System.out.print("Id: ");
String id = teclado.nextLine();
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
System.out.print("Salario: ");
double salario = Double.parseDouble(teclado.nextLine());
System.out.print("Lenguaje programación: ");
String lenguaje = teclado.nextLine();

return new Programador(id, nombre, salario, lenguaje);
}
}

Y una clase similar, para la gestión de proyectos.
Esta ni siquiera la he empezado, pero su estructura será análoga a la anterior:
Código: [Seleccionar]
public class GestorProyectos implements Serializable {

private ArrayList<Proyecto> proyectos;

public GestorProyectos() {
proyectos = new ArrayList<Proyecto>();
}

/*
* Faltan todos los métodos necesarios para gestionar proyectos
*/
}

Estos dos gestores, puesto que contienen los ArrayList, serán los que nos interesen poder guardar en disco.
Y no solo hay que guardarlos a ellos, también hay que guardar al Lider que ha sido nombrado como director general de la empresa.
Para facilitar el guardado de todo esto, he creado otra clase donde agrupo estos tres elementos con el único propósito de luego poder guardarlo todo en disco como un único objeto.
Así que a priori, no tendrá métodos ni nada. Básicamente es una especie de "contenedor".
La he llamado RecursosHumanos.
Fíjate que el director se lo paso por constructor, esto es porque dicho Lider lo construiremos desde otra clase.
Código: [Seleccionar]
public class RecursosHumanos implements Serializable {

GestorContratos contratos;
GestorProyectos proyectos;
final Lider director;

public RecursosHumanos(Lider director) {
contratos = new GestorContratos();
proyectos = new GestorProyectos();
this.director = director;
}

}

Y ya por último, tendría la clase principal, con un método main para poner en marcha la aplicación, y será aquí donde se mostrarán distintos menús, se pedirán entradas por teclado, se le pedirá a las clases de gestión que hagan una cosa o la otra y también se controlará la persistencia de los datos.

Al iniciarse la aplicación, lo que hará es buscar el archivo de datos guardados y recuperarlo, por lo que obtendremos un objeto RecursosHumanos con el director general y los gestores(y sus ArrayList)

Si no lo encuentra, o bien no consigue recuperar los datos que contiene, se creará un nuevo Director General y los ArrayList se inicializarán sin datos.

Esta clase tampoco la he terminado, pero tiene suficiente código para ver como se van a estructurar los menús, como llamamos al objeto RecursosHumanos para acceder a sus gestores y sobre todo vemos como se guarda y se recupera en disco.
Código: [Seleccionar]
public final class Empresa {

private static Scanner teclado = new Scanner(System.in);
private static RecursosHumanos RRHH;

public static void main(String[] args) {

File fichero = new File("d:/empresa.dat");

if (fichero.exists()) {
try {
ObjectInputStream lector = new ObjectInputStream(new FileInputStream(fichero));
RRHH = (RecursosHumanos) lector.readObject();
lector.close();
} catch (Exception e) {
System.out.println("Error recuperando datos de empresa. Se generará una nueva.\n");
RRHH = new RecursosHumanos(crearDirector());
}
}
else //No hay datos de Empresa guardados
RRHH = new RecursosHumanos(crearDirector());

menuPrincipal();

}

private static Lider crearDirector() {
System.out.println("Indique a continuación los datos del Técnico que será Dir. General de la Empresa");
System.out.print("Id: ");
String id = teclado.nextLine();
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
System.out.print("Salario: ");
double salario = Double.parseDouble(teclado.nextLine());
return new Lider(id, nombre, salario);
}

private static void menuPrincipal() {
int opcion = 0;
while(opcion != 5) {
System.out.println("\n\n\t\tMENU PRINCIPAL");
System.out.println("\t\t---- ---------\n");
System.out.println("[1] -- Gestion Contratos");
System.out.println("[2] -- Gestion Nominas");
System.out.println("[3] -- Gestion Proyectos");
System.out.println("[4] -- Guardar Datos");
System.out.println("[5] -- TERMINAR PROGRAMA");
System.out.print("Opcion: ");
opcion = Integer.parseInt(teclado.nextLine());
switch(opcion) {
case 1:
menuContratos();
break;
case 2:
//menuNominas();
break;
case 3:
//menuProyectos();
break;
case 4:
guardarDatos();
break;
case 5:
System.out.println("\n\n\t\tFIN DE PROGRAMA");
break;
default:
System.out.println("Opcion equivocada");
}
}
}

private static void menuContratos() {
int opcion = 0;
while (opcion != 8) {
System.out.println("\n\n\t\tGESTION CONTRATOS");
System.out.println("\t\t------- ---------\n");
System.out.println("[1] -- Nuevo Contrato: Consultor");
System.out.println("[2] -- Nuevo Contrato: Programador");
System.out.println("[3] -- Dar de baja un Contrato");
System.out.println("[4] -- Listar Contratos activos");
System.out.println("[5] -- Listar Contratos finalizados");
System.out.println("[6] -- Listar Estructura Jerárquica");
System.out.println("[7] -- Mostrar datos de un Lider");
System.out.println("[8] -- Volver a Menú Principal");
System.out.print("Opcion: ");
opcion = Integer.parseInt(teclado.nextLine());
switch(opcion) {
case 1:
RRHH.contratos.registrarConsultor();
break;
case 2:
RRHH.contratos.registrarProgramador();
break;
case 3:
RRHH.contratos.finalizarContrato();
break;
case 4:
RRHH.contratos.listarContratosActivos();
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
//Opcion para volver al menu principal, nada que hacer aquí
break;
default:
System.out.println("Opcion equivocada");
}
}
}

private static void guardarDatos() {
File fichero = new File("d:/empresa.dat");
try {
if (!fichero.exists())
fichero.createNewFile();

ObjectOutputStream escritor = new ObjectOutputStream(new FileOutputStream(fichero));
escritor.writeObject(RRHH);
escritor.close();
} catch (Exception e) {
System.out.println("No ha sido posible guardar los datos.\n" + e.getMessage());
e.printStackTrace();
}
}

}


En tu caso parece que has tirado por caminos más complejos.
Parece que los menús quieres tratarlos también como objetos, en lugar de hacer simples métodos.
Aunque lo cierto es que es un camino interesante, quizás esa complejidad luego proporcione alguna ventaja..., no lo se...

Y tu forma de guardar/recuperar datos si que me parece complicada en exceso.
Para salvar los datos también haces una clase, que hereda de la clase menus (¿por qué una "acción de guardar" es un "menú"?) y además implementa la interfaz Serializable, lo cuál es innecesario porque no creo que vayas a guardar en disco un objeto Salvar_Datos

La interfaz Serializable es para las clases que van a ser guardados en disco.

Y por otro lado, no TODO tiene por qué ser una clase.
Las clases normalmente se usan para modelar una entidad o un concepto: un contrato, un proyecto, un perro, una persona, una escuela, un hotel, una factura, un teatro, etc...

Acciones como mostrar un menú o guardar datos en disco, en realidad son funcionalidades y pueden resolverse mediante métodos (que por eso también se le llaman "funciones") escritos en la clase principal o tal vez en alguna otra clase.

Pueden resolverse creando clases, por supuesto, pero luego puede ser más difícil buscar la manera de encajarlos en el proyecto y que se comuniquen con el resto de clases que intervienen.

En fin, revisa el camino que yo he tomado. Decide tú si te parece mejor, o si quizás te da alguna inspiración para lograr resolver mejor tu camino.
Insisto en que no he terminado el programa, así que luego pueden salir errores o necesidad de cambiar algo de lo que ya tengo hecho.
Pero en esencia, el programa ya ha quedado estructurado.

Pregunta lo que no haya quedado claro.
Un saludo.
« Última modificación: 07 de Febrero 2022, 00:43 por Kabuto »
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

luu_cuuesta

  • Visitante
Re: Java - Ejercicio de Recursos Humanos
« Respuesta #4 en: 08 de Febrero 2022, 18:07 »
Muchas gracias por tu explicación la verdad porque ha habido cosas que me han quedado muchísimo más claras.
Acerca de lo que me has dicho sobre mi forma de guardar los datos, creo que es bastante complicada, como tú bien dices. No creo que fuera necesario crear otra clase más para esta opción. Lo tendré en cuenta. Además del hecho de crear otras clases para cada menú.

Voy a intentar adaptar mi programa con los cambios que me has sugerido y si tengo alguna duda más respecto a cualquier cosa la publico en el foro.
Muchas gracias por tu tiempo :)

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".