0% encontró este documento útil (0 votos)
4 vistas

codigo

El documento describe la implementación de un sistema de gestión de servicio técnico utilizando Java y MySQL. Incluye la conexión a la base de datos, la interfaz gráfica con menús y paneles para gestionar clientes, trabajos y reportes, así como funcionalidades para agregar, editar y eliminar registros. Además, se presentan métodos para contar registros y buscar clientes en la base de datos.

Cargado por

centenosaraza
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como TXT, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
4 vistas

codigo

El documento describe la implementación de un sistema de gestión de servicio técnico utilizando Java y MySQL. Incluye la conexión a la base de datos, la interfaz gráfica con menús y paneles para gestionar clientes, trabajos y reportes, así como funcionalidades para agregar, editar y eliminar registros. Además, se presentan métodos para contar registros y buscar clientes en la base de datos.

Cargado por

centenosaraza
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como TXT, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 28

import javax.swing.

*;
import java.awt.*;
import java.sql.*;
import javax.swing.table.DefaultTableModel;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.io.File; // Agrega esta línea con los otros imports

public class SistemaServicioTecnico extends JFrame {


private static final Color MENU_BG_COLOR = new Color(50, 50, 100);
private static final Color TEXT_COLOR = Color.WHITE;
private static final Font MENU_FONT = new Font("Arial", Font.BOLD, 14);

// Datos de conexión a MySQL


private static final String DB_URL =
"jdbc:mysql://localhost:3306/servicio_tecnico";
private static final String DB_USER = "servicio_user";
private static final String DB_PASSWORD = "Servicio123$";

private Connection connection;


private JPanel contentPanel;
private CardLayout cardLayout;

// Identificadores de paneles
private static final String INICIO_PANEL = "INICIO";
private static final String CLIENTES_PANEL = "CLIENTES";
private static final String TRABAJOS_PANEL = "TRABAJOS";
private static final String REPORTES_PANEL = "REPORTES";

// Modelos de tabla
private DefaultTableModel clientesTableModel;
private DefaultTableModel trabajosTableModel;
private DefaultTableModel reportesTableModel;
private DefaultTableModel tecnicosTableModel;
private DefaultTableModel categoriasTableModel;

public SistemaServicioTecnico() {
try {
// Cargar el driver de MySQL
Class.forName("com.mysql.cj.jdbc.Driver");
// Establecer conexión con la base de datos
connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
System.out.println("Conexión establecida con MySQL");
} catch (ClassNotFoundException e) {
JOptionPane.showMessageDialog(this, "Driver JDBC no encontrado: " +
e.getMessage(),
"Error de conexión", JOptionPane.ERROR_MESSAGE);
System.exit(1);
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error al conectar con la base de
datos: " + e.getMessage(),
"Error de conexión", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}

inicializarInterfaz();
crearMenuPrincipal();
configurarPanelesContenido();
setVisible(true);
}

private void inicializarInterfaz() {


setTitle("Sistema de Gestión de Servicio Técnico - MySQL");
setSize(1200, 800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
getContentPane().setLayout(new BorderLayout());

try {
ImageIcon icon = new ImageIcon("icon.png");
setIconImage(icon.getImage());
} catch (Exception e) {
System.err.println("Error cargando icono: " + e.getMessage());
}
}

private void crearMenuPrincipal() {


JPanel menuPanel = new JPanel();
menuPanel.setBackground(MENU_BG_COLOR);
menuPanel.setLayout(new BoxLayout(menuPanel, BoxLayout.Y_AXIS));
menuPanel.setPreferredSize(new Dimension(200, 800));

addMenuButton(menuPanel, "Inicio", () -> mostrarPanel(INICIO_PANEL));


addSeparator(menuPanel);
addMenuButton(menuPanel, "Gestión de Clientes", () -> {
mostrarPanel(CLIENTES_PANEL);
actualizarTablaClientes();
});
addSeparator(menuPanel);
addMenuButton(menuPanel, "Gestión de Trabajos", () -> {
mostrarPanel(TRABAJOS_PANEL);
actualizarTablaTrabajos();
});
addSeparator(menuPanel);
addMenuButton(menuPanel, "Reportes", () -> {
mostrarPanel(REPORTES_PANEL);
actualizarReportes();
});
addSeparator(menuPanel);
addMenuButton(menuPanel, "Salir", () -> {
try {
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
System.exit(0);
});
addSeparator(menuPanel);

getContentPane().add(menuPanel, BorderLayout.WEST);
}

private void configurarPanelesContenido() {


contentPanel = new JPanel();
cardLayout = new CardLayout();
contentPanel.setLayout(cardLayout);
contentPanel.add(crearPanelInicio(), INICIO_PANEL);
contentPanel.add(crearPanelClientes(), CLIENTES_PANEL);
contentPanel.add(crearPanelTrabajos(), TRABAJOS_PANEL);
contentPanel.add(crearPanelReportes(), REPORTES_PANEL);

getContentPane().add(contentPanel, BorderLayout.CENTER);
mostrarPanel(INICIO_PANEL);
}

private void addMenuButton(JPanel panel, String texto, Runnable accion) {


JButton boton = new JButton(texto);
boton.setForeground(TEXT_COLOR);
boton.setFont(MENU_FONT);
boton.setBackground(new Color(0, 0, 0, 0));
boton.setBorderPainted(false);
boton.setFocusPainted(false);
boton.setAlignmentX(Component.LEFT_ALIGNMENT);
boton.setMaximumSize(new Dimension(200, 40));

boton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(java.awt.event.MouseEvent evt) {
boton.setBackground(new Color(70, 70, 130));
}

public void mouseExited(java.awt.event.MouseEvent evt) {


boton.setBackground(new Color(0, 0, 0, 0));
}
});

boton.addActionListener(e -> accion.run());


panel.add(boton);
}

private void addSeparator(JPanel panel) {


JSeparator separador = new JSeparator(SwingConstants.HORIZONTAL);
separador.setForeground(new Color(200, 200, 200));
separador.setMaximumSize(new Dimension(180, 1));
panel.add(separador);
}

private void mostrarPanel(String nombrePanel) {


cardLayout.show(contentPanel, nombrePanel);
}

// Métodos para crear paneles


private JPanel crearPanelInicio() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(Color.WHITE);

JLabel titulo = new JLabel("Sistema de Gestión de Servicio Técnico",


SwingConstants.CENTER);
titulo.setFont(new Font("Arial", Font.BOLD, 24));
titulo.setForeground(MENU_BG_COLOR);

JLabel subtitulo = new JLabel("Conectado a MySQL Database",


SwingConstants.CENTER);
subtitulo.setFont(new Font("Arial", Font.PLAIN, 16));
// Panel de estadísticas
JPanel statsPanel = new JPanel(new GridLayout(3, 2, 10, 10));
statsPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
statsPanel.setBackground(Color.WHITE);

statsPanel.add(crearStatCard("Clientes Registrados",
contarRegistros("clientes")));
statsPanel.add(crearStatCard("Trabajos Pendientes",
contarTrabajosPorEstado("Pendiente")));
statsPanel.add(crearStatCard("Trabajos en Proceso",
contarTrabajosPorEstado("Terminado")));
statsPanel.add(crearStatCard("Trabajos Entregados",
contarTrabajosPorEstado("Entregado")));
statsPanel.add(crearStatCard("Técnicos Activos", contarRegistros("tecnicos
WHERE activo = TRUE")));
statsPanel.add(crearStatCard("Categorías de Equipos",
contarRegistros("categorias_equipos")));

JPanel centerPanel = new JPanel(new BorderLayout());


centerPanel.setBackground(Color.WHITE);
centerPanel.add(titulo, BorderLayout.NORTH);
centerPanel.add(subtitulo, BorderLayout.CENTER);
centerPanel.add(statsPanel, BorderLayout.SOUTH);

panel.add(centerPanel, BorderLayout.CENTER);
return panel;
}

private JPanel crearStatCard(String titulo, int valor) {


JPanel card = new JPanel(new BorderLayout());
card.setBackground(new Color(240, 240, 240));
card.setBorder(BorderFactory.createLineBorder(MENU_BG_COLOR, 1));

JLabel tituloLabel = new JLabel(titulo, SwingConstants.CENTER);


tituloLabel.setFont(new Font("Arial", Font.BOLD, 14));
tituloLabel.setForeground(MENU_BG_COLOR);

JLabel valorLabel = new JLabel(String.valueOf(valor),


SwingConstants.CENTER);
valorLabel.setFont(new Font("Arial", Font.BOLD, 24));

card.add(tituloLabel, BorderLayout.NORTH);
card.add(valorLabel, BorderLayout.CENTER);

return card;
}

private int contarRegistros(String tabla) {


try {
String sql = "SELECT COUNT(*) FROM " + tabla;
try (Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
if (rs.next()) {
return rs.getInt(1);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}

private int contarTrabajosPorEstado(String estado) {


try {
String sql = "SELECT COUNT(*) FROM trabajos WHERE estado = ?";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
pstmt.setString(1, estado);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
return rs.getInt(1);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}

private JPanel crearPanelClientes() {


JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panel.setBackground(Color.WHITE);

JLabel titulo = new JLabel("Gestión de Clientes", SwingConstants.CENTER);


titulo.setFont(new Font("Arial", Font.BOLD, 20));
titulo.setForeground(MENU_BG_COLOR);
panel.add(titulo, BorderLayout.NORTH);

// Panel de búsqueda
JPanel busquedaPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
busquedaPanel.setBackground(Color.WHITE);
busquedaPanel.setBorder(BorderFactory.createTitledBorder("Búsqueda"));

JTextField txtBuscar = new JTextField(20);


JButton btnBuscar = new JButton("Buscar");
btnBuscar.setBackground(MENU_BG_COLOR);
btnBuscar.setForeground(Color.WHITE);
btnBuscar.addActionListener(e ->
buscarClientes(txtBuscar.getText().trim()));

busquedaPanel.add(new JLabel("DNI o Nombre:"));


busquedaPanel.add(txtBuscar);
busquedaPanel.add(btnBuscar);

// Tabla de clientes
String[] columnasClientes = {"DNI", "Nombres", "Apellidos", "Teléfono",
"Email", "Dirección", "Fecha Registro"};
clientesTableModel = new DefaultTableModel(columnasClientes, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
JTable tablaClientes = new JTable(clientesTableModel);
tablaClientes.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrollClientes = new JScrollPane(tablaClientes);

// Panel de botones
JPanel botonesPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10,
10));
botonesPanel.setBackground(Color.WHITE);

JButton btnAgregar = new JButton("Agregar Cliente");


btnAgregar.setBackground(MENU_BG_COLOR);
btnAgregar.setForeground(Color.WHITE);
btnAgregar.addActionListener(e -> mostrarDialogoCliente(null));

JButton btnEditar = new JButton("Editar Cliente");


btnEditar.setBackground(MENU_BG_COLOR);
btnEditar.setForeground(Color.WHITE);
btnEditar.addActionListener(e -> {
int fila = tablaClientes.getSelectedRow();
if (fila == -1) {
JOptionPane.showMessageDialog(this, "Seleccione un cliente para
editar", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
String dni = (String) clientesTableModel.getValueAt(fila, 0);
mostrarDialogoCliente(dni);
});

JButton btnEliminar = new JButton("Eliminar Cliente");


btnEliminar.setBackground(MENU_BG_COLOR);
btnEliminar.setForeground(Color.WHITE);
btnEliminar.addActionListener(e -> {
int fila = tablaClientes.getSelectedRow();
if (fila == -1) {
JOptionPane.showMessageDialog(this, "Seleccione un cliente para
eliminar", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
String dni = (String) clientesTableModel.getValueAt(fila, 0);
String nombre = (String) clientesTableModel.getValueAt(fila, 1) + " " +
clientesTableModel.getValueAt(fila, 2);
eliminarCliente(dni, nombre);
});

JButton btnActualizar = new JButton("Actualizar");


btnActualizar.setBackground(MENU_BG_COLOR);
btnActualizar.setForeground(Color.WHITE);
btnActualizar.addActionListener(e -> actualizarTablaClientes());

botonesPanel.add(btnAgregar);
botonesPanel.add(btnEditar);
botonesPanel.add(btnEliminar);
botonesPanel.add(btnActualizar);

// Organizar componentes
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.setBackground(Color.WHITE);
centerPanel.add(busquedaPanel, BorderLayout.NORTH);
centerPanel.add(scrollClientes, BorderLayout.CENTER);
centerPanel.add(botonesPanel, BorderLayout.SOUTH);

panel.add(centerPanel, BorderLayout.CENTER);
return panel;
}
private void buscarClientes(String criterio) {
try {
clientesTableModel.setRowCount(0);
String sql = "SELECT dni, nombres, apellidos, telefono, email,
direccion, fecha_registro " +
"FROM clientes WHERE dni LIKE ? OR nombres LIKE ? OR apellidos
LIKE ? " +
"ORDER BY apellidos, nombres";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
pstmt.setString(1, "%" + criterio + "%");
pstmt.setString(2, "%" + criterio + "%");
pstmt.setString(3, "%" + criterio + "%");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
clientesTableModel.addRow(new Object[]{
rs.getString("dni"),
rs.getString("nombres"),
rs.getString("apellidos"),
rs.getString("telefono"),
rs.getString("email"),
rs.getString("direccion"),
rs.getTimestamp("fecha_registro")
});
}
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error al buscar clientes: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}

private void mostrarDialogoCliente(String dni) {


JDialog dialog = new JDialog(this, dni == null ? "Nuevo Cliente" : "Editar
Cliente", true);
dialog.setLayout(new BorderLayout());
dialog.setSize(500, 400);
dialog.setLocationRelativeTo(this);

JPanel panelFormulario = new JPanel(new GridLayout(7, 2, 5, 5));


panelFormulario.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

JTextField txtDNI = new JTextField();


JTextField txtNombres = new JTextField();
JTextField txtApellidos = new JTextField();
JTextField txtTelefono = new JTextField();
JTextField txtEmail = new JTextField();
JTextField txtDireccion = new JTextField();

if (dni != null) {
// Cargar datos del cliente existente
try {
String sql = "SELECT * FROM clientes WHERE dni = ?";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
pstmt.setString(1, dni);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
txtDNI.setText(rs.getString("dni"));
txtNombres.setText(rs.getString("nombres"));
txtApellidos.setText(rs.getString("apellidos"));
txtTelefono.setText(rs.getString("telefono"));
txtEmail.setText(rs.getString("email"));
txtDireccion.setText(rs.getString("direccion"));
}
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(dialog, "Error al cargar cliente: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}

panelFormulario.add(new JLabel("DNI:"));
panelFormulario.add(txtDNI);
panelFormulario.add(new JLabel("Nombres:"));
panelFormulario.add(txtNombres);
panelFormulario.add(new JLabel("Apellidos:"));
panelFormulario.add(txtApellidos);
panelFormulario.add(new JLabel("Teléfono:"));
panelFormulario.add(txtTelefono);
panelFormulario.add(new JLabel("Email:"));
panelFormulario.add(txtEmail);
panelFormulario.add(new JLabel("Dirección:"));
panelFormulario.add(txtDireccion);

JPanel panelBotones = new JPanel(new FlowLayout(FlowLayout.CENTER));


JButton btnGuardar = new JButton("Guardar");
btnGuardar.setBackground(MENU_BG_COLOR);
btnGuardar.setForeground(Color.WHITE);
btnGuardar.addActionListener(e -> {
if (validarCamposCliente(txtDNI, txtNombres, txtApellidos)) {
guardarCliente(
txtDNI.getText(),
txtNombres.getText(),
txtApellidos.getText(),
txtTelefono.getText(),
txtEmail.getText(),
txtDireccion.getText(),
dni != null
);
dialog.dispose();
actualizarTablaClientes();
}
});

JButton btnCancelar = new JButton("Cancelar");


btnCancelar.setBackground(MENU_BG_COLOR);
btnCancelar.setForeground(Color.WHITE);
btnCancelar.addActionListener(e -> dialog.dispose());

panelBotones.add(btnGuardar);
panelBotones.add(btnCancelar);

dialog.add(panelFormulario, BorderLayout.CENTER);
dialog.add(panelBotones, BorderLayout.SOUTH);
dialog.setVisible(true);
}
private boolean validarCamposCliente(JTextField dni, JTextField nombres,
JTextField apellidos) {
if (dni.getText().trim().isEmpty()) {
JOptionPane.showMessageDialog(this, "El DNI es obligatorio", "Error",
JOptionPane.ERROR_MESSAGE);
return false;
}
if (nombres.getText().trim().isEmpty()) {
JOptionPane.showMessageDialog(this, "Los nombres son obligatorios",
"Error", JOptionPane.ERROR_MESSAGE);
return false;
}
if (apellidos.getText().trim().isEmpty()) {
JOptionPane.showMessageDialog(this, "Los apellidos son obligatorios",
"Error", JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}

private void guardarCliente(String dni, String nombres, String apellidos,


String telefono, String email, String direccion,
boolean esEdicion) {
try {
String sql;
if (esEdicion) {
sql = "UPDATE clientes SET nombres = ?, apellidos = ?, telefono
= ?, email = ?, direccion = ? WHERE dni = ?";
} else {
sql = "INSERT INTO clientes (dni, nombres, apellidos, telefono,
email, direccion) VALUES (?, ?, ?, ?, ?, ?)";
}

try (PreparedStatement pstmt = connection.prepareStatement(sql)) {


if (esEdicion) {
pstmt.setString(1, nombres);
pstmt.setString(2, apellidos);
pstmt.setString(3, telefono);
pstmt.setString(4, email);
pstmt.setString(5, direccion);
pstmt.setString(6, dni);
} else {
pstmt.setString(1, dni);
pstmt.setString(2, nombres);
pstmt.setString(3, apellidos);
pstmt.setString(4, telefono);
pstmt.setString(5, email);
pstmt.setString(6, direccion);
}
pstmt.executeUpdate();
}

JOptionPane.showMessageDialog(this, "Cliente " + (esEdicion ?


"actualizado" : "registrado") + " exitosamente",
"Éxito", JOptionPane.INFORMATION_MESSAGE);
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error al guardar cliente: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}

private void eliminarCliente(String dni, String nombre) {


int confirmacion = JOptionPane.showConfirmDialog(
this,
"¿Está seguro que desea eliminar al cliente " + nombre + "?",
"Confirmar eliminación",
JOptionPane.YES_NO_OPTION
);

if (confirmacion == JOptionPane.YES_OPTION) {
try {
// Verificar si el cliente tiene trabajos asociados
String sqlCheck = "SELECT COUNT(*) FROM trabajos WHERE dni_cliente
= ?";
try (PreparedStatement pstmt =
connection.prepareStatement(sqlCheck)) {
pstmt.setString(1, dni);
ResultSet rs = pstmt.executeQuery();
if (rs.next() && rs.getInt(1) > 0) {
JOptionPane.showMessageDialog(this,
"No se puede eliminar el cliente porque tiene
trabajos asociados",
"Error", JOptionPane.ERROR_MESSAGE);
return;
}
}

// Eliminar cliente
String sqlDelete = "DELETE FROM clientes WHERE dni = ?";
try (PreparedStatement pstmt =
connection.prepareStatement(sqlDelete)) {
pstmt.setString(1, dni);
pstmt.executeUpdate();
}

JOptionPane.showMessageDialog(this, "Cliente eliminado


exitosamente",
"Éxito", JOptionPane.INFORMATION_MESSAGE);
actualizarTablaClientes();
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error al eliminar cliente: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}
}

private void actualizarTablaClientes() {


try {
clientesTableModel.setRowCount(0);
String sql = "SELECT dni, nombres, apellidos, telefono, email,
direccion, fecha_registro " +
"FROM clientes ORDER BY apellidos, nombres";
try (Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
clientesTableModel.addRow(new Object[]{
rs.getString("dni"),
rs.getString("nombres"),
rs.getString("apellidos"),
rs.getString("telefono"),
rs.getString("email"),
rs.getString("direccion"),
rs.getTimestamp("fecha_registro")
});
}
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error al cargar clientes: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}

private JPanel crearPanelTrabajos() {


JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panel.setBackground(Color.WHITE);

JLabel titulo = new JLabel("Gestión de Trabajos Técnicos",


SwingConstants.CENTER);
titulo.setFont(new Font("Arial", Font.BOLD, 20));
titulo.setForeground(MENU_BG_COLOR);
panel.add(titulo, BorderLayout.NORTH);

// Panel de búsqueda y filtros


JPanel filtrosPanel = new JPanel(new GridLayout(2, 3, 5, 5));
filtrosPanel.setBackground(Color.WHITE);
filtrosPanel.setBorder(BorderFactory.createTitledBorder("Filtros"));

JTextField txtBuscarDNI = new JTextField();


JComboBox<String> cmbEstado = new JComboBox<>(new String[]{"Todos",
"Pendiente", "Terminado", "Entregado"});
JComboBox<String> cmbTecnico = new JComboBox<>();
cargarComboTecnicos(cmbTecnico);

JButton btnBuscar = new JButton("Buscar");


btnBuscar.setBackground(MENU_BG_COLOR);
btnBuscar.setForeground(Color.WHITE);
btnBuscar.addActionListener(e -> {
String dni = txtBuscarDNI.getText().trim();
String estado = cmbEstado.getSelectedIndex() == 0 ? "" : (String)
cmbEstado.getSelectedItem();
String tecnico = cmbTecnico.getSelectedIndex() == 0 ? "" :
cmbTecnico.getSelectedItem().toString().split(" - ")[0];
buscarTrabajos(dni, estado, tecnico);
});

filtrosPanel.add(new JLabel("DNI Cliente:"));


filtrosPanel.add(new JLabel("Estado:"));
filtrosPanel.add(new JLabel("Técnico:"));
filtrosPanel.add(txtBuscarDNI);
filtrosPanel.add(cmbEstado);
filtrosPanel.add(cmbTecnico);
// Tabla de trabajos
String[] columnasTrabajos = {"ID", "Equipo", "Categoría", "Marca",
"Modelo", "Estado", "Cliente", "Técnico", "Fecha Recepción"};
trabajosTableModel = new DefaultTableModel(columnasTrabajos, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
JTable tablaTrabajos = new JTable(trabajosTableModel);
tablaTrabajos.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrollTrabajos = new JScrollPane(tablaTrabajos);

// Panel de botones
JPanel botonesPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10,
10));
botonesPanel.setBackground(Color.WHITE);

JButton btnAgregar = new JButton("Agregar Trabajo");


btnAgregar.setBackground(MENU_BG_COLOR);
btnAgregar.setForeground(Color.WHITE);
btnAgregar.addActionListener(e -> mostrarDialogoTrabajo(null));

JButton btnEditar = new JButton("Editar Trabajo");


btnEditar.setBackground(MENU_BG_COLOR);
btnEditar.setForeground(Color.WHITE);
btnEditar.addActionListener(e -> {
int fila = tablaTrabajos.getSelectedRow();
if (fila == -1) {
JOptionPane.showMessageDialog(this, "Seleccione un trabajo para
editar", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
int id = (int) trabajosTableModel.getValueAt(fila, 0);
mostrarDialogoTrabajo(id);
});

JButton btnCambiarEstado = new JButton("Cambiar Estado");


btnCambiarEstado.setBackground(MENU_BG_COLOR);
btnCambiarEstado.setForeground(Color.WHITE);
btnCambiarEstado.addActionListener(e -> {
int fila = tablaTrabajos.getSelectedRow();
if (fila == -1) {
JOptionPane.showMessageDialog(this, "Seleccione un trabajo para
cambiar estado", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
int id = (int) trabajosTableModel.getValueAt(fila, 0);
String estadoActual = (String) trabajosTableModel.getValueAt(fila, 5);
mostrarDialogoCambioEstado(id, estadoActual);
});

JButton btnEliminar = new JButton("Eliminar Trabajo");


btnEliminar.setBackground(MENU_BG_COLOR);
btnEliminar.setForeground(Color.WHITE);
btnEliminar.addActionListener(e -> {
int fila = tablaTrabajos.getSelectedRow();
if (fila == -1) {
JOptionPane.showMessageDialog(this, "Seleccione un trabajo para
eliminar", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
int id = (int) trabajosTableModel.getValueAt(fila, 0);
String equipo = (String) trabajosTableModel.getValueAt(fila, 1);
eliminarTrabajo(id, equipo);
});

JButton btnActualizar = new JButton("Actualizar");


btnActualizar.setBackground(MENU_BG_COLOR);
btnActualizar.setForeground(Color.WHITE);
btnActualizar.addActionListener(e -> actualizarTablaTrabajos());

botonesPanel.add(btnAgregar);
botonesPanel.add(btnEditar);
botonesPanel.add(btnCambiarEstado);
botonesPanel.add(btnEliminar);
botonesPanel.add(btnActualizar);

// Organizar componentes
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.setBackground(Color.WHITE);
centerPanel.add(filtrosPanel, BorderLayout.NORTH);
centerPanel.add(scrollTrabajos, BorderLayout.CENTER);
centerPanel.add(botonesPanel, BorderLayout.SOUTH);

panel.add(centerPanel, BorderLayout.CENTER);
return panel;
}

private void cargarComboTecnicos(JComboBox<String> combo) {


combo.removeAllItems();
combo.addItem("Todos los técnicos");
try {
String sql = "SELECT id, nombres, apellidos FROM tecnicos WHERE activo
= TRUE ORDER BY apellidos, nombres";
try (Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
combo.addItem(rs.getInt("id") + " - " + rs.getString("nombres")
+ " " + rs.getString("apellidos"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}

private void buscarTrabajos(String dni, String estado, String idTecnico) {


try {
trabajosTableModel.setRowCount(0);

StringBuilder sql = new StringBuilder();


sql.append("SELECT t.id, t.equipo, ce.nombre AS categoria, t.marca,
t.modelo, t.estado, ");
sql.append("CONCAT(c.nombres, ' ', c.apellidos) AS cliente, ");
sql.append("CONCAT(tec.nombres, ' ', tec.apellidos) AS tecnico,
t.fecha_recepcion ");
sql.append("FROM trabajos t ");
sql.append("JOIN clientes c ON t.dni_cliente = c.dni ");
sql.append("LEFT JOIN tecnicos tec ON t.id_tecnico_asignado = tec.id
");
sql.append("LEFT JOIN categorias_equipos ce ON t.id_categoria = ce.id
");
sql.append("WHERE 1=1 ");

if (!dni.isEmpty()) {
sql.append("AND t.dni_cliente LIKE ? ");
}
if (!estado.isEmpty()) {
sql.append("AND t.estado = ? ");
}
if (!idTecnico.isEmpty()) {
sql.append("AND t.id_tecnico_asignado = ? ");
}
sql.append("ORDER BY t.estado, t.fecha_recepcion DESC");

try (PreparedStatement pstmt =


connection.prepareStatement(sql.toString())) {
int paramIndex = 1;
if (!dni.isEmpty()) {
pstmt.setString(paramIndex++, "%" + dni + "%");
}
if (!estado.isEmpty()) {
pstmt.setString(paramIndex++, estado);
}
if (!idTecnico.isEmpty()) {
pstmt.setInt(paramIndex++, Integer.parseInt(idTecnico));
}

ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
trabajosTableModel.addRow(new Object[]{
rs.getInt("id"),
rs.getString("equipo"),
rs.getString("categoria"),
rs.getString("marca"),
rs.getString("modelo"),
rs.getString("estado"),
rs.getString("cliente"),
rs.getString("tecnico"),
rs.getTimestamp("fecha_recepcion")
});
}
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error al buscar trabajos: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}

private void mostrarDialogoTrabajo(Integer id) {


JDialog dialog = new JDialog(this, id == null ? "Nuevo Trabajo" : "Editar
Trabajo", true);
dialog.setLayout(new BorderLayout());
dialog.setSize(600, 500);
dialog.setLocationRelativeTo(this);
JPanel panelFormulario = new JPanel(new GridBagLayout());
panelFormulario.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;

// Campos del formulario


JComboBox<String> cmbClientes = new JComboBox<>();
cargarComboClientes(cmbClientes);

JTextField txtEquipo = new JTextField(20);


JComboBox<String> cmbCategorias = new JComboBox<>();
cargarComboCategorias(cmbCategorias);
JTextField txtMarca = new JTextField(20);
JTextField txtModelo = new JTextField(20);
JTextField txtSerie = new JTextField(20);
JTextArea txtProblema = new JTextArea(3, 20);
txtProblema.setLineWrap(true);
JTextArea txtDiagnostico = new JTextArea(3, 20);
txtDiagnostico.setLineWrap(true);
JTextArea txtSolucion = new JTextArea(3, 20);
txtSolucion.setLineWrap(true);
JTextArea txtObservaciones = new JTextArea(3, 20);
txtObservaciones.setLineWrap(true);
JComboBox<String> cmbTecnicos = new JComboBox<>();
cargarComboTecnicos(cmbTecnicos);
JTextField txtCostoEstimado = new JTextField(10);
JTextField txtCostoFinal = new JTextField(10);
JSpinner spnGarantia = new JSpinner(new SpinnerNumberModel(3, 0, 24, 1));

if (id != null) {
// Cargar datos del trabajo existente
try {
String sql = "SELECT * FROM trabajos WHERE id = ?";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
pstmt.setInt(1, id);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
cmbClientes.setSelectedItem(rs.getString("dni_cliente"));
txtEquipo.setText(rs.getString("equipo"));
cmbCategorias.setSelectedItem(rs.getInt("id_categoria"));
txtMarca.setText(rs.getString("marca"));
txtModelo.setText(rs.getString("modelo"));
txtSerie.setText(rs.getString("numero_serie"));
txtProblema.setText(rs.getString("descripcion_problema"));
txtDiagnostico.setText(rs.getString("diagnostico"));
txtSolucion.setText(rs.getString("solucion_implementada"));
txtObservaciones.setText(rs.getString("observaciones"));

cmbTecnicos.setSelectedItem(rs.getInt("id_tecnico_asignado"));
txtCostoEstimado.setText(rs.getBigDecimal("costo_estimado")
!= null ? rs.getBigDecimal("costo_estimado").toString() : "");
txtCostoFinal.setText(rs.getBigDecimal("costo_final") !=
null ? rs.getBigDecimal("costo_final").toString() : "");
spnGarantia.setValue(rs.getInt("garantia_meses"));
}
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(dialog, "Error al cargar trabajo: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}

// Configurar GridBagLayout
gbc.gridx = 0;
gbc.gridy = 0;
panelFormulario.add(new JLabel("Cliente:"), gbc);

gbc.gridx = 1;
panelFormulario.add(cmbClientes, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Equipo:"), gbc);

gbc.gridx = 1;
panelFormulario.add(txtEquipo, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Categoría:"), gbc);

gbc.gridx = 1;
panelFormulario.add(cmbCategorias, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Marca:"), gbc);

gbc.gridx = 1;
panelFormulario.add(txtMarca, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Modelo:"), gbc);

gbc.gridx = 1;
panelFormulario.add(txtModelo, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Número de Serie:"), gbc);

gbc.gridx = 1;
panelFormulario.add(txtSerie, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Descripción del Problema:"), gbc);

gbc.gridx = 1;
panelFormulario.add(new JScrollPane(txtProblema), gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Diagnóstico:"), gbc);

gbc.gridx = 1;
panelFormulario.add(new JScrollPane(txtDiagnostico), gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Solución Implementada:"), gbc);

gbc.gridx = 1;
panelFormulario.add(new JScrollPane(txtSolucion), gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Observaciones:"), gbc);

gbc.gridx = 1;
panelFormulario.add(new JScrollPane(txtObservaciones), gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Técnico Asignado:"), gbc);

gbc.gridx = 1;
panelFormulario.add(cmbTecnicos, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Costo Estimado:"), gbc);

gbc.gridx = 1;
panelFormulario.add(txtCostoEstimado, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Costo Final:"), gbc);

gbc.gridx = 1;
panelFormulario.add(txtCostoFinal, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Garantía (meses):"), gbc);

gbc.gridx = 1;
panelFormulario.add(spnGarantia, gbc);

JPanel panelBotones = new JPanel(new FlowLayout(FlowLayout.CENTER));


JButton btnGuardar = new JButton("Guardar");
btnGuardar.setBackground(MENU_BG_COLOR);
btnGuardar.setForeground(Color.WHITE);
btnGuardar.addActionListener(e -> {
if (validarCamposTrabajo(cmbClientes, txtEquipo, txtProblema)) {
guardarTrabajo(
id,
cmbClientes.getSelectedItem().toString(),
txtEquipo.getText(),
cmbCategorias.getSelectedIndex() > 0 ?
Integer.parseInt(cmbCategorias.getSelectedItem().toString().split(" - ")[0]) :
null,
txtMarca.getText(),
txtModelo.getText(),
txtSerie.getText(),
txtProblema.getText(),
txtDiagnostico.getText(),
txtSolucion.getText(),
txtObservaciones.getText(),
cmbTecnicos.getSelectedIndex() > 0 ?
Integer.parseInt(cmbTecnicos.getSelectedItem().toString().split(" - ")[0]) : null,
txtCostoEstimado.getText().isEmpty() ? null :
Double.parseDouble(txtCostoEstimado.getText()),
txtCostoFinal.getText().isEmpty() ? null :
Double.parseDouble(txtCostoFinal.getText()),
(int) spnGarantia.getValue(),
id == null
);
dialog.dispose();
actualizarTablaTrabajos();
}
});

JButton btnCancelar = new JButton("Cancelar");


btnCancelar.setBackground(MENU_BG_COLOR);
btnCancelar.setForeground(Color.WHITE);
btnCancelar.addActionListener(e -> dialog.dispose());

panelBotones.add(btnGuardar);
panelBotones.add(btnCancelar);

dialog.add(panelFormulario, BorderLayout.CENTER);
dialog.add(panelBotones, BorderLayout.SOUTH);
dialog.setVisible(true);
}

private void cargarComboClientes(JComboBox<String> combo) {


combo.removeAllItems();
try {
String sql = "SELECT dni, nombres, apellidos FROM clientes ORDER BY
apellidos, nombres";
try (Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
combo.addItem(rs.getString("dni") + " - " +
rs.getString("nombres") + " " + rs.getString("apellidos"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}

private void cargarComboCategorias(JComboBox<String> combo) {


combo.removeAllItems();
combo.addItem("Seleccione categoría");
try {
String sql = "SELECT id, nombre FROM categorias_equipos ORDER BY
nombre";
try (Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
combo.addItem(rs.getInt("id") + " - " +
rs.getString("nombre"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}

private boolean validarCamposTrabajo(JComboBox<String> cliente, JTextField


equipo, JTextArea problema) {
if (cliente.getSelectedIndex() == -1) {
JOptionPane.showMessageDialog(this, "Seleccione un cliente", "Error",
JOptionPane.ERROR_MESSAGE);
return false;
}
if (equipo.getText().trim().isEmpty()) {
JOptionPane.showMessageDialog(this, "El equipo es obligatorio",
"Error", JOptionPane.ERROR_MESSAGE);
return false;
}
if (problema.getText().trim().isEmpty()) {
JOptionPane.showMessageDialog(this, "La descripción del problema es
obligatoria", "Error", JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}

private void guardarTrabajo(Integer id, String dniCliente, String equipo,


Integer idCategoria,
String marca, String modelo, String numeroSerie,
String descripcionProblema,
String diagnostico, String solucionImplementada,
String observaciones,
Integer idTecnico, Double costoEstimado, Double
costoFinal, int garantiaMeses,
boolean esNuevo) {
try {
String sql;
if (esNuevo) {
sql = "INSERT INTO trabajos (dni_cliente, equipo, id_categoria,
marca, modelo, numero_serie, " +
"descripcion_problema, diagnostico, solucion_implementada,
observaciones, " +
"id_tecnico_asignado, costo_estimado, costo_final,
garantia_meses, fecha_recepcion) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())";
} else {
sql = "UPDATE trabajos SET dni_cliente = ?, equipo = ?,
id_categoria = ?, marca = ?, modelo = ?, " +
"numero_serie = ?, descripcion_problema = ?, diagnostico
= ?, solucion_implementada = ?, " +
"observaciones = ?, id_tecnico_asignado = ?, costo_estimado
= ?, costo_final = ?, " +
"garantia_meses = ? WHERE id = ?";
}
try (PreparedStatement pstmt = connection.prepareStatement(sql,
Statement.RETURN_GENERATED_KEYS)) {
pstmt.setString(1, dniCliente.split(" - ")[0]);
pstmt.setString(2, equipo);
if (idCategoria != null) {
pstmt.setInt(3, idCategoria);
} else {
pstmt.setNull(3, Types.INTEGER);
}
pstmt.setString(4, marca);
pstmt.setString(5, modelo);
pstmt.setString(6, numeroSerie);
pstmt.setString(7, descripcionProblema);
pstmt.setString(8, diagnostico);
pstmt.setString(9, solucionImplementada);
pstmt.setString(10, observaciones);
if (idTecnico != null) {
pstmt.setInt(11, idTecnico);
} else {
pstmt.setNull(11, Types.INTEGER);
}
if (costoEstimado != null) {
pstmt.setDouble(12, costoEstimado);
} else {
pstmt.setNull(12, Types.DECIMAL);
}
if (costoFinal != null) {
pstmt.setDouble(13, costoFinal);
} else {
pstmt.setNull(13, Types.DECIMAL);
}
pstmt.setInt(14, garantiaMeses);

if (!esNuevo) {
pstmt.setInt(15, id);
}

pstmt.executeUpdate();

if (esNuevo) {
try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) {
if (generatedKeys.next()) {
id = generatedKeys.getInt(1);
}
}
}
}

JOptionPane.showMessageDialog(this, "Trabajo " + (esNuevo ?


"registrado" : "actualizado") + " exitosamente",
"Éxito", JOptionPane.INFORMATION_MESSAGE);
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error al guardar trabajo: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}
private void mostrarDialogoCambioEstado(int idTrabajo, String estadoActual) {
JDialog dialog = new JDialog(this, "Cambiar Estado del Trabajo", true);
dialog.setLayout(new BorderLayout());
dialog.setSize(400, 300);
dialog.setLocationRelativeTo(this);

JPanel panelFormulario = new JPanel(new GridBagLayout());


panelFormulario.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.anchor = GridBagConstraints.WEST;

// Obtener información del trabajo


String infoTrabajo = "";
try {
String sql = "SELECT t.equipo, CONCAT(c.nombres, ' ', c.apellidos) AS
cliente " +
"FROM trabajos t JOIN clientes c ON t.dni_cliente = c.dni WHERE
t.id = ?";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
pstmt.setInt(1, idTrabajo);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
infoTrabajo = rs.getString("equipo") + " - " +
rs.getString("cliente");
}
}
} catch (SQLException e) {
e.printStackTrace();
}

panelFormulario.add(new JLabel("Trabajo: " + infoTrabajo), gbc);

gbc.gridy++;
panelFormulario.add(new JLabel("Estado Actual: " + estadoActual), gbc);

gbc.gridy++;
panelFormulario.add(new JLabel("Nuevo Estado:"), gbc);

gbc.gridx = 1;
JComboBox<String> cmbEstado = new JComboBox<>();

// Configurar estados posibles según el estado actual


if (estadoActual.equals("Pendiente")) {
cmbEstado.addItem("Terminado");
cmbEstado.addItem("Entregado");
} else if (estadoActual.equals("Terminado")) {
cmbEstado.addItem("Entregado");
} else {
cmbEstado.addItem("No hay cambios posibles");
cmbEstado.setEnabled(false);
}

panelFormulario.add(cmbEstado, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Técnico:"), gbc);
gbc.gridx = 1;
JComboBox<String> cmbTecnicos = new JComboBox<>();
cargarComboTecnicos(cmbTecnicos);
panelFormulario.add(cmbTecnicos, gbc);

gbc.gridx = 0;
gbc.gridy++;
panelFormulario.add(new JLabel("Observaciones:"), gbc);

gbc.gridx = 1;
JTextArea txtObservaciones = new JTextArea(3, 20);
txtObservaciones.setLineWrap(true);
panelFormulario.add(new JScrollPane(txtObservaciones), gbc);

JPanel panelBotones = new JPanel(new FlowLayout(FlowLayout.CENTER));


JButton btnGuardar = new JButton("Guardar Cambio");
btnGuardar.setBackground(MENU_BG_COLOR);
btnGuardar.setForeground(Color.WHITE);
btnGuardar.addActionListener(e -> {
if (cmbEstado.isEnabled() && cmbEstado.getSelectedIndex() != -1) {
cambiarEstadoTrabajo(
idTrabajo,
estadoActual,
cmbEstado.getSelectedItem().toString(),
cmbTecnicos.getSelectedIndex() > 0 ?
Integer.parseInt(cmbTecnicos.getSelectedItem().toString().split(" - ")[0]) : null,
txtObservaciones.getText()
);
dialog.dispose();
actualizarTablaTrabajos();
}
});

JButton btnCancelar = new JButton("Cancelar");


btnCancelar.setBackground(MENU_BG_COLOR);
btnCancelar.setForeground(Color.WHITE);
btnCancelar.addActionListener(e -> dialog.dispose());

panelBotones.add(btnGuardar);
panelBotones.add(btnCancelar);

dialog.add(panelFormulario, BorderLayout.CENTER);
dialog.add(panelBotones, BorderLayout.SOUTH);
dialog.setVisible(true);
}

private void cambiarEstadoTrabajo(int idTrabajo, String estadoActual, String


nuevoEstado,
Integer idTecnico, String observaciones) {
try {
// Usar el procedimiento almacenado
String sql = "{call cambiar_estado_trabajo(?, ?, ?, ?, ?)}";
try (CallableStatement cstmt = connection.prepareCall(sql)) {
cstmt.setInt(1, idTrabajo);
cstmt.setString(2, nuevoEstado);
cstmt.setObject(3, idTecnico, Types.INTEGER);
cstmt.setString(4, observaciones);
cstmt.registerOutParameter(5, Types.VARCHAR);
cstmt.execute();
String resultado = cstmt.getString(5);
if (resultado.startsWith("Error:")) {
JOptionPane.showMessageDialog(this, resultado, "Error",
JOptionPane.ERROR_MESSAGE);
} else {
JOptionPane.showMessageDialog(this, resultado, "Éxito",
JOptionPane.INFORMATION_MESSAGE);
}
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error al cambiar estado: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}

private void eliminarTrabajo(int id, String equipo) {


int confirmacion = JOptionPane.showConfirmDialog(
this,
"¿Está seguro que desea eliminar el trabajo de " + equipo + "?",
"Confirmar eliminación",
JOptionPane.YES_NO_OPTION
);

if (confirmacion == JOptionPane.YES_OPTION) {
try {
// Eliminar repuestos asociados primero
String sqlDeleteRepuestos = "DELETE FROM repuestos_utilizados WHERE
id_trabajo = ?";
try (PreparedStatement pstmt =
connection.prepareStatement(sqlDeleteRepuestos)) {
pstmt.setInt(1, id);
pstmt.executeUpdate();
}

// Eliminar historial de estados


String sqlDeleteHistorial = "DELETE FROM historial_estados WHERE
id_trabajo = ?";
try (PreparedStatement pstmt =
connection.prepareStatement(sqlDeleteHistorial)) {
pstmt.setInt(1, id);
pstmt.executeUpdate();
}

// Finalmente eliminar el trabajo


String sqlDeleteTrabajo = "DELETE FROM trabajos WHERE id = ?";
try (PreparedStatement pstmt =
connection.prepareStatement(sqlDeleteTrabajo)) {
pstmt.setInt(1, id);
pstmt.executeUpdate();
}

JOptionPane.showMessageDialog(this, "Trabajo eliminado


exitosamente",
"Éxito", JOptionPane.INFORMATION_MESSAGE);
actualizarTablaTrabajos();
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error al eliminar trabajo: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}
}

private void actualizarTablaTrabajos() {


buscarTrabajos("", "", "");
}

private JPanel crearPanelReportes() {


JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panel.setBackground(Color.WHITE);

JLabel titulo = new JLabel("Reportes de Trabajos Técnicos",


SwingConstants.CENTER);
titulo.setFont(new Font("Arial", Font.BOLD, 20));
titulo.setForeground(MENU_BG_COLOR);
panel.add(titulo, BorderLayout.NORTH);

// Panel de filtros
JPanel filtrosPanel = new JPanel(new GridLayout(2, 4, 5, 5));
filtrosPanel.setBackground(Color.WHITE);
filtrosPanel.setBorder(BorderFactory.createTitledBorder("Filtros"));

JComboBox<String> cmbEstado = new JComboBox<>(new String[]{"Todos",


"Pendiente", "Terminado", "Entregado"});
JComboBox<String> cmbTecnico = new JComboBox<>();
cargarComboTecnicos(cmbTecnico);
JComboBox<String> cmbCategoria = new JComboBox<>();
cargarComboCategorias(cmbCategoria);
JTextField txtFechaInicio = new JTextField();
txtFechaInicio.setToolTipText("YYYY-MM-DD");
JTextField txtFechaFin = new JTextField();
txtFechaFin.setToolTipText("YYYY-MM-DD");

JButton btnGenerar = new JButton("Generar Reporte");


btnGenerar.setBackground(MENU_BG_COLOR);
btnGenerar.setForeground(Color.WHITE);
btnGenerar.addActionListener(e -> {
String estado = cmbEstado.getSelectedIndex() == 0 ? "" : (String)
cmbEstado.getSelectedItem();
String tecnico = cmbTecnico.getSelectedIndex() == 0 ? "" :
cmbTecnico.getSelectedItem().toString().split(" - ")[0];
String categoria = cmbCategoria.getSelectedIndex() == 0 ? "" :
cmbCategoria.getSelectedItem().toString().split(" - ")[0];
String fechaInicio = txtFechaInicio.getText().trim();
String fechaFin = txtFechaFin.getText().trim();
generarReporte(estado, tecnico, categoria, fechaInicio, fechaFin);
});

filtrosPanel.add(new JLabel("Estado:"));
filtrosPanel.add(new JLabel("Técnico:"));
filtrosPanel.add(new JLabel("Categoría:"));
filtrosPanel.add(new JLabel("Fechas:"));
filtrosPanel.add(cmbEstado);
filtrosPanel.add(cmbTecnico);
filtrosPanel.add(cmbCategoria);
JPanel panelFechas = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
panelFechas.add(new JLabel("Desde:"));
panelFechas.add(txtFechaInicio);
panelFechas.add(new JLabel("Hasta:"));
panelFechas.add(txtFechaFin);
filtrosPanel.add(panelFechas);

// Tabla de reportes
String[] columnasReportes = {"ID", "Equipo", "Categoría", "Estado",
"Cliente", "Técnico",
"Fecha Recepción", "Fecha Término", "Fecha Entrega", "Costo
Final"};
reportesTableModel = new DefaultTableModel(columnasReportes, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
JTable tablaReportes = new JTable(reportesTableModel);
JScrollPane scrollReportes = new JScrollPane(tablaReportes);

// Panel de botones
JPanel botonesPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
botonesPanel.setBackground(Color.WHITE);
botonesPanel.add(btnGenerar);

JButton btnExportar = new JButton("Exportar a CSV");


btnExportar.setBackground(MENU_BG_COLOR);
btnExportar.setForeground(Color.WHITE);
btnExportar.addActionListener(e -> exportarReporteCSV());
botonesPanel.add(btnExportar);

// Organizar componentes
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.setBackground(Color.WHITE);
centerPanel.add(filtrosPanel, BorderLayout.NORTH);
centerPanel.add(scrollReportes, BorderLayout.CENTER);
centerPanel.add(botonesPanel, BorderLayout.SOUTH);

panel.add(centerPanel, BorderLayout.CENTER);
return panel;
}

private void generarReporte(String estado, String idTecnico, String


idCategoria,
String fechaInicio, String fechaFin) {
try {
reportesTableModel.setRowCount(0);

StringBuilder sql = new StringBuilder();


sql.append("SELECT t.id, t.equipo, ce.nombre AS categoria, t.estado,
");
sql.append("CONCAT(c.nombres, ' ', c.apellidos) AS cliente, ");
sql.append("CONCAT(tec.nombres, ' ', tec.apellidos) AS tecnico, ");
sql.append("t.fecha_recepcion, t.fecha_termino_reparacion,
t.fecha_entrega, t.costo_final ");
sql.append("FROM trabajos t ");
sql.append("JOIN clientes c ON t.dni_cliente = c.dni ");
sql.append("LEFT JOIN tecnicos tec ON t.id_tecnico_asignado = tec.id
");
sql.append("LEFT JOIN categorias_equipos ce ON t.id_categoria = ce.id
");
sql.append("WHERE 1=1 ");

if (!estado.isEmpty()) {
sql.append("AND t.estado = ? ");
}
if (!idTecnico.isEmpty()) {
sql.append("AND t.id_tecnico_asignado = ? ");
}
if (!idCategoria.isEmpty()) {
sql.append("AND t.id_categoria = ? ");
}
if (!fechaInicio.isEmpty() && !fechaFin.isEmpty()) {
sql.append("AND DATE(t.fecha_recepcion) BETWEEN ? AND ? ");
} else if (!fechaInicio.isEmpty()) {
sql.append("AND DATE(t.fecha_recepcion) >= ? ");
} else if (!fechaFin.isEmpty()) {
sql.append("AND DATE(t.fecha_recepcion) <= ? ");
}
sql.append("ORDER BY t.estado, t.fecha_recepcion DESC");

try (PreparedStatement pstmt =


connection.prepareStatement(sql.toString())) {
int paramIndex = 1;
if (!estado.isEmpty()) {
pstmt.setString(paramIndex++, estado);
}
if (!idTecnico.isEmpty()) {
pstmt.setInt(paramIndex++, Integer.parseInt(idTecnico));
}
if (!idCategoria.isEmpty()) {
pstmt.setInt(paramIndex++, Integer.parseInt(idCategoria));
}
if (!fechaInicio.isEmpty() && !fechaFin.isEmpty()) {
pstmt.setString(paramIndex++, fechaInicio);
pstmt.setString(paramIndex++, fechaFin);
} else if (!fechaInicio.isEmpty()) {
pstmt.setString(paramIndex++, fechaInicio);
} else if (!fechaFin.isEmpty()) {
pstmt.setString(paramIndex++, fechaFin);
}

ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
reportesTableModel.addRow(new Object[]{
rs.getInt("id"),
rs.getString("equipo"),
rs.getString("categoria"),
rs.getString("estado"),
rs.getString("cliente"),
rs.getString("tecnico"),
rs.getTimestamp("fecha_recepcion"),
rs.getTimestamp("fecha_termino_reparacion"),
rs.getTimestamp("fecha_entrega"),
rs.getBigDecimal("costo_final") != null ? "S/ " +
rs.getBigDecimal("costo_final") : ""
});
}
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error al generar reporte: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}

private void exportarReporteCSV() {


if (reportesTableModel.getRowCount() == 0) {
JOptionPane.showMessageDialog(this, "No hay datos para exportar",
"Error", JOptionPane.ERROR_MESSAGE);
return;
}

JFileChooser fileChooser = new JFileChooser();


fileChooser.setDialogTitle("Guardar reporte como CSV");

// Corrección: Separar la creación del nombre del archivo en pasos más


claros
String timestamp =
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
String nombreArchivo = "reporte_trabajos_" + timestamp + ".csv";
fileChooser.setSelectedFile(new File(nombreArchivo));

int userSelection = fileChooser.showSaveDialog(this);


if (userSelection == JFileChooser.APPROVE_OPTION) {
File fileToSave = fileChooser.getSelectedFile();
try (java.io.PrintWriter pw = new java.io.PrintWriter(fileToSave)) {
// Escribir encabezados
for (int i = 0; i < reportesTableModel.getColumnCount(); i++) {
pw.print(reportesTableModel.getColumnName(i));
if (i < reportesTableModel.getColumnCount() - 1) {
pw.print(",");
}
}
pw.println();

// Escribir datos
for (int row = 0; row < reportesTableModel.getRowCount(); row++) {
for (int col = 0; col < reportesTableModel.getColumnCount();
col++) {
Object value = reportesTableModel.getValueAt(row, col);
if (value != null) {
pw.print(value.toString().replace(",", "")); //
Eliminar comas para evitar problemas en CSV
}
if (col < reportesTableModel.getColumnCount() - 1) {
pw.print(",");
}
}
pw.println();
}

JOptionPane.showMessageDialog(this, "Reporte exportado exitosamente


a " + fileToSave.getAbsolutePath(),
"Éxito", JOptionPane.INFORMATION_MESSAGE);
} catch (java.io.IOException e) {
JOptionPane.showMessageDialog(this, "Error al exportar reporte: " +
e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}
}
private void actualizarReportes() {
generarReporte("", "", "", "", "");
}

public static void main(String[] args) {


SwingUtilities.invokeLater(() -> {
try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new SistemaServicioTecnico();
} catch (Exception e) {
e.printStackTrace();
}
});
}
}

También podría gustarte