Files
sistema-caja/src/danielcortes/xyz/controllers/EgresosController.java
2018-12-30 21:22:39 -03:00

430 lines
16 KiB
Java

/*
* MIT License
*
* Copyright (c) 2018 Daniel Cortes
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package danielcortes.xyz.controllers;
import danielcortes.xyz.models.caja.Caja;
import danielcortes.xyz.models.egreso.Egreso;
import danielcortes.xyz.models.egreso.EgresoDAO;
import danielcortes.xyz.models.tipo_egreso.TipoEgreso;
import danielcortes.xyz.models.tipo_egreso.TipoEgresoDAO;
import danielcortes.xyz.views.EgresosView;
import danielcortes.xyz.views.components.EgresosTableModel;
import javax.swing.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class EgresosController {
private EgresosView view;
private EgresoDAO egresoDAO;
private TipoEgresoDAO tipoEgresoDAO;
private Caja caja;
private int editingId;
private boolean editing;
private Egreso editingEgreso;
/**
* Crea el controlador, el cual esta acoplado con la vista de egresos, controlando el estado y el contenido de esta
* Al inicial ejecuta:
* - Metodo que genera los eventos para la vista.
* - Metodo que llena los tipos de egresos en la vista.
* - Actualiza el estado de los botones.
*/
public EgresosController(EgresosView view, EgresoDAO egresoDAO, TipoEgresoDAO tipoEgresoDAO) {
this.view = view;
this.egresoDAO = egresoDAO;
this.tipoEgresoDAO = tipoEgresoDAO;
this.setUpViewEvents();
this.fillTipoEgresoCombo();
this.updateButtonsEnabled();
}
/**
* Getter!
* @return
*/
public EgresoDAO getEgresoDAO() {
return egresoDAO;
}
/**
* Getter
* @return
*/
public TipoEgresoDAO getTipoEgresoDAO() {
return tipoEgresoDAO;
}
/**
* Guarda la caja entregada y actualiza los datos de la tabla de egresos y actualiza el field con el total de egresos.
*/
public void updateCaja(Caja caja){
this.caja = caja;
this.fillEgresosTable();
this.updateTotalEgresos();
}
/**
* Rellena el ComboBox con los tipos de egresos disponibles
*/
private void fillTipoEgresoCombo() {
JComboBox<TipoEgreso> tipoCombo = view.getTipoCombo();
for (TipoEgreso tipoEgreso : this.tipoEgresoDAO.findAll()) {
tipoCombo.addItem(tipoEgreso);
}
}
/**
* Rellena la tabla de egresos con los egresos correspondientes a la caja seleccionada
*/
private void fillEgresosTable() {
EgresosTableModel egresosTableModel = view.getEgresosTableModel();
egresosTableModel.removeRows();
for (Egreso egreso : this.egresoDAO.findByCaja(this.caja)) {
egresosTableModel.addRow(egreso);
}
}
/**
* Asigna todos los eventos para la vista de egresos.
* - Cuando se apreta el boton de guardar o se apreta enter en los fields de descripcion, nro, valor y tipo
* Se llama al metodo guardarActionListener.
* - Cuando se apreta el boton de eliminar se llama al metodos eliminarActionListener
* - Cuando se presiona editar o se realizan 2 clicks en la tabla de egresos se llama a editarActionListener
* - Cuando se selecciona una fila en la tabla se llama a updateButtonsEnabled
*/
private void setUpViewEvents() {
this.view.getEgresosTable().getSelectionModel().addListSelectionListener(e -> updateButtonsEnabled());
this.view.getGuardarButton().addActionListener(e -> guardarActionListener());
this.view.getEliminarButton().addActionListener(e -> eliminarActionListener());
this.view.getEditarButton().addActionListener(e -> editarActionListener());
this.view.getDescripcionField().addActionListener(e -> guardarActionListener());
this.view.getNroField().addActionListener(e -> guardarActionListener());
this.view.getValorField().addActionListener(e -> guardarActionListener());
this.view.getTipoCombo().addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
guardarActionListener();
}
}
});
this.view.getEgresosTable().addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent mouseEvent) {
JTable table = (JTable) mouseEvent.getSource();
if (mouseEvent.getClickCount() == 2 && table.getSelectedRow() != -1) {
EgresosController.this.editarActionListener();
}
}
});
}
/**
* Realiza las preparaciones previas a guardar un egreso
* Primero llama a normalizar los inputs y a ocultar los mensajes de error
* Luego si es que esta colocada la flag de editing se llama al metodo editarEgreso y si no, se llama a guardarEgreso
* Al terminar esto, se llama a resetear el focus en los inputs y a actualizar el total de egresos
*
*/
private void guardarActionListener() {
this.normalizeInputs();
this.hideErrorMessages();
String nro = this.view.getNroField().getText();
String descripcion = this.view.getDescripcionField().getText();
String valor = this.view.getValorField().getText();
TipoEgreso tipo = (TipoEgreso) this.view.getTipoCombo().getSelectedItem();
if(editing){
this.editarEgreso(nro, descripcion, valor, tipo, this.caja);
}else {
this.guardarEgreso(nro, descripcion, valor, tipo, this.caja);
}
this.resetFocus();
}
/**
* Realiza las acciones necesarias para eliminar un egreso
* Obtiene el egreso seleccionado y lo elimina, luego llama a actualizar el total de egresos y a actualizar el estado de los botones.
*/
private void eliminarActionListener() {
int selectedID = this.view.getEgresosTable().getSelectedRow();
if (selectedID >= 0) {
Egreso egreso = this.view.getEgresosTableModel().getEgreso(selectedID);
this.view.getEgresosTableModel().removeRow(selectedID);
this.egresoDAO.deleteEgreso(egreso);
this.updateTotalEgresos();
this.updateButtonsEnabled();
}
}
/**
* Realiza lo necesario para comenzar a editar un egreso
* Llama a esconder los mensajes de error.
* Guarda globalmente en la clase el egreso que se esta editando, su id y una flag indicando que se esta en modo editar.
* Ademas rellena los campos de input con los valores del egreso que se esta editando.
*/
private void editarActionListener() {
this.hideErrorMessages();
int selectedID = this.view.getEgresosTable().getSelectedRow();
if (selectedID >= 0) {
Egreso egreso = this.view.getEgresosTableModel().getEgreso(selectedID);
this.editingId = selectedID;
this.editingEgreso = egreso;
this.editing = true;
this.view.getNroField().setText(egreso.getNro());
this.view.getDescripcionField().setText(egreso.getDescripcion());
this.view.getValorField().setText(String.valueOf(egreso.getValor()));
this.view.getTipoCombo().setSelectedItem(egreso.getTipoEgreso());
}
}
/**
* Obtiene el total de egresos y los coloca en el campo de totalEgresosField.
*/
private void updateTotalEgresos() {
int total = this.egresoDAO.getTotalEgreso(this.caja);
this.view.getTotalEgresosField().setText(String.valueOf(total));
}
/**
* Cuando se tiene seleccionada una fila de la tabla activa los botones de eliminar y editar
* Si no esta seleccionada los desactiva
*/
private void updateButtonsEnabled() {
if (this.view.getEgresosTable().getSelectedRow() >= 0) {
this.view.getEliminarButton().setEnabled(true);
this.view.getEditarButton().setEnabled(true);
} else {
this.view.getEliminarButton().setEnabled(false);
this.view.getEditarButton().setEnabled(false);
}
}
/**
* Guarda un egreso tras llamar a validar su input
* Luego de guardar, agrega el egreso a la tabla, llama a actualizar el total de egresos y llama a limpiar a los inputs
*/
private void guardarEgreso(String nro, String descripcion, String valor, TipoEgreso tipo, Caja caja) {
if (this.validateInput(nro, descripcion, valor, tipo, caja)) {
Egreso egreso = new Egreso();
egreso.setValor(Integer.valueOf(valor));
egreso.setDescripcion(descripcion);
egreso.setNro(nro);
egreso.setTipoEgreso(tipo);
egreso.setCaja(caja);
egresoDAO.insertEgreso(egreso);
this.view.getEgresosTableModel().addRow(egreso);
this.updateTotalEgresos();
this.clearInputs();
}
}
/**
* Actualiza un egreso tras llamar a validar su input
* Tras esto actualiza el egreso en la tabla, llama a actualizar el total de egresos y a limpiar los inputs
* Finalmente setea la flag editing a false
*/
private void editarEgreso(String nro, String descripcion, String valor, TipoEgreso tipo, Caja caja) {
if (this.validateInput(nro, descripcion, valor, tipo, caja)) {
this.editingEgreso.setValor(Integer.valueOf(valor));
this.editingEgreso.setDescripcion(descripcion);
this.editingEgreso.setNro(nro);
this.editingEgreso.setTipoEgreso(tipo);
egresoDAO.updateEgreso(this.editingEgreso);
this.view.getEgresosTableModel().setEgreso(this.editingId, this.editingEgreso);
this.updateTotalEgresos();
this.clearInputs();
this.editing = false;
}
}
/**
* llama a los metodos necesarios para validar los inputs entregados
* @return true cuando todas las validaciones retoran true, si no, false
*/
private boolean validateInput(String nro, String descripcion, String valor, TipoEgreso tipoEgreso, Caja caja) {
boolean nroValidation = this.validateNro(nro);
boolean descripcionValidation = this.validateDescripcion(descripcion);
boolean valorValidation = this.validateValor(valor);
boolean tipoEgresoValidation = this.validateTipoEgreso(tipoEgreso);
boolean cajaValidation = this.validateCaja(caja);
return nroValidation && descripcionValidation && valorValidation && tipoEgresoValidation;
}
/**
* Valida la variable nro contra los casos
* - Es null
* - Esta vacio
* Cuando el primer caso sea true, colocara un mensaje de error correspondiente en el jlabel correspondiente
* @return Si cualquiera de estos casos son true se retornara false, si no, se retorna true
*/
private boolean validateNro(String nro) {
if (nro == null) {
this.view.getErrorNumero().setText("Hubo un problema con los datos");
this.view.getErrorNumero().setVisible(true);
return false;
}
nro = nro.trim();
if (nro.isEmpty()) {
this.view.getErrorNumero().setText("El campo esta vacio");
this.view.getErrorNumero().setVisible(true);
return false;
}
return true;
}
/**
* Valida la variable descripcion contra los casos
* - Es null
* - Esta vacio
* Cuando el primer caso sea true, colocara un mensaje de error correspondiente en el jlabel correspondiente
* @return Si cualquiera de estos casos son true se retornara false, si no, se retorna true
*/
private boolean validateDescripcion(String descripcion) {
if (descripcion == null) {
this.view.getErrorDescripcion().setText("Hubo un problema con los datos");
this.view.getErrorDescripcion().setVisible(true);
return false;
}
if (descripcion.isEmpty()) {
this.view.getErrorDescripcion().setText("El campo esta vacio");
this.view.getErrorDescripcion().setVisible(true);
return false;
}
return true;
}
/**
* Valida la variable valor contra los casos
* - Es null
* - Esta vacio
* - Los caracteres no son todos digitos
* - El largo del string es mayot a 10
* Cuando el primer caso sea true, colocara un mensaje de error correspondiente en el jlabel correspondiente
* @return Si cualquiera de estos casos son true se retornara false, si no, se retorna true
*/
private boolean validateValor(String valor) {
if (valor == null) {
this.view.getErrorValor().setText("Hubo un problema con los datos");
this.view.getErrorValor().setVisible(true);
return false;
}
if (valor.isEmpty()) {
this.view.getErrorValor().setText("El campo esta vacio");
this.view.getErrorValor().setVisible(true);
return false;
}
if (!valor.chars().allMatch(Character::isDigit)) {
this.view.getErrorValor().setText("Deben ser numeros");
this.view.getErrorValor().setVisible(true);
return false;
}
if (valor.length() > 10) {
this.view.getErrorValor().setText("El numero ingresado es demasiado largo");
this.view.getErrorValor().setVisible(true);
return false;
}
return true;
}
/**
* Valida la variable tipoEgreso contra los casos
* - Es null
* Cuando este caso sea true, colocara un mensaje de error correspondiente en el jlabel correspondiente
* @return Si este caso es true se retornara false, si no, se retorna true
*/
private boolean validateTipoEgreso(TipoEgreso tipoEgreso) {
if (tipoEgreso == null) {
this.view.getErrorTipoEgreso().setText("Hubo un problema con los datos");
this.view.getErrorTipoEgreso().setVisible(true);
return false;
}
return true;
}
/**
* Valida la variable caja contra los casos
* - Es null
* @return Si este caso es true se retornara false, si no, se retorna true
*/
private boolean validateCaja(Caja caja){
return caja != null;
}
/**
* Esconde los mensajes de error en la ventana de egresos
*/
private void hideErrorMessages() {
this.view.getErrorTipoEgreso().setVisible(false);
this.view.getErrorValor().setVisible(false);
this.view.getErrorDescripcion().setVisible(false);
this.view.getErrorNumero().setVisible(false);
}
/**
* Vacia los campos de texto y selecciona la primera opcion en el jcombobox
*/
private void clearInputs() {
this.view.getTipoCombo().setSelectedIndex(0);
this.view.getNroField().setText("");
this.view.getValorField().setText("");
this.view.getDescripcionField().setText("");
}
/**
* Ejecuta trim sobre todos los campos de texto
*/
private void normalizeInputs(){
this.view.getValorField().setText(this.view.getValorField().getText().trim());
this.view.getNroField().setText(this.view.getNroField().getText().trim());
this.view.getDescripcionField().setText(this.view.getDescripcionField().getText().trim());
}
/**
* Setea el focus en el campo nroField
*/
private void resetFocus() {
this.view.getNroField().requestFocus();
}
}