012 - Aplicación de Stock con Java. Hibernate – MySQL – JPA. Formulario transaccional Compra.

Primeramente vemos el diseño final del formulario (img. 01, clic para ampliar), que como siempre es un “jDialog”. Ponemos en letra roja como referencia los nombre de variable para cada objeto del diseño, esto es importante para que se ajusten a los métodos y eventos que vayamos creando. Los objetos sombreados están deshabilitadas para la edición, esto es importante y se puede aplicar desde “propiedades” de cada objeto, específicamente la propiedad “editable”. Se puede cambiar el “Nombre de variable” de cada objeto haciendo clic derecho sobre el mismo y en el menú desplegable seleccionar “Cambiar nombre de variable…”. El formulario de compras es similar a la de ventas, es posible reutilizar ese formulario modificando los datos que cambian, en este caso sacando cliente y agregando proveedor; además de otros puntos importantes.
En la imagen siguiente (img. 02) podemos ver las importaciones que agregamos para hacer funcionar nuestro formulario. También vemos los métodos que llamamos desde el constructor de la clase, que como sabemos se ejecutan al crear el formulario. Y las variables de clase que necesitaremos. Se agregan comentario para facilitar la comprensión de ciertas líneas de código.
Ahora debemos agregar los eventos necesarios. Como ya vimos en anteriores tutoriales, debemos de saber cómo implementarlas y sobre que objetos. Obs.: Utilizamos el evento “ActionPerformed” para llamar los métodos desde los botones. Se utiliza el evento “MouseClicked” para el jTable. Los eventos “KeyPressed” para los campos de texto, este último se activa al presionar una tecla específica, en este caso lo configuramos con la tecla “Intro”. Para utilizar un “Evento” hacemos clic derecho sobre el objeto y seleccionamos “Eventos” de la lista utilizamos la que podamos aplicar al objeto. En la mayoría de los casos se utiliza el “ActionPerformed”. Se agregan comentarios para tratar de facilitar el entendimiento.
Código Java
    private void nuevoActionPerformed(java.awt.event.ActionEvent evt) {                                      
nuevo();// Evento ActionPerformed para botón nuevo.
}

private void cancelarActionPerformed(java.awt.event.ActionEvent evt) {
arranque();// Evento ActionPerformed para botón cancelar.
}

private void agregarActionPerformed(java.awt.event.ActionEvent evt) {
agregar();// Evento ActionPerformed para botón agregar.

}

private void idKeyPressed(java.awt.event.KeyEvent evt) {
//Uso del Evento KeyPressed dentro del campo de texto "id".
if(evt.getKeyCode()== KeyEvent.VK_ENTER){
buscarFuncionario();
}
}

private void idProvKeyPressed(java.awt.event.KeyEvent evt) {
//Uso del Evento KeyPressed dentro del campo de texto "idProv".
if(evt.getKeyCode() == KeyEvent.VK_ENTER){
buscarProveedor();
}
}

private void idArtKeyPressed(java.awt.event.KeyEvent evt) {
//Uso del Evento KeyPressed dentro del campo de texto "idArt".
if(evt.getKeyCode() == KeyEvent.VK_ENTER){
buscarArticulo();
}
}

private void cantidadKeyPressed(java.awt.event.KeyEvent evt) {
//Uso del Evento KeyPressed dentro del campo de texto "cantidad".
if(evt.getKeyCode() == KeyEvent.VK_ENTER){
calcularParcial();
}
}

private void eliminarActionPerformed(java.awt.event.ActionEvent evt) {
eliminar();// Evento ActionPerformed para botón eliminar.
}

private void guardarActionPerformed(java.awt.event.ActionEvent evt) {
guardar();// Evento ActionPerformed para botón guardar.
}
A continuación vemos los métodos que utilizaremos para hacer funcionar a nuestro formulario. A cada método le asignamos un nombre que nos indica la función que está cumpliendo, esto facilita entender en qué lugar la aplicamos. En partes específicas se agregan comentarios para facilitar el entendimiento de ciertas líneas de código.
Código Java
public void hibernateSession(){
//Abrimos una session y la guardamos en una variable de clase.
st = HibernateUtil.getSessionFactory().openSession();
}
public void arranque(){
//Configuramos objetos para el arranque.
this.nuevo.setEnabled(true);
this.agregar.setEnabled(false);
this.eliminar.setEnabled(false);
this.guardar.setEnabled(false);
this.num.setText(null);
this.fecha.setText(null);
this.hora.setText(null);
this.id.setText(null);
this.id.setEnabled(false);
this.nombres.setText(null);
this.apellidos.setText(null);
this.idProv.setText(null);
this.idProv.setEnabled(false);
this.dirProv.setText(null);
this.idArt.setText(null);
this.idArt.setEnabled(false);
this.desArt.setText(null);
this.pco.setText(null);
this.can.setText(null);
this.cantidad.setText(null);
this.cantidad.setEnabled(false);
this.total.setText(null);
this.totalGeneral.setText(null);
tableModel();
}
public void tableModel(){
//Configuramos el jTable utilizando DefaultTableModel
this.jTable1.getColumnModel().getColumn(0).setPreferredWidth(15);
this.jTable1.getColumnModel().getColumn(1).setPreferredWidth(150);
this.jTable1.getColumnModel().getColumn(2).setPreferredWidth(80);
this.jTable1.getColumnModel().getColumn(3).setPreferredWidth(50);
this.jTable1.getColumnModel().getColumn(4).setPreferredWidth(80);
model = (DefaultTableModel)this.jTable1.getModel();
model.setNumRows(0);
}
public void nuevo(){
//Configuramos acciones, habilitamos campos al precionar el botón nuevo
obtenetID();
this.id.setEnabled(true);
this.idProv.setEnabled(true);
this.idArt.setEnabled(true);
this.cantidad.setEnabled(true);
this.agregar.setEnabled(true);
this.eliminar.setEnabled(true);
this.guardar.setEnabled(true);
this.nuevo.setEnabled(false);
this.id.requestFocus();
Calendar cal = Calendar.getInstance();
String calString = retornarString(cal);
String calHora = retornarStringHora(cal);
this.fecha.setText(calString);
this.num.setText(String.valueOf(numCompra));
this.hora.setText(calHora);
}
public void obtenetID(){
//Utilizamos el método siguiente para conseguir en número de compra...
//correspondiente
numCompra = 0;
List<CompraCab> lista = (List<CompraCab>)st.createQuery("From CompraCab").list();
for (Iterator<CompraCab> it = lista.iterator(); it.hasNext();) {
CompraCab compraCab = it.next();
numCompra = compraCab.getNum() + 1;
}
if(numCompra==0){
numCompra=1;
}
}
public void buscarArticulo(){
//Utilizamos el método siguiente para buscar artículos por el "ID",
//este método se llama desde un evento KeyPressed.
int idArti = 0;
try {
try {
idArti = Integer.parseInt(this.idArt.getText());
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "ID debe ser numérico.");
}
Articulo art = (Articulo)st.load(Articulo.class, idArti);
this.desArt.setText(art.getDes());
this.pco.setText(String.valueOf(art.getPco()));
this.can.setText(String.valueOf(art.getCan()));
this.cantidad.requestFocus();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "No hay artículo con ID: " + idArti);
}
}
public void calcularParcial(){
//Lo siguiente nos permite calcular el total para cada artículo,
//esto tomando en cuenta total de compra y precio de compra.
int canCompra = 0;
int pCompra = 0;
int totalParcial = 0 ;
try {
canCompra = Integer.parseInt(this.cantidad.getText());
pCompra = Integer.parseInt(this.pco.getText());
totalParcial = canCompra * pCompra;
this.total.setText(String.valueOf(totalParcial));
this.agregar.requestFocus();

} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Se requiere datos numérico.");
}
}
public void buscarFuncionario(){
//Utilizamos el método siguiente para buscar funcionario por el "ID",
//este método se llama desde un evento KeyPressed.
int idFunc = 0;
try {
try {
idFunc = Integer.parseInt(this.id.getText());
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "ID debe ser numérico.");
}
Funcionario funcio = (Funcionario)st.load(Funcionario.class, idFunc);
this.nombres.setText(funcio.getNombres());
this.apellidos.setText(funcio.getApellidos());
this.idProv.requestFocus();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "No hay funcionario con ID: " + idFunc);
}
}
public void buscarProveedor(){
//Utilizamos el método siguiente para buscar proveedor por el "ID",
//este método se llama desde un evento KeyPressed.
int idPrv = 0;
try {
try {
idPrv = Integer.parseInt(this.idProv.getText());
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "ID debe ser numérico.");
}
Proveedor proveedor = (Proveedor)st.load(Proveedor.class, idPrv);
this.desProv.setText(proveedor.getDes());
this.dirProv.setText(proveedor.getDir());
this.idArt.requestFocus();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "No hay proveedor con ID: " + idPrv);
}
}
public void agregar(){
//Método llamado desde el botón agregar, primeramente comprobamos que los datos sean correctos,
//que los campos no esten vacios, que no se repitan datos.
if(this.id.getText().isEmpty()){
JOptionPane.showMessageDialog(null, "Seleccione un funcionario.");
}
else{
if(this.idProv.getText().isEmpty()){
JOptionPane.showMessageDialog(null, "Seleccione un proveedor.");
}
else{
if(this.idArt.getText().isEmpty()){
JOptionPane.showMessageDialog(null, "Seleccione un articulo.");
}
else{
if(this.cantidad.getText().isEmpty()){
JOptionPane.showMessageDialog(null, "Indique una cantidad.");
}
else{
verificar();
if(var>=1){
int showConfirmDialog = JOptionPane.showConfirmDialog(null, "Artículo ya Agregado. Desea sumar la cantidad.", "Mensaje del Sistema.", JOptionPane.YES_NO_OPTION);
if(showConfirmDialog==0){
sumarRepetido();
calcular();
confimAgregar();
limpiar();
}
else{
limpiar();
this.idArt.requestFocus();
}
}
else{
model.addRow(new Object[]{
this.idArt.getText(),this.desArt.getText(),this.pco.getText(),this.cantidad.getText(),this.total.getText()
});
calcular();
confimAgregar();
limpiar();
}

}
}
}
}
}
public void confimAgregar(){
//Método que pregunta al usuario si desea agregar más artículo a la lista.
int showConfirmDialog = JOptionPane.showConfirmDialog(null, "Agregar más Articulos.", "Mensaje del Sistema.", JOptionPane.YES_NO_OPTION);
if(showConfirmDialog == 0){
this.idArt.requestFocus();
}
else{
this.guardar.requestFocus();
}

}
public void limpiar(){
//Limpia campo de datos..
this.idArt.setText(null);
this.desArt.setText(null);
this.pco.setText(null);
this.can.setText(null);
this.cantidad.setText(null);
this.total.setText(null);
this.id.setEnabled(false);
this.idProv.setEnabled(false);
}
public void calcular(){
//Método para calcular el total de la compra, obteniendo datos del jtable.
int totalG = 0;
for (int i = 0; i < this.jTable1.getRowCount(); i++) {
Object valueAt = model.getValueAt(i, 4);
totalG += Integer.parseInt(valueAt.toString());
}
this.totalGeneral.setText(String.valueOf(totalG));
}
public void verificar(){
//Método para verificar que no se duplique el mismo artículo en la tabla,
//para ello se comprueba el id del artículo.
var = 0;
int idAr = Integer.parseInt(this.idArt.getText());
if(this.jTable1.getRowCount()>=1){
for (int i = 0; i < this.jTable1.getRowCount(); i++) {
Object valueAt = model.getValueAt(i, 0);
int parseInt = Integer.parseInt(valueAt.toString());
if(idAr == parseInt){
var = 1;
idArtt = i;
}
}
}
}
public void sumarRepetido(){
//Si se repite el ingreso de un artículo específico,se puede obtar por sumar la cantidad de compra,
//este método localizar el id del artículo específico y aumenta la cantidad de la
//compra sumandola.
int artCant = Integer.parseInt(this.cantidad.getText());
int artTotal = Integer.parseInt(this.total.getText());
Object valueAt = model.getValueAt(idArtt, 3);
Object valueAt1 = model.getValueAt(idArtt, 4);
int cantArt = Integer.parseInt(valueAt.toString());
int totalArt = Integer.parseInt(valueAt1.toString());
int x = artCant + cantArt;
int y = artTotal + totalArt;
model.setValueAt(x, idArtt, 3);
model.setValueAt(y, idArtt, 4);
}

public String retornarString(Calendar fecha){
//Médodo que se le para un objeto calendar y la combierte en formato String-Fecha
String retorno=null;
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
if (fecha != null) {
retorno = sdf.format(fecha.getTime());
}
return retorno;
}
public String retornarStringHora(Calendar fecha){
//Médodo que se le para un objeto calendar y la combierte en formato String-hora
String retorno=null;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
if (fecha != null) {
retorno = sdf.format(fecha.getTime());
}
return retorno;
}
public Calendar retornarCalendar(String fecha){
//Se le pasa como argumento un String-Fecha y la combierte en objeto calendar.
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Calendar cal = Calendar.getInstance();
try {
cal.setTime(sdf.parse(fecha));
} catch (ParseException ex) {
JOptionPane.showMessageDialog(null, "Error; compruebe formato de fecha: " + ex);
}
return cal;
}
public void eliminar(){
//Permite al usuario seleccionar una fila específica de la table y eliminarla.
if(this.jTable1.getSelectedRow()==-1){
JOptionPane.showMessageDialog(null, "No ha seleccionado ninguna fila de la tabla.");
}
else{
int showConfirmDialog = JOptionPane.showConfirmDialog(null, "Eliminar fila seleccionada.", "Mensaje del Sistema.", JOptionPane.YES_NO_OPTION);
if(showConfirmDialog == 0){
int sel = this.jTable1.getSelectedRow();
model.removeRow(sel);
this.idArt.requestFocus();
}
else{
this.idArt.requestFocus();
}
}
}
public void guardar(){
//Metodo que nos permite almacenar los datos intruducidos en la base de datos,
//los datos se guardan en la tabla CompraCab y CompraDet.
//la primera almacena la cabecera de compra y la segunda los detalles.
if(this.id.getText().isEmpty() ||this.idProv.getText().isEmpty() ){
JOptionPane.showMessageDialog(null, "Faltan datos para guardar. Verifique.");
}
else{
if(this.jTable1.getRowCount()==0){
JOptionPane.showMessageDialog(null, "No hay datos para guardar.");
}
else{
int showConfirmDialog = JOptionPane.showConfirmDialog(null, "Desea guardar esta compra.", "Mensaje del Sistema.", JOptionPane.YES_NO_OPTION);
if(showConfirmDialog == 0){
try {
st.beginTransaction();
CompraCab compra = new CompraCab();
int idFun = Integer.parseInt(this.id.getText());
int idPrv = Integer.parseInt(this.idProv.getText());
long totalCompra = Long.parseLong(this.totalGeneral.getText());
Funcionario funcionario = (Funcionario)st.load(Funcionario.class, idFun);
Proveedor proveedor = (Proveedor)st.load(Proveedor.class, idPrv);
Calendar fechaCompra = retornarCalendar(this.fecha.getText());
String horaCompra = this.hora.getText();
compra.setNum(Integer.valueOf(this.num.getText()));
compra.setProveedor(proveedor);
compra.setFuncionario(funcionario);
compra.setFecha(fechaCompra);
compra.setHora(horaCompra);
compra.setTotal(totalCompra);
funcionario.getCompraCabs().add(compra);
proveedor.getCompraCabs().add(compra);
int rowCount = this.jTable1.getRowCount();
int[] idArti = new int[rowCount];
int[] cantCompra = new int[rowCount];
for (int i = 0; i < this.jTable1.getRowCount(); i++) {
CompraDet detalleCompra = new CompraDet();
int idArticulo = Integer.parseInt(String.valueOf(model.getValueAt(i, 0)));
idArti[i] = idArticulo;
Articulo ventaArticulo = (Articulo)st.load(Articulo.class, idArticulo);
int cantidadCompra = Integer.parseInt(String.valueOf(model.getValueAt(i, 3)));
cantCompra[i]= cantidadCompra;
int importeVenta = Integer.parseInt(String.valueOf(model.getValueAt(i, 4)));
detalleCompra.setArticulo(ventaArticulo);
detalleCompra.setCantidad(cantidadCompra);
detalleCompra.setImporte(importeVenta);
detalleCompra.setCabecera(compra);
compra.getCompraDets().add(detalleCompra);
}
st.save(compra);
st.getTransaction().commit();
for (int i = 0; i < idArti.length; i++) {
actualizarStrock(cantCompra[i], idArti[i]);
}
arranque();
JOptionPane.showMessageDialog(null, "Compra guardada correctamente.");
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error guardando compra. Verifique.");
}

}
else{
this.idArt.requestFocus();
}

}
}
}
public void actualizarStrock(int cantidadCompra, int idArticulo){
//Despúes que el proceso de guardado se de de forma correcta,
//se actualizar el stock de los artículos comprados.
st.beginTransaction();
Articulo actualizar = (Articulo)st.load(Articulo.class, idArticulo);
int temp = actualizar.getCan() + cantidadCompra;
actualizar.setCan(temp);
st.update(actualizar);
st.getTransaction().commit();
}
Por último, (img. 03) vemos el resultado ejecutando el formulario.
Obs.: Resulta difícil explicar todo el proceso y función de cada línea de código por tanto pueden realizar un comentario con sus dudas.

2 comentarios :

  1. creo que la variable total estaba puesta como toral muchas gracias por el tuto

    ResponderEliminar
    Respuestas
    1. He visto el error, gracias por la puntualización. Tendría que ser total.

      Eliminar