package com.jasamedika.medifirst2000.dao;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import com.jasamedika.medifirst2000.entities.Pegawai;

@Repository("PayRollPegawaiDao")
public interface PayRollPegawaiDao extends PagingAndSortingRepository<Pegawai, Integer> {
	
	@Query("select new Map(model.id as id,"
			+ "detailkategoripegawai.id as detailKatogoriId,"
			+ "rangemasakerja.id as rangeMasaKerjaId,"
			+ "pendidikan.id as pendidikanId,"
			+ "komponenharga.id as komponenHargaId,"
			+ "model.hargaSatuan as hargaSatuan,"
			+ "model.factorRate as factorRate) "
			+ "from PegawaiStrukturGajiByMaKaPe model "
			+ "left join model.detailKategoriPegawai detailkategoripegawai "
			+ "left join model.pendidikan pendidikan "
			+ "left join model.komponenHarga komponenharga "
			+ "left join model.rangeMasaKerja rangemasakerja "
			+ "where model.detailKategoriPegawai.id=:idDetailKategoriPegawai and "
			+ "model.rangeMasaKerja.id=:idRangeMasaKerja and model.pendidikan.id=:idPendidikan")
	List<Map<String, Object>> findGajiByMakape(@Param("idDetailKategoriPegawai")Integer idDetailKategoriPegawai,
			@Param("idRangeMasaKerja")Integer idRangeMasaKerja,
			@Param("idPendidikan")Integer idPendidikan);

	@Query("select new Map(model.id as id,"
			+ "detailkategoripegawai.id as detailKatogoriId,"
			+ "rangemasakerja.id as rangeMasaKerjaId,"
			+ "pendidikan.id as pendidikanId,"
			+ "komponenharga.id as komponenHargaId,"
			+ "model.hargaSatuan as hargaSatuan,"
			+ "model.factorRate as factorRate) "
			+ "from PegawaiStrukturGajiByMaKaPe model "
			+ "left join model.detailKategoriPegawai detailkategoripegawai "
			+ "left join model.pendidikan pendidikan "
			+ "left join model.komponenHarga komponenharga "
			+ "left join model.rangeMasaKerja rangemasakerja "
			+ "where model.detailKategoriPegawai.id=:idDetailKategoriPegawai "
			+ "and model.pendidikan.id=:idPendidikan")
	List<Map<String, Object>> findGajiByMakape(@Param("idDetailKategoriPegawai")Integer idDetailKategoriPegawai,
			@Param("idPendidikan")Integer idPendidikan);

	@Query("select new Map(model.id as id,"
			+ "jabatan.id as jabatanId,"
			+ "komponenharga.id as komponenHargaId,"
			+ "model.hargaSatuan as hargaSatuan,"
			+ "model.factorRate as factorRate) "
			+ "from PegawaiStrukturGajiByJa model "
			+ "left join model.jabatan jabatan "
			+ "left join model.komponenHarga komponenharga "
			+ "where jabatan.id=:idJabatan and komponenharga.id=57")
	List<Map<String, Object>> findGajiByJa(@Param("idJabatan")Integer idJabatan);
	
	@Query("select new Map(model.id as id,"
			+ "jabatan.id as jabatanId,"
			+ "pendidikan.id as pendidikanId,"
			+ "komponenHarga.id as komponenHargaId,"
			+ "model.hargaSatuan as hargaSatuan,"
			+ "model.factorRate as factorRate) "
			+ "from PegawaiStrukturGajiByJaPe model "
			+ "left join model.jabatan jabatan "
			+ "left join model.pendidikan pendidikan "
			+ "left join model.komponenHarga komponenharga "
			+ "where jabatan.id=:idJabatan and pendidikan.id=:idPendidikan")
	List<Map<String, Object>> findGajiByJaPe(@Param("idJabatan")Integer idJabatan,
			@Param("idPendidikan")Integer idPendidikan);

	@Query("select new Map(model.id as id,"
			+ "leveltingkat.id as levelTingkatId,"
			+ "jabatan.id as jabatanId,"
			+ "komponenharga.id as komponenHargaId,"
			+ "model.hargaSatuan as hargaSatuan,"
			+ "model.factorRate as factorRate) "
			+ "from PegawaiStrukturGajiByLTJa model "
			+ "left join model.levelTingkat leveltingkat "
			+ "left join model.jabatan jabatan "
			+ "left join model.komponenHarga komponenharga "
			+ "where jabatan.id=:idJabatan and leveltingkat.id=:idLevelTingkat")
	List<Map<String, Object>> findGajiByLTJa(@Param("idJabatan")Integer idJabatan,
			@Param("idLevelTingkat")Integer idLevelTingkat);

	@Query("select new Map(model.id as id,"
			+ "rekanan.id as rekananId,"
			+ "rekanan.namaRekanan as namaRekanan,"
			+ "komponenharga.id as komponenHargaId,"
			+ "komponenharga.komponenHarga as namaKomponenHarga,"
			+ "model.hargaSatuanPremi as hargaSatuanPremi,"
			+ "model.persenHargaSatuanPremi as persenHargaSatuanPremi,"
			+ "model.factorRate as factorRate,"
			+ "model.totalFactorRatePremi as totalFactorRatePremi,"
			+ "model.isByMonth as isByMonth,"
			+ "model.isByYear as isByYear,"
			+ "model.keteranganLainnya as keteranganLainnya) "
			+ "from PegawaiSKAsuransi model "
			+ "left join model.rekanan rekanan "
			+ "left join model.komponenHarga komponenharga "
			+ "where model.rekanan.id=:idRekananPenjamin and komponenharga.id=:idKomponenHarga "
			+ "and model.statusEnabled=true")
	List<Map<String, Object>> findGajiByAsuransi(@Param("idRekananPenjamin")Integer idRekananPenjamin,
			@Param("idKomponenHarga")Integer idKomponenHarga);

	@Query("select new Map(model.id as id,"
			+ "golonganpegawai.id as golonganPegawaiId,"
			+ "komponenharga.id as komponenHargaId,"
			+ "model.hargaSatuan as hargaSatuan,"
			+ "model.factorRate as factorRate) "
			+ "from PegawaiStrukturGajiByGolongan model "
			+ "left join model.golonganPegawai golonganpegawai "
			+ "left join model.komponenHarga komponenharga "
			+ "where golonganpegawai.id=:idGolonganPegawai and komponenharga.id=:idKomponenHarga")
	List<Map<String, Object>> findGajiByGolongan(@Param("idGolonganPegawai")Integer idGolonganPegawai,
			@Param("idKomponenHarga")Integer idKomponenHarga);

	@Query("select new Map(model.id as id,"
			+ "golonganpegawai.id as golonganPegawaiId,"
			+ "objekpajak.id as objekPajakId,"
			+ "objekpajak.objekPajak as objekPajak,"
			+ "range.id as rangeId,"
			+ "model.persenPajak as persenPajak,"
			+ "model.keteranganLainnya as keteranganLainnya) "
			+ "from PegawaiSKPajak model "
			+ "left join model.objekPajak objekpajak "
			+ "left join model.golonganPegawai golonganpegawai "
			+ "left join model.range range "
			+ "where :idObjekPajak=:idObjekPajak and golonganpegawai.id=:idGolongaPegawai and "
			+ "range.id=:idRange")
	List<Map<String, Object>> findGajiByPajak(@Param("idObjekPajak")Integer idObjekPajak,
			@Param("idGolongaPegawai")Integer idGolongaPegawai,@Param("idRange")Integer idRange);

	@Query("select new Map(model.id,"
			+ "model.golonganPegawai.id,"
			+ "model.objekPajak.id,"
			+ "model.range.id,"
			+ "model.persenPajak,"
			+ "model.keteranganLainnya) "
			+ "from PegawaiSKPajak model "
			+ "where model.objekPajak.id=:idObjekPajak and model.golonganPegawai.id=:idGolongaPegawai and "
			+ "model.range.id=:idRange")
	List<Map<String, Object>> findPegawaiByDetailKategory(@Param("idObjekPajak")Integer idObjekPajak,
			@Param("idGolongaPegawai")Integer idGolongaPegawai,@Param("idRange")Integer idRange);

	@Query("select new Map (model.namaLengkap as namaLengkap,"
			+"golonganpegawai.golonganPegawai as golonganPegawai,"
			+"golonganpegawai.id as golonganPegawaiId,"
			+ "pendidikan.namaPendidikan as pendidikan,"
			+ "pendidikan.id as pendidikanId,"
			+"jabatanfungsional.id as jabatanId,"
			+"jabatanfungsional.namaJabatan as namaJabatan,"
			+"detailkategoripegawai.id as detailKategoriPegawaiId,"
			+"detailkategoripegawai.detailKategoryPegawai as detailKategoriPegawai,"
			+ "model.nipPns as nipPns,"
			+ "statuspegawai.statusPegawai as statusPegawai,"
			+"kategoripegawai.kategoryPegawai as kategoriPegawai,"
			+ "model.tglMasuk as tglMasuk,"
			+ "model.id as pegawaiId,"
			+ "kelompokshift.id as kelompokShiftId,"
			+ "ruangan.id as ruanganId,"
			+ "ruangan.namaRuangan as namaRuangan) "
			+"from Pegawai model "
			+"left join model.golonganPegawai golonganpegawai "
			+"left join model.pendidikan pendidikan "
			+"left join model.jabatanFungsional jabatanfungsional "
			+"left join model.detailKategoryPegawai detailkategoripegawai "
			+"left join detailkategoripegawai.kategoryPegawai kategoripegawai "
			+ "left join model.statusPegawai statuspegawai "
			+ "left join model.shiftKerja kelompokshift "
			+ "left join model.ruangan ruangan "
			+"where detailkategoripegawai.id = :idDetailKategoriPegawai and statuspegawai.id=2 "
			+ "order by model.namaLengkap")
	List<Map<String, Object>> findPegawaiByDetailKategori(@Param("idDetailKategoriPegawai")Integer idDetailKategoriPegawai);
	
	@Query("select new Map(model.id as id, "
			+ "model.komponenHarga as komponenHarga) "
			+ "from KomponenHarga model "
			+ "where model.id=:idKomponenHarga")
	Map<String,Object> findKomponenHargaNameById(@Param("idKomponenHarga")Integer idKomponenHarga);
	
	@Query("select new Map(model.id as id, "
			+ "model.objekPajak as objekPajak) "
			+ "from ObjekPajak model "
			+ "where model.id=:idObjekPajak")
	Map<String,Object> findObjekPajakById(@Param("idObjekPajak")Integer idObjekPajak);
	
	@Query("select new Map(model.id as id) from Range model where namarange='Range Masa Kerja' and (rangemin<=:umur and rangemax>=:umur)")
	Map<String,Object> findRangeId(@Param("umur")Integer umur);
	
	@Query("select new Map(model.id as id,model.detailKategoryPegawai as detailKategoryPegawai) from DetailKategoryPegawai model where model.id in (:ids)")
	List<Map<String,Object>> findDetailKategoryPegawaiBluPkwt(@Param("ids")List<Integer> ids);
	
	@Query("select new Map(model.id as id,model.name as name) from JenisGaji model")
	List<Map<String,Object>> findAllJenisGaji();
	
	@Query("select new Map(kelompokshift.id as kelompokShifId,kelompokshift.kelompokShiftKerja as kelompokShiftKerja,"
		+"shiftkerja.id as shiftKerjaId,shiftkerja.namaShift as shiftKerja,"
		+ "komponenindex.id as komponenIndexId,"
		+ "komponenindex.komponenIndex as komponenIndex) "
		+ "from MapKelompokShiftToShift model "
		+"left join model.kelompokShift kelompokshift "
		+"left join model.shiftKerja shiftkerja "
		+"left join shiftkerja.komponenIndex komponenindex "
		+"where kelompokshift.id = :idKelompokShift")
	List<Map<String,Object>> findKomponenIndexByIdKelompokShift(@Param("idKelompokShift")Integer idKelompokShift);
	
	@Query("select new Map(sum(model.nilaiIndex) as sumNilaiIndex,"
			+ "pegawai.id as pegawaiId,"
			+ "ruangan.id as ruaganId ) "
			+ "from PegawaiHistoriRekapIndex model "
		+"left join model.komponenIndex komponenindex "
		+"left join model.strukHistory strukhistory "
		+"left join model.pegawai pegawai "
		+"left join strukhistory.ruangan ruangan "
		+"where komponenindex.id in (:listKomponenIndex) and ruangan.id=:idRuangan and pegawai.id=:idPegawai "
		+ "and to_char(strukhistory.tglAwal,'mm-yyyy')=:periodeBulan "
		+"group by pegawai.id,ruangan.id")
	Map<String,Object> getJumlahHari(@Param("listKomponenIndex")List<Integer> listKomponenIndex,@Param("idRuangan")Integer idRuangan,
			@Param("idPegawai")Integer idPegawai,
			@Param("periodeBulan")String periodeBulan);
	
	@Query("select new Map(model.id as id,"
			+ "golonganpegawai.id as golonganPegawaiId,"
			+ "komponenharga.id as komponenHargaId,"
			+ "model.hargaSatuan as hargaSatuan,"
			+ "model.factorRate as factorRate) "
			+ "from PegawaiStrukturGajiByGolongan model "
			+ "left join model.golonganPegawai golonganpegawai "
			+ "left join model.komponenHarga komponenharga "
			+ "where komponenharga.id=:idKomponenHarga")
	List<Map<String, Object>> findGajiHarianLepas(@Param("idKomponenHarga")Integer idKomponenHarga);

	@Query("select new Map (model.namaLengkap as namaLengkap,"
			+"golonganpegawai.golonganPegawai as golonganPegawai,"
			+"golonganpegawai.id as golonganPegawaiId,"
			+ "pendidikan.namaPendidikan as pendidikan,"
			+ "pendidikan.id as pendidikanId,"
			+"jabatanfungsional.id as jabatanId,"
			+"jabatanfungsional.namaJabatan as namaJabatan,"
			+"detailkategoripegawai.id as detailKategoriPegawaiId,"
			+"detailkategoripegawai.detailKategoryPegawai as detailKategoriPegawai,"
			+ "model.nipPns as nipPns,"
			+ "statuspegawai.statusPegawai as statusPegawai,"
			+"kategoripegawai.kategoryPegawai as kategoriPegawai,"
			+ "model.tglMasuk as tglMasuk,"
			+ "model.id as pegawaiId,"
			+ "kelompokshift.id as kelompokshiftId,"
			+ "ruangan.id as ruanganId,"
			+ "ruangan.namaRuangan as namaRuangan) "
			+"from Pegawai model "
			+"left join model.golonganPegawai golonganpegawai "
			+"left join model.pendidikan pendidikan "
			+"left join model.jabatanFungsional jabatanfungsional "
			+"left join model.detailKategoryPegawai detailkategoripegawai "
			+"left join detailkategoripegawai.kategoryPegawai kategoripegawai "
			+ "left join model.statusPegawai statuspegawai "
			+ "left join model.shiftKerja kelompokshift "
			+ "left join model.jenisPegawai jenispegawai "
			+ "left join model.ruangan ruangan "
			+"where detailkategoripegawai.id = :idDetailKategoriPegawai and statuspegawai.id=2 "
			+ "and jenispegawai.id = 1 "
			+ "order by model.namaLengkap")
	List<Map<String, Object>> findPegawaiByDetailKategoriDokterPsikologi(@Param("idDetailKategoriPegawai")Integer idDetailKategoriPegawai);
	
	@Query("select new Map (model.namaLengkap as namaLengkap,"
			+"golonganpegawai.golonganPegawai as golonganPegawai,"
			+"golonganpegawai.id as golonganPegawaiId,"
			+ "pendidikan.namaPendidikan as pendidikan,"
			+ "pendidikan.id as pendidikanId,"
			+"jabatanfungsional.id as jabatanId,"
			+"jabatanfungsional.namaJabatan as namaJabatan,"
			+"detailkategoripegawai.id as detailKategoriPegawaiId,"
			+"detailkategoripegawai.detailKategoryPegawai as detailKategoriPegawai,"
			+ "model.nipPns as nipPns,"
			+ "statuspegawai.statusPegawai as statusPegawai,"
			+"kategoripegawai.kategoryPegawai as kategoriPegawai,"
			+ "model.tglMasuk as tglMasuk,"
			+ "model.id as pegawaiId,"
			+ "kelompokshift.id as kelompokshiftId,"
			+ "ruangan.id as ruanganId,"
			+ "ruangan.namaRuangan as namaRuangan,"
			+ "model.tglLahir as tglLahir,"
			+ "asuransiPasien.noAsuransi as noAsuransi,"
			+ "rekanan.id as rekananId,"
			+ "rekanan.namaRekanan as namaRekanan) "
			+ "from AsuransiPasien asuransiPasien "
			+ "left join asuransiPasien.pegawai model " 
			+"left join model.golonganPegawai golonganpegawai "
			+"left join model.pendidikan pendidikan "
			+"left join model.jabatanFungsional jabatanfungsional "
			+"left join model.detailKategoryPegawai detailkategoripegawai "
			+"left join detailkategoripegawai.kategoryPegawai kategoripegawai "
			+ "left join model.statusPegawai statuspegawai "
			+ "left join model.shiftKerja kelompokshift "
			+ "left join model.ruangan ruangan "
			+ "left join asuransiPasien.rekanan rekanan "
			+"where rekanan.id is not null and statuspegawai.id=2 "
			+ "and rekanan.id = :idRekanan "
			+ "order by model.namaLengkap")
	List<Map<String, Object>> findPegawaiByAsuransi(@Param("idRekanan") Integer idRekanan);

	@Query("select new Map(model.totalFactorRatePremi as umr, "
			+"to_char(nosk.tglBerlakuAkhir,'yyyy') as tahun ) "
			+"from PegawaiSKAsuransi model "
			+"left join model.noSK nosk "
			+"where  nosk.tglBerlakuAwal <= :periode "
			+"and nosk.tglBerlakuAkhir >= :periode "
			+ "and model.statusEnabled=true")
	public List<Map<String,Object>> findUmr(@Param("periode") Date periode);

}
