4. TP 1: Gerenciamento básico de uma folha de pagamento
4.1. Introduction
Para aplicar o que foi visto anteriormente, propomos agora um trabalho que consiste em desenvolver um aplicativo Android para tablet, permitindo simular cálculos da folha de pagamento dos funcionários de uma associação.
O aplicativo terá uma arquitetura cliente/servidor:

- o servidor [1] já está disponível;
- é necessário desenvolver o cliente Android [2].
4.2. O banco de dados
4.2.1. Definição
Os dados estáticos necessários para gerar a folha de pagamento serão armazenados em um banco de dados que, doravante, designaremos como dbpam. Esse banco de dados possui as seguintes tabelas:
Estrutura:
chave primária | |
número de versão – aumenta a cada alteração na linha | |
número de previdência social do funcionário – único | |
nome do funcionário | |
nome próprio | |
seu endereço | |
sua cidade | |
seu CEP | |
chave estrangeira no campo [ID] da tabela [INDEMNITES] |
Seu conteúdo poderia ser o seguinte:

Estrutura:
chave primária | |
número de versão – aumenta a cada modificação da linha | |
porcentagem: contribuição social generalizada + contribuição para o pagamento da dívida social | |
porcentagem: contribuição social generalizada dedutível | |
porcentagem: previdência social, pensão de viuvez, aposentadoria | |
porcentagem: aposentadoria complementar + seguro-desemprego |
Seu conteúdo poderia ser o seguinte:
![]()
As alíquotas das contribuições sociais são independentes do empregado. A tabela anterior possui apenas uma linha.
chave primária | |
número da versão – aumenta a cada modificação da linha | |
índice de processamento – único | |
preço líquido em euros por hora de plantão | |
subsídio de manutenção em euros por dia de plantão | |
Subsídio de alimentação em euros por dia de plantão | |
Subsídio de férias remuneradas. Trata-se de uma porcentagem a ser aplicada ao salário-base. |
Seu conteúdo poderia ser o seguinte:

Observe-se que os subsídios podem variar de uma babá para outra. Na verdade, eles estão associados a uma babá específica por meio do índice salarial dela. Assim, a Sra. Marie Jouveinal, que possui um índice salarial de 2 (tabela EMPLOYES), tem um salário por hora de 2,1 euros (tabela INDEMNITES).
4.2.2. Geração
O script [dbpam_hibernate.sql] para geração do banco de dados é fornecido:
![]() |
Crie o banco de dados [dbpam_hibernate] (esse é o nome do BD que o servidor web / jSON utiliza) e certifique-se de que o login root, sem senha, tenha acesso a ela. Você pode proceder da seguinte forma:
Inicie o MySQL e, em seguida, o [PhpMyAdmin]:
![]() | ![]() |
- [1-2]: importe o script [dbpam_hibernate.sql] e, em seguida, execute-o;
4.2.3. Modelagem Java do banco de dados
Os elementos das tabelas [EMPLOYES], [INDEMNITES] e [COTISATIONS] são modelados pelas seguintes classes:
[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 e setters
....
}
- linhas 8-15: esses campos correspondem às colunas da tabela [EMPLOYES];
- linha 16: o campo [indemniteId] corresponde à coluna [INDEMNITE_ID], que é a chave estrangeira da tabela [EMPLOYES];
- linha 17: a indenização do funcionário. Esse campo nem sempre é preenchido:
- não é preenchido quando se solicita o URL [/employes],
- mas está preenchido quando se solicita o 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 e setters
....
}
- linhas 8-14: os campos correspondem às colunas da tabela [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 e setters
...
}
- linhas 8-13: os campos correspondem às colunas da tabela [COTISATIONS];
4.3. Instalação do servidor web / jSON
![]() |
4.3.1. Instalação
O binário Java do servidor web / jSON é fornecido a você:
![]() |
Para iniciar o servidor web / jSON, proceda da seguinte forma:
- execute o SGBD MySQL;
- verifique se o BD [dbpam_hibernate] existe;
- abra uma janela do DOS;
- navegue até a pasta do arquivo .jar;
- digite o comando:
Isso pressupõe que o binário [java.exe] esteja no diretório PATH do seu computador. Caso contrário, digite o caminho completo para o [java.exe], por exemplo:
Os registros são exibidos:
- linha 16: o URL [/salaire/{SS}/{ht}/{jt}] é detectado;
- linha 17: o URL [/employes] é detectado;
4.3.2. Os URL do serviço web/jSON
![]() |
O serviço web / jSON é implementado pelo Spring MVC e expõe dois 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) {
O serviço web aceita as duas seguintes URL:
- linha 1: /empregados: para obter a lista de funcionários;
- linha 4: /salário/SS/ht/jt: para obter a folha de pagamento do funcionário com o nº [SS] que trabalhou [ht] horas durante [jt] dias;
Aqui estão algumas capturas de tela que ilustram isso.
Solicita-se os funcionários:

Desligamos o banco de dados, reiniciamos o servidor e consultamos os funcionários:

Solicitamos um salário:

Solicita-se o salário de uma pessoa inexistente:

4.3.3. Respostas jSON do serviço web/jSON
![]() |
![]() |
Os URL do serviço web / jSON enviam respostas do tipo [Response<T>]:
package client.android.dao.service;
import java.util.List;
public class Response<T> {
// ----------------- propriedades
// status da operação
private int status;
// eventuais mensagens de status
private List<String> messages;
// o corpo da resposta
private T body;
// construtores
public Response() {
}
public Response(int status, List<String> messages, T body) {
this.status = status;
this.messages = messages;
this.body = body;
}
// getters e setters
...
}
- o URL e o [/employes] retornam um tipo Response<List<Empregado>>;
- o URL e o [/salaire] retornam um tipo Response<FeuilleSalaire>;
A classe [FeuilleSalaire] é a seguinte:
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;
// construtores
public FeuilleSalaire() {
}
public FeuilleSalaire(Employe employe, Cotisation cotisation, ElementsSalaire elementsSalaire) {
...
}
// getters e setters
...
}
- linha 9: a classe [Employe] foi apresentada no parágrafo 4.2.3;
- linha 10: a classe [Cotisation] foi apresentada no parágrafo 4.2.3;
A classe [ElementsSalaire] (linha 11) é a seguinte:
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;
// construtores
public ElementsSalaire() {
}
public ElementsSalaire(double salaireBase, double cotisationsSociales, double indemnitesEntretien, double indemnitesRepas, double salaireNet) {
...
}
// getters e setters
...
}
4.4. Testes do cliente Android
![]() |
O binário executável do cliente Android finalizado é fornecido a você:
![]() |
Com o mouse, arraste o arquivo binário [pam-client.apk] acima para um emulador de tablet [GenyMotion]. Ele será então salvo e executado. Inicie também o servidor web / jSON, caso ainda não tenha feito isso. O cliente Android tem como objetivo recuperar as informações enviadas pelo servidor web / jSON e formatá-las. As diferentes telas do cliente Android são as seguintes:
Primeiro, é necessário conectar-se ao serviço web / jSON:

- em [1], fornece-se o URL do serviço web / jSON. Com o emulador, insira um dos endereços IP ou PC (mas não 127.0.0.1). Em um tablet, insira o endereço Wi-Fi do servidor web / jSON e desative o firewall do servidor, caso haja um, pois ele pode bloquear as conexões de entrada;
- no [2], faça o login;
Chega-se então à página de simulação:

- em [3], selecione um funcionário;
- em [4], insira o número de horas;
- em [5], indique o número de dias;
- em [6], solicita-se a simulação;
A página de simulação exibida é a seguinte:

- em [7], a simulação obtida;
- em [8], ela é salva;

- em [9], a lista de simulações;
- em [10], remove-se uma simulação;

- em [11], não há mais simulações;
- em [12], retorna-se ao formulário de simulação;

- em [13], voltamos ao formulário;
- em [14], retorna-se à página de configuração;

- em [15], voltamos ao formulário de login inicial.
4.5. Tarefa a ser realizada
A estrutura do cliente Android apresentada anteriormente já está à sua disposição. Ela foi criada a partir do projeto [client-android-skel] descrito no parágrafo 2.
![]() |
O projeto é executável e já possui as visualizações necessárias. Basta adicionar código para que o aplicativo execute as tarefas necessárias. O procedimento a ser seguido é o seguinte:
- execute a versão completa para compreender o trabalho a ser feito;
- execute a versão simplificada e analise o código dela. Ele segue os métodos de projeto utilizados nas páginas anteriores;
- adicione o código que falta;










