4. TP 1: Maaş bordrosunun temel yönetimi
4.1. Introduction
Daha önce görülenleri uygulamak için, şimdi bir derneğin çalışanlarının maaş bordro hesaplamalarını simüle etmeyi sağlayan bir tablet Android istemcisi yazma ödevini öneriyoruz.
Uygulama, istemci/sunucu mimarisine sahip olacaktır:

- [1] sunucusu sağlanmıştır;
- Android istemcisi [2]'i oluşturmanız gerekmektedir.
4.2. Veritabanı
4.2.1. Tanım
Maaş bordrosunu oluşturmak için gerekli statik veriler, bundan sonra dbpam olarak adlandıracağımız bir veritabanına yerleştirilecektir. Bu veritabanında aşağıdaki tablolar bulunmaktadır:
Yapı:
birincil anahtar | |
sürüm numarası – satır her değiştirildiğinde artar | |
çalışanın sosyal güvenlik numarası – benzersiz | |
çalışanın adı | |
ad | |
adresi | |
şehri | |
posta kodu | |
[INDEMNITES] tablosundaki [ID] alanında bulunan yabancı anahtar |
İçeriği şu şekilde olabilir:

Yapı:
birincil anahtar | |
sürüm numarası – satır her değiştirildiğinde artar | |
yüzde: genel sosyal katkı payı + sosyal borç geri ödemesine katkı payı | |
yüzde: indirilebilir genel sosyal katkı payı | |
yüzde: sosyal güvenlik, dul ve yaşlılık | |
yüzde: ek emeklilik + işsizlik sigortası |
İçeriği şu şekilde olabilir:
![]()
Sosyal güvenlik prim oranları çalışandan bağımsızdır. Yukarıdaki tablo sadece bir satırdan oluşur.
birincil anahtar | |
sürüm numarası – satır her değiştirildiğinde artar | |
işlem numarası – benzersiz | |
bir saatlik nöbetin net fiyatı (Euro) | |
bakım günü başına euro cinsinden bakım ücreti | |
bakım hizmeti verilen her gün için euro cinsinden yemek ödeneği | |
Ücretli izin ödeneği. Bu, temel maaşa uygulanacak bir yüzde oranıdır. |
İçeriği şu şekilde olabilir:

Ödeneklerin çocuk bakıcısından bakıcıya farklılık gösterebileceği unutulmamalıdır. Bu ödenekler, çocuk bakıcısının maaş endeksi aracılığıyla o bakıcıya özel olarak belirlenir. Örneğin, maaş endeksi 2 olan Bayan Marie Jouveinal’ın (EMPLOYES tablosu) saatlik ücreti 2,1 avrodur (INDEMNITES tablosu).
4.2.2. Oluşturma
Veritabanını oluşturmak için [dbpam_hibernate.sql] komut dosyası sağlanmıştır:
![]() |
[dbpam_hibernate] veritabanını oluşturun (bu, web sunucusunun / jSON'in kullandığı BD'in adıdır) ve şifresiz root kullanıcı adının bu veritabanına erişebilmesini sağlayın. Bunun için şu adımları uygulayabilirsiniz:
MySQL'i ve ardından [PhpMyAdmin]'i başlatın:
![]() | ![]() |
- [1-2]: [dbpam_hibernate.sql] komut dosyasını içe aktarın ve çalıştırın;
4.2.3. Veritabanının Java ile modellenmesi
[EMPLOYES], [INDEMNITES] ve [COTISATIONS] tablolarındaki öğeler aşağıdaki sınıflarla modellenmiştir:
[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) {
...
}
// getter ve setter'lar
....
}
- 8-15. satırlar: bu alanlar, [EMPLOYES] tablosunun sütunlarına karşılık gelir;
- 16. satır: [indemniteId] alanı, [INDEMNITE_ID] sütununa karşılık gelir; bu sütun, [EMPLOYES] tablosunun yabancı anahtarıdır;
- 17. satır: çalışanın tazminatı. Bu alan her zaman doldurulmaz:
- URL [/employes] talep edildiğinde doldurulmaz,
- URL ve [/salaire] talep edildiğinde doldurulur;
[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) {
...
}
// getter ve setter'lar
....
}
- 8-14. satırlar: alanlar, [INDEMNITES] tablosunun sütunlarına karşılık gelir;
[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) {
...
}
// getter ve setter'lar
...
}
- satır 8-13: alanlar, [COTISATIONS] tablosundaki sütunlara karşılık gelir;
4.3. Web sunucusunun kurulumu / jSON
![]() |
4.3.1. Kurulum
Web sunucusunun Java ikili dosyası / jSON size sağlanmıştır:
![]() |
Web sunucusunu / jSON başlatmak için aşağıdaki adımları izleyin:
- SGBD MySQL dosyasını çalıştırın;
- BD ve [dbpam_hibernate] dosyalarının mevcut olduğundan emin olun;
- bir DOS penceresi açın;
- jar dosyasının bulunduğu klasöre gidin;
- şu komutu yazın:
Bu, [java.exe] ikili dosyasının bilgisayarınızdaki PATH klasöründe olduğunu varsayar. Aksi takdirde, [java.exe] dosyasının tam yolunu yazın, örneğin:
Günlükler görüntülenir:
- 16. satır: URL [/salaire/{SS}/{ht}/{jt}] bulundu;
- 17. satır: URL ve [/employes] tespit edildi;
4.3.2. Web hizmeti/jSON'in URL'i
![]() |
Web hizmeti / jSON, Spring MVC tarafından uygulanır ve iki URL sunar:
@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) {
Web hizmeti aşağıdaki iki URL'i kabul eder:
- 1. satır: /employes: çalışan listesini almak için;
- 4. satır: /maaş/SS/ht/jt: [SS] numaralı çalışanın, [ht] saat boyunca [jt] gün çalışmış olduğu maaş bordrosunu almak için;
Bunu gösteren ekran görüntüleri aşağıdadır.
Çalışanlardan istenen bilgiler:

Veritabanını kapatıp sunucuyu yeniden başlattıktan sonra çalışanları sorguladığımızda:

Maaş sorgulanıyor:

Var olmayan bir kişinin maaşını soruyoruz:

4.3.3. Web hizmetinden gelen yanıtlar: jSON / jSON
![]() |
![]() |
Web hizmetinden gelen URL / jSON, [Response<T>] türünde yanıtlar gönderir:
package client.android.dao.service;
import java.util.List;
public class Response<T> {
// ----------------- özellikler
// işlem durumu
private int status;
// olası durum mesajları
private List<String> messages;
// yanıtın gövdesi
private T body;
// yapıcılar
public Response() {
}
public Response(int status, List<String> messages, T body) {
this.status = status;
this.messages = messages;
this.body = body;
}
// getter ve setter'lar
...
}
- URL ve [/employes], Response<List<Employe>> türünde yanıtlar döndürür;
- URL ve [/salaire], Response<FeuilleSalaire> türünde yanıt döndürür;
[FeuilleSalaire] sınıfı şu şekildedir:
package pam.entities;
import java.io.Serializable;
public class FeuilleSalaire implements Serializable {
private static final long serialVersionUID = 1L;
// özel alanlar
private Employe employe;
private Cotisation cotisation;
private ElementsSalaire elementsSalaire;
// yapıcılar
public FeuilleSalaire() {
}
public FeuilleSalaire(Employe employe, Cotisation cotisation, ElementsSalaire elementsSalaire) {
...
}
// getter ve setter'lar
...
}
- 9. satır: [Employe] sınıfı 4.2.3. paragrafta tanıtılmıştır;
- 10. satır: [Cotisation] sınıfı 4.2.3. paragrafta sunulmuştur;
[ElementsSalaire] sınıfı (satır 11) şu şekildedir:
package pam.entities;
import java.io.Serializable;
public class ElementsSalaire implements Serializable {
private static final long serialVersionUID = 1L;
// özel alanlar
private double salaireBase;
private double cotisationsSociales;
private double indemnitesEntretien;
private double indemnitesRepas;
private double salaireNet;
// yapıcılar
public ElementsSalaire() {
}
public ElementsSalaire(double salaireBase, double cotisationsSociales, double indemnitesEntretien, double indemnitesRepas, double salaireNet) {
...
}
// getter ve setter'lar
...
}
4.4. Android istemcisi testleri
![]() |
Tamamlanmış Android istemcisinin yürütülebilir dosyası aşağıda verilmiştir:
![]() |
Fare ile yukarıdaki [pam-client.apk] dosyasını bir tablet emülatörüne ([GenyMotion]) sürükleyip bırakın. Dosya kaydedilip çalıştırılacaktır. Henüz yapmadıysanız, web sunucusunu (jSON) da başlatın. Android istemcisinin amacı, / jSON web sunucusu tarafından geri gönderilen bilgileri almak ve bunları biçimlendirmektir. Android istemcisinin farklı görünümleri şunlardır:
Öncelikle / jSON web hizmetine bağlanmanız gerekir:

- [1] adresinde, /jSON web hizmetinin URL adresi verilir. Emülatörde, IP veya PC adreslerinden birini girin (ancak 127.0.0.1 adresini girmeyin). Bir tablet kullanıyorsanız, web sunucusunun cihazının Wi-Fi adresini / jSON girin ve sunucu cihazında varsa güvenlik duvarını devre dışı bırakın, çünkü gelen çağrıları engelleyebilir;
- [2] adresinden bağlanın;
Böylece simülasyon sayfasına ulaşılır:

- [3]'te bir çalışan seçin;
- [4]'te saat sayısını belirtin;
- [5] adresinde, gün sayısını girin;
- [6]'te simülasyon talebinde bulunulur;
Elde edilen simülasyon sayfası şöyledir:

- [7]'te, elde edilen simülasyon;
- [8]'te, simülasyon kaydedilir;

- [9]'te simülasyon listesi;
- [10]'te, bir simülasyon silinir;

- [11]'e, artık simülasyon kalmamıştır;
- [12]'te, simülasyon formuna geri dönülür;

- [13]'te, forma geri dönülür;
- [14]'te, yapılandırma sayfasına geri dönülür;

- [15]'e geldiğinizde, ilk oturum açma formuna geri dönersiniz.
4.5. Yapılması gerekenler
Daha önce sunulan Android istemcisinin iskeleti size verilmiştir. Bu iskelet, 2. paragrafta açıklanan [client-android-skel] projesinden oluşturulmuştur.
![]() |
Proje çalıştırılabilir durumdadır ve gerekli görünümler zaten mevcuttur. Uygulamanın yapması gerekeni yerine getirebilmesi için sadece biraz kod eklenmesi gerekmektedir. İzlenecek prosedür şöyledir:
- Yapılması gereken işi kavramak için tam sürümü çalıştırın;
- hafifletilmiş sürümü çalıştırın ve kodunu inceleyin. Bu kod, önceki sayfalarda kullanılan tasarım yöntemlerine uygundur;
- eksik kodu ekleyin;










