diff --git a/src/main/java/com/utp/clsHerramientas/semestral/Cliente.java b/src/main/java/com/utp/clsHerramientas/semestral/Cliente.java new file mode 100644 index 0000000..e01538e --- /dev/null +++ b/src/main/java/com/utp/clsHerramientas/semestral/Cliente.java @@ -0,0 +1,29 @@ +package com.utp.clsHerramientas.semestral; + +public record Cliente(String codigo, String nombre, String apellido, String direccion, String telefono_1, + String telefono_2) { + + public static final Integer generales_clientes_len = 20; + + public static Cliente[] cargar_clientes() { + Cliente[] clientes = new Cliente[generales_clientes_len]; + String[] datosGral = new String[generales_clientes_len]; + Datos.generalesCliente(datosGral); + for (int i = 0; i < generales_clientes_len; i++) { + String[] datos = datosGral[i].split(" +"); + clientes[i] = new Cliente(datos[0], datos[1], datos[2], datos[3], datos[4], datos[5]); + } + return clientes; + } + + public String nombre_completo(){ + return nombre + " " + apellido; + } + public static void main(String[] args) { + Cliente[] clientes = cargar_clientes(); + for (int i = 0; i < clientes.length; i++) { + System.out.println(i + "-)" + clientes[i]); + } + } + +} diff --git a/src/main/java/com/utp/clsHerramientas/semestral/Datos.java b/src/main/java/com/utp/clsHerramientas/semestral/Datos.java new file mode 100644 index 0000000..83abd9b --- /dev/null +++ b/src/main/java/com/utp/clsHerramientas/semestral/Datos.java @@ -0,0 +1,90 @@ +package com.utp.clsHerramientas.semestral; + +public class Datos { + public static void generalesCliente(String datosGral[]) { + datosGral[0] = "A280188 ANA CORDOVA DAVID 9603-5645 774-4563"; + datosGral[1] = "A280210 CRISTOBAL MORALES ALANJE 6563-9875 730-2592"; + datosGral[2] = "A280001 VICTOR ALVAREZ PUERTO_ARMUELLES 6897-4563 730-2564"; + datosGral[3] = "A280002 BELLA LEGUISAMO BOCAS_DEL_TORO 8945-6978 775-4786"; + datosGral[4] = "A123456 CRISTOBAL PORTILLO CHIRIQUI 6365-4563 774-8858"; + datosGral[5] = "A280019 MORER MARTINEZ GUALACA 7589-4563 774-6570"; + datosGral[6] = "A280020 QUIM ATENCIO BUGABA 7845-9865 721-1458"; + datosGral[7] = "A280221 FERNANDO COLMENARES BOQUETE 7410-2589 730-1235"; + datosGral[8] = "A280031 BLASCO JIMENEZ ALANJE 3698-5421 730-4251"; + datosGral[9] = "A280039 CARMEN CASTELBLANCO PUERTO_ARMUELLES 8656-7854 730-1234"; + datosGral[10] = "A280043 LUISA ESPINALES TOLE 7845-1111 721-1234"; + datosGral[11] = "A280044 JOSE ESQUIVEL REMEDIOS 8547-9632 721-1289"; + datosGral[12] = "A280045 ANGELES ESTRADA BOQUERON 2587-4525 730-4578"; + datosGral[13] = "A280066 JUAN PEREZ TIERRAS_ALTAS 6345-8574 730-4563"; + datosGral[14] = "A280067 REBECA SANTOS POTRERILLOS 4239-8712 774-1263"; + datosGral[15] = "A280068 MARGARITA CASTILLO BOQUETE 4502-1234 721-4567"; + datosGral[16] = "A280069 JUAN PERALTA DAVID 4127-3211 721-7878"; + datosGral[17] = "A280070 DIEGO AROSEMENA PUERTO_ARMUELLES 3645-2233 730-9898"; + datosGral[18] = "A280240 FELIPE ESTRADA ALANJE 6565-8521 775-6363"; + datosGral[19] = "A280245 JUAN AROSEMENA DAVID 6536-8712 774-4567"; + } + + public static void facturasCliente(String datosFac[]) { + datosFac[0] = "A123456 0400250 06/04/2024 896.55"; + datosFac[1] = "A123456 0700175 08/07/2023 658.45"; + datosFac[2] = "A123456 0200133 09/02/2024 995.48"; + datosFac[3] = "A280001 0700145 03/07/2023 365.37"; + datosFac[4] = "A280001 0200127 04/02/2024 142.64"; + datosFac[5] = "A280001 0200131 07/02/2024 819.97"; + datosFac[6] = "A280002 0100245 10/01/2024 353.82"; + datosFac[7] = "A280002 0700185 08/07/2023 456.40"; + datosFac[8] = "A280002 0500342 02/05/2024 17.63"; + datosFac[9] = "A280019 0500381 08/05/2024 740.96"; + datosFac[10] = "A280019 0800453 03/08/2023 57.27"; + datosFac[11] = "A280019 0700195 08/07/2023 563.96"; + datosFac[12] = "A280020 0600100 01/06/2018 372.81"; + datosFac[13] = "A280020 1000345 07/10/2023 426.16"; + datosFac[14] = "A280020 0200134 10/02/2024 49.19"; + datosFac[15] = "A280031 0700125 02/07/2023 921.65"; + datosFac[16] = "A280031 0500125 01/05/2023 478.83"; + datosFac[17] = "A280031 0500350 03/05/2024 551.04"; + datosFac[18] = "A280039 1000456 08/10/2023 452.61"; + datosFac[19] = "A280039 0800850 07/08/2023 195.10"; + datosFac[20] = "A280039 0600500 02/06/2024 97.08"; + datosFac[21] = "A280043 0900234 02/09/2023 800.62"; + datosFac[22] = "A280043 0600600 02/06/2024 382.58"; + datosFac[23] = "A280043 0600900 06/06/2024 203.94"; + datosFac[24] = "A280044 0300564 04/03/2024 285.19"; + datosFac[25] = "A280044 0400131 04/04/2024 264.22"; + datosFac[26] = "A280044 0500234 01/05/2024 720.59"; + datosFac[27] = "A280045 0200130 06/02/2024 247.73"; + datosFac[28] = "A280045 0500360 06/05/2024 227.84"; + datosFac[29] = "A280045 0700155 04/07/2023 559.76"; + datosFac[30] = "A280066 0400380 07/04/2024 477.88"; + datosFac[31] = "A280066 0500286 07/05/2024 681.78"; + datosFac[32] = "A280066 0600800 03/06/2024 153.47"; + datosFac[33] = "A280067 0200125 02/02/2024 271.25"; + datosFac[34] = "A280067 1000678 10/10/2023 156.87"; + datosFac[35] = "A280067 0700135 03/07/2023 971.39"; + datosFac[36] = "A280068 0600905 06/06/2024 35.23"; + datosFac[37] = "A280068 0800585 05/08/2023 121.72"; + datosFac[38] = "A280068 0900456 12/09/2023 821.41"; + datosFac[39] = "A280069 0800570 04/08/2023 328.48"; + datosFac[40] = "A280069 0600700 02/06/2024 986.55"; + datosFac[41] = "A280069 0700165 06/07/2023 886.81"; + datosFac[42] = "A280070 0400325 08/04/2024 261.19"; + datosFac[43] = "A280070 0400128 02/04/2024 138.72"; + datosFac[44] = "A280070 0400139 05/04/2024 643.90"; + datosFac[45] = "A280188 1000789 10/10/2023 585.19"; + datosFac[46] = "A280188 0900123 01/09/2023 917.15"; + datosFac[47] = "A280188 1000234 06/10/2023 223.43"; + datosFac[48] = "A280210 0900345 04/09/2023 293.31"; + datosFac[49] = "A280210 0800567 03/08/2023 926.49"; + datosFac[50] = "A280210 0500356 04/05/2024 525.80"; + datosFac[51] = "A280221 0400137 04/04/2024 638.48"; + datosFac[52] = "A280221 0600907 09/06/2024 316.19"; + datosFac[53] = "A280221 0800876 10/08/2023 221.08"; + datosFac[54] = "A280240 1000123 03/10/2023 177.75"; + datosFac[55] = "A280240 0800800 06/08/2023 293.39"; + datosFac[56] = "A280240 1100234 01/11/2023 561.22"; + datosFac[57] = "A280245 0500001 01/05/2024 203.01"; + datosFac[58] = "A280245 1000567 09/10/2023 529.11"; + datosFac[59] = "A280245 0500382 08/05/2024 96.13"; + } + +} diff --git a/src/main/java/com/utp/clsHerramientas/semestral/Main.java b/src/main/java/com/utp/clsHerramientas/semestral/Main.java new file mode 100644 index 0000000..a23a058 --- /dev/null +++ b/src/main/java/com/utp/clsHerramientas/semestral/Main.java @@ -0,0 +1,185 @@ +package com.utp.clsHerramientas.semestral; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JTextField; + +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.KeyEvent; + +import com.utp.clsHerramientas.semestral.ui.Factura; +import com.utp.clsHerramientas.semestral.ui.Reporte; +import com.utp.clsHerramientas.semestral.ui.UI; + +import static com.utp.clsHerramientas.semestral.App.CMD.*; + +public class Main { + public static void main(String[] args) { + App app = new App(); + app.run(); + } +} + +/** + * Bibliografías : + * 1. https://www.rapidtables.com/web/color/RGB_Color.html + * 2. + * https://stackoverflow.com/questions/20165564/calculating-days-between-two-dates-with-java + * 3. + * https://stackoverflow.com/questions/2138085/java-date-format-including-additional-characters + * 4. + * https://stackoverflow.com/questions/2442599/how-to-set-jframe-to-appear-centered-regardless-of-monitor-resolution + */ + +class App { + public final Cliente[] clientes = Cliente.cargar_clientes(); + public final Factura[] facturas = Factura.cargar_facturas(); + public final JFrame frame = new JFrame("Trabajo Final - Arreglo de Objetos"); + final JButton btn_mostrar_factura = new JButton("Mostrar Factura"); + final JTextField txt_buscar = new JTextField(35); + final JLabel user_hint = new JLabel(); + boolean last_buscar_result = true; + + void run() { + frame.add(content_pane()); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + } + + App() { + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + } + + JPanel content_pane() { + // Inicializar estado de la aplicación + send_command(new Buscar(txt_buscar.getText())); + + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.BOTH; + gbc.gridx = 0; + gbc.gridy = 0; + gbc.insets = new Insets(2, 0, 2, 0); + panel.add(user_hint, gbc); + + gbc.gridy = 1; + panel.add(txt_buscar, gbc); + gbc.gridy = 2; + panel.add(btn_mostrar_factura, gbc); + + JButton btn_mostrar_clientes = new JButton("Mostrar Clientes"); + gbc.gridy = 3; + panel.add(btn_mostrar_clientes, gbc); + + btn_mostrar_clientes.addActionListener(e -> { + JTextArea txt_area = new JTextArea(); + txt_area.setEditable(false); + StringBuilder sb = new StringBuilder(); + for (Cliente cliente : clientes) { + sb.append(cliente.codigo()).append(" :"); + sb.append(cliente.nombre_completo()).append("\n"); + } + sb.delete(sb.length() - 1, sb.length()); + txt_area.setText(sb.toString()); + JOptionPane.showMessageDialog(btn_mostrar_clientes, txt_area, "Clientes registrados", + JOptionPane.INFORMATION_MESSAGE); + }); + txt_buscar.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyReleased(java.awt.event.KeyEvent evt) { + send_command(new Buscar(txt_buscar.getText())); + if (btn_mostrar_factura.isEnabled() && KeyEvent.VK_ENTER == evt.getKeyCode()) { + send_command(new MostrarFactura()); + } + evt.consume(); + } + }); + + btn_mostrar_factura.addActionListener(e -> { + send_command(new MostrarFactura()); + }); + + return panel; + } + + public void send_command(CMD cmd) { + switch (cmd) { + case Buscar(String codigo) -> { + Cliente cliente = null; + if (!codigo.trim().isEmpty()) { + for (Cliente cliente_n : clientes) { + if (cliente_n.codigo().equals(codigo)) { + if (!last_buscar_result) { + last_buscar_result = true; + System.out.println("Cliente existe: `" + cliente_n.codigo() + "`"); + } + cliente = cliente_n; + break; + } + } + } + if (cliente == null) { + btn_mostrar_factura.setEnabled(false); + if (txt_buscar.getText().isEmpty()) { + user_hint.setText("Ingrese el Codigo de Cliente"); + user_hint.setForeground(Color.BLACK); + } else { + user_hint.setText("Código no se reconoce"); + user_hint.setForeground(Color.RED); + } + if (last_buscar_result) { + System.out.println("Cliente: `" + codigo + "` no existe"); + last_buscar_result = false; + } + return; + } + user_hint.setText("Codigo Reconocido"); + user_hint.setForeground(UI.DarkGreen); + btn_mostrar_factura.setEnabled(true); + } + case MostrarFactura() -> { + Cliente Cliente = null; + for (Cliente cliente_n : clientes) { + if (cliente_n.codigo().equals(txt_buscar.getText())) { + Cliente = cliente_n; + break; + } + } + // reiniciar la búsqueda + txt_buscar.setText(""); + send_command(new Buscar("")); + Reporte reporte = new Reporte(Cliente, facturas); + + var reporte1 = UI.show(reporte.as_reporte_1()); + var reporte2 = UI.show(reporte.as_reporte_2()); + String titulo = "Reporte de Facturas - Cliente: " + Cliente.nombre_completo(); + reporte1.setTitle(titulo); + reporte2.setTitle(titulo); + reporte1.toFront(); + reporte.add_ok_action(new Runnable() { + @Override + public void run() { + reporte1.dispose(); + reporte2.dispose(); + } + }); + } + + } + } + + public sealed interface CMD { + // @formatter:off + public record Buscar(String codigo) implements CMD{}; + public record MostrarFactura() implements CMD{}; + // @formatter:on + } + +} \ No newline at end of file diff --git "a/src/main/java/com/utp/clsHerramientas/semestral/Pr\303\241ctica Final 2.pdf" "b/src/main/java/com/utp/clsHerramientas/semestral/Pr\303\241ctica Final 2.pdf" new file mode 100644 index 0000000..90d8fcf Binary files /dev/null and "b/src/main/java/com/utp/clsHerramientas/semestral/Pr\303\241ctica Final 2.pdf" differ diff --git a/src/main/java/com/utp/clsHerramientas/semestral/Querier.java b/src/main/java/com/utp/clsHerramientas/semestral/Querier.java new file mode 100644 index 0000000..96f0248 --- /dev/null +++ b/src/main/java/com/utp/clsHerramientas/semestral/Querier.java @@ -0,0 +1,16 @@ +package com.utp.clsHerramientas.semestral; + +import java.util.ArrayList; + +import com.utp.clsHerramientas.semestral.ui.Factura; + +public final class Querier { + public static Factura[] selectFacturas(Cliente cliente, Factura[] facturas) { + ArrayList facturasCliente = new ArrayList(); + for (Factura fact : facturas) { + if (fact.codigo().equals(cliente.codigo())) + facturasCliente.add(fact); + } + return facturasCliente.toArray(new Factura[0]); + } +} diff --git a/src/main/java/com/utp/clsHerramientas/semestral/ui/Factura.java b/src/main/java/com/utp/clsHerramientas/semestral/ui/Factura.java new file mode 100644 index 0000000..a9d0596 --- /dev/null +++ b/src/main/java/com/utp/clsHerramientas/semestral/ui/Factura.java @@ -0,0 +1,61 @@ +package com.utp.clsHerramientas.semestral.ui; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; +import java.text.NumberFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; + +import com.utp.clsHerramientas.semestral.Datos; + +public record Factura(String codigo, int numero_factura, LocalDate fecha, BigDecimal monto) + implements Comparable { + + public static final Integer FACTURAS_CLIENTE_LEN = 60; + public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + @Override + public int compareTo(Factura o) { + return codigo.compareTo(o.codigo); + } + + public Factura(String codigo, int numero_factura, String fecha, String monto) { + this(codigo, numero_factura, LocalDate.parse(fecha, FORMATTER), + new BigDecimal(monto, new MathContext(24, RoundingMode.HALF_EVEN))); + } + + public String fecha_as_string() { + return fecha.format(FORMATTER); + } + + public String monto_as_string() { + var format = NumberFormat.getInstance(); + format.setMinimumFractionDigits(2); + return format.format(monto); + } + public long antiguedad(){ + return ChronoUnit.DAYS.between(LocalDate.now(), fecha); + } + + public static void main(String[] args) { + Factura[] facturas = cargar_facturas(); + for (int i = 0; i < facturas.length; i++) { + System.out.println(i + "-)" + facturas[i]); + } + System.out.println(facturas[58].monto_as_string()); + } + + public static Factura[] cargar_facturas() { + Factura[] facturas = new Factura[FACTURAS_CLIENTE_LEN]; + String[] datosFac = new String[FACTURAS_CLIENTE_LEN]; + Datos.facturasCliente(datosFac); + for (int i = 0; i < FACTURAS_CLIENTE_LEN; i++) { + String[] datos = datosFac[i].split(" +"); + facturas[i] = new Factura(datos[0], Integer.parseInt(datos[1]), datos[2], datos[3]); + } + Arrays.sort(facturas); + return facturas; + } +} diff --git a/src/main/java/com/utp/clsHerramientas/semestral/ui/Reporte.java b/src/main/java/com/utp/clsHerramientas/semestral/ui/Reporte.java new file mode 100644 index 0000000..2b4ca86 --- /dev/null +++ b/src/main/java/com/utp/clsHerramientas/semestral/ui/Reporte.java @@ -0,0 +1,211 @@ +package com.utp.clsHerramientas.semestral.ui; + +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import com.utp.clsHerramientas.semestral.Cliente; +import com.utp.clsHerramientas.semestral.Querier; + +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Locale; + +public final class Reporte { + public static final DateTimeFormatter FORMATTER = DateTimeFormatter + .ofPattern("EEEE dd 'de' MMMM 'de' yyyy HH:mm:ss a, zzzz", + new Locale.Builder().setLanguage("es").setRegion("PA").build()); + final Cliente cliente; + final Factura[] facturas; + public final JButton ok = new JButton("Salir"); + static public final int[] dias = { 10000, 120, 90, 60, 30, 0 }; + + public Reporte(Cliente cliente, Factura[] facturas) { + this.cliente = cliente; + this.facturas = Querier.selectFacturas(cliente, facturas); + } + + public JPanel as_reporte_1() { + + JPanel final_panel = new JPanel(new GridBagLayout()); + Table tabla = new Table(facturas, cliente); + + var gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + + final_panel.add(this.encabezado(), gbc); + gbc.gridy = 1; + final_panel.add(this.empty_panel(), gbc); + gbc.gridy = 2; + final_panel.add(tabla.as_panel(), gbc); + gbc.gridy = 3; + final_panel.add(this.empty_panel(), gbc); + gbc.gridy = 4; + final_panel.add(ok, gbc); + + return final_panel; + } + + public JPanel as_reporte_2() { + + JPanel final_panel = new JPanel(new GridBagLayout()); + + var gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + + final_panel.add(this.encabezado(), gbc); + gbc.gridy = 1; + // RESUMEN FINAL DE CUENTAS POR COBRAR/CLIENTES + final_panel.add(this.empty_panel(), gbc); + gbc.gridy = 2; + final_panel.add(into_label("RESUMEN FINAL DE CUENTAS POR COBRAR/CLIENTES"), gbc); + gbc.gridy = 3; + final_panel.add(this.empty_panel()); + gbc.gridy = 4; + + JPanel resumen = new JPanel(new GridBagLayout()); + JLabel[] labels = { into_label("MES CORRIENTE: "), + into_label("30 DIAS: "), + into_label("60 DIAS: "), + into_label("90 DIAS: "), + into_label("+120 DIAS: ") }; + var resumen_gbc = new GridBagConstraints(); + for (int i = 1; i < labels.length + 1; i++) { + resumen_gbc.gridx = 0; + resumen_gbc.gridy = i - 1; + resumen.add(labels[i - 1], resumen_gbc); + resumen_gbc.gridx = 1; + // some offset due to dias[] layout + BigDecimal summary = summary(labels.length - i + 1); + JLabel monto; + if (summary.equals(BigDecimal.ZERO)) { + monto = into_label("0.00"); + } else { + monto = into_label(summary.toString()); + } + if (i == 1) { + monto.setForeground(UI.DarkCyan); + + } + resumen_gbc.anchor = GridBagConstraints.EAST; + resumen.add(monto, resumen_gbc); + } + final_panel.add(resumen, gbc); + gbc.gridy = 5; + final_panel.add(this.empty_panel(), gbc); + gbc.gridy = 6; + + // Table tabla = new Table(facturas, cliente); + // final_panel.add(tabla.as_panel(), gbc); + // gbc.gridy = 7; + final_panel.add(ok, gbc); + return final_panel; + } + + public BigDecimal summary(int idx_dia) { + BigDecimal resumen = BigDecimal.ZERO; + for (int i = 0; i < facturas.length; i++) { + long antiguedad = -facturas[i].antiguedad(); + if (antiguedad >= dias[idx_dia] && antiguedad < dias[idx_dia - 1]) { + resumen = resumen.add(facturas[i].monto()); + } + // System.out.printf("%d)Antiguedad: %d, monto: %s (%s)\n", idx_dia, antiguedad, + // facturas[i].monto(), + // (antiguedad >= dias[idx_dia] && antiguedad < dias[idx_dia - 1])); + } + resumen.setScale(2, RoundingMode.HALF_EVEN); + return resumen; + } + + public JPanel encabezado() { + + JPanel panel = new JPanel(new GridBagLayout()); + var gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.gridwidth = 4; + gbc.fill = GridBagConstraints.VERTICAL; + panel.add(into_header_label("UNIVERSIDAD TECNOLÓGICA DE PANAMÁ"), gbc); + gbc.gridy = 1; + panel.add(into_header_label("CENTRO REGIONAL DE CHIRIQUÍ"), gbc); + gbc.gridy = 2; + panel.add(into_header_label("FACULTAD DE INGENIERÍA DE SISTEMAS COMPUTACIONALES"), gbc); + gbc.gridy = 3; + panel.add(into_header_label("CARRERA: LICENCIATURA EN INGENIERÍA DE SISTEMAS COMPUTACIONALES"), gbc); + gbc.gridy = 4; + panel.add(into_header_label("GRUPO: 2IL701"), gbc); + gbc.gridy = 5; + panel.add(empty_panel(), gbc); + gbc.gridy = 6; + panel.add(into_header_label("ANÁLISIS DE CUENTAS POR COBRAR POR CLIENTE"), gbc); + gbc.gridy = 7; + gbc.gridx = 0; + gbc.gridwidth = 1; + gbc.fill = GridBagConstraints.NONE; + gbc.anchor = GridBagConstraints.WEST; + panel.add(into_label("ESTUDIANTE: ANTONIO NG"), gbc); + gbc.gridx = 2; + panel.add(into_label("DOCENTE: Prof. Eduardo Beitia"), gbc); + + gbc.gridy = 8; + gbc.gridx = 0; + gbc.gridwidth = 4; + // panel.add(into_label("FECHA: " + FORMATTER.format(LocalDate.now())), gbc); + panel.add(into_label("FECHA: " + FORMATTER.format(ZonedDateTime.now())), gbc); + + gbc.gridy = 9; + gbc.gridx = 0; + gbc.gridwidth = 2; + + panel.add(into_label("Codigo de Cliente: " + + cliente.codigo() + ""), gbc); + gbc.gridwidth = 2; + gbc.gridx = 2; + panel.add(into_label(" Nombre: " + cliente.nombre_completo()), gbc); + + return panel; + } + + public void add_ok_action(Runnable action) { + ok.addActionListener(e -> action.run()); + } + + JLabel into_header_label(String text) { + JLabel label = new JLabel(text); + label.setFont(UI.ProjFont.HEADER); + label.setForeground(UI.DarkGreen); + return label; + } + + JLabel into_label(String text) { + JLabel label = new JLabel(text); + label.setFont(UI.ProjFont.NORMAL); + label.setForeground(UI.Black); + return label; + } + + JPanel empty_panel() { + var empty_panel = new JPanel(); + empty_panel.setPreferredSize(new Dimension(50, 20)); + return empty_panel; + } + + public static void main(String[] args) { + Cliente[] cliente = Cliente.cargar_clientes(); + Factura[] facturas = Factura.cargar_facturas(); + Reporte reporte = new Reporte(cliente[4], facturas); + reporte.add_ok_action(() -> { + System.out.println("OK! Exiting...."); + System.exit(0); + }); + UI.show(reporte.as_reporte_1()); + UI.show(reporte.as_reporte_2()); + } +} diff --git a/src/main/java/com/utp/clsHerramientas/semestral/ui/Table.java b/src/main/java/com/utp/clsHerramientas/semestral/ui/Table.java new file mode 100644 index 0000000..1b6616a --- /dev/null +++ b/src/main/java/com/utp/clsHerramientas/semestral/ui/Table.java @@ -0,0 +1,173 @@ +package com.utp.clsHerramientas.semestral.ui; + +import javax.swing.BorderFactory; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; + +import com.utp.clsHerramientas.semestral.Cliente; + +public final class Table { + static final Integer MAX_HEIGHT = 300; + static final Color DarkCyan = UI.DarkCyan; + static final Color DarkGreen = UI.DarkGreen; + final Factura[] facturas; + final Cliente cliente; + + final JLabel[] encabezados = { new JLabel("FECHA dd/MM/yyyy"), new JLabel("NUM. FACTURA"), new JLabel("MONTO"), + new JLabel("MES CORRIENTE"), + new JLabel("30 DÍAS"), new JLabel("60 DÍAS"), new JLabel("90 DÍAS"), new JLabel("+120 DÍAS") }; + final JPanel[] columnas = { new JPanel(), new JPanel(), new JPanel(), new JPanel(), new JPanel(), new JPanel(), + new JPanel(), new JPanel() }; + final BigDecimal[] montos = { new BigDecimal("0.00"), new BigDecimal("0.00"), new BigDecimal("0.00"), + new BigDecimal("0.00"), new BigDecimal("0.00"), new BigDecimal("0.00") }; + final static Integer[] rangos = { 0, 30, 60, 90, 120 }; + + Table(Factura[] facturas, Cliente cliente) { + // this.facturas = Querier.selectFacturas(cliente, facturas); + this.facturas = facturas; + this.cliente = cliente; + } + + public JScrollPane as_panel() { + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.gridx = 0; + c.gridy = 0; + c.anchor = GridBagConstraints.WEST; + + // Insertar los encabezados de la tabla + for (int col = 0; col < encabezados.length; col++) { + columnas[col].setLayout(new GridBagLayout()); + var prefered_size = encabezados[col].getPreferredSize(); + encabezados[col].setPreferredSize(new Dimension(prefered_size.width + 34, prefered_size.height + 20)); + columnas[col].add(encabezados[col], c); + // columnas[col].add(, c); + encabezados[col].setHorizontalAlignment(JLabel.CENTER); + encabezados[col].setVerticalAlignment(JLabel.CENTER); + encabezados[col].setFont(new Font(Font.MONOSPACED, Font.BOLD, 12)); + encabezados[col].setForeground(DarkCyan); + encabezados[col].setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, UI.Violet)); + } + + c.insets = new Insets(2, 2, 2, 2); + c.fill = GridBagConstraints.NONE; + c.gridx = 0; + c.gridy = 1; + for (Factura factura : this.facturas) { + + // Insertar datos a la fila + JLabel[] datos = { new JLabel(factura.fecha_as_string()), + new JLabel(String.valueOf(factura.numero_factura())), + new JLabel(factura.monto_as_string()) }; + c.anchor = GridBagConstraints.CENTER; + for (int col = 0; col < datos.length; col++) { + columnas[col].setAlignmentX(1.0f); + datos[col].setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + datos[col].setForeground(UI.Black); + if (col >= 1) { + c.anchor = GridBagConstraints.EAST; + } + columnas[col].add(datos[col], c); + } + + // Insertar los montos de la tabla + c.anchor = GridBagConstraints.EAST; + boolean populated = false; + long dias = -ChronoUnit.DAYS.between(LocalDate.now(), factura.fecha()); + c.weightx = 0; + for (int col = encabezados.length - 1; col >= 3; col--) { + JLabel label = new JLabel(); + label.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + if (!populated && dias > rangos[col - 3]) { + label.setForeground(DarkCyan); + label.setText(factura.monto_as_string()); + montos[col - 2] = montos[col - 2].add(factura.monto()); + populated = true; + } else { + label.setText("0.00"); + label.setForeground(UI.Gray); + } + columnas[col].add(label, c); + } + montos[0] = montos[0].add(factura.monto()); + c.gridy++; + } + + JLabel[] summary_labels = { new JLabel("Trab. Final"), new JLabel("Total"), + new JLabel(montos[0].toString()), + new JLabel(montos[1].toString()), + new JLabel(montos[2].toString()), + new JLabel(montos[3].toString()), + new JLabel(montos[4].toString()), + new JLabel(montos[5].toString()) }; + c.fill = GridBagConstraints.BOTH; + c.anchor = GridBagConstraints.EAST; + c.insets = new Insets(4, 0, 4, 0); + for (JLabel label : summary_labels) { + label.setHorizontalAlignment(JLabel.RIGHT); + if (label.getText().equals("0.00")) { + label.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + label.setForeground(UI.Gray); + } else { + label.setFont(new Font(Font.MONOSPACED, Font.BOLD, 12)); + label.setForeground(DarkGreen); + } + label.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UI.Violet)); + } + summary_labels[0].setForeground(UI.DarkCyan); + summary_labels[0].setHorizontalAlignment(JLabel.LEFT); + summary_labels[1].setForeground(UI.DarkCyan); + summary_labels[1].setHorizontalAlignment(JLabel.LEFT); + + for (int col = 0; col < summary_labels.length; col++) { + columnas[col].add(summary_labels[col], c); + } + + JPanel table_content = new JPanel(new GridBagLayout()); + c.gridy = 0; + c.gridx = 0; + c.insets = new Insets(0, 0, 0, 0); + + // Acoplar cada columna a la tabla + for (JPanel columna : columnas) { + table_content.add(columna, c); + var border = BorderFactory.createMatteBorder(2, 0, 2, 1, UI.Violet); + columna.setBorder(border); + c.gridx++; + } + columnas[0].setBorder(BorderFactory.createMatteBorder(2, 2, 2, 1, UI.Violet)); + columnas[columnas.length - 1].setBorder(BorderFactory.createMatteBorder(2, 0, 2, 2, UI.Violet)); + JScrollPane scrollPane = new JScrollPane(table_content); + + var prefered = scrollPane.getPreferredSize(); + int prefered_height = Math.min(MAX_HEIGHT, prefered.height); + int minimum_width = (MAX_HEIGHT < prefered.height) ? prefered.width + 17 : prefered.width; + scrollPane.setPreferredSize(new Dimension(minimum_width, prefered_height)); + return scrollPane; + } + + public static void main(String[] args) { + JFrame frame = new JFrame("Table"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(1200, 600); + Factura[] facturas = Factura.cargar_facturas(); + Cliente[] cliente = Cliente.cargar_clientes(); + // Table table = new Table(Querier.selectFacturas(cliente[15], facturas), cliente[15]); + Table table = new Table(facturas, cliente[15]); + frame.add(table.as_panel()); + frame.pack(); + frame.setVisible(true); + } +} diff --git a/src/main/java/com/utp/clsHerramientas/semestral/ui/UI.java b/src/main/java/com/utp/clsHerramientas/semestral/ui/UI.java new file mode 100644 index 0000000..e18172e --- /dev/null +++ b/src/main/java/com/utp/clsHerramientas/semestral/ui/UI.java @@ -0,0 +1,31 @@ +package com.utp.clsHerramientas.semestral.ui; + +import java.awt.Color; +import java.awt.Font; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +public final class UI { + public static final Color Black = Color.BLACK; + public static final Color DarkCyan = new Color(0, 102, 204); + public static final Color DarkGreen = new Color(0, 153, 76); + public static final Color Gray = new Color(192, 192, 192); + public static final Color Violet = new Color(153, 0, 153); + + public static class ProjFont { + public static final Font HEADER = new Font(Font.MONOSPACED, Font.BOLD, 14); + public static final Font NORMAL = new Font(Font.MONOSPACED, Font.PLAIN, 12); + } + + public static JFrame show(JPanel panel) { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + return frame; + } +}