4. Tarea 1: Gestión básica de nóminas
4.1. Introducción
Para aplicar lo que hemos tratado anteriormente, proponemos ahora un encargo consistente en el desarrollo de un cliente Android para tabletas, diseñado para simular el cálculo de las nóminas de los empleados de una asociación.
La aplicación tendrá una arquitectura cliente/servidor:

- el servidor [1];
- debes construir el cliente Android [2].
4.2. La base de datos
4.2.1. Definición
Los datos estáticos necesarios para construir el recibo de salarios se almacenarán en una base de datos a la que nos referiremos en adelante como dbpam. Esta base de datos contiene las siguientes tablas:
Estructura:
clave primaria | |
número de versión - aumenta con cada modificación de la fila | |
Número de la Seguridad Social del empleado - único | |
Apellido del empleado | |
nombre de pila | |
su dirección | |
su ciudad | |
su ZIP código | |
Clave foránea en el campo [ID] de la tabla [INDEMNITES] |
Su contenido podría ser el siguiente:

Estructura:
clave primaria | |
número de versión - aumenta con cada modificación de la fila | |
Porcentaje: Contribución social general + Contribución al reembolso de la deuda social | |
porcentaje: cotización social general deducible | |
porcentaje: seguridad social, viudedad, vejez | |
porcentaje: pensión complementaria + seguro de desempleo |
Su contenido podría ser el siguiente:

Los tipos de cotización a la Seguridad Social son independientes del trabajador. La tabla anterior sólo tiene una fila.
clave primaria | |
número de versión - aumenta con cada modificación de la fila | |
Índice de tratamiento - único | |
Precio neto en euros por una hora de guardia | |
indemnización diaria en euros por día de asistencia | |
Subsidio de comida en euros por día de asistencia | |
Indemnización por vacaciones pagadas. Se trata de un porcentaje aplicado al salario base. |
Su contenido podría ser el siguiente:

Tenga en cuenta que los complementos pueden variar de un cuidador a otro. Están vinculadas a un cuidador concreto a través de su categoría salarial. Por ejemplo, la Sra. Marie Jouveinal, que tiene un grado salarial 2 (tabla EMPLOYEES), tiene un salario por hora de 2,1 euros (tabla INDEMNITES).
4.2.2. Generación
Se proporciona el script de generación de la base de datos [dbpam_hibernate.sql]:
![]() |
Cree la base de datos [dbpam_hibernate] (este es el nombre de la base de datos utilizada por el servidor web/jSON) y asegúrese de que el archivo raíz (sin contraseña) puede acceder a ella. Puede hacerlo de la siguiente manera:
Inicie MySQL, luego [PhpMyAdmin]:
![]() | ![]() |
- [1-2]: Importa el script [dbpam_hibernate.sql] y ejecútalo;
4.2.3. Modelado Java de la base de datos
Los elementos de las tablas [EMPLOYEES], [ALLOWANCES] y [CONTRIBUTIONS] se modelan mediante las siguientes clases:
package pam.entities;
import java.io.Serializable;
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private int version;
private String SS;
private String lastName;
private String firstName;
private String address;
private String city;
private String zipCode;
private int allowanceID;
private Indemnity indemnity;
public Employee() {
}
public Employee(String lastName, String firstName, String middleName, String address, String city, String zipCode, Indemnity indemnity) {
...
}
// getters and setters
....
}
- líneas 8-15: estos campos corresponden a las columnas de la tabla [EMPLOYEES];
- línea 16: el campo [indemniteId] corresponde a la columna [INDEMNITE_ID], que es la clave externa de la tabla [EMPLOYEES];
- línea 17: indemnización del empleado. Este campo no siempre se rellena:
- no se rellena al solicitar el URL [/empleados],
- es al solicitar el URL [/salario];
package pam.entities;
import java.io.Serializable;
public class Indemnite implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private int version;
private int index;
private double baseTime;
private double room, daily cleaning;
private double meal per day;
private double severancePay;
public Indemnity() {
}
public Allowance(int index, double baseHour, double dailyMaintenance, double dailyMeal, double CPAllowance) {
...
}
// getters and setters
....
}
- líneas 8-14: los campos corresponden a las columnas de la tabla [INDEMNITES];
package pam.entities;
import java.io.Serializable;
public class Contribution implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private int version;
private double csgrds;
private double csgd;
private double socialsecurity;
private double pension;
public Contribution() {
}
public Contribution(double csgrds, double csgd, double secu, double retirement) {
...
}
// getters and setters
...
}
- líneas 8-13: los campos corresponden a las columnas de la tabla [COTISATIONS];
4.3. Servidor web / JSON instalación
![]() |
4.3.1. Instalación
Se proporciona el binario Java para el servidor web/jSON:
![]() |
Para iniciar el servidor web/JSON, proceda del siguiente modo:
- Inicie el MySQL DBMS;
- asegúrese de que la base de datos [dbpam_hibernate] existe;
- Abra una ventana de símbolo del sistema;
- Vaya a la carpeta jar;
- teclea el comando:
Esto supone que el ejecutable [java.exe] está en el PATH de su máquina. Si no es así, escriba la ruta completa a [java.exe], por ejemplo:
Se muestran los registros:
- línea 16: el URL [/salary/{SS}/{ht}/{jt}] está resuelto;
- línea 17: el URL [/empleados];
4.3.2. Servicio web/JSON URLs
![]() |
El servicio web / JSON está implementado por Spring MVC y expone dos URLs:
@RequestMapping(value = "/employees", method = RequestMethod.GET, content-type = "application/json; charset=UTF-8")
public EmployeesResponse getEmployees() {
...
@RequestMapping(value = "/salary/{SS}/{ht}/{jt}", method = RequestMethod.GET, response-type = "application/json; charset=UTF-8")
public PaystubResponse getPaystub(@PathVariable("SS") String SS, @PathVariable("ht") double ht, @PathVariable("jt") int jt) {
El servicio web acepta los dos URLs siguientes:
- línea 1: /empleados: para recuperar la lista de empleados;
- Línea 4: /salario/SS/ht/jt: para recuperar el recibo de sueldo del empleado #[SS] que trabajó [ht] horas durante [jt] días;
Aquí tienes algunas capturas de pantalla que lo ilustran.
Preguntamos a los empleados:

Hacemos una copia de seguridad de la base de datos, reiniciamos el servidor y consultamos a los empleados:

Consultamos un salario:

Solicitamos el salario de una persona inexistente:

4.3.3. Las respuestas JSON del servicio web/JSON
![]() |
![]() |
El servicio web/jSON URLs devuelve respuestas de tipo [Response<T>]:
package client.android.dao.service;
import java.util.List;
public class Response<T> {
// ----------------- properties
// operation status
private int status;
// any status messages
private List<String> messages;
// response body
private T body;
// constructors
public Response() {
}
public Response(int status, List<String> messages, T body) {
this.status = status;
this.messages = messages;
this.body = body;
}
// getters and setters
...
}
- El URL [/empleados] devuelve un Respuesta<Lista<Empleado>>;
- El URL [/salario] devuelve un Respuesta<PayStub> tipo;
La clase [PayrollSheet] es la siguiente:
package pam.entities;
import java.io.Serializable;
public class Payroll implements Serializable {
private static final long serialVersionUID = 1L;
// private fields
private Employee employee;
private Contribution contribution;
private PayrollElements payrollElements;
// constructors
public Payroll() {
}
public Payroll(Employee employee, Contribution contribution, SalaryElements salaryElements) {
...
}
// getters and setters
...
}
- línea 9: la clase [Empleado] se introdujo en la sección 4.2.3;
- línea 10: la clase [Contribution] se introdujo en la sección 4.2.3;
La clase [SalaryElements] (línea 11) es la siguiente:
package pam.entities;
import java.io.Serializable;
public class SalaryElements implements Serializable {
private static final long serialVersionUID = 1L;
// private fields
private double baseSalary;
private double socialSecurityContributions;
private double maintenanceAllowance;
private double mealAllowance;
private double netSalary;
// constructors
public ElementsSalary() {
}
public ElementsSalary(double baseSalary, double socialContributions, double maintenanceAllowance, double mealAllowance, double netSalary) {
...
}
// getters and setters
...
}
4.4. Pruebas de clientes Android
![]() |
A continuación se proporciona el binario ejecutable para el cliente Android terminado:
![]() |
Utilice el ratón para arrastrar el archivo [pam-client.apk] anterior a un emulador de tableta [GenyMotion]. A continuación, se guardará y se ejecutará. Inicia también el servidor web/JSON si aún no lo has hecho. El propósito del cliente Android es recuperar la información devuelta por el servidor web/JSON y formatearla. Las diferentes vistas del cliente Android son las siguientes:
En primer lugar, debe conectarse al servicio web / JSON:

- en [1], introduzca el URL del servicio web/JSON. Con el emulador, introduzca una de las direcciones PC del IP (pero no 127.0.0.1). Con una tableta, introduce la dirección Wi-Fi del equipo servidor web/JSON y desactiva el cortafuegos del servidor si lo tiene, ya que puede bloquear las llamadas entrantes;
- En [2], inicia sesión;
A continuación, accederá a la página de la simulación:

- En [3], seleccione un empleado;
- En [4], introduzca un número de horas;
- En [5], introduzca el número de días;
- En [6], ejecuta la simulación;
La página de simulación resultante es la siguiente:

- en [7], los resultados de la simulación;
- en [8], guárdelo;

- en [9], la lista de simulaciones;
- en [10], se suprime una simulación;

- en [11], no hay más simulaciones;
- En [12], se vuelve al formulario de simulación;

- en [13], se vuelve a la forma;
- en [14], se vuelve a la página de configuración;

- en [15], se vuelve al formulario de acceso inicial.
4.5. Trabajo por hacer
Te proporcionamos el esqueleto de cliente Android presentado anteriormente. Se construyó a partir del proyecto [client-android-skel] descrito en la Sección 2.
![]() |
El proyecto es ejecutable y ya contiene las vistas necesarias. Simplemente hay que añadir código para que la aplicación haga lo que se supone que debe hacer. El procedimiento es el siguiente:
- ejecute la versión completa para comprender el trabajo que hay que hacer;
- ejecute la versión ligera y estudie su código. Sigue los métodos de diseño utilizados en las páginas anteriores;
- añade el código que falta;










