Tolong pilih kategori sesuai, jenis posting (diskusi atau bukan) dan sertakan tag/topik yang sesuai seperti komputer, java, php, mysql, dll. Promosi atau posting tidak pada tempatnya akan kami hapus!
query sql untuk hitung cuti karyawan
Siang master,
Ada beberapa hal pertanyaan menyangkut perhitungan cuti di sql :
1. Cara hitung sisa cuti berdasarkan masa kerja di atas 1 tahun dapat 12 cuti - jumlah cuti bersama + sisa cuti periode tahun sebelumnya. Masa kerja di bawah 1 tahun belum dapat cuti.
Contoh 12 - 4 + 2 = 10 sisa cuti yang bisa di ambil karyawan.
2. Masa berlaku cuti adalah 2 tahun, jika tidak di ambil akan hangus otomatis & akan di munculkan di report karyawan
3. Untuk pengambilan cuti, bisa setengah hari (4 jam). Jadi nanti untuk sisa cuti, contoh 12 hari 4 jam karena sudah pernah mengambil cuti setengah hari (4 jam).
Mohon bimbingannya master.
Comments
ya ...
elo pahami sendiri aja dah query di bawah ...
ribet juga jelasin kalo sudah kompleks
jangan lupa buka mysql manual, dan baca
btw, tuh enum, mending type nya integer
enum bakal ribet kalo mau dijumlahkan, lihat sendiri di query di bawah
SELECT
k.id_karyawan,
IF(
ABS(TIMESTAMPDIFF(YEAR,NOW(),k.tgl_masuk))>2,
2,
ABS(TIMESTAMPDIFF(YEAR,NOW(),k.tgl_masuk))
)*12 AS jml_cuti,
IF(
ABS(TIMESTAMPDIFF(YEAR,NOW(),k.tgl_masuk))>0,
cb.lalu,
0
) AS jml_cuti_bersama_thn_lalu,
IF(
ABS(TIMESTAMPDIFF(YEAR,NOW(),k.tgl_masuk))>0,
cb.ini,
0
) AS jml_cuti_bersama_thn_ini,
SUM(IF(YEAR(cm.tgl_cuti)=YEAR(NOW())-1,ELT(cm.jml_jam+0,1,0.5),0)) AS jml_cuti_diambil_thn_lalu,
SUM(IF(YEAR(cm.tgl_cuti)=YEAR(NOW()),ELT(cm.jml_jam+0,1,0.5),0)) AS jml_cuti_diambil_thn_ini,
(
IF(
ABS(TIMESTAMPDIFF(YEAR,NOW(),k.tgl_masuk))>2,
2,
ABS(TIMESTAMPDIFF(YEAR,NOW(),k.tgl_masuk)))*12
)
-(
IF(ABS(TIMESTAMPDIFF(YEAR,NOW(),k.tgl_masuk))>0,cb.lalu,0)
+IF(ABS(TIMESTAMPDIFF(YEAR,NOW(),k.tgl_masuk))>0,cb.ini,0)
)
-(
SUM(IF(YEAR(cm.tgl_cuti)=YEAR(NOW())-1,ELT(cm.jml_jam+0,1,0.5),0))
+SUM(IF(YEAR(cm.tgl_cuti)=YEAR(NOW()),ELT(cm.jml_jam+0,1,0.5),0))
) AS sisa_hari_cuti
FROM
karyawan k
LEFT JOIN
cuti_karyawan ck
ON
ck.id_karyawan=k.id_karyawan
LEFT JOIN
cuti_karyawan_mutasi cm
ON
cm.id_cuti_karyawan=ck.id_cuti_karyawan
AND YEAR(cm.tgl_cuti) IN (YEAR(NOW()),YEAR(NOW())-1),
(
SELECT
SUM(IF(YEAR(tgl_kalender_kerja)=YEAR(NOW()),1,0)) AS ini,
SUM(IF(YEAR(tgl_kalender_kerja)=YEAR(NOW())-1,1,0)) AS lalu
FROM
kalender_kerja kk
WHERE
YEAR(tgl_kalender_kerja) IN (YEAR(NOW()),YEAR(NOW())-1)
AND REPLACE(LOWER(keterangan_kalender_kerja)," ","")="cutibersama"
) cb
GROUP BY k.id_karyawan
query di atas belum sempurna
masalahnya sample elo juga sedikit
ini gambaran masalahnya
si A, id 1, masuk 2011, masa kerja sudah 5 tahun
dan anggap cuti bersama sama 4 hari tiap tahun, biar gampang ngasih contohnya
tiap tahun dapat cuti 12 hari, karena cuti bersama sama terus jumlahnya,
anggap pertahun dapat jatah cuti efektif 8 hari
tahun 1 ndak ada cuti kecuali cuti bersama, oke, ndak masalah
tahun 2, dapat cuti 8 hari, tidak diambil, utuh
tahun 3, dapat cuti 8 hari, jadi 8(2) + 8(3), diambil 4 hari ...
4 hari ini harusnya ambil jatah dari 8(2), yg 8(3) utuh
tahun 4, dapat cuti 8 hari, jadi 8(3) + 8(4) ... ini bisa utuh diambil 16 hari
kalo pake query di atas, pasti ndak ketemu
satu-satunya cara yg paling baik yg bisa elo pakai :
bikin satu table lagi, tabel sisa cuti
ini yg merekam sisa cuti tahun berjalan
fieldnya cukup :
id_karyawan | tahun | sisa_cuti
kalo dari contoh di atas, isinya bakal jadi
1 | 2011 | 0
1 | 2012 | 4
1 | 2013 | 8
1 | 2014 | 8
ngitungnya lebih gampang
elo ndak perlu nge-trace dari awal tahun masuk
dipahami dulu
ubah dari situ
ndak berubah banyak
logika nya masih bisa dipake
emang kalo int kenapa ?
kan sama aja bisa elo isi angka 4 atau 8
malah kalo mau pake desimal, bukan integer
elo simpan 1 dan 0.5
1 hari atau 0.5 hari
semisal sisa cuti 7.5
elo floor() dapet 7 hari
kalo elo bandingkan sisa cuti dan hasil floor lebih besar sisa cuti ...
7 < 7.5
berarti pasti ada tambahan 4 jam, ndak mungkin lain
kalo int, hasil SUM() mesti di /8 dan floor() dulu
baru ketemu jumlah hari
dan di %8 ketemu sisa jam
mau int atau dec, nambahnya gampang, tinggal SUM()
drpd pake enum mesti pake ELT() baru bisa di SUM()
sisa libur yg masih bisa dipake 2015 & 2016, bener to ?
elo ambil aja dulu 2 data 2 tahun terakhir ...
SELECT * FROM sisa_cuti WHERE id_karyawan="xxx" ORDER BY tahun DESC LIMIT 2
itu bakal dapat data 2 tahun terakhir
ambil semua tampung di array
misal jadi
$sisa_cuti = array( 2016 => 5 , 2015 => 2.5 );
misal
$ambil_cuti = 4;
$tahun_ini = date('Y'); // 2016
$tahun_lalu = $tahun_ini - 1;
if($sisa_cuti[$tahun_lalu]<$ambil_cuti) {
$sisa_cuti[$tahun_lalu] = 0;
$ambil_cuti = $ambil_cuti - $sisa_cuti[$tahun_lalu];
}
else {
$sisa_cuti[$tahun_lalu] = $sisa_cuti[$tahun_lalu] - $ambil_cuti;
$ambil_cuti = 0;
}
if($sisa_cuti[$tahun_ini]<$ambil_cuti) {
$sisa_cuti[$tahun_ini] = 0;
$ambil_cuti = $ambil_cuti - $sisa_cuti[$tahun_ini];
}
else {
$sisa_cuti[$tahun_ini] = $sisa_cuti[$tahun_ini] - $ambil_cuti;
$ambil_cuti = 0;
}
itu proses nya, tinggal UPDATE 2x
UPDATE sisa_cuti SET sisa_cuti=$sisa_cuti[$tahun_lalu] WHERE id_karyawan="xxx" AND tahun=$tahun_lalu
UPDATE sisa_cuti SET sisa_cuti=$sisa_cuti[$tahun_ini] WHERE id_karyawan="xxx" AND tahun=$tahun_ini
selesai
itu nama variabelnya sudah menunjukkan itu data apa ...
ya value data itu di koding elo ada di mana ?
kalo masalah tahun kan otomatis by system
baca tanggal system langsung
WHERE
YEAR(tgl_kalender_kerja) IN (YEAR(NOW()),YEAR(NOW())-1)
emang gak bisa kalo ndak pake sub query ?
k.id_karyawan,nama_lengkap,nik,is_active,
IFNULL(SUM(cuti_sisa),0) AS total_cuti,
b.nama_dept,f.jabatan
FROM karyawan k
LEFT JOIN dept b ON k.id_dept = b.id
LEFT JOIN jabatan_user f ON k.id_jabatan = f.id
LEFT JOIN cuti_sisa c ON c.id_karyawan = k.id_karyawan
WHERE is_active='0' AND k.id_karyawan= 8
AND YEAR(tahun) IN (YEAR(NOW()),YEAR(NOW())-1)
GROUP BY k.id_karyawan
yg gw tandai merah ...
kalo elo mainan query multi table
pake nama table nya atau alias nya buat nunjukin itu field table yg mana
padahal yg biru sudah bener lho,
pake alias buat nunjuk itu ada di table yg mana
kok bisa belang ?
itu dari table apa ?
iya gw tau mas'e ... gw kan juga bilang :
"pake nama table nya atau alias nya buat nunjukin itu field table yg mana"
itu pun masih ada field yg belum elo tulis table atau alias nya
lalu ?
hasilnya masih kosong ?
di table karyawan , data dgn id_karyawan = 8 dan is_active = 0 ... ada atau tidak ?
SELECT YEAR(NOW()),YEAR(NOW())-1 FROM DUAL;
apa hasilnya ?
k.id_karyawan,nama_lengkap,nik,is_active,
IFNULL(SUM(c.cuti_sisa),0) AS total_cuti,
b.nama_dept,f.jabatan
FROM karyawan k
LEFT JOIN dept b ON k.id_dept = b.id
LEFT JOIN jabatan_user f ON k.id_jabatan = f.id
LEFT JOIN cuti_sisa c ON c.id_karyawan = k.id_karyawan
WHERE
is_active='0' AND k.id_karyawan=8
AND YEAR(c.tahun) IN (YEAR(NOW()),YEAR(NOW())-1)
apa hasilnya ?
SUM(IFNULL(c.cuti_sisa,0))
AND YEAR(c.tahun) IN (YEAR(NOW()),YEAR(NOW())-1)
kok ndak ikut masuk ... gimana tooooooo ...
itu kan kunci buat milih hanya tahun 2015 & 2016 -nya
tanpa itu ya 2014 ikut masuk
posting kemari
AND YEAR(c.tahun) IN (YEAR(NOW()),YEAR(NOW())-1)
jelas salah ...
YEAR(c.tahun)
lha wong c.tahun elo isinya bukan type DATE
cuma :
2014
2015
2016
ya cukup begini :
AND c.tahun IN (YEAR(NOW()),YEAR(NOW())-1)
A PHP Error was encountered
Severity: Notice
Message: Undefined offset: 2015
Filename: models/data_cuti_karyawan_model.php
Line Number: 72
A PHP Error was encountered
Severity: Notice
Message: Undefined offset: 2016
Filename: models/data_cuti_karyawan_model.php
Line Number: 81
lengkapnya kaya apa ?
itu artinya elo mau coba ambil :
$total_cuti_db[2015]
lha wong elo adanya cuma ini :
$total_cuti_db[] = $tmp2;
coba elo liat hasilnya ini :
<?php
$a=array();
$a[]=1;
$a[]=2;
$a[]=3;
print_r($a);
?>
index nya bagaimana ? ada 2015 ?
$cuti_sisa[$tahun_lalu] ... sama saja
$cuti_sisa[2015]
adanya cuma ini :
$cuti_sisa = array(
'cuti_sisa' =>$c,
'last_update' =>date('Y-m-d H:i:s'),
'updated_by' => $this->session->userdata('nama')
);
coba elo : print_r($cuti_sisa);
ada yg index nya 2015 ?
SELECT * FROM sisa_cuti WHERE id_karyawan="xxx" ORDER BY tahun DESC LIMIT 2
itu bakal dapat data 2 tahun terakhir
ambil semua tampung di array
misal jadi
$sisa_cuti = array( 2016 => 5 , 2015 => 2.5 );
..."
elo itu mau bikin itu ?
ya gini to mas ...
$total_cuti_db = array();
foreach ($sql->result_array() as $row) {
$total_cuti_db[$row['tahun']] = $row['cuti_sisa'];
}
A PHP Error was encountered
Severity: Notice
Message: Undefined offset: 2015
Filename: models/data_cuti_karyawan_model.php
Line Number: 96
ya jelas $cuti_sisa[$tahun_lalu] ndak mungkin ada to maaasssssss ...
$cuti_sisa[$tahun_lalu]
$cuti_sisa[2015]
lha wong $cuti_sisa elo itu isinya ini :
Array (
[cuti_sisa] => 3
[last_update] => 2016-06-29 08:32:02
[updated_by] => Administrator
)
nama ada [2015] di situ ?
elo nyari apa sih ?
sisa cuti yg bisa diambil terakhir ?
kan ada di : $total_cuti_db
coba dah elo bandingin isinya ...
$total_cuti_db = array();
foreach ($sql->result_array() as $row) {
$total_cuti_db[$row['tahun']] = $row['cuti_sisa'];
}
print_r($total_cuti_db);
...
...
...
if($total_cuti_db[$tahun_lalu]<$cuti_sisa['cuti_sisa']) {
$total_cuti_db[$tahun_lalu] = 0;
$cuti_sisa['cuti_sisa'] = $cuti_sisa['cuti_sisa'] - $total_cuti_db[$tahun_lalu];
}
else {
$total_cuti_db[$tahun_lalu] = $total_cuti_db[$tahun_lalu] - $cuti_sisa['cuti_sisa'];
$cuti_sisa['cuti_sisa'] = 0;
}
if($total_cuti_db[$tahun_ini]<$cuti_sisa['cuti_sisa']) {
$total_cuti_db[$tahun_ini] = 0;
$cuti_sisa['cuti_sisa'] = $cuti_sisa['cuti_sisa'] - $total_cuti_db[$tahun_ini];
}
else {
$total_cuti_db[$tahun_ini] = $total_cuti_db[$tahun_ini] - $cuti_sisa['cuti_sisa'];
$cuti_sisa['cuti_sisa'] = 0;
}
print_r($total_cuti_db);
if($total_cuti_db[$tahun_lalu]<$cuti_sisa['cuti_sisa']) {
$total_cuti_db[$tahun_lalu] = 0;
$cuti_sisa['cuti_sisa'] = $cuti_sisa['cuti_sisa'] - $total_cuti_db[$tahun_lalu];
}
harusnya ...
if($total_cuti_db[$tahun_lalu]<$cuti_sisa['cuti_sisa']) {
$cuti_sisa['cuti_sisa'] = $cuti_sisa['cuti_sisa'] - $total_cuti_db[$tahun_lalu];
$total_cuti_db[$tahun_lalu] = 0;
}
ini juga kebalik ...
if($total_cuti_db[$tahun_ini]<$cuti_sisa['cuti_sisa']) {
$total_cuti_db[$tahun_ini] = 0;
$cuti_sisa['cuti_sisa'] = $cuti_sisa['cuti_sisa'] - $total_cuti_db[$tahun_ini];
}
harusnya ...
if($total_cuti_db[$tahun_ini]<$cuti_sisa['cuti_sisa']) {
$cuti_sisa['cuti_sisa'] = $cuti_sisa['cuti_sisa'] - $total_cuti_db[$tahun_ini];
$total_cuti_db[$tahun_ini] = 0;
}
$cuti_sisa['cuti_sisa']
terakhir harus 0
kalo lebih dari 0 berarti harus mengeluarkan pesan error :
jumlah cuti yg mau diambil melebihi jatah
lha tipe elo kan emang decimal, pasti bisa tampung nilai 0.5
yg validasi ...
jangan cuma mengandalkan validasi js mas'e
kan gw sudah nulis ...
ini elo pegang :
jangan percaya apa pun yg di input user
kalo memungkinkan di hitung ulang : hitung ulang
kalo bisa ambil ulang dari db : ambil dari db
ealah, elo type decimal, tapi length nya 11,0 ???
11 digit bilangan bulat
0 angka di belakang koma
gitu ?
mau simpan 0.5 gimana caranya mas'e ?
elo definisikan 0 angka di belakang koma