sábado, 20 de abril de 2013

MODULO IV



Bases de Datos con Tecnología Java

Les comparto mi diseño de la base de datos de mi proyecto de un sistema para la administración de una farmacia.




Tabla de sustancia_activa

Esta tabla contiene el id y el nombre de la sustancia activa que compone a un medicamento, es un catálogo de sustancias activas que se relaciona la tabla nombre_comercial.

Tabla de nombre_comercial

Contiene un identificador único y el nombre comercial de un medicamento, esta tabla se relaciona con la tabla sustancia_activa.

Tabla dosificacion

Esta tabla contiene un catálogo  de tipos de dosis con la que se debe de aplicar el medicamento y un identificador único.

Tabla forma_farmaceutica

Esta tabla contiene un catálogo con la descripción de la disposición externa que se da a los medicamentos para facilitar su administración.

Tabla laboratorio

Esta tabla contiene un catálogo de nombre de laboratorios que fabrican los medicamentos.

Tabla proveedor

Catálogo de las empresas a las que se les compra el medicamento para su venta en la farmacia.

Tabla compra

Contiene la fecha de compra y la cantidad de medicamentos comprados.

Tabla venta

Esta tabla contiene la fecha en la que se vendió un medicamento así como la cantidad de medicamentos que se vendieron.

Tabla medicamento

Contiene un catálogo de medicamentos con los detalles de esta, contenido total, fecha de caducidad, nombre comercial, dosificación, laboratorio, sustancia activa, forma farmacéutica y precio. Esta tabla es la base del funcionamiento del sistema para poder conocer los detalles de un medicamento y poder venderlo o comprarlo.

Tabla compra_medicamento
Aquí se van relacionar las tablas compra con medicamento, esta tabla contendrá un registro de cada uno de las compras en base a las claves o id de estas tablas, con esta tabla podremos saber cuántos medicamentos de cada tipo se han comprado la farmacia

Tabla venta_medicamento
En esta tabla así como en compra_medicamento se van a registrar cada una de las transacciones de salida de medicamentos,  se podrá generar una consulta de ventas y compras para un medicamento y así sabremos cual ha sido los medicamentos más vendidos y en qué periodo de tiempo para poder generar futuras compras.

API utilizada
Se utilizó la biblioteca de clases java.io para realizar inserciones en la base de datos, es decir para poder actualizar los catálogos de medicamento, se utilizó la clase Scanner para poder leer los datos de teclado y guardarlos.
Cuando se implemente el sistema se tiene pensado cargar los datos mediante una lista de Excel que tiene el “cliente” para evitar llenar los registros uno por uno.
Para visualizar los datos de cada una de las tablas se utilizó javax.swing desde eclipse con el plugin CloudGarden's Jigloo. Se utilizaron JList y JTable para poder mostrar los datos en un JFrame, en un futuro se tiene planeado utilizar HTML para mostrar estos datos desde un JSP.

Estructura de mi proyecto separando las capas del sistema en modelo vista y servicios o controlador.

  Data Acces Object

Metodo para insertar proveedores a la base de Datos:

public Proveedor saveProveedor(Proveedor proveedor) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
       
                // Creación del DataSource
                BasicDataSource dataSource = new BasicDataSource();
                dataSource.setDriverClassName("com.mysql.jdbc.Driver");
                dataSource.setUsername("root");
                dataSource.setPassword("admin");
                dataSource.setUrl("jdbc:mysql://localhost:3306/farmamedic");
               
                // Se obtiene la conexión
                conn = dataSource.getConnection();
                // BEGIN TRANSACTION
                conn.setAutoCommit(false);
               
                String sql = "INSERT INTO proveedor " +
                        "(nombre) " +
                        "VALUES (?)";
                pstmt = conn.prepareStatement(sql);
                pstmt.setString(1, proveedor.getNombre());
                pstmt.executeUpdate();
                conn.commit();
               
            return proveedor;
               
        }catch(SQLException ex)
        {
            try{
                System.out.println(ex.getMessage());
            conn.rollback();
            }catch (SQLException e1)
            {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
        finally
        {
           
            try {
                pstmt.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return proveedor;
    }


Se maneja el uso de transacciones que en caso de algún error o excepción genera un rollback en las instrucciones sql ejecutadas.También se cierran los flujos con la base de datos y se capturan las excepciones que pueden generar.

En el paquete model se encuentran las clases que contienen la estructura de cada una de las tablas de la base de datos para su manipulación como objetos(métodos get y set).

public class Proveedor implements Serializable {

    private static final long serialVersionUID = 2189161461106174085L;
    private int clave;
    private String nombre;
    public int getClave() {
        return clave;
    }
    public void setClave(int clave) {
        this.clave = clave;
    }
    public String getNombre() {
        return nombre;
    }
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

}

El paquete de servicios contiene las clases para interatuar con el modelo para pasar los datos a la vista en caso de que así se requiera, ejemplo:


public class ProveedorServiceImpl implements ProveedorService {

    @Override
    public Proveedor addProveedor(Proveedor proveedor) {
        if(proveedor==null)
        {
           
            throw new BusinessException("Proveedor requerido");
        }
        ProveedorDao proveedorDao=new ProveedorDaoImpl();
        return proveedorDao.saveProveedor(proveedor);
    }

    @Override
    public Proveedor updateProveedor(Proveedor proveedor) {
        ProveedorDao proveedorDao=new ProveedorDaoImpl();
        return proveedorDao.updateProveedor(proveedor);
    }

    @Override
    public void deleteProveedor(Proveedor proveedor) {
        ProveedorDao proveedorDao=new ProveedorDaoImpl();
        proveedorDao.deleteProveedor(proveedor);
    }

    @Override
    public List<Proveedor> getProveedor( ) {
        return new ProveedorDaoImpl().findProveedor();
    }

}
Las vistas contienen las clases para interactura con el usuario en caso de agregar medicamentos, actualizar catálogos o borrarlos, utilicé java.io y javax.swing.

Interfaz  de listado de proveedores:

 Código para vender medicamentos con java.io:

public class VentaForm {

    /**
     * @param args
     */
    public static void main(String[] args) {
      
        Scanner sc=new Scanner(System.in);
        Venta venta=new Venta();
        VentaService ventaServicio=new VentaServiceImpl();
      
        System.out.println("Venta de medicamentos");
      
        System.out.println("Ingresa le fecha de venta");
        String fecha=sc.next();
      
        System.out.println("Ingresa la cantidad");
        int cantidad=sc.nextInt();
      
        venta.setFecha_venta(fecha);
        venta.setCantidad(cantidad);
        ventaServicio.addVenta(venta);
        System.out.println("Venta Realizada");
        sc.close();
    }

}

 

viernes, 1 de marzo de 2013

MODULO III




Java Para Aplicaciones de Escritorio

Hilos

En el proyecto se utiliza el concepto de hilos en los JFrames de Java, al mostrar el frame:

SwingUtilities.invokeLater(new Runnable() {
public void run() {
Inicio inst = new Inicio();
inst.setLocationRelativeTo(null);
inst.setVisible(true);
}
});

Aparte de utilizar hilos dentro de cada JFrame, en el sistema se implemento un hilo que cambia la imagen del logo para simular un tipo de Banner en la pantalla de Inicio.


public void run() {
try {
while (activarhilo) {

{
banner = new JLabel();
jPanel1.add(banner);
banner.setIcon(new ImageIcon(getClass().getClassLoader().getResource("InterfazInicio/Imagenes/Imagen1.png")));
banner.setBounds(82, 14, 214, 57);
}

Thread.sleep( delay );
jPanel1.remove(banner);
{
banner = new JLabel();
jPanel1.add(banner);
banner.setIcon(new ImageIcon(getClass().getClassLoader().getResource("InterfazInicio/Imagenes/Imagen2.png")));
banner.setBounds(81, 18, 211, 48);
}


Thread.sleep( delay );
jPanel1.remove(banner);
}
} catch (InterruptedException ex) {
ex.printStackTrace();

}//fin catch

}





Colecciones y Genéricos

Las colecciones que se utilizaron en el avance del proyecto son:


  1. HashMap
  2. TreeMap
  3. HashTable


Se simulo una una base de datos de usuarios que entran al sistema, para ellos se uso un HashTable donde la clave es el nombre de usuario y el valor es la contraseña. Por lo tanto no pueden haber usuarios repetidos.


 Hashtable<String,String> tabla = new Hashtable<String,String>();
    
        tabla.put("empleado1", "aspirina1");


Cada registro de accesos se guarda en un archivo que simula la tabla de accesos de usuarios:


FileWriter f=new FileWriter(archlogin,true);
Fecha.getDate();
f.write("Usuario: "+usuario+"     "+"Fecha: "+Fecha.toString());
f.write("\n\n");


Desde el menú se pueden seleccionar diversas opciones para manejar la base de datos de medicamentos:


Desde este menu se llena el TreeMap de medicamentos utilizando la siguiente función:
private TreeMap<Integer,Medicamentos> medIn = new TreeMap<Integer,Medicamentos>();
private void PoblarMedicamentos(){
try
{
int id=1;
FileInputStream fstream = new FileInputStream("src/InterfazInicio/Catalogo.txt");
DataInputStream entrada = new DataInputStream(fstream);
BufferedReader buffer = new BufferedReader(new InputStreamReader(entrada));
String strLinea;
StringTokenizer token;
        // Leer el archivo linea por linea
        while ((strLinea = buffer.readLine()) != null){
       
        token= new StringTokenizer(strLinea, ":");
         
        String substancia=token.nextToken();
        String nombre=token.nextToken();
        String fecha=token.nextToken();
        String lab=token.nextToken();
        String contenido=token.nextToken();
        float precio=Float.parseFloat(token.nextToken());
        String proveedor=token.nextToken();
        String presentacion=token.nextToken();
       
      medIn.put(id, new Medicamentos(substancia,nombre,fecha,
    "", lab,contenido,precio, proveedor, presentacion));
      id++;
        }
        // Cerramos el archivo
        entrada.close();
}catch(IOException ex)
{
//System.out.println(ex.getMessage());
}
catch(Exception ex)
{
//System.out.println(ex.getMessage());
}
}//fin de poblarMedicamentos


La llave es un entero consecutivo y el valor es un objeto de la clase Medicamentos, la cual define los atributos y propiedades de un tipo de medicamento.

Este TreeMap se manda a las opciones Agregar Productos al Catálogo y Ver Catálogo.

Para agregar productos al TreeMap se utiliza el siguiente código:


medIn.put(new Integer(codigo.getText()),new Medicamentos(sustanciaActiva.getText(), nomComercial.getText(),
ingresoText.getText(),"", laboratorio.getText(),
contenidoTotal.getText(), Float.parseFloat(precio.getText()),
jComboBox1.getSelectedItem().toString(), jComboBox2.getSelectedItem().toString()));



Para mostrar el Catálogo se utiliza un JTable que se llena utilizando el TreeMap de Medicamentos, se define el modelo y se agrega a la tabla junto con la información de cada renglón y columna:
Model.addColumn("id");
Model.addColumn("SustanciaActiva");
Model.addColumn("nombreMed"); 
Model.addColumn("fechaEntrada"); 
Model.addColumn("fechaSalida"); 
Model.addColumn("Laboratorio"); 
Model.addColumn("contenidoTotal"); 
Model.addColumn("precio");
Model.addColumn("proveedor");
Model.addColumn("presentacion");
Model.setNumRows(medIn.size());
   while(itr.hasNext())
   {
    Object sustancia=itr.next();
    Medicamentos med=(Medicamentos) sustancia;
    Model.setValueAt(i, i, 0);
    Model.setValueAt(med.getSustanciaActiva(), i, 1);
    Model.setValueAt(med.getNombreMed(), i, 2);
    Model.setValueAt(med.getFechaEntrada(), i, 3);
    Model.setValueAt("", i, 4);
    Model.setValueAt(med.getLaboratorio(), i, 5);
    Model.setValueAt(med.getContenidoTotal(), i, 6);
    Model.setValueAt(med.getPrecio(), i, 7);
    Model.setValueAt(med.getProveedor(), i, 8);
    Model.setValueAt(med.getPresentacion(), i, 9);
    i++;
   }
jPanel1.add(tabla);
tabla.setModel(Model);
tabla.setBounds(49, 135, 665, 268);
tabla.setRequestFocusEnabled(false);



En la venta de medicamento se utilizan HashMap<String,Double>, se guardan los datos de la venta(código y precio), el precio es la multiplicación de la cantidad por el precio unitario; los precios se van a actualizar automáticamente cuando el usuario capture el código, el vendedor solo se encargará de capturar la cantidad de productos y al final se realizará la suma de todos los precios para cobrar el total por la venta.

Cuando se cree la base de datos todas las ventas serán registradas.

//Productos en la venta codigo precio
HashMap<String,Double> venta=new HashMap<String,Double>();

//Agregar Producto a la Venta
private void jButton1AgregarActionPerformed(ActionEvent evt) {
//Si la llave esta en el HasMap(codigo)
if(venta.containsKey(codigo.getText()))
{
Double val=(Double)venta.get(codigo.getText());
Double suma=(Double.parseDouble(cantidad.getText())*Double.parseDouble(precioUnitario.getText()))+val;
venta.put(codigo.getText(), suma);
}
else
venta.put(codigo.getText(),
Double.parseDouble(cantidad.getText())*Double.parseDouble(precioUnitario.getText()));
}
//Boton Sumar todos los productos
private void jButton1ActionPerformed(ActionEvent evt) {
Double suma=0.0d;
java.util.Iterator<Entry<String, Double>> it = venta.entrySet().iterator();
while (it.hasNext()) 
{
Map.Entry e = (Map.Entry)it.next();
suma=(Double)e.getValue()+suma;
}
Sumatotal.setText(String.valueOf(suma));
}