4. TP 1: Administración básica de una nómina
4.1. Introduction
Para poner en práctica lo visto anteriormente, proponemos ahora un ejercicio que consiste en desarrollar una aplicación cliente para tabletas Android, que permita simular los cálculos de las nóminas de los empleados de una asociación.
La aplicación tendrá una arquitectura cliente/servidor:

- El servidor [1] ya está disponible;
- hay que desarrollar el cliente de Android [2].
4.2. La base de datos
4.2.1. Definición
Los datos estáticos necesarios para generar la nómina se almacenarán en una base de datos a la que en adelante nos referiremos c e dbpam. Esta base de datos cuenta con las siguientes tablas:
Estructura:
clave primaria | |
N.º de versión: aumenta con cada modificación de la fila | |
número de seguro social del empleado – único | |
nombre del empleado | |
su nombre | |
su dirección | |
su ciudad | |
su código postal | |
clave externa en el campo [ID] de la tabla [INDEMNITES] |
Su contenido podría ser el siguiente:

Estructura:
clave primaria | |
N.º de versión: aumenta con cada modificación de la línea | |
porcentaje: contribución social generalizada + contribución al pago de la deuda social | |
porcentaje: contribución social generalizada deducible | |
porcentaje: seguridad social, viudedad, vejez | |
porcentaje: pensión complementaria + seguro de desempleo |
Su contenido podría ser el siguiente:
![]()
Las tasas de las cotizaciones sociales son independientes del empleado. La tabla anterior solo tiene una fila.
clave primaria | |
N.º de versión: aumenta con cada modificación de la línea | |
índice de procesamiento: único | |
precio neto en euros por una hora de guardia | |
indemnización de manutención en euros por día de custodia | |
indemnización por comida en euros por día de cuidado | |
Indemnización por vacaciones pagadas. Es un porcentaje que se aplica al salario base. |
Su contenido podría ser el siguiente:

Cabe señalar que las indemnizaciones pueden variar de una cuidadora a otra. De hecho, están vinculadas a una cuidadora específica a través de su índice salarial. Así, la Sra. Marie Jouveinal, que tiene un índice salarial de 2 (tabla EMPLOYES), tiene un salario por hora de 2,1 euros (tabla INDEMNITES).
4.2.2. Generación
Se proporciona el script [dbpam_hibernate.sql] para la generación de la base de datos:
![]() |
Crea la base de datos [dbpam_hibernate] (este es el nombre de la base de datos BD que utiliza el servidor web / jSON) y asegúrese de que el usuario root, sin contraseña, pueda acceder a ella. Puede hacerlo de la siguiente manera:
Inicie MySQL y luego [PhpMyAdmin]:
![]() | ![]() |
- [1-2]: importa el script [dbpam_hibernate.sql] y luego ejecútalo;
4.2.3. Modelado Java de la base de datos
Los elementos de las tablas [EMPLOYES], [INDEMNITES] y [COTISATIONS] se modelan mediante las siguientes clases:
[Employe]
package pam.entities;
import java.io.Serializable;
public class Employe implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private int version;
private String SS;
private String nom;
private String prenom;
private String adresse;
private String ville;
private String codePostal;
private int idIndemnite;
private Indemnite indemnite;
public Employe() {
}
public Employe(String SS, String nom, String prenom, String adresse, String ville, String codePostal, Indemnite indemnite) {
...
}
// getters y setters
....
}
- líneas 8-15: estos campos corresponden a las columnas de la tabla [EMPLOYES];
- línea 16: el campo [indemniteId] corresponde a la columna [INDEMNITE_ID], que es la clave externa de la tabla [EMPLOYES];
- línea 17: la indemnización del empleado. Este campo no siempre está completado:
- no lo está cuando se solicita el URL [/employes],
- sí lo está cuando se solicita el URL [/salaire];
[Indemnite]
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 indice;
private double baseHeure;
private double entretienJour;
private double repasJour;
private double indemnitesCp;
public Indemnite() {
}
public Indemnite(int indice, double baseHeure, double entretienJour, double repasJour, double indemnitesCP) {
...
}
// getters y setters
....
}
- líneas 8-14: los campos corresponden a las columnas de la tabla [INDEMNITES];
[Cotisation]
package pam.entities;
import java.io.Serializable;
public class Cotisation implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private int version;
private double csgrds;
private double csgd;
private double secu;
private double retraite;
public Cotisation() {
}
public Cotisation(double csgrds, double csgd, double secu, double retraite) {
...
}
// getters y setters
...
}
- líneas 8-13: los campos corresponden a las columnas de la tabla [COTISATIONS];
4.3. Instalación del servidor web / jSON
![]() |
4.3.1. Instalación
Se le proporciona el binario Java del servidor web / jSON:
![]() |
Para iniciar el servidor web / jSON, siga estos pasos:
- ejecute el SGBD MySQL;
- asegúrese de que existan BD y [dbpam_hibernate];
- abre una ventana DOS;
- navega hasta la carpeta del archivo .jar;
- escriba el comando:
Esto supone que el binario [java.exe] se encuentra en el directorio PATH de tu equipo. Si no es así, escribe la ruta completa de [java.exe], por ejemplo:
Aparecerán los registros:
- línea 16: se detecta el archivo URL [/salaire/{SS}/{ht}/{jt}];
- línea 17: se detecta el URL [/employes];
4.3.2. Los URL del servicio web/jSON
![]() |
El servicio web / jSON está implementado por Spring MVC y expone dos URL:
@RequestMapping(value = "/employes", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
public EmployesResponse getEmployes() {
...
@RequestMapping(value = "/salaire/{SS}/{ht}/{jt}", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
public FeuilleSalaireResponse getFeuilleSalaire(@PathVariable("SS") String SS, @PathVariable("ht") double ht, @PathVariable("jt") int jt) {
El servicio web acepta las siguientes dos URL:
- línea 1: /empleados: para obtener la lista de empleados;
- línea 4: /salario/SS/ht/jt: para obtener la nómina del empleado con el n.º [SS] que trabajó [ht] horas durante [jt] días;
Aquí hay algunas capturas de pantalla que lo muestran.
Se solicitan los empleados:

Se desconecta la base de datos, se reinicia el servidor y se consultan los empleados:

Se consulta un salario:

Se solicita el salario de una persona que no existe:

4.3.3. Las respuestas jSON del servicio web/jSON
![]() |
![]() |
Los URL del servicio web / jSON envían respuestas del tipo [Response<T>]:
package client.android.dao.service;
import java.util.List;
public class Response<T> {
// ----------------- propiedades
// estado de la operación
private int status;
// posibles mensajes de estado
private List<String> messages;
// el cuerpo de la respuesta
private T body;
// constructores
public Response() {
}
public Response(int status, List<String> messages, T body) {
this.status = status;
this.messages = messages;
this.body = body;
}
// getters y setters
...
}
- el URL [/employes] devuelve un tipo Response<List<Empleado>>;
- URL y [/salaire] devuelven un tipo Response<FeuilleSalaire>;
La clase [FeuilleSalaire] es la siguiente:
package pam.entities;
import java.io.Serializable;
public class FeuilleSalaire implements Serializable {
private static final long serialVersionUID = 1L;
// campos privados
private Employe employe;
private Cotisation cotisation;
private ElementsSalaire elementsSalaire;
// constructores
public FeuilleSalaire() {
}
public FeuilleSalaire(Employe employe, Cotisation cotisation, ElementsSalaire elementsSalaire) {
...
}
// getters y setters
...
}
- línea 9: la clase [Employe] se presentó en el párrafo 4.2.3;
- línea 10: la clase [Cotisation] se presentó en el párrafo 4.2.3;
La clase [ElementsSalaire] (línea 11) es la siguiente:
package pam.entities;
import java.io.Serializable;
public class ElementsSalaire implements Serializable {
private static final long serialVersionUID = 1L;
// campos privados
private double salaireBase;
private double cotisationsSociales;
private double indemnitesEntretien;
private double indemnitesRepas;
private double salaireNet;
// constructores
public ElementsSalaire() {
}
public ElementsSalaire(double salaireBase, double cotisationsSociales, double indemnitesEntretien, double indemnitesRepas, double salaireNet) {
...
}
// getters y setters
...
}
4.4. Pruebas del cliente de Android
![]() |
Se te proporciona el binario ejecutable del cliente de Android ya terminado:
![]() |
Con el ratón, arrastre el archivo binario [pam-client.apk] que aparece arriba y suéltelo en un emulador de tableta [GenyMotion]. Se guardará y luego se ejecutará. Inicie también el servidor web / jSON si aún no lo ha hecho. El cliente de Android tiene como objetivo recuperar la información enviada por el servidor web / jSON y darle formato. Las diferentes vistas del cliente de Android son las siguientes:
En primer lugar, hay que conectarse al servicio web / jSON:

- en [1], se proporciona el URL del servicio web / jSON. Con el emulador, ingresa una de las direcciones IP o PC (pero no 127.0.0.1). Con una tableta, ingresa la dirección Wi-Fi de la máquina del servidor web / jSON y desactiva el firewall del servidor, si lo tiene, ya que podría bloquear las llamadas entrantes;
- en [2], nos conectamos;
A continuación, se llega a la página de simulación:

- en [3], se selecciona un empleado;
- en [4], se indica un número de horas;
- en [5], se indica un número de días;
- en [6], se solicita la simulación;
La página de simulación que se obtiene es la siguiente:

- en [7], la simulación obtenida;
- en [8], se guarda;

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

- en [11], ya no hay simulaciones;
- en [12], se regresa al formulario de simulación;

- en [13], se vuelve a mostrar el formulario;
- en [14], se regresa a la página de configuración;

- en [15], se vuelve al formulario de inicio de sesión inicial.
4.5. Tarea a realizar
Se te proporciona el esqueleto del cliente para Android presentado anteriormente. Se ha creado a partir del proyecto [client-android-skel] descrito en el párrafo 2.
![]() |
El proyecto es ejecutable y ya cuenta con las vistas necesarias. Solo hay que agregar código para que la aplicación haga lo que debe hacer. El procedimiento a seguir es el siguiente:
- ejecuta la versión completa para comprender el trabajo que hay que hacer;
- ejecute la versión simplificada y estudie su código. Este respeta los métodos de diseño utilizados en las páginas anteriores;
- agregue el código que falta;










