458 lines
18 KiB
Java
458 lines
18 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.ingreso.Ingreso;
|
|
import danielcortes.xyz.models.ingreso.IngresoDAO;
|
|
import danielcortes.xyz.models.tipo_ingreso.TipoIngreso;
|
|
import danielcortes.xyz.models.tipo_ingreso.TipoIngresoDAO;
|
|
import danielcortes.xyz.views.IngresosView;
|
|
import danielcortes.xyz.views.components.IngresosTableModel;
|
|
import org.jetbrains.annotations.Contract;
|
|
|
|
import javax.swing.*;
|
|
import java.awt.event.*;
|
|
|
|
/**
|
|
* Controlador el cual esta orientado a manejar la vista de IngresosView
|
|
* Maneja su contenido y las acciones que esta realiza
|
|
*/
|
|
public class IngresosController {
|
|
private IngresosView view;
|
|
private IngresoDAO ingresoDAO;
|
|
private TipoIngresoDAO tipoIngresoDAO;
|
|
private Caja caja;
|
|
|
|
private int editingId;
|
|
private Ingreso editingIngreso;
|
|
private boolean editing;
|
|
|
|
/**
|
|
* Crea el controlado de egresos, el cual esta acoplado con la vista de ingresos, controlando el estado y contenido de esta.
|
|
* Al iniciarse ejecuta.
|
|
* - Metodo que llena el combobox de tipos de ingreso
|
|
* - Metodo que genera los eventos para la vista
|
|
* - Metodo que actualiza el estado de los botones
|
|
*/
|
|
public IngresosController(IngresosView view, IngresoDAO ingresoDAO, TipoIngresoDAO tipoIngresoDAO) {
|
|
this.view = view;
|
|
this.ingresoDAO = ingresoDAO;
|
|
this.tipoIngresoDAO = tipoIngresoDAO;
|
|
this.fillTipoIngresoCombo();
|
|
this.setupViewEvents();
|
|
this.updateButtonsEnabled();
|
|
}
|
|
|
|
/**
|
|
* Getter!!
|
|
*/
|
|
public IngresoDAO getIngresoDAO() {
|
|
return ingresoDAO;
|
|
}
|
|
|
|
/**
|
|
* Getter!!!
|
|
* @return
|
|
*/
|
|
public TipoIngresoDAO getTipoIngresoDAO() {
|
|
return tipoIngresoDAO;
|
|
}
|
|
|
|
/**
|
|
* Guarda la caja ingresada y actualiza el contenido de la tabla de ingresos y el campo de total de ingresos
|
|
*/
|
|
public void updateCaja(Caja caja){
|
|
this.caja = caja;
|
|
this.fillIngresosTable();
|
|
this.updateTotalIngresos();
|
|
}
|
|
|
|
/**
|
|
* LLena el combobox de tipos de ingresos
|
|
*/
|
|
private void fillTipoIngresoCombo() {
|
|
JComboBox<TipoIngreso> tipoCombo = this.view.getTipoCombo();
|
|
for (TipoIngreso tipo : this.tipoIngresoDAO.findAll()) {
|
|
tipoCombo.addItem(tipo);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Llena la tabla de ingresos con los ingresos pertenecientes a la caja guarda
|
|
*/
|
|
private void fillIngresosTable() {
|
|
IngresosTableModel ingresosTableModel = this.view.getIngresosTableModel();
|
|
ingresosTableModel.removeRows();
|
|
for (Ingreso ingreso : this.ingresoDAO.findByCaja(this.caja)) {
|
|
ingresosTableModel.addRow(ingreso);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Genera los eventos para los distintos componentes de la vista
|
|
* - Cuando se presiona el boton de guardar o se apreta enter en los fields de valor, nro inicial,
|
|
* nro final y tipo se llama a guardarActionListener
|
|
* - Cuando se presiona el boton de eliminar se llama al eliminarActionListener
|
|
* - Cuando se selecciona una fila en la tabla se llama a updateButtonsEnabled
|
|
* - Cuando se presiona el boton de editar o se hace doble click sobre una fila de la tabla se llama a editarActionListener
|
|
*/
|
|
private void setupViewEvents() {
|
|
this.view.getValorField().getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke("ENTER"), "nextField");
|
|
this.view.getNroInicialField().getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke("ENTER"), "nextField");
|
|
this.view.getNroFinalField().getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke("ENTER"), "nextField");
|
|
this.view.getTipoCombo().getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke("ENTER"), "save");
|
|
|
|
this.view.getValorField().getActionMap().put("nextField", new NextAction(this.view.getNroInicialField()));
|
|
this.view.getNroInicialField().getActionMap().put("nextField", new NextAction(this.view.getNroFinalField()));
|
|
this.view.getNroFinalField().getActionMap().put("nextField", new NextAction(this.view.getTipoCombo()));
|
|
this.view.getTipoCombo().getActionMap().put("save", new GuardarAction(this));
|
|
|
|
this.view.getIngresosTable().getSelectionModel().addListSelectionListener(e -> updateButtonsEnabled());
|
|
this.view.getGuardarButton().addActionListener(e -> guardarActionListener());
|
|
this.view.getEliminarButton().addActionListener(e -> eliminarActionListener());
|
|
this.view.getEditarButton().addActionListener(e -> editarActionListener());
|
|
|
|
this.view.getIngresosTable().addMouseListener(new MouseAdapter() {
|
|
public void mouseClicked(MouseEvent mouseEvent) {
|
|
JTable table = (JTable) mouseEvent.getSource();
|
|
if (mouseEvent.getClickCount() == 2 && table.getSelectedRow() != -1) {
|
|
IngresosController.this.editarActionListener();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Realiza las preparaciones previas a guardar un ingreso
|
|
* Primero llama a normalizar los inputs y a esconder los mensajes de error
|
|
* Luego dependiendo si se tiene la flag editing en true o false se llama a editar ingreso o a guardarlo
|
|
* Tras terminar esto se llama a resetear el focus.
|
|
*/
|
|
private void guardarActionListener() {
|
|
this.normalizeInputs();
|
|
this.hideErrorMessages();
|
|
|
|
String valor = this.view.getValorField().getText();
|
|
String nroInicial = this.view.getNroInicialField().getText();
|
|
String nroFinal = this.view.getNroFinalField().getText();
|
|
TipoIngreso tipoIngreso = (TipoIngreso) this.view.getTipoCombo().getSelectedItem();
|
|
|
|
if(editing) {
|
|
this.editarIngreso(valor, nroInicial, nroFinal, tipoIngreso, this.caja);
|
|
} else {
|
|
this.guardarIngreso(valor, nroInicial, nroFinal, tipoIngreso, this.caja);
|
|
}
|
|
this.resetFocus();
|
|
}
|
|
|
|
/**
|
|
* Realiza las acciones necesarias para eliminar un ingreso
|
|
* Solo lo va a realizar si es que esta seleccionada una fila de la tabla, se eliminara el ingreso seleccionado
|
|
* Una vez eliminado se llama a actualizar el total de ingresos y el estado de los botones
|
|
*/
|
|
private void eliminarActionListener() {
|
|
int selectedId = this.view.getIngresosTable().getSelectedRow();
|
|
if(selectedId >= 0){
|
|
Ingreso ingreso = this.view.getIngresosTableModel().getIngreso(selectedId);
|
|
this.view.getIngresosTableModel().removeRow(selectedId);
|
|
this.ingresoDAO.deleteIngreso(ingreso);
|
|
this.updateTotalIngresos();
|
|
this.updateButtonsEnabled();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Realiza las preparaciones previas a editar un ingreso
|
|
* Primero llama a esconder los mensajes de error.
|
|
* Guarda globlarmente el ingreso a ser editar, el id de este y una flag que indica que se esta en modo de editar.
|
|
* Finalmente llena los campos de inputs con los datos del ingreso a editar.
|
|
*/
|
|
private void editarActionListener() {
|
|
this.hideErrorMessages();
|
|
|
|
int selectedID = this.view.getIngresosTable().getSelectedRow();
|
|
int selectedModelID = this.view.getIngresosTable().getRowSorter().convertRowIndexToModel(selectedID);
|
|
if(selectedModelID >= 0) {
|
|
Ingreso ingreso = this.view.getIngresosTableModel().getIngreso(selectedModelID);
|
|
|
|
this.editingId = selectedModelID;
|
|
this.editingIngreso = ingreso;
|
|
this.editing = true;
|
|
|
|
this.view.getTipoCombo().setSelectedItem(ingreso.getTipoIngreso());
|
|
this.view.getValorField().setText(String.valueOf(ingreso.getValor()));
|
|
this.view.getNroInicialField().setText(String.valueOf(ingreso.getNroInicial()));
|
|
this.view.getNroFinalField().setText(String.valueOf(ingreso.getNroFinal()));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Obtiene el total de ingresos de la caja y lo coloca en el el field totalingresos
|
|
*/
|
|
private void updateTotalIngresos(){
|
|
int total = this.ingresoDAO.getTotalIngreso(this.caja);
|
|
this.view.getTotalIngresoField().setText(String.valueOf(total));
|
|
}
|
|
|
|
/**
|
|
* Actualiza si los botones estan habilitados
|
|
* Esto depende de si se encuentra al menos una fila en la tabla seleccionada
|
|
* Si es asi, son habilidatos, si no, de deshabilitan
|
|
*/
|
|
private void updateButtonsEnabled() {
|
|
if(this.view.getIngresosTable().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 ingreso tras llamar a validar el input
|
|
* Luego de guardar agrega a la tabla el ingreso, llama a limpiar los campos de input y a actualizar el total de ingresos
|
|
*/
|
|
private void guardarIngreso(String valor, String nroInicial, String nroFinal, TipoIngreso tipoIngreso, Caja caja){
|
|
if(this.validateInput(valor, nroInicial, nroFinal, tipoIngreso, caja)){
|
|
Ingreso ingreso = new Ingreso();
|
|
ingreso.setTipoIngreso(tipoIngreso);
|
|
ingreso.setCaja(caja);
|
|
ingreso.setValor(Integer.valueOf(valor));
|
|
ingreso.setNroInicial(nroInicial);
|
|
ingreso.setNroFinal(nroFinal);
|
|
|
|
this.ingresoDAO.insertIngreso(ingreso);
|
|
this.view.getIngresosTableModel().addRow(ingreso);
|
|
|
|
this.clearInputs();
|
|
this.updateTotalIngresos();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Edita el ingreso tras llamar a validar el input
|
|
* Tras esto actualiza el ingreso en la tabla, llama a actualizar el total de ingresos, a limpiar los campos de input y a desactivar la flag de editing.
|
|
*
|
|
*/
|
|
private void editarIngreso(String valor, String nroInicial, String nroFinal, TipoIngreso tipoIngreso, Caja caja){
|
|
if(this.validateInput(valor, nroInicial, nroFinal, tipoIngreso, caja)){
|
|
this.editingIngreso.setTipoIngreso(tipoIngreso);
|
|
this.editingIngreso.setValor(Integer.valueOf(valor));
|
|
this.editingIngreso.setNroInicial(nroInicial);
|
|
this.editingIngreso.setNroFinal(nroFinal);
|
|
this.ingresoDAO.updateIngreso(this.editingIngreso);
|
|
this.view.getIngresosTableModel().setIngreso(this.editingId, this.editingIngreso);
|
|
this.updateTotalIngresos();
|
|
this.clearInputs();
|
|
this.editing = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Llama a los metodos necesarios para validar el input
|
|
* @return true cuando todas las validaciones retoran true, si no, false
|
|
*/
|
|
private boolean validateInput(String valor, String nroInicial, String nroFinal, TipoIngreso tipoIngreso, Caja caja) {
|
|
this.hideErrorMessages();
|
|
|
|
boolean valorValidation = this.validateValor(valor);
|
|
boolean nroInicialValidation = this.validateNroInicial(nroInicial);
|
|
boolean nroFinalValidation = this.validateNroFinal(nroFinal);
|
|
boolean tipoIngresoValidation = this.validateTipoIngreso(tipoIngreso);
|
|
boolean cajaValidation = this.validateCaja(caja);
|
|
|
|
return valorValidation && tipoIngresoValidation && cajaValidation;
|
|
}
|
|
|
|
/**
|
|
* Valida la variable caja este caso
|
|
* - Es null
|
|
* @return Si este caso es true se retornara false, si no, se retorna true
|
|
*/
|
|
private boolean validateCaja(Caja caja) {
|
|
return caja != null;
|
|
}
|
|
|
|
/**
|
|
* Valida la variable valor contra los casos
|
|
* - Es null
|
|
* - Esta vacio
|
|
* - Los caracteres no son solamente digitos
|
|
* - El largo del string es mayor 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 nroInicial 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 validateNroInicial(String nroInicial){
|
|
if (nroInicial == null) {
|
|
this.view.getErrorNroInicial().setText("Hubo un problema con los datos");
|
|
this.view.getErrorNroInicial().setVisible(true);
|
|
return false;
|
|
}
|
|
|
|
if (nroInicial.isEmpty()) {
|
|
this.view.getErrorNroInicial().setText("El campo esta vacio");
|
|
this.view.getErrorNroInicial().setVisible(true);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Valida la variable nroFinal 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 validateNroFinal(String nroFinal){
|
|
if (nroFinal == null) {
|
|
this.view.getErrorNroFinal().setText("Hubo un problema con los datos");
|
|
this.view.getErrorNroFinal().setVisible(true);
|
|
return false;
|
|
}
|
|
|
|
if (nroFinal.isEmpty()) {
|
|
this.view.getErrorNroFinal().setText("El campo esta vacio");
|
|
this.view.getErrorNroFinal().setVisible(true);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Valida la variable caja este caso
|
|
* - Es null
|
|
* Cuando sea true, colocara un mensaje de error en el jlabel correspondiente
|
|
* @return Si este caso es true se retornara false, si no, se retorna true
|
|
*/
|
|
private boolean validateTipoIngreso(TipoIngreso tipoIngreso) {
|
|
if (tipoIngreso == null) {
|
|
this.view.getErrorTipoIngreso().setText("Hubo un problema con los datos");
|
|
this.view.getErrorTipoIngreso().setVisible(true);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Esconde los mensajes de error en la ventana de ingresos
|
|
*/
|
|
private void hideErrorMessages() {
|
|
this.view.getErrorTipoIngreso().setVisible(false);
|
|
this.view.getErrorValor().setVisible(false);
|
|
this.view.getErrorNroInicial().setVisible(false);
|
|
this.view.getErrorNroFinal().setVisible(false);
|
|
}
|
|
|
|
/**
|
|
* Vacia los jtextfields y selecciona la primera opcion del jcombobox
|
|
*/
|
|
private void clearInputs() {
|
|
this.view.getTipoCombo().setSelectedIndex(0);
|
|
this.view.getValorField().setText("");
|
|
this.view.getNroInicialField().setText("");
|
|
this.view.getNroFinalField().setText("");
|
|
}
|
|
|
|
/**
|
|
* Ejecuta un trim sobre todos los jtextfield
|
|
*/
|
|
private void normalizeInputs(){
|
|
this.view.getValorField().setText(this.view.getValorField().getText().trim());
|
|
this.view.getNroInicialField().setText(this.view.getNroInicialField().getText().trim());
|
|
this.view.getNroFinalField().setText(this.view.getNroFinalField().getText().trim());
|
|
}
|
|
|
|
/**
|
|
* Le pide focus al tipo combo
|
|
*/
|
|
private void resetFocus(){
|
|
this.view.getValorField().requestFocus();
|
|
}
|
|
|
|
private class NextAction extends AbstractAction{
|
|
JComponent next;
|
|
|
|
NextAction(JComponent next){
|
|
this.next = next;
|
|
}
|
|
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
this.next.requestFocus();
|
|
}
|
|
}
|
|
|
|
private class GuardarAction extends AbstractAction{
|
|
IngresosController controller;
|
|
GuardarAction(IngresosController controller){
|
|
this.controller = controller;
|
|
}
|
|
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
this.controller.guardarActionListener();
|
|
}
|
|
}
|
|
}
|