package com.jasamedika.medifirst2000.service.impl;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jasamedika.medifirst2000.constants.Master;
import com.jasamedika.medifirst2000.converter.BaseConverterImpl;
import com.jasamedika.medifirst2000.dao.HabsenDao;
import com.jasamedika.medifirst2000.dao.JatahCutiDanIzinDao;
import com.jasamedika.medifirst2000.dao.KalenderDao;
import com.jasamedika.medifirst2000.dao.KomponenIndexDao;
import com.jasamedika.medifirst2000.dao.ListTanggalCutiDao;
import com.jasamedika.medifirst2000.dao.MapKalenderToHariLiburDao;
import com.jasamedika.medifirst2000.dao.MapPegawaiJabatanToUnitKerjaDao;
import com.jasamedika.medifirst2000.dao.PegawaiDao;
import com.jasamedika.medifirst2000.dao.PegawaiHistoriRekapIndexDao;
import com.jasamedika.medifirst2000.dao.PegawaiJadwalKerjaDao;
import com.jasamedika.medifirst2000.dao.PermohonanCutiPegawaiDao;
import com.jasamedika.medifirst2000.dao.PlanningPegawaiStatusDao;
import com.jasamedika.medifirst2000.dao.RunningNumberDao;
import com.jasamedika.medifirst2000.dao.SettingDataFixedDao;
import com.jasamedika.medifirst2000.dao.StatusPegawaiDao;
import com.jasamedika.medifirst2000.dao.StrukHistoriDao;
import com.jasamedika.medifirst2000.dao.SuratKeputusanDao;
import com.jasamedika.medifirst2000.dao.custom.PlanningPegawaiStatusDaoCustom;
import com.jasamedika.medifirst2000.entities.Jabatan;
import com.jasamedika.medifirst2000.entities.JatahCutiDanIzin;
import com.jasamedika.medifirst2000.entities.JenisKeputusan;
import com.jasamedika.medifirst2000.entities.KomponenIndex;
import com.jasamedika.medifirst2000.entities.ListTanggalCuti;
import com.jasamedika.medifirst2000.entities.Pegawai;
import com.jasamedika.medifirst2000.entities.PegawaiHistoriRekapIndex;
import com.jasamedika.medifirst2000.entities.PlanningPegawaiStatus;
import com.jasamedika.medifirst2000.entities.RunningNumber;
import com.jasamedika.medifirst2000.entities.StatusPegawai;
import com.jasamedika.medifirst2000.entities.StrukHistori;
import com.jasamedika.medifirst2000.entities.SuratKeputusan;
import com.jasamedika.medifirst2000.service.LoginUserService;
import com.jasamedika.medifirst2000.service.MonitoringAbsenService;
import com.jasamedika.medifirst2000.service.PermohonanStatusPegawaiService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.util.DateUtil;
import com.jasamedika.medifirst2000.util.StringUtil;
import com.jasamedika.medifirst2000.vo.FactoRateKelompokShiftVO;
import com.jasamedika.medifirst2000.vo.JabatanVO;
import com.jasamedika.medifirst2000.vo.JatahCutiDanIzinVO;
import com.jasamedika.medifirst2000.vo.JenisKeputusanVO;
import com.jasamedika.medifirst2000.vo.KelompokShiftKerjaCustomVO;
import com.jasamedika.medifirst2000.vo.KomponenIndexVO;
import com.jasamedika.medifirst2000.vo.ListTanggalCutiVO;
import com.jasamedika.medifirst2000.vo.PegawaiVO;
import com.jasamedika.medifirst2000.vo.PlanningPegawaiStatusVO;
import com.jasamedika.medifirst2000.vo.StatusPegawaiVO;

@Service("PegawaiCutiService")
public class PermohonanStatusPegawaiImpl implements PermohonanStatusPegawaiService {

	@Autowired
	private LoginUserService loginUserService;

	@Autowired
	private MonitoringAbsenService monitoringAbsenService;

	@Autowired
	private PlanningPegawaiStatusDao planningPegawaiStatusDao;

	@Autowired
	private SettingDataFixedDao settingDataFixedDao;

	@Autowired
	private StatusPegawaiDao statusPegawaiDao;

	@Autowired
	private ListTanggalCutiDao listTanggalCutiDao;

	@Autowired
	private JatahCutiDanIzinDao jatahCutiDanIzinDao;

	@Autowired
	private PegawaiDao pegawaiDao;

	@Autowired
	private SuratKeputusanDao suratKeputusanDao;

	@Autowired
	private RunningNumberDao runningNumberDao;

	@Autowired
	private StrukHistoriDao strukHistoriDao;

	@Autowired
	private KomponenIndexDao komponenIndexDao;

	@Autowired
	private PegawaiHistoriRekapIndexDao pegawaiHistoriRekapIndexDao;

	@Autowired
	private PegawaiJadwalKerjaDao pegawaiJadwalKerjaDao;

	@Autowired
	private MapPegawaiJabatanToUnitKerjaDao mapPegawaiJabatanToUnitKerjaDao;

	@Autowired
	private MapKalenderToHariLiburDao mapKalenderToHariLiburDao;

	@Autowired
	private HabsenDao habsenDao;

	@Autowired
	private PermohonanCutiPegawaiDao permohonanCutiPegawaiDao;

	@Autowired
	private KalenderDao kalenderDao;

	@Autowired
	private PlanningPegawaiStatusDaoCustom planningPegawaiStatusDaoCustom;

	@Autowired
	private BaseConverterImpl<PlanningPegawaiStatusVO, PlanningPegawaiStatus> planningPegawaiStatusConverter;

	@Autowired
	private BaseConverterImpl<KomponenIndexVO, KomponenIndex> komponenIndexConverter;

	@Autowired
	private BaseConverterImpl<PegawaiVO, Pegawai> pegawaiConverter;

	@Autowired
	private BaseConverterImpl<JenisKeputusanVO, JenisKeputusan> jenisKeputusanConverter;

	@Autowired
	private BaseConverterImpl<ListTanggalCutiVO, ListTanggalCuti> listTanggalConverter;

	@Autowired
	private BaseConverterImpl<StatusPegawaiVO, StatusPegawai> statusPegawaiConverter;

	@Autowired
	private BaseConverterImpl<JabatanVO, Jabatan> jabatanConverter;

	@Override
	public Map<String, Object> getUserLogin(Integer idPegawai) {
		Map<String, Object> result = new HashMap<String, Object>();
		Map<String, Object> pegawai = pegawaiDao.getPegawaiByIdCustom(idPegawai);
		Map<String, Object> mapPegawai = mapPegawaiJabatanToUnitKerjaDao.findAllByPegawaiPrimary(idPegawai);
		if (CommonUtil.isNotNullOrEmpty(pegawai)) {
			result.put("name", pegawai.get("namaLengkap"));
			result.put("idPegawai", pegawai.get("id"));
			result.put("idRuangan", pegawai.get("ruanganId"));
			if (CommonUtil.isNotNullOrEmpty(mapPegawai.get("subUnitKerjaPegawaiId"))) {
				result.put("idSubUnitKerja", mapPegawai.get("subUnitKerjaPegawaiId"));
			} else {
				result.put("idSubUnitKerja", 0);
			}
			if (CommonUtil.isNotNullOrEmpty(mapPegawai.get("jabatanId"))) {
				result.put("idJabatan", mapPegawai.get("jabatanId"));
			} else {
				result.put("idJabatan", 0);
			}

		}
		return result;
	}

	@Override
	public Map<String, Object> noUsulan() {
		Map<String, Object> result = new HashMap<>();
		String monthNow = String.valueOf(DateUtil.getMonthFromDate(new Date()));
		String yearNow = String.valueOf(DateUtil.getYearFromDate(new Date())).substring(2, 4);

		if (monthNow.length() == 1)
			monthNow = "0" + monthNow;

		List<String> list = planningPegawaiStatusDao.noPlanning("PS" + yearNow + monthNow);
		if (CommonUtil.isNotNullOrEmpty(list)) {
			Integer data = Integer.parseInt(list.get(list.size() - 1).substring(6)) + 1;
			result.put("noUsulan", "PS" + yearNow + monthNow + String.format("%04d", data));
		} else {
			result.put("noUsulan", "PS" + yearNow + monthNow + "0001");
		}

		return result;
	}

	@Override
	public Map<String, Object> getLoadData(Integer ruanganId) {
		Map<String, Object> result = new HashMap<>();

		Map<String, Object> noUsulan = noUsulan();
		if (CommonUtil.isNotNullOrEmpty(noUsulan)) {
			result.put("noUsulan", noUsulan.get("noUsulan"));
		}
		List<Map<String, Object>> listPegawai = planningPegawaiStatusDao.getListPegawai(ruanganId);
		if (CommonUtil.isNotNullOrEmpty(listPegawai)) {
			result.put("listPegawai", listPegawai);
		}
		List<Map<String, Object>> listStatusPegawai = planningPegawaiStatusDao.getListStatusPegawai();
		if (CommonUtil.isNotNullOrEmpty(listStatusPegawai)) {
			result.put("listStatusPegawai", listStatusPegawai);
		}
		return result;
	}

	@Override
	public Map<String, Object> getDataPermohonanStatus(Integer id) {
		Map<String, Object> result = new HashMap<>();
		Map<String, Object> data = planningPegawaiStatusDao.getDataPermohonanStatus(id);
		result.put("kategoriPegawaiId", data.get("kategoriPegawaiId"));

		return data;
	}

	@Override
	public Map<String, Object> getDataMapPermohonanStatus(Integer id) {
		Map<String, Object> result = planningPegawaiStatusDao.getDataMapPermohonanStatus(id);
		Map<String, Object> mapJabatanUtama = mapPegawaiJabatanToUnitKerjaDao.getMapJabatanUtamaByPegawai(id);

		result.putAll(mapJabatanUtama);

		return result;
	}

	@Override
	public Integer countSisaCuti(Integer dataCuti, Integer cutiTerpakai, Integer cutiBersama, Boolean isTangguhkan) {
		if (dataCuti - difCutiTerpakai(cutiTerpakai, cutiBersama) > 6 && !isTangguhkan) {
			return 6;
		} else {
			return dataCuti - difCutiTerpakai(cutiTerpakai, cutiBersama);
		}
	}

	@Override
	public Integer difCutiTerpakai(Integer cutiTerpakai, Integer dataCuti) {
		Integer difCutiTerpakai = 0;
		if (cutiTerpakai > dataCuti) {
			difCutiTerpakai = cutiTerpakai - dataCuti;
		} else {
			difCutiTerpakai = 0;
		}
		return difCutiTerpakai;
	}

	@Override
	public Map<String, Object> getDataCuti(Integer pegawaiId, String year, Integer statusPegawaiId) {
		Map<String, Object> result = new HashMap<>();

		List<Integer> listKomponenIndex = new ArrayList<>();

		Integer sisaCuti = 0;
		Integer sisaCutiB2 = 0;
		Integer sisaCutiB1 = 0;
		Integer sisaCutiB = 0;
		Integer sisaCutiN2 = 0;
		Integer sisaCutiN1 = 0;
		Integer sisaCutiN = 0;
		Integer jatahCuti = 0;
		Integer sisaJatahRawatJalan = 0;
		Integer sisaJatahRawatInap = 0;
		Integer sisaIzin = 0;

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		SimpleDateFormat formatter = new SimpleDateFormat("yyyy");
		if (CommonUtil.isNullOrEmpty(year)) {
			year = formatter.format(DateUtil.now());
		}

		Integer yearn1 = Integer.parseInt(year) - 1;
		Integer yearn2 = Integer.parseInt(year) - 2;
		Integer yearn3 = Integer.parseInt(year) + 1;
		String yearN1 = yearn1.toString();
		String yearN2 = yearn2.toString();
		String yearN3 = yearn3.toString();

		if (statusPegawaiId == 5 || statusPegawaiId == 1 || statusPegawaiId == 21) {
			// ------------------------------------------SETTING_DATA_FIX------------------------------------------
			String komponen = Master.KomponenIndex.CUTI_NONSHIFT.toString();
			String komponenIndeksCutiShift = Master.KomponenIndex.CUTI_SHIFT.toString();
			String komponenIndeksCutiBersama = Master.KomponenIndex.CUTI_BERSAMA.toString();

			listKomponenIndex.add(Integer.valueOf(komponen));
			listKomponenIndex.add(Integer.valueOf(komponenIndeksCutiShift));

			// Initiate cuti bersama
			Integer cutiTerpakaiB2 = 0;
			Integer cutiTerpakaiB1 = 0;
			Integer cutiTerpakaiB = 0;
			// Menghitung cuti terpakai tahun n-2
			Integer cutiTerpakaiN2 = pegawaiHistoriRekapIndexDao.getCutiTerpakai(yearN2, pegawaiId, listKomponenIndex);
			if (CommonUtil.isNullOrEmpty(cutiTerpakaiN2)) {
				cutiTerpakaiN2 = 0;
			}
			// Menghitung cuti terpakai tahun n-1
			Integer cutiTerpakaiN1 = pegawaiHistoriRekapIndexDao.getCutiTerpakai(yearN1, pegawaiId, listKomponenIndex);
			if (CommonUtil.isNullOrEmpty(cutiTerpakaiN1)) {
				cutiTerpakaiN1 = 0;
			}
			// Menghitung cuti terpakai tahun n
			Integer cutiTerpakaiN = pegawaiHistoriRekapIndexDao.getCutiTerpakai(year, pegawaiId, listKomponenIndex);
			if (CommonUtil.isNullOrEmpty(cutiTerpakaiN)) {
				cutiTerpakaiN = 0;
			}

			// Menghitung cuti terpakai by histori pengajuan
			Integer jumlahTglByPengajuan = pegawaiHistoriRekapIndexDao.getHistoriCutiTerpakaiByTahunPengajuan(year,
					pegawaiId, listKomponenIndex);
			if (CommonUtil.isNullOrEmpty(jumlahTglByPengajuan)) {
				jumlahTglByPengajuan = 0;
			}

			Integer rekapHistoriCutiTerpakai = pegawaiHistoriRekapIndexDao.getHistoriCutiTerpakai(yearN2, pegawaiId,
					listKomponenIndex);
			if (CommonUtil.isNullOrEmpty(rekapHistoriCutiTerpakai)) {
				rekapHistoriCutiTerpakai = 0;
			}
			Integer dataHistoriCutiTerpakai = jatahCutiDanIzinDao.getHistoriCutiTerpakai(pegawaiId, yearN2);
			if (CommonUtil.isNullOrEmpty(dataHistoriCutiTerpakai)) {
				dataHistoriCutiTerpakai = 0;
			}

			Integer diffHistori = dataHistoriCutiTerpakai - rekapHistoriCutiTerpakai;
			if (rekapHistoriCutiTerpakai < dataHistoriCutiTerpakai) {
				if (cutiTerpakaiN2 > diffHistori) {
					cutiTerpakaiN2 -= diffHistori;
				} else {
					diffHistori -= cutiTerpakaiN2;
					cutiTerpakaiN2 = 0;
					if (cutiTerpakaiN1 > diffHistori) {
						cutiTerpakaiN1 -= diffHistori;
					} else {
						diffHistori -= cutiTerpakaiN1;
						cutiTerpakaiN1 = 0;
						if (cutiTerpakaiN > diffHistori) {
							cutiTerpakaiN -= diffHistori;
						} else {
							cutiTerpakaiN = 0;
						}
					}
				}
			} else {
				// impossible scenario
			}

			// Mendapatkan seluruh data jatah cuti untuk pegawai tertentu
			Integer dataCutiB2 = jatahCutiDanIzinDao.getDataCuti(yearN2, pegawaiId,
					Integer.valueOf(komponenIndeksCutiBersama)); // dataCutiBersama_di_n-2
			Integer dataCutiB1 = jatahCutiDanIzinDao.getDataCuti(yearN1, pegawaiId,
					Integer.valueOf(komponenIndeksCutiBersama)); // dataCutiBersama_di_n-1
			Integer dataCutiB = jatahCutiDanIzinDao.getDataCuti(year, pegawaiId,
					Integer.valueOf(komponenIndeksCutiBersama)); // dataCutiBersama_di_n
			Integer dataCutiN2 = jatahCutiDanIzinDao.getDataCuti(yearN2, pegawaiId, Integer.valueOf(komponen)); // dataCutiTahunan_tahun_n-2
			Integer dataCutiN1 = jatahCutiDanIzinDao.getDataCuti(yearN1, pegawaiId, Integer.valueOf(komponen)); // dataCutiTahunan_tahun_n-1
			Integer dataCutiN = jatahCutiDanIzinDao.getDataCuti(year, pegawaiId, Integer.valueOf(komponen)); // dataCutiTahunan_tahun_n
			Integer dataCutiN3 = jatahCutiDanIzinDao.getDataCuti(yearN3, pegawaiId, Integer.valueOf(komponen)); // dataCutiTahunan_tahun_n+1
			// Validasi existing data
			if (CommonUtil.isNullOrEmpty(dataCutiB2)) {
				dataCutiB2 = 0;
			}
			if (CommonUtil.isNullOrEmpty(dataCutiB1)) {
				dataCutiB1 = 0;
			}
			if (CommonUtil.isNullOrEmpty(dataCutiB)) {
				dataCutiB = 0;
			}
			if (CommonUtil.isNullOrEmpty(dataCutiN2)) {
				dataCutiN2 = 0;
			}
			if (CommonUtil.isNullOrEmpty(dataCutiN1)) {
				dataCutiN1 = 0;
			}
			if (CommonUtil.isNullOrEmpty(dataCutiN)) {
				dataCutiN = 0;
			}
			if (CommonUtil.isNullOrEmpty(dataCutiN3)) {
				dataCutiN3 = 12;
			}

			// mapping jatah cuti
			result.put("dataCutiB2", dataCutiB2);
			result.put("dataCutiB1", dataCutiB1);
			result.put("dataCutiB", dataCutiB);
			result.put("dataCutiN2", dataCutiN2);
			result.put("dataCutiN1", dataCutiN1);
			result.put("dataCutiN", dataCutiN);
			result.put("dataCutiN3", dataCutiN3);

			// Hitung Absen di tanggal cuti bersama
			List<String> listTglCutiBersama = mapKalenderToHariLiburDao.getTglCutiBersama(year);
			int countDataHabsen = 0;
			for (String tglStr : listTglCutiBersama) {
				List<Date> dataHabsen = new ArrayList<>();

				// cek shift malam
				String tglPrev = sdf.format(java.sql.Date.valueOf(LocalDate.parse(tglStr).minusDays(1)));
				List<Map<String, Object>> listMap = pegawaiJadwalKerjaDao.getNamaShiftKerjaPegawaiByTanggal(tglPrev,
						tglStr, pegawaiId);
				if (listMap.size() == 2) {
					if (!listMap.get(0).get("namaShift").toString().toLowerCase().contains("malam")
							&& listMap.get(1).get("namaShift").toString().toLowerCase().contains("malam")) {
						dataHabsen = habsenDao.countAbsenTglCutiBersama(tglStr, pegawaiDao.getidFinger(pegawaiId));
					} else if (listMap.get(0).get("namaShift").toString().toLowerCase().contains("malam")
							&& listMap.get(1).get("namaShift").toString().toLowerCase().contains("malam")) {
						dataHabsen = habsenDao.countAbsenTglCutiBersama(tglStr, pegawaiDao.getidFinger(pegawaiId));
					} else if (!listMap.get(0).get("namaShift").toString().toLowerCase().contains("malam")
							&& !listMap.get(1).get("namaShift").toString().toLowerCase().contains("malam")) {
						dataHabsen = habsenDao.countAbsenTglCutiBersama(tglStr, pegawaiDao.getidFinger(pegawaiId));
					}
				}

				if (CommonUtil.isNotNullOrEmpty(dataHabsen)) {
					if (listMap.size() == 2) {
						if (Arrays.asList(Master.ShiftKerja.TUJUH_BELAS_JAM_SHIFT)
								.contains(Integer.parseInt(listMap.get(1).get("idShift").toString()))) {
							countDataHabsen += 2;
						} else {
							countDataHabsen += 1;
						}
					} else {
						countDataHabsen += 1;
					}
				} else {
					// cuti tahunan di tanggal cuti bersama
					List<Date> tglCutiTahunanDiTglCutiBersama = jatahCutiDanIzinDao
							.getCutiTahunanDiTglCutiBersama(Master.StatusPegawai.CUTI_TAHUNAN, pegawaiId, tglStr);
					if (CommonUtil.isNotNullOrEmpty(tglCutiTahunanDiTglCutiBersama)) {
						if (listMap.size() == 2) {
							if (Arrays.asList(Master.ShiftKerja.TUJUH_BELAS_JAM_SHIFT)
									.contains(Integer.parseInt(listMap.get(1).get("idShift").toString()))) {
								countDataHabsen += 2;
							} else {
								countDataHabsen += 1;
							}
						} else {
							countDataHabsen += 1;
						}
					}
				}
			}
			dataCutiB = countDataHabsen;
			result.put("dataCutiB", dataCutiB);

			// kondisikan cuti bersama yg sudah berlalu
			if (cutiTerpakaiN2 > dataCutiB2) {
				cutiTerpakaiB2 = dataCutiB2;
			} else {
				cutiTerpakaiB2 = cutiTerpakaiN2;
			}
			if (cutiTerpakaiN1 > dataCutiB1) {
				cutiTerpakaiB1 = dataCutiB1;
			} else {
				cutiTerpakaiB1 = cutiTerpakaiN1;
			}

			// Mendapatkan kondisi penangguhan saat ini
			result.put("isTangguhkanB2", false);
			result.put("isTangguhkanB1", false);
			result.put("isTangguhkanB", false);
			Boolean jCutiN2 = jatahCutiDanIzinDao.getPenangguhanSisaCuti(yearN2, pegawaiId, Integer.valueOf(komponen));
			if (CommonUtil.isNotNullOrEmpty(jCutiN2)) {
				result.put("isTangguhkanN2", jCutiN2);
			} else {
				jCutiN2 = false;
				result.put("isTangguhkanN2", false);
			}
			Boolean jCutiN1 = jatahCutiDanIzinDao.getPenangguhanSisaCuti(yearN1, pegawaiId, Integer.valueOf(komponen));
			if (CommonUtil.isNotNullOrEmpty(jCutiN1)) {
				result.put("isTangguhkanN1", jCutiN1);
			} else {
				jCutiN1 = false;
				result.put("isTangguhkanN1", false);
			}
			Boolean jCutiN = jatahCutiDanIzinDao.getPenangguhanSisaCuti(year, pegawaiId, Integer.valueOf(komponen));
			if (CommonUtil.isNotNullOrEmpty(jCutiN)) {
				result.put("isTangguhkanN", jCutiN);
			} else {
				jCutiN = false;
				result.put("isTangguhkanN", false);
			}

			// formula menghitung sisa cuti bersama dan mapping
			if (dataCutiB >= cutiTerpakaiN) {
				sisaCutiB = dataCutiB - cutiTerpakaiN;
				cutiTerpakaiB = cutiTerpakaiN;
				result.put("sisaCutiB2", sisaCutiB2);
				result.put("sisaCutiB1", sisaCutiB1);
				result.put("sisaCutiB", sisaCutiB);
				result.put("cutiTerpakaiB2", cutiTerpakaiB2);
				result.put("cutiTerpakaiB1", cutiTerpakaiB1);
				result.put("cutiTerpakaiB", cutiTerpakaiB);
			} else { // jika cuti terpakai tahun berjalan lebih besar dari jatah
						// cuti bersama
				sisaCutiB = 0;
				cutiTerpakaiB = dataCutiB;
				result.put("sisaCutiB2", sisaCutiB2);
				result.put("sisaCutiB1", sisaCutiB1);
				result.put("sisaCutiB", sisaCutiB);
				result.put("cutiTerpakaiB2", cutiTerpakaiB2);
				result.put("cutiTerpakaiB1", cutiTerpakaiB1);
				result.put("cutiTerpakaiB", cutiTerpakaiB);
			}

			// menghitung jatah cuti yang terpakai
			Integer jatahCutiTerpakaiN2 = 0, jatahCutiTerpakaiN1 = 0, jatahCutiTerpakaiN = 0;
			Integer allCutiTerpakai = difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
					+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) + difCutiTerpakai(cutiTerpakaiN, dataCutiB);
			if (dataCutiN2 > 0) {
				if (allCutiTerpakai >= dataCutiN2) {
					if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
							+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 12) {
						jatahCutiTerpakaiN2 = difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
								+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1);
					} else {
						jatahCutiTerpakaiN2 = dataCutiN2;
					}

					// menghitung sisa cuti terlebih dahulu
					if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
							+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 12) {
						if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2) > 0) {
							sisaCutiN2 = 0; // hangus
						} else {
							if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
									+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 6 && dataCutiN2 > 0) {
								if (jatahCutiTerpakaiN2 == 0 && !jCutiN1) {
									sisaCutiN2 = 6;
								} else if (jatahCutiTerpakaiN2 == 0 && jCutiN1) {
									sisaCutiN2 = 0;
								} else if (!jCutiN2 && !jCutiN1) {
									sisaCutiN2 = 6 - jatahCutiTerpakaiN2;
								} else {
									sisaCutiN2 = 0;
								}
							} else if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
									+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 6 && dataCutiN2 <= 0) {
								sisaCutiN2 = 0;
							} else {
								sisaCutiN2 = dataCutiN2 - jatahCutiTerpakaiN2;
							}
						}
					} else {
						if (dataCutiN2 - jatahCutiTerpakaiN2 >= 6 && !jCutiN2) {
							sisaCutiN2 = 6 - jatahCutiTerpakaiN2;
						} else {
							sisaCutiN2 = dataCutiN2 - jatahCutiTerpakaiN2;
						}
					}
					// hitung ulang jatah cuti terpakai karena pengajuan cuti
					// tahun n menggunakan sisa n-2
					if (sisaCutiN2 > 0 && difCutiTerpakai(cutiTerpakaiN, dataCutiB) > 0) {
						if (sisaCutiN2 > difCutiTerpakai(cutiTerpakaiN, dataCutiB)) {
							jatahCutiTerpakaiN2 += difCutiTerpakai(cutiTerpakaiN, dataCutiB);
						} else {
							jatahCutiTerpakaiN2 += sisaCutiN2;
						}
					}

					allCutiTerpakai = allCutiTerpakai - jatahCutiTerpakaiN2;
					if (allCutiTerpakai > 0) {
						if (allCutiTerpakai >= dataCutiN1) {
							jatahCutiTerpakaiN1 = dataCutiN1;
							allCutiTerpakai = allCutiTerpakai - jatahCutiTerpakaiN1;
							if ((allCutiTerpakai > 0) && (allCutiTerpakai <= dataCutiN)) {
								jatahCutiTerpakaiN = allCutiTerpakai;
							} else {
								jatahCutiTerpakaiN = 0;
							}
						} else {
							jatahCutiTerpakaiN1 = allCutiTerpakai;
						}
					}
				} else {
					if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
							+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 12) {
						jatahCutiTerpakaiN2 = difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
								+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1);
					} else {
						jatahCutiTerpakaiN2 = allCutiTerpakai;
					}

					// menghitung sisa cuti terlebih dahulu
					if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
							+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 12) {
						if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2) > 0) {
							sisaCutiN2 = 0; // hangus
						} else {
							if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
									+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 6 && dataCutiN2 > 0) {
								if (jatahCutiTerpakaiN2 == 0 && !jCutiN1) {
									sisaCutiN2 = 6;
								} else if (jatahCutiTerpakaiN2 == 0 && jCutiN1) {
									sisaCutiN2 = 0;
								} else if (!jCutiN2 && !jCutiN1) {
									sisaCutiN2 = 6 - jatahCutiTerpakaiN2;
								} else {
									sisaCutiN2 = 0;
								}
							} else if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
									+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 6 && dataCutiN2 <= 0) {
								sisaCutiN2 = 0;
							} else {
								sisaCutiN2 = dataCutiN2 - jatahCutiTerpakaiN2;
							}
						}
					} else {
						if (dataCutiN2 - jatahCutiTerpakaiN2 >= 6 && !jCutiN2) {
							sisaCutiN2 = 6 - jatahCutiTerpakaiN2;
						} else {
							sisaCutiN2 = dataCutiN2 - jatahCutiTerpakaiN2;
						}
					}
					// hitung ulang jatah cuti terpakai karena pengajuan cuti
					// tahun n menggunakan sisa n-2
					if (sisaCutiN2 > 0 && difCutiTerpakai(cutiTerpakaiN, dataCutiB) > 0) {
						if (sisaCutiN2 > difCutiTerpakai(cutiTerpakaiN, dataCutiB)) {
							jatahCutiTerpakaiN2 += difCutiTerpakai(cutiTerpakaiN, dataCutiB);
						} else {
							jatahCutiTerpakaiN2 += sisaCutiN2;
						}
					}

					allCutiTerpakai = allCutiTerpakai - jatahCutiTerpakaiN2;
					if (allCutiTerpakai > 0) {
						if (allCutiTerpakai >= dataCutiN1) {
							jatahCutiTerpakaiN1 = dataCutiN1;
							allCutiTerpakai = allCutiTerpakai - jatahCutiTerpakaiN1;
							if ((allCutiTerpakai > 0) && (allCutiTerpakai <= dataCutiN)) {
								jatahCutiTerpakaiN = allCutiTerpakai;
							} else {
								jatahCutiTerpakaiN = 0;
							}
						} else {
							jatahCutiTerpakaiN1 = allCutiTerpakai;
						}
					}
				}
			} else if (dataCutiN1 > 0) {
				if (allCutiTerpakai >= dataCutiN1) {
					jatahCutiTerpakaiN1 = dataCutiN1;
					allCutiTerpakai = allCutiTerpakai - jatahCutiTerpakaiN1;
					if ((allCutiTerpakai > 0) && (allCutiTerpakai <= dataCutiN)) {
						jatahCutiTerpakaiN = allCutiTerpakai;
					} else {
						jatahCutiTerpakaiN = 0;
					}
				} else {
					jatahCutiTerpakaiN1 = allCutiTerpakai;
				}
			} else if (dataCutiN > 0) {
				if (allCutiTerpakai <= dataCutiN) {
					jatahCutiTerpakaiN = allCutiTerpakai;
				} else {
					jatahCutiTerpakaiN = 0;
				}
			}

			// Menghitung cuti terpakai tahun n+1
			Integer cutiTerpakaiN3 = pegawaiHistoriRekapIndexDao.getCutiTerpakai(yearN3, pegawaiId, listKomponenIndex);
			if (CommonUtil.isNullOrEmpty(cutiTerpakaiN3)) {
				cutiTerpakaiN3 = 0;
			}

			if (cutiTerpakaiN3 > 0) {
				// menghitung sisa cuti n-1 terlebih dahulu
				if (dataCutiN1 - jatahCutiTerpakaiN1 >= 6 && !jCutiN1) {
					sisaCutiN1 = 6 - jatahCutiTerpakaiN1;
				} else {
					sisaCutiN1 = dataCutiN1 - jatahCutiTerpakaiN1;
				}

				// juga menghitung sisa cuti n terlebih dahulu
				sisaCutiN = dataCutiN - jatahCutiTerpakaiN;

				// menghitung jatah cuti terpakai karena pengajuan lintas tahun
				if (difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) == 0 && !jCutiN1) {
					if (sisaCutiN1 > 0) {
						if (cutiTerpakaiN3 > sisaCutiN1) {
							jatahCutiTerpakaiN1 += sisaCutiN1;
							cutiTerpakaiN3 -= sisaCutiN1;
							if (cutiTerpakaiN3 > 0 && sisaCutiN > 0) {
								if (cutiTerpakaiN3 > sisaCutiN) {
									jatahCutiTerpakaiN += sisaCutiN;
								} else {
									jatahCutiTerpakaiN += cutiTerpakaiN3;
								}
							}
						} else {
							jatahCutiTerpakaiN1 += cutiTerpakaiN3;
						}
					} else if (sisaCutiN > 0) {
						if (cutiTerpakaiN3 > sisaCutiN) {
							jatahCutiTerpakaiN += sisaCutiN;
						} else {
							jatahCutiTerpakaiN += cutiTerpakaiN3;
						}
					}
				} else {
					if (sisaCutiN > 0) {
						if (cutiTerpakaiN3 > sisaCutiN) {
							jatahCutiTerpakaiN += sisaCutiN;
						} else {
							jatahCutiTerpakaiN += cutiTerpakaiN3;
						}
					}
				}
			}

			// put all data jatah cuti terpakai
			result.put("cutiTerpakaiN2", jatahCutiTerpakaiN2);
			result.put("cutiTerpakaiN1", jatahCutiTerpakaiN1);
			result.put("cutiTerpakaiN", jatahCutiTerpakaiN);

			// menghitung sisa cuti
			if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2) + difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 12) {
				if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2) > 0) {
					sisaCutiN2 = 0; // hangus
				} else {
					if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2) + difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 6
							&& dataCutiN2 > 0) {
						if (jatahCutiTerpakaiN2 == 0 && !jCutiN1) {
							sisaCutiN2 = 6;
						} else if (jatahCutiTerpakaiN2 == 0 && jCutiN1) {
							sisaCutiN2 = 0;
						} else if (!jCutiN2 && !jCutiN1) {
							sisaCutiN2 = 6 - jatahCutiTerpakaiN2;
						} else {
							sisaCutiN2 = 0;
						}
					} else if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
							+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) < 6 && dataCutiN2 <= 0) {
						sisaCutiN2 = 0;
					} else if (difCutiTerpakai(cutiTerpakaiN2, dataCutiB2)
							+ difCutiTerpakai(cutiTerpakaiN1, dataCutiB1) > 6 && jCutiN1) {
						sisaCutiN2 = 0;
					} else {
						sisaCutiN2 = dataCutiN2 - jatahCutiTerpakaiN2;
					}
				}
			} else {
				if (dataCutiN2 - jatahCutiTerpakaiN2 >= 6 && !jCutiN2) {
					sisaCutiN2 = 6 - jatahCutiTerpakaiN2;
				} else {
					sisaCutiN2 = dataCutiN2 - jatahCutiTerpakaiN2;
				}
			}
			if (dataCutiN1 - jatahCutiTerpakaiN1 >= 6 && !jCutiN1) {
				jumlahTglByPengajuan -= (dataHistoriCutiTerpakai + jatahCutiTerpakaiN2 + cutiTerpakaiB + cutiTerpakaiB1
						+ cutiTerpakaiB2);

				if (jumlahTglByPengajuan < 0) {
					jumlahTglByPengajuan = 0;
				}

				if (jumlahTglByPengajuan > jatahCutiTerpakaiN1) {
					sisaCutiN1 = 6;
				} else {
					sisaCutiN1 = 6 - (jatahCutiTerpakaiN1 - jumlahTglByPengajuan);
				}
			} else {
				sisaCutiN1 = dataCutiN1 - jatahCutiTerpakaiN1;
			}
			sisaCutiN = dataCutiN - jatahCutiTerpakaiN;

			// put all data sisa cuti
			result.put("sisaCutiN2", sisaCutiN2);
			result.put("sisaCutiN1", sisaCutiN1);
			result.put("sisaCutiN", sisaCutiN);
		}
		if (statusPegawaiId == 24) {
			// ------------------------------------------SETTING_DATA_FIX------------------------------------------
			if (CommonUtil.isNotNullOrEmpty(jatahCuti)) {
				result.put("jatahCuti", "-");
			}
			result.put("sisaCuti", "-");
		}

		if (statusPegawaiId == 25) {
			// ------------------------------------------SETTING_DATA_FIX------------------------------------------
			Map<String, Object> data = planningPegawaiStatusDao.getJatahCutiMelahirkan(statusPegawaiId);
			if (CommonUtil.isNotNullOrEmpty(jatahCuti)) {
				result.put("jatahCuti", data.get("kuotaTotalHari"));
			}
			result.put("sisaCuti", "-");
		}

		if (statusPegawaiId == 26) {
			// ------------------------------------------SETTING_DATA_FIX------------------------------------------
			if (CommonUtil.isNotNullOrEmpty(jatahCuti)) {
				result.put("jatahCuti", "-");
			}
			result.put("sisaCuti", "-");
		}
		// Izin
		if (statusPegawaiId == 27) {
			Integer komponenIzin = 17; // komponenIndex untuk izin
			Integer jatahIzin = 2; // sesuai kesepakatan

			Integer jumlahIzinTerpakai = pegawaiHistoriRekapIndexDao.getIzinTerpakai(pegawaiId, komponenIzin);
			if (CommonUtil.isNotNullOrEmpty(jumlahIzinTerpakai)) {
				sisaIzin = jatahIzin - jumlahIzinTerpakai;
			} else {
				sisaIzin = jatahIzin;
			}

			result.put("jatahIzin", jatahIzin);
			result.put("sisaIzin", sisaIzin);
		}
		if (statusPegawaiId == 28) {
			// ------------------------------------------SETTING_DATA_FIX------------------------------------------
			if (CommonUtil.isNotNullOrEmpty(jatahCuti)) {
				result.put("jatahCuti", "-");
			}
			result.put("sisaCuti", "-");
		}
		if (statusPegawaiId == 17) {
			// ------------------------------------------SETTING_DATA_FIX------------------------------------------
			Integer cutiTerpakai = pegawaiHistoriRekapIndexDao.getNilaiIndexPegawaiHistoriRekapIndex(pegawaiId, 17);
			Integer dataCuti = jatahCutiDanIzinDao.getDataCuti(year, pegawaiId, 17);
			if (CommonUtil.isNotNullOrEmpty(dataCuti)) {
				if (CommonUtil.isNullOrEmpty(cutiTerpakai)) {
					cutiTerpakai = 0;
				}
				sisaCuti = dataCuti - cutiTerpakai;
				if (sisaCuti < 0) {
					sisaCuti = 0;
				}
			} else {
				sisaCuti = 0;
				dataCuti = 0;
			}
			result.put("sisaCuti", sisaCuti);
			result.put("jatahCuti", dataCuti);
		}
		// sakit
		if (statusPegawaiId == 29 || statusPegawaiId == 6) {
			// ------------------------------------------SETTING_DATA_FIX------------------------------------------
			Integer komponenSakit = 7;
			Integer komponenSakitShift = 8;

			Integer jumlahRawatJalan = pegawaiHistoriRekapIndexDao.getSakitTerpakai(pegawaiId, komponenSakit, 1);
			if (CommonUtil.isNullOrEmpty(jumlahRawatJalan)) {
				jumlahRawatJalan = pegawaiHistoriRekapIndexDao.getSakitTerpakai(pegawaiId, komponenSakitShift, 1);
			}

			Integer jumlahRawatInap = pegawaiHistoriRekapIndexDao.getSakitTerpakai(pegawaiId, komponenSakit, 2);
			if (CommonUtil.isNullOrEmpty(jumlahRawatInap)) {
				jumlahRawatInap = pegawaiHistoriRekapIndexDao.getSakitTerpakai(pegawaiId, komponenSakitShift, 2);
			}

			if ((CommonUtil.isNotNullOrEmpty(jumlahRawatJalan)) || (CommonUtil.isNotNullOrEmpty(jumlahRawatInap))) {
				sisaJatahRawatJalan = 3 - jumlahRawatJalan;
				sisaJatahRawatInap = 5 - jumlahRawatInap;
			}
			result.put("sisaJatahRawatJalan", sisaJatahRawatJalan);
			result.put("sisaJatahRawatInap", sisaJatahRawatInap);
		}

		return result;
	}

	@Override
	public boolean validateTanggalPermohonanRev(Integer statusPegawaiPlanVOId, Set<ListTanggalCutiVO> listTanggalCutiVO,
			Integer idPegawaiVO) {
		List<String> listNorec = new ArrayList<>();
		List<String> listTahunPengajuanCuti = new ArrayList<>();
		List<Date> listTgl = new ArrayList<>();
		List<Date> listTanggalSudahDiajukan = new ArrayList<>();
		List<Date> listTglPeriode = new ArrayList<>();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat y = new SimpleDateFormat("yyyy");

		int listTglSize = 0;

		for (ListTanggalCutiVO vo : listTanggalCutiVO) {
			if (!listTahunPengajuanCuti.contains(y.format(vo.getTgl()))) {
				listTahunPengajuanCuti.add(y.format(vo.getTgl()));
			}
		}

		List<Map<String, Object>> allPlanningNonPeriodik = permohonanCutiPegawaiDao.getAllPlanning(idPegawaiVO,
				Master.PengajuanCuti.DITANGGUHKAN,
				Arrays.asList(Master.StatusPegawai.NONPERIODIK_PENGAJUAN_KETIDAKHADIRAN), listTahunPengajuanCuti);
		List<Map<String, Object>> allPlanningPeriodik = permohonanCutiPegawaiDao.getAllPlanning(idPegawaiVO,
				Master.PengajuanCuti.DITANGGUHKAN,
				Arrays.asList(Master.StatusPegawai.PERIODIK_PENGAJUAN_KETIDAKHADIRAN), listTahunPengajuanCuti);

		if (CommonUtil.isNotNullOrEmpty(allPlanningNonPeriodik)) {
			for (Map<String, Object> map : allPlanningNonPeriodik) {
				listTanggalSudahDiajukan.add((Date) map.get("tgl"));
			}
		}
		if (CommonUtil.isNotNullOrEmpty(allPlanningPeriodik)) {
			for (Map<String, Object> map : allPlanningPeriodik) {
				if (!listNorec.contains(map.get("noRec").toString())) {
					listNorec.add(map.get("noRec").toString());
				}
			}

			for (String norec : listNorec) {
				listTglPeriode.clear();
				for (Map<String, Object> map : allPlanningPeriodik) {
					if (norec.equals(map.get("noRec").toString())) {
						listTglPeriode.add((Date) map.get("tgl"));
					}
				}
				Collections.sort(listTglPeriode);
				List<Date> listTglDetail = new ArrayList<>();
				if (listTglPeriode.size() == 2) {
					List<Date> listDetailTglPeriode = kalenderDao.getDateFromPeriodicParameter(
							sdf.format(listTglPeriode.get(0)), sdf.format(listTglPeriode.get(1)));
					for (Date tgl : listDetailTglPeriode) {
						Date dateDetail = DateUtils.addHours(tgl, 7);
						listTglDetail.add(dateDetail);
					}
					listTanggalSudahDiajukan.addAll(listTglDetail);
				} else {
					listTanggalSudahDiajukan.addAll(listTglPeriode);
				}
			}
		}

		if (Arrays.asList(Master.StatusPegawai.PERIODIK_PENGAJUAN_KETIDAKHADIRAN).contains(statusPegawaiPlanVOId)) {
			for (ListTanggalCutiVO vo : listTanggalCutiVO) {
				listTgl.add(vo.getTgl());
			}
			Collections.sort(listTgl);
			List<Date> listTglDetail = new ArrayList<>();
			if (listTgl.size() == 2) {
				listTgl = kalenderDao.getDateFromPeriodicParameter(sdf.format(listTgl.get(0)),
						sdf.format(listTgl.get(1)));
				for (Date tgl : listTgl) {
					Date dateDetail = DateUtils.addHours(tgl, 7);
					listTglDetail.add(dateDetail);
				}
				listTgl.clear();
				listTgl.addAll(listTglDetail);
				listTglSize = listTgl.size();
			} else {
				listTglSize = listTgl.size();
			}
		} else {
			for (ListTanggalCutiVO vo : listTanggalCutiVO) {
				listTgl.add(vo.getTgl());
			}
			listTglSize = listTgl.size();
		}

		if (CommonUtil.isNotNullOrEmpty(listTanggalSudahDiajukan)) {
			listTgl.removeAll(listTanggalSudahDiajukan);
			if (listTgl.size() != listTglSize) {
				return false; // tidak bisa cuti
			} else {
				return true; // bisa cuti
			}
		} else {
			return true; // bisa cuti
		}
	}

	@Override
	public boolean validateTanggalPermohonan(Integer statusPegawaiPlanId, Set<ListTanggalCutiVO> listTanggalCutiVO,
			Integer idPegawai) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		List<String> listNorecPlanning = permohonanCutiPegawaiDao.getAllNorecPlanning(idPegawai);
		if (CommonUtil.isNotNullOrEmpty(listNorecPlanning)) {
			List<Date> listTgl = new ArrayList<>();
			List<Date> listTanggalSudahDiajukan = new ArrayList<>();
			if (Arrays.asList(Master.StatusPegawai.PERIODIK_PENGAJUAN_KETIDAKHADIRAN).contains(statusPegawaiPlanId)) {
				int listTglSize = 0;
				for (ListTanggalCutiVO vo : listTanggalCutiVO) {
					listTgl.add(vo.getTgl());
				}
				Collections.sort(listTgl);
				List<Date> listTglAdjust = new ArrayList<>();
				if (listTgl.size() == 2) {
					listTgl = kalenderDao.getDateFromPeriodicParameter(sdf.format(listTgl.get(0)),
							sdf.format(listTgl.get(1)));
					for (Date tgl : listTgl) {
						Date dateAdjust = DateUtils.addHours(tgl, 7);
						listTglAdjust.add(dateAdjust);
					}
					listTgl.clear();
					listTgl.addAll(listTglAdjust);
					listTglSize = listTgl.size();
				} else {
					listTglSize = listTgl.size();
				}
				List<Date> listAllTanggalCutiApproved = planningPegawaiStatusDao
						.getListAllTanggalCutiApproved(listNorecPlanning, listTgl);
				List<Date> listAllTanggalCutiNotYetApprove = planningPegawaiStatusDao
						.getListAllTanggalCutiNotYetApprove(listNorecPlanning, listTgl);
				if (CommonUtil.isNotNullOrEmpty(listAllTanggalCutiApproved)) {
					listTanggalSudahDiajukan.addAll(listAllTanggalCutiApproved);
				}
				if (CommonUtil.isNotNullOrEmpty(listAllTanggalCutiNotYetApprove)) {
					listTanggalSudahDiajukan.addAll(listAllTanggalCutiNotYetApprove);
				}
				if (CommonUtil.isNotNullOrEmpty(listTanggalSudahDiajukan)) {
					listTgl.removeAll(listTanggalSudahDiajukan);
					if (listTgl.size() != listTglSize) {
						return false; // tidak bisa cuti
					} else {
						return true; // bisa cuti
					}
				} else {
					return true; // bisa cuti
				}
			} else {
				for (ListTanggalCutiVO vo : listTanggalCutiVO) {
					listTgl.add(vo.getTgl());
				}
				if (CommonUtil.isNotNullOrEmpty(
						planningPegawaiStatusDao.getListAllTanggalCutiApproved(listNorecPlanning, listTgl))) {
					listTanggalSudahDiajukan = planningPegawaiStatusDao.getListAllTanggalCutiApproved(listNorecPlanning,
							listTgl);
				}
				if (CommonUtil.isNotNullOrEmpty(
						planningPegawaiStatusDao.getListAllTanggalCutiNotYetApprove(listNorecPlanning, listTgl))) {
					listTanggalSudahDiajukan.addAll(
							planningPegawaiStatusDao.getListAllTanggalCutiNotYetApprove(listNorecPlanning, listTgl));
				}
				if (CommonUtil.isNotNullOrEmpty(listTanggalSudahDiajukan)) {
					return false; // tidak bisa cuti
				} else {
					return true; // bisa cuti
				}
			}
		} else {
			return true; // bisa cuti
		}
	}

	@Override
	public boolean validateTanggalPermohonanRev(List<Date> listTgl, Integer idPegawaiVO) {
		List<String> listNorec = new ArrayList<>();
		List<String> listTahunPengajuanCuti = new ArrayList<>();
		List<Date> listTanggalSudahDiajukan = new ArrayList<>();
		List<Date> listTglPeriode = new ArrayList<>();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat y = new SimpleDateFormat("yyyy");

		int listTglSize = listTgl.size();

		for (Date tglPengajuanEdit : listTgl) {
			if (!listTahunPengajuanCuti.contains(y.format(tglPengajuanEdit))) {
				listTahunPengajuanCuti.add(y.format(tglPengajuanEdit));
			}
		}

		List<Map<String, Object>> allPlanningNonPeriodik = permohonanCutiPegawaiDao.getAllPlanning(idPegawaiVO,
				Master.PengajuanCuti.DITANGGUHKAN,
				Arrays.asList(Master.StatusPegawai.NONPERIODIK_PENGAJUAN_KETIDAKHADIRAN), listTahunPengajuanCuti);
		List<Map<String, Object>> allPlanningPeriodik = permohonanCutiPegawaiDao.getAllPlanning(idPegawaiVO,
				Master.PengajuanCuti.DITANGGUHKAN,
				Arrays.asList(Master.StatusPegawai.PERIODIK_PENGAJUAN_KETIDAKHADIRAN), listTahunPengajuanCuti);

		if (CommonUtil.isNotNullOrEmpty(allPlanningNonPeriodik)) {
			for (Map<String, Object> map : allPlanningNonPeriodik) {
				listTanggalSudahDiajukan.add((Date) map.get("tgl"));
			}
		}
		if (CommonUtil.isNotNullOrEmpty(allPlanningPeriodik)) {
			for (Map<String, Object> map : allPlanningPeriodik) {
				if (!listNorec.contains(map.get("noRec").toString())) {
					listNorec.add(map.get("noRec").toString());
				}
			}

			for (String norec : listNorec) {
				listTglPeriode.clear();
				for (Map<String, Object> map : allPlanningPeriodik) {
					if (norec.equals(map.get("noRec").toString())) {
						listTglPeriode.add((Date) map.get("tgl"));
					}
				}
				Collections.sort(listTglPeriode);
				List<Date> listTglDetail = new ArrayList<>();
				if (listTglPeriode.size() == 2) {
					List<Date> listDetailTglPeriode = kalenderDao.getDateFromPeriodicParameter(
							sdf.format(listTglPeriode.get(0)), sdf.format(listTglPeriode.get(1)));
					for (Date tgl : listDetailTglPeriode) {
						Date dateDetail = DateUtils.addHours(tgl, 7);
						listTglDetail.add(dateDetail);
					}
					listTanggalSudahDiajukan.addAll(listTglDetail);
				} else {
					listTanggalSudahDiajukan.addAll(listTglPeriode);
				}
			}
		}

		if (CommonUtil.isNotNullOrEmpty(listTanggalSudahDiajukan)) {
			listTgl.removeAll(listTanggalSudahDiajukan);
			if (listTgl.size() != listTglSize) {
				return false; // tidak bisa cuti
			} else {
				return true; // bisa cuti
			}
		} else {
			return true; // bisa cuti
		}
	}

	@Override
	public boolean validateTanggalPermohonan(Integer statusPegawaiPlanId, List<Date> listTgl, Integer idPegawai) {
		List<String> listNorecPlanning = permohonanCutiPegawaiDao.getAllNorecPlanning(idPegawai);
		if (CommonUtil.isNotNullOrEmpty(listNorecPlanning) && CommonUtil.isNotNullOrEmpty(listTgl)) {
			List<Date> listTanggalSudahDiajukan = new ArrayList<>();
			int listTglSize = listTgl.size();
			if (CommonUtil.isNotNullOrEmpty(
					planningPegawaiStatusDao.getListAllTanggalCutiApproved(listNorecPlanning, listTgl))) {
				listTanggalSudahDiajukan = planningPegawaiStatusDao.getListAllTanggalCutiApproved(listNorecPlanning,
						listTgl);
			}
			if (CommonUtil.isNotNullOrEmpty(
					planningPegawaiStatusDao.getListAllTanggalCutiNotYetApprove(listNorecPlanning, listTgl))) {
				listTanggalSudahDiajukan.addAll(
						planningPegawaiStatusDao.getListAllTanggalCutiNotYetApprove(listNorecPlanning, listTgl));
			}
			if (Arrays.asList(Master.StatusPegawai.PERIODIK_PENGAJUAN_KETIDAKHADIRAN).contains(statusPegawaiPlanId)) {
				if (CommonUtil.isNotNullOrEmpty(listTanggalSudahDiajukan)) {
					listTgl.removeAll(listTanggalSudahDiajukan);
					if (listTgl.size() != listTglSize) {
						return false; // tidak bisa cuti
					} else {
						return true; // bisa cuti
					}
				} else {
					return true; // bisa cuti
				}
			} else {
				if (CommonUtil.isNotNullOrEmpty(listTanggalSudahDiajukan)) {
					return false; // tidak bisa cuti
				} else {
					return true; // bisa cuti
				}
			}
		} else {
			return true; // bisa cuti
		}
	}

	@Override
	public Map<String, Object> checkPermohonanStatusPegawai(String norec) {
		Map<String, Object> result = new HashMap<>();

		PlanningPegawaiStatus model = planningPegawaiStatusDao.findOne(norec);
		if (CommonUtil.isNotNullOrEmpty(model.getNoRec())) {
			result.put("norec", "true");
		} else {
			result.put("norec", "false");
		}
		return result;
	}

	@Override
	@Transactional(noRollbackFor = Exception.class)
	public Map<String, Object> savePlanningPegawaiStatus(PlanningPegawaiStatusVO vo) {
		try {
			Map<String, Object> result = new HashMap<>();
			List<String> listTgl = new ArrayList<>();

			Integer day = 0;
			String noPlanning = noUsulan().get("noUsulan").toString();

			PlanningPegawaiStatus planningPegawaiStatus = planningPegawaiStatusConverter.transferVOToModel(vo,
					new PlanningPegawaiStatus());
			if (CommonUtil.isNotNullOrEmpty(planningPegawaiStatus)) {
				planningPegawaiStatus.setNoPlanning(noPlanning);
				planningPegawaiStatus.setStatusEnabled(true);
				planningPegawaiStatus.setApprovalStatus(0);

				if (CommonUtil.isNotNullOrEmpty(vo.getStatusPegawaiPlan())) {
					planningPegawaiStatus.setStatusPegawaiPlan(
							statusPegawaiConverter.transferVOToModel(vo.getStatusPegawaiPlan(), new StatusPegawai()));
				}
				if (CommonUtil.isNotNullOrEmpty(vo.getJabatanPemberiNotaDinas())) {
					planningPegawaiStatus.setJabatanPemberiNotaDinas(
							jabatanConverter.transferVOToModel(vo.getJabatanPemberiNotaDinas(), new Jabatan()));
				}
				if (CommonUtil.isNotNullOrEmpty(vo.getPegawai())) {
					planningPegawaiStatus
							.setPegawai(pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai()));
				}

				Set<ListTanggalCuti> listTanggal = new HashSet<ListTanggalCuti>();
				for (ListTanggalCutiVO date : vo.getListTanggal()) {
					day++;
					ListTanggalCuti tanggal = listTanggalConverter.transferVOToModel(date, new ListTanggalCuti());
					tanggal.setPlanningPegawaiStatus(planningPegawaiStatus);
					tanggal.setStatusEnabled(true);
					listTanggal.add(tanggal);
				}
				planningPegawaiStatus.setJumlahHari(day);
				// planningPegawaiStatus.setListTanggal(listTanggal);
				planningPegawaiStatus.getListTanggal().clear();
				planningPegawaiStatus.getListTanggal().addAll(listTanggal);

				if (CommonUtil.isNotNullOrEmpty(vo.getDeskripsiStatusPegawaiPlan())) {
					planningPegawaiStatus.setDeskripsiStatusPegawaiPlan(vo.getDeskripsiStatusPegawaiPlan());
				}
				if (CommonUtil.isNotNullOrEmpty(vo.getKeteranganLainyaPlan())) {
					planningPegawaiStatus.setKeteranganLainyaPlan(vo.getKeteranganLainyaPlan());
				}

				planningPegawaiStatus.setAlamatCuti(vo.getAlamatCuti());
				planningPegawaiStatus.setNomorTelepon(vo.getNomorTelepon());
				planningPegawaiStatus.setIsCutiLuarNegeri(vo.getIsCutiLuarNegeri());
				planningPegawaiStatus.setIsCutiLuarKota(vo.getIsCutiLuarKota());

				if (CommonUtil.isNotNullOrEmpty(vo.getAlamatTugas())) {
					planningPegawaiStatus.setAlamatTugas(vo.getAlamatTugas());
				}
				if (CommonUtil.isNotNullOrEmpty(vo.getNoSuratTugas())) {
					planningPegawaiStatus.setNoSuratTugas(vo.getNoSuratTugas());
				}
				if (CommonUtil.isNotNullOrEmpty(vo.getNoNotaDinas())) {
					planningPegawaiStatus.setNoNotaDinas(vo.getNoNotaDinas());
				}
				if (CommonUtil.isNotNullOrEmpty(vo.getTglNotaDinas())) {
					planningPegawaiStatus.setTglNotaDinas(vo.getTglNotaDinas());
				}
				if (CommonUtil.isNotNullOrEmpty(vo.getJenisPerawatan())) {
					planningPegawaiStatus.setJenisPerawatan(vo.getJenisPerawatan());
				}

				PlanningPegawaiStatus model = planningPegawaiStatusDao.save(planningPegawaiStatus);

				for (ListTanggalCuti listTanggalCuti : model.getListTanggal()) {
					listTgl.add(listTanggalCuti.getNoRec());
				}
				result.put("listTgl", listTgl);
				result.put("noRec", model.getNoRec());
				result.put("bisaCuti", true);

				return result;
			} else {
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

	}

	@Override
	@Transactional(noRollbackFor = Exception.class)
	public Map<String, Object> updatePlanningPegawaiStatus(PlanningPegawaiStatusVO vo) {
		Map<String, Object> result = new HashMap<>();
		List<Date> listTglCutiEdit = new ArrayList<>();
		List<Date> listTglCutiAdjust = new ArrayList<>();
		List<Date> listTglCutiPlanAdjust = new ArrayList<>();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		for (ListTanggalCutiVO listTglCutiVo : vo.getListTanggal()) {
			listTglCutiEdit.add(listTglCutiVo.getTgl());
		}
		List<Date> listTglCutiPlan = listTanggalCutiDao.getTglCuti(vo.getNoRec());
		List<Date> listTglCuti = new ArrayList<>(listTglCutiEdit);

		if (Arrays.asList(Master.StatusPegawai.PERIODIK_PENGAJUAN_KETIDAKHADIRAN)
				.contains(vo.getStatusPegawaiPlan().getId())) {
			Collections.sort(listTglCuti);
			if (listTglCuti.size() == 2) {
				listTglCuti = kalenderDao.getDateFromPeriodicParameter(sdf.format(listTglCuti.get(0)),
						sdf.format(listTglCuti.get(1)));
				for (Date tglCuti : listTglCuti) {
					Date dateAdjust = DateUtils.addHours(tglCuti, 7);
					listTglCutiAdjust.add(dateAdjust);
				}
				listTglCuti.clear();
				listTglCuti.addAll(listTglCutiAdjust);
			}

			Collections.sort(listTglCutiPlan);
			if (listTglCutiPlan.size() == 2) {
				listTglCutiPlan = kalenderDao.getDateFromPeriodicParameter(sdf.format(listTglCutiPlan.get(0)),
						sdf.format(listTglCutiPlan.get(1)));
				for (Date tglCutiPlan : listTglCutiPlan) {
					Date datePlanAdjust = DateUtils.addHours(tglCutiPlan, 7);
					listTglCutiPlanAdjust.add(datePlanAdjust);
				}
				listTglCutiPlan.clear();
				listTglCutiPlan.addAll(listTglCutiPlanAdjust);
			}
		}

		listTglCuti.removeAll(listTglCutiPlan);

		boolean statusTanggalPermohonan = true;
		if (CommonUtil.isNotNullOrEmpty(listTglCuti)) {
			statusTanggalPermohonan = validateTanggalPermohonanRev(listTglCuti, vo.getPegawai().getId());
		}
		if (CommonUtil.isNotNullOrEmpty(statusTanggalPermohonan) && !statusTanggalPermohonan) {
			result.put("bisaCuti", statusTanggalPermohonan);
			result.put("status", "Tanggal Permohonan sudah pernah diajukan!"); // Validasi
																				// tanggal
																				// permohonan
																				// yang
																				// sudah
																				// diajukan
			return result;
		} else {
			Integer day = 0;
			if (CommonUtil.isNotNullOrEmpty(vo) && CommonUtil.isNotNullOrEmpty(vo.getNoRec())) {
				PlanningPegawaiStatus planningPegawaiStatus = planningPegawaiStatusDao.findOne(vo.getNoRec());
				if (CommonUtil.isNotNullOrEmpty(planningPegawaiStatus)) {
					String noPlanning = noUsulan().get("noUsulan").toString();
					if (CommonUtil.isNotNullOrEmpty(noPlanning)) {
						planningPegawaiStatus.setNoPlanning(noPlanning);
						if (CommonUtil.isNotNullOrEmpty(vo.getStatusPegawaiPlan())) {
							planningPegawaiStatus.setStatusPegawaiPlan(statusPegawaiConverter
									.transferVOToModel(vo.getStatusPegawaiPlan(), new StatusPegawai()));
						}
						if (CommonUtil.isNotNullOrEmpty(vo.getJabatanPemberiNotaDinas())) {
							planningPegawaiStatus.setJabatanPemberiNotaDinas(
									jabatanConverter.transferVOToModel(vo.getJabatanPemberiNotaDinas(), new Jabatan()));
						}
						planningPegawaiStatus.setApprovalStatus(0);
						if (CommonUtil.isNotNullOrEmpty(vo.getPegawai())) {
							planningPegawaiStatus
									.setPegawai(pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai()));
						}
						Set<ListTanggalCuti> listTanggal = new HashSet<ListTanggalCuti>();

						listTanggalCutiDao.deleteDatas(vo.getNoRec().toString());
						// listTanggalCutiDao.delete(vo.getNoRec());
						for (ListTanggalCutiVO date : vo.getListTanggal()) {
							day++;
							ListTanggalCuti tanggal = listTanggalConverter.transferVOToModel(date,
									new ListTanggalCuti());
							tanggal.setPlanningPegawaiStatus(planningPegawaiStatus);
							tanggal.setStatusEnabled(true);
							listTanggalCutiDao.save(tanggal);
							listTanggal.add(tanggal);
						}
						planningPegawaiStatus.setJumlahHari(day);
						// planningPegawaiStatus.setListTanggal(listTanggal);
						planningPegawaiStatus.getListTanggal().clear();
						planningPegawaiStatus.getListTanggal().addAll(listTanggal);
						if (CommonUtil.isNotNullOrEmpty(vo.getDeskripsiStatusPegawaiPlan())) {
							planningPegawaiStatus.setDeskripsiStatusPegawaiPlan(vo.getDeskripsiStatusPegawaiPlan());
						}
						if (CommonUtil.isNotNullOrEmpty(vo.getKeteranganLainyaPlan())) {
							planningPegawaiStatus.setKeteranganLainyaPlan(vo.getKeteranganLainyaPlan());
						}
						// Set Alamat Cuti dan No Telepon
						planningPegawaiStatus.setAlamatCuti(vo.getAlamatCuti());
						planningPegawaiStatus.setNomorTelepon(vo.getNomorTelepon());

						if (CommonUtil.isNotNullOrEmpty(vo.getAlamatTugas())) {
							planningPegawaiStatus.setAlamatTugas(vo.getAlamatTugas());
						}
						if (CommonUtil.isNotNullOrEmpty(vo.getNoSuratTugas())) {
							planningPegawaiStatus.setNoSuratTugas(vo.getNoSuratTugas());
						}
						if (CommonUtil.isNotNullOrEmpty(vo.getNoNotaDinas())) {
							planningPegawaiStatus.setNoNotaDinas(vo.getNoNotaDinas());
						}
						if (CommonUtil.isNotNullOrEmpty(vo.getTglNotaDinas())) {
							planningPegawaiStatus.setTglNotaDinas(vo.getTglNotaDinas());
						}
						if (CommonUtil.isNotNullOrEmpty(vo.getJenisPerawatan())) {
							planningPegawaiStatus.setJenisPerawatan(vo.getJenisPerawatan());
						}

						planningPegawaiStatus.setIsCutiLuarNegeri(vo.getIsCutiLuarNegeri());
						planningPegawaiStatus.setIsCutiLuarKota(vo.getIsCutiLuarKota());

						planningPegawaiStatus.setStatusEnabled(true);
						PlanningPegawaiStatus planningPegawaiStatusResult = planningPegawaiStatusDao
								.save(planningPegawaiStatus);
						result.put("noRec", planningPegawaiStatusResult.getNoRec());
						result.put("bisaCuti", statusTanggalPermohonan);
					}
				}

			}

			return result;
		}
	}

	@Override
	public Map<String, Object> deletePlanningPegawaiStatus(String noRec) {
		Map<String, Object> result = new HashMap<>();
		if (CommonUtil.isNotNullOrEmpty(noRec)) {
			PlanningPegawaiStatus planningPegawaiStatus = planningPegawaiStatusDao.findOne(noRec);
			if (CommonUtil.isNotNullOrEmpty(planningPegawaiStatus)) {
				planningPegawaiStatus.setApprovalStatus(3);// dibatalkan
				PlanningPegawaiStatus planningPegawaiStatusResult = planningPegawaiStatusDao
						.save(planningPegawaiStatus);
				if (CommonUtil.isNotNullOrEmpty(planningPegawaiStatusResult)) {
					List<ListTanggalCuti> listTanggalCuti = new ArrayList<>();
					for (ListTanggalCuti tanggalCutiLama : planningPegawaiStatusResult.getListTanggal()) {
						ListTanggalCuti tanggalCutiBaru = listTanggalCutiDao.findOne(tanggalCutiLama.getNoRec());
						tanggalCutiBaru.setApprovalStatus(false);
						listTanggalCuti.add(tanggalCutiBaru);
					}
					listTanggalCutiDao.save(listTanggalCuti);
				}
				result.put("noRec", planningPegawaiStatusResult.getNoRec());
			}
		}
		return result;
	}

	@Override
	public Map<String, Object> getListPermohonanStatus(Integer unitKerjaId) {
		Map<String, Object> result = new HashMap<>();
		List<Map<String, Object>> listData = planningPegawaiStatusDao.getListPermohonanStatus(unitKerjaId);

		if (CommonUtil.isNotNullOrEmpty(listData)) {
			for (Map<String, Object> map : listData) {
				List<Map<String, Object>> listTanggalCuti = planningPegawaiStatusDao
						.getListTanggalCuti((String) map.get("noRec"));
				map.put("lisTanggal", listTanggalCuti);
			}
			result.put("listData", listData);
		}
		return result;
	}

	@Override
	public Map<String, Object> getApprovalStatus(Integer idPegawai) {
		Map<String, Object> result = new HashMap<>();

		List<Map<String, Object>> listRawData = new ArrayList<>();

		List<String> listNorec = new ArrayList<>();
		List<Date> listTglPengajuan = new ArrayList<>();

		Integer currentYear = Calendar.getInstance().get(Calendar.YEAR);

		List<Integer> pegawaiSdmKesejahteraan = pegawaiDao.getPegawaiSDMforCred(Master.UnitKerja.BAG_SDM,
				Master.SubUnitKerja.SUBBAG_KESEJAHTERAAN);
		List<Integer> pegawaiSdmPengembangan = pegawaiDao.getPegawaiSDMforCred(Master.UnitKerja.BAG_SDM,
				Master.SubUnitKerja.SUBBAG_PENGEMBANGAN);

		List<Map<String, Object>> listData = planningPegawaiStatusDao.getApprovalStatus(idPegawai,
				currentYear.toString(), Master.PengajuanCuti.DITANGGUHKAN, Master.PengajuanCuti.BELUM_DISETUJUI,
				Arrays.asList(Master.StatusPegawai.KETIDAKHADIRAN));
		// List<Map<String, Object>> listData =
		// planningPegawaiStatusDaoCustom.getApprovalStatus(idPegawai);
		if (pegawaiSdmKesejahteraan.contains(idPegawai)) {
			// List<Map<String, Object>> listDataCutiAlasanPentingDanSakit =
			// planningPegawaiStatusDaoCustom.getApprovalStatusCutiAlasanPentingDanSakit();
			List<Map<String, Object>> listDataCutiAlasanPentingDanSakit = planningPegawaiStatusDao.getApprovalStatusSdm(
					Master.PengajuanCuti.BELUM_DISETUJUI, Arrays.asList(Master.StatusPegawai.SAKIT_ALASAN_PENTING));
			listData.addAll(listDataCutiAlasanPentingDanSakit);
		} else if (pegawaiSdmPengembangan.contains(idPegawai)) {
			List<Map<String, Object>> listDataCutiTugasLuar = planningPegawaiStatusDao.getApprovalStatusSdm(
					Master.PengajuanCuti.BELUM_DISETUJUI, Arrays.asList(Master.StatusPegawai.TUGAS_LUAR));
			listData.addAll(listDataCutiTugasLuar);
		}

		for (Map<String, Object> map : listData) {
			if (!listNorec.contains(map.get("noRec").toString())) {
				listNorec.add(map.get("noRec").toString());
			}
			if (!listTglPengajuan.contains((Date) map.get("tglPengajuan"))) {
				listTglPengajuan.add((Date) map.get("tglPengajuan"));
			}
		}

		// Collections.sort(listNorec, Collections.reverseOrder());
		Collections.sort(listTglPengajuan, Collections.reverseOrder());

		for (String norec : listNorec) {
			for (Date tglPengajuan : listTglPengajuan) {
				int count = 0;
				Map<String, Object> rawData = new HashMap<>();
				List<Map<String, Object>> listTanggalCuti = new ArrayList<>();
				List<Map<String, Object>> listTanggalCutiApproved = new ArrayList<>();
				for (Map<String, Object> map : listData) {
					if (CommonUtil.isNotNullOrEmpty(map.get("approvalStatusTgl"))) {
						if (norec.equals(map.get("noRec").toString())
								&& tglPengajuan.equals((Date) map.get("tglPengajuan"))
								&& Boolean.parseBoolean(map.get("approvalStatusTgl").toString())) {
							count += 1;
							Map<String, Object> mapTglCutiApproved = new HashMap<>();
							mapTglCutiApproved.put("noRec", map.get("norecTgl").toString());
							mapTglCutiApproved.put("tgl", (Date) map.get("tgl"));
							listTanggalCutiApproved.add(mapTglCutiApproved);

							if (count == 1) {
								rawData.putAll(map);
							}
						}
						if (norec.equals(map.get("noRec").toString())
								&& tglPengajuan.equals((Date) map.get("tglPengajuan"))) {
							count += 1;
							Map<String, Object> mapTglCuti = new HashMap<>();
							mapTglCuti.put("noRec", map.get("norecTgl").toString());
							mapTglCuti.put("tgl", (Date) map.get("tgl"));
							listTanggalCuti.add(mapTglCuti);

							if (count == 1) {
								rawData.putAll(map);
							}
						}
					} else {
						if (norec.equals(map.get("noRec").toString())
								&& tglPengajuan.equals((Date) map.get("tglPengajuan"))) {
							count += 1;
							Map<String, Object> mapTglCuti = new HashMap<>();
							mapTglCuti.put("noRec", map.get("norecTgl").toString());
							mapTglCuti.put("tgl", (Date) map.get("tgl"));
							listTanggalCuti.add(mapTglCuti);

							if (count == 1) {
								rawData.putAll(map);
							}
						}
					}
				}
				if (CommonUtil.isNotNullOrEmpty(rawData.get("noRec"))) {
					rawData.put("lisTanggal", listTanggalCuti);
					rawData.put("listTanggalCutiDisetujui", listTanggalCutiApproved);
					listRawData.add(rawData);
				}
			}
		}

		if (CommonUtil.isNotNullOrEmpty(listRawData)) {
			result.put("listData", listRawData);
		}

		// if (CommonUtil.isNotNullOrEmpty(listData)) {
		// for (Map<String, Object> map : listData) {
		// List<Map<String, Object>> listTanggalCuti =
		// planningPegawaiStatusDao.getListTanggalCuti((String)
		// map.get("noRec"));
		// List<Map<String, Object>> listTanggalCutiApproved =
		// planningPegawaiStatusDao.getListTanggalCutiApproved((String)
		// map.get("noRec"));
		// map.put("lisTanggal", listTanggalCuti);
		// map.put("listTanggalCutiDisetujui", listTanggalCutiApproved);
		// }
		// result.put("listData", listData);
		// }

		return result;
	}

	@Override
	public List<Map<String, Object>> getListTanggalPermohonan(Integer idPegawai) {
		List<Map<String, Object>> listResult = new ArrayList<>();
		List<Integer> pegawaiSdm = pegawaiDao.getPegawaiSDMforCred(Master.UnitKerja.BAG_SDM,
				Master.SubUnitKerja.SUBBAG_KESEJAHTERAAN);
		List<Map<String, Object>> listData = planningPegawaiStatusDaoCustom.getApprovalStatus(idPegawai);

		// store idPegawai dan tanggal permohonan
		for (Map<String, Object> map : listData) {
			Map<String, Object> mapp = new HashMap<>();
			List<Map<String, Object>> listTanggalCuti = planningPegawaiStatusDao
					.getListTanggalCuti((String) map.get("noRec"));
			mapp.put("idPegawai", idPegawai);
			mapp.put("lisTanggal", listTanggalCuti);
			listResult.add(mapp);
		}

		if (pegawaiSdm.contains(idPegawai)) {
			List<Map<String, Object>> listDataCutiAlasanPenting = planningPegawaiStatusDaoCustom
					.getApprovalStatusCutiAlasanPentingDanSakit();
			for (Map<String, Object> map : listDataCutiAlasanPenting) {
				Map<String, Object> mapp = new HashMap<>();
				List<Map<String, Object>> listTanggalCuti = planningPegawaiStatusDao
						.getListTanggalCuti((String) map.get("noRec"));
				mapp.put("idPegawai", map.get("pegwaiId"));
				mapp.put("lisTanggal", listTanggalCuti);
				listResult.add(mapp);
			}
		}

		return listResult;
	}

	@Override
	public Map<String, Object> getApprovalStatusPaging(Integer page, Integer limit, String sort, String dir,
			Integer idPegawai, String nama, String jenisPermohonan, Integer statusPermohonan) {
		Map<String, Object> result = new HashMap<>();
		Long totalRow = planningPegawaiStatusDaoCustom.countApprovalStatus(sort, idPegawai, nama, jenisPermohonan,
				statusPermohonan);
		int totalPages = 0;

		int pageRequested = page;

		if (totalRow > 0) {
			totalPages = (int) Math.ceil((double) totalRow / (double) limit);
		} else {
			totalPages = 0;
		}

		if (pageRequested > totalPages)
			pageRequested = totalPages;
		int rowStart = pageRequested * limit - limit;
		if (rowStart < 0) {
			rowStart = 0;
		}
		int rowEnd = limit;

		List<Map<String, Object>> listData = planningPegawaiStatusDaoCustom.getApprovalStatusPaging(rowStart, rowEnd,
				sort, dir, idPegawai, nama, jenisPermohonan, statusPermohonan);

		if (CommonUtil.isNotNullOrEmpty(listData)) {
			for (Map<String, Object> map : listData) {
				List<Map<String, Object>> listTanggalCuti = planningPegawaiStatusDao
						.getListTanggalCuti((String) map.get("noRec"));
				List<Map<String, Object>> listTanggalCutiApproved = planningPegawaiStatusDao
						.getListTanggalCutiApproved((String) map.get("noRec"));
				map.put("lisTanggal", listTanggalCuti);
				map.put("listTanggalCutiDisetujui", listTanggalCutiApproved);
			}
			result.put("listData", listData);
			result.put("totalPages", totalPages);
		}
		return result;
	}

	@Override
	public Map<String, Object> getApprovalStatusPaging(Integer page, Integer limit, String sort, String dir,
			Integer idPegawai, String nama, String jenisPermohonan, Integer statusPermohonan, String tglPermohonan,
			Boolean isCutiLuarNegeri, Boolean isCutiLuarKota) {
		Map<String, Object> result = new HashMap<>();
		Long totalRow = planningPegawaiStatusDaoCustom.countApprovalStatus(sort, idPegawai, nama, jenisPermohonan,
				statusPermohonan, tglPermohonan, isCutiLuarNegeri, isCutiLuarKota);

		if (CommonUtil.isNotNullOrEmpty(tglPermohonan)) {
			limit = Math.toIntExact(totalRow);
		}

		int totalPages = 0;
		int pageRequested = page;

		if (totalRow > 0) {
			totalPages = (int) Math.ceil((double) totalRow / (double) limit);
		} else {
			totalPages = 0;
		}

		if (pageRequested > totalPages)
			pageRequested = totalPages;

		int rowStart = pageRequested * limit - limit;
		if (rowStart < 0) {
			rowStart = 0;
		}
		int rowEnd = limit;

		List<Map<String, Object>> listData = planningPegawaiStatusDaoCustom.getApprovalStatusPaging(rowStart, rowEnd,
				sort, dir, idPegawai, nama, jenisPermohonan, statusPermohonan, tglPermohonan, isCutiLuarNegeri,
				isCutiLuarKota);

		if (CommonUtil.isNotNullOrEmpty(listData)) {
			for (Map<String, Object> map : listData) {
				List<Map<String, Object>> listTanggalCuti = planningPegawaiStatusDao
						.getListTanggalCuti((String) map.get("noRec"));
				List<Map<String, Object>> listTanggalCutiApproved = planningPegawaiStatusDao
						.getListTanggalCutiApproved((String) map.get("noRec"));
				map.put("lisTanggal", listTanggalCuti);
				map.put("listTanggalCutiDisetujui", listTanggalCutiApproved);
			}
			result.put("listData", listData);
			result.put("totalPages", totalPages);
		}
		return result;
	}

	@Override
	public Map<String, Object> getApprovalStatusByStatusPegawaiPlan(Integer idPegawai, Integer statusPegawaiPlanId) {
		Map<String, Object> result = new HashMap<>();
		List<Map<String, Object>> listData = planningPegawaiStatusDaoCustom
				.getApprovalStatusByStatusPegawaiPlan(idPegawai, statusPegawaiPlanId);

		if (CommonUtil.isNotNullOrEmpty(listData)) {
			for (Map<String, Object> map : listData) {
				List<Map<String, Object>> listTanggalCuti = planningPegawaiStatusDao
						.getListTanggalCuti((String) map.get("noRec"));
				map.put("lisTanggal", listTanggalCuti);
			}
			result.put("listData", listData);
		}
		return result;
	}

	@Override
	@Transactional(noRollbackFor = Exception.class)
	public Map<String, Object> approvalPermohonanStatus(PlanningPegawaiStatusVO vo) {
		Map<String, Object> result = new HashMap<>();
		int day = 0;
		SuratKeputusan suratKeputusan = new SuratKeputusan();
		if (CommonUtil.isNotNullOrEmpty(vo.getPegawai())) {
			suratKeputusan.setPegawaiTTFk(pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai()));
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getJenisKeputusan())) {
			suratKeputusan.setJenisKeputusan(
					jenisKeputusanConverter.transferVOToModel(vo.getJenisKeputusan(), new JenisKeputusan()));
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getTglSkSpmt())) {
			suratKeputusan.setTglTTSK(vo.getTglSkSpmt());
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getNoSkTemp())) {
			suratKeputusan.setNoSK(vo.getNoSkTemp());
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getUraian())) {
			suratKeputusan.setNamaSK(vo.getUraian());
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getTglTmtSpmt())) {
			suratKeputusan.setTglBerlakuAwal(vo.getTglTmtSpmt());
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getTglKeputusan())) {
			suratKeputusan.setTglBerlakuAkhir(vo.getTglKeputusan());
		}

		if (CommonUtil.isNotNullOrEmpty(suratKeputusan)) {
			SuratKeputusan suratKeputusanResult = suratKeputusanDao.save(suratKeputusan);

			PlanningPegawaiStatus planningPegawaiStatus = planningPegawaiStatusDao.findOne(vo.getNoRec());

			if (CommonUtil.isNotNullOrEmpty(suratKeputusanResult)) {
				planningPegawaiStatus.setNoSk(suratKeputusanResult);
				planningPegawaiStatus.setApprovalStatus(1);
			}
			if (CommonUtil.isNotNullOrEmpty(vo.getStatusPegawaiExec())) {
				planningPegawaiStatus.setStatusPegawaiExec(
						statusPegawaiConverter.transferVOToModel(vo.getStatusPegawaiExec(), new StatusPegawai()));
			}
			if (CommonUtil.isNotNullOrEmpty(vo.getDeskripsiStatusPegawaiExec())) {
				planningPegawaiStatus.setDeskripsiStatusPegawaiExec(vo.getDeskripsiStatusPegawaiExec());
			}
			if (CommonUtil.isNotNullOrEmpty(vo.getKeteranganLainyaExec())) {
				planningPegawaiStatus.setKeteranganLainyaExec(vo.getKeteranganLainyaExec());
			}
			if (CommonUtil.isNotNullOrEmpty(vo.getTglKeputusan())) {
				planningPegawaiStatus.setTglKeputusan(vo.getTglKeputusan());
			}
			Set<ListTanggalCuti> listTanggal = new HashSet<ListTanggalCuti>();
			List<ListTanggalCuti> listTgl = new ArrayList<ListTanggalCuti>();
			StatusPegawai statusPegawai = statusPegawaiDao.getAll(vo.getStatusPegawaiExec().getId());
			for (ListTanggalCutiVO date : vo.getListTanggal()) {
				day++;
				ListTanggalCuti tanggal = listTanggalCutiDao.findOne(date.getNoRec());
				if (CommonUtil.isNotNullOrEmpty(planningPegawaiStatus)) {
					tanggal.setPlanningPegawaiStatus(planningPegawaiStatus);
				}
				tanggal.setApprovalStatus(true);
				listTanggal.add(tanggal);
				// tampungan jika Cuti Besar atau Cuti Melahirkan
				listTgl.add(tanggal);
			}

			if (CommonUtil.isNotNullOrEmpty(statusPegawai) && (statusPegawai.getStatusPegawai().equals("Cuti Besar")
					|| statusPegawai.getStatusPegawai().equals("Cuti Melahirkan")
					|| statusPegawai.getStatusPegawai().equals("Cuti Alasan Penting"))) {
				DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

				Date tglAwal = listTgl.get(0).getTgl();
				Date tglAkhir = listTgl.get(listTgl.size() - 1).getTgl();
				if (tglAkhir.getTime() > tglAwal.getTime()) {
					day = pegawaiJadwalKerjaDao.getJadwalCustom(planningPegawaiStatus.getPegawaiId(),
							df.format(tglAwal), df.format(tglAkhir));
				} else {
					day = pegawaiJadwalKerjaDao.getJadwalCustom(planningPegawaiStatus.getPegawaiId(),
							df.format(tglAkhir), df.format(tglAwal));
				}

				planningPegawaiStatus.setJumlahHari(day);
				vo.setJumlahHari(day);
			} else {
				planningPegawaiStatus.setJumlahHari(day);
				vo.setJumlahHari(day);
			}
			// planningPegawaiStatus.setListTanggal(listTanggal);
			planningPegawaiStatus.getListTanggal().clear();
			planningPegawaiStatus.getListTanggal().addAll(listTanggal);

			if (CommonUtil.isNotNullOrEmpty(planningPegawaiStatus)) {
				PlanningPegawaiStatus planningPegawaiStatusResult = planningPegawaiStatusDao
						.save(planningPegawaiStatus);
				if (CommonUtil.isNotNullOrEmpty(planningPegawaiStatusResult.noRec)) {
					result = checkKelompokShiftKerja(vo, (Integer) planningPegawaiStatus.getStatusPegawaiPlan().getId(),
							planningPegawaiStatusResult.getNoRec());
				}
			}
		}
		return result;
	}

	@Transactional(readOnly = false)
	public String getRunningNumber(String kegunaan) {
		RunningNumber runningNumber = runningNumberDao.findByResetAndKegunaan("0", kegunaan);
		Integer number = (runningNumber.getNomerTerbaru() + (Integer) 1);
		runningNumber.setNomerTerbaru(runningNumber.getNomerTerbaru() + (Integer) 1);
		String noOrderIntern = StringUtil.formatNumber(number.toString(), 6);
		runningNumberDao.save(runningNumber);
		return noOrderIntern;
	}

	@Override
	@Transactional(readOnly = false)
	public Map<String, Object> checkKelompokShiftKerja(PlanningPegawaiStatusVO vo, Integer statusPegawaiId,
			String noRecPlanning) {
		Map<String, Object> result = new HashMap<>();
		StrukHistori strukHistori = new StrukHistori();
		Integer idNonShift = monitoringAbsenService.getIdNonShift();
		Integer idnonShiftPlus = monitoringAbsenService.getIdNonShiftPlus();
		Integer idShift2 = monitoringAbsenService.getIdShift2();
		Integer idShift3 = monitoringAbsenService.getIdShift3();
		Integer komponenCuti = monitoringAbsenService.getkomponenIndexCutiNonShift();
		Integer komponenCutiShift = monitoringAbsenService.getkomponenIndexCutiShift();

		Date dateNow = DateUtil.now();
		if (CommonUtil.isNotNullOrEmpty(vo)) {
			strukHistori.setNonHistori(getRunningNumber("Struk Histori"));
		}
		if (CommonUtil.isNotNullOrEmpty(dateNow)) {
			strukHistori.setTglHistori(dateNow);
		}
		if (CommonUtil.isNotNullOrEmpty(strukHistori)) {
			StrukHistori strukHistoriResult = strukHistoriDao.save(strukHistori);

			PegawaiHistoriRekapIndex pegawaiHistoriRekapIndex = new PegawaiHistoriRekapIndex();
			if (CommonUtil.isNotNullOrEmpty(strukHistoriResult)) {
				pegawaiHistoriRekapIndex.setStrukHistory(strukHistoriResult);
			}
			if (CommonUtil.isNotNullOrEmpty(vo.getPegawai())) {
				pegawaiHistoriRekapIndex.setPegawai(pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai()));
			}

			Map<String, Object> kelompokShift = planningPegawaiStatusDao.getKelompokShift(vo.getPegawai().getId());
			if (CommonUtil.isNotNullOrEmpty(kelompokShift.get("id"))) {
				Integer kelomokIndexId = null;

				// ------------------------------------------SETTING DATA
				// FIX------------------------------------------
				if (statusPegawaiId == 1) {
					if ((Integer) kelompokShift.get("id") == idNonShift
							|| (Integer) kelompokShift.get("id") == idnonShiftPlus) {
						kelomokIndexId = komponenCuti;
					} else if ((Integer) kelompokShift.get("id") == idShift2
							|| (Integer) kelompokShift.get("id") == idShift3) {
						kelomokIndexId = komponenCutiShift;
					}
				} else if (statusPegawaiId == 24 || statusPegawaiId == 25 || statusPegawaiId == 26) {
					if ((Integer) kelompokShift.get("id") == idNonShift
							|| (Integer) kelompokShift.get("id") == idnonShiftPlus) {
						kelomokIndexId = 9;
					} else if ((Integer) kelompokShift.get("id") == idShift2
							|| (Integer) kelompokShift.get("id") == idShift3) {
						kelomokIndexId = 10;
					}
				} else if (statusPegawaiId == 28) {
					kelomokIndexId = 11;
				} else if (statusPegawaiId == 27) {
					kelomokIndexId = 17;
				} else if (statusPegawaiId == 29) {
					if ((Integer) kelompokShift.get("id") == idNonShift
							|| (Integer) kelompokShift.get("id") == idnonShiftPlus) {
						kelomokIndexId = 7;
					} else if ((Integer) kelompokShift.get("id") == idShift2
							|| (Integer) kelompokShift.get("id") == idShift3) {
						kelomokIndexId = 8;
					}
				}
				// ------------------------------------------SETTING DATA
				// FIX------------------------------------------

				if (CommonUtil.isNotNullOrEmpty(kelomokIndexId)) {
					result = savePegawaiHistoriRekapIndex(vo, pegawaiHistoriRekapIndex, kelomokIndexId, noRecPlanning);
				}
			}
		}
		return result;
	}

	@Override
	public Map<String, Object> savePegawaiHistoriRekapIndex(PlanningPegawaiStatusVO vo,
			PegawaiHistoriRekapIndex pegawaiHistoriRekapIndex, Integer kelomokIndexId, String noRecPlanning) {
		Map<String, Object> result = new HashMap<>();

		Map<String, Object> komponenIndexMap = planningPegawaiStatusDao.getKomponenIndex(kelomokIndexId);
		if (CommonUtil.isNotNullOrEmpty(kelomokIndexId)) {
			if (CommonUtil.isNotNullOrEmpty(komponenIndexMap)) {
				if (CommonUtil.isNotNullOrEmpty(komponenIndexMap)) {
					KomponenIndex komponenIndex = komponenIndexDao.findOne(kelomokIndexId);
					pegawaiHistoriRekapIndex.setKomponenIndex(komponenIndex);
				}
			}

			Float factorRate = (Float) komponenIndexMap.get("factorRate");
			if (CommonUtil.isNotNullOrEmpty(factorRate)) {
				Integer day = vo.getJumlahHari();

				String operatorFactorRate = (String) komponenIndexMap.get("operatorFactorRate");
				Float nilaiIndexTotal = null;
				if (operatorFactorRate.equalsIgnoreCase("X")) {
					nilaiIndexTotal = (day.floatValue()) * factorRate;
				} else if (operatorFactorRate.equalsIgnoreCase("/")) {
					nilaiIndexTotal = (day.floatValue()) / factorRate;
				} else if (operatorFactorRate.equalsIgnoreCase("+")) {
					nilaiIndexTotal = (day.floatValue()) + factorRate;
				}
				if (CommonUtil.isNotNullOrEmpty(day)) {
					pegawaiHistoriRekapIndex.setNilaiIndex(day.intValue());
				}
				if (CommonUtil.isNotNullOrEmpty(nilaiIndexTotal)) {
					pegawaiHistoriRekapIndex.setNilaiIndexTotal(nilaiIndexTotal.doubleValue());
				}
			}

			if (CommonUtil.isNotNullOrEmpty(pegawaiHistoriRekapIndex)) {
				pegawaiHistoriRekapIndex.setNoRecPlanningPerubahanStatus(noRecPlanning);
				PegawaiHistoriRekapIndex data = pegawaiHistoriRekapIndexDao.getPegawaiHistoriRekapIndex(noRecPlanning);
				if (CommonUtil.isNullOrEmpty(data)) {
					PegawaiHistoriRekapIndex pegawaiHistoriRekapIndexResult = pegawaiHistoriRekapIndexDao
							.save(pegawaiHistoriRekapIndex);
					result.put("noRec", pegawaiHistoriRekapIndexResult.noRec);
					System.out.println((String) komponenIndexMap.get("komponenIndex"));
				}
			}
		}
		return result;
	}

	public Integer getDayJadwalHadir(String settingFixed, Integer pegawaiId, String startDate, String endDate) {
		Integer day = 0;
		String idKomponenIndexHadir = settingDataFixedDao.getSettingDataFixed(settingFixed);
		if (CommonUtil.isNotNullOrEmpty(idKomponenIndexHadir)) {
			String[] arr = idKomponenIndexHadir.split(",");
			List<Integer> listId = new ArrayList<Integer>();
			for (String id : arr) {
				listId.add(Integer.valueOf(id));
			}
			day = planningPegawaiStatusDao.getDayHadir(pegawaiId, listId, startDate, endDate);
		}
		return day;
	}

	@Override
	public Map<String, Object> unVerifPermohonanStatus(PlanningPegawaiStatusVO vo) {
		Map<String, Object> result = new HashMap<>();
		PlanningPegawaiStatus planningPegawaiStatus = planningPegawaiStatusDao.findOne(vo.getNoRec());

		if (CommonUtil.isNotNullOrEmpty(planningPegawaiStatus)) {
			planningPegawaiStatus.setApprovalStatus(2);
			PlanningPegawaiStatus planningPegawaiStatusResult = planningPegawaiStatusDao.save(planningPegawaiStatus);
			result.put("noRec", planningPegawaiStatusResult.noRec);
		}
		return result;
	}

	@Override
	public Map<String, Object> getListPermohonanStatusPegawai(Boolean isSdm) {
		Map<String, Object> result = new HashMap<>();
		Pegawai pegawai = loginUserService.getLoginUser().getPegawai();
		List<Map<String, Object>> listData = planningPegawaiStatusDao.getListPermohonanStatusByPegawai(pegawai.getId());
		if (isSdm) {
			listData = planningPegawaiStatusDao.getListPermohonanStatusAll();
		}
		if (CommonUtil.isNotNullOrEmpty(listData)) {
			for (Map<String, Object> map : listData) {
				List<Map<String, Object>> listTanggalCuti = planningPegawaiStatusDao
						.getListTanggalCutiApproved((String) map.get("noRec"));
				map.put("lisTanggal", listTanggalCuti);
			}
			result.put("listData", listData);
		}
		return result;
	}

	@Override
	public Map<String, Object> getListPermohonanStatusPegawaiPaging(Integer page, Integer limit, String sort,
			String dir, Integer idPegawai, String nama, String jenisPermohonan, Integer statusPermohonan,
			Boolean isSdm) {
		Map<String, Object> result = new HashMap<>();
		List<Map<String, Object>> listData = new ArrayList<>();
		// Pegawai pegawai = loginUserService.getLoginUser().getPegawai();

		int totalPages = 0;
		if (isSdm) {
			Long totalRow = planningPegawaiStatusDaoCustom.countPermohonanStatusAll(sort, idPegawai, nama,
					jenisPermohonan, statusPermohonan);

			int pageRequested = page;

			if (totalRow > 0) {
				totalPages = (int) Math.ceil((double) totalRow / (double) limit);
			} else {
				totalPages = 0;
			}

			if (pageRequested > totalPages)
				pageRequested = totalPages;
			int rowStart = pageRequested * limit - limit;
			if (rowStart < 0) {
				rowStart = 0;
			}
			int rowEnd = limit;

			listData = planningPegawaiStatusDaoCustom.getListPermohonanStatusAll(rowStart, rowEnd, sort, dir, idPegawai,
					nama, jenisPermohonan, statusPermohonan);
		} else {
			Long totalRow = planningPegawaiStatusDaoCustom.countApprovedStatus(sort, idPegawai, nama, jenisPermohonan,
					statusPermohonan);

			int pageRequested = page;

			if (totalRow > 0) {
				totalPages = (int) Math.ceil((double) totalRow / (double) limit);
			} else {
				totalPages = 0;
			}

			if (pageRequested > totalPages)
				pageRequested = totalPages;
			int rowStart = pageRequested * limit - limit;
			if (rowStart < 0) {
				rowStart = 0;
			}
			int rowEnd = limit;

			listData = planningPegawaiStatusDaoCustom.getListPermohonanDisetujuiByPegawai(rowStart, rowEnd, sort, dir,
					idPegawai, nama, jenisPermohonan, statusPermohonan);
		}

		if (CommonUtil.isNotNullOrEmpty(listData)) {
			for (Map<String, Object> map : listData) {
				List<Map<String, Object>> listTanggalCuti = planningPegawaiStatusDao
						.getListTanggalCutiApproved((String) map.get("noRec"));
				map.put("lisTanggal", listTanggalCuti);
			}
			result.put("listData", listData);
			result.put("totalPages", totalPages);
		}
		return result;
	}

	@Override
	public Map<String, Object> getListPermohonanStatusPegawaiPaging(Integer page, Integer limit, String sort,
			String dir, Integer idPegawai, String nama, String jenisPermohonan, Integer statusPermohonan,
			String tglPermohonan, Boolean isSdm, Boolean isCutiLuarNegeri, Boolean isCutiLuarKota) {
		Map<String, Object> result = new HashMap<>();
		List<Map<String, Object>> listData = new ArrayList<>();
		// Pegawai pegawai = loginUserService.getLoginUser().getPegawai();

		int totalPages = 0;
		if (isSdm) {
			Long totalRow = planningPegawaiStatusDaoCustom.countPermohonanStatusAll(sort, idPegawai, nama,
					jenisPermohonan, statusPermohonan, tglPermohonan, isCutiLuarNegeri, isCutiLuarKota);

			if (CommonUtil.isNotNullOrEmpty(tglPermohonan)) {
				limit = Math.toIntExact(totalRow);
			}
			int pageRequested = page;

			if (totalRow > 0) {
				totalPages = (int) Math.ceil((double) totalRow / (double) limit);
			} else {
				totalPages = 0;
			}

			if (pageRequested > totalPages)
				pageRequested = totalPages;
			int rowStart = pageRequested * limit - limit;
			if (rowStart < 0) {
				rowStart = 0;
			}
			int rowEnd = limit;

			listData = planningPegawaiStatusDaoCustom.getListPermohonanStatusAll(rowStart, rowEnd, sort, dir, idPegawai,
					nama, jenisPermohonan, statusPermohonan, tglPermohonan, isCutiLuarNegeri, isCutiLuarKota);
		} else {
			Long totalRow = planningPegawaiStatusDaoCustom.countApprovedStatus(sort, idPegawai, nama, jenisPermohonan,
					statusPermohonan, tglPermohonan, isCutiLuarNegeri, isCutiLuarKota);

			if (CommonUtil.isNotNullOrEmpty(tglPermohonan)) {
				limit = Math.toIntExact(totalRow);
			}
			int pageRequested = page;

			if (totalRow > 0) {
				totalPages = (int) Math.ceil((double) totalRow / (double) limit);
			} else {
				totalPages = 0;
			}

			if (pageRequested > totalPages)
				pageRequested = totalPages;
			int rowStart = pageRequested * limit - limit;
			if (rowStart < 0) {
				rowStart = 0;
			}
			int rowEnd = limit;

			listData = planningPegawaiStatusDaoCustom.getListPermohonanDisetujuiByPegawai(rowStart, rowEnd, sort, dir,
					idPegawai, nama, jenisPermohonan, statusPermohonan, tglPermohonan, isCutiLuarNegeri,
					isCutiLuarKota);
		}

		if (CommonUtil.isNotNullOrEmpty(listData)) {
			for (Map<String, Object> map : listData) {
				List<Map<String, Object>> listTanggalCuti = planningPegawaiStatusDao
						.getListTanggalCutiApproved((String) map.get("noRec"));
				map.put("lisTanggal", listTanggalCuti);
			}
			result.put("listData", listData);
			result.put("totalPages", totalPages);
		}
		return result;
	}

	@Override
	@Transactional(noRollbackFor = Exception.class)
	public Map<String, Object> penangguhanPerubahanStatusKehadiran(PlanningPegawaiStatusVO vo) {
		Map<String, Object> result = new HashMap<>();
		if (CommonUtil.isNotNullOrEmpty(vo)) {
			PegawaiHistoriRekapIndex historiRekap = pegawaiHistoriRekapIndexDao
					.getPegawaiHistoriRekapIndex(vo.getNoRec());
			PlanningPegawaiStatus planningPegawaiStatus = planningPegawaiStatusDao.findOne(vo.getNoRec());

			PlanningPegawaiStatus model = new PlanningPegawaiStatus();
			if (CommonUtil.isNotNullOrEmpty(historiRekap)) {
				if (planningPegawaiStatus.getJumlahHari() == vo.getListTanggal().size()) {
					planningPegawaiStatus.setApprovalStatus(3);// ditangguhkan

					// approval status false untuk setiap tanggal yang
					// di-ceklist
					Set<ListTanggalCuti> listTanggal = new HashSet<ListTanggalCuti>();
					for (ListTanggalCutiVO date : vo.getListTanggal()) {
						ListTanggalCuti tanggal = listTanggalCutiDao.findOne(date.getNoRec());
						ListTanggalCuti tgl = new ListTanggalCuti();
						tgl.setNoRec(tanggal.getNoRec());
						tgl.setTgl(tanggal.getTgl());
						listTanggalCutiDao.delete(tanggal);
						tgl.setApprovalStatus(false);
						tgl.setPlanningPegawaiStatus(planningPegawaiStatus);
						tgl.setStatusEnabled(true);
						listTanggal.add(tgl);

					}
					// planningPegawaiStatus.setListTanggal(listTanggal);
					planningPegawaiStatus.getListTanggal().clear();
					planningPegawaiStatus.getListTanggal().addAll(listTanggal);

					historiRekap.setNilaiIndex(0);
					historiRekap.setNilaiIndexTotal(0.0);
				} else {
					PlanningPegawaiStatus planningPegawaiStatusDitangguhkan = new PlanningPegawaiStatus();
					planningPegawaiStatusDitangguhkan.setPegawai(planningPegawaiStatus.getPegawai());
					planningPegawaiStatusDitangguhkan
							.setDeskripsiStatusPegawaiPlan(planningPegawaiStatus.getDeskripsiStatusPegawaiPlan());
					planningPegawaiStatusDitangguhkan.setNoPlanning(planningPegawaiStatus.getNoPlanning());
					planningPegawaiStatusDitangguhkan.setStatusEnabled(true);
					planningPegawaiStatusDitangguhkan.setTglPengajuan(planningPegawaiStatus.getTglPengajuan());
					planningPegawaiStatusDitangguhkan.setTglKeputusan(new Date());
					planningPegawaiStatusDitangguhkan.setApprovalStatus(3);// ditangguhkan
					Set<ListTanggalCuti> listTanggal = new HashSet<ListTanggalCuti>();
					int day = 0;
					for (ListTanggalCutiVO date : vo.getListTanggal()) {
						day++;
						ListTanggalCuti tanggal = listTanggalCutiDao.findOne(date.getNoRec());
						ListTanggalCuti tgl = new ListTanggalCuti();
						tgl.setTgl(tanggal.getTgl());
						listTanggalCutiDao.delete(tanggal);
						tgl.setApprovalStatus(false);
						tgl.setPlanningPegawaiStatus(planningPegawaiStatusDitangguhkan);
						tgl.setStatusEnabled(true);
						listTanggal.add(tgl);
					}
					planningPegawaiStatusDitangguhkan.setJumlahHari(day);
					planningPegawaiStatusDitangguhkan.getListTanggal().clear();
					// planningPegawaiStatusDitangguhkan.setListTanggal(listTanggal);
					planningPegawaiStatusDitangguhkan.getListTanggal().addAll(listTanggal);
					Double selisih = 0.0;
					if (CommonUtil.isNotNullOrEmpty(historiRekap.getNilaiIndex())
							&& CommonUtil.isNotNullOrEmpty(historiRekap.getNilaiIndexTotal())) {
						selisih = historiRekap.getNilaiIndexTotal() / historiRekap.getNilaiIndex().doubleValue();
						int selisihHari = historiRekap.getNilaiIndex() - day;
						historiRekap.setNilaiIndex(selisihHari);
						planningPegawaiStatus.setJumlahHari(selisihHari);
						historiRekap.setNilaiIndexTotal(selisih * selisihHari);
					}
					model = planningPegawaiStatusDao.save(planningPegawaiStatusDitangguhkan);

				}
				planningPegawaiStatusDao.save(planningPegawaiStatus);
				PegawaiHistoriRekapIndex models = pegawaiHistoriRekapIndexDao.save(historiRekap);
				result.put("noRecPlanningDitangguhkan", model.getNoRec());
				result.put("noRecPlanning", vo.getNoRec());
				result.put("noRecHistoryRekap", models.getNoRec());

			}
		}
		return result;
	}

	@Override
	public Map<String, Object> savePlanningPegawaiStatusRev(PlanningPegawaiStatusVO vo) {
		Map<String, Object> result = new HashMap<>();
		PlanningPegawaiStatus planningPegawaiStatus = new PlanningPegawaiStatus();
		List<String> listTgl = new ArrayList<>();

		if (CommonUtil.isNotNullOrEmpty(vo)) {
			planningPegawaiStatus = planningPegawaiStatusConverter.transferVOToModel(vo, new PlanningPegawaiStatus());
		}
		Integer day = 0;
		String noPlanning = noUsulan().get("noUsulan").toString();

		planningPegawaiStatus.setNoPlanning(noPlanning);
		planningPegawaiStatus.setStatusEnabled(true);
		planningPegawaiStatus.setApprovalStatus(0);

		if (CommonUtil.isNotNullOrEmpty(vo.getStatusPegawaiPlan())) {
			planningPegawaiStatus.setStatusPegawaiPlan(
					statusPegawaiConverter.transferVOToModel(vo.getStatusPegawaiPlan(), new StatusPegawai()));
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getJabatanPemberiNotaDinas())) {
			planningPegawaiStatus.setJabatanPemberiNotaDinas(
					jabatanConverter.transferVOToModel(vo.getJabatanPemberiNotaDinas(), new Jabatan()));
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getPegawai())) {
			planningPegawaiStatus.setPegawai(pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai()));
		}

		Set<ListTanggalCuti> listTanggal = new HashSet<ListTanggalCuti>();
		if (CommonUtil.isNotNullOrEmpty(vo.getListTanggal())) {
			for (ListTanggalCutiVO date : vo.getListTanggal()) {
				day++;
				ListTanggalCuti tanggal = listTanggalConverter.transferVOToModel(date, new ListTanggalCuti());
				tanggal.setPlanningPegawaiStatus(planningPegawaiStatus);
				tanggal.setStatusEnabled(true);
				if (CommonUtil.isNotNullOrEmpty(tanggal)) {
					listTanggal.add(tanggal);
				}
			}
		}
		planningPegawaiStatus.setJumlahHari(day);
		if (CommonUtil.isNotNullOrEmpty(listTanggal)) {
			planningPegawaiStatus.setListTanggal(listTanggal);
		}

		if (CommonUtil.isNotNullOrEmpty(vo.getDeskripsiStatusPegawaiPlan())) {
			planningPegawaiStatus.setDeskripsiStatusPegawaiPlan(vo.getDeskripsiStatusPegawaiPlan());
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getKeteranganLainyaPlan())) {
			planningPegawaiStatus.setKeteranganLainyaPlan(vo.getKeteranganLainyaPlan());
		}

		planningPegawaiStatus.setAlamatCuti(vo.getAlamatCuti());
		planningPegawaiStatus.setNomorTelepon(vo.getNomorTelepon());
		planningPegawaiStatus.setIsCutiLuarNegeri(vo.getIsCutiLuarNegeri());
		planningPegawaiStatus.setIsCutiLuarKota(vo.getIsCutiLuarKota());

		if (CommonUtil.isNotNullOrEmpty(vo.getAlamatTugas())) {
			planningPegawaiStatus.setAlamatTugas(vo.getAlamatTugas());
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getNoSuratTugas())) {
			planningPegawaiStatus.setNoSuratTugas(vo.getNoSuratTugas());
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getNoNotaDinas())) {
			planningPegawaiStatus.setNoNotaDinas(vo.getNoNotaDinas());
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getTglNotaDinas())) {
			planningPegawaiStatus.setTglNotaDinas(vo.getTglNotaDinas());
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getJenisPerawatan())) {
			planningPegawaiStatus.setJenisPerawatan(vo.getJenisPerawatan());
		}

		PlanningPegawaiStatus model = planningPegawaiStatusDao.save(planningPegawaiStatus);

		for (ListTanggalCuti listTanggalCuti : model.getListTanggal()) {
			listTgl.add(listTanggalCuti.getNoRec());
		}
		result.put("listTgl", listTgl);
		result.put("noRec", model.getNoRec());
		result.put("bisaCuti", true);

		return result;
	}

	@Override
	public Map<String, Object> setJatahCuti(KelompokShiftKerjaCustomVO vo) {
		Map<String, Object> result = new HashMap<String, Object>();
		if (CommonUtil.isNotNullOrEmpty(vo)) {
			for (FactoRateKelompokShiftVO vos : vo.getFactorRateKelompokShift()) {
				Date monthDayNow = new Date();
				Calendar cal = Calendar.getInstance();
				cal.setTime(monthDayNow);
				String monthPeriodInput = String.valueOf(cal.get(Calendar.MONTH) + 1);
				if (monthPeriodInput.length() == 1) {
					monthPeriodInput = "0" + monthPeriodInput;
				}
				String dayPeriodInput = String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
				if (dayPeriodInput.length() == 1) {
					dayPeriodInput = "0" + dayPeriodInput;
				}
				String periodeInput = String.valueOf(Integer.valueOf(vos.getPeriode().toString()) - 1) + "-"
						+ monthPeriodInput + "-" + dayPeriodInput;
				List<Pegawai> listpegawai = pegawaiDao.findPegawaiStatusAktif(vos.getKelompokShift().getId(),
						periodeInput);
				for (Pegawai pegawai : listpegawai) {
					int todaysYear = Calendar.getInstance().get(Calendar.YEAR);
					int todaysYear1 = Integer
							.valueOf(settingDataFixedDao.getSettingDataFixed("tahunPenangguhanException"));
					// storing data cuti
					Map<String, Object> dataCuti = getDataCuti(pegawai.getId(), String.valueOf(todaysYear),
							vos.getKomponenIndex().getId()); // menghitung data
																// cuti selalu
																// based on
																// tahun
																// berjalan
					List<Map<String, Object>> listDataCuti = new ArrayList<>();
					Map<String, Object> mapDataCutiB2 = new HashMap<>();
					Map<String, Object> mapDataCutiB1 = new HashMap<>();
					Map<String, Object> mapDataCutiB = new HashMap<>();
					Map<String, Object> mapDataCutiN = new HashMap<>();
					Map<String, Object> mapDataCutiN1 = new HashMap<>();
					Map<String, Object> mapDataCutiN2 = new HashMap<>();
					mapDataCutiB2.put("sisaCuti", dataCuti.get("sisaCutiB2"));
					mapDataCutiB2.put("cutiTerpakai", dataCuti.get("cutiTerpakaiB2"));
					mapDataCutiB2.put("isTangguhkan", dataCuti.get("isTangguhkanB2"));
					mapDataCutiB2.put("tahun", todaysYear - 2);
					mapDataCutiB2.put("komponenIndex", 21);
					mapDataCutiB1.put("sisaCuti", dataCuti.get("sisaCutiB1"));
					mapDataCutiB1.put("cutiTerpakai", dataCuti.get("cutiTerpakaiB1"));
					mapDataCutiB1.put("isTangguhkan", dataCuti.get("isTangguhkanB1"));
					mapDataCutiB1.put("tahun", todaysYear - 1);
					mapDataCutiB1.put("komponenIndex", 21);
					mapDataCutiB.put("sisaCuti", dataCuti.get("sisaCutiB"));
					mapDataCutiB.put("cutiTerpakai", dataCuti.get("cutiTerpakaiB"));
					mapDataCutiB.put("isTangguhkan", dataCuti.get("isTangguhkanB"));
					mapDataCutiB.put("tahun", todaysYear);
					mapDataCutiB.put("komponenIndex", 21);
					mapDataCutiN.put("sisaCuti", dataCuti.get("sisaCutiN"));
					mapDataCutiN.put("cutiTerpakai", dataCuti.get("cutiTerpakaiN"));
					mapDataCutiN.put("isTangguhkan", dataCuti.get("isTangguhkanN"));
					mapDataCutiN.put("tahun", todaysYear);
					mapDataCutiN.put("komponenIndex", 5);
					mapDataCutiN1.put("sisaCuti", dataCuti.get("sisaCutiN1"));
					mapDataCutiN1.put("cutiTerpakai", dataCuti.get("cutiTerpakaiN1"));
					mapDataCutiN1.put("isTangguhkan", dataCuti.get("isTangguhkanN1"));
					mapDataCutiN1.put("tahun", todaysYear - 1);
					mapDataCutiN1.put("komponenIndex", 5);
					mapDataCutiN2.put("sisaCuti", dataCuti.get("sisaCutiN2"));
					mapDataCutiN2.put("cutiTerpakai", dataCuti.get("cutiTerpakaiN2"));
					mapDataCutiN2.put("isTangguhkan", dataCuti.get("isTangguhkanN2"));
					mapDataCutiN2.put("tahun", todaysYear - 2);
					mapDataCutiN2.put("komponenIndex", 5);
					listDataCuti.add(mapDataCutiB2);
					listDataCuti.add(mapDataCutiB1);
					listDataCuti.add(mapDataCutiB);
					listDataCuti.add(mapDataCutiN);
					listDataCuti.add(mapDataCutiN1);
					listDataCuti.add(mapDataCutiN2);
					KomponenIndexVO kompIndexVoB = new KomponenIndexVO();
					kompIndexVoB.setId(21);
					KomponenIndexVO kompIndexVoT = new KomponenIndexVO();
					kompIndexVoT.setId(5);

					for (Map<String, Object> mapDataCuti : listDataCuti) {
						JatahCutiDanIzin jatahCutiDanIzin = new JatahCutiDanIzin();
						jatahCutiDanIzin.setPegawai(pegawai);
						if (mapDataCuti.get("komponenIndex").equals(kompIndexVoB.getId())) {
							jatahCutiDanIzin.setKomponenIndex(
									komponenIndexConverter.transferVOToModel(kompIndexVoB, new KomponenIndex()));
							JatahCutiDanIzin currentData = jatahCutiDanIzinDao.getJatahCuti(
									mapDataCuti.get("tahun").toString(), pegawai.getId(), kompIndexVoB.getId());
							if (CommonUtil.isNotNullOrEmpty(currentData)) {
								jatahCutiDanIzin.setNoRec(currentData.getNoRec());
								if (vos.getKomponenIndex().getId().equals(mapDataCuti.get("komponenIndex"))
										&& vos.getPeriode().equals(mapDataCuti.get("tahun").toString())) {
									jatahCutiDanIzin.setValue(vos.getValue());
								} else {
									jatahCutiDanIzin.setValue(currentData.getValue());
								}
							} else {
								if (vos.getKomponenIndex().getId().equals(mapDataCuti.get("komponenIndex"))
										&& vos.getPeriode().equals(mapDataCuti.get("tahun").toString())) {
									jatahCutiDanIzin.setValue(vos.getValue());
								} else {
									jatahCutiDanIzin.setValue(0);
								}
							}
						} else {
							jatahCutiDanIzin.setKomponenIndex(
									komponenIndexConverter.transferVOToModel(kompIndexVoT, new KomponenIndex()));
							JatahCutiDanIzin currentData = jatahCutiDanIzinDao.getJatahCuti(
									mapDataCuti.get("tahun").toString(), pegawai.getId(), kompIndexVoT.getId());
							if (CommonUtil.isNotNullOrEmpty(currentData)) {
								jatahCutiDanIzin.setNoRec(currentData.getNoRec());
								if (vos.getKomponenIndex().getId().equals(mapDataCuti.get("komponenIndex"))
										&& vos.getPeriode().equals(mapDataCuti.get("tahun").toString())) {
									jatahCutiDanIzin.setValue(vos.getValue());
								} else {
									jatahCutiDanIzin.setValue(currentData.getValue());
								}
							} else {
								if (vos.getKomponenIndex().getId().equals(mapDataCuti.get("komponenIndex"))
										&& vos.getPeriode().equals(mapDataCuti.get("tahun").toString())) {
									jatahCutiDanIzin.setValue(vos.getValue());
								} else {
									jatahCutiDanIzin.setValue(0);
								}
							}
						}
						if (Integer.parseInt(vos.getPeriode()) > todaysYear) {
							jatahCutiDanIzin.setKomponenIndex(komponenIndexConverter
									.transferVOToModel(vos.getKomponenIndex(), new KomponenIndex()));
							JatahCutiDanIzin currentData = jatahCutiDanIzinDao.getJatahCuti(vos.getPeriode().toString(),
									pegawai.getId(), vos.getKomponenIndex().getId());
							if (CommonUtil.isNotNullOrEmpty(currentData)) {
								jatahCutiDanIzin.setNoRec(currentData.getNoRec());
							}
							jatahCutiDanIzin.setValue(vos.getValue());
							jatahCutiDanIzin.setTahun(vos.getPeriode().toString());
							jatahCutiDanIzin.setCutiTerpakai(0);
							jatahCutiDanIzin.setSisaCuti(vos.getValue());
							jatahCutiDanIzin.setIsTangguhkan(false);
							if (CommonUtil.isNotNullOrEmpty(jatahCutiDanIzin)) {
								JatahCutiDanIzin model = jatahCutiDanIzinDao.save(jatahCutiDanIzin);
								result.put("tahun ", model.getTahun());
								result.put("komponenIndex ", model.getKomponenIndex().getId());
							}
							break;
						} else if (Integer.parseInt(vos.getPeriode()) <= todaysYear
								&& Integer.parseInt(vos.getPeriode()) >= todaysYear - 2) {
							jatahCutiDanIzin.setTahun(mapDataCuti.get("tahun").toString());
							if (vos.getIsTangguhkan()) { // penangguhan
								if (Integer.parseInt(vos.getPeriode()) == todaysYear
										&& Integer.parseInt(mapDataCuti.get("tahun").toString()) == todaysYear
										&& mapDataCuti.get("komponenIndex").equals(kompIndexVoT.getId())) {
									jatahCutiDanIzin.setIsTangguhkan(vos.getIsTangguhkan());
								} else if (Integer.parseInt(vos.getPeriode()) == todaysYear1
										&& Integer.parseInt(mapDataCuti.get("tahun").toString()) == todaysYear1
										&& mapDataCuti.get("komponenIndex").equals(kompIndexVoT.getId())) {
									jatahCutiDanIzin.setIsTangguhkan(vos.getIsTangguhkan());
								} else {
									if ((Boolean) mapDataCuti.get("isTangguhkan")) {
										jatahCutiDanIzin.setIsTangguhkan((Boolean) mapDataCuti.get("isTangguhkan"));
									} else {
										jatahCutiDanIzin.setIsTangguhkan(false);
									}
								}
							} else { // simpan atau update jatah cuti
								if ((Boolean) mapDataCuti.get("isTangguhkan")) {
									jatahCutiDanIzin.setIsTangguhkan((Boolean) mapDataCuti.get("isTangguhkan"));
								} else {
									jatahCutiDanIzin.setIsTangguhkan(false);
								}
							}
							if (CommonUtil.isNotNullOrEmpty(mapDataCuti.get("cutiTerpakai"))) {
								jatahCutiDanIzin
										.setCutiTerpakai(Integer.parseInt(mapDataCuti.get("cutiTerpakai").toString()));
							} else {
								jatahCutiDanIzin.setCutiTerpakai(0);
							}
							if (CommonUtil.isNotNullOrEmpty(mapDataCuti.get("sisaCuti"))) {
								jatahCutiDanIzin.setSisaCuti(Integer.parseInt(mapDataCuti.get("sisaCuti").toString()));
							} else {
								jatahCutiDanIzin.setSisaCuti(0);
							}
							if (CommonUtil.isNotNullOrEmpty(jatahCutiDanIzin)) {
								JatahCutiDanIzin model = jatahCutiDanIzinDao.save(jatahCutiDanIzin);
								result.put("tahun ", model.getTahun());
								result.put("komponenIndex ", model.getKomponenIndex().getId());
							}
						}
					}
				}
			}
		}
		return result;
	}

	@Override
	public Map<String, Object> setJatahCutiPegawai(JatahCutiDanIzinVO vo) {
		Map<String, Object> result = new HashMap<String, Object>();
		if (CommonUtil.isNotNullOrEmpty(vo)) {
			int todaysYear = Calendar.getInstance().get(Calendar.YEAR);
			int todaysYear1 = todaysYear - 1;

			// storing_data_cuti
			Map<String, Object> dataCuti = getDataCuti(vo.getPegawai().getId(), String.valueOf(todaysYear),
					vo.getKomponenIndex().getId()); // menghitung_data_cuti_selalu_based_on_tahun_berjalan

			List<Map<String, Object>> listDataCuti = new ArrayList<>();
			Map<String, Object> mapDataCutiB2 = new HashMap<>();
			Map<String, Object> mapDataCutiB1 = new HashMap<>();
			Map<String, Object> mapDataCutiB = new HashMap<>();
			Map<String, Object> mapDataCutiN = new HashMap<>();
			Map<String, Object> mapDataCutiN1 = new HashMap<>();
			Map<String, Object> mapDataCutiN2 = new HashMap<>();
			mapDataCutiB2.put("sisaCuti", dataCuti.get("sisaCutiB2"));
			mapDataCutiB2.put("cutiTerpakai", dataCuti.get("cutiTerpakaiB2"));
			mapDataCutiB2.put("isTangguhkan", dataCuti.get("isTangguhkanB2"));
			mapDataCutiB2.put("tahun", todaysYear - 2);
			mapDataCutiB2.put("komponenIndex", 21);
			mapDataCutiB1.put("sisaCuti", dataCuti.get("sisaCutiB1"));
			mapDataCutiB1.put("cutiTerpakai", dataCuti.get("cutiTerpakaiB1"));
			mapDataCutiB1.put("isTangguhkan", dataCuti.get("isTangguhkanB1"));
			mapDataCutiB1.put("tahun", todaysYear - 1);
			mapDataCutiB1.put("komponenIndex", 21);
			mapDataCutiB.put("sisaCuti", dataCuti.get("sisaCutiB"));
			mapDataCutiB.put("cutiTerpakai", dataCuti.get("cutiTerpakaiB"));
			mapDataCutiB.put("isTangguhkan", dataCuti.get("isTangguhkanB"));
			mapDataCutiB.put("tahun", todaysYear);
			mapDataCutiB.put("komponenIndex", 21);
			mapDataCutiN.put("sisaCuti", dataCuti.get("sisaCutiN"));
			mapDataCutiN.put("cutiTerpakai", dataCuti.get("cutiTerpakaiN"));
			mapDataCutiN.put("isTangguhkan", dataCuti.get("isTangguhkanN"));
			mapDataCutiN.put("tahun", todaysYear);
			mapDataCutiN.put("komponenIndex", 5);
			mapDataCutiN1.put("sisaCuti", dataCuti.get("sisaCutiN1"));
			mapDataCutiN1.put("cutiTerpakai", dataCuti.get("cutiTerpakaiN1"));
			mapDataCutiN1.put("isTangguhkan", dataCuti.get("isTangguhkanN1"));
			mapDataCutiN1.put("tahun", todaysYear - 1);
			mapDataCutiN1.put("komponenIndex", 5);
			mapDataCutiN2.put("sisaCuti", dataCuti.get("sisaCutiN2"));
			mapDataCutiN2.put("cutiTerpakai", dataCuti.get("cutiTerpakaiN2"));
			mapDataCutiN2.put("isTangguhkan", dataCuti.get("isTangguhkanN2"));
			mapDataCutiN2.put("tahun", todaysYear - 2);
			mapDataCutiN2.put("komponenIndex", 5);
			listDataCuti.add(mapDataCutiB2);
			listDataCuti.add(mapDataCutiB1);
			listDataCuti.add(mapDataCutiB);
			listDataCuti.add(mapDataCutiN);
			listDataCuti.add(mapDataCutiN1);
			listDataCuti.add(mapDataCutiN2);
			KomponenIndexVO kompIndexVoB = new KomponenIndexVO();
			kompIndexVoB.setId(21);
			KomponenIndexVO kompIndexVoT = new KomponenIndexVO();
			kompIndexVoT.setId(5);

			for (Map<String, Object> mapDataCuti : listDataCuti) {
				JatahCutiDanIzin jatahCutiDanIzin = new JatahCutiDanIzin();
				jatahCutiDanIzin.setPegawai(pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai()));
				if (mapDataCuti.get("komponenIndex").equals(kompIndexVoB.getId())) {
					jatahCutiDanIzin.setKomponenIndex(
							komponenIndexConverter.transferVOToModel(kompIndexVoB, new KomponenIndex()));
					JatahCutiDanIzin currentData = jatahCutiDanIzinDao.getJatahCuti(mapDataCuti.get("tahun").toString(),
							vo.getPegawai().getId(), kompIndexVoB.getId());
					if (CommonUtil.isNotNullOrEmpty(currentData)) {
						jatahCutiDanIzin.setNoRec(currentData.getNoRec());
						if (vo.getKomponenIndex().getId().equals(mapDataCuti.get("komponenIndex"))
								&& vo.getTahun().equals(mapDataCuti.get("tahun").toString())) {
							jatahCutiDanIzin.setValue(vo.getValue());
						} else {
							jatahCutiDanIzin.setValue(currentData.getValue());
						}
					} else {
						if (vo.getKomponenIndex().getId().equals(mapDataCuti.get("komponenIndex"))
								&& vo.getTahun().equals(mapDataCuti.get("tahun").toString())) {
							jatahCutiDanIzin.setValue(vo.getValue());
						} else {
							jatahCutiDanIzin.setValue(0);
						}
					}
				} else {
					jatahCutiDanIzin.setKomponenIndex(
							komponenIndexConverter.transferVOToModel(kompIndexVoT, new KomponenIndex()));
					JatahCutiDanIzin currentData = jatahCutiDanIzinDao.getJatahCuti(mapDataCuti.get("tahun").toString(),
							vo.getPegawai().getId(), kompIndexVoT.getId());
					if (CommonUtil.isNotNullOrEmpty(currentData)) {
						jatahCutiDanIzin.setNoRec(currentData.getNoRec());
						if (vo.getKomponenIndex().getId().equals(mapDataCuti.get("komponenIndex"))
								&& vo.getTahun().equals(mapDataCuti.get("tahun").toString())) {
							jatahCutiDanIzin.setValue(vo.getValue());
						} else {
							jatahCutiDanIzin.setValue(currentData.getValue());
						}
					} else {
						if (vo.getKomponenIndex().getId().equals(mapDataCuti.get("komponenIndex"))
								&& vo.getTahun().equals(mapDataCuti.get("tahun").toString())) {
							jatahCutiDanIzin.setValue(vo.getValue());
						} else {
							jatahCutiDanIzin.setValue(0);
						}
					}
				}
				if (Integer.parseInt(vo.getTahun()) > todaysYear) {
					jatahCutiDanIzin.setKomponenIndex(
							komponenIndexConverter.transferVOToModel(vo.getKomponenIndex(), new KomponenIndex()));
					JatahCutiDanIzin currentData = jatahCutiDanIzinDao.getJatahCuti(vo.getTahun().toString(),
							vo.getPegawai().getId(), vo.getKomponenIndex().getId());
					if (CommonUtil.isNotNullOrEmpty(currentData)) {
						jatahCutiDanIzin.setNoRec(currentData.getNoRec());
					}
					jatahCutiDanIzin.setValue(vo.getValue());
					jatahCutiDanIzin.setTahun(vo.getTahun().toString());
					jatahCutiDanIzin.setCutiTerpakai(0);
					jatahCutiDanIzin.setSisaCuti(vo.getValue());
					jatahCutiDanIzin.setIsTangguhkan(false);
					if (CommonUtil.isNotNullOrEmpty(jatahCutiDanIzin)) {
						JatahCutiDanIzin model = jatahCutiDanIzinDao.save(jatahCutiDanIzin);
						result.put("tahun ", model.getTahun());
						result.put("komponenIndex ", model.getKomponenIndex().getId());
					}
					break;
				} else if (Integer.parseInt(vo.getTahun()) <= todaysYear
						&& Integer.parseInt(vo.getTahun()) >= todaysYear - 2) {
					jatahCutiDanIzin.setTahun(mapDataCuti.get("tahun").toString());
					if (vo.getIsTangguhkan()) { // penangguhan
						if (Integer.parseInt(vo.getTahun()) == todaysYear
								&& Integer.parseInt(mapDataCuti.get("tahun").toString()) == todaysYear
								&& mapDataCuti.get("komponenIndex").equals(kompIndexVoT.getId())) {
							jatahCutiDanIzin.setIsTangguhkan(vo.getIsTangguhkan());
						} else if (Integer.parseInt(vo.getTahun()) == todaysYear1
								&& Integer.parseInt(mapDataCuti.get("tahun").toString()) == todaysYear1
								&& mapDataCuti.get("komponenIndex").equals(kompIndexVoT.getId())) {
							jatahCutiDanIzin.setIsTangguhkan(vo.getIsTangguhkan());
						} else {
							if ((Boolean) mapDataCuti.get("isTangguhkan")) {
								jatahCutiDanIzin.setIsTangguhkan((Boolean) mapDataCuti.get("isTangguhkan"));
							} else {
								jatahCutiDanIzin.setIsTangguhkan(false);
							}
						}
					} else { // simpan atau update jatah cuti
						if ((Boolean) mapDataCuti.get("isTangguhkan")) {
							jatahCutiDanIzin.setIsTangguhkan((Boolean) mapDataCuti.get("isTangguhkan"));
						} else {
							jatahCutiDanIzin.setIsTangguhkan(false);
						}
					}
					if (CommonUtil.isNotNullOrEmpty(mapDataCuti.get("cutiTerpakai"))) {
						jatahCutiDanIzin.setCutiTerpakai(Integer.parseInt(mapDataCuti.get("cutiTerpakai").toString()));
					} else {
						jatahCutiDanIzin.setCutiTerpakai(0);
					}
					if (CommonUtil.isNotNullOrEmpty(mapDataCuti.get("sisaCuti"))) {
						jatahCutiDanIzin.setSisaCuti(Integer.parseInt(mapDataCuti.get("sisaCuti").toString()));
					} else {
						jatahCutiDanIzin.setSisaCuti(0);
					}
					if (CommonUtil.isNotNullOrEmpty(jatahCutiDanIzin)) {
						JatahCutiDanIzin model = jatahCutiDanIzinDao.save(jatahCutiDanIzin);
						result.put("tahun ", model.getTahun());
						result.put("komponenIndex ", model.getKomponenIndex().getId());
					}
				}
			}
		}
		return result;
	}

	@Override
	public List<Map<String, Object>> getAllDataCuti() {
		String komponen = settingDataFixedDao.getSettingDataFixed("komponenIndeksCuti");
		List<Map<String, Object>> result = jatahCutiDanIzinDao.getAllJatahCuti(Integer.valueOf(komponen));

		return result;
	}

	@Override
	public List<Map<String, Object>> getAllDataCuti(Integer idPegawai) {
		LocalDateTime now = LocalDateTime.now();
		Integer tahunIni = now.getYear();
		Integer tahunLalu = tahunIni - 1;
		Integer duaTahunLalu = tahunIni - 2;

		String batasPenangguhan = settingDataFixedDao.getSettingDataFixed("tglBatasPenangguhanCuti");
		String tglBatasPenangguhan = String.valueOf(now.getYear()) + "-" + batasPenangguhan;
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime penangguhanCutOff = LocalDateTime.parse(tglBatasPenangguhan, formatter);

		String komponenCutiTahunan = settingDataFixedDao.getSettingDataFixed("komponenIndeksCuti");
		String komponenCutiBersama = settingDataFixedDao.getSettingDataFixed("komponenIndeksCutiBersama");
		List<Integer> komponen = new ArrayList<>();
		komponen.add(Integer.valueOf(komponenCutiTahunan));
		komponen.add(Integer.valueOf(komponenCutiBersama));
		List<Map<String, Object>> result = jatahCutiDanIzinDao.getAllJatahCuti(komponen, idPegawai);

		for (Map<String, Object> map : result) {
			if (map.get("isTangguhkan").equals(false) && map.get("komponenIndexId").equals(5)) {
				if (Integer.parseInt(map.get("tahun").toString()) <= duaTahunLalu) {
					map.put("statusPenangguhan", "Tidak Ditangguhkan");
				} else if (duaTahunLalu < Integer.parseInt(map.get("tahun").toString())
						&& Integer.parseInt(map.get("tahun").toString()) <= tahunLalu
						&& now.isAfter(penangguhanCutOff)) {
					map.put("statusPenangguhan", "Tidak Ditangguhkan");
				} else {
					map.put("statusPenangguhan", "Belum Ditangguhkan");
				}
			} else if (map.get("isTangguhkan").equals(false) && map.get("komponenIndexId").equals(21)) {
				map.put("statusPenangguhan", "Tidak Dapat Ditangguhkan");
			} else {
				map.put("statusPenangguhan", "Ditangguhkan");
			}
		}

		return result;
	}

	@Override
	public Map<String, Object> perbaruiDataCuti(Integer idPegawai, Integer idStatusPegawai) {
		PegawaiVO pegawaiVo = new PegawaiVO();
		pegawaiVo.setId(idPegawai);

		KomponenIndexVO komponenIndexVo = new KomponenIndexVO();
		komponenIndexVo.setId(Master.KomponenIndex.CUTI_BERSAMA);

		SimpleDateFormat formatter = new SimpleDateFormat("yyyy");
		String year = formatter.format(DateUtil.now());

		Integer yearn1 = Integer.parseInt(year) - 1;
		String yearN1 = yearn1.toString();

		Integer yearn2 = Integer.parseInt(year) - 2;
		String yearN2 = yearn2.toString();

		Map<String, Object> dataCuti = this.getDataCuti(idPegawai, year, idStatusPegawai);

		JatahCutiDanIzinVO voTahunIni = new JatahCutiDanIzinVO();
		voTahunIni.setStatusEnabled(Master.STATUS_ENABLE_TRUE);
		voTahunIni.setTahun(year);
		voTahunIni.setKdProfile(Master.KODE_PROFILE);
		voTahunIni.setPegawai(pegawaiVo);
		voTahunIni.setValue(Integer.valueOf(dataCuti.get("dataCutiB").toString()));
		voTahunIni.setKomponenIndex(komponenIndexVo);
		voTahunIni.setIsTangguhkan(false);
		this.setJatahCutiPegawaiRecursive(voTahunIni);

		JatahCutiDanIzinVO voTahunLalu = new JatahCutiDanIzinVO();
		voTahunLalu.setStatusEnabled(Master.STATUS_ENABLE_TRUE);
		voTahunLalu.setTahun(yearN1);
		voTahunLalu.setKdProfile(Master.KODE_PROFILE);
		voTahunLalu.setPegawai(pegawaiVo);
		voTahunLalu.setValue(Integer.valueOf(dataCuti.get("dataCutiB1").toString()));
		voTahunLalu.setKomponenIndex(komponenIndexVo);
		voTahunLalu.setIsTangguhkan(false);
		this.setJatahCutiPegawaiRecursive(voTahunLalu);

		JatahCutiDanIzinVO voDuaTahunLalu = new JatahCutiDanIzinVO();
		voDuaTahunLalu.setStatusEnabled(Master.STATUS_ENABLE_TRUE);
		voDuaTahunLalu.setTahun(yearN2);
		voDuaTahunLalu.setKdProfile(Master.KODE_PROFILE);
		voDuaTahunLalu.setPegawai(pegawaiVo);
		voDuaTahunLalu.setValue(Integer.valueOf(dataCuti.get("dataCutiB2").toString()));
		voDuaTahunLalu.setKomponenIndex(komponenIndexVo);
		voDuaTahunLalu.setIsTangguhkan(false);
		this.setJatahCutiPegawaiRecursive(voDuaTahunLalu);

		Map<String, Object> result = new HashMap<>();
		result.putAll(dataCuti);

		return result;
	}

	@Override
	public Map<String, Object> setJatahCutiRecursive(KelompokShiftKerjaCustomVO vo) {
		/**
		 * set pertama untuk update data value(jatah cuti) ke tabel jatah cuti
		 */
		setJatahCuti(vo);
		/**
		 * set kedua untuk getDataCuti() terbaru agar push ke tabel jatah cuti
		 */
		Map<String, Object> result = setJatahCuti(vo);

		return result;
	}

	@Override
	public Map<String, Object> setJatahCutiPegawaiRecursive(JatahCutiDanIzinVO vo) {
		/**
		 * set pertama untuk update data value(jatah cuti) ke tabel jatah cuti
		 */
		setJatahCutiPegawai(vo);
		/**
		 * set kedua untuk getDataCuti() terbaru agar push ke tabel jatah cuti
		 */
		Map<String, Object> result = setJatahCutiPegawai(vo);

		return result;
	}

	@Override
	public JatahCutiDanIzinVO setJatahCutiDanIzinVo(Integer idPegawai, Integer idStatusPegawai) {
		JatahCutiDanIzinVO result = new JatahCutiDanIzinVO();
		PegawaiVO pegawai = new PegawaiVO();
		KomponenIndexVO komponenIndex = new KomponenIndexVO();

		Calendar now = Calendar.getInstance();
		int year = now.get(Calendar.YEAR);
		String tahun = String.valueOf(year);
		/**
		 * komponen index cuti tahunan
		 */
		List<Integer> listIdKomponenIndexId = new ArrayList<>();
		listIdKomponenIndexId.add(5);
		listIdKomponenIndexId.add(6);
		JatahCutiDanIzin jCuti = jatahCutiDanIzinDao.getJatahCuti(tahun, idPegawai, listIdKomponenIndexId);

		komponenIndex.setId(jCuti.getKomponenIndex().getId());
		pegawai.setId(idPegawai);
		result.setStatusEnabled(true);
		result.setTahun(tahun);
		result.setKdProfile((short) 0);
		result.setPegawai(pegawai);
		result.setValue(jCuti.getValue());
		result.setKomponenIndex(komponenIndex);
		result.setIsTangguhkan(jCuti.getIsTangguhkan());

		return result;
	}

	@Override
	public Map<String, Object> getApprovalStatusByNorecPlanning(Integer idPegawai, String noRec) {
		Map<String, Object> result = new HashMap<>();
		List<Integer> pegawaiSdm = pegawaiDao.getPegawaiSDMforCred(Master.UnitKerja.BAG_SDM,
				Master.SubUnitKerja.SUBBAG_KESEJAHTERAAN);
		List<Map<String, Object>> listData = planningPegawaiStatusDaoCustom.getApprovalStatusByNorecPlanning(idPegawai,
				noRec);
		if (pegawaiSdm.contains(idPegawai)) {
			List<Map<String, Object>> listDataCutiAlasanPenting = planningPegawaiStatusDaoCustom
					.getApprovalStatusCutiAlasanPentingDanSakit();
			for (Map<String, Object> map : listDataCutiAlasanPenting) {
				listData.add(map);
			}
		}

		if (CommonUtil.isNotNullOrEmpty(listData)) {
			for (Map<String, Object> map : listData) {
				List<Map<String, Object>> listTanggalCuti = planningPegawaiStatusDao
						.getListTanggalCuti((String) map.get("noRec"));
				List<Map<String, Object>> listTanggalCutiApproved = planningPegawaiStatusDao
						.getListTanggalCutiApproved((String) map.get("noRec"));
				map.put("lisTanggal", listTanggalCuti);
				map.put("listTanggalCutiDisetujui", listTanggalCutiApproved);
			}
			result.put("listData", listData);
		}
		return result;
	}

	@Override
	public Integer countJumlahPengajuanDiprosesByPegawai(Integer idPegawai, Integer idPlan) {
		Integer result = null;
		if (idPlan.equals(Master.StatusPegawai.CUTI_TAHUNAN)) {
			result = planningPegawaiStatusDao.getJumlahPengajuanDiprosesByPegawai(idPegawai, idPlan);
		} else if (idPlan.equals(Master.StatusPegawai.IZIN)) {
			result = planningPegawaiStatusDao.getJumlahPengajuanDiprosesTahunIniByPegawai(idPegawai, idPlan);
		}
		if (CommonUtil.isNullOrEmpty(result)) {
			result = 0;
		}
		return result;
	}

	@Override
	public Integer countJumlahPengajuanTahunDepanDiprosesByPegawai(Integer idPegawai, Integer idPlan) {
		Integer result = null;
		result = planningPegawaiStatusDao.getJumlahPengajuanDiprosesTahunDepanByPegawai(idPegawai, idPlan);
		if (CommonUtil.isNullOrEmpty(result)) {
			result = 0;
		}
		return result;
	}

	@Override
	public Integer countJumlahPengajuanDiprosesByPegawai(Integer idPegawai, Integer idPlan, String noPlanning) {
		Integer result = null;
		if (idPlan.equals(Master.StatusPegawai.CUTI_TAHUNAN)) {
			result = planningPegawaiStatusDao.getJumlahPengajuanDiprosesByPegawai(idPegawai, idPlan, noPlanning);
		} else if (idPlan.equals(Master.StatusPegawai.IZIN)) {
			result = planningPegawaiStatusDao.getJumlahPengajuanDiprosesTahunIniByPegawai(idPegawai, idPlan,
					noPlanning);
		}
		if (CommonUtil.isNullOrEmpty(result)) {
			result = 0;
		}
		return result;
	}

	@Override
	public Integer countJumlahPengajuanTahunDepanDiprosesByPegawai(Integer idPegawai, Integer idPlan,
			String noPlanning) {
		Integer result = null;
		result = planningPegawaiStatusDao.getJumlahPengajuanDiprosesTahunDepanByPegawai(idPegawai, idPlan, noPlanning);
		if (CommonUtil.isNullOrEmpty(result)) {
			result = 0;
		}
		return result;
	}

}
