package com.jasamedika.medifirst2000.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.joda.time.Chronology;
import org.joda.time.LocalDate;
import org.joda.time.chrono.IslamicChronology;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaSystemException;
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.AnggaranRemunerasiDao;
import com.jasamedika.medifirst2000.dao.BobotJenisIndikatorDao;
import com.jasamedika.medifirst2000.dao.IkiDanRemunerasiDao;
import com.jasamedika.medifirst2000.dao.IndikatorKinerjaDao;
import com.jasamedika.medifirst2000.dao.IndikatorKinerjaDetailDao;
import com.jasamedika.medifirst2000.dao.IndikatorKinerjaJabatanDao;
import com.jasamedika.medifirst2000.dao.JabatanDao;
import com.jasamedika.medifirst2000.dao.KalenderDao;
import com.jasamedika.medifirst2000.dao.LogbookKinerjaDao;
import com.jasamedika.medifirst2000.dao.LogbookKinerjaDetailDao;
import com.jasamedika.medifirst2000.dao.LogbookKinerjaDokterDao;
import com.jasamedika.medifirst2000.dao.MapPegawaiJabatanToUnitKerjaDao;
import com.jasamedika.medifirst2000.dao.MapPegawaiLaboratRadiologiDao;
import com.jasamedika.medifirst2000.dao.PegawaiDao;
import com.jasamedika.medifirst2000.dao.PelayananFarmakologiDao;
import com.jasamedika.medifirst2000.dao.PelayananNakesDao;
import com.jasamedika.medifirst2000.dao.PelayananPasienNakesDao;
import com.jasamedika.medifirst2000.dao.PelayananPasienPerawatDao;
import com.jasamedika.medifirst2000.dao.PelayananPasienPetugasDao;
import com.jasamedika.medifirst2000.dao.SettingDataFixedDao;
import com.jasamedika.medifirst2000.dao.ShiftKerjaDao;
import com.jasamedika.medifirst2000.dao.SkoringTindakanMedisDao;
import com.jasamedika.medifirst2000.dao.TabelAcuanIndeksIKIDao;
import com.jasamedika.medifirst2000.dao.TargetSkorDokterDetailDao;
import com.jasamedika.medifirst2000.dao.custom.SkoringTindakanMedisDaoCustom;
import com.jasamedika.medifirst2000.entities.IndikatorKinerja;
import com.jasamedika.medifirst2000.entities.IndikatorKinerjaDetail;
import com.jasamedika.medifirst2000.entities.Jabatan;
import com.jasamedika.medifirst2000.entities.Kalender;
import com.jasamedika.medifirst2000.entities.LogbookKinerja;
import com.jasamedika.medifirst2000.entities.LogbookKinerjaDokter;
import com.jasamedika.medifirst2000.entities.Pegawai;
import com.jasamedika.medifirst2000.entities.PelayananNakes;
import com.jasamedika.medifirst2000.entities.PelayananPasienNakes;
import com.jasamedika.medifirst2000.entities.PelayananPasienPerawat;
import com.jasamedika.medifirst2000.entities.SatuanIndikator;
import com.jasamedika.medifirst2000.exception.ServiceVOException;
import com.jasamedika.medifirst2000.service.CatatanPerkembanganPasienTerintegrasiService;
import com.jasamedika.medifirst2000.service.LogbookKinerjaService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.util.DateUtil;
import com.jasamedika.medifirst2000.vo.IndikatorKinerjaVO;
import com.jasamedika.medifirst2000.vo.JabatanVO;
import com.jasamedika.medifirst2000.vo.LogbookKinerjaVO;
import com.jasamedika.medifirst2000.vo.PegawaiVO;
import com.jasamedika.medifirst2000.vo.ReferensiSkorAnestesiVO;
import com.jasamedika.medifirst2000.vo.SatuanIndikatorVO;
import com.jasamedika.medifirst2000.vo.SkorDokterVO;

@Service("LogbookKinerjaService")
public class LogbookKinerjaServiceImpl extends BaseVoServiceImpl implements LogbookKinerjaService {

	@Autowired
	private BaseConverterImpl<LogbookKinerjaVO, LogbookKinerja> logbookKinerjaConverter;

	@Autowired
	private BaseConverterImpl<PegawaiVO, Pegawai> pegawaiConverter;

	@Autowired
	private BaseConverterImpl<JabatanVO, Jabatan> jabatanConverter;

	@Autowired
	private BaseConverterImpl<IndikatorKinerjaVO, IndikatorKinerja> indikatorKinerjaConverter;

	@Autowired
	private BaseConverterImpl<SatuanIndikatorVO, SatuanIndikator> satuanIndikatorConverter;

	@Autowired
	private LogbookKinerjaDao logbookKinerjaDao;

	@Autowired
	private LogbookKinerjaDetailDao logbookKinerjaDetailDao;

	@Autowired
	private IndikatorKinerjaDao indikatorKinerjaDao;

	@Autowired
	private AnggaranRemunerasiDao anggaranRemunerasiDao;

	@Autowired
	private PegawaiDao pegawaiDao;

	@Autowired
	private LogbookKinerjaDokterDao logbookKinerjaDokterDao;

	@Autowired
	private IkiDanRemunerasiDao ikiDanRemunerasiDao;

	@Autowired
	private SkoringTindakanMedisDao skoringTindakanMedisDao;

	@Autowired
	private SkoringTindakanMedisDaoCustom skoringTindakanMedisDaoCustom;

	@Autowired
	private IndikatorKinerjaDetailDao indikatorKinerjaDetailDao;

	@Autowired
	private TabelAcuanIndeksIKIDao tabelAcuanIndeksIKIDao;

	@Autowired
	private ShiftKerjaDao shiftKerjaDao;

	@Autowired
	private MapPegawaiLaboratRadiologiDao mapPegawaiLaboratRadiologiDao;

	@Autowired
	private MapPegawaiJabatanToUnitKerjaDao mapPegawaiJabatanToUnitKerjaDao;

	@Autowired
	private BobotJenisIndikatorDao bobotJenisIndikatorDao;

	@Autowired
	private KalenderDao kalenderDao;

	@Autowired
	private JabatanDao jabatanDao;

	@Autowired
	private CatatanPerkembanganPasienTerintegrasiService cpptService;

	@Autowired
	private PelayananPasienPetugasDao pelayananPasienPetugasDao;

	@Autowired
	private PelayananPasienNakesDao pelayananPasienNakesDao;

	@Autowired
	private PelayananNakesDao pelayananNakesDao;

	@Autowired
	private TargetSkorDokterDetailDao targetSkorDokterDetailDao;

	@Autowired
	private PelayananPasienPerawatDao pelayananPasienPerawatDao;

	@Autowired
	private PelayananFarmakologiDao pelayananFarmakologiDao;

	@Autowired
	private IndikatorKinerjaJabatanDao indikatorKinerjaJabatanDao;

	@Autowired
	private SettingDataFixedDao settingDataFixedDao;

	@Override
	public LogbookKinerjaVO add(LogbookKinerjaVO vo) throws JpaSystemException, ServiceVOException {
		Pegawai pegawai = pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai());
		Jabatan jabatan = jabatanConverter.transferVOToModel(vo.getJabatan(), new Jabatan());
		IndikatorKinerja indikatorKinerja = indikatorKinerjaConverter.transferVOToModel(vo.getIndikatorKinerja(),
				new IndikatorKinerja());
		LogbookKinerja logbookKinerja = logbookKinerjaConverter.transferVOToModel(vo, new LogbookKinerja());

		logbookKinerja.setPegawai(pegawai);
		logbookKinerja.setJabatan(jabatan);
		logbookKinerja.setIndikatorKinerja(indikatorKinerja);
		if (vo.getIndikatorKinerja().getId().equals(Master.IndikatorKinerja.PEMENUHAN_JAM_KERJA)) {
			Double targetJamKerja = hitungTargetMenitKerja(vo.getBulan());
			logbookKinerja.setTarget(targetJamKerja);
		}
		logbookKinerja.setCapaian(0.0);
		LogbookKinerja resultModel = logbookKinerjaDao.save(logbookKinerja);

		LogbookKinerjaVO resultVO = new LogbookKinerjaVO();
		resultVO = logbookKinerjaConverter.transferModelToVO(resultModel, resultVO);

		return resultVO;
	}

	@Override
	public LogbookKinerjaVO update(LogbookKinerjaVO vo) throws JpaSystemException, ServiceVOException {
		DateFormat mf = new SimpleDateFormat("yyyy-MM");

		LogbookKinerja logbookKinerjaLama = logbookKinerjaDao.findOne(vo.getNoRec());

		Pegawai pegawai = pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai());
		Jabatan jabatan = jabatanConverter.transferVOToModel(vo.getJabatan(), new Jabatan());
		IndikatorKinerja indikatorKinerja = indikatorKinerjaConverter.transferVOToModel(vo.getIndikatorKinerja(),
				new IndikatorKinerja());
		LogbookKinerja logbookKinerjaBaru = logbookKinerjaConverter.transferVOToModel(vo, logbookKinerjaLama);

		logbookKinerjaBaru.setPegawai(pegawai);
		logbookKinerjaBaru.setJabatan(jabatan);
		logbookKinerjaBaru.setIndikatorKinerja(indikatorKinerja);
		if (vo.getIndikatorKinerja().getId().equals(Master.IndikatorKinerja.PEMENUHAN_JAM_KERJA)) {
			Integer targetHariKerja = hitungTargetHariKerja(vo.getBulan());
			Double targetJamKerja = targetHariKerja.doubleValue() * Master.MENIT_KERJA_HARIAN;
			logbookKinerjaBaru.setTarget(targetJamKerja);
		}

		LogbookKinerjaVO resultVO = new LogbookKinerjaVO();
		if (vo.getIndikatorKinerja().getId().equals(Master.IndikatorKinerja.KEPATUHAN_PELAYANAN_MEDIS)) {
			List<LogbookKinerjaDokter> listLogbookDetail = new ArrayList<>();

			List<IndikatorKinerjaDetail> listIndikatorDetail = indikatorKinerjaDetailDao
					.findByIndikator(vo.getIndikatorKinerja().getId());
			for (IndikatorKinerjaDetail indikatorDetail : listIndikatorDetail) {
				LogbookKinerjaDokter logbookDetail = logbookKinerjaDokterDao.findOne(mf.format(vo.getBulan()),
						vo.getPegawai().getId(), vo.getJabatan().getId(), indikatorDetail.getId());
				listLogbookDetail.add(logbookDetail);
			}
			for (LogbookKinerjaDokter logbookDetail : listLogbookDetail) {
				if (CommonUtil.isNotNullOrEmpty(logbookDetail)
						&& CommonUtil.isNotNullOrEmpty(logbookDetail.getDetailCapaian()) && !vo.getStatusVerifikasi()
						&& vo.getStatusEnabled()) {
					resultVO.setResponseMessage(
							"Catatan kegiatan kinerja sudah diverifikasi, tidak dapat batal verifikasi kontrak!");

					break;
				} else if (CommonUtil.isNotNullOrEmpty(logbookDetail)
						&& CommonUtil.isNotNullOrEmpty(logbookDetail.getDetailCapaian()) && !vo.getStatusVerifikasi()
						&& !vo.getStatusEnabled()) {
					resultVO.setResponseMessage(
							"Catatan kegiatan kinerja sudah diverifikasi, tidak dapat hapus kontrak!");

					break;
				}
			}

			if (CommonUtil.isNullOrEmpty(resultVO.getResponseMessage()) && !vo.getStatusEnabled()) {
				/**
				 * Hapus komponen detail kontrak kinerja
				 */
				logbookKinerjaDokterDao.delete(listLogbookDetail);

				LogbookKinerja resultModel = logbookKinerjaDao.save(logbookKinerjaBaru);
				resultVO = logbookKinerjaConverter.transferModelToVO(resultModel, resultVO);
			} else if (CommonUtil.isNullOrEmpty(resultVO.getResponseMessage())) {
				LogbookKinerja resultModel = logbookKinerjaDao.save(logbookKinerjaBaru);
				resultVO = logbookKinerjaConverter.transferModelToVO(resultModel, resultVO);
			}
		} else {
			List<Map<String, Object>> existedWorkingRecord = findUsedWorkingRecordByKontrak(vo.getNoRec());
			if (existedWorkingRecord.size() > 0 && !vo.getStatusVerifikasi() && vo.getStatusEnabled()) {
				resultVO.setResponseMessage("Catatan kegiatan kinerja sudah diisi, tidak dapat batal verifikasi!");
			} else if (existedWorkingRecord.size() > 0 && !vo.getStatusVerifikasi() && !vo.getStatusEnabled()) {
				resultVO.setResponseMessage("Catatan kegiatan kinerja sudah diisi, tidak dapat hapus kontrak!");
			} else {
				LogbookKinerja resultModel = logbookKinerjaDao.save(logbookKinerjaBaru);
				resultVO = logbookKinerjaConverter.transferModelToVO(resultModel, resultVO);
			}
		}

		return resultVO;
	}

	@Override
	public Boolean delete(String key) throws JpaSystemException {
		logbookKinerjaDao.delete(key);

		return true;
	}

	@Override
	public LogbookKinerjaVO findById(String key) throws JpaSystemException {
		LogbookKinerjaVO result = new LogbookKinerjaVO();

		LogbookKinerja logbookKinerja = logbookKinerjaDao.findOne(key);
		if (CommonUtil.isNotNullOrEmpty(logbookKinerja)) {
			result = logbookKinerjaConverter.transferModelToVO(logbookKinerja, result);
		}

		return result;
	}

	@Override
	public List<LogbookKinerjaVO> findAll() throws JpaSystemException {
		List<LogbookKinerjaVO> result = new ArrayList<LogbookKinerjaVO>();

		Iterable<LogbookKinerja> models = logbookKinerjaDao.findAll();
		if (CommonUtil.isNotNullOrEmpty(models)) {
			for (LogbookKinerja model : models) {
				LogbookKinerjaVO vo = new LogbookKinerjaVO();
				vo = logbookKinerjaConverter.transferModelToVO(model, vo);
				result.add(vo);
			}
		}

		return result;
	}

	@Override
	public Map<String, Object> findAllWithPageAndLimitAndSortByAndDirectionParameter(Integer page, Integer limit,
			String sort, String dir) {

		return null;
	}

	@Override
	public LogbookKinerjaVO verify(LogbookKinerjaVO vo) throws JpaSystemException, ServiceVOException {
		DateFormat df = new SimpleDateFormat("yyyy-MM");

		Map<String, Object> kontrak = logbookKinerjaDao.findKontrakForVerify(df.format(vo.getBulan()),
				vo.getPegawai().getId(), vo.getIndikatorKinerja().getId());

		if (CommonUtil.isNullOrEmpty(kontrak)) {
			return null;
		}

		LogbookKinerja logbookKinerjaLama = logbookKinerjaDao.findOne(kontrak.get("noRec").toString());

		Pegawai pegawai = pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai());
		Jabatan jabatan = new Jabatan();
		jabatan.setId(Integer.valueOf(kontrak.get("jabatanId").toString()));
		IndikatorKinerja indikatorKinerja = indikatorKinerjaConverter.transferVOToModel(vo.getIndikatorKinerja(),
				new IndikatorKinerja());
		LogbookKinerja logbookKinerjaBaru = logbookKinerjaConverter.transferVOToModel(vo, logbookKinerjaLama);

		logbookKinerjaBaru.setPegawai(pegawai);
		logbookKinerjaBaru.setJabatan(jabatan);
		logbookKinerjaBaru.setIndikatorKinerja(indikatorKinerja);
		LogbookKinerja resultModel = logbookKinerjaDao.save(logbookKinerjaBaru);

		LogbookKinerjaVO resultVO = new LogbookKinerjaVO();
		resultVO = logbookKinerjaConverter.transferModelToVO(resultModel, resultVO);

		return resultVO;
	}

	@Transactional
	public void autoVerify(LogbookKinerjaVO vo) throws JpaSystemException, ServiceVOException {
		DateFormat df = new SimpleDateFormat("yyyy-MM");

		Map<String, Object> kontrak = logbookKinerjaDao.findKontrakForVerify(df.format(vo.getBulan()),
				vo.getPegawai().getId(), vo.getIndikatorKinerja().getId());
		LogbookKinerja logbookKinerja = logbookKinerjaDao.findOne(kontrak.get("noRec").toString());

		Pegawai pegawai = new Pegawai();
		pegawai.setId(vo.getPegawai().getId());
		Jabatan jabatan = new Jabatan();
		jabatan.setId(Integer.valueOf(kontrak.get("jabatanId").toString()));
		IndikatorKinerja indikatorKinerja = new IndikatorKinerja();
		indikatorKinerja.setId(vo.getIndikatorKinerja().getId());

		logbookKinerja.setPegawai(pegawai);
		logbookKinerja.setJabatan(jabatan);
		logbookKinerja.setIndikatorKinerja(indikatorKinerja);
		logbookKinerja.setCapaian(vo.getCapaian());
		logbookKinerjaDao.save(logbookKinerja);
	}

	@Override
	public LogbookKinerjaVO addPengajuanKontrakKinerja(LogbookKinerjaVO vo)
			throws JpaSystemException, ServiceVOException {
		SatuanIndikator satuanIndikator = satuanIndikatorConverter
				.transferVOToModel(vo.getIndikatorKinerja().getSatuanIndikator(), new SatuanIndikator());

		IndikatorKinerja indikatorKinerja = indikatorKinerjaConverter.transferVOToModel(vo.getIndikatorKinerja(),
				new IndikatorKinerja());
		indikatorKinerja.setSatuanIndikator(satuanIndikator);
		indikatorKinerja.setStatusVerifikasi(false);
		indikatorKinerja.setStatusEnabled(true);
		indikatorKinerja.setKdProfile((short) 0);

		Pegawai pegawai = pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai());
		Jabatan jabatan = jabatanConverter.transferVOToModel(vo.getJabatan(), new Jabatan());

		LogbookKinerja logbookKinerja = logbookKinerjaConverter.transferVOToModel(vo, new LogbookKinerja());
		logbookKinerja.setPegawai(pegawai);
		logbookKinerja.setJabatan(jabatan);
		logbookKinerja.setCapaian(0.0);
		logbookKinerja.setStatusVerifikasi(false);
		logbookKinerja.setStatusEnabled(true);
		logbookKinerja.setKdProfile((short) 0);
		logbookKinerja.setIndikatorKinerja(indikatorKinerja);

		indikatorKinerjaDao.save(indikatorKinerja);
		LogbookKinerja resultModel = logbookKinerjaDao.save(logbookKinerja);

		LogbookKinerjaVO resultVO = new LogbookKinerjaVO();
		resultVO = logbookKinerjaConverter.transferModelToVO(resultModel, resultVO);

		return resultVO;
	}

	@Override
	public LogbookKinerjaVO updatePengajuanKontrakKinerja(LogbookKinerjaVO vo)
			throws JpaSystemException, ServiceVOException {
		IndikatorKinerja indikatorKinerjaLama = indikatorKinerjaDao.findOne(vo.getIndikatorKinerja().getId());
		LogbookKinerja logbookKinerjaLama = logbookKinerjaDao.findOne(vo.getNoRec());

		SatuanIndikator satuanIndikator = satuanIndikatorConverter
				.transferVOToModel(vo.getIndikatorKinerja().getSatuanIndikator(), new SatuanIndikator());
		Pegawai pegawai = pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai());
		Jabatan jabatan = jabatanConverter.transferVOToModel(vo.getJabatan(), new Jabatan());

		IndikatorKinerja indikatorKinerjaBaru = indikatorKinerjaConverter.transferVOToModel(vo.getIndikatorKinerja(),
				indikatorKinerjaLama);
		LogbookKinerja logbookKinerjaBaru = logbookKinerjaConverter.transferVOToModel(vo, logbookKinerjaLama);

		indikatorKinerjaBaru.setSatuanIndikator(satuanIndikator);
		if (vo.getIndikatorKinerja().getStatusVerifikasi()) {
			indikatorKinerjaBaru.setStatusEnabled(true);
		} else {
			indikatorKinerjaBaru.setStatusEnabled(false);
		}
		indikatorKinerjaBaru.setKdProfile((short) 0);
		logbookKinerjaBaru.setPegawai(pegawai);
		logbookKinerjaBaru.setJabatan(jabatan);
		if (vo.getStatusVerifikasi()) {
			logbookKinerjaBaru.setStatusEnabled(true);
		} else {
			logbookKinerjaBaru.setStatusEnabled(false);
		}
		logbookKinerjaBaru.setKdProfile((short) 0);
		logbookKinerjaBaru.setIndikatorKinerja(indikatorKinerjaBaru);

		indikatorKinerjaDao.save(indikatorKinerjaBaru);
		LogbookKinerja resultModel = logbookKinerjaDao.save(logbookKinerjaBaru);

		LogbookKinerjaVO resultVO = new LogbookKinerjaVO();
		resultVO = logbookKinerjaConverter.transferModelToVO(resultModel, resultVO);

		return resultVO;
	}

	@Override
	public List<Map<String, Object>> findPengajuanKontrakKinerja(Integer idPegawai, Integer idJabatan)
			throws JpaSystemException {
		List<Map<String, Object>> result = logbookKinerjaDao.findPengajuanIndikatorByPegawaiJabatan(idPegawai,
				idJabatan);

		return result;
	}

	@Override
	public List<Map<String, Object>> findDupKontrakKinerja(Integer idPegawai, Integer idJabatan, Long bulan,
			Integer idIndikator) throws JpaSystemException {
		DateFormat df = new SimpleDateFormat("yyyy-MM");

		List<Map<String, Object>> result = logbookKinerjaDao.findDupKontrakKinerja(idPegawai, idJabatan,
				df.format(new Date(bulan)), idIndikator);

		return result;
	}

	private Integer hitungTargetHariKerja(Date bulan) {
		Date start = DateUtil.startMonth(bulan);
		Date end = DateUtil.endMonth(bulan);
		List<Kalender> targetPresensi = kalenderDao.getTargetKerja(start, end);
		Integer result = targetPresensi.size();

		return result;
	}

	private Double hitungTargetMenitKerja(Date bulan) {
		Double result = 0.0;
		Chronology hijri = IslamicChronology.getInstance();
		Date start = DateUtil.startMonth(bulan);
		Date end = DateUtil.endMonth(bulan);

		List<Kalender> targetPresensi = kalenderDao.getTargetKerja(start, end);
		Integer jumlahHariKerjaHarian = 0;
		Integer jumlahHariKerjaRamadhan = 0;
		for (Kalender kalender : targetPresensi) {
			LocalDate hijriDate = new LocalDate(kalender.getTanggal().getTime(), hijri);
			if (hijriDate.getMonthOfYear() == 9) {
				jumlahHariKerjaRamadhan += 1;
			} else {
				jumlahHariKerjaHarian += 1;
			}
		}

		result += jumlahHariKerjaHarian.doubleValue() * Master.MENIT_KERJA_HARIAN;
		result += jumlahHariKerjaRamadhan.doubleValue() * Master.MENIT_KERJA_RAMADHAN;

		return result;
	}

	@Override
	public Map<String, Object> findKontrakKinerja(Integer idPegawai, Integer idJabatan, Long bulan)
			throws JpaSystemException {
		Map<String, Object> result = new HashMap<>();
		List<Map<String, Object>> listRes = new ArrayList<>();
		List<Integer> listIdIndikator = new ArrayList<>();

		Date startMonth = DateUtil.startMonth(bulan);
		Date endMonth = DateUtil.endMonth(bulan);
		Date startYear = DateUtil.startYear(bulan);
		Date endYear = DateUtil.endMonth(bulan);

		DateFormat mf = new SimpleDateFormat("yyyy-MM");

		Integer targetHariKerja = hitungTargetHariKerja(new Date(bulan));
		Double targetJamKerja = hitungTargetMenitKerja(new Date(bulan));

		List<Map<String, Object>> listMap = logbookKinerjaDao.findIndikatorByJabatan(idJabatan,
				mf.format(new Date(bulan)));
		List<Map<String, Object>> data = logbookKinerjaDao.findKontrakKinerja(idPegawai, idJabatan,
				mf.format(new Date(bulan)));

		/**
		 * Mengecek status indikator yang memiliki komponen detail
		 */
		boolean isKualitasDokterExisted = false;
		for (Map<String, Object> map : data) {
			if (Master.IndikatorKinerja.KEPATUHAN_PELAYANAN_MEDIS.equals(map.get("indikatorId"))
					&& Boolean.parseBoolean(map.get("isStatusVerifikasi").toString())) {
				isKualitasDokterExisted = true;

				break;
			}
		}

		for (Map<String, Object> map : listMap) {
			if (!listIdIndikator.contains(map.get("indikatorId"))) {
				listIdIndikator.add(Integer.valueOf(map.get("indikatorId").toString()));

				/**
				 * Komponen target kuantitas indikator pelayanan medis
				 */
				if (map.get("indikatorId").equals(Master.IndikatorKinerja.PELAYANAN_MEDIS_JAM_KERJA)) {
					List<Double> target = targetSkorDokterDetailDao.findTargetByPegawai(idPegawai, endMonth, startYear,
							endYear);
					if (CommonUtil.isNotNullOrEmpty(target)) {
						map.put("target", Math.floor(target.get(0)));
					} else {
						map.put("target", 0);
					}

				}
				/**
				 * Komponen target kualitas indikator pelayanan medis
				 */
				if (map.get("indikatorId").equals(Master.IndikatorKinerja.KEPATUHAN_PELAYANAN_MEDIS)
						&& isKualitasDokterExisted) {
					List<Map<String, Object>> detailIndikator2 = logbookKinerjaDokterDao.findDetailLogbookDokter(
							startMonth, endMonth, idPegawai, idJabatan,
							Integer.valueOf(map.get("indikatorId").toString()));
					if (CommonUtil.isNotNullOrEmpty(detailIndikator2)) {
						map.put("detail", detailIndikator2);
					} else {
						List<IndikatorKinerjaDetail> ikds = indikatorKinerjaDetailDao
								.findByIndikator(Integer.valueOf(map.get("indikatorId").toString()));
						List<LogbookKinerjaDokter> lkds = new ArrayList<>();
						for (IndikatorKinerjaDetail ikd : ikds) {
							Jabatan jb = jabatanDao.findOne(idJabatan);
							Pegawai pg = pegawaiDao.findOne(idPegawai);

							LogbookKinerjaDokter logbookKinerjaLama = logbookKinerjaDokterDao
									.findOne(mf.format(new Date(bulan)), idPegawai, idJabatan, ikd.getId());
							if (CommonUtil.isNullOrEmpty(logbookKinerjaLama)) {
								LogbookKinerjaDokter logbookKinerjaBaru = new LogbookKinerjaDokter();
								logbookKinerjaBaru.setBulan(new Date(bulan));
								logbookKinerjaBaru.setDetailTarget(70.0);
								logbookKinerjaBaru.setKdProfile((short) 0);
								logbookKinerjaBaru.setStatusEnabled(true);
								logbookKinerjaBaru.setTglHitung(new Date());
								logbookKinerjaBaru.setIndikatorDetail(ikd);
								logbookKinerjaBaru.setJabatan(jb);
								logbookKinerjaBaru.setPegawai(pg);
								lkds.add(logbookKinerjaBaru);
							}
						}

						if (CommonUtil.isNotNullOrEmpty(lkds)) {
							Iterable<LogbookKinerjaDokter> models = logbookKinerjaDokterDao.save(lkds);
							if (CommonUtil.isNotNullOrEmpty(models)) {
								List<Map<String, Object>> detailIndikator3 = logbookKinerjaDokterDao
										.findDetailLogbookDokter(startMonth, endMonth, idPegawai, idJabatan,
												Integer.valueOf(map.get("indikatorId").toString()));
								if (CommonUtil.isNotNullOrEmpty(detailIndikator3)) {
									map.put("detail", detailIndikator3);
								}
							}
						}
					}
				}

				listRes.add(map);
			}
		}
		for (Map<String, Object> map : data) {
			if (!listIdIndikator.contains(map.get("indikatorId"))) {
				listIdIndikator.add(Integer.valueOf(map.get("indikatorId").toString()));
				listRes.add(map);
			}
		}

		for (Map<String, Object> res : listRes) {
			res.put("noRecMap", res.get("noRecMap"));
			res.put("isNotEditable", false);
			for (Map<String, Object> map : data) {
				if (res.get("indikatorId").equals(map.get("indikatorId"))) {
					res.put("noRec", map.get("noRec"));
					res.put("target", map.get("target"));
					res.put("bobot", map.get("bobot"));
					res.put("isStatusVerifikasi", map.get("isStatusVerifikasi"));
					res.put("statusVerifikasi", map.get("statusVerifikasi"));
					if (res.get("indikatorId").equals(Master.IndikatorKinerja.PEMENUHAN_JAM_KERJA)) {
						res.put("isNotEditable", true);
					}
				}
			}
			if (CommonUtil.isNullOrEmpty(res.get("noRec"))) {
				res.put("noRec", null);
				if (res.get("indikatorId").equals(Master.IndikatorKinerja.PEMENUHAN_JAM_KERJA)) {
					res.put("target", targetJamKerja);
					res.put("isNotEditable", true);
				} else if (res.get("indikatorId").equals(Master.IndikatorKinerja.PEMENUHAN_HARI_KERJA)) {
					res.put("target", targetHariKerja.doubleValue());
				} else if (res.get("indikatorId").equals(Master.IndikatorKinerja.KETEPATAN_KEHADIRAN)) {
					res.put("target", 100.0);
				} else if (res.get("indikatorId").equals(Master.IndikatorKinerja.KEPATUHAN_PELAYANAN_MEDIS)) {
					res.put("target", 100.0);
				} else if (CommonUtil.isNotNullOrEmpty(res.get("target"))) {
					res.put("target", res.get("target"));
				} else {
					res.put("target", null);
				}
				res.put("bobot", null);
				res.put("isStatusVerifikasi", null);
				res.put("statusVerifikasi", null);
			}
		}

		for (Integer idJenisIndikator : Arrays.asList(Master.Remunerasi.JENIS_INDIKATOR)) {
			List<Map<String, Object>> resByJenisIndikator = new ArrayList<>();
			for (Map<String, Object> res : listRes) {
				if (res.get("jenisIndikatorId").equals(idJenisIndikator)) {
					resByJenisIndikator.add(res);
				}
			}

			resByJenisIndikator = resByJenisIndikator.stream()
					.sorted(Comparator.comparing(o1 -> o1.get("namaIndikator").toString()))
					.collect(Collectors.toList());

			if (idJenisIndikator.equals(1)) {
				result.put("kuantitas", resByJenisIndikator);
			} else if (idJenisIndikator.equals(2)) {
				result.put("kualitas", resByJenisIndikator);
			} else if (idJenisIndikator.equals(3)) {
				result.put("perilaku", resByJenisIndikator);
			}
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findKontrakKinerja(Integer idIndikator) throws JpaSystemException {
		List<Map<String, Object>> result = logbookKinerjaDao.findKontrakKinerja(idIndikator);

		return result;
	}

	public Map<String, Object> findAnggaranRemunerasi(Integer idPegawai, Integer idJabatan, String tahun)
			throws JpaSystemException {
		Map<String, Object> result = new HashMap<>();

		List<Map<String, Object>> data = anggaranRemunerasiDao.findAnggaran(idPegawai, idJabatan, tahun);
		if (CommonUtil.isNotNullOrEmpty(data) && data.size() > 0) {
			result = data.get(0);
		}

		return result;
	}

	@Override
	public Map<String, Object> findLogbookKinerja(Integer idPegawai, Integer idJabatan, Long bulan)
			throws JpaSystemException {
		Map<String, Object> result = new HashMap<>();
		List<Map<String, Object>> resData = new ArrayList<>();
		List<Map<String, Object>> listJenisIndikator = new ArrayList<>();

		Date start = DateUtil.startMonth(bulan);
		Date end = DateUtil.endMonth(bulan);

		DateFormat mf = new SimpleDateFormat("yyyy-MM");
		DateFormat yf = new SimpleDateFormat("yyyy");
		Integer idKelompokJabatan = null;
		double totAllPersen = 0.0;
		double nilaiJabatan = 0.0;
		double pir = 0.0;
		double plafonGaji = 0.0;
		double plafonInsentif = 0.0;

		DecimalFormatSymbols formatRp = new DecimalFormatSymbols();
		formatRp.setCurrencySymbol("Rp");
		formatRp.setMonetaryDecimalSeparator(',');
		formatRp.setGroupingSeparator('.');

		DecimalFormat kursINA = (DecimalFormat) DecimalFormat.getCurrencyInstance();
		kursINA.setDecimalFormatSymbols(formatRp);

		DecimalFormat df = new DecimalFormat("0.00");
		df.setRoundingMode(RoundingMode.HALF_UP);

		List<Integer> listIdJabatan = new ArrayList<>();
		if (CommonUtil.isNotNullOrEmpty(idJabatan)) {
			listIdJabatan.add(idJabatan);
		} else {
			List<Map<String, Object>> listJab = findJabatanKontrakVerifKinerja(idPegawai, idPegawai);
			for (Map<String, Object> jab : listJab) {
				listIdJabatan.add(Integer.valueOf(jab.get("id").toString()));
			}
		}

		for (Integer idJab : listIdJabatan) {
			Map<String, Object> rsMap = new HashMap<>();

			List<Double> persenIndikator = findBobotJenisJabatan(bulan, idJab);

			List<Map<String, Object>> rs = logbookKinerjaDao.findLogbookKinerja(idPegawai, idJab,
					mf.format(new Date(bulan)));
			Map<String, Object> anggaran = findAnggaranRemunerasi(idPegawai, idJab, yf.format(new Date(bulan)));

			if (CommonUtil.isNotNullOrEmpty(rs) && rs.size() > 0) {
				nilaiJabatan = Double.valueOf(rs.get(0).get("nilaiJabatan").toString());
				idKelompokJabatan = Integer.parseInt(rs.get(0).get("kelompokJabatanId").toString());
			}
			if (CommonUtil.isNotNullOrEmpty(anggaran)) {
				pir = Double.valueOf(anggaran.get("pir").toString());
				plafonGaji = Double.valueOf(anggaran.get("plafonGaji").toString());
				plafonInsentif = Double.valueOf(anggaran.get("plafonInsentif").toString());
			}

			for (String ji : Arrays.asList(Master.JENIS_INDIKATOR)) {
				double hasil = 0.0;
				List<Map<String, Object>> data = new ArrayList<>();
				Map<String, Object> jenisIndikator = new HashMap<>();
				jenisIndikator.put("jenisIndikator", ji);
				for (Map<String, Object> map : rs) {
					if (map.get("jenisIndikator").equals(ji)) {
						if (Master.IndikatorKinerja.PELAYANAN_MEDIS_JAM_KERJA.equals(map.get("idIndikator"))
								&& Double.valueOf(map.get("fragCapaian").toString()).equals(0.0)) {
							List<Map<String, Object>> logbookDokter = findLogbookJamKerjaDokter(idPegawai, bulan);
							double capaian = 0.0;
							for (Map<String, Object> ld : logbookDokter) {
								capaian += Double.valueOf(ld.get("tSkor").toString());
							}
							String fragCapaian = df.format(capaian / Double.valueOf(map.get("target").toString()));
							hasil += capaian / Double.valueOf(map.get("target").toString())
									* Double.valueOf(map.get("bobot").toString());
							map.put("fragCapaian", Double.parseDouble(fragCapaian));
							map.put("persenCapaianDibulatkan",
									new BigDecimal(Double.valueOf(map.get("fragCapaian").toString()) * 100).setScale(2,
											RoundingMode.HALF_UP));
							data.add(map);
						} else if (Master.IndikatorKinerja.KEPATUHAN_PELAYANAN_MEDIS.equals(map.get("idIndikator"))) {
							List<Map<String, Object>> listDetail = logbookKinerjaDokterDao.findDetailLogbookDokter(
									start, end, idPegawai, idJabatan,
									Master.IndikatorKinerja.KEPATUHAN_PELAYANAN_MEDIS);

							int detailSize = listDetail.size();
							double persenCapaian = 0.0;
							for (Map<String, Object> detail : listDetail) {
								if (Master.IndikatorKinerjaDetail.KEPATUHAN_WAKTU_VISITE.equals(detail.get("id"))) {
									Map<String, Object> presensiVisite = cpptService.findPresensiVisiteDokter(idPegawai,
											bulan);
									if (CommonUtil.isNotNullOrEmpty(presensiVisite)) {
										if (Double.valueOf(presensiVisite.get("rataCapaian").toString()) >= Double
												.valueOf(detail.get("detailTarget").toString())) {
											persenCapaian += Double.valueOf(detail.get("detailTarget").toString())
													/ Double.valueOf(detail.get("detailTarget").toString());
										} else {
											persenCapaian += Double
													.valueOf(presensiVisite.get("rataCapaian").toString())
													/ Double.valueOf(detail.get("detailTarget").toString());
										}
									}
								}
							}

							double capaian = 0.0;
							if (detailSize > 0) {
								capaian = persenCapaian / detailSize;
							}

							String fragCapaian = df.format(capaian * Double.valueOf(map.get("target").toString()));
							hasil += capaian * Double.valueOf(map.get("target").toString()) / 100
									* Double.valueOf(map.get("bobot").toString());
							map.put("fragCapaian", Double.parseDouble(fragCapaian));
							map.put("persenCapaianDibulatkan",
									new BigDecimal(Double.valueOf(map.get("fragCapaian").toString())).setScale(2,
											RoundingMode.HALF_UP));
							data.add(map);
						} else if (Master.IndikatorKinerja.PELAYANAN_NAKES.equals(map.get("idIndikator"))) {
							List<PelayananPasienNakes> listPelayananPasien = pelayananPasienNakesDao
									.findAllPelayananByKontrak(mf.format(new Date(bulan)), idPegawai);
							List<PelayananNakes> listPelayananNonpasien = pelayananNakesDao
									.findAllByKontrak(mf.format(new Date(bulan)), idPegawai);

							double capaian = 0.0;
							for (PelayananPasienNakes pelayananPasien : listPelayananPasien) {
								capaian += pelayananPasien.getJumlah() * pelayananPasien.getSkor();
							}
							for (PelayananNakes pelayananNonpasien : listPelayananNonpasien) {
								capaian += pelayananNonpasien.getJumlah() * pelayananNonpasien.getSkor();
							}

							String fragCapaian = df.format(capaian / Double.valueOf(map.get("target").toString()));
							hasil += capaian / Double.valueOf(map.get("target").toString())
									* Double.valueOf(map.get("bobot").toString());
							map.put("fragCapaian", Double.parseDouble(fragCapaian));
							map.put("persenCapaianDibulatkan",
									new BigDecimal(Double.valueOf(map.get("fragCapaian").toString()) * 100).setScale(2,
											RoundingMode.HALF_UP));
							data.add(map);
						} else if (Master.IndikatorKinerja.PELAYANAN_PERAWAT.equals(map.get("idIndikator"))) {
							List<PelayananPasienPerawat> listPelayananPasien = pelayananPasienPerawatDao
									.findAllPelayananByKontrak(mf.format(new Date(bulan)), idPegawai);

							double capaian = 0.0;
							for (PelayananPasienPerawat pelayananPasien : listPelayananPasien) {
								capaian += pelayananPasien.getJumlah() * pelayananPasien.getSkor();
							}

							String fragCapaian = df.format(capaian / Double.valueOf(map.get("target").toString()));
							hasil += capaian / Double.valueOf(map.get("target").toString())
									* Double.valueOf(map.get("bobot").toString());
							map.put("fragCapaian", Double.parseDouble(fragCapaian));
							map.put("persenCapaianDibulatkan",
									new BigDecimal(Double.valueOf(map.get("fragCapaian").toString()) * 100).setScale(2,
											RoundingMode.HALF_UP));
							data.add(map);
						} else {
							hasil += Double.parseDouble(df.format(Double.valueOf(map.get("fragCapaian").toString())))
									* Double.valueOf(map.get("bobot").toString());
							map.put("persenCapaianDibulatkan",
									new BigDecimal(Double.valueOf(map.get("fragCapaian").toString()) * 100).setScale(2,
											RoundingMode.HALF_UP));
							data.add(map);
						}
					}
				}

				if (ji.equals("Kuantitas")) {
					totAllPersen += hasil;
					jenisIndikator.put("persenCapaian", (100.0 / persenIndikator.get(0)) * hasil);
					jenisIndikator.put("persenCapaianDibulatkan",
							new BigDecimal(Double.valueOf((100.0 / persenIndikator.get(0)) * hasil)).setScale(2,
									RoundingMode.HALF_UP));
				} else if (ji.equals("Kualitas")) {
					totAllPersen += hasil;
					jenisIndikator.put("persenCapaian", (100.0 / persenIndikator.get(1)) * hasil);
					jenisIndikator.put("persenCapaianDibulatkan",
							new BigDecimal(Double.valueOf((100.0 / persenIndikator.get(1)) * hasil)).setScale(2,
									RoundingMode.HALF_UP));
				} else if (ji.equals("Perilaku")) {
					totAllPersen += hasil;
					jenisIndikator.put("persenCapaian", (100.0 / persenIndikator.get(2)) * hasil);
					jenisIndikator.put("persenCapaianDibulatkan",
							new BigDecimal(Double.valueOf((100.0 / persenIndikator.get(2)) * hasil)).setScale(2,
									RoundingMode.HALF_UP));
				}
				jenisIndikator.put("data", data);

				listJenisIndikator.add(jenisIndikator);
			}

			Double iki = 0.0;
			if (Arrays.asList(Master.KelompokJabatan.DIR_MS).contains(idKelompokJabatan)) {
				List<Map<String, Object>> acuanIndeks = tabelAcuanIndeksIKIDao
						.findAllAcuanIndeks(Master.TabelAcuanIndeksIKI.MAX_DIR_MS);
				for (Map<String, Object> aiki : acuanIndeks) {
					if ((Double.valueOf(aiki.get("nilaiBawah").toString()) < Double.parseDouble(df.format(totAllPersen))
							&& Double.parseDouble(df.format(totAllPersen)) <= Double
									.valueOf(aiki.get("nilaiAtas").toString()))
							|| (Double.parseDouble(df.format(totAllPersen)) > 1000
									&& Double.valueOf(aiki.get("nilaiAtas").toString()) == 1000)) {
						iki = Double.valueOf(aiki.get("iki").toString());

						break;
					}
				}
			} else {
				List<Map<String, Object>> acuanIndeks = tabelAcuanIndeksIKIDao
						.findAllAcuanIndeks(Master.TabelAcuanIndeksIKI.MAX_OTHERS);
				for (Map<String, Object> aiki : acuanIndeks) {
					if ((Double.valueOf(aiki.get("nilaiBawah").toString()) < Double.parseDouble(df.format(totAllPersen))
							&& Double.parseDouble(df.format(totAllPersen)) <= Double
									.valueOf(aiki.get("nilaiAtas").toString()))
							|| (Double.parseDouble(df.format(totAllPersen)) > 160
									&& Double.valueOf(aiki.get("nilaiAtas").toString()) == 160)) {
						iki = Double.valueOf(aiki.get("iki").toString());

						break;
					}
				}
			}

			double targetRupiahP1 = nilaiJabatan * Master.Remunerasi.IK_STANDAR * pir * Master.Remunerasi.PERSEN_P1;
			double targetRupiahP2 = nilaiJabatan * Master.Remunerasi.IKU * Master.Remunerasi.IKI_STANDAR * pir
					* Master.Remunerasi.PERSEN_P2;

			double capaianRupiahP1 = nilaiJabatan * Master.Remunerasi.IK_STANDAR * pir * Master.Remunerasi.PERSEN_P1;
			double capaianRupiahP2 = nilaiJabatan * Master.Remunerasi.IKU * iki * pir * Master.Remunerasi.PERSEN_P2;

			if (CommonUtil.isNotNullOrEmpty(idJabatan)) {
				rsMap.put("listJenisIndikator", listJenisIndikator);

				rsMap.put("plafonP1", kursINA.format(plafonGaji).toString());
				rsMap.put("rupiahTargetP1", targetRupiahP1);
				rsMap.put("rupiahTargetFormatP1", kursINA.format(targetRupiahP1).toString());
				rsMap.put("rupiahCapaianP1", capaianRupiahP1);
				rsMap.put("rupiahCapaianP1Format", kursINA.format(capaianRupiahP1).toString());

				rsMap.put("plafonP2", kursINA.format(plafonInsentif).toString());
				rsMap.put("rupiahTargetP2", targetRupiahP2);
				rsMap.put("rupiahTargetFormatP2", kursINA.format(targetRupiahP2).toString());
				rsMap.put("rupiahCapaianP2", capaianRupiahP2);
				rsMap.put("rupiahCapaianP2Format", kursINA.format(capaianRupiahP2).toString());
			}

			rsMap.put("persenCapaian", totAllPersen);
			rsMap.put("persenCapaianDibulatkan",
					new BigDecimal(Double.valueOf(totAllPersen)).setScale(2, RoundingMode.HALF_UP));

			resData.add(rsMap);
		}

		result.put("data", resData);

		return result;
	}

	@Override
	public List<Map<String, Object>> findAksesPegawai(Integer idPegawai, List<Integer> listIdKelompokJabatan) {
		List<Map<String, Object>> result = new ArrayList<>();
		List<Map<String, Object>> rsAll = new ArrayList<>();
		List<Map<String, Object>> aksesByStaf = new ArrayList<>();
		List<Map<String, Object>> aksesByAtasan = new ArrayList<>();
		List<Map<String, Object>> aksesByPenilai = new ArrayList<>();

		List<Integer> listPurnaWaktu = Arrays.asList(Master.KategoryPegawai.PURNA_WAKTU);

		List<Integer> listIdSDM = pegawaiDao.getPegawaiSDMforCred(Master.UnitKerja.BAG_SDM,
				Master.SubUnitKerja.SUBBAG_KESEJAHTERAAN);
		if (listIdSDM.contains(idPegawai)) {
			rsAll = pegawaiDao.findPegawaiByListKategori(listPurnaWaktu);
			result.addAll(rsAll);
			for (Map<String, Object> map : result) {
				map.put("isGranted", false);
			}
		}

		if (CommonUtil.isNotNullOrEmpty(listIdKelompokJabatan)) {
			aksesByStaf = logbookKinerjaDao.findAksesPegawaiByStaf(idPegawai, listPurnaWaktu, listIdKelompokJabatan);
			aksesByAtasan = logbookKinerjaDao.findAksesPegawaiByAtasan(idPegawai, listPurnaWaktu,
					listIdKelompokJabatan);
			aksesByPenilai = logbookKinerjaDao.findAksesPegawaiByPenilai(idPegawai, listPurnaWaktu,
					listIdKelompokJabatan);
		} else {
			aksesByStaf = logbookKinerjaDao.findAksesPegawaiByStaf(idPegawai, listPurnaWaktu);
			aksesByAtasan = logbookKinerjaDao.findAksesPegawaiByAtasan(idPegawai, listPurnaWaktu);
			aksesByPenilai = logbookKinerjaDao.findAksesPegawaiByPenilai(idPegawai, listPurnaWaktu);
		}

		List<Integer> listIdPegawai = new ArrayList<>();
		if (CommonUtil.isNotNullOrEmpty(aksesByStaf) && CommonUtil.isNullOrEmpty(rsAll)) {
			for (Map<String, Object> map : aksesByStaf) {
				map.put("isGranted", false);
				if (!listIdPegawai.contains(map.get("id"))) {
					listIdPegawai.add(Integer.parseInt(map.get("id").toString()));
					result.add(map);
				}
			}
		}
		if (CommonUtil.isNotNullOrEmpty(aksesByAtasan)) {
			if (CommonUtil.isNullOrEmpty(rsAll)) {
				for (Map<String, Object> map : aksesByAtasan) {
					map.put("isGranted", true);
					if (!listIdPegawai.contains(map.get("id"))) {
						listIdPegawai.add(Integer.parseInt(map.get("id").toString()));
						result.add(map);
					}
				}
			} else {
				for (Map<String, Object> res : result) {
					for (Map<String, Object> map : aksesByAtasan) {
						if (res.get("id").equals(map.get("id"))) {
							res.put("isGranted", true);
							break;
						}
					}
				}
			}
		}
		if (CommonUtil.isNotNullOrEmpty(aksesByPenilai) && CommonUtil.isNullOrEmpty(rsAll)) {
			for (Map<String, Object> map : aksesByPenilai) {
				map.put("isGranted", false);
				if (!listIdPegawai.contains(map.get("id"))) {
					listIdPegawai.add(Integer.parseInt(map.get("id").toString()));
					result.add(map);
				}
			}
		}

		if (CommonUtil.isNotNullOrEmpty(result)) {
			result.sort(Comparator.comparing(m -> (String) m.get("namaLengkap"), String.CASE_INSENSITIVE_ORDER));
		}

		return result;
	}

	public List<Map<String, Object>> findUsedWorkingRecordByKontrak(String logbookNoRec) throws JpaSystemException {
		List<Map<String, Object>> result = logbookKinerjaDetailDao.findUsedWorkingRecordByKontrak(logbookNoRec);

		return result;
	}

	@Override
	public List<Map<String, Object>> findLogbookJamKerjaDokter(Integer idPegawai, Long bulan) {
		List<Map<String, Object>> result = new ArrayList<>();
		List<String> listTglPelayanan = new ArrayList<>();
		List<Integer> listIdIndikator = new ArrayList<>();
		List<Integer> listIdProduk = new ArrayList<>();
		List<Double> listSkor = new ArrayList<>();
		List<Integer> listDetailJenisProduk = new ArrayList<>();
		List<Integer> listDetailJenisProdukException = new ArrayList<>();

		DateFormat mf = new SimpleDateFormat("yyyy-MM");
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

		DecimalFormat decf = new DecimalFormat("###.###");
		decf.setRoundingMode(RoundingMode.HALF_UP);

		LocalDateTime PSBBDate = LocalDateTime.of(2020, 9, 14, 0, 0, 0);
		LocalDateTime PSBBEnd = LocalDateTime.parse(GetSettingDataFixed("psbbperiod"), dtf);

		Date pssbAwal = Date.from(PSBBDate.atZone(ZoneId.systemDefault()).toInstant());
		Date pssbAkhir = Date.from(PSBBEnd.atZone(ZoneId.systemDefault()).toInstant());

		List<Integer> listRuangEks = splitDataSettingDatafixed("IdRuanganEksekutif");
		List<Integer> listKonsulTapiVisit = splitDataSettingDatafixed("konsulTapiVisit");

		List<Integer> drKsmUmumList = pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_UMUM);

		List<Integer> listIdNonjadwal = shiftKerjaDao.findListNonjadwal();
		List<Integer> laboranRadiologList = mapPegawaiLaboratRadiologiDao.findPegawaiLaboranRadiolog();
		if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_PATOLOGI_ANATOMI).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_pa");
		} else if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_PATOLOGI_KLINIK).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_pk");
		} else if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_RADIOLOGI).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_radiologi");
		} else {
			listDetailJenisProduk = splitDataSettingDatafixed("medis_utama");
		}

		if (laboranRadiologList.contains(idPegawai)) {
			listDetailJenisProdukException = splitDataSettingDatafixed("admin_nonpk");
			listDetailJenisProdukException.removeAll(listDetailJenisProduk);

			listDetailJenisProduk.addAll(listDetailJenisProdukException);
		}

		List<Map<String, Object>> dataLayanan = ikiDanRemunerasiDao.getDataLogbookJamKerjaDokter(
				mf.format(new Date(bulan)), pssbAwal, pssbAkhir, listIdNonjadwal, Master.JenisPegawai.DOKTER,
				Arrays.asList(idPegawai), Arrays.asList(Master.Departemen.GRUP_RAWAT_JALAN), listDetailJenisProduk,
				splitDataSettingDatafixed("pr_dokter_umum_igd"), drKsmUmumList, Master.Departemen.IGD,
				Arrays.asList(Master.JenisProduk.NONTINDAKAN), Arrays.asList(Master.KelompokPasien.KELOMPOK_BPJS),
				Master.Produk.KARCIS);

		/**
		 * Menghitung skor asa dokter anestesi
		 */
		List<String> listIdPelayananAnestesi = new ArrayList<>();
		{
			List<Map<String, Object>> dataLayananAnestesi = new ArrayList<>();
			for (Map<String, Object> map : dataLayanan) {
				if (map.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.DOKTER_ANASTESI)) {
					listIdPelayananAnestesi.add(map.get("noRec").toString());
					dataLayananAnestesi.add(map);
				}
			}

			List<Map<String, Object>> listCountReferensiSkor = new ArrayList<>();
			if (CommonUtil.isNotNullOrEmpty(listIdPelayananAnestesi)) {
				listCountReferensiSkor = pelayananPasienPetugasDao
						.countReferensiSkorPelayananAnestesi(listIdPelayananAnestesi);
			}

			List<String> listIdRefSkor = new ArrayList<>();
			for (Map<String, Object> map : listCountReferensiSkor) {
				listIdRefSkor.add(map.get("pelayananId").toString());
			}

			List<Map<String, Object>> listDataReferensiSkor = new ArrayList<>();
			if (CommonUtil.isNotNullOrEmpty(listIdRefSkor)) {
				listDataReferensiSkor = pelayananPasienPetugasDao.findReferensiSkorPelayananAnestesi(listIdRefSkor,
						Arrays.asList(Master.UnitKerja.KSM));
			}

			List<ReferensiSkorAnestesiVO> listRefSkor = new ArrayList<>();
			for (String idRefSkor : listIdRefSkor) {
				ReferensiSkorAnestesiVO ref = new ReferensiSkorAnestesiVO();
				for (Map<String, Object> map : listDataReferensiSkor) {
					if (idRefSkor.equals(map.get("pelayananId"))) {
						ref.setPelayananId(map.get("pelayananId").toString());
						ref.setProdukId(Integer.valueOf(map.get("produkId").toString()));
						if (map.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.DOKTER_PEMERIKSA)) {
							ref.setDokterPemeriksaId(Integer.valueOf(map.get("petugasId").toString()));
							ref.setKelompokKerjaId(Integer.valueOf(map.get("kkId").toString()));
						} else if (map.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.DOKTER_ANASTESI)
								&& idPegawai.equals(map.get("petugasId"))) {
							ref.setDokterAnestesiId(Integer.valueOf(map.get("petugasId").toString()));
							ref.setAsaId(Byte.valueOf(map.get("asaId").toString()));
						}
					}
				}
				listRefSkor.add(ref);
			}

			List<Map<String, Object>> dataSkorAnestesi = new ArrayList<>();
			if (CommonUtil.isNotNullOrEmpty(listRefSkor)) {
				dataSkorAnestesi = skoringTindakanMedisDaoCustom.findSkoringLogbookDokter(mf.format(new Date(bulan)),
						listRefSkor);
			}

			/**
			 * Skor dokter anestesi (bukan tindakan mandiri)
			 */
			for (ReferensiSkorAnestesiVO refSkor : listRefSkor) {
				for (Map<String, Object> mapLayanan : dataLayananAnestesi) {
					for (Map<String, Object> mapSkor : dataSkorAnestesi) {
						if (CommonUtil.isNotNullOrEmpty(refSkor.getPelayananId())
								&& CommonUtil.isNotNullOrEmpty(mapLayanan.get("noRec"))
								&& CommonUtil.isNotNullOrEmpty(refSkor.getAsaId())
								&& CommonUtil.isNotNullOrEmpty(mapLayanan.get("asaId"))
								&& CommonUtil.isNotNullOrEmpty(refSkor.getProdukId())
								&& CommonUtil.isNotNullOrEmpty(mapLayanan.get("produkId"))
								&& CommonUtil.isNotNullOrEmpty(mapSkor.get("produkId"))
								&& CommonUtil.isNotNullOrEmpty(refSkor.getDokterAnestesiId())
								&& CommonUtil.isNotNullOrEmpty(mapLayanan.get("pegawaiId"))
								&& CommonUtil.isNotNullOrEmpty(refSkor.getDokterPemeriksaId())
								&& CommonUtil.isNotNullOrEmpty(mapSkor.get("pegawaiId"))
								&& CommonUtil.isNotNullOrEmpty(refSkor.getKelompokKerjaId())
								&& CommonUtil.isNotNullOrEmpty(mapSkor.get("kelompokKerjaId"))
								&& CommonUtil.isNotNullOrEmpty(mapLayanan.get("tglPelayanan"))
								&& CommonUtil.isNotNullOrEmpty(mapSkor.get("tglMulaiBerlaku"))
								&& refSkor.getPelayananId().equals(mapLayanan.get("noRec").toString())
								&& refSkor.getAsaId().equals(Byte.valueOf(mapLayanan.get("asaId").toString()))
								&& refSkor.getProdukId().equals(Integer.valueOf(mapLayanan.get("produkId").toString()))
								&& refSkor.getProdukId().equals(Integer.valueOf(mapSkor.get("produkId").toString()))
								&& Integer.valueOf(mapLayanan.get("produkId").toString())
										.equals(Integer.valueOf(mapSkor.get("produkId").toString()))
								&& refSkor.getDokterAnestesiId()
										.equals(Integer.valueOf(mapLayanan.get("pegawaiId").toString()))
								&& refSkor.getDokterPemeriksaId()
										.equals(Integer.valueOf(mapSkor.get("pegawaiId").toString()))
								&& refSkor.getKelompokKerjaId()
										.equals(Integer.valueOf(mapSkor.get("kelompokKerjaId").toString()))
								&& (((Date) mapLayanan.get("tglPelayanan")).after((Date) mapSkor.get("tglMulaiBerlaku"))
										|| ((Date) mapLayanan.get("tglPelayanan"))
												.equals((Date) mapSkor.get("tglMulaiBerlaku")))) {
							if (!mapLayanan.containsKey("skor")) {
								if (refSkor.getAsaId() >= 3) {
									double skor = 0.8 * Double.valueOf(mapSkor.get("skor").toString());
									mapLayanan.put("skor", skor);
									break;
								} else if (refSkor.getAsaId() == 2) {
									double skor = 0.5 * Double.valueOf(mapSkor.get("skor").toString());
									mapLayanan.put("skor", skor);
									break;
								} else if (refSkor.getAsaId() == 1) {
									double skor = 0.4 * Double.valueOf(mapSkor.get("skor").toString());
									mapLayanan.put("skor", skor);
									break;
								}
							}
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(dataLayananAnestesi)) {
				for (Map<String, Object> mapLayanan : dataLayanan) {
					for (Map<String, Object> mapLayananAnestesi : dataLayananAnestesi) {
						if (mapLayanan.get("noRec").toString().equals(mapLayananAnestesi.get("noRec"))) {
							mapLayanan.putAll(mapLayananAnestesi);
							break;
						}
					}
				}
			}
		}

		List<Map<String, Object>> dataSkor = skoringTindakanMedisDao.findSkoringLogbookDokter(
				mf.format(new Date(bulan)), Arrays.asList(idPegawai), Arrays.asList(Master.UnitKerja.KSM));

		// SCORE
		for (Map<String, Object> mapLayanan : dataLayanan) {
			for (Map<String, Object> mapSkor : dataSkor) {
				if (!listIdPelayananAnestesi.contains(mapLayanan.get("noRec")) && !mapLayanan.containsKey("skor")
						&& mapLayanan.get("produkId").equals(mapSkor.get("produkId"))
						&& (((Date) mapLayanan.get("tglPelayanan")).after((Date) mapSkor.get("tglMulaiBerlaku"))
								|| ((Date) mapLayanan.get("tglPelayanan"))
										.equals((Date) mapSkor.get("tglMulaiBerlaku")))) {
					mapLayanan.put("skor", mapSkor.get("skor"));
					break;
				}
			}
			if (!mapLayanan.containsKey("skor")) {
				mapLayanan.put("skor", 1.0);
			}
		}

		// RULES
		for (Map<String, Object> mapLayanan : dataLayanan) {
			if (Integer.valueOf(mapLayanan.get("jenisPetugasId").toString())
					.equals(Master.JenisPetugasPelaksana.DOKTER_PEMERIKSA)
					&& Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
					&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
							|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
				// tidak_dapat_skor_untuk_diskon_dpjp
				mapLayanan.put("skor", 0.000);
				mapLayanan.put("tSkor", 0.000);
			} else if (!mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& !mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.VISIT)
					&& listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				mapLayanan.put("skor", Double.parseDouble(decf.format(
						Double.valueOf(mapLayanan.get("skor").toString()) * Master.Remunerasi.PERSEN_SKOR_EKSEKUTIF)));
				mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Double.valueOf(mapLayanan.get("jumlah").toString()))));
			} else if (mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
				mapLayanan.put("skor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Master.Remunerasi.PERSEN_SKOR_ASISTEN_SPESIALIS)));
				mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Double.valueOf(mapLayanan.get("jumlah").toString()))));
			} else {
				mapLayanan.put("skor",
						Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString()))));
				mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Double.valueOf(mapLayanan.get("jumlah").toString()))));
			}
		}

		// GROUPING_INDIKATOR
		for (Map<String, Object> mapLayanan : dataLayanan) {
			if (listKonsulTapiVisit.contains(mapLayanan.get("produkId"))
					|| mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.VISIT)) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaJamKerja.VISITE);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaJamKerja.VISITE));
			} else if (mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaJamKerja.KONSUL_EKS);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaJamKerja.KONSUL_EKS));
			} else if (mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& mapLayanan.get("departemenId").equals(Master.Departemen.IGD)) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaJamKerja.KONSUL_GADAR);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaJamKerja.KONSUL_GADAR));
			} else if (mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaJamKerja.KONSUL_REG);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaJamKerja.KONSUL_REG));
			} else if (listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaJamKerja.TINDAKAN_EKS);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaJamKerja.TINDAKAN_EKS));
			} else if (mapLayanan.get("departemenId").equals(Master.Departemen.IGD)) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaJamKerja.TINDAKAN_GADAR);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaJamKerja.TINDAKAN_GADAR));
			} else if (mapLayanan.get("ruanganId").equals(Master.Ruangan.OK)) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaJamKerja.TINDAKAN_OPS);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaJamKerja.TINDAKAN_OPS));
			} else {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaJamKerja.TINDAKAN_REG);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaJamKerja.TINDAKAN_REG));
			}
		}

		for (Map<String, Object> mapLayanan : dataLayanan) {
			if (!listIdIndikator.contains(mapLayanan.get("indikatorId"))) {
				listIdIndikator.add(Integer.valueOf(mapLayanan.get("indikatorId").toString()));
			}
			if (!listIdProduk.contains(mapLayanan.get("produkId"))) {
				listIdProduk.add(Integer.valueOf(mapLayanan.get("produkId").toString()));
			}
			if (!listSkor.contains(mapLayanan.get("skor"))) {
				listSkor.add(Double.valueOf(mapLayanan.get("skor").toString()));
			}
			if (!listTglPelayanan.contains(df.format(((Date) mapLayanan.get("tglPelayanan"))))) {
				listTglPelayanan.add(df.format(((Date) mapLayanan.get("tglPelayanan"))));
			}
		}

		List<String> listTglPelayananSorted = listTglPelayanan.stream().sorted().collect(Collectors.toList());

		// GROUPING_TANGGAL_PELAYANAN
		List<Map<String, Object>> dataTglPelayanan = new ArrayList<>();
		for (Integer idIndikator : listIdIndikator) {
			for (Integer idProduk : listIdProduk) {
				for (Double skor : listSkor) {
					for (String tglPelayanan : listTglPelayananSorted) {
						Map<String, Object> data = new HashMap<>();
						double jumlahTindakan = 0.0;
						double jumlahSkor = 0.0;
						for (Map<String, Object> mapLayanan : dataLayanan) {
							if (idIndikator.equals(mapLayanan.get("indikatorId"))
									&& idProduk.equals(mapLayanan.get("produkId"))
									&& skor.equals(mapLayanan.get("skor"))
									&& tglPelayanan.equals(df.format(((Date) mapLayanan.get("tglPelayanan"))))) {
								jumlahTindakan += Double.valueOf(mapLayanan.get("jumlah").toString());
								jumlahSkor += Double.valueOf(mapLayanan.get("tSkor").toString());
								data.putAll(mapLayanan);
								data.put("tglPelayanan", df.format(((Date) mapLayanan.get("tglPelayanan"))));
							}
						}
						if (CommonUtil.isNotNullOrEmpty(data)) {
							data.put("jumlah", jumlahTindakan);
							data.put("tSkor", jumlahSkor);

							dataTglPelayanan.add(data);
						}
					}
				}
			}
		}

		// GROUPING_HEADER
		for (Integer idIndikator : listIdIndikator) {
			for (Integer idProduk : listIdProduk) {
				for (Double skor : listSkor) {
					Map<String, Object> data = new HashMap<>();
					List<Map<String, Object>> detail = new ArrayList<>();
					double jumlahTindakan = 0.0;
					double jumlahSkor = 0.0;
					for (Map<String, Object> mapLayanan : dataTglPelayanan) {
						if (idIndikator.equals(mapLayanan.get("indikatorId"))
								&& idProduk.equals(mapLayanan.get("produkId")) && skor.equals(mapLayanan.get("skor"))) {
							jumlahTindakan += Double.valueOf(mapLayanan.get("jumlah").toString());
							jumlahSkor += Double.valueOf(mapLayanan.get("tSkor").toString());

							Map<String, Object> mapDetail = new HashMap<>();
							mapDetail.put("jumlah", mapLayanan.get("jumlah"));
							mapDetail.put("tglPelayanan", mapLayanan.get("tglPelayanan"));
							detail.add(mapDetail);

							mapLayanan.remove("noRec");
							mapLayanan.remove("tglPelayanan");
							mapLayanan.remove("statusDiskon");
							mapLayanan.remove("hargaDiskon");
							mapLayanan.remove("departemenId");
							mapLayanan.remove("ruanganId");
							data.putAll(mapLayanan);
						}
					}
					if (CommonUtil.isNotNullOrEmpty(data)) {
						data.put("detail", detail);
						data.put("jumlah", jumlahTindakan);
						data.put("tSkor", Double.parseDouble(decf.format(jumlahSkor)));

						result.add(data);
					}
				}
			}
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findLogbookLuarJamKerjaDokter(Integer idPegawai, Long bulan) {
		List<Map<String, Object>> result = new ArrayList<>();
		List<String> listTglPelayanan = new ArrayList<>();
		List<Integer> listIdIndikator = new ArrayList<>();
		List<Integer> listIdProduk = new ArrayList<>();
		List<Integer> listDetailJenisProduk = new ArrayList<>();
		List<Integer> listDetailJenisProdukException = new ArrayList<>();
		List<Double> listSkor = new ArrayList<>();

		DateFormat mf = new SimpleDateFormat("yyyy-MM");
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

		DecimalFormat decf = new DecimalFormat("###.###");
		decf.setRoundingMode(RoundingMode.HALF_UP);

		LocalDateTime PSBBDate = LocalDateTime.of(2020, 9, 14, 0, 0, 0);
		LocalDateTime PSBBEnd = LocalDateTime.parse(GetSettingDataFixed("psbbperiod"), dtf);

		Date pssbAwal = Date.from(PSBBDate.atZone(ZoneId.systemDefault()).toInstant());
		Date pssbAkhir = Date.from(PSBBEnd.atZone(ZoneId.systemDefault()).toInstant());

		List<Integer> listRuangEks = splitDataSettingDatafixed("IdRuanganEksekutif");
		List<Integer> listKonsulTapiVisit = splitDataSettingDatafixed("konsulTapiVisit");

		List<Integer> drKsmUmumList = pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_UMUM);

		List<Integer> listIdNonjadwal = shiftKerjaDao.findListNonjadwal();
		List<Integer> laboranRadiologList = mapPegawaiLaboratRadiologiDao.findPegawaiLaboranRadiolog();
		if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_PATOLOGI_ANATOMI).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_pa");
		} else if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_PATOLOGI_KLINIK).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_pk");
		} else if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_RADIOLOGI).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_radiologi");
		} else {
			listDetailJenisProduk = splitDataSettingDatafixed("medis_utama");
		}

		if (laboranRadiologList.contains(idPegawai)) {
			listDetailJenisProdukException = splitDataSettingDatafixed("admin_nonpk");
			listDetailJenisProdukException.removeAll(listDetailJenisProduk);

			listDetailJenisProduk.addAll(listDetailJenisProdukException);
		}

		List<Map<String, Object>> dataLayanan = ikiDanRemunerasiDao.getDataLogbookLuarJamKerjaDokter(
				mf.format(new Date(bulan)), pssbAwal, pssbAkhir, listIdNonjadwal, Master.JenisPegawai.DOKTER, idPegawai,
				Arrays.asList(Master.Departemen.GRUP_RAWAT_JALAN), listDetailJenisProduk,
				splitDataSettingDatafixed("pr_dokter_umum_igd"), drKsmUmumList, Master.Departemen.IGD,
				Arrays.asList(Master.JenisProduk.NONTINDAKAN), Arrays.asList(Master.KelompokPasien.KELOMPOK_BPJS),
				Master.Produk.KARCIS);

		/**
		 * Menghitung skor asa dokter anestesi
		 */
		List<String> listIdPelayananAnestesi = new ArrayList<>();
		{
			List<Map<String, Object>> dataLayananAnestesi = new ArrayList<>();
			for (Map<String, Object> map : dataLayanan) {
				if (map.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.DOKTER_ANASTESI)) {
					listIdPelayananAnestesi.add(map.get("noRec").toString());
					dataLayananAnestesi.add(map);
				}
			}

			List<Map<String, Object>> listCountReferensiSkor = new ArrayList<>();
			if (CommonUtil.isNotNullOrEmpty(listIdPelayananAnestesi)) {
				listCountReferensiSkor = pelayananPasienPetugasDao
						.countReferensiSkorPelayananAnestesi(listIdPelayananAnestesi);
			}

			List<String> listIdRefSkor = new ArrayList<>();
			for (Map<String, Object> map : listCountReferensiSkor) {
				listIdRefSkor.add(map.get("pelayananId").toString());
			}

			List<Map<String, Object>> listDataReferensiSkor = new ArrayList<>();
			if (CommonUtil.isNotNullOrEmpty(listIdRefSkor)) {
				listDataReferensiSkor = pelayananPasienPetugasDao.findReferensiSkorPelayananAnestesi(listIdRefSkor,
						Arrays.asList(Master.UnitKerja.KSM));
			}

			List<ReferensiSkorAnestesiVO> listRefSkor = new ArrayList<>();
			for (String idRefSkor : listIdRefSkor) {
				ReferensiSkorAnestesiVO ref = new ReferensiSkorAnestesiVO();
				for (Map<String, Object> map : listDataReferensiSkor) {
					if (idRefSkor.equals(map.get("pelayananId"))) {
						ref.setPelayananId(map.get("pelayananId").toString());
						ref.setProdukId(Integer.valueOf(map.get("produkId").toString()));
						if (map.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.DOKTER_PEMERIKSA)) {
							ref.setDokterPemeriksaId(Integer.valueOf(map.get("petugasId").toString()));
							ref.setKelompokKerjaId(Integer.valueOf(map.get("kkId").toString()));
						} else if (map.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.DOKTER_ANASTESI)
								&& idPegawai.equals(map.get("petugasId"))) {
							ref.setDokterAnestesiId(Integer.valueOf(map.get("petugasId").toString()));
							ref.setAsaId(Byte.valueOf(map.get("asaId").toString()));
						}
					}
				}
				listRefSkor.add(ref);
			}

			List<Map<String, Object>> dataSkorAnestesi = new ArrayList<>();
			if (CommonUtil.isNotNullOrEmpty(listRefSkor)) {
				dataSkorAnestesi = skoringTindakanMedisDaoCustom.findSkoringLogbookDokter(mf.format(new Date(bulan)),
						listRefSkor);
			}

			/**
			 * Skor dokter anestesi (bukan tindakan mandiri)
			 */
			for (ReferensiSkorAnestesiVO refSkor : listRefSkor) {
				for (Map<String, Object> mapLayanan : dataLayananAnestesi) {
					for (Map<String, Object> mapSkor : dataSkorAnestesi) {
						if (refSkor.getPelayananId().equals(mapLayanan.get("noRec").toString())
								&& refSkor.getAsaId().equals(Byte.valueOf(mapLayanan.get("asaId").toString()))
								&& refSkor.getProdukId().equals(Integer.valueOf(mapLayanan.get("produkId").toString()))
								&& refSkor.getProdukId().equals(Integer.valueOf(mapSkor.get("produkId").toString()))
								&& Integer.valueOf(mapLayanan.get("produkId").toString())
										.equals(Integer.valueOf(mapSkor.get("produkId").toString()))
								&& refSkor.getDokterAnestesiId()
										.equals(Integer.valueOf(mapLayanan.get("pegawaiId").toString()))
								&& refSkor.getDokterPemeriksaId()
										.equals(Integer.valueOf(mapSkor.get("pegawaiId").toString()))
								&& refSkor.getKelompokKerjaId()
										.equals(Integer.valueOf(mapSkor.get("kelompokKerjaId").toString()))
								&& (((Date) mapLayanan.get("tglPelayanan")).after((Date) mapSkor.get("tglMulaiBerlaku"))
										|| ((Date) mapLayanan.get("tglPelayanan"))
												.equals((Date) mapSkor.get("tglMulaiBerlaku")))) {
							double skor = 0.0;
							if (refSkor.getAsaId() >= 3) {
								skor = 0.8 * Double.valueOf(mapSkor.get("skor").toString());
							} else if (refSkor.getAsaId() == 2) {
								skor = 0.5 * Double.valueOf(mapSkor.get("skor").toString());
							} else {
								skor = 0.4 * Double.valueOf(mapSkor.get("skor").toString());
							}
							mapLayanan.put("skor", skor);
							break;
						}
					}
				}
			}
		}

		List<Map<String, Object>> dataSkor = skoringTindakanMedisDao.findSkoringLogbookDokter(
				mf.format(new Date(bulan)), Arrays.asList(idPegawai), Arrays.asList(Master.UnitKerja.KSM));

		// SCORE
		for (Map<String, Object> mapLayanan : dataLayanan) {
			for (Map<String, Object> mapSkor : dataSkor) {
				if (!listIdPelayananAnestesi.contains(mapLayanan.get("noRec"))
						&& mapLayanan.get("produkId").equals(mapSkor.get("produkId"))
						&& (((Date) mapLayanan.get("tglPelayanan")).after((Date) mapSkor.get("tglMulaiBerlaku"))
								|| ((Date) mapLayanan.get("tglPelayanan"))
										.equals((Date) mapSkor.get("tglMulaiBerlaku")))) {
					mapLayanan.put("skor", mapSkor.get("skor"));
					break;
				}
			}
			if (!mapLayanan.containsKey("skor")) {
				mapLayanan.put("skor", 1.0);
			}
		}

		// RULES
		for (Map<String, Object> mapLayanan : dataLayanan) {
			if (Integer.valueOf(mapLayanan.get("jenisPetugasId").toString())
					.equals(Master.JenisPetugasPelaksana.DOKTER_PEMERIKSA)
					&& Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
					&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
							|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
				// tidak_dapat_skor_untuk_diskon_dpjp
				mapLayanan.put("skor", 0.000);
				mapLayanan.put("tSkor", 0.000);
			} else if (!mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& !mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.VISIT)
					&& listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				mapLayanan.put("skor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Master.Remunerasi.PERSEN_SKOR_LUAR_JAM_KERJA)));
				mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Double.valueOf(mapLayanan.get("jumlah").toString()))));
			} else if (mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
				mapLayanan.put("skor",
						Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
								* Master.Remunerasi.PERSEN_SKOR_LUAR_JAM_KERJA
								* Master.Remunerasi.PERSEN_SKOR_ASISTEN_SPESIALIS)));
				mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Double.valueOf(mapLayanan.get("jumlah").toString()))));
			} else {
				mapLayanan.put("skor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Master.Remunerasi.PERSEN_SKOR_LUAR_JAM_KERJA)));
				mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Double.valueOf(mapLayanan.get("jumlah").toString()))));
			}
		}

		// GROUPING_INDIKATOR
		for (Map<String, Object> mapLayanan : dataLayanan) {
			if (listKonsulTapiVisit.contains(mapLayanan.get("produkId"))
					|| mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.VISIT)) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaLuarJamKerja.VISITE);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaLuarJamKerja.VISITE));
			} else if (mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaLuarJamKerja.KONSUL_EKS);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaLuarJamKerja.KONSUL_EKS));
			} else if (mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& mapLayanan.get("departemenId").equals(Master.Departemen.IGD)) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaLuarJamKerja.KONSUL_GADAR);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaLuarJamKerja.KONSUL_GADAR));
			} else if (mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaLuarJamKerja.KONSUL_REG);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaLuarJamKerja.KONSUL_REG));
			} else if (listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_EKS);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_EKS));
			} else if (mapLayanan.get("departemenId").equals(Master.Departemen.IGD)) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_GADAR);
				mapLayanan.put("namaIndikator", indikatorKinerjaDetailDao
						.findNamaIndikator(Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_GADAR));
			} else if (mapLayanan.get("ruanganId").equals(Master.Ruangan.OK)) {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_OPS);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_OPS));
			} else {
				mapLayanan.put("indikatorId", Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_REG);
				mapLayanan.put("namaIndikator",
						indikatorKinerjaDetailDao.findNamaIndikator(Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_REG));
			}
		}

		for (Map<String, Object> mapLayanan : dataLayanan) {
			if (!listIdIndikator.contains(mapLayanan.get("indikatorId"))) {
				listIdIndikator.add(Integer.valueOf(mapLayanan.get("indikatorId").toString()));
			}
			if (!listIdProduk.contains(mapLayanan.get("produkId"))) {
				listIdProduk.add(Integer.valueOf(mapLayanan.get("produkId").toString()));
			}
			if (!listSkor.contains(mapLayanan.get("skor"))) {
				listSkor.add(Double.valueOf(mapLayanan.get("skor").toString()));
			}
			if (!listTglPelayanan.contains(df.format(((Date) mapLayanan.get("tglPelayanan"))))) {
				listTglPelayanan.add(df.format(((Date) mapLayanan.get("tglPelayanan"))));
			}
		}

		List<String> listTglPelayananSorted = listTglPelayanan.stream().sorted().collect(Collectors.toList());

		// GROUPING_TANGGAL_PELAYANAN
		List<Map<String, Object>> dataTglPelayanan = new ArrayList<>();
		for (Integer idIndikator : listIdIndikator) {
			for (Integer idProduk : listIdProduk) {
				for (Double skor : listSkor) {
					for (String tglPelayanan : listTglPelayananSorted) {
						Map<String, Object> data = new HashMap<>();
						double jumlahTindakan = 0.0;
						double jumlahSkor = 0.0;
						for (Map<String, Object> mapLayanan : dataLayanan) {
							if (idIndikator.equals(mapLayanan.get("indikatorId"))
									&& idProduk.equals(mapLayanan.get("produkId"))
									&& skor.equals(mapLayanan.get("skor"))
									&& tglPelayanan.equals(df.format(((Date) mapLayanan.get("tglPelayanan"))))) {
								jumlahTindakan += Double.valueOf(mapLayanan.get("jumlah").toString());
								jumlahSkor += Double.valueOf(mapLayanan.get("tSkor").toString());
								data.putAll(mapLayanan);
								data.put("tglPelayanan", df.format(((Date) mapLayanan.get("tglPelayanan"))));
							}
						}
						if (CommonUtil.isNotNullOrEmpty(data)) {
							data.put("jumlah", jumlahTindakan);
							data.put("tSkor", jumlahSkor);

							dataTglPelayanan.add(data);
						}
					}
				}
			}
		}

		// GROUPING_HEADER
		for (Integer idIndikator : listIdIndikator) {
			for (Integer idProduk : listIdProduk) {
				for (Double skor : listSkor) {
					Map<String, Object> data = new HashMap<>();
					List<Map<String, Object>> detail = new ArrayList<>();
					double jumlahTindakan = 0.0;
					double jumlahSkor = 0.0;
					for (Map<String, Object> mapLayanan : dataTglPelayanan) {
						if (idIndikator.equals(mapLayanan.get("indikatorId"))
								&& idProduk.equals(mapLayanan.get("produkId")) && skor.equals(mapLayanan.get("skor"))) {
							jumlahTindakan += Double.valueOf(mapLayanan.get("jumlah").toString());
							jumlahSkor += Double.valueOf(mapLayanan.get("tSkor").toString());

							Map<String, Object> mapDetail = new HashMap<>();
							mapDetail.put("jumlah", mapLayanan.get("jumlah"));
							mapDetail.put("tglPelayanan", mapLayanan.get("tglPelayanan"));
							detail.add(mapDetail);

							mapLayanan.remove("noRec");
							mapLayanan.remove("tglPelayanan");
							mapLayanan.remove("statusDiskon");
							mapLayanan.remove("hargaDiskon");
							mapLayanan.remove("departemenId");
							mapLayanan.remove("ruanganId");
							data.putAll(mapLayanan);
						}
					}
					if (CommonUtil.isNotNullOrEmpty(data)) {
						data.put("detail", detail);
						data.put("jumlah", jumlahTindakan);
						data.put("tSkor", Double.parseDouble(decf.format(jumlahSkor)));

						result.add(data);
					}
				}
			}
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findDetailLogbookJamKerjaDokter(Integer idPegawai, Integer idIndikator,
			Integer idProduk, String tglPelayanan, Integer idJenisPetugas, Double skor) {
		List<Map<String, Object>> result = new ArrayList<>();

		List<Integer> listDetailJenisProduk = new ArrayList<>();
		List<Integer> listDetailJenisProdukException = new ArrayList<>();

		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

		LocalDateTime PSBBDate = LocalDateTime.of(2020, 9, 14, 0, 0, 0);
		LocalDateTime PSBBEnd = LocalDateTime.parse(GetSettingDataFixed("psbbperiod"), dtf);

		Date pssbAwal = Date.from(PSBBDate.atZone(ZoneId.systemDefault()).toInstant());
		Date pssbAkhir = Date.from(PSBBEnd.atZone(ZoneId.systemDefault()).toInstant());

		String[] blnComp = tglPelayanan.split("-");
		String bulan = blnComp[0] + "-" + blnComp[1];

		List<Integer> listRuangEks = splitDataSettingDatafixed("IdRuanganEksekutif");
		List<Integer> listKonsulTapiVisit = splitDataSettingDatafixed("konsulTapiVisit");

		List<Integer> drKsmUmumList = pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_UMUM);

		List<Integer> listIdNonjadwal = shiftKerjaDao.findListNonjadwal();
		List<Integer> laboranRadiologList = mapPegawaiLaboratRadiologiDao.findPegawaiLaboranRadiolog();
		if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_PATOLOGI_ANATOMI).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_pa");
		} else if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_PATOLOGI_KLINIK).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_pk");
		} else if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_RADIOLOGI).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_radiologi");
		} else {
			listDetailJenisProduk = splitDataSettingDatafixed("medis_utama");
		}

		if (laboranRadiologList.contains(idPegawai)) {
			listDetailJenisProdukException = splitDataSettingDatafixed("admin_nonpk");
			listDetailJenisProdukException.removeAll(listDetailJenisProduk);

			listDetailJenisProduk.addAll(listDetailJenisProdukException);
		}

		List<Map<String, Object>> dataLayanan = ikiDanRemunerasiDao.findDetailPasienLogbookJamKerjaDokter(idProduk,
				tglPelayanan, pssbAwal, pssbAkhir, listIdNonjadwal, Master.JenisPegawai.DOKTER, idPegawai,
				Arrays.asList(Master.Departemen.GRUP_RAWAT_JALAN), listDetailJenisProduk,
				splitDataSettingDatafixed("pr_dokter_umum_igd"), drKsmUmumList, Master.Departemen.IGD,
				Arrays.asList(Master.JenisProduk.NONTINDAKAN), Arrays.asList(Master.KelompokPasien.KELOMPOK_BPJS),
				Master.Produk.KARCIS);

		/**
		 * Menghitung skor asa dokter anestesi
		 */
		List<String> listIdPelayananAnestesi = new ArrayList<>();
		{
			List<Map<String, Object>> dataLayananAnestesi = new ArrayList<>();
			for (Map<String, Object> map : dataLayanan) {
				if (map.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.DOKTER_ANASTESI)) {
					listIdPelayananAnestesi.add(map.get("noRec").toString());
					dataLayananAnestesi.add(map);
				}
			}

			List<Map<String, Object>> listCountReferensiSkor = new ArrayList<>();
			if (CommonUtil.isNotNullOrEmpty(listIdPelayananAnestesi)) {
				listCountReferensiSkor = pelayananPasienPetugasDao
						.countReferensiSkorPelayananAnestesi(listIdPelayananAnestesi);
			}

			List<String> listIdRefSkor = new ArrayList<>();
			for (Map<String, Object> map : listCountReferensiSkor) {
				listIdRefSkor.add(map.get("pelayananId").toString());
			}

			List<Map<String, Object>> listDataReferensiSkor = new ArrayList<>();
			if (CommonUtil.isNotNullOrEmpty(listIdRefSkor)) {
				listDataReferensiSkor = pelayananPasienPetugasDao.findReferensiSkorPelayananAnestesi(listIdRefSkor,
						Arrays.asList(Master.UnitKerja.KSM));
			}

			List<ReferensiSkorAnestesiVO> listRefSkor = new ArrayList<>();
			for (String idRefSkor : listIdRefSkor) {
				ReferensiSkorAnestesiVO ref = new ReferensiSkorAnestesiVO();
				for (Map<String, Object> map : listDataReferensiSkor) {
					if (idRefSkor.equals(map.get("pelayananId"))) {
						ref.setPelayananId(map.get("pelayananId").toString());
						ref.setProdukId(Integer.valueOf(map.get("produkId").toString()));
						if (map.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.DOKTER_PEMERIKSA)) {
							ref.setDokterPemeriksaId(Integer.valueOf(map.get("petugasId").toString()));
							ref.setKelompokKerjaId(Integer.valueOf(map.get("kkId").toString()));
						} else if (map.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.DOKTER_ANASTESI)
								&& idPegawai.equals(map.get("petugasId"))) {
							ref.setDokterAnestesiId(Integer.valueOf(map.get("petugasId").toString()));
							ref.setAsaId(Byte.valueOf(map.get("asaId").toString()));
						}
					}
				}
				listRefSkor.add(ref);
			}

			List<Map<String, Object>> dataSkorAnestesi = new ArrayList<>();
			if (CommonUtil.isNotNullOrEmpty(listRefSkor)) {
				dataSkorAnestesi = skoringTindakanMedisDaoCustom.findSkoringLogbookDokter(bulan, listRefSkor);
			}

			/**
			 * Skor dokter anestesi (bukan tindakan mandiri)
			 */
			for (ReferensiSkorAnestesiVO refSkor : listRefSkor) {
				for (Map<String, Object> mapLayanan : dataLayananAnestesi) {
					for (Map<String, Object> mapSkor : dataSkorAnestesi) {
						if (CommonUtil.isNotNullOrEmpty(refSkor.getPelayananId())
								&& CommonUtil.isNotNullOrEmpty(mapLayanan.get("noRec"))
								&& CommonUtil.isNotNullOrEmpty(refSkor.getAsaId())
								&& CommonUtil.isNotNullOrEmpty(mapLayanan.get("asaId"))
								&& CommonUtil.isNotNullOrEmpty(refSkor.getProdukId())
								&& CommonUtil.isNotNullOrEmpty(mapLayanan.get("produkId"))
								&& CommonUtil.isNotNullOrEmpty(mapSkor.get("produkId"))
								&& CommonUtil.isNotNullOrEmpty(refSkor.getDokterAnestesiId())
								&& CommonUtil.isNotNullOrEmpty(idPegawai)
								&& CommonUtil.isNotNullOrEmpty(refSkor.getDokterPemeriksaId())
								&& CommonUtil.isNotNullOrEmpty(mapSkor.get("pegawaiId"))
								&& CommonUtil.isNotNullOrEmpty(refSkor.getKelompokKerjaId())
								&& CommonUtil.isNotNullOrEmpty(mapSkor.get("kelompokKerjaId"))
								&& CommonUtil.isNotNullOrEmpty(mapLayanan.get("tglPelayanan"))
								&& CommonUtil.isNotNullOrEmpty(mapSkor.get("tglMulaiBerlaku"))
								&& refSkor.getPelayananId().equals(mapLayanan.get("noRec").toString())
								&& refSkor.getAsaId().equals(Byte.valueOf(mapLayanan.get("asaId").toString()))
								&& refSkor.getProdukId().equals(Integer.valueOf(mapLayanan.get("produkId").toString()))
								&& refSkor.getProdukId().equals(Integer.valueOf(mapSkor.get("produkId").toString()))
								&& Integer.valueOf(mapLayanan.get("produkId").toString())
										.equals(Integer.valueOf(mapSkor.get("produkId").toString()))
								&& idPegawai.equals(refSkor.getDokterAnestesiId())
								&& refSkor.getDokterPemeriksaId()
										.equals(Integer.valueOf(mapSkor.get("pegawaiId").toString()))
								&& refSkor.getKelompokKerjaId()
										.equals(Integer.valueOf(mapSkor.get("kelompokKerjaId").toString()))
								&& (((Date) mapLayanan.get("tglPelayanan")).after((Date) mapSkor.get("tglMulaiBerlaku"))
										|| ((Date) mapLayanan.get("tglPelayanan"))
												.equals((Date) mapSkor.get("tglMulaiBerlaku")))) {
							if (!mapLayanan.containsKey("skor")) {
								if (refSkor.getAsaId() >= 3) {
									double calcSkor = 0.8 * Double.valueOf(mapSkor.get("skor").toString());
									mapLayanan.put("skor", calcSkor);
									break;
								} else if (refSkor.getAsaId() == 2) {
									double calcSkor = 0.5 * Double.valueOf(mapSkor.get("skor").toString());
									mapLayanan.put("skor", calcSkor);
									break;
								} else if (refSkor.getAsaId() == 1) {
									double calcSkor = 0.4 * Double.valueOf(mapSkor.get("skor").toString());
									mapLayanan.put("skor", calcSkor);
									break;
								}
							}
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(dataLayananAnestesi)) {
				for (Map<String, Object> mapLayanan : dataLayanan) {
					for (Map<String, Object> mapLayananAnestesi : dataLayananAnestesi) {
						if (mapLayanan.get("noRec").toString().equals(mapLayananAnestesi.get("noRec"))) {
							mapLayanan.putAll(mapLayananAnestesi);
							break;
						}
					}
				}
			}
		}

		List<Map<String, Object>> dataSkor = skoringTindakanMedisDao.findSkoringLogbookDokter(bulan,
				Arrays.asList(idPegawai), Arrays.asList(Master.UnitKerja.KSM));

		// SCORE
		for (Map<String, Object> mapLayanan : dataLayanan) {
			for (Map<String, Object> mapSkor : dataSkor) {
				if (!listIdPelayananAnestesi.contains(mapLayanan.get("noRec")) && !mapLayanan.containsKey("skor")
						&& mapLayanan.get("produkId").equals(mapSkor.get("produkId"))
						&& (((Date) mapLayanan.get("tglPelayanan")).after((Date) mapSkor.get("tglMulaiBerlaku"))
								|| ((Date) mapLayanan.get("tglPelayanan"))
										.equals((Date) mapSkor.get("tglMulaiBerlaku")))) {
					mapLayanan.put("skor", mapSkor.get("skor"));
					break;
				}
			}
			if (!mapLayanan.containsKey("skor")) {
				mapLayanan.put("skor", 1.0);
			}
		}

		// FILTERING
		List<Map<String, Object>> dataLayananFiltered = new ArrayList<>();
		for (Map<String, Object> map : dataLayanan) {
			if (skor.equals(map.get("skor"))) {
				dataLayananFiltered.add(map);
			}
		}

		// RULES
		for (Map<String, Object> mapLayanan : dataLayananFiltered) {
			if (idIndikator.equals(Master.IndikatorKinerjaJamKerja.VISITE)
					&& (listKonsulTapiVisit.contains(mapLayanan.get("produkId"))
							|| mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.VISIT))) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaJamKerja.KONSUL_EKS)
					&& mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaJamKerja.KONSUL_GADAR)
					&& mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& mapLayanan.get("departemenId").equals(Master.Departemen.IGD)) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaJamKerja.KONSUL_REG)
					&& mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaJamKerja.TINDAKAN_EKS)
					&& listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaJamKerja.TINDAKAN_GADAR)
					&& mapLayanan.get("departemenId").equals(Master.Departemen.IGD)) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaJamKerja.TINDAKAN_OPS)
					&& mapLayanan.get("ruanganId").equals(Master.Ruangan.OK)) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaJamKerja.TINDAKAN_REG)
					&& !listKonsulTapiVisit.contains(mapLayanan.get("produkId"))
					&& !mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.VISIT)
					&& !mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& !listRuangEks.contains(mapLayanan.get("ruanganId"))
					&& !mapLayanan.get("departemenId").equals(Master.Departemen.IGD)
					&& !mapLayanan.get("ruanganId").equals(Master.Ruangan.OK)) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			}
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findDetailLogbookLuarJamKerjaDokter(Integer idPegawai, Integer idIndikator,
			Integer idProduk, String tglPelayanan, Integer idJenisPetugas, Double skor) {
		List<Map<String, Object>> result = new ArrayList<>();

		List<Integer> listDetailJenisProduk = new ArrayList<>();
		List<Integer> listDetailJenisProdukException = new ArrayList<>();

		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

		LocalDateTime PSBBDate = LocalDateTime.of(2020, 9, 14, 0, 0, 0);
		LocalDateTime PSBBEnd = LocalDateTime.parse(GetSettingDataFixed("psbbperiod"), dtf);

		Date pssbAwal = Date.from(PSBBDate.atZone(ZoneId.systemDefault()).toInstant());
		Date pssbAkhir = Date.from(PSBBEnd.atZone(ZoneId.systemDefault()).toInstant());

		List<Integer> listRuangEks = splitDataSettingDatafixed("IdRuanganEksekutif");
		List<Integer> listKonsulTapiVisit = splitDataSettingDatafixed("konsulTapiVisit");

		List<Integer> drKsmUmumList = pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_UMUM);

		List<Integer> listIdNonjadwal = shiftKerjaDao.findListNonjadwal();
		List<Integer> laboranRadiologList = mapPegawaiLaboratRadiologiDao.findPegawaiLaboranRadiolog();
		if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_PATOLOGI_ANATOMI).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_pa");
		} else if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_PATOLOGI_KLINIK).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_pk");
		} else if (pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_RADIOLOGI).contains(idPegawai)) {
			listDetailJenisProduk = splitDataSettingDatafixed("penunjang_radiologi");
		} else {
			listDetailJenisProduk = splitDataSettingDatafixed("medis_utama");
		}

		if (laboranRadiologList.contains(idPegawai)) {
			listDetailJenisProdukException = splitDataSettingDatafixed("admin_nonpk");
			listDetailJenisProdukException.removeAll(listDetailJenisProduk);

			listDetailJenisProduk.addAll(listDetailJenisProdukException);
		}

		List<Map<String, Object>> dataLayanan = ikiDanRemunerasiDao.findDetailPasienLogbookLuarJamKerjaDokter(idProduk,
				tglPelayanan, pssbAwal, pssbAkhir, listIdNonjadwal, Master.JenisPegawai.DOKTER, idPegawai,
				Arrays.asList(Master.Departemen.GRUP_RAWAT_JALAN), listDetailJenisProduk,
				splitDataSettingDatafixed("pr_dokter_umum_igd"), drKsmUmumList, Master.Departemen.IGD,
				Arrays.asList(Master.JenisProduk.NONTINDAKAN), Arrays.asList(Master.KelompokPasien.KELOMPOK_BPJS),
				Master.Produk.KARCIS);

		for (Map<String, Object> mapLayanan : dataLayanan) {
			if (idIndikator.equals(Master.IndikatorKinerjaLuarJamKerja.VISITE)
					&& (listKonsulTapiVisit.contains(mapLayanan.get("produkId"))
							|| mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.VISIT))) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaLuarJamKerja.KONSUL_EKS)
					&& mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaLuarJamKerja.KONSUL_GADAR)
					&& mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& mapLayanan.get("departemenId").equals(Master.Departemen.IGD)) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaLuarJamKerja.KONSUL_REG)
					&& mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_EKS)
					&& listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_GADAR)
					&& mapLayanan.get("departemenId").equals(Master.Departemen.IGD)) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_OPS)
					&& mapLayanan.get("ruanganId").equals(Master.Ruangan.OK)) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			} else if (idIndikator.equals(Master.IndikatorKinerjaLuarJamKerja.TINDAKAN_REG)
					&& !listKonsulTapiVisit.contains(mapLayanan.get("produkId"))
					&& !mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.VISIT)
					&& !mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& !listRuangEks.contains(mapLayanan.get("ruanganId"))
					&& !mapLayanan.get("departemenId").equals(Master.Departemen.IGD)
					&& !mapLayanan.get("ruanganId").equals(Master.Ruangan.OK)) {
				if (idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				} else if (!idJenisPetugas.equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)
						&& !mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
					if (skor.equals(0.0) && Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
							&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
									|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					} else if (!skor.equals(0.0)) {
						mapLayanan.remove("noRec");
						mapLayanan.remove("statusDiskon");
						mapLayanan.remove("departemenId");
						mapLayanan.remove("ruanganId");
						mapLayanan.remove("hargaDiskon");
						result.add(mapLayanan);
					}
				}
			}
		}

		return result;
	}

	@Override
	public Map<String, Object> findPenilaianKinerja(Integer idPegawai, Integer idJabatan, Long bulan)
			throws JpaSystemException {
		Map<String, Object> result = new HashMap<>();

		DateFormat mf = new SimpleDateFormat("yyyy-MM");

		DecimalFormat df = new DecimalFormat("0.00");
		df.setRoundingMode(RoundingMode.HALF_UP);

		List<Map<String, Object>> data = logbookKinerjaDao.findPenilaianKinerja(idPegawai, idJabatan,
				mf.format(new Date(bulan)));

		Integer idKelompokJabatan = null;
		if (CommonUtil.isNotNullOrEmpty(data) && data.size() > 0) {
			idKelompokJabatan = Integer.parseInt(data.get(0).get("kelompokJabatanId").toString());
		}

		double tBobot = 0.00;
		double tHasil = 0.00;
		for (Integer idJenisIndikator : Arrays.asList(Master.Remunerasi.JENIS_INDIKATOR)) {
			Map<String, Object> jiData = new HashMap<>();
			List<Map<String, Object>> jiDetail = new ArrayList<>();
			double jiBobot = 0.00;
			double jiHasil = 0.00;
			for (Map<String, Object> map : data) {
				if (idJenisIndikator.equals(map.get("jenisIndikatorId"))) {
					String nilai = df.format(Double.valueOf(map.get("realisasi").toString())
							/ Double.valueOf(map.get("target").toString()));
					String hasil = df.format(Double.parseDouble(nilai) * Double.valueOf(map.get("bobot").toString()));
					map.put("nilai", Double.parseDouble(nilai));
					map.put("hasil", Double.parseDouble(hasil));
					map.put("realisasi", new BigDecimal(Double.valueOf(map.get("realisasi").toString())).setScale(2,
							RoundingMode.HALF_UP));
					jiDetail.add(map);

					jiBobot += Double.valueOf(map.get("bobot").toString());
					jiHasil += Double.valueOf(map.get("hasil").toString());

					tBobot += Double.valueOf(map.get("bobot").toString());
					tHasil += Double.valueOf(map.get("hasil").toString());
				}
			}
			jiDetail = jiDetail.stream().sorted(Comparator.comparing(o2 -> o2.get("namaIndikator").toString()))
					.collect(Collectors.toList());

			jiData.put("detail", jiDetail);
			jiData.put("stBobot", jiBobot);
			jiData.put("stHasil", jiHasil);

			if (idJenisIndikator == 1) {
				result.put("kuantitas", jiData);
			} else if (idJenisIndikator == 2) {
				result.put("kualitas", jiData);
			} else if (idJenisIndikator == 3) {
				result.put("perilaku", jiData);
			}
		}

		Double iki = 0.0;
		String kriteria = "-";
		if (Arrays.asList(Master.KelompokJabatan.DIR_MS).contains(idKelompokJabatan)) {
			List<Map<String, Object>> acuanIndeks = tabelAcuanIndeksIKIDao
					.findAllAcuanIndeks(Master.TabelAcuanIndeksIKI.MAX_DIR_MS);
			for (Map<String, Object> aiki : acuanIndeks) {
				if ((Double.valueOf(aiki.get("nilaiBawah").toString()) < Double.parseDouble(df.format(tHasil))
						&& Double.parseDouble(df.format(tHasil)) <= Double.valueOf(aiki.get("nilaiAtas").toString()))
						|| (Double.parseDouble(df.format(tHasil)) > 1000
								&& Double.valueOf(aiki.get("nilaiAtas").toString()) == 1000)) {
					iki = Double.valueOf(aiki.get("iki").toString());
					kriteria = aiki.get("kriteria").toString();

					break;
				}
			}
		} else {
			List<Map<String, Object>> acuanIndeks = tabelAcuanIndeksIKIDao
					.findAllAcuanIndeks(Master.TabelAcuanIndeksIKI.MAX_OTHERS);
			for (Map<String, Object> aiki : acuanIndeks) {
				if ((Double.valueOf(aiki.get("nilaiBawah").toString()) < Double.parseDouble(df.format(tHasil))
						&& Double.parseDouble(df.format(tHasil)) <= Double.valueOf(aiki.get("nilaiAtas").toString()))
						|| (Double.parseDouble(df.format(tHasil)) > 160
								&& Double.valueOf(aiki.get("nilaiAtas").toString()) == 160)) {
					iki = Double.valueOf(aiki.get("iki").toString());
					kriteria = aiki.get("kriteria").toString();

					break;
				}
			}
		}

		result.put("tBobot", tBobot);
		result.put("tHasil", Double.parseDouble(df.format(tHasil)));
		result.put("iki", iki);
		result.put("kriteria", kriteria);

		return result;
	}

	@Override
	public List<Map<String, Object>> findRekapPenilaianKinerja(Long bulan, Integer idUnitKerja, Integer idSubunitKerja,
			Integer idPegawai) throws JpaSystemException {
		List<Map<String, Object>> result = new ArrayList<>();
		List<Map<String, Object>> data = new ArrayList<>();
		List<Map<String, Object>> recapData = new ArrayList<>();
		List<Integer> listIdUnitKerja = new ArrayList<>();
		List<Integer> listIdSubunitKerja = new ArrayList<>();
		List<Integer> listIdPegawai = new ArrayList<>();
		List<Integer> listIdJabatan = new ArrayList<>();

		DecimalFormatSymbols formatRp = new DecimalFormatSymbols();
		formatRp.setCurrencySymbol("Rp");
		formatRp.setMonetaryDecimalSeparator(',');
		formatRp.setGroupingSeparator('.');

		DecimalFormat kursINA = (DecimalFormat) DecimalFormat.getCurrencyInstance();
		kursINA.setDecimalFormatSymbols(formatRp);

		DateFormat mf = new SimpleDateFormat("yyyy-MM");
		DateFormat yf = new SimpleDateFormat("yyyy");

		DecimalFormat df = new DecimalFormat("0.00");
		df.setRoundingMode(RoundingMode.HALF_UP);

		List<Map<String, Object>> anggaran = anggaranRemunerasiDao.findAnggaran(yf.format(new Date(bulan)));

		List<Map<String, Object>> acuanIndeks = tabelAcuanIndeksIKIDao.findAllAcuanIndeks();

		if (CommonUtil.isNotNullOrEmpty(bulan) && CommonUtil.isNullOrEmpty(idUnitKerja)
				&& CommonUtil.isNullOrEmpty(idSubunitKerja) && CommonUtil.isNullOrEmpty(idPegawai)) {
			data = logbookKinerjaDao.findPenilaianKinerja(mf.format(new Date(bulan)));
		} else if (CommonUtil.isNotNullOrEmpty(bulan) && CommonUtil.isNotNullOrEmpty(idUnitKerja)
				&& CommonUtil.isNullOrEmpty(idSubunitKerja) && CommonUtil.isNullOrEmpty(idPegawai)) {
			data = logbookKinerjaDao.findPenilaianKinerjaUnitKerja(mf.format(new Date(bulan)), idUnitKerja);
		} else if (CommonUtil.isNotNullOrEmpty(bulan) && CommonUtil.isNotNullOrEmpty(idUnitKerja)
				&& CommonUtil.isNotNullOrEmpty(idSubunitKerja) && CommonUtil.isNullOrEmpty(idPegawai)) {
			data = logbookKinerjaDao.findPenilaianKinerjaSubunitKerja(mf.format(new Date(bulan)), idUnitKerja,
					idSubunitKerja);
		} else if (CommonUtil.isNotNullOrEmpty(bulan) && CommonUtil.isNullOrEmpty(idUnitKerja)
				&& CommonUtil.isNullOrEmpty(idSubunitKerja) && CommonUtil.isNotNullOrEmpty(idPegawai)) {
			data = logbookKinerjaDao.findPenilaianKinerjaPegawai(mf.format(new Date(bulan)), idPegawai);
		} else if (CommonUtil.isNotNullOrEmpty(bulan) && CommonUtil.isNotNullOrEmpty(idUnitKerja)
				&& CommonUtil.isNotNullOrEmpty(idSubunitKerja) && CommonUtil.isNotNullOrEmpty(idPegawai)) {
			data = logbookKinerjaDao.findPenilaianKinerjaPegawai(mf.format(new Date(bulan)), idUnitKerja,
					idSubunitKerja, idPegawai);
		}

		for (Map<String, Object> map : data) {
			if (!listIdUnitKerja.contains(map.get("unitKerjaId"))) {
				listIdUnitKerja.add(Integer.valueOf(map.get("unitKerjaId").toString()));
			}
			if (!listIdSubunitKerja.contains(map.get("subunitKerjaId"))) {
				listIdSubunitKerja.add(Integer.valueOf(map.get("subunitKerjaId").toString()));
			}
			if (!listIdPegawai.contains(map.get("pegawaiId"))) {
				listIdPegawai.add(Integer.valueOf(map.get("pegawaiId").toString()));
			}
			if (!listIdJabatan.contains(map.get("jabatanId"))) {
				listIdJabatan.add(Integer.valueOf(map.get("jabatanId").toString()));
			}
		}

		for (Integer idUK : listIdUnitKerja) {
			for (Integer idSK : listIdSubunitKerja) {
				for (Integer idP : listIdPegawai) {
					for (Integer idJ : listIdJabatan) {
						Integer idKelompokJabatan = Integer.parseInt(data.get(0).get("kelompokJabatanId").toString());

						Map<String, Object> rsMap = new HashMap<>();
						double tHasil = 0.00;
						for (Integer idJI : Arrays.asList(Master.Remunerasi.JENIS_INDIKATOR)) {
							double jiBobot = 0.00;
							double jiHasil = 0.00;
							for (Map<String, Object> map : data) {
								if (idUK.equals(map.get("unitKerjaId")) && idSK.equals(map.get("subunitKerjaId"))
										&& idP.equals(map.get("pegawaiId")) && idJ.equals(map.get("jabatanId"))
										&& idJI.equals(map.get("jenisIndikatorId"))) {
									String nilai = df.format(Double.valueOf(map.get("realisasi").toString())
											/ Double.valueOf(map.get("target").toString()));
									String hasil = df.format(
											Double.parseDouble(nilai) * Double.valueOf(map.get("bobot").toString()));

									jiBobot += Double.valueOf(map.get("bobot").toString());
									jiHasil += Double.parseDouble(hasil);
									tHasil += Double.parseDouble(hasil);

									rsMap.put("unitKerjaId", map.get("unitKerjaId"));
									rsMap.put("unitKerja", map.get("unitKerja"));
									rsMap.put("subunitKerjaId", map.get("subunitKerjaId"));
									rsMap.put("subunitKerja", map.get("subunitKerja"));
									rsMap.put("pegawaiId", map.get("pegawaiId"));
									rsMap.put("namaLengkap", map.get("namaLengkap"));
									rsMap.put("jabatanId", map.get("jabatanId"));
									rsMap.put("namaJabatan", map.get("namaJabatan"));
									rsMap.put("nilaiJabatan", map.get("nilaiJabatan"));
								}
							}
							if (idJI == 1) {
								rsMap.put("bobotKuantitas", jiBobot);
								rsMap.put("hasilKuantitas", Double.parseDouble(df.format(jiHasil)));
							} else if (idJI == 2) {
								rsMap.put("bobotKualitas", jiBobot);
								rsMap.put("hasilKualitas", Double.parseDouble(df.format(jiHasil)));
							} else if (idJI == 3) {
								rsMap.put("bobotPerilaku", jiBobot);
								rsMap.put("hasilPerilaku", Double.parseDouble(df.format(jiHasil)));
							}
						}
						if (CommonUtil.isNotNullOrEmpty(rsMap.get("unitKerjaId"))
								&& CommonUtil.isNotNullOrEmpty(rsMap.get("subunitKerjaId"))
								&& CommonUtil.isNotNullOrEmpty(rsMap.get("pegawaiId"))
								&& CommonUtil.isNotNullOrEmpty(rsMap.get("jabatanId"))
								&& CommonUtil.isNotNullOrEmpty(rsMap.get("nilaiJabatan"))) {
							Double iki = 0.00;
							String kriteria = "";
							if (Arrays.asList(Master.KelompokJabatan.DIR_MS).contains(idKelompokJabatan)) {
								for (Map<String, Object> aiki : acuanIndeks) {
									if ((Double.valueOf(aiki.get("nilaiBawah").toString()) < Double
											.parseDouble(df.format(tHasil))
											&& Double.parseDouble(df.format(tHasil)) <= Double
													.valueOf(aiki.get("nilaiAtas").toString()))
											|| (Double.parseDouble(df.format(tHasil)) > 1000
													&& Double.valueOf(aiki.get("nilaiAtas").toString()) == 1000)) {
										iki = Double.valueOf(aiki.get("iki").toString());
										kriteria = aiki.get("kriteria").toString();

										break;
									}
								}
							} else {
								List<Map<String, Object>> acuanIndeksLain = new ArrayList<>();
								for (Map<String, Object> aiki : acuanIndeks) {
									if (Double.parseDouble(
											aiki.get("iki").toString()) <= Master.TabelAcuanIndeksIKI.MAX_OTHERS) {
										acuanIndeksLain.add(aiki);
									}
								}

								for (Map<String, Object> aiki : acuanIndeksLain) {
									if ((Double.valueOf(aiki.get("nilaiBawah").toString()) < Double
											.parseDouble(df.format(tHasil))
											&& Double.parseDouble(df.format(tHasil)) <= Double
													.valueOf(aiki.get("nilaiAtas").toString()))
											|| (Double.parseDouble(df.format(tHasil)) > 160
													&& Double.valueOf(aiki.get("nilaiAtas").toString()) == 160)) {
										iki = Double.valueOf(aiki.get("iki").toString());
										kriteria = aiki.get("kriteria").toString();

										break;
									}
								}
							}

							rsMap.put("totalHasil", Double.parseDouble(df.format(tHasil)));
							rsMap.put("iki", iki);
							rsMap.put("kriteria", kriteria);

							recapData.add(rsMap);
						}
					}
				}
			}
		}

		for (Map<String, Object> rd : recapData) {
			for (Map<String, Object> ag : anggaran) {
				if (rd.get("pegawaiId").equals(ag.get("pegawaiId"))
						&& rd.get("jabatanId").equals(ag.get("jabatanId"))) {
					rd.put("pir", ag.get("pir"));

					break;
				}
			}
			double p1 = Double.valueOf(rd.get("nilaiJabatan").toString()) * Master.Remunerasi.IK_STANDAR
					* Double.valueOf(rd.get("pir").toString()) * Master.Remunerasi.PERSEN_P1;
			double p2 = Double.valueOf(rd.get("nilaiJabatan").toString()) * Double.valueOf(rd.get("iki").toString())
					* Master.Remunerasi.IKU * Double.valueOf(rd.get("pir").toString()) * Master.Remunerasi.PERSEN_P2;

			rd.put("p1", p1);
			rd.put("p2", p2);

			rd.put("rpP1", kursINA.format(p1).toString());
			rd.put("rpP2", kursINA.format(p2).toString());

			result.add(rd);
		}

		return result;
	}

	/**
	 * @param bulan
	 *            bulan spesifik perhitungan
	 * @param typeId
	 *            1-Hitung Target, 2-Hitung Verifikasi
	 */
	public List<SkorDokterVO> hitungSkorDokter(Date bulan, byte typeId) {
		List<SkorDokterVO> result = new ArrayList<>();
		List<Integer> listDetailJenisProduk = new ArrayList<>();
		List<Integer> listDetailJenisProdukException = new ArrayList<>();

		DateFormat mf = new SimpleDateFormat("yyyy-MM");

		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

		DecimalFormat decf = new DecimalFormat("###.###");
		decf.setRoundingMode(RoundingMode.HALF_UP);

		LocalDateTime PSBBDate = LocalDateTime.of(2020, 9, 14, 0, 0, 0);
		LocalDateTime PSBBEnd = LocalDateTime.parse(GetSettingDataFixed("psbbperiod"), dtf);

		Date pssbAwal = Date.from(PSBBDate.atZone(ZoneId.systemDefault()).toInstant());
		Date pssbAkhir = Date.from(PSBBEnd.atZone(ZoneId.systemDefault()).toInstant());

		Date start = DateUtil.startMonth(mf.format(bulan));
		Date end = DateUtil.endMonth(mf.format(bulan));

		List<Integer> listRuangEks = splitDataSettingDatafixed("IdRuanganEksekutif");

		List<Integer> listIdNonjadwal = shiftKerjaDao.findListNonjadwal();

		List<Integer> listIdPegawai = new ArrayList<>();
		if (typeId == 1) {
			listIdPegawai = mapPegawaiJabatanToUnitKerjaDao
					.findAllDokterKelompokStafMedik(Arrays.asList(Master.UnitKerja.KSM));
		} else if (typeId == 2) {
			listIdPegawai = logbookKinerjaDao.findPegawaiKontrakByIndikator(start, end,
					Master.IndikatorKinerja.PELAYANAN_MEDIS_JAM_KERJA);
		}

		List<Map<String, Object>> dataLayanan = ikiDanRemunerasiDao.getDataLogbookJamKerjaDokter(mf.format(bulan),
				pssbAwal, pssbAkhir, listIdNonjadwal, Master.JenisPegawai.DOKTER, listIdPegawai,
				Arrays.asList(Master.Departemen.GRUP_RAWAT_JALAN), Arrays.asList(Master.JenisProduk.NONTINDAKAN),
				Arrays.asList(Master.KelompokPasien.KELOMPOK_BPJS), Master.Produk.KARCIS);

		List<Map<String, Object>> dataSkor = skoringTindakanMedisDao.findSkoringLogbookDokter(mf.format(bulan),
				listIdPegawai, Arrays.asList(Master.UnitKerja.KSM));

		// SCORE
		for (Map<String, Object> mapLayanan : dataLayanan) {
			for (Map<String, Object> mapSkor : dataSkor) {
				if (mapLayanan.get("pegawaiId").equals(mapSkor.get("pegawaiId"))
						&& mapLayanan.get("produkId").equals(mapSkor.get("produkId"))
						&& (((Date) mapLayanan.get("tglPelayanan")).after((Date) mapSkor.get("tglMulaiBerlaku"))
								|| ((Date) mapLayanan.get("tglPelayanan"))
										.equals((Date) mapSkor.get("tglMulaiBerlaku")))) {
					mapLayanan.put("skor", mapSkor.get("skor"));
					break;
				}
			}
			if (!mapLayanan.containsKey("skor")) {
				mapLayanan.put("skor", 1.0);
			}
		}

		// RULES
		for (Map<String, Object> mapLayanan : dataLayanan) {
			if (Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0
					&& (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon"))
							|| Integer.valueOf(mapLayanan.get("statusDiskon").toString()).equals(0))) {
				// tidak_dapat_skor_untuk_diskon_dpjp
				mapLayanan.put("skor", 0.0);
				mapLayanan.put("tSkor", 0.0);
			} else if (!mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL)
					&& !mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.VISIT)
					&& listRuangEks.contains(mapLayanan.get("ruanganId"))) {
				mapLayanan.put("skor", Double.parseDouble(decf.format(
						Double.valueOf(mapLayanan.get("skor").toString()) * Master.Remunerasi.PERSEN_SKOR_EKSEKUTIF)));
				mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Double.valueOf(mapLayanan.get("jumlah").toString()))));
			} else if (mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) {
				mapLayanan.put("skor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Master.Remunerasi.PERSEN_SKOR_ASISTEN_SPESIALIS)));
				mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Double.valueOf(mapLayanan.get("jumlah").toString()))));
			} else {
				mapLayanan.put("skor",
						Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString()))));
				mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString())
						* Double.valueOf(mapLayanan.get("jumlah").toString()))));
			}
		}

		List<Integer> idsRegDJPAdminNonPK = splitDataSettingDatafixed("admin_nonpk");
		List<Integer> idsRegDJPMedisUtama = splitDataSettingDatafixed("medis_utama");
		List<Integer> idsRegDJPPenunjangPA = splitDataSettingDatafixed("penunjang_pa");
		List<Integer> idsRegDJPPenunjangPK = splitDataSettingDatafixed("penunjang_pk");
		List<Integer> idsRegDJPPenunjangRad = splitDataSettingDatafixed("penunjang_radiologi");

		List<Integer> laboranRadiologList = mapPegawaiLaboratRadiologiDao.findPegawaiLaboranRadiolog();
		List<Integer> drKsmUmumList = pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_UMUM);
		List<Integer> drLabPAList = pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_PATOLOGI_ANATOMI);
		List<Integer> drLabPKList = pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_PATOLOGI_KLINIK);
		List<Integer> drRadList = pegawaiDao.getDokterByKelompokKerja(Master.SubUnitKerja.KK_RADIOLOGI);
		
		List<Integer> idsDokterUmumIGD = splitDataSettingDatafixed("pr_dokter_umum_igd");
		for (Integer idPegawai : listIdPegawai) {
			SkorDokterVO skorDokterVO = new SkorDokterVO();

			if (drLabPAList.contains(idPegawai)) {
				listDetailJenisProduk = idsRegDJPPenunjangPA;
			} else if (drLabPKList.contains(idPegawai)) {
				listDetailJenisProduk = idsRegDJPPenunjangPK;
			} else if (drRadList.contains(idPegawai)) {
				listDetailJenisProduk = idsRegDJPPenunjangRad;
			} else {
				listDetailJenisProduk = idsRegDJPMedisUtama;
			}

			if (laboranRadiologList.contains(idPegawai)) {
				listDetailJenisProdukException = idsRegDJPAdminNonPK;
				listDetailJenisProdukException.removeAll(listDetailJenisProduk);

				listDetailJenisProduk.addAll(listDetailJenisProdukException);
			}

			double capaian = 0.0;
			for (Map<String, Object> mapLayanan : dataLayanan) {
				if (mapLayanan.get("pegawaiId").equals(idPegawai) && (listDetailJenisProduk
						.contains(mapLayanan.get("detailJenisProdukId"))
						|| (!listDetailJenisProduk.contains(mapLayanan.get("detailJenisProdukId"))
								&& idsDokterUmumIGD.contains(mapLayanan.get("produkId"))
								&& drKsmUmumList.contains(mapLayanan.get("pegawaiId"))
								&& mapLayanan.get("departemenId").equals(Master.Departemen.IGD)))) {
					capaian += Double.valueOf(mapLayanan.get("tSkor").toString());
				}
			}

			skorDokterVO.setBulan(bulan);
			skorDokterVO.setIdPegawai(idPegawai);
			skorDokterVO.setSkor(capaian);
			result.add(skorDokterVO);
		}

		return result;
	}

	@Override
	public void autoVerifKontrakJamKerjaDokter(Date bulan) {
		DateFormat mf = new SimpleDateFormat("yyyy-MM");

		List<Integer> listIdPegawai = new ArrayList<>();
		List<Integer> listIdJabatan = new ArrayList<>();
		List<String> listJabatanIndikator = new ArrayList<>();
		List<Map<String, Object>> listMapFilter = new ArrayList<>();

		Date endMonth = DateUtil.endMonth(bulan);
		Date startYear = DateUtil.startYear(bulan);
		Date endYear = DateUtil.endYear(bulan);
		/*
		 * Get All Mapping Indikator Dokter
		 */
		List<Map<String, Object>> listIndikatorDokter = indikatorKinerjaJabatanDao
				.findAllByIndikator(Master.IndikatorKinerja.PELAYANAN_MEDIS_JAM_KERJA);
		for (Map<String, Object> map : listIndikatorDokter) {
			if (!listIdJabatan.contains(Integer.parseInt(map.get("jabatanId").toString()))) {
				listIdJabatan.add(Integer.parseInt(map.get("jabatanId").toString()));
			}
		}

		List<Map<String, Object>> listMapIndikator = logbookKinerjaDao.findIndikatorByJabatan(listIdJabatan,
				mf.format(bulan));
		for (Map<String, Object> map : listMapIndikator) {
			if (!listJabatanIndikator
					.contains(map.get("jabatanId").toString() + "" + map.get("indikatorId").toString())) {
				listMapFilter.add(map);
			}
		}

		/*
		 * Get All Dokter Mapped Indikator
		 */
		List<Map<String, Object>> listKontrak = mapPegawaiJabatanToUnitKerjaDao.findAllPegawaiByJabatan(listIdJabatan);
		for (Map<String, Object> map : listKontrak) {
			if (!listIdPegawai.contains(Integer.parseInt(map.get("pegawaiId").toString()))) {
				listIdPegawai.add(Integer.parseInt(map.get("pegawaiId").toString()));
			}
		}
		/*
		 * Get Target Jumlah Pemenuhan Medis
		 */
		List<Map<String, Object>> listTargetSkor = targetSkorDokterDetailDao.findTargetByPegawai(listIdPegawai,
				endMonth, startYear, endYear);
		/*
		 * Get Bobot Jumlah Pemenuhan Medis
		 */
		Double bobotSkor = Double.parseDouble(settingDataFixedDao.getSettingDataFixed("bobotSkorDokter"));
		/*
		 * Get Target Pemenuhan Hari Kerja
		 */
		Integer targetHariKerja = hitungTargetHariKerja(bulan);
		/*
		 * Get Bobot Pemenuhan Hari Kerja
		 */
		Double bobotHariKerja = Double.parseDouble(settingDataFixedDao.getSettingDataFixed("bobotHariKerja"));
		/*
		 * Get Target Pemenuhan Jam Kerja
		 */
		Double targetJamKerja = hitungTargetMenitKerja(bulan);
		/*
		 * Get Bobot Pemenuhan Jam Kerja
		 */
		Double bobotJamKerja = Double.parseDouble(settingDataFixedDao.getSettingDataFixed("bobotJamKerja"));
		/*
		 * Get Target Kepatuhan Pelayanan Medis
		 */
		Double targetKualitasPelayanan = Double
				.parseDouble(settingDataFixedDao.getSettingDataFixed("targetKualitasDokter"));
		/*
		 * Get Bobot Kepatuhan Pelayanan Medis
		 */
		Double bobotKualitasPelayanan = Double
				.parseDouble(settingDataFixedDao.getSettingDataFixed("bobotKualitasDokter"));
		/*
		 * Get Detail Target Kepatuhan Pelayanan Medis
		 */
		List<IndikatorKinerjaDetail> ikds = indikatorKinerjaDetailDao
				.findByIndikator(Master.IndikatorKinerja.KEPATUHAN_PELAYANAN_MEDIS);
		/*
		 * Get Target Kepatuhan Waktu Visite
		 */
		Double targetPatuhWaktuVisite = Double
				.parseDouble(settingDataFixedDao.getSettingDataFixed("targetPatuhWaktuVisite"));
		/*
		 * Get Target Ketepatan Kehadiran
		 */
		Double targetPerilakuDokter = Double
				.parseDouble(settingDataFixedDao.getSettingDataFixed("targetPerilakuDokter"));
		/*
		 * Get Bobot Ketepatan Kehadiran
		 */
		Double bobotPerilakuDokter = Double.parseDouble(settingDataFixedDao.getSettingDataFixed("bobotPerilakuDokter"));
		/*
		 * Merge for virtual object logbook kinerja
		 */
		for (Map<String, Object> map : listMapFilter) {
			Integer idJabatan1 = Integer.parseInt(map.get("jabatanId").toString());
			for (Map<String, Object> kontrak : listKontrak) {
				Integer idJabatan2 = Integer.parseInt(kontrak.get("jabatanId").toString());
				if (idJabatan1.equals(idJabatan2)) {
					map.putAll(kontrak);
				}
			}
		}

		/*
		 * Save logbook kinerja dokter
		 */
		for (Map<String, Object> map : listMapFilter) {
			if (CommonUtil.isNotNullOrEmpty(map.get("pegawaiId"))
					&& CommonUtil.isNotNullOrEmpty(map.get("jabatanId"))) {
				LogbookKinerjaVO vo = new LogbookKinerjaVO();
				vo.setBulan(bulan);
				Integer idPegawai = Integer.parseInt(map.get("pegawaiId").toString());
				PegawaiVO pegawaiVO = new PegawaiVO();
				pegawaiVO.setId(idPegawai);
				vo.setPegawai(pegawaiVO);
				Integer idJabatan = Integer.parseInt(map.get("jabatanId").toString());
				JabatanVO jabatanVO = new JabatanVO();
				jabatanVO.setId(idJabatan);
				vo.setJabatan(jabatanVO);
				vo.setKdProfile((short) 0);
				vo.setStatusEnabled(true);
				vo.setStatusVerifikasi(true);
				IndikatorKinerjaVO logbookKinerjaVO = new IndikatorKinerjaVO();
				List<LogbookKinerjaDokter> lkds = new ArrayList<>();
				if (map.get("indikatorId").equals(Master.IndikatorKinerja.PELAYANAN_MEDIS_JAM_KERJA)) {
					logbookKinerjaVO.setId(Integer.parseInt(map.get("indikatorId").toString()));
					vo.setIndikatorKinerja(logbookKinerjaVO);
					vo.setBobot(bobotSkor);
					for (Map<String, Object> targetSkor : listTargetSkor) {
						if (idPegawai.equals(targetSkor.get("pegawaiId"))) {
							double target = Double.parseDouble(targetSkor.get("skor").toString());
							vo.setTarget(Math.floor(target));
							break;
						}
					}
				} else if (map.get("indikatorId").equals(Master.IndikatorKinerja.PEMENUHAN_HARI_KERJA)) {
					logbookKinerjaVO.setId(Integer.parseInt(map.get("indikatorId").toString()));
					vo.setIndikatorKinerja(logbookKinerjaVO);
					vo.setBobot(bobotHariKerja);
					vo.setTarget(targetHariKerja.doubleValue());
					vo.setCapaian(targetHariKerja.doubleValue());
				} else if (map.get("indikatorId").equals(Master.IndikatorKinerja.PEMENUHAN_JAM_KERJA)) {
					logbookKinerjaVO.setId(Integer.parseInt(map.get("indikatorId").toString()));
					vo.setIndikatorKinerja(logbookKinerjaVO);
					vo.setBobot(bobotJamKerja);
					vo.setTarget(targetJamKerja);
					vo.setCapaian(targetJamKerja);
				} else if (map.get("indikatorId").equals(Master.IndikatorKinerja.KEPATUHAN_PELAYANAN_MEDIS)) {
					logbookKinerjaVO.setId(Integer.parseInt(map.get("indikatorId").toString()));
					vo.setIndikatorKinerja(logbookKinerjaVO);
					vo.setBobot(bobotKualitasPelayanan);
					vo.setTarget(targetKualitasPelayanan);
					vo.setCapaian(targetKualitasPelayanan);
					/*
					 * Set Detail Target Kepatuhan Pelayanan Medis
					 */
					for (IndikatorKinerjaDetail ikd : ikds) {
						LogbookKinerjaDokter logbookKinerjaBaru = new LogbookKinerjaDokter();
						logbookKinerjaBaru.setBulan(bulan);
						logbookKinerjaBaru.setDetailTarget(targetPatuhWaktuVisite);
						logbookKinerjaBaru.setKdProfile((short) 0);
						logbookKinerjaBaru.setStatusEnabled(true);
						logbookKinerjaBaru.setTglHitung(new Date());
						logbookKinerjaBaru.setIndikatorDetail(ikd);
						Jabatan jb = new Jabatan();
						jb.setId(Integer.parseInt(map.get("jabatanId").toString()));
						logbookKinerjaBaru.setJabatan(jb);
						Pegawai pg = new Pegawai();
						pg.setId(Integer.parseInt(map.get("pegawaiId").toString()));
						logbookKinerjaBaru.setPegawai(pg);
						lkds.add(logbookKinerjaBaru);
					}
				} else if (map.get("indikatorId").equals(Master.IndikatorKinerja.KETEPATAN_KEHADIRAN)) {
					logbookKinerjaVO.setId(Integer.parseInt(map.get("indikatorId").toString()));
					vo.setIndikatorKinerja(logbookKinerjaVO);
					vo.setBobot(bobotPerilakuDokter);
					vo.setTarget(targetPerilakuDokter);
					vo.setCapaian(targetPerilakuDokter);
				}

				if (CommonUtil.isNotNullOrEmpty(lkds) && CommonUtil.isNotNullOrEmpty(vo.getTarget())) {
					logbookKinerjaDokterDao.save(lkds);
					this.add(vo);
				} else if (CommonUtil.isNotNullOrEmpty(vo.getTarget())) {
					this.add(vo);
				}
			}
		}
	}

	@Override
	public void autoVerifLogbookJamKerjaDokter(Date bulan) {
		byte verifId = 2;
		List<SkorDokterVO> listSkorDokterVO = hitungSkorDokter(bulan, verifId);

		for (SkorDokterVO skorDokterVO : listSkorDokterVO) {
			LogbookKinerjaVO vo = new LogbookKinerjaVO();
			PegawaiVO pegawai = new PegawaiVO();
			pegawai.setId(skorDokterVO.getIdPegawai());
			vo.setPegawai(pegawai);
			IndikatorKinerjaVO indikator = new IndikatorKinerjaVO();
			indikator.setId(Master.IndikatorKinerja.PELAYANAN_MEDIS_JAM_KERJA);
			vo.setIndikatorKinerja(indikator);
			vo.setBulan(skorDokterVO.getBulan());
			vo.setCapaian(skorDokterVO.getSkor());
			this.autoVerify(vo);
		}
	}

	@Override
	public List<SkorDokterVO> hitungTargetSkorLogbookDokter(String bulanAwal, String bulanAkhir) throws ParseException {
		List<SkorDokterVO> result = new ArrayList<>();

		DateFormat mf = new SimpleDateFormat("yyyy-MM");
		DateTimeFormatter smf = DateTimeFormatter.ofPattern("yyyy-MM");
		byte hitungTargetId = 1;
		java.time.LocalDate startDate = java.time.LocalDate.parse(bulanAwal + "-01");
		java.time.LocalDate endDate = java.time.LocalDate.parse(bulanAkhir + "-01");
		for (java.time.LocalDate date = startDate; date.isBefore(endDate)
				|| date.equals(endDate); date = date.plusMonths(1)) {
			List<SkorDokterVO> listRs = hitungSkorDokter(mf.parse(date.format(smf)), hitungTargetId);
			result.addAll(listRs);
		}

		/**
		 * Untuk output internal
		 */
		List<Integer> listIdPegawai = new ArrayList<>();
		List<Date> listBulan = new ArrayList<>();
		for (SkorDokterVO skorDokterVO : result) {
			if (!listIdPegawai.contains(skorDokterVO.getIdPegawai())) {
				listIdPegawai.add(skorDokterVO.getIdPegawai());
			}
			if (!listBulan.contains(skorDokterVO.getBulan())) {
				listBulan.add(skorDokterVO.getBulan());
			}
		}
		List<Integer> sortedListIdPegawai = listIdPegawai.stream().sorted().collect(Collectors.toList());
		List<Date> sortedListBulan = listBulan.stream().sorted().collect(Collectors.toList());

		for (Integer idPegawai : sortedListIdPegawai) {
			String out = "";
			String skor = "";
			for (Date bulan : sortedListBulan) {
				for (SkorDokterVO vo : result) {
					if (idPegawai.equals(vo.getIdPegawai()) && bulan.equals(vo.getBulan())) {
						if (skor == "") {
							skor = vo.getSkor().toString();
						} else {
							skor += "," + vo.getSkor().toString();
						}
					}
				}
			}
			out = idPegawai + "," + skor;
			System.out.println(out);
		}

		return result;
	}

	@Override
	public List<Double> findBobotJenisJabatan(Long periode, Integer idJabatan) {
		List<Double> result = new ArrayList<>();

		List<Map<String, Object>> data = new ArrayList<>();
		List<Date> bulanBerlaku = new ArrayList<>();

		DateFormat df = new SimpleDateFormat("yyyy-MM");

		bulanBerlaku = bobotJenisIndikatorDao.findBulanBerlaku(df.format(new Date(periode)), idJabatan);
		if (CommonUtil.isNullOrEmpty(bulanBerlaku)) {
			bulanBerlaku = bobotJenisIndikatorDao.findBulanBerlaku(df.format(new Date(periode)));
		}

		if (CommonUtil.isNotNullOrEmpty(bulanBerlaku)) {
			data = bobotJenisIndikatorDao.findBobotJenisKontrak(bulanBerlaku.get(0), idJabatan);
			if (CommonUtil.isNullOrEmpty(data) || data.size() != 3) {
				data = bobotJenisIndikatorDao.findBobotJenisKontrak(bulanBerlaku.get(0));
			}
		}

		if (CommonUtil.isNotNullOrEmpty(data)) {
			for (Map<String, Object> map : data) {
				result.add(Double.parseDouble(map.get("persentase").toString()));
			}
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findJabatanKontrakVerifKinerja(Integer idPegawai, Integer idPegawaiLogin) {
		List<Map<String, Object>> result = mapPegawaiJabatanToUnitKerjaDao.findJabLvlUkAtasan(idPegawai);
		for (Map<String, Object> map : result) {
			if ((CommonUtil.isNotNullOrEmpty(map.get("atasanId")) && map.get("atasanId").equals(idPegawaiLogin))
					|| (CommonUtil.isNotNullOrEmpty(map.get("penilaiId"))
							&& map.get("penilaiId").equals(idPegawaiLogin))
					|| idPegawai.equals(idPegawaiLogin)) {
				map.put("isCariAkses", true);
			} else {
				map.put("isCariAkses", false);
			}
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findLogbookPerawat(Integer idPegawai, Long bulan) {
		List<Map<String, Object>> result = new ArrayList<>();

		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		DateFormat mf = new SimpleDateFormat("yyyy-MM");

		DecimalFormat decf = new DecimalFormat("###.###");
		decf.setRoundingMode(RoundingMode.HALF_UP);

		List<Map<String, Object>> pelayananPerawat = pelayananPasienPerawatDao
				.findPelayananPerawat(mf.format(new Date(bulan)), idPegawai);

		pelayananPerawat = pelayananPerawat.stream().sorted(Comparator.comparing(o1 -> (Date) o1.get("tglPelayanan")))
				.sorted(Comparator.comparing(o2 -> o2.get("namaProduk").toString())).collect(Collectors.toList());

		List<Integer> listIdProduk = new ArrayList<>();
		List<Double> listSkor = new ArrayList<>();
		List<String> listTglPelayanan = new ArrayList<>();
		for (Map<String, Object> map : pelayananPerawat) {
			if (!listIdProduk.contains(map.get("produkId"))) {
				listIdProduk.add(Integer.parseInt(map.get("produkId").toString()));
			}
			if (!listSkor.contains(map.get("skor"))) {
				listSkor.add(Double.parseDouble(map.get("skor").toString()));
			}
			if (!listTglPelayanan.contains(df.format((Date) map.get("tglPelayanan")))) {
				listTglPelayanan.add(df.format((Date) map.get("tglPelayanan")));
			}
		}
		listTglPelayanan = listTglPelayanan.stream().sorted().collect(Collectors.toList());

		// GROUPING_TANGGAL_PELAYANAN
		List<Map<String, Object>> dataTglPelayanan = new ArrayList<>();
		for (Integer idProduk : listIdProduk) {
			for (Double skor : listSkor) {
				for (String tglPelayanan : listTglPelayanan) {
					Map<String, Object> data = new HashMap<>();
					double jumlahTindakan = 0.0;
					double jumlahSkor = 0.0;
					for (Map<String, Object> mapLayanan : pelayananPerawat) {
						if (idProduk.equals(mapLayanan.get("produkId")) && skor.equals(mapLayanan.get("skor"))
								&& tglPelayanan.equals(df.format((Date) mapLayanan.get("tglPelayanan")))) {
							jumlahTindakan += Double.valueOf(mapLayanan.get("jumlah").toString());
							jumlahSkor += Double.valueOf(mapLayanan.get("tSkor").toString());
							data.putAll(mapLayanan);
							data.put("tglPelayanan", df.format(((Date) mapLayanan.get("tglPelayanan"))));
						}
					}
					if (CommonUtil.isNotNullOrEmpty(data)) {
						data.put("jumlah", jumlahTindakan);
						data.put("tSkor", jumlahSkor);

						dataTglPelayanan.add(data);
					}
				}
			}
		}

		// GROUPING_HEADER
		for (Integer idProduk : listIdProduk) {
			for (Double skor : listSkor) {
				Map<String, Object> data = new HashMap<>();
				List<Map<String, Object>> detail = new ArrayList<>();
				double jumlahTindakan = 0.0;
				double jumlahSkor = 0.0;
				for (Map<String, Object> mapLayanan : dataTglPelayanan) {
					if (idProduk.equals(mapLayanan.get("produkId")) && skor.equals(mapLayanan.get("skor"))) {
						jumlahTindakan += Double.valueOf(mapLayanan.get("jumlah").toString());
						jumlahSkor += Double.valueOf(mapLayanan.get("tSkor").toString());

						Map<String, Object> mapDetail = new HashMap<>();
						mapDetail.put("jumlah", mapLayanan.get("jumlah"));
						mapDetail.put("tglPelayanan", mapLayanan.get("tglPelayanan"));
						detail.add(mapDetail);

						mapLayanan.remove("noRec");
						mapLayanan.remove("tglPelayanan");
						data.putAll(mapLayanan);
					}
				}
				if (CommonUtil.isNotNullOrEmpty(data)) {
					data.put("detail", detail);
					data.put("jumlah", jumlahTindakan);
					data.put("tSkor", Double.parseDouble(decf.format(jumlahSkor)));

					result.add(data);
				}
			}
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findDetailLogbookPerawat(Integer idPegawai, Integer idProduk,
			String tglPelayanan) {
		List<Map<String, Object>> result = pelayananPasienPerawatDao.findPelayananPerawatDetail(idPegawai, idProduk,
				tglPelayanan);

		return result;
	}

	@Override
	public List<Map<String, Object>> findLogbookNakes(Integer idPegawai, Long bulan) {
		List<Map<String, Object>> result = new ArrayList<>();

		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		DateFormat mf = new SimpleDateFormat("yyyy-MM");

		DecimalFormat decf = new DecimalFormat("###.###");
		decf.setRoundingMode(RoundingMode.HALF_UP);

		List<Map<String, Object>> pelayananNakes = new ArrayList<>();
		pelayananNakes.addAll(pelayananPasienNakesDao.findPelayananNakes(mf.format(new Date(bulan)), idPegawai));
		pelayananNakes.addAll(pelayananNakesDao.findPelayananNakes(mf.format(new Date(bulan)), idPegawai));

		pelayananNakes = pelayananNakes.stream().sorted(Comparator.comparing(o1 -> (Date) o1.get("tglPelayanan")))
				.sorted(Comparator.comparing(o2 -> o2.get("namaProduk").toString())).collect(Collectors.toList());

		List<Integer> listIdProduk = new ArrayList<>();
		List<Double> listSkor = new ArrayList<>();
		List<String> listTglPelayanan = new ArrayList<>();
		for (Map<String, Object> map : pelayananNakes) {
			if (!listIdProduk.contains(map.get("produkId"))) {
				listIdProduk.add(Integer.parseInt(map.get("produkId").toString()));
			}
			if (!listSkor.contains(map.get("skor"))) {
				listSkor.add(Double.parseDouble(map.get("skor").toString()));
			}
			if (!listTglPelayanan.contains(df.format((Date) map.get("tglPelayanan")))) {
				listTglPelayanan.add(df.format((Date) map.get("tglPelayanan")));
			}
		}
		listTglPelayanan = listTglPelayanan.stream().sorted().collect(Collectors.toList());

		// GROUPING_TANGGAL_PELAYANAN
		List<Map<String, Object>> dataTglPelayanan = new ArrayList<>();
		for (Integer idProduk : listIdProduk) {
			for (Double skor : listSkor) {
				for (String tglPelayanan : listTglPelayanan) {
					Map<String, Object> data = new HashMap<>();
					double jumlahTindakan = 0.0;
					double jumlahSkor = 0.0;
					for (Map<String, Object> mapLayanan : pelayananNakes) {
						if (idProduk.equals(mapLayanan.get("produkId")) && skor.equals(mapLayanan.get("skor"))
								&& tglPelayanan.equals(df.format((Date) mapLayanan.get("tglPelayanan")))) {
							jumlahTindakan += Double.valueOf(mapLayanan.get("jumlah").toString());
							jumlahSkor += Double.valueOf(mapLayanan.get("tSkor").toString());
							data.putAll(mapLayanan);
							data.put("tglPelayanan", df.format(((Date) mapLayanan.get("tglPelayanan"))));
						}
					}
					if (CommonUtil.isNotNullOrEmpty(data)) {
						data.put("jumlah", jumlahTindakan);
						data.put("tSkor", jumlahSkor);

						dataTglPelayanan.add(data);
					}
				}
			}
		}

		// GROUPING_HEADER
		for (Integer idProduk : listIdProduk) {
			for (Double skor : listSkor) {
				Map<String, Object> data = new HashMap<>();
				List<Map<String, Object>> detail = new ArrayList<>();
				double jumlahTindakan = 0.0;
				double jumlahSkor = 0.0;
				for (Map<String, Object> mapLayanan : dataTglPelayanan) {
					if (idProduk.equals(mapLayanan.get("produkId")) && skor.equals(mapLayanan.get("skor"))) {
						jumlahTindakan += Double.valueOf(mapLayanan.get("jumlah").toString());
						jumlahSkor += Double.valueOf(mapLayanan.get("tSkor").toString());

						Map<String, Object> mapDetail = new HashMap<>();
						mapDetail.put("jumlah", mapLayanan.get("jumlah"));
						mapDetail.put("tglPelayanan", mapLayanan.get("tglPelayanan"));
						detail.add(mapDetail);

						mapLayanan.remove("noRec");
						mapLayanan.remove("tglPelayanan");
						data.putAll(mapLayanan);
					}
				}
				if (CommonUtil.isNotNullOrEmpty(data)) {
					data.put("detail", detail);
					data.put("jumlah", jumlahTindakan);
					data.put("tSkor", Double.parseDouble(decf.format(jumlahSkor)));

					result.add(data);
				}
			}
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findDetailLogbookNakes(Integer idPegawai, Integer idProduk, String tglPelayanan) {
		List<Map<String, Object>> result = new ArrayList<>();

		result = pelayananPasienNakesDao.findPelayananNakesDetail(idPegawai, idProduk, tglPelayanan);
		if (CommonUtil.isNullOrEmpty(result)) {
			result = pelayananNakesDao.findPelayananNakesDetail(idPegawai, idProduk, tglPelayanan);
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findLogbookFarmakologi(Integer idPegawai, Long bulan) {
		List<Map<String, Object>> result = new ArrayList<>();

		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		DateFormat mf = new SimpleDateFormat("yyyy-MM");

		DecimalFormat decf = new DecimalFormat("###.###");
		decf.setRoundingMode(RoundingMode.HALF_UP);

		List<Map<String, Object>> pelayananFarmakologi = pelayananFarmakologiDao
				.findPelayananFarmakologi(mf.format(new Date(bulan)), idPegawai);

		List<Integer> listIdProduk = new ArrayList<>();
		List<Double> listSkor = new ArrayList<>();
		List<String> listTglPelayanan = new ArrayList<>();
		for (Map<String, Object> map : pelayananFarmakologi) {
			if (!listIdProduk.contains(map.get("produkId"))) {
				listIdProduk.add(Integer.parseInt(map.get("produkId").toString()));
			}
			if (!listSkor.contains(map.get("skor"))) {
				listSkor.add(Double.parseDouble(map.get("skor").toString()));
			}
			if (!listTglPelayanan.contains(df.format((Date) map.get("tglPelayanan")))) {
				listTglPelayanan.add(df.format((Date) map.get("tglPelayanan")));
			}
		}
		listTglPelayanan = listTglPelayanan.stream().sorted().collect(Collectors.toList());

		// GROUPING_TANGGAL_PELAYANAN
		List<Map<String, Object>> dataTglPelayanan = new ArrayList<>();
		for (Integer idProduk : listIdProduk) {
			for (Double skor : listSkor) {
				for (String tglPelayanan : listTglPelayanan) {
					Map<String, Object> data = new HashMap<>();
					double jumlahTindakan = 0.0;
					double jumlahSkor = 0.0;
					for (Map<String, Object> mapLayanan : pelayananFarmakologi) {
						if (idProduk.equals(mapLayanan.get("produkId")) && skor.equals(mapLayanan.get("skor"))
								&& tglPelayanan.equals(df.format((Date) mapLayanan.get("tglPelayanan")))) {
							jumlahTindakan += Double.valueOf(mapLayanan.get("jumlah").toString());
							jumlahSkor += Double.valueOf(mapLayanan.get("tSkor").toString());
							data.putAll(mapLayanan);
							data.put("tglPelayanan", df.format(((Date) mapLayanan.get("tglPelayanan"))));
						}
					}
					if (CommonUtil.isNotNullOrEmpty(data)) {
						data.put("jumlah", jumlahTindakan);
						data.put("tSkor", jumlahSkor);

						dataTglPelayanan.add(data);
					}
				}
			}
		}

		// GROUPING_HEADER
		for (Integer idProduk : listIdProduk) {
			for (Double skor : listSkor) {
				Map<String, Object> data = new HashMap<>();
				List<Map<String, Object>> detail = new ArrayList<>();
				double jumlahTindakan = 0.0;
				double jumlahSkor = 0.0;
				for (Map<String, Object> mapLayanan : dataTglPelayanan) {
					if (idProduk.equals(mapLayanan.get("produkId")) && skor.equals(mapLayanan.get("skor"))) {
						jumlahTindakan += Double.valueOf(mapLayanan.get("jumlah").toString());
						jumlahSkor += Double.valueOf(mapLayanan.get("tSkor").toString());

						Map<String, Object> mapDetail = new HashMap<>();
						mapDetail.put("jumlah", mapLayanan.get("jumlah"));
						mapDetail.put("tglPelayanan", mapLayanan.get("tglPelayanan"));
						detail.add(mapDetail);

						mapLayanan.remove("noRec");
						mapLayanan.remove("tglPelayanan");
						data.putAll(mapLayanan);
					}
				}
				if (CommonUtil.isNotNullOrEmpty(data)) {
					data.put("detail", detail);
					data.put("jumlah", jumlahTindakan);
					data.put("tSkor", Double.parseDouble(decf.format(jumlahSkor)));

					result.add(data);
				}
			}
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findDetailLogbookFarmakologi(Integer idPegawai, Integer idProduk,
			String tglPelayanan) {
		List<Map<String, Object>> result = pelayananFarmakologiDao.findPelayananFarmakologiDetail(idPegawai, idProduk,
				tglPelayanan);

		return result;
	}

	@Override
	public List<Map<String, Object>> findJabatanByLogbookPegawai(Integer idPegawai, Long bulan) {
		DateFormat mf = new SimpleDateFormat("yyyy-MM");

		List<Map<String, Object>> result = logbookKinerjaDao.findJabatanByPegawai(idPegawai,
				mf.format(new Date(bulan)));
		for (Map<String, Object> map : result) {
			map.put("isCariAkses", true);
		}

		return result;
	}

}