4. Compito 1: Gestione di base delle buste paga
4.1. Introduzione
Per mettere in pratica quanto visto in precedenza, proponiamo ora un compito che prevede lo sviluppo di un client Android per tablet, progettato per simulare i calcoli delle buste paga per i dipendenti di un'associazione.
L'applicazione avrà un'architettura client/server:

- il server [1] è già disponibile;
- è necessario compilare il client Android [2].
4.2. Il database
4.2.1. Definizione
I dati statici necessari per generare la busta paga saranno memorizzati in un database che d'ora in poi chiameremo dbpam. Questo database contiene le seguenti tabelle:
Struttura:
chiave primaria | |
numero di versione – aumenta ad ogni modifica della riga | |
Numero di previdenza sociale del dipendente – univoco | |
Cognome del dipendente | |
nome | |
il loro indirizzo | |
la sua città | |
il suo codice postale | |
Chiave esterna sul campo [ID] della tabella [INDEMNITES] |
Il suo contenuto potrebbe essere il seguente:

Struttura:
chiave primaria | |
numero di versione – aumenta ad ogni modifica della riga | |
Percentuale: Contributo sociale generale + Contributo al rimborso del debito sociale | |
percentuale: contributo sociale generale deducibile | |
percentuale: previdenza sociale, vedovanza, vecchiaia | |
percentuale: pensione integrativa + assicurazione contro la disoccupazione |
Il contenuto potrebbe essere il seguente:
![]()
Le aliquote dei contributi previdenziali sono indipendenti dal dipendente. La tabella precedente ha una sola riga.
chiave primaria | |
numero di versione – aumenta ad ogni modifica della riga | |
Indice di elaborazione – univoco | |
Prezzo netto in euro per un'ora di reperibilità | |
indennità giornaliera in euro per ogni giorno di assistenza | |
Indennità pasti in euro per giorno di assistenza | |
Indennità per ferie pagate. Si tratta di una percentuale applicata allo stipendio base. |
Il suo contenuto potrebbe essere il seguente:

Si noti che le indennità possono variare da un operatore dell'assistenza all'infanzia all'altro. Esse sono collegate a uno specifico operatore dell'assistenza all'infanzia tramite la sua categoria retributiva. Ad esempio, la sig.ra Marie Jouveinal, che ha una categoria retributiva 2 (tabella EMPLOYEES), ha una retribuzione oraria di 2,1 euro (tabella INDEMNITES).
4.2.2. Generazione
Viene fornito lo script di generazione del database [dbpam_hibernate.sql]:
![]() |
Crea il database [dbpam_hibernate] (questo è il nome del database utilizzato dal server web/jSON) e assicurati che l'account root (senza password) possa accedervi. Puoi farlo come segue:
Avviare MySQL, quindi [PhpMyAdmin]:
![]() | ![]() |
- [1-2]: Importa lo script [dbpam_hibernate.sql] e poi eseguilo;
4.2.3. Modellazione Java del database
Gli elementi delle tabelle [EMPLOYEES], [ALLOWANCES] e [CONTRIBUTIONS] sono modellati dalle seguenti classi:
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 and setters
....
}
- righe 8–15: questi campi corrispondono alle colonne della tabella [EMPLOYEES];
- riga 16: il campo [indemniteId] corrisponde alla colonna [INDEMNITE_ID], che è la chiave esterna della tabella [EMPLOYEES];
- riga 17: l'indennità del dipendente. Questo campo non è sempre compilato:
- non viene compilato quando si richiede l'URL [/employees],
- lo è quando si richiede l'URL [/salary];
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 and setters
....
}
- righe 8-14: i campi corrispondono alle colonne della tabella [INDEMNITES];
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 and setters
...
}
- righe 8-13: i campi corrispondono alle colonne della tabella [COTISATIONS];
4.3. Installazione del server web / JSON
![]() |
4.3.1. Installazione
Viene fornito il binario Java per il server web/JSON:
![]() |
Per avviare il server web/JSON, procedere come segue:
- Avvia il DBMS MySQL;
- assicurarsi che il database [dbpam_hibernate] esista;
- Aprire una finestra del prompt dei comandi;
- Accedere alla cartella jar;
- digitare il comando:
Questo presuppone che l'eseguibile [java.exe] si trovi nel PATH del tuo computer. Se così non fosse, digita il percorso completo di [java.exe], ad esempio:
Vengono visualizzati i log:
- riga 16: l'URL [/salary/{SS}/{ht}/{jt}] è stato risolto;
- riga 17: l'URL [/employees] è stato individuato;
4.3.2. URL dei servizi web/JSON
![]() |
Il servizio web / JSON è implementato da Spring MVC ed espone due 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) {
Il servizio web accetta i seguenti due URL:
- riga 1: /employees: per recuperare l'elenco dei dipendenti;
- Riga 4: /salary/SS/ht/jt: per recuperare la busta paga del dipendente n. [SS] che ha lavorato [ht] ore in [jt] giorni;
Ecco alcuni screenshot che illustrano la situazione.
Interroghiamo i dipendenti:

Eseguiamo il backup del database, riavviamo il server ed eseguiamo la query sui dipendenti:

Interroghiamo uno stipendio:

Richiediamo lo stipendio di una persona inesistente:

4.3.3. Le risposte JSON dal servizio web/JSON
![]() |
![]() |
Gli URL del servizio web/jSON restituiscono risposte di 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;
// the body of the reply
private T body;
// manufacturers
public Response() {
}
public Response(int status, List<String> messages, T body) {
this.status = status;
this.messages = messages;
this.body = body;
}
// getters and setters
...
}
- L'URL [/employees] restituisce un Response<List<Employee>>;
- L'URL [/salary] restituisce un tipo Response<PayStub>;
La classe [PayrollSheet] è la seguente:
package pam.entities;
import java.io.Serializable;
public class FeuilleSalaire implements Serializable {
private static final long serialVersionUID = 1L;
// private fields
private Employe employe;
private Cotisation cotisation;
private ElementsSalaire elementsSalaire;
// manufacturers
public FeuilleSalaire() {
}
public FeuilleSalaire(Employe employe, Cotisation cotisation, ElementsSalaire elementsSalaire) {
...
}
// getters and setters
...
}
- riga 9: la classe [Employee] è stata introdotta nella sezione 4.2.3;
- riga 10: la classe [Contribution] è stata introdotta nella sezione 4.2.3;
La classe [SalaryElements] (riga 11) è la seguente:
package pam.entities;
import java.io.Serializable;
public class ElementsSalaire implements Serializable {
private static final long serialVersionUID = 1L;
// private fields
private double salaireBase;
private double cotisationsSociales;
private double indemnitesEntretien;
private double indemnitesRepas;
private double salaireNet;
// manufacturers
public ElementsSalaire() {
}
public ElementsSalaire(double salaireBase, double cotisationsSociales, double indemnitesEntretien, double indemnitesRepas, double salaireNet) {
...
}
// getters and setters
...
}
4.4. Test del client Android
![]() |
Di seguito è riportato il file binario eseguibile del client Android completato:
![]() |
Usa il mouse per trascinare il file [pam-client.apk] qui sopra su un emulatore di tablet [GenyMotion]. Verrà quindi salvato ed eseguito. Avvia anche il server web/JSON se non l'hai già fatto. Lo scopo del client Android è recuperare le informazioni restituite dal server web/JSON e formattarle. Le diverse schermate del client Android sono le seguenti:
Per prima cosa, devi collegarti al servizio web / JSON:

- in [1], inserisci l'URL del servizio web/JSON. Con l'emulatore, inserisci uno degli indirizzi IP del PC (ma non 127.0.0.1). Con un tablet, inserisci l'indirizzo Wi-Fi del computer che ospita il server web/JSON e disattiva il firewall del server, se presente, poiché potrebbe bloccare le chiamate in entrata;
- In [2], effettuare l'accesso;
Verrai quindi reindirizzato alla pagina di simulazione:

- In [3], seleziona un dipendente;
- In [4], inserisci un numero di ore;
- In [5], inserisci il numero di giorni;
- In [6], avvia la simulazione;
La pagina della simulazione risultante è la seguente:

- in [7], i risultati della simulazione;
- in [8], salvalo;

- in [9], l'elenco delle simulazioni;
- in [10], una simulazione viene eliminata;

- in [11], non ci sono più simulazioni;
- In [12], si ritorna al modulo di simulazione;

- in [13], si torna al modulo;
- in [14], si torna alla pagina di configurazione;

- in [15], si torna al modulo di accesso iniziale.
4.5. Lavoro da svolgere
Lo scheletro del client Android presentato in precedenza è a vostra disposizione. È stato creato a partire dal progetto [client-android-skel] descritto nella Sezione 2.
![]() |
Il progetto è eseguibile e contiene già le viste necessarie. Devi semplicemente aggiungere il codice affinché l'applicazione funzioni come previsto. La procedura è la seguente:
- eseguire la versione completa per comprendere il lavoro da svolgere;
- eseguire la versione leggera e studiarne il codice. Segue i metodi di progettazione utilizzati nelle pagine precedenti;
- aggiungere il codice mancante;










